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