From 1952c7d55e5f3cb5d7d75eeab965af32459d2b31 Mon Sep 17 00:00:00 2001 From: "aa@chromium.org" Date: Thu, 4 Mar 2010 23:48:34 +0000 Subject: Load the bookmark manager extension at Chrome startup. Review URL: http://codereview.chromium.org/660232 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@40683 0039d316-1c4b-4281-b951-d872f2087c98 --- chrome/browser/browser_resources.grd | 3 +- chrome/browser/extensions/extension_apitest.cc | 24 +++-- chrome/browser/extensions/extension_prefs.cc | 14 ++- chrome/browser/extensions/extension_updater.cc | 7 ++ .../extensions/extension_updater_unittest.cc | 1 + chrome/browser/extensions/extensions_service.cc | 102 ++++++++++++++------- chrome/browser/extensions/extensions_service.h | 28 ++++++ .../extensions/extensions_service_unittest.cc | 39 ++++++++ chrome/browser/extensions/extensions_ui.cc | 24 ++++- chrome/browser/profile.cc | 19 ++++ .../resources/bookmark_manager/manifest.json | 1 + chrome/chrome.gyp | 83 +++++++++++++++++ chrome/common/chrome_paths.cc | 13 ++- chrome/common/chrome_paths.h | 53 ++++++----- chrome/common/extensions/extension.cc | 58 +++++------- chrome/common/extensions/extension.h | 22 +++-- chrome/common/extensions/extension_unittest.cc | 11 +++ 17 files changed, 384 insertions(+), 118 deletions(-) (limited to 'chrome') diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index fb746ab..fd1886d 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd @@ -1,6 +1,6 @@ +without changes to the corresponding grd file. aa1 --> @@ -42,6 +42,7 @@ without changes to the corresponding grd file. taaaag --> + diff --git a/chrome/browser/extensions/extension_apitest.cc b/chrome/browser/extensions/extension_apitest.cc index e5a0768..a842c97 100644 --- a/chrome/browser/extensions/extension_apitest.cc +++ b/chrome/browser/extensions/extension_apitest.cc @@ -87,13 +87,25 @@ bool ExtensionApiTest::RunExtensionTest(const char* extension_name) { // Test that exactly one extension loaded. Extension* ExtensionApiTest::GetSingleLoadedExtension() { ExtensionsService* service = browser()->profile()->GetExtensionsService(); - if (service->extensions()->size() != 1u) { - message_ = StringPrintf( - "Expected only one extension to be present. Found %u.", - static_cast(service->extensions()->size())); - return NULL; + + int found_extension_index = -1; + for (size_t i = 0; i < service->extensions()->size(); ++i) { + // Ignore any component extensions. They are automatically loaded into all + // profiles and aren't the extension we're looking for here. + if (service->extensions()->at(i)->location() == Extension::COMPONENT) + continue; + + if (found_extension_index != -1) { + message_ = StringPrintf( + "Expected only one extension to be present. Found %u.", + static_cast(service->extensions()->size())); + return NULL; + } + + found_extension_index = static_cast(i); } - Extension* extension = service->extensions()->at(0); + + Extension* extension = service->extensions()->at(found_extension_index); if (!extension) { message_ = "extension pointer is NULL."; return NULL; diff --git a/chrome/browser/extensions/extension_prefs.cc b/chrome/browser/extensions/extension_prefs.cc index 3aeda24..388172d 100644 --- a/chrome/browser/extensions/extension_prefs.cc +++ b/chrome/browser/extensions/extension_prefs.cc @@ -538,15 +538,23 @@ ExtensionPrefs::ExtensionsInfo* ExtensionPrefs::CollectExtensionsInfo( NOTREACHED(); continue; } + + // Only internal and external extensions can be installed permanently in the + // preferences. + Extension::Location location = + static_cast(location_value); + if (location != Extension::INTERNAL && + !Extension::IsExternalLocation(location)) { + NOTREACHED(); + continue; + } + DictionaryValue* manifest = NULL; if (!ext->GetDictionary(kPrefManifest, &manifest)) { LOG(WARNING) << "Missing manifest for extension " << *extension_id; // Just a warning for now. } - Extension::Location location = - static_cast(location_value); - extensions_info->push_back(linked_ptr(new ExtensionInfo( manifest, WideToASCII(*extension_id), FilePath(path), location))); } diff --git a/chrome/browser/extensions/extension_updater.cc b/chrome/browser/extensions/extension_updater.cc index 8480ac2..96e4282 100644 --- a/chrome/browser/extensions/extension_updater.cc +++ b/chrome/browser/extensions/extension_updater.cc @@ -553,6 +553,13 @@ void ExtensionUpdater::CheckNow() { for (ExtensionList::const_iterator iter = extensions->begin(); iter != extensions->end(); ++iter) { Extension* extension = (*iter); + + // Only internal and external extensions can be autoupdated. + if (extension->location() != Extension::INTERNAL && + !Extension::IsExternalLocation(extension->location())) { + continue; + } + const GURL& update_url = extension->update_url(); // Collect histogram data and skip extensions with no update url. diff --git a/chrome/browser/extensions/extension_updater_unittest.cc b/chrome/browser/extensions/extension_updater_unittest.cc index bc28387..3f89d07 100644 --- a/chrome/browser/extensions/extension_updater_unittest.cc +++ b/chrome/browser/extensions/extension_updater_unittest.cc @@ -126,6 +126,7 @@ void CreateTestExtensions(int count, ExtensionList *list, FilePath path(StringPrintf("/extension%i", i)); #endif Extension* e = new Extension(path); + e->set_location(Extension::INTERNAL); input.SetString(extension_manifest_keys::kVersion, StringPrintf("%d.0.0.0", i)); input.SetString(extension_manifest_keys::kName, diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc index 77f7f48..e94d9bd 100644 --- a/chrome/browser/extensions/extensions_service.cc +++ b/chrome/browser/extensions/extensions_service.cc @@ -38,6 +38,7 @@ #include "chrome/common/extensions/extension_l10n_util.h" #include "chrome/common/notification_service.h" #include "chrome/common/notification_type.h" +#include "chrome/common/json_value_serializer.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" #include "webkit/database/database_tracker.h" @@ -321,9 +322,37 @@ void ExtensionsService::LoadExtension(const FilePath& extension_path) { extension_path, scoped_refptr(this))); } +void ExtensionsService::LoadComponentExtensions() { + for (RegisteredComponentExtensions::iterator it = + component_extension_manifests_.begin(); + it != component_extension_manifests_.end(); ++it) { + JSONStringValueSerializer serializer(it->manifest); + scoped_ptr manifest(serializer.Deserialize(NULL)); + DCHECK(manifest.get()); + + scoped_ptr extension(new Extension(it->root_directory)); + extension->set_location(Extension::COMPONENT); + + std::string error; + if (!extension->InitFromValue( + *static_cast(manifest.get()), + true, // require key + &error)) { + NOTREACHED(); + return; + } + + OnExtensionLoaded(extension.release(), false); // Don't allow privilege + // increase. + } +} + void ExtensionsService::LoadAllExtensions() { base::TimeTicks start_time = base::TimeTicks::Now(); + // Load any component extensions. + LoadComponentExtensions(); + // Load the previously installed extensions. scoped_ptr info( ExtensionPrefs::CollectExtensionsInfo(extension_prefs_.get())); @@ -363,43 +392,46 @@ void ExtensionsService::ContinueLoadAllExtensions( UMA_HISTOGRAM_COUNTS_100("Extensions.LoadAll", extensions_.size()); UMA_HISTOGRAM_COUNTS_100("Extensions.Disabled", disabled_extensions_.size()); - if (extensions_.size()) { - UMA_HISTOGRAM_TIMES("Extensions.LoadAllTime", - base::TimeTicks::Now() - start_time); - - int user_script_count = 0; - int extension_count = 0; - int theme_count = 0; - int external_count = 0; - int page_action_count = 0; - int browser_action_count = 0; - ExtensionList::iterator ex; - for (ex = extensions_.begin(); ex != extensions_.end(); ++ex) { - if ((*ex)->IsTheme()) { - theme_count++; - } else if ((*ex)->converted_from_user_script()) { - user_script_count++; - } else { - extension_count++; - } - if (Extension::IsExternalLocation((*ex)->location())) { - external_count++; - } - if ((*ex)->page_action() != NULL) { - page_action_count++; - } - if ((*ex)->browser_action() != NULL) { - browser_action_count++; - } + UMA_HISTOGRAM_TIMES("Extensions.LoadAllTime", + base::TimeTicks::Now() - start_time); + + int user_script_count = 0; + int extension_count = 0; + int theme_count = 0; + int external_count = 0; + int page_action_count = 0; + int browser_action_count = 0; + ExtensionList::iterator ex; + for (ex = extensions_.begin(); ex != extensions_.end(); ++ex) { + // Don't count component extensions, since they are only extensions as an + // implementation detail. + if ((*ex)->location() == Extension::COMPONENT) + continue; + + if ((*ex)->IsTheme()) { + theme_count++; + } else if ((*ex)->converted_from_user_script()) { + user_script_count++; + } else { + extension_count++; + } + if (Extension::IsExternalLocation((*ex)->location())) { + external_count++; + } + if ((*ex)->page_action() != NULL) { + page_action_count++; + } + if ((*ex)->browser_action() != NULL) { + browser_action_count++; } - UMA_HISTOGRAM_COUNTS_100("Extensions.LoadExtension", extension_count); - UMA_HISTOGRAM_COUNTS_100("Extensions.LoadUserScript", user_script_count); - UMA_HISTOGRAM_COUNTS_100("Extensions.LoadTheme", theme_count); - UMA_HISTOGRAM_COUNTS_100("Extensions.LoadExternal", external_count); - UMA_HISTOGRAM_COUNTS_100("Extensions.LoadPageAction", page_action_count); - UMA_HISTOGRAM_COUNTS_100("Extensions.LoadBrowserAction", - browser_action_count); } + UMA_HISTOGRAM_COUNTS_100("Extensions.LoadExtension", extension_count); + UMA_HISTOGRAM_COUNTS_100("Extensions.LoadUserScript", user_script_count); + UMA_HISTOGRAM_COUNTS_100("Extensions.LoadTheme", theme_count); + UMA_HISTOGRAM_COUNTS_100("Extensions.LoadExternal", external_count); + UMA_HISTOGRAM_COUNTS_100("Extensions.LoadPageAction", page_action_count); + UMA_HISTOGRAM_COUNTS_100("Extensions.LoadBrowserAction", + browser_action_count); } void ExtensionsService::LoadInstalledExtension(const ExtensionInfo& info, diff --git a/chrome/browser/extensions/extensions_service.h b/chrome/browser/extensions/extensions_service.h index a95d0aa..6501824 100644 --- a/chrome/browser/extensions/extensions_service.h +++ b/chrome/browser/extensions/extensions_service.h @@ -66,6 +66,22 @@ class ExtensionsService public ExtensionUpdateService, public NotificationObserver { public: + // Information about a registered component extension. + struct ComponentExtensionInfo { + ComponentExtensionInfo(const std::string& manifest, + const FilePath& root_directory) + : manifest(manifest), + root_directory(root_directory) { + } + + // The extension's manifest. This is required for component extensions so + // that ExtensionsService doesn't need to go to disk to load them. + std::string manifest; + + // Directory where the extension is stored. + FilePath root_directory; + }; + // The name of the directory inside the profile where extensions are // installed to. static const char* kInstallDirectoryName; @@ -97,6 +113,11 @@ class ExtensionsService return &disabled_extensions_; } + // Registers an extension to be loaded as a component extension. + void register_component_extension(const ComponentExtensionInfo& info) { + component_extension_manifests_.push_back(info); + } + // Returns true if any extensions are installed. virtual bool HasInstalledExtensions() { return !(extensions_.empty() && disabled_extensions_.empty()); @@ -155,6 +176,9 @@ class ExtensionsService // Load the extension from the directory |extension_path|. void LoadExtension(const FilePath& extension_path); + // Load any component extensions. + void LoadComponentExtensions(); + // Load all known extensions (used by startup and testing code). void LoadAllExtensions(); @@ -330,6 +354,10 @@ class ExtensionsService NotificationRegistrar registrar_; + // List of registered component extensions (see Extension::Location). + typedef std::vector RegisteredComponentExtensions; + RegisteredComponentExtensions component_extension_manifests_; + DISALLOW_COPY_AND_ASSIGN(ExtensionsService); }; diff --git a/chrome/browser/extensions/extensions_service_unittest.cc b/chrome/browser/extensions/extensions_service_unittest.cc index b2ea08a..eb2520a 100644 --- a/chrome/browser/extensions/extensions_service_unittest.cc +++ b/chrome/browser/extensions/extensions_service_unittest.cc @@ -1684,3 +1684,42 @@ TEST_F(ExtensionsServiceTest, StorageQuota) { EXPECT_EQ(profile_->GetDatabaseTracker()->GetDefaultQuota(), limited_quota); EXPECT_EQ(kint64max, unlimited_quota); } + +// Tests ExtensionsService::register_component_extension(). +TEST_F(ExtensionsServiceTest, ComponentExtensions) { + InitializeEmptyExtensionsService(); + + FilePath path; + ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path)); + path = path.AppendASCII("extensions") + .AppendASCII("good") + .AppendASCII("Extensions") + .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj") + .AppendASCII("1.0.0.0"); + + std::string manifest; + ASSERT_TRUE(file_util::ReadFileToString( + path.Append(Extension::kManifestFilename), &manifest)); + + service_->register_component_extension( + ExtensionsService::ComponentExtensionInfo(manifest, path)); + service_->Init(); + + // Note that we do not pump messages -- the extension should be loaded + // immediately. + + EXPECT_EQ(0u, GetErrors().size()); + ASSERT_EQ(1u, loaded_.size()); + EXPECT_EQ(Extension::COMPONENT, loaded_[0]->location()); + EXPECT_EQ(1u, service_->extensions()->size()); + + // Component extensions shouldn't get recourded in the prefs. + ValidatePrefKeyCount(0); + + // Reload all extensions, and make sure it comes back. + std::string extension_id = service_->extensions()->at(0)->id(); + loaded_.clear(); + service_->ReloadExtensions(); + ASSERT_EQ(1u, service_->extensions()->size()); + EXPECT_EQ(extension_id, service_->extensions()->at(0)->id()); +} diff --git a/chrome/browser/extensions/extensions_ui.cc b/chrome/browser/extensions/extensions_ui.cc index d1dfb9c..cc1224d 100644 --- a/chrome/browser/extensions/extensions_ui.cc +++ b/chrome/browser/extensions/extensions_ui.cc @@ -48,6 +48,24 @@ #include "net/base/net_util.h" #include "webkit/glue/image_decoder.h" +namespace { + +static bool ShouldShowExtension(Extension* extension) { + // Don't show the themes since this page's UI isn't really useful for + // themes. + if (extension->IsTheme()) + return false; + + // Don't show component extensions because they are only extensions as an + // implementation detail of Chrome. + if (extension->location() == Extension::COMPONENT) + return false; + + return true; +} + +} + //////////////////////////////////////////////////////////////////////////////// // // ExtensionsHTMLSource @@ -289,9 +307,7 @@ void ExtensionsDOMHandler::HandleRequestExtensionsData(const Value* value) { const ExtensionList* extensions = extensions_service_->extensions(); for (ExtensionList::const_iterator extension = extensions->begin(); extension != extensions->end(); ++extension) { - // Don't show the themes since this page's UI isn't really useful for - // themes. - if (!(*extension)->IsTheme()) { + if (ShouldShowExtension(*extension)) { extensions_list->Append(CreateExtensionDetailValue( extensions_service_.get(), *extension, GetActivePagesForExtension((*extension)->id()), true)); @@ -301,7 +317,7 @@ void ExtensionsDOMHandler::HandleRequestExtensionsData(const Value* value) { extensions = extensions_service_->disabled_extensions(); for (ExtensionList::const_iterator extension = extensions->begin(); extension != extensions->end(); ++extension) { - if (!(*extension)->IsTheme()) { + if (ShouldShowExtension(*extension)) { extensions_list->Append(CreateExtensionDetailValue( extensions_service_.get(), *extension, GetActivePagesForExtension((*extension)->id()), false)); diff --git a/chrome/browser/profile.cc b/chrome/browser/profile.cc index 6a3bd8c..1e248e2 100644 --- a/chrome/browser/profile.cc +++ b/chrome/browser/profile.cc @@ -4,6 +4,7 @@ #include "chrome/browser/profile.h" +#include "app/resource_bundle.h" #include "app/theme_provider.h" #include "base/command_line.h" #include "base/file_path.h" @@ -60,6 +61,7 @@ #include "chrome/common/notification_service.h" #include "chrome/common/pref_names.h" #include "chrome/common/render_messages.h" +#include "grit/browser_resources.h" #include "grit/locale_settings.h" #include "net/base/transport_security_state.h" #include "webkit/database/database_tracker.h" @@ -660,6 +662,23 @@ void ProfileImpl::InitExtensions() { GetPath().AppendASCII(ExtensionsService::kInstallDirectoryName), true); + // Register the bookmark manager extension. + if (CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableTabbedBookmarkManager)) { + FilePath bookmark_manager_path; + if (PathService::Get(chrome::DIR_BOOKMARK_MANAGER, + &bookmark_manager_path)) { + std::string manifest = + ResourceBundle::GetSharedInstance().GetRawDataResource( + IDR_BOOKMARKS_MANIFEST).as_string(); + extensions_service_->register_component_extension( + ExtensionsService::ComponentExtensionInfo(manifest, + bookmark_manager_path)); + } else { + NOTREACHED(); + } + } + extensions_service_->Init(); // Load any extensions specified with --load-extension. diff --git a/chrome/browser/resources/bookmark_manager/manifest.json b/chrome/browser/resources/bookmark_manager/manifest.json index 9ebe6f4..aeb0afd 100644 --- a/chrome/browser/resources/bookmark_manager/manifest.json +++ b/chrome/browser/resources/bookmark_manager/manifest.json @@ -1,4 +1,5 @@ { + "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCfHy1M+jghaHyaVAILzx/c/Dy+RXtcaP9/5pC7EY8JlNEI/G4DIIng9IzlrH8UWStpMWMyGUsdyusn2PkYFrqfVzhc2azVF3PX9D0KHG3FLN3mNoz1YTBHvO5QSXJf292qW0tTYuoGqeTfXtF9odLdg20Xd0YrLmtS4TQkpSYGDwIDAQAB", "name": "Bookmark Manager", "version": "0.1", "description": "Bookmark Manager", diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index 7efea0c..f6b8fd6 100755 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -415,6 +415,89 @@ ], }, { + 'target_name': 'component_extensions', + 'type': 'none', + 'msvs_guid': '50B52703-525F-404C-BFE2-C46D3375D73E', + # TODO(aa): Once the linux port supports it, change this to recursively + # copy the entire directory instead of listing the files. + # http://crbug.com/37340. + 'copies': [ + { + 'destination': '<(PRODUCT_DIR)/resources/bookmark_manager', + 'files': [ + 'browser/resources/bookmark_manager/main.html', + 'browser/resources/bookmark_manager/manifest.json', + ] + }, + { + 'destination': '<(PRODUCT_DIR)/resources/bookmark_manager/css', + 'files': [ + 'browser/resources/bookmark_manager/css/bmm.css', + 'browser/resources/bookmark_manager/css/bmm.css.js', + 'browser/resources/bookmark_manager/css/list.css', + 'browser/resources/bookmark_manager/css/menu.css', + 'browser/resources/bookmark_manager/css/tree.css', + 'browser/resources/bookmark_manager/css/tree.css.js', + ] + }, + { + 'destination': '<(PRODUCT_DIR)/resources/bookmark_manager/js', + 'files': [ + 'browser/resources/bookmark_manager/js/bmm.js', + 'browser/resources/bookmark_manager/js/cr.js', + 'browser/resources/bookmark_manager/js/i18ntemplate.js', + 'browser/resources/bookmark_manager/js/localstrings.js', + 'browser/resources/bookmark_manager/js/util.js', + ] + }, + { + 'destination': '<(PRODUCT_DIR)/resources/bookmark_manager/js/cr', + 'files': [ + 'browser/resources/bookmark_manager/js/cr/event.js', + 'browser/resources/bookmark_manager/js/cr/eventtarget.js', + 'browser/resources/bookmark_manager/js/cr/promise.js', + 'browser/resources/bookmark_manager/js/cr/ui.js', + ] + }, + { + 'destination': '<(PRODUCT_DIR)/resources/bookmark_manager/js/cr/ui', + 'files': [ + 'browser/resources/bookmark_manager/js/cr/ui/menuitem.js', + 'browser/resources/bookmark_manager/js/cr/ui/command.js', + 'browser/resources/bookmark_manager/js/cr/ui/menubutton.js', + 'browser/resources/bookmark_manager/js/cr/ui/list.js', + 'browser/resources/bookmark_manager/js/cr/ui/tree.js', + 'browser/resources/bookmark_manager/js/cr/ui/listselectionmodel.js', + 'browser/resources/bookmark_manager/js/cr/ui/menu.js', + 'browser/resources/bookmark_manager/js/cr/ui/listitem.js', + 'browser/resources/bookmark_manager/js/cr/ui/contextmenuhandler.js', + ] + }, + { + 'destination': '<(PRODUCT_DIR)/resources/bookmark_manager/js/bmm', + 'files': [ + 'browser/resources/bookmark_manager/js/bmm/bookmarklist.js', + 'browser/resources/bookmark_manager/js/bmm/bookmarktree.js', + 'browser/resources/bookmark_manager/js/bmm/treeiterator.js', + ] + }, + { + 'destination': '<(PRODUCT_DIR)/resources/bookmark_manager/images', + 'files': [ + 'browser/resources/bookmark_manager/images/folder_open_rtl.png', + 'browser/resources/bookmark_manager/images/folder_open.png', + 'browser/resources/bookmark_manager/images/bookmark_manager_recent.png', + 'browser/resources/bookmark_manager/images/bookmark_bar_folder_mac.png', + 'browser/resources/bookmark_manager/images/bookmarks_favicon.png', + 'browser/resources/bookmark_manager/images/bookmarks_section.png', + 'browser/resources/bookmark_manager/images/folder_closed.png', + 'browser/resources/bookmark_manager/images/bookmark_manager_search.png', + 'browser/resources/bookmark_manager/images/folder_closed_rtl.png', + ] + }, + ] + }, + { 'target_name': 'debugger', 'type': '<(library)', 'msvs_guid': '57823D8C-A317-4713-9125-2C91FDFD12D6', diff --git a/chrome/common/chrome_paths.cc b/chrome/common/chrome_paths.cc index d423507..58e8f68 100644 --- a/chrome/common/chrome_paths.cc +++ b/chrome/common/chrome_paths.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2006-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. @@ -111,7 +111,7 @@ bool PathProvider(int key, FilePath* result) { if (!GetUserDesktop(&cur)) return false; break; - case chrome::DIR_INSPECTOR: + case chrome::DIR_RESOURCES: #if defined(OS_MACOSX) cur = mac_util::MainAppBundlePath(); cur = cur.Append(FILE_PATH_LITERAL("Resources")); @@ -120,6 +120,15 @@ bool PathProvider(int key, FilePath* result) { return false; cur = cur.Append(FILE_PATH_LITERAL("resources")); #endif + break; + case chrome::DIR_BOOKMARK_MANAGER: + if (!PathService::Get(chrome::DIR_RESOURCES, &cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("bookmark_manager")); + break; + case chrome::DIR_INSPECTOR: + if (!PathService::Get(chrome::DIR_RESOURCES, &cur)) + return false; cur = cur.Append(FILE_PATH_LITERAL("inspector")); break; case chrome::DIR_APP_DICTIONARIES: diff --git a/chrome/common/chrome_paths.h b/chrome/common/chrome_paths.h index 3b0521b..2bfaeea 100644 --- a/chrome/common/chrome_paths.h +++ b/chrome/common/chrome_paths.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2006-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. @@ -15,38 +15,41 @@ namespace chrome { enum { PATH_START = 1000, - DIR_APP = PATH_START, // directory where dlls and data reside - DIR_LOGS, // directory where logs should be written - DIR_USER_DATA, // directory where user data can be written - DIR_CRASH_DUMPS, // directory where crash dumps are written - DIR_USER_DESKTOP, // directory that correspond to the desktop - DIR_INSPECTOR, // directory where web inspector is located - DIR_APP_DICTIONARIES, // directory where the global dictionaries are - DIR_USER_DOCUMENTS, // directory for a user's "My Documents" - DIR_DEFAULT_DOWNLOADS_SAFE, // directory for a user's - // "My Documents/Downloads" - DIR_DEFAULT_DOWNLOADS, // directory for a user's downloads - FILE_RESOURCE_MODULE, // full path and filename of the module that + DIR_APP = PATH_START, // Directory where dlls and data reside. + DIR_LOGS, // Directory where logs should be written. + DIR_USER_DATA, // Directory where user data can be written. + DIR_CRASH_DUMPS, // Directory where crash dumps are written. + DIR_USER_DESKTOP, // Directory that correspond to the desktop. + DIR_RESOURCES, // Directory containing separate file resources + // used by Chrome at runtime. + DIR_BOOKMARK_MANAGER, // Directory containing the bookmark manager. + DIR_INSPECTOR, // Directory where web inspector is located. + DIR_APP_DICTIONARIES, // Directory where the global dictionaries are. + DIR_USER_DOCUMENTS, // Directory for a user's "My Documents". + DIR_DEFAULT_DOWNLOADS_SAFE, // Directory for a user's + // "My Documents/Downloads". + DIR_DEFAULT_DOWNLOADS, // Directory for a user's downloads. + FILE_RESOURCE_MODULE, // Full path and filename of the module that // contains embedded resources (version, - // strings, images, etc.) - FILE_LOCAL_STATE, // path and filename to the file in which - // machine/installation-specific state is saved - FILE_RECORDED_SCRIPT, // full path to the script.log file that - // contains recorded browser events for playback - FILE_GEARS_PLUGIN, // full path to the gears.dll plugin file. - FILE_LIBAVCODEC, // full path to libavcodec media decoding + // strings, images, etc.). + FILE_LOCAL_STATE, // Path and filename to the file in which + // machine/installation-specific state is saved. + FILE_RECORDED_SCRIPT, // Full path to the script.log file that + // contains recorded browser events for playback. + FILE_GEARS_PLUGIN, // Full path to the gears.dll plugin file. + FILE_LIBAVCODEC, // Full path to libavcodec media decoding // library. - FILE_LIBAVFORMAT, // full path to libavformat media parsing + FILE_LIBAVFORMAT, // Full path to libavformat media parsing // library. - FILE_LIBAVUTIL, // full path to libavutil media utility library. + FILE_LIBAVUTIL, // Full path to libavutil media utility library. #if defined(OS_CHROMEOS) - FILE_CHROMEOS_API, // full path to chrome os api shared object. + FILE_CHROMEOS_API, // Full path to chrome os api shared object. #endif // Valid only in development environment; TODO(darin): move these - DIR_TEST_DATA, // directory where unit test data resides - DIR_TEST_TOOLS, // directory where unit test tools reside + DIR_TEST_DATA, // Directory where unit test data resides. + DIR_TEST_TOOLS, // Directory where unit test tools reside. PATH_END }; diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc index 0130929..4436b72 100644 --- a/chrome/common/extensions/extension.cc +++ b/chrome/common/extensions/extension.cc @@ -58,25 +58,6 @@ static void ConvertHexadecimalToIDAlphabet(std::string* id) { (*id)[i] = HexStringToInt(id->substr(i, 1)) + 'a'; } -// Returns true if the given string is an API permission (see kPermissionNames). -static bool IsAPIPermission(const std::string& str) { - for (size_t i = 0; i < Extension::kNumPermissions; ++i) { - if (str == Extension::kPermissionNames[i]) { - if (str == Extension::kExperimentalPermission && - !CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableExperimentalExtensionApis) && - // TODO(arv): Tighten this so that not all extensions can access the - // experimental APIs. - !CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableTabbedBookmarkManager)) { - return false; - } - return true; - } - } - return false; -} - } // namespace const FilePath::CharType Extension::kManifestFilename[] = @@ -177,19 +158,6 @@ GURL Extension::GetResourceURL(const GURL& extension_url, return ret_val; } -Extension::Location Extension::ExternalExtensionInstallType( - std::string registry_path) { -#if defined(OS_WIN) - HKEY reg_root = HKEY_LOCAL_MACHINE; - RegKey key; - registry_path.append("\\"); - registry_path.append(id_); - if (key.Open(reg_root, ASCIIToWide(registry_path).c_str())) - return Extension::EXTERNAL_REGISTRY; -#endif - return Extension::EXTERNAL_PREF; -} - bool Extension::GenerateId(const std::string& input, std::string* output) { CHECK(output); if (input.length() == 0) @@ -788,7 +756,7 @@ void Extension::DecodeIconFromPath(const FilePath& icon_path, result->swap(decoded); } -bool Extension::InitFromValue(const DictionaryValue& source, bool require_id, +bool Extension::InitFromValue(const DictionaryValue& source, bool require_key, std::string* error) { if (source.HasKey(keys::kPublicKey)) { std::string public_key_bytes; @@ -798,7 +766,7 @@ bool Extension::InitFromValue(const DictionaryValue& source, bool require_id, *error = errors::kInvalidKey; return false; } - } else if (require_id) { + } else if (require_key) { *error = errors::kInvalidKey; return false; } else { @@ -1447,3 +1415,25 @@ bool Extension::HasAccessToAllHosts() const { return false; } + +bool Extension::IsAPIPermission(const std::string& str) { + for (size_t i = 0; i < Extension::kNumPermissions; ++i) { + if (str == Extension::kPermissionNames[i]) { + // Only allow the experimental API permission if the command line + // flag is present, or if the extension is a component of Chrome. + if (str == Extension::kExperimentalPermission) { + if (CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableExperimentalExtensionApis)) { + return true; + } else if (location() == Extension::COMPONENT) { + return true; + } else { + return false; + } + } else { + return true; + } + } + } + return false; +} diff --git a/chrome/common/extensions/extension.h b/chrome/common/extensions/extension.h index 88d093f..78e75a6 100644 --- a/chrome/common/extensions/extension.h +++ b/chrome/common/extensions/extension.h @@ -28,13 +28,18 @@ class Extension { typedef std::map URLOverrideMap; // What an extension was loaded from. + // NOTE: These values are stored as integers in the preferences, so you + // really don't want to change any existing ones. enum Location { INVALID, INTERNAL, // A crx file from the internal Extensions directory. EXTERNAL_PREF, // A crx file from an external directory (via prefs). EXTERNAL_REGISTRY, // A crx file from an external directory (via eg the // registry on Windows). - LOAD // --load-extension. + LOAD, // --load-extension. + COMPONENT // An integral component of Chrome itself, which happens + // to be implemented as an extension. We don't show + // these in the management UI. }; enum State { @@ -188,9 +193,10 @@ class Extension { scoped_ptr* result); // Initialize the extension from a parsed manifest. - // If |require_id| is true, will return an error if the "id" key is missing - // from the value. - bool InitFromValue(const DictionaryValue& value, bool require_id, + // Usually, the id of an extension is generated by the "key" property of + // its manifest, but if |require_key| is |false|, a temporary ID will be + // generated based on the path. + bool InitFromValue(const DictionaryValue& value, bool require_key, std::string* error); const FilePath& path() const { return path_; } @@ -247,10 +253,6 @@ class Extension { const GURL& update_url() const { return update_url_; } const std::map& icons() const { return icons_; } - // Returns the origin of this extension. This function takes a |registry_path| - // so that the registry location can be overwritten during testing. - Location ExternalExtensionInstallType(std::string registry_path); - // Theme-related. DictionaryValue* GetThemeImages() const { return theme_images_.get(); } DictionaryValue* GetThemeColors() const { return theme_colors_.get(); } @@ -334,6 +336,10 @@ class Extension { // Helper method to verify the app section of the manifest. bool LoadAppHelper(const DictionaryValue* app, std::string* error); + // Returns true if the string is one of the known api permissions (see + // kPermissionNames). + bool IsAPIPermission(const std::string& permission); + // The absolute path to the directory the extension is stored in. FilePath path_; diff --git a/chrome/common/extensions/extension_unittest.cc b/chrome/common/extensions/extension_unittest.cc index d0d1f89..29ba032e 100644 --- a/chrome/common/extensions/extension_unittest.cc +++ b/chrome/common/extensions/extension_unittest.cc @@ -25,6 +25,17 @@ namespace errors = extension_manifest_errors; class ExtensionTest : public testing::Test { }; +// We persist location values in the preferences, so this is a sanity test that +// someone doesn't accidentally change them. +TEST(ExtensionTest, LocationValuesTest) { + ASSERT_EQ(0, Extension::INVALID); + ASSERT_EQ(1, Extension::INTERNAL); + ASSERT_EQ(2, Extension::EXTERNAL_PREF); + ASSERT_EQ(3, Extension::EXTERNAL_REGISTRY); + ASSERT_EQ(4, Extension::LOAD); + ASSERT_EQ(5, Extension::COMPONENT); +} + TEST(ExtensionTest, InitFromValueInvalid) { #if defined(OS_WIN) FilePath path(FILE_PATH_LITERAL("c:\\foo")); -- cgit v1.1