cld_component_installer.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
1c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko// Copyright 2014 The Chromium Authors. All rights reserved.
2c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko// Use of this source code is governed by a BSD-style license that can be
3c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko// found in the LICENSE file.
4c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko
5c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko#include "chrome/browser/component_updater/cld_component_installer.h"
6c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko
7c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko#include <string>
8c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko#include <vector>
9c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko
10c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko#include "base/bind.h"
11c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko#include "base/file_util.h"
12c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko#include "base/files/file_path.h"
13c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko#include "base/lazy_instance.h"
14c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko#include "base/logging.h"
156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "base/path_service.h"
16c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko#include "components/component_updater/component_updater_paths.h"
17c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko#include "components/translate/content/browser/browser_cld_data_provider.h"
188f1fa25a9e9f3fa4f2d7ecc0a08ebb08c0c4e642Dmitri Gribenko#include "components/translate/content/common/cld_data_source.h"
19c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko#include "content/public/browser/browser_thread.h"
20c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko#include "net/ssl/ssl_config_service.h"
21c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko
22c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenkousing component_updater::ComponentUpdateService;
236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
24c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenkonamespace {
25c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko// TODO(andrewhayden): Make the data file path into a gyp/gn define
266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// If you change this, also update component_cld_data_harness.cc
276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// and cld_component_installer_unittest.cc accordingly!
28c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenkoconst base::FilePath::CharType kCldDataFileName[] =
29c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko  FILE_PATH_LITERAL("cld2_data.bin");
30c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko
318f1fa25a9e9f3fa4f2d7ecc0a08ebb08c0c4e642Dmitri Gribenko// Tracks the last value seen in SetLatestCldDataFile.
32c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenkobase::LazyInstance<base::FilePath>::Leaky g_latest_cld_data_file =
33c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko  LAZY_INSTANCE_INITIALIZER;
34c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko}  // namespace
35c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko
36c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenkonamespace component_updater {
37c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko
38c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko// The SHA256 of the SubjectPublicKeyInfo used to sign the extension.
396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// The extension id is: dpedmmgabcgnikllifiidmijgoiihfgf
406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesconst uint8 kPublicKeySHA256[32] = {
41c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko    0x3f, 0x43, 0xcc, 0x60, 0x12, 0x6d, 0x8a, 0xbb,
42c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko    0x85, 0x88, 0x3c, 0x89, 0x6e, 0x88, 0x75, 0x65,
43c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko    0xb9, 0x46, 0x09, 0xe8, 0xca, 0x92, 0xdd, 0x82,
446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    0x4e, 0x6d, 0x0e, 0xe6, 0x79, 0x8a, 0x87, 0xf5
456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines};
46c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko
476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesconst char kCldManifestName[] = "CLD2 Data";
48c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko
496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen HinesCldComponentInstallerTraits::CldComponentInstallerTraits() {
50c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko}
51c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko
52c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenkobool CldComponentInstallerTraits::CanAutoUpdate() const {
538f1fa25a9e9f3fa4f2d7ecc0a08ebb08c0c4e642Dmitri Gribenko  return true;
54c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko}
55c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko
56c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenkobool CldComponentInstallerTraits::OnCustomInstall(
57c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko    const base::DictionaryValue& manifest,
58c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko    const base::FilePath& install_dir) {
59c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko  return true;  // Nothing custom here.
60c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko}
61c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko
62c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenkobase::FilePath CldComponentInstallerTraits::GetInstalledPath(
63c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko    const base::FilePath& base) {
64c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko  // Currently, all platforms have the file at the same location because there
65c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko  // is no binary difference in the generated file on any supported platform.
66  // NB: This may change when 64-bit is officially supported.
67  return base.Append(FILE_PATH_LITERAL("_platform_specific"))
68      .Append(FILE_PATH_LITERAL("all"))
69      .Append(kCldDataFileName);
70}
71
72void CldComponentInstallerTraits::ComponentReady(
73    const base::Version& version,
74    const base::FilePath& path,
75    scoped_ptr<base::DictionaryValue> manifest) {
76  VLOG(1) << "Component ready, version " << version.GetString() << " in "
77          << path.value();
78  SetLatestCldDataFile(GetInstalledPath(path));
79}
80
81bool CldComponentInstallerTraits::VerifyInstallation(
82    const base::FilePath& install_dir) const {
83  // We can't really do much to verify the CLD2 data file. In theory we could
84  // read the headers, but that won't do much other than tell us whether or
85  // not the headers are valid. So just check if the file exists.
86  const base::FilePath expected_file = GetInstalledPath(install_dir);
87  VLOG(1) << "Verifying install: " << expected_file.value();
88  const bool result = base::PathExists(expected_file);
89  VLOG(1) << "Verification result: " << (result ? "valid" : "invalid");
90  return result;
91}
92
93base::FilePath CldComponentInstallerTraits::GetBaseDirectory() const {
94  base::FilePath result;
95  PathService::Get(DIR_COMPONENT_CLD2, &result);
96  return result;
97}
98
99void CldComponentInstallerTraits::GetHash(std::vector<uint8>* hash) const {
100  hash->assign(kPublicKeySHA256,
101               kPublicKeySHA256 + arraysize(kPublicKeySHA256));
102}
103
104std::string CldComponentInstallerTraits::GetName() const {
105  return kCldManifestName;
106}
107
108void RegisterCldComponent(ComponentUpdateService* cus) {
109  // Make sure we don't start up if the CLD data source isn't compatible.
110  if (!translate::CldDataSource::ShouldRegisterForComponentUpdates()) {
111    // This is a serious build-time configuration error.
112    LOG(ERROR) << "Wrong CLD data source: " <<
113        translate::CldDataSource::GetName();
114    NOTREACHED();
115    return;
116  }
117
118  // This log line is to help with determining which kind of provider has been
119  // configured. See also: chrome://translate-internals
120  VLOG(1) << "Registering CLD component with the component update service";
121
122  scoped_ptr<ComponentInstallerTraits> traits(
123      new CldComponentInstallerTraits());
124  // |cus| will take ownership of |installer| during installer->Register(cus).
125  DefaultComponentInstaller* installer =
126      new DefaultComponentInstaller(traits.Pass());
127  installer->Register(cus);
128}
129
130void CldComponentInstallerTraits::SetLatestCldDataFile(
131    const base::FilePath& path) {
132  VLOG(1) << "Setting CLD data file location: " << path.value();
133  g_latest_cld_data_file.Get() = path;
134  translate::SetCldDataFilePath(path);
135}
136
137base::FilePath CldComponentInstallerTraits::GetLatestCldDataFile() {
138  return g_latest_cld_data_file.Get();
139}
140
141}  // namespace component_updater
142