Index: chrome/browser/extensions/extension_service.cc |
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc |
index 8fc25936e35cbc882f8ff4f3fafdc3b9c56e78b5..728554274a620a84977f2b4afe8c9eda53c4f855 100644 |
--- a/chrome/browser/extensions/extension_service.cc |
+++ b/chrome/browser/extensions/extension_service.cc |
@@ -78,6 +78,7 @@ |
#include "chrome/common/chrome_switches.h" |
#include "chrome/common/chrome_version_info.h" |
#include "chrome/common/extensions/api/plugins/plugins_handler.h" |
+#include "chrome/common/extensions/api/url_handlers/url_handlers_parser.h" |
#include "chrome/common/extensions/background_info.h" |
#include "chrome/common/extensions/extension.h" |
#include "chrome/common/extensions/extension_file_util.h" |
@@ -94,6 +95,7 @@ |
#include "chrome/common/url_constants.h" |
#include "content/public/browser/browser_thread.h" |
#include "content/public/browser/devtools_agent_host.h" |
+#include "content/public/browser/extension_system_notifications.h" |
#include "content/public/browser/notification_service.h" |
#include "content/public/browser/notification_types.h" |
#include "content/public/browser/plugin_service.h" |
@@ -131,6 +133,7 @@ using extensions::PermissionMessage; |
using extensions::PermissionMessages; |
using extensions::PermissionSet; |
using extensions::UnloadedExtensionInfo; |
+using extensions::AppEventRouter; |
namespace errors = extension_manifest_errors; |
@@ -378,6 +381,8 @@ ExtensionService::ExtensionService(Profile* profile, |
content::NotificationService::AllBrowserContextsAndSources()); |
registrar_.Add(this, chrome::NOTIFICATION_UPGRADE_RECOMMENDED, |
content::NotificationService::AllBrowserContextsAndSources()); |
+ registrar_.Add(this, content::NOTIFICATION_LAUNCH_APP_WITH_URL, |
+ content::NotificationService::AllBrowserContextsAndSources()); |
pref_change_registrar_.Init(profile->GetPrefs()); |
base::Closure callback = |
base::Bind(&ExtensionService::OnExtensionInstallPrefChanged, |
@@ -454,7 +459,7 @@ scoped_ptr<const ExtensionSet> |
} |
extensions::PendingExtensionManager* |
- ExtensionService::pending_extension_manager() { |
+ExtensionService::pending_extension_manager() { |
return &pending_extension_manager_; |
} |
@@ -2493,6 +2498,43 @@ bool ExtensionService::ShouldBlockUrlInBrowserTab(GURL* url) { |
return false; |
} |
+bool ExtensionService::MaybeRedirectUrlToApp(const GURL& url, |
+ const GURL& referrer_url) { |
+ // NOTE: The current API spec enforces at most a single app matching a URL. |
+ // TODO: Actually implement the above-mentioned enforcement. |
+ const extensions::UrlHandlerInfo* handler = |
+ extensions_.GetHandlingAppForURL(url); |
+ if (handler) { |
+ DCHECK(handler->app->is_platform_app()); |
+ extensions::AppEventRouter::DispatchOnLaunchedEventWithURL( |
+ profile_, handler->app, handler->id, url, referrer_url); |
+ return true; |
+ } |
+ |
+ return false; |
+} |
not at google - send to devlin
2013/08/19 23:32:24
This doesn't need to be in ExtensionService. Pull
sergeygs
2013/08/29 08:24:42
Done. The class is PlatformAppRedirector in chrome
|
+ |
+bool ExtensionService::RedirectUrlToApp(const std::string& app_id, |
+ const std::string& handler_id, |
+ const GURL& url, |
+ const GURL& referrer_url) { |
+ // We're just saving some time here by explicitly passing both the url and |
+ // the handling app ID here. The original initiator of the app's invocation |
+ // (e.g. ChromeContentRendererClient) already has to know this info before |
+ // calling us. If the caller doesn't know that, it should use |
+ // MaybeRedirectUrlToApp() instead. |
+ const Extension* app = GetExtensionById(app_id, true); |
+ if (app) { |
+ DCHECK(app->is_platform_app() && |
+ app == extensions_.GetHandlingAppForURL(url)->app); |
+ extensions::AppEventRouter::DispatchOnLaunchedEventWithURL( |
+ profile_, app, handler_id, url, referrer_url); |
+ return true; |
+ } |
+ |
+ return false; |
+} |
+ |
bool ExtensionService::OnExternalExtensionFileFound( |
const std::string& id, |
const Version* version, |
@@ -2598,12 +2640,14 @@ void ExtensionService::Observe(int type, |
const content::NotificationSource& source, |
const content::NotificationDetails& details) { |
switch (type) { |
- case chrome::NOTIFICATION_APP_TERMINATING: |
+ case chrome::NOTIFICATION_APP_TERMINATING: { |
// Shutdown has started. Don't start any more extension installs. |
// (We cannot use ExtensionService::Shutdown() for this because it |
// happens too late in browser teardown.) |
browser_terminating_ = true; |
break; |
+ } |
+ |
case chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED: { |
if (profile_ != |
content::Source<Profile>(source).ptr()->GetOriginalProfile()) { |
@@ -2626,6 +2670,7 @@ void ExtensionService::Observe(int type, |
host->extension())); |
break; |
} |
+ |
case content::NOTIFICATION_RENDERER_PROCESS_CREATED: { |
content::RenderProcessHost* process = |
content::Source<content::RenderProcessHost>(source).ptr(); |
@@ -2659,6 +2704,7 @@ void ExtensionService::Observe(int type, |
process->Send(new ExtensionMsg_Loaded(loaded_extensions)); |
break; |
} |
+ |
case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: { |
content::RenderProcessHost* process = |
content::Source<content::RenderProcessHost>(source).ptr(); |
@@ -2675,10 +2721,12 @@ void ExtensionService::Observe(int type, |
process->GetID())); |
break; |
} |
+ |
case chrome::NOTIFICATION_IMPORT_FINISHED: { |
InitAfterImport(); |
break; |
} |
+ |
case chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED: { |
extensions::ExtensionHost* host = |
content::Details<extensions::ExtensionHost>(details).ptr(); |
@@ -2694,6 +2742,7 @@ void ExtensionService::Observe(int type, |
} |
break; |
} |
+ |
case chrome::NOTIFICATION_UPGRADE_RECOMMENDED: { |
// Notify extensions that chrome update is available. |
extensions::RuntimeEventRouter::DispatchOnBrowserUpdateAvailableEvent( |
@@ -2705,6 +2754,17 @@ void ExtensionService::Observe(int type, |
break; |
} |
+ case content::NOTIFICATION_LAUNCH_APP_WITH_URL: { |
+ // Notify the extension system that a navigation has happened whose |
+ // target URL was claimed by one of the platform apps, and instruct |
+ // it to launch that app. |
+ content::LaunchAppWithUrlDetails* launch = |
+ content::Details<content::LaunchAppWithUrlDetails>(details).ptr(); |
+ RedirectUrlToApp(launch->app_id, launch->handler_id, |
+ launch->url, launch->referrer_url); |
+ break; |
+ } |
+ |
default: |
NOTREACHED() << "Unexpected notification type."; |
} |