blob: 2dc86e3a197a27c3f39e652a7be8448c07f2f0b0 [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>
dchengc963c7142016-04-08 03:55:229#include <memory>
[email protected]655b2b1a2011-10-13 17:13:0610#include <string>
[email protected]655b2b1a2011-10-13 17:13:0611
12#include "base/compiler_specific.h"
thestiga0e18cd2015-09-25 04:58:3613#include "base/gtest_prod_util.h"
[email protected]98e4e522011-10-25 13:00:1614#include "base/memory/ref_counted.h"
[email protected]17f07822014-05-22 08:45:1515#include "base/scoped_observer.h"
[email protected]d59d40c2012-08-08 18:18:3716#include "base/supports_user_data.h"
[email protected]c80fe5f2014-03-26 04:36:3017#include "base/timer/timer.h"
[email protected]21a5ad62012-04-03 04:48:4518#include "base/values.h"
[email protected]669b2372013-10-17 15:04:5819#include "base/version.h"
[email protected]af6efb22012-10-12 02:23:0520#include "chrome/browser/extensions/extension_install_prompt.h"
Min Qineb78b7a2018-02-03 00:43:1621#include "components/download/public/common/download_interrupt_reasons.h"
Min Qina9f487872018-02-09 20:43:2322#include "components/download/public/common/download_item.h"
[email protected]ed0757ec2012-08-02 17:23:2623#include "content/public/browser/browser_thread.h"
[email protected]6c2381d2011-10-19 02:52:5324#include "content/public/browser/notification_observer.h"
25#include "content/public/browser/notification_registrar.h"
[email protected]2acf3a52014-02-13 00:26:0026#include "content/public/browser/web_contents_observer.h"
[email protected]17f07822014-05-22 08:45:1527#include "extensions/browser/extension_registry_observer.h"
[email protected]301116c62013-11-26 10:37:4528#include "extensions/common/manifest_handlers/shared_module_info.h"
[email protected]7b4eea602013-02-08 06:19:4729#include "ui/gfx/image/image_skia.h"
[email protected]a6483d22013-07-03 22:11:0030#include "url/gurl.h"
[email protected]655b2b1a2011-10-13 17:13:0631
[email protected]655b2b1a2011-10-13 17:13:0632class Profile;
33
[email protected]a3ef4832013-02-02 05:12:3334namespace base {
35class FilePath;
36}
37
[email protected]cdcb1dee2012-01-04 00:46:2038namespace content {
[email protected]2acf3a52014-02-13 00:26:0039class WebContents;
[email protected]cdcb1dee2012-01-04 00:46:2040}
41
[email protected]3d61a7f2012-07-12 19:11:2542namespace extensions {
43
[email protected]5206ae82014-04-23 12:03:3344class CrxInstaller;
[email protected]669b2372013-10-17 15:04:5845class Extension;
[email protected]17f07822014-05-22 08:45:1546class ExtensionRegistry;
[email protected]21c01042013-03-10 23:41:1447class Manifest;
48
[email protected]655b2b1a2011-10-13 17:13:0649// Downloads and installs extensions from the web store.
[email protected]2acf3a52014-02-13 00:26:0050class WebstoreInstaller : public content::NotificationObserver,
[email protected]17f07822014-05-22 08:45:1551 public ExtensionRegistryObserver,
Min Qina9f487872018-02-09 20:43:2352 public download::DownloadItem::Observer,
[email protected]2acf3a52014-02-13 00:26:0053 public content::WebContentsObserver,
54 public base::RefCountedThreadSafe<
[email protected]17f07822014-05-22 08:45:1555 WebstoreInstaller,
56 content::BrowserThread::DeleteOnUIThread> {
[email protected]655b2b1a2011-10-13 17:13:0657 public:
[email protected]084e35482013-09-25 02:46:1958 enum InstallSource {
[email protected]99dfecd2011-10-18 01:11:5059 // Inline installs trigger slightly different behavior (install source
60 // is different, download referrers are the item's page in the gallery).
Benjamin Ackermanc4fb02302018-10-03 19:55:4161 // TODO(ackermanb): Remove once server side metrics (omaha) tracking with
62 // this enum is figured out with any of the subclasses of
63 // WebstoreStandaloneInstaller.
[email protected]084e35482013-09-25 02:46:1964 INSTALL_SOURCE_INLINE,
65 INSTALL_SOURCE_APP_LAUNCHER,
66 INSTALL_SOURCE_OTHER
[email protected]655b2b1a2011-10-13 17:13:0667 };
68
[email protected]bcd1eaf72012-10-03 05:42:2969 enum FailureReason {
70 FAILURE_REASON_CANCELLED,
[email protected]669b2372013-10-17 15:04:5871 FAILURE_REASON_DEPENDENCY_NOT_FOUND,
72 FAILURE_REASON_DEPENDENCY_NOT_SHARED_MODULE,
[email protected]bcd1eaf72012-10-03 05:42:2973 FAILURE_REASON_OTHER
74 };
75
[email protected]669b2372013-10-17 15:04:5876 enum ManifestCheckLevel {
77 // Do not check for any manifest equality.
78 MANIFEST_CHECK_LEVEL_NONE,
79
80 // Only check that the expected and actual permissions have the same
81 // effective permissions.
82 MANIFEST_CHECK_LEVEL_LOOSE,
83
84 // All data in the expected and actual manifests must match.
85 MANIFEST_CHECK_LEVEL_STRICT,
86 };
87
[email protected]655b2b1a2011-10-13 17:13:0688 class Delegate {
89 public:
[email protected]bcd1eaf72012-10-03 05:42:2990 virtual void OnExtensionDownloadStarted(const std::string& id,
Min Qina9f487872018-02-09 20:43:2391 download::DownloadItem* item);
[email protected]bcd1eaf72012-10-03 05:42:2992 virtual void OnExtensionDownloadProgress(const std::string& id,
Min Qina9f487872018-02-09 20:43:2393 download::DownloadItem* item);
[email protected]655b2b1a2011-10-13 17:13:0694 virtual void OnExtensionInstallSuccess(const std::string& id) = 0;
95 virtual void OnExtensionInstallFailure(const std::string& id,
[email protected]bcd1eaf72012-10-03 05:42:2996 const std::string& error,
97 FailureReason reason) = 0;
[email protected]512d03f2012-06-26 01:06:0698
99 protected:
100 virtual ~Delegate() {}
[email protected]655b2b1a2011-10-13 17:13:06101 };
102
[email protected]89019d62012-05-17 18:47:09103 // Contains information about what parts of the extension install process can
104 // be skipped or modified. If one of these is present, it means that a CRX
105 // download was initiated by WebstoreInstaller. The Approval instance should
106 // be checked further for additional details.
[email protected]d59d40c2012-08-08 18:18:37107 struct Approval : public base::SupportsUserData::Data {
dchengc963c7142016-04-08 03:55:22108 static std::unique_ptr<Approval> CreateWithInstallPrompt(Profile* profile);
[email protected]85290822013-08-23 20:27:38109
[email protected]669b2372013-10-17 15:04:58110 // Creates an Approval for installing a shared module.
dchengc963c7142016-04-08 03:55:22111 static std::unique_ptr<Approval> CreateForSharedModule(Profile* profile);
[email protected]669b2372013-10-17 15:04:58112
[email protected]85290822013-08-23 20:27:38113 // Creates an Approval that will skip putting up an install confirmation
114 // prompt if the actual manifest from the extension to be installed matches
115 // |parsed_manifest|. The |strict_manifest_check| controls whether we want
116 // to require an exact manifest match, or are willing to tolerate a looser
117 // check just that the effective permissions are the same.
dchengc963c7142016-04-08 03:55:22118 static std::unique_ptr<Approval> CreateWithNoInstallPrompt(
[email protected]89019d62012-05-17 18:47:09119 Profile* profile,
120 const std::string& extension_id,
dchengc963c7142016-04-08 03:55:22121 std::unique_ptr<base::DictionaryValue> parsed_manifest,
[email protected]85290822013-08-23 20:27:38122 bool strict_manifest_check);
[email protected]89019d62012-05-17 18:47:09123
dchengae36a4a2014-10-21 12:36:36124 ~Approval() override;
[email protected]21a5ad62012-04-03 04:48:45125
126 // The extension id that was approved for installation.
127 std::string extension_id;
128
129 // The profile the extension should be installed into.
130 Profile* profile;
131
132 // The expected manifest, before localization.
dchengc963c7142016-04-08 03:55:22133 std::unique_ptr<Manifest> manifest;
[email protected]21a5ad62012-04-03 04:48:45134
135 // Whether to use a bubble notification when an app is installed, instead of
136 // the default behavior of transitioning to the new tab page.
137 bool use_app_installed_bubble;
138
139 // Whether to skip the post install UI like the extension installed bubble.
140 bool skip_post_install_ui;
[email protected]89019d62012-05-17 18:47:09141
142 // Whether to skip the install dialog once the extension has been downloaded
143 // and unpacked. One reason this can be true is that in the normal webstore
144 // installation, the dialog is shown earlier, before any download is done,
145 // so there's no need to show it again.
146 bool skip_install_dialog;
147
[email protected]669b2372013-10-17 15:04:58148 // Manifest check level for checking actual manifest against expected
149 // manifest.
150 ManifestCheckLevel manifest_check_level;
[email protected]85290822013-08-23 20:27:38151
[email protected]af6efb22012-10-12 02:23:05152 // Used to show the install dialog.
153 ExtensionInstallPrompt::ShowDialogCallback show_dialog_callback;
154
[email protected]7b4eea602013-02-08 06:19:47155 // The icon to use to display the extension while it is installing.
156 gfx::ImageSkia installing_icon;
157
[email protected]669b2372013-10-17 15:04:58158 // A dummy extension created from |manifest|;
159 scoped_refptr<Extension> dummy_extension;
160
161 // Required minimum version.
pwnallcbd73192016-08-22 18:59:17162 std::unique_ptr<base::Version> minimum_version;
[email protected]669b2372013-10-17 15:04:58163
[email protected]e7684952014-05-09 21:41:35164 // The authuser index required to download the item being installed. May be
165 // the empty string, in which case no authuser parameter is used.
166 std::string authuser;
167
[email protected]89019d62012-05-17 18:47:09168 private:
169 Approval();
[email protected]21a5ad62012-04-03 04:48:45170 };
171
172 // Gets the Approval associated with the |download|, or NULL if there's none.
173 // Note that the Approval is owned by |download|.
174 static const Approval* GetAssociatedApproval(
Min Qina9f487872018-02-09 20:43:23175 const download::DownloadItem& download);
[email protected]21a5ad62012-04-03 04:48:45176
[email protected]98e4e522011-10-25 13:00:16177 // Creates a WebstoreInstaller for downloading and installing the extension
178 // with the given |id| from the Chrome Web Store. If |delegate| is not NULL,
179 // it will be notified when the install succeeds or fails. The installer will
180 // use the specified |controller| to download the extension. Only one
[email protected]21a5ad62012-04-03 04:48:45181 // WebstoreInstaller can use a specific controller at any given time. This
182 // also associates the |approval| with this install.
[email protected]98e4e522011-10-25 13:00:16183 // Note: the delegate should stay alive until being called back.
184 WebstoreInstaller(Profile* profile,
185 Delegate* delegate,
[email protected]2acf3a52014-02-13 00:26:00186 content::WebContents* web_contents,
[email protected]98e4e522011-10-25 13:00:16187 const std::string& id,
dchengc963c7142016-04-08 03:55:22188 std::unique_ptr<Approval> approval,
[email protected]084e35482013-09-25 02:46:19189 InstallSource source);
[email protected]655b2b1a2011-10-13 17:13:06190
[email protected]98e4e522011-10-25 13:00:16191 // Starts downloading and installing the extension.
192 void Start();
[email protected]655b2b1a2011-10-13 17:13:06193
[email protected]17f07822014-05-22 08:45:15194 // content::NotificationObserver.
dchengae36a4a2014-10-21 12:36:36195 void Observe(int type,
196 const content::NotificationSource& source,
197 const content::NotificationDetails& details) override;
[email protected]655b2b1a2011-10-13 17:13:06198
[email protected]17f07822014-05-22 08:45:15199 // ExtensionRegistryObserver.
dchengae36a4a2014-10-21 12:36:36200 void OnExtensionInstalled(content::BrowserContext* browser_context,
201 const Extension* extension,
202 bool is_update) override;
[email protected]17f07822014-05-22 08:45:15203
[email protected]e074e322012-10-30 01:12:09204 // Removes the reference to the delegate passed in the constructor. Used when
205 // the delegate object must be deleted before this object.
206 void InvalidateDelegate();
207
[email protected]9c265d02011-12-29 22:13:43208 // Instead of using the default download directory, use |directory| instead.
209 // This does *not* transfer ownership of |directory|.
[email protected]a3ef4832013-02-02 05:12:33210 static void SetDownloadDirectoryForTests(base::FilePath* directory);
[email protected]9c265d02011-12-29 22:13:43211
amistry7d82d50a2015-01-12 20:17:28212 protected:
213 // For testing.
214 ~WebstoreInstaller() override;
215
[email protected]655b2b1a2011-10-13 17:13:06216 private:
[email protected]902a8a012013-05-04 05:04:16217 FRIEND_TEST_ALL_PREFIXES(WebstoreInstallerTest, PlatformParams);
[email protected]ed0757ec2012-08-02 17:23:26218 friend struct content::BrowserThread::DeleteOnThread<
amistry7d82d50a2015-01-12 20:17:28219 content::BrowserThread::UI>;
[email protected]ed0757ec2012-08-02 17:23:26220 friend class base::DeleteHelper<WebstoreInstaller>;
[email protected]5f2a4752012-04-27 22:18:58221
[email protected]902a8a012013-05-04 05:04:16222 // Helper to get install URL.
223 static GURL GetWebstoreInstallURL(const std::string& extension_id,
[email protected]669b2372013-10-17 15:04:58224 InstallSource source);
[email protected]902a8a012013-05-04 05:04:16225
[email protected]8adbe3112012-03-27 05:42:22226 // DownloadManager::DownloadUrl callback.
amistry7d82d50a2015-01-12 20:17:28227 void OnDownloadStarted(const std::string& extension_id,
Min Qina9f487872018-02-09 20:43:23228 download::DownloadItem* item,
Min Qineb78b7a2018-02-03 00:43:16229 download::DownloadInterruptReason interrupt_reason);
[email protected]8adbe3112012-03-27 05:42:22230
231 // DownloadItem::Observer implementation:
Min Qina9f487872018-02-09 20:43:23232 void OnDownloadUpdated(download::DownloadItem* download) override;
233 void OnDownloadDestroyed(download::DownloadItem* download) override;
[email protected]8adbe3112012-03-27 05:42:22234
[email protected]669b2372013-10-17 15:04:58235 // Downloads next pending module in |pending_modules_|.
236 void DownloadNextPendingModule();
237
238 // Downloads and installs a single Crx with the given |extension_id|.
239 // This function is used for both the extension Crx and dependences.
240 void DownloadCrx(const std::string& extension_id, InstallSource source);
241
amistry7d82d50a2015-01-12 20:17:28242 // Starts downloading the extension with ID |extension_id| to |file_path|.
243 void StartDownload(const std::string& extension_id,
244 const base::FilePath& file_path);
[email protected]f66a50a2011-11-02 23:53:46245
[email protected]c80fe5f2014-03-26 04:36:30246 // Updates the InstallTracker with the latest download progress.
247 void UpdateDownloadProgress();
248
[email protected]5206ae82014-04-23 12:03:33249 // Creates and starts CrxInstaller for the downloaded extension package.
Min Qina9f487872018-02-09 20:43:23250 void StartCrxInstaller(const download::DownloadItem& item);
[email protected]5206ae82014-04-23 12:03:33251
[email protected]655b2b1a2011-10-13 17:13:06252 // Reports an install |error| to the delegate for the given extension if this
253 // managed its installation. This also removes the associated PendingInstall.
[email protected]bcd1eaf72012-10-03 05:42:29254 void ReportFailure(const std::string& error, FailureReason reason);
[email protected]655b2b1a2011-10-13 17:13:06255
256 // Reports a successful install to the delegate for the given extension if
257 // this managed its installation. This also removes the associated
258 // PendingInstall.
[email protected]98e4e522011-10-25 13:00:16259 void ReportSuccess();
[email protected]655b2b1a2011-10-13 17:13:06260
[email protected]0a2a7242013-11-20 20:49:24261 // Records stats regarding an interrupted webstore download item.
Min Qina9f487872018-02-09 20:43:23262 void RecordInterrupt(const download::DownloadItem* download) const;
[email protected]0a2a7242013-11-20 20:49:24263
[email protected]6c2381d2011-10-19 02:52:53264 content::NotificationRegistrar registrar_;
[email protected]17f07822014-05-22 08:45:15265 ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
266 extension_registry_observer_;
[email protected]655b2b1a2011-10-13 17:13:06267 Profile* profile_;
[email protected]98e4e522011-10-25 13:00:16268 Delegate* delegate_;
[email protected]98e4e522011-10-25 13:00:16269 std::string id_;
[email protected]669b2372013-10-17 15:04:58270 InstallSource install_source_;
[email protected]8adbe3112012-03-27 05:42:22271 // The DownloadItem is owned by the DownloadManager and is valid from when
[email protected]81b80bc2012-08-31 18:27:44272 // OnDownloadStarted is called (with no error) until OnDownloadDestroyed().
Min Qina9f487872018-02-09 20:43:23273 download::DownloadItem* download_item_;
[email protected]c80fe5f2014-03-26 04:36:30274 // Used to periodically update the extension's download status. This will
275 // trigger at least every second, though sometimes more frequently (depending
276 // on number of modules, etc).
danakj8c3eb802015-09-24 07:53:00277 base::OneShotTimer download_progress_timer_;
dchengc963c7142016-04-08 03:55:22278 std::unique_ptr<Approval> approval_;
[email protected]98e4e522011-10-25 13:00:16279 GURL download_url_;
[email protected]5206ae82014-04-23 12:03:33280 scoped_refptr<CrxInstaller> crx_installer_;
[email protected]669b2372013-10-17 15:04:58281
282 // Pending modules.
283 std::list<SharedModuleInfo::ImportInfo> pending_modules_;
284 // Total extension modules we need download and install (the main module and
285 // depedences).
286 int total_modules_;
287 bool download_started_;
[email protected]655b2b1a2011-10-13 17:13:06288};
289
[email protected]3d61a7f2012-07-12 19:11:25290} // namespace extensions
291
[email protected]655b2b1a2011-10-13 17:13:06292#endif // CHROME_BROWSER_EXTENSIONS_WEBSTORE_INSTALLER_H_