cld_component_installer.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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/file_util.h"
125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/files/file_path.h"
135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/lazy_instance.h"
145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/logging.h"
155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/path_service.h"
165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/platform_file.h"
175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "chrome/browser/profiles/profile.h"
185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "chrome/common/chrome_constants.h"
195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "chrome/common/chrome_paths.h"
205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "content/public/browser/browser_thread.h"
215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "net/ssl/ssl_config_service.h"
225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuusing component_updater::ComponentUpdateService;
245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuusing content::BrowserThread;
255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunamespace {
275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Once we have acquired a valid file from the component installer, we need to
295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// make the path available to other parts of the system such as the
305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// translation libraries. We create a global to hold onto the path, and a
315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// lock to guard it. See GetLatestCldDataFile(...) for more info.
325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubase::LazyInstance<base::Lock> cld_file_lock = LAZY_INSTANCE_INITIALIZER;
335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubase::LazyInstance<base::FilePath> cld_file = LAZY_INSTANCE_INITIALIZER;
345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunamespace component_updater {
385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// The SHA256 of the SubjectPublicKeyInfo used to sign the extension.
405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// The extension id is: dpedmmgabcgnikllifiidmijgoiihfgf
415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuconst uint8 kPublicKeySHA256[32] = {
42010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    0x3f, 0x43, 0xcc, 0x60, 0x12, 0x6d, 0x8a, 0xbb,
43010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    0x85, 0x88, 0x3c, 0x89, 0x6e, 0x88, 0x75, 0x65,
44010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    0xb9, 0x46, 0x09, 0xe8, 0xca, 0x92, 0xdd, 0x82,
45010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    0x4e, 0x6d, 0x0e, 0xe6, 0x79, 0x8a, 0x87, 0xf5
465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu};
475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuconst char kCldManifestName[] = "CLD2 Data";
495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuCldComponentInstallerTraits::CldComponentInstallerTraits() {
515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool CldComponentInstallerTraits::CanAutoUpdate() const {
545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return true;
555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool CldComponentInstallerTraits::OnCustomInstall(
585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const base::DictionaryValue& manifest,
595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const base::FilePath& install_dir) {
60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return true;  // Nothing custom here.
615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubase::FilePath CldComponentInstallerTraits::GetInstalledPath(
64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const base::FilePath& base) {
655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Currently, all platforms have the file at the same location because there
665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // is no binary difference in the generated file on any supported platform.
675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // NB: This may change when 64-bit is officially supported.
685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return base.Append(FILE_PATH_LITERAL("_platform_specific"))
695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      .Append(FILE_PATH_LITERAL("all"))
705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      .Append(chrome::kCLDDataFilename);
715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid CldComponentInstallerTraits::ComponentReady(
745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const base::Version& version,
755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const base::FilePath& path,
765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    scoped_ptr<base::DictionaryValue> manifest) {
77010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  VLOG(1) << "Component ready, version " << version.GetString() << " in "
78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          << path.value();
795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  SetLatestCldDataFile(GetInstalledPath(path));
805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool CldComponentInstallerTraits::VerifyInstallation(
835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const base::FilePath& install_dir) const {
845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // We can't really do much to verify the CLD2 data file. In theory we could
855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // read the headers, but that won't do much other than tell us whether or
865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // not the headers are valid. So just check if the file exists.
875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  const base::FilePath expected_file = GetInstalledPath(install_dir);
885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  VLOG(1) << "Verifying install: " << expected_file.value();
895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  const bool result = base::PathExists(expected_file);
905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  VLOG(1) << "Verification result: " << (result ? "valid" : "invalid");
915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return result;
925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubase::FilePath CldComponentInstallerTraits::GetBaseDirectory() const {
955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  base::FilePath result;
965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  PathService::Get(chrome::DIR_COMPONENT_CLD2, &result);
975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return result;
985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid CldComponentInstallerTraits::GetHash(std::vector<uint8>* hash) const {
1015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  hash->assign(kPublicKeySHA256,
1025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu               kPublicKeySHA256 + arraysize(kPublicKeySHA256));
1035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
1045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liustd::string CldComponentInstallerTraits::GetName() const {
1065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return kCldManifestName;
1075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
1085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid RegisterCldComponent(ComponentUpdateService* cus) {
1105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_ptr<ComponentInstallerTraits> traits(
1115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      new CldComponentInstallerTraits());
1125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // |cus| will take ownership of |installer| during installer->Register(cus).
113010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DefaultComponentInstaller* installer =
114010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      new DefaultComponentInstaller(traits.Pass());
1155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  installer->Register(cus);
1165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
1175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid CldComponentInstallerTraits::SetLatestCldDataFile(
1195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const base::FilePath& path) {
1205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  VLOG(1) << "Setting CLD data file location: " << path.value();
1215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  base::AutoLock lock(cld_file_lock.Get());
1225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  cld_file.Get() = path;
1235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
1245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)base::FilePath GetLatestCldDataFile() {
1265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  base::AutoLock lock(cld_file_lock.Get());
127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // cld_file is an empty path by default, meaning "file not available yet".
128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return cld_file.Get();
1295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
1305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}  // namespace component_updater
132