summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/shell/app_shell.gyp3
-rw-r--r--apps/shell/browser/shell_extensions_browser_client.cc7
-rw-r--r--apps/shell/browser/shell_extensions_browser_client.h2
-rw-r--r--apps/shell/browser/shell_runtime_api_delegate.cc68
-rw-r--r--apps/shell/browser/shell_runtime_api_delegate.h38
-rw-r--r--apps/shell/common/shell_extensions_client.cc5
-rw-r--r--chrome/browser/chromeos/app_mode/kiosk_app_update_service.cc12
-rw-r--r--chrome/browser/extensions/api/messaging/message_property_provider.cc2
-rw-r--r--chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate.cc284
-rw-r--r--chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate.h86
-rw-r--r--chrome/browser/extensions/browser_context_keyed_service_factories.cc2
-rw-r--r--chrome/browser/extensions/chrome_extensions_browser_client.cc8
-rw-r--r--chrome/browser/extensions/chrome_extensions_browser_client.h2
-rw-r--r--chrome/browser/extensions/extension_messages_apitest.cc2
-rw-r--r--chrome/browser/extensions/installed_loader.cc2
-rw-r--r--chrome/chrome_browser_extensions.gypi6
-rw-r--r--chrome/chrome_tests.gypi3
-rw-r--r--chrome/common/extensions/api/_api_features.json53
-rw-r--r--chrome/common/extensions/api/_permission_features.json6
-rw-r--r--chrome/common/extensions/api/api.gyp2
-rw-r--r--chrome/renderer/resources/extensions/last_error.js6
-rw-r--r--extensions/DEPS5
-rw-r--r--extensions/browser/DEPS1
-rw-r--r--extensions/browser/api/runtime/runtime_api.cc (renamed from chrome/browser/extensions/api/runtime/runtime_api.cc)435
-rw-r--r--extensions/browser/api/runtime/runtime_api.h (renamed from chrome/browser/extensions/api/runtime/runtime_api.h)95
-rw-r--r--extensions/browser/api/runtime/runtime_api_delegate.cc16
-rw-r--r--extensions/browser/api/runtime/runtime_api_delegate.h77
-rw-r--r--extensions/browser/api/runtime/runtime_apitest.cc (renamed from chrome/browser/extensions/api/runtime/runtime_apitest.cc)14
-rw-r--r--extensions/browser/browser_context_keyed_service_factories.cc8
-rw-r--r--extensions/browser/extensions_browser_client.h7
-rw-r--r--extensions/browser/test_extensions_browser_client.cc7
-rw-r--r--extensions/browser/test_extensions_browser_client.h2
-rw-r--r--extensions/browser/test_runtime_api_delegate.cc53
-rw-r--r--extensions/browser/test_runtime_api_delegate.h36
-rw-r--r--extensions/common/api/_api_features.json53
-rw-r--r--extensions/common/api/_permission_features.json6
-rw-r--r--extensions/common/api/api.gyp1
-rw-r--r--extensions/common/api/runtime.json (renamed from chrome/common/extensions/api/runtime.json)49
-rw-r--r--extensions/extensions.gyp10
39 files changed, 1012 insertions, 462 deletions
diff --git a/apps/shell/app_shell.gyp b/apps/shell/app_shell.gyp
index 9ce5329..6da130d 100644
--- a/apps/shell/app_shell.gyp
+++ b/apps/shell/app_shell.gyp
@@ -130,6 +130,8 @@
'browser/shell_extensions_browser_client.h',
'browser/shell_network_controller_chromeos.cc',
'browser/shell_network_controller_chromeos.h',
+ 'browser/shell_runtime_api_delegate.cc',
+ 'browser/shell_runtime_api_delegate.h',
'common/shell_app_runtime.cc',
'common/shell_app_runtime.h',
'common/shell_content_client.cc',
@@ -149,6 +151,7 @@
'conditions': [
['chromeos==1', {
'dependencies': [
+ '<(DEPTH)/chromeos/chromeos.gyp:chromeos',
'<(DEPTH)/ui/chromeos/ui_chromeos.gyp:ui_chromeos',
],
}],
diff --git a/apps/shell/browser/shell_extensions_browser_client.cc b/apps/shell/browser/shell_extensions_browser_client.cc
index 769350c..054a717 100644
--- a/apps/shell/browser/shell_extensions_browser_client.cc
+++ b/apps/shell/browser/shell_extensions_browser_client.cc
@@ -7,6 +7,7 @@
#include "apps/shell/browser/shell_app_sorting.h"
#include "apps/shell/browser/shell_extension_system_factory.h"
#include "apps/shell/browser/shell_extension_web_contents_observer.h"
+#include "apps/shell/browser/shell_runtime_api_delegate.h"
#include "apps/shell/common/api/generated_api.h"
#include "base/prefs/pref_service.h"
#include "base/prefs/pref_service_factory.h"
@@ -235,4 +236,10 @@ void ShellExtensionsBrowserClient::RegisterExtensionFunctions(
apps::shell_api::GeneratedFunctionRegistry::RegisterAll(registry);
}
+scoped_ptr<RuntimeAPIDelegate>
+ShellExtensionsBrowserClient::CreateRuntimeAPIDelegate(
+ content::BrowserContext* context) const {
+ return scoped_ptr<RuntimeAPIDelegate>(new apps::ShellRuntimeAPIDelegate());
+}
+
} // namespace extensions
diff --git a/apps/shell/browser/shell_extensions_browser_client.h b/apps/shell/browser/shell_extensions_browser_client.h
index 0862dd5..67e937d 100644
--- a/apps/shell/browser/shell_extensions_browser_client.h
+++ b/apps/shell/browser/shell_extensions_browser_client.h
@@ -73,6 +73,8 @@ class ShellExtensionsBrowserClient : public ExtensionsBrowserClient {
virtual ExtensionSystemProvider* GetExtensionSystemFactory() OVERRIDE;
virtual void RegisterExtensionFunctions(
ExtensionFunctionRegistry* registry) const OVERRIDE;
+ virtual scoped_ptr<RuntimeAPIDelegate> CreateRuntimeAPIDelegate(
+ content::BrowserContext* context) const OVERRIDE;
private:
// The single BrowserContext for app_shell. Not owned.
diff --git a/apps/shell/browser/shell_runtime_api_delegate.cc b/apps/shell/browser/shell_runtime_api_delegate.cc
new file mode 100644
index 0000000..fc475ba
--- /dev/null
+++ b/apps/shell/browser/shell_runtime_api_delegate.cc
@@ -0,0 +1,68 @@
+// Copyright 2014 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 "apps/shell/browser/shell_runtime_api_delegate.h"
+
+#include "extensions/common/api/runtime.h"
+
+#if defined(OS_CHROMEOS)
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/power_manager_client.h"
+#endif
+
+using extensions::core_api::runtime::PlatformInfo;
+
+namespace apps {
+
+ShellRuntimeAPIDelegate::ShellRuntimeAPIDelegate() {
+}
+
+ShellRuntimeAPIDelegate::~ShellRuntimeAPIDelegate() {
+}
+
+void ShellRuntimeAPIDelegate::AddUpdateObserver(
+ extensions::UpdateObserver* observer) {
+}
+
+void ShellRuntimeAPIDelegate::RemoveUpdateObserver(
+ extensions::UpdateObserver* observer) {
+}
+
+base::Version ShellRuntimeAPIDelegate::GetPreviousExtensionVersion(
+ const extensions::Extension* extension) {
+ return base::Version();
+}
+
+void ShellRuntimeAPIDelegate::ReloadExtension(const std::string& extension_id) {
+}
+
+bool ShellRuntimeAPIDelegate::CheckForUpdates(
+ const std::string& extension_id,
+ const UpdateCheckCallback& callback) {
+ return false;
+}
+
+void ShellRuntimeAPIDelegate::OpenURL(const GURL& uninstall_url) {
+}
+
+bool ShellRuntimeAPIDelegate::GetPlatformInfo(PlatformInfo* info) {
+#if defined(OS_CHROMEOS)
+ info->os = PlatformInfo::OS_CROS_;
+#elif defined(OS_LINUX)
+ info->os = PlatformInfo::OS_LINUX_;
+#endif
+ return true;
+}
+
+bool ShellRuntimeAPIDelegate::RestartDevice(std::string* error_message) {
+// We allow chrome.runtime.restart() to request a device restart on ChromeOS.
+#if defined(OS_CHROMEOS)
+ chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart();
+ return true;
+#endif
+ *error_message = "Restart is only supported on ChromeOS.";
+ return false;
+}
+
+} // namespace apps
diff --git a/apps/shell/browser/shell_runtime_api_delegate.h b/apps/shell/browser/shell_runtime_api_delegate.h
new file mode 100644
index 0000000..fcef1b7
--- /dev/null
+++ b/apps/shell/browser/shell_runtime_api_delegate.h
@@ -0,0 +1,38 @@
+// Copyright 2014 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.
+
+#ifndef APPS_SHELL_BROWSER_SHELL_RUNTIME_API_DELEGATE_H_
+#define APPS_SHELL_BROWSER_SHELL_RUNTIME_API_DELEGATE_H_
+
+#include "base/macros.h"
+#include "extensions/browser/api/runtime/runtime_api_delegate.h"
+
+namespace apps {
+
+class ShellRuntimeAPIDelegate : public extensions::RuntimeAPIDelegate {
+ public:
+ ShellRuntimeAPIDelegate();
+ virtual ~ShellRuntimeAPIDelegate();
+
+ // extensions::RuntimeAPIDelegate implementation.
+ virtual void AddUpdateObserver(extensions::UpdateObserver* observer) OVERRIDE;
+ virtual void RemoveUpdateObserver(
+ extensions::UpdateObserver* observer) OVERRIDE;
+ virtual base::Version GetPreviousExtensionVersion(
+ const extensions::Extension* extension) OVERRIDE;
+ virtual void ReloadExtension(const std::string& extension_id) OVERRIDE;
+ virtual bool CheckForUpdates(const std::string& extension_id,
+ const UpdateCheckCallback& callback) OVERRIDE;
+ virtual void OpenURL(const GURL& uninstall_url) OVERRIDE;
+ virtual bool GetPlatformInfo(
+ extensions::core_api::runtime::PlatformInfo* info) OVERRIDE;
+ virtual bool RestartDevice(std::string* error_message) OVERRIDE;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ShellRuntimeAPIDelegate);
+};
+
+} // namespace apps
+
+#endif // APPS_SHELL_BROWSER_SHELL_RUNTIME_API_DELEGATE_H_
diff --git a/apps/shell/common/shell_extensions_client.cc b/apps/shell/common/shell_extensions_client.cc
index 9b96545..5c142d4 100644
--- a/apps/shell/common/shell_extensions_client.cc
+++ b/apps/shell/common/shell_extensions_client.cc
@@ -24,7 +24,6 @@
#include "extensions/common/permissions/permissions_provider.h"
#include "extensions/common/url_pattern_set.h"
#include "grit/app_shell_resources.h"
-#include "grit/common_resources.h"
#include "grit/extensions_resources.h"
using extensions::APIPermissionInfo;
@@ -129,18 +128,14 @@ scoped_ptr<FeatureProvider> ShellExtensionsClient::CreateFeatureProvider(
if (name == "api") {
source.LoadJSON(IDR_EXTENSION_API_FEATURES);
source.LoadJSON(IDR_SHELL_EXTENSION_API_FEATURES);
- // TODO(yoz): Don't include Chrome resources.
- source.LoadJSON(IDR_CHROME_EXTENSION_API_FEATURES);
return scoped_ptr<FeatureProvider>(new BaseFeatureProvider(
source.dictionary(), CreateFeature<extensions::APIFeature>));
} else if (name == "manifest") {
source.LoadJSON(IDR_EXTENSION_MANIFEST_FEATURES);
- source.LoadJSON(IDR_CHROME_EXTENSION_MANIFEST_FEATURES);
return scoped_ptr<FeatureProvider>(new BaseFeatureProvider(
source.dictionary(), CreateFeature<extensions::ManifestFeature>));
} else if (name == "permission") {
source.LoadJSON(IDR_EXTENSION_PERMISSION_FEATURES);
- source.LoadJSON(IDR_CHROME_EXTENSION_PERMISSION_FEATURES);
return scoped_ptr<FeatureProvider>(new BaseFeatureProvider(
source.dictionary(), CreateFeature<extensions::PermissionFeature>));
} else {
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_update_service.cc b/chrome/browser/chromeos/app_mode/kiosk_app_update_service.cc
index a488b51..e695674 100644
--- a/chrome/browser/chromeos/app_mode/kiosk_app_update_service.cc
+++ b/chrome/browser/chromeos/app_mode/kiosk_app_update_service.cc
@@ -10,11 +10,11 @@
#include "chrome/browser/browser_process_platform_part_chromeos.h"
#include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
#include "chrome/browser/chromeos/system/automatic_reboot_manager.h"
-#include "chrome/browser/extensions/api/runtime/runtime_api.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/lifetime/application_lifetime.h"
#include "chrome/browser/profiles/profile.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
+#include "extensions/browser/api/runtime/runtime_api.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/extension_system_provider.h"
#include "extensions/browser/extensions_browser_client.h"
@@ -82,22 +82,22 @@ void KioskAppUpdateService::OnAppUpdateAvailable(
extensions::RuntimeEventRouter::DispatchOnRestartRequiredEvent(
profile_,
app_id_,
- extensions::api::runtime::OnRestartRequired::REASON_APP_UPDATE);
+ extensions::core_api::runtime::OnRestartRequired::REASON_APP_UPDATE);
StartAppUpdateRestartTimer();
}
void KioskAppUpdateService::OnRebootScheduled(Reason reason) {
- extensions::api::runtime::OnRestartRequired::Reason restart_reason =
- extensions::api::runtime::OnRestartRequired::REASON_NONE;
+ extensions::core_api::runtime::OnRestartRequired::Reason restart_reason =
+ extensions::core_api::runtime::OnRestartRequired::REASON_NONE;
switch (reason) {
case REBOOT_REASON_OS_UPDATE:
restart_reason =
- extensions::api::runtime::OnRestartRequired::REASON_OS_UPDATE;
+ extensions::core_api::runtime::OnRestartRequired::REASON_OS_UPDATE;
break;
case REBOOT_REASON_PERIODIC:
restart_reason =
- extensions::api::runtime::OnRestartRequired::REASON_PERIODIC;
+ extensions::core_api::runtime::OnRestartRequired::REASON_PERIODIC;
break;
default:
NOTREACHED() << "Unknown reboot reason=" << reason;
diff --git a/chrome/browser/extensions/api/messaging/message_property_provider.cc b/chrome/browser/extensions/api/messaging/message_property_provider.cc
index c15c3ad..4871bc3 100644
--- a/chrome/browser/extensions/api/messaging/message_property_provider.cc
+++ b/chrome/browser/extensions/api/messaging/message_property_provider.cc
@@ -10,8 +10,8 @@
#include "base/strings/string_piece.h"
#include "base/values.h"
#include "chrome/browser/profiles/profile.h"
-#include "chrome/common/extensions/api/runtime.h"
#include "content/public/browser/browser_thread.h"
+#include "extensions/common/api/runtime.h"
#include "net/base/completion_callback.h"
#include "net/cert/asn1_util.h"
#include "net/cert/jwk_serializer.h"
diff --git a/chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate.cc b/chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate.cc
new file mode 100644
index 0000000..59e611c
--- /dev/null
+++ b/chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate.cc
@@ -0,0 +1,284 @@
+// Copyright 2014 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/extensions/api/runtime/chrome_runtime_api_delegate.h"
+
+#include "base/message_loop/message_loop.h"
+#include "base/metrics/histogram.h"
+#include "base/time/time.h"
+#include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/extensions/extension_warning_service.h"
+#include "chrome/browser/extensions/extension_warning_set.h"
+#include "chrome/browser/extensions/updater/extension_updater.h"
+#include "chrome/browser/omaha_query_params/omaha_query_params.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/browser_navigator.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "content/public/browser/notification_service.h"
+#include "extensions/browser/extension_system.h"
+#include "extensions/common/api/runtime.h"
+
+#if defined(OS_CHROMEOS)
+#include "chrome/browser/chromeos/login/user_manager.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/power_manager_client.h"
+#endif
+
+using extensions::Extension;
+using extensions::ExtensionSystem;
+using extensions::ExtensionUpdater;
+
+using extensions::core_api::runtime::PlatformInfo;
+
+namespace {
+
+const char kUpdateThrottled[] = "throttled";
+const char kUpdateNotFound[] = "no_update";
+const char kUpdateFound[] = "update_available";
+
+// If an extension reloads itself within this many miliseconds of reloading
+// itself, the reload is considered suspiciously fast.
+const int kFastReloadTime = 10000;
+
+// After this many suspiciously fast consecutive reloads, an extension will get
+// disabled.
+const int kFastReloadCount = 5;
+
+} // namespace
+
+ChromeRuntimeAPIDelegate::ChromeRuntimeAPIDelegate(
+ content::BrowserContext* context)
+ : browser_context_(context), registered_for_updates_(false) {
+ registrar_.Add(this,
+ chrome::NOTIFICATION_EXTENSION_UPDATE_FOUND,
+ content::NotificationService::AllSources());
+}
+
+ChromeRuntimeAPIDelegate::~ChromeRuntimeAPIDelegate() {
+}
+
+void ChromeRuntimeAPIDelegate::AddUpdateObserver(
+ extensions::UpdateObserver* observer) {
+ registered_for_updates_ = true;
+ ExtensionSystem::Get(browser_context_)
+ ->extension_service()
+ ->AddUpdateObserver(observer);
+}
+
+void ChromeRuntimeAPIDelegate::RemoveUpdateObserver(
+ extensions::UpdateObserver* observer) {
+ if (registered_for_updates_) {
+ ExtensionSystem::Get(browser_context_)
+ ->extension_service()
+ ->RemoveUpdateObserver(observer);
+ }
+}
+
+base::Version ChromeRuntimeAPIDelegate::GetPreviousExtensionVersion(
+ const Extension* extension) {
+ // Get the previous version to check if this is an upgrade.
+ ExtensionService* service =
+ ExtensionSystem::Get(browser_context_)->extension_service();
+ const Extension* old = service->GetExtensionById(extension->id(), true);
+ if (old)
+ return *old->version();
+ return base::Version();
+}
+
+void ChromeRuntimeAPIDelegate::ReloadExtension(
+ const std::string& extension_id) {
+ std::pair<base::TimeTicks, int>& reload_info =
+ last_reload_time_[extension_id];
+ base::TimeTicks now = base::TimeTicks::Now();
+ if (reload_info.first.is_null() ||
+ (now - reload_info.first).InMilliseconds() > kFastReloadTime) {
+ reload_info.second = 0;
+ } else {
+ reload_info.second++;
+ }
+ if (!reload_info.first.is_null()) {
+ UMA_HISTOGRAM_LONG_TIMES("Extensions.RuntimeReloadTime",
+ now - reload_info.first);
+ }
+ UMA_HISTOGRAM_COUNTS_100("Extensions.RuntimeReloadFastCount",
+ reload_info.second);
+ reload_info.first = now;
+
+ ExtensionService* service =
+ ExtensionSystem::Get(browser_context_)->extension_service();
+ if (reload_info.second >= kFastReloadCount) {
+ // Unloading an extension clears all warnings, so first terminate the
+ // extension, and then add the warning. Since this is called from an
+ // extension function unloading the extension has to be done
+ // asynchronously. Fortunately PostTask guarentees FIFO order so just
+ // post both tasks.
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(&ExtensionService::TerminateExtension,
+ service->AsWeakPtr(),
+ extension_id));
+ extensions::ExtensionWarningSet warnings;
+ warnings.insert(
+ extensions::ExtensionWarning::CreateReloadTooFrequentWarning(
+ extension_id));
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(&extensions::ExtensionWarningService::NotifyWarningsOnUI,
+ browser_context_,
+ warnings));
+ } else {
+ // We can't call ReloadExtension directly, since when this method finishes
+ // it tries to decrease the reference count for the extension, which fails
+ // if the extension has already been reloaded; so instead we post a task.
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(&ExtensionService::ReloadExtension,
+ service->AsWeakPtr(),
+ extension_id));
+ }
+}
+
+bool ChromeRuntimeAPIDelegate::CheckForUpdates(
+ const std::string& extension_id,
+ const UpdateCheckCallback& callback) {
+ ExtensionSystem* system = ExtensionSystem::Get(browser_context_);
+ ExtensionService* service = system->extension_service();
+ ExtensionUpdater* updater = service->updater();
+ if (!updater) {
+ return false;
+ }
+ if (!updater->CheckExtensionSoon(
+ extension_id,
+ base::Bind(&ChromeRuntimeAPIDelegate::UpdateCheckComplete,
+ base::Unretained(this),
+ extension_id))) {
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(callback, UpdateCheckResult(true, kUpdateThrottled, "")));
+ } else {
+ UpdateCallbackList& callbacks = pending_update_checks_[extension_id];
+ callbacks.push_back(callback);
+ }
+ return true;
+}
+
+void ChromeRuntimeAPIDelegate::OpenURL(const GURL& uninstall_url) {
+#if defined(ENABLE_EXTENSIONS)
+ Profile* profile = Profile::FromBrowserContext(browser_context_);
+ Browser* browser =
+ chrome::FindLastActiveWithProfile(profile, chrome::GetActiveDesktop());
+ if (!browser)
+ browser =
+ new Browser(Browser::CreateParams(profile, chrome::GetActiveDesktop()));
+
+ chrome::NavigateParams params(
+ browser, uninstall_url, content::PAGE_TRANSITION_CLIENT_REDIRECT);
+ params.disposition = NEW_FOREGROUND_TAB;
+ params.user_gesture = false;
+ chrome::Navigate(&params);
+#endif
+}
+
+bool ChromeRuntimeAPIDelegate::GetPlatformInfo(PlatformInfo* info) {
+ const char* os = chrome::OmahaQueryParams::GetOS();
+ if (strcmp(os, "mac") == 0) {
+ info->os = PlatformInfo::OS_MAC_;
+ } else if (strcmp(os, "win") == 0) {
+ info->os = PlatformInfo::OS_WIN_;
+ } else if (strcmp(os, "android") == 0) {
+ info->os = PlatformInfo::OS_ANDROID_;
+ } else if (strcmp(os, "cros") == 0) {
+ info->os = PlatformInfo::OS_CROS_;
+ } else if (strcmp(os, "linux") == 0) {
+ info->os = PlatformInfo::OS_LINUX_;
+ } else if (strcmp(os, "openbsd") == 0) {
+ info->os = PlatformInfo::OS_OPENBSD_;
+ } else {
+ NOTREACHED();
+ return false;
+ }
+
+ const char* arch = chrome::OmahaQueryParams::GetArch();
+ if (strcmp(arch, "arm") == 0) {
+ info->arch = PlatformInfo::ARCH_ARM;
+ } else if (strcmp(arch, "x86") == 0) {
+ info->arch = PlatformInfo::ARCH_X86_32;
+ } else if (strcmp(arch, "x64") == 0) {
+ info->arch = PlatformInfo::ARCH_X86_64;
+ } else {
+ NOTREACHED();
+ return false;
+ }
+
+ const char* nacl_arch = chrome::OmahaQueryParams::GetNaclArch();
+ if (strcmp(nacl_arch, "arm") == 0) {
+ info->nacl_arch = PlatformInfo::NACL_ARCH_ARM;
+ } else if (strcmp(nacl_arch, "x86-32") == 0) {
+ info->nacl_arch = PlatformInfo::NACL_ARCH_X86_32;
+ } else if (strcmp(nacl_arch, "x86-64") == 0) {
+ info->nacl_arch = PlatformInfo::NACL_ARCH_X86_64;
+ } else {
+ NOTREACHED();
+ return false;
+ }
+
+ return true;
+}
+
+bool ChromeRuntimeAPIDelegate::RestartDevice(std::string* error_message) {
+#if defined(OS_CHROMEOS)
+ if (chromeos::UserManager::Get()->IsLoggedInAsKioskApp()) {
+ chromeos::DBusThreadManager::Get()
+ ->GetPowerManagerClient()
+ ->RequestRestart();
+ return true;
+ }
+#endif
+ *error_message = "Function available only for ChromeOS kiosk mode.";
+ return false;
+}
+
+void ChromeRuntimeAPIDelegate::Observe(
+ int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) {
+ DCHECK(type == chrome::NOTIFICATION_EXTENSION_UPDATE_FOUND);
+ typedef const std::pair<std::string, Version> UpdateDetails;
+ const std::string& id = content::Details<UpdateDetails>(details)->first;
+ const Version& version = content::Details<UpdateDetails>(details)->second;
+ if (version.IsValid()) {
+ CallUpdateCallbacks(
+ id, UpdateCheckResult(true, kUpdateFound, version.GetString()));
+ }
+}
+
+void ChromeRuntimeAPIDelegate::UpdateCheckComplete(
+ const std::string& extension_id) {
+ ExtensionSystem* system = ExtensionSystem::Get(browser_context_);
+ ExtensionService* service = system->extension_service();
+ const Extension* update = service->GetPendingExtensionUpdate(extension_id);
+ if (update) {
+ CallUpdateCallbacks(
+ extension_id,
+ UpdateCheckResult(true, kUpdateFound, update->VersionString()));
+ } else {
+ CallUpdateCallbacks(extension_id,
+ UpdateCheckResult(true, kUpdateNotFound, ""));
+ }
+}
+
+void ChromeRuntimeAPIDelegate::CallUpdateCallbacks(
+ const std::string& extension_id,
+ const UpdateCheckResult& result) {
+ UpdateCallbackList callbacks = pending_update_checks_[extension_id];
+ pending_update_checks_.erase(extension_id);
+ for (UpdateCallbackList::const_iterator iter = callbacks.begin();
+ iter != callbacks.end();
+ ++iter) {
+ const UpdateCheckCallback& callback = *iter;
+ callback.Run(result);
+ }
+}
diff --git a/chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate.h b/chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate.h
new file mode 100644
index 0000000..cdb6e7a
--- /dev/null
+++ b/chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate.h
@@ -0,0 +1,86 @@
+// Copyright 2014 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.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_API_RUNTIME_CHROME_RUNTIME_API_DELEGATE_H_
+#define CHROME_BROWSER_EXTENSIONS_API_RUNTIME_CHROME_RUNTIME_API_DELEGATE_H_
+
+#include <map>
+#include <vector>
+
+#include "base/macros.h"
+#include "content/public/browser/notification_observer.h"
+#include "content/public/browser/notification_registrar.h"
+#include "extensions/browser/api/runtime/runtime_api.h"
+#include "extensions/browser/api/runtime/runtime_api_delegate.h"
+
+namespace base {
+class TimeTicks;
+}
+
+namespace content {
+class BrowserContext;
+class NotificationDetails;
+class NotificationSource;
+}
+
+namespace extensions {
+class RuntimeAPI;
+class UpdateObserver;
+}
+
+class ChromeRuntimeAPIDelegate : public extensions::RuntimeAPIDelegate,
+ public content::NotificationObserver {
+ public:
+ explicit ChromeRuntimeAPIDelegate(content::BrowserContext* context);
+ virtual ~ChromeRuntimeAPIDelegate();
+
+ private:
+ friend class extensions::RuntimeAPI;
+
+ // extensions::RuntimeAPIDelegate implementation.
+ virtual void AddUpdateObserver(extensions::UpdateObserver* observer) OVERRIDE;
+ virtual void RemoveUpdateObserver(
+ extensions::UpdateObserver* observer) OVERRIDE;
+ virtual base::Version GetPreviousExtensionVersion(
+ const extensions::Extension* extension) OVERRIDE;
+ virtual void ReloadExtension(const std::string& extension_id) OVERRIDE;
+ virtual bool CheckForUpdates(const std::string& extension_id,
+ const UpdateCheckCallback& callback) OVERRIDE;
+ virtual void OpenURL(const GURL& uninstall_url) OVERRIDE;
+ virtual bool GetPlatformInfo(
+ extensions::core_api::runtime::PlatformInfo* info) OVERRIDE;
+ virtual bool RestartDevice(std::string* error_message) OVERRIDE;
+
+ // content::NotificationObserver implementation.
+ virtual void Observe(int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) OVERRIDE;
+
+ void UpdateCheckComplete(const std::string& extension_id);
+ void CallUpdateCallbacks(const std::string& extension_id,
+ const UpdateCheckResult& result);
+
+ content::BrowserContext* browser_context_;
+
+ content::NotificationRegistrar registrar_;
+
+ // Whether the API registered with the ExtensionService to receive
+ // update notifications.
+ bool registered_for_updates_;
+
+ // Map to prevent extensions from getting stuck in reload loops. Maps
+ // extension id to the last time it was reloaded and the number of times
+ // it was reloaded with not enough time in between reloads.
+ std::map<std::string, std::pair<base::TimeTicks, int> > last_reload_time_;
+
+ // Pending update checks.
+ typedef std::vector<UpdateCheckCallback> UpdateCallbackList;
+ typedef std::map<std::string, UpdateCallbackList> UpdateCallbackMap;
+ UpdateCallbackMap pending_update_checks_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ChromeRuntimeAPIDelegate);
+};
+
+#endif // CHROME_BROWSER_EXTENSIONS_API_RUNTIME_CHROME_RUNTIME_API_DELEGATE_H_
diff --git a/chrome/browser/extensions/browser_context_keyed_service_factories.cc b/chrome/browser/extensions/browser_context_keyed_service_factories.cc
index d83454b..884f801 100644
--- a/chrome/browser/extensions/browser_context_keyed_service_factories.cc
+++ b/chrome/browser/extensions/browser_context_keyed_service_factories.cc
@@ -38,7 +38,6 @@
#include "chrome/browser/extensions/api/preference/preference_api.h"
#include "chrome/browser/extensions/api/processes/processes_api.h"
#include "chrome/browser/extensions/api/push_messaging/push_messaging_api.h"
-#include "chrome/browser/extensions/api/runtime/runtime_api.h"
#include "chrome/browser/extensions/api/serial/serial_connection.h"
#include "chrome/browser/extensions/api/sessions/sessions_api.h"
#include "chrome/browser/extensions/api/settings_overrides/settings_overrides_api.h"
@@ -143,7 +142,6 @@ void EnsureBrowserContextKeyedServiceFactoriesBuilt() {
extensions::PreferenceAPI::GetFactoryInstance();
extensions::ProcessesAPI::GetFactoryInstance();
extensions::PushMessagingAPI::GetFactoryInstance();
- extensions::RuntimeAPI::GetFactoryInstance();
extensions::SessionsAPI::GetFactoryInstance();
extensions::SettingsOverridesAPI::GetFactoryInstance();
extensions::SignedInDevicesManager::GetFactoryInstance();
diff --git a/chrome/browser/extensions/chrome_extensions_browser_client.cc b/chrome/browser/extensions/chrome_extensions_browser_client.cc
index cb0868a..fe53a07 100644
--- a/chrome/browser/extensions/chrome_extensions_browser_client.cc
+++ b/chrome/browser/extensions/chrome_extensions_browser_client.cc
@@ -12,6 +12,7 @@
#include "chrome/browser/extensions/activity_log/activity_log.h"
#include "chrome/browser/extensions/api/preference/chrome_direct_setting.h"
#include "chrome/browser/extensions/api/preference/preference_api.h"
+#include "chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate.h"
#include "chrome/browser/extensions/api/web_request/web_request_api.h"
#include "chrome/browser/extensions/chrome_app_sorting.h"
#include "chrome/browser/extensions/chrome_extension_host_delegate.h"
@@ -269,4 +270,11 @@ void ChromeExtensionsBrowserClient::RegisterExtensionFunctions(
#endif
}
+scoped_ptr<extensions::RuntimeAPIDelegate>
+ChromeExtensionsBrowserClient::CreateRuntimeAPIDelegate(
+ content::BrowserContext* context) const {
+ return scoped_ptr<extensions::RuntimeAPIDelegate>(
+ new ChromeRuntimeAPIDelegate(context));
+}
+
} // namespace extensions
diff --git a/chrome/browser/extensions/chrome_extensions_browser_client.h b/chrome/browser/extensions/chrome_extensions_browser_client.h
index c47e851..0c5d160 100644
--- a/chrome/browser/extensions/chrome_extensions_browser_client.h
+++ b/chrome/browser/extensions/chrome_extensions_browser_client.h
@@ -87,6 +87,8 @@ class ChromeExtensionsBrowserClient : public ExtensionsBrowserClient {
virtual ExtensionSystemProvider* GetExtensionSystemFactory() OVERRIDE;
virtual void RegisterExtensionFunctions(
ExtensionFunctionRegistry* registry) const OVERRIDE;
+ virtual scoped_ptr<extensions::RuntimeAPIDelegate> CreateRuntimeAPIDelegate(
+ content::BrowserContext* context) const OVERRIDE;
private:
friend struct base::DefaultLazyInstanceTraits<ChromeExtensionsBrowserClient>;
diff --git a/chrome/browser/extensions/extension_messages_apitest.cc b/chrome/browser/extensions/extension_messages_apitest.cc
index 83f3356..5d219d8 100644
--- a/chrome/browser/extensions/extension_messages_apitest.cc
+++ b/chrome/browser/extensions/extension_messages_apitest.cc
@@ -21,7 +21,6 @@
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
-#include "chrome/common/extensions/api/runtime.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/notification_service.h"
@@ -29,6 +28,7 @@
#include "extensions/browser/event_router.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_system.h"
+#include "extensions/common/api/runtime.h"
#include "extensions/common/extension_builder.h"
#include "extensions/common/value_builder.h"
#include "net/cert/asn1_util.h"
diff --git a/chrome/browser/extensions/installed_loader.cc b/chrome/browser/extensions/installed_loader.cc
index 5470083..2406160 100644
--- a/chrome/browser/extensions/installed_loader.cc
+++ b/chrome/browser/extensions/installed_loader.cc
@@ -11,7 +11,6 @@
#include "base/threading/thread_restrictions.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
-#include "chrome/browser/extensions/api/runtime/runtime_api.h"
#include "chrome/browser/extensions/extension_action_manager.h"
#include "chrome/browser/extensions/extension_error_reporter.h"
#include "chrome/browser/extensions/extension_service.h"
@@ -22,6 +21,7 @@
#include "chrome/common/pref_names.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/user_metrics.h"
+#include "extensions/browser/api/runtime/runtime_api.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
diff --git a/chrome/chrome_browser_extensions.gypi b/chrome/chrome_browser_extensions.gypi
index 44ee3f8..fa3bb94 100644
--- a/chrome/chrome_browser_extensions.gypi
+++ b/chrome/chrome_browser_extensions.gypi
@@ -473,8 +473,6 @@
'browser/extensions/api/push_messaging/push_messaging_invalidation_mapper.h',
'browser/extensions/api/reading_list_private/reading_list_private_api.cc',
'browser/extensions/api/reading_list_private/reading_list_private_api.h',
- 'browser/extensions/api/runtime/runtime_api.cc',
- 'browser/extensions/api/runtime/runtime_api.h',
'browser/extensions/api/serial/serial_api.cc',
'browser/extensions/api/serial/serial_api.h',
'browser/extensions/api/serial/serial_connection.cc',
@@ -650,6 +648,8 @@
'browser/extensions/chrome_extensions_browser_client.h',
'browser/extensions/chrome_notification_observer.cc',
'browser/extensions/chrome_notification_observer.h',
+ 'browser/extensions/api/runtime/chrome_runtime_api_delegate.cc',
+ 'browser/extensions/api/runtime/chrome_runtime_api_delegate.h',
'browser/extensions/component_loader.cc',
'browser/extensions/component_loader.h',
'browser/extensions/context_menu_matcher.cc',
@@ -1010,7 +1010,7 @@
['include', '^browser/extensions/api/preference/preference_api.cc'],
['include', '^browser/extensions/api/proxy/proxy_api.cc'],
['include', '^browser/extensions/api/proxy/proxy_api_constants.cc'],
- ['include', '^browser/extensions/api/runtime/runtime_api.cc'],
+ ['include', '^browser/extensions/api/runtime/chrome_runtime_api_delegate.cc'],
['include', '^browser/extensions/api/tabs/tabs_constants.cc'],
['include', '^browser/extensions/api/web_navigation/frame_navigation_state.cc'],
['include', '^browser/extensions/api/web_navigation/web_navigation_api.cc'],
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index ecd3178..9b94b27 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -829,6 +829,8 @@
'../components/autofill/content/renderer/test_password_autofill_agent.cc',
'../components/autofill/content/renderer/test_password_generation_agent.h',
'../components/autofill/content/renderer/test_password_generation_agent.cc',
+ # TODO(rockot): Remove this once extensions_browsertests exists.
+ '../extensions/browser/api/runtime/runtime_apitest.cc',
'app/chrome_command_ids.h',
'app/chrome_dll.rc',
'app/chrome_dll_resource.h',
@@ -1070,7 +1072,6 @@
'browser/extensions/api/push_messaging/push_messaging_canary_test.cc',
'browser/extensions/api/push_messaging/sync_setup_helper.cc',
'browser/extensions/api/reading_list_private/reading_list_private_apitest.cc',
- 'browser/extensions/api/runtime/runtime_apitest.cc',
'browser/extensions/api/serial/serial_apitest.cc',
'browser/extensions/api/sessions/sessions_apitest.cc',
'browser/extensions/api/settings_overrides/settings_overrides_browsertest.cc',
diff --git a/chrome/common/extensions/api/_api_features.json b/chrome/common/extensions/api/_api_features.json
index f072603..4a2af1a 100644
--- a/chrome/common/extensions/api/_api_features.json
+++ b/chrome/common/extensions/api/_api_features.json
@@ -598,49 +598,6 @@
"dependencies": ["permission:rtcPrivate"],
"contexts": ["blessed_extension"]
},
- "runtime": {
- "channel": "stable",
- "extension_types": ["extension", "legacy_packaged_app", "platform_app"],
- "contexts": ["blessed_extension"]
- },
- "runtime.connect": {
- "contexts": "all",
- "matches": ["<all_urls>"]
- },
- "runtime.getManifest": {
- "contexts": ["blessed_extension", "unblessed_extension", "content_script"]
- },
- "runtime.getURL": {
- "contexts": ["blessed_extension", "unblessed_extension", "content_script"]
- },
- "runtime.id": {
- "contexts": ["blessed_extension", "unblessed_extension", "content_script"]
- },
- "runtime.lastError": {
- "contexts": "all",
- "extension_types": "all",
- "matches": ["<all_urls>"]
- },
- "runtime.onConnect": {
- "contexts": ["blessed_extension", "unblessed_extension", "content_script"]
- },
- "runtime.onMessage": {
- "contexts": ["blessed_extension", "unblessed_extension", "content_script"]
- },
- "runtime.reload": {
- "contexts": ["blessed_extension", "unblessed_extension", "content_script"]
- },
- "runtime.requestUpdateCheck": {
- "contexts": ["blessed_extension", "unblessed_extension", "content_script"]
- },
- "runtime.sendMessage": {
- "contexts": "all",
- "matches": ["<all_urls>"]
- },
- "runtime.setUninstallURL": {
- "channel": "dev",
- "contexts": ["blessed_extension", "unblessed_extension", "content_script"]
- },
"scriptBadge": {
"dependencies": ["manifest:script_badge"],
"contexts": ["blessed_extension"]
@@ -722,16 +679,6 @@
"dependencies": ["permission:ttsEngine"],
"contexts": ["blessed_extension"]
},
- "types": {
- "channel": "stable",
- "extension_types": ["extension", "legacy_packaged_app", "platform_app"],
- "contexts": ["blessed_extension"]
- },
- "types.private": {
- "channel": "dev",
- "extension_types": ["extension"],
- "location": "component"
- },
"virtualKeyboardPrivate": {
"platforms": ["chromeos"],
"dependencies": ["permission:virtualKeyboardPrivate"],
diff --git a/chrome/common/extensions/api/_permission_features.json b/chrome/common/extensions/api/_permission_features.json
index 08396be..8c0e927 100644
--- a/chrome/common/extensions/api/_permission_features.json
+++ b/chrome/common/extensions/api/_permission_features.json
@@ -752,12 +752,6 @@
"312745D9BF916161191143F6490085EEA0434997" // Google Talk debug
]
},
- // Note: runtime is not actually a permission, but some systems check these
- // values to verify restrictions.
- "runtime": {
- "channel": "stable",
- "extension_types": ["extension", "legacy_packaged_app", "platform_app"]
- },
"screenlockPrivate": {
"channel": "stable",
"extension_types": ["platform_app"],
diff --git a/chrome/common/extensions/api/api.gyp b/chrome/common/extensions/api/api.gyp
index f701e84..6911770 100644
--- a/chrome/common/extensions/api/api.gyp
+++ b/chrome/common/extensions/api/api.gyp
@@ -102,7 +102,6 @@
'power.idl',
'push_messaging.idl',
'reading_list_private.json',
- 'runtime.json',
'serial.idl',
'sessions.json',
'signed_in_devices.idl',
@@ -145,7 +144,6 @@
'manifest_types.json',
'omnibox.json',
'permissions.json',
- 'runtime.json',
'sync_file_system.idl',
'tab_capture.idl',
'tabs.json',
diff --git a/chrome/renderer/resources/extensions/last_error.js b/chrome/renderer/resources/extensions/last_error.js
index 1d2b565..6d85b11 100644
--- a/chrome/renderer/resources/extensions/last_error.js
+++ b/chrome/renderer/resources/extensions/last_error.js
@@ -28,7 +28,7 @@ function set(name, message, stack, targetChrome) {
clear(targetChrome); // in case somebody has set a sneaky getter/setter
var errorObject = { message: message };
- if (GetAvailability('extension.lastError').is_available)
+ if (targetChrome && targetChrome.extension)
targetChrome.extension.lastError = errorObject;
assertRuntimeIsAvailable();
@@ -64,8 +64,8 @@ function clear(targetChrome) {
if (!targetChrome)
throw new Error('No target chrome to clear error');
- if (GetAvailability('extension.lastError').is_available)
- delete targetChrome.extension.lastError;
+ if (targetChrome && targetChrome.extension)
+ delete targetChrome.extension.lastError;
assertRuntimeIsAvailable();
delete targetChrome.runtime.lastError;
diff --git a/extensions/DEPS b/extensions/DEPS
index 11611da..9d6a6a0 100644
--- a/extensions/DEPS
+++ b/extensions/DEPS
@@ -26,16 +26,21 @@ specific_include_rules = {
# Temporarily allowed testing includes. See above.
# TODO(jamescook): Remove these. http://crbug.com/162530
+ "+chrome/browser/apps/app_browsertest_util.h",
+ "+chrome/browser/extensions/api/management/management_api.h",
"+chrome/browser/extensions/api/permissions/permissions_api.h",
"+chrome/browser/extensions/extension_api_unittest.h",
"+chrome/browser/extensions/extension_apitest.h",
+ "+chrome/browser/extensions/extension_function_test_utils.h",
"+chrome/browser/extensions/extension_service_unittest.h",
+ "+chrome/browser/extensions/test_extension_dir.h",
"+chrome/browser/extensions/test_extension_system.h",
"+chrome/browser/ui/browser.h",
"+chrome/common/chrome_paths.h",
"+chrome/common/extensions/features/feature_channel.h",
"+chrome/common/extensions/manifest_tests/extension_manifest_test.h",
"+chrome/test/base/testing_profile.h",
+ "+chrome/test/base/ui_test_utils.h",
],
"(simple|complex)_feature_unittest\.cc|base_feature_provider_unittest\.cc": [
"+chrome/common/extensions/features/chrome_channel_feature_filter.h",
diff --git a/extensions/browser/DEPS b/extensions/browser/DEPS
index dfc7fe1..af6e02ab 100644
--- a/extensions/browser/DEPS
+++ b/extensions/browser/DEPS
@@ -7,4 +7,5 @@ include_rules = [
"+sync",
"+third_party/leveldatabase",
"+third_party/skia/include",
+ "+webkit/browser/fileapi",
]
diff --git a/chrome/browser/extensions/api/runtime/runtime_api.cc b/extensions/browser/api/runtime/runtime_api.cc
index fbb35ed..942c3a60d 100644
--- a/chrome/browser/extensions/api/runtime/runtime_api.cc
+++ b/extensions/browser/api/runtime/runtime_api.cc
@@ -1,8 +1,8 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 2014 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/extensions/api/runtime/runtime_api.h"
+#include "extensions/browser/api/runtime/runtime_api.h"
#include <utility>
@@ -11,48 +11,34 @@
#include "base/memory/scoped_ptr.h"
#include "base/metrics/histogram.h"
#include "base/values.h"
-#include "chrome/browser/browser_process.h"
+#include "base/version.h"
#include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/extensions/extension_warning_service.h"
-#include "chrome/browser/extensions/updater/extension_updater.h"
-#include "chrome/browser/omaha_query_params/omaha_query_params.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/browser/ui/browser_finder.h"
-#include "chrome/browser/ui/browser_navigator.h"
-#include "chrome/browser/ui/browser_window.h"
-#include "chrome/common/extensions/api/runtime.h"
+#include "content/public/browser/browser_context.h"
#include "content/public/browser/child_process_security_policy.h"
#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_api_delegate.h"
#include "extensions/browser/event_router.h"
#include "extensions/browser/extension_host.h"
+#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/extensions_browser_client.h"
#include "extensions/browser/lazy_background_task_queue.h"
#include "extensions/browser/process_manager.h"
+#include "extensions/common/api/runtime.h"
#include "extensions/common/error_utils.h"
#include "extensions/common/extension.h"
#include "extensions/common/manifest_handlers/background_info.h"
#include "url/gurl.h"
#include "webkit/browser/fileapi/isolated_context.h"
-#if defined(OS_CHROMEOS)
-#include "chrome/browser/chromeos/login/user_manager.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/dbus/power_manager_client.h"
-#endif
-
using content::BrowserContext;
-namespace GetPlatformInfo = extensions::api::runtime::GetPlatformInfo;
-
namespace extensions {
-namespace runtime = api::runtime;
+namespace runtime = core_api::runtime;
namespace {
@@ -64,10 +50,9 @@ const char kInstallReasonUpdate[] = "update";
const char kInstallReasonInstall[] = "install";
const char kInstallPreviousVersion[] = "previousVersion";
const char kInvalidUrlError[] = "Invalid URL.";
+const char kPlatformInfoUnavailable[] = "Platform information unavailable.";
+
const char kUpdatesDisabledError[] = "Autoupdate is not enabled.";
-const char kUpdateFound[] = "update_available";
-const char kUpdateNotFound[] = "no_update";
-const char kUpdateThrottled[] = "throttled";
// A preference key storing the url loaded when an extension is uninstalled.
const char kUninstallUrl[] = "uninstall_url";
@@ -77,14 +62,6 @@ const char kUninstallUrl[] = "uninstall_url";
// with the equivalent Pepper API.
const char kPackageDirectoryPath[] = "crxfs";
-// If an extension reloads itself within this many miliseconds of reloading
-// itself, the reload is considered suspiciously fast.
-const int kFastReloadTime = 10000;
-
-// After this many suspiciously fast consecutive reloads, an extension will get
-// disabled.
-const int kFastReloadCount = 5;
-
void DispatchOnStartupEventImpl(BrowserContext* browser_context,
const std::string& extension_id,
bool first_call,
@@ -113,27 +90,27 @@ void DispatchOnStartupEventImpl(BrowserContext* browser_context,
extension_id);
if (extension && BackgroundInfo::HasPersistentBackgroundPage(extension) &&
first_call &&
- system->lazy_background_task_queue()->
- ShouldEnqueueTask(browser_context, extension)) {
+ 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));
+ 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()));
+ 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,
const std::string& url_string) {
- prefs->UpdateExtensionPref(extension_id,
- kUninstallUrl,
- new base::StringValue(url_string));
+ prefs->UpdateExtensionPref(
+ extension_id, kUninstallUrl, new base::StringValue(url_string));
}
#if defined(ENABLE_EXTENSIONS)
@@ -158,19 +135,23 @@ BrowserContextKeyedAPIFactory<RuntimeAPI>* RuntimeAPI::GetFactoryInstance() {
}
RuntimeAPI::RuntimeAPI(content::BrowserContext* context)
- : browser_context_(context),
- dispatch_chrome_updated_event_(false),
- registered_for_updates_(false) {
- registrar_.Add(this, chrome::NOTIFICATION_EXTENSIONS_READY,
+ : browser_context_(context), dispatch_chrome_updated_event_(false) {
+ registrar_.Add(this,
+ chrome::NOTIFICATION_EXTENSIONS_READY,
content::Source<BrowserContext>(context));
registrar_.Add(this,
chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED,
content::Source<BrowserContext>(context));
- registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED,
+ registrar_.Add(this,
+ chrome::NOTIFICATION_EXTENSION_INSTALLED,
content::Source<BrowserContext>(context));
- registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
+ registrar_.Add(this,
+ chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
content::Source<BrowserContext>(context));
+ delegate_ = ExtensionsBrowserClient::Get()->CreateRuntimeAPIDelegate(
+ browser_context_);
+
// Check if registered events are up-to-date. We can only do this once
// per browser context, since it updates internal state when called.
dispatch_chrome_updated_event_ =
@@ -178,10 +159,7 @@ RuntimeAPI::RuntimeAPI(content::BrowserContext* context)
}
RuntimeAPI::~RuntimeAPI() {
- if (registered_for_updates_) {
- ExtensionSystem::Get(browser_context_)->
- extension_service()->RemoveUpdateObserver(this);
- }
+ delegate_->RemoveUpdateObserver(this);
}
void RuntimeAPI::Observe(int type,
@@ -220,16 +198,14 @@ void RuntimeAPI::OnExtensionsReady() {
// We're done restarting Chrome after an update.
dispatch_chrome_updated_event_ = false;
- registered_for_updates_ = true;
-
- ExtensionSystem* extension_system = ExtensionSystem::Get(browser_context_);
- extension_system->extension_service()->AddUpdateObserver(this);
+ delegate_->AddUpdateObserver(this);
// RuntimeAPI is redirected in incognito, so |browser_context_| is never
// incognito. We don't observe incognito ProcessManagers but that is OK
// because we don't send onStartup events to incognito browser contexts.
DCHECK(!browser_context_->IsOffTheRecord());
// Some tests use partially constructed Profiles without a process manager.
+ ExtensionSystem* extension_system = ExtensionSystem::Get(browser_context_);
if (extension_system->process_manager())
extension_system->process_manager()->AddObserver(this);
}
@@ -254,13 +230,7 @@ void RuntimeAPI::OnExtensionInstalled(const Extension* extension) {
if (extension->is_ephemeral())
return;
- // Get the previous version to check if this is an upgrade.
- 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();
+ Version old_version = delegate_->GetPreviousExtensionVersion(extension);
// Dispatch the onInstalled event.
base::MessageLoop::current()->PostTask(
@@ -270,7 +240,6 @@ void RuntimeAPI::OnExtensionInstalled(const Extension* extension) {
extension->id(),
old_version,
false));
-
}
void RuntimeAPI::OnExtensionUninstalled(const Extension* extension) {
@@ -279,8 +248,7 @@ void RuntimeAPI::OnExtensionUninstalled(const Extension* extension) {
if (extension->is_ephemeral())
return;
- Profile* profile = Profile::FromBrowserContext(browser_context_);
- RuntimeEventRouter::OnExtensionUninstalled(profile, extension->id());
+ RuntimeEventRouter::OnExtensionUninstalled(browser_context_, extension->id());
}
void RuntimeAPI::Shutdown() {
@@ -294,76 +262,46 @@ void RuntimeAPI::Shutdown() {
}
void RuntimeAPI::OnAppUpdateAvailable(const Extension* extension) {
- Profile* profile = Profile::FromBrowserContext(browser_context_);
RuntimeEventRouter::DispatchOnUpdateAvailableEvent(
- profile, extension->id(), extension->manifest()->value());
+ browser_context_, extension->id(), extension->manifest()->value());
}
void RuntimeAPI::OnChromeUpdateAvailable() {
- Profile* profile = Profile::FromBrowserContext(browser_context_);
- RuntimeEventRouter::DispatchOnBrowserUpdateAvailableEvent(profile);
+ RuntimeEventRouter::DispatchOnBrowserUpdateAvailableEvent(browser_context_);
}
void RuntimeAPI::OnBackgroundHostStartup(const Extension* extension) {
RuntimeEventRouter::DispatchOnStartupEvent(browser_context_, extension->id());
}
-void RuntimeAPI::MaybeReloadExtension(const std::string& extension_id) {
- std::pair<base::TimeTicks, int>& reload_info =
- last_reload_time_[extension_id];
- base::TimeTicks now = base::TimeTicks::Now();
- if (reload_info.first.is_null() ||
- (now - reload_info.first).InMilliseconds() > kFastReloadTime) {
- reload_info.second = 0;
- } else {
- reload_info.second++;
- }
- if (!reload_info.first.is_null()) {
- UMA_HISTOGRAM_LONG_TIMES("Extensions.RuntimeReloadTime",
- now - reload_info.first);
- }
- UMA_HISTOGRAM_COUNTS_100("Extensions.RuntimeReloadFastCount",
- reload_info.second);
- reload_info.first = now;
-
- ExtensionService* service =
- ExtensionSystem::Get(browser_context_)->extension_service();
- if (reload_info.second >= kFastReloadCount) {
- // Unloading an extension clears all warnings, so first terminate the
- // extension, and then add the warning. Since this is called from an
- // extension function unloading the extension has to be done
- // asynchronously. Fortunately PostTask guarentees FIFO order so just
- // post both tasks.
- base::MessageLoop::current()->PostTask(
- FROM_HERE,
- base::Bind(&ExtensionService::TerminateExtension,
- service->AsWeakPtr(),
- extension_id));
- ExtensionWarningSet warnings;
- warnings.insert(
- ExtensionWarning::CreateReloadTooFrequentWarning(extension_id));
- base::MessageLoop::current()->PostTask(
- FROM_HERE,
- base::Bind(&ExtensionWarningService::NotifyWarningsOnUI,
- browser_context_,
- warnings));
- } else {
- // We can't call ReloadExtension directly, since when this method finishes
- // it tries to decrease the reference count for the extension, which fails
- // if the extension has already been reloaded; so instead we post a task.
- base::MessageLoop::current()->PostTask(
- FROM_HERE,
- base::Bind(&ExtensionService::ReloadExtension,
- service->AsWeakPtr(),
- extension_id));
- }
+void RuntimeAPI::ReloadExtension(const std::string& extension_id) {
+ delegate_->ReloadExtension(extension_id);
+}
+
+bool RuntimeAPI::CheckForUpdates(
+ const std::string& extension_id,
+ const RuntimeAPIDelegate::UpdateCheckCallback& callback) {
+ return delegate_->CheckForUpdates(extension_id, callback);
+}
+
+void RuntimeAPI::OpenURL(const GURL& update_url) {
+ delegate_->OpenURL(update_url);
+}
+
+bool RuntimeAPI::GetPlatformInfo(runtime::PlatformInfo* info) {
+ return delegate_->GetPlatformInfo(info);
+}
+
+bool RuntimeAPI::RestartDevice(std::string* error_message) {
+ return delegate_->RestartDevice(error_message);
}
///////////////////////////////////////////////////////////////////////////////
// static
void RuntimeEventRouter::DispatchOnStartupEvent(
- content::BrowserContext* context, const std::string& extension_id) {
+ content::BrowserContext* context,
+ const std::string& extension_id) {
DispatchOnStartupEventImpl(context, extension_id, true, NULL);
}
@@ -391,55 +329,55 @@ void RuntimeEventRouter::DispatchOnInstalledEvent(
info->SetString(kInstallReason, kInstallReasonInstall);
}
DCHECK(system->event_router());
- scoped_ptr<Event> event(new Event(runtime::OnInstalled::kEventName,
- event_args.Pass()));
+ 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,
+ content::BrowserContext* context,
const std::string& extension_id,
const base::DictionaryValue* manifest) {
- ExtensionSystem* system = ExtensionSystem::Get(profile);
+ ExtensionSystem* system = ExtensionSystem::Get(context);
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()));
+ 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);
+ content::BrowserContext* context) {
+ ExtensionSystem* system = ExtensionSystem::Get(context);
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()));
+ scoped_ptr<Event> event(
+ new Event(runtime::OnBrowserUpdateAvailable::kEventName, args.Pass()));
system->event_router()->BroadcastEvent(event.Pass());
}
// static
void RuntimeEventRouter::DispatchOnRestartRequiredEvent(
- Profile* profile,
+ content::BrowserContext* context,
const std::string& app_id,
- api::runtime::OnRestartRequired::Reason reason) {
- ExtensionSystem* system = ExtensionSystem::Get(profile);
+ core_api::runtime::OnRestartRequired::Reason reason) {
+ ExtensionSystem* system = ExtensionSystem::Get(context);
if (!system)
return;
scoped_ptr<Event> event(
new Event(runtime::OnRestartRequired::kEventName,
- api::runtime::OnRestartRequired::Create(reason)));
+ core_api::runtime::OnRestartRequired::Create(reason)));
DCHECK(system->event_router());
system->event_router()->DispatchEventToExtension(app_id, event.Pass());
@@ -447,214 +385,116 @@ void RuntimeEventRouter::DispatchOnRestartRequiredEvent(
// static
void RuntimeEventRouter::OnExtensionUninstalled(
- Profile* profile,
+ content::BrowserContext* context,
const std::string& extension_id) {
#if defined(ENABLE_EXTENSIONS)
- GURL uninstall_url(GetUninstallURL(ExtensionPrefs::Get(profile),
- extension_id));
+ GURL uninstall_url(
+ GetUninstallURL(ExtensionPrefs::Get(context), extension_id));
if (uninstall_url.is_empty())
return;
- Browser* browser = chrome::FindLastActiveWithProfile(profile,
- chrome::GetActiveDesktop());
- if (!browser)
- browser = new Browser(Browser::CreateParams(profile,
- chrome::GetActiveDesktop()));
-
- chrome::NavigateParams params(browser, uninstall_url,
- content::PAGE_TRANSITION_CLIENT_REDIRECT);
- params.disposition = NEW_FOREGROUND_TAB;
- params.user_gesture = false;
- chrome::Navigate(&params);
+ RuntimeAPI::GetFactoryInstance()->Get(context)->OpenURL(uninstall_url);
#endif // defined(ENABLE_EXTENSIONS)
}
-bool RuntimeGetBackgroundPageFunction::RunAsync() {
- ExtensionSystem* system = ExtensionSystem::Get(GetProfile());
- ExtensionHost* host = system->process_manager()->
- GetBackgroundHostForExtension(extension_id());
- if (system->lazy_background_task_queue()->ShouldEnqueueTask(GetProfile(),
+ExtensionFunction::ResponseAction RuntimeGetBackgroundPageFunction::Run() {
+ ExtensionSystem* system = ExtensionSystem::Get(browser_context());
+ ExtensionHost* host =
+ system->process_manager()->GetBackgroundHostForExtension(extension_id());
+ if (system->lazy_background_task_queue()->ShouldEnqueueTask(browser_context(),
GetExtension())) {
system->lazy_background_task_queue()->AddPendingTask(
- GetProfile(),
+ browser_context(),
extension_id(),
base::Bind(&RuntimeGetBackgroundPageFunction::OnPageLoaded, this));
} else if (host) {
OnPageLoaded(host);
} else {
- error_ = kNoBackgroundPageError;
- return false;
+ return RespondNow(Error(kNoBackgroundPageError));
}
- return true;
+ return RespondLater();
}
void RuntimeGetBackgroundPageFunction::OnPageLoaded(ExtensionHost* host) {
if (host) {
- SendResponse(true);
+ Respond(NoArguments());
} else {
- error_ = kPageLoadError;
- SendResponse(false);
+ Respond(Error(kPageLoadError));
}
}
-bool RuntimeSetUninstallURLFunction::RunSync() {
+ExtensionFunction::ResponseAction RuntimeSetUninstallURLFunction::Run() {
std::string url_string;
- EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &url_string));
+ EXTENSION_FUNCTION_VALIDATE_TYPESAFE(args_->GetString(0, &url_string));
GURL url(url_string);
if (!url.is_valid()) {
- error_ = ErrorUtils::FormatErrorMessage(kInvalidUrlError, url_string);
- return false;
+ return RespondNow(
+ Error(ErrorUtils::FormatErrorMessage(kInvalidUrlError, url_string)));
}
-
SetUninstallURL(
- ExtensionPrefs::Get(GetProfile()), extension_id(), url_string);
- return true;
+ ExtensionPrefs::Get(browser_context()), extension_id(), url_string);
+ return RespondNow(NoArguments());
}
-bool RuntimeReloadFunction::RunSync() {
- RuntimeAPI::GetFactoryInstance()->Get(GetProfile())->MaybeReloadExtension(
+ExtensionFunction::ResponseAction RuntimeReloadFunction::Run() {
+ RuntimeAPI::GetFactoryInstance()->Get(browser_context())->ReloadExtension(
extension_id());
- return true;
+ return RespondNow(NoArguments());
}
-RuntimeRequestUpdateCheckFunction::RuntimeRequestUpdateCheckFunction() {
- registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UPDATE_FOUND,
- content::NotificationService::AllSources());
-}
-
-bool RuntimeRequestUpdateCheckFunction::RunAsync() {
- ExtensionSystem* system = ExtensionSystem::Get(GetProfile());
- ExtensionService* service = system->extension_service();
- ExtensionUpdater* updater = service->updater();
- if (!updater) {
- error_ = kUpdatesDisabledError;
- return false;
- }
-
- did_reply_ = false;
- if (!updater->CheckExtensionSoon(extension_id(), base::Bind(
- &RuntimeRequestUpdateCheckFunction::CheckComplete, this))) {
- did_reply_ = true;
- SetResult(new base::StringValue(kUpdateThrottled));
- SendResponse(true);
+ExtensionFunction::ResponseAction RuntimeRequestUpdateCheckFunction::Run() {
+ if (!RuntimeAPI::GetFactoryInstance()
+ ->Get(browser_context())
+ ->CheckForUpdates(
+ extension_id(),
+ base::Bind(&RuntimeRequestUpdateCheckFunction::CheckComplete,
+ this))) {
+ return RespondNow(Error(kUpdatesDisabledError));
}
- return true;
-}
-
-void RuntimeRequestUpdateCheckFunction::CheckComplete() {
- if (did_reply_)
- return;
-
- did_reply_ = true;
-
- // Since no UPDATE_FOUND notification was seen, this generally would mean
- // that no update is found, but a previous update check might have already
- // queued up an update, so check for that here to make sure we return the
- // right value.
- ExtensionSystem* system = ExtensionSystem::Get(GetProfile());
- ExtensionService* service = system->extension_service();
- const Extension* update = service->GetPendingExtensionUpdate(extension_id());
- if (update) {
- ReplyUpdateFound(update->VersionString());
+ return RespondLater();
+}
+
+void RuntimeRequestUpdateCheckFunction::CheckComplete(
+ const RuntimeAPIDelegate::UpdateCheckResult& result) {
+ if (result.success) {
+ base::ListValue* results = new base::ListValue;
+ results->AppendString(result.response);
+ base::DictionaryValue* details = new base::DictionaryValue;
+ results->Append(details);
+ details->SetString("version", result.version);
+ Respond(MultipleArguments(results));
} else {
- SetResult(new base::StringValue(kUpdateNotFound));
+ Respond(SingleArgument(new base::StringValue(result.response)));
}
- SendResponse(true);
}
-void RuntimeRequestUpdateCheckFunction::Observe(
- int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) {
- if (did_reply_)
- return;
-
- DCHECK(type == chrome::NOTIFICATION_EXTENSION_UPDATE_FOUND);
- typedef const std::pair<std::string, Version> UpdateDetails;
- const std::string& id = content::Details<UpdateDetails>(details)->first;
- const Version& version = content::Details<UpdateDetails>(details)->second;
- if (id == extension_id()) {
- ReplyUpdateFound(version.GetString());
+ExtensionFunction::ResponseAction RuntimeRestartFunction::Run() {
+ std::string message;
+ bool result =
+ RuntimeAPI::GetFactoryInstance()->Get(browser_context())->RestartDevice(
+ &message);
+ if (!result) {
+ return RespondNow(Error(message));
}
+ return RespondNow(NoArguments());
}
-void RuntimeRequestUpdateCheckFunction::ReplyUpdateFound(
- const std::string& version) {
- did_reply_ = true;
- results_.reset(new base::ListValue);
- results_->AppendString(kUpdateFound);
- base::DictionaryValue* details = new base::DictionaryValue;
- results_->Append(details);
- details->SetString("version", version);
- SendResponse(true);
-}
-
-bool RuntimeRestartFunction::RunSync() {
-#if defined(OS_CHROMEOS)
- if (chromeos::UserManager::Get()->IsLoggedInAsKioskApp()) {
- chromeos::DBusThreadManager::Get()
- ->GetPowerManagerClient()
- ->RequestRestart();
- return true;
- }
-#endif
- SetError("Function available only for ChromeOS kiosk mode.");
- return false;
-}
-
-bool RuntimeGetPlatformInfoFunction::RunSync() {
- GetPlatformInfo::Results::PlatformInfo info;
-
- const char* os = chrome::OmahaQueryParams::GetOS();
- if (strcmp(os, "mac") == 0) {
- info.os = GetPlatformInfo::Results::PlatformInfo::OS_MAC_;
- } else if (strcmp(os, "win") == 0) {
- info.os = GetPlatformInfo::Results::PlatformInfo::OS_WIN_;
- } else if (strcmp(os, "android") == 0) {
- info.os = GetPlatformInfo::Results::PlatformInfo::OS_ANDROID_;
- } else if (strcmp(os, "cros") == 0) {
- info.os = GetPlatformInfo::Results::PlatformInfo::OS_CROS_;
- } else if (strcmp(os, "linux") == 0) {
- info.os = GetPlatformInfo::Results::PlatformInfo::OS_LINUX_;
- } else if (strcmp(os, "openbsd") == 0) {
- info.os = GetPlatformInfo::Results::PlatformInfo::OS_OPENBSD_;
- } else {
- NOTREACHED();
- return false;
+ExtensionFunction::ResponseAction RuntimeGetPlatformInfoFunction::Run() {
+ runtime::PlatformInfo info;
+ if (!RuntimeAPI::GetFactoryInstance()
+ ->Get(browser_context())
+ ->GetPlatformInfo(&info)) {
+ return RespondNow(Error(kPlatformInfoUnavailable));
}
-
- const char* arch = chrome::OmahaQueryParams::GetArch();
- if (strcmp(arch, "arm") == 0) {
- info.arch = GetPlatformInfo::Results::PlatformInfo::ARCH_ARM;
- } else if (strcmp(arch, "x86") == 0) {
- info.arch = GetPlatformInfo::Results::PlatformInfo::ARCH_X86_32;
- } else if (strcmp(arch, "x64") == 0) {
- info.arch = GetPlatformInfo::Results::PlatformInfo::ARCH_X86_64;
- } else {
- NOTREACHED();
- return false;
- }
-
- const char* nacl_arch = chrome::OmahaQueryParams::GetNaclArch();
- if (strcmp(nacl_arch, "arm") == 0) {
- info.nacl_arch = GetPlatformInfo::Results::PlatformInfo::NACL_ARCH_ARM;
- } else if (strcmp(nacl_arch, "x86-32") == 0) {
- info.nacl_arch = GetPlatformInfo::Results::PlatformInfo::NACL_ARCH_X86_32;
- } else if (strcmp(nacl_arch, "x86-64") == 0) {
- info.nacl_arch = GetPlatformInfo::Results::PlatformInfo::NACL_ARCH_X86_64;
- } else {
- NOTREACHED();
- return false;
- }
-
- results_ = GetPlatformInfo::Results::Create(info);
- return true;
+ return RespondNow(MultipleArguments(
+ runtime::GetPlatformInfo::Results::Create(info).release()));
}
-bool RuntimeGetPackageDirectoryEntryFunction::RunSync() {
+ExtensionFunction::ResponseAction
+RuntimeGetPackageDirectoryEntryFunction::Run() {
fileapi::IsolatedContext* isolated_context =
fileapi::IsolatedContext::GetInstance();
DCHECK(isolated_context);
@@ -669,10 +509,9 @@ bool RuntimeGetPackageDirectoryEntryFunction::RunSync() {
content::ChildProcessSecurityPolicy::GetInstance();
policy->GrantReadFileSystem(renderer_id, filesystem_id);
base::DictionaryValue* dict = new base::DictionaryValue();
- SetResult(dict);
dict->SetString("fileSystemId", filesystem_id);
dict->SetString("baseName", relative_path);
- return true;
+ return RespondNow(SingleArgument(dict));
}
-} // namespace extensions
+} // namespace extensions
diff --git a/chrome/browser/extensions/api/runtime/runtime_api.h b/extensions/browser/api/runtime/runtime_api.h
index f648be1..e341398 100644
--- a/chrome/browser/extensions/api/runtime/runtime_api.h
+++ b/extensions/browser/api/runtime/runtime_api.h
@@ -1,21 +1,20 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 2014 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.
-#ifndef CHROME_BROWSER_EXTENSIONS_API_RUNTIME_RUNTIME_API_H_
-#define CHROME_BROWSER_EXTENSIONS_API_RUNTIME_RUNTIME_API_H_
+#ifndef EXTENSIONS_BROWSER_API_RUNTIME_RUNTIME_API_H_
+#define EXTENSIONS_BROWSER_API_RUNTIME_RUNTIME_API_H_
#include <string>
-#include "chrome/browser/extensions/chrome_extension_function.h"
-#include "chrome/common/extensions/api/runtime.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
+#include "extensions/browser/api/runtime/runtime_api_delegate.h"
#include "extensions/browser/browser_context_keyed_api_factory.h"
+#include "extensions/browser/extension_function.h"
#include "extensions/browser/process_manager_observer.h"
#include "extensions/browser/update_observer.h"
-
-class Profile;
+#include "extensions/common/api/runtime.h"
namespace base {
class Version;
@@ -26,6 +25,13 @@ class BrowserContext;
}
namespace extensions {
+
+namespace core_api {
+namespace runtime {
+struct PlatformInfo;
+}
+}
+
class Extension;
class ExtensionHost;
@@ -47,7 +53,12 @@ class RuntimeAPI : public BrowserContextKeyedAPI,
const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE;
- void MaybeReloadExtension(const std::string& extension_id);
+ void ReloadExtension(const std::string& extension_id);
+ bool CheckForUpdates(const std::string& extension_id,
+ const RuntimeAPIDelegate::UpdateCheckCallback& callback);
+ void OpenURL(const GURL& uninstall_url);
+ bool GetPlatformInfo(core_api::runtime::PlatformInfo* info);
+ bool RestartDevice(std::string* error_message);
private:
friend class BrowserContextKeyedAPIFactory<RuntimeAPI>;
@@ -70,23 +81,16 @@ class RuntimeAPI : public BrowserContextKeyedAPI,
// ProcessManagerObserver implementation:
virtual void OnBackgroundHostStartup(const Extension* extension) OVERRIDE;
+ scoped_ptr<RuntimeAPIDelegate> delegate_;
+
content::BrowserContext* browser_context_;
// True if we should dispatch the chrome.runtime.onInstalled event with
// reason "chrome_update" upon loading each extension.
bool dispatch_chrome_updated_event_;
- // Whether the API registered with the ExtensionService to receive
- // update notifications.
- bool registered_for_updates_;
-
content::NotificationRegistrar registrar_;
- // Map to prevent extensions from getting stuck in reload loops. Maps
- // extension id to the last time it was reloaded and the number of times
- // it was reloaded with not enough time in between reloads.
- std::map<std::string, std::pair<base::TimeTicks, int> > last_reload_time_;
-
DISALLOW_COPY_AND_ASSIGN(RuntimeAPI);
};
@@ -104,108 +108,99 @@ class RuntimeEventRouter {
// Dispatches the onUpdateAvailable event to the given extension.
static void DispatchOnUpdateAvailableEvent(
- Profile* profile,
+ content::BrowserContext* context,
const std::string& extension_id,
const base::DictionaryValue* manifest);
// Dispatches the onBrowserUpdateAvailable event to all extensions.
- static void DispatchOnBrowserUpdateAvailableEvent(Profile* profile);
+ static void DispatchOnBrowserUpdateAvailableEvent(
+ content::BrowserContext* context);
// Dispatches the onRestartRequired event to the given app.
static void DispatchOnRestartRequiredEvent(
- Profile* profile,
+ content::BrowserContext* context,
const std::string& app_id,
- api::runtime::OnRestartRequired::Reason reason);
+ core_api::runtime::OnRestartRequired::Reason reason);
// Does any work needed at extension uninstall (e.g. load uninstall url).
- static void OnExtensionUninstalled(Profile* profile,
+ static void OnExtensionUninstalled(content::BrowserContext* context,
const std::string& extension_id);
};
-class RuntimeGetBackgroundPageFunction : public ChromeAsyncExtensionFunction {
+class RuntimeGetBackgroundPageFunction : public UIThreadExtensionFunction {
public:
DECLARE_EXTENSION_FUNCTION("runtime.getBackgroundPage",
RUNTIME_GETBACKGROUNDPAGE)
protected:
virtual ~RuntimeGetBackgroundPageFunction() {}
- virtual bool RunAsync() OVERRIDE;
+ virtual ResponseAction Run() OVERRIDE;
private:
void OnPageLoaded(ExtensionHost*);
};
-class RuntimeSetUninstallURLFunction : public ChromeSyncExtensionFunction {
+class RuntimeSetUninstallURLFunction : public UIThreadExtensionFunction {
public:
- DECLARE_EXTENSION_FUNCTION("runtime.setUninstallURL",
- RUNTIME_SETUNINSTALLURL)
+ DECLARE_EXTENSION_FUNCTION("runtime.setUninstallURL", RUNTIME_SETUNINSTALLURL)
protected:
virtual ~RuntimeSetUninstallURLFunction() {}
- virtual bool RunSync() OVERRIDE;
+ virtual ResponseAction Run() OVERRIDE;
};
-class RuntimeReloadFunction : public ChromeSyncExtensionFunction {
+class RuntimeReloadFunction : public UIThreadExtensionFunction {
public:
DECLARE_EXTENSION_FUNCTION("runtime.reload", RUNTIME_RELOAD)
protected:
virtual ~RuntimeReloadFunction() {}
- virtual bool RunSync() OVERRIDE;
+ virtual ResponseAction Run() OVERRIDE;
};
-class RuntimeRequestUpdateCheckFunction : public ChromeAsyncExtensionFunction,
- public content::NotificationObserver {
+class RuntimeRequestUpdateCheckFunction : public UIThreadExtensionFunction {
public:
DECLARE_EXTENSION_FUNCTION("runtime.requestUpdateCheck",
RUNTIME_REQUESTUPDATECHECK)
- RuntimeRequestUpdateCheckFunction();
protected:
virtual ~RuntimeRequestUpdateCheckFunction() {}
- virtual bool RunAsync() OVERRIDE;
+ virtual ResponseAction Run() OVERRIDE;
- // Implements content::NotificationObserver interface.
- virtual void Observe(int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) OVERRIDE;
private:
- void CheckComplete();
- void ReplyUpdateFound(const std::string& version);
-
- content::NotificationRegistrar registrar_;
- bool did_reply_;
+ void CheckComplete(const RuntimeAPIDelegate::UpdateCheckResult& result);
};
-class RuntimeRestartFunction : public ChromeSyncExtensionFunction {
+class RuntimeRestartFunction : public UIThreadExtensionFunction {
public:
DECLARE_EXTENSION_FUNCTION("runtime.restart", RUNTIME_RESTART)
protected:
virtual ~RuntimeRestartFunction() {}
- virtual bool RunSync() OVERRIDE;
+ virtual ResponseAction Run() OVERRIDE;
};
-class RuntimeGetPlatformInfoFunction : public ChromeSyncExtensionFunction {
+class RuntimeGetPlatformInfoFunction : public UIThreadExtensionFunction {
public:
DECLARE_EXTENSION_FUNCTION("runtime.getPlatformInfo",
RUNTIME_GETPLATFORMINFO);
+
protected:
virtual ~RuntimeGetPlatformInfoFunction() {}
- virtual bool RunSync() OVERRIDE;
+ virtual ResponseAction Run() OVERRIDE;
};
class RuntimeGetPackageDirectoryEntryFunction
- : public ChromeSyncExtensionFunction {
+ : public UIThreadExtensionFunction {
public:
DECLARE_EXTENSION_FUNCTION("runtime.getPackageDirectoryEntry",
RUNTIME_GETPACKAGEDIRECTORYENTRY)
protected:
virtual ~RuntimeGetPackageDirectoryEntryFunction() {}
- virtual bool RunSync() OVERRIDE;
+ virtual ResponseAction Run() OVERRIDE;
};
} // namespace extensions
-#endif // CHROME_BROWSER_EXTENSIONS_API_RUNTIME_RUNTIME_API_H_
+#endif // EXTENSIONS_BROWSER_API_RUNTIME_RUNTIME_API_H_
diff --git a/extensions/browser/api/runtime/runtime_api_delegate.cc b/extensions/browser/api/runtime/runtime_api_delegate.cc
new file mode 100644
index 0000000..3ead8b6
--- /dev/null
+++ b/extensions/browser/api/runtime/runtime_api_delegate.cc
@@ -0,0 +1,16 @@
+// Copyright 2014 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 "extensions/browser/api/runtime/runtime_api_delegate.h"
+
+namespace extensions {
+
+RuntimeAPIDelegate::UpdateCheckResult::UpdateCheckResult(
+ bool success,
+ const std::string& response,
+ const std::string& version)
+ : success(success), response(response), version(version) {
+}
+
+} // namespace extensions
diff --git a/extensions/browser/api/runtime/runtime_api_delegate.h b/extensions/browser/api/runtime/runtime_api_delegate.h
new file mode 100644
index 0000000..98b4963
--- /dev/null
+++ b/extensions/browser/api/runtime/runtime_api_delegate.h
@@ -0,0 +1,77 @@
+// Copyright 2014 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.
+
+#ifndef EXTENSIONS_BROWSER_API_RUNTIME_RUNTIME_API_DELEGATE_H
+#define EXTENSIONS_BROWSER_API_RUNTIME_RUNTIME_API_DELEGATE_H
+
+#include "base/callback.h"
+#include "base/version.h"
+
+class GURL;
+
+namespace extensions {
+
+namespace core_api {
+namespace runtime {
+struct PlatformInfo;
+}
+}
+
+class Extension;
+class UpdateObserver;
+
+// This is a delegate interface for chrome.runtime API behavior. Clients must
+// vend some implementation of this interface through
+// ExtensionsBrowserClient::CreateRuntimeAPIDelegate.
+class RuntimeAPIDelegate {
+ public:
+ struct UpdateCheckResult {
+ bool success;
+ std::string response;
+ std::string version;
+
+ UpdateCheckResult(bool success,
+ const std::string& response,
+ const std::string& version);
+ };
+
+ virtual ~RuntimeAPIDelegate() {}
+
+ // The callback given to RequestUpdateCheck.
+ typedef base::Callback<void(const UpdateCheckResult&)> UpdateCheckCallback;
+
+ // Registers an UpdateObserver on behalf of the runtime API.
+ virtual void AddUpdateObserver(UpdateObserver* observer) = 0;
+
+ // Unregisters an UpdateObserver on behalf of the runtime API.
+ virtual void RemoveUpdateObserver(UpdateObserver* observer) = 0;
+
+ // Determines an extension's previously installed version if applicable.
+ virtual base::Version GetPreviousExtensionVersion(
+ const Extension* extension) = 0;
+
+ // Reloads an extension.
+ virtual void ReloadExtension(const std::string& extension_id) = 0;
+
+ // Requests an extensions update update check. Returns |false| if updates
+ // are disabled. Otherwise |callback| is called with the result of the
+ // update check.
+ virtual bool CheckForUpdates(const std::string& extension_id,
+ const UpdateCheckCallback& callback) = 0;
+
+ // Navigates the browser to a URL on behalf of the runtime API.
+ virtual void OpenURL(const GURL& uninstall_url) = 0;
+
+ // Populates platform info to be provided by the getPlatformInfo function.
+ // Returns false iff no info is provided.
+ virtual bool GetPlatformInfo(core_api::runtime::PlatformInfo* info) = 0;
+
+ // Request a restart of the host device. Returns false iff the device
+ // will not be restarted.
+ virtual bool RestartDevice(std::string* error_message) = 0;
+};
+
+} // namespace extensions
+
+#endif // EXTENSIONS_BROWSER_API_RUNTIME_RUNTIME_API_DELEGATE_H
diff --git a/chrome/browser/extensions/api/runtime/runtime_apitest.cc b/extensions/browser/api/runtime/runtime_apitest.cc
index ccb45ce..6fd81f1 100644
--- a/chrome/browser/extensions/api/runtime/runtime_apitest.cc
+++ b/extensions/browser/api/runtime/runtime_apitest.cc
@@ -1,15 +1,15 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 2014 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_browsertest_util.h"
#include "chrome/browser/extensions/api/management/management_api.h"
-#include "chrome/browser/extensions/api/runtime/runtime_api.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_function_test_utils.h"
#include "chrome/browser/extensions/test_extension_dir.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/notification_service.h"
+#include "extensions/browser/api/runtime/runtime_api.h"
#include "extensions/browser/extension_registry.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
@@ -34,9 +34,9 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ChromeRuntimeUnprivileged) {
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ChromeRuntimeUninstallURL) {
// Auto-confirm the uninstall dialog.
extensions::ManagementUninstallFunction::SetAutoConfirmForTest(true);
- ASSERT_TRUE(LoadExtension(
- test_data_dir_.AppendASCII("runtime").AppendASCII("uninstall_url").
- AppendASCII("sets_uninstall_url")));
+ ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("runtime")
+ .AppendASCII("uninstall_url")
+ .AppendASCII("sets_uninstall_url")));
ASSERT_TRUE(RunExtensionTest("runtime/uninstall_url")) << message_;
}
@@ -45,9 +45,7 @@ namespace extensions {
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ChromeRuntimeGetPlatformInfo) {
scoped_ptr<base::Value> result(
extension_function_test_utils::RunFunctionAndReturnSingleResult(
- new RuntimeGetPlatformInfoFunction(),
- "[]",
- browser()));
+ new RuntimeGetPlatformInfoFunction(), "[]", browser()));
ASSERT_TRUE(result.get() != NULL);
base::DictionaryValue* dict =
extension_function_test_utils::ToDictionary(result.get());
diff --git a/extensions/browser/browser_context_keyed_service_factories.cc b/extensions/browser/browser_context_keyed_service_factories.cc
index 38ee253..6091a0f 100644
--- a/extensions/browser/browser_context_keyed_service_factories.cc
+++ b/extensions/browser/browser_context_keyed_service_factories.cc
@@ -5,6 +5,7 @@
#include "extensions/browser/browser_context_keyed_service_factories.h"
#include "extensions/browser/api/api_resource_manager.h"
+#include "extensions/browser/api/runtime/runtime_api.h"
#include "extensions/browser/api/socket/socket.h"
#include "extensions/browser/api/socket/tcp_socket.h"
#include "extensions/browser/api/socket/udp_socket.h"
@@ -26,9 +27,10 @@ void EnsureBrowserContextKeyedServiceFactoriesBuilt() {
core_api::TCPServerSocketEventDispatcher::GetFactoryInstance();
core_api::TCPSocketEventDispatcher::GetFactoryInstance();
core_api::UDPSocketEventDispatcher::GetFactoryInstance();
- extensions::ExtensionPrefsFactory::GetInstance();
- extensions::RendererStartupHelperFactory::GetInstance();
- extensions::StorageFrontend::GetFactoryInstance();
+ ExtensionPrefsFactory::GetInstance();
+ RendererStartupHelperFactory::GetInstance();
+ RuntimeAPI::GetFactoryInstance();
+ StorageFrontend::GetFactoryInstance();
}
} // namespace extensions
diff --git a/extensions/browser/extensions_browser_client.h b/extensions/browser/extensions_browser_client.h
index e3b91b2..9356aa6 100644
--- a/extensions/browser/extensions_browser_client.h
+++ b/extensions/browser/extensions_browser_client.h
@@ -40,6 +40,7 @@ class ExtensionPrefsObserver;
class ExtensionSystem;
class ExtensionSystemProvider;
class InfoMap;
+class RuntimeAPIDelegate;
// Interface to allow the extensions module to make browser-process-specific
// queries of the embedder. Should be Set() once in the browser process.
@@ -166,6 +167,12 @@ class ExtensionsBrowserClient {
virtual void RegisterExtensionFunctions(
ExtensionFunctionRegistry* registry) const = 0;
+ // Creates a RuntimeAPIDelegate responsible for handling extensions
+ // management-related events such as update and installation on behalf of the
+ // core runtime API implementation.
+ virtual scoped_ptr<RuntimeAPIDelegate> CreateRuntimeAPIDelegate(
+ content::BrowserContext* context) const = 0;
+
// Returns the single instance of |this|.
static ExtensionsBrowserClient* Get();
diff --git a/extensions/browser/test_extensions_browser_client.cc b/extensions/browser/test_extensions_browser_client.cc
index 6e919ea..7708ca7 100644
--- a/extensions/browser/test_extensions_browser_client.cc
+++ b/extensions/browser/test_extensions_browser_client.cc
@@ -7,6 +7,7 @@
#include "content/public/browser/browser_context.h"
#include "extensions/browser/app_sorting.h"
#include "extensions/browser/extension_host_delegate.h"
+#include "extensions/browser/test_runtime_api_delegate.h"
using content::BrowserContext;
@@ -155,4 +156,10 @@ TestExtensionsBrowserClient::GetExtensionSystemFactory() {
void TestExtensionsBrowserClient::RegisterExtensionFunctions(
ExtensionFunctionRegistry* registry) const {}
+scoped_ptr<RuntimeAPIDelegate>
+TestExtensionsBrowserClient::CreateRuntimeAPIDelegate(
+ content::BrowserContext* context) const {
+ return scoped_ptr<RuntimeAPIDelegate>(new TestRuntimeAPIDelegate());
+}
+
} // namespace extensions
diff --git a/extensions/browser/test_extensions_browser_client.h b/extensions/browser/test_extensions_browser_client.h
index f7401fe..ff09ae3 100644
--- a/extensions/browser/test_extensions_browser_client.h
+++ b/extensions/browser/test_extensions_browser_client.h
@@ -73,6 +73,8 @@ class TestExtensionsBrowserClient : public ExtensionsBrowserClient {
virtual ExtensionSystemProvider* GetExtensionSystemFactory() OVERRIDE;
virtual void RegisterExtensionFunctions(
ExtensionFunctionRegistry* registry) const OVERRIDE;
+ virtual scoped_ptr<RuntimeAPIDelegate> CreateRuntimeAPIDelegate(
+ content::BrowserContext* context) const OVERRIDE;
private:
content::BrowserContext* main_context_; // Not owned.
diff --git a/extensions/browser/test_runtime_api_delegate.cc b/extensions/browser/test_runtime_api_delegate.cc
new file mode 100644
index 0000000..9394050
--- /dev/null
+++ b/extensions/browser/test_runtime_api_delegate.cc
@@ -0,0 +1,53 @@
+// Copyright 2014 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 "extensions/browser/test_runtime_api_delegate.h"
+
+#include "extensions/common/api/runtime.h"
+
+namespace extensions {
+
+using core_api::runtime::PlatformInfo;
+
+TestRuntimeAPIDelegate::TestRuntimeAPIDelegate() {
+}
+
+TestRuntimeAPIDelegate::~TestRuntimeAPIDelegate() {
+}
+
+void TestRuntimeAPIDelegate::AddUpdateObserver(UpdateObserver* observer) {
+}
+
+void TestRuntimeAPIDelegate::RemoveUpdateObserver(UpdateObserver* observer) {
+}
+
+base::Version TestRuntimeAPIDelegate::GetPreviousExtensionVersion(
+ const Extension* extension) {
+ return base::Version();
+}
+
+void TestRuntimeAPIDelegate::ReloadExtension(const std::string& extension_id) {
+}
+
+bool TestRuntimeAPIDelegate::CheckForUpdates(
+ const std::string& extension_id,
+ const UpdateCheckCallback& callback) {
+ return false;
+}
+
+void TestRuntimeAPIDelegate::OpenURL(const GURL& uninstall_url) {
+}
+
+bool TestRuntimeAPIDelegate::GetPlatformInfo(PlatformInfo* info) {
+ // TODO(rockot): This probably isn't right. Maybe this delegate should just
+ // support manual PlatformInfo override for tests if necessary.
+ info->os = PlatformInfo::OS_CROS_;
+ return true;
+}
+
+bool TestRuntimeAPIDelegate::RestartDevice(std::string* error_message) {
+ return false;
+}
+
+} // namespace extensions
diff --git a/extensions/browser/test_runtime_api_delegate.h b/extensions/browser/test_runtime_api_delegate.h
new file mode 100644
index 0000000..8922bd5
--- /dev/null
+++ b/extensions/browser/test_runtime_api_delegate.h
@@ -0,0 +1,36 @@
+// Copyright 2014 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.
+
+#ifndef EXENSIONS_BROWSER_TEST_RUNTIME_API_DELEGATE_H_
+#define EXENSIONS_BROWSER_TEST_RUNTIME_API_DELEGATE_H_
+
+#include "base/macros.h"
+#include "extensions/browser/api/runtime/runtime_api_delegate.h"
+
+namespace extensions {
+
+class TestRuntimeAPIDelegate : public RuntimeAPIDelegate {
+ public:
+ TestRuntimeAPIDelegate();
+ virtual ~TestRuntimeAPIDelegate();
+
+ // RuntimeAPIDelegate implementation.
+ virtual void AddUpdateObserver(UpdateObserver* observer) OVERRIDE;
+ virtual void RemoveUpdateObserver(UpdateObserver* observer) OVERRIDE;
+ virtual base::Version GetPreviousExtensionVersion(
+ const Extension* extension) OVERRIDE;
+ virtual void ReloadExtension(const std::string& extension_id) OVERRIDE;
+ virtual bool CheckForUpdates(const std::string& extension_id,
+ const UpdateCheckCallback& callback) OVERRIDE;
+ virtual void OpenURL(const GURL& uninstall_url) OVERRIDE;
+ virtual bool GetPlatformInfo(core_api::runtime::PlatformInfo* info) OVERRIDE;
+ virtual bool RestartDevice(std::string* error_message) OVERRIDE;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TestRuntimeAPIDelegate);
+};
+
+} // namespace extensions
+
+#endif // EXENSIONS_BROWSER_TEST_RUNTIME_API_DELEGATE_H_
diff --git a/extensions/common/api/_api_features.json b/extensions/common/api/_api_features.json
index 4ea9b9e..6fa7d8b 100644
--- a/extensions/common/api/_api_features.json
+++ b/extensions/common/api/_api_features.json
@@ -14,6 +14,49 @@
"dependencies": ["permission:dns"],
"contexts": ["blessed_extension"]
},
+ "runtime": {
+ "channel": "stable",
+ "extension_types": ["extension", "legacy_packaged_app", "platform_app"],
+ "contexts": ["blessed_extension"]
+ },
+ "runtime.getManifest": {
+ "contexts": ["blessed_extension", "unblessed_extension", "content_script"]
+ },
+ "runtime.connect": {
+ "contexts": "all",
+ "matches": ["<all_urls>"]
+ },
+ "runtime.getURL": {
+ "contexts": ["blessed_extension", "unblessed_extension", "content_script"]
+ },
+ "runtime.id": {
+ "contexts": ["blessed_extension", "unblessed_extension", "content_script"]
+ },
+ "runtime.lastError": {
+ "contexts": "all",
+ "extension_types": "all",
+ "matches": ["<all_urls>"]
+ },
+ "runtime.onConnect": {
+ "contexts": ["blessed_extension", "unblessed_extension", "content_script"]
+ },
+ "runtime.onMessage": {
+ "contexts": ["blessed_extension", "unblessed_extension", "content_script"]
+ },
+ "runtime.reload": {
+ "contexts": ["blessed_extension", "unblessed_extension", "content_script"]
+ },
+ "runtime.requestUpdateCheck": {
+ "contexts": ["blessed_extension", "unblessed_extension", "content_script"]
+ },
+ "runtime.sendMessage": {
+ "contexts": "all",
+ "matches": ["<all_urls>"]
+ },
+ "runtime.setUninstallURL": {
+ "channel": "dev",
+ "contexts": ["blessed_extension", "unblessed_extension", "content_script"]
+ },
"socket": {
"dependencies": ["permission:socket"],
"contexts": ["blessed_extension"]
@@ -40,6 +83,16 @@
"extension_types": "all",
"contexts": ["blessed_extension", "unblessed_extension", "content_script"]
},
+ "types": {
+ "channel": "stable",
+ "extension_types": ["extension", "legacy_packaged_app", "platform_app"],
+ "contexts": ["blessed_extension"]
+ },
+ "types.private": {
+ "channel": "dev",
+ "extension_types": ["extension"],
+ "location": "component"
+ },
"usb": {
"dependencies": ["permission:usb"],
"contexts": ["blessed_extension"]
diff --git a/extensions/common/api/_permission_features.json b/extensions/common/api/_permission_features.json
index 3447aac..4a24afe 100644
--- a/extensions/common/api/_permission_features.json
+++ b/extensions/common/api/_permission_features.json
@@ -33,6 +33,12 @@
]
}
],
+ // Note: runtime is not actually a permission, but some systems check these
+ // values to verify restrictions.
+ "runtime": {
+ "channel": "stable",
+ "extension_types": ["extension", "legacy_packaged_app", "platform_app"]
+ },
"socket": [
{
"channel": "stable",
diff --git a/extensions/common/api/api.gyp b/extensions/common/api/api.gyp
index b124637..400701d 100644
--- a/extensions/common/api/api.gyp
+++ b/extensions/common/api/api.gyp
@@ -24,6 +24,7 @@
'schema_files': [
'dns.idl',
'extensions_manifest_types.json',
+ 'runtime.json',
'socket.idl',
'sockets_tcp.idl',
'sockets_tcp_server.idl',
diff --git a/chrome/common/extensions/api/runtime.json b/extensions/common/api/runtime.json
index 55704f1e..6009576 100644
--- a/chrome/common/extensions/api/runtime.json
+++ b/extensions/common/api/runtime.json
@@ -1,7 +1,10 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 2014 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.
+// Note: Many of these functions and events are implemented by hand and should
+// not elicit any code generation from the schema compiler. These items are
+// marked "nocompile."
[
{
"namespace": "runtime",
@@ -29,6 +32,7 @@
{
"id": "MessageSender",
"type": "object",
+ "nocompile": true,
"description": "An object containing information about the script context that sent a message or request.",
"properties": {
"tab": {"$ref": "tabs.Tab", "optional": true, "description": "The $(ref:tabs.Tab) which opened the connection, if any. This property will <strong>only</strong> be present when the connection was opened from a tab (including content scripts), and <strong>only</strong> if the receiver is an extension, not an app."},
@@ -36,6 +40,28 @@
"url": {"type": "string", "optional": true, "description": "The URL of the page or frame that opened the connection, if any. This property will <strong>only</strong> be present when the connection was opened from a tab or content script."},
"tlsChannelId": {"type": "string", "optional": true, "description": "The TLS channel ID of the web page that opened the connection, if requested by the extension or app, and if available."}
}
+ },
+ {
+ "id": "PlatformInfo",
+ "type": "object",
+ "description": "An object containing information about the current platform.",
+ "properties": {
+ "os": {
+ "type": "string",
+ "description": "The operating system chrome is running on.",
+ "enum": ["mac", "win", "android", "cros", "linux", "openbsd"]
+ },
+ "arch": {
+ "type": "string",
+ "enum": ["arm", "x86-32", "x86-64"],
+ "description": "The machine's processor architecture."
+ },
+ "nacl_arch" : {
+ "description": "The native client architecture. This may be different from arch on some platforms.",
+ "type": "string",
+ "enum": ["arm", "x86-32", "x86-64"]
+ }
+ }
}
],
"properties": {
@@ -283,24 +309,7 @@
"parameters": [
{
"name": "platformInfo",
- "type": "object",
- "properties": {
- "os": {
- "type": "string",
- "description": "The operating system chrome is running on.",
- "enum": ["mac", "win", "android", "cros", "linux", "openbsd"]
- },
- "arch": {
- "type": "string",
- "enum": ["arm", "x86-32", "x86-64"],
- "description": "The machine's processor architecture."
- },
- "nacl_arch" : {
- "description": "The native client architecture. This may be different from arch on some platforms.",
- "type": "string",
- "enum": ["arm", "x86-32", "x86-64"]
- }
- }
+ "$ref": "PlatformInfo"
}
]
}
@@ -423,6 +432,7 @@
"options": {
"unmanaged": true
},
+ "nocompile": true,
"description": "Fired when a message is sent from either an extension process or a content script.",
"parameters": [
{"name": "message", "type": "any", "optional": true, "description": "The message sent by the calling script."},
@@ -441,6 +451,7 @@
"options": {
"unmanaged": true
},
+ "nocompile": true,
"description": "Fired when a message is sent from another extension/app. Cannot be used in a content script.",
"parameters": [
{"name": "message", "type": "any", "optional": true, "description": "The message sent by the calling script."},
diff --git a/extensions/extensions.gyp b/extensions/extensions.gyp
index 2ec0dcd..f2774b2 100644
--- a/extensions/extensions.gyp
+++ b/extensions/extensions.gyp
@@ -255,6 +255,10 @@
'browser/api/dns/host_resolver_wrapper.h',
'browser/api/extensions_api_client.cc',
'browser/api/extensions_api_client.h',
+ 'browser/api/runtime/runtime_api.cc',
+ 'browser/api/runtime/runtime_api.h',
+ 'browser/api/runtime/runtime_api_delegate.cc',
+ 'browser/api/runtime/runtime_api_delegate.h',
'browser/api/socket/socket.cc',
'browser/api/socket/socket.h',
'browser/api/socket/socket_api.cc',
@@ -407,6 +411,8 @@
# when enable_extensions==0.
'sources/': [
['exclude', '^browser/api/'],
+ ['include', '^browser/api/runtime/runtime_api.cc'],
+ ['include', '^browser/api/runtime/runtime_api_delegate.cc'],
],
'sources!': [
'browser/browser_context_keyed_service_factories.cc',
@@ -549,17 +555,21 @@
'dependencies': [
'../base/base.gyp:base',
'../testing/gtest.gyp:gtest',
+ 'common/api/api.gyp:extensions_api',
'extensions_browser',
'extensions_common',
],
'include_dirs': [
'..',
+ '<(SHARED_INTERMEDIATE_DIR)',
],
'sources': [
'browser/test_extensions_browser_client.cc',
'browser/test_extensions_browser_client.h',
'browser/test_management_policy.cc',
'browser/test_management_policy.h',
+ 'browser/test_runtime_api_delegate.cc',
+ 'browser/test_runtime_api_delegate.h',
'common/extension_builder.cc',
'common/extension_builder.h',
'common/test_util.cc',