summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandrewhayden@chromium.org <andrewhayden@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-30 11:27:19 +0000
committerandrewhayden@chromium.org <andrewhayden@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-30 11:27:19 +0000
commitfb53e6560669a1b4753c9d603d54103535cef824 (patch)
tree0c8f1a3670b16527fa01699509249f5eb5e3137f
parent10955d3b8976ffb9a2aada7f135798c5171fc424 (diff)
downloadchromium_src-fb53e6560669a1b4753c9d603d54103535cef824.zip
chromium_src-fb53e6560669a1b4753c9d603d54103535cef824.tar.gz
chromium_src-fb53e6560669a1b4753c9d603d54103535cef824.tar.bz2
Add a component updater for the CLD2 data file.
BUG=326023,367239 Review URL: https://codereview.chromium.org/216923006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@267181 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--build/common.gypi13
-rw-r--r--chrome/browser/chrome_browser_main.cc5
-rw-r--r--chrome/browser/component_updater/cld_component_installer.cc157
-rw-r--r--chrome/browser/component_updater/cld_component_installer.h24
-rw-r--r--chrome/browser/component_updater/component_unpacker.cc7
-rw-r--r--chrome/browser/component_updater/component_updater_service.cc22
-rw-r--r--chrome/browser/component_updater/update_checker.cc4
-rw-r--r--chrome/browser/component_updater/url_fetcher_downloader.cc8
-rw-r--r--chrome/browser/translate/translate_tab_helper.cc10
-rw-r--r--chrome/chrome_browser.gypi2
-rw-r--r--chrome/common/chrome_paths.cc7
-rw-r--r--chrome/common/chrome_paths.h2
-rw-r--r--third_party/cld_2/crx_gen/manifest.json12
13 files changed, 272 insertions, 1 deletions
diff --git a/build/common.gypi b/build/common.gypi
index df2858e..9fae86e 100644
--- a/build/common.gypi
+++ b/build/common.gypi
@@ -446,6 +446,14 @@
# be loaded at runtime.
'cld2_dynamic%': 0,
+ # Whether CLD2 is a component. Only evaluated if cld_version == 2 and
+ # cld2_dynamic == 1.
+ # 0: Not a component. If cld2_dynamic == 1, it is up to the distribution
+ # to ensure that the data file is provided if desired.
+ # 1: Componentized. CLD data should be obtained via the Component
+ # Updater.
+ 'cld2_is_component%': 0,
+
# Enable spell checker.
'enable_spellcheck%': 1,
@@ -646,6 +654,7 @@
'enable_google_now%': 0,
'cld_version%': 1,
'cld2_dynamic%': 0,
+ 'cld2_is_component%': 0,
'enable_spellcheck%': 0,
'enable_themes%': 0,
'remoting%': 0,
@@ -1015,6 +1024,7 @@
'cld_version%': '<(cld_version)',
'cld2_table_size%': '<(cld2_table_size)',
'cld2_dynamic%': '<(cld2_dynamic)',
+ 'cld2_is_component%': '<(cld2_is_component)',
'enable_captive_portal_detection%': '<(enable_captive_portal_detection)',
'disable_ftp_support%': '<(disable_ftp_support)',
'enable_task_manager%': '<(enable_task_manager)',
@@ -2562,6 +2572,9 @@
['cld2_dynamic!=0', {
'defines': ['CLD2_DYNAMIC_MODE=1'],
}],
+ ['cld2_is_component!=0', {
+ 'defines': ['CLD2_IS_COMPONENT=1'],
+ }],
['enable_printing==1', {
'defines': ['ENABLE_FULL_PRINTING=1', 'ENABLE_PRINTING=1'],
}],
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc
index 558942f..19c4cad 100644
--- a/chrome/browser/chrome_browser_main.cc
+++ b/chrome/browser/chrome_browser_main.cc
@@ -42,6 +42,7 @@
#include "chrome/browser/browser_process_platform_part.h"
#include "chrome/browser/browser_shutdown.h"
#include "chrome/browser/chrome_browser_main_extra_parts.h"
+#include "chrome/browser/component_updater/cld_component_installer.h"
#include "chrome/browser/component_updater/component_updater_service.h"
#include "chrome/browser/component_updater/flash_component_installer.h"
#include "chrome/browser/component_updater/pnacl/pnacl_component_installer.h"
@@ -406,6 +407,10 @@ void RegisterComponentsForUpdate(const CommandLine& command_line) {
g_browser_process->crl_set_fetcher()->StartInitialLoad(cus);
#endif
+#if defined(CLD2_DYNAMIC_MODE) && defined(CLD2_IS_COMPONENT)
+ RegisterCldComponent(cus);
+#endif
+
cus->Start();
}
diff --git a/chrome/browser/component_updater/cld_component_installer.cc b/chrome/browser/component_updater/cld_component_installer.cc
new file mode 100644
index 0000000..6e493ac
--- /dev/null
+++ b/chrome/browser/component_updater/cld_component_installer.cc
@@ -0,0 +1,157 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/component_updater/cld_component_installer.h"
+
+#include "base/bind.h"
+#include "base/file_util.h"
+#include "base/files/file_path.h"
+#include "base/lazy_instance.h"
+#include "base/logging.h"
+#include "base/path_service.h"
+#include "base/platform_file.h"
+#include "chrome/browser/component_updater/default_component_installer.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/common/chrome_constants.h"
+#include "chrome/common/chrome_paths.h"
+#include "content/public/browser/browser_thread.h"
+#include "net/ssl/ssl_config_service.h"
+
+using component_updater::ComponentUpdateService;
+using content::BrowserThread;
+
+namespace {
+
+// Once we have acquired a valid file from the component installer, we need to
+// make the path available to other parts of the system such as the
+// translation libraries. We create a global to hold onto the path, and a
+// lock to guard it. See GetLatestCldDataFile(...) for more info.
+base::LazyInstance<base::Lock> cld_file_lock = LAZY_INSTANCE_INITIALIZER;
+base::LazyInstance<base::FilePath> cld_file = LAZY_INSTANCE_INITIALIZER;
+
+}
+
+namespace component_updater {
+
+// The SHA256 of the SubjectPublicKeyInfo used to sign the extension.
+// The extension id is: dpedmmgabcgnikllifiidmijgoiihfgf
+const uint8 kPublicKeySHA256[32] = {
+ 0x3f, 0x43, 0xcc, 0x60, 0x12, 0x6d, 0x8a, 0xbb,
+ 0x85, 0x88, 0x3c, 0x89, 0x6e, 0x88, 0x75, 0x65,
+ 0xb9, 0x46, 0x09, 0xe8, 0xca, 0x92, 0xdd, 0x82,
+ 0x4e, 0x6d, 0x0e, 0xe6, 0x79, 0x8a, 0x87, 0xf5
+};
+
+const char kCldManifestName[] = "CLD2 Data";
+
+class CldComponentInstallerTraits : public ComponentInstallerTraits {
+ public:
+ CldComponentInstallerTraits();
+ virtual ~CldComponentInstallerTraits() {}
+
+ private:
+ // The following methods override ComponentInstallerTraits.
+ virtual bool CanAutoUpdate() const OVERRIDE;
+ virtual bool OnCustomInstall(const base::DictionaryValue& manifest,
+ const base::FilePath& install_dir) OVERRIDE;
+ virtual bool VerifyInstallation(
+ const base::FilePath& install_dir) const OVERRIDE;
+ virtual void ComponentReady(
+ const base::Version& version,
+ const base::FilePath& path,
+ scoped_ptr<base::DictionaryValue> manifest) OVERRIDE;
+ virtual base::FilePath GetBaseDirectory() const OVERRIDE;
+ virtual void GetHash(std::vector<uint8>* hash) const OVERRIDE;
+ virtual std::string GetName() const OVERRIDE;
+
+ base::FilePath GetInstalledPath(const base::FilePath& base) const;
+ void SetLatestCldDataFile(const base::FilePath& path);
+ DISALLOW_COPY_AND_ASSIGN(CldComponentInstallerTraits);
+};
+
+CldComponentInstallerTraits::CldComponentInstallerTraits() {
+}
+
+bool CldComponentInstallerTraits::CanAutoUpdate() const {
+ return true;
+}
+
+bool CldComponentInstallerTraits::OnCustomInstall(
+ const base::DictionaryValue& manifest,
+ const base::FilePath& install_dir) {
+ return true; // Nothing custom here.
+}
+
+base::FilePath CldComponentInstallerTraits::GetInstalledPath(
+ const base::FilePath& base) const {
+ // Currently, all platforms have the file at the same location because there
+ // is no binary difference in the generated file on any supported platform.
+ // NB: This may change when 64-bit is officially supported.
+ return base.Append(FILE_PATH_LITERAL("_platform_specific"))
+ .Append(FILE_PATH_LITERAL("all"))
+ .Append(chrome::kCLDDataFilename);
+}
+
+void CldComponentInstallerTraits::ComponentReady(
+ const base::Version& version,
+ const base::FilePath& path,
+ scoped_ptr<base::DictionaryValue> manifest) {
+ VLOG(1) << "Component ready, version " << version.GetString()
+ << " in " << path.value();
+ SetLatestCldDataFile(GetInstalledPath(path));
+}
+
+bool CldComponentInstallerTraits::VerifyInstallation(
+ const base::FilePath& install_dir) const {
+ // We can't really do much to verify the CLD2 data file. In theory we could
+ // read the headers, but that won't do much other than tell us whether or
+ // not the headers are valid. So just check if the file exists.
+ const base::FilePath expected_file = GetInstalledPath(install_dir);
+ VLOG(1) << "Verifying install: " << expected_file.value();
+ const bool result = base::PathExists(expected_file);
+ VLOG(1) << "Verification result: " << (result ? "valid" : "invalid");
+ return result;
+}
+
+base::FilePath CldComponentInstallerTraits::GetBaseDirectory() const {
+ base::FilePath result;
+ PathService::Get(chrome::DIR_COMPONENT_CLD2, &result);
+ return result;
+}
+
+void CldComponentInstallerTraits::GetHash(std::vector<uint8>* hash) const {
+ hash->assign(kPublicKeySHA256,
+ kPublicKeySHA256 + arraysize(kPublicKeySHA256));
+}
+
+std::string CldComponentInstallerTraits::GetName() const {
+ return kCldManifestName;
+}
+
+void RegisterCldComponent(ComponentUpdateService* cus) {
+ scoped_ptr<ComponentInstallerTraits> traits(
+ new CldComponentInstallerTraits());
+ // |cus| will take ownership of |installer| during installer->Register(cus).
+ DefaultComponentInstaller* installer
+ = new DefaultComponentInstaller(traits.Pass());
+ installer->Register(cus);
+}
+
+// This method is completely threadsafe.
+void CldComponentInstallerTraits::SetLatestCldDataFile(
+ const base::FilePath& path) {
+ VLOG(1) << "Setting CLD data file location: " << path.value();
+ base::AutoLock lock(cld_file_lock.Get());
+ cld_file.Get() = path;
+}
+
+bool GetLatestCldDataFile(base::FilePath* path) {
+ base::AutoLock lock(cld_file_lock.Get());
+ const base::FilePath cached = cld_file.Get();
+ if (cached.empty()) return false;
+ *path = cached;
+ return true;
+}
+
+} // namespace component_updater
diff --git a/chrome/browser/component_updater/cld_component_installer.h b/chrome/browser/component_updater/cld_component_installer.h
new file mode 100644
index 0000000..20a4b3c
--- /dev/null
+++ b/chrome/browser/component_updater/cld_component_installer.h
@@ -0,0 +1,24 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_COMPONENT_UPDATER_CLD_COMPONENT_INSTALLER_H_
+#define CHROME_BROWSER_COMPONENT_UPDATER_CLD_COMPONENT_INSTALLER_H_
+
+#include "base/files/file_path.h"
+
+namespace component_updater {
+
+class ComponentUpdateService;
+
+void RegisterCldComponent(ComponentUpdateService* cus);
+
+// Places the path to the latest CLD data file into the specified path object.
+// Returns true if and only if the file has been observed to exist at least
+// once and was valid when it was observed; if the function returns false, the
+// path parameter is not modified. This function is threadsafe.
+bool GetLatestCldDataFile(base::FilePath* path);
+
+} // namespace component_updater
+
+#endif // CHROME_BROWSER_COMPONENT_UPDATER_CLD_COMPONENT_INSTALLER_H_
diff --git a/chrome/browser/component_updater/component_unpacker.cc b/chrome/browser/component_updater/component_unpacker.cc
index 49aafac..48c584c 100644
--- a/chrome/browser/component_updater/component_unpacker.cc
+++ b/chrome/browser/component_updater/component_unpacker.cc
@@ -143,6 +143,7 @@ void ComponentUnpacker::Unpack(const Callback& callback) {
}
bool ComponentUnpacker::Verify() {
+ VLOG(1) << "Verifying component: " << path_.value();
if (pk_hash_.empty() || path_.empty()) {
error_ = kInvalidParams;
return false;
@@ -171,23 +172,29 @@ bool ComponentUnpacker::Verify() {
sha256->Finish(hash, arraysize(hash));
if (!std::equal(pk_hash_.begin(), pk_hash_.end(), hash)) {
+ VLOG(1) << "Hash mismatch: " << path_.value();
error_ = kInvalidId;
return false;
}
+ VLOG(1) << "Verification successful: " << path_.value();
return true;
}
bool ComponentUnpacker::Unzip() {
base::FilePath& destination = is_delta_ ? unpack_diff_path_ : unpack_path_;
+ VLOG(1) << "Unpacking in: " << destination.value();
if (!base::CreateNewTempDirectory(base::FilePath::StringType(),
&destination)) {
+ VLOG(1) << "Unable to create temporary directory for unpacking.";
error_ = kUnzipPathError;
return false;
}
if (!zip::Unzip(path_, destination)) {
+ VLOG(1) << "Unzipping failed.";
error_ = kUnzipFailed;
return false;
}
+ VLOG(1) << "Unpacked successfully";
return true;
}
diff --git a/chrome/browser/component_updater/component_updater_service.cc b/chrome/browser/component_updater/component_updater_service.cc
index 2a8d14f..5d6e71d 100644
--- a/chrome/browser/component_updater/component_updater_service.cc
+++ b/chrome/browser/component_updater/component_updater_service.cc
@@ -313,12 +313,15 @@ ComponentUpdateService::Status CrxUpdateService::Start() {
// Note that RegisterComponent will call Start() when the first
// component is registered, so it can be called twice. This way
// we avoid scheduling the timer if there is no work to do.
+ VLOG(1) << "CrxUpdateService starting up";
running_ = true;
if (work_items_.empty())
return kOk;
NotifyObservers(Observer::COMPONENT_UPDATER_STARTED, "");
+ VLOG(1) << "First update attempt will take place in "
+ << config_->InitialDelay() << " seconds";
timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(config_->InitialDelay()),
this, &CrxUpdateService::ProcessPendingItems);
return kOk;
@@ -327,6 +330,7 @@ ComponentUpdateService::Status CrxUpdateService::Start() {
// Stop the main check + update loop. In flight operations will be
// completed.
ComponentUpdateService::Status CrxUpdateService::Stop() {
+ VLOG(1) << "CrxUpdateService stopping";
running_ = false;
timer_.Stop();
return kOk;
@@ -389,6 +393,7 @@ void CrxUpdateService::ScheduleNextRun(StepDelayInterval step_delay) {
return;
}
+ VLOG(1) << "Scheduling next run to occur in " << delay_seconds << " seconds";
timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(delay_seconds),
this, &CrxUpdateService::ProcessPendingItems);
}
@@ -620,9 +625,18 @@ bool CrxUpdateService::CheckForUpdates() {
if (!item->on_demand &&
time_since_last_checked < minimum_recheck_wait_time) {
+ VLOG(1) << "Skipping check for component update: id=" << item->id
+ << ", time_since_last_checked="
+ << time_since_last_checked.InSeconds()
+ << " seconds: too soon to check for an update";
continue;
}
+ VLOG(1) << "Scheduling update check for component id=" << item->id
+ << ", time_since_last_checked="
+ << time_since_last_checked.InSeconds()
+ << " seconds";
+
ChangeItemState(item, CrxUpdateItem::kChecking);
item->last_check = now;
@@ -710,6 +724,7 @@ void CrxUpdateService::OnUpdateCheckSucceeded(
const UpdateResponse::Results& results) {
size_t num_updates_pending = 0;
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ VLOG(1) << "Update check succeeded.";
std::vector<UpdateResponse::Result>::const_iterator it;
for (it = results.list.begin(); it != results.list.end(); ++it) {
CrxUpdateItem* crx = FindUpdateItemById(it->extension_id);
@@ -724,18 +739,21 @@ void CrxUpdateService::OnUpdateCheckSucceeded(
if (it->manifest.version.empty()) {
// No version means no update available.
ChangeItemState(crx, CrxUpdateItem::kNoUpdate);
+ VLOG(1) << "No update available for component: " << crx->id;
continue;
}
if (!IsVersionNewer(crx->component.version, it->manifest.version)) {
// The component is up to date.
ChangeItemState(crx, CrxUpdateItem::kUpToDate);
+ VLOG(1) << "Component already up-to-date: " << crx->id;
continue;
}
if (!it->manifest.browser_min_version.empty()) {
if (IsVersionNewer(chrome_version_, it->manifest.browser_min_version)) {
// The component is not compatible with this Chrome version.
+ VLOG(1) << "Ignoring incompatible component: " << crx->id;
ChangeItemState(crx, CrxUpdateItem::kNoUpdate);
continue;
}
@@ -743,6 +761,7 @@ void CrxUpdateService::OnUpdateCheckSucceeded(
if (it->manifest.packages.size() != 1) {
// Assume one and only one package per component.
+ VLOG(1) << "Ignoring multiple packages for component: " << crx->id;
ChangeItemState(crx, CrxUpdateItem::kNoUpdate);
continue;
}
@@ -750,6 +769,8 @@ void CrxUpdateService::OnUpdateCheckSucceeded(
// Parse the members of the result and queue an upgrade for this component.
crx->next_version = Version(it->manifest.version);
+ VLOG(1) << "Update found for component: " << crx->id;
+
typedef UpdateResponse::Result::Manifest::Package Package;
const Package& package(it->manifest.packages[0]);
crx->next_fp = package.fingerprint;
@@ -787,6 +808,7 @@ void CrxUpdateService::OnUpdateCheckFailed(int error,
size_t count = ChangeItemStatus(CrxUpdateItem::kChecking,
CrxUpdateItem::kNoUpdate);
DCHECK_GT(count, 0ul);
+ VLOG(1) << "Update check failed.";
ScheduleNextRun(kStepDelayLong);
}
diff --git a/chrome/browser/component_updater/update_checker.cc b/chrome/browser/component_updater/update_checker.cc
index f1800cd..bd2fc0a 100644
--- a/chrome/browser/component_updater/update_checker.cc
+++ b/chrome/browser/component_updater/update_checker.cc
@@ -5,6 +5,7 @@
#include "chrome/browser/component_updater/update_checker.h"
#include "base/compiler_specific.h"
+#include "base/logging.h"
#include "base/strings/stringprintf.h"
#include "chrome/browser/component_updater/component_updater_utils.h"
#include "chrome/browser/component_updater/crx_update_item.h"
@@ -54,6 +55,7 @@ std::string BuildUpdateCheckRequest(const std::vector<CrxUpdateItem*>& items,
}
base::StringAppendF(&app, "</app>");
app_elements.append(app);
+ VLOG(1) << "Appending to update request: " << app;
}
return BuildProtocolRequest(app_elements, additional_attributes);
@@ -140,10 +142,12 @@ void UpdateCheckerImpl::OnURLFetchComplete(const net::URLFetcher* source) {
if (!update_response.Parse(xml)) {
error = -1;
error_message = update_response.errors();
+ VLOG(1) << "Update request failed: " << error_message;
}
} else {
error = GetFetchError(*source);
error_message.assign("network error");
+ VLOG(1) << "Update request failed: network error";
}
url_fetcher_.reset();
diff --git a/chrome/browser/component_updater/url_fetcher_downloader.cc b/chrome/browser/component_updater/url_fetcher_downloader.cc
index d2d2f31..39579cd 100644
--- a/chrome/browser/component_updater/url_fetcher_downloader.cc
+++ b/chrome/browser/component_updater/url_fetcher_downloader.cc
@@ -4,6 +4,7 @@
#include "chrome/browser/component_updater/url_fetcher_downloader.h"
+#include "base/logging.h"
#include "chrome/browser/component_updater/component_updater_utils.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/load_flags.h"
@@ -42,6 +43,7 @@ void UrlFetcherDownloader::DoStartDownload(const GURL& url) {
url_fetcher_->SetAutomaticallyRetryOn5xx(false);
url_fetcher_->SaveResponseToTemporaryFile(task_runner_);
+ VLOG(1) << "Starting background download: " << url.spec();
url_fetcher_->Start();
download_start_time_ = base::Time::Now();
@@ -78,6 +80,12 @@ void UrlFetcherDownloader::OnURLFetchComplete(const net::URLFetcher* source) {
download_metrics.bytes_total = total_bytes_;
download_metrics.download_time_ms = download_time.InMilliseconds();
+ base::FilePath local_path_;
+ source->GetResponseAsFilePath(false, &local_path_);
+ VLOG(1) << "Downloaded " << downloaded_bytes_ << " bytes in "
+ << download_time.InMilliseconds() << "ms from "
+ << source->GetURL().spec()
+ << " to " << local_path_.value();
CrxDownloader::OnDownloadComplete(is_handled, result, download_metrics);
}
diff --git a/chrome/browser/translate/translate_tab_helper.cc b/chrome/browser/translate/translate_tab_helper.cc
index 3ad5942..9af958f7 100644
--- a/chrome/browser/translate/translate_tab_helper.cc
+++ b/chrome/browser/translate/translate_tab_helper.cc
@@ -43,6 +43,10 @@
#include "content/public/browser/render_view_host.h"
#endif
+#if defined(CLD2_IS_COMPONENT)
+#include "chrome/browser/component_updater/cld_component_installer.h"
+#endif
+
namespace {
// The maximum number of attempts we'll do to see if the page has finshed
@@ -387,16 +391,20 @@ void TranslateTabHelper::HandleCLDDataRequest() {
}
base::FilePath path;
+#if defined(CLD2_IS_COMPONENT)
+ if (!component_updater::GetLatestCldDataFile(&path))
+ return;
+#else
if (!PathService::Get(chrome::DIR_USER_DATA, &path)) {
LOG(WARNING) << "Unable to locate user data directory";
return; // Chrome isn't properly installed.
}
-
// If the file exists, we can send an IPC-safe construct back to the
// renderer process immediately.
path = path.Append(chrome::kCLDDataFilename);
if (!base::PathExists(path))
return;
+#endif
// Attempt to open the file for reading.
scoped_ptr<base::File> file(
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 8983941..851ab1aa 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -430,6 +430,8 @@
'browser/common/cancelable_request.h',
'browser/component_updater/background_downloader_win.cc',
'browser/component_updater/background_downloader_win.h',
+ 'browser/component_updater/cld_component_installer.cc',
+ 'browser/component_updater/cld_component_installer.h',
'browser/component_updater/component_patcher.cc',
'browser/component_updater/component_patcher.h',
'browser/component_updater/component_patcher_operation.cc',
diff --git a/chrome/common/chrome_paths.cc b/chrome/common/chrome_paths.cc
index 352b51a..0cdfbd40 100644
--- a/chrome/common/chrome_paths.cc
+++ b/chrome/common/chrome_paths.cc
@@ -364,6 +364,13 @@ bool PathProvider(int key, base::FilePath* result) {
cur = cur.Append(kGTalkPluginFileName);
break;
#endif
+#if defined(CLD2_IS_COMPONENT)
+ case chrome::DIR_COMPONENT_CLD2:
+ if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
+ return false;
+ cur = cur.Append(FILE_PATH_LITERAL("CLD"));
+ break;
+#endif // defined(CLD2_IS_COMPONENT)
#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS)
#if defined(WIDEVINE_CDM_IS_COMPONENT)
case chrome::DIR_COMPONENT_WIDEVINE_CDM:
diff --git a/chrome/common/chrome_paths.h b/chrome/common/chrome_paths.h
index e03fe9f..407715d 100644
--- a/chrome/common/chrome_paths.h
+++ b/chrome/common/chrome_paths.h
@@ -94,6 +94,8 @@ enum {
FILE_O1D_PLUGIN, // Full path to the O1D Pepper plugin file.
FILE_EFFECTS_PLUGIN, // Full path to the Effects Pepper plugin file.
FILE_GTALK_PLUGIN, // Full path to the GTalk Pepper plugin file.
+ DIR_COMPONENT_CLD2, // Directory that contains component-updated
+ // Compact Language Detector files
DIR_COMPONENT_WIDEVINE_CDM, // Directory that contains component-updated
// Widevine CDM files.
FILE_WIDEVINE_CDM_ADAPTER, // Full path to the Widevine CDM adapter file.
diff --git a/third_party/cld_2/crx_gen/manifest.json b/third_party/cld_2/crx_gen/manifest.json
new file mode 100644
index 0000000..4b3a098
--- /dev/null
+++ b/third_party/cld_2/crx_gen/manifest.json
@@ -0,0 +1,12 @@
+{
+ "manifest_version": 2,
+ "name": "CLD2 Data",
+ "description": "Compact Language Detector 2 (CLD2) data for Chrome",
+ "minimum_chrome_version": "36",
+ "version": "160",
+ "platforms": [
+ {
+ "sub_package_path": "_platform_specific/all/"
+ }
+ ]
+} \ No newline at end of file