Index: chrome/browser/extensions/api/runtime/runtime_api.cc |
diff --git a/chrome/browser/extensions/api/runtime/runtime_api.cc b/chrome/browser/extensions/api/runtime/runtime_api.cc |
index 0a9c61b6e53c0f444a4ae9147c7ff458c437c5f2..3545291a3ab7e1d64d05a1aa102b0a567e2d8acf 100644 |
--- a/chrome/browser/extensions/api/runtime/runtime_api.cc |
+++ b/chrome/browser/extensions/api/runtime/runtime_api.cc |
@@ -10,6 +10,7 @@ |
#include "base/logging.h" |
#include "base/memory/scoped_ptr.h" |
#include "base/values.h" |
+#include "chrome/browser/browser_process.h" |
#include "chrome/browser/chrome_notification_types.h" |
#include "chrome/browser/extensions/extension_service.h" |
#include "chrome/browser/extensions/updater/extension_updater.h" |
@@ -24,7 +25,7 @@ |
#include "content/public/browser/notification_service.h" |
#include "content/public/browser/render_process_host.h" |
#include "content/public/browser/render_view_host.h" |
-#include "extensions/browser/api/runtime/runtime_event_router.h" |
+#include "extensions/browser/event_router.h" |
#include "extensions/browser/extension_host.h" |
#include "extensions/browser/extension_registry.h" |
#include "extensions/browser/extension_system.h" |
@@ -55,6 +56,11 @@ |
const char kNoBackgroundPageError[] = "You do not have a background page."; |
const char kPageLoadError[] = "Background page failed to load."; |
+const char kInstallReason[] = "reason"; |
+const char kInstallReasonChromeUpdate[] = "chrome_update"; |
+const char kInstallReasonUpdate[] = "update"; |
+const char kInstallReasonInstall[] = "install"; |
+const char kInstallPreviousVersion[] = "previousVersion"; |
const char kInvalidUrlError[] = "Invalid URL."; |
const char kUpdatesDisabledError[] = "Autoupdate is not enabled."; |
const char kUpdateFound[] = "update_available"; |
@@ -68,6 +74,49 @@ |
// particular value does not matter to user code, but is chosen for consistency |
// with the equivalent Pepper API. |
const char kPackageDirectoryPath[] = "crxfs"; |
+ |
+void DispatchOnStartupEventImpl(BrowserContext* browser_context, |
+ const std::string& extension_id, |
+ bool first_call, |
+ ExtensionHost* host) { |
+ // A NULL host from the LazyBackgroundTaskQueue means the page failed to |
+ // load. Give up. |
+ if (!host && !first_call) |
+ return; |
+ |
+ // Don't send onStartup events to incognito browser contexts. |
+ if (browser_context->IsOffTheRecord()) |
+ return; |
+ |
+ if (ExtensionsBrowserClient::Get()->IsShuttingDown() || |
+ !ExtensionsBrowserClient::Get()->IsValidContext(browser_context)) |
+ return; |
+ ExtensionSystem* system = ExtensionSystem::Get(browser_context); |
+ if (!system) |
+ return; |
+ |
+ // If this is a persistent background page, we want to wait for it to load |
+ // (it might not be ready, since this is startup). But only enqueue once. |
+ // If it fails to load the first time, don't bother trying again. |
+ const Extension* extension = |
+ ExtensionRegistry::Get(browser_context)->enabled_extensions().GetByID( |
+ extension_id); |
+ if (extension && BackgroundInfo::HasPersistentBackgroundPage(extension) && |
+ first_call && |
+ system->lazy_background_task_queue()-> |
+ ShouldEnqueueTask(browser_context, extension)) { |
+ system->lazy_background_task_queue()->AddPendingTask( |
+ browser_context, extension_id, |
+ base::Bind(&DispatchOnStartupEventImpl, |
+ browser_context, extension_id, false)); |
+ return; |
+ } |
+ |
+ scoped_ptr<base::ListValue> event_args(new base::ListValue()); |
+ scoped_ptr<Event> event(new Event(runtime::OnStartup::kEventName, |
+ event_args.Pass())); |
+ system->event_router()->DispatchEventToExtension(extension_id, event.Pass()); |
+} |
void SetUninstallURL(ExtensionPrefs* prefs, |
const std::string& extension_id, |
@@ -98,7 +147,7 @@ |
return g_factory.Pointer(); |
} |
-RuntimeAPI::RuntimeAPI(BrowserContext* context) |
+RuntimeAPI::RuntimeAPI(content::BrowserContext* context) |
: browser_context_(context), |
dispatch_chrome_updated_event_(false), |
registered_for_updates_(false) { |
@@ -187,9 +236,9 @@ |
return; |
// Get the previous version to check if this is an upgrade. |
- const Extension* old = |
- ExtensionRegistry::Get(browser_context_) |
- ->GetExtensionById(extension->id(), ExtensionRegistry::EVERYTHING); |
+ ExtensionService* service = ExtensionSystem::Get( |
+ browser_context_)->extension_service(); |
+ const Extension* old = service->GetExtensionById(extension->id(), true); |
Version old_version; |
if (old) |
old_version = *old->version(); |
@@ -212,12 +261,110 @@ |
return; |
Profile* profile = Profile::FromBrowserContext(browser_context_); |
- ShowUninstallURL(profile, extension->id()); |
-} |
+ RuntimeEventRouter::OnExtensionUninstalled(profile, extension->id()); |
+} |
+ |
+void RuntimeAPI::OnAppUpdateAvailable(const Extension* extension) { |
+ Profile* profile = Profile::FromBrowserContext(browser_context_); |
+ RuntimeEventRouter::DispatchOnUpdateAvailableEvent( |
+ profile, extension->id(), extension->manifest()->value()); |
+} |
+ |
+void RuntimeAPI::OnChromeUpdateAvailable() { |
+ Profile* profile = Profile::FromBrowserContext(browser_context_); |
+ RuntimeEventRouter::DispatchOnBrowserUpdateAvailableEvent(profile); |
+} |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
// static |
-void RuntimeAPI::ShowUninstallURL(Profile* profile, |
- const std::string& extension_id) { |
+void RuntimeEventRouter::DispatchOnStartupEvent( |
+ content::BrowserContext* context, const std::string& extension_id) { |
+ DispatchOnStartupEventImpl(context, extension_id, true, NULL); |
+} |
+ |
+// static |
+void RuntimeEventRouter::DispatchOnInstalledEvent( |
+ content::BrowserContext* context, |
+ const std::string& extension_id, |
+ const Version& old_version, |
+ bool chrome_updated) { |
+ if (!ExtensionsBrowserClient::Get()->IsValidContext(context)) |
+ return; |
+ ExtensionSystem* system = ExtensionSystem::Get(context); |
+ if (!system) |
+ return; |
+ |
+ scoped_ptr<base::ListValue> event_args(new base::ListValue()); |
+ base::DictionaryValue* info = new base::DictionaryValue(); |
+ event_args->Append(info); |
+ if (old_version.IsValid()) { |
+ info->SetString(kInstallReason, kInstallReasonUpdate); |
+ info->SetString(kInstallPreviousVersion, old_version.GetString()); |
+ } else if (chrome_updated) { |
+ info->SetString(kInstallReason, kInstallReasonChromeUpdate); |
+ } else { |
+ info->SetString(kInstallReason, kInstallReasonInstall); |
+ } |
+ DCHECK(system->event_router()); |
+ scoped_ptr<Event> event(new Event(runtime::OnInstalled::kEventName, |
+ event_args.Pass())); |
+ system->event_router()->DispatchEventWithLazyListener(extension_id, |
+ event.Pass()); |
+} |
+ |
+// static |
+void RuntimeEventRouter::DispatchOnUpdateAvailableEvent( |
+ Profile* profile, |
+ const std::string& extension_id, |
+ const base::DictionaryValue* manifest) { |
+ ExtensionSystem* system = ExtensionSystem::Get(profile); |
+ if (!system) |
+ return; |
+ |
+ scoped_ptr<base::ListValue> args(new base::ListValue); |
+ args->Append(manifest->DeepCopy()); |
+ DCHECK(system->event_router()); |
+ scoped_ptr<Event> event(new Event(runtime::OnUpdateAvailable::kEventName, |
+ args.Pass())); |
+ system->event_router()->DispatchEventToExtension(extension_id, event.Pass()); |
+} |
+ |
+// static |
+void RuntimeEventRouter::DispatchOnBrowserUpdateAvailableEvent( |
+ Profile* profile) { |
+ ExtensionSystem* system = ExtensionSystem::Get(profile); |
+ if (!system) |
+ return; |
+ |
+ scoped_ptr<base::ListValue> args(new base::ListValue); |
+ DCHECK(system->event_router()); |
+ scoped_ptr<Event> event(new Event( |
+ runtime::OnBrowserUpdateAvailable::kEventName, args.Pass())); |
+ system->event_router()->BroadcastEvent(event.Pass()); |
+} |
+ |
+// static |
+void RuntimeEventRouter::DispatchOnRestartRequiredEvent( |
+ Profile* profile, |
+ const std::string& app_id, |
+ api::runtime::OnRestartRequired::Reason reason) { |
+ ExtensionSystem* system = ExtensionSystem::Get(profile); |
+ if (!system) |
+ return; |
+ |
+ scoped_ptr<Event> event( |
+ new Event(runtime::OnRestartRequired::kEventName, |
+ api::runtime::OnRestartRequired::Create(reason))); |
+ |
+ DCHECK(system->event_router()); |
+ system->event_router()->DispatchEventToExtension(app_id, event.Pass()); |
+} |
+ |
+// static |
+void RuntimeEventRouter::OnExtensionUninstalled( |
+ Profile* profile, |
+ const std::string& extension_id) { |
#if defined(ENABLE_EXTENSIONS) |
GURL uninstall_url(GetUninstallURL(ExtensionPrefs::Get(profile), |
extension_id)); |
@@ -238,17 +385,6 @@ |
chrome::Navigate(¶ms); |
#endif // defined(ENABLE_EXTENSIONS) |
} |
- |
-void RuntimeAPI::OnAppUpdateAvailable(const Extension* extension) { |
- RuntimeEventRouter::DispatchOnUpdateAvailableEvent( |
- browser_context_, extension->id(), extension->manifest()->value()); |
-} |
- |
-void RuntimeAPI::OnChromeUpdateAvailable() { |
- RuntimeEventRouter::DispatchOnBrowserUpdateAvailableEvent(browser_context_); |
-} |
- |
-/////////////////////////////////////////////////////////////////////////////// |
bool RuntimeGetBackgroundPageFunction::RunImpl() { |
ExtensionSystem* system = ExtensionSystem::Get(GetProfile()); |
@@ -279,8 +415,6 @@ |
} |
} |
-////////////////////////////////////////////////////////////////////////////// |
- |
bool RuntimeSetUninstallURLFunction::RunImpl() { |
std::string url_string; |
EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &url_string)); |
@@ -295,8 +429,6 @@ |
ExtensionPrefs::Get(GetProfile()), extension_id(), url_string); |
return true; |
} |
- |
-////////////////////////////////////////////////////////////////////////////// |
bool RuntimeReloadFunction::RunImpl() { |
// We can't call ReloadExtension directly, since when this method finishes |
@@ -309,8 +441,6 @@ |
extension_id())); |
return true; |
} |
- |
-////////////////////////////////////////////////////////////////////////////// |
RuntimeRequestUpdateCheckFunction::RuntimeRequestUpdateCheckFunction() { |
registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UPDATE_FOUND, |
@@ -384,8 +514,6 @@ |
SendResponse(true); |
} |
-////////////////////////////////////////////////////////////////////////////// |
- |
bool RuntimeRestartFunction::RunImpl() { |
#if defined(OS_CHROMEOS) |
if (chromeos::UserManager::Get()->IsLoggedInAsKioskApp()) { |
@@ -398,8 +526,6 @@ |
SetError("Function available only for ChromeOS kiosk mode."); |
return false; |
} |
- |
-////////////////////////////////////////////////////////////////////////////// |
bool RuntimeGetPlatformInfoFunction::RunImpl() { |
GetPlatformInfo::Results::PlatformInfo info; |
@@ -450,8 +576,6 @@ |
return true; |
} |
-////////////////////////////////////////////////////////////////////////////// |
- |
bool RuntimeGetPackageDirectoryEntryFunction::RunImpl() { |
fileapi::IsolatedContext* isolated_context = |
fileapi::IsolatedContext::GetInstance(); |