Make default apps cache multiprofile friendly
[chromium-blink-merge.git] / chrome / browser / extensions / crx_installer.h
blobfde15b69d9897c09e6f07f956ebed01a0e4b3076
1 // Copyright (c) 2012 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.
5 #ifndef CHROME_BROWSER_EXTENSIONS_CRX_INSTALLER_H_
6 #define CHROME_BROWSER_EXTENSIONS_CRX_INSTALLER_H_
8 #include <string>
10 #include "base/compiler_specific.h"
11 #include "base/files/file_path.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/version.h"
15 #include "chrome/browser/extensions/blacklist.h"
16 #include "chrome/browser/extensions/extension_install_prompt.h"
17 #include "chrome/browser/extensions/extension_installer.h"
18 #include "chrome/browser/extensions/sandboxed_unpacker.h"
19 #include "chrome/browser/extensions/webstore_installer.h"
20 #include "chrome/common/extensions/extension.h"
21 #include "extensions/common/manifest.h"
22 #include "sync/api/string_ordinal.h"
24 class ExtensionService;
25 class ExtensionServiceTest;
26 class SkBitmap;
27 struct WebApplicationInfo;
29 namespace base {
30 class SequencedTaskRunner;
33 namespace extensions {
34 class CrxInstallerError;
35 class ExtensionUpdaterTest;
36 class RequirementsChecker;
38 // This class installs a crx file into a profile.
40 // Installing a CRX is a multi-step process, including unpacking the crx,
41 // validating it, prompting the user, and installing. Since many of these
42 // steps must occur on the file thread, this class contains a copy of all data
43 // necessary to do its job. (This also minimizes external dependencies for
44 // easier testing).
46 // Lifetime management:
48 // This class is ref-counted by each call it makes to itself on another thread,
49 // and by UtilityProcessHost.
51 // Additionally, we hold a reference to our own client so that it lives at least
52 // long enough to receive the result of unpacking.
54 // IMPORTANT: Callers should keep a reference to a CrxInstaller while they are
55 // working with it, eg:
57 // scoped_refptr<CrxInstaller> installer(new CrxInstaller(...));
58 // installer->set_foo();
59 // installer->set_bar();
60 // installer->InstallCrx(...);
62 // Installation is aborted if the extension service learns that Chrome is
63 // terminating during the install. We can't listen for the app termination
64 // notification here in this class because it can be destroyed on any thread
65 // and won't safely be able to clean up UI thread notification listeners.
66 class CrxInstaller
67 : public SandboxedUnpackerClient,
68 public ExtensionInstallPrompt::Delegate {
69 public:
70 // Used in histograms; do not change order.
71 enum OffStoreInstallAllowReason {
72 OffStoreInstallDisallowed,
73 OffStoreInstallAllowedFromSettingsPage,
74 OffStoreInstallAllowedBecausePref,
75 OffStoreInstallAllowedInTest,
76 NumOffStoreInstallAllowReasons
79 // Extensions will be installed into service->install_directory(), then
80 // registered with |service|. This does a silent install - see below for
81 // other options.
82 static scoped_refptr<CrxInstaller> CreateSilent(ExtensionService* service);
84 // Same as above, but use |client| to generate a confirmation prompt.
85 static scoped_refptr<CrxInstaller> Create(
86 ExtensionService* service,
87 scoped_ptr<ExtensionInstallPrompt> client);
89 // Same as the previous method, except use the |approval| to bypass the
90 // prompt. Note that the caller retains ownership of |approval|.
91 static scoped_refptr<CrxInstaller> Create(
92 ExtensionService* service,
93 scoped_ptr<ExtensionInstallPrompt> client,
94 const WebstoreInstaller::Approval* approval);
96 // Install the crx in |source_file|.
97 void InstallCrx(const base::FilePath& source_file);
99 // Convert the specified user script into an extension and install it.
100 void InstallUserScript(const base::FilePath& source_file,
101 const GURL& download_url);
103 // Convert the specified web app into an extension and install it.
104 void InstallWebApp(const WebApplicationInfo& web_app);
106 // Overridden from ExtensionInstallPrompt::Delegate:
107 virtual void InstallUIProceed() OVERRIDE;
108 virtual void InstallUIAbort(bool user_initiated) OVERRIDE;
110 int creation_flags() const { return creation_flags_; }
111 void set_creation_flags(int val) { creation_flags_ = val; }
113 const GURL& download_url() const { return download_url_; }
114 void set_download_url(const GURL& val) { download_url_ = val; }
116 const base::FilePath& source_file() const { return source_file_; }
118 Manifest::Location install_source() const {
119 return install_source_;
121 void set_install_source(Manifest::Location source) {
122 install_source_ = source;
125 const std::string& expected_id() const { return expected_id_; }
126 void set_expected_id(const std::string& val) { expected_id_ = val; }
128 void set_expected_version(const Version& val) {
129 expected_version_.reset(new Version(val));
132 bool delete_source() const { return delete_source_; }
133 void set_delete_source(bool val) { delete_source_ = val; }
135 bool allow_silent_install() const { return allow_silent_install_; }
136 void set_allow_silent_install(bool val) { allow_silent_install_ = val; }
138 bool is_gallery_install() const {
139 return (creation_flags_ & Extension::FROM_WEBSTORE) > 0;
141 void set_is_gallery_install(bool val) {
142 if (val)
143 creation_flags_ |= Extension::FROM_WEBSTORE;
144 else
145 creation_flags_ &= ~Extension::FROM_WEBSTORE;
148 // The original download URL should be set when the WebstoreInstaller is
149 // tracking the installation. The WebstoreInstaller uses this URL to match
150 // failure notifications to the extension.
151 const GURL& original_download_url() const { return original_download_url_; }
152 void set_original_download_url(const GURL& url) {
153 original_download_url_ = url;
156 // If |apps_require_extension_mime_type_| is set to true, be sure to set
157 // |original_mime_type_| as well.
158 void set_apps_require_extension_mime_type(
159 bool apps_require_extension_mime_type) {
160 apps_require_extension_mime_type_ = apps_require_extension_mime_type;
163 void set_original_mime_type(const std::string& original_mime_type) {
164 original_mime_type_ = original_mime_type;
167 extension_misc::CrxInstallCause install_cause() const {
168 return install_cause_;
170 void set_install_cause(extension_misc::CrxInstallCause install_cause) {
171 install_cause_ = install_cause;
174 OffStoreInstallAllowReason off_store_install_allow_reason() const {
175 return off_store_install_allow_reason_;
177 void set_off_store_install_allow_reason(OffStoreInstallAllowReason reason) {
178 off_store_install_allow_reason_ = reason;
181 void set_page_ordinal(const syncer::StringOrdinal& page_ordinal) {
182 page_ordinal_ = page_ordinal;
185 void set_error_on_unsupported_requirements(bool val) {
186 error_on_unsupported_requirements_ = val;
189 void set_install_wait_for_idle(bool val) {
190 install_wait_for_idle_ = val;
193 bool did_handle_successfully() const { return did_handle_successfully_; }
195 Profile* profile() { return installer_.profile(); }
197 const Extension* extension() { return installer_.extension().get(); }
199 private:
200 friend class ::ExtensionServiceTest;
201 friend class ExtensionUpdaterTest;
202 friend class ExtensionCrxInstallerTest;
204 CrxInstaller(base::WeakPtr<ExtensionService> service_weak,
205 scoped_ptr<ExtensionInstallPrompt> client,
206 const WebstoreInstaller::Approval* approval);
207 virtual ~CrxInstaller();
209 // Converts the source user script to an extension.
210 void ConvertUserScriptOnFileThread();
212 // Converts the source web app to an extension.
213 void ConvertWebAppOnFileThread(const WebApplicationInfo& web_app,
214 const base::FilePath& install_directory);
216 // Called after OnUnpackSuccess as a last check to see whether the install
217 // should complete.
218 CrxInstallerError AllowInstall(const Extension* extension);
220 // SandboxedUnpackerClient
221 virtual void OnUnpackFailure(const string16& error_message) OVERRIDE;
222 virtual void OnUnpackSuccess(const base::FilePath& temp_dir,
223 const base::FilePath& extension_dir,
224 const base::DictionaryValue* original_manifest,
225 const Extension* extension,
226 const SkBitmap& install_icon) OVERRIDE;
228 // Called on the UI thread to start the requirements check on the extension.
229 void CheckImportsAndRequirements();
231 // Runs on the UI thread. Callback from RequirementsChecker.
232 void OnRequirementsChecked(std::vector<std::string> requirement_errors);
234 // Runs on the UI thread. Callback from Blacklist.
235 void OnBlacklistChecked(
236 extensions::Blacklist::BlacklistState blacklist_state);
238 // Runs on the UI thread. Confirms the installation to the ExtensionService.
239 void ConfirmInstall();
241 // Runs on File thread. Install the unpacked extension into the profile and
242 // notify the frontend.
243 void CompleteInstall();
245 // Result reporting.
246 void ReportFailureFromFileThread(const CrxInstallerError& error);
247 void ReportFailureFromUIThread(const CrxInstallerError& error);
248 void ReportSuccessFromFileThread();
249 void ReportSuccessFromUIThread();
250 void NotifyCrxInstallComplete(bool success);
252 // Deletes temporary directory and crx file if needed.
253 void CleanupTempFiles();
255 // Checks whether the current installation is initiated by the user from
256 // the extension settings page to update an existing extension or app.
257 void CheckUpdateFromSettingsPage();
259 // Show re-enable prompt if the update is initiated from the settings page
260 // and needs additional permissions.
261 void ConfirmReEnable();
263 // The file we're installing.
264 base::FilePath source_file_;
266 // The URL the file was downloaded from.
267 GURL download_url_;
269 // The directory extensions are installed to.
270 base::FilePath install_directory_;
272 // The location the installation came from (bundled with Chromium, registry,
273 // manual install, etc). This metadata is saved with the installation if
274 // successful. Defaults to INTERNAL.
275 Manifest::Location install_source_;
277 // Indicates whether the user has already approved the extension to be
278 // installed. If true, |expected_manifest_| and |expected_id_| must match
279 // those of the CRX.
280 bool approved_;
282 // For updates, external and webstore installs we have an ID we're expecting
283 // the extension to contain.
284 std::string expected_id_;
286 // A parsed copy of the expected manifest, before any transformations like
287 // localization have taken place. If |approved_| is true, then the
288 // extension's manifest must match this for the install to proceed.
289 scoped_ptr<Manifest> expected_manifest_;
291 // Set to true if we want a strict, exact match check between the actual and
292 // expected manifest, rather than just a check that the effective permissions
293 // are the same.
294 bool expected_manifest_strict_checking_;
296 // If non-NULL, contains the expected version of the extension we're
297 // installing. Important for external sources, where claiming the wrong
298 // version could cause unnecessary unpacking of an extension at every
299 // restart.
300 scoped_ptr<Version> expected_version_;
302 // Whether manual extension installation is enabled. We can't just check this
303 // before trying to install because themes are special-cased to always be
304 // allowed.
305 bool extensions_enabled_;
307 // Whether we're supposed to delete the source file on destruction. Defaults
308 // to false.
309 bool delete_source_;
311 // The download URL, before redirects, if this is a gallery install.
312 GURL original_download_url_;
314 // Whether to create an app shortcut after successful installation. This is
315 // set based on the user's selection in the UI and can only ever be true for
316 // apps.
317 bool create_app_shortcut_;
319 // The ordinal of the NTP apps page |extension_| will be shown on.
320 syncer::StringOrdinal page_ordinal_;
322 // A parsed copy of the unmodified original manifest, before any
323 // transformations like localization have taken place.
324 scoped_ptr<Manifest> original_manifest_;
326 // If non-empty, contains the current version of the extension we're
327 // installing (for upgrades).
328 std::string current_version_;
330 // The icon we will display in the installation UI, if any.
331 scoped_ptr<SkBitmap> install_icon_;
333 // The temp directory extension resources were unpacked to. We own this and
334 // must delete it when we are done with it.
335 base::FilePath temp_dir_;
337 // The frontend we will report results back to.
338 base::WeakPtr<ExtensionService> service_weak_;
340 // The client we will work with to do the installation. This can be NULL, in
341 // which case the install is silent.
342 // NOTE: we may be deleted on the file thread. To ensure the UI is deleted on
343 // the main thread we don't use a scoped_ptr here.
344 ExtensionInstallPrompt* client_;
346 // The root of the unpacked extension directory. This is a subdirectory of
347 // temp_dir_, so we don't have to delete it explicitly.
348 base::FilePath unpacked_extension_root_;
350 // True when the CRX being installed was just downloaded.
351 // Used to trigger extra checks before installing.
352 bool apps_require_extension_mime_type_;
354 // Allows for the possibility of a normal install (one in which a |client|
355 // is provided in the ctor) to procede without showing the permissions prompt
356 // dialog.
357 bool allow_silent_install_;
359 // The value of the content type header sent with the CRX.
360 // Ignorred unless |require_extension_mime_type_| is true.
361 std::string original_mime_type_;
363 // What caused this install? Used only for histograms that report
364 // on failure rates, broken down by the cause of the install.
365 extension_misc::CrxInstallCause install_cause_;
367 // Creation flags to use for the extension. These flags will be used
368 // when calling Extenion::Create() by the crx installer.
369 int creation_flags_;
371 // Whether to allow off store installation.
372 OffStoreInstallAllowReason off_store_install_allow_reason_;
374 // Whether the installation was handled successfully. This is used to
375 // indicate to the client whether the file should be removed and any UI
376 // initiating the installation can be removed. This is different than whether
377 // there was an error; if there was an error that rejects installation we
378 // still consider the installation 'handled'.
379 bool did_handle_successfully_;
381 // Whether we should produce an error if the manifest declares requirements
382 // that are not met. If false and there is an unmet requirement, the install
383 // will continue but the extension will be distabled.
384 bool error_on_unsupported_requirements_;
386 bool has_requirement_errors_;
388 extensions::Blacklist::BlacklistState blacklist_state_;
390 bool install_wait_for_idle_;
392 // Sequenced task runner where file I/O operations will be performed.
393 scoped_refptr<base::SequencedTaskRunner> installer_task_runner_;
395 // Used to show the install dialog.
396 ExtensionInstallPrompt::ShowDialogCallback show_dialog_callback_;
398 // Whether the update is initiated by the user from the extension settings
399 // page.
400 bool update_from_settings_page_;
402 // Gives access to common methods and data of an extension installer.
403 ExtensionInstaller installer_;
405 DISALLOW_COPY_AND_ASSIGN(CrxInstaller);
408 } // namespace extensions
410 #endif // CHROME_BROWSER_EXTENSIONS_CRX_INSTALLER_H_