Index: chrome/browser/apps/app_url_redirector.cc |
diff --git a/chrome/browser/apps/app_url_redirector.cc b/chrome/browser/apps/app_url_redirector.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..2e004d23209e9c969a5ed4874f2e097f3ec8f94f |
--- /dev/null |
+++ b/chrome/browser/apps/app_url_redirector.cc |
@@ -0,0 +1,86 @@ |
+// Copyright 2013 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chrome/browser/apps/app_url_redirector.h" |
+ |
+#include "apps/launcher.h" |
+#include "base/bind.h" |
+#include "base/logging.h" |
+#include "chrome/browser/extensions/extension_service.h" |
+#include "chrome/browser/extensions/extension_system.h" |
+#include "chrome/browser/profiles/profile.h" |
+#include "chrome/common/extensions/api/url_handlers/url_handlers_parser.h" |
+#include "chrome/common/extensions/extension_messages.h" |
+#include "chrome/common/extensions/extension_set.h" |
+#include "components/navigation_interception/intercept_navigation_resource_throttle.h" |
+#include "components/navigation_interception/navigation_params.h" |
+#include "content/public/browser/browser_thread.h" |
+#include "content/public/browser/render_view_host.h" |
+#include "content/public/browser/resource_throttle.h" |
+#include "content/public/browser/web_contents.h" |
+#include "net/url_request/url_request.h" |
+ |
+ |
+using content::BrowserThread; |
+using content::WebContents; |
+ |
+namespace { |
+ |
+bool MaybeRedirectUrlToApp( |
+ content::RenderViewHost* source, |
+ const navigation_interception::NavigationParams& params) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ DCHECK(source); |
+ |
+ // Redirect top-level navigations only. This excludes iframes and webviews |
+ // in particular. |
+ if (source->IsSubframe()) |
+ return false; |
+ |
+ if (params.is_post()) |
darin (slow to review)
2013/09/05 23:54:25
I would just use DCHECKs for anything that is redu
sergeygs
2013/09/06 02:51:14
Done. IsSubframe() is needed. MAIN_FRAME check aro
|
+ return false; |
+ |
+ WebContents* web_contents = WebContents::FromRenderViewHost(source); |
+ if (!web_contents) |
+ return false; |
+ |
+ Profile* profile = |
+ Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
+ // Never redirect URLs to apps in incognito. Technically, apps are not |
+ // supported in incognito, but that may change in future. |
+ // See crbug.com/240879, which tracks incognito support for v2 apps. |
+ if (!profile || profile->IsOffTheRecord()) |
+ return false; |
+ |
+ ExtensionService* service = |
+ extensions::ExtensionSystem::Get(profile)->extension_service(); |
+ if (!service) |
+ return false; |
+ |
+ const GURL& url = params.url(); |
+ const GURL& referrer_url = params.referrer().url; |
+ |
+ for (ExtensionSet::const_iterator iter = service->extensions()->begin(); |
+ iter != service->extensions()->end(); |
+ ++iter) { |
+ const extensions::UrlHandlerInfo* handler = |
+ extensions::UrlHandlers::FindMatchingUrlHandler(*iter, url); |
+ if (handler) { |
+ apps::LaunchPlatformAppWithUrl( |
+ profile, *iter, handler->id, url, referrer_url); |
+ return true; |
+ } |
+ } |
+ |
+ return false; |
+} |
+ |
+} // namespace |
+ |
+// static |
+content::ResourceThrottle* |
+AppUrlRedirector::CreateThrottleFor(net::URLRequest* request) { |
+ return new navigation_interception::InterceptNavigationResourceThrottle( |
+ request, base::Bind(&MaybeRedirectUrlToApp)); |
+} |