summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions
diff options
context:
space:
mode:
authorKristian Monsen <kristianm@google.com>2011-05-11 20:53:37 +0100
committerKristian Monsen <kristianm@google.com>2011-05-16 13:54:48 +0100
commit21d179b334e59e9a3bfcaed4c4430bef1bc5759d (patch)
tree64e2bb6da27af6a5c93ca34f6051584aafbfcb9e /chrome/browser/extensions
parent0c63f00edd6ed0482fd5cbcea937ca088baf7858 (diff)
downloadexternal_chromium-21d179b334e59e9a3bfcaed4c4430bef1bc5759d.zip
external_chromium-21d179b334e59e9a3bfcaed4c4430bef1bc5759d.tar.gz
external_chromium-21d179b334e59e9a3bfcaed4c4430bef1bc5759d.tar.bz2
Merge Chromium at 10.0.621.0: Initial merge by git.
Change-Id: I070cc91c608dfa4a968a5a54c173260765ac8097
Diffstat (limited to 'chrome/browser/extensions')
-rw-r--r--chrome/browser/extensions/alert_apitest.cc4
-rw-r--r--chrome/browser/extensions/all_urls_apitest.cc8
-rw-r--r--chrome/browser/extensions/app_process_apitest.cc5
-rw-r--r--chrome/browser/extensions/autoupdate_interceptor.cc10
-rw-r--r--chrome/browser/extensions/autoupdate_interceptor.h2
-rw-r--r--chrome/browser/extensions/browser_action_apitest.cc8
-rw-r--r--chrome/browser/extensions/browser_action_test_util_mac.mm12
-rw-r--r--chrome/browser/extensions/content_script_extension_process_apitest.cc3
-rw-r--r--chrome/browser/extensions/convert_user_script.cc5
-rw-r--r--chrome/browser/extensions/convert_user_script_unittest.cc15
-rw-r--r--chrome/browser/extensions/convert_web_app.cc3
-rw-r--r--chrome/browser/extensions/convert_web_app_browsertest.cc24
-rw-r--r--chrome/browser/extensions/crashed_extension_infobar.cc9
-rw-r--r--chrome/browser/extensions/crashed_extension_infobar.h10
-rw-r--r--chrome/browser/extensions/crx_installer.cc19
-rw-r--r--chrome/browser/extensions/crx_installer.h8
-rw-r--r--chrome/browser/extensions/crx_installer_browsertest.cc6
-rw-r--r--chrome/browser/extensions/default_apps.cc151
-rw-r--r--chrome/browser/extensions/default_apps.h62
-rw-r--r--chrome/browser/extensions/default_apps_unittest.cc207
-rw-r--r--chrome/browser/extensions/execute_code_in_tab_function.cc6
-rw-r--r--chrome/browser/extensions/extension_accessibility_api.cc4
-rw-r--r--chrome/browser/extensions/extension_apitest.cc8
-rw-r--r--chrome/browser/extensions/extension_apitest.h1
-rw-r--r--chrome/browser/extensions/extension_bookmark_manager_api.cc2
-rw-r--r--chrome/browser/extensions/extension_bookmarks_module.cc4
-rw-r--r--chrome/browser/extensions/extension_bookmarks_module.h15
-rw-r--r--chrome/browser/extensions/extension_browser_event_router.cc5
-rw-r--r--chrome/browser/extensions/extension_browser_event_router.h6
-rw-r--r--chrome/browser/extensions/extension_browsertest.cc26
-rw-r--r--chrome/browser/extensions/extension_browsertests_misc.cc36
-rw-r--r--chrome/browser/extensions/extension_clipboard_api.cc2
-rw-r--r--chrome/browser/extensions/extension_context_menu_api.cc14
-rw-r--r--chrome/browser/extensions/extension_context_menu_browsertest.cc9
-rw-r--r--chrome/browser/extensions/extension_context_menu_model.cc13
-rw-r--r--chrome/browser/extensions/extension_cookies_api.cc6
-rw-r--r--chrome/browser/extensions/extension_cookies_api.h4
-rw-r--r--chrome/browser/extensions/extension_cookies_helpers.cc13
-rw-r--r--chrome/browser/extensions/extension_cookies_helpers.h4
-rw-r--r--chrome/browser/extensions/extension_cookies_unittest.cc4
-rw-r--r--chrome/browser/extensions/extension_crash_recovery_browsertest.cc211
-rw-r--r--chrome/browser/extensions/extension_data_deleter.cc14
-rw-r--r--chrome/browser/extensions/extension_data_deleter.h12
-rw-r--r--chrome/browser/extensions/extension_devtools_bridge.cc4
-rw-r--r--chrome/browser/extensions/extension_devtools_browsertests.cc5
-rw-r--r--chrome/browser/extensions/extension_disabled_infobar_delegate.cc35
-rw-r--r--chrome/browser/extensions/extension_disabled_infobar_delegate.h6
-rw-r--r--chrome/browser/extensions/extension_dom_ui.cc12
-rw-r--r--chrome/browser/extensions/extension_event_router.cc10
-rw-r--r--chrome/browser/extensions/extension_fileapi_apitest.cc9
-rw-r--r--chrome/browser/extensions/extension_function.cc6
-rw-r--r--chrome/browser/extensions/extension_function_dispatcher.cc28
-rw-r--r--chrome/browser/extensions/extension_history_api.cc2
-rw-r--r--chrome/browser/extensions/extension_host.cc50
-rw-r--r--chrome/browser/extensions/extension_host.h18
-rw-r--r--chrome/browser/extensions/extension_host_mac.mm6
-rw-r--r--chrome/browser/extensions/extension_i18n_api.cc2
-rw-r--r--chrome/browser/extensions/extension_idle_api.cc4
-rw-r--r--chrome/browser/extensions/extension_idle_api.h3
-rw-r--r--chrome/browser/extensions/extension_incognito_apitest.cc8
-rw-r--r--chrome/browser/extensions/extension_infobar_apitest.cc2
-rw-r--r--chrome/browser/extensions/extension_infobar_delegate.cc10
-rw-r--r--chrome/browser/extensions/extension_infobar_delegate.h2
-rw-r--r--chrome/browser/extensions/extension_infobar_module.cc2
-rw-r--r--chrome/browser/extensions/extension_input_api.cc1
-rw-r--r--chrome/browser/extensions/extension_install_ui.cc40
-rw-r--r--chrome/browser/extensions/extension_install_ui_browsertest.cc4
-rw-r--r--chrome/browser/extensions/extension_management_api.cc17
-rw-r--r--chrome/browser/extensions/extension_management_api.h4
-rw-r--r--chrome/browser/extensions/extension_management_apitest.cc6
-rw-r--r--chrome/browser/extensions/extension_management_browsertest.cc72
-rw-r--r--chrome/browser/extensions/extension_menu_manager.cc15
-rw-r--r--chrome/browser/extensions/extension_menu_manager_unittest.cc11
-rw-r--r--chrome/browser/extensions/extension_message_service.cc4
-rw-r--r--chrome/browser/extensions/extension_message_service.h6
-rw-r--r--chrome/browser/extensions/extension_messages_apitest.cc3
-rw-r--r--chrome/browser/extensions/extension_metrics_apitest.cc2
-rw-r--r--chrome/browser/extensions/extension_module.cc6
-rw-r--r--chrome/browser/extensions/extension_omnibox_api.cc17
-rw-r--r--chrome/browser/extensions/extension_omnibox_apitest.cc4
-rw-r--r--chrome/browser/extensions/extension_override_apitest.cc8
-rw-r--r--chrome/browser/extensions/extension_page_actions_module.cc6
-rw-r--r--chrome/browser/extensions/extension_popup_api.cc7
-rw-r--r--chrome/browser/extensions/extension_pref_store.cc197
-rw-r--r--chrome/browser/extensions/extension_pref_store.h118
-rw-r--r--chrome/browser/extensions/extension_pref_store_unittest.cc369
-rw-r--r--chrome/browser/extensions/extension_prefs.cc257
-rw-r--r--chrome/browser/extensions/extension_prefs.h87
-rw-r--r--chrome/browser/extensions/extension_prefs_unittest.cc367
-rw-r--r--chrome/browser/extensions/extension_process_manager.cc33
-rw-r--r--chrome/browser/extensions/extension_processes_api.cc5
-rw-r--r--chrome/browser/extensions/extension_protocols.cc40
-rw-r--r--chrome/browser/extensions/extension_proxy_api.cc54
-rw-r--r--chrome/browser/extensions/extension_proxy_api.h8
-rw-r--r--chrome/browser/extensions/extension_proxy_apitest.cc119
-rw-r--r--chrome/browser/extensions/extension_rlz_apitest.cc1
-rw-r--r--chrome/browser/extensions/extension_service.cc (renamed from chrome/browser/extensions/extensions_service.cc)493
-rw-r--r--chrome/browser/extensions/extension_service.h (renamed from chrome/browser/extensions/extensions_service.h)118
-rw-r--r--chrome/browser/extensions/extension_service_unittest.cc (renamed from chrome/browser/extensions/extensions_service_unittest.cc)518
-rw-r--r--chrome/browser/extensions/extension_service_unittest.h (renamed from chrome/browser/extensions/extensions_service_unittest.h)22
-rw-r--r--chrome/browser/extensions/extension_sidebar_api.cc6
-rw-r--r--chrome/browser/extensions/extension_startup_browsertest.cc9
-rw-r--r--chrome/browser/extensions/extension_tabs_apitest.cc2
-rw-r--r--chrome/browser/extensions/extension_tabs_module.cc66
-rw-r--r--chrome/browser/extensions/extension_tabs_module.h1
-rw-r--r--chrome/browser/extensions/extension_tabs_module_constants.cc2
-rw-r--r--chrome/browser/extensions/extension_tabs_module_constants.h1
-rw-r--r--chrome/browser/extensions/extension_test_api.cc17
-rw-r--r--chrome/browser/extensions/extension_test_api.h5
-rw-r--r--chrome/browser/extensions/extension_toolbar_model.cc23
-rw-r--r--chrome/browser/extensions/extension_toolbar_model.h8
-rw-r--r--chrome/browser/extensions/extension_toolbar_model_browsertest.cc8
-rw-r--r--chrome/browser/extensions/extension_tts_api.cc362
-rw-r--r--chrome/browser/extensions/extension_tts_api.h141
-rw-r--r--chrome/browser/extensions/extension_tts_api_chromeos.cc51
-rw-r--r--chrome/browser/extensions/extension_tts_api_util.cc15
-rw-r--r--chrome/browser/extensions/extension_tts_api_util.h20
-rw-r--r--chrome/browser/extensions/extension_tts_apitest.cc43
-rw-r--r--chrome/browser/extensions/extension_uitest.cc28
-rw-r--r--chrome/browser/extensions/extension_updater.cc52
-rw-r--r--chrome/browser/extensions/extension_updater.h12
-rw-r--r--chrome/browser/extensions/extension_updater_unittest.cc34
-rw-r--r--chrome/browser/extensions/extension_webglbackground_apitest.cc9
-rw-r--r--chrome/browser/extensions/extension_webnavigation_api.cc51
-rw-r--r--chrome/browser/extensions/extension_webnavigation_api.h31
-rw-r--r--chrome/browser/extensions/extension_webnavigation_apitest.cc1
-rw-r--r--chrome/browser/extensions/extension_webnavigation_unittest.cc37
-rw-r--r--chrome/browser/extensions/extension_webstore_private_api.cc13
-rw-r--r--chrome/browser/extensions/extension_webstore_private_browsertest.cc2
-rw-r--r--chrome/browser/extensions/extensions_startup.cc109
-rw-r--r--chrome/browser/extensions/extensions_startup.h39
-rw-r--r--chrome/browser/extensions/extensions_ui.cc28
-rw-r--r--chrome/browser/extensions/extensions_ui.h16
-rw-r--r--chrome/browser/extensions/external_extension_provider.h6
-rw-r--r--chrome/browser/extensions/external_policy_extension_provider.cc21
-rw-r--r--chrome/browser/extensions/external_policy_extension_provider.h10
-rw-r--r--chrome/browser/extensions/external_policy_extension_provider_unittest.cc21
-rw-r--r--chrome/browser/extensions/external_pref_extension_provider.cc7
-rw-r--r--chrome/browser/extensions/external_pref_extension_provider.h2
-rw-r--r--chrome/browser/extensions/external_registry_extension_provider_win.cc15
-rw-r--r--chrome/browser/extensions/external_registry_extension_provider_win.h6
-rw-r--r--chrome/browser/extensions/fragment_navigation_apitest.cc4
-rw-r--r--chrome/browser/extensions/gtk_theme_installed_infobar_delegate.cc2
-rw-r--r--chrome/browser/extensions/image_loading_tracker.cc8
-rw-r--r--chrome/browser/extensions/image_loading_tracker_unittest.cc4
-rw-r--r--chrome/browser/extensions/notifications_apitest.cc10
-rw-r--r--chrome/browser/extensions/pack_extension_job.cc40
-rw-r--r--chrome/browser/extensions/pack_extension_job.h9
-rw-r--r--chrome/browser/extensions/page_action_apitest.cc6
-rw-r--r--chrome/browser/extensions/sandboxed_extension_unpacker.cc173
-rw-r--r--chrome/browser/extensions/sandboxed_extension_unpacker.h6
-rw-r--r--chrome/browser/extensions/stateful_external_extension_provider.cc18
-rw-r--r--chrome/browser/extensions/stateful_external_extension_provider.h14
-rw-r--r--chrome/browser/extensions/test_extension_prefs.cc43
-rw-r--r--chrome/browser/extensions/test_extension_prefs.h1
-rw-r--r--chrome/browser/extensions/theme_installed_infobar_delegate.cc6
-rw-r--r--chrome/browser/extensions/user_script_listener.cc12
-rw-r--r--chrome/browser/extensions/user_script_listener_unittest.cc31
-rw-r--r--chrome/browser/extensions/user_script_master.cc16
-rw-r--r--chrome/browser/extensions/window_open_apitest.cc4
160 files changed, 3446 insertions, 2544 deletions
diff --git a/chrome/browser/extensions/alert_apitest.cc b/chrome/browser/extensions/alert_apitest.cc
index 292e1bd..10b310b 100644
--- a/chrome/browser/extensions/alert_apitest.cc
+++ b/chrome/browser/extensions/alert_apitest.cc
@@ -2,12 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/browser/app_modal_dialog.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extension_process_manager.h"
#include "chrome/browser/renderer_host/render_view_host.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/ui_test_utils.h"
diff --git a/chrome/browser/extensions/all_urls_apitest.cc b/chrome/browser/extensions/all_urls_apitest.cc
index e0e2a4a..522610e 100644
--- a/chrome/browser/extensions/all_urls_apitest.cc
+++ b/chrome/browser/extensions/all_urls_apitest.cc
@@ -3,9 +3,9 @@
// found in the LICENSE file.
#include "chrome/browser/extensions/extension_apitest.h"
-#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_test_message_listener.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/test/ui_test_utils.h"
@@ -44,7 +44,7 @@ IN_PROC_BROWSER_TEST_F(AllUrlsApiTest, WhitelistedExtension) {
// Then load extensions.
Checkpoint("LoadExtension1", start_time);
- ExtensionsService* service = browser()->profile()->GetExtensionsService();
+ ExtensionService* service = browser()->profile()->GetExtensionService();
const size_t size_before = service->extensions()->size();
ASSERT_TRUE(LoadExtension(extension_dir1));
Checkpoint("LoadExtension2", start_time);
@@ -123,7 +123,7 @@ IN_PROC_BROWSER_TEST_F(AllUrlsApiTest, DISABLED_RegularExtensions) {
FilePath extension_dir2 = test_data_dir_.AppendASCII("all_urls")
.AppendASCII("execute_script");
- ExtensionsService* service = browser()->profile()->GetExtensionsService();
+ ExtensionService* service = browser()->profile()->GetExtensionService();
const size_t size_before = service->extensions()->size();
ASSERT_TRUE(LoadExtension(extension_dir1));
ASSERT_TRUE(LoadExtension(extension_dir2));
diff --git a/chrome/browser/extensions/app_process_apitest.cc b/chrome/browser/extensions/app_process_apitest.cc
index 1d1b707..dece83c 100644
--- a/chrome/browser/extensions/app_process_apitest.cc
+++ b/chrome/browser/extensions/app_process_apitest.cc
@@ -7,7 +7,7 @@
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extension_process_manager.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/ui/browser.h"
@@ -84,7 +84,8 @@ IN_PROC_BROWSER_TEST_F(AppApiTest, MAYBE_AppProcess) {
// The app under test acts on URLs whose host is "localhost",
// so the URLs we navigate to must have host "localhost".
GURL::Replacements replace_host;
- replace_host.SetHostStr("localhost");
+ std::string host_str("localhost"); // must stay in scope with replace_host
+ replace_host.SetHostStr(host_str);
base_url = base_url.ReplaceComponents(replace_host);
browser()->NewTab();
diff --git a/chrome/browser/extensions/autoupdate_interceptor.cc b/chrome/browser/extensions/autoupdate_interceptor.cc
index ef0091f..e919189 100644
--- a/chrome/browser/extensions/autoupdate_interceptor.cc
+++ b/chrome/browser/extensions/autoupdate_interceptor.cc
@@ -15,7 +15,7 @@
// code relies on.
class AutoUpdateTestRequestJob : public URLRequestTestJob {
public:
- AutoUpdateTestRequestJob(URLRequest* request,
+ AutoUpdateTestRequestJob(net::URLRequest* request,
const std::string& response_data) : URLRequestTestJob(
request, URLRequestTestJob::test_headers(), response_data, true) {}
virtual int GetResponseCode() const { return 200; }
@@ -26,15 +26,15 @@ class AutoUpdateTestRequestJob : public URLRequestTestJob {
AutoUpdateInterceptor::AutoUpdateInterceptor() {
- URLRequest::RegisterRequestInterceptor(this);
+ net::URLRequest::RegisterRequestInterceptor(this);
}
AutoUpdateInterceptor::~AutoUpdateInterceptor() {
- URLRequest::UnregisterRequestInterceptor(this);
+ net::URLRequest::UnregisterRequestInterceptor(this);
}
-
-URLRequestJob* AutoUpdateInterceptor::MaybeIntercept(URLRequest* request) {
+net::URLRequestJob* AutoUpdateInterceptor::MaybeIntercept(
+ net::URLRequest* request) {
EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
if (request->url().scheme() != "http" ||
request->url().host() != "localhost") {
diff --git a/chrome/browser/extensions/autoupdate_interceptor.h b/chrome/browser/extensions/autoupdate_interceptor.h
index 219941a..a2e0891 100644
--- a/chrome/browser/extensions/autoupdate_interceptor.h
+++ b/chrome/browser/extensions/autoupdate_interceptor.h
@@ -15,7 +15,7 @@
// This url request interceptor lets us respond to localhost http request urls
// with the contents of files on disk for use in tests.
class AutoUpdateInterceptor
- : public URLRequest::Interceptor,
+ : public net::URLRequest::Interceptor,
public base::RefCountedThreadSafe<AutoUpdateInterceptor> {
public:
AutoUpdateInterceptor();
diff --git a/chrome/browser/extensions/browser_action_apitest.cc b/chrome/browser/extensions/browser_action_apitest.cc
index 59e56ca..8c413e4 100644
--- a/chrome/browser/extensions/browser_action_apitest.cc
+++ b/chrome/browser/extensions/browser_action_apitest.cc
@@ -13,8 +13,8 @@
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_browser_event_router.h"
#include "chrome/browser/extensions/extension_tabs_module.h"
-#include "chrome/browser/extensions/extensions_service.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_switches.h"
@@ -286,7 +286,7 @@ IN_PROC_BROWSER_TEST_F(BrowserActionApiTest, IncognitoBasic) {
// Now enable the extension in incognito mode, and test that the browser
// action shows up. Note that we don't update the existing window at the
// moment, so we just create a new one.
- browser()->profile()->GetExtensionsService()->extension_prefs()->
+ browser()->profile()->GetExtensionService()->extension_prefs()->
SetIsIncognitoEnabled(extension->id(), true);
incognito_browser->CloseWindow();
@@ -299,7 +299,7 @@ IN_PROC_BROWSER_TEST_F(BrowserActionApiTest, IncognitoBasic) {
}
IN_PROC_BROWSER_TEST_F(BrowserActionApiTest, IncognitoDragging) {
- ExtensionsService* service = browser()->profile()->GetExtensionsService();
+ ExtensionService* service = browser()->profile()->GetExtensionService();
// The tooltips for each respective browser action.
const char kTooltipA[] = "Make this page red";
diff --git a/chrome/browser/extensions/browser_action_test_util_mac.mm b/chrome/browser/extensions/browser_action_test_util_mac.mm
index bc46a88..3b6dcc6 100644
--- a/chrome/browser/extensions/browser_action_test_util_mac.mm
+++ b/chrome/browser/extensions/browser_action_test_util_mac.mm
@@ -5,13 +5,13 @@
#include "browser_action_test_util.h"
#include "base/sys_string_conversions.h"
-#import "chrome/browser/cocoa/browser_window_cocoa.h"
-#import "chrome/browser/cocoa/browser_window_controller.h"
-#import "chrome/browser/cocoa/extensions/browser_actions_controller.h"
-#import "chrome/browser/cocoa/extensions/extension_popup_controller.h"
-#import "chrome/browser/cocoa/info_bubble_window.h"
-#import "chrome/browser/cocoa/toolbar_controller.h"
#include "chrome/browser/ui/browser.h"
+#import "chrome/browser/ui/cocoa/browser_window_cocoa.h"
+#import "chrome/browser/ui/cocoa/browser_window_controller.h"
+#import "chrome/browser/ui/cocoa/extensions/browser_actions_controller.h"
+#import "chrome/browser/ui/cocoa/extensions/extension_popup_controller.h"
+#import "chrome/browser/ui/cocoa/info_bubble_window.h"
+#import "chrome/browser/ui/cocoa/toolbar_controller.h"
#include "gfx/rect.h"
#include "gfx/size.h"
diff --git a/chrome/browser/extensions/content_script_extension_process_apitest.cc b/chrome/browser/extensions/content_script_extension_process_apitest.cc
index f6748de..100e77b 100644
--- a/chrome/browser/extensions/content_script_extension_process_apitest.cc
+++ b/chrome/browser/extensions/content_script_extension_process_apitest.cc
@@ -3,8 +3,7 @@
// found in the LICENSE file.
#include "chrome/browser/extensions/extension_apitest.h"
-#include "chrome/browser/extensions/extensions_service.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/test/ui_test_utils.h"
diff --git a/chrome/browser/extensions/convert_user_script.cc b/chrome/browser/extensions/convert_user_script.cc
index 89caec4..bcb0f5a 100644
--- a/chrome/browser/extensions/convert_user_script.cc
+++ b/chrome/browser/extensions/convert_user_script.cc
@@ -34,6 +34,11 @@ scoped_refptr<Extension> ConvertUserScriptToExtension(
return NULL;
}
+ if (!IsStringUTF8(content)) {
+ *error = "User script must be UTF8 encoded.";
+ return NULL;
+ }
+
UserScript script;
if (!UserScriptMaster::ScriptReloader::ParseMetadataHeader(content,
&script)) {
diff --git a/chrome/browser/extensions/convert_user_script_unittest.cc b/chrome/browser/extensions/convert_user_script_unittest.cc
index a0e1b8b..e9c73cb 100644
--- a/chrome/browser/extensions/convert_user_script_unittest.cc
+++ b/chrome/browser/extensions/convert_user_script_unittest.cc
@@ -92,3 +92,18 @@ TEST(ExtensionFromUserScript, NoMetdata) {
// Cleanup
file_util::Delete(extension->path(), true);
}
+
+TEST(ExtensionFromUserScript, NotUTF8) {
+ FilePath test_file;
+
+ ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_file));
+ test_file = test_file.AppendASCII("extensions")
+ .AppendASCII("user_script_not_utf8.user.js");
+
+ std::string error;
+ scoped_refptr<Extension> extension(ConvertUserScriptToExtension(
+ test_file, GURL("http://www.google.com/foo/bar.user.js?monkey"), &error));
+
+ ASSERT_FALSE(extension.get());
+ EXPECT_EQ("User script must be UTF8 encoded.", error);
+}
diff --git a/chrome/browser/extensions/convert_web_app.cc b/chrome/browser/extensions/convert_web_app.cc
index 11303ff..e1c8c92 100644
--- a/chrome/browser/extensions/convert_web_app.cc
+++ b/chrome/browser/extensions/convert_web_app.cc
@@ -101,6 +101,9 @@ scoped_refptr<Extension> ConvertWebAppToExtension(
root->SetString(keys::kDescription, UTF16ToUTF8(web_app.description));
root->SetString(keys::kLaunchWebURL, web_app.app_url.spec());
+ if (!web_app.launch_container.empty())
+ root->SetString(keys::kLaunchContainer, web_app.launch_container);
+
// Add the icons.
DictionaryValue* icons = new DictionaryValue();
root->Set(keys::kIcons, icons);
diff --git a/chrome/browser/extensions/convert_web_app_browsertest.cc b/chrome/browser/extensions/convert_web_app_browsertest.cc
index a6cdb19..bb2ea24 100644
--- a/chrome/browser/extensions/convert_web_app_browsertest.cc
+++ b/chrome/browser/extensions/convert_web_app_browsertest.cc
@@ -4,9 +4,9 @@
#include <string>
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/extensions/extension_service.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/notification_details.h"
@@ -47,7 +47,7 @@ class ExtensionFromWebAppTest
IN_PROC_BROWSER_TEST_F(ExtensionFromWebAppTest, Basic) {
ASSERT_TRUE(test_server()->Start());
- browser()->profile()->GetExtensionsService()->set_show_extensions_prompts(
+ browser()->profile()->GetExtensionService()->set_show_extensions_prompts(
false);
NotificationRegistrar registrar;
@@ -65,4 +65,22 @@ IN_PROC_BROWSER_TEST_F(ExtensionFromWebAppTest, Basic) {
EXPECT_TRUE(installed_extension_);
EXPECT_TRUE(installed_extension_->is_hosted_app());
+ EXPECT_EQ("Test application", installed_extension_->name());
+ EXPECT_EQ("the description is", installed_extension_->description());
+ EXPECT_EQ(extension_misc::LAUNCH_PANEL,
+ installed_extension_->launch_container());
+
+ ASSERT_EQ(2u, installed_extension_->api_permissions().size());
+ EXPECT_TRUE(installed_extension_->api_permissions().find("geolocation") !=
+ installed_extension_->api_permissions().end());
+ EXPECT_TRUE(installed_extension_->api_permissions().find("notifications") !=
+ installed_extension_->api_permissions().end());
+
+ ASSERT_EQ(3u, installed_extension_->icons().map().size());
+ EXPECT_EQ("icons/16.png", installed_extension_->icons().Get(
+ 16, ExtensionIconSet::MATCH_EXACTLY));
+ EXPECT_EQ("icons/48.png", installed_extension_->icons().Get(
+ 48, ExtensionIconSet::MATCH_EXACTLY));
+ EXPECT_EQ("icons/128.png", installed_extension_->icons().Get(
+ 128, ExtensionIconSet::MATCH_EXACTLY));
}
diff --git a/chrome/browser/extensions/crashed_extension_infobar.cc b/chrome/browser/extensions/crashed_extension_infobar.cc
index 053b4b4..fbed6e6 100644
--- a/chrome/browser/extensions/crashed_extension_infobar.cc
+++ b/chrome/browser/extensions/crashed_extension_infobar.cc
@@ -7,7 +7,7 @@
#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "base/utf_string_conversions.h"
-#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/extensions/extension_service.h"
#include "chrome/common/extensions/extension.h"
#include "grit/browser_resources.h"
#include "grit/generated_resources.h"
@@ -15,7 +15,7 @@
CrashedExtensionInfoBarDelegate::CrashedExtensionInfoBarDelegate(
TabContents* tab_contents,
- ExtensionsService* extensions_service,
+ ExtensionService* extensions_service,
const Extension* extension)
: ConfirmInfoBarDelegate(tab_contents),
extensions_service_(extensions_service),
@@ -30,6 +30,11 @@ AsCrashedExtensionInfoBarDelegate() {
return this;
}
+bool CrashedExtensionInfoBarDelegate::ShouldExpire(
+ const NavigationController::LoadCommittedDetails& details) const {
+ return false;
+}
+
string16 CrashedExtensionInfoBarDelegate::GetMessageText() const {
return l10n_util::GetStringFUTF16(IDS_EXTENSION_CRASHED_INFOBAR_MESSAGE,
UTF8ToUTF16(extension_name_));
diff --git a/chrome/browser/extensions/crashed_extension_infobar.h b/chrome/browser/extensions/crashed_extension_infobar.h
index 1508ae5..201e606 100644
--- a/chrome/browser/extensions/crashed_extension_infobar.h
+++ b/chrome/browser/extensions/crashed_extension_infobar.h
@@ -12,7 +12,7 @@
#include "chrome/browser/tab_contents/infobar_delegate.h"
class Extension;
-class ExtensionsService;
+class ExtensionService;
class SkBitmap;
// This infobar will be displayed when an extension process crashes. It allows
@@ -21,15 +21,17 @@ class CrashedExtensionInfoBarDelegate : public ConfirmInfoBarDelegate {
public:
// |tab_contents| should point to the TabContents the infobar will be added
// to. |extension| should be the crashed extension, and |extensions_service|
- // the ExtensionsService which manages that extension.
+ // the ExtensionService which manages that extension.
CrashedExtensionInfoBarDelegate(TabContents* tab_contents,
- ExtensionsService* extensions_service,
+ ExtensionService* extensions_service,
const Extension* extension);
const std::string extension_id() { return extension_id_; }
// InfoBarDelegate
virtual CrashedExtensionInfoBarDelegate* AsCrashedExtensionInfoBarDelegate();
+ virtual bool ShouldExpire(
+ const NavigationController::LoadCommittedDetails& details) const;
// ConfirmInfoBarDelegate
virtual string16 GetMessageText() const;
@@ -41,7 +43,7 @@ class CrashedExtensionInfoBarDelegate : public ConfirmInfoBarDelegate {
virtual bool Accept();
private:
- ExtensionsService* extensions_service_;
+ ExtensionService* extensions_service_;
const std::string extension_id_;
const std::string extension_name_;
diff --git a/chrome/browser/extensions/crx_installer.cc b/chrome/browser/extensions/crx_installer.cc
index 8441baa..f6708c5 100644
--- a/chrome/browser/extensions/crx_installer.cc
+++ b/chrome/browser/extensions/crx_installer.cc
@@ -9,9 +9,9 @@
#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "base/file_util.h"
+#include "base/lazy_instance.h"
#include "base/path_service.h"
#include "base/scoped_temp_dir.h"
-#include "base/singleton.h"
#include "base/stl_util-inl.h"
#include "base/stringprintf.h"
#include "base/time.h"
@@ -23,9 +23,8 @@
#include "chrome/browser/browser_thread.h"
#include "chrome/browser/extensions/convert_user_script.h"
#include "chrome/browser/extensions/convert_web_app.h"
-#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_error_reporter.h"
-#include "chrome/browser/profile.h"
#include "chrome/browser/shell_integration.h"
#include "chrome/browser/web_applications/web_app.h"
#include "chrome/common/chrome_paths.h"
@@ -51,25 +50,28 @@ struct WhitelistedInstallData {
std::set<std::string> ids;
};
+static base::LazyInstance<WhitelistedInstallData>
+ g_whitelisted_install_data(base::LINKER_INITIALIZED);
+
} // namespace
// static
void CrxInstaller::SetWhitelistedInstallId(const std::string& id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- Singleton<WhitelistedInstallData>::get()->ids.insert(id);
+ g_whitelisted_install_data.Get().ids.insert(id);
}
// static
bool CrxInstaller::IsIdWhitelisted(const std::string& id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- std::set<std::string>& ids = Singleton<WhitelistedInstallData>::get()->ids;
+ std::set<std::string>& ids = g_whitelisted_install_data.Get().ids;
return ContainsKey(ids, id);
}
// static
bool CrxInstaller::ClearWhitelistedInstallId(const std::string& id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- std::set<std::string>& ids = Singleton<WhitelistedInstallData>::get()->ids;
+ std::set<std::string>& ids = g_whitelisted_install_data.Get().ids;
if (ContainsKey(ids, id)) {
ids.erase(id);
return true;
@@ -77,7 +79,7 @@ bool CrxInstaller::ClearWhitelistedInstallId(const std::string& id) {
return false;
}
-CrxInstaller::CrxInstaller(ExtensionsService* frontend,
+CrxInstaller::CrxInstaller(ExtensionService* frontend,
ExtensionInstallUI* client)
: install_directory_(frontend->install_directory()),
install_source_(Extension::INTERNAL),
@@ -308,8 +310,7 @@ void CrxInstaller::ConfirmInstall() {
GURL overlapping_url;
const Extension* overlapping_extension =
frontend_->GetExtensionByOverlappingWebExtent(extension_->web_extent());
- if (overlapping_extension &&
- overlapping_extension->id() != extension_->id()) {
+ if (overlapping_extension) {
ReportFailureFromUIThread(l10n_util::GetStringFUTF8(
IDS_EXTENSION_OVERLAPPING_WEB_EXTENT,
UTF8ToUTF16(overlapping_extension->name())));
diff --git a/chrome/browser/extensions/crx_installer.h b/chrome/browser/extensions/crx_installer.h
index c22a4a9..4a6aa28 100644
--- a/chrome/browser/extensions/crx_installer.h
+++ b/chrome/browser/extensions/crx_installer.h
@@ -15,7 +15,7 @@
#include "chrome/common/extensions/extension.h"
#include "chrome/common/web_apps.h"
-class ExtensionsService;
+class ExtensionService;
class SkBitmap;
// This class installs a crx file into a profile.
@@ -65,7 +65,7 @@ class CrxInstaller
// frontend->install_directory() then registered with |frontend|. Any install
// UI will be displayed using |client|. Pass NULL for |client| for silent
// install.
- CrxInstaller(ExtensionsService* frontend,
+ CrxInstaller(ExtensionService* frontend,
ExtensionInstallUI* client);
// Install the crx in |source_file|.
@@ -182,7 +182,7 @@ class CrxInstaller
bool create_app_shortcut_;
// The extension we're installing. We own this and either pass it off to
- // ExtensionsService on success, or delete it on failure.
+ // ExtensionService on success, or delete it on failure.
scoped_refptr<const Extension> extension_;
// If non-empty, contains the current version of the extension we're
@@ -197,7 +197,7 @@ class CrxInstaller
FilePath temp_dir_;
// The frontend we will report results back to.
- scoped_refptr<ExtensionsService> frontend_;
+ scoped_refptr<ExtensionService> frontend_;
// The client we will work with to do the installation. This can be NULL, in
// which case the install is silent.
diff --git a/chrome/browser/extensions/crx_installer_browsertest.cc b/chrome/browser/extensions/crx_installer_browsertest.cc
index f49c577..e1a412f 100644
--- a/chrome/browser/extensions/crx_installer_browsertest.cc
+++ b/chrome/browser/extensions/crx_installer_browsertest.cc
@@ -5,8 +5,8 @@
#include "chrome/browser/extensions/crx_installer.h"
#include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/browser/extensions/extension_install_ui.h"
-#include "chrome/browser/extensions/extensions_service.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/ui_test_utils.h"
@@ -48,7 +48,7 @@ class ExtensionCrxInstallerTest : public ExtensionBrowserTest {
// happened or not.
bool DidWhitelistInstallPrompt(const std::string& crx_relpath,
const std::string& id) {
- ExtensionsService* service = browser()->profile()->GetExtensionsService();
+ ExtensionService* service = browser()->profile()->GetExtensionService();
MockInstallUI* mock_install_ui = new MockInstallUI(browser()->profile());
scoped_refptr<CrxInstaller> installer(
diff --git a/chrome/browser/extensions/default_apps.cc b/chrome/browser/extensions/default_apps.cc
index cee5c32..a9e305f 100644
--- a/chrome/browser/extensions/default_apps.cc
+++ b/chrome/browser/extensions/default_apps.cc
@@ -18,146 +18,89 @@ void DefaultApps::RegisterUserPrefs(PrefService* prefs) {
prefs->RegisterIntegerPref(prefs::kAppsPromoCounter, 0);
}
-DefaultApps::DefaultApps(PrefService* prefs,
- const std::string& application_locale)
- : prefs_(prefs), application_locale_(application_locale) {
+DefaultApps::DefaultApps(PrefService* prefs)
+ : prefs_(prefs) {
+#if !defined(OS_CHROMEOS)
// Poppit, Entanglement
ids_.insert("mcbkbpnkkkipelfledbfocopglifcfmi");
ids_.insert("aciahcmjmecflokailenpkdchphgkefd");
+#endif // OS_CHROMEOS
}
DefaultApps::~DefaultApps() {}
-const ExtensionIdSet& DefaultApps::default_apps() const {
- return ids_;
-}
-
-bool DefaultApps::DefaultAppSupported() {
- // On Chrome OS the default apps are installed via a different mechanism.
-#if defined(OS_CHROMEOS)
- return false;
-#else
- return DefaultAppsSupportedForLanguage();
-#endif
+const ExtensionIdSet* DefaultApps::GetAppsToInstall() const {
+ if (GetDefaultAppsInstalled())
+ return NULL;
+ else
+ return &ids_;
}
-bool DefaultApps::DefaultAppsSupportedForLanguage() {
- return application_locale_ == "en-US";
+const ExtensionIdSet* DefaultApps::GetDefaultApps() const {
+ return &ids_;
}
-bool DefaultApps::ShouldInstallDefaultApps(
- const ExtensionIdSet& installed_ids) {
- if (!DefaultAppSupported())
- return false;
-
- if (GetDefaultAppsInstalled())
- return false;
-
- // If there are any non-default apps installed, we should never try to install
- // the default apps again, even if the non-default apps are later removed.
- if (NonDefaultAppIsInstalled(installed_ids)) {
+void DefaultApps::DidInstallApp(const ExtensionIdSet& installed_ids) {
+ // If all the default apps have been installed, stop trying to install them.
+ // Note that we use std::includes here instead of == because apps might have
+ // been manually installed while the the default apps were installing and we
+ // wouldn't want to keep trying to install them in that case.
+ if (!GetDefaultAppsInstalled() &&
+ std::includes(installed_ids.begin(), installed_ids.end(),
+ ids_.begin(), ids_.end())) {
SetDefaultAppsInstalled(true);
- return false;
}
-
- return true;
}
-bool DefaultApps::ShouldShowAppLauncher(const ExtensionIdSet& installed_ids) {
- // On Chrome OS the default apps are installed via a separate mechanism that
- // is always enabled. Therefore we always show the launcher.
-#if defined(OS_CHROME)
- return true;
-#else
- // The app store only supports en-us at the moment, so we don't show the apps
- // section by default for users in other locales. But we do show it if a user
- // from a non-supported locale somehow installs an app (eg by navigating
- // directly to the store).
- if (!DefaultAppsSupportedForLanguage())
- return !installed_ids.empty();
-
- // For supported locales, we need to wait for all the default apps to be
- // installed before showing the apps section. We also show it if any
- // non-default app is installed (eg because the user installed the app in a
- // previous version of Chrome).
- if (GetDefaultAppsInstalled() || NonDefaultAppIsInstalled(installed_ids))
- return true;
- else
- return false;
+bool DefaultApps::CheckShouldShowPromo(const ExtensionIdSet& installed_ids) {
+#if defined(OS_CHROMEOS)
+ // Don't show the promo at all on Chrome OS.
+ return false;
#endif
-}
-
-bool DefaultApps::ShouldShowPromo(const ExtensionIdSet& installed_ids,
- bool* just_expired) {
- *just_expired = false;
-
if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kForceAppsPromoVisible)) {
return true;
}
- if (!DefaultAppSupported())
- return false;
-
- if (!GetDefaultAppsInstalled())
- return false;
-
- int promo_counter = GetPromoCounter();
- if (promo_counter <= kAppsPromoCounterMax) {
+ if (GetDefaultAppsInstalled() && GetPromoCounter() < kAppsPromoCounterMax) {
// If we have the exact set of default apps, show the promo. If we don't
// have the exact set of default apps, this means that the user manually
- // installed or uninstalled one. The promo doesn't make sense if it shows
- // apps the user manually installed, so expire it immediately in that
- // situation.
- if (ids_ != installed_ids) {
- SetPromoHidden();
- return false;
- }
-
- if (promo_counter == kAppsPromoCounterMax) {
- *just_expired = true;
- UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram,
- extension_misc::PROMO_EXPIRE,
- extension_misc::PROMO_BUCKET_BOUNDARY);
- SetPromoCounter(++promo_counter);
- return false;
- } else {
- UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram,
- extension_misc::PROMO_SEEN,
- extension_misc::PROMO_BUCKET_BOUNDARY);
- SetPromoCounter(++promo_counter);
+ // installed one. The promo doesn't make sense if it shows apps the user
+ // manually installed, so expire it immediately in that situation.
+ if (installed_ids == ids_)
return true;
- }
+ else
+ SetPromoHidden();
}
return false;
}
-void DefaultApps::DidInstallApp(const ExtensionIdSet& installed_ids) {
- // If all the default apps have been installed, stop trying to install them.
- // Note that we use std::includes here instead of == because apps might have
- // been manually installed while the the default apps were installing and we
- // wouldn't want to keep trying to install them in that case.
- if (!GetDefaultAppsInstalled() &&
- std::includes(installed_ids.begin(), installed_ids.end(),
- ids_.begin(), ids_.end())) {
- SetDefaultAppsInstalled(true);
+void DefaultApps::DidShowPromo() {
+ if (!GetDefaultAppsInstalled()) {
+ NOTREACHED() << "Should not show promo until default apps are installed.";
+ return;
}
-}
-bool DefaultApps::NonDefaultAppIsInstalled(
- const ExtensionIdSet& installed_ids) const {
- for (ExtensionIdSet::const_iterator iter = installed_ids.begin();
- iter != installed_ids.end(); ++iter) {
- if (ids_.find(*iter) == ids_.end())
- return true;
+ int promo_counter = GetPromoCounter();
+ if (promo_counter == kAppsPromoCounterMax) {
+ NOTREACHED() << "Promo has already been shown the maximum number of times.";
+ return;
}
- return false;
+ if (promo_counter < kAppsPromoCounterMax) {
+ if (promo_counter + 1 == kAppsPromoCounterMax)
+ UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppsPromoHistogram,
+ extension_misc::PROMO_EXPIRE,
+ extension_misc::PROMO_BUCKET_BOUNDARY);
+ SetPromoCounter(++promo_counter);
+ } else {
+ SetPromoHidden();
+ }
}
void DefaultApps::SetPromoHidden() {
- SetPromoCounter(kAppsPromoCounterMax + 1);
+ SetPromoCounter(kAppsPromoCounterMax);
}
int DefaultApps::GetPromoCounter() const {
diff --git a/chrome/browser/extensions/default_apps.h b/chrome/browser/extensions/default_apps.h
index 2ff8801..b03f6ec 100644
--- a/chrome/browser/extensions/default_apps.h
+++ b/chrome/browser/extensions/default_apps.h
@@ -13,60 +13,65 @@
class PrefService;
-// Encapsulates business logic for:
-// - Whether to install default apps on Chrome startup
-// - Whether to show the app launcher
-// - Whether to show the apps promo in the launcher
+// Manages the installation of the set of default apps into Chrome, and the
+// promotion of those apps in the launcher.
+//
+// It implements the following rules:
+//
+// - Only install default apps once per-profile.
+// - Don't install default apps if any apps are already installed.
+// - Do not start showing the promo until all default apps have been installed.
+// - Do not show the promo if it has been hidden by the user.
+// - Do not show promo after one app has been manually installed or uninstalled.
+// - Do not show promo if the set of installed apps is different than the set of
+// default apps.
+// - Only show promo a certain amount of times.
+//
+// The promo can also be forced on with --force-apps-promo-visible.
class DefaultApps {
public:
- // The maximum number of times to show the apps promo. The promo counter
- // actually goes up to this number + 1 because we need to differentiate
- // between the first time we overflow and subsequent times.
+ // The maximum number of times to show the apps promo.
static const int kAppsPromoCounterMax;
// Register our preferences.
static void RegisterUserPrefs(PrefService* prefs);
- explicit DefaultApps(PrefService* prefs,
- const std::string& application_locale);
+ explicit DefaultApps(PrefService* prefs);
~DefaultApps();
- // Gets the set of default apps.
- const ExtensionIdSet& default_apps() const;
+ // Gets the list of default apps that should be installed. Can return NULL if
+ // no apps need to be installed.
+ const ExtensionIdSet* GetAppsToInstall() const;
- // Returns true if the default apps should be installed.
- bool ShouldInstallDefaultApps(const ExtensionIdSet& installed_ids);
+ // Gets the list of default apps.
+ const ExtensionIdSet* GetDefaultApps() const;
- // Returns true if the app launcher in the NTP should be shown.
- bool ShouldShowAppLauncher(const ExtensionIdSet& installed_ids);
+ // Returns true if the default apps have been installed. False otherwise.
+ bool GetDefaultAppsInstalled() const;
+
+ // Should be called after each app is installed. Once installed_ids contains
+ // all the default apps, GetAppsToInstall() will start returning NULL.
+ void DidInstallApp(const ExtensionIdSet& installed_ids);
// Returns true if the apps promo should be displayed in the launcher.
//
// NOTE: If the default apps have been installed, but |installed_ids| is
// different than GetDefaultApps(), this will permanently expire the promo.
- bool ShouldShowPromo(const ExtensionIdSet& installed_ids, bool* just_expired);
+ bool CheckShouldShowPromo(const ExtensionIdSet& installed_ids);
- // Should be called after each app is installed. Once installed_ids contains
- // all the default apps, GetAppsToInstall() will start returning NULL.
- void DidInstallApp(const ExtensionIdSet& installed_ids);
+ // Should be called after each time the promo is installed.
+ void DidShowPromo();
// Force the promo to be hidden.
void SetPromoHidden();
private:
- FRIEND_TEST_ALL_PREFIXES(ExtensionDefaultApps, HappyPath);
- FRIEND_TEST_ALL_PREFIXES(ExtensionDefaultApps, UnsupportedLocale);
+ FRIEND_TEST_ALL_PREFIXES(ExtensionDefaultApps, Basics);
FRIEND_TEST_ALL_PREFIXES(ExtensionDefaultApps, HidePromo);
FRIEND_TEST_ALL_PREFIXES(ExtensionDefaultApps, InstallingAnAppHidesPromo);
FRIEND_TEST_ALL_PREFIXES(ExtensionDefaultApps,
ManualAppInstalledWhileInstallingDefaultApps);
- bool DefaultAppSupported();
- bool DefaultAppsSupportedForLanguage();
-
- bool NonDefaultAppIsInstalled(const ExtensionIdSet& installed_ids) const;
-
- bool GetDefaultAppsInstalled() const;
void SetDefaultAppsInstalled(bool val);
int GetPromoCounter() const;
@@ -75,9 +80,6 @@ class DefaultApps {
// Our permanent state is stored in this PrefService instance.
PrefService* prefs_;
- // The locale the browser is currently in.
- std::string application_locale_;
-
// The set of default extensions. Initialized to a static list in the
// constructor.
ExtensionIdSet ids_;
diff --git a/chrome/browser/extensions/default_apps_unittest.cc b/chrome/browser/extensions/default_apps_unittest.cc
index 316568d..4fa9bc2 100644
--- a/chrome/browser/extensions/default_apps_unittest.cc
+++ b/chrome/browser/extensions/default_apps_unittest.cc
@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/logging.h"
#include "chrome/browser/extensions/default_apps.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/test/testing_pref_service.h"
@@ -11,180 +10,94 @@
// TODO(dpolukhin): On Chrome OS all apps are installed via external extensions,
// and the web store promo is never shown.
#if !defined(OS_CHROMEOS)
-TEST(ExtensionDefaultApps, HappyPath) {
+TEST(ExtensionDefaultApps, Basics) {
TestingPrefService pref_service;
DefaultApps::RegisterUserPrefs(&pref_service);
- DefaultApps default_apps(&pref_service, "en-US");
+ DefaultApps default_apps(&pref_service);
- const ExtensionIdSet& default_app_ids = default_apps.default_apps();
+ ExtensionIdSet default_app_ids = *default_apps.GetAppsToInstall();
ASSERT_GT(default_app_ids.size(), 0u);
EXPECT_FALSE(default_apps.GetDefaultAppsInstalled());
EXPECT_EQ(0, default_apps.GetPromoCounter());
-
- // If no apps are installed, the default apps should be installed.
- ExtensionIdSet installed_app_ids;
- EXPECT_TRUE(default_apps.ShouldInstallDefaultApps(installed_app_ids));
-
- // The launcher should not be shown until the default apps have been
- // installed.
- EXPECT_FALSE(default_apps.ShouldShowAppLauncher(installed_app_ids));
+ EXPECT_EQ(default_app_ids, *default_apps.GetDefaultApps());
// The promo should not be shown until the default apps have been installed.
- bool promo_just_expired = false;
- EXPECT_FALSE(default_apps.ShouldShowPromo(installed_app_ids,
- &promo_just_expired));
- EXPECT_FALSE(promo_just_expired);
+ ExtensionIdSet installed_app_ids;
+ EXPECT_FALSE(default_apps.CheckShouldShowPromo(installed_app_ids));
// Simulate installing the apps one by one and notifying default_apps after
// each intallation. Nothing should change until we have installed all the
// default apps.
- for (size_t i = 0; i < default_app_ids.size() - 1; ++i) {
- ExtensionIdSet::const_iterator iter = default_app_ids.begin();
- for (size_t j = 0; j <= i; ++j)
- ++iter;
- installed_app_ids.insert(*iter);
- default_apps.DidInstallApp(installed_app_ids);
+ ExtensionIdSet extension_id_sets[] = {
+ default_app_ids,
+ default_app_ids,
+ default_app_ids
+ };
+ extension_id_sets[0].clear();
+ extension_id_sets[1].erase(extension_id_sets[1].begin());
+ extension_id_sets[2].erase(extension_id_sets[2].begin(),
+ ++extension_id_sets[2].begin());
+ for (size_t i = 0; i < arraysize(extension_id_sets); ++i) {
+ default_apps.DidInstallApp(extension_id_sets[i]);
+ EXPECT_TRUE(default_app_ids == *default_apps.GetAppsToInstall());
EXPECT_FALSE(default_apps.GetDefaultAppsInstalled());
- EXPECT_TRUE(default_apps.ShouldInstallDefaultApps(installed_app_ids));
- EXPECT_FALSE(default_apps.ShouldShowAppLauncher(installed_app_ids));
- EXPECT_FALSE(default_apps.ShouldShowPromo(installed_app_ids,
- &promo_just_expired));
- EXPECT_FALSE(promo_just_expired);
+ EXPECT_FALSE(default_apps.CheckShouldShowPromo(extension_id_sets[i]));
}
// Simulate all the default apps being installed. Now we should stop getting
// default apps to install.
- installed_app_ids = default_app_ids;
- default_apps.DidInstallApp(installed_app_ids);
+ default_apps.DidInstallApp(default_app_ids);
+ EXPECT_EQ(NULL, default_apps.GetAppsToInstall());
EXPECT_TRUE(default_apps.GetDefaultAppsInstalled());
- EXPECT_FALSE(default_apps.ShouldInstallDefaultApps(installed_app_ids));
- // And the promo and launcher should become available.
- EXPECT_TRUE(default_apps.ShouldShowAppLauncher(installed_app_ids));
- EXPECT_TRUE(default_apps.ShouldShowPromo(installed_app_ids,
- &promo_just_expired));
- EXPECT_FALSE(promo_just_expired);
+ // And the promo should become available.
+ EXPECT_TRUE(default_apps.CheckShouldShowPromo(default_app_ids));
// The promo should be available up to the max allowed times, then stop.
- // We start counting at 1 because of the call to ShouldShowPromo() above.
- for (int i = 1; i < DefaultApps::kAppsPromoCounterMax; ++i) {
- EXPECT_TRUE(default_apps.ShouldShowPromo(installed_app_ids,
- &promo_just_expired));
- EXPECT_FALSE(promo_just_expired);
+ for (int i = 0; i < DefaultApps::kAppsPromoCounterMax; ++i) {
+ EXPECT_TRUE(default_apps.CheckShouldShowPromo(default_app_ids));
+ default_apps.DidShowPromo();
EXPECT_EQ(i + 1, default_apps.GetPromoCounter());
}
-
- // The first time, should_show_promo should flip to true, then back to false.
- EXPECT_FALSE(default_apps.ShouldShowPromo(installed_app_ids,
- &promo_just_expired));
- EXPECT_TRUE(promo_just_expired);
- EXPECT_EQ(DefaultApps::kAppsPromoCounterMax + 1,
- default_apps.GetPromoCounter());
-
- // Even if all the apps are subsequently removed, the apps section should
- // remain.
- installed_app_ids.clear();
- EXPECT_FALSE(default_apps.ShouldInstallDefaultApps(installed_app_ids));
- EXPECT_TRUE(default_apps.ShouldShowAppLauncher(installed_app_ids));
- EXPECT_FALSE(default_apps.ShouldShowPromo(installed_app_ids,
- &promo_just_expired));
- EXPECT_FALSE(promo_just_expired);
- EXPECT_EQ(DefaultApps::kAppsPromoCounterMax + 1,
- default_apps.GetPromoCounter());
-}
-
-TEST(ExtensionDefaultApps, UnsupportedLocale) {
- TestingPrefService pref_service;
- DefaultApps::RegisterUserPrefs(&pref_service);
- DefaultApps default_apps(&pref_service, "fr");
-
- const ExtensionIdSet& default_app_ids = default_apps.default_apps();
- EXPECT_GT(default_app_ids.size(), 0u);
-
- // Since the store only supports en-US at the moment, we don't install default
- // apps or promote the store.
- ExtensionIdSet installed_ids;
- EXPECT_FALSE(default_apps.ShouldInstallDefaultApps(installed_ids));
- EXPECT_FALSE(default_apps.ShouldShowAppLauncher(installed_ids));
-
- bool promo_just_expired = false;
- EXPECT_FALSE(default_apps.ShouldShowPromo(installed_ids,
- &promo_just_expired));
- EXPECT_FALSE(promo_just_expired);
-
- // If the user installs an app manually, then we show the apps section, but
- // no promotion or default apps.
- installed_ids.insert(*(default_app_ids.begin()));
- EXPECT_FALSE(default_apps.ShouldInstallDefaultApps(installed_ids));
- EXPECT_TRUE(default_apps.ShouldShowAppLauncher(installed_ids));
- EXPECT_FALSE(default_apps.ShouldShowPromo(installed_ids,
- &promo_just_expired));
- EXPECT_FALSE(promo_just_expired);
-
- // Even if the user installs the exact set of default apps, we don't show the
- // promo.
- installed_ids = default_app_ids;
- EXPECT_FALSE(default_apps.ShouldInstallDefaultApps(installed_ids));
- EXPECT_TRUE(default_apps.ShouldShowAppLauncher(installed_ids));
- EXPECT_FALSE(default_apps.ShouldShowPromo(installed_ids,
- &promo_just_expired));
- EXPECT_FALSE(promo_just_expired);
-
- // If the user uninstalls the apps again, we go back to not showing the
- // apps section.
- installed_ids.clear();
- EXPECT_FALSE(default_apps.ShouldInstallDefaultApps(installed_ids));
- EXPECT_FALSE(default_apps.ShouldShowAppLauncher(installed_ids));
- EXPECT_FALSE(default_apps.ShouldShowPromo(installed_ids,
- &promo_just_expired));
- EXPECT_FALSE(promo_just_expired);
+ EXPECT_FALSE(default_apps.CheckShouldShowPromo(default_app_ids));
+ EXPECT_EQ(DefaultApps::kAppsPromoCounterMax, default_apps.GetPromoCounter());
}
TEST(ExtensionDefaultApps, HidePromo) {
TestingPrefService pref_service;
DefaultApps::RegisterUserPrefs(&pref_service);
- DefaultApps default_apps(&pref_service, "en-US");
+ DefaultApps default_apps(&pref_service);
- const ExtensionIdSet& default_app_ids = default_apps.default_apps();
+ ExtensionIdSet default_app_ids = *default_apps.GetAppsToInstall();
default_apps.DidInstallApp(default_app_ids);
- bool promo_just_expired = false;
- EXPECT_TRUE(default_apps.ShouldShowPromo(default_app_ids,
- &promo_just_expired));
- EXPECT_FALSE(promo_just_expired);
+ EXPECT_TRUE(default_apps.CheckShouldShowPromo(default_app_ids));
+ default_apps.DidShowPromo();
EXPECT_EQ(1, default_apps.GetPromoCounter());
default_apps.SetPromoHidden();
- EXPECT_FALSE(default_apps.ShouldShowPromo(default_app_ids,
- &promo_just_expired));
- EXPECT_FALSE(promo_just_expired);
- EXPECT_EQ(DefaultApps::kAppsPromoCounterMax + 1,
- default_apps.GetPromoCounter());
+ EXPECT_FALSE(default_apps.CheckShouldShowPromo(default_app_ids));
+ EXPECT_EQ(DefaultApps::kAppsPromoCounterMax, default_apps.GetPromoCounter());
}
TEST(ExtensionDefaultApps, InstallingAnAppHidesPromo) {
TestingPrefService pref_service;
DefaultApps::RegisterUserPrefs(&pref_service);
- DefaultApps default_apps(&pref_service, "en-US");
+ DefaultApps default_apps(&pref_service);
- const ExtensionIdSet& default_app_ids = default_apps.default_apps();
+ ExtensionIdSet default_app_ids = *default_apps.GetAppsToInstall();
ExtensionIdSet installed_app_ids = default_app_ids;
default_apps.DidInstallApp(installed_app_ids);
- bool promo_just_expired = false;
- EXPECT_TRUE(default_apps.ShouldShowPromo(installed_app_ids,
- &promo_just_expired));
- EXPECT_FALSE(promo_just_expired);
+ EXPECT_TRUE(default_apps.CheckShouldShowPromo(installed_app_ids));
+ default_apps.DidShowPromo();
EXPECT_EQ(1, default_apps.GetPromoCounter());
// Now simulate a new extension being installed. This should cause the promo
// to be hidden.
installed_app_ids.insert("foo");
- EXPECT_FALSE(default_apps.ShouldShowPromo(installed_app_ids,
- &promo_just_expired));
- EXPECT_FALSE(promo_just_expired);
- EXPECT_EQ(DefaultApps::kAppsPromoCounterMax + 1,
- default_apps.GetPromoCounter());
+ EXPECT_FALSE(default_apps.CheckShouldShowPromo(installed_app_ids));
+ EXPECT_EQ(DefaultApps::kAppsPromoCounterMax, default_apps.GetPromoCounter());
}
TEST(ExtensionDefaultApps, ManualAppInstalledWhileInstallingDefaultApps) {
@@ -198,39 +111,27 @@ TEST(ExtensionDefaultApps, ManualAppInstalledWhileInstallingDefaultApps) {
// the default ones.
TestingPrefService pref_service;
DefaultApps::RegisterUserPrefs(&pref_service);
- DefaultApps default_apps(&pref_service, "en-US");
+ DefaultApps default_apps(&pref_service);
// Simulate an app getting installed before the complete set of default apps.
- // This should stop the default apps from trying to be installed. The launcher
- // should also immediately show up.
+ // This shouldn't affect us installing default apps. We should keep trying.
ExtensionIdSet installed_ids;
installed_ids.insert("foo");
- EXPECT_FALSE(default_apps.ShouldInstallDefaultApps(installed_ids));
+ default_apps.DidInstallApp(installed_ids);
+ EXPECT_FALSE(default_apps.GetDefaultAppsInstalled());
+ EXPECT_TRUE(default_apps.GetAppsToInstall());
+
+ // Now add all the default apps in addition to the extra app. We should stop
+ // trying to install default apps.
+ installed_ids = *default_apps.GetAppsToInstall();
+ installed_ids.insert("foo");
+ default_apps.DidInstallApp(installed_ids);
EXPECT_TRUE(default_apps.GetDefaultAppsInstalled());
- EXPECT_TRUE(default_apps.ShouldShowAppLauncher(installed_ids));
+ EXPECT_FALSE(default_apps.GetAppsToInstall());
// The promo shouldn't turn on though, because it would look weird with the
// user's extra, manually installed extensions.
- bool promo_just_expired = false;
- EXPECT_FALSE(default_apps.ShouldShowPromo(installed_ids,
- &promo_just_expired));
- EXPECT_FALSE(promo_just_expired);
- EXPECT_EQ(DefaultApps::kAppsPromoCounterMax + 1,
- default_apps.GetPromoCounter());
-
- // Going back to a subset of the default apps shouldn't allow the default app
- // install to continue.
- installed_ids.clear();
- EXPECT_FALSE(default_apps.ShouldInstallDefaultApps(installed_ids));
- EXPECT_TRUE(default_apps.GetDefaultAppsInstalled());
- EXPECT_TRUE(default_apps.ShouldShowAppLauncher(installed_ids));
- EXPECT_FALSE(default_apps.ShouldShowPromo(installed_ids,
- &promo_just_expired));
- EXPECT_FALSE(promo_just_expired);
-
- // Going to the exact set of default apps shouldn't show the promo.
- EXPECT_FALSE(default_apps.ShouldShowPromo(default_apps.default_apps(),
- &promo_just_expired));
- EXPECT_FALSE(promo_just_expired);
+ EXPECT_FALSE(default_apps.CheckShouldShowPromo(installed_ids));
+ EXPECT_EQ(DefaultApps::kAppsPromoCounterMax, default_apps.GetPromoCounter());
}
#endif // OS_CHROMEOS
diff --git a/chrome/browser/extensions/execute_code_in_tab_function.cc b/chrome/browser/extensions/execute_code_in_tab_function.cc
index 1659af3..b3bfee0 100644
--- a/chrome/browser/extensions/execute_code_in_tab_function.cc
+++ b/chrome/browser/extensions/execute_code_in_tab_function.cc
@@ -9,12 +9,12 @@
#include "base/utf_string_conversions.h"
#include "chrome/browser/extensions/extension_tabs_module.h"
#include "chrome/browser/extensions/extension_tabs_module_constants.h"
-#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/file_reader.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
-#include "chrome/browser/tab_contents_wrapper.h"
#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/extensions/extension_error_utils.h"
diff --git a/chrome/browser/extensions/extension_accessibility_api.cc b/chrome/browser/extensions/extension_accessibility_api.cc
index 3dd0345..fa0ee0e 100644
--- a/chrome/browser/extensions/extension_accessibility_api.cc
+++ b/chrome/browser/extensions/extension_accessibility_api.cc
@@ -14,8 +14,8 @@
#include "chrome/browser/extensions/extension_accessibility_api_constants.h"
#include "chrome/browser/extensions/extension_event_router.h"
#include "chrome/browser/extensions/extension_function_dispatcher.h"
-#include "chrome/browser/extensions/extensions_service.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/notification_service.h"
diff --git a/chrome/browser/extensions/extension_apitest.cc b/chrome/browser/extensions/extension_apitest.cc
index f65d8eb..dbb47cd 100644
--- a/chrome/browser/extensions/extension_apitest.cc
+++ b/chrome/browser/extensions/extension_apitest.cc
@@ -7,8 +7,8 @@
#include "base/string_util.h"
#include "base/stringprintf.h"
#include "chrome/browser/extensions/extension_test_api.h"
-#include "chrome/browser/extensions/extensions_service.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/notification_registrar.h"
#include "chrome/test/ui_test_utils.h"
@@ -143,7 +143,7 @@ bool ExtensionApiTest::RunExtensionTestImpl(const char* extension_name,
DCHECK(!std::string(extension_name).empty()) <<
"Relative page_url given with no extension_name";
- ExtensionsService* service = browser()->profile()->GetExtensionsService();
+ ExtensionService* service = browser()->profile()->GetExtensionService();
const Extension* extension =
service->GetExtensionById(last_loaded_extension_id_, false);
if (!extension)
@@ -166,7 +166,7 @@ bool ExtensionApiTest::RunExtensionTestImpl(const char* extension_name,
// Test that exactly one extension loaded.
const Extension* ExtensionApiTest::GetSingleLoadedExtension() {
- ExtensionsService* service = browser()->profile()->GetExtensionsService();
+ ExtensionService* service = browser()->profile()->GetExtensionService();
int found_extension_index = -1;
for (size_t i = 0; i < service->extensions()->size(); ++i) {
diff --git a/chrome/browser/extensions/extension_apitest.h b/chrome/browser/extensions/extension_apitest.h
index b2079a6..4f76d28 100644
--- a/chrome/browser/extensions/extension_apitest.h
+++ b/chrome/browser/extensions/extension_apitest.h
@@ -11,7 +11,6 @@
#include "base/values.h"
#include "chrome/browser/extensions/extension_browsertest.h"
-#include "chrome/common/notification_service.h"
class Extension;
diff --git a/chrome/browser/extensions/extension_bookmark_manager_api.cc b/chrome/browser/extensions/extension_bookmark_manager_api.cc
index cc38ad1..67963b2 100644
--- a/chrome/browser/extensions/extension_bookmark_manager_api.cc
+++ b/chrome/browser/extensions/extension_bookmark_manager_api.cc
@@ -18,7 +18,7 @@
#include "chrome/browser/extensions/extension_bookmarks_module_constants.h"
#include "chrome/browser/extensions/extension_dom_ui.h"
#include "chrome/browser/extensions/extension_event_router.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "grit/generated_resources.h"
diff --git a/chrome/browser/extensions/extension_bookmarks_module.cc b/chrome/browser/extensions/extension_bookmarks_module.cc
index f805a1e..180a5bb 100644
--- a/chrome/browser/extensions/extension_bookmarks_module.cc
+++ b/chrome/browser/extensions/extension_bookmarks_module.cc
@@ -22,7 +22,7 @@
#include "chrome/browser/importer/importer.h"
#include "chrome/browser/importer/importer_data_types.h"
#include "chrome/browser/prefs/pref_service.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/pref_names.h"
@@ -75,7 +75,7 @@ void BookmarksFunction::Observe(NotificationType type,
}
// static
-ExtensionBookmarkEventRouter* ExtensionBookmarkEventRouter::GetSingleton() {
+ExtensionBookmarkEventRouter* ExtensionBookmarkEventRouter::GetInstance() {
return Singleton<ExtensionBookmarkEventRouter>::get();
}
diff --git a/chrome/browser/extensions/extension_bookmarks_module.h b/chrome/browser/extensions/extension_bookmarks_module.h
index e8e91a1..21b9ad8 100644
--- a/chrome/browser/extensions/extension_bookmarks_module.h
+++ b/chrome/browser/extensions/extension_bookmarks_module.h
@@ -21,7 +21,7 @@
// the extension system.
class ExtensionBookmarkEventRouter : public BookmarkModelObserver {
public:
- static ExtensionBookmarkEventRouter* GetSingleton();
+ static ExtensionBookmarkEventRouter* GetInstance();
virtual ~ExtensionBookmarkEventRouter();
// Call this for each model to observe. Safe to call multiple times per
@@ -179,8 +179,9 @@ class BookmarksIOFunction : public BookmarksFunction,
// Overridden from SelectFileDialog::Listener:
virtual void FileSelected(const FilePath& path, int index, void* params) = 0;
- void MultiFilesSelected(const std::vector<FilePath>& files, void* params);
- void FileSelectionCanceled(void* params);
+ virtual void MultiFilesSelected(const std::vector<FilePath>& files,
+ void* params);
+ virtual void FileSelectionCanceled(void* params);
void SelectFile(SelectFileDialog::Type type);
protected:
@@ -190,8 +191,8 @@ class BookmarksIOFunction : public BookmarksFunction,
class ImportBookmarksFunction : public BookmarksIOFunction {
public:
// Override BookmarkManagerIOFunction.
- bool RunImpl();
- void FileSelected(const FilePath& path, int index, void* params);
+ virtual bool RunImpl();
+ virtual void FileSelected(const FilePath& path, int index, void* params);
private:
DECLARE_EXTENSION_FUNCTION_NAME("bookmarks.import");
@@ -200,8 +201,8 @@ class ImportBookmarksFunction : public BookmarksIOFunction {
class ExportBookmarksFunction : public BookmarksIOFunction {
public:
// Override BookmarkManagerIOFunction.
- bool RunImpl();
- void FileSelected(const FilePath& path, int index, void* params);
+ virtual bool RunImpl();
+ virtual void FileSelected(const FilePath& path, int index, void* params);
private:
DECLARE_EXTENSION_FUNCTION_NAME("bookmarks.export");
diff --git a/chrome/browser/extensions/extension_browser_event_router.cc b/chrome/browser/extensions/extension_browser_event_router.cc
index b49c1a9..6df9ede 100644
--- a/chrome/browser/extensions/extension_browser_event_router.cc
+++ b/chrome/browser/extensions/extension_browser_event_router.cc
@@ -10,13 +10,12 @@
#include "chrome/browser/extensions/extension_event_router.h"
#include "chrome/browser/extensions/extension_page_actions_module_constants.h"
#include "chrome/browser/extensions/extension_tabs_module_constants.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tab_contents/navigation_entry.h"
#include "chrome/browser/tab_contents/tab_contents.h"
-#include "chrome/browser/tab_contents_wrapper.h"
-#include "chrome/browser/tab_contents_wrapper.h"
#include "chrome/browser/tabs/tab_strip_model.h"
#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/notification_service.h"
diff --git a/chrome/browser/extensions/extension_browser_event_router.h b/chrome/browser/extensions/extension_browser_event_router.h
index e951290..cdf2efe 100644
--- a/chrome/browser/extensions/extension_browser_event_router.h
+++ b/chrome/browser/extensions/extension_browser_event_router.h
@@ -92,9 +92,9 @@ class ExtensionBrowserEventRouter : public TabStripModelObserver,
Browser* browser);
// NotificationObserver.
- void Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details);
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
private:
// "Synthetic" event. Called from TabInsertedAt if new tab is detected.
void TabCreatedAt(TabContents* contents, int index, bool foreground);
diff --git a/chrome/browser/extensions/extension_browsertest.cc b/chrome/browser/extensions/extension_browsertest.cc
index ae90a66..8178848 100644
--- a/chrome/browser/extensions/extension_browsertest.cc
+++ b/chrome/browser/extensions/extension_browsertest.cc
@@ -15,10 +15,10 @@
#include "chrome/browser/extensions/extension_error_reporter.h"
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extension_install_ui.h"
-#include "chrome/browser/extensions/extensions_service.h"
-#include "chrome/browser/location_bar.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/omnibox/location_bar.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/notification_registrar.h"
@@ -46,7 +46,7 @@ void ExtensionBrowserTest::SetUpCommandLine(CommandLine* command_line) {
#if defined(OS_CHROMEOS)
// This makes sure that we create the Default profile first, with no
- // ExtensionsService and then the real profile with one, as we do when
+ // ExtensionService and then the real profile with one, as we do when
// running on chromeos.
command_line->AppendSwitchASCII(switches::kLoginUser,
"TestUser@gmail.com");
@@ -57,7 +57,7 @@ void ExtensionBrowserTest::SetUpCommandLine(CommandLine* command_line) {
bool ExtensionBrowserTest::LoadExtensionImpl(const FilePath& path,
bool incognito_enabled) {
- ExtensionsService* service = browser()->profile()->GetExtensionsService();
+ ExtensionService* service = browser()->profile()->GetExtensionService();
{
NotificationRegistrar registrar;
registrar.Add(this, NotificationType::EXTENSION_LOADED,
@@ -124,7 +124,7 @@ bool ExtensionBrowserTest::InstallOrUpdateExtension(const std::string& id,
const FilePath& path,
InstallUIType ui_type,
int expected_change) {
- ExtensionsService* service = browser()->profile()->GetExtensionsService();
+ ExtensionService* service = browser()->profile()->GetExtensionService();
service->set_show_extensions_prompts(false);
size_t num_before = service->extensions()->size();
@@ -174,7 +174,7 @@ bool ExtensionBrowserTest::InstallOrUpdateExtension(const std::string& id,
}
void ExtensionBrowserTest::ReloadExtension(const std::string& extension_id) {
- ExtensionsService* service = browser()->profile()->GetExtensionsService();
+ ExtensionService* service = browser()->profile()->GetExtensionService();
service->ReloadExtension(extension_id);
ui_test_utils::RegisterAndWait(this,
NotificationType::EXTENSION_LOADED,
@@ -182,22 +182,22 @@ void ExtensionBrowserTest::ReloadExtension(const std::string& extension_id) {
}
void ExtensionBrowserTest::UnloadExtension(const std::string& extension_id) {
- ExtensionsService* service = browser()->profile()->GetExtensionsService();
- service->UnloadExtension(extension_id);
+ ExtensionService* service = browser()->profile()->GetExtensionService();
+ service->UnloadExtension(extension_id, UnloadedExtensionInfo::DISABLE);
}
void ExtensionBrowserTest::UninstallExtension(const std::string& extension_id) {
- ExtensionsService* service = browser()->profile()->GetExtensionsService();
+ ExtensionService* service = browser()->profile()->GetExtensionService();
service->UninstallExtension(extension_id, false);
}
void ExtensionBrowserTest::DisableExtension(const std::string& extension_id) {
- ExtensionsService* service = browser()->profile()->GetExtensionsService();
+ ExtensionService* service = browser()->profile()->GetExtensionService();
service->DisableExtension(extension_id);
}
void ExtensionBrowserTest::EnableExtension(const std::string& extension_id) {
- ExtensionsService* service = browser()->profile()->GetExtensionsService();
+ ExtensionService* service = browser()->profile()->GetExtensionService();
service->EnableExtension(extension_id);
}
@@ -272,7 +272,7 @@ void ExtensionBrowserTest::WaitForExtensionLoad() {
bool ExtensionBrowserTest::WaitForExtensionCrash(
const std::string& extension_id) {
- ExtensionsService* service = browser()->profile()->GetExtensionsService();
+ ExtensionService* service = browser()->profile()->GetExtensionService();
if (!service->GetExtensionById(extension_id, true)) {
// The extension is already unloaded, presumably due to a crash.
diff --git a/chrome/browser/extensions/extension_browsertests_misc.cc b/chrome/browser/extensions/extension_browsertests_misc.cc
index 4787fc5..df03580 100644
--- a/chrome/browser/extensions/extension_browsertests_misc.cc
+++ b/chrome/browser/extensions/extension_browsertests_misc.cc
@@ -13,18 +13,17 @@
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extension_process_manager.h"
#include "chrome/browser/extensions/extension_tabs_module.h"
-#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_updater.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/site_instance.h"
#include "chrome/browser/tab_contents/tab_contents.h"
-#include "chrome/browser/tab_contents_wrapper.h"
#include "chrome/browser/tabs/tab_strip_model.h"
#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/extensions/extension_action.h"
-#include "chrome/common/notification_service.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/ui_test_utils.h"
#include "net/base/mock_host_resolver.h"
@@ -173,6 +172,23 @@ IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, TabContents) {
EXPECT_TRUE(result);
}
+// Tests that GPU-related WebKit preferences are set for extension background
+// pages. See http://crbug.com/64512.
+IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, WebKitPrefsBackgroundPage) {
+ ASSERT_TRUE(LoadExtension(
+ test_data_dir_.AppendASCII("good").AppendASCII("Extensions")
+ .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
+ .AppendASCII("1.0.0.0")));
+
+ ExtensionProcessManager* manager =
+ browser()->profile()->GetExtensionProcessManager();
+ ExtensionHost* host = FindHostWithPath(manager, "/backgroundpage.html", 1);
+ WebPreferences prefs = host->GetWebkitPrefs();
+ ASSERT_FALSE(prefs.experimental_webgl_enabled);
+ ASSERT_FALSE(prefs.accelerated_compositing_enabled);
+ ASSERT_FALSE(prefs.accelerated_2d_canvas_enabled);
+}
+
// Tests that we can load page actions in the Omnibox.
IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, PageAction) {
ASSERT_TRUE(test_server()->Start());
@@ -252,7 +268,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, UnloadPageAction) {
IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, PageActionRefreshCrash) {
base::TimeTicks start_time = base::TimeTicks::Now();
- ExtensionsService* service = browser()->profile()->GetExtensionsService();
+ ExtensionService* service = browser()->profile()->GetExtensionService();
size_t size_before = service->extensions()->size();
@@ -321,7 +337,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSMultiRelLink) {
// Tests that tooltips of a browser action icon can be specified using UTF8.
// See http://crbug.com/25349.
IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, TitleLocalizationBrowserAction) {
- ExtensionsService* service = browser()->profile()->GetExtensionsService();
+ ExtensionService* service = browser()->profile()->GetExtensionService();
const size_t size_before = service->extensions()->size();
FilePath extension_path(test_data_dir_.AppendASCII("browsertest")
.AppendASCII("title_localized"));
@@ -344,7 +360,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, TitleLocalizationBrowserAction) {
IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, TitleLocalizationPageAction) {
ASSERT_TRUE(test_server()->Start());
- ExtensionsService* service = browser()->profile()->GetExtensionsService();
+ ExtensionService* service = browser()->profile()->GetExtensionService();
const size_t size_before = service->extensions()->size();
FilePath extension_path(test_data_dir_.AppendASCII("browsertest")
@@ -443,7 +459,7 @@ void NavigateToFeedAndValidate(net::TestServer* server,
// TODO(finnur): Implement this is a non-flaky way.
}
- ExtensionsService* service = browser->profile()->GetExtensionsService();
+ ExtensionService* service = browser->profile()->GetExtensionService();
const Extension* extension = service->extensions()->back();
std::string id = extension->id();
@@ -745,7 +761,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, MAYBE_PluginLoadUnload) {
tab->render_view_host(), L"", L"testPluginWorks()", &result));
EXPECT_FALSE(result);
- ExtensionsService* service = browser()->profile()->GetExtensionsService();
+ ExtensionService* service = browser()->profile()->GetExtensionService();
const size_t size_before = service->extensions()->size();
ASSERT_TRUE(LoadExtension(extension_dir));
EXPECT_EQ(size_before + 1, service->extensions()->size());
@@ -797,7 +813,7 @@ static const wchar_t* jscript_click_option_button =
IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, DISABLED_OptionsPage) {
// Install an extension with an options page.
ASSERT_TRUE(InstallExtension(test_data_dir_.AppendASCII("options.crx"), 1));
- ExtensionsService* service = browser()->profile()->GetExtensionsService();
+ ExtensionService* service = browser()->profile()->GetExtensionService();
const ExtensionList* extensions = service->extensions();
ASSERT_EQ(1u, extensions->size());
const Extension* extension = extensions->at(0);
diff --git a/chrome/browser/extensions/extension_clipboard_api.cc b/chrome/browser/extensions/extension_clipboard_api.cc
index f80be6b..8cde22f 100644
--- a/chrome/browser/extensions/extension_clipboard_api.cc
+++ b/chrome/browser/extensions/extension_clipboard_api.cc
@@ -9,7 +9,7 @@
#include "chrome/browser/extensions/extension_tabs_module.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/tab_contents/tab_contents.h"
-#include "chrome/browser/tab_contents_wrapper.h"
+#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/common/extensions/extension_error_utils.h"
namespace {
diff --git a/chrome/browser/extensions/extension_context_menu_api.cc b/chrome/browser/extensions/extension_context_menu_api.cc
index a004b97..78f4f03 100644
--- a/chrome/browser/extensions/extension_context_menu_api.cc
+++ b/chrome/browser/extensions/extension_context_menu_api.cc
@@ -9,8 +9,8 @@
#include "base/values.h"
#include "base/string_number_conversions.h"
#include "base/string_util.h"
-#include "chrome/browser/extensions/extensions_service.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/common/extensions/extension_error_utils.h"
const char kCheckedKey[] = "checked";
@@ -213,7 +213,7 @@ bool CreateContextMenuFunction::RunImpl() {
return false;
ExtensionMenuManager* menu_manager =
- profile()->GetExtensionsService()->menu_manager();
+ profile()->GetExtensionService()->menu_manager();
ExtensionMenuItem::ContextList contexts(ExtensionMenuItem::PAGE);
if (!ParseContexts(*properties, kContextsKey, &contexts))
@@ -268,7 +268,7 @@ bool UpdateContextMenuFunction::RunImpl() {
ExtensionMenuItem::Id item_id(profile(), extension_id(), 0);
EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &item_id.uid));
- ExtensionsService* service = profile()->GetExtensionsService();
+ ExtensionService* service = profile()->GetExtensionService();
ExtensionMenuManager* manager = service->menu_manager();
ExtensionMenuItem* item = manager->GetItemById(item_id);
if (!item || item->extension_id() != extension_id()) {
@@ -282,7 +282,7 @@ bool UpdateContextMenuFunction::RunImpl() {
EXTENSION_FUNCTION_VALIDATE(properties != NULL);
ExtensionMenuManager* menu_manager =
- profile()->GetExtensionsService()->menu_manager();
+ profile()->GetExtensionService()->menu_manager();
// Type.
ExtensionMenuItem::Type type;
@@ -334,7 +334,7 @@ bool UpdateContextMenuFunction::RunImpl() {
bool RemoveContextMenuFunction::RunImpl() {
ExtensionMenuItem::Id id(profile(), extension_id(), 0);
EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &id.uid));
- ExtensionsService* service = profile()->GetExtensionsService();
+ ExtensionService* service = profile()->GetExtensionService();
ExtensionMenuManager* manager = service->menu_manager();
ExtensionMenuItem* item = manager->GetItemById(id);
@@ -349,7 +349,7 @@ bool RemoveContextMenuFunction::RunImpl() {
}
bool RemoveAllContextMenusFunction::RunImpl() {
- ExtensionsService* service = profile()->GetExtensionsService();
+ ExtensionService* service = profile()->GetExtensionService();
ExtensionMenuManager* manager = service->menu_manager();
manager->RemoveAllContextItems(extension_id());
return true;
diff --git a/chrome/browser/extensions/extension_context_menu_browsertest.cc b/chrome/browser/extensions/extension_context_menu_browsertest.cc
index 2397aa7..fe893f9 100644
--- a/chrome/browser/extensions/extension_context_menu_browsertest.cc
+++ b/chrome/browser/extensions/extension_context_menu_browsertest.cc
@@ -3,12 +3,13 @@
// found in the LICENSE file.
#include "app/menus/menu_model.h"
+#include "base/utf_string_conversions.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/browser/extensions/extension_test_message_listener.h"
-#include "chrome/browser/extensions/extensions_service.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tab_contents/render_view_context_menu.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/ui/browser.h"
@@ -145,14 +146,14 @@ class ExtensionContextMenuBrowserTest : public ExtensionBrowserTest {
// Shortcut to return the current ExtensionMenuManager.
ExtensionMenuManager* menu_manager() {
- return browser()->profile()->GetExtensionsService()->menu_manager();
+ return browser()->profile()->GetExtensionService()->menu_manager();
}
// Returns a pointer to the currently loaded extension with |name|, or null
// if not found.
const Extension* GetExtensionNamed(std::string name) {
const ExtensionList* extensions =
- browser()->profile()->GetExtensionsService()->extensions();
+ browser()->profile()->GetExtensionService()->extensions();
ExtensionList::const_iterator i;
for (i = extensions->begin(); i != extensions->end(); ++i) {
if ((*i)->name() == name) {
diff --git a/chrome/browser/extensions/extension_context_menu_model.cc b/chrome/browser/extensions/extension_context_menu_model.cc
index 047af99..70d4189 100644
--- a/chrome/browser/extensions/extension_context_menu_model.cc
+++ b/chrome/browser/extensions/extension_context_menu_model.cc
@@ -5,11 +5,10 @@
#include "chrome/browser/extensions/extension_context_menu_model.h"
#include "base/utf_string_conversions.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_tabs_module.h"
#include "chrome/browser/prefs/pref_service.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/extensions/extension_action.h"
#include "chrome/common/extensions/extension_constants.h"
@@ -118,12 +117,12 @@ void ExtensionContextMenuModel::ExecuteCommand(int command_id) {
browser_);
break;
case HIDE: {
- ExtensionsService* extension_service = profile_->GetExtensionsService();
+ ExtensionService* extension_service = profile_->GetExtensionService();
extension_service->SetBrowserActionVisibility(extension, false);
break;
}
case DISABLE: {
- ExtensionsService* extension_service = profile_->GetExtensionsService();
+ ExtensionService* extension_service = profile_->GetExtensionService();
extension_service->DisableExtension(extension_id_);
break;
}
@@ -150,7 +149,7 @@ void ExtensionContextMenuModel::ExecuteCommand(int command_id) {
void ExtensionContextMenuModel::InstallUIProceed() {
if (GetExtension())
- profile_->GetExtensionsService()->UninstallExtension(extension_id_, false);
+ profile_->GetExtensionService()->UninstallExtension(extension_id_, false);
Release();
}
@@ -160,6 +159,6 @@ void ExtensionContextMenuModel::InstallUIAbort() {
}
const Extension* ExtensionContextMenuModel::GetExtension() const {
- ExtensionsService* extension_service = profile_->GetExtensionsService();
+ ExtensionService* extension_service = profile_->GetExtensionService();
return extension_service->GetExtensionById(extension_id_, false);
}
diff --git a/chrome/browser/extensions/extension_cookies_api.cc b/chrome/browser/extensions/extension_cookies_api.cc
index e66c4b3..0f61602 100644
--- a/chrome/browser/extensions/extension_cookies_api.cc
+++ b/chrome/browser/extensions/extension_cookies_api.cc
@@ -14,7 +14,7 @@
#include "chrome/browser/extensions/extension_cookies_api_constants.h"
#include "chrome/browser/extensions/extension_cookies_helpers.h"
#include "chrome/browser/extensions/extension_event_router.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_error_utils.h"
#include "chrome/common/net/url_request_context_getter.h"
@@ -191,7 +191,7 @@ void GetCookieFunction::GetCookieOnIOThread() {
void GetCookieFunction::RespondOnUIThread() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- net::CookieMonster::CookieList::iterator it;
+ net::CookieList::iterator it;
for (it = cookie_list_.begin(); it != cookie_list_.end(); ++it) {
// Return the first matching cookie. Relies on the fact that the
// CookieMonster returns them in canonical order (longest path, then
@@ -425,7 +425,7 @@ bool GetAllCookieStoresFunction::RunImpl() {
scoped_ptr<ListValue> original_tab_ids(new ListValue());
Profile* incognito_profile = NULL;
scoped_ptr<ListValue> incognito_tab_ids;
- if (include_incognito()) {
+ if (include_incognito() && profile()->HasOffTheRecordProfile()) {
incognito_profile = profile()->GetOffTheRecordProfile();
if (incognito_profile)
incognito_tab_ids.reset(new ListValue());
diff --git a/chrome/browser/extensions/extension_cookies_api.h b/chrome/browser/extensions/extension_cookies_api.h
index 50b922b..dc81731 100644
--- a/chrome/browser/extensions/extension_cookies_api.h
+++ b/chrome/browser/extensions/extension_cookies_api.h
@@ -106,7 +106,7 @@ class GetCookieFunction : public CookiesFunction {
GURL url_;
std::string store_id_;
scoped_refptr<URLRequestContextGetter> store_context_;
- net::CookieMonster::CookieList cookie_list_;
+ net::CookieList cookie_list_;
};
// Implements the cookies.getAll() extension function.
@@ -125,7 +125,7 @@ class GetAllCookiesFunction : public CookiesFunction {
GURL url_;
std::string store_id_;
scoped_refptr<URLRequestContextGetter> store_context_;
- net::CookieMonster::CookieList cookie_list_;
+ net::CookieList cookie_list_;
};
// Implements the cookies.set() extension function.
diff --git a/chrome/browser/extensions/extension_cookies_helpers.cc b/chrome/browser/extensions/extension_cookies_helpers.cc
index a140c8e..42e2fae 100644
--- a/chrome/browser/extensions/extension_cookies_helpers.cc
+++ b/chrome/browser/extensions/extension_cookies_helpers.cc
@@ -10,10 +10,10 @@
#include "base/values.h"
#include "chrome/browser/extensions/extension_cookies_api_constants.h"
#include "chrome/browser/extensions/extension_tabs_module.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tabs/tab_strip_model.h"
-#include "chrome/browser/tab_contents_wrapper.h"
#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/url_constants.h"
#include "googleurl/src/gurl.h"
@@ -30,7 +30,8 @@ Profile* ChooseProfileFromStoreId(const std::string& store_id,
bool include_incognito) {
DCHECK(profile);
bool allow_original = !profile->IsOffTheRecord();
- bool allow_incognito = profile->IsOffTheRecord() || include_incognito;
+ bool allow_incognito = profile->IsOffTheRecord() ||
+ (include_incognito && profile->HasOffTheRecordProfile());
if (store_id == kOriginalProfileStoreId && allow_original)
return profile->GetOriginalProfile();
if (store_id == kOffTheRecordProfileStoreId && allow_incognito)
@@ -75,7 +76,7 @@ DictionaryValue* CreateCookieStoreValue(Profile* profile,
return result;
}
-net::CookieMonster::CookieList GetCookieListFromStore(
+net::CookieList GetCookieListFromStore(
net::CookieStore* cookie_store, const GURL& url) {
DCHECK(cookie_store);
net::CookieMonster* monster = cookie_store->GetCookieMonster();
@@ -97,12 +98,12 @@ GURL GetURLFromCanonicalCookie(
}
void AppendMatchingCookiesToList(
- const net::CookieMonster::CookieList& all_cookies,
+ const net::CookieList& all_cookies,
const std::string& store_id,
const GURL& url, const DictionaryValue* details,
const Extension* extension,
ListValue* match_list) {
- net::CookieMonster::CookieList::const_iterator it;
+ net::CookieList::const_iterator it;
for (it = all_cookies.begin(); it != all_cookies.end(); ++it) {
// Ignore any cookie whose domain doesn't match the extension's
// host permissions.
diff --git a/chrome/browser/extensions/extension_cookies_helpers.h b/chrome/browser/extensions/extension_cookies_helpers.h
index 7bb33d2..18bbf8d 100644
--- a/chrome/browser/extensions/extension_cookies_helpers.h
+++ b/chrome/browser/extensions/extension_cookies_helpers.h
@@ -49,7 +49,7 @@ DictionaryValue* CreateCookieStoreValue(Profile* profile,
// Retrieves all cookies from the given cookie store corresponding to the given
// URL. If the URL is empty, all cookies in the cookie store are retrieved.
// This can only be called on the IO thread.
-net::CookieMonster::CookieList GetCookieListFromStore(
+net::CookieList GetCookieListFromStore(
net::CookieStore* cookie_store, const GURL& url);
// Constructs a URL from a cookie's information for use in checking
@@ -63,7 +63,7 @@ GURL GetURLFromCanonicalCookie(
// match list all the cookies that both match the given URL and cookie details
// and are allowed by extension host permissions.
void AppendMatchingCookiesToList(
- const net::CookieMonster::CookieList& all_cookies,
+ const net::CookieList& all_cookies,
const std::string& store_id,
const GURL& url, const DictionaryValue* details,
const Extension* extension,
diff --git a/chrome/browser/extensions/extension_cookies_unittest.cc b/chrome/browser/extensions/extension_cookies_unittest.cc
index 6665052..2aa34a3 100644
--- a/chrome/browser/extensions/extension_cookies_unittest.cc
+++ b/chrome/browser/extensions/extension_cookies_unittest.cc
@@ -42,6 +42,10 @@ class OtrTestingProfile : public TestingProfile {
return linked_profile_;
}
+ virtual bool HasOffTheRecordProfile() {
+ return (!IsOffTheRecord() && linked_profile_);
+ }
+
static void LinkProfiles(OtrTestingProfile* profile1,
OtrTestingProfile* profile2) {
profile1->set_linked_profile(profile2);
diff --git a/chrome/browser/extensions/extension_crash_recovery_browsertest.cc b/chrome/browser/extensions/extension_crash_recovery_browsertest.cc
index 898de6b..cb489a1 100644
--- a/chrome/browser/extensions/extension_crash_recovery_browsertest.cc
+++ b/chrome/browser/extensions/extension_crash_recovery_browsertest.cc
@@ -7,19 +7,21 @@
#include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extension_process_manager.h"
-#include "chrome/browser/extensions/extensions_service.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/tab_contents/infobar_delegate.h"
#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/browser/tabs/tab_strip_model.h"
#include "chrome/browser/ui/browser.h"
+#include "chrome/common/result_codes.h"
#include "chrome/test/ui_test_utils.h"
class ExtensionCrashRecoveryTest : public ExtensionBrowserTest {
protected:
- ExtensionsService* GetExtensionsService() {
- return browser()->profile()->GetExtensionsService();
+ ExtensionService* GetExtensionService() {
+ return browser()->profile()->GetExtensionService();
}
ExtensionProcessManager* GetExtensionProcessManager() {
@@ -50,9 +52,9 @@ class ExtensionCrashRecoveryTest : public ExtensionBrowserTest {
}
void CrashExtension(size_t index) {
- ASSERT_LT(index, GetExtensionsService()->extensions()->size());
+ ASSERT_LT(index, GetExtensionService()->extensions()->size());
const Extension* extension =
- GetExtensionsService()->extensions()->at(index);
+ GetExtensionService()->extensions()->at(index);
ASSERT_TRUE(extension);
std::string extension_id(extension->id());
ExtensionHost* extension_host =
@@ -61,17 +63,16 @@ class ExtensionCrashRecoveryTest : public ExtensionBrowserTest {
RenderProcessHost* extension_rph =
extension_host->render_view_host()->process();
- base::KillProcess(extension_rph->GetHandle(),
- base::PROCESS_END_KILLED_BY_USER, false);
+ base::KillProcess(extension_rph->GetHandle(), ResultCodes::KILLED, false);
ASSERT_TRUE(WaitForExtensionCrash(extension_id));
ASSERT_FALSE(
GetExtensionProcessManager()->GetBackgroundHostForExtension(extension));
}
void CheckExtensionConsistency(size_t index) {
- ASSERT_LT(index, GetExtensionsService()->extensions()->size());
+ ASSERT_LT(index, GetExtensionService()->extensions()->size());
const Extension* extension =
- GetExtensionsService()->extensions()->at(index);
+ GetExtensionService()->extensions()->at(index);
ASSERT_TRUE(extension);
ExtensionHost* extension_host =
GetExtensionProcessManager()->GetBackgroundHostForExtension(extension);
@@ -84,21 +85,21 @@ class ExtensionCrashRecoveryTest : public ExtensionBrowserTest {
void LoadTestExtension() {
ExtensionBrowserTest::SetUpInProcessBrowserTestFixture();
- const size_t size_before = GetExtensionsService()->extensions()->size();
+ const size_t size_before = GetExtensionService()->extensions()->size();
ASSERT_TRUE(LoadExtension(
test_data_dir_.AppendASCII("common").AppendASCII("background_page")));
- const Extension* extension = GetExtensionsService()->extensions()->back();
+ const Extension* extension = GetExtensionService()->extensions()->back();
ASSERT_TRUE(extension);
first_extension_id_ = extension->id();
CheckExtensionConsistency(size_before);
}
void LoadSecondExtension() {
- int offset = GetExtensionsService()->extensions()->size();
+ int offset = GetExtensionService()->extensions()->size();
ASSERT_TRUE(LoadExtension(
test_data_dir_.AppendASCII("install").AppendASCII("install")));
const Extension* extension =
- GetExtensionsService()->extensions()->at(offset);
+ GetExtensionService()->extensions()->at(offset);
ASSERT_TRUE(extension);
second_extension_id_ = extension->id();
CheckExtensionConsistency(offset);
@@ -109,10 +110,10 @@ class ExtensionCrashRecoveryTest : public ExtensionBrowserTest {
};
IN_PROC_BROWSER_TEST_F(ExtensionCrashRecoveryTest, Basic) {
- const size_t size_before = GetExtensionsService()->extensions()->size();
+ const size_t size_before = GetExtensionService()->extensions()->size();
LoadTestExtension();
CrashExtension(size_before);
- ASSERT_EQ(size_before, GetExtensionsService()->extensions()->size());
+ ASSERT_EQ(size_before, GetExtensionService()->extensions()->size());
AcceptCrashedExtensionInfobar(0);
SCOPED_TRACE("after clicking the infobar");
@@ -120,10 +121,10 @@ IN_PROC_BROWSER_TEST_F(ExtensionCrashRecoveryTest, Basic) {
}
IN_PROC_BROWSER_TEST_F(ExtensionCrashRecoveryTest, CloseAndReload) {
- const size_t size_before = GetExtensionsService()->extensions()->size();
+ const size_t size_before = GetExtensionService()->extensions()->size();
LoadTestExtension();
CrashExtension(size_before);
- ASSERT_EQ(size_before, GetExtensionsService()->extensions()->size());
+ ASSERT_EQ(size_before, GetExtensionService()->extensions()->size());
CancelCrashedExtensionInfobar(0);
ReloadExtension(first_extension_id_);
@@ -132,10 +133,10 @@ IN_PROC_BROWSER_TEST_F(ExtensionCrashRecoveryTest, CloseAndReload) {
}
IN_PROC_BROWSER_TEST_F(ExtensionCrashRecoveryTest, ReloadIndependently) {
- const size_t size_before = GetExtensionsService()->extensions()->size();
+ const size_t size_before = GetExtensionService()->extensions()->size();
LoadTestExtension();
CrashExtension(size_before);
- ASSERT_EQ(size_before, GetExtensionsService()->extensions()->size());
+ ASSERT_EQ(size_before, GetExtensionService()->extensions()->size());
ReloadExtension(first_extension_id_);
@@ -150,22 +151,148 @@ IN_PROC_BROWSER_TEST_F(ExtensionCrashRecoveryTest, ReloadIndependently) {
ASSERT_EQ(0, current_tab->infobar_delegate_count());
}
+IN_PROC_BROWSER_TEST_F(ExtensionCrashRecoveryTest,
+ ReloadIndependentlyChangeTabs) {
+ const size_t size_before = GetExtensionService()->extensions()->size();
+ LoadTestExtension();
+ CrashExtension(size_before);
+ ASSERT_EQ(size_before, GetExtensionService()->extensions()->size());
+
+ TabContents* original_tab = browser()->GetSelectedTabContents();
+ ASSERT_TRUE(original_tab);
+ ASSERT_EQ(1, original_tab->infobar_delegate_count());
+
+ // Open a new tab so the info bar will not be in the current tab.
+ browser()->NewTab();
+ TabContents* new_current_tab = browser()->GetSelectedTabContents();
+ ASSERT_TRUE(new_current_tab);
+ ASSERT_NE(new_current_tab, original_tab);
+ ASSERT_EQ(0, new_current_tab->infobar_delegate_count());
+
+ ReloadExtension(first_extension_id_);
+
+ SCOPED_TRACE("after reloading");
+ CheckExtensionConsistency(size_before);
+
+ // The infobar should automatically hide after the extension is successfully
+ // reloaded.
+ ASSERT_EQ(0, original_tab->infobar_delegate_count());
+}
+
+IN_PROC_BROWSER_TEST_F(ExtensionCrashRecoveryTest,
+ ReloadIndependentlyNavigatePage) {
+ const size_t size_before = GetExtensionService()->extensions()->size();
+ LoadTestExtension();
+ CrashExtension(size_before);
+ ASSERT_EQ(size_before, GetExtensionService()->extensions()->size());
+
+ TabContents* current_tab = browser()->GetSelectedTabContents();
+ ASSERT_TRUE(current_tab);
+ ASSERT_EQ(1, current_tab->infobar_delegate_count());
+
+ // Navigate to another page.
+ ui_test_utils::NavigateToURL(browser(),
+ ui_test_utils::GetTestUrl(FilePath(FilePath::kCurrentDirectory),
+ FilePath(FILE_PATH_LITERAL("title1.html"))));
+ ASSERT_EQ(1, current_tab->infobar_delegate_count());
+
+ ReloadExtension(first_extension_id_);
+
+ SCOPED_TRACE("after reloading");
+ CheckExtensionConsistency(size_before);
+
+ // The infobar should automatically hide after the extension is successfully
+ // reloaded.
+ ASSERT_EQ(0, current_tab->infobar_delegate_count());
+}
+
+IN_PROC_BROWSER_TEST_F(ExtensionCrashRecoveryTest,
+ ReloadIndependentlyTwoInfoBars) {
+ const size_t size_before = GetExtensionService()->extensions()->size();
+ LoadTestExtension();
+
+ // Open a new window so that there will be an info bar in each.
+ Browser* browser2 = CreateBrowser(browser()->profile());
+
+ CrashExtension(size_before);
+ ASSERT_EQ(size_before, GetExtensionService()->extensions()->size());
+
+ TabContents* current_tab = browser()->GetSelectedTabContents();
+ ASSERT_TRUE(current_tab);
+ ASSERT_EQ(1, current_tab->infobar_delegate_count());
+
+ TabContents* current_tab2 = browser2->GetSelectedTabContents();
+ ASSERT_TRUE(current_tab2);
+ ASSERT_EQ(1, current_tab2->infobar_delegate_count());
+
+ ReloadExtension(first_extension_id_);
+
+ SCOPED_TRACE("after reloading");
+ CheckExtensionConsistency(size_before);
+
+ // Both infobars should automatically hide after the extension is successfully
+ // reloaded.
+ ASSERT_EQ(0, current_tab->infobar_delegate_count());
+ ASSERT_EQ(0, current_tab2->infobar_delegate_count());
+}
+
+IN_PROC_BROWSER_TEST_F(ExtensionCrashRecoveryTest,
+ ReloadIndependentlyTwoInfoBarsSameBrowser) {
+ const size_t size_before = GetExtensionService()->extensions()->size();
+ LoadTestExtension();
+
+ // Open a new window so that there will be an info bar in each.
+ Browser* browser2 = CreateBrowser(browser()->profile());
+
+ CrashExtension(size_before);
+ ASSERT_EQ(size_before, GetExtensionService()->extensions()->size());
+
+ TabContents* current_tab = browser()->GetSelectedTabContents();
+ ASSERT_TRUE(current_tab);
+ ASSERT_EQ(1, current_tab->infobar_delegate_count());
+
+ TabContents* current_tab2 = browser2->GetSelectedTabContents();
+ ASSERT_TRUE(current_tab2);
+ ASSERT_EQ(1, current_tab2->infobar_delegate_count());
+
+ // Move second window into first browser so there will be multiple tabs
+ // with the info bar for the same extension in one browser.
+ TabContentsWrapper* contents =
+ browser2->tabstrip_model()->DetachTabContentsAt(0);
+ browser()->tabstrip_model()->AppendTabContents(contents, true);
+ current_tab2 = browser()->GetSelectedTabContents();
+ ASSERT_EQ(1, current_tab2->infobar_delegate_count());
+ ASSERT_NE(current_tab2, current_tab);
+
+ ReloadExtension(first_extension_id_);
+
+ SCOPED_TRACE("after reloading");
+ CheckExtensionConsistency(size_before);
+
+ // Both infobars should automatically hide after the extension is successfully
+ // reloaded.
+ ASSERT_EQ(0, current_tab2->infobar_delegate_count());
+ browser()->SelectPreviousTab();
+ ASSERT_EQ(current_tab, browser()->GetSelectedTabContents());
+ ASSERT_EQ(0, current_tab->infobar_delegate_count());
+}
+
// Make sure that when we don't do anything about the crashed extension
// and close the browser, it doesn't crash. The browser is closed implicitly
// at the end of each browser test.
IN_PROC_BROWSER_TEST_F(ExtensionCrashRecoveryTest, ShutdownWhileCrashed) {
- const size_t size_before = GetExtensionsService()->extensions()->size();
+ const size_t size_before = GetExtensionService()->extensions()->size();
LoadTestExtension();
CrashExtension(size_before);
- ASSERT_EQ(size_before, GetExtensionsService()->extensions()->size());
+ ASSERT_EQ(size_before, GetExtensionService()->extensions()->size());
}
IN_PROC_BROWSER_TEST_F(ExtensionCrashRecoveryTest, TwoExtensionsCrashFirst) {
- const size_t size_before = GetExtensionsService()->extensions()->size();
+ const size_t size_before = GetExtensionService()->extensions()->size();
LoadTestExtension();
LoadSecondExtension();
CrashExtension(size_before);
- ASSERT_EQ(size_before + 1, GetExtensionsService()->extensions()->size());
+ ASSERT_EQ(size_before + 1, GetExtensionService()->extensions()->size());
AcceptCrashedExtensionInfobar(0);
SCOPED_TRACE("after clicking the infobar");
@@ -174,11 +301,11 @@ IN_PROC_BROWSER_TEST_F(ExtensionCrashRecoveryTest, TwoExtensionsCrashFirst) {
}
IN_PROC_BROWSER_TEST_F(ExtensionCrashRecoveryTest, TwoExtensionsCrashSecond) {
- const size_t size_before = GetExtensionsService()->extensions()->size();
+ const size_t size_before = GetExtensionService()->extensions()->size();
LoadTestExtension();
LoadSecondExtension();
CrashExtension(size_before + 1);
- ASSERT_EQ(size_before + 1, GetExtensionsService()->extensions()->size());
+ ASSERT_EQ(size_before + 1, GetExtensionService()->extensions()->size());
AcceptCrashedExtensionInfobar(0);
SCOPED_TRACE("after clicking the infobar");
@@ -188,13 +315,13 @@ IN_PROC_BROWSER_TEST_F(ExtensionCrashRecoveryTest, TwoExtensionsCrashSecond) {
IN_PROC_BROWSER_TEST_F(ExtensionCrashRecoveryTest,
TwoExtensionsCrashBothAtOnce) {
- const size_t size_before = GetExtensionsService()->extensions()->size();
+ const size_t size_before = GetExtensionService()->extensions()->size();
LoadTestExtension();
LoadSecondExtension();
CrashExtension(size_before);
- ASSERT_EQ(size_before + 1, GetExtensionsService()->extensions()->size());
+ ASSERT_EQ(size_before + 1, GetExtensionService()->extensions()->size());
CrashExtension(size_before);
- ASSERT_EQ(size_before, GetExtensionsService()->extensions()->size());
+ ASSERT_EQ(size_before, GetExtensionService()->extensions()->size());
{
SCOPED_TRACE("first infobar");
@@ -211,13 +338,13 @@ IN_PROC_BROWSER_TEST_F(ExtensionCrashRecoveryTest,
}
IN_PROC_BROWSER_TEST_F(ExtensionCrashRecoveryTest, TwoExtensionsOneByOne) {
- const size_t size_before = GetExtensionsService()->extensions()->size();
+ const size_t size_before = GetExtensionService()->extensions()->size();
LoadTestExtension();
CrashExtension(size_before);
- ASSERT_EQ(size_before, GetExtensionsService()->extensions()->size());
+ ASSERT_EQ(size_before, GetExtensionService()->extensions()->size());
LoadSecondExtension();
CrashExtension(size_before);
- ASSERT_EQ(size_before, GetExtensionsService()->extensions()->size());
+ ASSERT_EQ(size_before, GetExtensionService()->extensions()->size());
{
SCOPED_TRACE("first infobar");
@@ -238,42 +365,42 @@ IN_PROC_BROWSER_TEST_F(ExtensionCrashRecoveryTest, TwoExtensionsOneByOne) {
// at the end of each browser test.
IN_PROC_BROWSER_TEST_F(ExtensionCrashRecoveryTest,
TwoExtensionsShutdownWhileCrashed) {
- const size_t size_before = GetExtensionsService()->extensions()->size();
+ const size_t size_before = GetExtensionService()->extensions()->size();
LoadTestExtension();
CrashExtension(size_before);
- ASSERT_EQ(size_before, GetExtensionsService()->extensions()->size());
+ ASSERT_EQ(size_before, GetExtensionService()->extensions()->size());
LoadSecondExtension();
CrashExtension(size_before);
- ASSERT_EQ(size_before, GetExtensionsService()->extensions()->size());
+ ASSERT_EQ(size_before, GetExtensionService()->extensions()->size());
}
IN_PROC_BROWSER_TEST_F(ExtensionCrashRecoveryTest,
TwoExtensionsIgnoreFirst) {
- const size_t size_before = GetExtensionsService()->extensions()->size();
+ const size_t size_before = GetExtensionService()->extensions()->size();
LoadTestExtension();
LoadSecondExtension();
CrashExtension(size_before);
- ASSERT_EQ(size_before + 1, GetExtensionsService()->extensions()->size());
+ ASSERT_EQ(size_before + 1, GetExtensionService()->extensions()->size());
CrashExtension(size_before);
- ASSERT_EQ(size_before, GetExtensionsService()->extensions()->size());
+ ASSERT_EQ(size_before, GetExtensionService()->extensions()->size());
CancelCrashedExtensionInfobar(0);
AcceptCrashedExtensionInfobar(1);
SCOPED_TRACE("infobars done");
- ASSERT_EQ(size_before + 1, GetExtensionsService()->extensions()->size());
+ ASSERT_EQ(size_before + 1, GetExtensionService()->extensions()->size());
CheckExtensionConsistency(size_before);
}
IN_PROC_BROWSER_TEST_F(ExtensionCrashRecoveryTest,
TwoExtensionsReloadIndependently) {
- const size_t size_before = GetExtensionsService()->extensions()->size();
+ const size_t size_before = GetExtensionService()->extensions()->size();
LoadTestExtension();
LoadSecondExtension();
CrashExtension(size_before);
- ASSERT_EQ(size_before + 1, GetExtensionsService()->extensions()->size());
+ ASSERT_EQ(size_before + 1, GetExtensionService()->extensions()->size());
CrashExtension(size_before);
- ASSERT_EQ(size_before, GetExtensionsService()->extensions()->size());
+ ASSERT_EQ(size_before, GetExtensionService()->extensions()->size());
{
SCOPED_TRACE("first: reload");
diff --git a/chrome/browser/extensions/extension_data_deleter.cc b/chrome/browser/extensions/extension_data_deleter.cc
index 14ea9a2..f98ac86 100644
--- a/chrome/browser/extensions/extension_data_deleter.cc
+++ b/chrome/browser/extensions/extension_data_deleter.cc
@@ -5,13 +5,14 @@
#include "chrome/browser/extensions/extension_data_deleter.h"
#include "chrome/browser/in_process_webkit/webkit_context.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/net/url_request_context_getter.h"
#include "net/base/cookie_monster.h"
#include "net/base/net_errors.h"
#include "webkit/database/database_util.h"
#include "webkit/database/database_tracker.h"
+#include "webkit/fileapi/sandboxed_file_system_context.h"
ExtensionDataDeleter::ExtensionDataDeleter(Profile* profile,
const GURL& extension_url) {
@@ -19,6 +20,7 @@ ExtensionDataDeleter::ExtensionDataDeleter(Profile* profile,
webkit_context_ = profile->GetWebKitContext();
database_tracker_ = profile->GetDatabaseTracker();
extension_request_context_ = profile->GetRequestContextForExtensions();
+ file_system_context_ = profile->GetFileSystemContext();
extension_url_ = extension_url;
origin_id_ =
webkit_database::DatabaseUtil::GetOriginIdentifier(extension_url_);
@@ -48,6 +50,11 @@ void ExtensionDataDeleter::StartDeleting() {
BrowserThread::FILE, FROM_HERE,
NewRunnableMethod(
this, &ExtensionDataDeleter::DeleteDatabaseOnFileThread));
+
+ BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
+ NewRunnableMethod(
+ this, &ExtensionDataDeleter::DeleteFileSystemOnFileThread));
}
void ExtensionDataDeleter::DeleteCookiesOnIOThread() {
@@ -74,3 +81,8 @@ void ExtensionDataDeleter::DeleteIndexedDBOnWebkitThread() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
webkit_context_->indexed_db_context()->DeleteIndexedDBForOrigin(origin_id_);
}
+
+void ExtensionDataDeleter::DeleteFileSystemOnFileThread() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ file_system_context_->DeleteDataForOriginOnFileThread(extension_url_);
+}
diff --git a/chrome/browser/extensions/extension_data_deleter.h b/chrome/browser/extensions/extension_data_deleter.h
index 0a535fe..960f06f 100644
--- a/chrome/browser/extensions/extension_data_deleter.h
+++ b/chrome/browser/extensions/extension_data_deleter.h
@@ -15,13 +15,17 @@ namespace webkit_database {
class DatabaseTracker;
}
+namespace fileapi {
+class SandboxedFileSystemContext;
+}
+
class Profile;
class URLRequestContextGetter;
class WebKitContext;
// A helper class that takes care of removing local storage, databases and
// cookies for a given extension. This is used by
-// ExtensionsService::ClearExtensionData() upon uninstalling an extension.
+// ExtensionService::ClearExtensionData() upon uninstalling an extension.
class ExtensionDataDeleter
: public base::RefCountedThreadSafe<ExtensionDataDeleter,
BrowserThread::DeleteOnUIThread> {
@@ -52,6 +56,10 @@ class ExtensionDataDeleter
// webkit thread.
void DeleteIndexedDBOnWebkitThread();
+ // Deletes filesystem files for the extension. May only be called on the
+ // file thread.
+ void DeleteFileSystemOnFileThread();
+
// The database context for deleting the database.
scoped_refptr<webkit_database::DatabaseTracker> database_tracker_;
@@ -67,6 +75,8 @@ class ExtensionDataDeleter
// Webkit context for accessing the DOM storage helper.
scoped_refptr<WebKitContext> webkit_context_;
+ scoped_refptr<fileapi::SandboxedFileSystemContext> file_system_context_;
+
DISALLOW_COPY_AND_ASSIGN(ExtensionDataDeleter);
};
diff --git a/chrome/browser/extensions/extension_devtools_bridge.cc b/chrome/browser/extensions/extension_devtools_bridge.cc
index 3a8f525..8394ad0 100644
--- a/chrome/browser/extensions/extension_devtools_bridge.cc
+++ b/chrome/browser/extensions/extension_devtools_bridge.cc
@@ -12,9 +12,9 @@
#include "chrome/browser/extensions/extension_devtools_manager.h"
#include "chrome/browser/extensions/extension_event_router.h"
#include "chrome/browser/extensions/extension_tabs_module.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
-#include "chrome/browser/tab_contents_wrapper.h"
+#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/common/devtools_messages.h"
ExtensionDevToolsBridge::ExtensionDevToolsBridge(int tab_id,
diff --git a/chrome/browser/extensions/extension_devtools_browsertests.cc b/chrome/browser/extensions/extension_devtools_browsertests.cc
index cc61b3d..c29a4ca 100644
--- a/chrome/browser/extensions/extension_devtools_browsertests.cc
+++ b/chrome/browser/extensions/extension_devtools_browsertests.cc
@@ -11,9 +11,9 @@
#include "chrome/browser/extensions/extension_error_reporter.h"
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extension_process_manager.h"
-#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_tabs_module.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/site_instance.h"
#include "chrome/browser/tab_contents/tab_contents.h"
@@ -21,7 +21,6 @@
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/devtools_messages.h"
-#include "chrome/common/notification_service.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/ui_test_utils.h"
#include "net/base/net_util.h"
diff --git a/chrome/browser/extensions/extension_disabled_infobar_delegate.cc b/chrome/browser/extensions/extension_disabled_infobar_delegate.cc
index 354fea9..28e0709 100644
--- a/chrome/browser/extensions/extension_disabled_infobar_delegate.cc
+++ b/chrome/browser/extensions/extension_disabled_infobar_delegate.cc
@@ -8,16 +8,16 @@
#include "app/l10n_util.h"
#include "base/utf_string_conversions.h"
-#include "chrome/browser/browser_thread.h"
#include "chrome/browser/extensions/extension_install_ui.h"
-#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/tab_contents/infobar_delegate.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/browser_list.h"
#include "chrome/common/extensions/extension_file_util.h"
#include "chrome/common/extensions/extension_resource.h"
+#include "chrome/common/notification_details.h"
#include "chrome/common/notification_registrar.h"
-#include "chrome/common/notification_service.h"
+#include "chrome/common/notification_source.h"
#include "grit/generated_resources.h"
class ExtensionDisabledDialogDelegate
@@ -25,7 +25,7 @@ class ExtensionDisabledDialogDelegate
public base::RefCountedThreadSafe<ExtensionDisabledDialogDelegate> {
public:
ExtensionDisabledDialogDelegate(Profile* profile,
- ExtensionsService* service,
+ ExtensionService* service,
const Extension* extension)
: service_(service), extension_(extension) {
AddRef(); // Balanced in Proceed or Abort.
@@ -52,7 +52,7 @@ class ExtensionDisabledDialogDelegate
// The UI for showing the install dialog when enabling.
scoped_ptr<ExtensionInstallUI> install_ui_;
- ExtensionsService* service_;
+ ExtensionService* service_;
const Extension* extension_;
};
@@ -61,7 +61,7 @@ class ExtensionDisabledInfobarDelegate
public NotificationObserver {
public:
ExtensionDisabledInfobarDelegate(TabContents* tab_contents,
- ExtensionsService* service,
+ ExtensionService* service,
const Extension* extension)
: ConfirmInfoBarDelegate(tab_contents),
tab_contents_(tab_contents),
@@ -70,7 +70,7 @@ class ExtensionDisabledInfobarDelegate
// The user might re-enable the extension in other ways, so watch for that.
registrar_.Add(this, NotificationType::EXTENSION_LOADED,
Source<Profile>(service->profile()));
- registrar_.Add(this, NotificationType::EXTENSION_UNLOADED_DISABLED,
+ registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
Source<Profile>(service->profile()));
}
virtual ~ExtensionDisabledInfobarDelegate() {
@@ -106,27 +106,34 @@ class ExtensionDisabledInfobarDelegate
const NotificationDetails& details) {
// TODO(mpcomplete): RemoveInfoBar doesn't seem to always result in us
// getting deleted.
+ const Extension* extension = NULL;
switch (type.value) {
case NotificationType::EXTENSION_LOADED:
- case NotificationType::EXTENSION_UNLOADED_DISABLED: {
- const Extension* extension = Details<const Extension>(details).ptr();
- if (extension == extension_)
- tab_contents_->RemoveInfoBar(this);
+ extension = Details<const Extension>(details).ptr();
+ break;
+ case NotificationType::EXTENSION_UNLOADED: {
+ UnloadedExtensionInfo* info =
+ Details<UnloadedExtensionInfo>(details).ptr();
+ if (info->reason == UnloadedExtensionInfo::DISABLE)
+ extension = info->extension;
break;
}
default:
NOTREACHED();
+ return;
}
+ if (extension == extension_)
+ tab_contents_->RemoveInfoBar(this);
}
private:
NotificationRegistrar registrar_;
TabContents* tab_contents_;
- ExtensionsService* service_;
+ ExtensionService* service_;
const Extension* extension_;
};
-void ShowExtensionDisabledUI(ExtensionsService* service, Profile* profile,
+void ShowExtensionDisabledUI(ExtensionService* service, Profile* profile,
const Extension* extension) {
Browser* browser = BrowserList::GetLastActiveWithProfile(profile);
if (!browser)
@@ -140,7 +147,7 @@ void ShowExtensionDisabledUI(ExtensionsService* service, Profile* profile,
tab_contents, service, extension));
}
-void ShowExtensionDisabledDialog(ExtensionsService* service, Profile* profile,
+void ShowExtensionDisabledDialog(ExtensionService* service, Profile* profile,
const Extension* extension) {
// This object manages its own lifetime.
new ExtensionDisabledDialogDelegate(profile, service, extension);
diff --git a/chrome/browser/extensions/extension_disabled_infobar_delegate.h b/chrome/browser/extensions/extension_disabled_infobar_delegate.h
index 430e652..665b0eb 100644
--- a/chrome/browser/extensions/extension_disabled_infobar_delegate.h
+++ b/chrome/browser/extensions/extension_disabled_infobar_delegate.h
@@ -7,16 +7,16 @@
#pragma once
class Extension;
-class ExtensionsService;
+class ExtensionService;
class Profile;
// Shows UI to inform the user that an extension was disabled after upgrading
// to higher permissions.
-void ShowExtensionDisabledUI(ExtensionsService* service, Profile* profile,
+void ShowExtensionDisabledUI(ExtensionService* service, Profile* profile,
const Extension* extension);
// Shows the extension install dialog.
-void ShowExtensionDisabledDialog(ExtensionsService* service, Profile* profile,
+void ShowExtensionDisabledDialog(ExtensionService* service, Profile* profile,
const Extension* extension);
#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_DISABLED_INFOBAR_DELEGATE_H_
diff --git a/chrome/browser/extensions/extension_dom_ui.cc b/chrome/browser/extensions/extension_dom_ui.cc
index faaa74b..97889d7 100644
--- a/chrome/browser/extensions/extension_dom_ui.cc
+++ b/chrome/browser/extensions/extension_dom_ui.cc
@@ -5,17 +5,17 @@
#include "chrome/browser/extensions/extension_dom_ui.h"
#include <set>
+#include <vector>
#include "net/base/file_stream.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/browser_list.h"
-#include "chrome/browser/browser_thread.h"
#include "chrome/browser/extensions/extension_bookmark_manager_api.h"
-#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/image_loading_tracker.h"
#include "chrome/browser/prefs/pref_service.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_host/render_widget_host_view.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/ui/browser.h"
@@ -64,7 +64,7 @@ class ExtensionDOMUIImageLoadingTracker : public ImageLoadingTracker::Observer {
extension_(NULL) {
// Even when the extensions service is enabled by default, it's still
// disabled in incognito mode.
- ExtensionsService* service = profile->GetExtensionsService();
+ ExtensionService* service = profile->GetExtensionService();
if (service)
extension_ = service->GetExtensionByURL(page_url);
}
@@ -125,7 +125,7 @@ const char ExtensionDOMUI::kExtensionURLOverrides[] =
ExtensionDOMUI::ExtensionDOMUI(TabContents* tab_contents, const GURL& url)
: DOMUI(tab_contents),
url_(url) {
- ExtensionsService* service = tab_contents->profile()->GetExtensionsService();
+ ExtensionService* service = tab_contents->profile()->GetExtensionService();
const Extension* extension = service->GetExtensionByURL(url);
if (!extension)
extension = service->GetExtensionByWebExtent(url);
@@ -242,7 +242,7 @@ bool ExtensionDOMUI::HandleChromeURLOverride(GURL* url, Profile* profile) {
if (!overrides || !overrides->GetList(page, &url_list))
return false;
- ExtensionsService* service = profile->GetExtensionsService();
+ ExtensionService* service = profile->GetExtensionService();
size_t i = 0;
while (i < url_list->GetSize()) {
diff --git a/chrome/browser/extensions/extension_event_router.cc b/chrome/browser/extensions/extension_event_router.cc
index 4fc48e3..0b4f799 100644
--- a/chrome/browser/extensions/extension_event_router.cc
+++ b/chrome/browser/extensions/extension_event_router.cc
@@ -10,8 +10,8 @@
#include "chrome/browser/extensions/extension_processes_api.h"
#include "chrome/browser/extensions/extension_processes_api_constants.h"
#include "chrome/browser/extensions/extension_tabs_module.h"
-#include "chrome/browser/extensions/extensions_service.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/notification_service.h"
@@ -56,7 +56,7 @@ struct ExtensionEventRouter::EventListener {
bool ExtensionEventRouter::CanCrossIncognito(Profile* profile,
const std::string& extension_id) {
const Extension* extension =
- profile->GetExtensionsService()->GetExtensionById(extension_id, false);
+ profile->GetExtensionService()->GetExtensionById(extension_id, false);
return CanCrossIncognito(profile, extension);
}
@@ -66,7 +66,7 @@ bool ExtensionEventRouter::CanCrossIncognito(Profile* profile,
// We allow the extension to see events and data from another profile iff it
// uses "spanning" behavior and it has incognito access. "split" mode
// extensions only see events for a matching profile.
- return (profile->GetExtensionsService()->IsIncognitoEnabled(extension) &&
+ return (profile->GetExtensionService()->IsIncognitoEnabled(extension) &&
!extension->incognito_split_mode());
}
@@ -168,7 +168,7 @@ void ExtensionEventRouter::DispatchEventImpl(
return;
std::set<EventListener>& listeners = it->second;
- ExtensionsService* service = profile_->GetExtensionsService();
+ ExtensionService* service = profile_->GetExtensionService();
// Send the event only to renderers that are listening for it.
for (std::set<EventListener>::iterator listener = listeners.begin();
diff --git a/chrome/browser/extensions/extension_fileapi_apitest.cc b/chrome/browser/extensions/extension_fileapi_apitest.cc
new file mode 100644
index 0000000..782a600
--- /dev/null
+++ b/chrome/browser/extensions/extension_fileapi_apitest.cc
@@ -0,0 +1,9 @@
+// Copyright (c) 2010 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/extension_apitest.h"
+
+IN_PROC_BROWSER_TEST_F(ExtensionApiTest, FileAPI) {
+ ASSERT_TRUE(RunExtensionTest("fileapi")) << message_;
+}
diff --git a/chrome/browser/extensions/extension_function.cc b/chrome/browser/extensions/extension_function.cc
index 88a6c9e..054c882 100644
--- a/chrome/browser/extensions/extension_function.cc
+++ b/chrome/browser/extensions/extension_function.cc
@@ -7,8 +7,8 @@
#include "base/json/json_writer.h"
#include "base/logging.h"
#include "chrome/browser/extensions/extension_function_dispatcher.h"
-#include "chrome/browser/extensions/extensions_service.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/profiles/profile.h"
ExtensionFunction::ExtensionFunction()
: request_id_(-1),
@@ -22,7 +22,7 @@ ExtensionFunction::~ExtensionFunction() {
}
const Extension* ExtensionFunction::GetExtension() {
- ExtensionsService* service = profile_->GetExtensionsService();
+ ExtensionService* service = profile_->GetExtensionService();
DCHECK(service);
return service->GetExtensionById(extension_id_, false);
}
diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc
index 7c86ed7..3c98cf3 100644
--- a/chrome/browser/extensions/extension_function_dispatcher.cc
+++ b/chrome/browser/extensions/extension_function_dispatcher.cc
@@ -50,10 +50,12 @@
#include "chrome/browser/extensions/extension_tts_api.h"
#include "chrome/browser/extensions/extension_webstore_private_api.h"
#include "chrome/browser/extensions/extensions_quota_service.h"
-#include "chrome/browser/extensions/extensions_service.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/metrics/user_metrics.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/renderer_host/render_view_host.h"
+#include "chrome/common/notification_service.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/render_messages_params.h"
#include "chrome/common/result_codes.h"
@@ -75,7 +77,7 @@ ExtensionFunction* NewExtensionFunction() {
// create instances of them.
class FactoryRegistry {
public:
- static FactoryRegistry* instance();
+ static FactoryRegistry* GetInstance();
FactoryRegistry() { ResetFunctions(); }
// Resets all functions to their default values.
@@ -102,7 +104,7 @@ class FactoryRegistry {
FactoryMap factories_;
};
-FactoryRegistry* FactoryRegistry::instance() {
+FactoryRegistry* FactoryRegistry::GetInstance() {
return Singleton<FactoryRegistry>::get();
}
@@ -239,6 +241,7 @@ void FactoryRegistry::ResetFunctions() {
RegisterFunction<ExtensionTtsSpeakFunction>();
RegisterFunction<ExtensionTtsStopSpeakingFunction>();
RegisterFunction<ExtensionTtsIsSpeakingFunction>();
+ RegisterFunction<ExtensionTtsSpeakCompletedFunction>();
// Clipboard.
RegisterFunction<ExecuteCopyClipboardFunction>();
@@ -325,24 +328,24 @@ ExtensionFunction* FactoryRegistry::NewFunction(const std::string& name) {
void ExtensionFunctionDispatcher::GetAllFunctionNames(
std::vector<std::string>* names) {
- FactoryRegistry::instance()->GetAllNames(names);
+ FactoryRegistry::GetInstance()->GetAllNames(names);
}
bool ExtensionFunctionDispatcher::OverrideFunction(
const std::string& name, ExtensionFunctionFactory factory) {
- return FactoryRegistry::instance()->OverrideFunction(name, factory);
+ return FactoryRegistry::GetInstance()->OverrideFunction(name, factory);
}
void ExtensionFunctionDispatcher::ResetFunctions() {
- FactoryRegistry::instance()->ResetFunctions();
+ FactoryRegistry::GetInstance()->ResetFunctions();
}
ExtensionFunctionDispatcher* ExtensionFunctionDispatcher::Create(
RenderViewHost* render_view_host,
Delegate* delegate,
const GURL& url) {
- ExtensionsService* service =
- render_view_host->process()->profile()->GetExtensionsService();
+ ExtensionService* service =
+ render_view_host->process()->profile()->GetExtensionService();
DCHECK(service);
if (!service->ExtensionBindingsAllowed(url))
@@ -387,7 +390,7 @@ ExtensionFunctionDispatcher::ExtensionFunctionDispatcher(
DOMUIFavIconSource* favicon_source = new DOMUIFavIconSource(profile_);
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
- NewRunnableMethod(Singleton<ChromeURLDataManager>::get(),
+ NewRunnableMethod(ChromeURLDataManager::GetInstance(),
&ChromeURLDataManager::AddDataSource,
make_scoped_refptr(favicon_source)));
}
@@ -444,7 +447,7 @@ Browser* ExtensionFunctionDispatcher::GetCurrentBrowser(
void ExtensionFunctionDispatcher::HandleRequest(
const ViewHostMsg_DomMessage_Params& params) {
scoped_refptr<ExtensionFunction> function(
- FactoryRegistry::instance()->NewFunction(params.name));
+ FactoryRegistry::GetInstance()->NewFunction(params.name));
function->set_dispatcher_peer(peer_);
function->set_profile(profile_);
function->set_extension_id(extension_id());
@@ -453,7 +456,7 @@ void ExtensionFunctionDispatcher::HandleRequest(
function->set_request_id(params.request_id);
function->set_has_callback(params.has_callback);
function->set_user_gesture(params.user_gesture);
- ExtensionsService* service = profile()->GetExtensionsService();
+ ExtensionService* service = profile()->GetExtensionService();
DCHECK(service);
const Extension* extension = service->GetExtensionById(extension_id(), false);
DCHECK(extension);
@@ -493,6 +496,7 @@ void ExtensionFunctionDispatcher::HandleBadMessage(ExtensionFunction* api) {
CHECK(false);
} else {
NOTREACHED();
+ UserMetrics::RecordAction(UserMetricsAction("BadMessageTerminate_EFD"));
base::KillProcess(render_view_host_->process()->GetHandle(),
ResultCodes::KILLED_BAD_MESSAGE, false);
}
diff --git a/chrome/browser/extensions/extension_history_api.cc b/chrome/browser/extensions/extension_history_api.cc
index 6c07488..5ff98e3 100644
--- a/chrome/browser/extensions/extension_history_api.cc
+++ b/chrome/browser/extensions/extension_history_api.cc
@@ -14,7 +14,7 @@
#include "chrome/browser/extensions/extension_history_api_constants.h"
#include "chrome/browser/history/history.h"
#include "chrome/browser/history/history_types.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/common/notification_type.h"
#include "chrome/common/notification_service.h"
diff --git a/chrome/browser/extensions/extension_host.cc b/chrome/browser/extensions/extension_host.cc
index 4aea841..1d60390 100644
--- a/chrome/browser/extensions/extension_host.cc
+++ b/chrome/browser/extensions/extension_host.cc
@@ -21,12 +21,11 @@
#include "chrome/browser/dom_ui/dom_ui_factory.h"
#include "chrome/browser/extensions/extension_message_service.h"
#include "chrome/browser/extensions/extension_tabs_module.h"
-#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/file_select_helper.h"
-#include "chrome/browser/message_box_handler.h"
#include "chrome/browser/platform_util.h"
#include "chrome/browser/prefs/pref_service.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/render_widget_host.h"
@@ -37,6 +36,7 @@
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tab_contents/tab_contents_view.h"
#include "chrome/browser/themes/browser_theme_provider.h"
+#include "chrome/browser/ui/app_modal_dialogs/message_box_handler.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/bindings_policy.h"
#include "chrome/common/extensions/extension.h"
@@ -66,7 +66,7 @@ bool ExtensionHost::enable_dom_automation_ = false;
// ExtensionHosts, to avoid blocking the UI.
class ExtensionHost::ProcessCreationQueue {
public:
- static ProcessCreationQueue* get() {
+ static ProcessCreationQueue* GetInstance() {
return Singleton<ProcessCreationQueue>::get();
}
@@ -155,7 +155,7 @@ ExtensionHost::~ExtensionHost() {
NotificationType::EXTENSION_HOST_DESTROYED,
Source<Profile>(profile_),
Details<ExtensionHost>(this));
- ProcessCreationQueue::get()->Remove(this);
+ ProcessCreationQueue::GetInstance()->Remove(this);
render_view_host_->Shutdown(); // deletes render_view_host
}
@@ -177,6 +177,10 @@ void ExtensionHost::CreateView(Browser* browser) {
#endif
}
+TabContents* ExtensionHost::associated_tab_contents() const {
+ return associated_tab_contents_;
+}
+
RenderProcessHost* ExtensionHost::render_process_host() const {
return render_view_host_->process();
}
@@ -197,7 +201,7 @@ void ExtensionHost::CreateRenderViewSoon(RenderWidgetHostView* host_view) {
// to defer.
CreateRenderViewNow();
} else {
- ProcessCreationQueue::get()->CreateSoon(this);
+ ProcessCreationQueue::GetInstance()->CreateSoon(this);
}
}
@@ -206,7 +210,7 @@ void ExtensionHost::CreateRenderViewNow() {
NavigateToURL(url_);
DCHECK(IsRenderViewLive());
if (is_background_page())
- profile_->GetExtensionsService()->DidCreateRenderViewForBackgroundPage(
+ profile_->GetExtensionService()->DidCreateRenderViewForBackgroundPage(
this);
}
@@ -231,7 +235,7 @@ void ExtensionHost::NavigateToURL(const GURL& url) {
url_ = url;
if (!is_background_page() &&
- !profile_->GetExtensionsService()->IsBackgroundPageReady(extension_)) {
+ !profile_->GetExtensionService()->IsBackgroundPageReady(extension_)) {
// Make sure the background page loads before any others.
registrar_.Add(this, NotificationType::EXTENSION_BACKGROUND_PAGE_READY,
Source<Extension>(extension_));
@@ -246,7 +250,7 @@ void ExtensionHost::Observe(NotificationType type,
const NotificationDetails& details) {
switch (type.value) {
case NotificationType::EXTENSION_BACKGROUND_PAGE_READY:
- DCHECK(profile_->GetExtensionsService()->
+ DCHECK(profile_->GetExtensionService()->
IsBackgroundPageReady(extension_));
NavigateToURL(url_);
break;
@@ -261,7 +265,7 @@ void ExtensionHost::Observe(NotificationType type,
// sent. NULL it out so that dirty pointer issues don't arise in cases
// when multiple ExtensionHost objects pointing to the same Extension are
// present.
- if (extension_ == Details<const Extension>(details).ptr())
+ if (extension_ == Details<UnloadedExtensionInfo>(details)->extension)
extension_ = NULL;
break;
default:
@@ -284,7 +288,9 @@ void ExtensionHost::ClearInspectorSettings() {
RenderViewHostDelegateHelper::ClearInspectorSettings(profile());
}
-void ExtensionHost::RenderViewGone(RenderViewHost* render_view_host) {
+void ExtensionHost::RenderViewGone(RenderViewHost* render_view_host,
+ base::TerminationStatus status,
+ int error_code) {
// During browser shutdown, we may use sudden termination on an extension
// process, so it is expected to lose our connection to the render view.
// Do nothing.
@@ -391,7 +397,7 @@ void ExtensionHost::DocumentAvailableInMainFrame(RenderViewHost* rvh) {
document_element_available_ = true;
if (is_background_page()) {
- profile_->GetExtensionsService()->SetBackgroundPageReady(extension_);
+ profile_->GetExtensionService()->SetBackgroundPageReady(extension_);
} else {
switch (extension_host_type_) {
case ViewType::EXTENSION_INFOBAR:
@@ -444,6 +450,14 @@ gfx::NativeWindow ExtensionHost::GetMessageBoxRootWindow() {
return NULL;
}
+TabContents* ExtensionHost::AsTabContents() {
+ return NULL;
+}
+
+ExtensionHost* ExtensionHost::AsExtensionHost() {
+ return this;
+}
+
void ExtensionHost::OnMessageBoxClosed(IPC::Message* reply_msg,
bool success,
const std::wstring& prompt) {
@@ -487,6 +501,14 @@ WebPreferences ExtensionHost::GetWebkitPrefs() {
extension_host_type_ == ViewType::EXTENSION_INFOBAR)
webkit_prefs.allow_scripts_to_close_windows = true;
+ // Disable anything that requires the GPU process for background pages.
+ // See http://crbug.com/64512 and http://crbug.com/64841.
+ if (extension_host_type_ == ViewType::EXTENSION_BACKGROUND_PAGE) {
+ webkit_prefs.experimental_webgl_enabled = false;
+ webkit_prefs.accelerated_compositing_enabled = false;
+ webkit_prefs.accelerated_2d_canvas_enabled = false;
+ }
+
// TODO(dcheng): incorporate this setting into kClipboardPermission check.
webkit_prefs.javascript_can_access_clipboard = true;
@@ -734,6 +756,10 @@ ViewType::Type ExtensionHost::GetRenderViewType() const {
return extension_host_type_;
}
+const GURL& ExtensionHost::GetURL() const {
+ return url_;
+}
+
void ExtensionHost::RenderViewCreated(RenderViewHost* render_view_host) {
if (view_.get())
view_->RenderViewCreated();
diff --git a/chrome/browser/extensions/extension_host.h b/chrome/browser/extensions/extension_host.h
index d121145..801bdab 100644
--- a/chrome/browser/extensions/extension_host.h
+++ b/chrome/browser/extensions/extension_host.h
@@ -12,13 +12,13 @@
#include "base/perftimer.h"
#include "base/scoped_ptr.h"
#include "chrome/browser/extensions/extension_function_dispatcher.h"
-#include "chrome/browser/js_modal_dialog.h"
#include "chrome/browser/renderer_host/render_view_host_delegate.h"
#include "chrome/browser/tab_contents/render_view_host_delegate_helper.h"
+#include "chrome/browser/ui/app_modal_dialogs/js_modal_dialog.h"
#if defined(TOOLKIT_VIEWS)
#include "chrome/browser/views/extensions/extension_view.h"
#elif defined(OS_MACOSX)
-#include "chrome/browser/cocoa/extension_view_mac.h"
+#include "chrome/browser/ui/cocoa/extension_view_mac.h"
#elif defined(TOOLKIT_GTK)
#include "chrome/browser/gtk/extension_view_gtk.h"
#endif
@@ -83,9 +83,7 @@ class ExtensionHost : public RenderViewHostDelegate,
ViewType::Type extension_host_type() const { return extension_host_type_; }
// ExtensionFunctionDispatcher::Delegate
- virtual TabContents* associated_tab_contents() const {
- return associated_tab_contents_;
- }
+ virtual TabContents* associated_tab_contents() const;
void set_associated_tab_contents(TabContents* associated_tab_contents) {
associated_tab_contents_ = associated_tab_contents;
}
@@ -109,12 +107,14 @@ class ExtensionHost : public RenderViewHostDelegate,
void DisableScrollbarsForSmallWindows(const gfx::Size& size_limit);
// RenderViewHostDelegate::View implementation.
- virtual const GURL& GetURL() const { return url_; }
+ virtual const GURL& GetURL() const;
virtual void RenderViewCreated(RenderViewHost* render_view_host);
virtual ViewType::Type GetRenderViewType() const;
virtual FileSelect* GetFileSelectDelegate();
virtual int GetBrowserWindowID() const;
- virtual void RenderViewGone(RenderViewHost* render_view_host);
+ virtual void RenderViewGone(RenderViewHost* render_view_host,
+ base::TerminationStatus status,
+ int error_code);
virtual void DidNavigate(RenderViewHost* render_view_host,
const ViewHostMsg_FrameNavigate_Params& params);
virtual void DidStopLoading();
@@ -192,8 +192,8 @@ class ExtensionHost : public RenderViewHostDelegate,
const std::wstring& prompt);
virtual void SetSuppressMessageBoxes(bool suppress_message_boxes) {}
virtual gfx::NativeWindow GetMessageBoxRootWindow();
- virtual TabContents* AsTabContents() { return NULL; }
- virtual ExtensionHost* AsExtensionHost() { return this; }
+ virtual TabContents* AsTabContents();
+ virtual ExtensionHost* AsExtensionHost();
protected:
// Internal functions used to support the CreateNewWidget() method. If a
diff --git a/chrome/browser/extensions/extension_host_mac.mm b/chrome/browser/extensions/extension_host_mac.mm
index d6de067..67bc851 100644
--- a/chrome/browser/extensions/extension_host_mac.mm
+++ b/chrome/browser/extensions/extension_host_mac.mm
@@ -4,10 +4,10 @@
#include "chrome/browser/extensions/extension_host_mac.h"
-#import "chrome/browser/cocoa/chrome_event_processing_window.h"
-#import "chrome/browser/cocoa/extensions/extension_popup_controller.h"
-#import "chrome/browser/cocoa/info_bubble_window.h"
#include "chrome/browser/renderer_host/render_widget_host_view_mac.h"
+#import "chrome/browser/ui/cocoa/chrome_event_processing_window.h"
+#import "chrome/browser/ui/cocoa/extensions/extension_popup_controller.h"
+#import "chrome/browser/ui/cocoa/info_bubble_window.h"
#include "chrome/common/native_web_keyboard_event.h"
ExtensionHostMac::~ExtensionHostMac() {
diff --git a/chrome/browser/extensions/extension_i18n_api.cc b/chrome/browser/extensions/extension_i18n_api.cc
index 40964a7..def4380 100644
--- a/chrome/browser/extensions/extension_i18n_api.cc
+++ b/chrome/browser/extensions/extension_i18n_api.cc
@@ -7,7 +7,7 @@
#include "base/string_piece.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/prefs/pref_service.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/common/pref_names.h"
// Errors.
diff --git a/chrome/browser/extensions/extension_idle_api.cc b/chrome/browser/extensions/extension_idle_api.cc
index 76144a4..b43e6c8 100644
--- a/chrome/browser/extensions/extension_idle_api.cc
+++ b/chrome/browser/extensions/extension_idle_api.cc
@@ -17,11 +17,11 @@
#include "chrome/browser/extensions/extension_event_router.h"
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extension_idle_api_constants.h"
-#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/extensions/extension.h"
-#include "chrome/common/notification_service.h"
namespace keys = extension_idle_api_constants;
diff --git a/chrome/browser/extensions/extension_idle_api.h b/chrome/browser/extensions/extension_idle_api.h
index d6e0c89..9f40481 100644
--- a/chrome/browser/extensions/extension_idle_api.h
+++ b/chrome/browser/extensions/extension_idle_api.h
@@ -7,9 +7,10 @@
#pragma once
#include "chrome/browser/idle.h"
-#include "chrome/browser/profile.h"
#include "chrome/browser/extensions/extension_function.h"
+class Profile;
+
// Event router class for events related to the idle API.
class ExtensionIdleEventRouter {
public:
diff --git a/chrome/browser/extensions/extension_incognito_apitest.cc b/chrome/browser/extensions/extension_incognito_apitest.cc
index 52ee7c3..315ac99 100644
--- a/chrome/browser/extensions/extension_incognito_apitest.cc
+++ b/chrome/browser/extensions/extension_incognito_apitest.cc
@@ -6,10 +6,10 @@
#include "chrome/browser/browser_window.h"
#include "chrome/browser/extensions/browser_action_test_util.h"
#include "chrome/browser/extensions/extension_apitest.h"
-#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_test_message_listener.h"
#include "chrome/browser/extensions/user_script_master.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_switches.h"
@@ -86,8 +86,8 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, IncognitoYesScript) {
// accidentially create and incognito profile.
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DontCreateIncognitoProfile) {
ASSERT_FALSE(browser()->profile()->HasOffTheRecordProfile());
- ASSERT_TRUE(
- RunExtensionTestIncognito("incognito/enumerate_tabs")) << message_;
+ ASSERT_TRUE(RunExtensionTestIncognito(
+ "incognito/dont_create_profile")) << message_;
ASSERT_FALSE(browser()->profile()->HasOffTheRecordProfile());
}
diff --git a/chrome/browser/extensions/extension_infobar_apitest.cc b/chrome/browser/extensions/extension_infobar_apitest.cc
index 5932185..0ca70c8 100644
--- a/chrome/browser/extensions/extension_infobar_apitest.cc
+++ b/chrome/browser/extensions/extension_infobar_apitest.cc
@@ -6,7 +6,7 @@
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/common/chrome_switches.h"
-#if defined(TOOLKIT_VIEWS)
+#if defined(OS_WIN)
#define MAYBE_Infobars Infobars
#else
// Need to finish port to Linux. See http://crbug.com/39916 for details.
diff --git a/chrome/browser/extensions/extension_infobar_delegate.cc b/chrome/browser/extensions/extension_infobar_delegate.cc
index 3f9b861..140a82f 100644
--- a/chrome/browser/extensions/extension_infobar_delegate.cc
+++ b/chrome/browser/extensions/extension_infobar_delegate.cc
@@ -6,9 +6,10 @@
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extension_process_manager.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/ui/browser.h"
+#include "chrome/common/extensions/extension.h"
#include "chrome/common/notification_details.h"
#include "chrome/common/notification_source.h"
#include "chrome/common/notification_type.h"
@@ -38,6 +39,10 @@ ExtensionInfoBarDelegate::~ExtensionInfoBarDelegate() {
observer_->OnDelegateDeleted();
}
+void ExtensionInfoBarDelegate::InfoBarDismissed() {
+ closing_ = true;
+}
+
bool ExtensionInfoBarDelegate::EqualsDelegate(InfoBarDelegate* delegate) const {
ExtensionInfoBarDelegate* extension_delegate =
delegate->AsExtensionInfoBarDelegate();
@@ -78,7 +83,8 @@ void ExtensionInfoBarDelegate::Observe(NotificationType type,
break;
}
case NotificationType::EXTENSION_UNLOADED: {
- const Extension* extension = Details<const Extension>(details).ptr();
+ const Extension* extension =
+ Details<UnloadedExtensionInfo>(details)->extension;
if (extension_ == extension)
tab_contents_->RemoveInfoBar(this);
break;
diff --git a/chrome/browser/extensions/extension_infobar_delegate.h b/chrome/browser/extensions/extension_infobar_delegate.h
index e929fee..f286a11 100644
--- a/chrome/browser/extensions/extension_infobar_delegate.h
+++ b/chrome/browser/extensions/extension_infobar_delegate.h
@@ -37,7 +37,7 @@ class ExtensionInfoBarDelegate : public InfoBarDelegate,
void set_observer(DelegateObserver* observer) { observer_ = observer; }
// Overridden from InfoBarDelegate:
- virtual void InfoBarDismissed() { closing_ = true; }
+ virtual void InfoBarDismissed();
virtual bool EqualsDelegate(InfoBarDelegate* delegate) const;
virtual void InfoBarClosed();
virtual InfoBar* CreateInfoBar();
diff --git a/chrome/browser/extensions/extension_infobar_module.cc b/chrome/browser/extensions/extension_infobar_module.cc
index 21d94ae..707630c 100644
--- a/chrome/browser/extensions/extension_infobar_module.cc
+++ b/chrome/browser/extensions/extension_infobar_module.cc
@@ -14,8 +14,8 @@
#include "chrome/browser/extensions/extension_tabs_module_constants.h"
#include "chrome/browser/tab_contents/infobar_delegate.h"
#include "chrome/browser/tab_contents/tab_contents.h"
-#include "chrome/browser/tab_contents_wrapper.h"
#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_error_utils.h"
#include "chrome/common/url_constants.h"
diff --git a/chrome/browser/extensions/extension_input_api.cc b/chrome/browser/extensions/extension_input_api.cc
index 850a344..cc5cb43 100644
--- a/chrome/browser/extensions/extension_input_api.cc
+++ b/chrome/browser/extensions/extension_input_api.cc
@@ -11,7 +11,6 @@
#include "chrome/browser/browser_window.h"
#include "chrome/browser/extensions/extension_tabs_module.h"
#include "chrome/browser/renderer_host/render_view_host.h"
-#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/views/frame/browser_view.h"
#include "chrome/common/native_web_keyboard_event.h"
diff --git a/chrome/browser/extensions/extension_install_ui.cc b/chrome/browser/extensions/extension_install_ui.cc
index aca3de6..391a54c 100644
--- a/chrome/browser/extensions/extension_install_ui.cc
+++ b/chrome/browser/extensions/extension_install_ui.cc
@@ -10,6 +10,7 @@
#include "app/resource_bundle.h"
#include "base/command_line.h"
#include "base/file_util.h"
+#include "base/i18n/rtl.h"
#include "base/string_number_conversions.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
@@ -17,7 +18,7 @@
#include "chrome/browser/browser_window.h"
#include "chrome/browser/extensions/theme_installed_infobar_delegate.h"
#include "chrome/browser/platform_util.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tabs/tab_strip_model.h"
#include "chrome/common/chrome_switches.h"
@@ -33,7 +34,7 @@
#include "grit/theme_resources.h"
#if defined(OS_MACOSX)
-#include "chrome/browser/cocoa/extension_installed_bubble_bridge.h"
+#include "chrome/browser/ui/cocoa/extension_installed_bubble_bridge.h"
#endif
#if defined(TOOLKIT_VIEWS)
@@ -76,22 +77,7 @@ ExtensionInstallUI::ExtensionInstallUI(Profile* profile)
extension_(NULL),
delegate_(NULL),
prompt_type_(NUM_PROMPT_TYPES),
- ALLOW_THIS_IN_INITIALIZER_LIST(tracker_(this)) {
- // Remember the current theme in case the user presses undo.
- if (profile_) {
- const Extension* previous_theme = profile_->GetTheme();
- if (previous_theme)
- previous_theme_id_ = previous_theme->id();
-#if defined(TOOLKIT_GTK)
- // On Linux, we also need to take the user's system settings into account
- // to undo theme installation.
- previous_use_system_theme_ =
- GtkThemeProvider::GetFrom(profile_)->UseGtkTheme();
-#else
- DCHECK(!previous_use_system_theme_);
-#endif
- }
-}
+ ALLOW_THIS_IN_INITIALIZER_LIST(tracker_(this)) {}
ExtensionInstallUI::~ExtensionInstallUI() {
}
@@ -106,6 +92,20 @@ void ExtensionInstallUI::ConfirmInstall(Delegate* delegate,
// immediately installed, and then we show an infobar (see OnInstallSuccess)
// to allow the user to revert if they don't like it.
if (extension->is_theme()) {
+ // Remember the current theme in case the user pressed undo.
+ const Extension* previous_theme = profile_->GetTheme();
+ if (previous_theme)
+ previous_theme_id_ = previous_theme->id();
+
+#if defined(TOOLKIT_GTK)
+ // On Linux, we also need to take the user's system settings into account
+ // to undo theme installation.
+ previous_use_system_theme_ =
+ GtkThemeProvider::GetFrom(profile_)->UseGtkTheme();
+#else
+ DCHECK(!previous_use_system_theme_);
+#endif
+
delegate->InstallUIProceed();
return;
}
@@ -296,9 +296,11 @@ void ExtensionInstallUI::ShowGenericExtensionInstalledInfoBar(
if (!tab_contents)
return;
+ string16 extension_name = UTF8ToUTF16(new_extension->name());
+ base::i18n::AdjustStringForLocaleDirection(&extension_name);
string16 msg =
l10n_util::GetStringFUTF16(IDS_EXTENSION_INSTALLED_HEADING,
- UTF8ToUTF16(new_extension->name())) +
+ extension_name) +
UTF8ToUTF16(" ") +
l10n_util::GetStringUTF16(IDS_EXTENSION_INSTALLED_MANAGE_INFO_MAC);
InfoBarDelegate* delegate = new SimpleAlertInfoBarDelegate(
diff --git a/chrome/browser/extensions/extension_install_ui_browsertest.cc b/chrome/browser/extensions/extension_install_ui_browsertest.cc
index 818c414..6866325 100644
--- a/chrome/browser/extensions/extension_install_ui_browsertest.cc
+++ b/chrome/browser/extensions/extension_install_ui_browsertest.cc
@@ -3,9 +3,9 @@
// found in the LICENSE file.
#include "chrome/browser/extensions/extension_browsertest.h"
-#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/theme_installed_infobar_delegate.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/ui_test_utils.h"
diff --git a/chrome/browser/extensions/extension_management_api.cc b/chrome/browser/extensions/extension_management_api.cc
index bcb12c6..50117c4 100644
--- a/chrome/browser/extensions/extension_management_api.cc
+++ b/chrome/browser/extensions/extension_management_api.cc
@@ -13,9 +13,9 @@
#include "base/string_util.h"
#include "chrome/browser/extensions/extension_event_names.h"
#include "chrome/browser/extensions/extension_event_router.h"
-#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_updater.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/extensions/extension_error_utils.h"
@@ -47,8 +47,8 @@ const char kNoExtensionError[] = "No extension with id *";
const char kNotAnAppError[] = "Extension * is not an App";
}
-ExtensionsService* ExtensionManagementFunction::service() {
- return profile()->GetExtensionsService();
+ExtensionService* ExtensionManagementFunction::service() {
+ return profile()->GetExtensionService();
}
static DictionaryValue* CreateExtensionInfo(const Extension& extension,
@@ -267,9 +267,14 @@ void ExtensionManagementEventRouter::Observe(
Details<UninstalledExtensionInfo>(details).ptr()->extension_id;
args.Append(Value::CreateStringValue(extension_id));
} else {
- const Extension* extension = Details<const Extension>(details).ptr();
+ const Extension* extension = NULL;
+ if (event_name == events::kOnExtensionDisabled) {
+ extension = Details<UnloadedExtensionInfo>(details)->extension;
+ } else {
+ extension = Details<const Extension>(details).ptr();
+ }
CHECK(extension);
- ExtensionsService* service = profile->GetExtensionsService();
+ ExtensionService* service = profile->GetExtensionService();
bool enabled = service->GetExtensionById(extension->id(), false) != NULL;
args.Append(CreateExtensionInfo(*extension, enabled));
}
diff --git a/chrome/browser/extensions/extension_management_api.h b/chrome/browser/extensions/extension_management_api.h
index 864741f..5349955 100644
--- a/chrome/browser/extensions/extension_management_api.h
+++ b/chrome/browser/extensions/extension_management_api.h
@@ -11,11 +11,11 @@
#include "chrome/common/notification_observer.h"
#include "chrome/common/notification_registrar.h"
-class ExtensionsService;
+class ExtensionService;
class ExtensionManagementFunction : public SyncExtensionFunction {
protected:
- ExtensionsService* service();
+ ExtensionService* service();
};
class GetAllExtensionsFunction : public ExtensionManagementFunction {
diff --git a/chrome/browser/extensions/extension_management_apitest.cc b/chrome/browser/extensions/extension_management_apitest.cc
index bdbb057..9883f5d 100644
--- a/chrome/browser/extensions/extension_management_apitest.cc
+++ b/chrome/browser/extensions/extension_management_apitest.cc
@@ -3,8 +3,8 @@
// found in the LICENSE file.
#include "chrome/browser/extensions/extension_apitest.h"
-#include "chrome/browser/extensions/extensions_service.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
class ExtensionManagementApiTest : public ExtensionApiTest {
@@ -19,7 +19,7 @@ class ExtensionManagementApiTest : public ExtensionApiTest {
ASSERT_TRUE(LoadExtension(basedir.AppendASCII("permissions")));
// Load 2 disabled items.
- ExtensionsService* service = browser()->profile()->GetExtensionsService();
+ ExtensionService* service = browser()->profile()->GetExtensionService();
ASSERT_TRUE(LoadExtension(basedir.AppendASCII("disabled_extension")));
service->DisableExtension(last_loaded_extension_id_);
ASSERT_TRUE(LoadExtension(basedir.AppendASCII("disabled_app")));
diff --git a/chrome/browser/extensions/extension_management_browsertest.cc b/chrome/browser/extensions/extension_management_browsertest.cc
index 6120c73..a1eb2f6 100644
--- a/chrome/browser/extensions/extension_management_browsertest.cc
+++ b/chrome/browser/extensions/extension_management_browsertest.cc
@@ -6,11 +6,12 @@
#include "chrome/browser/extensions/autoupdate_interceptor.h"
#include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/browser/extensions/extension_host.h"
-#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_test_message_listener.h"
#include "chrome/browser/extensions/extension_updater.h"
#include "chrome/browser/prefs/pref_service.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/prefs/scoped_pref_update.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/pref_names.h"
@@ -56,7 +57,7 @@ class ExtensionManagementTest : public ExtensionBrowserTest {
// to the second version requiring increased permissions. Returns whether
// the operation was completed successfully.
bool InstallAndUpdateIncreasingPermissionsExtension() {
- ExtensionsService* service = browser()->profile()->GetExtensionsService();
+ ExtensionService* service = browser()->profile()->GetExtensionService();
size_t size_before = service->extensions()->size();
// Install the initial version, which should happen just fine.
@@ -81,7 +82,7 @@ class ExtensionManagementTest : public ExtensionBrowserTest {
// Tests that installing the same version overwrites.
IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, InstallSameVersion) {
- ExtensionsService* service = browser()->profile()->GetExtensionsService();
+ ExtensionService* service = browser()->profile()->GetExtensionService();
const size_t size_before = service->extensions()->size();
ASSERT_TRUE(InstallExtension(
test_data_dir_.AppendASCII("install/install.crx"), 1));
@@ -99,7 +100,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, InstallSameVersion) {
}
IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, InstallOlderVersion) {
- ExtensionsService* service = browser()->profile()->GetExtensionsService();
+ ExtensionService* service = browser()->profile()->GetExtensionService();
const size_t size_before = service->extensions()->size();
ASSERT_TRUE(InstallExtension(
test_data_dir_.AppendASCII("install/install.crx"), 1));
@@ -110,7 +111,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, InstallOlderVersion) {
}
IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, InstallThenCancel) {
- ExtensionsService* service = browser()->profile()->GetExtensionsService();
+ ExtensionService* service = browser()->profile()->GetExtensionService();
const size_t size_before = service->extensions()->size();
ASSERT_TRUE(InstallExtension(
test_data_dir_.AppendASCII("install/install.crx"), 1));
@@ -137,7 +138,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, Incognito) {
// Tests the process of updating an extension to one that requires higher
// permissions.
IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, UpdatePermissions) {
- ExtensionsService* service = browser()->profile()->GetExtensionsService();
+ ExtensionService* service = browser()->profile()->GetExtensionService();
ASSERT_TRUE(InstallAndUpdateIncreasingPermissionsExtension());
const size_t size_before = service->extensions()->size();
@@ -149,7 +150,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, UpdatePermissions) {
// Tests that we can uninstall a disabled extension.
IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, UninstallDisabled) {
- ExtensionsService* service = browser()->profile()->GetExtensionsService();
+ ExtensionService* service = browser()->profile()->GetExtensionService();
ASSERT_TRUE(InstallAndUpdateIncreasingPermissionsExtension());
const size_t size_before = service->extensions()->size();
@@ -163,7 +164,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, UninstallDisabled) {
IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, DisableEnable) {
ExtensionProcessManager* manager = browser()->profile()->
GetExtensionProcessManager();
- ExtensionsService* service = browser()->profile()->GetExtensionsService();
+ ExtensionService* service = browser()->profile()->GetExtensionService();
const size_t size_before = service->extensions()->size();
// Load an extension, expect the background page to be available.
@@ -206,7 +207,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, AutoUpdate) {
// Install version 1 of the extension.
ExtensionTestMessageListener listener1("v1 installed", false);
- ExtensionsService* service = browser()->profile()->GetExtensionsService();
+ ExtensionService* service = browser()->profile()->GetExtensionService();
const size_t size_before = service->extensions()->size();
ASSERT_TRUE(service->disabled_extensions()->empty());
ASSERT_TRUE(InstallExtension(basedir.AppendASCII("v1.crx"), 1));
@@ -252,7 +253,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, AutoUpdate) {
// See http://crbug.com/57378 for flakiness details.
IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, ExternalUrlUpdate) {
- ExtensionsService* service = browser()->profile()->GetExtensionsService();
+ ExtensionService* service = browser()->profile()->GetExtensionService();
const char* kExtensionId = "ogjcoiohnmldgjemafoockdghcjciccf";
// We don't want autoupdate blacklist checks.
service->updater()->set_blacklist_checks_enabled(false);
@@ -272,7 +273,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, ExternalUrlUpdate) {
ASSERT_TRUE(service->disabled_extensions()->empty());
// The code that reads external_extensions.json uses this method to inform
- // the ExtensionsService of an extension to download. Using the real code
+ // the ExtensionService of an extension to download. Using the real code
// is race-prone, because instantating the ExtensionService starts a read
// of external_extensions.json before this test function starts.
service->AddPendingExtensionFromExternalUpdateUrl(
@@ -292,31 +293,39 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, ExternalUrlUpdate) {
UninstallExtension(kExtensionId);
- std::set<std::string> killed_ids;
- service->extension_prefs()->GetKilledExtensionIds(&killed_ids);
- EXPECT_TRUE(killed_ids.end() != killed_ids.find(kExtensionId))
+ ExtensionPrefs* extension_prefs = service->extension_prefs();
+ EXPECT_TRUE(extension_prefs->IsExtensionKilled(kExtensionId))
<< "Uninstalling should set kill bit on externaly installed extension.";
+ // Try to install the extension again from an external source. It should fail
+ // because of the killbit.
+ service->AddPendingExtensionFromExternalUpdateUrl(
+ kExtensionId, GURL("http://localhost/autoupdate/manifest"),
+ Extension::EXTERNAL_PREF_DOWNLOAD);
+ const PendingExtensionMap& pending_extensions =
+ service->pending_extensions();
+ EXPECT_TRUE(
+ pending_extensions.find(kExtensionId) == pending_extensions.end())
+ << "External reinstall of a killed extension shouldn't work.";
+ EXPECT_TRUE(extension_prefs->IsExtensionKilled(kExtensionId))
+ << "External reinstall of a killed extension should leave it killed.";
+
// Installing from non-external source.
ASSERT_TRUE(InstallExtension(basedir.AppendASCII("v2.crx"), 1));
- killed_ids.clear();
- service->extension_prefs()->GetKilledExtensionIds(&killed_ids);
- EXPECT_TRUE(killed_ids.end() == killed_ids.find(kExtensionId))
+ EXPECT_FALSE(extension_prefs->IsExtensionKilled(kExtensionId))
<< "Reinstalling should clear the kill bit.";
// Uninstalling from a non-external source should not set the kill bit.
UninstallExtension(kExtensionId);
- killed_ids.clear();
- service->extension_prefs()->GetKilledExtensionIds(&killed_ids);
- EXPECT_TRUE(killed_ids.end() == killed_ids.find(kExtensionId))
+ EXPECT_FALSE(extension_prefs->IsExtensionKilled(kExtensionId))
<< "Uninstalling non-external extension should not set kill bit.";
}
// See http://crbug.com/57378 for flakiness details.
IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, ExternalPolicyRefresh) {
- ExtensionsService* service = browser()->profile()->GetExtensionsService();
+ ExtensionService* service = browser()->profile()->GetExtensionService();
const char* kExtensionId = "ogjcoiohnmldgjemafoockdghcjciccf";
// We don't want autoupdate blacklist checks.
service->updater()->set_blacklist_checks_enabled(false);
@@ -335,15 +344,17 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, ExternalPolicyRefresh) {
const size_t size_before = service->extensions()->size();
ASSERT_TRUE(service->disabled_extensions()->empty());
- // Set the policy as a user preference and fire notification observers.
PrefService* prefs = browser()->profile()->GetPrefs();
- ListValue* forcelist =
- prefs->GetMutableList(prefs::kExtensionInstallForceList);
- ASSERT_TRUE(forcelist->empty());
- forcelist->Append(Value::CreateStringValue(
- "ogjcoiohnmldgjemafoockdghcjciccf;"
- "http://localhost/autoupdate/manifest"));
- prefs->pref_notifier()->FireObservers(prefs::kExtensionInstallForceList);
+ {
+ // Set the policy as a user preference and fire notification observers.
+ ScopedPrefUpdate pref_update(prefs, prefs::kExtensionInstallForceList);
+ ListValue* forcelist =
+ prefs->GetMutableList(prefs::kExtensionInstallForceList);
+ ASSERT_TRUE(forcelist->empty());
+ forcelist->Append(Value::CreateStringValue(
+ "ogjcoiohnmldgjemafoockdghcjciccf;"
+ "http://localhost/autoupdate/manifest"));
+ }
// Check if the extension got installed.
ASSERT_TRUE(WaitForExtensionInstall());
@@ -356,5 +367,4 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, ExternalPolicyRefresh) {
// Check that emptying the list doesn't cause any trouble.
prefs->ClearPref(prefs::kExtensionInstallForceList);
- prefs->pref_notifier()->FireObservers(prefs::kExtensionInstallForceList);
}
diff --git a/chrome/browser/extensions/extension_menu_manager.cc b/chrome/browser/extensions/extension_menu_manager.cc
index eae74f6..0d3c891 100644
--- a/chrome/browser/extensions/extension_menu_manager.cc
+++ b/chrome/browser/extensions/extension_menu_manager.cc
@@ -15,8 +15,9 @@
#include "base/json/json_writer.h"
#include "chrome/browser/extensions/extension_event_router.h"
#include "chrome/browser/extensions/extension_tabs_module.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/common/extensions/extension.h"
+#include "chrome/common/notification_service.h"
#include "gfx/favicon_size.h"
#include "webkit/glue/context_menu.h"
@@ -73,10 +74,8 @@ string16 ExtensionMenuItem::TitleWithReplacement(
// put "%s" in titles that won't get substituted.
ReplaceSubstringsAfterOffset(&result, 0, ASCIIToUTF16("%s"), selection);
- if (result.length() > max_length) {
- result = WideToUTF16(l10n_util::TruncateString(UTF16ToWideHack(result),
- max_length));
- }
+ if (result.length() > max_length)
+ result = l10n_util::TruncateString(result, max_length);
return result;
}
@@ -412,8 +411,7 @@ void ExtensionMenuManager::ExecuteCommand(
AddURLProperty(properties, "frameUrl", params.frame_url);
if (params.selection_text.length() > 0)
- properties->SetString("selectionText",
- WideToUTF16Hack(params.selection_text));
+ properties->SetString("selectionText", params.selection_text);
properties->SetBoolean("editable", params.is_editable);
@@ -455,7 +453,8 @@ void ExtensionMenuManager::Observe(NotificationType type,
NOTREACHED();
return;
}
- const Extension* extension = Details<const Extension>(details).ptr();
+ const Extension* extension =
+ Details<UnloadedExtensionInfo>(details)->extension;
if (ContainsKey(context_items_, extension->id())) {
RemoveAllContextItems(extension->id());
}
diff --git a/chrome/browser/extensions/extension_menu_manager_unittest.cc b/chrome/browser/extensions/extension_menu_manager_unittest.cc
index cbd9a52..ca844cc 100644
--- a/chrome/browser/extensions/extension_menu_manager_unittest.cc
+++ b/chrome/browser/extensions/extension_menu_manager_unittest.cc
@@ -8,6 +8,7 @@
#include "base/path_service.h"
#include "base/scoped_temp_dir.h"
#include "base/scoped_vector.h"
+#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/browser_thread.h"
#include "chrome/browser/extensions/extension_event_router.h"
@@ -321,9 +322,10 @@ TEST_F(ExtensionMenuManagerTest, ExtensionUnloadRemovesMenuItems) {
// Notify that the extension was unloaded, and make sure the right item is
// gone.
+ UnloadedExtensionInfo details(extension1, UnloadedExtensionInfo::DISABLE);
notifier->Notify(NotificationType::EXTENSION_UNLOADED,
Source<Profile>(NULL),
- Details<const Extension>(extension1));
+ Details<UnloadedExtensionInfo>(&details));
ASSERT_EQ(NULL, manager_.MenuItems(extension1->id()));
ASSERT_EQ(1u, manager_.MenuItems(extension2->id())->size());
ASSERT_TRUE(manager_.GetItemById(id1) == NULL);
@@ -419,7 +421,7 @@ TEST_F(ExtensionMenuManagerTest, ExecuteCommand) {
params.media_type = WebKit::WebContextMenuData::MediaTypeImage;
params.src_url = GURL("http://foo.bar/image.png");
params.page_url = GURL("http://foo.bar");
- params.selection_text = L"Hello World";
+ params.selection_text = ASCIIToUTF16("Hello World");
params.is_editable = false;
Extension* extension = AddExtension("test");
@@ -471,8 +473,9 @@ TEST_F(ExtensionMenuManagerTest, ExecuteCommand) {
ASSERT_TRUE(info->GetString("pageUrl", &tmp));
ASSERT_EQ(params.page_url.spec(), tmp);
- ASSERT_TRUE(info->GetString("selectionText", &tmp));
- ASSERT_EQ(WideToUTF8(params.selection_text), tmp);
+ string16 tmp16;
+ ASSERT_TRUE(info->GetString("selectionText", &tmp16));
+ ASSERT_EQ(params.selection_text, tmp16);
bool bool_tmp = true;
ASSERT_TRUE(info->GetBoolean("editable", &bool_tmp));
diff --git a/chrome/browser/extensions/extension_message_service.cc b/chrome/browser/extensions/extension_message_service.cc
index 67c6e71..c72c9d8 100644
--- a/chrome/browser/extensions/extension_message_service.cc
+++ b/chrome/browser/extensions/extension_message_service.cc
@@ -11,12 +11,12 @@
#include "chrome/browser/child_process_security_policy.h"
#include "chrome/browser/extensions/extension_process_manager.h"
#include "chrome/browser/extensions/extension_tabs_module.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tab_contents/tab_util.h"
-#include "chrome/browser/tab_contents_wrapper.h"
+#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/render_messages.h"
diff --git a/chrome/browser/extensions/extension_message_service.h b/chrome/browser/extensions/extension_message_service.h
index 9135a1c..30c771d 100644
--- a/chrome/browser/extensions/extension_message_service.h
+++ b/chrome/browser/extensions/extension_message_service.h
@@ -134,9 +134,9 @@ class ExtensionMessageService
bool notify_other_port);
// NotificationObserver interface.
- void Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details);
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
// An IPC sender that might be in our list of channels has closed.
void OnSenderClosed(IPC::Message::Sender* sender);
diff --git a/chrome/browser/extensions/extension_messages_apitest.cc b/chrome/browser/extensions/extension_messages_apitest.cc
index 760a627..24291a5 100644
--- a/chrome/browser/extensions/extension_messages_apitest.cc
+++ b/chrome/browser/extensions/extension_messages_apitest.cc
@@ -4,8 +4,9 @@
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_event_router.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/common/notification_registrar.h"
+#include "chrome/common/notification_service.h"
#include "googleurl/src/gurl.h"
namespace {
diff --git a/chrome/browser/extensions/extension_metrics_apitest.cc b/chrome/browser/extensions/extension_metrics_apitest.cc
index c9464d2..81875b6 100644
--- a/chrome/browser/extensions/extension_metrics_apitest.cc
+++ b/chrome/browser/extensions/extension_metrics_apitest.cc
@@ -5,11 +5,11 @@
#include <map>
#include "base/metrics/histogram.h"
-#include "chrome/browser/browser_process.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/notification_registrar.h"
+#include "chrome/common/notification_service.h"
namespace {
diff --git a/chrome/browser/extensions/extension_module.cc b/chrome/browser/extensions/extension_module.cc
index 84c3789..1ef27a9 100644
--- a/chrome/browser/extensions/extension_module.cc
+++ b/chrome/browser/extensions/extension_module.cc
@@ -7,11 +7,11 @@
#include <string>
#include "chrome/browser/extensions/extension_prefs.h"
-#include "chrome/browser/extensions/extensions_service.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/profiles/profile.h"
ExtensionPrefs* SetUpdateUrlDataFunction::extension_prefs() {
- return profile()->GetExtensionsService()->extension_prefs();
+ return profile()->GetExtensionService()->extension_prefs();
}
bool SetUpdateUrlDataFunction::RunImpl() {
diff --git a/chrome/browser/extensions/extension_omnibox_api.cc b/chrome/browser/extensions/extension_omnibox_api.cc
index 605374b..4981c98 100644
--- a/chrome/browser/extensions/extension_omnibox_api.cc
+++ b/chrome/browser/extensions/extension_omnibox_api.cc
@@ -5,13 +5,13 @@
#include "chrome/browser/extensions/extension_omnibox_api.h"
#include "base/json/json_writer.h"
-#include "base/singleton.h"
+#include "base/lazy_instance.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/extensions/extension_event_router.h"
-#include "chrome/browser/extensions/extensions_service.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search_engines/template_url.h"
#include "chrome/common/notification_service.h"
@@ -36,8 +36,11 @@ const char kDescriptionStylesType[] = "type";
const char kDescriptionStylesOffset[] = "offset";
const char kDescriptionStylesLength[] = "length";
+static base::LazyInstance<PropertyAccessor<ExtensionOmniboxSuggestion> >
+ g_extension_omnibox_suggestion_property_accessor(base::LINKER_INITIALIZED);
+
PropertyAccessor<ExtensionOmniboxSuggestion>& GetPropertyAccessor() {
- return *Singleton< PropertyAccessor<ExtensionOmniboxSuggestion> >::get();
+ return g_extension_omnibox_suggestion_property_accessor.Get();
}
// Returns the suggestion object set by the extension via the
@@ -45,11 +48,11 @@ PropertyAccessor<ExtensionOmniboxSuggestion>& GetPropertyAccessor() {
const ExtensionOmniboxSuggestion* GetDefaultSuggestionForExtension(
Profile* profile, const std::string& extension_id) {
const Extension* extension =
- profile->GetExtensionsService()->GetExtensionById(extension_id, false);
+ profile->GetExtensionService()->GetExtensionById(extension_id, false);
if (!extension)
return NULL;
return GetPropertyAccessor().GetProperty(
- profile->GetExtensionsService()->GetPropertyBag(extension));
+ profile->GetExtensionService()->GetPropertyBag(extension));
}
}; // namespace
@@ -161,7 +164,7 @@ bool OmniboxSetDefaultSuggestionFunction::RunImpl() {
// Store the suggestion in the extension's runtime data.
GetPropertyAccessor().SetProperty(
- profile_->GetExtensionsService()->GetPropertyBag(GetExtension()),
+ profile_->GetExtensionService()->GetPropertyBag(GetExtension()),
suggestion);
NotificationService::current()->Notify(
diff --git a/chrome/browser/extensions/extension_omnibox_apitest.cc b/chrome/browser/extensions/extension_omnibox_apitest.cc
index 854662d..0eba9be 100644
--- a/chrome/browser/extensions/extension_omnibox_apitest.cc
+++ b/chrome/browser/extensions/extension_omnibox_apitest.cc
@@ -12,11 +12,11 @@
#include "chrome/browser/autocomplete/autocomplete_popup_model.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/extensions/extension_apitest.h"
-#include "chrome/browser/location_bar.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search_engines/template_url.h"
#include "chrome/browser/search_engines/template_url_model.h"
#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/omnibox/location_bar.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/notification_type.h"
#include "chrome/common/url_constants.h"
diff --git a/chrome/browser/extensions/extension_override_apitest.cc b/chrome/browser/extensions/extension_override_apitest.cc
index 3f0c801..4fd73f4 100644
--- a/chrome/browser/extensions/extension_override_apitest.cc
+++ b/chrome/browser/extensions/extension_override_apitest.cc
@@ -5,9 +5,9 @@
#include "chrome/browser/browser_list.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_dom_ui.h"
-#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/prefs/pref_service.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/url_constants.h"
@@ -115,7 +115,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionOverrideTest, ShouldNotCreateDuplicateEntries) {
for (size_t i = 0; i < 3; ++i) {
ExtensionDOMUI::RegisterChromeURLOverrides(
browser()->profile(),
- browser()->profile()->GetExtensionsService()->extensions()->back()->
+ browser()->profile()->GetExtensionService()->extensions()->back()->
GetChromeURLOverrides());
}
@@ -161,7 +161,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionOverrideTest, OverrideKeyboard) {
// Unload the failing version. We should be back to passing now.
const ExtensionList *extensions =
- browser()->profile()->GetExtensionsService()->extensions();
+ browser()->profile()->GetExtensionService()->extensions();
UnloadExtension((*extensions->rbegin())->id());
{
ResultCatcher catcher;
diff --git a/chrome/browser/extensions/extension_page_actions_module.cc b/chrome/browser/extensions/extension_page_actions_module.cc
index c9dc2a3..0e26d60 100644
--- a/chrome/browser/extensions/extension_page_actions_module.cc
+++ b/chrome/browser/extensions/extension_page_actions_module.cc
@@ -8,12 +8,12 @@
#include "chrome/browser/browser_list.h"
#include "chrome/browser/extensions/extension_page_actions_module_constants.h"
#include "chrome/browser/extensions/extension_tabs_module.h"
-#include "chrome/browser/extensions/extensions_service.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tab_contents/navigation_entry.h"
#include "chrome/browser/tab_contents/tab_contents.h"
-#include "chrome/browser/tab_contents_wrapper.h"
#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_action.h"
#include "chrome/common/extensions/extension_error_utils.h"
diff --git a/chrome/browser/extensions/extension_popup_api.cc b/chrome/browser/extensions/extension_popup_api.cc
index 2af847e..25d3657 100644
--- a/chrome/browser/extensions/extension_popup_api.cc
+++ b/chrome/browser/extensions/extension_popup_api.cc
@@ -4,6 +4,8 @@
#include "chrome/browser/extensions/extension_popup_api.h"
+#include <string>
+
#include "base/json/json_writer.h"
#include "base/string_util.h"
#include "base/stringprintf.h"
@@ -11,14 +13,13 @@
#include "chrome/browser/extensions/extension_dom_ui.h"
#include "chrome/browser/extensions/extension_event_router.h"
#include "chrome/browser/extensions/extension_host.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/render_view_host_delegate.h"
#include "chrome/browser/renderer_host/render_widget_host_view.h"
-#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
-#include "chrome/browser/window_sizer.h"
+#include "chrome/browser/ui/window_sizer.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/notification_details.h"
#include "chrome/common/notification_service.h"
diff --git a/chrome/browser/extensions/extension_pref_store.cc b/chrome/browser/extensions/extension_pref_store.cc
index 27719ed..b3aba44 100644
--- a/chrome/browser/extensions/extension_pref_store.cc
+++ b/chrome/browser/extensions/extension_pref_store.cc
@@ -4,196 +4,25 @@
#include "chrome/browser/extensions/extension_pref_store.h"
-#include "base/logging.h"
-#include "base/values.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/prefs/pref_service.h"
-#include "chrome/browser/profile.h"
-#include "chrome/common/extensions/extension.h"
-#include "chrome/common/notification_service.h"
-
-ExtensionPrefStore::ExtensionPrefStore(Profile* profile,
- PrefNotifier::PrefStoreType type)
- : prefs_(new DictionaryValue()),
- profile_(profile),
- type_(type) {
- RegisterObservers();
+ExtensionPrefStore::ExtensionPrefStore()
+ : initialization_complete_(false) {
}
-ExtensionPrefStore::~ExtensionPrefStore() {
- STLDeleteElements(&extension_stack_);
- notification_registrar_.RemoveAll();
+void ExtensionPrefStore::SetExtensionPref(const std::string& key,
+ Value* value) {
+ SetValue(key, value);
}
-void ExtensionPrefStore::InstallExtensionPref(const Extension* extension,
- const char* new_pref_path,
- Value* new_pref_value) {
- ExtensionStack::iterator i;
- for (i = extension_stack_.begin(); i != extension_stack_.end(); ++i) {
- if ((*i)->extension == extension)
- break;
- }
-
- // If this extension is not already in the stack, add it. Otherwise, update
- // or add the value of this preference, but don't change the extension's
- // position in the stack. We store the extension even if this preference
- // isn't registered with our PrefService, so that the ordering of extensions
- // is consistent among all local-state and user ExtensionPrefStores.
- PrefService* pref_service = GetPrefService();
- // The pref_service may be NULL in unit testing.
- bool is_registered_pref = (pref_service == NULL ||
- pref_service->FindPreference(new_pref_path) != NULL);
- PrefValueMap* pref_values;
- if (i == extension_stack_.end()) {
- pref_values = new PrefValueMap();
- if (is_registered_pref)
- (*pref_values)[new_pref_path] = new_pref_value;
-
- ExtensionPrefs* extension_prefs = new ExtensionPrefs(extension,
- pref_values);
- extension_stack_.push_front(extension_prefs);
- } else if (is_registered_pref) {
- pref_values = (*i)->pref_values;
- delete (*pref_values)[new_pref_path];
- (*pref_values)[new_pref_path] = new_pref_value;
- }
-
- // Apply the preference to our local |prefs_| store.
- UpdateOnePref(new_pref_path);
+void ExtensionPrefStore::RemoveExtensionPref(const std::string& key) {
+ RemoveValue(key);
}
-void ExtensionPrefStore::UninstallExtension(const Extension* extension) {
- // Remove this extension from the stack.
- for (ExtensionStack::iterator i = extension_stack_.begin();
- i != extension_stack_.end(); ++i) {
- if ((*i)->extension == extension) {
- scoped_ptr<ExtensionPrefs> to_be_deleted(*i);
- extension_stack_.erase(i);
- UpdatePrefs(to_be_deleted->pref_values);
- return;
- }
- }
+void ExtensionPrefStore::OnInitializationCompleted() {
+ DCHECK(!initialization_complete_);
+ initialization_complete_ = true;
+ NotifyInitializationCompleted();
}
-void ExtensionPrefStore::GetExtensionIDs(std::vector<std::string>* result) {
- for (ExtensionStack::iterator i = extension_stack_.begin();
- i != extension_stack_.end(); ++i) {
- (*result).push_back((*i)->extension->id());
- }
-}
-
-// This could be sped up by keeping track of which extension currently controls
-// a given preference, among other optimizations. But probably fewer than 10
-// installed extensions will be trying to control any preferences, so stick
-// with this simpler algorithm until it causes a problem.
-void ExtensionPrefStore::UpdateOnePref(const char* path) {
- PrefService* pref_service = GetPrefService();
-
- // There are at least two PrefServices, one for local state and one for
- // user prefs. (See browser_main.cc.) Different preferences are registered
- // in each; if this one doesn't have the desired pref registered, we ignore
- // it and let the other one handle it.
- // The pref_service may be NULL in unit testing.
- if (pref_service && !pref_service->FindPreference(path))
- return;
-
- // Save the old value before removing it from the local cache.
- Value* my_old_value_ptr = NULL;
- prefs_->Get(path, &my_old_value_ptr);
- scoped_ptr<Value> my_old_value;
- if (my_old_value_ptr)
- my_old_value.reset(my_old_value_ptr->DeepCopy());
-
- // DictionaryValue::Set complains if a key is overwritten with the same
- // value, so remove it first.
- prefs_->Remove(path, NULL);
-
- // Find the first extension that wants to set this pref and use its value.
- Value* my_new_value = NULL;
- for (ExtensionStack::iterator ext_iter = extension_stack_.begin();
- ext_iter != extension_stack_.end(); ++ext_iter) {
- PrefValueMap::iterator value_iter = (*ext_iter)->pref_values->find(path);
- if (value_iter != (*ext_iter)->pref_values->end()) {
- prefs_->Set(path, (*value_iter).second->DeepCopy());
- my_new_value = (*value_iter).second;
- break;
- }
- }
-
- if (pref_service) {
- bool value_changed = true;
- if (!my_old_value.get() && !my_new_value) {
- value_changed = false;
- } else if (my_old_value.get() &&
- my_new_value &&
- my_old_value->Equals(my_new_value)) {
- value_changed = false;
- }
-
- if (value_changed)
- pref_service->pref_notifier()->OnPreferenceSet(path, type_);
- }
-}
-
-void ExtensionPrefStore::UpdatePrefs(const PrefValueMap* pref_values) {
- if (!pref_values)
- return;
-
- for (PrefValueMap::const_iterator i = pref_values->begin();
- i != pref_values->end(); ++i) {
- UpdateOnePref(i->first);
- }
-}
-
-PrefService* ExtensionPrefStore::GetPrefService() {
- if (profile_)
- return profile_->GetPrefs();
- return g_browser_process->local_state();
-}
-
-void ExtensionPrefStore::RegisterObservers() {
- notification_registrar_.Add(this,
- NotificationType::EXTENSION_PREF_CHANGED,
- NotificationService::AllSources());
-
- notification_registrar_.Add(this,
- NotificationType::EXTENSION_UNLOADED,
- NotificationService::AllSources());
-}
-
-void ExtensionPrefStore::Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details) {
- switch (type.value) {
- case NotificationType::EXTENSION_PREF_CHANGED: {
- Profile* extension_profile = Source<Profile>(source).ptr();
- // The ExtensionPrefStore for the local state watches all profiles.
- if (!profile_ || profile_ == extension_profile) {
- ExtensionPrefStore::ExtensionPrefDetails* data =
- Details<ExtensionPrefStore::ExtensionPrefDetails>(details).ptr();
- InstallExtensionPref(data->first, data->second.first,
- data->second.second);
- }
- break;
- }
- case NotificationType::EXTENSION_UNLOADED: {
- Profile* extension_profile = Source<Profile>(source).ptr();
- const Extension* extension = Details<const Extension>(details).ptr();
- // The ExtensionPrefStore for the local state watches all profiles.
- if (profile_ == NULL || profile_ == extension_profile)
- UninstallExtension(extension);
- break;
- }
- default: {
- NOTREACHED();
- }
- }
-}
-
-ExtensionPrefStore::ExtensionPrefs::ExtensionPrefs(const Extension* extension,
- PrefValueMap* values) : extension(extension), pref_values(values) {}
-
-ExtensionPrefStore::ExtensionPrefs::~ExtensionPrefs() {
- STLDeleteValues(pref_values);
- delete pref_values;
+bool ExtensionPrefStore::IsInitializationComplete() const {
+ return initialization_complete_;
}
diff --git a/chrome/browser/extensions/extension_pref_store.h b/chrome/browser/extensions/extension_pref_store.h
index f176758..f2db809 100644
--- a/chrome/browser/extensions/extension_pref_store.h
+++ b/chrome/browser/extensions/extension_pref_store.h
@@ -6,119 +6,31 @@
#define CHROME_BROWSER_EXTENSIONS_EXTENSION_PREF_STORE_H_
#pragma once
-#include <list>
-#include <map>
-#include <string>
-#include <utility>
-#include <vector>
+#include "chrome/browser/prefs/value_map_pref_store.h"
-#include "base/basictypes.h"
-#include "base/scoped_ptr.h"
-#include "base/stl_util-inl.h"
-#include "chrome/browser/prefs/pref_notifier.h"
-#include "chrome/common/notification_observer.h"
-#include "chrome/common/notification_registrar.h"
-#include "chrome/common/pref_store.h"
-
-class DictionaryValue;
-class Extension;
-class PrefService;
-class Profile;
-class Value;
-
-// This PrefStore keeps track of preferences set by extensions: for example,
-// proxy settings. A stack of relevant extensions is stored in order of
-// their addition to this PrefStore. For each preference, the last-added
-// enabled extension that tries to set it overrules any others.
-class ExtensionPrefStore : public PrefStore,
- public NotificationObserver {
+// A PrefStore implementation that holds preferences set by extensions.
+class ExtensionPrefStore : public ValueMapPrefStore {
public:
- // Maps preference paths to their values.
- typedef std::map<const char*, Value*> PrefValueMap;
-
- // The type passed as Details for an EXTENSION_PREF_CHANGED notification.
- // The nested pairs are <extension, <pref_path, pref_value> >. This is here,
- // rather than in (say) notification_type.h, to keep the dependency on
- // std::pair out of the many places that include notification_type.h.
- typedef std::pair<const Extension*, std::pair<const char*, Value*> >
- ExtensionPrefDetails;
-
- ExtensionPrefStore(Profile* profile, PrefNotifier::PrefStoreType type);
- virtual ~ExtensionPrefStore();
-
- // Begins tracking the preference and value an extension wishes to set. This
- // must be called each time an extension API tries to set a preference.
- // The ExtensionPrefStore will take ownership of the |pref_value|.
- virtual void InstallExtensionPref(const Extension* extension,
- const char* pref_path,
- Value* pref_value);
+ ExtensionPrefStore();
+ virtual ~ExtensionPrefStore() {}
- // Removes an extension and all its preference settings from this PrefStore.
- // This must be called when an extension is uninstalled or disabled.
- virtual void UninstallExtension(const Extension* extension);
+ // Set an extension preference |value| for |key|. Takes ownership of |value|.
+ void SetExtensionPref(const std::string& key, Value* value);
- // PrefStore methods:
- virtual DictionaryValue* prefs() const { return prefs_.get(); }
+ // Remove the extension preference value for |key|.
+ void RemoveExtensionPref(const std::string& key);
- virtual PrefReadError ReadPrefs() { return PREF_READ_ERROR_NONE; }
-
- protected:
- // Returns a vector of the extension IDs in the extension_stack_.
- // This should only be accessed by subclasses for unit-testing.
- void GetExtensionIDs(std::vector<std::string>* result);
-
- // Returns the applicable pref service from the profile (if we have one) or
- // the browser's local state. This should only be accessed or overridden by
- // subclasses for unit-testing.
- virtual PrefService* GetPrefService();
+ // Tell the store it's now fully initialized.
+ void OnInitializationCompleted();
private:
- // Associates an extension with the prefs it sets. Owns the pref values.
- struct ExtensionPrefs {
- ExtensionPrefs(const Extension* extension, PrefValueMap* values);
- ~ExtensionPrefs();
-
- const Extension* extension;
- PrefValueMap* pref_values;
- };
-
- // A pseudo-stack of extensions and their preferences. Extensions are always
- // added to the head, but may be removed from the middle.
- typedef std::list<ExtensionPrefs*> ExtensionStack;
+ // PrefStore overrides:
+ virtual bool IsInitializationComplete() const;
- // Applies the highest-priority extension's setting for the given preference
- // path to the |prefs_| store, or clears the setting there if no extensions
- // wish to control it.
- void UpdateOnePref(const char* path);
-
- // Updates each preference in the key set of the |pref_values| map.
- void UpdatePrefs(const PrefValueMap* pref_values);
-
- // Registers this as an observer for relevant notifications.
- void RegisterObservers();
-
- // Responds to observed notifications.
- void Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details);
-
- // A cache of the highest-priority values for each preference that any
- // extension is controlling, for quick read access. Owns the stored values.
- scoped_ptr<DictionaryValue> prefs_;
-
- ExtensionStack extension_stack_;
-
- NotificationRegistrar notification_registrar_;
-
- // Weak reference to the profile whose extensions we're interested in. May be
- // NULL (for the local-state preferences), in which case we watch all
- // extensions.
- Profile* profile_;
-
- // My PrefStore type, assigned by the PrefValueStore.
- PrefNotifier::PrefStoreType type_;
+ bool initialization_complete_;
DISALLOW_COPY_AND_ASSIGN(ExtensionPrefStore);
};
+
#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_PREF_STORE_H_
diff --git a/chrome/browser/extensions/extension_pref_store_unittest.cc b/chrome/browser/extensions/extension_pref_store_unittest.cc
deleted file mode 100644
index 580dd3e..0000000
--- a/chrome/browser/extensions/extension_pref_store_unittest.cc
+++ /dev/null
@@ -1,369 +0,0 @@
-// Copyright (c) 2010 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 <string>
-#include <vector>
-
-#include "base/scoped_ptr.h"
-#include "base/scoped_temp_dir.h"
-#include "base/values.h"
-#include "chrome/browser/extensions/extension_pref_store.h"
-#include "chrome/browser/prefs/default_pref_store.h"
-#include "chrome/browser/prefs/pref_service.h"
-#include "chrome/browser/prefs/pref_value_store.h"
-#include "chrome/common/extensions/extension.h"
-#include "chrome/test/testing_pref_service.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace keys = extension_manifest_keys;
-
-namespace {
-
-class TestExtensionPrefStore : public ExtensionPrefStore {
- public:
- TestExtensionPrefStore()
- : ExtensionPrefStore(NULL, PrefNotifier::EXTENSION_STORE),
- ext1(NULL),
- ext2(NULL),
- ext3(NULL),
- pref_service_(NULL) {
- // Can't use ASSERT_TRUE here because a constructor can't return a value.
- if (!temp_dir_.CreateUniqueTempDir()) {
- ADD_FAILURE() << "Failed to create temp dir";
- return;
- }
- DictionaryValue simple_dict;
- std::string error;
-
- simple_dict.SetString(keys::kVersion, "1.0.0.0");
- simple_dict.SetString(keys::kName, "unused");
-
- ext1_scoped_ = Extension::Create(
- temp_dir_.path().AppendASCII("ext1"), Extension::INVALID,
- simple_dict, false, &error);
- ext2_scoped_ = Extension::Create(
- temp_dir_.path().AppendASCII("ext2"), Extension::INVALID,
- simple_dict, false, &error);
- ext3_scoped_ = Extension::Create(
- temp_dir_.path().AppendASCII("ext3"), Extension::INVALID,
- simple_dict, false, &error);
-
- ext1 = ext1_scoped_.get();
- ext2 = ext2_scoped_.get();
- ext3 = ext3_scoped_.get();
- }
-
- typedef std::vector<std::string> ExtensionIDs;
- void GetExtensionIDList(ExtensionIDs* result) {
- GetExtensionIDs(result);
- }
-
- void SetPrefService(PrefService* pref_service) {
- pref_service_ = pref_service;
- }
-
- // Overridden from ExtensionPrefStore.
- virtual PrefService* GetPrefService() {
- return pref_service_;
- }
-
- // Weak references, for convenience.
- Extension* ext1;
- Extension* ext2;
- Extension* ext3;
-
- private:
- ScopedTempDir temp_dir_;
-
- scoped_refptr<Extension> ext1_scoped_;
- scoped_refptr<Extension> ext2_scoped_;
- scoped_refptr<Extension> ext3_scoped_;
-
- // Weak reference.
- PrefService* pref_service_;
-};
-
-// Mock PrefNotifier that allows the notifications to be tracked.
-class MockPrefNotifier : public PrefNotifier {
- public:
- MockPrefNotifier(PrefService* service, PrefValueStore* value_store)
- : PrefNotifier(service, value_store) {}
-
- virtual ~MockPrefNotifier() {}
-
- MOCK_METHOD1(FireObservers, void(const char* path));
-};
-
-// Mock PrefService that allows the PrefNotifier to be injected.
-class MockPrefService : public PrefService {
- public:
- explicit MockPrefService(PrefValueStore* pref_value_store)
- : PrefService(pref_value_store) {
- }
-
- void SetPrefNotifier(MockPrefNotifier* notifier) {
- pref_notifier_.reset(notifier);
- }
-};
-
-// Use constants to avoid confusing std::map with hard-coded strings.
-const char kPref1[] = "path1.subpath";
-const char kPref2[] = "path2";
-const char kPref3[] = "path3";
-const char kPref4[] = "path4";
-
-} // namespace
-
-TEST(ExtensionPrefStoreTest, InstallOneExtension) {
- TestExtensionPrefStore eps;
- ASSERT_TRUE(eps.ext1 != NULL);
- eps.InstallExtensionPref(eps.ext1, kPref1, Value::CreateStringValue("val1"));
-
- TestExtensionPrefStore::ExtensionIDs ids;
- eps.GetExtensionIDList(&ids);
- EXPECT_EQ(1u, ids.size());
- EXPECT_EQ(eps.ext1->id(), ids[0]);
-
- DictionaryValue* prefs = eps.prefs();
- ASSERT_EQ(1u, prefs->size());
- std::string actual;
- ASSERT_TRUE(prefs->GetString(kPref1, &actual));
- EXPECT_EQ("val1", actual);
-}
-
-// Make sure the last-installed extension wins.
-TEST(ExtensionPrefStoreTest, InstallMultipleExtensions) {
- TestExtensionPrefStore eps;
- ASSERT_TRUE(eps.ext1 != NULL);
- eps.InstallExtensionPref(eps.ext1, kPref1, Value::CreateStringValue("val1"));
- eps.InstallExtensionPref(eps.ext2, kPref1, Value::CreateStringValue("val2"));
- eps.InstallExtensionPref(eps.ext3, kPref1, Value::CreateStringValue("val3"));
-
- TestExtensionPrefStore::ExtensionIDs ids;
- eps.GetExtensionIDList(&ids);
- EXPECT_EQ(3u, ids.size());
- EXPECT_EQ(eps.ext3->id(), ids[0]);
- EXPECT_EQ(eps.ext2->id(), ids[1]);
- EXPECT_EQ(eps.ext1->id(), ids[2]);
-
- DictionaryValue* prefs = eps.prefs();
- ASSERT_EQ(1u, prefs->size());
- std::string actual;
- ASSERT_TRUE(prefs->GetString(kPref1, &actual));
- EXPECT_EQ("val3", actual);
-}
-
-// Make sure the last-installed extension wins for each preference.
-TEST(ExtensionPrefStoreTest, InstallOverwrittenExtensions) {
- TestExtensionPrefStore eps;
- ASSERT_TRUE(eps.ext1 != NULL);
- eps.InstallExtensionPref(eps.ext1, kPref1, Value::CreateStringValue("val1"));
- eps.InstallExtensionPref(eps.ext2, kPref1, Value::CreateStringValue("val2"));
- eps.InstallExtensionPref(eps.ext3, kPref1, Value::CreateStringValue("val3"));
-
- eps.InstallExtensionPref(eps.ext1, kPref2, Value::CreateStringValue("val4"));
- eps.InstallExtensionPref(eps.ext2, kPref2, Value::CreateStringValue("val5"));
-
- eps.InstallExtensionPref(eps.ext1, kPref1, Value::CreateStringValue("val6"));
- eps.InstallExtensionPref(eps.ext1, kPref2, Value::CreateStringValue("val7"));
- eps.InstallExtensionPref(eps.ext1, kPref3, Value::CreateStringValue("val8"));
-
- TestExtensionPrefStore::ExtensionIDs ids;
- eps.GetExtensionIDList(&ids);
- EXPECT_EQ(3u, ids.size());
- EXPECT_EQ(eps.ext3->id(), ids[0]);
- EXPECT_EQ(eps.ext2->id(), ids[1]);
- EXPECT_EQ(eps.ext1->id(), ids[2]);
-
- DictionaryValue* prefs = eps.prefs();
- ASSERT_EQ(3u, prefs->size());
- std::string actual;
- EXPECT_TRUE(prefs->GetString(kPref1, &actual));
- EXPECT_EQ("val3", actual);
- EXPECT_TRUE(prefs->GetString(kPref2, &actual));
- EXPECT_EQ("val5", actual);
- EXPECT_TRUE(prefs->GetString(kPref3, &actual));
- EXPECT_EQ("val8", actual);
-}
-
-// Make sure the last-installed extension wins even if other extensions set
-// the same or different preferences later.
-TEST(ExtensionPrefStoreTest, InstallInterleavedExtensions) {
- TestExtensionPrefStore eps;
- ASSERT_TRUE(eps.ext1 != NULL);
- eps.InstallExtensionPref(eps.ext1, kPref1, Value::CreateStringValue("val1"));
- eps.InstallExtensionPref(eps.ext2, kPref2, Value::CreateStringValue("val2"));
- eps.InstallExtensionPref(eps.ext3, kPref3, Value::CreateStringValue("val3"));
-
- eps.InstallExtensionPref(eps.ext3, kPref3, Value::CreateStringValue("val4"));
- eps.InstallExtensionPref(eps.ext2, kPref3, Value::CreateStringValue("val5"));
- eps.InstallExtensionPref(eps.ext1, kPref3, Value::CreateStringValue("val6"));
-
- eps.InstallExtensionPref(eps.ext3, kPref1, Value::CreateStringValue("val7"));
-
- TestExtensionPrefStore::ExtensionIDs ids;
- eps.GetExtensionIDList(&ids);
- EXPECT_EQ(3u, ids.size());
- EXPECT_EQ(eps.ext3->id(), ids[0]);
- EXPECT_EQ(eps.ext2->id(), ids[1]);
- EXPECT_EQ(eps.ext1->id(), ids[2]);
-
- DictionaryValue* prefs = eps.prefs();
- ASSERT_EQ(3u, prefs->size());
- std::string actual;
- EXPECT_TRUE(prefs->GetString(kPref1, &actual));
- EXPECT_EQ("val7", actual);
- EXPECT_TRUE(prefs->GetString(kPref2, &actual));
- EXPECT_EQ("val2", actual);
- EXPECT_TRUE(prefs->GetString(kPref3, &actual));
- EXPECT_EQ("val4", actual);
-}
-
-TEST(ExtensionPrefStoreTest, UninstallOnlyExtension) {
- TestExtensionPrefStore eps;
- ASSERT_TRUE(eps.ext1 != NULL);
- eps.InstallExtensionPref(eps.ext1, kPref1, Value::CreateStringValue("val1"));
- eps.InstallExtensionPref(eps.ext1, kPref2, Value::CreateStringValue("val2"));
-
- // No need to check the state here; the Install* tests cover that.
- eps.UninstallExtension(eps.ext1);
-
- TestExtensionPrefStore::ExtensionIDs ids;
- eps.GetExtensionIDList(&ids);
- EXPECT_EQ(0u, ids.size());
-
- DictionaryValue* prefs = eps.prefs();
- std::string actual;
- // "path1.name" has been removed, but an empty "path1" dictionary is still
- // present.
- ASSERT_EQ(1u, prefs->size());
- EXPECT_FALSE(prefs->GetString(kPref1, &actual));
- EXPECT_FALSE(prefs->GetString(kPref2, &actual));
-}
-
-// Tests uninstalling an extension that wasn't winning for any preferences.
-TEST(ExtensionPrefStoreTest, UninstallIrrelevantExtension) {
- TestExtensionPrefStore eps;
- ASSERT_TRUE(eps.ext1 != NULL);
- eps.InstallExtensionPref(eps.ext1, kPref1, Value::CreateStringValue("val1"));
- eps.InstallExtensionPref(eps.ext2, kPref1, Value::CreateStringValue("val2"));
-
- eps.InstallExtensionPref(eps.ext1, kPref2, Value::CreateStringValue("val3"));
- eps.InstallExtensionPref(eps.ext2, kPref2, Value::CreateStringValue("val4"));
-
- eps.UninstallExtension(eps.ext1);
-
- TestExtensionPrefStore::ExtensionIDs ids;
- eps.GetExtensionIDList(&ids);
- EXPECT_EQ(1u, ids.size());
- EXPECT_EQ(eps.ext2->id(), ids[0]);
-
- DictionaryValue* prefs = eps.prefs();
- ASSERT_EQ(2u, prefs->size());
- std::string actual;
- EXPECT_TRUE(prefs->GetString(kPref1, &actual));
- EXPECT_EQ("val2", actual);
- EXPECT_TRUE(prefs->GetString(kPref2, &actual));
- EXPECT_EQ("val4", actual);
-}
-
-// Tests uninstalling an extension that was winning for all preferences.
-TEST(ExtensionPrefStoreTest, UninstallExtensionFromTop) {
- TestExtensionPrefStore eps;
- ASSERT_TRUE(eps.ext1 != NULL);
- eps.InstallExtensionPref(eps.ext1, kPref1, Value::CreateStringValue("val1"));
- eps.InstallExtensionPref(eps.ext2, kPref1, Value::CreateStringValue("val2"));
- eps.InstallExtensionPref(eps.ext3, kPref1, Value::CreateStringValue("val3"));
-
- eps.InstallExtensionPref(eps.ext1, kPref2, Value::CreateStringValue("val4"));
- eps.InstallExtensionPref(eps.ext3, kPref2, Value::CreateStringValue("val5"));
-
- eps.UninstallExtension(eps.ext3);
-
- TestExtensionPrefStore::ExtensionIDs ids;
- eps.GetExtensionIDList(&ids);
- EXPECT_EQ(2u, ids.size());
- EXPECT_EQ(eps.ext2->id(), ids[0]);
- EXPECT_EQ(eps.ext1->id(), ids[1]);
-
- DictionaryValue* prefs = eps.prefs();
- ASSERT_EQ(2u, prefs->size());
- std::string actual;
- EXPECT_TRUE(prefs->GetString(kPref1, &actual));
- EXPECT_EQ("val2", actual);
- EXPECT_TRUE(prefs->GetString(kPref2, &actual));
- EXPECT_EQ("val4", actual);
-}
-
-// Tests uninstalling an extension that was winning for only some preferences.
-TEST(ExtensionPrefStoreTest, UninstallExtensionFromMiddle) {
- TestExtensionPrefStore eps;
- ASSERT_TRUE(eps.ext1 != NULL);
- eps.InstallExtensionPref(eps.ext1, kPref1, Value::CreateStringValue("val1"));
- eps.InstallExtensionPref(eps.ext2, kPref1, Value::CreateStringValue("val2"));
- eps.InstallExtensionPref(eps.ext3, kPref1, Value::CreateStringValue("val3"));
-
- eps.InstallExtensionPref(eps.ext1, kPref2, Value::CreateStringValue("val4"));
- eps.InstallExtensionPref(eps.ext2, kPref2, Value::CreateStringValue("val5"));
-
- eps.InstallExtensionPref(eps.ext1, kPref3, Value::CreateStringValue("val6"));
-
- eps.InstallExtensionPref(eps.ext2, kPref4, Value::CreateStringValue("val7"));
-
- eps.UninstallExtension(eps.ext2);
-
- TestExtensionPrefStore::ExtensionIDs ids;
- eps.GetExtensionIDList(&ids);
- EXPECT_EQ(2u, ids.size());
- EXPECT_EQ(eps.ext3->id(), ids[0]);
- EXPECT_EQ(eps.ext1->id(), ids[1]);
-
- DictionaryValue* prefs = eps.prefs();
- ASSERT_EQ(3u, prefs->size());
- std::string actual;
- EXPECT_TRUE(prefs->GetString(kPref1, &actual));
- EXPECT_EQ("val3", actual);
- EXPECT_TRUE(prefs->GetString(kPref2, &actual));
- EXPECT_EQ("val4", actual);
- EXPECT_TRUE(prefs->GetString(kPref3, &actual));
- EXPECT_EQ("val6", actual);
- EXPECT_FALSE(prefs->GetString(kPref4, &actual));
-}
-
-TEST(ExtensionPrefStoreTest, NotifyWhenNeeded) {
- using testing::Mock;
-
- TestExtensionPrefStore* eps = new TestExtensionPrefStore;
- DefaultPrefStore* dps = new DefaultPrefStore;
- ASSERT_TRUE(eps->ext1 != NULL);
-
- // The PrefValueStore takes ownership of the PrefStores; in this case, that's
- // only an ExtensionPrefStore. Likewise, the PrefService takes ownership of
- // the PrefValueStore and PrefNotifier.
- PrefValueStore* value_store = new TestingPrefService::TestingPrefValueStore(
- NULL, NULL, eps, NULL, NULL, NULL, dps);
- scoped_ptr<MockPrefService> pref_service(new MockPrefService(value_store));
- MockPrefNotifier* pref_notifier = new MockPrefNotifier(pref_service.get(),
- value_store);
- pref_service->SetPrefNotifier(pref_notifier);
-
- eps->SetPrefService(pref_service.get());
- pref_service->RegisterStringPref(kPref1, std::string());
-
- EXPECT_CALL(*pref_notifier, FireObservers(kPref1));
- eps->InstallExtensionPref(eps->ext1, kPref1,
- Value::CreateStringValue("https://www.chromium.org"));
- Mock::VerifyAndClearExpectations(pref_notifier);
-
- EXPECT_CALL(*pref_notifier, FireObservers(kPref1)).Times(0);
- eps->InstallExtensionPref(eps->ext1, kPref1,
- Value::CreateStringValue("https://www.chromium.org"));
- Mock::VerifyAndClearExpectations(pref_notifier);
-
- EXPECT_CALL(*pref_notifier, FireObservers(kPref1)).Times(2);
- eps->InstallExtensionPref(eps->ext1, kPref1,
- Value::CreateStringValue("chrome://newtab"));
- eps->UninstallExtension(eps->ext1);
-}
diff --git a/chrome/browser/extensions/extension_prefs.cc b/chrome/browser/extensions/extension_prefs.cc
index 0cc2ec5..1f128ab 100644
--- a/chrome/browser/extensions/extension_prefs.cc
+++ b/chrome/browser/extensions/extension_prefs.cc
@@ -7,6 +7,8 @@
#include "base/string_util.h"
#include "base/string_number_conversions.h"
#include "base/utf_string_conversions.h"
+#include "chrome/browser/extensions/extension_pref_store.h"
+#include "chrome/browser/prefs/pref_notifier.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/url_pattern.h"
#include "chrome/common/notification_service.h"
@@ -91,6 +93,12 @@ const char kPrefGrantedPermissionsAPI[] = "granted_permissions.api";
const char kPrefGrantedPermissionsHost[] = "granted_permissions.host";
const char kPrefGrantedPermissionsAll[] = "granted_permissions.full";
+// A preference that indicates when an extension was installed.
+const char kPrefInstallTime[] = "install_time";
+
+// A preference that contains any extension-controlled preferences.
+const char kPrefPreferences[] = "preferences";
+
} // namespace
////////////////////////////////////////////////////////////////////////////////
@@ -133,14 +141,19 @@ static void ExtentToStringSet(const ExtensionExtent& host_extent,
} // namespace
-ExtensionPrefs::ExtensionPrefs(PrefService* prefs, const FilePath& root_dir)
+ExtensionPrefs::ExtensionPrefs(PrefService* prefs,
+ const FilePath& root_dir,
+ ExtensionPrefStore* pref_store)
: prefs_(prefs),
- install_directory_(root_dir) {
+ install_directory_(root_dir),
+ pref_store_(pref_store) {
// TODO(asargent) - Remove this in a couple of months. (See comment above
// CleanupBadExtensionKeys).
- CleanupBadExtensionKeys(prefs);
+ CleanupBadExtensionKeys(prefs_);
MakePathsRelative();
+
+ InitPrefStore();
}
ExtensionPrefs::~ExtensionPrefs() {}
@@ -325,7 +338,9 @@ void ExtensionPrefs::AddToExtensionPrefStringSet(
void ExtensionPrefs::SavePrefsAndNotify() {
prefs_->ScheduleSavePersistentPrefs();
- prefs_->pref_notifier()->OnUserPreferenceSet(kExtensionsPref);
+ // TODO(mnissler, danno): Don't use pref_notifier() here, but tell the
+ // PrefService by some other means that we changed the pref value.
+ prefs_->pref_notifier()->OnPreferenceChanged(kExtensionsPref);
}
bool ExtensionPrefs::IsBlacklistBitSet(DictionaryValue* ext) {
@@ -622,36 +637,17 @@ void ExtensionPrefs::SetLaunchType(const std::string& extension_id,
SavePrefsAndNotify();
}
-void ExtensionPrefs::GetKilledExtensionIds(std::set<std::string>* killed_ids) {
- const DictionaryValue* dict = prefs_->GetDictionary(kExtensionsPref);
- if (!dict || dict->empty())
- return;
-
- for (DictionaryValue::key_iterator i = dict->begin_keys();
- i != dict->end_keys(); ++i) {
- const std::string& key_name(*i);
- if (!Extension::IdIsValid(key_name)) {
- LOG(WARNING) << "Invalid external extension ID encountered: " << key_name;
- continue;
- }
-
- DictionaryValue* extension;
- if (!dict->GetDictionary(key_name, &extension)) {
- NOTREACHED();
- continue;
- }
-
- // Check to see if the extension has been killed.
- int state;
- if (extension->GetInteger(kPrefState, &state) &&
- state == static_cast<int>(Extension::KILLBIT)) {
- killed_ids->insert(StringToLowerASCII(key_name));
- }
- }
+bool ExtensionPrefs::IsExtensionKilled(const std::string& id) {
+ DictionaryValue* extension = GetExtensionPref(id);
+ if (!extension)
+ return false;
+ int state = 0;
+ return extension->GetInteger(kPrefState, &state) &&
+ state == static_cast<int>(Extension::KILLBIT);
}
std::vector<std::string> ExtensionPrefs::GetToolbarOrder() {
- std::vector<std::string> extension_ids;
+ ExtensionPrefs::ExtensionIdSet extension_ids;
const ListValue* toolbar_order = prefs_->GetList(kExtensionToolbar);
if (toolbar_order) {
for (size_t i = 0; i < toolbar_order->GetSize(); ++i) {
@@ -678,12 +674,18 @@ void ExtensionPrefs::OnExtensionInstalled(
const Extension* extension, Extension::State initial_state,
bool initial_incognito_enabled) {
const std::string& id = extension->id();
+ const base::Time install_time = GetCurrentTime();
UpdateExtensionPref(id, kPrefState,
Value::CreateIntegerValue(initial_state));
UpdateExtensionPref(id, kPrefIncognitoEnabled,
Value::CreateBooleanValue(initial_incognito_enabled));
UpdateExtensionPref(id, kPrefLocation,
Value::CreateIntegerValue(extension->location()));
+ UpdateExtensionPref(id, kPrefInstallTime,
+ Value::CreateStringValue(
+ base::Int64ToString(install_time.ToInternalValue())));
+ UpdateExtensionPref(id, kPrefPreferences, new DictionaryValue());
+
FilePath::StringType path = MakePathRelative(install_directory_,
extension->path(), NULL);
UpdateExtensionPref(id, kPrefPath, Value::CreateStringValue(path));
@@ -701,6 +703,9 @@ void ExtensionPrefs::OnExtensionInstalled(
void ExtensionPrefs::OnExtensionUninstalled(const std::string& extension_id,
const Extension::Location& location,
bool external_uninstall) {
+ PrefKeySet pref_keys;
+ GetExtensionControlledPrefKeys(extension_id, &pref_keys);
+
// For external extensions, we save a preference reminding ourself not to try
// and install the extension anymore (except when |external_uninstall| is
// true, which signifies that the registry key was deleted or the pref file
@@ -712,10 +717,12 @@ void ExtensionPrefs::OnExtensionUninstalled(const std::string& extension_id,
} else {
DeleteExtensionPrefs(extension_id);
}
+
+ UpdatePrefStore(pref_keys);
}
Extension::State ExtensionPrefs::GetExtensionState(
- const std::string& extension_id) {
+ const std::string& extension_id) const {
DictionaryValue* extension = GetExtensionPref(extension_id);
// If the extension doesn't have a pref, it's a --load-extension.
@@ -736,6 +743,11 @@ void ExtensionPrefs::SetExtensionState(const Extension* extension,
Extension::State state) {
UpdateExtensionPref(extension->id(), kPrefState,
Value::CreateIntegerValue(state));
+
+ PrefKeySet pref_keys;
+ GetExtensionControlledPrefKeys(extension->id(), &pref_keys);
+ UpdatePrefStore(pref_keys);
+
SavePrefsAndNotify();
}
@@ -841,6 +853,18 @@ DictionaryValue* ExtensionPrefs::GetExtensionPref(
return extension;
}
+DictionaryValue* ExtensionPrefs::GetExtensionControlledPrefs(
+ const std::string& extension_id) const {
+ DictionaryValue* extension = GetExtensionPref(extension_id);
+ if (!extension) {
+ NOTREACHED();
+ return NULL;
+ }
+ DictionaryValue* preferences = NULL;
+ extension->GetDictionary(kPrefPreferences, &preferences);
+ return preferences;
+}
+
// Helper function for GetInstalledExtensionsInfo.
static ExtensionInfo* GetInstalledExtensionInfoImpl(
DictionaryValue* extension_data,
@@ -1100,6 +1124,175 @@ std::string ExtensionPrefs::GetUpdateUrlData(const std::string& extension_id) {
return data;
}
+base::Time ExtensionPrefs::GetCurrentTime() const {
+ return base::Time::Now();
+}
+
+base::Time ExtensionPrefs::GetInstallTime(
+ const std::string& extension_id) const {
+ const DictionaryValue* extension = GetExtensionPref(extension_id);
+ if (!extension) {
+ NOTREACHED();
+ return base::Time();
+ }
+ std::string install_time_str("0");
+ extension->GetString(kPrefInstallTime, &install_time_str);
+ int64 install_time_i64 = 0;
+ base::StringToInt64(install_time_str, &install_time_i64);
+ LOG_IF(ERROR, install_time_i64 == 0)
+ << "Error parsing installation time of an extension.";
+ return base::Time::FromInternalValue(install_time_i64);
+}
+
+void ExtensionPrefs::GetEnabledExtensions(ExtensionIdSet* out) const {
+ CHECK(out);
+ const DictionaryValue* extensions =
+ pref_service()->GetDictionary(kExtensionsPref);
+
+ for (DictionaryValue::key_iterator ext_id = extensions->begin_keys();
+ ext_id != extensions->end_keys(); ++ext_id) {
+ if (GetExtensionState(*ext_id) != Extension::ENABLED)
+ continue;
+ out->push_back(*ext_id);
+ }
+}
+
+void ExtensionPrefs::FixMissingPrefs(const ExtensionIdSet& extension_ids) {
+ // Fix old entries that did not get an installation time entry when they
+ // were installed or don't have a preferences field.
+ bool persist_required = false;
+ for (ExtensionIdSet::const_iterator ext_id = extension_ids.begin();
+ ext_id != extension_ids.end(); ++ext_id) {
+ DictionaryValue* extension = GetExtensionPref(*ext_id);
+ CHECK(extension);
+
+ if (GetInstallTime(*ext_id) == base::Time()) {
+ const base::Time install_time = GetCurrentTime();
+ extension->Set(kPrefInstallTime,
+ Value::CreateStringValue(
+ base::Int64ToString(install_time.ToInternalValue())));
+ persist_required = true;
+ }
+ }
+ if (persist_required)
+ SavePrefsAndNotify();
+}
+
+void ExtensionPrefs::InitPrefStore() {
+ // When this is called, the PrefService is initialized and provides access
+ // to the user preferences stored in a JSON file.
+ ExtensionIdSet extension_ids;
+ GetEnabledExtensions(&extension_ids);
+ FixMissingPrefs(extension_ids);
+
+ // Collect the unique extension controlled preference keys of all extensions.
+ PrefKeySet ext_controlled_prefs;
+ for (ExtensionIdSet::iterator ext_id = extension_ids.begin();
+ ext_id != extension_ids.end(); ++ext_id) {
+ GetExtensionControlledPrefKeys(*ext_id, &ext_controlled_prefs);
+ }
+
+ // Store winning preference for each extension controlled preference.
+ UpdatePrefStore(ext_controlled_prefs);
+ pref_store_->OnInitializationCompleted();
+}
+
+const Value* ExtensionPrefs::GetWinningExtensionControlledPrefValue(
+ const std::string& key) const {
+ Value *winner = NULL;
+ base::Time winners_install_time = base::Time();
+
+ ExtensionIdSet extension_ids;
+ GetEnabledExtensions(&extension_ids);
+ for (ExtensionIdSet::iterator ext_id = extension_ids.begin();
+ ext_id != extension_ids.end(); ++ext_id) {
+ base::Time extension_install_time = GetInstallTime(*ext_id);
+
+ // We do not need to consider extensions that were installed before the
+ // most recent extension found that provides the requested preference.
+ if (extension_install_time < winners_install_time)
+ continue;
+
+ DictionaryValue* preferences = GetExtensionControlledPrefs(*ext_id);
+ Value *value = NULL;
+ if (preferences && preferences->GetWithoutPathExpansion(key, &value)) {
+ // This extension is more recent than the last one providing this pref.
+ winner = value;
+ winners_install_time = extension_install_time;
+ }
+ }
+
+ return winner;
+}
+
+void ExtensionPrefs::UpdatePrefStore(
+ const ExtensionPrefs::PrefKeySet& pref_keys) {
+ for (PrefKeySet::const_iterator i = pref_keys.begin();
+ i != pref_keys.end(); ++i) {
+ UpdatePrefStore(*i);
+ }
+}
+
+void ExtensionPrefs::UpdatePrefStore(const std::string& pref_key) {
+ if (pref_store_ == NULL)
+ return;
+ const Value* winning_pref_value =
+ GetWinningExtensionControlledPrefValue(pref_key);
+
+ if (winning_pref_value)
+ pref_store_->SetExtensionPref(pref_key, winning_pref_value->DeepCopy());
+ else
+ pref_store_->RemoveExtensionPref(pref_key);
+}
+
+void ExtensionPrefs::SetExtensionControlledPref(const std::string& extension_id,
+ const std::string& pref_key,
+ Value* value) {
+ scoped_ptr<Value> scoped_value(value);
+ DCHECK(pref_service()->FindPreference(pref_key.c_str()))
+ << "Extension controlled preference key " << pref_key
+ << " not registered.";
+ DictionaryValue* extension_preferences =
+ GetExtensionControlledPrefs(extension_id);
+
+ if (extension_preferences == NULL) { // May be pruned when writing to disk.
+ DictionaryValue* extension = GetExtensionPref(extension_id);
+ if (extension == NULL) {
+ LOG(ERROR) << "Extension preference for " << extension_id << " undefined";
+ return;
+ }
+ extension_preferences = new DictionaryValue;
+ extension->Set(kPrefPreferences, extension_preferences);
+ }
+
+ Value* oldValue = NULL;
+ extension_preferences->GetWithoutPathExpansion(pref_key, &oldValue);
+ bool modified = !Value::Equals(oldValue, scoped_value.get());
+ if (!modified)
+ return;
+
+ if (scoped_value.get() == NULL)
+ extension_preferences->RemoveWithoutPathExpansion(pref_key, NULL);
+ else
+ extension_preferences->SetWithoutPathExpansion(pref_key,
+ scoped_value.release());
+ pref_service()->ScheduleSavePersistentPrefs();
+
+ UpdatePrefStore(pref_key);
+}
+
+void ExtensionPrefs::GetExtensionControlledPrefKeys(
+ const std::string& extension_id, PrefKeySet *out) const {
+ DCHECK(out != NULL);
+ DictionaryValue* ext_prefs = GetExtensionControlledPrefs(extension_id);
+ if (ext_prefs) {
+ for (DictionaryValue::key_iterator i = ext_prefs->begin_keys();
+ i != ext_prefs->end_keys(); ++i) {
+ out->insert(*i);
+ }
+ }
+}
+
// static
void ExtensionPrefs::RegisterUserPrefs(PrefService* prefs) {
prefs->RegisterDictionaryPref(kExtensionsPref);
diff --git a/chrome/browser/extensions/extension_prefs.h b/chrome/browser/extensions/extension_prefs.h
index 6245eda..8c8be82 100644
--- a/chrome/browser/extensions/extension_prefs.h
+++ b/chrome/browser/extensions/extension_prefs.h
@@ -16,9 +16,23 @@
#include "chrome/common/extensions/extension.h"
#include "googleurl/src/gurl.h"
+class ExtensionPrefStore;
+
// Class for managing global and per-extension preferences.
-// This class is instantiated by ExtensionsService, so it should be accessed
-// from there.
+//
+// This class distinguishes the following kinds of preferences:
+// - global preferences:
+// internal state for the extension system in general, not associated
+// with an individual extension, such as lastUpdateTime.
+// - per-extension preferences:
+// meta-preferences describing properties of the extension like
+// installation time, whether the extension is enabled, etc.
+// - extension controlled preferences:
+// browser preferences that an extension controls. For example, an
+// extension could use the proxy API to specify the browser's proxy
+// preference. Extension-controlled preferences are stored in
+// PrefValueStore::extension_prefs(), which this class populates and
+// maintains as the underlying extensions change.
class ExtensionPrefs {
public:
// Key name for a preference that keeps track of per-extension settings. This
@@ -28,6 +42,12 @@ class ExtensionPrefs {
typedef std::vector<linked_ptr<ExtensionInfo> > ExtensionsInfo;
+ // Vector containing identifiers for preferences.
+ typedef std::set<std::string> PrefKeySet;
+
+ // Vector containing identifiers for extensions.
+ typedef std::vector<std::string> ExtensionIdSet;
+
// This enum is used for the launch type the user wants to use for an
// application.
// Do not remove items or re-order this enum as it is used in preferences
@@ -39,7 +59,9 @@ class ExtensionPrefs {
LAUNCH_WINDOW
};
- explicit ExtensionPrefs(PrefService* prefs, const FilePath& root_dir_);
+ explicit ExtensionPrefs(PrefService* prefs,
+ const FilePath& root_dir,
+ ExtensionPrefStore* extension_pref_store);
~ExtensionPrefs();
// Returns a copy of the Extensions prefs.
@@ -47,8 +69,9 @@ class ExtensionPrefs {
// aware of the internal structure of the preferences.
DictionaryValue* CopyCurrentExtensions();
- // Populate |killed_ids| with extension ids that have been killed.
- void GetKilledExtensionIds(std::set<std::string>* killed_ids);
+ // Returns true if the specified extension has an entry in prefs
+ // and its killbit is on.
+ bool IsExtensionKilled(const std::string& id);
// Get the order that toolstrip URLs appear in the shelf.
typedef std::vector<GURL> URLList;
@@ -74,11 +97,14 @@ class ExtensionPrefs {
bool external_uninstall);
// Returns the state (enabled/disabled) of the given extension.
- Extension::State GetExtensionState(const std::string& extension_id);
+ Extension::State GetExtensionState(const std::string& extension_id) const;
// Called to change the extension's state when it is enabled/disabled.
void SetExtensionState(const Extension* extension, Extension::State);
+ // Returns all installed and enabled extensions
+ void GetEnabledExtensions(ExtensionIdSet* out) const;
+
// Getter and setter for browser action visibility.
bool GetBrowserActionVisibility(const Extension* extension);
void SetBrowserActionVisibility(const Extension* extension, bool visible);
@@ -232,11 +258,23 @@ class ExtensionPrefs {
const std::string& data);
std::string GetUpdateUrlData(const std::string& extension_id);
+ // Sets a preference value that is controlled by the extension. In other
+ // words, this is not a pref value *about* the extension but something
+ // global the extension wants to override.
+ void SetExtensionControlledPref(const std::string& extension_id,
+ const std::string& pref_key,
+ Value* value);
+
static void RegisterUserPrefs(PrefService* prefs);
// The underlying PrefService.
PrefService* pref_service() const { return prefs_; }
+ protected:
+ // For unit testing. Enables injecting an artificial clock that is used
+ // to query the current time, when an extension is installed.
+ virtual base::Time GetCurrentTime() const;
+
private:
// Converts absolute paths in the pref to paths relative to the
// install_directory_.
@@ -296,6 +334,11 @@ class ExtensionPrefs {
// Same as above, but returns NULL if it doesn't exist.
DictionaryValue* GetExtensionPref(const std::string& id) const;
+ // Returns the dictionary of preferences controlled by the specified extension
+ // or NULL if unknown. All entries in the dictionary contain non-expanded
+ // paths.
+ DictionaryValue* GetExtensionControlledPrefs(const std::string& id) const;
+
// Serializes the data and schedules a persistent save via the |PrefService|.
// Additionally fires a PREF_CHANGED notification with the top-level
// |kExtensionsPref| path set.
@@ -313,12 +356,44 @@ class ExtensionPrefs {
base::Time LastPingDayImpl(const DictionaryValue* dictionary) const;
void SetLastPingDayImpl(const base::Time& time, DictionaryValue* dictionary);
+ // Helper method to acquire the installation time of an extension.
+ base::Time GetInstallTime(const std::string& extension_id) const;
+
+ // Fix missing preference entries in the extensions that are were introduced
+ // in a later Chrome version.
+ void FixMissingPrefs(const ExtensionIdSet& extension_ids);
+
+ // Installs the persistent extension preferences into |prefs_|'s extension
+ // pref store.
+ void InitPrefStore();
+
+ // Returns the extension controlled preference value of the extension that was
+ // installed most recently.
+ const Value* GetWinningExtensionControlledPrefValue(
+ const std::string& key) const;
+
+ // Executes UpdatePrefStore for all |pref_keys|.
+ void UpdatePrefStore(const PrefKeySet& pref_keys);
+
+ // Finds the most recently installed extension that defines a preference
+ // for |pref_key|, then stores its value in the PrefValueStore's extension
+ // pref store and sends notifications to observers in case the value changed.
+ void UpdatePrefStore(const std::string& pref_key);
+
+ // Retrieves a list of preference keys that the specified extension
+ // intends to manage. Keys are always appended, |out| is not cleared.
+ void GetExtensionControlledPrefKeys(const std::string& extension_id,
+ PrefKeySet *out) const;
+
// The pref service specific to this set of extension prefs.
PrefService* prefs_;
// Base extensions install directory.
FilePath install_directory_;
+ // Used to manipulate extension preferences.
+ ExtensionPrefStore* pref_store_;
+
// The URLs of all of the toolstrips.
URLList shelf_order_;
diff --git a/chrome/browser/extensions/extension_prefs_unittest.cc b/chrome/browser/extensions/extension_prefs_unittest.cc
index d6dcc23..6b59740 100644
--- a/chrome/browser/extensions/extension_prefs_unittest.cc
+++ b/chrome/browser/extensions/extension_prefs_unittest.cc
@@ -8,17 +8,31 @@
#include "base/stl_util-inl.h"
#include "base/string_number_conversions.h"
#include "base/stringprintf.h"
-#include "chrome/browser/browser_thread.h"
#include "chrome/browser/extensions/extension_prefs.h"
#include "chrome/browser/extensions/test_extension_prefs.h"
+#include "chrome/browser/prefs/pref_change_registrar.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/extensions/extension_constants.h"
+#include "chrome/common/notification_details.h"
+#include "chrome/common/notification_observer_mock.h"
+#include "chrome/common/notification_source.h"
#include "testing/gtest/include/gtest/gtest.h"
using base::Time;
using base::TimeDelta;
+const char kPref1[] = "path1.subpath";
+const char kPref2[] = "path2";
+const char kPref3[] = "path3";
+const char kPref4[] = "path4";
+
+// Default values in case an extension pref value is not overridden.
+const char kDefaultPref1[] = "default pref 1";
+const char kDefaultPref2[] = "default pref 2";
+const char kDefaultPref3[] = "default pref 3";
+const char kDefaultPref4[] = "default pref 4";
+
static void AddPattern(ExtensionExtent* extent, const std::string& pattern) {
int schemes = URLPattern::SCHEME_ALL;
extent->AddPattern(URLPattern(schemes, pattern));
@@ -55,7 +69,11 @@ class ExtensionPrefsTest : public testing::Test {
// things don't break after any ExtensionPrefs startup work.
virtual void Verify() = 0;
+ // This function is called to Register preference default values.
+ virtual void RegisterPreferences() {}
+
virtual void SetUp() {
+ RegisterPreferences();
Initialize();
}
@@ -64,6 +82,7 @@ class ExtensionPrefsTest : public testing::Test {
// Reset ExtensionPrefs, and re-verify.
prefs_.RecreateExtensionPrefs();
+ RegisterPreferences();
Verify();
}
@@ -527,3 +546,349 @@ class ExtensionPrefsAppLaunchIndex : public ExtensionPrefsTest {
scoped_refptr<Extension> extension_;
};
TEST_F(ExtensionPrefsAppLaunchIndex, ExtensionPrefsAppLaunchIndex) {}
+
+namespace keys = extension_manifest_keys;
+
+class ExtensionPrefsPreferencesBase : public ExtensionPrefsTest {
+ public:
+ ExtensionPrefsPreferencesBase()
+ : ExtensionPrefsTest(),
+ ext1_(NULL),
+ ext2_(NULL),
+ ext3_(NULL),
+ installed() {
+ DictionaryValue simple_dict;
+ std::string error;
+
+ simple_dict.SetString(keys::kVersion, "1.0.0.0");
+ simple_dict.SetString(keys::kName, "unused");
+
+ ext1_scoped_ = Extension::Create(
+ prefs_.temp_dir().AppendASCII("ext1_"), Extension::INVALID,
+ simple_dict, false, &error);
+ ext2_scoped_ = Extension::Create(
+ prefs_.temp_dir().AppendASCII("ext2_"), Extension::INVALID,
+ simple_dict, false, &error);
+ ext3_scoped_ = Extension::Create(
+ prefs_.temp_dir().AppendASCII("ext3_"), Extension::INVALID,
+ simple_dict, false, &error);
+
+ ext1_ = ext1_scoped_.get();
+ ext2_ = ext2_scoped_.get();
+ ext3_ = ext3_scoped_.get();
+
+ for (size_t i = 0; i < arraysize(installed); ++i)
+ installed[i] = false;
+ }
+
+ void RegisterPreferences() {
+ prefs()->pref_service()->RegisterStringPref(kPref1, kDefaultPref1);
+ prefs()->pref_service()->RegisterStringPref(kPref2, kDefaultPref2);
+ prefs()->pref_service()->RegisterStringPref(kPref3, kDefaultPref3);
+ prefs()->pref_service()->RegisterStringPref(kPref4, kDefaultPref4);
+ }
+
+ void InstallExtControlledPref(Extension *ext,
+ const std::string& key,
+ Value* val) {
+ // Install extension the first time a preference is set for it.
+ Extension* extensions[] = {ext1_, ext2_, ext3_};
+ for (int i = 0; i < 3; ++i) {
+ if (ext == extensions[i] && !installed[i]) {
+ prefs()->OnExtensionInstalled(ext, Extension::ENABLED, true);
+ installed[i] = true;
+ break;
+ }
+ }
+
+ prefs()->SetExtensionControlledPref(ext->id(), key, val);
+ }
+
+ void UninstallExtension(const std::string& extension_id) {
+ prefs()->OnExtensionUninstalled(extension_id, Extension::INTERNAL, false);
+ }
+
+ // Weak references, for convenience.
+ Extension* ext1_;
+ Extension* ext2_;
+ Extension* ext3_;
+
+ // Flags indicating whether each of the extensions has been installed, yet.
+ bool installed[3];
+
+ private:
+ scoped_refptr<Extension> ext1_scoped_;
+ scoped_refptr<Extension> ext2_scoped_;
+ scoped_refptr<Extension> ext3_scoped_;
+};
+
+class ExtensionPrefsInstallOneExtension
+ : public ExtensionPrefsPreferencesBase {
+ virtual void Initialize() {
+ InstallExtControlledPref(ext1_, kPref1, Value::CreateStringValue("val1"));
+ }
+ virtual void Verify() {
+ std::string actual = prefs()->pref_service()->GetString(kPref1);
+ EXPECT_EQ("val1", actual);
+ }
+};
+TEST_F(ExtensionPrefsInstallOneExtension, ExtensionPrefsInstallOneExtension) {}
+
+// Make sure the last-installed extension wins for each preference.
+class ExtensionPrefsInstallOverwrittenExtensions
+ : public ExtensionPrefsPreferencesBase {
+ virtual void Initialize() {
+ InstallExtControlledPref(ext1_, kPref1, Value::CreateStringValue("val1"));
+ InstallExtControlledPref(ext2_, kPref1, Value::CreateStringValue("val2"));
+ InstallExtControlledPref(ext3_, kPref1, Value::CreateStringValue("val3"));
+
+ InstallExtControlledPref(ext1_, kPref2, Value::CreateStringValue("val4"));
+ InstallExtControlledPref(ext2_, kPref2, Value::CreateStringValue("val5"));
+
+ InstallExtControlledPref(ext1_, kPref1, Value::CreateStringValue("val6"));
+ InstallExtControlledPref(ext1_, kPref2, Value::CreateStringValue("val7"));
+ InstallExtControlledPref(ext1_, kPref3, Value::CreateStringValue("val8"));
+ }
+ virtual void Verify() {
+ std::string actual;
+ actual = prefs()->pref_service()->GetString(kPref1);
+ EXPECT_EQ("val3", actual);
+ actual = prefs()->pref_service()->GetString(kPref2);
+ EXPECT_EQ("val5", actual);
+ actual = prefs()->pref_service()->GetString(kPref3);
+ EXPECT_EQ("val8", actual);
+ }
+};
+TEST_F(ExtensionPrefsInstallOverwrittenExtensions,
+ ExtensionPrefsInstallOverwrittenExtensions) {}
+
+// Make sure the last-installed extension wins even if other extensions set
+// the same or different preferences later.
+class ExtensionPrefsInstallInterleavedExtensions
+ : public ExtensionPrefsPreferencesBase {
+ virtual void Initialize() {
+ InstallExtControlledPref(ext1_, kPref1, Value::CreateStringValue("val1"));
+ InstallExtControlledPref(ext2_, kPref2, Value::CreateStringValue("val2"));
+ InstallExtControlledPref(ext3_, kPref3, Value::CreateStringValue("val3"));
+
+ InstallExtControlledPref(ext3_, kPref3, Value::CreateStringValue("val4"));
+ InstallExtControlledPref(ext2_, kPref3, Value::CreateStringValue("val5"));
+ InstallExtControlledPref(ext1_, kPref3, Value::CreateStringValue("val6"));
+
+ InstallExtControlledPref(ext3_, kPref1, Value::CreateStringValue("val7"));
+ }
+ virtual void Verify() {
+ std::string actual;
+ actual = prefs()->pref_service()->GetString(kPref1);
+ EXPECT_EQ("val7", actual);
+ actual = prefs()->pref_service()->GetString(kPref2);
+ EXPECT_EQ("val2", actual);
+ actual = prefs()->pref_service()->GetString(kPref3);
+ EXPECT_EQ("val4", actual);
+ }
+};
+TEST_F(ExtensionPrefsInstallInterleavedExtensions,
+ ExtensionPrefsInstallInterleavedExtensions) {}
+
+class ExtensionPrefsUninstallOnlyExtension
+ : public ExtensionPrefsPreferencesBase {
+ virtual void Initialize() {
+ InstallExtControlledPref(ext1_, kPref1, Value::CreateStringValue("val1"));
+ InstallExtControlledPref(ext1_, kPref2, Value::CreateStringValue("val2"));
+
+ UninstallExtension(ext1_->id());
+ }
+ virtual void Verify() {
+ std::string actual;
+ actual = prefs()->pref_service()->GetString(kPref1);
+ EXPECT_EQ(kDefaultPref1, actual);
+ actual = prefs()->pref_service()->GetString(kPref2);
+ EXPECT_EQ(kDefaultPref2, actual);
+ }
+};
+TEST_F(ExtensionPrefsUninstallOnlyExtension,
+ ExtensionPrefsUninstallOnlyExtension) {}
+
+// Tests uninstalling an extension that wasn't winning for any preferences.
+class ExtensionPrefsUninstallIrrelevantExtension
+ : public ExtensionPrefsPreferencesBase {
+ virtual void Initialize() {
+ InstallExtControlledPref(ext1_, kPref1, Value::CreateStringValue("val1"));
+ InstallExtControlledPref(ext2_, kPref1, Value::CreateStringValue("val2"));
+
+ InstallExtControlledPref(ext1_, kPref2, Value::CreateStringValue("val3"));
+ InstallExtControlledPref(ext2_, kPref2, Value::CreateStringValue("val4"));
+
+ UninstallExtension(ext1_->id());
+ }
+ virtual void Verify() {
+ std::string actual;
+ actual = prefs()->pref_service()->GetString(kPref1);
+ EXPECT_EQ("val2", actual);
+ actual = prefs()->pref_service()->GetString(kPref2);
+ EXPECT_EQ("val4", actual);
+ }
+};
+TEST_F(ExtensionPrefsUninstallIrrelevantExtension,
+ ExtensionPrefsUninstallIrrelevantExtension) {}
+
+// Tests uninstalling an extension that was winning for all preferences.
+class ExtensionPrefsUninstallExtensionFromTop
+ : public ExtensionPrefsPreferencesBase {
+ virtual void Initialize() {
+ InstallExtControlledPref(ext1_, kPref1, Value::CreateStringValue("val1"));
+ InstallExtControlledPref(ext2_, kPref1, Value::CreateStringValue("val2"));
+ InstallExtControlledPref(ext3_, kPref1, Value::CreateStringValue("val3"));
+
+ InstallExtControlledPref(ext1_, kPref2, Value::CreateStringValue("val4"));
+ InstallExtControlledPref(ext3_, kPref2, Value::CreateStringValue("val5"));
+
+ UninstallExtension(ext3_->id());
+ }
+ virtual void Verify() {
+ std::string actual;
+ actual = prefs()->pref_service()->GetString(kPref1);
+ EXPECT_EQ("val2", actual);
+ actual = prefs()->pref_service()->GetString(kPref2);
+ EXPECT_EQ("val4", actual);
+ }
+};
+TEST_F(ExtensionPrefsUninstallExtensionFromTop,
+ ExtensionPrefsUninstallExtensionFromTop) {}
+
+// Tests uninstalling an extension that was winning for only some preferences.
+class ExtensionPrefsUninstallExtensionFromMiddle
+ : public ExtensionPrefsPreferencesBase {
+ virtual void Initialize() {
+ InstallExtControlledPref(ext1_, kPref1, Value::CreateStringValue("val1"));
+ InstallExtControlledPref(ext2_, kPref1, Value::CreateStringValue("val2"));
+ InstallExtControlledPref(ext3_, kPref1, Value::CreateStringValue("val3"));
+
+ InstallExtControlledPref(ext1_, kPref2, Value::CreateStringValue("val4"));
+ InstallExtControlledPref(ext2_, kPref2, Value::CreateStringValue("val5"));
+
+ InstallExtControlledPref(ext1_, kPref3, Value::CreateStringValue("val6"));
+
+ InstallExtControlledPref(ext2_, kPref4, Value::CreateStringValue("val7"));
+
+ UninstallExtension(ext2_->id());
+ }
+ virtual void Verify() {
+ std::string actual;
+ actual = prefs()->pref_service()->GetString(kPref1);
+ EXPECT_EQ("val3", actual);
+ actual = prefs()->pref_service()->GetString(kPref2);
+ EXPECT_EQ("val4", actual);
+ actual = prefs()->pref_service()->GetString(kPref3);
+ EXPECT_EQ("val6", actual);
+ actual = prefs()->pref_service()->GetString(kPref4);
+ EXPECT_EQ(kDefaultPref4, actual);
+ }
+};
+TEST_F(ExtensionPrefsUninstallExtensionFromMiddle,
+ ExtensionPrefsUninstallExtensionFromMiddle) {}
+
+// Tests triggering of notifications to registered observers
+class ExtensionPrefsNotifyWhenNeeded
+ : public ExtensionPrefsPreferencesBase {
+ virtual void Initialize() {
+ using testing::_;
+ using testing::Mock;
+ using testing::StrEq;
+
+ scoped_ptr<NotificationObserverMock> observer(
+ new NotificationObserverMock());
+ PrefChangeRegistrar registrar;
+ registrar.Init(prefs()->pref_service());
+ registrar.Add(kPref1, observer.get());
+
+ EXPECT_CALL(*observer, Observe(_, _, _));
+ InstallExtControlledPref(ext1_, kPref1,
+ Value::CreateStringValue("https://www.chromium.org"));
+ Mock::VerifyAndClearExpectations(observer.get());
+
+ EXPECT_CALL(*observer, Observe(_, _, _)).Times(0);
+ InstallExtControlledPref(ext1_, kPref1,
+ Value::CreateStringValue("https://www.chromium.org"));
+ Mock::VerifyAndClearExpectations(observer.get());
+
+ EXPECT_CALL(*observer, Observe(_, _, _)).Times(2);
+ InstallExtControlledPref(ext1_, kPref1,
+ Value::CreateStringValue("chrome://newtab"));
+
+ UninstallExtension(ext1_->id());
+ registrar.Remove(kPref1, observer.get());
+ }
+ virtual void Verify() {
+ std::string actual = prefs()->pref_service()->GetString(kPref1);
+ EXPECT_EQ(kDefaultPref1, actual);
+ }
+};
+TEST_F(ExtensionPrefsNotifyWhenNeeded,
+ ExtensionPrefsNotifyWhenNeeded) {}
+
+// Tests disabling an extension
+class ExtensionPrefsDisableExt
+ : public ExtensionPrefsPreferencesBase {
+ virtual void Initialize() {
+ InstallExtControlledPref(ext1_, kPref1, Value::CreateStringValue("val1"));
+ std::string actual = prefs()->pref_service()->GetString(kPref1);
+ EXPECT_EQ("val1", actual);
+ prefs()->SetExtensionState(ext1_, Extension::DISABLED);
+ }
+ virtual void Verify() {
+ std::string actual = prefs()->pref_service()->GetString(kPref1);
+ EXPECT_EQ(kDefaultPref1, actual);
+ }
+};
+TEST_F(ExtensionPrefsDisableExt, ExtensionPrefsDisableExt) {}
+
+// Tests disabling and reenabling an extension
+class ExtensionPrefsReenableExt
+ : public ExtensionPrefsPreferencesBase {
+ virtual void Initialize() {
+ InstallExtControlledPref(ext1_, kPref1, Value::CreateStringValue("val1"));
+ prefs()->SetExtensionState(ext1_, Extension::DISABLED);
+ prefs()->SetExtensionState(ext1_, Extension::ENABLED);
+ }
+ virtual void Verify() {
+ std::string actual = prefs()->pref_service()->GetString(kPref1);
+ EXPECT_EQ("val1", actual);
+ }
+};
+TEST_F(ExtensionPrefsDisableExt, ExtensionPrefsReenableExt) {}
+
+// Mock class to test whether objects are deleted correctly.
+class MockStringValue : public StringValue {
+ public:
+ explicit MockStringValue(const std::string& in_value)
+ : StringValue(in_value) {
+ }
+ virtual ~MockStringValue() {
+ Die();
+ }
+ MOCK_METHOD0(Die, void());
+};
+
+class ExtensionPrefsSetExtensionControlledPref
+ : public ExtensionPrefsPreferencesBase {
+ public:
+ virtual void Initialize() {
+ MockStringValue* v1 = new MockStringValue("https://www.chromium.org");
+ MockStringValue* v2 = new MockStringValue("https://www.chromium.org");
+ // Ownership is taken, value shall not be deleted.
+ EXPECT_CALL(*v1, Die()).Times(0);
+ InstallExtControlledPref(ext1_, kPref1, v1);
+ testing::Mock::VerifyAndClearExpectations(v1);
+ // Make sure there is no memory leak and both values are deleted.
+ EXPECT_CALL(*v2, Die()).Times(1);
+ EXPECT_CALL(*v1, Die()).Times(1);
+ InstallExtControlledPref(ext1_, kPref1, v2);
+ prefs_.RecreateExtensionPrefs();
+ }
+
+ virtual void Verify() {
+ }
+};
+TEST_F(ExtensionPrefsSetExtensionControlledPref,
+ ExtensionPrefsSetExtensionControlledPref) {}
diff --git a/chrome/browser/extensions/extension_process_manager.cc b/chrome/browser/extensions/extension_process_manager.cc
index c273033..03e868d 100644
--- a/chrome/browser/extensions/extension_process_manager.cc
+++ b/chrome/browser/extensions/extension_process_manager.cc
@@ -10,8 +10,8 @@
#include "chrome/browser/extensions/extension_host_mac.h"
#endif
#include "chrome/browser/extensions/extension_host.h"
-#include "chrome/browser/extensions/extensions_service.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_host/site_instance.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/tab_contents/tab_contents.h"
@@ -135,8 +135,8 @@ ExtensionHost* ExtensionProcessManager::CreateView(const GURL& url,
ViewType::Type view_type) {
// A NULL browser may only be given for pop-up views.
DCHECK(browser || (!browser && view_type == ViewType::EXTENSION_POPUP));
- ExtensionsService* service =
- browsing_instance_->profile()->GetExtensionsService();
+ ExtensionService* service =
+ browsing_instance_->profile()->GetExtensionService();
if (service) {
const Extension* extension = service->GetExtensionByURL(url);
if (extension)
@@ -226,8 +226,8 @@ void ExtensionProcessManager::RegisterExtensionProcess(
DCHECK(it == process_ids_.end());
process_ids_[extension_id] = process_id;
- ExtensionsService* extension_service =
- browsing_instance_->profile()->GetExtensionsService();
+ ExtensionService* extension_service =
+ browsing_instance_->profile()->GetExtensionService();
std::vector<std::string> page_action_ids;
const Extension* extension =
@@ -281,13 +281,13 @@ void ExtensionProcessManager::Observe(NotificationType type,
switch (type.value) {
case NotificationType::EXTENSIONS_READY: {
CreateBackgroundHosts(this,
- Source<Profile>(source).ptr()->GetExtensionsService()->extensions());
+ Source<Profile>(source).ptr()->GetExtensionService()->extensions());
break;
}
case NotificationType::EXTENSION_LOADED: {
- ExtensionsService* service =
- Source<Profile>(source).ptr()->GetExtensionsService();
+ ExtensionService* service =
+ Source<Profile>(source).ptr()->GetExtensionService();
if (service->is_ready()) {
const Extension* extension = Details<const Extension>(details).ptr();
::CreateBackgroundHost(this, extension);
@@ -296,7 +296,8 @@ void ExtensionProcessManager::Observe(NotificationType type,
}
case NotificationType::EXTENSION_UNLOADED: {
- const Extension* extension = Details<const Extension>(details).ptr();
+ const Extension* extension =
+ Details<UnloadedExtensionInfo>(details)->extension;
for (ExtensionHostSet::iterator iter = background_hosts_.begin();
iter != background_hosts_.end(); ++iter) {
ExtensionHost* host = *iter;
@@ -427,8 +428,8 @@ RenderProcessHost* IncognitoExtensionProcessManager::GetExtensionProcess(
const Extension* IncognitoExtensionProcessManager::GetExtensionOrAppByURL(
const GURL& url) {
- ExtensionsService* service =
- browsing_instance_->profile()->GetExtensionsService();
+ ExtensionService* service =
+ browsing_instance_->profile()->GetExtensionService();
if (!service)
return NULL;
return (url.SchemeIs(chrome::kExtensionScheme)) ?
@@ -437,8 +438,8 @@ const Extension* IncognitoExtensionProcessManager::GetExtensionOrAppByURL(
bool IncognitoExtensionProcessManager::IsIncognitoEnabled(
const Extension* extension) {
- ExtensionsService* service =
- browsing_instance_->profile()->GetExtensionsService();
+ ExtensionService* service =
+ browsing_instance_->profile()->GetExtensionService();
return service && service->IsIncognitoEnabled(extension);
}
@@ -456,8 +457,8 @@ void IncognitoExtensionProcessManager::Observe(
// On Chrome OS, a login screen is implemented as a browser.
// This browser has no extension service. In this case,
// service will be NULL.
- ExtensionsService* service =
- browsing_instance_->profile()->GetExtensionsService();
+ ExtensionService* service =
+ browsing_instance_->profile()->GetExtensionService();
if (service && service->is_ready())
CreateBackgroundHosts(this, service->extensions());
}
diff --git a/chrome/browser/extensions/extension_processes_api.cc b/chrome/browser/extensions/extension_processes_api.cc
index 99b72e8..5edc2f0 100644
--- a/chrome/browser/extensions/extension_processes_api.cc
+++ b/chrome/browser/extensions/extension_processes_api.cc
@@ -16,13 +16,12 @@
#include "chrome/browser/extensions/extension_processes_api_constants.h"
#include "chrome/browser/extensions/extension_tabs_module.h"
#include "chrome/browser/extensions/extension_tabs_module_constants.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/tab_contents/tab_contents.h"
-#include "chrome/browser/tab_contents_wrapper.h"
#include "chrome/browser/task_manager/task_manager.h"
+#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/common/extensions/extension_error_utils.h"
-#include "chrome/common/notification_service.h"
#include "chrome/common/notification_type.h"
namespace keys = extension_processes_api_constants;
diff --git a/chrome/browser/extensions/extension_protocols.cc b/chrome/browser/extensions/extension_protocols.cc
index edf937b..e95f18d 100644
--- a/chrome/browser/extensions/extension_protocols.cc
+++ b/chrome/browser/extensions/extension_protocols.cc
@@ -32,15 +32,15 @@
namespace {
-class URLRequestResourceBundleJob : public URLRequestSimpleJob {
+class URLRequestResourceBundleJob : public net::URLRequestSimpleJob {
public:
- explicit URLRequestResourceBundleJob(URLRequest* request,
+ explicit URLRequestResourceBundleJob(net::URLRequest* request,
const FilePath& filename, int resource_id)
- : URLRequestSimpleJob(request),
+ : net::URLRequestSimpleJob(request),
filename_(filename),
resource_id_(resource_id) { }
- // URLRequestSimpleJob method.
+ // Overridden from URLRequestSimpleJob:
virtual bool GetData(std::string* mime_type,
std::string* charset,
std::string* data) const {
@@ -67,7 +67,7 @@ class URLRequestResourceBundleJob : public URLRequestSimpleJob {
};
// Returns true if an chrome-extension:// resource should be allowed to load.
-bool AllowExtensionResourceLoad(URLRequest* request,
+bool AllowExtensionResourceLoad(net::URLRequest* request,
ChromeURLRequestContext* context,
const std::string& scheme) {
const ResourceDispatcherHostRequestInfo* info =
@@ -142,16 +142,17 @@ bool AllowExtensionResourceLoad(URLRequest* request,
} // namespace
-// Factory registered with URLRequest to create URLRequestJobs for extension://
-// URLs.
-static URLRequestJob* CreateExtensionURLRequestJob(URLRequest* request,
- const std::string& scheme) {
+// Factory registered with net::URLRequest to create URLRequestJobs for
+// extension:// URLs.
+static net::URLRequestJob* CreateExtensionURLRequestJob(
+ net::URLRequest* request,
+ const std::string& scheme) {
ChromeURLRequestContext* context =
static_cast<ChromeURLRequestContext*>(request->context());
// TODO(mpcomplete): better error code.
if (!AllowExtensionResourceLoad(request, context, scheme))
- return new URLRequestErrorJob(request, net::ERR_ADDRESS_UNREACHABLE);
+ return new net::URLRequestErrorJob(request, net::ERR_ADDRESS_UNREACHABLE);
// chrome-extension://extension-id/resource/path.js
const std::string& extension_id = request->url().host();
@@ -198,13 +199,14 @@ static URLRequestJob* CreateExtensionURLRequestJob(URLRequest* request,
base::ThreadRestrictions::ScopedAllowIO allow_io;
resource_file_path = resource.GetFilePath();
}
- return new URLRequestFileJob(request, resource_file_path);
+ return new net::URLRequestFileJob(request, resource_file_path);
}
-// Factory registered with URLRequest to create URLRequestJobs for
+// Factory registered with net::URLRequest to create URLRequestJobs for
// chrome-user-script:/ URLs.
-static URLRequestJob* CreateUserScriptURLRequestJob(URLRequest* request,
- const std::string& scheme) {
+static net::URLRequestJob* CreateUserScriptURLRequestJob(
+ net::URLRequest* request,
+ const std::string& scheme) {
ChromeURLRequestContext* context =
static_cast<ChromeURLRequestContext*>(request->context());
@@ -214,12 +216,12 @@ static URLRequestJob* CreateUserScriptURLRequestJob(URLRequest* request,
ExtensionResource resource(request->url().host(), directory_path,
extension_file_util::ExtensionURLToRelativeFilePath(request->url()));
- return new URLRequestFileJob(request, resource.GetFilePath());
+ return new net::URLRequestFileJob(request, resource.GetFilePath());
}
void RegisterExtensionProtocols() {
- URLRequest::RegisterProtocolFactory(chrome::kExtensionScheme,
- &CreateExtensionURLRequestJob);
- URLRequest::RegisterProtocolFactory(chrome::kUserScriptScheme,
- &CreateUserScriptURLRequestJob);
+ net::URLRequest::RegisterProtocolFactory(chrome::kExtensionScheme,
+ &CreateExtensionURLRequestJob);
+ net::URLRequest::RegisterProtocolFactory(chrome::kUserScriptScheme,
+ &CreateUserScriptURLRequestJob);
}
diff --git a/chrome/browser/extensions/extension_proxy_api.cc b/chrome/browser/extensions/extension_proxy_api.cc
index 030b711..d71c055 100644
--- a/chrome/browser/extensions/extension_proxy_api.cc
+++ b/chrome/browser/extensions/extension_proxy_api.cc
@@ -7,8 +7,9 @@
#include "base/string_util.h"
#include "base/stringprintf.h"
#include "base/values.h"
-#include "chrome/browser/extensions/extension_pref_store.h"
-#include "chrome/common/notification_service.h"
+#include "chrome/browser/prefs/proxy_prefs.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/extensions/extension_service.h"
#include "chrome/common/pref_names.h"
namespace {
@@ -53,8 +54,8 @@ bool UseCustomProxySettingsFunction::RunImpl() {
DictionaryValue* proxy_config;
EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &proxy_config));
- bool auto_detect = false;
- proxy_config->GetBoolean("autoDetect", &auto_detect);
+ std::string proxy_mode;
+ proxy_config->GetString("mode", &proxy_mode);
DictionaryValue* pac_dict = NULL;
proxy_config->GetDictionary("pacScript", &pac_dict);
@@ -62,7 +63,9 @@ bool UseCustomProxySettingsFunction::RunImpl() {
DictionaryValue* proxy_rules = NULL;
proxy_config->GetDictionary("rules", &proxy_rules);
- return ApplyAutoDetect(auto_detect) &&
+ // TODO(battre,gfeher): Make sure all the preferences get always
+ // overwritten.
+ return ApplyMode(proxy_mode) &&
ApplyPacScript(pac_dict) &&
ApplyProxyRules(proxy_rules);
}
@@ -75,13 +78,19 @@ bool UseCustomProxySettingsFunction::GetProxyServer(
return true;
}
-bool UseCustomProxySettingsFunction::ApplyAutoDetect(bool auto_detect) {
- // We take control of the auto-detect preference even if none was specified,
- // so that all proxy preferences are controlled by the same extension (if not
- // by a higher-priority source).
- SendNotification(prefs::kProxyAutoDetect,
- Value::CreateBooleanValue(auto_detect));
- return true;
+bool UseCustomProxySettingsFunction::ApplyMode(const std::string& mode) {
+ // We take control of the mode preference even if none was specified, so that
+ // all proxy preferences are controlled by the same extension (if not by a
+ // higher-priority source).
+ bool result = true;
+ ProxyPrefs::ProxyMode mode_enum;
+ if (!ProxyPrefs::StringToProxyMode(mode, &mode_enum)) {
+ mode_enum = ProxyPrefs::MODE_SYSTEM;
+ LOG(WARNING) << "Invalid mode for proxy settings: " << mode;
+ result = false;
+ }
+ ApplyPreference(prefs::kProxyMode, Value::CreateIntegerValue(mode_enum));
+ return result;
}
bool UseCustomProxySettingsFunction::ApplyPacScript(DictionaryValue* pac_dict) {
@@ -92,14 +101,16 @@ bool UseCustomProxySettingsFunction::ApplyPacScript(DictionaryValue* pac_dict) {
// We take control of the PAC preference even if none was specified, so that
// all proxy preferences are controlled by the same extension (if not by a
// higher-priority source).
- SendNotification(prefs::kProxyPacUrl, Value::CreateStringValue(pac_url));
+ ApplyPreference(prefs::kProxyPacUrl, Value::CreateStringValue(pac_url));
return true;
}
bool UseCustomProxySettingsFunction::ApplyProxyRules(
DictionaryValue* proxy_rules) {
- if (!proxy_rules)
+ if (!proxy_rules) {
+ ApplyPreference(prefs::kProxyServer, Value::CreateStringValue(""));
return true;
+ }
// Local data into which the parameters will be parsed. has_proxy describes
// whether a setting was found for the scheme; proxy_dict holds the
@@ -153,17 +164,12 @@ bool UseCustomProxySettingsFunction::ApplyProxyRules(
}
}
- SendNotification(prefs::kProxyServer, Value::CreateStringValue(proxy_pref));
+ ApplyPreference(prefs::kProxyServer, Value::CreateStringValue(proxy_pref));
return true;
}
-void UseCustomProxySettingsFunction::SendNotification(const char* pref_path,
- Value* pref_value) {
- ExtensionPrefStore::ExtensionPrefDetails details =
- std::make_pair(GetExtension(), std::make_pair(pref_path, pref_value));
-
- NotificationService::current()->Notify(
- NotificationType::EXTENSION_PREF_CHANGED,
- Source<Profile>(profile_),
- Details<ExtensionPrefStore::ExtensionPrefDetails>(&details));
+void UseCustomProxySettingsFunction::ApplyPreference(const char* pref_path,
+ Value* pref_value) {
+ profile()->GetExtensionService()->extension_prefs()
+ ->SetExtensionControlledPref(extension_id(), pref_path, pref_value);
}
diff --git a/chrome/browser/extensions/extension_proxy_api.h b/chrome/browser/extensions/extension_proxy_api.h
index 95be304..d645c44 100644
--- a/chrome/browser/extensions/extension_proxy_api.h
+++ b/chrome/browser/extensions/extension_proxy_api.h
@@ -33,14 +33,12 @@ class UseCustomProxySettingsFunction : public SyncExtensionFunction {
bool GetProxyServer(const DictionaryValue* dict, ProxyServer* proxy_server);
- bool ApplyAutoDetect(bool auto_detect);
+ bool ApplyMode(const std::string& mode);
bool ApplyPacScript(DictionaryValue* pac_dict);
bool ApplyProxyRules(DictionaryValue* proxy_rules);
- // Sends a notification that the given pref would like to change to the
- // indicated pref_value. This is mainly useful so the ExtensionPrefStore can
- // apply the requested change.
- void SendNotification(const char* pref_path, Value* pref_value);
+ // Takes ownership of |pref_value|.
+ void ApplyPreference(const char* pref_path, Value* pref_value);
};
#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_PROXY_API_H_
diff --git a/chrome/browser/extensions/extension_proxy_apitest.cc b/chrome/browser/extensions/extension_proxy_apitest.cc
index 7f83407..5537f32 100644
--- a/chrome/browser/extensions/extension_proxy_apitest.cc
+++ b/chrome/browser/extensions/extension_proxy_apitest.cc
@@ -4,13 +4,46 @@
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/prefs/pref_service.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/prefs/proxy_prefs.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/pref_names.h"
-// Tests auto-detect and PAC proxy settings.
+// Tests direct connection settings.
+IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ProxyDirectSettings) {
+ CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kEnableExperimentalExtensionApis);
+
+ ASSERT_TRUE(RunExtensionTest("proxy/direct")) << message_;
+ const Extension* extension = GetSingleLoadedExtension();
+ ASSERT_TRUE(extension);
+
+ PrefService* pref_service = browser()->profile()->GetPrefs();
+
+ const PrefService::Preference* pref =
+ pref_service->FindPreference(prefs::kProxyMode);
+ ASSERT_TRUE(pref != NULL);
+ ASSERT_TRUE(pref->IsExtensionControlled());
+ int mode = pref_service->GetInteger(prefs::kProxyMode);
+ EXPECT_EQ(ProxyPrefs::MODE_DIRECT, mode);
+
+ // Other proxy prefs should also be set, so they're all controlled from one
+ // place.
+ pref = pref_service->FindPreference(prefs::kProxyPacUrl);
+ ASSERT_TRUE(pref != NULL);
+ EXPECT_TRUE(pref->IsExtensionControlled());
+ EXPECT_EQ("", pref_service->GetString(prefs::kProxyPacUrl));
+
+ // No manual proxy prefs were set.
+ pref = pref_service->FindPreference(prefs::kProxyServer);
+ ASSERT_TRUE(pref != NULL);
+ EXPECT_TRUE(pref->IsExtensionControlled());
+ EXPECT_EQ("", pref_service->GetString(prefs::kProxyServer));
+}
+
+// Tests auto-detect settings.
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ProxyAutoSettings) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableExperimentalExtensionApis);
@@ -22,11 +55,37 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ProxyAutoSettings) {
PrefService* pref_service = browser()->profile()->GetPrefs();
const PrefService::Preference* pref =
- pref_service->FindPreference(prefs::kProxyAutoDetect);
+ pref_service->FindPreference(prefs::kProxyMode);
+ ASSERT_TRUE(pref != NULL);
+ ASSERT_TRUE(pref->IsExtensionControlled());
+ int mode = pref_service->GetInteger(prefs::kProxyMode);
+ EXPECT_EQ(ProxyPrefs::MODE_AUTO_DETECT, mode);
+
+ // Other proxy prefs should also be set, so they're all controlled from one
+ // place.
+ pref = pref_service->FindPreference(prefs::kProxyPacUrl);
+ ASSERT_TRUE(pref != NULL);
+ EXPECT_TRUE(pref->IsExtensionControlled());
+ EXPECT_EQ("", pref_service->GetString(prefs::kProxyPacUrl));
+}
+
+// Tests PAC proxy settings.
+IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ProxyPacScript) {
+ CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kEnableExperimentalExtensionApis);
+
+ ASSERT_TRUE(RunExtensionTest("proxy/pac")) << message_;
+ const Extension* extension = GetSingleLoadedExtension();
+ ASSERT_TRUE(extension);
+
+ PrefService* pref_service = browser()->profile()->GetPrefs();
+
+ const PrefService::Preference* pref =
+ pref_service->FindPreference(prefs::kProxyMode);
ASSERT_TRUE(pref != NULL);
ASSERT_TRUE(pref->IsExtensionControlled());
- bool auto_detect = pref_service->GetBoolean(prefs::kProxyAutoDetect);
- EXPECT_TRUE(auto_detect);
+ int mode = pref_service->GetInteger(prefs::kProxyMode);
+ EXPECT_EQ(ProxyPrefs::MODE_PAC_SCRIPT, mode);
pref = pref_service->FindPreference(prefs::kProxyPacUrl);
ASSERT_TRUE(pref != NULL);
@@ -37,11 +96,12 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ProxyAutoSettings) {
// No manual proxy prefs were set.
pref = pref_service->FindPreference(prefs::kProxyServer);
ASSERT_TRUE(pref != NULL);
- EXPECT_TRUE(pref->IsDefaultValue());
+ EXPECT_TRUE(pref->IsExtensionControlled());
+ EXPECT_EQ("", pref_service->GetString(prefs::kProxyServer));
}
// Tests setting a single proxy to cover all schemes.
-IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ProxyManualSingle) {
+IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ProxyFixedSingle) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableExperimentalExtensionApis);
@@ -64,19 +124,53 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ProxyManualSingle) {
// Other proxy prefs should also be set, so they're all controlled from one
// place.
- pref = pref_service->FindPreference(prefs::kProxyAutoDetect);
+ pref = pref_service->FindPreference(prefs::kProxyMode);
+ ASSERT_TRUE(pref != NULL);
+ EXPECT_TRUE(pref->IsExtensionControlled());
+ EXPECT_EQ(ProxyPrefs::MODE_FIXED_SERVERS,
+ pref_service->GetInteger(prefs::kProxyMode));
+
+ pref = pref_service->FindPreference(prefs::kProxyPacUrl);
ASSERT_TRUE(pref != NULL);
EXPECT_TRUE(pref->IsExtensionControlled());
- EXPECT_FALSE(pref_service->GetBoolean(prefs::kProxyAutoDetect));
+ EXPECT_EQ("", pref_service->GetString(prefs::kProxyPacUrl));
+}
+
+// Tests setting to use the system's proxy settings.
+IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ProxySystem) {
+ CommandLine::ForCurrentProcess()->AppendSwitch(
+ switches::kEnableExperimentalExtensionApis);
+
+ ASSERT_TRUE(RunExtensionTest("proxy/system")) << message_;
+ const Extension* extension = GetSingleLoadedExtension();
+ ASSERT_TRUE(extension);
+
+ PrefService* pref_service = browser()->profile()->GetPrefs();
+
+ // There should be no values superseding the extension-set proxy in this test.
+ const PrefService::Preference* pref =
+ pref_service->FindPreference(prefs::kProxyMode);
+ ASSERT_TRUE(pref != NULL);
+ ASSERT_TRUE(pref->IsExtensionControlled());
+ int proxy_server_mode = pref_service->GetInteger(prefs::kProxyMode);
+ EXPECT_EQ(ProxyPrefs::MODE_SYSTEM, proxy_server_mode);
+ // Other proxy prefs should also be set, so they're all controlled from one
+ // place.
pref = pref_service->FindPreference(prefs::kProxyPacUrl);
ASSERT_TRUE(pref != NULL);
EXPECT_TRUE(pref->IsExtensionControlled());
EXPECT_EQ("", pref_service->GetString(prefs::kProxyPacUrl));
+
+ // No manual proxy prefs were set.
+ pref = pref_service->FindPreference(prefs::kProxyServer);
+ ASSERT_TRUE(pref != NULL);
+ EXPECT_TRUE(pref->IsExtensionControlled());
+ EXPECT_EQ("", pref_service->GetString(prefs::kProxyServer));
}
// Tests setting separate proxies for each scheme.
-IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ProxyManualIndividual) {
+IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ProxyFixedIndividual) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableExperimentalExtensionApis);
@@ -100,10 +194,11 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ProxyManualIndividual) {
// Other proxy prefs should also be set, so they're all controlled from one
// place.
- pref = pref_service->FindPreference(prefs::kProxyAutoDetect);
+ pref = pref_service->FindPreference(prefs::kProxyMode);
ASSERT_TRUE(pref != NULL);
EXPECT_TRUE(pref->IsExtensionControlled());
- EXPECT_FALSE(pref_service->GetBoolean(prefs::kProxyAutoDetect));
+ EXPECT_EQ(ProxyPrefs::MODE_FIXED_SERVERS,
+ pref_service->GetInteger(prefs::kProxyMode));
pref = pref_service->FindPreference(prefs::kProxyPacUrl);
ASSERT_TRUE(pref != NULL);
diff --git a/chrome/browser/extensions/extension_rlz_apitest.cc b/chrome/browser/extensions/extension_rlz_apitest.cc
index 10bfba6..efb275a 100644
--- a/chrome/browser/extensions/extension_rlz_apitest.cc
+++ b/chrome/browser/extensions/extension_rlz_apitest.cc
@@ -5,7 +5,6 @@
#include <map>
#include "base/win/registry.h"
-#include "chrome/browser/browser_process.h"
#include "chrome/browser/extensions/extension_function.h"
#include "chrome/browser/extensions/extension_function_dispatcher.h"
#include "chrome/browser/extensions/extension_apitest.h"
diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extension_service.cc
index 6842a84..bb24e1e 100644
--- a/chrome/browser/extensions/extensions_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/extensions/extension_service.h"
#include <algorithm>
@@ -47,10 +47,8 @@
#include "chrome/browser/extensions/external_pref_extension_provider.h"
#include "chrome/browser/net/chrome_url_request_context.h"
#include "chrome/browser/prefs/pref_service.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search_engines/template_url_model.h"
-#include "chrome/browser/sync/glue/extension_sync_traits.h"
-#include "chrome/browser/sync/glue/extension_util.h"
#include "chrome/common/child_process_logging.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension.h"
@@ -146,14 +144,14 @@ void GetExplicitOriginsInExtent(const Extension* extension,
PendingExtensionInfo::PendingExtensionInfo(
const GURL& update_url,
- PendingExtensionInfo::ExpectedCrxType expected_crx_type,
+ ShouldInstallExtensionPredicate should_install_extension,
bool is_from_sync,
bool install_silently,
bool enable_on_install,
bool enable_incognito_on_install,
Extension::Location location)
: update_url(update_url),
- expected_crx_type(expected_crx_type),
+ should_install_extension(should_install_extension),
is_from_sync(is_from_sync),
install_silently(install_silently),
enable_on_install(enable_on_install),
@@ -162,7 +160,7 @@ PendingExtensionInfo::PendingExtensionInfo(
PendingExtensionInfo::PendingExtensionInfo()
: update_url(),
- expected_crx_type(PendingExtensionInfo::UNKNOWN),
+ should_install_extension(NULL),
is_from_sync(true),
install_silently(false),
enable_on_install(false),
@@ -170,27 +168,27 @@ PendingExtensionInfo::PendingExtensionInfo()
install_source(Extension::INVALID) {}
-ExtensionsService::ExtensionRuntimeData::ExtensionRuntimeData()
+ExtensionService::ExtensionRuntimeData::ExtensionRuntimeData()
: background_page_ready(false),
being_upgraded(false) {
}
-ExtensionsService::ExtensionRuntimeData::~ExtensionRuntimeData() {
+ExtensionService::ExtensionRuntimeData::~ExtensionRuntimeData() {
}
-// ExtensionsService.
+// ExtensionService.
-const char* ExtensionsService::kInstallDirectoryName = "Extensions";
-const char* ExtensionsService::kCurrentVersionFileName = "Current Version";
+const char* ExtensionService::kInstallDirectoryName = "Extensions";
+const char* ExtensionService::kCurrentVersionFileName = "Current Version";
-// Implements IO for the ExtensionsService.
+// Implements IO for the ExtensionService.
-class ExtensionsServiceBackend
- : public base::RefCountedThreadSafe<ExtensionsServiceBackend>,
+class ExtensionServiceBackend
+ : public base::RefCountedThreadSafe<ExtensionServiceBackend>,
public ExternalExtensionProvider::Visitor {
public:
// |install_directory| is a path where to look for extensions to load.
- ExtensionsServiceBackend(PrefService* prefs,
+ ExtensionServiceBackend(PrefService* prefs,
const FilePath& install_directory);
// Loads a single extension from |path| where |path| is the top directory of
@@ -200,17 +198,16 @@ class ExtensionsServiceBackend
// TODO(erikkay): It might be useful to be able to load a packed extension
// (presumably into memory) without installing it.
void LoadSingleExtension(const FilePath &path,
- scoped_refptr<ExtensionsService> frontend);
+ scoped_refptr<ExtensionService> frontend);
// Check externally updated extensions for updates and install if necessary.
// Errors are reported through ExtensionErrorReporter. Succcess is not
// reported.
- void CheckForExternalUpdates(const std::set<std::string>& ids_to_ignore,
- scoped_refptr<ExtensionsService> frontend);
+ void CheckForExternalUpdates(scoped_refptr<ExtensionService> frontend);
// For the extension in |version_path| with |id|, check to see if it's an
// externally managed extension. If so, tell the frontend to uninstall it.
- void CheckExternalUninstall(scoped_refptr<ExtensionsService> frontend,
+ void CheckExternalUninstall(scoped_refptr<ExtensionService> frontend,
const std::string& id);
// Clear all ExternalExtensionProviders.
@@ -234,9 +231,9 @@ class ExtensionsServiceBackend
scoped_refptr<RefCountedList> forcelist);
private:
- friend class base::RefCountedThreadSafe<ExtensionsServiceBackend>;
+ friend class base::RefCountedThreadSafe<ExtensionServiceBackend>;
- virtual ~ExtensionsServiceBackend();
+ virtual ~ExtensionServiceBackend();
// Finish installing the extension in |crx_path| after it has been unpacked to
// |unpacked_path|. If |expected_id| is not empty, it's verified against the
@@ -256,7 +253,7 @@ class ExtensionsServiceBackend
// This is a naked pointer which is set by each entry point.
// The entry point is responsible for ensuring lifetime.
- ExtensionsService* frontend_;
+ ExtensionService* frontend_;
// The top-level extensions directory being installed to.
FilePath install_directory_;
@@ -278,10 +275,10 @@ class ExtensionsServiceBackend
// if an update check is needed to install pending extensions.
bool external_extension_added_;
- DISALLOW_COPY_AND_ASSIGN(ExtensionsServiceBackend);
+ DISALLOW_COPY_AND_ASSIGN(ExtensionServiceBackend);
};
-ExtensionsServiceBackend::ExtensionsServiceBackend(
+ExtensionServiceBackend::ExtensionServiceBackend(
PrefService* prefs,
const FilePath& install_directory)
: frontend_(NULL),
@@ -303,17 +300,16 @@ ExtensionsServiceBackend::ExtensionsServiceBackend(
// variable so that UpdateExternalPolicyExtensionProvider can access it and
// update its extension list later.
external_policy_extension_provider_.reset(
- new ExternalPolicyExtensionProvider());
- external_policy_extension_provider_->SetPreferences(
- prefs->GetList(prefs::kExtensionInstallForceList));
+ new ExternalPolicyExtensionProvider(
+ prefs->GetList(prefs::kExtensionInstallForceList)));
external_extension_providers_.push_back(external_policy_extension_provider_);
}
-ExtensionsServiceBackend::~ExtensionsServiceBackend() {
+ExtensionServiceBackend::~ExtensionServiceBackend() {
}
-void ExtensionsServiceBackend::LoadSingleExtension(
- const FilePath& path_in, scoped_refptr<ExtensionsService> frontend) {
+void ExtensionServiceBackend::LoadSingleExtension(
+ const FilePath& path_in, scoped_refptr<ExtensionService> frontend) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
frontend_ = frontend;
@@ -341,18 +337,18 @@ void ExtensionsServiceBackend::LoadSingleExtension(
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
NewRunnableMethod(frontend_,
- &ExtensionsService::OnExtensionInstalled,
+ &ExtensionService::OnExtensionInstalled,
extension));
}
-void ExtensionsServiceBackend::ReportExtensionLoadError(
+void ExtensionServiceBackend::ReportExtensionLoadError(
const FilePath& extension_path, const std::string &error) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
NewRunnableMethod(
frontend_,
- &ExtensionsService::ReportExtensionLoadError, extension_path,
+ &ExtensionService::ReportExtensionLoadError, extension_path,
error, NotificationType::EXTENSION_INSTALL_ERROR, alert_on_error_));
}
@@ -362,9 +358,8 @@ void ExtensionsServiceBackend::ReportExtensionLoadError(
// (and also, on Windows, in the registry) and this code will periodically
// check that location for a .crx file, which it will then install locally if
// a new version is available.
-void ExtensionsServiceBackend::CheckForExternalUpdates(
- const std::set<std::string>& ids_to_ignore,
- scoped_refptr<ExtensionsService> frontend) {
+void ExtensionServiceBackend::CheckForExternalUpdates(
+ scoped_refptr<ExtensionService> frontend) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
// Note that this installation is intentionally silent (since it didn't
@@ -382,7 +377,7 @@ void ExtensionsServiceBackend::CheckForExternalUpdates(
for (i = external_extension_providers_.begin();
i != external_extension_providers_.end(); ++i) {
ExternalExtensionProvider* provider = i->get();
- provider->VisitRegisteredExtension(this, ids_to_ignore);
+ provider->VisitRegisteredExtension(this);
}
if (external_extension_added_ && frontend->updater()) {
@@ -393,8 +388,8 @@ void ExtensionsServiceBackend::CheckForExternalUpdates(
}
}
-void ExtensionsServiceBackend::CheckExternalUninstall(
- scoped_refptr<ExtensionsService> frontend, const std::string& id) {
+void ExtensionServiceBackend::CheckExternalUninstall(
+ scoped_refptr<ExtensionService> frontend, const std::string& id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
// Check if the providers know about this extension.
@@ -409,27 +404,27 @@ void ExtensionsServiceBackend::CheckExternalUninstall(
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
NewRunnableMethod(
- frontend.get(), &ExtensionsService::UninstallExtension, id, true));
+ frontend.get(), &ExtensionService::UninstallExtension, id, true));
}
-void ExtensionsServiceBackend::UpdateExternalPolicyExtensionProvider(
+void ExtensionServiceBackend::UpdateExternalPolicyExtensionProvider(
scoped_refptr<RefCountedList> forcelist) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
external_policy_extension_provider_->SetPreferences(forcelist->Get());
}
-void ExtensionsServiceBackend::ClearProvidersForTesting() {
+void ExtensionServiceBackend::ClearProvidersForTesting() {
external_extension_providers_.clear();
}
-void ExtensionsServiceBackend::AddProviderForTesting(
+void ExtensionServiceBackend::AddProviderForTesting(
ExternalExtensionProvider* test_provider) {
DCHECK(test_provider);
external_extension_providers_.push_back(
linked_ptr<ExternalExtensionProvider>(test_provider));
}
-void ExtensionsServiceBackend::OnExternalExtensionFileFound(
+void ExtensionServiceBackend::OnExternalExtensionFileFound(
const std::string& id, const Version* version, const FilePath& path,
Extension::Location location) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
@@ -438,11 +433,11 @@ void ExtensionsServiceBackend::OnExternalExtensionFileFound(
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
NewRunnableMethod(
- frontend_, &ExtensionsService::OnExternalExtensionFileFound, id,
+ frontend_, &ExtensionService::OnExternalExtensionFileFound, id,
version->GetString(), path, location));
}
-void ExtensionsServiceBackend::OnExternalExtensionUpdateUrlFound(
+void ExtensionServiceBackend::OnExternalExtensionUpdateUrlFound(
const std::string& id,
const GURL& update_url,
Extension::Location location) {
@@ -457,12 +452,12 @@ void ExtensionsServiceBackend::OnExternalExtensionUpdateUrlFound(
BrowserThread::UI, FROM_HERE,
NewRunnableMethod(
frontend_,
- &ExtensionsService::AddPendingExtensionFromExternalUpdateUrl,
+ &ExtensionService::AddPendingExtensionFromExternalUpdateUrl,
id, update_url, location));
external_extension_added_ |= true;
}
-bool ExtensionsService::IsDownloadFromGallery(const GURL& download_url,
+bool ExtensionService::IsDownloadFromGallery(const GURL& download_url,
const GURL& referrer_url) {
// Special-case the themes mini-gallery.
// TODO(erikkay) When that gallery goes away, remove this code.
@@ -511,15 +506,25 @@ bool ExtensionsService::IsDownloadFromGallery(const GURL& download_url,
return (referrer_valid && download_valid);
}
-bool ExtensionsService::IsDownloadFromMiniGallery(const GURL& download_url) {
+bool ExtensionService::IsDownloadFromMiniGallery(const GURL& download_url) {
return StartsWithASCII(download_url.spec(),
extension_urls::kMiniGalleryDownloadPrefix,
false); // case_sensitive
}
+bool ExtensionService::IsInstalledApp(const GURL& url) {
+ // Check for hosted app.
+ if (GetExtensionByWebExtent(url) != NULL)
+ return true;
+
+ // Check for packaged app.
+ const Extension* extension = GetExtensionByURL(url);
+ return extension != NULL && extension->is_app();
+}
+
// static
-bool ExtensionsService::UninstallExtensionHelper(
- ExtensionsService* extensions_service,
+bool ExtensionService::UninstallExtensionHelper(
+ ExtensionService* extensions_service,
const std::string& extension_id) {
DCHECK(extensions_service);
@@ -536,20 +541,19 @@ bool ExtensionsService::UninstallExtensionHelper(
return true;
}
-ExtensionsService::ExtensionsService(Profile* profile,
+ExtensionService::ExtensionService(Profile* profile,
const CommandLine* command_line,
const FilePath& install_directory,
+ ExtensionPrefs* extension_prefs,
bool autoupdate_enabled)
: profile_(profile),
- extension_prefs_(new ExtensionPrefs(profile->GetPrefs(),
- install_directory)),
+ extension_prefs_(extension_prefs),
install_directory_(install_directory),
extensions_enabled_(true),
show_extensions_prompts_(true),
ready_(false),
ALLOW_THIS_IN_INITIALIZER_LIST(toolbar_model_(this)),
- default_apps_(profile->GetPrefs(),
- g_browser_process->GetApplicationLocale()),
+ default_apps_(profile->GetPrefs()),
event_routers_initialized_(false) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -580,7 +584,7 @@ ExtensionsService::ExtensionsService(Profile* profile,
update_frequency);
}
- backend_ = new ExtensionsServiceBackend(profile->GetPrefs(),
+ backend_ = new ExtensionServiceBackend(profile->GetPrefs(),
install_directory_);
// Use monochrome icons for Omnibox icons.
@@ -590,7 +594,23 @@ ExtensionsService::ExtensionsService(Profile* profile,
0, kOmniboxIconPaddingRight));
}
-ExtensionsService::~ExtensionsService() {
+const ExtensionList* ExtensionService::extensions() const {
+ return &extensions_;
+}
+
+const ExtensionList* ExtensionService::disabled_extensions() const {
+ return &disabled_extensions_;
+}
+
+const PendingExtensionMap& ExtensionService::pending_extensions() const {
+ return pending_extensions_;
+}
+
+bool ExtensionService::HasInstalledExtensions() {
+ return !(extensions_.empty() && disabled_extensions_.empty());
+}
+
+ExtensionService::~ExtensionService() {
DCHECK(!profile_); // Profile should have told us it's going away.
UnloadAllExtensions();
if (updater_.get()) {
@@ -598,14 +618,14 @@ ExtensionsService::~ExtensionsService() {
}
}
-void ExtensionsService::InitEventRouters() {
+void ExtensionService::InitEventRouters() {
if (event_routers_initialized_)
return;
ExtensionHistoryEventRouter::GetInstance()->ObserveProfile(profile_);
ExtensionAccessibilityEventRouter::GetInstance()->ObserveProfile(profile_);
ExtensionBrowserEventRouter::GetInstance()->Init(profile_);
- ExtensionBookmarkEventRouter::GetSingleton()->Observe(
+ ExtensionBookmarkEventRouter::GetInstance()->Observe(
profile_->GetBookmarkModel());
ExtensionCookiesEventRouter::GetInstance()->Init();
ExtensionManagementEventRouter::GetInstance()->Init();
@@ -614,7 +634,12 @@ void ExtensionsService::InitEventRouters() {
event_routers_initialized_ = true;
}
-void ExtensionsService::Init() {
+const Extension* ExtensionService::GetExtensionById(const std::string& id,
+ bool include_disabled) {
+ return GetExtensionByIdInternal(id, true, include_disabled);
+}
+
+void ExtensionService::Init() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK(!ready_); // Can't redo init.
@@ -634,7 +659,7 @@ void ExtensionsService::Init() {
GarbageCollectExtensions();
}
-void ExtensionsService::InstallExtension(const FilePath& extension_path) {
+void ExtensionService::InstallExtension(const FilePath& extension_path) {
scoped_refptr<CrxInstaller> installer(
new CrxInstaller(this, // frontend
NULL)); // no client (silent install)
@@ -650,7 +675,7 @@ namespace {
}
} // namespace
-void ExtensionsService::UpdateExtension(const std::string& id,
+void ExtensionService::UpdateExtension(const std::string& id,
const FilePath& extension_path,
const GURL& download_url) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -689,9 +714,9 @@ void ExtensionsService::UpdateExtension(const std::string& id,
installer->InstallCrx(extension_path);
}
-void ExtensionsService::AddPendingExtensionFromSync(
+void ExtensionService::AddPendingExtensionFromSync(
const std::string& id, const GURL& update_url,
- PendingExtensionInfo::ExpectedCrxType expected_crx_type,
+ ShouldInstallExtensionPredicate should_install_extension,
bool install_silently, bool enable_on_install,
bool enable_incognito_on_install) {
if (GetExtensionByIdInternal(id, true, true)) {
@@ -700,22 +725,29 @@ void ExtensionsService::AddPendingExtensionFromSync(
return;
}
- AddPendingExtensionInternal(id, update_url, expected_crx_type, true,
+ AddPendingExtensionInternal(id, update_url, should_install_extension, true,
install_silently, enable_on_install,
enable_incognito_on_install,
Extension::INTERNAL);
}
-void ExtensionsService::AddPendingExtensionFromExternalUpdateUrl(
+namespace {
+
+bool AlwaysInstall(const Extension& extension) {
+ return true;
+}
+
+} // namespace
+
+void ExtensionService::AddPendingExtensionFromExternalUpdateUrl(
const std::string& id, const GURL& update_url,
Extension::Location location) {
- // Add the extension to this list of extensions to update.
- const PendingExtensionInfo::ExpectedCrxType kExpectedCrxType =
- PendingExtensionInfo::UNKNOWN;
const bool kIsFromSync = false;
const bool kInstallSilently = true;
const bool kEnableOnInstall = true;
const bool kEnableIncognitoOnInstall = false;
+ if (extension_prefs_->IsExtensionKilled(id))
+ return;
if (GetExtensionByIdInternal(id, true, true)) {
LOG(DFATAL) << "Trying to add extension " << id
@@ -723,17 +755,25 @@ void ExtensionsService::AddPendingExtensionFromExternalUpdateUrl(
return;
}
- AddPendingExtensionInternal(id, update_url, kExpectedCrxType, kIsFromSync,
- kInstallSilently, kEnableOnInstall,
- kEnableIncognitoOnInstall,
+ AddPendingExtensionInternal(id, update_url, &AlwaysInstall,
+ kIsFromSync, kInstallSilently,
+ kEnableOnInstall, kEnableIncognitoOnInstall,
location);
}
-void ExtensionsService::AddPendingExtensionFromDefaultAppList(
+namespace {
+
+bool IsApp(const Extension& extension) {
+ return extension.is_app();
+}
+
+} // namespace
+
+// TODO(akalin): Change DefaultAppList to DefaultExtensionList and
+// remove the IsApp() check.
+
+void ExtensionService::AddPendingExtensionFromDefaultAppList(
const std::string& id) {
- // Add the extension to this list of extensions to update.
- const PendingExtensionInfo::ExpectedCrxType kExpectedCrxType =
- PendingExtensionInfo::APP;
const bool kIsFromSync = false;
const bool kInstallSilently = true;
const bool kEnableOnInstall = true;
@@ -744,15 +784,15 @@ void ExtensionsService::AddPendingExtensionFromDefaultAppList(
if (GetExtensionByIdInternal(id, true, true))
return;
- AddPendingExtensionInternal(id, GURL(), kExpectedCrxType, kIsFromSync,
- kInstallSilently, kEnableOnInstall,
- kEnableIncognitoOnInstall,
+ AddPendingExtensionInternal(id, GURL(), &IsApp,
+ kIsFromSync, kInstallSilently,
+ kEnableOnInstall, kEnableIncognitoOnInstall,
Extension::INTERNAL);
}
-void ExtensionsService::AddPendingExtensionInternal(
+void ExtensionService::AddPendingExtensionInternal(
const std::string& id, const GURL& update_url,
- PendingExtensionInfo::ExpectedCrxType expected_crx_type,
+ ShouldInstallExtensionPredicate should_install_extension,
bool is_from_sync, bool install_silently,
bool enable_on_install, bool enable_incognito_on_install,
Extension::Location install_source) {
@@ -776,14 +816,13 @@ void ExtensionsService::AddPendingExtensionInternal(
return;
}
-
pending_extensions_[id] =
- PendingExtensionInfo(update_url, expected_crx_type, is_from_sync,
- install_silently, enable_on_install,
+ PendingExtensionInfo(update_url, should_install_extension,
+ is_from_sync, install_silently, enable_on_install,
enable_incognito_on_install, install_source);
}
-void ExtensionsService::ReloadExtension(const std::string& extension_id) {
+void ExtensionService::ReloadExtension(const std::string& extension_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
FilePath path;
const Extension* current_extension = GetExtensionById(extension_id, false);
@@ -826,7 +865,7 @@ void ExtensionsService::ReloadExtension(const std::string& extension_id) {
}
}
-void ExtensionsService::UninstallExtension(const std::string& extension_id,
+void ExtensionService::UninstallExtension(const std::string& extension_id,
bool external_uninstall) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -843,7 +882,7 @@ void ExtensionsService::UninstallExtension(const std::string& extension_id,
UninstalledExtensionInfo uninstalled_extension_info(*extension);
UMA_HISTOGRAM_ENUMERATION("Extensions.UninstallType",
- extension->GetHistogramType(), 100);
+ extension->GetType(), 100);
// Also copy the extension identifier since the reference might have been
// obtained via Extension::id().
@@ -854,7 +893,7 @@ void ExtensionsService::UninstallExtension(const std::string& extension_id,
// Unload before doing more cleanup to ensure that nothing is hanging on to
// any of these resources.
- UnloadExtension(extension_id);
+ UnloadExtension(extension_id, UnloadedExtensionInfo::UNINSTALL);
extension_prefs_->OnExtensionUninstalled(extension_id_copy, location,
external_uninstall);
@@ -878,13 +917,13 @@ void ExtensionsService::UninstallExtension(const std::string& extension_id,
Details<UninstalledExtensionInfo>(&uninstalled_extension_info));
}
-void ExtensionsService::ClearExtensionData(const GURL& extension_url) {
+void ExtensionService::ClearExtensionData(const GURL& extension_url) {
scoped_refptr<ExtensionDataDeleter> deleter(
new ExtensionDataDeleter(profile_, extension_url));
deleter->StartDeleting();
}
-void ExtensionsService::EnableExtension(const std::string& extension_id) {
+void ExtensionService::EnableExtension(const std::string& extension_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
const Extension* extension =
@@ -911,7 +950,7 @@ void ExtensionsService::EnableExtension(const std::string& extension_id) {
UpdateActiveExtensionsInCrashReporter();
}
-void ExtensionsService::DisableExtension(const std::string& extension_id) {
+void ExtensionService::DisableExtension(const std::string& extension_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
const Extension* extension =
@@ -932,11 +971,11 @@ void ExtensionsService::DisableExtension(const std::string& extension_id) {
ExtensionDOMUI::UnregisterChromeURLOverrides(profile_,
extension->GetChromeURLOverrides());
- NotifyExtensionUnloaded(extension);
+ NotifyExtensionUnloaded(extension, UnloadedExtensionInfo::DISABLE);
UpdateActiveExtensionsInCrashReporter();
}
-void ExtensionsService::GrantPermissions(const Extension* extension) {
+void ExtensionService::GrantPermissions(const Extension* extension) {
CHECK(extension);
// We only maintain the granted permissions prefs for INTERNAL extensions.
@@ -949,7 +988,7 @@ void ExtensionsService::GrantPermissions(const Extension* extension) {
effective_hosts);
}
-void ExtensionsService::GrantPermissionsAndEnableExtension(
+void ExtensionService::GrantPermissionsAndEnableExtension(
const Extension* extension) {
CHECK(extension);
GrantPermissions(extension);
@@ -957,16 +996,16 @@ void ExtensionsService::GrantPermissionsAndEnableExtension(
EnableExtension(extension->id());
}
-void ExtensionsService::LoadExtension(const FilePath& extension_path) {
+void ExtensionService::LoadExtension(const FilePath& extension_path) {
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
NewRunnableMethod(
backend_.get(),
- &ExtensionsServiceBackend::LoadSingleExtension,
- extension_path, scoped_refptr<ExtensionsService>(this)));
+ &ExtensionServiceBackend::LoadSingleExtension,
+ extension_path, scoped_refptr<ExtensionService>(this)));
}
-void ExtensionsService::LoadComponentExtensions() {
+void ExtensionService::LoadComponentExtensions() {
for (RegisteredComponentExtensions::iterator it =
component_extension_manifests_.begin();
it != component_extension_manifests_.end(); ++it) {
@@ -993,7 +1032,7 @@ void ExtensionsService::LoadComponentExtensions() {
}
}
-void ExtensionsService::LoadAllExtensions() {
+void ExtensionService::LoadAllExtensions() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
base::TimeTicks start_time = base::TimeTicks::Now();
@@ -1072,7 +1111,7 @@ void ExtensionsService::LoadAllExtensions() {
ExtensionList::iterator ex;
for (ex = extensions_.begin(); ex != extensions_.end(); ++ex) {
Extension::Location location = (*ex)->location();
- Extension::HistogramType type = (*ex)->GetHistogramType();
+ Extension::Type type = (*ex)->GetType();
if ((*ex)->is_app()) {
UMA_HISTOGRAM_ENUMERATION("Extensions.AppLocation",
location, 100);
@@ -1134,7 +1173,7 @@ void ExtensionsService::LoadAllExtensions() {
browser_action_count);
}
-void ExtensionsService::LoadInstalledExtension(const ExtensionInfo& info,
+void ExtensionService::LoadInstalledExtension(const ExtensionInfo& info,
bool write_to_prefs) {
std::string error;
scoped_refptr<const Extension> extension(NULL);
@@ -1167,13 +1206,13 @@ void ExtensionsService::LoadInstalledExtension(const ExtensionInfo& info,
BrowserThread::FILE, FROM_HERE,
NewRunnableMethod(
backend_.get(),
- &ExtensionsServiceBackend::CheckExternalUninstall,
- scoped_refptr<ExtensionsService>(this),
+ &ExtensionServiceBackend::CheckExternalUninstall,
+ scoped_refptr<ExtensionService>(this),
info.extension_id));
}
}
-void ExtensionsService::NotifyExtensionLoaded(const Extension* extension) {
+void ExtensionService::NotifyExtensionLoaded(const Extension* extension) {
// The ChromeURLRequestContexts need to be first to know that the extension
// was loaded, otherwise a race can arise where a renderer that is created
// for the extension may try to load an extension URL with an extension id
@@ -1199,11 +1238,13 @@ void ExtensionsService::NotifyExtensionLoaded(const Extension* extension) {
Details<const Extension>(extension));
}
-void ExtensionsService::NotifyExtensionUnloaded(const Extension* extension) {
+void ExtensionService::NotifyExtensionUnloaded(
+ const Extension* extension, UnloadedExtensionInfo::Reason reason) {
+ UnloadedExtensionInfo details(extension, reason);
NotificationService::current()->Notify(
NotificationType::EXTENSION_UNLOADED,
Source<Profile>(profile_),
- Details<const Extension>(extension));
+ Details<UnloadedExtensionInfo>(&details));
if (profile_) {
profile_->UnregisterExtensionWithRequestContexts(extension);
@@ -1219,7 +1260,7 @@ void ExtensionsService::NotifyExtensionUnloaded(const Extension* extension) {
}
}
-void ExtensionsService::GrantProtectedStorage(const Extension* extension) {
+void ExtensionService::GrantProtectedStorage(const Extension* extension) {
DCHECK(extension->is_app()) << "Only Apps are allowed protected storage.";
std::vector<GURL> origins;
GetExplicitOriginsInExtent(extension, &origins);
@@ -1227,7 +1268,7 @@ void ExtensionsService::GrantProtectedStorage(const Extension* extension) {
++protected_storage_map_[origins[i]];
}
-void ExtensionsService::RevokeProtectedStorage(const Extension* extension) {
+void ExtensionService::RevokeProtectedStorage(const Extension* extension) {
DCHECK(extension->is_app()) << "Attempting to revoke protected storage from "
<< " a non-app extension.";
std::vector<GURL> origins;
@@ -1240,7 +1281,7 @@ void ExtensionsService::RevokeProtectedStorage(const Extension* extension) {
}
}
-void ExtensionsService::GrantUnlimitedStorage(const Extension* extension) {
+void ExtensionService::GrantUnlimitedStorage(const Extension* extension) {
DCHECK(extension->HasApiPermission(Extension::kUnlimitedStoragePermission));
std::vector<GURL> origins;
GetExplicitOriginsInExtent(extension, &origins);
@@ -1269,13 +1310,13 @@ void ExtensionsService::GrantUnlimitedStorage(const Extension* extension) {
BrowserThread::IO, FROM_HERE,
NewRunnableMethod(
profile_->GetFileSystemContext(),
- &BrowserFileSystemContext::SetOriginQuotaUnlimited,
+ &fileapi::SandboxedFileSystemContext::SetOriginQuotaUnlimited,
origin));
}
}
}
-void ExtensionsService::RevokeUnlimitedStorage(const Extension* extension) {
+void ExtensionService::RevokeUnlimitedStorage(const Extension* extension) {
DCHECK(extension->HasApiPermission(Extension::kUnlimitedStoragePermission));
std::vector<GURL> origins;
GetExplicitOriginsInExtent(extension, &origins);
@@ -1304,13 +1345,13 @@ void ExtensionsService::RevokeUnlimitedStorage(const Extension* extension) {
BrowserThread::IO, FROM_HERE,
NewRunnableMethod(
profile_->GetFileSystemContext(),
- &BrowserFileSystemContext::ResetOriginQuotaUnlimited,
+ &fileapi::SandboxedFileSystemContext::ResetOriginQuotaUnlimited,
origin));
}
}
}
-void ExtensionsService::UpdateExtensionBlacklist(
+void ExtensionService::UpdateExtensionBlacklist(
const std::vector<std::string>& blacklist) {
// Use this set to indicate if an extension in the blacklist has been used.
std::set<std::string> blacklist_set;
@@ -1333,17 +1374,21 @@ void ExtensionsService::UpdateExtensionBlacklist(
// UnloadExtension will change the extensions_ list. So, we should
// call it outside the iterator loop.
for (unsigned int i = 0; i < to_be_removed.size(); ++i) {
- UnloadExtension(to_be_removed[i]);
+ UnloadExtension(to_be_removed[i], UnloadedExtensionInfo::DISABLE);
}
}
-void ExtensionsService::DestroyingProfile() {
+void ExtensionService::DestroyingProfile() {
pref_change_registrar_.RemoveAll();
profile_ = NULL;
toolbar_model_.DestroyingProfile();
}
-void ExtensionsService::CheckAdminBlacklist() {
+ExtensionPrefs* ExtensionService::extension_prefs() {
+ return extension_prefs_;
+}
+
+void ExtensionService::CheckAdminBlacklist() {
std::vector<std::string> to_be_removed;
// Loop through extensions list, unload installed extensions.
for (ExtensionList::const_iterator iter = extensions_.begin();
@@ -1356,10 +1401,10 @@ void ExtensionsService::CheckAdminBlacklist() {
// UnloadExtension will change the extensions_ list. So, we should
// call it outside the iterator loop.
for (unsigned int i = 0; i < to_be_removed.size(); ++i)
- UnloadExtension(to_be_removed[i]);
+ UnloadExtension(to_be_removed[i], UnloadedExtensionInfo::DISABLE);
}
-bool ExtensionsService::IsIncognitoEnabled(const Extension* extension) {
+bool ExtensionService::IsIncognitoEnabled(const Extension* extension) {
// If this is a component extension we always allow it to work in incognito
// mode.
if (extension->location() == Extension::COMPONENT)
@@ -1369,7 +1414,7 @@ bool ExtensionsService::IsIncognitoEnabled(const Extension* extension) {
return extension_prefs_->IsIncognitoEnabled(extension->id());
}
-void ExtensionsService::SetIsIncognitoEnabled(const Extension* extension,
+void ExtensionService::SetIsIncognitoEnabled(const Extension* extension,
bool enabled) {
extension_prefs_->SetIsIncognitoEnabled(extension->id(), enabled);
@@ -1378,25 +1423,25 @@ void ExtensionsService::SetIsIncognitoEnabled(const Extension* extension,
bool is_enabled = std::find(extensions_.begin(), extensions_.end(),
extension) != extensions_.end();
if (is_enabled) {
- NotifyExtensionUnloaded(extension);
+ NotifyExtensionUnloaded(extension, UnloadedExtensionInfo::DISABLE);
NotifyExtensionLoaded(extension);
}
}
-bool ExtensionsService::CanCrossIncognito(const Extension* extension) {
+bool ExtensionService::CanCrossIncognito(const Extension* extension) {
// We allow the extension to see events and data from another profile iff it
// uses "spanning" behavior and it has incognito access. "split" mode
// extensions only see events for a matching profile.
return IsIncognitoEnabled(extension) && !extension->incognito_split_mode();
}
-bool ExtensionsService::AllowFileAccess(const Extension* extension) {
+bool ExtensionService::AllowFileAccess(const Extension* extension) {
return (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableExtensionsFileAccessCheck) ||
extension_prefs_->AllowFileAccess(extension->id()));
}
-void ExtensionsService::SetAllowFileAccess(const Extension* extension,
+void ExtensionService::SetAllowFileAccess(const Extension* extension,
bool allow) {
extension_prefs_->SetAllowFileAccess(extension->id(), allow);
NotificationService::current()->Notify(
@@ -1405,29 +1450,24 @@ void ExtensionsService::SetAllowFileAccess(const Extension* extension,
Details<const Extension>(extension));
}
-bool ExtensionsService::GetBrowserActionVisibility(const Extension* extension) {
+bool ExtensionService::GetBrowserActionVisibility(const Extension* extension) {
return extension_prefs_->GetBrowserActionVisibility(extension);
}
-void ExtensionsService::SetBrowserActionVisibility(const Extension* extension,
+void ExtensionService::SetBrowserActionVisibility(const Extension* extension,
bool visible) {
extension_prefs_->SetBrowserActionVisibility(extension, visible);
}
-void ExtensionsService::CheckForExternalUpdates() {
- // This installs or updates externally provided extensions.
- // TODO(aa): Why pass this list into the provider, why not just filter it
- // later?
- std::set<std::string> killed_extensions;
- extension_prefs_->GetKilledExtensionIds(&killed_extensions);
+void ExtensionService::CheckForExternalUpdates() {
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
NewRunnableMethod(
- backend_.get(), &ExtensionsServiceBackend::CheckForExternalUpdates,
- killed_extensions, scoped_refptr<ExtensionsService>(this)));
+ backend_.get(), &ExtensionServiceBackend::CheckForExternalUpdates,
+ scoped_refptr<ExtensionService>(this)));
}
-void ExtensionsService::UpdateExternalPolicyExtensionProvider() {
+void ExtensionService::UpdateExternalPolicyExtensionProvider() {
const ListValue* list_pref =
profile_->GetPrefs()->GetList(prefs::kExtensionInstallForceList);
ListValue* list_copy = NULL;
@@ -1437,12 +1477,14 @@ void ExtensionsService::UpdateExternalPolicyExtensionProvider() {
BrowserThread::FILE, FROM_HERE,
NewRunnableMethod(
backend_.get(),
- &ExtensionsServiceBackend::UpdateExternalPolicyExtensionProvider,
+ &ExtensionServiceBackend::UpdateExternalPolicyExtensionProvider,
scoped_refptr<RefCountedList>(
new RefCountedList(list_copy))));
}
-void ExtensionsService::UnloadExtension(const std::string& extension_id) {
+void ExtensionService::UnloadExtension(
+ const std::string& extension_id,
+ UnloadedExtensionInfo::Reason reason) {
// Make sure the extension gets deleted after we return from this function.
scoped_refptr<const Extension> extension(
GetExtensionByIdInternal(extension_id, true, true));
@@ -1469,11 +1511,13 @@ void ExtensionsService::UnloadExtension(const std::string& extension_id) {
disabled_extensions_.end(),
extension.get());
if (iter != disabled_extensions_.end()) {
+ UnloadedExtensionInfo details(extension, reason);
+ details.already_disabled = true;
disabled_extensions_.erase(iter);
NotificationService::current()->Notify(
- NotificationType::EXTENSION_UNLOADED_DISABLED,
+ NotificationType::EXTENSION_UNLOADED,
Source<Profile>(profile_),
- Details<const Extension>(extension.get()));
+ Details<UnloadedExtensionInfo>(&details));
return;
}
@@ -1482,11 +1526,11 @@ void ExtensionsService::UnloadExtension(const std::string& extension_id) {
// Remove the extension from our list.
extensions_.erase(iter);
- NotifyExtensionUnloaded(extension.get());
+ NotifyExtensionUnloaded(extension.get(), reason);
UpdateActiveExtensionsInCrashReporter();
}
-void ExtensionsService::UnloadAllExtensions() {
+void ExtensionService::UnloadAllExtensions() {
extensions_.clear();
disabled_extensions_.clear();
extension_runtime_data_.clear();
@@ -1496,13 +1540,13 @@ void ExtensionsService::UnloadAllExtensions() {
// or uninstalled, and UnloadAll is just part of shutdown.
}
-void ExtensionsService::ReloadExtensions() {
+void ExtensionService::ReloadExtensions() {
UnloadAllExtensions();
LoadAllExtensions();
}
-void ExtensionsService::GarbageCollectExtensions() {
- if (extension_prefs_->pref_service()->read_only())
+void ExtensionService::GarbageCollectExtensions() {
+ if (extension_prefs_->pref_service()->ReadOnly())
return;
scoped_ptr<ExtensionPrefs::ExtensionsInfo> info(
@@ -1526,7 +1570,7 @@ void ExtensionsService::GarbageCollectExtensions() {
}
}
-void ExtensionsService::OnLoadedInstalledExtensions() {
+void ExtensionService::OnLoadedInstalledExtensions() {
if (updater_.get()) {
updater_->Start();
}
@@ -1538,7 +1582,7 @@ void ExtensionsService::OnLoadedInstalledExtensions() {
NotificationService::NoDetails());
}
-void ExtensionsService::OnExtensionLoaded(const Extension* extension) {
+void ExtensionService::OnExtensionLoaded(const Extension* extension) {
// Ensure extension is deleted unless we transfer ownership.
scoped_refptr<const Extension> scoped_extension(extension);
@@ -1598,7 +1642,7 @@ void ExtensionsService::OnExtensionLoaded(const Extension* extension) {
}
}
-void ExtensionsService::DisableIfPrivilegeIncrease(const Extension* extension) {
+void ExtensionService::DisableIfPrivilegeIncrease(const Extension* extension) {
// We keep track of all permissions the user has granted each extension.
// This allows extensions to gracefully support backwards compatibility
// by including unknown permissions in their manifests. When the user
@@ -1654,8 +1698,10 @@ void ExtensionsService::DisableIfPrivilegeIncrease(const Extension* extension) {
}
if (is_extension_upgrade) {
- // CrxInstaller should have guaranteed that we aren't downgrading.
- CHECK(extension->version()->CompareTo(*(old->version())) >= 0);
+ // Other than for unpacked extensions, CrxInstaller should have guaranteed
+ // that we aren't downgrading.
+ if (extension->location() != Extension::LOAD)
+ CHECK(extension->version()->CompareTo(*(old->version())) >= 0);
// Extensions get upgraded if the privileges are allowed to increase or
// the privileges haven't increased.
@@ -1666,7 +1712,7 @@ void ExtensionsService::DisableIfPrivilegeIncrease(const Extension* extension) {
// To upgrade an extension in place, unload the old one and
// then load the new one.
- UnloadExtension(old->id());
+ UnloadExtension(old->id(), UnloadedExtensionInfo::UPDATE);
old = NULL;
}
@@ -1678,7 +1724,7 @@ void ExtensionsService::DisableIfPrivilegeIncrease(const Extension* extension) {
}
}
-void ExtensionsService::UpdateActiveExtensionsInCrashReporter() {
+void ExtensionService::UpdateActiveExtensionsInCrashReporter() {
std::set<std::string> extension_ids;
for (size_t i = 0; i < extensions_.size(); ++i) {
if (!extensions_[i]->is_theme() &&
@@ -1689,7 +1735,7 @@ void ExtensionsService::UpdateActiveExtensionsInCrashReporter() {
child_process_logging::SetActiveExtensions(extension_ids);
}
-void ExtensionsService::OnExtensionInstalled(const Extension* extension) {
+void ExtensionService::OnExtensionInstalled(const Extension* extension) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
// Ensure extension is deleted unless we transfer ownership.
@@ -1700,25 +1746,17 @@ void ExtensionsService::OnExtensionInstalled(const Extension* extension) {
pending_extensions_.find(extension->id());
if (it != pending_extensions_.end()) {
PendingExtensionInfo pending_extension_info = it->second;
- PendingExtensionInfo::ExpectedCrxType expected_crx_type =
- pending_extension_info.expected_crx_type;
- bool is_from_sync = pending_extension_info.is_from_sync;
pending_extensions_.erase(it);
it = pending_extensions_.end();
- // Set initial state from pending extension data.
- PendingExtensionInfo::ExpectedCrxType actual_crx_type =
- PendingExtensionInfo::EXTENSION;
- if (extension->is_app())
- actual_crx_type = PendingExtensionInfo::APP;
- else if (extension->is_theme())
- actual_crx_type = PendingExtensionInfo::THEME;
-
- if (expected_crx_type != PendingExtensionInfo::UNKNOWN &&
- expected_crx_type != actual_crx_type) {
+ if (!pending_extension_info.should_install_extension(*extension)) {
LOG(WARNING)
- << "Not installing pending extension " << extension->id()
- << " with is_theme = " << extension->is_theme();
+ << "should_install_extension ("
+ << pending_extension_info.should_install_extension
+ << ") returned false for " << extension->id()
+ << " of type " << extension->GetType()
+ << " and update URL " << extension->update_url().spec()
+ << "; not installing";
// Delete the extension directory since we're not going to
// load it.
BrowserThread::PostTask(
@@ -1727,55 +1765,6 @@ void ExtensionsService::OnExtensionInstalled(const Extension* extension) {
return;
}
- // If |extension| is not syncable, and was installed via sync, disallow
- // the instanation.
- //
- // Themes are always allowed. Because they contain no active code, they
- // are less of a risk than extensions.
- //
- // If |is_from_sync| is false, then the install was not initiated by sync,
- // and this check should pass. Extensions that were installed from an
- // update URL in external_extensions.json are an example. They are not
- // syncable, because the user did not make an explicit choice to install
- // them. However, they were installed through the update mechanism, so
- // control must pass into this function.
- //
- // TODO(akalin): When we do apps sync, we have to work with its
- // traits, too.
- const browser_sync::ExtensionSyncTraits extension_sync_traits =
- browser_sync::GetExtensionSyncTraits();
- const browser_sync::ExtensionSyncTraits app_sync_traits =
- browser_sync::GetAppSyncTraits();
- // If an extension is a theme, we bypass the valid/syncable check
- // as themes are harmless.
- if (!extension->is_theme() && is_from_sync &&
- !browser_sync::IsExtensionValidAndSyncable(
- *extension, extension_sync_traits.allowed_extension_types) &&
- !browser_sync::IsExtensionValidAndSyncable(
- *extension, app_sync_traits.allowed_extension_types)) {
- // We're an extension installed via sync that is unsyncable,
- // i.e. we may have been syncable previously. We block these
- // installs. We'll have to update the clause above if we decide
- // to sync other extension-like things, like apps or user
- // scripts.
- //
- // Note that this creates a small window where a user who tries
- // to download/install an extension that is simultaneously
- // installed via sync (and blocked) will find his download
- // blocked.
- //
- // TODO(akalin): Remove this check once we've put in UI to
- // approve synced extensions.
- LOG(WARNING)
- << "Not installing invalid or unsyncable extension "
- << extension->id();
- // Delete the extension directory since we're not going to
- // load it.
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableFunction(&DeleteFileHelper, extension->path(), true));
- return;
- }
if (extension->is_theme()) {
DCHECK(pending_extension_info.enable_on_install);
initial_state = Extension::ENABLED;
@@ -1800,7 +1789,7 @@ void ExtensionsService::OnExtensionInstalled(const Extension* extension) {
}
UMA_HISTOGRAM_ENUMERATION("Extensions.InstallType",
- extension->GetHistogramType(), 100);
+ extension->GetType(), 100);
ShownSectionsHandler::OnExtensionInstalled(profile_->GetPrefs(), extension);
extension_prefs_->OnExtensionInstalled(
extension, initial_state, initial_enable_incognito);
@@ -1834,7 +1823,7 @@ void ExtensionsService::OnExtensionInstalled(const Extension* extension) {
OnExtensionLoaded(scoped_extension);
}
-const Extension* ExtensionsService::GetExtensionByIdInternal(
+const Extension* ExtensionService::GetExtensionByIdInternal(
const std::string& id, bool include_enabled, bool include_disabled) {
std::string lowercase_id = StringToLowerASCII(id);
if (include_enabled) {
@@ -1854,16 +1843,16 @@ const Extension* ExtensionsService::GetExtensionByIdInternal(
return NULL;
}
-const Extension* ExtensionsService::GetWebStoreApp() {
+const Extension* ExtensionService::GetWebStoreApp() {
return GetExtensionById(extension_misc::kWebStoreAppId, false);
}
-const Extension* ExtensionsService::GetExtensionByURL(const GURL& url) {
+const Extension* ExtensionService::GetExtensionByURL(const GURL& url) {
return url.scheme() != chrome::kExtensionScheme ? NULL :
GetExtensionById(url.host(), false);
}
-const Extension* ExtensionsService::GetExtensionByWebExtent(const GURL& url) {
+const Extension* ExtensionService::GetExtensionByWebExtent(const GURL& url) {
for (size_t i = 0; i < extensions_.size(); ++i) {
if (extensions_[i]->web_extent().ContainsURL(url))
return extensions_[i];
@@ -1871,7 +1860,7 @@ const Extension* ExtensionsService::GetExtensionByWebExtent(const GURL& url) {
return NULL;
}
-bool ExtensionsService::ExtensionBindingsAllowed(const GURL& url) {
+bool ExtensionService::ExtensionBindingsAllowed(const GURL& url) {
// Allow bindings for all packaged extension.
if (GetExtensionByURL(url))
return true;
@@ -1881,7 +1870,7 @@ bool ExtensionsService::ExtensionBindingsAllowed(const GURL& url) {
return (extension && extension->location() == Extension::COMPONENT);
}
-const Extension* ExtensionsService::GetExtensionByOverlappingWebExtent(
+const Extension* ExtensionService::GetExtensionByOverlappingWebExtent(
const ExtensionExtent& extent) {
for (size_t i = 0; i < extensions_.size(); ++i) {
if (extensions_[i]->web_extent().OverlapsWith(extent))
@@ -1891,38 +1880,40 @@ const Extension* ExtensionsService::GetExtensionByOverlappingWebExtent(
return NULL;
}
-const SkBitmap& ExtensionsService::GetOmniboxIcon(
+const SkBitmap& ExtensionService::GetOmniboxIcon(
const std::string& extension_id) {
return omnibox_icon_manager_.GetIcon(extension_id);
}
-const SkBitmap& ExtensionsService::GetOmniboxPopupIcon(
+const SkBitmap& ExtensionService::GetOmniboxPopupIcon(
const std::string& extension_id) {
return omnibox_popup_icon_manager_.GetIcon(extension_id);
}
-void ExtensionsService::ClearProvidersForTesting() {
+void ExtensionService::ClearProvidersForTesting() {
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
NewRunnableMethod(
- backend_.get(), &ExtensionsServiceBackend::ClearProvidersForTesting));
+ backend_.get(), &ExtensionServiceBackend::ClearProvidersForTesting));
}
-void ExtensionsService::AddProviderForTesting(
+void ExtensionService::AddProviderForTesting(
ExternalExtensionProvider* test_provider) {
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
NewRunnableMethod(
- backend_.get(), &ExtensionsServiceBackend::AddProviderForTesting,
+ backend_.get(), &ExtensionServiceBackend::AddProviderForTesting,
test_provider));
}
-void ExtensionsService::OnExternalExtensionFileFound(
+void ExtensionService::OnExternalExtensionFileFound(
const std::string& id,
const std::string& version,
const FilePath& path,
Extension::Location location) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ if (extension_prefs_->IsExtensionKilled(id))
+ return;
// Before even bothering to unpack, check and see if we already have this
// version. This is important because these extensions are going to get
@@ -1944,6 +1935,20 @@ void ExtensionsService::OnExternalExtensionFileFound(
}
}
+ GURL update_url = GURL();
+ bool is_from_sync = false;
+ bool install_silently = true;
+ bool enable_on_install = true;
+ bool enable_incognito_on_install = false;
+ pending_extensions_[id] = PendingExtensionInfo(
+ update_url,
+ &AlwaysInstall,
+ is_from_sync,
+ install_silently,
+ enable_on_install,
+ enable_incognito_on_install,
+ location);
+
scoped_refptr<CrxInstaller> installer(
new CrxInstaller(this, // frontend
NULL)); // no client (silent install)
@@ -1952,7 +1957,7 @@ void ExtensionsService::OnExternalExtensionFileFound(
installer->InstallCrx(path);
}
-void ExtensionsService::ReportExtensionLoadError(
+void ExtensionService::ReportExtensionLoadError(
const FilePath& extension_path,
const std::string &error,
NotificationType type,
@@ -1970,7 +1975,7 @@ void ExtensionsService::ReportExtensionLoadError(
ExtensionErrorReporter::GetInstance()->ReportError(message, be_noisy);
}
-void ExtensionsService::DidCreateRenderViewForBackgroundPage(
+void ExtensionService::DidCreateRenderViewForBackgroundPage(
ExtensionHost* host) {
OrphanedDevTools::iterator iter =
orphaned_dev_tools_.find(host->extension()->id());
@@ -1982,7 +1987,7 @@ void ExtensionsService::DidCreateRenderViewForBackgroundPage(
orphaned_dev_tools_.erase(iter);
}
-void ExtensionsService::Observe(NotificationType type,
+void ExtensionService::Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
switch (type.value) {
@@ -1997,8 +2002,10 @@ void ExtensionsService::Observe(NotificationType type,
// We do it in a PostTask so that other handlers of this notification will
// still have access to the Extension and ExtensionHost.
MessageLoop::current()->PostTask(FROM_HERE,
- NewRunnableMethod(this, &ExtensionsService::UnloadExtension,
- host->extension()->id()));
+ NewRunnableMethod(this,
+ &ExtensionService::UnloadExtension,
+ host->extension()->id(),
+ UnloadedExtensionInfo::DISABLE));
break;
}
@@ -2024,11 +2031,11 @@ void ExtensionsService::Observe(NotificationType type,
}
}
-bool ExtensionsService::HasApps() const {
+bool ExtensionService::HasApps() const {
return !GetAppIds().empty();
}
-ExtensionIdSet ExtensionsService::GetAppIds() const {
+ExtensionIdSet ExtensionService::GetAppIds() const {
ExtensionIdSet result;
for (ExtensionList::const_iterator it = extensions_.begin();
it != extensions_.end(); ++it) {
@@ -2039,12 +2046,12 @@ ExtensionIdSet ExtensionsService::GetAppIds() const {
return result;
}
-bool ExtensionsService::IsBackgroundPageReady(const Extension* extension) {
+bool ExtensionService::IsBackgroundPageReady(const Extension* extension) {
return (extension->background_url().is_empty() ||
extension_runtime_data_[extension->id()].background_page_ready);
}
-void ExtensionsService::SetBackgroundPageReady(const Extension* extension) {
+void ExtensionService::SetBackgroundPageReady(const Extension* extension) {
DCHECK(!extension->background_url().is_empty());
extension_runtime_data_[extension->id()].background_page_ready = true;
NotificationService::current()->Notify(
@@ -2053,15 +2060,15 @@ void ExtensionsService::SetBackgroundPageReady(const Extension* extension) {
NotificationService::NoDetails());
}
-bool ExtensionsService::IsBeingUpgraded(const Extension* extension) {
+bool ExtensionService::IsBeingUpgraded(const Extension* extension) {
return extension_runtime_data_[extension->id()].being_upgraded;
}
-void ExtensionsService::SetBeingUpgraded(const Extension* extension,
+void ExtensionService::SetBeingUpgraded(const Extension* extension,
bool value) {
extension_runtime_data_[extension->id()].being_upgraded = value;
}
-PropertyBag* ExtensionsService::GetPropertyBag(const Extension* extension) {
+PropertyBag* ExtensionService::GetPropertyBag(const Extension* extension) {
return &extension_runtime_data_[extension->id()].property_bag;
}
diff --git a/chrome/browser/extensions/extensions_service.h b/chrome/browser/extensions/extension_service.h
index c831039..9e4206c 100644
--- a/chrome/browser/extensions/extensions_service.h
+++ b/chrome/browser/extensions/extension_service.h
@@ -2,12 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSIONS_SERVICE_H_
-#define CHROME_BROWSER_EXTENSIONS_EXTENSIONS_SERVICE_H_
+#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_SERVICE_H_
+#define CHROME_BROWSER_EXTENSIONS_EXTENSION_SERVICE_H_
#pragma once
#include <map>
-#include <set>
#include <string>
#include <vector>
@@ -35,41 +34,36 @@
#include "chrome/common/extensions/extension.h"
#include "chrome/common/property_bag.h"
-class ExtensionsServiceBackend;
+class ExtensionServiceBackend;
class ExtensionToolbarModel;
class ExtensionUpdater;
class GURL;
-class PrefService;
class Profile;
class Version;
+typedef bool (*ShouldInstallExtensionPredicate)(const Extension&);
+
// A pending extension is an extension that hasn't been installed yet
// and is intended to be installed in the next auto-update cycle. The
// update URL of a pending extension may be blank, in which case a
// default one is assumed.
struct PendingExtensionInfo {
- // TODO(skerner): Consider merging ExpectedCrxType with
- // browser_sync::ExtensionType.
- enum ExpectedCrxType {
- UNKNOWN, // Sometimes we don't know the type of a pending item. An
- // update URL from external_extensions.json is one such case.
- APP,
- THEME,
- EXTENSION
- };
-
- PendingExtensionInfo(const GURL& update_url,
- ExpectedCrxType expected_crx_type,
- bool is_from_sync,
- bool install_silently,
- bool enable_on_install,
- bool enable_incognito_on_install,
- Extension::Location install_source);
+ PendingExtensionInfo(
+ const GURL& update_url,
+ ShouldInstallExtensionPredicate should_install_extension,
+ bool is_from_sync,
+ bool install_silently,
+ bool enable_on_install,
+ bool enable_incognito_on_install,
+ Extension::Location install_source);
PendingExtensionInfo();
GURL update_url;
- ExpectedCrxType expected_crx_type;
+ // When the extension is about to be installed, this function is
+ // called. If this function returns true, the install proceeds. If
+ // this function returns false, the install is aborted.
+ ShouldInstallExtensionPredicate should_install_extension;
bool is_from_sync; // This update check was initiated from sync.
bool install_silently;
bool enable_on_install;
@@ -82,7 +76,7 @@ struct PendingExtensionInfo {
typedef std::map<std::string, PendingExtensionInfo> PendingExtensionMap;
// This is an interface class to encapsulate the dependencies that
-// ExtensionUpdater has on ExtensionsService. This allows easy mocking.
+// ExtensionUpdater has on ExtensionService. This allows easy mocking.
class ExtensionUpdateService {
public:
virtual ~ExtensionUpdateService() {}
@@ -101,8 +95,8 @@ class ExtensionUpdateService {
};
// Manages installed and running Chromium extensions.
-class ExtensionsService
- : public base::RefCountedThreadSafe<ExtensionsService,
+class ExtensionService
+ : public base::RefCountedThreadSafe<ExtensionService,
BrowserThread::DeleteOnUIThread>,
public ExtensionUpdateService,
public NotificationObserver {
@@ -116,7 +110,7 @@ class ExtensionsService
}
// The extension's manifest. This is required for component extensions so
- // that ExtensionsService doesn't need to go to disk to load them.
+ // that ExtensionService doesn't need to go to disk to load them.
std::string manifest;
// Directory where the extension is stored.
@@ -143,26 +137,28 @@ class ExtensionsService
// Used to test if we need to show the "Loading" dialog for themes.
static bool IsDownloadFromMiniGallery(const GURL& download_url);
+ // Returns whether the URL is from either a hosted or packaged app.
+ bool IsInstalledApp(const GURL& url);
+
// Attempts to uninstall an extension from a given ExtensionService. Returns
// true iff the target extension exists.
- static bool UninstallExtensionHelper(ExtensionsService* extensions_service,
+ static bool UninstallExtensionHelper(ExtensionService* extensions_service,
const std::string& extension_id);
- ExtensionsService(Profile* profile,
+ // Constructor stores pointers to |profile| and |extension_prefs| but
+ // ownership remains at caller.
+ ExtensionService(Profile* profile,
const CommandLine* command_line,
const FilePath& install_directory,
+ ExtensionPrefs* extension_prefs,
bool autoupdate_enabled);
// Gets the list of currently installed extensions.
- virtual const ExtensionList* extensions() const { return &extensions_; }
- virtual const ExtensionList* disabled_extensions() const {
- return &disabled_extensions_;
- }
+ virtual const ExtensionList* extensions() const;
+ virtual const ExtensionList* disabled_extensions() const;
// Gets the set of pending extensions.
- virtual const PendingExtensionMap& pending_extensions() const {
- return pending_extensions_;
- }
+ virtual const PendingExtensionMap& pending_extensions() const;
// Registers an extension to be loaded as a component extension.
void register_component_extension(const ComponentExtensionInfo& info) {
@@ -170,9 +166,7 @@ class ExtensionsService
}
// Returns true if any extensions are installed.
- virtual bool HasInstalledExtensions() {
- return !(extensions_.empty() && disabled_extensions_.empty());
- }
+ virtual bool HasInstalledExtensions();
const FilePath& install_directory() const { return install_directory_; }
@@ -215,10 +209,8 @@ class ExtensionsService
void InitEventRouters();
// Look up an extension by ID.
- const Extension* GetExtensionById(const std::string& id,
- bool include_disabled) {
- return GetExtensionByIdInternal(id, true, include_disabled);
- }
+ virtual const Extension* GetExtensionById(const std::string& id,
+ bool include_disabled);
// Install the extension file at |extension_path|. Will install as an
// update if an older version is already installed.
@@ -246,7 +238,7 @@ class ExtensionsService
// pre-enabled permissions.
void AddPendingExtensionFromSync(
const std::string& id, const GURL& update_url,
- const PendingExtensionInfo::ExpectedCrxType expected_crx_type,
+ ShouldInstallExtensionPredicate should_install_extension,
bool install_silently, bool enable_on_install,
bool enable_incognito_on_install);
@@ -310,7 +302,8 @@ class ExtensionsService
void UpdateExternalPolicyExtensionProvider();
// Unload the specified extension.
- void UnloadExtension(const std::string& extension_id);
+ void UnloadExtension(const std::string& extension_id,
+ UnloadedExtensionInfo::Reason reason);
// Unload all extensions. This is currently only called on shutdown, and
// does not send notifications.
@@ -402,7 +395,7 @@ class ExtensionsService
// it.
void DestroyingProfile();
- ExtensionPrefs* extension_prefs() { return extension_prefs_.get(); }
+ virtual ExtensionPrefs* extension_prefs();
// Whether the extension service is ready.
// TODO(skerner): Get rid of this method. crbug.com/63756
@@ -422,7 +415,7 @@ class ExtensionsService
}
// Notify the frontend that there was an error loading an extension.
- // This method is public because ExtensionsServiceBackend can post to here.
+ // This method is public because ExtensionServiceBackend can post to here.
void ReportExtensionLoadError(const FilePath& extension_path,
const std::string& error,
NotificationType type,
@@ -445,7 +438,7 @@ class ExtensionsService
private:
friend class BrowserThread;
- friend class DeleteTask<ExtensionsService>;
+ friend class DeleteTask<ExtensionService>;
// Contains Extension data that can change during the life of the process,
// but does not persist across restarts.
@@ -464,7 +457,7 @@ class ExtensionsService
};
typedef std::map<std::string, ExtensionRuntimeData> ExtensionRuntimeDataMap;
- virtual ~ExtensionsService();
+ virtual ~ExtensionService();
// Clear all persistent data that may have been stored by the extension.
void ClearExtensionData(const GURL& extension_url);
@@ -475,11 +468,11 @@ class ExtensionsService
bool include_enabled,
bool include_disabled);
- // Like AddPendingExtension() but assumes an extension with the same
- // id is not already installed.
+ // Like AddPendingExtension*() functions above, but assumes an
+ // extension with the same id is not already installed.
void AddPendingExtensionInternal(
const std::string& id, const GURL& update_url,
- PendingExtensionInfo::ExpectedCrxType crx_type,
+ ShouldInstallExtensionPredicate should_install_extension,
bool is_from_sync, bool install_silently,
bool enable_on_install, bool enable_incognito_on_install,
Extension::Location install_source);
@@ -488,7 +481,8 @@ class ExtensionsService
void NotifyExtensionLoaded(const Extension* extension);
// Handles sending notification that |extension| was unloaded.
- void NotifyExtensionUnloaded(const Extension* extension);
+ void NotifyExtensionUnloaded(const Extension* extension,
+ UnloadedExtensionInfo::Reason reason);
// Helper that updates the active extension list used for crash reporting.
void UpdateActiveExtensionsInCrashReporter();
@@ -502,11 +496,11 @@ class ExtensionsService
void GrantUnlimitedStorage(const Extension* extension);
void RevokeUnlimitedStorage(const Extension* extension);
- // The profile this ExtensionsService is part of.
+ // The profile this ExtensionService is part of.
Profile* profile_;
- // Preferences for the owning profile.
- scoped_ptr<ExtensionPrefs> extension_prefs_;
+ // Preferences for the owning profile (weak reference).
+ ExtensionPrefs* extension_prefs_;
// The current list of installed extensions.
ExtensionList extensions_;
@@ -530,7 +524,7 @@ class ExtensionsService
bool show_extensions_prompts_;
// The backend that will do IO on behalf of this instance.
- scoped_refptr<ExtensionsServiceBackend> backend_;
+ scoped_refptr<ExtensionServiceBackend> backend_;
// Used by dispatchers to limit API quota for individual extensions.
ExtensionsQuotaService quota_service_;
@@ -595,13 +589,13 @@ class ExtensionsService
// Flag to make sure event routers are only initialized once.
bool event_routers_initialized_;
- FRIEND_TEST_ALL_PREFIXES(ExtensionsServiceTest,
+ FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest,
UpdatePendingExtensionAlreadyInstalled);
- FRIEND_TEST_ALL_PREFIXES(ExtensionsServiceTest,
+ FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest,
InstallAppsWithUnlimtedStorage);
- FRIEND_TEST_ALL_PREFIXES(ExtensionsServiceTest,
+ FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest,
InstallAppsAndCheckStorageProtection);
- DISALLOW_COPY_AND_ASSIGN(ExtensionsService);
+ DISALLOW_COPY_AND_ASSIGN(ExtensionService);
};
-#endif // CHROME_BROWSER_EXTENSIONS_EXTENSIONS_SERVICE_H_
+#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_SERVICE_H_
diff --git a/chrome/browser/extensions/extensions_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc
index e6c4e3a..7f052b6 100644
--- a/chrome/browser/extensions/extensions_service_unittest.cc
+++ b/chrome/browser/extensions/extension_service_unittest.cc
@@ -2,9 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/browser/extensions/extensions_service_unittest.h"
+#include "chrome/browser/extensions/extension_service_unittest.h"
#include <algorithm>
+#include <set>
#include <vector>
#include "base/basictypes.h"
@@ -23,18 +24,19 @@
#include "base/version.h"
#include "chrome/browser/appcache/chrome_appcache_service.h"
#include "chrome/browser/browser_thread.h"
-#include "chrome/browser/file_system/browser_file_system_context.h"
#include "chrome/browser/extensions/crx_installer.h"
#include "chrome/browser/extensions/extension_creator.h"
#include "chrome/browser/extensions/extension_error_reporter.h"
-#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/external_extension_provider.h"
#include "chrome/browser/extensions/external_pref_extension_provider.h"
#include "chrome/browser/extensions/pack_extension_job.cc"
+#include "chrome/browser/file_system/browser_file_system_helper.h"
#include "chrome/browser/in_process_webkit/dom_storage_context.h"
#include "chrome/browser/in_process_webkit/webkit_context.h"
#include "chrome/browser/prefs/browser_prefs.h"
-#include "chrome/browser/prefs/pref_value_store.h"
+#include "chrome/browser/prefs/pref_service_mock_builder.h"
+#include "chrome/browser/prefs/scoped_pref_update.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension.h"
@@ -140,13 +142,10 @@ class MockExtensionProvider : public ExternalExtensionProvider {
}
// ExternalExtensionProvider implementation:
- virtual void VisitRegisteredExtension(
- Visitor* visitor, const std::set<std::string>& ids_to_ignore) const {
+ virtual void VisitRegisteredExtension(Visitor* visitor) const {
visit_count_++;
for (DataMap::const_iterator i = extension_map_.begin();
i != extension_map_.end(); ++i) {
- if (ids_to_ignore.find(i->first) != ids_to_ignore.end())
- continue;
scoped_ptr<Version> version;
version.reset(Version::GetVersionFromString(i->second.first));
@@ -198,8 +197,7 @@ class MockProviderVisitor : public ExternalExtensionProvider::Visitor {
MockProviderVisitor() : ids_found_(0) {
}
- int Visit(const std::string& json_data,
- const std::set<std::string>& ignore_list) {
+ int Visit(const std::string& json_data) {
// Give the test json file to the provider for parsing.
provider_.reset(new ExternalPrefExtensionProvider());
provider_->SetPreferencesForTesting(json_data);
@@ -220,9 +218,8 @@ class MockProviderVisitor : public ExternalExtensionProvider::Visitor {
// Reset our counter.
ids_found_ = 0;
- // Ask the provider to look up all extensions (and return the ones
- // found (that are not on the ignore list).
- provider_->VisitRegisteredExtension(this, ignore_list);
+ // Ask the provider to look up all extensions and return them.
+ provider_->VisitRegisteredExtension(this);
return ids_found_;
}
@@ -302,10 +299,10 @@ class ExtensionTestingProfile : public TestingProfile {
ExtensionTestingProfile() : service_(NULL) {
}
- void set_extensions_service(ExtensionsService* service) {
+ void set_extensions_service(ExtensionService* service) {
service_ = service;
}
- virtual ExtensionsService* GetExtensionsService() { return service_; }
+ virtual ExtensionService* GetExtensionService() { return service_; }
virtual ChromeAppCacheService* GetAppCacheService() {
if (!appcache_service_) {
@@ -320,21 +317,21 @@ class ExtensionTestingProfile : public TestingProfile {
return appcache_service_;
}
- virtual BrowserFileSystemContext* GetFileSystemContext() {
- if (!browser_file_system_context_)
- browser_file_system_context_ = new BrowserFileSystemContext(
+ virtual fileapi::SandboxedFileSystemContext* GetFileSystemContext() {
+ if (!file_system_context_)
+ file_system_context_ = CreateFileSystemContext(
GetPath(), IsOffTheRecord());
- return browser_file_system_context_;
+ return file_system_context_;
}
private:
- ExtensionsService* service_;
+ ExtensionService* service_;
scoped_refptr<ChromeAppCacheService> appcache_service_;
- scoped_refptr<BrowserFileSystemContext> browser_file_system_context_;
+ scoped_refptr<fileapi::SandboxedFileSystemContext> file_system_context_;
};
// Our message loop may be used in tests which require it to be an IO loop.
-ExtensionsServiceTestBase::ExtensionsServiceTestBase()
+ExtensionServiceTestBase::ExtensionServiceTestBase()
: total_successes_(0),
loop_(MessageLoop::TYPE_IO),
ui_thread_(BrowserThread::UI, &loop_),
@@ -344,8 +341,8 @@ ExtensionsServiceTestBase::ExtensionsServiceTestBase()
io_thread_(BrowserThread::IO, &loop_) {
}
-ExtensionsServiceTestBase::~ExtensionsServiceTestBase() {
- // Drop our reference to ExtensionsService and TestingProfile, so that they
+ExtensionServiceTestBase::~ExtensionServiceTestBase() {
+ // Drop our reference to ExtensionService and TestingProfile, so that they
// can be destroyed while BrowserThreads and MessageLoop are still around
// (they are used in the destruction process).
service_ = NULL;
@@ -353,19 +350,19 @@ ExtensionsServiceTestBase::~ExtensionsServiceTestBase() {
MessageLoop::current()->RunAllPending();
}
-void ExtensionsServiceTestBase::InitializeExtensionsService(
+void ExtensionServiceTestBase::InitializeExtensionService(
const FilePath& pref_file, const FilePath& extensions_install_dir) {
ExtensionTestingProfile* profile = new ExtensionTestingProfile();
- // Create a preference service that only contains user defined
- // preference values.
- PrefService* prefs = PrefService::CreateUserPrefService(pref_file);
+ // Create a PrefService that only contains user defined preference values.
+ PrefService* prefs =
+ PrefServiceMockBuilder().WithUserFilePrefs(pref_file).Create();
Profile::RegisterUserPrefs(prefs);
browser::RegisterUserPrefs(prefs);
profile->SetPrefService(prefs);
profile_.reset(profile);
- service_ = profile->CreateExtensionsService(
+ service_ = profile->CreateExtensionService(
CommandLine::ForCurrentProcess(),
extensions_install_dir);
service_->set_extensions_enabled(true);
@@ -382,7 +379,7 @@ void ExtensionsServiceTestBase::InitializeExtensionsService(
total_successes_ = 0;
}
-void ExtensionsServiceTestBase::InitializeInstalledExtensionsService(
+void ExtensionServiceTestBase::InitializeInstalledExtensionService(
const FilePath& prefs_file, const FilePath& source_install_dir) {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
FilePath path_ = temp_dir_.path();
@@ -396,10 +393,10 @@ void ExtensionsServiceTestBase::InitializeInstalledExtensionsService(
file_util::Delete(extensions_install_dir_, true);
file_util::CopyDirectory(source_install_dir, extensions_install_dir_, true);
- InitializeExtensionsService(temp_prefs, extensions_install_dir_);
+ InitializeExtensionService(temp_prefs, extensions_install_dir_);
}
-void ExtensionsServiceTestBase::InitializeEmptyExtensionsService() {
+void ExtensionServiceTestBase::InitializeEmptyExtensionService() {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
FilePath path_ = temp_dir_.path();
path_ = path_.Append(FILE_PATH_LITERAL("TestingExtensionsPath"));
@@ -411,22 +408,22 @@ void ExtensionsServiceTestBase::InitializeEmptyExtensionsService() {
file_util::Delete(extensions_install_dir_, true);
file_util::CreateDirectory(extensions_install_dir_);
- InitializeExtensionsService(prefs_filename, extensions_install_dir_);
+ InitializeExtensionService(prefs_filename, extensions_install_dir_);
}
// static
-void ExtensionsServiceTestBase::SetUpTestCase() {
+void ExtensionServiceTestBase::SetUpTestCase() {
ExtensionErrorReporter::Init(false); // no noisy errors
}
-void ExtensionsServiceTestBase::SetUp() {
+void ExtensionServiceTestBase::SetUp() {
ExtensionErrorReporter::GetInstance()->ClearErrors();
}
-class ExtensionsServiceTest
- : public ExtensionsServiceTestBase, public NotificationObserver {
+class ExtensionServiceTest
+ : public ExtensionServiceTestBase, public NotificationObserver {
public:
- ExtensionsServiceTest() : installed_(NULL) {
+ ExtensionServiceTest() : installed_(NULL) {
registrar_.Add(this, NotificationType::EXTENSION_LOADED,
NotificationService::AllSources());
registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
@@ -451,7 +448,8 @@ class ExtensionsServiceTest
}
case NotificationType::EXTENSION_UNLOADED: {
- const Extension* e = Details<const Extension>(details).ptr();
+ const Extension* e =
+ Details<UnloadedExtensionInfo>(details)->extension;
unloaded_id_ = e->id();
ExtensionList::iterator i =
std::find(loaded_.begin(), loaded_.end(), e);
@@ -820,7 +818,7 @@ void PackExtensionTestClient::OnPackFailure(const std::string& error_message) {
}
// Test loading good extensions from the profile directory.
-TEST_F(ExtensionsServiceTest, LoadAllExtensionsFromDirectorySuccess) {
+TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectorySuccess) {
// Initialize the test dir with a good Preferences/extensions.
FilePath source_install_dir;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &source_install_dir));
@@ -831,7 +829,7 @@ TEST_F(ExtensionsServiceTest, LoadAllExtensionsFromDirectorySuccess) {
FilePath pref_path = source_install_dir
.DirName()
.AppendASCII("Preferences");
- InitializeInstalledExtensionsService(pref_path, source_install_dir);
+ InitializeInstalledExtensionService(pref_path, source_install_dir);
service_->Init();
@@ -924,7 +922,7 @@ TEST_F(ExtensionsServiceTest, LoadAllExtensionsFromDirectorySuccess) {
};
// Test loading bad extensions from the profile directory.
-TEST_F(ExtensionsServiceTest, LoadAllExtensionsFromDirectoryFail) {
+TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectoryFail) {
// Initialize the test dir with a bad Preferences/extensions.
FilePath source_install_dir;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &source_install_dir));
@@ -936,7 +934,7 @@ TEST_F(ExtensionsServiceTest, LoadAllExtensionsFromDirectoryFail) {
.DirName()
.AppendASCII("Preferences");
- InitializeInstalledExtensionsService(pref_path, source_install_dir);
+ InitializeInstalledExtensionService(pref_path, source_install_dir);
service_->Init();
loop_.RunAllPending();
@@ -963,7 +961,7 @@ TEST_F(ExtensionsServiceTest, LoadAllExtensionsFromDirectoryFail) {
// Test that partially deleted extensions are cleaned up during startup
// Test loading bad extensions from the profile directory.
-TEST_F(ExtensionsServiceTest, CleanupOnStartup) {
+TEST_F(ExtensionServiceTest, CleanupOnStartup) {
FilePath source_install_dir;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &source_install_dir));
source_install_dir = source_install_dir
@@ -974,7 +972,7 @@ TEST_F(ExtensionsServiceTest, CleanupOnStartup) {
.DirName()
.AppendASCII("Preferences");
- InitializeInstalledExtensionsService(pref_path, source_install_dir);
+ InitializeInstalledExtensionService(pref_path, source_install_dir);
// Simulate that one of them got partially deleted by clearing its pref.
DictionaryValue* dict =
@@ -1003,8 +1001,8 @@ TEST_F(ExtensionsServiceTest, CleanupOnStartup) {
// Test installing extensions. This test tries to install few extensions using
// crx files. If you need to change those crx files, feel free to repackage
// them, throw away the key used and change the id's above.
-TEST_F(ExtensionsServiceTest, InstallExtension) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, InstallExtension) {
+ InitializeEmptyExtensionService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
@@ -1062,11 +1060,57 @@ TEST_F(ExtensionsServiceTest, InstallExtension) {
// TODO(erikkay): add tests for upgrade cases.
}
+// Test the handling of killed extensions.
+TEST_F(ExtensionServiceTest, KilledExtensions) {
+ InitializeEmptyExtensionService();
+
+ FilePath extensions_path;
+ ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
+ extensions_path = extensions_path.AppendASCII("extensions");
+ FilePath path = extensions_path.AppendASCII("good.crx");
+ set_extensions_enabled(true);
+
+ // Install an external extension.
+ service_->OnExternalExtensionFileFound(good_crx, "1.0.0.0",
+ path, Extension::EXTERNAL_PREF);
+ loop_.RunAllPending();
+ ASSERT_TRUE(NULL != service_->GetExtensionById(good_crx, false));
+
+ // Uninstall it and check that its killbit gets set.
+ service_->UninstallExtension(good_crx, false);
+ loop_.RunAllPending();
+ ValidateIntegerPref(good_crx, "location", Extension::KILLBIT);
+
+ // Try to re-install it externally. This should fail because of the killbit.
+ service_->OnExternalExtensionFileFound(good_crx, "1.0.0.0",
+ path, Extension::EXTERNAL_PREF);
+ loop_.RunAllPending();
+ ASSERT_TRUE(NULL == service_->GetExtensionById(good_crx, false));
+ ValidateIntegerPref(good_crx, "location", Extension::KILLBIT);
+
+ // Repeat the same thing with a newer version of the extension.
+ path = extensions_path.AppendASCII("good2.crx");
+ service_->OnExternalExtensionFileFound(good_crx, "1.0.0.1",
+ path, Extension::EXTERNAL_PREF);
+ loop_.RunAllPending();
+ ASSERT_TRUE(NULL == service_->GetExtensionById(good_crx, false));
+ ValidateIntegerPref(good_crx, "location", Extension::KILLBIT);
+
+ // Try adding the same extension from an external update URL.
+ service_->AddPendingExtensionFromExternalUpdateUrl(
+ good_crx,
+ GURL("http:://fake.update/url"),
+ Extension::EXTERNAL_PREF_DOWNLOAD);
+ const PendingExtensionMap& pending_extensions =
+ service_->pending_extensions();
+ ASSERT_TRUE(pending_extensions.find(good_crx) == pending_extensions.end());
+}
+
// Install a user script (they get converted automatically to an extension)
-TEST_F(ExtensionsServiceTest, InstallUserScript) {
+TEST_F(ExtensionServiceTest, InstallUserScript) {
// The details of script conversion are tested elsewhere, this just tests
- // integration with ExtensionsService.
- InitializeEmptyExtensionsService();
+ // integration with ExtensionService.
+ InitializeEmptyExtensionService();
FilePath path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path));
@@ -1096,8 +1140,8 @@ TEST_F(ExtensionsServiceTest, InstallUserScript) {
// This tests that the granted permissions preferences are correctly set when
// installing an extension.
-TEST_F(ExtensionsServiceTest, GrantedPermissions) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, GrantedPermissions) {
+ InitializeEmptyExtensionService();
FilePath path;
FilePath pem_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path));
@@ -1155,8 +1199,8 @@ TEST_F(ExtensionsServiceTest, GrantedPermissions) {
// Tests that the granted permissions full_access bit gets set correctly when
// an extension contains an NPAPI plugin. Don't run this test on Chrome OS
// since they don't support plugins.
-TEST_F(ExtensionsServiceTest, GrantedFullAccessPermissions) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, GrantedFullAccessPermissions) {
+ InitializeEmptyExtensionService();
FilePath path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path));
@@ -1191,8 +1235,8 @@ TEST_F(ExtensionsServiceTest, GrantedFullAccessPermissions) {
// Tests that the extension is disabled when permissions are missing from
// the extension's granted permissions preferences. (This simulates updating
// the browser to a version which recognizes more permissions).
-TEST_F(ExtensionsServiceTest, GrantedAPIAndHostPermissions) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, GrantedAPIAndHostPermissions) {
+ InitializeEmptyExtensionService();
FilePath path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path));
@@ -1321,8 +1365,8 @@ TEST_F(ExtensionsServiceTest, GrantedAPIAndHostPermissions) {
}
// Test Packaging and installing an extension.
-TEST_F(ExtensionsServiceTest, PackExtension) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, PackExtension) {
+ InitializeEmptyExtensionService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
extensions_path = extensions_path.AppendASCII("extensions");
@@ -1369,8 +1413,8 @@ TEST_F(ExtensionsServiceTest, PackExtension) {
}
// Test Packaging and installing an extension whose name contains punctuation.
-TEST_F(ExtensionsServiceTest, PackPunctuatedExtension) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, PackPunctuatedExtension) {
+ InitializeEmptyExtensionService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
extensions_path = extensions_path.AppendASCII("extensions");
@@ -1448,8 +1492,8 @@ TEST_F(ExtensionsServiceTest, PackPunctuatedExtension) {
// > openssl pkcs8 -topk8 -nocrypt -in privkey.pem -out privkey_asn1.pem
// The privkey.pem is a PrivateKey, and the pcks8 -topk8 creates a
// PrivateKeyInfo ASN.1 structure, we our RSAPrivateKey expects.
-TEST_F(ExtensionsServiceTest, PackExtensionOpenSSLKey) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, PackExtensionOpenSSLKey) {
+ InitializeEmptyExtensionService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
extensions_path = extensions_path.AppendASCII("extensions");
@@ -1475,8 +1519,8 @@ TEST_F(ExtensionsServiceTest, PackExtensionOpenSSLKey) {
InstallExtension(crx_path, true);
}
-TEST_F(ExtensionsServiceTest, InstallTheme) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, InstallTheme) {
+ InitializeEmptyExtensionService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
extensions_path = extensions_path.AppendASCII("extensions");
@@ -1511,9 +1555,9 @@ TEST_F(ExtensionsServiceTest, InstallTheme) {
ValidatePrefKeyCount(pref_count);
}
-TEST_F(ExtensionsServiceTest, LoadLocalizedTheme) {
+TEST_F(ExtensionServiceTest, LoadLocalizedTheme) {
// Load.
- InitializeEmptyExtensionsService();
+ InitializeEmptyExtensionService();
FilePath extension_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extension_path));
extension_path = extension_path
@@ -1529,8 +1573,8 @@ TEST_F(ExtensionsServiceTest, LoadLocalizedTheme) {
EXPECT_EQ("description", service_->extensions()->at(0)->description());
}
-TEST_F(ExtensionsServiceTest, InstallLocalizedTheme) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, InstallLocalizedTheme) {
+ InitializeEmptyExtensionService();
FilePath theme_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &theme_path));
theme_path = theme_path
@@ -1545,8 +1589,8 @@ TEST_F(ExtensionsServiceTest, InstallLocalizedTheme) {
EXPECT_EQ("description", service_->extensions()->at(0)->description());
}
-TEST_F(ExtensionsServiceTest, InstallApps) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, InstallApps) {
+ InitializeEmptyExtensionService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
extensions_path = extensions_path.AppendASCII("extensions");
@@ -1569,8 +1613,8 @@ TEST_F(ExtensionsServiceTest, InstallApps) {
ValidatePrefKeyCount(pref_count);
}
-TEST_F(ExtensionsServiceTest, InstallAppsWithUnlimtedStorage) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, InstallAppsWithUnlimtedStorage) {
+ InitializeEmptyExtensionService();
EXPECT_TRUE(service_->extensions()->empty());
EXPECT_TRUE(service_->unlimited_storage_map_.empty());
@@ -1629,8 +1673,8 @@ TEST_F(ExtensionsServiceTest, InstallAppsWithUnlimtedStorage) {
EXPECT_TRUE(service_->unlimited_storage_map_.empty());
}
-TEST_F(ExtensionsServiceTest, InstallAppsAndCheckStorageProtection) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, InstallAppsAndCheckStorageProtection) {
+ InitializeEmptyExtensionService();
EXPECT_TRUE(service_->extensions()->empty());
EXPECT_TRUE(service_->protected_storage_map_.empty());
@@ -1673,8 +1717,8 @@ TEST_F(ExtensionsServiceTest, InstallAppsAndCheckStorageProtection) {
}
// Test that when an extension version is reinstalled, nothing happens.
-TEST_F(ExtensionsServiceTest, Reinstall) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, Reinstall) {
+ InitializeEmptyExtensionService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
extensions_path = extensions_path.AppendASCII("extensions");
@@ -1708,8 +1752,8 @@ TEST_F(ExtensionsServiceTest, Reinstall) {
}
// Test upgrading a signed extension.
-TEST_F(ExtensionsServiceTest, UpgradeSignedGood) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, UpgradeSignedGood) {
+ InitializeEmptyExtensionService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
extensions_path = extensions_path.AppendASCII("extensions");
@@ -1735,8 +1779,8 @@ TEST_F(ExtensionsServiceTest, UpgradeSignedGood) {
}
// Test upgrading a signed extension with a bad signature.
-TEST_F(ExtensionsServiceTest, UpgradeSignedBad) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, UpgradeSignedBad) {
+ InitializeEmptyExtensionService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
extensions_path = extensions_path.AppendASCII("extensions");
@@ -1762,8 +1806,8 @@ TEST_F(ExtensionsServiceTest, UpgradeSignedBad) {
}
// Test a normal update via the UpdateExtension API
-TEST_F(ExtensionsServiceTest, UpdateExtension) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, UpdateExtension) {
+ InitializeEmptyExtensionService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
extensions_path = extensions_path.AppendASCII("extensions");
@@ -1781,8 +1825,8 @@ TEST_F(ExtensionsServiceTest, UpdateExtension) {
}
// Test updating a not-already-installed extension - this should fail
-TEST_F(ExtensionsServiceTest, UpdateNotInstalledExtension) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, UpdateNotInstalledExtension) {
+ InitializeEmptyExtensionService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
extensions_path = extensions_path.AppendASCII("extensions");
@@ -1797,8 +1841,8 @@ TEST_F(ExtensionsServiceTest, UpdateNotInstalledExtension) {
}
// Makes sure you can't downgrade an extension via UpdateExtension
-TEST_F(ExtensionsServiceTest, UpdateWillNotDowngrade) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, UpdateWillNotDowngrade) {
+ InitializeEmptyExtensionService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
extensions_path = extensions_path.AppendASCII("extensions");
@@ -1817,8 +1861,8 @@ TEST_F(ExtensionsServiceTest, UpdateWillNotDowngrade) {
}
// Make sure calling update with an identical version does nothing
-TEST_F(ExtensionsServiceTest, UpdateToSameVersionIsNoop) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, UpdateToSameVersionIsNoop) {
+ InitializeEmptyExtensionService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
extensions_path = extensions_path.AppendASCII("extensions");
@@ -1832,8 +1876,8 @@ TEST_F(ExtensionsServiceTest, UpdateToSameVersionIsNoop) {
}
// Tests that updating an extension does not clobber old state.
-TEST_F(ExtensionsServiceTest, UpdateExtensionPreservesState) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, UpdateExtensionPreservesState) {
+ InitializeEmptyExtensionService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
extensions_path = extensions_path.AppendASCII("extensions");
@@ -1859,8 +1903,8 @@ TEST_F(ExtensionsServiceTest, UpdateExtensionPreservesState) {
}
// Tests that updating preserves extension location.
-TEST_F(ExtensionsServiceTest, UpdateExtensionPreservesLocation) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, UpdateExtensionPreservesLocation) {
+ InitializeEmptyExtensionService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
extensions_path = extensions_path.AppendASCII("extensions");
@@ -1883,36 +1927,83 @@ TEST_F(ExtensionsServiceTest, UpdateExtensionPreservesLocation) {
EXPECT_EQ(good2->location(), Extension::EXTERNAL_PREF);
}
+// Makes sure that LOAD extension types can downgrade.
+TEST_F(ExtensionServiceTest, LoadExtensionsCanDowngrade) {
+ InitializeEmptyExtensionService();
+
+ ScopedTempDir temp;
+ ASSERT_TRUE(temp.CreateUniqueTempDir());
+
+ // We'll write the extension manifest dynamically to a temporary path
+ // to make it easier to change the version number.
+ FilePath extension_path = temp.path();
+ FilePath manifest_path = extension_path.Append(Extension::kManifestFilename);
+ ASSERT_FALSE(file_util::PathExists(manifest_path));
+
+ // Start with version 2.0.
+ DictionaryValue manifest;
+ manifest.SetString("version", "2.0");
+ manifest.SetString("name", "LOAD Downgrade Test");
+
+ JSONFileValueSerializer serializer(manifest_path);
+ ASSERT_TRUE(serializer.Serialize(manifest));
+
+ service_->LoadExtension(extension_path);
+ loop_.RunAllPending();
+
+ EXPECT_EQ(0u, GetErrors().size());
+ ASSERT_EQ(1u, loaded_.size());
+ EXPECT_EQ(Extension::LOAD, loaded_[0]->location());
+ EXPECT_EQ(1u, service_->extensions()->size());
+ EXPECT_EQ("2.0", loaded_[0]->VersionString());
+
+ // Now set the version number to 1.0, reload the extensions and verify that
+ // the downgrade was accepted.
+ manifest.SetString("version", "1.0");
+ ASSERT_TRUE(serializer.Serialize(manifest));
+
+ service_->LoadExtension(extension_path);
+ loop_.RunAllPending();
+
+ EXPECT_EQ(0u, GetErrors().size());
+ ASSERT_EQ(1u, loaded_.size());
+ EXPECT_EQ(Extension::LOAD, loaded_[0]->location());
+ EXPECT_EQ(1u, service_->extensions()->size());
+ EXPECT_EQ("1.0", loaded_[0]->VersionString());
+}
+
+namespace {
+
+bool IsExtension(const Extension& extension) {
+ return extension.GetType() == Extension::TYPE_EXTENSION;
+}
+
+} // namespace
+
// Test adding a pending extension.
-TEST_F(ExtensionsServiceTest, AddPendingExtension) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, AddPendingExtensionFromSync) {
+ InitializeEmptyExtensionService();
const std::string kFakeId("fake-id");
const GURL kFakeUpdateURL("http:://fake.update/url");
- const PendingExtensionInfo::ExpectedCrxType kFakeExpectedCrxType =
- PendingExtensionInfo::EXTENSION;
const bool kFakeInstallSilently(true);
const Extension::State kFakeInitialState(Extension::ENABLED);
const bool kFakeInitialIncognitoEnabled(false);
service_->AddPendingExtensionFromSync(
- kFakeId, kFakeUpdateURL, kFakeExpectedCrxType, kFakeInstallSilently,
- kFakeInitialState, kFakeInitialIncognitoEnabled);
+ kFakeId, kFakeUpdateURL, &IsExtension,
+ kFakeInstallSilently, kFakeInitialState, kFakeInitialIncognitoEnabled);
PendingExtensionMap::const_iterator it =
service_->pending_extensions().find(kFakeId);
ASSERT_TRUE(it != service_->pending_extensions().end());
EXPECT_EQ(kFakeUpdateURL, it->second.update_url);
- EXPECT_EQ(kFakeExpectedCrxType, it->second.expected_crx_type);
+ EXPECT_EQ(&IsExtension, it->second.should_install_extension);
EXPECT_EQ(kFakeInstallSilently, it->second.install_silently);
}
namespace {
const char kGoodId[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
const char kGoodUpdateURL[] = "http://good.update/url";
-const PendingExtensionInfo::ExpectedCrxType kCrxTypeTheme =
- PendingExtensionInfo::THEME;
-const PendingExtensionInfo::ExpectedCrxType kCrxTypeExtension =
- PendingExtensionInfo::EXTENSION;
const bool kGoodIsFromSync = true;
const bool kGoodInstallSilently = true;
const Extension::State kGoodInitialState = Extension::DISABLED;
@@ -1920,10 +2011,10 @@ const bool kGoodInitialIncognitoEnabled = true;
} // namespace
// Test updating a pending extension.
-TEST_F(ExtensionsServiceTest, UpdatePendingExtension) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, UpdatePendingExtension) {
+ InitializeEmptyExtensionService();
service_->AddPendingExtensionFromSync(
- kGoodId, GURL(kGoodUpdateURL), kCrxTypeExtension,
+ kGoodId, GURL(kGoodUpdateURL), &IsExtension,
kGoodInstallSilently, kGoodInitialState,
kGoodInitialIncognitoEnabled);
EXPECT_TRUE(ContainsKey(service_->pending_extensions(), kGoodId));
@@ -1947,11 +2038,19 @@ TEST_F(ExtensionsServiceTest, UpdatePendingExtension) {
service_->IsIncognitoEnabled(extension));
}
+namespace {
+
+bool IsTheme(const Extension& extension) {
+ return extension.is_theme();
+}
+
+} // namespace
+
// Test updating a pending theme.
-TEST_F(ExtensionsServiceTest, UpdatePendingTheme) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, UpdatePendingTheme) {
+ InitializeEmptyExtensionService();
service_->AddPendingExtensionFromSync(
- theme_crx, GURL(), PendingExtensionInfo::THEME,
+ theme_crx, GURL(), &IsTheme,
false, Extension::ENABLED, false);
EXPECT_TRUE(ContainsKey(service_->pending_extensions(), theme_crx));
@@ -1974,8 +2073,8 @@ TEST_F(ExtensionsServiceTest, UpdatePendingTheme) {
// Test updating a pending CRX as if the source is an external extension
// with an update URL. In this case we don't know if the CRX is a theme
// or not.
-TEST_F(ExtensionsServiceTest, UpdatePendingExternalCrx) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, UpdatePendingExternalCrx) {
+ InitializeEmptyExtensionService();
service_->AddPendingExtensionFromExternalUpdateUrl(
theme_crx, GURL(), Extension::EXTERNAL_PREF_DOWNLOAD);
@@ -2000,12 +2099,12 @@ TEST_F(ExtensionsServiceTest, UpdatePendingExternalCrx) {
// Test updating a pending CRX as if the source is an external extension
// with an update URL. The external update should overwrite a sync update,
// but a sync update should not overwrite a non-sync update.
-TEST_F(ExtensionsServiceTest, UpdatePendingExternalCrxWinsOverSync) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, UpdatePendingExternalCrxWinsOverSync) {
+ InitializeEmptyExtensionService();
// Add a crx to be installed from the update mechanism.
service_->AddPendingExtensionFromSync(
- kGoodId, GURL(kGoodUpdateURL), kCrxTypeExtension,
+ kGoodId, GURL(kGoodUpdateURL), &IsExtension,
kGoodInstallSilently, kGoodInitialState,
kGoodInitialIncognitoEnabled);
@@ -2026,7 +2125,7 @@ TEST_F(ExtensionsServiceTest, UpdatePendingExternalCrxWinsOverSync) {
// Add a crx to be installed from the update mechanism.
service_->AddPendingExtensionFromSync(
- kGoodId, GURL(kGoodUpdateURL), kCrxTypeExtension,
+ kGoodId, GURL(kGoodUpdateURL), &IsExtension,
kGoodInstallSilently, kGoodInitialState,
kGoodInitialIncognitoEnabled);
@@ -2038,11 +2137,10 @@ TEST_F(ExtensionsServiceTest, UpdatePendingExternalCrxWinsOverSync) {
// Updating a theme should fail if the updater is explicitly told that
// the CRX is not a theme.
-TEST_F(ExtensionsServiceTest, UpdatePendingCrxThemeMismatch) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, UpdatePendingCrxThemeMismatch) {
+ InitializeEmptyExtensionService();
service_->AddPendingExtensionFromSync(
- theme_crx, GURL(),
- PendingExtensionInfo::EXTENSION,
+ theme_crx, GURL(), &IsExtension,
true, Extension::ENABLED, false);
EXPECT_TRUE(ContainsKey(service_->pending_extensions(), theme_crx));
@@ -2063,13 +2161,13 @@ TEST_F(ExtensionsServiceTest, UpdatePendingCrxThemeMismatch) {
// we can mock out ExtensionInstallUI and inject our version into
// UpdateExtension().
-// Test updating a pending extension with wrong is_theme.
-TEST_F(ExtensionsServiceTest, UpdatePendingExtensionWrongIsTheme) {
- InitializeEmptyExtensionsService();
+// Test updating a pending extension which fails the should-install test.
+TEST_F(ExtensionServiceTest, UpdatePendingExtensionFailedShouldInstallTest) {
+ InitializeEmptyExtensionService();
// Add pending extension with a flipped is_theme.
service_->AddPendingExtensionFromSync(
- kGoodId, GURL(kGoodUpdateURL),
- kCrxTypeTheme, kGoodInstallSilently, kGoodInitialState,
+ kGoodId, GURL(kGoodUpdateURL), &IsTheme,
+ kGoodInstallSilently, kGoodInitialState,
kGoodInitialIncognitoEnabled);
EXPECT_TRUE(ContainsKey(service_->pending_extensions(), kGoodId));
@@ -2089,8 +2187,8 @@ TEST_F(ExtensionsServiceTest, UpdatePendingExtensionWrongIsTheme) {
// unsyncable extensions are blocked.
// Test updating a pending extension for one that is not pending.
-TEST_F(ExtensionsServiceTest, UpdatePendingExtensionNotPending) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, UpdatePendingExtensionNotPending) {
+ InitializeEmptyExtensionService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
@@ -2103,8 +2201,8 @@ TEST_F(ExtensionsServiceTest, UpdatePendingExtensionNotPending) {
// Test updating a pending extension for one that is already
// installed.
-TEST_F(ExtensionsServiceTest, UpdatePendingExtensionAlreadyInstalled) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, UpdatePendingExtensionAlreadyInstalled) {
+ InitializeEmptyExtensionService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
@@ -2119,8 +2217,7 @@ TEST_F(ExtensionsServiceTest, UpdatePendingExtensionAlreadyInstalled) {
// Use AddPendingExtensionInternal() as AddPendingExtension() would
// balk.
service_->AddPendingExtensionInternal(
- good->id(), good->update_url(),
- PendingExtensionInfo::EXTENSION,
+ good->id(), good->update_url(), &IsExtension,
kGoodIsFromSync, kGoodInstallSilently, kGoodInitialState,
kGoodInitialIncognitoEnabled, Extension::INTERNAL);
UpdateExtension(good->id(), path, INSTALLED);
@@ -2129,8 +2226,8 @@ TEST_F(ExtensionsServiceTest, UpdatePendingExtensionAlreadyInstalled) {
}
// Test pref settings for blacklist and unblacklist extensions.
-TEST_F(ExtensionsServiceTest, SetUnsetBlacklistInPrefs) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, SetUnsetBlacklistInPrefs) {
+ InitializeEmptyExtensionService();
std::vector<std::string> blacklist;
blacklist.push_back(good0);
blacklist.push_back("invalid_id"); // an invalid id
@@ -2158,8 +2255,8 @@ TEST_F(ExtensionsServiceTest, SetUnsetBlacklistInPrefs) {
}
// Unload installed extension from blacklist.
-TEST_F(ExtensionsServiceTest, UnloadBlacklistedExtension) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, UnloadBlacklistedExtension) {
+ InitializeEmptyExtensionService();
FilePath extensions_path;
EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
extensions_path = extensions_path.AppendASCII("extensions");
@@ -2191,8 +2288,8 @@ TEST_F(ExtensionsServiceTest, UnloadBlacklistedExtension) {
}
// Unload installed extension from blacklist.
-TEST_F(ExtensionsServiceTest, BlacklistedExtensionWillNotInstall) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, BlacklistedExtensionWillNotInstall) {
+ InitializeEmptyExtensionService();
std::vector<std::string> blacklist;
blacklist.push_back(good_crx);
service_->UpdateExtensionBlacklist(blacklist);
@@ -2215,7 +2312,7 @@ TEST_F(ExtensionsServiceTest, BlacklistedExtensionWillNotInstall) {
// Test loading extensions from the profile directory, except
// blacklisted ones.
-TEST_F(ExtensionsServiceTest, WillNotLoadBlacklistedExtensionsFromDirectory) {
+TEST_F(ExtensionServiceTest, WillNotLoadBlacklistedExtensionsFromDirectory) {
// Initialize the test dir with a good Preferences/extensions.
FilePath source_install_dir;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &source_install_dir));
@@ -2226,7 +2323,7 @@ TEST_F(ExtensionsServiceTest, WillNotLoadBlacklistedExtensionsFromDirectory) {
FilePath pref_path = source_install_dir
.DirName()
.AppendASCII("Preferences");
- InitializeInstalledExtensionsService(pref_path, source_install_dir);
+ InitializeInstalledExtensionService(pref_path, source_install_dir);
// Blacklist good1.
std::vector<std::string> blacklist;
@@ -2255,7 +2352,7 @@ TEST_F(ExtensionsServiceTest, WillNotLoadBlacklistedExtensionsFromDirectory) {
#if defined(OS_CHROMEOS)
// Test loading extensions from the profile directory, except
// ones with a plugin.
-TEST_F(ExtensionsServiceTest, WillNotLoadPluginExtensionsFromDirectory) {
+TEST_F(ExtensionServiceTest, WillNotLoadPluginExtensionsFromDirectory) {
// Initialize the test dir with a good Preferences/extensions.
FilePath source_install_dir;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &source_install_dir));
@@ -2266,7 +2363,7 @@ TEST_F(ExtensionsServiceTest, WillNotLoadPluginExtensionsFromDirectory) {
FilePath pref_path = source_install_dir
.DirName()
.AppendASCII("Preferences");
- InitializeInstalledExtensionsService(pref_path, source_install_dir);
+ InitializeInstalledExtensionService(pref_path, source_install_dir);
// good1 contains a plugin.
// Load extensions.
@@ -2286,13 +2383,13 @@ TEST_F(ExtensionsServiceTest, WillNotLoadPluginExtensionsFromDirectory) {
#endif
// Will not install extension blacklisted by policy.
-TEST_F(ExtensionsServiceTest, BlacklistedByPolicyWillNotInstall) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, BlacklistedByPolicyWillNotInstall) {
+ InitializeEmptyExtensionService();
ListValue* whitelist =
- profile_->GetPrefs()->GetMutableList("extensions.install.allowlist");
+ profile_->GetPrefs()->GetMutableList(prefs::kExtensionInstallAllowList);
ListValue* blacklist =
- profile_->GetPrefs()->GetMutableList("extensions.install.denylist");
+ profile_->GetPrefs()->GetMutableList(prefs::kExtensionInstallDenyList);
ASSERT_TRUE(whitelist != NULL && blacklist != NULL);
// Blacklist everything.
@@ -2317,8 +2414,8 @@ TEST_F(ExtensionsServiceTest, BlacklistedByPolicyWillNotInstall) {
}
// Extension blacklisted by policy get unloaded after installing.
-TEST_F(ExtensionsServiceTest, BlacklistedByPolicyRemovedIfRunning) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, BlacklistedByPolicyRemovedIfRunning) {
+ InitializeEmptyExtensionService();
// Install good_crx.
FilePath extensions_path;
@@ -2329,18 +2426,17 @@ TEST_F(ExtensionsServiceTest, BlacklistedByPolicyRemovedIfRunning) {
loop_.RunAllPending();
EXPECT_EQ(1u, service_->extensions()->size());
- PrefService* prefs = profile_->GetPrefs();
- ListValue* blacklist =
- prefs->GetMutableList("extensions.install.denylist");
- ASSERT_TRUE(blacklist != NULL);
-
- // Blacklist this extension.
- blacklist->Append(Value::CreateStringValue(good_crx));
- prefs->ScheduleSavePersistentPrefs();
-
- // Programmatically appending to the prefs doesn't seem to notify the
- // observers... :/
- prefs->pref_notifier()->FireObservers("extensions.install.denylist");
+ { // Scope for pref update notification.
+ PrefService* prefs = profile_->GetPrefs();
+ ScopedPrefUpdate pref_update(prefs, prefs::kExtensionInstallDenyList);
+ ListValue* blacklist =
+ prefs->GetMutableList(prefs::kExtensionInstallDenyList);
+ ASSERT_TRUE(blacklist != NULL);
+
+ // Blacklist this extension.
+ blacklist->Append(Value::CreateStringValue(good_crx));
+ prefs->ScheduleSavePersistentPrefs();
+ }
// Extension should not be running now.
loop_.RunAllPending();
@@ -2348,8 +2444,8 @@ TEST_F(ExtensionsServiceTest, BlacklistedByPolicyRemovedIfRunning) {
}
// Tests disabling extensions
-TEST_F(ExtensionsServiceTest, DisableExtension) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, DisableExtension) {
+ InitializeEmptyExtensionService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
extensions_path = extensions_path.AppendASCII("extensions");
@@ -2374,8 +2470,8 @@ TEST_F(ExtensionsServiceTest, DisableExtension) {
}
// Tests disabling all extensions (simulating --disable-extensions flag).
-TEST_F(ExtensionsServiceTest, DisableAllExtensions) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, DisableAllExtensions) {
+ InitializeEmptyExtensionService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
@@ -2412,8 +2508,8 @@ TEST_F(ExtensionsServiceTest, DisableAllExtensions) {
}
// Tests reloading extensions
-TEST_F(ExtensionsServiceTest, ReloadExtensions) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, ReloadExtensions) {
+ InitializeEmptyExtensionService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
extensions_path = extensions_path.AppendASCII("extensions");
@@ -2450,8 +2546,8 @@ TEST_F(ExtensionsServiceTest, ReloadExtensions) {
}
// Tests uninstalling normal extensions
-TEST_F(ExtensionsServiceTest, UninstallExtension) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, UninstallExtension) {
+ InitializeEmptyExtensionService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
extensions_path = extensions_path.AppendASCII("extensions");
@@ -2488,8 +2584,8 @@ TEST_F(ExtensionsServiceTest, UninstallExtension) {
}
// Tests the uninstaller helper.
-TEST_F(ExtensionsServiceTest, UninstallExtensionHelper) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, UninstallExtensionHelper) {
+ InitializeEmptyExtensionService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
extensions_path = extensions_path.AppendASCII("extensions");
@@ -2503,7 +2599,7 @@ TEST_F(ExtensionsServiceTest, UninstallExtensionHelper) {
FilePath extension_path = extensions_install_dir_.AppendASCII(extension_id);
EXPECT_TRUE(file_util::PathExists(extension_path));
- bool result = ExtensionsService::UninstallExtensionHelper(service_,
+ bool result = ExtensionService::UninstallExtensionHelper(service_,
extension_id);
total_successes_ = 0;
@@ -2524,13 +2620,13 @@ TEST_F(ExtensionsServiceTest, UninstallExtensionHelper) {
// Attempt to uninstall again. This should fail as we just removed the
// extension.
- result = ExtensionsService::UninstallExtensionHelper(service_, extension_id);
+ result = ExtensionService::UninstallExtensionHelper(service_, extension_id);
EXPECT_FALSE(result);
}
// Verifies extension state is removed upon uninstall
-TEST_F(ExtensionsServiceTest, ClearExtensionData) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, ClearExtensionData) {
+ InitializeEmptyExtensionService();
// Load a test extension.
FilePath path;
@@ -2550,8 +2646,7 @@ TEST_F(ExtensionsServiceTest, ClearExtensionData) {
ASSERT_TRUE(cookie_monster);
net::CookieOptions options;
cookie_monster->SetCookieWithOptions(ext_url, "dummy=value", options);
- net::CookieMonster::CookieList list =
- cookie_monster->GetAllCookiesForURL(ext_url);
+ net::CookieList list = cookie_monster->GetAllCookiesForURL(ext_url);
EXPECT_EQ(1U, list.size());
// Open a database.
@@ -2607,8 +2702,8 @@ TEST_F(ExtensionsServiceTest, ClearExtensionData) {
}
// Tests loading single extensions (like --load-extension)
-TEST_F(ExtensionsServiceTest, LoadExtension) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, LoadExtension) {
+ InitializeEmptyExtensionService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
extensions_path = extensions_path.AppendASCII("extensions");
@@ -2650,8 +2745,8 @@ TEST_F(ExtensionsServiceTest, LoadExtension) {
// Tests that we generate IDs when they are not specified in the manifest for
// --load-extension.
-TEST_F(ExtensionsServiceTest, GenerateID) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, GenerateID) {
+ InitializeEmptyExtensionService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
@@ -2676,7 +2771,7 @@ TEST_F(ExtensionsServiceTest, GenerateID) {
ASSERT_EQ(previous_id, loaded_[0]->id());
}
-void ExtensionsServiceTest::TestExternalProvider(
+void ExtensionServiceTest::TestExternalProvider(
MockExtensionProvider* provider, Extension::Location location) {
// Verify that starting with no providers loads no extensions.
service_->Init();
@@ -2806,9 +2901,9 @@ void ExtensionsServiceTest::TestExternalProvider(
// Tests the external installation feature
#if defined(OS_WIN)
-TEST_F(ExtensionsServiceTest, ExternalInstallRegistry) {
+TEST_F(ExtensionServiceTest, ExternalInstallRegistry) {
// This should all work, even when normal extension installation is disabled.
- InitializeEmptyExtensionsService();
+ InitializeEmptyExtensionService();
set_extensions_enabled(false);
// Now add providers. Extension system takes ownership of the objects.
@@ -2819,8 +2914,8 @@ TEST_F(ExtensionsServiceTest, ExternalInstallRegistry) {
}
#endif
-TEST_F(ExtensionsServiceTest, ExternalInstallPref) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, ExternalInstallPref) {
+ InitializeEmptyExtensionService();
// Now add providers. Extension system takes ownership of the objects.
MockExtensionProvider* pref_provider =
@@ -2830,9 +2925,9 @@ TEST_F(ExtensionsServiceTest, ExternalInstallPref) {
TestExternalProvider(pref_provider, Extension::EXTERNAL_PREF);
}
-TEST_F(ExtensionsServiceTest, ExternalInstallPrefUpdateUrl) {
+TEST_F(ExtensionServiceTest, ExternalInstallPrefUpdateUrl) {
// This should all work, even when normal extension installation is disabled.
- InitializeEmptyExtensionsService();
+ InitializeEmptyExtensionService();
set_extensions_enabled(false);
// TODO(skerner): The mock provider is not a good model of a provider
@@ -2850,7 +2945,7 @@ TEST_F(ExtensionsServiceTest, ExternalInstallPrefUpdateUrl) {
// Tests that external extensions get uninstalled when the external extension
// providers can't account for them.
-TEST_F(ExtensionsServiceTest, ExternalUninstall) {
+TEST_F(ExtensionServiceTest, ExternalUninstall) {
// Start the extensions service with one external extension already installed.
FilePath source_install_dir;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &source_install_dir));
@@ -2863,7 +2958,7 @@ TEST_F(ExtensionsServiceTest, ExternalUninstall) {
.AppendASCII("PreferencesExternal");
// This initializes the extensions service with no ExternalExtensionProviders.
- InitializeInstalledExtensionsService(pref_path, source_install_dir);
+ InitializeInstalledExtensionService(pref_path, source_install_dir);
set_extensions_enabled(false);
service_->Init();
@@ -2881,8 +2976,8 @@ TEST_F(ExtensionsServiceTest, ExternalUninstall) {
ASSERT_EQ(0u, loaded_.size());
}
-TEST_F(ExtensionsServiceTest, ExternalPrefProvider) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, ExternalPrefProvider) {
+ InitializeEmptyExtensionService();
std::string json_data =
"{"
" \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
@@ -2899,14 +2994,6 @@ TEST_F(ExtensionsServiceTest, ExternalPrefProvider) {
"}";
MockProviderVisitor visitor;
- std::set<std::string> ignore_list;
- EXPECT_EQ(3, visitor.Visit(json_data, ignore_list));
- ignore_list.insert("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
- EXPECT_EQ(2, visitor.Visit(json_data, ignore_list));
- ignore_list.insert("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
- EXPECT_EQ(1, visitor.Visit(json_data, ignore_list));
- ignore_list.insert("cccccccccccccccccccccccccccccccc");
- EXPECT_EQ(0, visitor.Visit(json_data, ignore_list));
// Simulate an external_extensions.json file that contains seven invalid
// extensions:
@@ -2950,12 +3037,11 @@ TEST_F(ExtensionsServiceTest, ExternalPrefProvider) {
" \"external_version\": \"1.0\""
" }"
"}";
- ignore_list.clear();
- EXPECT_EQ(1, visitor.Visit(json_data, ignore_list));
+ EXPECT_EQ(1, visitor.Visit(json_data));
}
// Test loading good extensions from the profile directory.
-TEST_F(ExtensionsServiceTest, LoadAndRelocalizeExtensions) {
+TEST_F(ExtensionServiceTest, LoadAndRelocalizeExtensions) {
// Initialize the test dir with a good Preferences/extensions.
FilePath source_install_dir;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &source_install_dir));
@@ -2963,7 +3049,7 @@ TEST_F(ExtensionsServiceTest, LoadAndRelocalizeExtensions) {
.AppendASCII("extensions")
.AppendASCII("l10n");
FilePath pref_path = source_install_dir.AppendASCII("Preferences");
- InitializeInstalledExtensionsService(pref_path, source_install_dir);
+ InitializeInstalledExtensionService(pref_path, source_install_dir);
service_->Init();
loop_.RunAllPending();
@@ -3013,25 +3099,25 @@ class ExtensionsReadyRecorder : public NotificationObserver {
};
// Test that we get enabled/disabled correctly for all the pref/command-line
-// combinations. We don't want to derive from the ExtensionsServiceTest class
-// for this test, so we use ExtensionsServiceTestSimple.
+// combinations. We don't want to derive from the ExtensionServiceTest class
+// for this test, so we use ExtensionServiceTestSimple.
//
// Also tests that we always fire EXTENSIONS_READY, no matter whether we are
// enabled or not.
-TEST(ExtensionsServiceTestSimple, Enabledness) {
+TEST(ExtensionServiceTestSimple, Enabledness) {
ExtensionsReadyRecorder recorder;
scoped_ptr<TestingProfile> profile(new TestingProfile());
MessageLoop loop;
BrowserThread ui_thread(BrowserThread::UI, &loop);
BrowserThread file_thread(BrowserThread::FILE, &loop);
scoped_ptr<CommandLine> command_line;
- scoped_refptr<ExtensionsService> service;
+ scoped_refptr<ExtensionService> service;
FilePath install_dir = profile->GetPath()
- .AppendASCII(ExtensionsService::kInstallDirectoryName);
+ .AppendASCII(ExtensionService::kInstallDirectoryName);
// By default, we are enabled.
command_line.reset(new CommandLine(CommandLine::NO_PROGRAM));
- service = profile->CreateExtensionsService(command_line.get(),
+ service = profile->CreateExtensionService(command_line.get(),
install_dir);
EXPECT_TRUE(service->extensions_enabled());
service->Init();
@@ -3042,7 +3128,7 @@ TEST(ExtensionsServiceTestSimple, Enabledness) {
recorder.set_ready(false);
profile.reset(new TestingProfile());
command_line->AppendSwitch(switches::kDisableExtensions);
- service = profile->CreateExtensionsService(command_line.get(),
+ service = profile->CreateExtensionService(command_line.get(),
install_dir);
EXPECT_FALSE(service->extensions_enabled());
service->Init();
@@ -3052,7 +3138,7 @@ TEST(ExtensionsServiceTestSimple, Enabledness) {
recorder.set_ready(false);
profile.reset(new TestingProfile());
profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
- service = profile->CreateExtensionsService(command_line.get(),
+ service = profile->CreateExtensionService(command_line.get(),
install_dir);
EXPECT_FALSE(service->extensions_enabled());
service->Init();
@@ -3063,7 +3149,7 @@ TEST(ExtensionsServiceTestSimple, Enabledness) {
profile.reset(new TestingProfile());
profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
command_line.reset(new CommandLine(CommandLine::NO_PROGRAM));
- service = profile->CreateExtensionsService(command_line.get(),
+ service = profile->CreateExtensionService(command_line.get(),
install_dir);
EXPECT_FALSE(service->extensions_enabled());
service->Init();
@@ -3076,8 +3162,8 @@ TEST(ExtensionsServiceTestSimple, Enabledness) {
}
// Test loading extensions that require limited and unlimited storage quotas.
-TEST_F(ExtensionsServiceTest, StorageQuota) {
- InitializeEmptyExtensionsService();
+TEST_F(ExtensionServiceTest, StorageQuota) {
+ InitializeEmptyExtensionService();
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
@@ -3135,9 +3221,9 @@ TEST_F(ExtensionsServiceTest, StorageQuota) {
EXPECT_EQ(kint64max, unlimited_quota);
}
-// Tests ExtensionsService::register_component_extension().
-TEST_F(ExtensionsServiceTest, ComponentExtensions) {
- InitializeEmptyExtensionsService();
+// Tests ExtensionService::register_component_extension().
+TEST_F(ExtensionServiceTest, ComponentExtensions) {
+ InitializeEmptyExtensionService();
// Component extensions should work even when extensions are disabled.
set_extensions_enabled(false);
@@ -3155,7 +3241,7 @@ TEST_F(ExtensionsServiceTest, ComponentExtensions) {
path.Append(Extension::kManifestFilename), &manifest));
service_->register_component_extension(
- ExtensionsService::ComponentExtensionInfo(manifest, path));
+ ExtensionService::ComponentExtensionInfo(manifest, path));
service_->Init();
// Note that we do not pump messages -- the extension should be loaded
diff --git a/chrome/browser/extensions/extensions_service_unittest.h b/chrome/browser/extensions/extension_service_unittest.h
index f38cc34..8ca7b28 100644
--- a/chrome/browser/extensions/extensions_service_unittest.h
+++ b/chrome/browser/extensions/extension_service_unittest.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSIONS_SERVICE_UNITTEST_H_
-#define CHROME_BROWSER_EXTENSIONS_EXTENSIONS_SERVICE_UNITTEST_H_
+#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_SERVICE_UNITTEST_H_
+#define CHROME_BROWSER_EXTENSIONS_EXTENSION_SERVICE_UNITTEST_H_
#pragma once
#include "base/file_path.h"
@@ -12,21 +12,21 @@
#include "base/scoped_ptr.h"
#include "base/scoped_temp_dir.h"
#include "chrome/browser/browser_thread.h"
-#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/extensions/extension_service.h"
#include "testing/gtest/include/gtest/gtest.h"
-class ExtensionsServiceTestBase : public testing::Test {
+class ExtensionServiceTestBase : public testing::Test {
public:
- ExtensionsServiceTestBase();
- ~ExtensionsServiceTestBase();
+ ExtensionServiceTestBase();
+ ~ExtensionServiceTestBase();
- virtual void InitializeExtensionsService(
+ virtual void InitializeExtensionService(
const FilePath& pref_file, const FilePath& extensions_install_dir);
- virtual void InitializeInstalledExtensionsService(
+ virtual void InitializeInstalledExtensionService(
const FilePath& prefs_file, const FilePath& source_install_dir);
- virtual void InitializeEmptyExtensionsService();
+ virtual void InitializeEmptyExtensionService();
static void SetUpTestCase();
@@ -40,7 +40,7 @@ class ExtensionsServiceTestBase : public testing::Test {
ScopedTempDir temp_dir_;
scoped_ptr<Profile> profile_;
FilePath extensions_install_dir_;
- scoped_refptr<ExtensionsService> service_;
+ scoped_refptr<ExtensionService> service_;
size_t total_successes_;
MessageLoop loop_;
BrowserThread ui_thread_;
@@ -50,4 +50,4 @@ class ExtensionsServiceTestBase : public testing::Test {
BrowserThread io_thread_;
};
-#endif // CHROME_BROWSER_EXTENSIONS_EXTENSIONS_SERVICE_UNITTEST_H_
+#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_SERVICE_UNITTEST_H_
diff --git a/chrome/browser/extensions/extension_sidebar_api.cc b/chrome/browser/extensions/extension_sidebar_api.cc
index 5495a8e..bd32d5a 100644
--- a/chrome/browser/extensions/extension_sidebar_api.cc
+++ b/chrome/browser/extensions/extension_sidebar_api.cc
@@ -10,13 +10,13 @@
#include "base/string16.h"
#include "base/values.h"
#include "chrome/browser/extensions/extension_event_router.h"
-#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_tabs_module.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/sidebar/sidebar_container.h"
#include "chrome/browser/sidebar/sidebar_manager.h"
#include "chrome/browser/tab_contents/tab_contents.h"
-#include "chrome/browser/tab_contents_wrapper.h"
+#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/extensions/extension_error_utils.h"
diff --git a/chrome/browser/extensions/extension_startup_browsertest.cc b/chrome/browser/extensions/extension_startup_browsertest.cc
index 97cc84d..25bad91 100644
--- a/chrome/browser/extensions/extension_startup_browsertest.cc
+++ b/chrome/browser/extensions/extension_startup_browsertest.cc
@@ -8,9 +8,9 @@
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
-#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/user_script_master.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_paths.h"
@@ -18,7 +18,6 @@
#include "chrome/common/notification_details.h"
#include "chrome/common/notification_observer.h"
#include "chrome/common/notification_registrar.h"
-#include "chrome/common/notification_service.h"
#include "chrome/common/notification_type.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
@@ -85,7 +84,7 @@ class ExtensionStartupTestBase : public InProcessBrowserTest {
void WaitForServicesToStart(int num_expected_extensions,
bool expect_extensions_enabled) {
- ExtensionsService* service = browser()->profile()->GetExtensionsService();
+ ExtensionService* service = browser()->profile()->GetExtensionService();
// Count the number of non-component extensions.
int found_extensions = 0;
@@ -168,7 +167,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionsStartupTest, Test) {
IN_PROC_BROWSER_TEST_F(ExtensionsStartupTest, MAYBE_NoFileAccess) {
WaitForServicesToStart(num_expected_extensions_, true);
- ExtensionsService* service = browser()->profile()->GetExtensionsService();
+ ExtensionService* service = browser()->profile()->GetExtensionService();
for (size_t i = 0; i < service->extensions()->size(); ++i) {
if (service->extensions()->at(i)->location() == Extension::COMPONENT)
continue;
diff --git a/chrome/browser/extensions/extension_tabs_apitest.cc b/chrome/browser/extensions/extension_tabs_apitest.cc
index 6ec3e6c..b736777 100644
--- a/chrome/browser/extensions/extension_tabs_apitest.cc
+++ b/chrome/browser/extensions/extension_tabs_apitest.cc
@@ -5,7 +5,7 @@
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/prefs/pref_service.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/pref_names.h"
diff --git a/chrome/browser/extensions/extension_tabs_module.cc b/chrome/browser/extensions/extension_tabs_module.cc
index 169cfff..b58e07c 100644
--- a/chrome/browser/extensions/extension_tabs_module.cc
+++ b/chrome/browser/extensions/extension_tabs_module.cc
@@ -4,6 +4,9 @@
#include "chrome/browser/extensions/extension_tabs_module.h"
+#include <algorithm>
+#include <vector>
+
#include "base/base64.h"
#include "base/string_number_conversions.h"
#include "base/string_util.h"
@@ -15,21 +18,22 @@
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extension_infobar_delegate.h"
#include "chrome/browser/extensions/extension_tabs_module_constants.h"
-#include "chrome/browser/extensions/extensions_service.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_host/backing_store.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/render_view_host_delegate.h"
#include "chrome/browser/tab_contents/navigation_entry.h"
#include "chrome/browser/tab_contents/tab_contents_view.h"
#include "chrome/browser/tab_contents/tab_contents.h"
-#include "chrome/browser/tab_contents_wrapper.h"
#include "chrome/browser/tabs/tab_strip_model.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_navigator.h"
-#include "chrome/browser/window_sizer.h"
+#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
+#include "chrome/browser/ui/window_sizer.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_error_utils.h"
+#include "chrome/common/notification_service.h"
#include "chrome/common/url_constants.h"
#include "gfx/codec/jpeg_codec.h"
#include "gfx/codec/png_codec.h"
@@ -310,6 +314,7 @@ bool GetAllWindowsFunction::RunImpl() {
bool CreateWindowFunction::RunImpl() {
DictionaryValue* args = NULL;
std::vector<GURL> urls;
+ TabContentsWrapper* contents = NULL;
if (HasOptionalArgument(0))
EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &args));
@@ -349,6 +354,29 @@ bool CreateWindowFunction::RunImpl() {
}
}
+ // Look for optional tab id.
+ if (args) {
+ int tab_id;
+ if (args->HasKey(keys::kTabIdKey)) {
+ EXTENSION_FUNCTION_VALIDATE(args->GetInteger(keys::kTabIdKey, &tab_id));
+
+ // Find the tab and detach it from the original window.
+ Browser* source_browser = NULL;
+ TabStripModel* source_tab_strip = NULL;
+ int tab_index = -1;
+ if (!GetTabById(tab_id, profile(), include_incognito(),
+ &source_browser, &source_tab_strip, &contents,
+ &tab_index, &error_))
+ return false;
+ contents = source_tab_strip->DetachTabContentsAt(tab_index);
+ if (!contents) {
+ error_ = ExtensionErrorUtils::FormatErrorMessage(
+ keys::kTabNotFoundError, base::IntToString(tab_id));
+ return false;
+ }
+ }
+ }
+
// Try to position the new browser relative its originating browser window.
gfx::Rect window_bounds;
bool maximized;
@@ -428,8 +456,13 @@ bool CreateWindowFunction::RunImpl() {
Browser* new_window = Browser::CreateForType(window_type, window_profile);
for (std::vector<GURL>::iterator i = urls.begin(); i != urls.end(); ++i)
new_window->AddSelectedTabWithURL(*i, PageTransition::LINK);
- if (urls.size() == 0)
+ if (contents) {
+ TabStripModel* target_tab_strip = new_window->tabstrip_model();
+ target_tab_strip->InsertTabContentsAt(urls.size(), contents,
+ TabStripModel::ADD_NONE);
+ } else if (urls.size() == 0) {
new_window->NewTab();
+ }
new_window->SelectNumberedTab(0);
if (window_type & Browser::TYPE_POPUP)
new_window->window()->SetBounds(popup_bounds);
@@ -517,6 +550,13 @@ bool RemoveWindowFunction::RunImpl() {
if (!browser)
return false;
+ // Don't let the extension remove the window if the user is dragging tabs
+ // in that window.
+ if (!browser->IsTabStripEditable()) {
+ error_ = keys::kTabStripNotEditableError;
+ return false;
+ }
+
browser->CloseWindow();
return true;
@@ -815,8 +855,9 @@ bool MoveTabFunction::RunImpl() {
&tab_index, &error_))
return false;
- if (source_browser->type() != Browser::TYPE_NORMAL) {
- error_ = keys::kCanOnlyMoveTabsWithinNormalWindowsError;
+ // Don't let the extension move the tab if the user is dragging tabs.
+ if (!source_browser->IsTabStripEditable()) {
+ error_ = keys::kTabStripNotEditableError;
return false;
}
@@ -830,6 +871,11 @@ bool MoveTabFunction::RunImpl() {
if (!target_browser)
return false;
+ if (!target_browser->IsTabStripEditable()) {
+ error_ = keys::kTabStripNotEditableError;
+ return false;
+ }
+
if (target_browser->type() != Browser::TYPE_NORMAL) {
error_ = keys::kCanOnlyMoveTabsWithinNormalWindowsError;
return false;
@@ -889,6 +935,12 @@ bool RemoveTabFunction::RunImpl() {
&browser, NULL, &contents, NULL, &error_))
return false;
+ // Don't let the extension remove a tab if the user is dragging tabs around.
+ if (!browser->IsTabStripEditable()) {
+ error_ = keys::kTabStripNotEditableError;
+ return false;
+ }
+
// Close the tab in this convoluted way, since there's a chance that the tab
// is being dragged, or we're in some other nested event loop. This code path
// should ensure that the tab is safely closed under such circumstances,
diff --git a/chrome/browser/extensions/extension_tabs_module.h b/chrome/browser/extensions/extension_tabs_module.h
index 4307c90..7125867 100644
--- a/chrome/browser/extensions/extension_tabs_module.h
+++ b/chrome/browser/extensions/extension_tabs_module.h
@@ -9,7 +9,6 @@
#include <string>
#include "chrome/browser/extensions/extension_function.h"
-#include "chrome/common/notification_service.h"
#include "chrome/common/notification_observer.h"
#include "chrome/common/notification_registrar.h"
diff --git a/chrome/browser/extensions/extension_tabs_module_constants.cc b/chrome/browser/extensions/extension_tabs_module_constants.cc
index 6405783..6ea521f 100644
--- a/chrome/browser/extensions/extension_tabs_module_constants.cc
+++ b/chrome/browser/extensions/extension_tabs_module_constants.cc
@@ -58,6 +58,8 @@ const char kNoCurrentWindowError[] = "No current window";
const char kNoLastFocusedWindowError[] = "No last-focused window";
const char kWindowNotFoundError[] = "No window with id: *.";
const char kTabNotFoundError[] = "No tab with id: *.";
+const char kTabStripNotEditableError[] =
+ "Tabs cannot be edited right now (user may be dragging a tab).";
const char kNoSelectedTabError[] = "No selected tab";
const char kInvalidUrlError[] = "Invalid url: \"*\".";
const char kInternalVisibleTabCaptureError[] =
diff --git a/chrome/browser/extensions/extension_tabs_module_constants.h b/chrome/browser/extensions/extension_tabs_module_constants.h
index 89c1cd3..4ac09de 100644
--- a/chrome/browser/extensions/extension_tabs_module_constants.h
+++ b/chrome/browser/extensions/extension_tabs_module_constants.h
@@ -61,6 +61,7 @@ extern const char kNoCurrentWindowError[];
extern const char kNoLastFocusedWindowError[];
extern const char kWindowNotFoundError[];
extern const char kTabNotFoundError[];
+extern const char kTabStripNotEditableError[];
extern const char kNoSelectedTabError[];
extern const char kInvalidUrlError[];
extern const char kInternalVisibleTabCaptureError[];
diff --git a/chrome/browser/extensions/extension_test_api.cc b/chrome/browser/extensions/extension_test_api.cc
index eb50391..83800b0 100644
--- a/chrome/browser/extensions/extension_test_api.cc
+++ b/chrome/browser/extensions/extension_test_api.cc
@@ -6,9 +6,10 @@
#include <string>
-#include "chrome/browser/extensions/extensions_service.h"
+#include "base/singleton.h"
+#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extensions_quota_service.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/notification_service.h"
@@ -55,7 +56,7 @@ bool ExtensionTestLogFunction::RunImpl() {
ExtensionTestQuotaResetFunction::~ExtensionTestQuotaResetFunction() {}
bool ExtensionTestQuotaResetFunction::RunImpl() {
- ExtensionsService* service = profile()->GetExtensionsService();
+ ExtensionService* service = profile()->GetExtensionService();
ExtensionsQuotaService* quota = service->quota_service();
quota->Purge();
quota->violators_.clear();
@@ -93,17 +94,23 @@ void ExtensionTestSendMessageFunction::Reply(const std::string& message) {
// static
void ExtensionTestGetConfigFunction::set_test_config_state(
DictionaryValue* value) {
- TestConfigState* test_config_state = Singleton<TestConfigState>::get();
+ TestConfigState* test_config_state = TestConfigState::GetInstance();
test_config_state->set_config_state(value);
}
ExtensionTestGetConfigFunction::TestConfigState::TestConfigState()
: config_state_(NULL) {}
+// static
+ExtensionTestGetConfigFunction::TestConfigState*
+ExtensionTestGetConfigFunction::TestConfigState::GetInstance() {
+ return Singleton<TestConfigState>::get();
+}
+
ExtensionTestGetConfigFunction::~ExtensionTestGetConfigFunction() {}
bool ExtensionTestGetConfigFunction::RunImpl() {
- TestConfigState* test_config_state = Singleton<TestConfigState>::get();
+ TestConfigState* test_config_state = TestConfigState::GetInstance();
if (!test_config_state->config_state()) {
error_ = kNoTestConfigDataError;
diff --git a/chrome/browser/extensions/extension_test_api.h b/chrome/browser/extensions/extension_test_api.h
index 27b55dc..1a0baa0 100644
--- a/chrome/browser/extensions/extension_test_api.h
+++ b/chrome/browser/extensions/extension_test_api.h
@@ -6,10 +6,11 @@
#define CHROME_BROWSER_EXTENSIONS_EXTENSION_TEST_API_H_
#pragma once
-#include "base/singleton.h"
#include "base/values.h"
#include "chrome/browser/extensions/extension_function.h"
+template <typename T> struct DefaultSingletonTraits;
+
class ExtensionTestPassFunction : public SyncExtensionFunction {
~ExtensionTestPassFunction();
virtual bool RunImpl();
@@ -65,6 +66,8 @@ class ExtensionTestGetConfigFunction : public SyncExtensionFunction {
// state, owned by the test code.
class TestConfigState {
public:
+ static TestConfigState* GetInstance();
+
void set_config_state(DictionaryValue* config_state) {
config_state_ = config_state;
}
diff --git a/chrome/browser/extensions/extension_toolbar_model.cc b/chrome/browser/extensions/extension_toolbar_model.cc
index 973dba8..3979cbf 100644
--- a/chrome/browser/extensions/extension_toolbar_model.cc
+++ b/chrome/browser/extensions/extension_toolbar_model.cc
@@ -5,14 +5,14 @@
#include "chrome/browser/extensions/extension_toolbar_model.h"
#include "chrome/browser/extensions/extension_prefs.h"
-#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/prefs/pref_service.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/pref_names.h"
-ExtensionToolbarModel::ExtensionToolbarModel(ExtensionsService* service)
+ExtensionToolbarModel::ExtensionToolbarModel(ExtensionService* service)
: service_(service),
prefs_(service->profile()->GetPrefs()),
extensions_initialized_(false) {
@@ -22,8 +22,6 @@ ExtensionToolbarModel::ExtensionToolbarModel(ExtensionsService* service)
Source<Profile>(service_->profile()));
registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
Source<Profile>(service_->profile()));
- registrar_.Add(this, NotificationType::EXTENSION_UNLOADED_DISABLED,
- Source<Profile>(service_->profile()));
registrar_.Add(this, NotificationType::EXTENSIONS_READY,
Source<Profile>(service_->profile()));
registrar_.Add(this,
@@ -96,7 +94,12 @@ void ExtensionToolbarModel::Observe(NotificationType type,
if (!service_->is_ready())
return;
- const Extension* extension = Details<const Extension>(details).ptr();
+ const Extension* extension = NULL;
+ if (type == NotificationType::EXTENSION_UNLOADED) {
+ extension = Details<UnloadedExtensionInfo>(details)->extension;
+ } else {
+ extension = Details<const Extension>(details).ptr();
+ }
if (type == NotificationType::EXTENSION_LOADED) {
// We don't want to add the same extension twice. It may have already been
// added by EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED below, if the user
@@ -105,9 +108,9 @@ void ExtensionToolbarModel::Observe(NotificationType type,
if (toolitems_[i].get() == extension)
return; // Already exists.
}
- AddExtension(extension);
- } else if (type == NotificationType::EXTENSION_UNLOADED ||
- type == NotificationType::EXTENSION_UNLOADED_DISABLED) {
+ if (service_->GetBrowserActionVisibility(extension))
+ AddExtension(extension);
+ } else if (type == NotificationType::EXTENSION_UNLOADED) {
RemoveExtension(extension);
} else if (type ==
NotificationType::EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED) {
@@ -160,7 +163,7 @@ void ExtensionToolbarModel::RemoveExtension(const Extension* extension) {
}
// Combine the currently enabled extensions that have browser actions (which
-// we get from the ExtensionsService) with the ordering we get from the
+// we get from the ExtensionService) with the ordering we get from the
// pref service. For robustness we use a somewhat inefficient process:
// 1. Create a vector of extensions sorted by their pref values. This vector may
// have holes.
diff --git a/chrome/browser/extensions/extension_toolbar_model.h b/chrome/browser/extensions/extension_toolbar_model.h
index 37c3a08..f782c05 100644
--- a/chrome/browser/extensions/extension_toolbar_model.h
+++ b/chrome/browser/extensions/extension_toolbar_model.h
@@ -11,13 +11,13 @@
#include "chrome/common/notification_observer.h"
#include "chrome/common/notification_registrar.h"
-class ExtensionsService;
+class ExtensionService;
class PrefService;
// Model for the browser actions toolbar.
class ExtensionToolbarModel : public NotificationObserver {
public:
- explicit ExtensionToolbarModel(ExtensionsService* service);
+ explicit ExtensionToolbarModel(ExtensionService* service);
~ExtensionToolbarModel();
// Notifies the toolbar model that the Profile that suplied its
@@ -96,8 +96,8 @@ class ExtensionToolbarModel : public NotificationObserver {
void AddExtension(const Extension* extension);
void RemoveExtension(const Extension* extension);
- // Our ExtensionsService, guaranteed to outlive us.
- ExtensionsService* service_;
+ // Our ExtensionService, guaranteed to outlive us.
+ ExtensionService* service_;
PrefService* prefs_;
diff --git a/chrome/browser/extensions/extension_toolbar_model_browsertest.cc b/chrome/browser/extensions/extension_toolbar_model_browsertest.cc
index 755ac01..951f424 100644
--- a/chrome/browser/extensions/extension_toolbar_model_browsertest.cc
+++ b/chrome/browser/extensions/extension_toolbar_model_browsertest.cc
@@ -3,16 +3,16 @@
// found in the LICENSE file.
#include "chrome/browser/extensions/extension_browsertest.h"
-#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_toolbar_model.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/in_process_browser_test.h"
// An InProcessBrowserTest for testing the ExtensionToolbarModel.
// TODO(erikkay) It's unfortunate that this needs to be an in-proc browser test.
-// It would be nice to refactor things so that ExtensionsService could run
+// It would be nice to refactor things so that ExtensionService could run
// without so much of the browser in place.
class ExtensionToolbarModelTest : public ExtensionBrowserTest,
public ExtensionToolbarModel::Observer {
@@ -27,7 +27,7 @@ class ExtensionToolbarModelTest : public ExtensionBrowserTest,
virtual Browser* CreateBrowser(Profile* profile) {
Browser* b = InProcessBrowserTest::CreateBrowser(profile);
- ExtensionsService* service = b->profile()->GetExtensionsService();
+ ExtensionService* service = b->profile()->GetExtensionService();
model_ = service->toolbar_model();
model_->AddObserver(this);
return b;
diff --git a/chrome/browser/extensions/extension_tts_api.cc b/chrome/browser/extensions/extension_tts_api.cc
index 1654b07..c618db3 100644
--- a/chrome/browser/extensions/extension_tts_api.cc
+++ b/chrome/browser/extensions/extension_tts_api.cc
@@ -2,22 +2,116 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/browser/extensions/extension_tts_api.h"
-
#include <string>
+#include <vector>
#include "base/float_util.h"
+#include "base/json/json_writer.h"
#include "base/message_loop.h"
#include "base/values.h"
+#include "chrome/browser/extensions/extension_event_router.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/extensions/extension_tts_api.h"
+#include "chrome/browser/profiles/profile.h"
namespace util = extension_tts_api_util;
namespace {
-const char kCrosLibraryNotLoadedError[] =
- "Cros shared library not loaded.";
+const char kSpeechInterruptedError[] = "Utterance interrupted.";
+const char kSpeechRemovedFromQueueError[] = "Utterance removed from queue.";
const int kSpeechCheckDelayIntervalMs = 100;
};
+namespace events {
+const char kOnSpeak[] = "experimental.tts.onSpeak";
+const char kOnStop[] = "experimental.tts.onStop";
+}; // namespace events
+
+//
+// ExtensionTtsPlatformImpl
+//
+
+std::string ExtensionTtsPlatformImpl::error() {
+ return error_;
+}
+
+void ExtensionTtsPlatformImpl::clear_error() {
+ error_ = std::string();
+}
+
+void ExtensionTtsPlatformImpl::set_error(const std::string& error) {
+ error_ = error;
+}
+
+//
+// Utterance
+//
+
+// static
+int Utterance::next_utterance_id_ = 0;
+
+Utterance::Utterance(Profile* profile,
+ const std::string& text,
+ DictionaryValue* options,
+ Task* completion_task)
+ : profile_(profile),
+ id_(next_utterance_id_++),
+ text_(text),
+ rate_(-1.0),
+ pitch_(-1.0),
+ volume_(-1.0),
+ can_enqueue_(false),
+ completion_task_(completion_task) {
+ if (!options) {
+ // Use all default options.
+ options_.reset(new DictionaryValue());
+ return;
+ }
+
+ options_.reset(options->DeepCopy());
+
+ if (options->HasKey(util::kVoiceNameKey))
+ options->GetString(util::kVoiceNameKey, &voice_name_);
+
+ if (options->HasKey(util::kLocaleKey))
+ options->GetString(util::kLocaleKey, &locale_);
+
+ if (options->HasKey(util::kGenderKey))
+ options->GetString(util::kGenderKey, &gender_);
+
+ if (util::ReadNumberByKey(options, util::kRateKey, &rate_)) {
+ if (!base::IsFinite(rate_) || rate_ < 0.0 || rate_ > 1.0)
+ rate_ = -1.0;
+ }
+
+ if (util::ReadNumberByKey(options, util::kPitchKey, &pitch_)) {
+ if (!base::IsFinite(pitch_) || pitch_ < 0.0 || pitch_ > 1.0)
+ pitch_ = -1.0;
+ }
+
+ if (util::ReadNumberByKey(options, util::kVolumeKey, &volume_)) {
+ if (!base::IsFinite(volume_) || volume_ < 0.0 || volume_ > 1.0)
+ volume_ = -1.0;
+ }
+
+ if (options->HasKey(util::kEnqueueKey))
+ options->GetBoolean(util::kEnqueueKey, &can_enqueue_);
+}
+
+Utterance::~Utterance() {
+ DCHECK_EQ(completion_task_, static_cast<Task *>(NULL));
+}
+
+void Utterance::FinishAndDestroy() {
+ completion_task_->Run();
+ completion_task_ = NULL;
+ delete this;
+}
+
+//
+// ExtensionTtsController
+//
+
// static
ExtensionTtsController* ExtensionTtsController::GetInstance() {
return Singleton<ExtensionTtsController>::get();
@@ -29,9 +123,13 @@ ExtensionTtsController::ExtensionTtsController()
platform_impl_(NULL) {
}
-void ExtensionTtsController::SpeakOrEnqueue(
- Utterance* utterance, bool can_enqueue) {
- if (IsSpeaking() && can_enqueue) {
+ExtensionTtsController::~ExtensionTtsController() {
+ FinishCurrentUtterance();
+ ClearUtteranceQueue();
+}
+
+void ExtensionTtsController::SpeakOrEnqueue(Utterance* utterance) {
+ if (IsSpeaking() && utterance->can_enqueue()) {
utterance_queue_.push(utterance);
} else {
Stop();
@@ -39,59 +137,167 @@ void ExtensionTtsController::SpeakOrEnqueue(
}
}
+std::string ExtensionTtsController::GetMatchingExtensionId(
+ Utterance* utterance) {
+ ExtensionService* service = utterance->profile()->GetExtensionService();
+ DCHECK(service);
+ ExtensionEventRouter* event_router =
+ utterance->profile()->GetExtensionEventRouter();
+ DCHECK(event_router);
+
+ const ExtensionList* extensions = service->extensions();
+ ExtensionList::const_iterator iter;
+ for (iter = extensions->begin(); iter != extensions->end(); ++iter) {
+ const Extension* extension = *iter;
+
+ if (!event_router->ExtensionHasEventListener(
+ extension->id(), events::kOnSpeak) ||
+ !event_router->ExtensionHasEventListener(
+ extension->id(), events::kOnStop)) {
+ continue;
+ }
+
+ const std::vector<Extension::TtsVoice>& tts_voices =
+ extension->tts_voices();
+ for (size_t i = 0; i < tts_voices.size(); ++i) {
+ const Extension::TtsVoice& voice = tts_voices[i];
+ if (!voice.voice_name.empty() &&
+ !utterance->voice_name().empty() &&
+ voice.voice_name != utterance->voice_name()) {
+ continue;
+ }
+ if (!voice.locale.empty() &&
+ !utterance->locale().empty() &&
+ voice.locale != utterance->locale()) {
+ continue;
+ }
+ if (!voice.gender.empty() &&
+ !utterance->gender().empty() &&
+ voice.gender != utterance->gender()) {
+ continue;
+ }
+
+ return extension->id();
+ }
+ }
+
+ return std::string();
+}
+
void ExtensionTtsController::SpeakNow(Utterance* utterance) {
+ std::string extension_id = GetMatchingExtensionId(utterance);
+ if (!extension_id.empty()) {
+ current_utterance_ = utterance;
+ utterance->set_extension_id(extension_id);
+
+ ListValue args;
+ args.Set(0, Value::CreateStringValue(utterance->text()));
+
+ // Pass through all options to the speech engine, except for
+ // "enqueue", which the speech engine doesn't need to handle.
+ DictionaryValue* options = static_cast<DictionaryValue*>(
+ utterance->options()->DeepCopy());
+ if (options->HasKey(util::kEnqueueKey))
+ options->Remove(util::kEnqueueKey, NULL);
+
+ args.Set(1, options);
+ args.Set(2, Value::CreateIntegerValue(utterance->id()));
+ std::string json_args;
+ base::JSONWriter::Write(&args, false, &json_args);
+
+ utterance->profile()->GetExtensionEventRouter()->DispatchEventToExtension(
+ extension_id,
+ events::kOnSpeak,
+ json_args,
+ utterance->profile(),
+ GURL());
+
+ return;
+ }
+
GetPlatformImpl()->clear_error();
bool success = GetPlatformImpl()->Speak(
- utterance->text,
- utterance->language,
- utterance->gender,
- utterance->rate,
- utterance->pitch,
- utterance->volume);
+ utterance->text(),
+ utterance->locale(),
+ utterance->gender(),
+ utterance->rate(),
+ utterance->pitch(),
+ utterance->volume());
if (!success) {
- utterance->error = GetPlatformImpl()->error();
- utterance->failure_task->Run();
- delete utterance->success_task;
- delete utterance;
+ utterance->set_error(GetPlatformImpl()->error());
+ utterance->FinishAndDestroy();
return;
}
current_utterance_ = utterance;
- // Post a task to check if this utterance has completed after a delay.
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE, method_factory_.NewRunnableMethod(
- &ExtensionTtsController::CheckSpeechStatus),
- kSpeechCheckDelayIntervalMs);
+ // Check to see if it's still speaking; finish the utterance if not and
+ // start polling if so. Checking immediately helps to avoid flaky unit
+ // tests by forcing them to set expectations for IsSpeaking.
+ CheckSpeechStatus();
}
void ExtensionTtsController::Stop() {
- GetPlatformImpl()->clear_error();
- GetPlatformImpl()->StopSpeaking();
+ if (current_utterance_ && !current_utterance_->extension_id().empty()) {
+ current_utterance_->profile()->GetExtensionEventRouter()->
+ DispatchEventToExtension(
+ current_utterance_->extension_id(),
+ events::kOnStop,
+ "[]",
+ current_utterance_->profile(),
+ GURL());
+ } else {
+ GetPlatformImpl()->clear_error();
+ GetPlatformImpl()->StopSpeaking();
+ }
+ if (current_utterance_)
+ current_utterance_->set_error(kSpeechInterruptedError);
FinishCurrentUtterance();
ClearUtteranceQueue();
}
+void ExtensionTtsController::OnSpeechFinished(
+ int request_id, std::string error_message) {
+ // We may sometimes receive completion callbacks "late", after we've
+ // already finished the utterance (for example because another utterance
+ // interrupted or we got a call to Stop). It's also possible that a buggy
+ // extension has called this more than once. In either case it's safe to
+ // just ignore this call.
+ if (!current_utterance_ || request_id != current_utterance_->id())
+ return;
+
+ current_utterance_->set_error(error_message);
+ FinishCurrentUtterance();
+ SpeakNextUtterance();
+}
+
bool ExtensionTtsController::IsSpeaking() const {
return current_utterance_ != NULL;
}
void ExtensionTtsController::FinishCurrentUtterance() {
if (current_utterance_) {
- current_utterance_->success_task->Run();
- delete current_utterance_->failure_task;
- delete current_utterance_;
+ current_utterance_->FinishAndDestroy();
current_utterance_ = NULL;
}
}
+void ExtensionTtsController::SpeakNextUtterance() {
+ // Start speaking the next utterance in the queue. Keep trying in case
+ // one fails but there are still more in the queue to try.
+ while (!utterance_queue_.empty() && !current_utterance_) {
+ Utterance* utterance = utterance_queue_.front();
+ utterance_queue_.pop();
+ SpeakNow(utterance);
+ }
+}
+
void ExtensionTtsController::ClearUtteranceQueue() {
while (!utterance_queue_.empty()) {
Utterance* utterance = utterance_queue_.front();
utterance_queue_.pop();
- utterance->success_task->Run();
- delete utterance->failure_task;
- delete utterance;
+ utterance->set_error(kSpeechRemovedFromQueueError);
+ utterance->FinishAndDestroy();
}
}
@@ -99,21 +305,19 @@ void ExtensionTtsController::CheckSpeechStatus() {
if (!current_utterance_)
return;
+ if (!current_utterance_->extension_id().empty())
+ return;
+
if (GetPlatformImpl()->IsSpeaking() == false) {
FinishCurrentUtterance();
-
- // Start speaking the next utterance in the queue. Keep trying in case
- // one fails but there are still more in the queue to try.
- while (!utterance_queue_.empty() && !current_utterance_) {
- Utterance* utterance = utterance_queue_.front();
- utterance_queue_.pop();
- SpeakNow(utterance);
- }
+ SpeakNextUtterance();
}
// If we're still speaking something (either the prevoius utterance or
// a new utterance), keep calling this method after another delay.
- if (current_utterance_) {
+ // TODO(dmazzoni): get rid of this as soon as all platform implementations
+ // provide completion callbacks rather than only supporting polling.
+ if (current_utterance_ && current_utterance_->extension_id().empty()) {
MessageLoop::current()->PostDelayedTask(
FROM_HERE, method_factory_.NewRunnableMethod(
&ExtensionTtsController::CheckSpeechStatus),
@@ -137,67 +341,25 @@ ExtensionTtsPlatformImpl* ExtensionTtsController::GetPlatformImpl() {
//
bool ExtensionTtsSpeakFunction::RunImpl() {
- utterance_ = new ExtensionTtsController::Utterance();
- bool can_enqueue = false;
-
- DictionaryValue* speak_options = NULL;
- EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &utterance_->text));
-
- if (args_->GetDictionary(1, &speak_options)) {
- if (speak_options->HasKey(util::kLanguageNameKey)) {
- speak_options->GetString(util::kLanguageNameKey, &utterance_->language);
- }
-
- if (speak_options->HasKey(util::kGenderKey)) {
- speak_options->GetString(util::kGenderKey, &utterance_->gender);
- }
-
- if (speak_options->HasKey(util::kEnqueueKey)) {
- speak_options->GetBoolean(util::kEnqueueKey, &can_enqueue);
- }
-
- if (util::ReadNumberByKey(
- speak_options, util::kRateKey, &utterance_->rate)) {
- if (!base::IsFinite(utterance_->rate) ||
- utterance_->rate < 0.0 ||
- utterance_->rate > 1.0) {
- utterance_->rate = -1.0;
- }
- }
-
- if (util::ReadNumberByKey(
- speak_options, util::kPitchKey, &utterance_->pitch)) {
- if (!base::IsFinite(utterance_->pitch) ||
- utterance_->pitch < 0.0 ||
- utterance_->pitch > 1.0) {
- utterance_->pitch = -1.0;
- }
- }
-
- if (util::ReadNumberByKey(
- speak_options, util::kVolumeKey, &utterance_->volume)) {
- if (!base::IsFinite(utterance_->volume) ||
- utterance_->volume < 0.0 ||
- utterance_->volume > 1.0) {
- utterance_->volume = -1.0;
- }
- }
- }
+ std::string text;
+ EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &text));
+ DictionaryValue* options = NULL;
+ if (args_->GetSize() >= 2)
+ EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &options));
+ Task* completion_task = NewRunnableMethod(
+ this, &ExtensionTtsSpeakFunction::SpeechFinished);
+ utterance_ = new Utterance(profile(), text, options, completion_task);
AddRef(); // Balanced in SpeechFinished().
- utterance_->success_task = NewRunnableMethod(
- this, &ExtensionTtsSpeakFunction::SpeechFinished, true);
- utterance_->failure_task = NewRunnableMethod(
- this, &ExtensionTtsSpeakFunction::SpeechFinished, false);
- ExtensionTtsController::GetInstance()->SpeakOrEnqueue(
- utterance_, can_enqueue);
+ ExtensionTtsController::GetInstance()->SpeakOrEnqueue(utterance_);
return true;
}
-void ExtensionTtsSpeakFunction::SpeechFinished(bool success) {
- error_ = utterance_->error;
+void ExtensionTtsSpeakFunction::SpeechFinished() {
+ error_ = utterance_->error();
+ bool success = error_.empty();
SendResponse(success);
- Release(); // Balanced in Speak().
+ Release(); // Balanced in RunImpl().
}
bool ExtensionTtsStopSpeakingFunction::RunImpl() {
@@ -210,3 +372,15 @@ bool ExtensionTtsIsSpeakingFunction::RunImpl() {
ExtensionTtsController::GetInstance()->IsSpeaking()));
return true;
}
+
+bool ExtensionTtsSpeakCompletedFunction::RunImpl() {
+ int request_id;
+ std::string error_message;
+ EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &request_id));
+ if (args_->GetSize() >= 2)
+ EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &error_message));
+ ExtensionTtsController::GetInstance()->OnSpeechFinished(
+ request_id, error_message);
+
+ return true;
+}
diff --git a/chrome/browser/extensions/extension_tts_api.h b/chrome/browser/extensions/extension_tts_api.h
index 0eedcc2..9f7da37 100644
--- a/chrome/browser/extensions/extension_tts_api.h
+++ b/chrome/browser/extensions/extension_tts_api.h
@@ -6,6 +6,7 @@
#define CHROME_BROWSER_EXTENSIONS_EXTENSION_TTS_API_H_
#include <queue>
+#include <string>
#include "base/singleton.h"
#include "base/task.h"
@@ -19,7 +20,7 @@ class ExtensionTtsPlatformImpl {
// Speak the given utterance with the given parameters if possible,
// and return true on success. Utterance will always be nonempty.
- // If the user does not specify the other values, language and gender
+ // If the user does not specify the other values, then locale and gender
// will be empty strings, and rate, pitch, and volume will be -1.0.
//
// The ExtensionTtsController will only try to speak one utterance at
@@ -28,7 +29,7 @@ class ExtensionTtsPlatformImpl {
// returns false before calling Speak again.
virtual bool Speak(
const std::string& utterance,
- const std::string& language,
+ const std::string& locale,
const std::string& gender,
double rate,
double pitch,
@@ -40,9 +41,9 @@ class ExtensionTtsPlatformImpl {
// Return true if the synthesis engine is currently speaking.
virtual bool IsSpeaking() = 0;
- virtual std::string error() { return error_; }
- virtual void clear_error() { error_ = std::string(); }
- virtual void set_error(const std::string& error) { error_ = error; }
+ virtual std::string error();
+ virtual void clear_error();
+ virtual void set_error(const std::string& error);
protected:
ExtensionTtsPlatformImpl() {}
@@ -53,51 +54,108 @@ class ExtensionTtsPlatformImpl {
DISALLOW_COPY_AND_ASSIGN(ExtensionTtsPlatformImpl);
};
+// One speech utterance.
+class Utterance {
+ public:
+ // Construct an utterance given a profile, the text to speak,
+ // the options passed to tts.speak, and a completion task to call
+ // when the utterance is done speaking.
+ Utterance(Profile* profile,
+ const std::string& text,
+ DictionaryValue* options,
+ Task* completion_task);
+ ~Utterance();
+
+ // Calls the completion task and then destroys itself.
+ void FinishAndDestroy();
+
+ void set_error(const std::string& error) { error_ = error; }
+ void set_extension_id(const std::string& extension_id) {
+ extension_id_ = extension_id;
+ }
+
+ // Accessors
+ Profile* profile() { return profile_; }
+ const std::string& extension_id() { return extension_id_; }
+ int id() { return id_; }
+ const std::string& text() { return text_; }
+ const Value* options() { return options_.get(); }
+ const std::string& voice_name() { return voice_name_; }
+ const std::string& locale() { return locale_; }
+ const std::string& gender() { return gender_; }
+ double rate() { return rate_; }
+ double pitch() { return pitch_; }
+ double volume() { return volume_; }
+ bool can_enqueue() { return can_enqueue_; }
+ const std::string& error() { return error_; }
+
+ private:
+ // The profile that initiated this utterance.
+ Profile* profile_;
+
+ // The extension ID of the extension providing TTS for this utterance, or
+ // empty if native TTS is being used.
+ std::string extension_id_;
+
+ // The unique ID of this utterance, used to associate callback functions
+ // with utterances.
+ int id_;
+
+ // The id of the next utterance, so we can associate requests with
+ // responses.
+ static int next_utterance_id_;
+
+ // The text to speak.
+ std::string text_;
+
+ // The full options arg passed to tts.speak, which may include fields
+ // other than the ones we explicitly parse, below.
+ scoped_ptr<Value> options_;
+
+ // The parsed options.
+ std::string voice_name_;
+ std::string locale_;
+ std::string gender_;
+ double rate_;
+ double pitch_;
+ double volume_;
+ bool can_enqueue_;
+
+ // The error string to pass to the completion task. Will be empty if
+ // no error occurred.
+ std::string error_;
+
+ // The method to call when this utterance has completed speaking.
+ Task* completion_task_;
+};
+
// Singleton class that manages text-to-speech.
class ExtensionTtsController {
public:
// Get the single instance of this class.
static ExtensionTtsController* GetInstance();
- struct Utterance {
- Utterance()
- : rate(-1.0),
- pitch(-1.0),
- volume(-1.0),
- success_task(NULL),
- failure_task(NULL) {
- }
-
- std::string text;
- std::string language;
- std::string gender;
- double rate;
- double pitch;
- double volume;
-
- Task* success_task;
- Task* failure_task;
-
- std::string error;
- };
-
// Returns true if we're currently speaking an utterance.
bool IsSpeaking() const;
- // Speak the given utterance. If |can_enqueue| is true and another
- // utterance is in progress, adds it to the end of the queue. Otherwise,
- // interrupts any current utterance and speaks this one immediately.
- void SpeakOrEnqueue(Utterance* utterance, bool can_enqueue);
+ // Speak the given utterance. If the utterance's can_enqueue flag is true
+ // and another utterance is in progress, adds it to the end of the queue.
+ // Otherwise, interrupts any current utterance and speaks this one
+ // immediately.
+ void SpeakOrEnqueue(Utterance* utterance);
// Stop all utterances and flush the queue.
void Stop();
+ // Called when an extension finishes speaking an utterance.
+ void OnSpeechFinished(int request_id, std::string error_message);
+
// For unit testing.
void SetPlatformImpl(ExtensionTtsPlatformImpl* platform_impl);
private:
ExtensionTtsController();
- virtual ~ExtensionTtsController() {}
+ virtual ~ExtensionTtsController();
// Get the platform TTS implementation (or injected mock).
ExtensionTtsPlatformImpl* GetPlatformImpl();
@@ -117,6 +175,14 @@ class ExtensionTtsController {
// Finalize and delete the current utterance.
void FinishCurrentUtterance();
+ // Start speaking the next utterance in the queue.
+ void SpeakNextUtterance();
+
+ // Return the id string of the first extension with tts_voices in its
+ // manifest that matches the speech parameters of this utterance,
+ // or the empty string if none is found.
+ std::string GetMatchingExtensionId(Utterance* utterance);
+
ScopedRunnableMethodFactory<ExtensionTtsController> method_factory_;
friend struct DefaultSingletonTraits<ExtensionTtsController>;
@@ -141,8 +207,8 @@ class ExtensionTtsSpeakFunction : public AsyncExtensionFunction {
private:
~ExtensionTtsSpeakFunction() {}
virtual bool RunImpl();
- void SpeechFinished(bool success);
- ExtensionTtsController::Utterance* utterance_;
+ void SpeechFinished();
+ Utterance* utterance_;
DECLARE_EXTENSION_FUNCTION_NAME("experimental.tts.speak")
};
@@ -160,4 +226,11 @@ class ExtensionTtsIsSpeakingFunction : public SyncExtensionFunction {
DECLARE_EXTENSION_FUNCTION_NAME("experimental.tts.isSpeaking")
};
+class ExtensionTtsSpeakCompletedFunction : public SyncExtensionFunction {
+ private:
+ ~ExtensionTtsSpeakCompletedFunction() {}
+ virtual bool RunImpl();
+ DECLARE_EXTENSION_FUNCTION_NAME("experimental.tts.speakCompleted")
+};
+
#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_TTS_API_H_
diff --git a/chrome/browser/extensions/extension_tts_api_chromeos.cc b/chrome/browser/extensions/extension_tts_api_chromeos.cc
index a183612..4e6ce65 100644
--- a/chrome/browser/extensions/extension_tts_api_chromeos.cc
+++ b/chrome/browser/extensions/extension_tts_api_chromeos.cc
@@ -21,7 +21,7 @@ class ExtensionTtsPlatformImplChromeOs : public ExtensionTtsPlatformImpl {
public:
virtual bool Speak(
const std::string& utterance,
- const std::string& language,
+ const std::string& locale,
const std::string& gender,
double rate,
double pitch,
@@ -38,6 +38,10 @@ class ExtensionTtsPlatformImplChromeOs : public ExtensionTtsPlatformImpl {
ExtensionTtsPlatformImplChromeOs() {}
virtual ~ExtensionTtsPlatformImplChromeOs() {}
+ void AppendSpeakOption(std::string key,
+ std::string value,
+ std::string* options);
+
friend struct DefaultSingletonTraits<ExtensionTtsPlatformImplChromeOs>;
DISALLOW_COPY_AND_ASSIGN(ExtensionTtsPlatformImplChromeOs);
@@ -50,7 +54,7 @@ ExtensionTtsPlatformImpl* ExtensionTtsPlatformImpl::GetInstance() {
bool ExtensionTtsPlatformImplChromeOs::Speak(
const std::string& utterance,
- const std::string& language,
+ const std::string& locale,
const std::string& gender,
double rate,
double pitch,
@@ -63,31 +67,41 @@ bool ExtensionTtsPlatformImplChromeOs::Speak(
std::string options;
- if (!language.empty()) {
- util::AppendSpeakOption(
- std::string(util::kNameKey), language, &options);
+ if (!locale.empty()) {
+ AppendSpeakOption(
+ chromeos::SpeechSynthesisLibrary::kSpeechPropertyLocale,
+ locale,
+ &options);
}
if (!gender.empty()) {
- util::AppendSpeakOption(
- std::string(util::kGenderKey), gender, &options);
+ AppendSpeakOption(
+ chromeos::SpeechSynthesisLibrary::kSpeechPropertyGender,
+ gender,
+ &options);
}
if (rate >= 0.0) {
- util::AppendSpeakOption(
- std::string(util::kRateKey), DoubleToString(rate * 5), &options);
+ AppendSpeakOption(
+ chromeos::SpeechSynthesisLibrary::kSpeechPropertyRate,
+ DoubleToString(rate * 5),
+ &options);
}
if (pitch >= 0.0) {
// The TTS service allows a range of 0 to 2 for speech pitch.
- util::AppendSpeakOption(
- std::string(util::kPitchKey), DoubleToString(pitch * 2), &options);
+ AppendSpeakOption(
+ chromeos::SpeechSynthesisLibrary::kSpeechPropertyPitch,
+ DoubleToString(pitch * 2),
+ &options);
}
if (volume >= 0.0) {
// The TTS service allows a range of 0 to 5 for speech volume.
- util::AppendSpeakOption(
- std::string(util::kVolumeKey), DoubleToString(volume * 5), &options);
+ AppendSpeakOption(
+ chromeos::SpeechSynthesisLibrary::kSpeechPropertyVolume,
+ DoubleToString(volume * 5),
+ &options);
}
if (!options.empty()) {
@@ -118,6 +132,17 @@ bool ExtensionTtsPlatformImplChromeOs::IsSpeaking() {
return false;
}
+void ExtensionTtsPlatformImplChromeOs::AppendSpeakOption(
+ std::string key,
+ std::string value,
+ std::string* options) {
+ *options +=
+ key +
+ chromeos::SpeechSynthesisLibrary::kSpeechPropertyEquals +
+ value +
+ chromeos::SpeechSynthesisLibrary::kSpeechPropertyDelimiter;
+}
+
// static
ExtensionTtsPlatformImplChromeOs*
ExtensionTtsPlatformImplChromeOs::GetInstance() {
diff --git a/chrome/browser/extensions/extension_tts_api_util.cc b/chrome/browser/extensions/extension_tts_api_util.cc
index ac5d53b..b3ef18c 100644
--- a/chrome/browser/extensions/extension_tts_api_util.cc
+++ b/chrome/browser/extensions/extension_tts_api_util.cc
@@ -6,6 +6,14 @@
namespace extension_tts_api_util {
+const char kVoiceNameKey[] = "voiceName";
+const char kLocaleKey[] = "locale";
+const char kGenderKey[] = "gender";
+const char kRateKey[] = "rate";
+const char kPitchKey[] = "pitch";
+const char kVolumeKey[] = "volume";
+const char kEnqueueKey[] = "enqueue";
+
// Static.
bool ReadNumberByKey(DictionaryValue* dict,
const char* key,
@@ -28,11 +36,4 @@ bool ReadNumberByKey(DictionaryValue* dict,
return true;
}
-// Static.
-void AppendSpeakOption(std::string key,
- std::string value,
- std::string* options) {
- *options += key + kEqualStr + value + kDelimiter;
-}
-
} // namespace extension_tts_api_util.
diff --git a/chrome/browser/extensions/extension_tts_api_util.h b/chrome/browser/extensions/extension_tts_api_util.h
index cf0d702..9d13e75 100644
--- a/chrome/browser/extensions/extension_tts_api_util.h
+++ b/chrome/browser/extensions/extension_tts_api_util.h
@@ -11,23 +11,17 @@
namespace extension_tts_api_util {
-const char kNameKey[] = "name";
-const char kLanguageNameKey[] = "languageName";
-const char kGenderKey[] = "gender";
-const char kRateKey[] = "rate";
-const char kPitchKey[] = "pitch";
-const char kVolumeKey[] = "volume";
-const char kEnqueueKey[] = "enqueue";
-const char kEqualStr[] = "=";
-const char kDelimiter[] = ";";
+extern const char kVoiceNameKey[];
+extern const char kLocaleKey[];
+extern const char kGenderKey[];
+extern const char kRateKey[];
+extern const char kPitchKey[];
+extern const char kVolumeKey[];
+extern const char kEnqueueKey[];
bool ReadNumberByKey(DictionaryValue* dict,
const char* key,
double* ret_value);
-void AppendSpeakOption(std::string key,
- std::string value,
- std::string* options);
-
} // namespace extension_tts_api_util.
#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_TTS_API_UTIL_H_
diff --git a/chrome/browser/extensions/extension_tts_apitest.cc b/chrome/browser/extensions/extension_tts_apitest.cc
index 6f37404..f7ed0d8 100644
--- a/chrome/browser/extensions/extension_tts_apitest.cc
+++ b/chrome/browser/extensions/extension_tts_apitest.cc
@@ -16,6 +16,7 @@
#include "chrome/browser/chromeos/cros/cros_mock.h"
#endif
+using ::testing::AnyNumber;
using ::testing::CreateFunctor;
using ::testing::DoAll;
using ::testing::InSequence;
@@ -28,7 +29,7 @@ class MockExtensionTtsPlatformImpl : public ExtensionTtsPlatformImpl {
public:
MOCK_METHOD6(Speak,
bool(const std::string& utterance,
- const std::string& language,
+ const std::string& locale,
const std::string& gender,
double rate,
double pitch,
@@ -83,11 +84,20 @@ IN_PROC_BROWSER_TEST_F(TtsApiTest, PlatformSpeakKeepsSpeakingTwice) {
}
IN_PROC_BROWSER_TEST_F(TtsApiTest, PlatformSpeakInterrupt) {
+ // One utterances starts speaking, and then a second interrupts.
InSequence s;
EXPECT_CALL(mock_platform_impl_, StopSpeaking())
.WillOnce(Return(true));
EXPECT_CALL(mock_platform_impl_, Speak("text 1", _, _, _, _, _))
.WillOnce(Return(true));
+
+ // Ensure that the first utterance keeps going until it's interrupted.
+ EXPECT_CALL(mock_platform_impl_, IsSpeaking())
+ .Times(AnyNumber())
+ .WillRepeatedly(Return(true));
+
+ // Expect the second utterance and allow it to continue for two calls to
+ // IsSpeaking and then finish successfully.
EXPECT_CALL(mock_platform_impl_, StopSpeaking())
.WillOnce(Return(true));
EXPECT_CALL(mock_platform_impl_, Speak("text 2", _, _, _, _, _))
@@ -107,6 +117,14 @@ IN_PROC_BROWSER_TEST_F(TtsApiTest, PlatformSpeakQueueInterrupt) {
.WillOnce(Return(true));
EXPECT_CALL(mock_platform_impl_, Speak("text 1", _, _, _, _, _))
.WillOnce(Return(true));
+
+ // Ensure that the first utterance keeps going until it's interrupted.
+ EXPECT_CALL(mock_platform_impl_, IsSpeaking())
+ .Times(AnyNumber())
+ .WillRepeatedly(Return(true));
+
+ // Expect the third utterance and allow it to continue for two calls to
+ // IsSpeaking and then finish successfully.
EXPECT_CALL(mock_platform_impl_, StopSpeaking())
.WillOnce(Return(true));
EXPECT_CALL(mock_platform_impl_, Speak("text 3", _, _, _, _, _))
@@ -145,12 +163,16 @@ IN_PROC_BROWSER_TEST_F(TtsApiTest, PlatformSpeakError) {
.WillOnce(Return(true));
EXPECT_CALL(mock_platform_impl_, IsSpeaking())
.WillOnce(Return(false));
+ EXPECT_CALL(mock_platform_impl_, StopSpeaking())
+ .WillOnce(Return(true));
EXPECT_CALL(mock_platform_impl_, Speak(_, _, _, _, _, _))
.WillOnce(DoAll(
InvokeWithoutArgs(
CreateFunctor(&mock_platform_impl_,
&MockExtensionTtsPlatformImpl::SetErrorToEpicFail)),
Return(false)));
+ EXPECT_CALL(mock_platform_impl_, StopSpeaking())
+ .WillOnce(Return(true));
EXPECT_CALL(mock_platform_impl_, Speak(_, _, _, _, _, _))
.WillOnce(Return(true));
EXPECT_CALL(mock_platform_impl_, IsSpeaking())
@@ -158,6 +180,25 @@ IN_PROC_BROWSER_TEST_F(TtsApiTest, PlatformSpeakError) {
ASSERT_TRUE(RunExtensionTest("tts/speak_error")) << message_;
}
+IN_PROC_BROWSER_TEST_F(TtsApiTest, Provide) {
+ EXPECT_CALL(mock_platform_impl_, StopSpeaking())
+ .WillRepeatedly(Return(true));
+ EXPECT_CALL(mock_platform_impl_, IsSpeaking())
+ .WillRepeatedly(Return(false));
+
+ {
+ InSequence s;
+ EXPECT_CALL(mock_platform_impl_, Speak("native speech", _, _, _, _, _))
+ .WillOnce(Return(true));
+ EXPECT_CALL(mock_platform_impl_, Speak("native speech 2", _, _, _, _, _))
+ .WillOnce(Return(true));
+ EXPECT_CALL(mock_platform_impl_, Speak("native speech 3", _, _, _, _, _))
+ .WillOnce(Return(true));
+ }
+
+ ASSERT_TRUE(RunExtensionTest("tts/provide")) << message_;
+}
+
#if defined(OS_CHROMEOS)
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, TtsChromeOs) {
CommandLine::ForCurrentProcess()->AppendSwitch(
diff --git a/chrome/browser/extensions/extension_uitest.cc b/chrome/browser/extensions/extension_uitest.cc
index bc25d75..845696e 100644
--- a/chrome/browser/extensions/extension_uitest.cc
+++ b/chrome/browser/extensions/extension_uitest.cc
@@ -126,15 +126,15 @@ TEST_F(ExtensionTestSimpleApiCall, FLAKY_RunTest) {
namespace keys = extension_automation_constants;
ASSERT_THAT(mock_, testing::NotNull());
- EXPECT_CALL(*mock_, OnDidNavigate(_, _)).Times(1);
- EXPECT_CALL(*mock_, OnNavigationStateChanged(_, _, _))
+ EXPECT_CALL(*mock_, OnDidNavigate(_)).Times(1);
+ EXPECT_CALL(*mock_, OnNavigationStateChanged(_, _))
.Times(testing::AnyNumber());
std::string message_received;
EXPECT_CALL(*mock_, OnForwardMessageToExternalHost(
- _, _, keys::kAutomationOrigin, keys::kAutomationRequestTarget))
+ _, keys::kAutomationOrigin, keys::kAutomationRequestTarget))
.WillOnce(DoAll(
- SaveArg<1>(&message_received),
+ SaveArg<0>(&message_received),
InvokeWithoutArgs(
CreateFunctor(&loop_, &TimedMessageLoopRunner::Quit))));
@@ -277,15 +277,15 @@ TEST_F(ExtensionTestRoundtripApiCall, FLAKY_RunTest) {
namespace keys = extension_automation_constants;
ASSERT_THAT(mock_, testing::NotNull());
- EXPECT_CALL(*mock_, OnDidNavigate(_, _)).Times(1);
- EXPECT_CALL(*mock_, OnNavigationStateChanged(_, _, _))
+ EXPECT_CALL(*mock_, OnDidNavigate(_)).Times(1);
+ EXPECT_CALL(*mock_, OnNavigationStateChanged(_, _))
.Times(testing::AnyNumber());
- EXPECT_CALL(*mock_, OnLoad(_, _)).Times(testing::AnyNumber());
+ EXPECT_CALL(*mock_, OnLoad(_)).Times(testing::AnyNumber());
EXPECT_CALL(*mock_, OnForwardMessageToExternalHost(
- _, _, keys::kAutomationOrigin, keys::kAutomationRequestTarget))
+ _, keys::kAutomationOrigin, keys::kAutomationRequestTarget))
.Times(2)
- .WillRepeatedly(WithArgs<1>(Invoke(
+ .WillRepeatedly(WithArgs<0>(Invoke(
CreateFunctor(this,
&ExtensionTestRoundtripApiCall::CheckAndSendResponse))));
@@ -465,14 +465,14 @@ TEST_F(ExtensionTestBrowserEvents, FLAKY_RunTest) {
namespace keys = extension_automation_constants;
ASSERT_THAT(mock_, testing::NotNull());
- EXPECT_CALL(*mock_, OnDidNavigate(_, _)).Times(1);
- EXPECT_CALL(*mock_, OnNavigationStateChanged(_, _, _))
+ EXPECT_CALL(*mock_, OnDidNavigate(_)).Times(1);
+ EXPECT_CALL(*mock_, OnNavigationStateChanged(_, _))
.Times(testing::AnyNumber());
- EXPECT_CALL(*mock_, OnLoad(_, _)).Times(testing::AnyNumber());
+ EXPECT_CALL(*mock_, OnLoad(_)).Times(testing::AnyNumber());
EXPECT_CALL(*mock_, OnForwardMessageToExternalHost(
- _, _, keys::kAutomationOrigin, _))
- .WillRepeatedly(WithArgs<1, 3>(Invoke(
+ _, keys::kAutomationOrigin, _))
+ .WillRepeatedly(WithArgs<0, 2>(Invoke(
CreateFunctor(this,
&ExtensionTestBrowserEvents::HandleMessageFromChrome))));
diff --git a/chrome/browser/extensions/extension_updater.cc b/chrome/browser/extensions/extension_updater.cc
index 15e26aa..63374ac 100644
--- a/chrome/browser/extensions/extension_updater.cc
+++ b/chrome/browser/extensions/extension_updater.cc
@@ -21,9 +21,9 @@
#include "base/version.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/extensions/extension_error_reporter.h"
-#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/prefs/pref_service.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/utility_process_host.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/chrome_version_info.h"
@@ -190,8 +190,7 @@ void ManifestFetchesBuilder::AddExtension(const Extension& extension) {
AddExtensionData(extension.location(),
extension.id(),
*extension.version(),
- (extension.is_theme() ? PendingExtensionInfo::THEME
- : PendingExtensionInfo::EXTENSION),
+ extension.GetType(),
extension.update_url(), update_url_data);
}
@@ -204,17 +203,20 @@ void ManifestFetchesBuilder::AddPendingExtension(
scoped_ptr<Version> version(
Version::GetVersionFromString("0.0.0.0"));
- AddExtensionData(info.install_source, id, *version,
- info.expected_crx_type, info.update_url, "");
+ AddExtensionData(
+ info.install_source, id, *version,
+ Extension::TYPE_UNKNOWN, info.update_url, "");
}
void ManifestFetchesBuilder::ReportStats() const {
- UMA_HISTOGRAM_COUNTS_100("Extensions.UpdateCheckExtensions",
- url_stats_.google_url_count +
- url_stats_.other_url_count -
- url_stats_.theme_count);
+ UMA_HISTOGRAM_COUNTS_100("Extensions.UpdateCheckExtension",
+ url_stats_.extension_count);
UMA_HISTOGRAM_COUNTS_100("Extensions.UpdateCheckTheme",
url_stats_.theme_count);
+ UMA_HISTOGRAM_COUNTS_100("Extensions.UpdateCheckApp",
+ url_stats_.app_count);
+ UMA_HISTOGRAM_COUNTS_100("Extensions.UpdateCheckPending",
+ url_stats_.pending_count);
UMA_HISTOGRAM_COUNTS_100("Extensions.UpdateCheckGoogleUrl",
url_stats_.google_url_count);
UMA_HISTOGRAM_COUNTS_100("Extensions.UpdateCheckOtherUrl",
@@ -239,7 +241,7 @@ void ManifestFetchesBuilder::AddExtensionData(
Extension::Location location,
const std::string& id,
const Version& version,
- PendingExtensionInfo::ExpectedCrxType crx_type,
+ Extension::Type extension_type,
GURL update_url,
const std::string& update_url_data) {
@@ -272,8 +274,21 @@ void ManifestFetchesBuilder::AddExtensionData(
url_stats_.other_url_count++;
}
- if (crx_type == PendingExtensionInfo::THEME) {
- url_stats_.theme_count++;
+ switch (extension_type) {
+ case Extension::TYPE_THEME:
+ ++url_stats_.theme_count;
+ break;
+ case Extension::TYPE_EXTENSION:
+ case Extension::TYPE_USER_SCRIPT:
+ ++url_stats_.extension_count;
+ break;
+ case Extension::TYPE_HOSTED_APP:
+ case Extension::TYPE_PACKAGED_APP:
+ ++url_stats_.app_count;
+ case Extension::TYPE_UNKNOWN:
+ default:
+ ++url_stats_.pending_count;
+ break;
}
DCHECK(!update_url.is_empty());
@@ -637,7 +652,7 @@ void ExtensionUpdater::OnCRXFetchComplete(const GURL& url,
ProcessBlacklist(data);
} else {
// Successfully fetched - now write crx to a file so we can have the
- // ExtensionsService install it.
+ // ExtensionService install it.
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
NewRunnableMethod(
@@ -669,7 +684,7 @@ void ExtensionUpdater::OnCRXFileWritten(const std::string& id,
// This can be called after we've been stopped.
if (!alive_)
return;
- // The ExtensionsService is now responsible for cleaning up the temp file
+ // The ExtensionService is now responsible for cleaning up the temp file
// at |path|.
service_->UpdateExtension(id, path, download_url);
}
@@ -701,7 +716,7 @@ void ExtensionUpdater::TimerFired() {
// If the user has overridden the update frequency, don't bother reporting
// this.
- if (frequency_seconds_ == ExtensionsService::kDefaultUpdateFrequencySeconds) {
+ if (frequency_seconds_ == ExtensionService::kDefaultUpdateFrequencySeconds) {
Time last = Time::FromInternalValue(prefs_->GetInt64(
kLastExtensionsUpdateCheck));
if (last.ToInternalValue() != 0) {
@@ -734,7 +749,10 @@ void ExtensionUpdater::CheckNow() {
service_->pending_extensions();
for (PendingExtensionMap::const_iterator iter = pending_extensions.begin();
iter != pending_extensions.end(); ++iter) {
- fetches_builder.AddPendingExtension(iter->first, iter->second);
+ Extension::Location location = iter->second.install_source;
+ if (location != Extension::EXTERNAL_PREF &&
+ location != Extension::EXTERNAL_REGISTRY)
+ fetches_builder.AddPendingExtension(iter->first, iter->second);
}
fetches_builder.ReportStats();
diff --git a/chrome/browser/extensions/extension_updater.h b/chrome/browser/extensions/extension_updater.h
index 041dba0..d9e6a3e 100644
--- a/chrome/browser/extensions/extension_updater.h
+++ b/chrome/browser/extensions/extension_updater.h
@@ -19,7 +19,7 @@
#include "base/task.h"
#include "base/time.h"
#include "base/timer.h"
-#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/extensions/extension_service.h"
#include "chrome/common/extensions/update_manifest.h"
#include "chrome/common/net/url_fetcher.h"
#include "googleurl/src/gurl.h"
@@ -104,15 +104,19 @@ class ManifestFetchesBuilder {
: no_url_count(0),
google_url_count(0),
other_url_count(0),
- theme_count(0) {}
+ extension_count(0),
+ theme_count(0),
+ app_count(0),
+ pending_count(0) {}
- int no_url_count, google_url_count, other_url_count, theme_count;
+ int no_url_count, google_url_count, other_url_count;
+ int extension_count, theme_count, app_count, pending_count;
};
void AddExtensionData(Extension::Location location,
const std::string& id,
const Version& version,
- PendingExtensionInfo::ExpectedCrxType crx_type,
+ Extension::Type extension_type,
GURL update_url,
const std::string& update_url_data);
ExtensionUpdateService* service_;
diff --git a/chrome/browser/extensions/extension_updater_unittest.cc b/chrome/browser/extensions/extension_updater_unittest.cc
index b85d5d8..d501de6 100644
--- a/chrome/browser/extensions/extension_updater_unittest.cc
+++ b/chrome/browser/extensions/extension_updater_unittest.cc
@@ -16,7 +16,7 @@
#include "chrome/browser/browser_thread.h"
#include "chrome/browser/extensions/extension_error_reporter.h"
#include "chrome/browser/extensions/extension_updater.h"
-#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/test_extension_prefs.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/common/extensions/extension.h"
@@ -124,22 +124,34 @@ std::string GenerateId(std::string input) {
return result;
}
+bool ShouldInstallExtensionsOnly(const Extension& extension) {
+ return extension.GetType() == Extension::TYPE_EXTENSION;
+}
+
+bool ShouldInstallThemesOnly(const Extension& extension) {
+ return extension.is_theme();
+}
+
+bool ShouldAlwaysInstall(const Extension& extension) {
+ return true;
+}
+
// Creates test pending extensions and inserts them into list. The
// name and version are all based on their index.
void CreateTestPendingExtensions(int count, const GURL& update_url,
PendingExtensionMap* pending_extensions) {
- PendingExtensionInfo::ExpectedCrxType crx_type;
for (int i = 1; i <= count; i++) {
- crx_type = ((i % 2) ? PendingExtensionInfo::EXTENSION
- : PendingExtensionInfo::THEME);
+ ShouldInstallExtensionPredicate should_install_extension =
+ (i % 2 == 0) ? &ShouldInstallThemesOnly :
+ &ShouldInstallExtensionsOnly;
const bool kIsFromSync = true;
const bool kInstallSilently = true;
const Extension::State kInitialState = Extension::ENABLED;
const bool kInitialIncognitoEnabled = false;
std::string id = GenerateId(base::StringPrintf("extension%i", i));
(*pending_extensions)[id] =
- PendingExtensionInfo(update_url, crx_type, kIsFromSync,
- kInstallSilently, kInitialState,
+ PendingExtensionInfo(update_url, should_install_extension,
+ kIsFromSync, kInstallSilently, kInitialState,
kInitialIncognitoEnabled, Extension::INTERNAL);
}
}
@@ -636,15 +648,13 @@ class ExtensionUpdaterTest : public testing::Test {
updater->FetchUpdatedExtension(id, test_url, hash, version->GetString());
if (pending) {
- const PendingExtensionInfo::ExpectedCrxType kExpectedCrxType =
- PendingExtensionInfo::EXTENSION;
const bool kIsFromSync = true;
const bool kInstallSilently = true;
const Extension::State kInitialState = Extension::ENABLED;
const bool kInitialIncognitoEnabled = false;
PendingExtensionMap pending_extensions;
pending_extensions[id] =
- PendingExtensionInfo(test_url, kExpectedCrxType, kIsFromSync,
+ PendingExtensionInfo(test_url, &ShouldAlwaysInstall, kIsFromSync,
kInstallSilently, kInitialState,
kInitialIncognitoEnabled, Extension::INTERNAL);
service.set_pending_extensions(pending_extensions);
@@ -985,14 +995,14 @@ TEST(ExtensionUpdaterTest, TestManifestFetchesBuilderAddExtension) {
// Extensions with invalid update URLs should be rejected.
builder.AddPendingExtension(
GenerateId("foo"), PendingExtensionInfo(GURL("http:google.com:foo"),
- PendingExtensionInfo::EXTENSION,
+ &ShouldInstallExtensionsOnly,
false, false, true, false,
Extension::INTERNAL));
EXPECT_TRUE(builder.GetFetches().empty());
// Extensions with empty IDs should be rejected.
builder.AddPendingExtension(
- "", PendingExtensionInfo(GURL(), PendingExtensionInfo::EXTENSION,
+ "", PendingExtensionInfo(GURL(), &ShouldInstallExtensionsOnly,
false, false, true, false,
Extension::INTERNAL));
EXPECT_TRUE(builder.GetFetches().empty());
@@ -1004,7 +1014,7 @@ TEST(ExtensionUpdaterTest, TestManifestFetchesBuilderAddExtension) {
// filled in.
builder.AddPendingExtension(
GenerateId("foo"), PendingExtensionInfo(GURL(),
- PendingExtensionInfo::EXTENSION,
+ &ShouldInstallExtensionsOnly,
false, false, true, false,
Extension::INTERNAL));
std::vector<ManifestFetchData*> fetches = builder.GetFetches();
diff --git a/chrome/browser/extensions/extension_webglbackground_apitest.cc b/chrome/browser/extensions/extension_webglbackground_apitest.cc
new file mode 100644
index 0000000..9e7701c
--- /dev/null
+++ b/chrome/browser/extensions/extension_webglbackground_apitest.cc
@@ -0,0 +1,9 @@
+// Copyright (c) 2010 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/extension_apitest.h"
+
+IN_PROC_BROWSER_TEST_F(ExtensionApiTest, WebGLBackground) {
+ ASSERT_TRUE(RunExtensionTest("webglbackground")) << message_;
+}
diff --git a/chrome/browser/extensions/extension_webnavigation_api.cc b/chrome/browser/extensions/extension_webnavigation_api.cc
index 9a3e4ab..2e3a1ca 100644
--- a/chrome/browser/extensions/extension_webnavigation_api.cc
+++ b/chrome/browser/extensions/extension_webnavigation_api.cc
@@ -12,12 +12,11 @@
#include "chrome/browser/extensions/extension_event_router.h"
#include "chrome/browser/extensions/extension_tabs_module.h"
#include "chrome/browser/extensions/extension_webnavigation_api_constants.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tab_contents/navigation_controller.h"
#include "chrome/browser/tab_contents/provisional_load_details.h"
#include "chrome/common/notification_type.h"
#include "chrome/common/notification_service.h"
-#include "chrome/common/url_constants.h"
#include "net/base/net_errors.h"
namespace keys = extension_webnavigation_api_constants;
@@ -37,34 +36,35 @@ double MilliSecondsFromTime(const base::Time& time) {
} // namespace
+
FrameNavigationState::FrameNavigationState() {
}
FrameNavigationState::~FrameNavigationState() {
}
-bool FrameNavigationState::CanSendEvents(long long frame_id) const {
+bool FrameNavigationState::CanSendEvents(int64 frame_id) const {
FrameIdToStateMap::const_iterator frame_state =
frame_state_map_.find(frame_id);
return frame_state != frame_state_map_.end() &&
!frame_state->second.error_occurred;
}
-void FrameNavigationState::TrackFrame(long long frame_id,
+void FrameNavigationState::TrackFrame(int64 frame_id,
const GURL& url,
bool is_main_frame,
+ bool is_error_page,
const TabContents* tab_contents) {
if (is_main_frame)
RemoveTabContentsState(tab_contents);
- tab_contents_map_.insert(
- TabContentsToFrameIdMap::value_type(tab_contents, frame_id));
+ tab_contents_map_.insert(std::make_pair(tab_contents, frame_id));
FrameState& frame_state = frame_state_map_[frame_id];
- frame_state.error_occurred = (url.spec() == chrome::kUnreachableWebDataURL);
+ frame_state.error_occurred = is_error_page;
frame_state.url = url;
frame_state.is_main_frame = is_main_frame;
}
-GURL FrameNavigationState::GetUrl(long long frame_id) const {
+GURL FrameNavigationState::GetUrl(int64 frame_id) const {
FrameIdToStateMap::const_iterator frame_state =
frame_state_map_.find(frame_id);
if (frame_state == frame_state_map_.end()) {
@@ -74,7 +74,7 @@ GURL FrameNavigationState::GetUrl(long long frame_id) const {
return frame_state->second.url;
}
-bool FrameNavigationState::IsMainFrame(long long frame_id) const {
+bool FrameNavigationState::IsMainFrame(int64 frame_id) const {
FrameIdToStateMap::const_iterator frame_state =
frame_state_map_.find(frame_id);
if (frame_state == frame_state_map_.end()) {
@@ -84,7 +84,7 @@ bool FrameNavigationState::IsMainFrame(long long frame_id) const {
return frame_state->second.is_main_frame;
}
-void FrameNavigationState::ErrorOccurredInFrame(long long frame_id) {
+void FrameNavigationState::ErrorOccurredInFrame(int64 frame_id) {
DCHECK(frame_state_map_.find(frame_id) != frame_state_map_.end());
frame_state_map_[frame_id].error_occurred = true;
}
@@ -93,7 +93,7 @@ void FrameNavigationState::RemoveTabContentsState(
const TabContents* tab_contents) {
typedef TabContentsToFrameIdMap::iterator FrameIdIterator;
std::pair<FrameIdIterator, FrameIdIterator> frame_ids =
- tab_contents_map_.equal_range(tab_contents);
+ tab_contents_map_.equal_range(tab_contents);
for (FrameIdIterator frame_id = frame_ids.first; frame_id != frame_ids.second;
++frame_id) {
frame_state_map_.erase(frame_id->second);
@@ -149,19 +149,18 @@ void ExtensionWebNavigationEventRouter::Observe(
case NotificationType::FRAME_DOM_CONTENT_LOADED:
FrameDomContentLoaded(
Source<NavigationController>(source).ptr(),
- *Details<long long>(details).ptr());
+ *Details<int64>(details).ptr());
break;
case NotificationType::FRAME_DID_FINISH_LOAD:
FrameDidFinishLoad(
Source<NavigationController>(source).ptr(),
- *Details<long long>(details).ptr());
+ *Details<int64>(details).ptr());
break;
case NotificationType::FAIL_PROVISIONAL_LOAD_WITH_ERROR:
FailProvisionalLoadWithError(
Source<NavigationController>(source).ptr(),
Details<ProvisionalLoadDetails>(details).ptr());
break;
-
case NotificationType::TAB_CONTENTS_DESTROYED:
navigation_state_.RemoveTabContentsState(
Source<TabContents>(source).ptr());
@@ -177,6 +176,7 @@ void ExtensionWebNavigationEventRouter::FrameProvisionalLoadStart(
navigation_state_.TrackFrame(details->frame_id(),
details->url(),
details->main_frame(),
+ details->is_error_page(),
controller->tab_contents());
if (!navigation_state_.CanSendEvents(details->frame_id()))
return;
@@ -184,8 +184,7 @@ void ExtensionWebNavigationEventRouter::FrameProvisionalLoadStart(
DictionaryValue* dict = new DictionaryValue();
dict->SetInteger(keys::kTabIdKey,
ExtensionTabUtil::GetTabId(controller->tab_contents()));
- dict->SetString(keys::kUrlKey,
- details->url().spec());
+ dict->SetString(keys::kUrlKey, details->url().spec());
dict->SetInteger(keys::kFrameIdKey, GetFrameId(details));
dict->SetInteger(keys::kRequestIdKey, 0);
dict->SetReal(keys::kTimeStampKey, MilliSecondsFromTime(base::Time::Now()));
@@ -205,8 +204,7 @@ void ExtensionWebNavigationEventRouter::FrameProvisionalLoadCommitted(
DictionaryValue* dict = new DictionaryValue();
dict->SetInteger(keys::kTabIdKey,
ExtensionTabUtil::GetTabId(controller->tab_contents()));
- dict->SetString(keys::kUrlKey,
- details->url().spec());
+ dict->SetString(keys::kUrlKey, details->url().spec());
dict->SetInteger(keys::kFrameIdKey, GetFrameId(details));
dict->SetString(keys::kTransitionTypeKey,
PageTransition::CoreTransitionString(
@@ -223,7 +221,8 @@ void ExtensionWebNavigationEventRouter::FrameProvisionalLoadCommitted(
}
void ExtensionWebNavigationEventRouter::FrameDomContentLoaded(
- NavigationController* controller, long long frame_id) {
+ NavigationController* controller,
+ int64 frame_id) {
if (!navigation_state_.CanSendEvents(frame_id))
return;
ListValue args;
@@ -231,8 +230,8 @@ void ExtensionWebNavigationEventRouter::FrameDomContentLoaded(
dict->SetInteger(keys::kTabIdKey,
ExtensionTabUtil::GetTabId(controller->tab_contents()));
dict->SetString(keys::kUrlKey, navigation_state_.GetUrl(frame_id).spec());
- dict->SetInteger(keys::kFrameIdKey, navigation_state_.IsMainFrame(frame_id) ?
- 0 : static_cast<int>(frame_id));
+ dict->SetInteger(keys::kFrameIdKey,
+ navigation_state_.IsMainFrame(frame_id) ? 0 : static_cast<int>(frame_id));
dict->SetReal(keys::kTimeStampKey, MilliSecondsFromTime(base::Time::Now()));
args.Append(dict);
@@ -242,7 +241,8 @@ void ExtensionWebNavigationEventRouter::FrameDomContentLoaded(
}
void ExtensionWebNavigationEventRouter::FrameDidFinishLoad(
- NavigationController* controller, long long frame_id) {
+ NavigationController* controller,
+ int64 frame_id) {
if (!navigation_state_.CanSendEvents(frame_id))
return;
ListValue args;
@@ -250,8 +250,8 @@ void ExtensionWebNavigationEventRouter::FrameDidFinishLoad(
dict->SetInteger(keys::kTabIdKey,
ExtensionTabUtil::GetTabId(controller->tab_contents()));
dict->SetString(keys::kUrlKey, navigation_state_.GetUrl(frame_id).spec());
- dict->SetInteger(keys::kFrameIdKey, navigation_state_.IsMainFrame(frame_id) ?
- 0 : static_cast<int>(frame_id));
+ dict->SetInteger(keys::kFrameIdKey,
+ navigation_state_.IsMainFrame(frame_id) ? 0 : static_cast<int>(frame_id));
dict->SetReal(keys::kTimeStampKey, MilliSecondsFromTime(base::Time::Now()));
args.Append(dict);
@@ -269,8 +269,7 @@ void ExtensionWebNavigationEventRouter::FailProvisionalLoadWithError(
DictionaryValue* dict = new DictionaryValue();
dict->SetInteger(keys::kTabIdKey,
ExtensionTabUtil::GetTabId(controller->tab_contents()));
- dict->SetString(keys::kUrlKey,
- details->url().spec());
+ dict->SetString(keys::kUrlKey, details->url().spec());
dict->SetInteger(keys::kFrameIdKey, GetFrameId(details));
dict->SetString(keys::kErrorKey,
std::string(net::ErrorToString(details->error_code())));
diff --git a/chrome/browser/extensions/extension_webnavigation_api.h b/chrome/browser/extensions/extension_webnavigation_api.h
index b595aca..0f5948e 100644
--- a/chrome/browser/extensions/extension_webnavigation_api.h
+++ b/chrome/browser/extensions/extension_webnavigation_api.h
@@ -22,43 +22,45 @@ class NavigationController;
class ProvisionalLoadDetails;
class TabContents;
-// Tracks which frames are in an error state, and no navigation events should
-// be sent for.
+// Tracks the navigation state of all frames currently known to the
+// webNavigation API. It is mainly used to track in which frames an error
+// occurred so no further events for this frame are being sent.
class FrameNavigationState {
public:
FrameNavigationState();
~FrameNavigationState();
// True if navigation events for the given frame can be sent.
- bool CanSendEvents(long long frame_id) const;
+ bool CanSendEvents(int64 frame_id) const;
// Starts to track a frame given by its |frame_id| showing the URL |url| in
// a |tab_contents|.
- void TrackFrame(long long frame_id,
+ void TrackFrame(int64 frame_id,
const GURL& url,
bool is_main_frame,
+ bool is_error_page,
const TabContents* tab_contents);
// Returns the URL corresponding to a tracked frame given by its |frame_id|.
- GURL GetUrl(long long frame_id) const;
+ GURL GetUrl(int64 frame_id) const;
// True if the frame given by its |frame_id| is the main frame of its tab.
- bool IsMainFrame(long long frame_id) const;
+ bool IsMainFrame(int64 frame_id) const;
// Marks a frame as in an error state.
- void ErrorOccurredInFrame(long long frame_id);
+ void ErrorOccurredInFrame(int64 frame_id);
// Removes state associated with this tab contents and all of its frames.
void RemoveTabContentsState(const TabContents* tab_contents);
private:
- typedef std::multimap<const TabContents*, long long> TabContentsToFrameIdMap;
+ typedef std::multimap<const TabContents*, int64> TabContentsToFrameIdMap;
struct FrameState {
bool error_occurred; // True if an error has occurred in this frame.
bool is_main_frame; // True if this is a main frame.
GURL url; // URL of this frame.
};
- typedef std::map<long long, FrameState> FrameIdToStateMap;
+ typedef std::map<int64, FrameState> FrameIdToStateMap;
// Tracks which frames belong to a given tab contents object.
TabContentsToFrameIdMap tab_contents_map_;
@@ -69,13 +71,16 @@ class FrameNavigationState {
DISALLOW_COPY_AND_ASSIGN(FrameNavigationState);
};
+
// Observes navigation notifications and routes them as events to the extension
// system.
class ExtensionWebNavigationEventRouter : public NotificationObserver {
public:
- // Single instance of the event router.
+ // Returns the singleton instance of the event router.
static ExtensionWebNavigationEventRouter* GetInstance();
+ // Invoked by the extensions service once the extension system is fully set
+ // up and can start dispatching events to extensions.
void Init();
private:
@@ -104,11 +109,11 @@ class ExtensionWebNavigationEventRouter : public NotificationObserver {
// Handler for the FRAME_DOM_CONTENT_LOADED event. The method takes the frame
// ID and constructs a suitable JSON formatted extension event from it.
void FrameDomContentLoaded(NavigationController* controller,
- long long frame_id);
+ int64 frame_id);
// Handler for the FRAME_DID_FINISH_LOAD event. The method takes the frame
// ID and constructs a suitable JSON formatted extension event from it.
- void FrameDidFinishLoad(NavigationController* controller, long long frame_id);
+ void FrameDidFinishLoad(NavigationController* controller, int64 frame_id);
// Handler for the FAIL_PROVISIONAL_LOAD_WITH_ERROR event. The method takes
// the details of such an event and constructs a suitable JSON formatted
@@ -116,7 +121,7 @@ class ExtensionWebNavigationEventRouter : public NotificationObserver {
void FailProvisionalLoadWithError(NavigationController* controller,
ProvisionalLoadDetails* details);
- // This method dispatches events to the extension message service.
+ // Dispatches events to the extension message service.
void DispatchEvent(Profile* context,
const char* event_name,
const std::string& json_args);
diff --git a/chrome/browser/extensions/extension_webnavigation_apitest.cc b/chrome/browser/extensions/extension_webnavigation_apitest.cc
index b27887b..8e833b0 100644
--- a/chrome/browser/extensions/extension_webnavigation_apitest.cc
+++ b/chrome/browser/extensions/extension_webnavigation_apitest.cc
@@ -6,6 +6,7 @@
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/common/chrome_switches.h"
+
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, WebNavigation) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableExperimentalExtensionApis);
diff --git a/chrome/browser/extensions/extension_webnavigation_unittest.cc b/chrome/browser/extensions/extension_webnavigation_unittest.cc
index 5ac378e..cfeada0 100644
--- a/chrome/browser/extensions/extension_webnavigation_unittest.cc
+++ b/chrome/browser/extensions/extension_webnavigation_unittest.cc
@@ -8,13 +8,12 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "base/values.h"
-#include "chrome/browser/browser_thread.h"
#include "chrome/browser/extensions/extension_webnavigation_api.h"
#include "chrome/browser/renderer_host/test/test_render_view_host.h"
#include "chrome/browser/tab_contents/test_tab_contents.h"
-#include "chrome/common/url_constants.h"
#include "chrome/test/testing_profile.h"
+
class FrameNavigationStateTest : public RenderViewHostTestHarness {
};
@@ -22,19 +21,19 @@ class FrameNavigationStateTest : public RenderViewHostTestHarness {
// goes away.
TEST_F(FrameNavigationStateTest, TrackFrame) {
FrameNavigationState navigation_state;
- const long long frame_id1 = 23;
- const long long frame_id2 = 42;
+ const int64 frame_id1 = 23;
+ const int64 frame_id2 = 42;
const GURL url1("http://www.google.com/");
const GURL url2("http://mail.google.com/");
// Create a main frame.
EXPECT_FALSE(navigation_state.CanSendEvents(frame_id1));
- navigation_state.TrackFrame(frame_id1, url1, true, contents());
+ navigation_state.TrackFrame(frame_id1, url1, true, false, contents());
EXPECT_TRUE(navigation_state.CanSendEvents(frame_id1));
// Add a sub frame.
EXPECT_FALSE(navigation_state.CanSendEvents(frame_id2));
- navigation_state.TrackFrame(frame_id2, url2, false, contents());
+ navigation_state.TrackFrame(frame_id2, url2, false, false, contents());
EXPECT_TRUE(navigation_state.CanSendEvents(frame_id2));
// Check frame state.
@@ -54,23 +53,22 @@ TEST_F(FrameNavigationStateTest, TrackFrame) {
// before a new navigation happened in this frame.
TEST_F(FrameNavigationStateTest, ErrorState) {
FrameNavigationState navigation_state;
- const long long frame_id = 42;
+ const int64 frame_id = 42;
const GURL url("http://www.google.com/");
- navigation_state.TrackFrame(frame_id, url, true, contents());
+ navigation_state.TrackFrame(frame_id, url, true, false, contents());
EXPECT_TRUE(navigation_state.CanSendEvents(frame_id));
// After an error occurred, no further events should be sent.
navigation_state.ErrorOccurredInFrame(frame_id);
EXPECT_FALSE(navigation_state.CanSendEvents(frame_id));
- // Navigations to the "unreachable web data" URL should be ignored.
- navigation_state.TrackFrame(
- frame_id, GURL(chrome::kUnreachableWebDataURL), true, contents());
+ // Navigations to a network error page should be ignored.
+ navigation_state.TrackFrame(frame_id, GURL(), true, true, contents());
EXPECT_FALSE(navigation_state.CanSendEvents(frame_id));
// However, when the frame navigates again, it should send events again.
- navigation_state.TrackFrame(frame_id, url, true, contents());
+ navigation_state.TrackFrame(frame_id, url, true, false, contents());
EXPECT_TRUE(navigation_state.CanSendEvents(frame_id));
}
@@ -78,12 +76,12 @@ TEST_F(FrameNavigationStateTest, ErrorState) {
// before a new navigation happened in this frame.
TEST_F(FrameNavigationStateTest, ErrorStateFrame) {
FrameNavigationState navigation_state;
- const long long frame_id1 = 23;
- const long long frame_id2 = 42;
+ const int64 frame_id1 = 23;
+ const int64 frame_id2 = 42;
const GURL url("http://www.google.com/");
- navigation_state.TrackFrame(frame_id1, url, true, contents());
- navigation_state.TrackFrame(frame_id2, url, false, contents());
+ navigation_state.TrackFrame(frame_id1, url, true, false, contents());
+ navigation_state.TrackFrame(frame_id2, url, false, false, contents());
EXPECT_TRUE(navigation_state.CanSendEvents(frame_id1));
EXPECT_TRUE(navigation_state.CanSendEvents(frame_id2));
@@ -92,14 +90,13 @@ TEST_F(FrameNavigationStateTest, ErrorStateFrame) {
EXPECT_TRUE(navigation_state.CanSendEvents(frame_id1));
EXPECT_FALSE(navigation_state.CanSendEvents(frame_id2));
- // Navigations to the "unreachable web data" URL should be ignored.
- navigation_state.TrackFrame(
- frame_id2, GURL(chrome::kUnreachableWebDataURL), false, contents());
+ // Navigations to a network error page should be ignored.
+ navigation_state.TrackFrame(frame_id2, GURL(), false, true, contents());
EXPECT_TRUE(navigation_state.CanSendEvents(frame_id1));
EXPECT_FALSE(navigation_state.CanSendEvents(frame_id2));
// However, when the frame navigates again, it should send events again.
- navigation_state.TrackFrame(frame_id2, url, false, contents());
+ navigation_state.TrackFrame(frame_id2, url, false, false, contents());
EXPECT_TRUE(navigation_state.CanSendEvents(frame_id1));
EXPECT_TRUE(navigation_state.CanSendEvents(frame_id2));
}
diff --git a/chrome/browser/extensions/extension_webstore_private_api.cc b/chrome/browser/extensions/extension_webstore_private_api.cc
index 468ae14..32b7c65 100644
--- a/chrome/browser/extensions/extension_webstore_private_api.cc
+++ b/chrome/browser/extensions/extension_webstore_private_api.cc
@@ -13,16 +13,17 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/extensions/crx_installer.h"
#include "chrome/browser/extensions/extension_prefs.h"
-#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/net/gaia/token_service.h"
-#include "chrome/browser/profile_manager.h"
+#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/extensions/extension_error_utils.h"
#include "chrome/common/net/gaia/gaia_constants.h"
-#include "chrome/common/notification_service.h"
+#include "chrome/common/notification_details.h"
+#include "chrome/common/notification_source.h"
#include "chrome/common/notification_type.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
@@ -58,7 +59,7 @@ BrowserSignin* GetBrowserSignin(Profile* profile) {
}
bool IsWebStoreURL(Profile* profile, const GURL& url) {
- ExtensionsService* service = profile->GetExtensionsService();
+ ExtensionService* service = profile->GetExtensionService();
const Extension* store = service->GetWebStoreApp();
if (!store) {
NOTREACHED();
@@ -185,7 +186,7 @@ bool GetBrowserLoginFunction::RunImpl() {
bool GetStoreLoginFunction::RunImpl() {
if (!IsWebStoreURL(profile_, source_url()))
return false;
- ExtensionsService* service = profile_->GetExtensionsService();
+ ExtensionService* service = profile_->GetExtensionService();
ExtensionPrefs* prefs = service->extension_prefs();
std::string login;
if (prefs->GetWebStoreLogin(&login)) {
@@ -201,7 +202,7 @@ bool SetStoreLoginFunction::RunImpl() {
return false;
std::string login;
EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &login));
- ExtensionsService* service = profile_->GetExtensionsService();
+ ExtensionService* service = profile_->GetExtensionService();
ExtensionPrefs* prefs = service->extension_prefs();
prefs->SetWebStoreLogin(login);
return true;
diff --git a/chrome/browser/extensions/extension_webstore_private_browsertest.cc b/chrome/browser/extensions/extension_webstore_private_browsertest.cc
index 01b8e45..3ed1383 100644
--- a/chrome/browser/extensions/extension_webstore_private_browsertest.cc
+++ b/chrome/browser/extensions/extension_webstore_private_browsertest.cc
@@ -10,7 +10,7 @@
#include "chrome/browser/extensions/extension_test_message_listener.h"
#include "chrome/browser/extensions/extension_webstore_private_api.h"
#include "chrome/browser/net/gaia/token_service.h"
-#include "chrome/browser/profile_manager.h"
+#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/chrome_switches.h"
diff --git a/chrome/browser/extensions/extensions_startup.cc b/chrome/browser/extensions/extensions_startup.cc
index 9faeac6..8e0b855 100644
--- a/chrome/browser/extensions/extensions_startup.cc
+++ b/chrome/browser/extensions/extensions_startup.cc
@@ -7,49 +7,31 @@
#include "base/string_util.h"
#include "base/stringprintf.h"
#include "base/utf_string_conversions.h"
-#include "chrome/browser/extensions/extensions_service.h"
-#include "chrome/browser/extensions/pack_extension_job.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_switches.h"
#if defined(OS_WIN)
#include "app/win_util.h"
#endif
-namespace extensions_startup {
+ExtensionsStartupUtil::ExtensionsStartupUtil() : pack_job_succeeded_(false) {}
-class PackExtensionLogger : public PackExtensionJob::Client {
- public:
- PackExtensionLogger() : process_startup_(false) {}
- virtual void OnPackSuccess(const FilePath& crx_path,
- const FilePath& output_private_key_path);
- virtual void OnPackFailure(const std::string& error_message);
-
- private:
- // We need to track if this extension packing job was created on process
- // startup or not so we know if we should Quit() the message loop after
- // packaging the extension.
- bool process_startup_;
- void ShowPackExtensionMessage(const std::wstring& caption,
- const std::wstring& message);
-
- DISALLOW_COPY_AND_ASSIGN(PackExtensionLogger);
-};
-
-void PackExtensionLogger::OnPackSuccess(
+void ExtensionsStartupUtil::OnPackSuccess(
const FilePath& crx_path,
const FilePath& output_private_key_path) {
+ pack_job_succeeded_ = true;
ShowPackExtensionMessage(L"Extension Packaging Success",
PackExtensionJob::StandardSuccessMessage(
crx_path, output_private_key_path));
}
-void PackExtensionLogger::OnPackFailure(const std::string& error_message) {
+void ExtensionsStartupUtil::OnPackFailure(const std::string& error_message) {
ShowPackExtensionMessage(L"Extension Packaging Error",
UTF8ToWide(error_message));
}
-void PackExtensionLogger::ShowPackExtensionMessage(
+void ExtensionsStartupUtil::ShowPackExtensionMessage(
const std::wstring& caption,
const std::wstring& message) {
#if defined(OS_WIN)
@@ -62,62 +44,49 @@ void PackExtensionLogger::ShowPackExtensionMessage(
out_text.append("\n");
base::StringPrintf("%s", out_text.c_str());
#endif
-
- // We got the notification and processed it; we don't expect any further tasks
- // to be posted to the current thread, so we should stop blocking and exit.
- // This call to |Quit()| matches the call to |Run()| in
- // |ProcessCmdLineImpl()|.
- MessageLoop::current()->Quit();
}
-bool HandlePackExtension(const CommandLine& cmd_line) {
- if (cmd_line.HasSwitch(switches::kPackExtension)) {
- // Input Paths.
- FilePath src_dir = cmd_line.GetSwitchValuePath(
- switches::kPackExtension);
- FilePath private_key_path;
- if (cmd_line.HasSwitch(switches::kPackExtensionKey)) {
- private_key_path = cmd_line.GetSwitchValuePath(
- switches::kPackExtensionKey);
- }
-
- // Launch a job to perform the packing on the file thread.
- PackExtensionLogger pack_client;
- scoped_refptr<PackExtensionJob> pack_job(
- new PackExtensionJob(&pack_client, src_dir, private_key_path));
- pack_job->Start();
-
- // The job will post a notification task to the current thread's message
- // loop when it is finished. We manually run the loop here so that we
- // block and catch the notification. Otherwise, the process would exit;
- // in particular, this would mean that |pack_client| would be destroyed
- // and we wouldn't be able to report success or failure back to the user.
- // This call to |Run()| is matched by a call to |Quit()| in the
- // |PackExtensionLogger|'s notification handling code.
- MessageLoop::current()->Run();
+bool ExtensionsStartupUtil::PackExtension(const CommandLine& cmd_line) {
+ if (!cmd_line.HasSwitch(switches::kPackExtension))
+ return false;
- return true;
+ // Input Paths.
+ FilePath src_dir = cmd_line.GetSwitchValuePath(switches::kPackExtension);
+ FilePath private_key_path;
+ if (cmd_line.HasSwitch(switches::kPackExtensionKey)) {
+ private_key_path = cmd_line.GetSwitchValuePath(switches::kPackExtensionKey);
}
- return false;
+ // Launch a job to perform the packing on the file thread.
+ pack_job_ = new PackExtensionJob(this, src_dir, private_key_path);
+ pack_job_->set_asynchronous(false);
+ pack_job_->Start();
+
+ return pack_job_succeeded_;
}
-bool HandleUninstallExtension(const CommandLine& cmd_line, Profile* profile) {
+bool ExtensionsStartupUtil::UninstallExtension(const CommandLine& cmd_line,
+ Profile* profile) {
DCHECK(profile);
- if (cmd_line.HasSwitch(switches::kUninstallExtension)) {
- ExtensionsService* extensions_service = profile->GetExtensionsService();
- if (extensions_service) {
- std::string extension_id = cmd_line.GetSwitchValueASCII(
- switches::kUninstallExtension);
- if (ExtensionsService::UninstallExtensionHelper(extensions_service,
- extension_id)) {
- return true;
- }
- }
+ if (!cmd_line.HasSwitch(switches::kUninstallExtension))
+ return false;
+
+ ExtensionService* extension_service = profile->GetExtensionService();
+ if (!extension_service)
+ return false;
+
+ std::string extension_id = cmd_line.GetSwitchValueASCII(
+ switches::kUninstallExtension);
+ if (ExtensionService::UninstallExtensionHelper(extension_service,
+ extension_id)) {
+ return true;
}
return false;
}
-} // namespace extensions_startup
+ExtensionsStartupUtil::~ExtensionsStartupUtil() {
+ if (pack_job_.get())
+ pack_job_->ClearClient();
+}
diff --git a/chrome/browser/extensions/extensions_startup.h b/chrome/browser/extensions/extensions_startup.h
index 85622de..2dee7d3 100644
--- a/chrome/browser/extensions/extensions_startup.h
+++ b/chrome/browser/extensions/extensions_startup.h
@@ -6,19 +6,38 @@
#define CHROME_BROWSER_EXTENSIONS_EXTENSIONS_STARTUP_H_
#pragma once
+#include "base/scoped_ptr.h"
+#include "chrome/browser/extensions/pack_extension_job.h"
+
class CommandLine;
class Profile;
// Initialization helpers for various Extension startup actions.
-namespace extensions_startup {
-// Handle --pack-extension flag from the |cmd_line| by packing the specified
-// extension. Returns false if the pack job could not be started.
-bool HandlePackExtension(const CommandLine& cmd_line);
-
-// Handle --uninstall-extension flag from the |cmd_line| by uninstalling the
-// specified extension from |profile|. Returns false if the uninstall job
-// could not be started.
-bool HandleUninstallExtension(const CommandLine& cmd_line, Profile* profile);
-} // namespace extensions_startup
+class ExtensionsStartupUtil : public PackExtensionJob::Client {
+ public:
+ ExtensionsStartupUtil();
+ virtual ~ExtensionsStartupUtil();
+
+ virtual void OnPackSuccess(const FilePath& crx_path,
+ const FilePath& output_private_key_path);
+ virtual void OnPackFailure(const std::string& error_message);
+
+ // Handle --pack-extension flag from the |cmd_line| by packing the specified
+ // extension. Returns false if the pack job failed.
+ bool PackExtension(const CommandLine& cmd_line);
+
+ // Handle --uninstall-extension flag from the |cmd_line| by uninstalling the
+ // specified extension from |profile|. Returns false if the uninstall job
+ // could not be started.
+ bool UninstallExtension(const CommandLine& cmd_line, Profile* profile);
+
+ private:
+ void ShowPackExtensionMessage(const std::wstring& caption,
+ const std::wstring& message);
+ scoped_refptr<PackExtensionJob> pack_job_;
+ bool pack_job_succeeded_;
+
+ DISALLOW_COPY_AND_ASSIGN(ExtensionsStartupUtil);
+};
#endif // CHROME_BROWSER_EXTENSIONS_EXTENSIONS_STARTUP_H_
diff --git a/chrome/browser/extensions/extensions_ui.cc b/chrome/browser/extensions/extensions_ui.cc
index 0078f0e..5d3a05d 100644
--- a/chrome/browser/extensions/extensions_ui.cc
+++ b/chrome/browser/extensions/extensions_ui.cc
@@ -4,6 +4,8 @@
#include "chrome/browser/extensions/extensions_ui.h"
+#include <algorithm>
+
#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "base/base64.h"
@@ -16,7 +18,6 @@
#include "base/thread.h"
#include "base/version.h"
#include "chrome/browser/browser_list.h"
-#include "chrome/browser/browser_process.h"
#include "chrome/browser/debugger/devtools_manager.h"
#include "chrome/browser/debugger/devtools_toggle_action.h"
#include "chrome/browser/extensions/crx_installer.h"
@@ -25,11 +26,11 @@
#include "chrome/browser/extensions/extension_function_dispatcher.h"
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extension_message_service.h"
-#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_updater.h"
#include "chrome/browser/google/google_util.h"
#include "chrome/browser/prefs/pref_service.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/renderer_host/render_widget_host.h"
#include "chrome/browser/renderer_host/render_view_host.h"
@@ -190,6 +191,9 @@ void ExtensionsUIHTMLSource::StartDataRequest(const std::string& path,
SendResponse(request_id, html_bytes);
}
+std::string ExtensionsUIHTMLSource::GetMimeType(const std::string&) const {
+ return "text/html";
+}
////////////////////////////////////////////////////////////////////////////////
//
@@ -289,7 +293,7 @@ void ExtensionsDOMHandler::IconLoader::ReportResultOnUIThread(
//
///////////////////////////////////////////////////////////////////////////////
-ExtensionsDOMHandler::ExtensionsDOMHandler(ExtensionsService* extension_service)
+ExtensionsDOMHandler::ExtensionsDOMHandler(ExtensionService* extension_service)
: extensions_service_(extension_service),
ignore_notifications_(false),
deleting_rvh_(NULL) {
@@ -387,8 +391,6 @@ void ExtensionsDOMHandler::OnIconsLoaded(DictionaryValue* json) {
NotificationService::AllSources());
registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
NotificationService::AllSources());
- registrar_.Add(this, NotificationType::EXTENSION_UNLOADED_DISABLED,
- NotificationService::AllSources());
registrar_.Add(this, NotificationType::EXTENSION_UPDATE_DISABLED,
NotificationService::AllSources());
registrar_.Add(this, NotificationType::EXTENSION_FUNCTION_DISPATCHER_CREATED,
@@ -675,6 +677,11 @@ void ExtensionsDOMHandler::FileSelected(const FilePath& path, int index,
dom_ui_->CallJavascriptFunction(L"window.handleFilePathSelected", results);
}
+void ExtensionsDOMHandler::MultiFilesSelected(
+ const std::vector<FilePath>& files, void* params) {
+ NOTREACHED();
+}
+
void ExtensionsDOMHandler::Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
@@ -702,7 +709,6 @@ void ExtensionsDOMHandler::Observe(NotificationType type,
case NotificationType::EXTENSION_LOADED:
case NotificationType::EXTENSION_PROCESS_CREATED:
case NotificationType::EXTENSION_UNLOADED:
- case NotificationType::EXTENSION_UNLOADED_DISABLED:
case NotificationType::EXTENSION_UPDATE_DISABLED:
case NotificationType::EXTENSION_FUNCTION_DISPATCHER_CREATED:
case NotificationType::EXTENSION_FUNCTION_DISPATCHER_DESTROYED:
@@ -784,7 +790,7 @@ static bool ExtensionWantsFileAccess(const Extension* extension) {
// Static
DictionaryValue* ExtensionsDOMHandler::CreateExtensionDetailValue(
- ExtensionsService* service, const Extension* extension,
+ ExtensionService* service, const Extension* extension,
const std::vector<ExtensionPage>& pages, bool enabled) {
DictionaryValue* extension_data = new DictionaryValue();
@@ -929,8 +935,8 @@ ExtensionsDOMHandler::~ExtensionsDOMHandler() {
// ExtensionsDOMHandler, public: -----------------------------------------------
ExtensionsUI::ExtensionsUI(TabContents* contents) : DOMUI(contents) {
- ExtensionsService *exstension_service =
- GetProfile()->GetOriginalProfile()->GetExtensionsService();
+ ExtensionService *exstension_service =
+ GetProfile()->GetOriginalProfile()->GetExtensionService();
ExtensionsDOMHandler* handler = new ExtensionsDOMHandler(exstension_service);
AddMessageHandler(handler);
@@ -942,7 +948,7 @@ ExtensionsUI::ExtensionsUI(TabContents* contents) : DOMUI(contents) {
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
NewRunnableMethod(
- Singleton<ChromeURLDataManager>::get(),
+ ChromeURLDataManager::GetInstance(),
&ChromeURLDataManager::AddDataSource,
make_scoped_refptr(html_source)));
}
diff --git a/chrome/browser/extensions/extensions_ui.h b/chrome/browser/extensions/extensions_ui.h
index 54ec298..b7a9b69 100644
--- a/chrome/browser/extensions/extensions_ui.h
+++ b/chrome/browser/extensions/extensions_ui.h
@@ -22,7 +22,7 @@
class DictionaryValue;
class Extension;
-class ExtensionsService;
+class ExtensionService;
class FilePath;
class ListValue;
class PrefService;
@@ -51,9 +51,7 @@ class ExtensionsUIHTMLSource : public ChromeURLDataManager::DataSource {
virtual void StartDataRequest(const std::string& path,
bool is_off_the_record,
int request_id);
- virtual std::string GetMimeType(const std::string&) const {
- return "text/html";
- }
+ virtual std::string GetMimeType(const std::string&) const;
private:
~ExtensionsUIHTMLSource() {}
@@ -104,7 +102,7 @@ class ExtensionsDOMHandler
ExtensionsDOMHandler* handler_;
};
- explicit ExtensionsDOMHandler(ExtensionsService* extension_service);
+ explicit ExtensionsDOMHandler(ExtensionService* extension_service);
virtual ~ExtensionsDOMHandler();
// DOMMessageHandler implementation.
@@ -113,7 +111,7 @@ class ExtensionsDOMHandler
// Extension Detail JSON Struct for page. (static for ease of testing).
// Note: service can be NULL in unit tests.
static DictionaryValue* CreateExtensionDetailValue(
- ExtensionsService* service,
+ ExtensionService* service,
const Extension* extension,
const std::vector<ExtensionPage>& pages,
bool enabled);
@@ -190,9 +188,7 @@ class ExtensionsDOMHandler
virtual void FileSelected(const FilePath& path,
int index, void* params);
virtual void MultiFilesSelected(
- const std::vector<FilePath>& files, void* params) {
- NOTREACHED();
- }
+ const std::vector<FilePath>& files, void* params);
virtual void FileSelectionCanceled(void* params) {}
// NotificationObserver
@@ -227,7 +223,7 @@ class ExtensionsDOMHandler
ExtensionInstallUI* GetExtensionInstallUI();
// Our model.
- scoped_refptr<ExtensionsService> extensions_service_;
+ scoped_refptr<ExtensionService> extensions_service_;
// Used to pick the directory when loading an extension.
scoped_refptr<SelectFileDialog> load_extension_dialog_;
diff --git a/chrome/browser/extensions/external_extension_provider.h b/chrome/browser/extensions/external_extension_provider.h
index 1d040bd..5bcce1d 100644
--- a/chrome/browser/extensions/external_extension_provider.h
+++ b/chrome/browser/extensions/external_extension_provider.h
@@ -6,9 +6,6 @@
#define CHROME_BROWSER_EXTENSIONS_EXTERNAL_EXTENSION_PROVIDER_H_
#pragma once
-#include <set>
-#include <string>
-
#include "chrome/common/extensions/extension.h"
class FilePath;
@@ -44,8 +41,7 @@ class ExternalExtensionProvider {
// Enumerate registered extension, calling OnExternalExtensionFound on
// the |visitor| object for each registered extension found. |ids_to_ignore|
// contains a list of extension ids that should not result in a call back.
- virtual void VisitRegisteredExtension(
- Visitor* visitor, const std::set<std::string>& ids_to_ignore) const = 0;
+ virtual void VisitRegisteredExtension(Visitor* visitor) const = 0;
// Test if this provider has an extension with id |id| registered.
virtual bool HasExtension(const std::string& id) const = 0;
diff --git a/chrome/browser/extensions/external_policy_extension_provider.cc b/chrome/browser/extensions/external_policy_extension_provider.cc
index d482bb3..5e87379 100644
--- a/chrome/browser/extensions/external_policy_extension_provider.cc
+++ b/chrome/browser/extensions/external_policy_extension_provider.cc
@@ -4,8 +4,10 @@
#include "chrome/browser/extensions/external_policy_extension_provider.h"
+#include "base/logging.h"
#include "base/values.h"
#include "chrome/common/pref_names.h"
+#include "chrome/browser/browser_thread.h"
#include "chrome/browser/extensions/stateful_external_extension_provider.h"
#include "chrome/browser/prefs/pref_service.h"
@@ -29,16 +31,27 @@ bool CheckExtension(std::string id, std::string update_url) {
}
-ExternalPolicyExtensionProvider::ExternalPolicyExtensionProvider()
- : StatefulExternalExtensionProvider(Extension::INVALID,
- Extension::EXTERNAL_POLICY_DOWNLOAD) {
+ExternalPolicyExtensionProvider::ExternalPolicyExtensionProvider(
+ const ListValue* forcelist)
+ : StatefulExternalExtensionProvider(
+ Extension::INVALID,
+ Extension::EXTERNAL_POLICY_DOWNLOAD) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ ProcessPreferences(forcelist);
}
ExternalPolicyExtensionProvider::~ExternalPolicyExtensionProvider() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
}
void ExternalPolicyExtensionProvider::SetPreferences(
const ListValue* forcelist) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ ProcessPreferences(forcelist);
+}
+
+void ExternalPolicyExtensionProvider::ProcessPreferences(
+ const ListValue* forcelist) {
DictionaryValue* result = new DictionaryValue();
if (forcelist != NULL) {
std::string extension_desc;
@@ -59,5 +72,5 @@ void ExternalPolicyExtensionProvider::SetPreferences(
}
}
}
- prefs_.reset(result);
+ set_prefs(result);
}
diff --git a/chrome/browser/extensions/external_policy_extension_provider.h b/chrome/browser/extensions/external_policy_extension_provider.h
index bb4cc7d..9c36960 100644
--- a/chrome/browser/extensions/external_policy_extension_provider.h
+++ b/chrome/browser/extensions/external_policy_extension_provider.h
@@ -14,11 +14,14 @@ class PrefService;
// A specialization of the ExternalExtensionProvider that uses
// prefs::kExtensionInstallForceList to look up which external extensions are
-// registered.
+// registered. The value of this preference is received via the constructor and
+// via |SetPreferences| in case of run-time updates.
+// Instances of this class are expected to be created and destroyed on the UI
+// thread and they are expecting public method calls from the FILE thread.
class ExternalPolicyExtensionProvider
: public StatefulExternalExtensionProvider {
public:
- explicit ExternalPolicyExtensionProvider();
+ explicit ExternalPolicyExtensionProvider(const ListValue* forcelist);
virtual ~ExternalPolicyExtensionProvider();
// Set the internal list of extensions based on |forcelist|.
@@ -28,6 +31,9 @@ class ExternalPolicyExtensionProvider
private:
friend class MockExternalPolicyExtensionProviderVisitor;
+ // Set the internal list of extensions based on |forcelist|.
+ // Does not take ownership of |forcelist|.
+ void ProcessPreferences(const ListValue* forcelist);
};
#endif // CHROME_BROWSER_EXTENSIONS_EXTERNAL_POLICY_EXTENSION_PROVIDER_H_
diff --git a/chrome/browser/extensions/external_policy_extension_provider_unittest.cc b/chrome/browser/extensions/external_policy_extension_provider_unittest.cc
index 4fb5117..cd5a3df 100644
--- a/chrome/browser/extensions/external_policy_extension_provider_unittest.cc
+++ b/chrome/browser/extensions/external_policy_extension_provider_unittest.cc
@@ -7,11 +7,26 @@
#include "base/logging.h"
#include "base/values.h"
#include "base/version.h"
+#include "chrome/browser/browser_thread.h"
#include "chrome/browser/extensions/external_policy_extension_provider.h"
#include "chrome/common/extensions/extension.h"
#include "testing/gtest/include/gtest/gtest.h"
class ExternalPolicyExtensionProviderTest : public testing::Test {
+ public:
+ ExternalPolicyExtensionProviderTest()
+ : loop_(MessageLoop::TYPE_IO),
+ ui_thread_(BrowserThread::UI, &loop_),
+ file_thread_(BrowserThread::FILE, &loop_) {
+ }
+
+ virtual ~ExternalPolicyExtensionProviderTest() {
+ }
+
+ private:
+ MessageLoop loop_;
+ BrowserThread ui_thread_;
+ BrowserThread file_thread_;
};
class MockExternalPolicyExtensionProviderVisitor
@@ -25,14 +40,12 @@ class MockExternalPolicyExtensionProviderVisitor
void Visit(ListValue* policy_forcelist,
ListValue* policy_validlist,
const std::set<std::string>& ignore_list) {
- provider_.reset(new ExternalPolicyExtensionProvider());
- // Give the list extensions to the provider.
- provider_->SetPreferences(policy_forcelist);
+ provider_.reset(new ExternalPolicyExtensionProvider(policy_forcelist));
// Extensions will be removed from this list as they visited,
// so it should be emptied by the end.
remaining_extensions = policy_validlist;
- provider_->VisitRegisteredExtension(this, ignore_list);
+ provider_->VisitRegisteredExtension(this);
EXPECT_EQ(0u, remaining_extensions->GetSize());
}
diff --git a/chrome/browser/extensions/external_pref_extension_provider.cc b/chrome/browser/extensions/external_pref_extension_provider.cc
index 7580388..7ea5f4a 100644
--- a/chrome/browser/extensions/external_pref_extension_provider.cc
+++ b/chrome/browser/extensions/external_pref_extension_provider.cc
@@ -9,12 +9,14 @@
#include "base/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
+#include "chrome/browser/browser_thread.h"
#include "chrome/browser/extensions/stateful_external_extension_provider.h"
#include "chrome/common/json_value_serializer.h"
ExternalPrefExtensionProvider::ExternalPrefExtensionProvider()
: StatefulExternalExtensionProvider(Extension::EXTERNAL_PREF,
Extension::EXTERNAL_PREF_DOWNLOAD) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
FilePath json_file;
PathService::Get(app::DIR_EXTERNAL_EXTENSIONS, &json_file);
json_file = json_file.Append(FILE_PATH_LITERAL("external_extensions.json"));
@@ -23,11 +25,12 @@ ExternalPrefExtensionProvider::ExternalPrefExtensionProvider()
JSONFileValueSerializer serializer(json_file);
SetPreferences(&serializer);
} else {
- prefs_.reset(new DictionaryValue());
+ set_prefs(new DictionaryValue());
}
}
ExternalPrefExtensionProvider::~ExternalPrefExtensionProvider() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
}
void ExternalPrefExtensionProvider::SetPreferencesForTesting(
@@ -50,5 +53,5 @@ void ExternalPrefExtensionProvider::SetPreferences(
dictionary.reset(static_cast<DictionaryValue*>(extensions));
}
}
- prefs_.reset(dictionary.release());
+ set_prefs(dictionary.release());
}
diff --git a/chrome/browser/extensions/external_pref_extension_provider.h b/chrome/browser/extensions/external_pref_extension_provider.h
index 8b9eb0b..b74be39 100644
--- a/chrome/browser/extensions/external_pref_extension_provider.h
+++ b/chrome/browser/extensions/external_pref_extension_provider.h
@@ -10,6 +10,8 @@
// A specialization of the ExternalExtensionProvider that uses a json file to
// look up which external extensions are registered.
+// Instances of this class are expected to be created and destroyed on the UI
+// thread and they are expecting public method calls from the FILE thread.
class ExternalPrefExtensionProvider : public StatefulExternalExtensionProvider {
public:
explicit ExternalPrefExtensionProvider();
diff --git a/chrome/browser/extensions/external_registry_extension_provider_win.cc b/chrome/browser/extensions/external_registry_extension_provider_win.cc
index 00bea09..16b107f 100644
--- a/chrome/browser/extensions/external_registry_extension_provider_win.cc
+++ b/chrome/browser/extensions/external_registry_extension_provider_win.cc
@@ -41,7 +41,7 @@ ExternalRegistryExtensionProvider::~ExternalRegistryExtensionProvider() {
}
void ExternalRegistryExtensionProvider::VisitRegisteredExtension(
- Visitor* visitor, const std::set<std::string>& ids_to_ignore) const {
+ Visitor* visitor) const {
base::win::RegistryKeyIterator iterator(
kRegRoot, ASCIIToWide(kRegistryExtensions).c_str());
while (iterator.Valid()) {
@@ -56,13 +56,10 @@ void ExternalRegistryExtensionProvider::VisitRegisteredExtension(
if (key.ReadValue(kRegistryExtensionVersion, &extension_version)) {
std::string id = WideToASCII(iterator.Name());
StringToLowerASCII(&id);
- if (ids_to_ignore.find(id) != ids_to_ignore.end()) {
- ++iterator;
- continue;
- }
scoped_ptr<Version> version;
- version.reset(Version::GetVersionFromString(extension_version));
+ version.reset(Version::GetVersionFromString(
+ WideToASCII(extension_version)));
if (!version.get()) {
LOG(ERROR) << "Invalid version value " << extension_version
<< " for key " << key_path;
@@ -107,8 +104,10 @@ bool ExternalRegistryExtensionProvider::GetExtensionDetails(
if (!key.ReadValue(kRegistryExtensionVersion, &extension_version))
return false;
- if (version)
- version->reset(Version::GetVersionFromString(extension_version));
+ if (version) {
+ version->reset(Version::GetVersionFromString(
+ WideToASCII(extension_version)));
+ }
if (location)
*location = Extension::EXTERNAL_REGISTRY;
diff --git a/chrome/browser/extensions/external_registry_extension_provider_win.h b/chrome/browser/extensions/external_registry_extension_provider_win.h
index bb60106..34899ae 100644
--- a/chrome/browser/extensions/external_registry_extension_provider_win.h
+++ b/chrome/browser/extensions/external_registry_extension_provider_win.h
@@ -6,9 +6,6 @@
#define CHROME_BROWSER_EXTENSIONS_EXTERNAL_REGISTRY_EXTENSION_PROVIDER_WIN_H_
#pragma once
-#include <set>
-#include <string>
-
#include "chrome/browser/extensions/external_extension_provider.h"
class Version;
@@ -21,8 +18,7 @@ class ExternalRegistryExtensionProvider : public ExternalExtensionProvider {
virtual ~ExternalRegistryExtensionProvider();
// ExternalExtensionProvider implementation:
- virtual void VisitRegisteredExtension(
- Visitor* visitor, const std::set<std::string>& ids_to_ignore) const;
+ virtual void VisitRegisteredExtension(Visitor* visitor) const;
virtual bool HasExtension(const std::string& id) const;
diff --git a/chrome/browser/extensions/fragment_navigation_apitest.cc b/chrome/browser/extensions/fragment_navigation_apitest.cc
index 68ca622..8d931a8 100644
--- a/chrome/browser/extensions/fragment_navigation_apitest.cc
+++ b/chrome/browser/extensions/fragment_navigation_apitest.cc
@@ -11,7 +11,9 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ContentScriptFragmentNavigation) {
ASSERT_TRUE(RunExtensionTest(extension_name)) << message_;
}
-IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ExecuteScriptFragmentNavigation) {
+// Crashy, http://crbug.com/67774.
+IN_PROC_BROWSER_TEST_F(ExtensionApiTest,
+ DISABLED_ExecuteScriptFragmentNavigation) {
ASSERT_TRUE(StartTestServer());
const char* extension_name = "executescript/fragment";
ASSERT_TRUE(RunExtensionTest(extension_name)) << message_;
diff --git a/chrome/browser/extensions/gtk_theme_installed_infobar_delegate.cc b/chrome/browser/extensions/gtk_theme_installed_infobar_delegate.cc
index d3fc1c0..cd2f123 100644
--- a/chrome/browser/extensions/gtk_theme_installed_infobar_delegate.cc
+++ b/chrome/browser/extensions/gtk_theme_installed_infobar_delegate.cc
@@ -4,7 +4,7 @@
#include "chrome/browser/extensions/gtk_theme_installed_infobar_delegate.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
GtkThemeInstalledInfoBarDelegate::GtkThemeInstalledInfoBarDelegate(
TabContents* tab_contents,
diff --git a/chrome/browser/extensions/image_loading_tracker.cc b/chrome/browser/extensions/image_loading_tracker.cc
index 496c3ad..873dcaa 100644
--- a/chrome/browser/extensions/image_loading_tracker.cc
+++ b/chrome/browser/extensions/image_loading_tracker.cc
@@ -123,8 +123,6 @@ ImageLoadingTracker::ImageLoadingTracker(Observer* observer)
next_id_(0) {
registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
NotificationService::AllSources());
- registrar_.Add(this, NotificationType::EXTENSION_UNLOADED_DISABLED,
- NotificationService::AllSources());
}
ImageLoadingTracker::~ImageLoadingTracker() {
@@ -184,10 +182,10 @@ void ImageLoadingTracker::OnImageLoaded(
void ImageLoadingTracker::Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
- DCHECK(type == NotificationType::EXTENSION_UNLOADED ||
- type == NotificationType::EXTENSION_UNLOADED_DISABLED);
+ DCHECK(type == NotificationType::EXTENSION_UNLOADED);
- const Extension* extension = Details<const Extension>(details).ptr();
+ const Extension* extension =
+ Details<UnloadedExtensionInfo>(details)->extension;
// Remove all entries in the load_map_ referencing the extension. This ensures
// we don't attempt to cache the image when the load completes.
diff --git a/chrome/browser/extensions/image_loading_tracker_unittest.cc b/chrome/browser/extensions/image_loading_tracker_unittest.cc
index 57b5268..4c9734f 100644
--- a/chrome/browser/extensions/image_loading_tracker_unittest.cc
+++ b/chrome/browser/extensions/image_loading_tracker_unittest.cc
@@ -160,10 +160,12 @@ TEST_F(ImageLoadingTrackerTest, DeleteExtensionWhileWaitingForCache) {
EXPECT_EQ(0, image_loaded_count());
// Send out notification the extension was uninstalled.
+ UnloadedExtensionInfo details(extension.get(),
+ UnloadedExtensionInfo::UNINSTALL);
NotificationService::current()->Notify(
NotificationType::EXTENSION_UNLOADED,
NotificationService::AllSources(),
- Details<const Extension>(extension.get()));
+ Details<UnloadedExtensionInfo>(&details));
// Chuck the extension, that way if anyone tries to access it we should crash
// or get valgrind errors.
diff --git a/chrome/browser/extensions/notifications_apitest.cc b/chrome/browser/extensions/notifications_apitest.cc
index 6a80635..7e2a34d 100644
--- a/chrome/browser/extensions/notifications_apitest.cc
+++ b/chrome/browser/extensions/notifications_apitest.cc
@@ -5,17 +5,11 @@
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/notifications/desktop_notification_service.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
-// Fails and hoses bot, http://crbug.com/50060.
// Flaky, http://crbug.com/42314.
-#if defined(OS_MACOSX)
-#define MAYBE_Notifications DISABLED_Notifications
-#else
-#define MAYBE_Notifications FLAKY_Notifications
-#endif
-IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_Notifications) {
+IN_PROC_BROWSER_TEST_F(ExtensionApiTest, FLAKY_Notifications) {
#if defined(OS_LINUX) && defined(TOOLKIT_VIEWS)
// Notifications not supported on linux/views yet.
#else
diff --git a/chrome/browser/extensions/pack_extension_job.cc b/chrome/browser/extensions/pack_extension_job.cc
index 5f64025..327d7c4 100644
--- a/chrome/browser/extensions/pack_extension_job.cc
+++ b/chrome/browser/extensions/pack_extension_job.cc
@@ -15,15 +15,19 @@
PackExtensionJob::PackExtensionJob(Client* client,
const FilePath& root_directory,
const FilePath& key_file)
- : client_(client), key_file_(key_file) {
+ : client_(client), key_file_(key_file), asynchronous_(true) {
root_directory_ = root_directory.StripTrailingSeparators();
CHECK(BrowserThread::GetCurrentThreadIdentifier(&client_thread_id_));
}
void PackExtensionJob::Start() {
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(this, &PackExtensionJob::RunOnFileThread));
+ if (asynchronous_) {
+ BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
+ NewRunnableMethod(this, &PackExtensionJob::Run));
+ } else {
+ Run();
+ }
}
void PackExtensionJob::ClearClient() {
@@ -32,7 +36,7 @@ void PackExtensionJob::ClearClient() {
PackExtensionJob::~PackExtensionJob() {}
-void PackExtensionJob::RunOnFileThread() {
+void PackExtensionJob::Run() {
crx_file_out_ = FilePath(root_directory_.value() +
chrome::kExtensionFileExtension);
@@ -44,16 +48,24 @@ void PackExtensionJob::RunOnFileThread() {
// returns. See bug 20734.
ExtensionCreator creator;
if (creator.Run(root_directory_, crx_file_out_, key_file_, key_file_out_)) {
- BrowserThread::PostTask(
- client_thread_id_, FROM_HERE,
- NewRunnableMethod(this,
- &PackExtensionJob::ReportSuccessOnClientThread));
+ if (asynchronous_) {
+ BrowserThread::PostTask(
+ client_thread_id_, FROM_HERE,
+ NewRunnableMethod(this,
+ &PackExtensionJob::ReportSuccessOnClientThread));
+ } else {
+ ReportSuccessOnClientThread();
+ }
} else {
- BrowserThread::PostTask(
- client_thread_id_, FROM_HERE,
- NewRunnableMethod(
- this, &PackExtensionJob::ReportFailureOnClientThread,
- creator.error_message()));
+ if (asynchronous_) {
+ BrowserThread::PostTask(
+ client_thread_id_, FROM_HERE,
+ NewRunnableMethod(
+ this, &PackExtensionJob::ReportFailureOnClientThread,
+ creator.error_message()));
+ } else {
+ ReportFailureOnClientThread(creator.error_message());
+ }
}
}
diff --git a/chrome/browser/extensions/pack_extension_job.h b/chrome/browser/extensions/pack_extension_job.h
index ecd3d68..e26687a 100644
--- a/chrome/browser/extensions/pack_extension_job.h
+++ b/chrome/browser/extensions/pack_extension_job.h
@@ -33,8 +33,7 @@ class PackExtensionJob : public base::RefCountedThreadSafe<PackExtensionJob> {
const FilePath& root_directory,
const FilePath& key_file);
- // Starts the packing thread job. See http://crbug.com/27944 for more details
- // on why this function is needed.
+ // Starts the packing job.
void Start();
// The client should call this when it is destroyed to prevent
@@ -45,12 +44,15 @@ class PackExtensionJob : public base::RefCountedThreadSafe<PackExtensionJob> {
static std::wstring StandardSuccessMessage(const FilePath& crx_file,
const FilePath& key_file);
+ void set_asynchronous(bool async) { asynchronous_ = async; }
+
private:
friend class base::RefCountedThreadSafe<PackExtensionJob>;
virtual ~PackExtensionJob();
- void RunOnFileThread();
+ // If |asynchronous_| is false, this is run on whichever thread calls it.
+ void Run();
void ReportSuccessOnClientThread();
void ReportFailureOnClientThread(const std::string& error);
@@ -60,6 +62,7 @@ class PackExtensionJob : public base::RefCountedThreadSafe<PackExtensionJob> {
FilePath key_file_;
FilePath crx_file_out_;
FilePath key_file_out_;
+ bool asynchronous_;
DISALLOW_COPY_AND_ASSIGN(PackExtensionJob);
};
diff --git a/chrome/browser/extensions/page_action_apitest.cc b/chrome/browser/extensions/page_action_apitest.cc
index dede04b..504f909 100644
--- a/chrome/browser/extensions/page_action_apitest.cc
+++ b/chrome/browser/extensions/page_action_apitest.cc
@@ -5,12 +5,12 @@
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_browser_event_router.h"
#include "chrome/browser/extensions/extension_tabs_module.h"
-#include "chrome/browser/extensions/extensions_service.h"
-#include "chrome/browser/location_bar.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/omnibox/location_bar.h"
#include "chrome/common/extensions/extension_action.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/test/ui_test_utils.h"
diff --git a/chrome/browser/extensions/sandboxed_extension_unpacker.cc b/chrome/browser/extensions/sandboxed_extension_unpacker.cc
index faf236b..9d7e45b 100644
--- a/chrome/browser/extensions/sandboxed_extension_unpacker.cc
+++ b/chrome/browser/extensions/sandboxed_extension_unpacker.cc
@@ -6,6 +6,7 @@
#include <set>
+#include "app/l10n_util.h"
#include "base/base64.h"
#include "base/crypto/signature_verifier.h"
#include "base/file_util.h"
@@ -15,7 +16,7 @@
#include "base/task.h"
#include "base/utf_string_conversions.h" // TODO(viettrungluu): delete me.
#include "chrome/browser/browser_thread.h"
-#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/renderer_host/resource_dispatcher_host.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension.h"
@@ -25,6 +26,7 @@
#include "chrome/common/extensions/extension_unpacker.h"
#include "chrome/common/json_value_serializer.h"
#include "gfx/codec/png_codec.h"
+#include "grit/generated_resources.h"
#include "third_party/skia/include/core/SkBitmap.h"
const char SandboxedExtensionUnpacker::kExtensionHeaderMagic[] = "Cr24";
@@ -46,7 +48,10 @@ void SandboxedExtensionUnpacker::Start() {
// Create a temporary directory to work in.
if (!temp_dir_.CreateUniqueTempDirUnderPath(temp_path_)) {
- ReportFailure("Could not create temporary directory.");
+ // Could not create temporary directory.
+ ReportFailure(l10n_util::GetStringFUTF8(
+ IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
+ ASCIIToUTF16("COULD_NOT_CREATE_TEMP_DIRECTORY")));
return;
}
@@ -61,7 +66,10 @@ void SandboxedExtensionUnpacker::Start() {
// Copy the crx file into our working directory.
FilePath temp_crx_path = temp_dir_.path().Append(crx_path_.BaseName());
if (!file_util::CopyFile(crx_path_, temp_crx_path)) {
- ReportFailure("Failed to copy extension file to temporary directory.");
+ // Failed to copy extension file to temporary directory.
+ ReportFailure(l10n_util::GetStringFUTF8(
+ IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
+ ASCIIToUTF16("FAILED_TO_COPY_EXTENSION_FILE_TO_TEMP_DIRECTORY")));
return;
}
@@ -81,21 +89,7 @@ void SandboxedExtensionUnpacker::Start() {
if (!file_util::NormalizeFilePath(temp_crx_path, &link_free_crx_path)) {
LOG(ERROR) << "Could not get the normalized path of "
<< temp_crx_path.value();
-#if defined (OS_WIN)
- // On windows, it is possible to mount a disk without the root of that
- // disk having a drive letter. The sandbox does not support this.
- // See crbug/49530 .
- ReportFailure(
- "Can not unpack extension. To safely unpack an extension, "
- "there must be a path to your profile directory that starts "
- "with a drive letter and does not contain a junction, mount "
- "point, or symlink. No such path exists for your profile.");
-#else
- ReportFailure(
- "Can not unpack extension. To safely unpack an extension, "
- "there must be a path to your profile directory that does "
- "not contain a symlink. No such path exists for your profile.");
-#endif
+ ReportFailure(l10n_util::GetStringUTF8(IDS_EXTENSION_UNPACK_FAILED));
return;
}
@@ -153,7 +147,9 @@ void SandboxedExtensionUnpacker::OnUnpackExtensionSucceeded(
if (!extension_l10n_util::LocalizeExtension(extension_root_,
final_manifest.get(),
&error)) {
- ReportFailure(error);
+ ReportFailure(l10n_util::GetStringFUTF8(
+ IDS_EXTENSION_PACKAGE_ERROR_MESSAGE,
+ ASCIIToUTF16(error)));
return;
}
@@ -178,21 +174,29 @@ void SandboxedExtensionUnpacker::OnUnpackExtensionFailed(
const std::string& error) {
DCHECK(BrowserThread::CurrentlyOn(thread_identifier_));
got_response_ = true;
- ReportFailure(error);
+ ReportFailure(l10n_util::GetStringFUTF8(
+ IDS_EXTENSION_PACKAGE_ERROR_MESSAGE,
+ ASCIIToUTF16(error)));
}
-void SandboxedExtensionUnpacker::OnProcessCrashed() {
+void SandboxedExtensionUnpacker::OnProcessCrashed(int exit_code) {
// Don't report crashes if they happen after we got a response.
if (got_response_)
return;
- ReportFailure("Utility process crashed while trying to install.");
+ // Utility process crashed while trying to install.
+ ReportFailure(l10n_util::GetStringFUTF8(
+ IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
+ ASCIIToUTF16("UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL")));
}
bool SandboxedExtensionUnpacker::ValidateSignature() {
ScopedStdioHandle file(file_util::OpenFile(crx_path_, "rb"));
if (!file.get()) {
- ReportFailure("Could not open crx file for reading");
+ // Could not open crx file for reading
+ ReportFailure(l10n_util::GetStringFUTF8(
+ IDS_EXTENSION_PACKAGE_ERROR_CODE,
+ ASCIIToUTF16("CRX_FILE_NOT_READABLE")));
return false;
}
@@ -207,29 +211,47 @@ bool SandboxedExtensionUnpacker::ValidateSignature() {
len = fread(&header, 1, sizeof(ExtensionHeader),
file.get());
if (len < sizeof(ExtensionHeader)) {
- ReportFailure("Invalid crx header");
+ // Invalid crx header
+ ReportFailure(l10n_util::GetStringFUTF8(
+ IDS_EXTENSION_PACKAGE_ERROR_CODE,
+ ASCIIToUTF16("CRX_HEADER_INVALID")));
return false;
}
if (strncmp(kExtensionHeaderMagic, header.magic,
sizeof(header.magic))) {
- ReportFailure("Bad magic number");
+ // Bad magic number
+ ReportFailure(l10n_util::GetStringFUTF8(
+ IDS_EXTENSION_PACKAGE_ERROR_CODE,
+ ASCIIToUTF16("CRX_MAGIC_NUMBER_INVALID")));
return false;
}
if (header.version != kCurrentVersion) {
- ReportFailure("Bad version number");
+ // Bad version numer
+ ReportFailure(l10n_util::GetStringFUTF8(
+ IDS_EXTENSION_PACKAGE_ERROR_CODE,
+ ASCIIToUTF16("CRX_VERSION_NUMBER_INVALID")));
return false;
}
if (header.key_size > kMaxPublicKeySize ||
header.signature_size > kMaxSignatureSize) {
- ReportFailure("Excessively large key or signature");
+ // Excessively large key or signature
+ ReportFailure(l10n_util::GetStringFUTF8(
+ IDS_EXTENSION_PACKAGE_ERROR_CODE,
+ ASCIIToUTF16("CRX_EXCESSIVELY_LARGE_KEY_OR_SIGNATURE")));
return false;
}
if (header.key_size == 0) {
- ReportFailure("Key length is zero");
+ // Key length is zero
+ ReportFailure(l10n_util::GetStringFUTF8(
+ IDS_EXTENSION_PACKAGE_ERROR_CODE,
+ ASCIIToUTF16("CRX_ZERO_KEY_LENGTH")));
return false;
}
if (header.signature_size == 0) {
- ReportFailure("Signature length is zero");
+ // Signature length is zero
+ ReportFailure(l10n_util::GetStringFUTF8(
+ IDS_EXTENSION_PACKAGE_ERROR_CODE,
+ ASCIIToUTF16("CRX_ZERO_SIGNATURE_LENGTH")));
return false;
}
@@ -237,7 +259,10 @@ bool SandboxedExtensionUnpacker::ValidateSignature() {
key.resize(header.key_size);
len = fread(&key.front(), sizeof(uint8), header.key_size, file.get());
if (len < header.key_size) {
- ReportFailure("Invalid public key");
+ // Invalid public key
+ ReportFailure(l10n_util::GetStringFUTF8(
+ IDS_EXTENSION_PACKAGE_ERROR_CODE,
+ ASCIIToUTF16("CRX_PUBLIC_KEY_INVALID")));
return false;
}
@@ -246,7 +271,10 @@ bool SandboxedExtensionUnpacker::ValidateSignature() {
len = fread(&signature.front(), sizeof(uint8), header.signature_size,
file.get());
if (len < header.signature_size) {
- ReportFailure("Invalid signature");
+ // Invalid signature
+ ReportFailure(l10n_util::GetStringFUTF8(
+ IDS_EXTENSION_PACKAGE_ERROR_CODE,
+ ASCIIToUTF16("CRX_SIGNATURE_INVALID")));
return false;
}
@@ -257,9 +285,11 @@ bool SandboxedExtensionUnpacker::ValidateSignature() {
signature.size(),
&key.front(),
key.size())) {
- ReportFailure("Signature verification initialization failed. "
- "This is most likely caused by a public key in "
- "the wrong format (should encode algorithm).");
+ // Signature verification initialization failed. This is most likely
+ // caused by a public key in the wrong format (should encode algorithm).
+ ReportFailure(l10n_util::GetStringFUTF8(
+ IDS_EXTENSION_PACKAGE_ERROR_CODE,
+ ASCIIToUTF16("CRX_SIGNATURE_VERIFICATION_INITIALIZATION_FAILED")));
return false;
}
@@ -268,7 +298,10 @@ bool SandboxedExtensionUnpacker::ValidateSignature() {
verifier.VerifyUpdate(buf, len);
if (!verifier.VerifyFinal()) {
- ReportFailure("Signature verification failed");
+ // Signature verification failed
+ ReportFailure(l10n_util::GetStringFUTF8(
+ IDS_EXTENSION_PACKAGE_ERROR_CODE,
+ ASCIIToUTF16("CRX_SIGNATURE_VERIFICATION_FAILED")));
return false;
}
@@ -300,7 +333,10 @@ DictionaryValue* SandboxedExtensionUnpacker::RewriteManifestFile(
JSONStringValueSerializer serializer(&manifest_json);
serializer.set_pretty_print(true);
if (!serializer.Serialize(*final_manifest)) {
- ReportFailure("Error serializing manifest.json.");
+ // Error serializing manifest.json.
+ ReportFailure(l10n_util::GetStringFUTF8(
+ IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
+ ASCIIToUTF16("ERROR_SERIALIZING_MANIFEST_JSON")));
return NULL;
}
@@ -308,7 +344,10 @@ DictionaryValue* SandboxedExtensionUnpacker::RewriteManifestFile(
extension_root_.Append(Extension::kManifestFilename);
if (!file_util::WriteFile(manifest_path,
manifest_json.data(), manifest_json.size())) {
- ReportFailure("Error saving manifest.json.");
+ // Error saving manifest.json.
+ ReportFailure(l10n_util::GetStringFUTF8(
+ IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
+ ASCIIToUTF16("ERROR_SAVING_MANIFEST_JSON")));
return NULL;
}
@@ -318,7 +357,10 @@ DictionaryValue* SandboxedExtensionUnpacker::RewriteManifestFile(
bool SandboxedExtensionUnpacker::RewriteImageFiles() {
ExtensionUnpacker::DecodedImages images;
if (!ExtensionUnpacker::ReadImagesFromFile(temp_dir_.path(), &images)) {
- ReportFailure("Couldn't read image data from disk.");
+ // Couldn't read image data from disk.
+ ReportFailure(l10n_util::GetStringFUTF8(
+ IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
+ ASCIIToUTF16("COULD_NOT_READ_IMAGE_DATA_FROM_DISK")));
return false;
}
@@ -327,7 +369,10 @@ bool SandboxedExtensionUnpacker::RewriteImageFiles() {
// originals are gone for good.
std::set<FilePath> image_paths = extension_->GetBrowserImages();
if (image_paths.size() != images.size()) {
- ReportFailure("Decoded images don't match what's in the manifest.");
+ // Decoded images don't match what's in the manifest.
+ ReportFailure(l10n_util::GetStringFUTF8(
+ IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
+ ASCIIToUTF16("DECODED_IMAGES_DO_NOT_MATCH_THE_MANIFEST")));
return false;
}
@@ -335,11 +380,17 @@ bool SandboxedExtensionUnpacker::RewriteImageFiles() {
it != image_paths.end(); ++it) {
FilePath path = *it;
if (path.IsAbsolute() || path.ReferencesParent()) {
- ReportFailure("Invalid path for browser image.");
+ // Invalid path for browser image.
+ ReportFailure(l10n_util::GetStringFUTF8(
+ IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
+ ASCIIToUTF16("INVALID_PATH_FOR_BROWSER_IMAGE")));
return false;
}
if (!file_util::Delete(extension_root_.Append(path), false)) {
- ReportFailure("Error removing old image file.");
+ // Error removing old image file.
+ ReportFailure(l10n_util::GetStringFUTF8(
+ IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
+ ASCIIToUTF16("ERROR_REMOVING_OLD_IMAGE_FILE")));
return false;
}
}
@@ -349,7 +400,10 @@ bool SandboxedExtensionUnpacker::RewriteImageFiles() {
const SkBitmap& image = images[i].a;
FilePath path_suffix = images[i].b;
if (path_suffix.IsAbsolute() || path_suffix.ReferencesParent()) {
- ReportFailure("Invalid path for bitmap image.");
+ // Invalid path for bitmap image.
+ ReportFailure(l10n_util::GetStringFUTF8(
+ IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
+ ASCIIToUTF16("INVALID_PATH_FOR_BITMAP_IMAGE")));
return false;
}
FilePath path = extension_root_.Append(path_suffix);
@@ -359,7 +413,10 @@ bool SandboxedExtensionUnpacker::RewriteImageFiles() {
// though they may originally be .jpg, etc. Figure something out.
// http://code.google.com/p/chromium/issues/detail?id=12459
if (!gfx::PNGCodec::EncodeBGRASkBitmap(image, false, &image_data)) {
- ReportFailure("Error re-encoding theme image.");
+ // Error re-encoding theme image.
+ ReportFailure(l10n_util::GetStringFUTF8(
+ IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
+ ASCIIToUTF16("ERROR_RE_ENCODING_THEME_IMAGE")));
return false;
}
@@ -367,7 +424,10 @@ bool SandboxedExtensionUnpacker::RewriteImageFiles() {
// so we can be sure the directory exists.
const char* image_data_ptr = reinterpret_cast<const char*>(&image_data[0]);
if (!file_util::WriteFile(path, image_data_ptr, image_data.size())) {
- ReportFailure("Error saving theme image.");
+ // Error saving theme image.
+ ReportFailure(l10n_util::GetStringFUTF8(
+ IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
+ ASCIIToUTF16("ERROR_SAVING_THEME_IMAGE")));
return false;
}
}
@@ -379,7 +439,10 @@ bool SandboxedExtensionUnpacker::RewriteCatalogFiles() {
DictionaryValue catalogs;
if (!ExtensionUnpacker::ReadMessageCatalogsFromFile(temp_dir_.path(),
&catalogs)) {
- ReportFailure("Could not read catalog data from disk.");
+ // Could not read catalog data from disk.
+ ReportFailure(l10n_util::GetStringFUTF8(
+ IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
+ ASCIIToUTF16("COULD_NOT_READ_CATALOG_DATA_FROM_DISK")));
return false;
}
@@ -388,7 +451,10 @@ bool SandboxedExtensionUnpacker::RewriteCatalogFiles() {
key_it != catalogs.end_keys(); ++key_it) {
DictionaryValue* catalog;
if (!catalogs.GetDictionaryWithoutPathExpansion(*key_it, &catalog)) {
- ReportFailure("Invalid catalog data.");
+ // Invalid catalog data.
+ ReportFailure(l10n_util::GetStringFUTF8(
+ IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
+ ASCIIToUTF16("INVALID_CATALOG_DATA")));
return false;
}
@@ -397,7 +463,10 @@ bool SandboxedExtensionUnpacker::RewriteCatalogFiles() {
FilePath relative_path = FilePath::FromWStringHack(UTF8ToWide(*key_it));
relative_path = relative_path.Append(Extension::kMessagesFilename);
if (relative_path.IsAbsolute() || relative_path.ReferencesParent()) {
- ReportFailure("Invalid path for catalog.");
+ // Invalid path for catalog.
+ ReportFailure(l10n_util::GetStringFUTF8(
+ IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
+ ASCIIToUTF16("INVALID_PATH_FOR_CATALOG")));
return false;
}
FilePath path = extension_root_.Append(relative_path);
@@ -406,7 +475,10 @@ bool SandboxedExtensionUnpacker::RewriteCatalogFiles() {
JSONStringValueSerializer serializer(&catalog_json);
serializer.set_pretty_print(true);
if (!serializer.Serialize(*catalog)) {
- ReportFailure("Error serializing catalog.");
+ // Error serializing catalog.
+ ReportFailure(l10n_util::GetStringFUTF8(
+ IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
+ ASCIIToUTF16("ERROR_SERIALIZING_CATALOG")));
return false;
}
@@ -415,7 +487,10 @@ bool SandboxedExtensionUnpacker::RewriteCatalogFiles() {
if (!file_util::WriteFile(path,
catalog_json.c_str(),
catalog_json.size())) {
- ReportFailure("Error saving catalog.");
+ // Error saving catalog.
+ ReportFailure(l10n_util::GetStringFUTF8(
+ IDS_EXTENSION_PACKAGE_INSTALL_ERROR,
+ ASCIIToUTF16("ERROR_SAVING_CATALOG")));
return false;
}
}
diff --git a/chrome/browser/extensions/sandboxed_extension_unpacker.h b/chrome/browser/extensions/sandboxed_extension_unpacker.h
index 8438482..e47b26c 100644
--- a/chrome/browser/extensions/sandboxed_extension_unpacker.h
+++ b/chrome/browser/extensions/sandboxed_extension_unpacker.h
@@ -122,9 +122,9 @@ class SandboxedExtensionUnpacker : public UtilityProcessHost::Client {
void StartProcessOnIOThread(const FilePath& temp_crx_path);
// SandboxedExtensionUnpacker
- void OnUnpackExtensionSucceeded(const DictionaryValue& manifest);
- void OnUnpackExtensionFailed(const std::string& error_message);
- void OnProcessCrashed();
+ virtual void OnUnpackExtensionSucceeded(const DictionaryValue& manifest);
+ virtual void OnUnpackExtensionFailed(const std::string& error_message);
+ virtual void OnProcessCrashed(int exit_code);
void ReportFailure(const std::string& message);
void ReportSuccess();
diff --git a/chrome/browser/extensions/stateful_external_extension_provider.cc b/chrome/browser/extensions/stateful_external_extension_provider.cc
index 63899da..fd1a42a 100644
--- a/chrome/browser/extensions/stateful_external_extension_provider.cc
+++ b/chrome/browser/extensions/stateful_external_extension_provider.cc
@@ -10,6 +10,7 @@
#include "base/path_service.h"
#include "base/values.h"
#include "base/version.h"
+#include "chrome/browser/browser_thread.h"
namespace {
@@ -27,19 +28,20 @@ StatefulExternalExtensionProvider::StatefulExternalExtensionProvider(
Extension::Location download_location)
: crx_location_(crx_location),
download_location_(download_location) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
}
StatefulExternalExtensionProvider::~StatefulExternalExtensionProvider() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
}
void StatefulExternalExtensionProvider::VisitRegisteredExtension(
- Visitor* visitor, const std::set<std::string>& ids_to_ignore) const {
+ Visitor* visitor) const {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ DCHECK(prefs_.get());
for (DictionaryValue::key_iterator i = prefs_->begin_keys();
i != prefs_->end_keys(); ++i) {
const std::string& extension_id = *i;
- if (ids_to_ignore.find(extension_id) != ids_to_ignore.end())
- continue;
-
DictionaryValue* extension;
if (!prefs_->GetDictionaryWithoutPathExpansion(extension_id, &extension))
continue;
@@ -123,12 +125,16 @@ void StatefulExternalExtensionProvider::VisitRegisteredExtension(
bool StatefulExternalExtensionProvider::HasExtension(
const std::string& id) const {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ DCHECK(prefs_.get());
return prefs_->HasKey(id);
}
bool StatefulExternalExtensionProvider::GetExtensionDetails(
const std::string& id, Extension::Location* location,
scoped_ptr<Version>* version) const {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ DCHECK(prefs_.get());
DictionaryValue* extension = NULL;
if (!prefs_->GetDictionary(id, &extension))
return false;
@@ -157,3 +163,7 @@ bool StatefulExternalExtensionProvider::GetExtensionDetails(
return true;
}
+
+void StatefulExternalExtensionProvider::set_prefs(DictionaryValue* prefs) {
+ prefs_.reset(prefs);
+}
diff --git a/chrome/browser/extensions/stateful_external_extension_provider.h b/chrome/browser/extensions/stateful_external_extension_provider.h
index 506873d..2fd481c 100644
--- a/chrome/browser/extensions/stateful_external_extension_provider.h
+++ b/chrome/browser/extensions/stateful_external_extension_provider.h
@@ -6,9 +6,6 @@
#define CHROME_BROWSER_EXTENSIONS_STATEFUL_EXTERNAL_EXTENSION_PROVIDER_H_
#pragma once
-#include <set>
-#include <string>
-
#include "chrome/browser/extensions/external_extension_provider.h"
class DictionaryValue;
@@ -23,6 +20,8 @@ class Version;
// This provider can provide external extensions from two sources: crx files
// and udpate URLs. The locations that the provider will report for these
// are specified at the constructor.
+// Instances of this class are expected to be created and destroyed on the UI
+// thread and they are expecting public method calls from the FILE thread.
class StatefulExternalExtensionProvider : public ExternalExtensionProvider {
public:
// Initialize the location for external extensions originating from crx
@@ -35,8 +34,7 @@ class StatefulExternalExtensionProvider : public ExternalExtensionProvider {
virtual ~StatefulExternalExtensionProvider();
// ExternalExtensionProvider implementation:
- virtual void VisitRegisteredExtension(
- Visitor* visitor, const std::set<std::string>& ids_to_ignore) const;
+ virtual void VisitRegisteredExtension(Visitor* visitor) const;
virtual bool HasExtension(const std::string& id) const;
@@ -50,6 +48,12 @@ class StatefulExternalExtensionProvider : public ExternalExtensionProvider {
// Location for external extensions that are provided by this provider from
// update URLs.
const Extension::Location download_location_;
+
+ // Stores the dictionary of external extensions internally. Takes ownership
+ // of |prefs|.
+ void set_prefs(DictionaryValue* prefs);
+
+ private:
// Dictionary of the external extensions that are provided by this provider.
scoped_ptr<DictionaryValue> prefs_;
};
diff --git a/chrome/browser/extensions/test_extension_prefs.cc b/chrome/browser/extensions/test_extension_prefs.cc
index 2cbb2d1..5b0ee7b 100644
--- a/chrome/browser/extensions/test_extension_prefs.cc
+++ b/chrome/browser/extensions/test_extension_prefs.cc
@@ -6,18 +6,46 @@
#include "base/file_util.h"
#include "base/message_loop.h"
+#include "base/message_loop_proxy.h"
#include "base/scoped_ptr.h"
#include "base/values.h"
#include "chrome/browser/browser_thread.h"
+#include "chrome/browser/extensions/extension_pref_store.h"
#include "chrome/browser/extensions/extension_prefs.h"
#include "chrome/browser/prefs/pref_service.h"
+#include "chrome/browser/prefs/pref_service_mock_builder.h"
#include "chrome/browser/prefs/pref_value_store.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/json_pref_store.h"
#include "testing/gtest/include/gtest/gtest.h"
-TestExtensionPrefs::TestExtensionPrefs() {
+namespace {
+
+// Mock ExtensionPrefs class with artificial clock to guarantee that no two
+// extensions get the same installation time stamp and we can reliably
+// assert the installation order in the tests below.
+class MockExtensionPrefs : public ExtensionPrefs {
+ public:
+ MockExtensionPrefs(PrefService* prefs,
+ const FilePath& root_dir_,
+ ExtensionPrefStore* pref_store)
+ : ExtensionPrefs(prefs, root_dir_, pref_store),
+ currentTime(base::Time::Now()) {}
+ ~MockExtensionPrefs() {}
+
+ protected:
+ mutable base::Time currentTime;
+
+ virtual base::Time GetCurrentTime() const {
+ currentTime += base::TimeDelta::FromSeconds(10);
+ return currentTime;
+ }
+};
+
+} // namespace
+
+TestExtensionPrefs::TestExtensionPrefs() : pref_service_(NULL) {
EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
preferences_file_ = temp_dir_.path().AppendASCII("Preferences");
extensions_dir_ = temp_dir_.path().AppendASCII("Extensions");
@@ -29,6 +57,9 @@ TestExtensionPrefs::TestExtensionPrefs() {
TestExtensionPrefs::~TestExtensionPrefs() {}
void TestExtensionPrefs::RecreateExtensionPrefs() {
+ // We persist and reload the PrefService's PrefStores because this process
+ // deletes all empty dictionaries. The ExtensionPrefs implementation
+ // needs to be able to handle this situation.
if (pref_service_.get()) {
// The PrefService writes its persistent file on the file thread, so we
// need to wait for any pending I/O to complete before creating a new
@@ -39,10 +70,14 @@ void TestExtensionPrefs::RecreateExtensionPrefs() {
file_loop.RunAllPending();
}
- // Create a |PrefService| instance that contains only user defined values.
- pref_service_.reset(PrefService::CreateUserPrefService(preferences_file_));
+ ExtensionPrefStore* pref_store = new ExtensionPrefStore;
+ PrefServiceMockBuilder builder;
+ builder.WithUserFilePrefs(preferences_file_);
+ builder.WithExtensionPrefs(pref_store);
+ pref_service_.reset(builder.Create());
ExtensionPrefs::RegisterUserPrefs(pref_service_.get());
- prefs_.reset(new ExtensionPrefs(pref_service_.get(), temp_dir_.path()));
+ prefs_.reset(new MockExtensionPrefs(pref_service_.get(), temp_dir_.path(),
+ pref_store));
}
scoped_refptr<Extension> TestExtensionPrefs::AddExtension(std::string name) {
diff --git a/chrome/browser/extensions/test_extension_prefs.h b/chrome/browser/extensions/test_extension_prefs.h
index cb723b2..3220d7a 100644
--- a/chrome/browser/extensions/test_extension_prefs.h
+++ b/chrome/browser/extensions/test_extension_prefs.h
@@ -16,7 +16,6 @@ class DictionaryValue;
class ExtensionPrefs;
class PrefService;
-
// This is a test class intended to make it easier to work with ExtensionPrefs
// in tests.
class TestExtensionPrefs {
diff --git a/chrome/browser/extensions/theme_installed_infobar_delegate.cc b/chrome/browser/extensions/theme_installed_infobar_delegate.cc
index 088e732..5f47084 100644
--- a/chrome/browser/extensions/theme_installed_infobar_delegate.cc
+++ b/chrome/browser/extensions/theme_installed_infobar_delegate.cc
@@ -9,8 +9,8 @@
#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "base/utf_string_conversions.h"
-#include "chrome/browser/extensions/extensions_service.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/themes/browser_theme_provider.h"
#include "chrome/common/extensions/extension.h"
@@ -75,7 +75,7 @@ string16 ThemeInstalledInfoBarDelegate::GetButtonLabel(
bool ThemeInstalledInfoBarDelegate::Cancel() {
if (!previous_theme_id_.empty()) {
- ExtensionsService* service = profile_->GetExtensionsService();
+ ExtensionService* service = profile_->GetExtensionService();
if (service) {
const Extension* previous_theme =
service->GetExtensionById(previous_theme_id_, true);
diff --git a/chrome/browser/extensions/user_script_listener.cc b/chrome/browser/extensions/user_script_listener.cc
index c553b1f..43965f0 100644
--- a/chrome/browser/extensions/user_script_listener.cc
+++ b/chrome/browser/extensions/user_script_listener.cc
@@ -5,8 +5,8 @@
#include "chrome/browser/extensions/user_script_listener.h"
#include "chrome/browser/browser_thread.h"
-#include "chrome/browser/extensions/extensions_service.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_host/global_request_id.h"
#include "chrome/browser/renderer_host/resource_dispatcher_host_request_info.h"
#include "chrome/common/extensions/extension.h"
@@ -34,7 +34,7 @@ void UserScriptListener::ShutdownMainThread() {
}
bool UserScriptListener::ShouldDelayRequest(
- URLRequest* request,
+ net::URLRequest* request,
const ResourceDispatcherHostRequestInfo& request_info,
const GlobalRequestID& request_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
@@ -136,14 +136,14 @@ void UserScriptListener::Observe(NotificationType type,
case NotificationType::EXTENSION_UNLOADED: {
const Extension* unloaded_extension =
- Details<const Extension>(details).ptr();
+ Details<UnloadedExtensionInfo>(details)->extension;
if (unloaded_extension->content_scripts().empty())
return; // no patterns to delete for this extension.
// Clear all our patterns and reregister all the still-loaded extensions.
URLPatterns new_patterns;
- ExtensionsService* service =
- Source<Profile>(source).ptr()->GetExtensionsService();
+ ExtensionService* service =
+ Source<Profile>(source).ptr()->GetExtensionService();
for (ExtensionList::const_iterator it = service->extensions()->begin();
it != service->extensions()->end(); ++it) {
if (*it != unloaded_extension)
diff --git a/chrome/browser/extensions/user_script_listener_unittest.cc b/chrome/browser/extensions/user_script_listener_unittest.cc
index ec13f9f..cd40fd5 100644
--- a/chrome/browser/extensions/user_script_listener_unittest.cc
+++ b/chrome/browser/extensions/user_script_listener_unittest.cc
@@ -4,7 +4,7 @@
#include "base/message_loop.h"
#include "base/thread.h"
-#include "chrome/browser/extensions/extensions_service_unittest.h"
+#include "chrome/browser/extensions/extension_service_unittest.h"
#include "chrome/browser/extensions/user_script_listener.h"
#include "chrome/browser/renderer_host/global_request_id.h"
#include "chrome/browser/renderer_host/resource_dispatcher_host_request_info.h"
@@ -90,35 +90,35 @@ ResourceDispatcherHostRequestInfo* CreateRequestInfo(int request_id) {
return new ResourceDispatcherHostRequestInfo(
new DummyResourceHandler(), ChildProcessInfo::RENDER_PROCESS, 0, 0,
request_id, "null", "null", ResourceType::MAIN_FRAME,
- 0, false, false, -1, -1);
+ 0, false, false, false, -1, -1);
}
-// A simple test URLRequestJob. We don't care what it does, only that whether it
-// starts and finishes.
+// A simple test net::URLRequestJob. We don't care what it does, only that
+// whether it starts and finishes.
class SimpleTestJob : public URLRequestTestJob {
public:
- explicit SimpleTestJob(URLRequest* request)
+ explicit SimpleTestJob(net::URLRequest* request)
: URLRequestTestJob(request, test_headers(), kTestData, true) {}
private:
~SimpleTestJob() {}
};
class UserScriptListenerTest
- : public ExtensionsServiceTestBase,
- public URLRequest::Interceptor {
+ : public ExtensionServiceTestBase,
+ public net::URLRequest::Interceptor {
public:
UserScriptListenerTest() {
- URLRequest::RegisterRequestInterceptor(this);
+ net::URLRequest::RegisterRequestInterceptor(this);
}
~UserScriptListenerTest() {
- URLRequest::UnregisterRequestInterceptor(this);
+ net::URLRequest::UnregisterRequestInterceptor(this);
}
virtual void SetUp() {
- ExtensionsServiceTestBase::SetUp();
+ ExtensionServiceTestBase::SetUp();
- InitializeEmptyExtensionsService();
+ InitializeEmptyExtensionService();
service_->Init();
MessageLoop::current()->RunAllPending();
@@ -135,13 +135,13 @@ class UserScriptListenerTest
MessageLoop::current()->RunAllPending();
}
- // URLRequest::Interceptor
- virtual URLRequestJob* MaybeIntercept(URLRequest* request) {
+ // net::URLRequest::Interceptor
+ virtual net::URLRequestJob* MaybeIntercept(net::URLRequest* request) {
return new SimpleTestJob(request);
}
protected:
- TestURLRequest* StartTestRequest(URLRequest::Delegate* delegate,
+ TestURLRequest* StartTestRequest(net::URLRequest::Delegate* delegate,
const std::string& url) {
TestURLRequest* request = new TestURLRequest(GURL(url), delegate);
scoped_ptr<ResourceDispatcherHostRequestInfo> rdh_info(
@@ -164,7 +164,8 @@ class UserScriptListenerTest
void UnloadTestExtension() {
ASSERT_FALSE(service_->extensions()->empty());
- service_->UnloadExtension(service_->extensions()->at(0)->id());
+ service_->UnloadExtension(service_->extensions()->at(0)->id(),
+ UnloadedExtensionInfo::DISABLE);
}
scoped_refptr<UserScriptListener> listener_;
diff --git a/chrome/browser/extensions/user_script_master.cc b/chrome/browser/extensions/user_script_master.cc
index 1712bb6..2af102e 100644
--- a/chrome/browser/extensions/user_script_master.cc
+++ b/chrome/browser/extensions/user_script_master.cc
@@ -15,9 +15,8 @@
#include "base/string_util.h"
#include "base/thread.h"
#include "base/version.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/extensions/extensions_service.h"
-#include "chrome/browser/profile.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_resource.h"
#include "chrome/common/notification_service.h"
@@ -340,9 +339,9 @@ void UserScriptMaster::Observe(NotificationType type,
case NotificationType::EXTENSION_LOADED: {
// Add any content scripts inside the extension.
const Extension* extension = Details<const Extension>(details).ptr();
- bool incognito_enabled = profile_->GetExtensionsService()->
+ bool incognito_enabled = profile_->GetExtensionService()->
IsIncognitoEnabled(extension);
- bool allow_file_access = profile_->GetExtensionsService()->
+ bool allow_file_access = profile_->GetExtensionService()->
AllowFileAccess(extension);
const UserScriptList& scripts = extension->content_scripts();
for (UserScriptList::const_iterator iter = scripts.begin();
@@ -357,7 +356,8 @@ void UserScriptMaster::Observe(NotificationType type,
}
case NotificationType::EXTENSION_UNLOADED: {
// Remove any content scripts.
- const Extension* extension = Details<const Extension>(details).ptr();
+ const Extension* extension =
+ Details<UnloadedExtensionInfo>(details)->extension;
UserScriptList new_lone_scripts;
for (UserScriptList::iterator iter = lone_scripts_.begin();
iter != lone_scripts_.end(); ++iter) {
@@ -375,9 +375,9 @@ void UserScriptMaster::Observe(NotificationType type,
case NotificationType::EXTENSION_USER_SCRIPTS_UPDATED: {
const Extension* extension = Details<const Extension>(details).ptr();
UserScriptList new_lone_scripts;
- bool incognito_enabled = profile_->GetExtensionsService()->
+ bool incognito_enabled = profile_->GetExtensionService()->
IsIncognitoEnabled(extension);
- bool allow_file_access = profile_->GetExtensionsService()->
+ bool allow_file_access = profile_->GetExtensionService()->
AllowFileAccess(extension);
for (UserScriptList::iterator iter = lone_scripts_.begin();
iter != lone_scripts_.end(); ++iter) {
diff --git a/chrome/browser/extensions/window_open_apitest.cc b/chrome/browser/extensions/window_open_apitest.cc
index 7fe20b9..567ccc7 100644
--- a/chrome/browser/extensions/window_open_apitest.cc
+++ b/chrome/browser/extensions/window_open_apitest.cc
@@ -4,14 +4,14 @@
#include "base/command_line.h"
#include "chrome/browser/extensions/extension_apitest.h"
-#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/ui_test_utils.h"
#include "net/base/mock_host_resolver.h"
-IN_PROC_BROWSER_TEST_F(ExtensionApiTest, WindowOpen) {
+// Disabled, http://crbug.com/64899.
+IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_WindowOpen) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableExperimentalExtensionApis);