crx_installer.h revision 513209b27ff55e2841eac0e4120199c23acce758
1// Copyright (c) 2009 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#ifndef CHROME_BROWSER_EXTENSIONS_CRX_INSTALLER_H_ 6#define CHROME_BROWSER_EXTENSIONS_CRX_INSTALLER_H_ 7#pragma once 8 9#include <string> 10 11#include "base/file_path.h" 12#include "base/ref_counted.h" 13#include "chrome/browser/extensions/extension_install_ui.h" 14#include "chrome/browser/extensions/sandboxed_extension_unpacker.h" 15#include "chrome/common/extensions/extension.h" 16 17class ExtensionsService; 18class SkBitmap; 19 20// This class installs a crx file into a profile. 21// 22// Installing a CRX is a multi-step process, including unpacking the crx, 23// validating it, prompting the user, and installing. Since many of these 24// steps must occur on the file thread, this class contains a copy of all data 25// necessary to do its job. (This also minimizes external dependencies for 26// easier testing). 27// 28// Lifetime management: 29// 30// This class is ref-counted by each call it makes to itself on another thread, 31// and by UtilityProcessHost. 32// 33// Additionally, we hold a reference to our own client so that it lives at least 34// long enough to receive the result of unpacking. 35// 36// IMPORTANT: Callers should keep a reference to a CrxInstaller while they are 37// working with it, eg: 38// 39// scoped_refptr<CrxInstaller> installer(new CrxInstaller(...)); 40// installer->set_foo(); 41// installer->set_bar(); 42// installer->InstallCrx(...); 43class CrxInstaller 44 : public SandboxedExtensionUnpackerClient, 45 public ExtensionInstallUI::Delegate { 46 public: 47 48 // This is pretty lame, but given the difficulty of connecting a particular 49 // ExtensionFunction to a resulting download in the download manager, it's 50 // currently necessary. This is the |id| of an extension to be installed 51 // *by the web store only* which should not get the permissions install 52 // prompt. This should only be called on the UI thread. 53 // crbug.com/54916 54 static void SetWhitelistedInstallId(const std::string& id); 55 56 // Returns whether |id| was found and removed (was whitelisted). This should 57 // only be called on the UI thread. 58 static bool ClearWhitelistedInstallId(const std::string& id); 59 60 // Constructor. Extensions will be unpacked to |install_directory|. 61 // Extension objects will be sent to |frontend|, and any UI will be shown 62 // via |client|. For silent install, pass NULL for |client|. 63 CrxInstaller(const FilePath& install_directory, 64 ExtensionsService* frontend, 65 ExtensionInstallUI* client); 66 67 // Install the crx in |source_file|. Note that this will most likely 68 // complete asynchronously. 69 void InstallCrx(const FilePath& source_file); 70 71 // Install the user script in |source_file|. Note that this will most likely 72 // complete asynchronously. 73 void InstallUserScript(const FilePath& source_file, 74 const GURL& original_url); 75 76 // Overridden from ExtensionInstallUI::Delegate: 77 virtual void InstallUIProceed(); 78 virtual void InstallUIAbort(); 79 80 const GURL& original_url() const { return original_url_; } 81 void set_original_url(const GURL& val) { original_url_ = val; } 82 83 Extension::Location install_source() const { return install_source_; } 84 void set_install_source(Extension::Location source) { 85 install_source_ = source; 86 } 87 88 const std::string& expected_id() const { return expected_id_; } 89 void set_expected_id(const std::string& val) { expected_id_ = val; } 90 91 bool delete_source() const { return delete_source_; } 92 void set_delete_source(bool val) { delete_source_ = val; } 93 94 bool allow_privilege_increase() const { return allow_privilege_increase_; } 95 void set_allow_privilege_increase(bool val) { 96 allow_privilege_increase_ = val; 97 } 98 99 bool allow_silent_install() const { return allow_silent_install_; } 100 void set_allow_silent_install(bool val) { allow_silent_install_ = val; } 101 102 bool is_gallery_install() const { return is_gallery_install_; } 103 void set_is_gallery_install(bool val) { is_gallery_install_ = val; } 104 105 // If |apps_require_extension_mime_type_| is set to true, be sure to set 106 // |original_mime_type_| as well. 107 void set_apps_require_extension_mime_type( 108 bool apps_require_extension_mime_type) { 109 apps_require_extension_mime_type_ = apps_require_extension_mime_type; 110 } 111 112 void set_original_mime_type(const std::string& original_mime_type) { 113 original_mime_type_ = original_mime_type; 114 } 115 116 private: 117 ~CrxInstaller(); 118 119 // Converts the source user script to an extension. 120 void ConvertUserScriptOnFileThread(); 121 122 // Called after OnUnpackSuccess as a last check to see whether the install 123 // should complete. 124 bool AllowInstall(const Extension* extension, std::string* error); 125 126 // SandboxedExtensionUnpackerClient 127 virtual void OnUnpackFailure(const std::string& error_message); 128 virtual void OnUnpackSuccess(const FilePath& temp_dir, 129 const FilePath& extension_dir, 130 const Extension* extension); 131 132 // Runs on the UI thread. Confirms with the user (via ExtensionInstallUI) that 133 // it is OK to install this extension. 134 void ConfirmInstall(); 135 136 // Runs on File thread. Install the unpacked extension into the profile and 137 // notify the frontend. 138 void CompleteInstall(); 139 140 // Result reporting. 141 void ReportFailureFromFileThread(const std::string& error); 142 void ReportFailureFromUIThread(const std::string& error); 143 void ReportSuccessFromFileThread(); 144 void ReportSuccessFromUIThread(); 145 146 // The file we're installing. 147 FilePath source_file_; 148 149 // The URL the file was downloaded from. 150 GURL original_url_; 151 152 // The directory extensions are installed to. 153 FilePath install_directory_; 154 155 // The location the installation came from (bundled with Chromium, registry, 156 // manual install, etc). This metadata is saved with the installation if 157 // successful. Defaults to INTERNAL. 158 Extension::Location install_source_; 159 160 // For updates and external installs we have an ID we're expecting the 161 // extension to contain. 162 std::string expected_id_; 163 164 // Whether manual extension installation is enabled. We can't just check this 165 // before trying to install because themes are special-cased to always be 166 // allowed. 167 bool extensions_enabled_; 168 169 // Whether we're supposed to delete the source file on destruction. Defaults 170 // to false. 171 bool delete_source_; 172 173 // Whether privileges should be allowed to silently increaes from any 174 // previously installed version of the extension. This is used for things 175 // like external extensions, where extensions come with third-party software 176 // or are distributed by the network administrator. There is no UI shown 177 // for these extensions, so there shouldn't be UI for privilege increase, 178 // either. Defaults to false. 179 bool allow_privilege_increase_; 180 181 // Whether the install originated from the gallery. 182 bool is_gallery_install_; 183 184 // Whether to create an app shortcut after successful installation. This is 185 // set based on the user's selection in the UI and can only ever be true for 186 // apps. 187 bool create_app_shortcut_; 188 189 // The extension we're installing. We own this and either pass it off to 190 // ExtensionsService on success, or delete it on failure. 191 scoped_refptr<const Extension> extension_; 192 193 // If non-empty, contains the current version of the extension we're 194 // installing (for upgrades). 195 std::string current_version_; 196 197 // The icon we will display in the installation UI, if any. 198 scoped_ptr<SkBitmap> install_icon_; 199 200 // The temp directory extension resources were unpacked to. We own this and 201 // must delete it when we are done with it. 202 FilePath temp_dir_; 203 204 // The frontend we will report results back to. 205 scoped_refptr<ExtensionsService> frontend_; 206 207 // The client we will work with to do the installation. This can be NULL, in 208 // which case the install is silent. 209 // NOTE: we may be deleted on the file thread. To ensure the UI is deleted on 210 // the main thread we don't use a scoped_ptr here. 211 ExtensionInstallUI* client_; 212 213 // The root of the unpacked extension directory. This is a subdirectory of 214 // temp_dir_, so we don't have to delete it explicitly. 215 FilePath unpacked_extension_root_; 216 217 // True when the CRX being installed was just downloaded. 218 // Used to trigger extra checks before installing. 219 bool apps_require_extension_mime_type_; 220 221 // Allows for the possibility of a normal install (one in which a |client| 222 // is provided in the ctor) to procede without showing the permissions prompt 223 // dialog. Note that this will only take place if |allow_silent_install_| 224 // is true AND the unpacked id of the extension is whitelisted with 225 // SetWhitelistedInstallId(). 226 bool allow_silent_install_; 227 228 // The value of the content type header sent with the CRX. 229 // Ignorred unless |require_extension_mime_type_| is true. 230 std::string original_mime_type_; 231 232 DISALLOW_COPY_AND_ASSIGN(CrxInstaller); 233}; 234 235#endif // CHROME_BROWSER_EXTENSIONS_CRX_INSTALLER_H_ 236