Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / extensions / webstore_installer.h
blob58e76fa9cf71371353c04556c72885f18071ecf1
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_WEBSTORE_INSTALLER_H_
6 #define CHROME_BROWSER_EXTENSIONS_WEBSTORE_INSTALLER_H_
8 #include <list>
9 #include <string>
11 #include "base/compiler_specific.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/scoped_observer.h"
15 #include "base/supports_user_data.h"
16 #include "base/timer/timer.h"
17 #include "base/values.h"
18 #include "base/version.h"
19 #include "chrome/browser/extensions/extension_install_prompt.h"
20 #include "content/public/browser/browser_thread.h"
21 #include "content/public/browser/download_interrupt_reasons.h"
22 #include "content/public/browser/download_item.h"
23 #include "content/public/browser/notification_observer.h"
24 #include "content/public/browser/notification_registrar.h"
25 #include "content/public/browser/web_contents_observer.h"
26 #include "extensions/browser/extension_registry_observer.h"
27 #include "extensions/common/manifest_handlers/shared_module_info.h"
28 #include "ui/gfx/image/image_skia.h"
29 #include "url/gurl.h"
31 class Profile;
33 namespace base {
34 class FilePath;
37 namespace content {
38 class WebContents;
41 namespace extensions {
43 class CrxInstaller;
44 class Extension;
45 class ExtensionRegistry;
46 class Manifest;
48 // Downloads and installs extensions from the web store.
49 class WebstoreInstaller : public content::NotificationObserver,
50 public ExtensionRegistryObserver,
51 public content::DownloadItem::Observer,
52 public content::WebContentsObserver,
53 public base::RefCountedThreadSafe<
54 WebstoreInstaller,
55 content::BrowserThread::DeleteOnUIThread> {
56 public:
57 enum InstallSource {
58 // Inline installs trigger slightly different behavior (install source
59 // is different, download referrers are the item's page in the gallery).
60 INSTALL_SOURCE_INLINE,
61 INSTALL_SOURCE_APP_LAUNCHER,
62 INSTALL_SOURCE_OTHER
65 enum FailureReason {
66 FAILURE_REASON_CANCELLED,
67 FAILURE_REASON_DEPENDENCY_NOT_FOUND,
68 FAILURE_REASON_DEPENDENCY_NOT_SHARED_MODULE,
69 FAILURE_REASON_OTHER
72 enum ManifestCheckLevel {
73 // Do not check for any manifest equality.
74 MANIFEST_CHECK_LEVEL_NONE,
76 // Only check that the expected and actual permissions have the same
77 // effective permissions.
78 MANIFEST_CHECK_LEVEL_LOOSE,
80 // All data in the expected and actual manifests must match.
81 MANIFEST_CHECK_LEVEL_STRICT,
84 class Delegate {
85 public:
86 virtual void OnExtensionDownloadStarted(const std::string& id,
87 content::DownloadItem* item);
88 virtual void OnExtensionDownloadProgress(const std::string& id,
89 content::DownloadItem* item);
90 virtual void OnExtensionInstallSuccess(const std::string& id) = 0;
91 virtual void OnExtensionInstallFailure(const std::string& id,
92 const std::string& error,
93 FailureReason reason) = 0;
95 protected:
96 virtual ~Delegate() {}
99 // 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.
103 struct Approval : public base::SupportsUserData::Data {
104 static scoped_ptr<Approval> CreateWithInstallPrompt(Profile* profile);
106 // Creates an Approval for installing a shared module.
107 static scoped_ptr<Approval> CreateForSharedModule(Profile* profile);
109 // 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.
114 static scoped_ptr<Approval> CreateWithNoInstallPrompt(
115 Profile* profile,
116 const std::string& extension_id,
117 scoped_ptr<base::DictionaryValue> parsed_manifest,
118 bool strict_manifest_check);
120 ~Approval() override;
122 // The extension id that was approved for installation.
123 std::string extension_id;
125 // The profile the extension should be installed into.
126 Profile* profile;
128 // The expected manifest, before localization.
129 scoped_ptr<Manifest> manifest;
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;
135 // Whether to skip the post install UI like the extension installed bubble.
136 bool skip_post_install_ui;
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;
144 // Whether we should enable the launcher before installing the app.
145 bool enable_launcher;
147 // Manifest check level for checking actual manifest against expected
148 // manifest.
149 ManifestCheckLevel manifest_check_level;
151 // Used to show the install dialog.
152 ExtensionInstallPrompt::ShowDialogCallback show_dialog_callback;
154 // The icon to use to display the extension while it is installing.
155 gfx::ImageSkia installing_icon;
157 // A dummy extension created from |manifest|;
158 scoped_refptr<Extension> dummy_extension;
160 // Required minimum version.
161 scoped_ptr<Version> minimum_version;
163 // Ephemeral apps are transiently installed.
164 bool is_ephemeral;
166 // 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;
170 private:
171 Approval();
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);
179 // 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
183 // WebstoreInstaller can use a specific controller at any given time. This
184 // also associates the |approval| with this install.
185 // Note: the delegate should stay alive until being called back.
186 WebstoreInstaller(Profile* profile,
187 Delegate* delegate,
188 content::WebContents* web_contents,
189 const std::string& id,
190 scoped_ptr<Approval> approval,
191 InstallSource source);
193 // Starts downloading and installing the extension.
194 void Start();
196 // content::NotificationObserver.
197 void Observe(int type,
198 const content::NotificationSource& source,
199 const content::NotificationDetails& details) override;
201 // ExtensionRegistryObserver.
202 void OnExtensionInstalled(content::BrowserContext* browser_context,
203 const Extension* extension,
204 bool is_update) override;
206 // 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();
210 // Instead of using the default download directory, use |directory| instead.
211 // This does *not* transfer ownership of |directory|.
212 static void SetDownloadDirectoryForTests(base::FilePath* directory);
214 protected:
215 // For testing.
216 ~WebstoreInstaller() override;
218 private:
219 FRIEND_TEST_ALL_PREFIXES(WebstoreInstallerTest, PlatformParams);
220 friend struct content::BrowserThread::DeleteOnThread<
221 content::BrowserThread::UI>;
222 friend class base::DeleteHelper<WebstoreInstaller>;
224 // Helper to get install URL.
225 static GURL GetWebstoreInstallURL(const std::string& extension_id,
226 InstallSource source);
228 // DownloadManager::DownloadUrl callback.
229 void OnDownloadStarted(const std::string& extension_id,
230 content::DownloadItem* item,
231 content::DownloadInterruptReason interrupt_reason);
233 // DownloadItem::Observer implementation:
234 void OnDownloadUpdated(content::DownloadItem* download) override;
235 void OnDownloadDestroyed(content::DownloadItem* download) override;
237 // Downloads next pending module in |pending_modules_|.
238 void DownloadNextPendingModule();
240 // Downloads and installs a single Crx with the given |extension_id|.
241 // This function is used for both the extension Crx and dependences.
242 void DownloadCrx(const std::string& extension_id, InstallSource source);
244 // Starts downloading the extension with ID |extension_id| to |file_path|.
245 void StartDownload(const std::string& extension_id,
246 const base::FilePath& file_path);
248 // Updates the InstallTracker with the latest download progress.
249 void UpdateDownloadProgress();
251 // Creates and starts CrxInstaller for the downloaded extension package.
252 void StartCrxInstaller(const content::DownloadItem& item);
254 // Reports an install |error| to the delegate for the given extension if this
255 // managed its installation. This also removes the associated PendingInstall.
256 void ReportFailure(const std::string& error, FailureReason reason);
258 // Reports a successful install to the delegate for the given extension if
259 // this managed its installation. This also removes the associated
260 // PendingInstall.
261 void ReportSuccess();
263 // Records stats regarding an interrupted webstore download item.
264 void RecordInterrupt(const content::DownloadItem* download) const;
266 content::NotificationRegistrar registrar_;
267 ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
268 extension_registry_observer_;
269 Profile* profile_;
270 Delegate* delegate_;
271 std::string id_;
272 InstallSource install_source_;
273 // The DownloadItem is owned by the DownloadManager and is valid from when
274 // OnDownloadStarted is called (with no error) until OnDownloadDestroyed().
275 content::DownloadItem* download_item_;
276 // Used to periodically update the extension's download status. This will
277 // trigger at least every second, though sometimes more frequently (depending
278 // on number of modules, etc).
279 base::OneShotTimer<WebstoreInstaller> download_progress_timer_;
280 scoped_ptr<Approval> approval_;
281 GURL download_url_;
282 scoped_refptr<CrxInstaller> crx_installer_;
284 // Pending modules.
285 std::list<SharedModuleInfo::ImportInfo> pending_modules_;
286 // Total extension modules we need download and install (the main module and
287 // depedences).
288 int total_modules_;
289 bool download_started_;
292 } // namespace extensions
294 #endif // CHROME_BROWSER_EXTENSIONS_WEBSTORE_INSTALLER_H_