summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorphajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-24 09:54:13 +0000
committerphajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-24 09:54:13 +0000
commit7c927b60bffa117129ba9214fcb6174d753351d9 (patch)
tree785de404571d36e57c8c9b916426805fc43ee476 /chrome/browser
parentaf2ae52b8f5ec53e1ba1b4593368cd66f59c3a4d (diff)
downloadchromium_src-7c927b60bffa117129ba9214fcb6174d753351d9.zip
chromium_src-7c927b60bffa117129ba9214fcb6174d753351d9.tar.gz
chromium_src-7c927b60bffa117129ba9214fcb6174d753351d9.tar.bz2
Further reduce the bad dependency of chrome/common on chrome/browser.
TEST=none BUG=none Review URL: http://codereview.chromium.org/656011 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@39877 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/browser_about_handler.cc2
-rw-r--r--chrome/browser/browser_main.cc2
-rw-r--r--chrome/browser/extensions/crx_installer.cc2
-rw-r--r--chrome/browser/extensions/extension_creator.cc2
-rw-r--r--chrome/browser/extensions/extension_disabled_infobar_delegate.cc2
-rw-r--r--chrome/browser/extensions/extension_file_util.cc523
-rw-r--r--chrome/browser/extensions/extension_file_util.h108
-rw-r--r--chrome/browser/extensions/extension_file_util_unittest.cc258
-rw-r--r--chrome/browser/extensions/extension_protocols.cc2
-rw-r--r--chrome/browser/extensions/extensions_service.cc2
-rw-r--r--chrome/browser/extensions/sandboxed_extension_unpacker.cc4
-rw-r--r--chrome/browser/extensions/user_script_listener_unittest.cc2
-rw-r--r--chrome/browser/metrics/histogram_synchronizer.cc278
-rw-r--r--chrome/browser/metrics/histogram_synchronizer.h145
-rw-r--r--chrome/browser/metrics/metrics_service.cc2
-rw-r--r--chrome/browser/renderer_host/buffered_resource_handler.cc1
-rw-r--r--chrome/browser/renderer_host/cross_site_resource_handler.h1
-rw-r--r--chrome/browser/renderer_host/download_resource_handler.cc1
-rw-r--r--chrome/browser/renderer_host/download_throttling_resource_handler.cc1
-rw-r--r--chrome/browser/renderer_host/resource_handler.h37
-rw-r--r--chrome/browser/renderer_host/resource_message_filter.cc4
-rw-r--r--chrome/browser/renderer_host/save_file_resource_handler.cc1
-rw-r--r--chrome/browser/renderer_host/save_file_resource_handler.h1
-rw-r--r--chrome/browser/renderer_host/sync_resource_handler.h1
-rw-r--r--chrome/browser/renderer_host/x509_user_cert_resource_handler.cc1
25 files changed, 447 insertions, 936 deletions
diff --git a/chrome/browser/browser_about_handler.cc b/chrome/browser/browser_about_handler.cc
index 88ee96f..a4126d1 100644
--- a/chrome/browser/browser_about_handler.cc
+++ b/chrome/browser/browser_about_handler.cc
@@ -27,6 +27,7 @@
#include "chrome/browser/dom_ui/chrome_url_data_manager.h"
#include "chrome/browser/google_service_auth_error.h"
#include "chrome/browser/memory_details.h"
+#include "chrome/browser/metrics/histogram_synchronizer.h"
#include "chrome/browser/net/dns_global.h"
#include "chrome/browser/pref_service.h"
#include "chrome/browser/profile.h"
@@ -35,7 +36,6 @@
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/common/chrome_paths.h"
-#include "chrome/common/histogram_synchronizer.h"
#include "chrome/common/jstemplate_builder.h"
#include "chrome/common/platform_util.h"
#include "chrome/common/pref_names.h"
diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc
index e462d1d..63a3e86 100644
--- a/chrome/browser/browser_main.cc
+++ b/chrome/browser/browser_main.cc
@@ -36,6 +36,7 @@
#include "chrome/browser/extensions/extension_protocols.h"
#include "chrome/browser/first_run.h"
#include "chrome/browser/jankometer.h"
+#include "chrome/browser/metrics/histogram_synchronizer.h"
#include "chrome/browser/metrics/metrics_service.h"
#include "chrome/browser/net/dns_global.h"
#include "chrome/browser/net/metadata_url_request.h"
@@ -52,7 +53,6 @@
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
-#include "chrome/common/histogram_synchronizer.h"
#include "chrome/common/jstemplate_builder.h"
#include "chrome/common/main_function_params.h"
#include "chrome/common/net/net_resource_provider.h"
diff --git a/chrome/browser/extensions/crx_installer.cc b/chrome/browser/extensions/crx_installer.cc
index e9874cd..fa466f3 100644
--- a/chrome/browser/extensions/crx_installer.cc
+++ b/chrome/browser/extensions/crx_installer.cc
@@ -13,11 +13,11 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/extensions/convert_user_script.h"
-#include "chrome/browser/extensions/extension_file_util.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/shell_integration.h"
#include "chrome/browser/web_applications/web_app.h"
#include "chrome/common/extensions/extension_error_reporter.h"
+#include "chrome/common/extensions/extension_file_util.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/notification_type.h"
#include "grit/browser_resources.h"
diff --git a/chrome/browser/extensions/extension_creator.cc b/chrome/browser/extensions/extension_creator.cc
index 3d1fc64..7c9ec15 100644
--- a/chrome/browser/extensions/extension_creator.cc
+++ b/chrome/browser/extensions/extension_creator.cc
@@ -13,9 +13,9 @@
#include "base/scoped_handle.h"
#include "base/scoped_temp_dir.h"
#include "base/string_util.h"
-#include "chrome/browser/extensions/extension_file_util.h"
#include "chrome/browser/extensions/sandboxed_extension_unpacker.h"
#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/extension_file_util.h"
#include "chrome/common/zip.h"
namespace {
diff --git a/chrome/browser/extensions/extension_disabled_infobar_delegate.cc b/chrome/browser/extensions/extension_disabled_infobar_delegate.cc
index dd12915..20acb53 100644
--- a/chrome/browser/extensions/extension_disabled_infobar_delegate.cc
+++ b/chrome/browser/extensions/extension_disabled_infobar_delegate.cc
@@ -6,12 +6,12 @@
#include "app/l10n_util.h"
#include "chrome/browser/chrome_thread.h"
-#include "chrome/browser/extensions/extension_file_util.h"
#include "chrome/browser/extensions/extension_install_ui.h"
#include "chrome/browser/extensions/extensions_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_registrar.h"
#include "chrome/common/notification_service.h"
diff --git a/chrome/browser/extensions/extension_file_util.cc b/chrome/browser/extensions/extension_file_util.cc
deleted file mode 100644
index 346bfab..0000000
--- a/chrome/browser/extensions/extension_file_util.cc
+++ /dev/null
@@ -1,523 +0,0 @@
-// Copyright (c) 2009 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_file_util.h"
-
-#include "app/l10n_util.h"
-#include "base/file_util.h"
-#include "base/logging.h"
-#include "base/scoped_temp_dir.h"
-#include "base/string_util.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/extensions/extension_prefs.h"
-#include "chrome/common/extensions/extension.h"
-#include "chrome/common/extensions/extension_l10n_util.h"
-#include "chrome/common/extensions/extension_constants.h"
-#include "chrome/common/json_value_serializer.h"
-#include "net/base/escape.h"
-#include "net/base/file_stream.h"
-
-namespace errors = extension_manifest_errors;
-namespace keys = extension_manifest_keys;
-
-namespace extension_file_util {
-
-// Validates locale info. Doesn't check if messages.json files are valid.
-static bool ValidateLocaleInfo(const Extension& extension, std::string* error);
-
-const char kInstallDirectoryName[] = "Extensions";
-// TODO(mpcomplete): obsolete. remove after migration period.
-// http://code.google.com/p/chromium/issues/detail?id=19733
-const char kCurrentVersionFileName[] = "Current Version";
-
-bool MoveDirSafely(const FilePath& source_dir, const FilePath& dest_dir) {
- if (file_util::PathExists(dest_dir)) {
- if (!file_util::Delete(dest_dir, true))
- return false;
- } else {
- FilePath parent = dest_dir.DirName();
- if (!file_util::DirectoryExists(parent)) {
- if (!file_util::CreateDirectory(parent))
- return false;
- }
- }
-
- if (!file_util::Move(source_dir, dest_dir))
- return false;
-
- return true;
-}
-
-Extension::InstallType CompareToInstalledVersion(
- const FilePath& extensions_dir,
- const std::string& extension_id,
- const std::string& current_version_str,
- const std::string& new_version_str,
- FilePath* version_dir) {
- FilePath dest_dir = extensions_dir.AppendASCII(extension_id);
- FilePath current_version_dir = dest_dir.AppendASCII(current_version_str);
- *version_dir = dest_dir.AppendASCII(new_version_str);
-
- if (current_version_str.empty())
- return Extension::NEW_INSTALL;
-
- scoped_ptr<Version> current_version(
- Version::GetVersionFromString(current_version_str));
- scoped_ptr<Version> new_version(
- Version::GetVersionFromString(new_version_str));
- int comp = new_version->CompareTo(*current_version);
- if (comp > 0)
- return Extension::UPGRADE;
- if (comp < 0)
- return Extension::DOWNGRADE;
-
- // Same version. Treat corrupted existing installation as new install case.
- if (!SanityCheckExtension(current_version_dir))
- return Extension::NEW_INSTALL;
-
- return Extension::REINSTALL;
-}
-
-bool SanityCheckExtension(const FilePath& dir) {
- // Verify that the directory actually exists.
- // TODO(erikkay): A further step would be to verify that the extension
- // has actually loaded successfully.
- FilePath manifest_file(dir.Append(Extension::kManifestFilename));
- return file_util::PathExists(dir) && file_util::PathExists(manifest_file);
-}
-
-bool InstallExtension(const FilePath& src_dir,
- const FilePath& version_dir,
- std::string* error) {
- // If anything fails after this, we want to delete the extension dir.
- ScopedTempDir scoped_version_dir;
- scoped_version_dir.Set(version_dir);
-
- if (!MoveDirSafely(src_dir, version_dir)) {
- *error = "Could not move extension directory into profile.";
- return false;
- }
-
- scoped_version_dir.Take();
- return true;
-}
-
-Extension* LoadExtension(const FilePath& extension_path,
- bool require_key,
- std::string* error) {
- FilePath manifest_path =
- extension_path.Append(Extension::kManifestFilename);
- if (!file_util::PathExists(manifest_path)) {
- *error = extension_manifest_errors::kManifestUnreadable;
- return NULL;
- }
-
- JSONFileValueSerializer serializer(manifest_path);
- scoped_ptr<Value> root(serializer.Deserialize(error));
- if (!root.get()) {
- if (error->empty()) {
- // If |error| is empty, than the file could not be read.
- // It would be cleaner to have the JSON reader give a specific error
- // in this case, but other code tests for a file error with
- // error->empty(). For now, be consistent.
- *error = extension_manifest_errors::kManifestUnreadable;
- } else {
- *error = StringPrintf("%s %s",
- extension_manifest_errors::kManifestParseError,
- error->c_str());
- }
- return NULL;
- }
-
- if (!root->IsType(Value::TYPE_DICTIONARY)) {
- *error = extension_manifest_errors::kInvalidManifest;
- return NULL;
- }
-
- DictionaryValue* manifest = static_cast<DictionaryValue*>(root.get());
-
- scoped_ptr<Extension> extension(new Extension(extension_path));
-
- if (!extension_l10n_util::LocalizeExtension(extension.get(), manifest, error))
- return NULL;
-
- if (!extension->InitFromValue(*manifest, require_key, error))
- return NULL;
-
- if (!ValidateExtension(extension.get(), error))
- return NULL;
-
- return extension.release();
-}
-
-bool ValidateExtension(Extension* extension, std::string* error) {
- // Validate icons exist.
- for (std::map<int, std::string>::const_iterator iter =
- extension->icons().begin(); iter != extension->icons().end(); ++iter) {
- const FilePath path = extension->GetResource(iter->second).GetFilePath();
- if (!file_util::PathExists(path)) {
- *error = StringPrintf("Could not load extension icon '%s'.",
- iter->second.c_str());
- return false;
- }
- }
-
- // Theme resource validation.
- if (extension->IsTheme()) {
- DictionaryValue* images_value = extension->GetThemeImages();
- if (images_value) {
- for (DictionaryValue::key_iterator iter = images_value->begin_keys();
- iter != images_value->end_keys(); ++iter) {
- std::string val;
- if (images_value->GetStringWithoutPathExpansion(*iter, &val)) {
- FilePath image_path = extension->path().AppendASCII(val);
- if (!file_util::PathExists(image_path)) {
- *error = StringPrintf(
- "Could not load '%s' for theme.",
- WideToUTF8(image_path.ToWStringHack()).c_str());
- return false;
- }
- }
- }
- }
-
- // Themes cannot contain other extension types.
- return true;
- }
-
- // Validate that claimed script resources actually exist.
- for (size_t i = 0; i < extension->content_scripts().size(); ++i) {
- const UserScript& script = extension->content_scripts()[i];
-
- for (size_t j = 0; j < script.js_scripts().size(); j++) {
- const UserScript::File& js_script = script.js_scripts()[j];
- const FilePath& path = ExtensionResource::GetFilePath(
- js_script.extension_root(), js_script.relative_path());
- if (!file_util::PathExists(path)) {
- *error = StringPrintf(
- "Could not load javascript '%s' for content script.",
- WideToUTF8(js_script.relative_path().ToWStringHack()).c_str());
- return false;
- }
- }
-
- for (size_t j = 0; j < script.css_scripts().size(); j++) {
- const UserScript::File& css_script = script.css_scripts()[j];
- const FilePath& path = ExtensionResource::GetFilePath(
- css_script.extension_root(), css_script.relative_path());
- if (!file_util::PathExists(path)) {
- *error = StringPrintf(
- "Could not load css '%s' for content script.",
- WideToUTF8(css_script.relative_path().ToWStringHack()).c_str());
- return false;
- }
- }
- }
-
- // Validate claimed plugin paths.
- for (size_t i = 0; i < extension->plugins().size(); ++i) {
- const Extension::PluginInfo& plugin = extension->plugins()[i];
- if (!file_util::PathExists(plugin.path)) {
- *error = StringPrintf("Could not load '%s' for plugin.",
- WideToUTF8(plugin.path.ToWStringHack()).c_str());
- return false;
- }
- }
-
- // Validate icon location for page actions.
- ExtensionAction* page_action = extension->page_action();
- if (page_action) {
- std::vector<std::string> icon_paths(*page_action->icon_paths());
- if (!page_action->default_icon_path().empty())
- icon_paths.push_back(page_action->default_icon_path());
- for (std::vector<std::string>::iterator iter = icon_paths.begin();
- iter != icon_paths.end(); ++iter) {
- if (!file_util::PathExists(extension->GetResource(*iter).GetFilePath())) {
- *error = StringPrintf("Could not load icon '%s' for page action.",
- iter->c_str());
- return false;
- }
- }
- }
-
- // Validate icon location for browser actions.
- // Note: browser actions don't use the icon_paths().
- ExtensionAction* browser_action = extension->browser_action();
- if (browser_action) {
- std::string path = browser_action->default_icon_path();
- if (!path.empty() &&
- !file_util::PathExists(extension->GetResource(path).GetFilePath())) {
- *error = StringPrintf("Could not load icon '%s' for browser action.",
- path.c_str());
- return false;
- }
- }
-
- // Validate background page location.
- if (!extension->background_url().is_empty()) {
- FilePath page_path = ExtensionURLToRelativeFilePath(
- extension->background_url());
- const FilePath path = extension->GetResource(page_path).GetFilePath();
- if (!file_util::PathExists(path)) {
- *error = StringPrintf("Could not load background page '%s'.",
- WideToUTF8(path.ToWStringHack()).c_str());
- return false;
- }
- }
-
- // Validate locale info.
- if (!ValidateLocaleInfo(*extension, error))
- return false;
-
- // Check children of extension root to see if any of them start with _ and is
- // not on the reserved list.
- if (!CheckForIllegalFilenames(extension->path(), error)) {
- return false;
- }
-
- return true;
-}
-
-void UninstallExtension(const std::string& id, const FilePath& extensions_dir) {
- // First, delete the Current Version file. If the directory delete fails, then
- // at least the extension won't be loaded again.
- FilePath extension_root = extensions_dir.AppendASCII(id);
-
- if (!file_util::PathExists(extension_root)) {
- LOG(WARNING) << "Asked to remove a non-existent extension " << id;
- return;
- }
-
- FilePath current_version_file = extension_root.AppendASCII(
- kCurrentVersionFileName);
- if (!file_util::PathExists(current_version_file)) {
- // This is OK, since we're phasing out the current version file.
- } else {
- if (!file_util::Delete(current_version_file, false)) {
- LOG(WARNING) << "Could not delete Current Version file for extension "
- << id;
- return;
- }
- }
-
- // OK, now try and delete the entire rest of the directory. One major place
- // this can fail is if the extension contains a plugin (stupid plugins). It's
- // not a big deal though, because we'll notice next time we startup that the
- // Current Version file is gone and finish the delete then.
- if (!file_util::Delete(extension_root, true))
- LOG(WARNING) << "Could not delete directory for extension " << id;
-}
-
-void GarbageCollectExtensions(
- const FilePath& install_directory,
- const std::set<std::string>& installed_ids,
- const std::map<std::string, std::string>& installed_versions) {
- // Nothing to clean up if it doesn't exist.
- if (!file_util::DirectoryExists(install_directory))
- return;
-
- LOG(INFO) << "Loading installed extensions...";
- file_util::FileEnumerator enumerator(install_directory,
- false, // Not recursive.
- file_util::FileEnumerator::DIRECTORIES);
- FilePath extension_path;
- for (extension_path = enumerator.Next(); !extension_path.value().empty();
- extension_path = enumerator.Next()) {
- std::string extension_id = WideToASCII(
- extension_path.BaseName().ToWStringHack());
-
- // If there is no entry in the prefs file, just delete the directory and
- // move on. This can legitimately happen when an uninstall does not
- // complete, for example, when a plugin is in use at uninstall time.
- if (installed_ids.count(extension_id) == 0) {
- LOG(INFO) << "Deleting unreferenced install for directory "
- << WideToASCII(extension_path.ToWStringHack()) << ".";
- file_util::Delete(extension_path, true); // Recursive.
- continue;
- }
-
- // Delete directories that aren't valid IDs.
- if (!Extension::IdIsValid(extension_id)) {
- LOG(WARNING) << "Invalid extension ID encountered in extensions "
- "directory: " << extension_id;
- LOG(INFO) << "Deleting invalid extension directory "
- << WideToASCII(extension_path.ToWStringHack()) << ".";
- file_util::Delete(extension_path, true); // Recursive.
- continue;
- }
-
- // Clean up old version directories.
- file_util::FileEnumerator versions_enumerator(
- extension_path,
- false, // Not recursive.
- file_util::FileEnumerator::DIRECTORIES);
- for (FilePath version_dir = versions_enumerator.Next();
- !version_dir.value().empty();
- version_dir = versions_enumerator.Next()) {
- std::map<std::string, std::string>::const_iterator installed_version =
- installed_versions.find(extension_id);
- if (installed_version == installed_versions.end()) {
- NOTREACHED() << "No installed version found for " << extension_id;
- continue;
- }
-
- std::string version = WideToASCII(version_dir.BaseName().ToWStringHack());
- if (version != installed_version->second) {
- LOG(INFO) << "Deleting old version for directory "
- << WideToASCII(version_dir.ToWStringHack()) << ".";
- file_util::Delete(version_dir, true); // Recursive.
- }
- }
- }
-}
-
-ExtensionMessageBundle* LoadExtensionMessageBundle(
- const FilePath& extension_path,
- const std::string& default_locale,
- std::string* error) {
- error->clear();
- // Load locale information if available.
- FilePath locale_path = extension_path.Append(Extension::kLocaleFolder);
- if (!file_util::PathExists(locale_path))
- return NULL;
-
- std::set<std::string> locales;
- if (!extension_l10n_util::GetValidLocales(locale_path, &locales, error))
- return NULL;
-
- if (default_locale.empty() ||
- locales.find(default_locale) == locales.end()) {
- *error = extension_manifest_errors::kLocalesNoDefaultLocaleSpecified;
- return NULL;
- }
-
- ExtensionMessageBundle* message_bundle =
- extension_l10n_util::LoadMessageCatalogs(
- locale_path,
- default_locale,
- extension_l10n_util::CurrentLocaleOrDefault(),
- locales,
- error);
-
- return message_bundle;
-}
-
-static bool ValidateLocaleInfo(const Extension& extension, std::string* error) {
- // default_locale and _locales have to be both present or both missing.
- const FilePath path = extension.path().Append(Extension::kLocaleFolder);
- bool path_exists = file_util::PathExists(path);
- std::string default_locale = extension.default_locale();
-
- // If both default locale and _locales folder are empty, skip verification.
- if (!default_locale.empty() || path_exists) {
- if (default_locale.empty() && path_exists) {
- *error = errors::kLocalesNoDefaultLocaleSpecified;
- return false;
- } else if (!default_locale.empty() && !path_exists) {
- *error = errors::kLocalesTreeMissing;
- return false;
- }
-
- // Treat all folders under _locales as valid locales.
- file_util::FileEnumerator locales(path,
- false,
- file_util::FileEnumerator::DIRECTORIES);
-
- FilePath locale_path = locales.Next();
- if (locale_path.empty()) {
- *error = errors::kLocalesTreeMissing;
- return false;
- }
-
- const FilePath default_locale_path = path.AppendASCII(default_locale);
- bool has_default_locale_message_file = false;
- do {
- // Skip any strings with '.'. This happens sometimes, for example with
- // '.svn' directories.
- FilePath relative_path;
- if (!extension.path().AppendRelativePath(locale_path, &relative_path))
- NOTREACHED();
- std::wstring subdir(relative_path.ToWStringHack());
- if (std::find(subdir.begin(), subdir.end(), L'.') != subdir.end())
- continue;
-
- FilePath messages_path =
- locale_path.Append(Extension::kMessagesFilename);
-
- if (!file_util::PathExists(messages_path)) {
- *error = StringPrintf(
- "%s %s", errors::kLocalesMessagesFileMissing,
- WideToUTF8(messages_path.ToWStringHack()).c_str());
- return false;
- }
-
- if (locale_path == default_locale_path)
- has_default_locale_message_file = true;
- } while (!(locale_path = locales.Next()).empty());
-
- // Only message file for default locale has to exist.
- if (!has_default_locale_message_file) {
- *error = errors::kLocalesNoDefaultMessages;
- return false;
- }
- }
-
- return true;
-}
-
-bool CheckForIllegalFilenames(const FilePath& extension_path,
- std::string* error) {
- // Reserved underscore names.
- static const FilePath::CharType* reserved_names[] = {
- Extension::kLocaleFolder,
- FILE_PATH_LITERAL("__MACOSX"),
- };
- static std::set<FilePath::StringType> reserved_underscore_names(
- reserved_names, reserved_names + arraysize(reserved_names));
-
- // Enumerate all files and directories in the extension root.
- // There is a problem when using pattern "_*" with FileEnumerator, so we have
- // to cheat with find_first_of and match all.
- file_util::FileEnumerator all_files(
- extension_path,
- false,
- static_cast<file_util::FileEnumerator::FILE_TYPE>(
- file_util::FileEnumerator::DIRECTORIES |
- file_util::FileEnumerator::FILES));
-
- FilePath file;
- while (!(file = all_files.Next()).empty()) {
- FilePath::StringType filename = file.BaseName().value();
- // Skip all that don't start with "_".
- if (filename.find_first_of(FILE_PATH_LITERAL("_")) != 0) continue;
- if (reserved_underscore_names.find(filename) ==
- reserved_underscore_names.end()) {
- *error = StringPrintf(
- "Cannot load extension with file or directory name %s. "
- "Filenames starting with \"_\" are reserved for use by the system.",
- filename.c_str());
- return false;
- }
- }
-
- return true;
-}
-
-FilePath ExtensionURLToRelativeFilePath(const GURL& url) {
- std::string url_path = url.path();
- if (url_path.empty() || url_path[0] != '/')
- return FilePath();
-
- // Drop the leading slash and convert %-encoded UTF8 to regular UTF8.
- std::string file_path = UnescapeURLComponent(url_path.substr(1),
- UnescapeRule::SPACES | UnescapeRule::URL_SPECIAL_CHARS);
-
-#if defined(OS_POSIX)
- return FilePath(file_path);
-#elif defined(OS_WIN)
- return FilePath(UTF8ToWide(file_path));
-#endif
-}
-
-} // namespace extension_file_util
diff --git a/chrome/browser/extensions/extension_file_util.h b/chrome/browser/extensions/extension_file_util.h
deleted file mode 100644
index d8bb448..0000000
--- a/chrome/browser/extensions/extension_file_util.h
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_FILE_UTIL_H_
-#define CHROME_BROWSER_EXTENSIONS_EXTENSION_FILE_UTIL_H_
-
-#include <set>
-#include <string>
-
-#include "base/file_path.h"
-#include "chrome/common/extensions/extension.h"
-
-class ExtensionMessageBundle;
-
-// Utilties for manipulating the on-disk storage of extensions.
-namespace extension_file_util {
-
-// The name of the directory inside the profile that we store installed
-// extension in.
-extern const char kInstallDirectoryName[];
-
-// The name of the file that contains the current version of an installed
-// extension.
-extern const char kCurrentVersionFileName[];
-
-// Move source_dir to dest_dir (it will actually be named dest_dir, not inside
-// dest_dir). If the parent path doesn't exixt, create it. If something else is
-// already there, remove it.
-bool MoveDirSafely(const FilePath& source_dir, const FilePath& dest_dir);
-
-// Updates the Current Version file inside the installed extension.
-bool SetCurrentVersion(const FilePath& dest_dir,
- const std::string& version,
- std::string* error);
-
-// Reads the Current Version file.
-bool ReadCurrentVersion(const FilePath& dir, std::string* version_string);
-
-// Determine what type of install it is (new, upgrade, overinstall, downgrade)
-// given the current version and a newly installing version. |extensions_dir| is
-// the root directory containing all extensions in the user profile.
-// |extension_id| and |current_version_str| are the id and version of the
-// extension contained in |src_dir|, if any.
-//
-// Returns the full path to the destination version directory and the type of
-// install that was attempted.
-Extension::InstallType CompareToInstalledVersion(
- const FilePath& extensions_dir,
- const std::string& extension_id,
- const std::string& current_version_str,
- const std::string& new_version_str,
- FilePath* version_dir);
-
-// Sanity check that the directory has the minimum files to be a working
-// extension.
-bool SanityCheckExtension(const FilePath& extension_root);
-
-// Installs an extension unpacked in |src_dir|.
-//
-// On failure, also returns an error message.
-//
-// NOTE: |src_dir| is not actually copied in the case of downgrades or
-// overinstall of previous verisons of the extension. In that case, the function
-// returns true and install_type is populated.
-bool InstallExtension(const FilePath& src_dir,
- const FilePath& version_dir,
- std::string* error);
-
-// Loads and validates an extension from the specified directory. Returns NULL
-// on failure, with a description of the error in |error|.
-Extension* LoadExtension(const FilePath& extension_root,
- bool require_key,
- std::string* error);
-
-// Returns true if the given extension object is valid and consistent.
-// Otherwise, a description of the error is returned in |error|.
-bool ValidateExtension(Extension* extension, std::string* error);
-
-// Uninstalls the extension |id| from the install directory |extensions_dir|.
-void UninstallExtension(const std::string& id, const FilePath& extensions_dir);
-
-// Clean up directories that aren't valid extensions from the install directory.
-void GarbageCollectExtensions(
- const FilePath& extensions_dir,
- const std::set<std::string>& installed_ids,
- const std::map<std::string, std::string>& installed_versions);
-
-// Loads extension message catalogs and returns message bundle.
-// Returns NULL on error, or if extension is not localized.
-ExtensionMessageBundle* LoadExtensionMessageBundle(
- const FilePath& extension_path,
- const std::string& default_locale,
- std::string* error);
-
-// We need to reserve the namespace of entries that start with "_" for future
-// use by Chrome.
-// If any files or directories are found using "_" prefix and are not on
-// reserved list we return false, and set error message.
-bool CheckForIllegalFilenames(const FilePath& extension_path,
- std::string* error);
-
-// Get a relative file path from a chrome-extension:// URL.
-FilePath ExtensionURLToRelativeFilePath(const GURL& url);
-
-} // extension_file_util
-
-#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_FILE_UTIL_H_
diff --git a/chrome/browser/extensions/extension_file_util_unittest.cc b/chrome/browser/extensions/extension_file_util_unittest.cc
deleted file mode 100644
index 31ed023..0000000
--- a/chrome/browser/extensions/extension_file_util_unittest.cc
+++ /dev/null
@@ -1,258 +0,0 @@
-// Copyright (c) 2009 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_file_util.h"
-
-#include "base/file_util.h"
-#include "base/scoped_temp_dir.h"
-#include "base/string_util.h"
-#include "base/path_service.h"
-#include "chrome/common/chrome_paths.h"
-#include "chrome/common/extensions/extension.h"
-#include "chrome/common/extensions/extension_constants.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace keys = extension_manifest_keys;
-
-TEST(ExtensionFileUtil, MoveDirSafely) {
- // Create a test directory structure with some data in it.
- ScopedTempDir temp;
- ASSERT_TRUE(temp.CreateUniqueTempDir());
-
- FilePath src_path = temp.path().AppendASCII("src");
- ASSERT_TRUE(file_util::CreateDirectory(src_path));
-
- std::string data = "foobar";
- ASSERT_TRUE(file_util::WriteFile(src_path.AppendASCII("data"),
- data.c_str(), data.length()));
-
- // Move it to a path that doesn't exist yet.
- FilePath dest_path = temp.path().AppendASCII("dest").AppendASCII("dest");
- ASSERT_TRUE(extension_file_util::MoveDirSafely(src_path, dest_path));
-
- // The path should get created.
- ASSERT_TRUE(file_util::DirectoryExists(dest_path));
-
- // The data should match.
- std::string data_out;
- ASSERT_TRUE(file_util::ReadFileToString(dest_path.AppendASCII("data"),
- &data_out));
- ASSERT_EQ(data, data_out);
-
- // The src path should be gone.
- ASSERT_FALSE(file_util::PathExists(src_path));
-
- // Create some new test data.
- ASSERT_TRUE(file_util::CopyDirectory(dest_path, src_path,
- true)); // recursive
- data = "hotdog";
- ASSERT_TRUE(file_util::WriteFile(src_path.AppendASCII("data"),
- data.c_str(), data.length()));
-
- // Test again, overwriting the old path.
- ASSERT_TRUE(extension_file_util::MoveDirSafely(src_path, dest_path));
- ASSERT_TRUE(file_util::DirectoryExists(dest_path));
-
- data_out.clear();
- ASSERT_TRUE(file_util::ReadFileToString(dest_path.AppendASCII("data"),
- &data_out));
- ASSERT_EQ(data, data_out);
- ASSERT_FALSE(file_util::PathExists(src_path));
-}
-
-TEST(ExtensionFileUtil, CompareToInstalledVersion) {
- // Compare to an existing extension.
- FilePath install_dir;
- ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &install_dir));
- install_dir = install_dir.AppendASCII("extensions")
- .AppendASCII("good")
- .AppendASCII("Extensions");
-
- const std::string kId = "behllobkkfkfnphdnhnkndlbkcpglgmj";
- const std::string kCurrentVersion = "1.0.0.0";
-
- FilePath version_dir;
-
- ASSERT_EQ(Extension::UPGRADE,
- extension_file_util::CompareToInstalledVersion(
- install_dir, kId, kCurrentVersion, "1.0.0.1", &version_dir));
-
- ASSERT_EQ(Extension::REINSTALL,
- extension_file_util::CompareToInstalledVersion(
- install_dir, kId, kCurrentVersion, "1.0.0.0", &version_dir));
-
- ASSERT_EQ(Extension::REINSTALL,
- extension_file_util::CompareToInstalledVersion(
- install_dir, kId, kCurrentVersion, "1.0.0", &version_dir));
-
- ASSERT_EQ(Extension::DOWNGRADE,
- extension_file_util::CompareToInstalledVersion(
- install_dir, kId, kCurrentVersion, "0.0.1.0", &version_dir));
-
- // Compare to an extension that is missing its manifest file.
- ScopedTempDir temp;
- ASSERT_TRUE(temp.CreateUniqueTempDir());
- FilePath src = install_dir.AppendASCII(kId).AppendASCII(kCurrentVersion);
- FilePath dest = temp.path().AppendASCII(kId).AppendASCII(kCurrentVersion);
- ASSERT_TRUE(file_util::CreateDirectory(dest.DirName()));
- ASSERT_TRUE(file_util::CopyDirectory(src, dest, true));
- ASSERT_TRUE(file_util::Delete(dest.AppendASCII("manifest.json"), false));
-
- ASSERT_EQ(Extension::NEW_INSTALL,
- extension_file_util::CompareToInstalledVersion(
- temp.path(), kId, kCurrentVersion, "1.0.0", &version_dir));
-
- // Compare to a non-existent extension.
- const std::string kMissingVersion = "";
- const std::string kBadId = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
- ASSERT_EQ(Extension::NEW_INSTALL,
- extension_file_util::CompareToInstalledVersion(
- temp.path(), kBadId, kMissingVersion, "1.0.0", &version_dir));
-}
-
-TEST(ExtensionFileUtil, LoadExtensionWithValidLocales) {
- FilePath install_dir;
- ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &install_dir));
- install_dir = install_dir.AppendASCII("extensions")
- .AppendASCII("good")
- .AppendASCII("Extensions")
- .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
- .AppendASCII("1.0.0.0");
-
- std::string error;
- scoped_ptr<Extension> extension(
- extension_file_util::LoadExtension(install_dir, false, &error));
- ASSERT_TRUE(extension != NULL);
- EXPECT_EQ("The first extension that I made.", extension->description());
-}
-
-TEST(ExtensionFileUtil, LoadExtensionWithoutLocalesFolder) {
- FilePath install_dir;
- ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &install_dir));
- install_dir = install_dir.AppendASCII("extensions")
- .AppendASCII("good")
- .AppendASCII("Extensions")
- .AppendASCII("bjafgdebaacbbbecmhlhpofkepfkgcpa")
- .AppendASCII("1.0");
-
- std::string error;
- scoped_ptr<Extension> extension(
- extension_file_util::LoadExtension(install_dir, false, &error));
- ASSERT_FALSE(extension == NULL);
- EXPECT_TRUE(error.empty());
-}
-
-TEST(ExtensionFileUtil, CheckIllegalFilenamesNoUnderscores) {
- ScopedTempDir temp;
- ASSERT_TRUE(temp.CreateUniqueTempDir());
-
- FilePath src_path = temp.path().AppendASCII("some_dir");
- ASSERT_TRUE(file_util::CreateDirectory(src_path));
-
- std::string data = "{ \"name\": { \"message\": \"foobar\" } }";
- ASSERT_TRUE(file_util::WriteFile(src_path.AppendASCII("some_file.txt"),
- data.c_str(), data.length()));
- std::string error;
- EXPECT_TRUE(extension_file_util::CheckForIllegalFilenames(temp.path(),
- &error));
-}
-
-TEST(ExtensionFileUtil, CheckIllegalFilenamesOnlyReserved) {
- ScopedTempDir temp;
- ASSERT_TRUE(temp.CreateUniqueTempDir());
-
- FilePath src_path = temp.path().Append(Extension::kLocaleFolder);
- ASSERT_TRUE(file_util::CreateDirectory(src_path));
-
- std::string error;
- EXPECT_TRUE(extension_file_util::CheckForIllegalFilenames(temp.path(),
- &error));
-}
-
-TEST(ExtensionFileUtil, CheckIllegalFilenamesReservedAndIllegal) {
- ScopedTempDir temp;
- ASSERT_TRUE(temp.CreateUniqueTempDir());
-
- FilePath src_path = temp.path().Append(Extension::kLocaleFolder);
- ASSERT_TRUE(file_util::CreateDirectory(src_path));
-
- src_path = temp.path().AppendASCII("_some_dir");
- ASSERT_TRUE(file_util::CreateDirectory(src_path));
-
- std::string error;
- EXPECT_FALSE(extension_file_util::CheckForIllegalFilenames(temp.path(),
- &error));
-}
-
-TEST(ExtensionFileUtil, LoadExtensionGivesHelpfullErrorOnMissingManifest) {
- FilePath install_dir;
- ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &install_dir));
- install_dir = install_dir.AppendASCII("extensions")
- .AppendASCII("bad")
- .AppendASCII("Extensions")
- .AppendASCII("dddddddddddddddddddddddddddddddd")
- .AppendASCII("1.0");
-
- std::string error;
- scoped_ptr<Extension> extension(
- extension_file_util::LoadExtension(install_dir, false, &error));
- ASSERT_TRUE(extension == NULL);
- ASSERT_FALSE(error.empty());
- ASSERT_STREQ("Manifest file is missing or unreadable.", error.c_str());
-}
-
-TEST(ExtensionFileUtil, LoadExtensionGivesHelpfullErrorOnBadManifest) {
- FilePath install_dir;
- ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &install_dir));
- install_dir = install_dir.AppendASCII("extensions")
- .AppendASCII("bad")
- .AppendASCII("Extensions")
- .AppendASCII("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee")
- .AppendASCII("1.0");
-
- std::string error;
- scoped_ptr<Extension> extension(
- extension_file_util::LoadExtension(install_dir, false, &error));
- ASSERT_TRUE(extension == NULL);
- ASSERT_FALSE(error.empty());
- ASSERT_STREQ("Manifest is not valid JSON. "
- "Line: 2, column: 16, Syntax error.", error.c_str());
-}
-
-#define URL_PREFIX "chrome-extension://extension-id/"
-
-TEST(ExtensionFileUtil, ExtensionURLToRelativeFilePath) {
- struct TestCase {
- const char* url;
- const char* expected_relative_path;
- } test_cases[] = {
- { URL_PREFIX "simple.html",
- "simple.html" },
- { URL_PREFIX "directory/to/file.html",
- "directory/to/file.html" },
- { URL_PREFIX "escape%20spaces.html",
- "escape spaces.html" },
- { URL_PREFIX "%C3%9Cber.html",
- "\xC3\x9C" "ber.html" },
- };
-
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
- GURL url(test_cases[i].url);
-#if defined(OS_POSIX)
- FilePath expected_path(test_cases[i].expected_relative_path);
-#elif defined(OS_WIN)
- FilePath expected_path(UTF8ToWide(test_cases[i].expected_relative_path));
-#endif
-
- FilePath actual_path =
- extension_file_util::ExtensionURLToRelativeFilePath(url);
- EXPECT_FALSE(actual_path.IsAbsolute()) <<
- " For the path " << actual_path.value();
- EXPECT_EQ(expected_path.value(), actual_path.value());
- }
-}
-
-// TODO(aa): More tests as motivation allows. Maybe steal some from
-// ExtensionsService? Many of them could probably be tested here without the
-// MessageLoop shenanigans.
diff --git a/chrome/browser/extensions/extension_protocols.cc b/chrome/browser/extensions/extension_protocols.cc
index 2141622..21dcd12 100644
--- a/chrome/browser/extensions/extension_protocols.cc
+++ b/chrome/browser/extensions/extension_protocols.cc
@@ -5,9 +5,9 @@
#include "chrome/browser/extensions/extension_protocols.h"
#include "base/string_util.h"
-#include "chrome/browser/extensions/extension_file_util.h"
#include "chrome/browser/net/chrome_url_request_context.h"
#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/extension_file_util.h"
#include "chrome/common/extensions/extension_resource.h"
#include "chrome/common/url_constants.h"
#include "googleurl/src/url_util.h"
diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc
index 7b98410..d171767 100644
--- a/chrome/browser/extensions/extensions_service.cc
+++ b/chrome/browser/extensions/extensions_service.cc
@@ -18,7 +18,6 @@
#include "chrome/browser/extensions/extension_bookmarks_module.h"
#include "chrome/browser/extensions/extension_browser_event_router.h"
#include "chrome/browser/extensions/extension_dom_ui.h"
-#include "chrome/browser/extensions/extension_file_util.h"
#include "chrome/browser/extensions/extension_history_api.h"
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extension_process_manager.h"
@@ -33,6 +32,7 @@
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/extensions/extension_error_reporter.h"
+#include "chrome/common/extensions/extension_file_util.h"
#include "chrome/common/extensions/extension_l10n_util.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/notification_type.h"
diff --git a/chrome/browser/extensions/sandboxed_extension_unpacker.cc b/chrome/browser/extensions/sandboxed_extension_unpacker.cc
index 9d004e3..a9d6966 100644
--- a/chrome/browser/extensions/sandboxed_extension_unpacker.cc
+++ b/chrome/browser/extensions/sandboxed_extension_unpacker.cc
@@ -14,14 +14,14 @@
#include "base/scoped_handle.h"
#include "base/task.h"
#include "chrome/browser/chrome_thread.h"
-#include "chrome/browser/extensions/extension_file_util.h"
#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/browser/renderer_host/resource_dispatcher_host.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_constants.h"
-#include "chrome/common/extensions/extension_unpacker.h"
+#include "chrome/common/extensions/extension_file_util.h"
#include "chrome/common/extensions/extension_l10n_util.h"
+#include "chrome/common/extensions/extension_unpacker.h"
#include "chrome/common/json_value_serializer.h"
#include "third_party/skia/include/core/SkBitmap.h"
diff --git a/chrome/browser/extensions/user_script_listener_unittest.cc b/chrome/browser/extensions/user_script_listener_unittest.cc
index 546c734..79abdcf 100644
--- a/chrome/browser/extensions/user_script_listener_unittest.cc
+++ b/chrome/browser/extensions/user_script_listener_unittest.cc
@@ -4,7 +4,6 @@
#include "base/message_loop.h"
#include "base/thread.h"
-#include "chrome/browser/extensions/extension_file_util.h"
#include "chrome/browser/extensions/extensions_service_unittest.h"
#include "chrome/browser/extensions/user_script_listener.h"
#include "chrome/browser/renderer_host/global_request_id.h"
@@ -12,6 +11,7 @@
#include "chrome/browser/renderer_host/resource_handler.h"
#include "chrome/browser/renderer_host/resource_queue.h"
#include "chrome/common/chrome_paths.h"
+#include "chrome/common/extensions/extension_file_util.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/notification_type.h"
#include "net/url_request/url_request.h"
diff --git a/chrome/browser/metrics/histogram_synchronizer.cc b/chrome/browser/metrics/histogram_synchronizer.cc
new file mode 100644
index 0000000..ff46199
--- /dev/null
+++ b/chrome/browser/metrics/histogram_synchronizer.cc
@@ -0,0 +1,278 @@
+// Copyright (c) 2009 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/metrics/histogram_synchronizer.h"
+
+#include "base/histogram.h"
+#include "base/logging.h"
+#include "base/thread.h"
+#include "chrome/browser/chrome_thread.h"
+#include "chrome/browser/renderer_host/render_process_host.h"
+#include "chrome/common/chrome_constants.h"
+#include "chrome/common/render_messages.h"
+
+using base::Time;
+using base::TimeDelta;
+using base::TimeTicks;
+
+HistogramSynchronizer::HistogramSynchronizer()
+ : lock_(),
+ received_all_renderer_historgrams_(&lock_),
+ callback_task_(NULL),
+ callback_thread_(NULL),
+ io_message_loop_(NULL),
+ next_available_sequence_number_(0),
+ async_sequence_number_(0),
+ async_renderers_pending_(0),
+ async_callback_start_time_(TimeTicks::Now()),
+ synchronous_sequence_number_(0),
+ synchronous_renderers_pending_(0) {
+ DCHECK(histogram_synchronizer_ == NULL);
+ histogram_synchronizer_ = this;
+}
+
+HistogramSynchronizer::~HistogramSynchronizer() {
+ // Clean up.
+ delete callback_task_;
+ callback_task_ = NULL;
+ callback_thread_ = NULL;
+ histogram_synchronizer_ = NULL;
+}
+
+// static
+HistogramSynchronizer* HistogramSynchronizer::CurrentSynchronizer() {
+ DCHECK(histogram_synchronizer_ != NULL);
+ return histogram_synchronizer_;
+}
+
+void HistogramSynchronizer::FetchRendererHistogramsSynchronously(
+ TimeDelta wait_time) {
+ DCHECK(MessageLoop::current()->type() == MessageLoop::TYPE_UI);
+
+ int sequence_number = GetNextAvaibleSequenceNumber(SYNCHRONOUS_HISTOGRAMS);
+ for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
+ !it.IsAtEnd(); it.Advance()) {
+ it.GetCurrentValue()->Send(
+ new ViewMsg_GetRendererHistograms(sequence_number));
+ IncrementPendingRenderers(SYNCHRONOUS_HISTOGRAMS);
+ }
+
+ TimeTicks start = TimeTicks::Now();
+ TimeTicks end_time = start + wait_time;
+ int unresponsive_renderer_count;
+ {
+ AutoLock auto_lock(lock_);
+ while (synchronous_renderers_pending_ > 0 &&
+ TimeTicks::Now() < end_time) {
+ wait_time = end_time - TimeTicks::Now();
+ received_all_renderer_historgrams_.TimedWait(wait_time);
+ }
+ unresponsive_renderer_count = synchronous_renderers_pending_;
+ synchronous_renderers_pending_ = 0;
+ synchronous_sequence_number_ = 0;
+ }
+ UMA_HISTOGRAM_COUNTS("Histogram.RendersNotRespondingSynchronous",
+ unresponsive_renderer_count);
+ if (!unresponsive_renderer_count)
+ UMA_HISTOGRAM_TIMES("Histogram.FetchRendererHistogramsSynchronously",
+ TimeTicks::Now() - start);
+}
+
+// static
+void HistogramSynchronizer::FetchRendererHistogramsAsynchronously(
+ MessageLoop* callback_thread,
+ Task* callback_task,
+ int wait_time) {
+ DCHECK(MessageLoop::current()->type() == MessageLoop::TYPE_UI);
+ DCHECK(callback_thread != NULL);
+ DCHECK(callback_task != NULL);
+
+ HistogramSynchronizer* current_synchronizer =
+ HistogramSynchronizer::CurrentSynchronizer();
+
+ if (current_synchronizer == NULL) {
+ // System teardown is happening.
+ callback_thread->PostTask(FROM_HERE, callback_task);
+ return;
+ }
+
+ // callback_task_ member can only be accessed on IO thread.
+ ChromeThread::PostTask(
+ ChromeThread::IO, FROM_HERE,
+ NewRunnableMethod(
+ current_synchronizer,
+ &HistogramSynchronizer::SetCallbackTaskToCallAfterGettingHistograms,
+ callback_thread,
+ callback_task));
+
+ // Tell all renderer processes to send their histograms.
+ int sequence_number =
+ current_synchronizer->GetNextAvaibleSequenceNumber(ASYNC_HISTOGRAMS);
+ for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
+ !it.IsAtEnd(); it.Advance()) {
+ it.GetCurrentValue()->Send(
+ new ViewMsg_GetRendererHistograms(sequence_number));
+ current_synchronizer->IncrementPendingRenderers(ASYNC_HISTOGRAMS);
+ }
+
+ // Post a task that would be called after waiting for wait_time.
+ ChromeThread::PostDelayedTask(
+ ChromeThread::IO, FROM_HERE,
+ NewRunnableMethod(
+ current_synchronizer,
+ &HistogramSynchronizer::ForceHistogramSynchronizationDoneCallback,
+ sequence_number),
+ wait_time);
+}
+
+// static
+void HistogramSynchronizer::DeserializeHistogramList(
+ int sequence_number,
+ const std::vector<std::string>& histograms) {
+ HistogramSynchronizer* current_synchronizer =
+ HistogramSynchronizer::CurrentSynchronizer();
+ if (current_synchronizer == NULL)
+ return;
+
+ DCHECK(current_synchronizer->IsOnIoThread());
+
+ for (std::vector<std::string>::const_iterator it = histograms.begin();
+ it < histograms.end();
+ ++it) {
+ Histogram::DeserializeHistogramInfo(*it);
+ }
+
+ // Record that we have received a histogram from renderer process.
+ current_synchronizer->RecordRendererHistogram(sequence_number);
+}
+
+bool HistogramSynchronizer::RecordRendererHistogram(int sequence_number) {
+ DCHECK(IsOnIoThread());
+
+ if (sequence_number == async_sequence_number_) {
+ if ((async_renderers_pending_ == 0) ||
+ (--async_renderers_pending_ > 0))
+ return false;
+ DCHECK(callback_task_ != NULL);
+ CallCallbackTaskAndResetData();
+ return true;
+ }
+
+ {
+ AutoLock auto_lock(lock_);
+ if (sequence_number != synchronous_sequence_number_) {
+ // No need to do anything if the sequence_number does not match current
+ // synchronous_sequence_number_ or async_sequence_number_.
+ return true;
+ }
+ if ((synchronous_renderers_pending_ == 0) ||
+ (--synchronous_renderers_pending_ > 0))
+ return false;
+ DCHECK_EQ(synchronous_renderers_pending_, 0);
+ }
+
+ // We could call Signal() without holding the lock.
+ received_all_renderer_historgrams_.Signal();
+ return true;
+}
+
+// This method is called on the IO thread.
+void HistogramSynchronizer::SetCallbackTaskToCallAfterGettingHistograms(
+ MessageLoop* callback_thread,
+ Task* callback_task) {
+ DCHECK(IsOnIoThread());
+
+ // Test for the existence of a previous task, and post call to post it if it
+ // exists. We promised to post it after some timeout... and at this point, we
+ // should just force the posting.
+ if (callback_task_ != NULL) {
+ CallCallbackTaskAndResetData();
+ }
+
+ // Assert there was no callback_task_ already.
+ DCHECK(callback_task_ == NULL);
+
+ // Save the thread and the callback_task.
+ DCHECK(callback_thread != NULL);
+ DCHECK(callback_task != NULL);
+ callback_task_ = callback_task;
+ callback_thread_ = callback_thread;
+ async_callback_start_time_ = TimeTicks::Now();
+}
+
+void HistogramSynchronizer::ForceHistogramSynchronizationDoneCallback(
+ int sequence_number) {
+ DCHECK(IsOnIoThread());
+
+ if (sequence_number == async_sequence_number_) {
+ CallCallbackTaskAndResetData();
+ }
+}
+
+// If wait time has elapsed or if we have received all the histograms from all
+// the renderers, call the callback_task if a callback_task exists. This is
+// called on IO Thread.
+void HistogramSynchronizer::CallCallbackTaskAndResetData() {
+ DCHECK(IsOnIoThread());
+
+ // callback_task_ would be set to NULL, if we have heard from all renderers
+ // and we would have called the callback_task already.
+ if (callback_task_ == NULL) {
+ return;
+ }
+
+ UMA_HISTOGRAM_COUNTS("Histogram.RendersNotRespondingAsynchronous",
+ async_renderers_pending_);
+ if (!async_renderers_pending_)
+ UMA_HISTOGRAM_TIMES("Histogram.FetchRendererHistogramsAsynchronously",
+ TimeTicks::Now() - async_callback_start_time_);
+
+ DCHECK(callback_thread_ != NULL);
+ DCHECK(callback_task_ != NULL);
+ callback_thread_->PostTask(FROM_HERE, callback_task_);
+ async_renderers_pending_ = 0;
+ async_callback_start_time_ = TimeTicks::Now();
+ callback_task_ = NULL;
+ callback_thread_ = NULL;
+}
+
+int HistogramSynchronizer::GetNextAvaibleSequenceNumber(
+ RendererHistogramRequester requester) {
+ AutoLock auto_lock(lock_);
+ ++next_available_sequence_number_;
+ if (0 > next_available_sequence_number_) {
+ // We wrapped around.
+ next_available_sequence_number_ =
+ chrome::kHistogramSynchronizerReservedSequenceNumber + 1;
+ }
+ DCHECK_NE(next_available_sequence_number_,
+ chrome::kHistogramSynchronizerReservedSequenceNumber);
+ if (requester == ASYNC_HISTOGRAMS) {
+ async_sequence_number_ = next_available_sequence_number_;
+ async_renderers_pending_ = 0;
+ } else if (requester == SYNCHRONOUS_HISTOGRAMS) {
+ synchronous_sequence_number_ = next_available_sequence_number_;
+ synchronous_renderers_pending_ = 0;
+ }
+ return next_available_sequence_number_;
+}
+
+void HistogramSynchronizer::IncrementPendingRenderers(
+ RendererHistogramRequester requester) {
+ if (requester == ASYNC_HISTOGRAMS) {
+ async_renderers_pending_++;
+ } else {
+ synchronous_renderers_pending_++;
+ }
+}
+
+bool HistogramSynchronizer::IsOnIoThread() {
+ if (io_message_loop_ == NULL) {
+ io_message_loop_ = MessageLoop::current();
+ }
+ return (MessageLoop::current() == io_message_loop_);
+}
+
+// static
+HistogramSynchronizer* HistogramSynchronizer::histogram_synchronizer_ = NULL;
diff --git a/chrome/browser/metrics/histogram_synchronizer.h b/chrome/browser/metrics/histogram_synchronizer.h
new file mode 100644
index 0000000..1a69afb
--- /dev/null
+++ b/chrome/browser/metrics/histogram_synchronizer.h
@@ -0,0 +1,145 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_METRICS_HISTOGRAM_SYNCHRONIZER_H_
+#define CHROME_BROWSER_METRICS_HISTOGRAM_SYNCHRONIZER_H_
+
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/condition_variable.h"
+#include "base/lock.h"
+#include "base/ref_counted.h"
+#include "base/time.h"
+
+class MessageLoop;
+class Task;
+
+class HistogramSynchronizer : public
+ base::RefCountedThreadSafe<HistogramSynchronizer> {
+ public:
+
+ enum RendererHistogramRequester {
+ ASYNC_HISTOGRAMS,
+ SYNCHRONOUS_HISTOGRAMS
+ };
+
+ HistogramSynchronizer();
+
+ ~HistogramSynchronizer();
+
+ // Return pointer to the singleton instance, which is allocated and
+ // deallocated on the main UI thread (during system startup and teardown).
+ static HistogramSynchronizer* CurrentSynchronizer();
+
+ // Contact all renderers, and get them to upload to the browser any/all
+ // changes to histograms. Return when all changes have been acquired, or when
+ // the wait time expires (whichever is sooner). This method is called on the
+ // main UI thread from about:histograms.
+ void FetchRendererHistogramsSynchronously(base::TimeDelta wait_time);
+
+ // Contact all renderers, and get them to upload to the browser any/all
+ // changes to histograms. When all changes have been acquired, or when the
+ // wait time expires (whichever is sooner), post the callback_task to the UI
+ // thread. Note the callback_task is posted exactly once. This method is
+ // called on the IO thread from UMA via PostMessage.
+ static void FetchRendererHistogramsAsynchronously(
+ MessageLoop* callback_thread, Task* callback_task, int wait_time);
+
+ // This method is called on the IO thread. Desrializes the histograms and
+ // records that we have received histograms from a renderer process.
+ static void DeserializeHistogramList(
+ int sequence_number, const std::vector<std::string>& histograms);
+
+ private:
+ // Records that we have received the histograms from a renderer for the given
+ // sequence number. If we have received a response from all histograms, either
+ // signal the waiting process or call the callback function. Returns true when
+ // we receive histograms from the last of N renderers that were contacted for
+ // an update. This is called on IO Thread.
+ bool RecordRendererHistogram(int sequence_number);
+
+ void SetCallbackTaskToCallAfterGettingHistograms(
+ MessageLoop* callback_thread, Task* callback_task);
+
+ void ForceHistogramSynchronizationDoneCallback(int sequence_number);
+
+ // Calls the callback task, if there is a callback_task.
+ void CallCallbackTaskAndResetData();
+
+ // Gets a new sequence number to be sent to renderers from broswer process.
+ // This will also reset the current pending renderers for the given type.
+ int GetNextAvaibleSequenceNumber(RendererHistogramRequester requster);
+
+ // Increments the count of the renderers we're waiting for for the request
+ // of the given type.
+ void IncrementPendingRenderers(RendererHistogramRequester requester);
+
+ // For use ONLY in a DCHECK. This method initializes io_message_loop_ in its
+ // first call and then compares io_message_loop_ with MessageLoop::current()
+ // in subsequent calls. This method guarantees we're consistently on the
+ // singular IO thread and we don't need to worry about locks.
+ bool IsOnIoThread();
+
+ // This lock_ protects access to sequence number and
+ // synchronous_renderers_pending_.
+ Lock lock_;
+
+ // This condition variable is used to block caller of the synchronous request
+ // to update histograms, and to signal that thread when updates are completed.
+ ConditionVariable received_all_renderer_historgrams_;
+
+ // When a request is made to asynchronously update the histograms, we store
+ // the task and thread we use to post a completion notification in
+ // callback_task_ and callback_thread_.
+ Task* callback_task_;
+ MessageLoop* callback_thread_;
+
+ // For use ONLY in a DCHECK and is used in IsOnIoThread(). io_message_loop_ is
+ // initialized during the first call to IsOnIoThread(), and then compares
+ // MessageLoop::current() against io_message_loop_ in subsequent calls for
+ // consistency.
+ MessageLoop* io_message_loop_;
+
+ // We don't track the actual renderers that are contacted for an update, only
+ // the count of the number of renderers, and we can sometimes time-out and
+ // give up on a "slow to respond" renderer. We use a sequence_number to be
+ // sure a response from a renderer is associated with the current round of
+ // requests (and not merely a VERY belated prior response).
+ // next_available_sequence_number_ is the next available number (used to
+ // avoid reuse for a long time).
+ int next_available_sequence_number_;
+
+ // The sequence number used by the most recent asynchronous update request to
+ // contact all renderers.
+ int async_sequence_number_;
+
+ // The number of renderers that have not yet responded to requests (as part of
+ // an asynchronous update).
+ int async_renderers_pending_;
+
+ // The time when we were told to start the fetch histograms asynchronously
+ // from renderers.
+ base::TimeTicks async_callback_start_time_;
+
+ // The sequence number used by the most recent synchronous update request to
+ // contact all renderers.
+ int synchronous_sequence_number_;
+
+ // The number of renderers that have not yet responded to requests (as part of
+ // a synchronous update).
+ int synchronous_renderers_pending_;
+
+ // This singleton instance should be started during the single threaded
+ // portion of main(). It initializes globals to provide support for all future
+ // calls. This object is created on the UI thread, and it is destroyed after
+ // all the other threads have gone away. As a result, it is ok to call it
+ // from the UI thread (for UMA uploads), or for about:histograms.
+ static HistogramSynchronizer* histogram_synchronizer_;
+
+ DISALLOW_COPY_AND_ASSIGN(HistogramSynchronizer);
+};
+
+#endif // CHROME_BROWSER_METRICS_HISTOGRAM_SYNCHRONIZER_H_
diff --git a/chrome/browser/metrics/metrics_service.cc b/chrome/browser/metrics/metrics_service.cc
index dbd48fa..6b4ebbb 100644
--- a/chrome/browser/metrics/metrics_service.cc
+++ b/chrome/browser/metrics/metrics_service.cc
@@ -174,13 +174,13 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/load_notification_details.h"
#include "chrome/browser/memory_details.h"
+#include "chrome/browser/metrics/histogram_synchronizer.h"
#include "chrome/browser/pref_service.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/search_engines/template_url_model.h"
#include "chrome/common/child_process_logging.h"
#include "chrome/common/chrome_switches.h"
-#include "chrome/common/histogram_synchronizer.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/render_messages.h"
diff --git a/chrome/browser/renderer_host/buffered_resource_handler.cc b/chrome/browser/renderer_host/buffered_resource_handler.cc
index d58bed5..a7d36af 100644
--- a/chrome/browser/renderer_host/buffered_resource_handler.cc
+++ b/chrome/browser/renderer_host/buffered_resource_handler.cc
@@ -15,6 +15,7 @@
#include "chrome/browser/renderer_host/resource_dispatcher_host_request_info.h"
#include "chrome/browser/renderer_host/x509_user_cert_resource_handler.h"
#include "chrome/common/extensions/user_script.h"
+#include "chrome/common/resource_response.h"
#include "chrome/common/url_constants.h"
#include "net/base/io_buffer.h"
#include "net/base/mime_sniffer.h"
diff --git a/chrome/browser/renderer_host/cross_site_resource_handler.h b/chrome/browser/renderer_host/cross_site_resource_handler.h
index fc6bef2..ddb289f 100644
--- a/chrome/browser/renderer_host/cross_site_resource_handler.h
+++ b/chrome/browser/renderer_host/cross_site_resource_handler.h
@@ -6,6 +6,7 @@
#define CHROME_BROWSER_RENDERER_HOST_CROSS_SITE_RESOURCE_HANDLER_H_
#include "chrome/browser/renderer_host/resource_handler.h"
+#include "net/url_request/url_request_status.h"
class ResourceDispatcherHost;
struct GlobalRequestID;
diff --git a/chrome/browser/renderer_host/download_resource_handler.cc b/chrome/browser/renderer_host/download_resource_handler.cc
index 1bbb757..e0aa870 100644
--- a/chrome/browser/renderer_host/download_resource_handler.cc
+++ b/chrome/browser/renderer_host/download_resource_handler.cc
@@ -10,6 +10,7 @@
#include "chrome/browser/download/download_manager.h"
#include "chrome/browser/renderer_host/global_request_id.h"
#include "chrome/browser/renderer_host/resource_dispatcher_host.h"
+#include "chrome/common/resource_response.h"
#include "net/base/io_buffer.h"
#include "net/url_request/url_request_context.h"
diff --git a/chrome/browser/renderer_host/download_throttling_resource_handler.cc b/chrome/browser/renderer_host/download_throttling_resource_handler.cc
index 87314dc..4609a4c 100644
--- a/chrome/browser/renderer_host/download_throttling_resource_handler.cc
+++ b/chrome/browser/renderer_host/download_throttling_resource_handler.cc
@@ -7,6 +7,7 @@
#include "base/logging.h"
#include "chrome/browser/renderer_host/download_resource_handler.h"
#include "chrome/browser/renderer_host/resource_dispatcher_host.h"
+#include "chrome/common/resource_response.h"
#include "net/base/io_buffer.h"
DownloadThrottlingResourceHandler::DownloadThrottlingResourceHandler(
diff --git a/chrome/browser/renderer_host/resource_handler.h b/chrome/browser/renderer_host/resource_handler.h
index 59f89c7..526c6a2 100644
--- a/chrome/browser/renderer_host/resource_handler.h
+++ b/chrome/browser/renderer_host/resource_handler.h
@@ -15,45 +15,14 @@
#include <string>
#include "chrome/browser/chrome_thread.h"
-#include "chrome/common/filter_policy.h"
-#include "net/url_request/url_request_status.h"
-#include "webkit/glue/resource_loader_bridge.h"
namespace net {
class IOBuffer;
}
-// Parameters for a resource response header.
-struct ResourceResponseHead
- : webkit_glue::ResourceLoaderBridge::ResponseInfo {
- ResourceResponseHead() : filter_policy(FilterPolicy::DONT_FILTER) {}
-
- // The response status.
- URLRequestStatus status;
-
- // Specifies if the resource should be filtered before being displayed
- // (insecure resources can be filtered to keep the page secure).
- FilterPolicy::Type filter_policy;
-};
-
-// Parameters for a synchronous resource response.
-struct SyncLoadResult : ResourceResponseHead {
- // The final URL after any redirects.
- GURL final_url;
-
- // The response data.
- std::string data;
-};
-
-// Simple wrapper that refcounts ResourceResponseHead.
-struct ResourceResponse : public base::RefCounted<ResourceResponse> {
- ResourceResponseHead response_head;
-
- private:
- friend class base::RefCounted<ResourceResponse>;
-
- ~ResourceResponse() {}
-};
+struct ResourceResponse;
+class GURL;
+class URLRequestStatus;
// The resource dispatcher host uses this interface to push load events to the
// renderer, allowing for differences in the types of IPC messages generated.
diff --git a/chrome/browser/renderer_host/resource_message_filter.cc b/chrome/browser/renderer_host/resource_message_filter.cc
index 9e9833c..2460db3 100644
--- a/chrome/browser/renderer_host/resource_message_filter.cc
+++ b/chrome/browser/renderer_host/resource_message_filter.cc
@@ -17,12 +17,12 @@
#include "chrome/browser/chrome_plugin_browsing_context.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/download/download_file.h"
-#include "chrome/browser/extensions/extension_file_util.h"
#include "chrome/browser/extensions/extension_message_service.h"
#include "chrome/browser/geolocation/geolocation_permission_context.h"
#include "chrome/browser/geolocation/geolocation_dispatcher_host.h"
#include "chrome/browser/host_zoom_map.h"
#include "chrome/browser/in_process_webkit/dom_storage_dispatcher_host.h"
+#include "chrome/browser/metrics/histogram_synchronizer.h"
#include "chrome/browser/nacl_host/nacl_process_host.h"
#include "chrome/browser/net/chrome_url_request_context.h"
#include "chrome/browser/net/dns_global.h"
@@ -49,8 +49,8 @@
#include "chrome/common/chrome_plugin_util.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension_constants.h"
+#include "chrome/common/extensions/extension_file_util.h"
#include "chrome/common/extensions/extension_message_bundle.h"
-#include "chrome/common/histogram_synchronizer.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/render_messages.h"
diff --git a/chrome/browser/renderer_host/save_file_resource_handler.cc b/chrome/browser/renderer_host/save_file_resource_handler.cc
index b6584f0..c6f8de2 100644
--- a/chrome/browser/renderer_host/save_file_resource_handler.cc
+++ b/chrome/browser/renderer_host/save_file_resource_handler.cc
@@ -10,6 +10,7 @@
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/download/save_file_manager.h"
#include "net/base/io_buffer.h"
+#include "net/url_request/url_request_status.h"
SaveFileResourceHandler::SaveFileResourceHandler(int render_process_host_id,
int render_view_id,
diff --git a/chrome/browser/renderer_host/save_file_resource_handler.h b/chrome/browser/renderer_host/save_file_resource_handler.h
index 07eca4d..825ad91 100644
--- a/chrome/browser/renderer_host/save_file_resource_handler.h
+++ b/chrome/browser/renderer_host/save_file_resource_handler.h
@@ -8,6 +8,7 @@
#include <string>
#include "chrome/browser/renderer_host/resource_handler.h"
+#include "googleurl/src/gurl.h"
class SaveFileManager;
diff --git a/chrome/browser/renderer_host/sync_resource_handler.h b/chrome/browser/renderer_host/sync_resource_handler.h
index cb2ae22..d15fe0d 100644
--- a/chrome/browser/renderer_host/sync_resource_handler.h
+++ b/chrome/browser/renderer_host/sync_resource_handler.h
@@ -9,6 +9,7 @@
#include "chrome/browser/renderer_host/resource_dispatcher_host.h"
#include "chrome/browser/renderer_host/resource_handler.h"
+#include "chrome/common/resource_response.h"
#include "net/base/io_buffer.h"
// Used to complete a synchronous resource request in response to resource load
diff --git a/chrome/browser/renderer_host/x509_user_cert_resource_handler.cc b/chrome/browser/renderer_host/x509_user_cert_resource_handler.cc
index 76dcedd..abf5541 100644
--- a/chrome/browser/renderer_host/x509_user_cert_resource_handler.cc
+++ b/chrome/browser/renderer_host/x509_user_cert_resource_handler.cc
@@ -10,6 +10,7 @@
#include "chrome/browser/download/download_file.h"
#include "chrome/browser/renderer_host/resource_dispatcher_host.h"
#include "chrome/browser/renderer_host/resource_dispatcher_host_request_info.h"
+#include "chrome/common/resource_response.h"
#include "chrome/common/url_constants.h"
#include "net/base/cert_database.h"
#include "net/base/io_buffer.h"