15c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Copyright 2014 The Chromium Authors. All rights reserved.
25c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Use of this source code is governed by a BSD-style license that can be
35c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// found in the LICENSE file.
45c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
55c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "chrome/browser/component_updater/cld_component_installer.h"
65c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
7010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include <string>
8010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include <vector>
9010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/bind.h"
115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/files/file_path.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/lazy_instance.h"
145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/logging.h"
155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/path_service.h"
16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/component_updater/component_updater_paths.h"
175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/translate/content/browser/browser_cld_data_provider.h"
185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/translate/content/common/cld_data_source.h"
195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "content/public/browser/browser_thread.h"
205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "net/ssl/ssl_config_service.h"
215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuusing component_updater::ComponentUpdateService;
235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunamespace {
25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// TODO(andrewhayden): Make the data file path into a gyp/gn define
26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// If you change this, also update component_cld_data_harness.cc
27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// and cld_component_installer_unittest.cc accordingly!
28116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst base::FilePath::CharType kCldDataFileName[] =
295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  FILE_PATH_LITERAL("cld2_data.bin");
305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Tracks the last value seen in SetLatestCldDataFile.
325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)base::LazyInstance<base::FilePath>::Leaky g_latest_cld_data_file =
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  LAZY_INSTANCE_INITIALIZER;
34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace
355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunamespace component_updater {
375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// The SHA256 of the SubjectPublicKeyInfo used to sign the extension.
395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// The extension id is: dpedmmgabcgnikllifiidmijgoiihfgf
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst uint8_t kPublicKeySHA256[32] = {
41010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    0x3f, 0x43, 0xcc, 0x60, 0x12, 0x6d, 0x8a, 0xbb,
42010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    0x85, 0x88, 0x3c, 0x89, 0x6e, 0x88, 0x75, 0x65,
43010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    0xb9, 0x46, 0x09, 0xe8, 0xca, 0x92, 0xdd, 0x82,
44010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    0x4e, 0x6d, 0x0e, 0xe6, 0x79, 0x8a, 0x87, 0xf5
455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu};
465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuconst char kCldManifestName[] = "CLD2 Data";
485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuCldComponentInstallerTraits::CldComponentInstallerTraits() {
505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool CldComponentInstallerTraits::CanAutoUpdate() const {
535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return true;
545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool CldComponentInstallerTraits::OnCustomInstall(
575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const base::DictionaryValue& manifest,
585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const base::FilePath& install_dir) {
59010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return true;  // Nothing custom here.
605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubase::FilePath CldComponentInstallerTraits::GetInstalledPath(
63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const base::FilePath& base) {
645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Currently, all platforms have the file at the same location because there
655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // is no binary difference in the generated file on any supported platform.
665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // NB: This may change when 64-bit is officially supported.
675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return base.Append(FILE_PATH_LITERAL("_platform_specific"))
685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      .Append(FILE_PATH_LITERAL("all"))
69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      .Append(kCldDataFileName);
705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid CldComponentInstallerTraits::ComponentReady(
735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const base::Version& version,
745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const base::FilePath& path,
755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    scoped_ptr<base::DictionaryValue> manifest) {
76010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  VLOG(1) << "Component ready, version " << version.GetString() << " in "
77010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          << path.value();
785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  SetLatestCldDataFile(GetInstalledPath(path));
795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool CldComponentInstallerTraits::VerifyInstallation(
825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const base::FilePath& install_dir) const {
835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // We can't really do much to verify the CLD2 data file. In theory we could
845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // read the headers, but that won't do much other than tell us whether or
855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // not the headers are valid. So just check if the file exists.
865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  const base::FilePath expected_file = GetInstalledPath(install_dir);
875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  VLOG(1) << "Verifying install: " << expected_file.value();
885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  const bool result = base::PathExists(expected_file);
895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  VLOG(1) << "Verification result: " << (result ? "valid" : "invalid");
905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return result;
915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubase::FilePath CldComponentInstallerTraits::GetBaseDirectory() const {
945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  base::FilePath result;
95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  PathService::Get(DIR_COMPONENT_CLD2, &result);
965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return result;
975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid CldComponentInstallerTraits::GetHash(std::vector<uint8_t>* hash) const {
1005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  hash->assign(kPublicKeySHA256,
1015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu               kPublicKeySHA256 + arraysize(kPublicKeySHA256));
1025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
1035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liustd::string CldComponentInstallerTraits::GetName() const {
1055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return kCldManifestName;
1065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
1075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid RegisterCldComponent(ComponentUpdateService* cus) {
1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Make sure we don't start up if the CLD data source isn't compatible.
1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!translate::CldDataSource::ShouldRegisterForComponentUpdates()) {
1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // This is a serious build-time configuration error.
1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    LOG(ERROR) << "Wrong CLD data source: " <<
1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        translate::CldDataSource::GetName();
1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    NOTREACHED();
1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // This log line is to help with determining which kind of provider has been
119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // configured. See also: chrome://translate-internals
120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  VLOG(1) << "Registering CLD component with the component update service";
121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_ptr<ComponentInstallerTraits> traits(
1235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      new CldComponentInstallerTraits());
1245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // |cus| will take ownership of |installer| during installer->Register(cus).
125010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DefaultComponentInstaller* installer =
126010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      new DefaultComponentInstaller(traits.Pass());
1275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  installer->Register(cus);
1285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
1295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid CldComponentInstallerTraits::SetLatestCldDataFile(
1315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const base::FilePath& path) {
1325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  VLOG(1) << "Setting CLD data file location: " << path.value();
1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  g_latest_cld_data_file.Get() = path;
1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  translate::SetCldDataFilePath(path);
1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)base::FilePath CldComponentInstallerTraits::GetLatestCldDataFile() {
1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return g_latest_cld_data_file.Get();
1395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
1405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}  // namespace component_updater
142