summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-04 23:48:34 +0000
committeraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-04 23:48:34 +0000
commit1952c7d55e5f3cb5d7d75eeab965af32459d2b31 (patch)
treecc32dc77802bbd5b87031a7edb54c936f602d2da
parent495839a63f9516e20abbf0ab2258aa5d7dfa7180 (diff)
downloadchromium_src-1952c7d55e5f3cb5d7d75eeab965af32459d2b31.zip
chromium_src-1952c7d55e5f3cb5d7d75eeab965af32459d2b31.tar.gz
chromium_src-1952c7d55e5f3cb5d7d75eeab965af32459d2b31.tar.bz2
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
-rw-r--r--chrome/browser/browser_resources.grd3
-rw-r--r--chrome/browser/extensions/extension_apitest.cc24
-rw-r--r--chrome/browser/extensions/extension_prefs.cc14
-rw-r--r--chrome/browser/extensions/extension_updater.cc7
-rw-r--r--chrome/browser/extensions/extension_updater_unittest.cc1
-rw-r--r--chrome/browser/extensions/extensions_service.cc102
-rw-r--r--chrome/browser/extensions/extensions_service.h28
-rw-r--r--chrome/browser/extensions/extensions_service_unittest.cc39
-rw-r--r--chrome/browser/extensions/extensions_ui.cc24
-rw-r--r--chrome/browser/profile.cc19
-rw-r--r--chrome/browser/resources/bookmark_manager/manifest.json1
-rwxr-xr-xchrome/chrome.gyp83
-rw-r--r--chrome/common/chrome_paths.cc13
-rw-r--r--chrome/common/chrome_paths.h53
-rw-r--r--chrome/common/extensions/extension.cc58
-rw-r--r--chrome/common/extensions/extension.h22
-rw-r--r--chrome/common/extensions/extension_unittest.cc11
17 files changed, 384 insertions, 118 deletions
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 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- This comment is only here because changes to resources are not picked up
-without changes to the corresponding grd file. taaaag -->
+without changes to the corresponding grd file. aa1 -->
<grit latest_public_release="0" current_release="1">
<outputs>
<output filename="grit/browser_resources.h" type="rc_header">
@@ -42,6 +42,7 @@ without changes to the corresponding grd file. taaaag -->
<include name="IDR_FILEBROWSE_HTML" file="resources\filebrowse.html" flattenhtml="true" type="BINDATA" />
<include name="IDR_OS_CREDITS_HTML" file="resources\about_os_credits.html" flattenhtml="true" type="BINDATA" />
</if>
+ <include name="IDR_BOOKMARKS_MANIFEST" file="resources\bookmark_manager\manifest.json" type="BINDATA" />
<include name="IDR_DOWNLOADS_HTML" file="resources\downloads.html" flattenhtml="true" type="BINDATA" />
<include name="IDR_LOCAL_STRINGS_JS" file="resources\local_strings.js" type="BINDATA" />
<include name="IDR_DOM_UI_CSS" file="resources\dom_ui.css" flattenhtml="true" type="BINDATA" />
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<unsigned>(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<unsigned>(service->extensions()->size()));
+ return NULL;
+ }
+
+ found_extension_index = static_cast<int>(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<Extension::Location>(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<Extension::Location>(location_value);
-
extensions_info->push_back(linked_ptr<ExtensionInfo>(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<ExtensionsService>(this)));
}
+void ExtensionsService::LoadComponentExtensions() {
+ for (RegisteredComponentExtensions::iterator it =
+ component_extension_manifests_.begin();
+ it != component_extension_manifests_.end(); ++it) {
+ JSONStringValueSerializer serializer(it->manifest);
+ scoped_ptr<Value> manifest(serializer.Deserialize(NULL));
+ DCHECK(manifest.get());
+
+ scoped_ptr<Extension> extension(new Extension(it->root_directory));
+ extension->set_location(Extension::COMPONENT);
+
+ std::string error;
+ if (!extension->InitFromValue(
+ *static_cast<DictionaryValue*>(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<ExtensionPrefs::ExtensionsInfo> 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<ComponentExtensionInfo> 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<const std::string, GURL> 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<SkBitmap>* 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<int, std::string>& 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"));