[email protected] | bdb74a2 | 2012-01-25 20:33:33 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
[email protected] | 8915f34 | 2011-08-29 22:14:37 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
[email protected] | 734bcec | 2012-10-08 20:29:05 | [diff] [blame] | 5 | #ifndef CHROME_BROWSER_EXTENSIONS_WEBSTORE_STANDALONE_INSTALLER_H_ |
| 6 | #define CHROME_BROWSER_EXTENSIONS_WEBSTORE_STANDALONE_INSTALLER_H_ |
[email protected] | 8915f34 | 2011-08-29 22:14:37 | [diff] [blame] | 7 | |
dcheng | c963c714 | 2016-04-08 03:55:22 | [diff] [blame] | 8 | #include <memory> |
[email protected] | 8915f34 | 2011-08-29 22:14:37 | [diff] [blame] | 9 | #include <string> |
| 10 | |
[email protected] | d2a639e | 2012-09-17 07:41:21 | [diff] [blame] | 11 | #include "base/callback.h" |
avi | a2f4804a | 2015-12-24 23:11:13 | [diff] [blame] | 12 | #include "base/macros.h" |
[email protected] | 8915f34 | 2011-08-29 22:14:37 | [diff] [blame] | 13 | #include "base/memory/ref_counted.h" |
[email protected] | 773272b | 2014-07-18 05:48:35 | [diff] [blame] | 14 | #include "chrome/browser/extensions/active_install_data.h" |
[email protected] | c82da8c4 | 2012-06-08 19:49:11 | [diff] [blame] | 15 | #include "chrome/browser/extensions/extension_install_prompt.h" |
[email protected] | 7b394105 | 2013-02-13 01:21:59 | [diff] [blame] | 16 | #include "chrome/browser/extensions/webstore_data_fetcher_delegate.h" |
[email protected] | 8915f34 | 2011-08-29 22:14:37 | [diff] [blame] | 17 | #include "chrome/browser/extensions/webstore_install_helper.h" |
[email protected] | 10c2d69 | 2012-05-11 05:32:23 | [diff] [blame] | 18 | #include "chrome/browser/extensions/webstore_installer.h" |
[email protected] | ced522c | 2014-07-23 20:23:59 | [diff] [blame] | 19 | #include "chrome/common/extensions/webstore_install_result.h" |
[email protected] | 15fb2aa | 2012-05-22 22:52:59 | [diff] [blame] | 20 | #include "net/url_request/url_fetcher_delegate.h" |
[email protected] | 8915f34 | 2011-08-29 22:14:37 | [diff] [blame] | 21 | #include "third_party/skia/include/core/SkBitmap.h" |
| 22 | |
[email protected] | d44ec7b | 2013-03-15 04:34:34 | [diff] [blame] | 23 | namespace base { |
| 24 | class DictionaryValue; |
| 25 | } |
[email protected] | 1c321ee | 2012-05-21 03:02:34 | [diff] [blame] | 26 | |
[email protected] | 3d61a7f | 2012-07-12 19:11:25 | [diff] [blame] | 27 | namespace extensions { |
| 28 | class Extension; |
[email protected] | 7b394105 | 2013-02-13 01:21:59 | [diff] [blame] | 29 | class WebstoreDataFetcher; |
[email protected] | 3d61a7f | 2012-07-12 19:11:25 | [diff] [blame] | 30 | |
[email protected] | d44ec7b | 2013-03-15 04:34:34 | [diff] [blame] | 31 | // A a purely abstract base for concrete classes implementing various types of |
| 32 | // standalone installs: |
| 33 | // 1) Downloads and parses metadata from the webstore. |
| 34 | // 2) Optionally shows an install dialog. |
| 35 | // 3) Starts download once the user confirms (if confirmation was requested). |
| 36 | // 4) Optionally shows a post-install UI. |
| 37 | // Follows the Template Method pattern. Implementing subclasses must override |
| 38 | // the primitive hooks in the corresponding section below. |
| 39 | |
[email protected] | 734bcec | 2012-10-08 20:29:05 | [diff] [blame] | 40 | class WebstoreStandaloneInstaller |
| 41 | : public base::RefCountedThreadSafe<WebstoreStandaloneInstaller>, |
[email protected] | 7b394105 | 2013-02-13 01:21:59 | [diff] [blame] | 42 | public WebstoreDataFetcherDelegate, |
[email protected] | cb08ba2 | 2011-10-19 21:41:40 | [diff] [blame] | 43 | public WebstoreInstaller::Delegate, |
[email protected] | 8915f34 | 2011-08-29 22:14:37 | [diff] [blame] | 44 | public WebstoreInstallHelper::Delegate { |
| 45 | public: |
[email protected] | d44ec7b | 2013-03-15 04:34:34 | [diff] [blame] | 46 | // A callback for when the install process completes, successfully or not. If |
[email protected] | d2a639e | 2012-09-17 07:41:21 | [diff] [blame] | 47 | // there was a failure, |success| will be false and |error| may contain a |
| 48 | // developer-readable error message about why it failed. |
Devlin Cronin | 1cf1016 | 2019-01-04 01:07:51 | [diff] [blame] | 49 | using Callback = base::OnceCallback<void(bool success, |
| 50 | const std::string& error, |
| 51 | webstore_install::Result result)>; |
[email protected] | d2a639e | 2012-09-17 07:41:21 | [diff] [blame] | 52 | |
[email protected] | d44ec7b | 2013-03-15 04:34:34 | [diff] [blame] | 53 | WebstoreStandaloneInstaller(const std::string& webstore_item_id, |
[email protected] | c1b2d04 | 2013-02-23 00:31:04 | [diff] [blame] | 54 | Profile* profile, |
Devlin Cronin | 1cf1016 | 2019-01-04 01:07:51 | [diff] [blame] | 55 | Callback callback); |
[email protected] | 8915f34 | 2011-08-29 22:14:37 | [diff] [blame] | 56 | void BeginInstall(); |
| 57 | |
[email protected] | d44ec7b | 2013-03-15 04:34:34 | [diff] [blame] | 58 | protected: |
dcheng | ae36a4a | 2014-10-21 12:36:36 | [diff] [blame] | 59 | ~WebstoreStandaloneInstaller() override; |
[email protected] | d44ec7b | 2013-03-15 04:34:34 | [diff] [blame] | 60 | |
rdevlin.cronin | 5f6b69d | 2014-09-20 01:23:35 | [diff] [blame] | 61 | // Runs the callback; primarily used for running a callback before it is |
Devlin Cronin | 1cf1016 | 2019-01-04 01:07:51 | [diff] [blame] | 62 | // cleared in AbortInstall(). This should only be called once for the lifetime |
| 63 | // of the class. |
rdevlin.cronin | 5f6b69d | 2014-09-20 01:23:35 | [diff] [blame] | 64 | void RunCallback( |
| 65 | bool success, const std::string& error, webstore_install::Result result); |
| 66 | |
[email protected] | 9c7b309 | 2014-06-21 01:19:03 | [diff] [blame] | 67 | // Called when the install should be aborted. The callback is cleared. |
[email protected] | d44ec7b | 2013-03-15 04:34:34 | [diff] [blame] | 68 | void AbortInstall(); |
[email protected] | 9c7b309 | 2014-06-21 01:19:03 | [diff] [blame] | 69 | |
[email protected] | 773272b | 2014-07-18 05:48:35 | [diff] [blame] | 70 | // Checks InstallTracker and returns true if the same extension is not |
| 71 | // currently being installed. Registers this install with the InstallTracker. |
| 72 | bool EnsureUniqueInstall(webstore_install::Result* reason, |
| 73 | std::string* error); |
| 74 | |
[email protected] | 9c7b309 | 2014-06-21 01:19:03 | [diff] [blame] | 75 | // Called when the install is complete. |
| 76 | virtual void CompleteInstall(webstore_install::Result result, |
| 77 | const std::string& error); |
| 78 | |
| 79 | // Called when the installer should proceed to prompt the user. |
| 80 | void ProceedWithInstallPrompt(); |
| 81 | |
| 82 | // Lazily creates a dummy extension for display from the parsed manifest. This |
| 83 | // is safe to call from OnManifestParsed() onwards. The manifest may be |
| 84 | // invalid, thus the caller must check that the return value is not NULL. |
| 85 | scoped_refptr<const Extension> GetLocalizedExtensionForDisplay(); |
[email protected] | d44ec7b | 2013-03-15 04:34:34 | [diff] [blame] | 86 | |
| 87 | // Template Method's hooks to be implemented by subclasses. |
| 88 | |
[email protected] | d44ec7b | 2013-03-15 04:34:34 | [diff] [blame] | 89 | // Called at certain check points of the workflow to decide whether it makes |
| 90 | // sense to proceed with installation. A requestor can be a website that |
| 91 | // initiated an inline installation, or a command line option. |
| 92 | virtual bool CheckRequestorAlive() const = 0; |
| 93 | |
[email protected] | d44ec7b | 2013-03-15 04:34:34 | [diff] [blame] | 94 | // Should a new tab be opened after installation to show the newly installed |
| 95 | // extension's icon? |
| 96 | virtual bool ShouldShowPostInstallUI() const = 0; |
| 97 | |
| 98 | // Should pop up an "App installed" bubble after installation? |
| 99 | virtual bool ShouldShowAppInstalledBubble() const = 0; |
| 100 | |
| 101 | // In the very least this should return a dummy WebContents (required |
| 102 | // by some calls even when no prompt or other UI is shown). A non-dummy |
| 103 | // WebContents is required if the prompt returned by CreateInstallPromt() |
| 104 | // contains a navigable link(s). Returned WebContents should correspond |
| 105 | // to |profile| passed into the constructor. |
| 106 | virtual content::WebContents* GetWebContents() const = 0; |
| 107 | |
| 108 | // Should return an installation prompt with desired properties or NULL if |
| 109 | // no prompt should be shown. |
dcheng | c963c714 | 2016-04-08 03:55:22 | [diff] [blame] | 110 | virtual std::unique_ptr<ExtensionInstallPrompt::Prompt> CreateInstallPrompt() |
[email protected] | d382baa | 2014-06-17 18:50:01 | [diff] [blame] | 111 | const = 0; |
[email protected] | d44ec7b | 2013-03-15 04:34:34 | [diff] [blame] | 112 | |
[email protected] | 9c7b309 | 2014-06-21 01:19:03 | [diff] [blame] | 113 | // Will be called after the extension's manifest has been successfully parsed. |
| 114 | // Subclasses can perform asynchronous checks at this point and call |
| 115 | // ProceedWithInstallPrompt() to proceed with the install or otherwise call |
| 116 | // CompleteInstall() with an error code. The default implementation calls |
| 117 | // ProceedWithInstallPrompt(). |
| 118 | virtual void OnManifestParsed(); |
[email protected] | ce35418b | 2013-11-25 01:22:33 | [diff] [blame] | 119 | |
[email protected] | f8b23b4 | 2013-06-27 20:12:14 | [diff] [blame] | 120 | // Returns an install UI to be shown. By default, this returns an install UI |
| 121 | // that is a transient child of the host window for GetWebContents(). |
dcheng | c963c714 | 2016-04-08 03:55:22 | [diff] [blame] | 122 | virtual std::unique_ptr<ExtensionInstallPrompt> CreateInstallUI(); |
[email protected] | f8b23b4 | 2013-06-27 20:12:14 | [diff] [blame] | 123 | |
[email protected] | ce35418b | 2013-11-25 01:22:33 | [diff] [blame] | 124 | // Create an approval to pass installation parameters to the CrxInstaller. |
dcheng | c963c714 | 2016-04-08 03:55:22 | [diff] [blame] | 125 | virtual std::unique_ptr<WebstoreInstaller::Approval> CreateApproval() const; |
[email protected] | ce35418b | 2013-11-25 01:22:33 | [diff] [blame] | 126 | |
rdevlin.cronin | 4159305 | 2016-01-08 01:40:12 | [diff] [blame] | 127 | // Called once the install prompt has finished. |
| 128 | virtual void OnInstallPromptDone(ExtensionInstallPrompt::Result result); |
rdevlin.cronin | 5f6b69d | 2014-09-20 01:23:35 | [diff] [blame] | 129 | |
[email protected] | d44ec7b | 2013-03-15 04:34:34 | [diff] [blame] | 130 | // Accessors to be used by subclasses. |
[email protected] | dcde34b3 | 2013-07-31 02:28:45 | [diff] [blame] | 131 | bool show_user_count() const { return show_user_count_; } |
[email protected] | d44ec7b | 2013-03-15 04:34:34 | [diff] [blame] | 132 | const std::string& localized_user_count() const { |
| 133 | return localized_user_count_; |
| 134 | } |
| 135 | double average_rating() const { return average_rating_; } |
| 136 | int rating_count() const { return rating_count_; } |
[email protected] | 084e3548 | 2013-09-25 02:46:19 | [diff] [blame] | 137 | void set_install_source(WebstoreInstaller::InstallSource source) { |
| 138 | install_source_ = source; |
| 139 | } |
| 140 | WebstoreInstaller::InstallSource install_source() const { |
| 141 | return install_source_; |
| 142 | } |
[email protected] | 1a93d8d | 2013-10-27 23:09:20 | [diff] [blame] | 143 | Profile* profile() const { return profile_; } |
| 144 | const std::string& id() const { return id_; } |
[email protected] | cb1078de | 2013-12-23 20:04:22 | [diff] [blame] | 145 | const base::DictionaryValue* manifest() const { return manifest_.get(); } |
[email protected] | 9c7b309 | 2014-06-21 01:19:03 | [diff] [blame] | 146 | const Extension* localized_extension_for_display() const { |
| 147 | return localized_extension_for_display_.get(); |
| 148 | } |
[email protected] | d44ec7b | 2013-03-15 04:34:34 | [diff] [blame] | 149 | |
[email protected] | 8915f34 | 2011-08-29 22:14:37 | [diff] [blame] | 150 | private: |
[email protected] | 734bcec | 2012-10-08 20:29:05 | [diff] [blame] | 151 | friend class base::RefCountedThreadSafe<WebstoreStandaloneInstaller>; |
[email protected] | 8915f34 | 2011-08-29 22:14:37 | [diff] [blame] | 152 | |
[email protected] | d44ec7b | 2013-03-15 04:34:34 | [diff] [blame] | 153 | // Several delegate/client interface implementations follow. The normal flow |
[email protected] | 8915f34 | 2011-08-29 22:14:37 | [diff] [blame] | 154 | // (for successful installs) is: |
| 155 | // |
| 156 | // 1. BeginInstall: starts the fetch of data from the webstore |
| 157 | // 2. OnURLFetchComplete: starts the parsing of data from the webstore |
| 158 | // 3. OnWebstoreResponseParseSuccess: starts the parsing of the manifest and |
| 159 | // fetching of icon data. |
| 160 | // 4. OnWebstoreParseSuccess: shows the install UI |
| 161 | // 5. InstallUIProceed: initiates the .crx download/install |
| 162 | // |
| 163 | // All flows (whether successful or not) end up in CompleteInstall, which |
| 164 | // informs our delegate of success/failure. |
| 165 | |
[email protected] | 7b394105 | 2013-02-13 01:21:59 | [diff] [blame] | 166 | // WebstoreDataFetcherDelegate interface implementation. |
dcheng | ae36a4a | 2014-10-21 12:36:36 | [diff] [blame] | 167 | void OnWebstoreRequestFailure() override; |
[email protected] | d44ec7b | 2013-03-15 04:34:34 | [diff] [blame] | 168 | |
dcheng | ae36a4a | 2014-10-21 12:36:36 | [diff] [blame] | 169 | void OnWebstoreResponseParseSuccess( |
dcheng | c963c714 | 2016-04-08 03:55:22 | [diff] [blame] | 170 | std::unique_ptr<base::DictionaryValue> webstore_data) override; |
[email protected] | d44ec7b | 2013-03-15 04:34:34 | [diff] [blame] | 171 | |
dcheng | ae36a4a | 2014-10-21 12:36:36 | [diff] [blame] | 172 | void OnWebstoreResponseParseFailure(const std::string& error) override; |
[email protected] | 8915f34 | 2011-08-29 22:14:37 | [diff] [blame] | 173 | |
| 174 | // WebstoreInstallHelper::Delegate interface implementation. |
Istiaque Ahmed | 27a6380 | 2018-11-07 20:34:38 | [diff] [blame] | 175 | void OnWebstoreParseSuccess( |
| 176 | const std::string& id, |
| 177 | const SkBitmap& icon, |
| 178 | std::unique_ptr<base::DictionaryValue> parsed_manifest) override; |
dcheng | ae36a4a | 2014-10-21 12:36:36 | [diff] [blame] | 179 | void OnWebstoreParseFailure(const std::string& id, |
| 180 | InstallHelperResultCode result_code, |
| 181 | const std::string& error_message) override; |
[email protected] | 8915f34 | 2011-08-29 22:14:37 | [diff] [blame] | 182 | |
[email protected] | cb08ba2 | 2011-10-19 21:41:40 | [diff] [blame] | 183 | // WebstoreInstaller::Delegate interface implementation. |
dcheng | ae36a4a | 2014-10-21 12:36:36 | [diff] [blame] | 184 | void OnExtensionInstallSuccess(const std::string& id) override; |
| 185 | void OnExtensionInstallFailure( |
[email protected] | bcd1eaf7 | 2012-10-03 05:42:29 | [diff] [blame] | 186 | const std::string& id, |
| 187 | const std::string& error, |
mostynb | a15bee1 | 2014-10-04 00:40:32 | [diff] [blame] | 188 | WebstoreInstaller::FailureReason reason) override; |
[email protected] | cb08ba2 | 2011-10-19 21:41:40 | [diff] [blame] | 189 | |
[email protected] | f8b23b4 | 2013-06-27 20:12:14 | [diff] [blame] | 190 | void ShowInstallUI(); |
[email protected] | e263a6b6 | 2014-06-05 23:19:49 | [diff] [blame] | 191 | void OnWebStoreDataFetcherDone(); |
[email protected] | bdb74a2 | 2012-01-25 20:33:33 | [diff] [blame] | 192 | |
[email protected] | c1b2d04 | 2013-02-23 00:31:04 | [diff] [blame] | 193 | // Input configuration. |
[email protected] | 8915f34 | 2011-08-29 22:14:37 | [diff] [blame] | 194 | std::string id_; |
[email protected] | d2a639e | 2012-09-17 07:41:21 | [diff] [blame] | 195 | Callback callback_; |
[email protected] | d44ec7b | 2013-03-15 04:34:34 | [diff] [blame] | 196 | Profile* profile_; |
[email protected] | 084e3548 | 2013-09-25 02:46:19 | [diff] [blame] | 197 | WebstoreInstaller::InstallSource install_source_; |
[email protected] | c1b2d04 | 2013-02-23 00:31:04 | [diff] [blame] | 198 | |
[email protected] | d44ec7b | 2013-03-15 04:34:34 | [diff] [blame] | 199 | // Installation dialog and its underlying prompt. |
dcheng | c963c714 | 2016-04-08 03:55:22 | [diff] [blame] | 200 | std::unique_ptr<ExtensionInstallPrompt> install_ui_; |
| 201 | std::unique_ptr<ExtensionInstallPrompt::Prompt> install_prompt_; |
[email protected] | 8915f34 | 2011-08-29 22:14:37 | [diff] [blame] | 202 | |
| 203 | // For fetching webstore JSON data. |
dcheng | c963c714 | 2016-04-08 03:55:22 | [diff] [blame] | 204 | std::unique_ptr<WebstoreDataFetcher> webstore_data_fetcher_; |
[email protected] | 8915f34 | 2011-08-29 22:14:37 | [diff] [blame] | 205 | |
| 206 | // Extracted from the webstore JSON data response. |
| 207 | std::string localized_name_; |
[email protected] | 5fdbd6f | 2011-09-01 17:33:04 | [diff] [blame] | 208 | std::string localized_description_; |
[email protected] | dcde34b3 | 2013-07-31 02:28:45 | [diff] [blame] | 209 | bool show_user_count_; |
[email protected] | 5fdbd6f | 2011-09-01 17:33:04 | [diff] [blame] | 210 | std::string localized_user_count_; |
| 211 | double average_rating_; |
| 212 | int rating_count_; |
dcheng | c963c714 | 2016-04-08 03:55:22 | [diff] [blame] | 213 | std::unique_ptr<base::DictionaryValue> webstore_data_; |
| 214 | std::unique_ptr<base::DictionaryValue> manifest_; |
[email protected] | 8915f34 | 2011-08-29 22:14:37 | [diff] [blame] | 215 | SkBitmap icon_; |
| 216 | |
[email protected] | 773272b | 2014-07-18 05:48:35 | [diff] [blame] | 217 | // Active install registered with the InstallTracker. |
dcheng | c963c714 | 2016-04-08 03:55:22 | [diff] [blame] | 218 | std::unique_ptr<ScopedActiveInstall> scoped_active_install_; |
[email protected] | 773272b | 2014-07-18 05:48:35 | [diff] [blame] | 219 | |
[email protected] | f8b23b4 | 2013-06-27 20:12:14 | [diff] [blame] | 220 | // Created by ShowInstallUI() when a prompt is shown (if |
[email protected] | d44ec7b | 2013-03-15 04:34:34 | [diff] [blame] | 221 | // the implementor returns a non-NULL in CreateInstallPrompt()). |
| 222 | scoped_refptr<Extension> localized_extension_for_display_; |
| 223 | |
[email protected] | 734bcec | 2012-10-08 20:29:05 | [diff] [blame] | 224 | DISALLOW_IMPLICIT_CONSTRUCTORS(WebstoreStandaloneInstaller); |
[email protected] | 8915f34 | 2011-08-29 22:14:37 | [diff] [blame] | 225 | }; |
| 226 | |
[email protected] | 3d61a7f | 2012-07-12 19:11:25 | [diff] [blame] | 227 | } // namespace extensions |
| 228 | |
[email protected] | 734bcec | 2012-10-08 20:29:05 | [diff] [blame] | 229 | #endif // CHROME_BROWSER_EXTENSIONS_WEBSTORE_STANDALONE_INSTALLER_H_ |