| 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();
|
|
|