blob: eac9c001a5638cc45e94a5821ab97120ecf60a9a [file] [log] [blame]
[email protected]29679dea2012-03-10 03:20:281// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]655b2b1a2011-10-13 17:13:062// 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_WEBSTORE_INSTALLER_H_
6#define CHROME_BROWSER_EXTENSIONS_WEBSTORE_INSTALLER_H_
[email protected]655b2b1a2011-10-13 17:13:067
[email protected]669b2372013-10-17 15:04:588#include <list>
[email protected]655b2b1a2011-10-13 17:13:069#include <string>
[email protected]655b2b1a2011-10-13 17:13:0610
11#include "base/compiler_specific.h"
[email protected]98e4e522011-10-25 13:00:1612#include "base/memory/ref_counted.h"
[email protected]21a5ad62012-04-03 04:48:4513#include "base/memory/scoped_ptr.h"
[email protected]17f07822014-05-22 08:45:1514#include "base/scoped_observer.h"
[email protected]d59d40c2012-08-08 18:18:3715#include "base/supports_user_data.h"
[email protected]c80fe5f2014-03-26 04:36:3016#include "base/timer/timer.h"
[email protected]21a5ad62012-04-03 04:48:4517#include "base/values.h"
[email protected]669b2372013-10-17 15:04:5818#include "base/version.h"
[email protected]af6efb22012-10-12 02:23:0519#include "chrome/browser/extensions/extension_install_prompt.h"
[email protected]ed0757ec2012-08-02 17:23:2620#include "content/public/browser/browser_thread.h"
[email protected]7f3918882014-01-14 06:14:5621#include "content/public/browser/download_interrupt_reasons.h"
[email protected]8adbe3112012-03-27 05:42:2222#include "content/public/browser/download_item.h"
[email protected]6c2381d2011-10-19 02:52:5323#include "content/public/browser/notification_observer.h"
24#include "content/public/browser/notification_registrar.h"
[email protected]2acf3a52014-02-13 00:26:0025#include "content/public/browser/web_contents_observer.h"
[email protected]17f07822014-05-22 08:45:1526#include "extensions/browser/extension_registry_observer.h"
[email protected]301116c62013-11-26 10:37:4527#include "extensions/common/manifest_handlers/shared_module_info.h"
[email protected]7b4eea602013-02-08 06:19:4728#include "ui/gfx/image/image_skia.h"
[email protected]a6483d22013-07-03 22:11:0029#include "url/gurl.h"
[email protected]655b2b1a2011-10-13 17:13:0630
[email protected]655b2b1a2011-10-13 17:13:0631class Profile;
32
[email protected]a3ef4832013-02-02 05:12:3333namespace base {
34class FilePath;
35}
36
[email protected]cdcb1dee2012-01-04 00:46:2037namespace content {
[email protected]2acf3a52014-02-13 00:26:0038class WebContents;
[email protected]cdcb1dee2012-01-04 00:46:2039}
40
[email protected]3d61a7f2012-07-12 19:11:2541namespace extensions {
42
[email protected]5206ae82014-04-23 12:03:3343class CrxInstaller;
[email protected]669b2372013-10-17 15:04:5844class Extension;
[email protected]17f07822014-05-22 08:45:1545class ExtensionRegistry;
[email protected]21c01042013-03-10 23:41:1446class Manifest;
47
[email protected]655b2b1a2011-10-13 17:13:0648// Downloads and installs extensions from the web store.
[email protected]2acf3a52014-02-13 00:26:0049class WebstoreInstaller : public content::NotificationObserver,
[email protected]17f07822014-05-22 08:45:1550 public ExtensionRegistryObserver,
[email protected]2acf3a52014-02-13 00:26:0051 public content::DownloadItem::Observer,
52 public content::WebContentsObserver,
53 public base::RefCountedThreadSafe<
[email protected]17f07822014-05-22 08:45:1554 WebstoreInstaller,
55 content::BrowserThread::DeleteOnUIThread> {
[email protected]655b2b1a2011-10-13 17:13:0656 public:
[email protected]084e35482013-09-25 02:46:1957 enum InstallSource {
[email protected]99dfecd2011-10-18 01:11:5058 // Inline installs trigger slightly different behavior (install source
59 // is different, download referrers are the item's page in the gallery).
[email protected]084e35482013-09-25 02:46:1960 INSTALL_SOURCE_INLINE,
61 INSTALL_SOURCE_APP_LAUNCHER,
62 INSTALL_SOURCE_OTHER
[email protected]655b2b1a2011-10-13 17:13:0663 };
64
[email protected]bcd1eaf72012-10-03 05:42:2965 enum FailureReason {
66 FAILURE_REASON_CANCELLED,
[email protected]669b2372013-10-17 15:04:5867 FAILURE_REASON_DEPENDENCY_NOT_FOUND,
68 FAILURE_REASON_DEPENDENCY_NOT_SHARED_MODULE,
[email protected]bcd1eaf72012-10-03 05:42:2969 FAILURE_REASON_OTHER
70 };
71
[email protected]669b2372013-10-17 15:04:5872 enum ManifestCheckLevel {
73 // Do not check for any manifest equality.
74 MANIFEST_CHECK_LEVEL_NONE,
75
76 // Only check that the expected and actual permissions have the same
77 // effective permissions.
78 MANIFEST_CHECK_LEVEL_LOOSE,
79
80 // All data in the expected and actual manifests must match.
81 MANIFEST_CHECK_LEVEL_STRICT,
82 };
83
[email protected]655b2b1a2011-10-13 17:13:0684 class Delegate {
85 public:
[email protected]bcd1eaf72012-10-03 05:42:2986 virtual void OnExtensionDownloadStarted(const std::string& id,
87 content::DownloadItem* item);
88 virtual void OnExtensionDownloadProgress(const std::string& id,
89 content::DownloadItem* item);
[email protected]655b2b1a2011-10-13 17:13:0690 virtual void OnExtensionInstallSuccess(const std::string& id) = 0;
91 virtual void OnExtensionInstallFailure(const std::string& id,
[email protected]bcd1eaf72012-10-03 05:42:2992 const std::string& error,
93 FailureReason reason) = 0;
[email protected]512d03f2012-06-26 01:06:0694
95 protected:
96 virtual ~Delegate() {}
[email protected]655b2b1a2011-10-13 17:13:0697 };
98
[email protected]89019d62012-05-17 18:47:0999 // Contains information about what parts of the extension install process can
100 // be skipped or modified. If one of these is present, it means that a CRX
101 // download was initiated by WebstoreInstaller. The Approval instance should
102 // be checked further for additional details.
[email protected]d59d40c2012-08-08 18:18:37103 struct Approval : public base::SupportsUserData::Data {
[email protected]89019d62012-05-17 18:47:09104 static scoped_ptr<Approval> CreateWithInstallPrompt(Profile* profile);
[email protected]85290822013-08-23 20:27:38105
[email protected]669b2372013-10-17 15:04:58106 // Creates an Approval for installing a shared module.
107 static scoped_ptr<Approval> CreateForSharedModule(Profile* profile);
108
[email protected]85290822013-08-23 20:27:38109 // Creates an Approval that will skip putting up an install confirmation
110 // prompt if the actual manifest from the extension to be installed matches
111 // |parsed_manifest|. The |strict_manifest_check| controls whether we want
112 // to require an exact manifest match, or are willing to tolerate a looser
113 // check just that the effective permissions are the same.
[email protected]89019d62012-05-17 18:47:09114 static scoped_ptr<Approval> CreateWithNoInstallPrompt(
115 Profile* profile,
116 const std::string& extension_id,
[email protected]85290822013-08-23 20:27:38117 scoped_ptr<base::DictionaryValue> parsed_manifest,
118 bool strict_manifest_check);
[email protected]89019d62012-05-17 18:47:09119
dchengae36a4a2014-10-21 12:36:36120 ~Approval() override;
[email protected]21a5ad62012-04-03 04:48:45121
122 // The extension id that was approved for installation.
123 std::string extension_id;
124
125 // The profile the extension should be installed into.
126 Profile* profile;
127
128 // The expected manifest, before localization.
[email protected]21c01042013-03-10 23:41:14129 scoped_ptr<Manifest> manifest;
[email protected]21a5ad62012-04-03 04:48:45130
131 // Whether to use a bubble notification when an app is installed, instead of
132 // the default behavior of transitioning to the new tab page.
133 bool use_app_installed_bubble;
134
135 // Whether to skip the post install UI like the extension installed bubble.
136 bool skip_post_install_ui;
[email protected]89019d62012-05-17 18:47:09137
138 // Whether to skip the install dialog once the extension has been downloaded
139 // and unpacked. One reason this can be true is that in the normal webstore
140 // installation, the dialog is shown earlier, before any download is done,
141 // so there's no need to show it again.
142 bool skip_install_dialog;
143
[email protected]fc652c02013-02-04 05:16:23144 // Whether we should enable the launcher before installing the app.
145 bool enable_launcher;
146
[email protected]669b2372013-10-17 15:04:58147 // Manifest check level for checking actual manifest against expected
148 // manifest.
149 ManifestCheckLevel manifest_check_level;
[email protected]85290822013-08-23 20:27:38150
[email protected]af6efb22012-10-12 02:23:05151 // Used to show the install dialog.
152 ExtensionInstallPrompt::ShowDialogCallback show_dialog_callback;
153
[email protected]7b4eea602013-02-08 06:19:47154 // The icon to use to display the extension while it is installing.
155 gfx::ImageSkia installing_icon;
156
[email protected]669b2372013-10-17 15:04:58157 // A dummy extension created from |manifest|;
158 scoped_refptr<Extension> dummy_extension;
159
160 // Required minimum version.
[email protected]c5e4a2222014-01-03 16:06:13161 scoped_ptr<Version> minimum_version;
[email protected]669b2372013-10-17 15:04:58162
[email protected]bc44b5da2014-06-12 14:20:00163 // Ephemeral apps are transiently installed.
[email protected]ce35418b2013-11-25 01:22:33164 bool is_ephemeral;
165
[email protected]e7684952014-05-09 21:41:35166 // The authuser index required to download the item being installed. May be
167 // the empty string, in which case no authuser parameter is used.
168 std::string authuser;
169
[email protected]89019d62012-05-17 18:47:09170 private:
171 Approval();
[email protected]21a5ad62012-04-03 04:48:45172 };
173
174 // Gets the Approval associated with the |download|, or NULL if there's none.
175 // Note that the Approval is owned by |download|.
176 static const Approval* GetAssociatedApproval(
177 const content::DownloadItem& download);
178
[email protected]98e4e522011-10-25 13:00:16179 // Creates a WebstoreInstaller for downloading and installing the extension
180 // with the given |id| from the Chrome Web Store. If |delegate| is not NULL,
181 // it will be notified when the install succeeds or fails. The installer will
182 // use the specified |controller| to download the extension. Only one
[email protected]21a5ad62012-04-03 04:48:45183 // WebstoreInstaller can use a specific controller at any given time. This
184 // also associates the |approval| with this install.
[email protected]98e4e522011-10-25 13:00:16185 // Note: the delegate should stay alive until being called back.
186 WebstoreInstaller(Profile* profile,
187 Delegate* delegate,
[email protected]2acf3a52014-02-13 00:26:00188 content::WebContents* web_contents,
[email protected]98e4e522011-10-25 13:00:16189 const std::string& id,
[email protected]21a5ad62012-04-03 04:48:45190 scoped_ptr<Approval> approval,
[email protected]084e35482013-09-25 02:46:19191 InstallSource source);
[email protected]655b2b1a2011-10-13 17:13:06192
[email protected]98e4e522011-10-25 13:00:16193 // Starts downloading and installing the extension.
194 void Start();
[email protected]655b2b1a2011-10-13 17:13:06195
[email protected]17f07822014-05-22 08:45:15196 // content::NotificationObserver.
dchengae36a4a2014-10-21 12:36:36197 void Observe(int type,
198 const content::NotificationSource& source,
199 const content::NotificationDetails& details) override;
[email protected]655b2b1a2011-10-13 17:13:06200
[email protected]17f07822014-05-22 08:45:15201 // ExtensionRegistryObserver.
dchengae36a4a2014-10-21 12:36:36202 void OnExtensionInstalled(content::BrowserContext* browser_context,
203 const Extension* extension,
204 bool is_update) override;
[email protected]17f07822014-05-22 08:45:15205
[email protected]e074e322012-10-30 01:12:09206 // Removes the reference to the delegate passed in the constructor. Used when
207 // the delegate object must be deleted before this object.
208 void InvalidateDelegate();
209
[email protected]9c265d02011-12-29 22:13:43210 // Instead of using the default download directory, use |directory| instead.
211 // This does *not* transfer ownership of |directory|.
[email protected]a3ef4832013-02-02 05:12:33212 static void SetDownloadDirectoryForTests(base::FilePath* directory);
[email protected]9c265d02011-12-29 22:13:43213
[email protected]655b2b1a2011-10-13 17:13:06214 private:
[email protected]902a8a012013-05-04 05:04:16215 FRIEND_TEST_ALL_PREFIXES(WebstoreInstallerTest, PlatformParams);
[email protected]ed0757ec2012-08-02 17:23:26216 friend struct content::BrowserThread::DeleteOnThread<
217 content::BrowserThread::UI>;
218 friend class base::DeleteHelper<WebstoreInstaller>;
dchengae36a4a2014-10-21 12:36:36219 ~WebstoreInstaller() override;
[email protected]5f2a4752012-04-27 22:18:58220
[email protected]902a8a012013-05-04 05:04:16221 // Helper to get install URL.
222 static GURL GetWebstoreInstallURL(const std::string& extension_id,
[email protected]669b2372013-10-17 15:04:58223 InstallSource source);
[email protected]902a8a012013-05-04 05:04:16224
[email protected]8adbe3112012-03-27 05:42:22225 // DownloadManager::DownloadUrl callback.
[email protected]7f3918882014-01-14 06:14:56226 void OnDownloadStarted(content::DownloadItem* item,
227 content::DownloadInterruptReason interrupt_reason);
[email protected]8adbe3112012-03-27 05:42:22228
229 // DownloadItem::Observer implementation:
dchengae36a4a2014-10-21 12:36:36230 void OnDownloadUpdated(content::DownloadItem* download) override;
231 void OnDownloadDestroyed(content::DownloadItem* download) override;
[email protected]8adbe3112012-03-27 05:42:22232
[email protected]669b2372013-10-17 15:04:58233 // Downloads next pending module in |pending_modules_|.
234 void DownloadNextPendingModule();
235
236 // Downloads and installs a single Crx with the given |extension_id|.
237 // This function is used for both the extension Crx and dependences.
238 void DownloadCrx(const std::string& extension_id, InstallSource source);
239
[email protected]f66a50a2011-11-02 23:53:46240 // Starts downloading the extension to |file_path|.
[email protected]a3ef4832013-02-02 05:12:33241 void StartDownload(const base::FilePath& file_path);
[email protected]f66a50a2011-11-02 23:53:46242
[email protected]c80fe5f2014-03-26 04:36:30243 // Updates the InstallTracker with the latest download progress.
244 void UpdateDownloadProgress();
245
[email protected]5206ae82014-04-23 12:03:33246 // Creates and starts CrxInstaller for the downloaded extension package.
247 void StartCrxInstaller(const content::DownloadItem& item);
248
[email protected]655b2b1a2011-10-13 17:13:06249 // Reports an install |error| to the delegate for the given extension if this
250 // managed its installation. This also removes the associated PendingInstall.
[email protected]bcd1eaf72012-10-03 05:42:29251 void ReportFailure(const std::string& error, FailureReason reason);
[email protected]655b2b1a2011-10-13 17:13:06252
253 // Reports a successful install to the delegate for the given extension if
254 // this managed its installation. This also removes the associated
255 // PendingInstall.
[email protected]98e4e522011-10-25 13:00:16256 void ReportSuccess();
[email protected]655b2b1a2011-10-13 17:13:06257
[email protected]0a2a7242013-11-20 20:49:24258 // Records stats regarding an interrupted webstore download item.
259 void RecordInterrupt(const content::DownloadItem* download) const;
260
[email protected]6c2381d2011-10-19 02:52:53261 content::NotificationRegistrar registrar_;
[email protected]17f07822014-05-22 08:45:15262 ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
263 extension_registry_observer_;
[email protected]655b2b1a2011-10-13 17:13:06264 Profile* profile_;
[email protected]98e4e522011-10-25 13:00:16265 Delegate* delegate_;
[email protected]98e4e522011-10-25 13:00:16266 std::string id_;
[email protected]669b2372013-10-17 15:04:58267 InstallSource install_source_;
[email protected]8adbe3112012-03-27 05:42:22268 // The DownloadItem is owned by the DownloadManager and is valid from when
[email protected]81b80bc2012-08-31 18:27:44269 // OnDownloadStarted is called (with no error) until OnDownloadDestroyed().
[email protected]8adbe3112012-03-27 05:42:22270 content::DownloadItem* download_item_;
[email protected]c80fe5f2014-03-26 04:36:30271 // Used to periodically update the extension's download status. This will
272 // trigger at least every second, though sometimes more frequently (depending
273 // on number of modules, etc).
274 base::OneShotTimer<WebstoreInstaller> download_progress_timer_;
[email protected]21a5ad62012-04-03 04:48:45275 scoped_ptr<Approval> approval_;
[email protected]98e4e522011-10-25 13:00:16276 GURL download_url_;
[email protected]5206ae82014-04-23 12:03:33277 scoped_refptr<CrxInstaller> crx_installer_;
[email protected]669b2372013-10-17 15:04:58278
279 // Pending modules.
280 std::list<SharedModuleInfo::ImportInfo> pending_modules_;
281 // Total extension modules we need download and install (the main module and
282 // depedences).
283 int total_modules_;
284 bool download_started_;
[email protected]655b2b1a2011-10-13 17:13:06285};
286
[email protected]3d61a7f2012-07-12 19:11:25287} // namespace extensions
288
[email protected]655b2b1a2011-10-13 17:13:06289#endif // CHROME_BROWSER_EXTENSIONS_WEBSTORE_INSTALLER_H_