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..726542757f3a744ab360e9e636c66c12f4355049 |
--- /dev/null |
+++ b/chrome/browser/apps/app_url_redirector.cc |
@@ -0,0 +1,99 @@ |
+// 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_info_map.h" |
+#include "chrome/browser/profiles/profile.h" |
+#include "chrome/browser/profiles/profile_io_data.h" |
+#include "chrome/common/extensions/api/url_handlers/url_handlers_parser.h" |
+#include "chrome/common/extensions/extension.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 LaunchAppWithUrl( |
+ const extensions::Extension* app, |
not at google - send to devlin
2013/09/06 03:53:59
pass a scoped_refptr here
sergeygs
2013/09/06 05:46:46
Done.
|
+ const std::string& handler_id, |
+ content::RenderViewHost* source, |
+ const navigation_interception::NavigationParams& params) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ |
+ // These are guaranteed by CreateThrottleFor below. |
+ DCHECK(!params.is_post()); |
+ DCHECK(!source->IsSubframe()); |
+ DCHECK(extensions::UrlHandlers::CanExtensionHandleUrl(app, params.url())); |
not at google - send to devlin
2013/09/06 03:53:59
if you want
sergeygs
2013/09/06 05:46:46
?
not at google - send to devlin
2013/09/06 14:11:33
Sorry, I was being unnecessarily cryptic.
What I
|
+ |
+ WebContents* web_contents = WebContents::FromRenderViewHost(source); |
+ if (!web_contents) |
+ return false; |
+ Profile* profile = |
+ Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
+ |
+ apps::LaunchPlatformAppWithUrl( |
+ profile, app, handler_id, params.url(), params.referrer().url); |
+ |
+ return true; |
+} |
+ |
+} // namespace |
+ |
+// static |
+content::ResourceThrottle* |
+AppUrlRedirector::MaybeCreateThrottleFor(net::URLRequest* request, |
+ int render_process_id, |
+ int render_view_id, |
+ ProfileIOData* profile_io_data) { |
+ // Support only GET for now. |
+ if (request->method() != "GET") |
+ return NULL; |
+ |
+ // Never redirect URLs to apps in incognito. Technically, apps are not |
+ // supported in incognito, but that may change in future. For now, the caller |
+ // of CreateThrottleFor() must make sure it's not an incognito profile. |
+ // See crbug.com/240879, which tracks incognito support for v2 apps. |
+ if (profile_io_data->is_incognito()) |
+ return NULL; |
+ |
+ content::RenderViewHost* render_view_host = |
+ content::RenderViewHost::FromID(render_process_id, render_view_id); |
+ if (!render_view_host) |
+ return NULL; |
+ |
+ // Redirect top-level navigations only. This excludes iframes and webviews |
+ // in particular. |
+ if (render_view_host->IsSubframe()) |
darin (slow to review)
2013/09/06 04:18:48
it is not valid to call RenderViewHost methods on
sergeygs
2013/09/06 05:46:46
Noted and done.
|
+ return NULL; |
+ |
+ const ExtensionSet& extensions = |
+ profile_io_data->GetExtensionInfoMap()->extensions(); |
+ for (ExtensionSet::const_iterator iter = extensions.begin(); |
+ iter != extensions.end(); |
+ ++iter) { |
+ const extensions::UrlHandlerInfo* handler = |
+ extensions::UrlHandlers::FindMatchingUrlHandler(*iter, request->url()); |
+ if (handler) { |
+ return new navigation_interception::InterceptNavigationResourceThrottle( |
+ request, |
+ base::Bind(&LaunchAppWithUrl, *iter, handler->id)); |
+ } |
+ } |
+ |
+ return NULL; |
+} |