cld_component_installer.cc revision 010d83a9304c5a91596085d917d248abff47903a
1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/component_updater/cld_component_installer.h" 6 7#include <string> 8#include <vector> 9 10#include "base/bind.h" 11#include "base/file_util.h" 12#include "base/files/file_path.h" 13#include "base/lazy_instance.h" 14#include "base/logging.h" 15#include "base/path_service.h" 16#include "base/platform_file.h" 17#include "chrome/browser/component_updater/default_component_installer.h" 18#include "chrome/browser/profiles/profile.h" 19#include "chrome/common/chrome_constants.h" 20#include "chrome/common/chrome_paths.h" 21#include "content/public/browser/browser_thread.h" 22#include "net/ssl/ssl_config_service.h" 23 24using component_updater::ComponentUpdateService; 25using content::BrowserThread; 26 27namespace { 28 29// Once we have acquired a valid file from the component installer, we need to 30// make the path available to other parts of the system such as the 31// translation libraries. We create a global to hold onto the path, and a 32// lock to guard it. See GetLatestCldDataFile(...) for more info. 33base::LazyInstance<base::Lock> cld_file_lock = LAZY_INSTANCE_INITIALIZER; 34base::LazyInstance<base::FilePath> cld_file = LAZY_INSTANCE_INITIALIZER; 35 36} 37 38namespace component_updater { 39 40// The SHA256 of the SubjectPublicKeyInfo used to sign the extension. 41// The extension id is: dpedmmgabcgnikllifiidmijgoiihfgf 42const uint8 kPublicKeySHA256[32] = { 43 0x3f, 0x43, 0xcc, 0x60, 0x12, 0x6d, 0x8a, 0xbb, 44 0x85, 0x88, 0x3c, 0x89, 0x6e, 0x88, 0x75, 0x65, 45 0xb9, 0x46, 0x09, 0xe8, 0xca, 0x92, 0xdd, 0x82, 46 0x4e, 0x6d, 0x0e, 0xe6, 0x79, 0x8a, 0x87, 0xf5 47}; 48 49const char kCldManifestName[] = "CLD2 Data"; 50 51class CldComponentInstallerTraits : public ComponentInstallerTraits { 52 public: 53 CldComponentInstallerTraits(); 54 virtual ~CldComponentInstallerTraits() {} 55 56 private: 57 // The following methods override ComponentInstallerTraits. 58 virtual bool CanAutoUpdate() const OVERRIDE; 59 virtual bool OnCustomInstall(const base::DictionaryValue& manifest, 60 const base::FilePath& install_dir) OVERRIDE; 61 virtual bool VerifyInstallation( 62 const base::FilePath& install_dir) const OVERRIDE; 63 virtual void ComponentReady( 64 const base::Version& version, 65 const base::FilePath& path, 66 scoped_ptr<base::DictionaryValue> manifest) OVERRIDE; 67 virtual base::FilePath GetBaseDirectory() const OVERRIDE; 68 virtual void GetHash(std::vector<uint8>* hash) const OVERRIDE; 69 virtual std::string GetName() const OVERRIDE; 70 71 base::FilePath GetInstalledPath(const base::FilePath& base) const; 72 void SetLatestCldDataFile(const base::FilePath& path); 73 DISALLOW_COPY_AND_ASSIGN(CldComponentInstallerTraits); 74}; 75 76CldComponentInstallerTraits::CldComponentInstallerTraits() { 77} 78 79bool CldComponentInstallerTraits::CanAutoUpdate() const { 80 return true; 81} 82 83bool CldComponentInstallerTraits::OnCustomInstall( 84 const base::DictionaryValue& manifest, 85 const base::FilePath& install_dir) { 86 return true; // Nothing custom here. 87} 88 89base::FilePath CldComponentInstallerTraits::GetInstalledPath( 90 const base::FilePath& base) const { 91 // Currently, all platforms have the file at the same location because there 92 // is no binary difference in the generated file on any supported platform. 93 // NB: This may change when 64-bit is officially supported. 94 return base.Append(FILE_PATH_LITERAL("_platform_specific")) 95 .Append(FILE_PATH_LITERAL("all")) 96 .Append(chrome::kCLDDataFilename); 97} 98 99void CldComponentInstallerTraits::ComponentReady( 100 const base::Version& version, 101 const base::FilePath& path, 102 scoped_ptr<base::DictionaryValue> manifest) { 103 VLOG(1) << "Component ready, version " << version.GetString() << " in " 104 << path.value(); 105 SetLatestCldDataFile(GetInstalledPath(path)); 106} 107 108bool CldComponentInstallerTraits::VerifyInstallation( 109 const base::FilePath& install_dir) const { 110 // We can't really do much to verify the CLD2 data file. In theory we could 111 // read the headers, but that won't do much other than tell us whether or 112 // not the headers are valid. So just check if the file exists. 113 const base::FilePath expected_file = GetInstalledPath(install_dir); 114 VLOG(1) << "Verifying install: " << expected_file.value(); 115 const bool result = base::PathExists(expected_file); 116 VLOG(1) << "Verification result: " << (result ? "valid" : "invalid"); 117 return result; 118} 119 120base::FilePath CldComponentInstallerTraits::GetBaseDirectory() const { 121 base::FilePath result; 122 PathService::Get(chrome::DIR_COMPONENT_CLD2, &result); 123 return result; 124} 125 126void CldComponentInstallerTraits::GetHash(std::vector<uint8>* hash) const { 127 hash->assign(kPublicKeySHA256, 128 kPublicKeySHA256 + arraysize(kPublicKeySHA256)); 129} 130 131std::string CldComponentInstallerTraits::GetName() const { 132 return kCldManifestName; 133} 134 135void RegisterCldComponent(ComponentUpdateService* cus) { 136 scoped_ptr<ComponentInstallerTraits> traits( 137 new CldComponentInstallerTraits()); 138 // |cus| will take ownership of |installer| during installer->Register(cus). 139 DefaultComponentInstaller* installer = 140 new DefaultComponentInstaller(traits.Pass()); 141 installer->Register(cus); 142} 143 144// This method is completely threadsafe. 145void CldComponentInstallerTraits::SetLatestCldDataFile( 146 const base::FilePath& path) { 147 VLOG(1) << "Setting CLD data file location: " << path.value(); 148 base::AutoLock lock(cld_file_lock.Get()); 149 cld_file.Get() = path; 150} 151 152bool GetLatestCldDataFile(base::FilePath* path) { 153 base::AutoLock lock(cld_file_lock.Get()); 154 const base::FilePath cached = cld_file.Get(); 155 if (cached.empty()) 156 return false; 157 *path = cached; 158 return true; 159} 160 161} // namespace component_updater 162