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_STANDALONE_INSTALLER_H_
6 #define CHROME_BROWSER_EXTENSIONS_WEBSTORE_STANDALONE_INSTALLER_H_
10 #include "base/callback.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "chrome/browser/extensions/active_install_data.h"
14 #include "chrome/browser/extensions/extension_install_prompt.h"
15 #include "chrome/browser/extensions/webstore_data_fetcher_delegate.h"
16 #include "chrome/browser/extensions/webstore_install_helper.h"
17 #include "chrome/browser/extensions/webstore_installer.h"
18 #include "chrome/common/extensions/webstore_install_result.h"
19 #include "net/url_request/url_fetcher_delegate.h"
20 #include "third_party/skia/include/core/SkBitmap.h"
25 class DictionaryValue
;
32 namespace extensions
{
34 class WebstoreDataFetcher
;
36 // A a purely abstract base for concrete classes implementing various types of
37 // standalone installs:
38 // 1) Downloads and parses metadata from the webstore.
39 // 2) Optionally shows an install dialog.
40 // 3) Starts download once the user confirms (if confirmation was requested).
41 // 4) Optionally shows a post-install UI.
42 // Follows the Template Method pattern. Implementing subclasses must override
43 // the primitive hooks in the corresponding section below.
45 class WebstoreStandaloneInstaller
46 : public base::RefCountedThreadSafe
<WebstoreStandaloneInstaller
>,
47 public ExtensionInstallPrompt::Delegate
,
48 public WebstoreDataFetcherDelegate
,
49 public WebstoreInstaller::Delegate
,
50 public WebstoreInstallHelper::Delegate
{
52 // A callback for when the install process completes, successfully or not. If
53 // there was a failure, |success| will be false and |error| may contain a
54 // developer-readable error message about why it failed.
55 typedef base::Callback
<void(bool success
,
56 const std::string
& error
,
57 webstore_install::Result result
)> Callback
;
59 WebstoreStandaloneInstaller(const std::string
& webstore_item_id
,
61 const Callback
& callback
);
65 ~WebstoreStandaloneInstaller() override
;
67 // Runs the callback; primarily used for running a callback before it is
68 // cleared in AbortInstall().
70 bool success
, const std::string
& error
, webstore_install::Result result
);
72 // Called when the install should be aborted. The callback is cleared.
75 // Checks InstallTracker and returns true if the same extension is not
76 // currently being installed. Registers this install with the InstallTracker.
77 bool EnsureUniqueInstall(webstore_install::Result
* reason
,
80 // Called when the install is complete.
81 virtual void CompleteInstall(webstore_install::Result result
,
82 const std::string
& error
);
84 // Called when the installer should proceed to prompt the user.
85 void ProceedWithInstallPrompt();
87 // Lazily creates a dummy extension for display from the parsed manifest. This
88 // is safe to call from OnManifestParsed() onwards. The manifest may be
89 // invalid, thus the caller must check that the return value is not NULL.
90 scoped_refptr
<const Extension
> GetLocalizedExtensionForDisplay();
92 // Template Method's hooks to be implemented by subclasses.
94 // Called when this install is about to be registered with the InstallTracker.
95 // Allows subclasses to set properties of the install data.
96 virtual void InitInstallData(ActiveInstallData
* install_data
) const;
98 // Called at certain check points of the workflow to decide whether it makes
99 // sense to proceed with installation. A requestor can be a website that
100 // initiated an inline installation, or a command line option.
101 virtual bool CheckRequestorAlive() const = 0;
103 // Requestor's URL, if any. Should be an empty GURL if URL is meaningless
104 // (e.g. for a command line option).
105 virtual const GURL
& GetRequestorURL() const = 0;
107 // Should a new tab be opened after installation to show the newly installed
109 virtual bool ShouldShowPostInstallUI() const = 0;
111 // Should pop up an "App installed" bubble after installation?
112 virtual bool ShouldShowAppInstalledBubble() const = 0;
114 // In the very least this should return a dummy WebContents (required
115 // by some calls even when no prompt or other UI is shown). A non-dummy
116 // WebContents is required if the prompt returned by CreateInstallPromt()
117 // contains a navigable link(s). Returned WebContents should correspond
118 // to |profile| passed into the constructor.
119 virtual content::WebContents
* GetWebContents() const = 0;
121 // Should return an installation prompt with desired properties or NULL if
122 // no prompt should be shown.
123 virtual scoped_refptr
<ExtensionInstallPrompt::Prompt
> CreateInstallPrompt()
126 // Perform all necessary checks to make sure inline install is permitted,
127 // e.g. in the extension's properties in the store. The implementation may
128 // choose to ignore such properties.
129 virtual bool CheckInlineInstallPermitted(
130 const base::DictionaryValue
& webstore_data
,
131 std::string
* error
) const = 0;
133 // Perform all necessary checks to make sure that requestor is allowed to
134 // initiate this install (e.g. that the requestor's URL matches the verified
135 // author's site specified in the extension's properties in the store).
136 virtual bool CheckRequestorPermitted(
137 const base::DictionaryValue
& webstore_data
,
138 std::string
* error
) const = 0;
140 // Will be called after the extension's manifest has been successfully parsed.
141 // Subclasses can perform asynchronous checks at this point and call
142 // ProceedWithInstallPrompt() to proceed with the install or otherwise call
143 // CompleteInstall() with an error code. The default implementation calls
144 // ProceedWithInstallPrompt().
145 virtual void OnManifestParsed();
147 // Returns an install UI to be shown. By default, this returns an install UI
148 // that is a transient child of the host window for GetWebContents().
149 virtual scoped_ptr
<ExtensionInstallPrompt
> CreateInstallUI();
151 // Create an approval to pass installation parameters to the CrxInstaller.
152 virtual scoped_ptr
<WebstoreInstaller::Approval
> CreateApproval() const;
154 // ExtensionInstallPrompt::Delegate interface implementation.
155 void InstallUIProceed() override
;
156 void InstallUIAbort(bool user_initiated
) override
;
158 // Accessors to be used by subclasses.
159 bool show_user_count() const { return show_user_count_
; }
160 const std::string
& localized_user_count() const {
161 return localized_user_count_
;
163 double average_rating() const { return average_rating_
; }
164 int rating_count() const { return rating_count_
; }
165 void set_install_source(WebstoreInstaller::InstallSource source
) {
166 install_source_
= source
;
168 WebstoreInstaller::InstallSource
install_source() const {
169 return install_source_
;
171 Profile
* profile() const { return profile_
; }
172 const std::string
& id() const { return id_
; }
173 const base::DictionaryValue
* manifest() const { return manifest_
.get(); }
174 const Extension
* localized_extension_for_display() const {
175 return localized_extension_for_display_
.get();
179 friend class base::RefCountedThreadSafe
<WebstoreStandaloneInstaller
>;
180 FRIEND_TEST_ALL_PREFIXES(WebstoreStandaloneInstallerTest
, DomainVerification
);
182 // Several delegate/client interface implementations follow. The normal flow
183 // (for successful installs) is:
185 // 1. BeginInstall: starts the fetch of data from the webstore
186 // 2. OnURLFetchComplete: starts the parsing of data from the webstore
187 // 3. OnWebstoreResponseParseSuccess: starts the parsing of the manifest and
188 // fetching of icon data.
189 // 4. OnWebstoreParseSuccess: shows the install UI
190 // 5. InstallUIProceed: initiates the .crx download/install
192 // All flows (whether successful or not) end up in CompleteInstall, which
193 // informs our delegate of success/failure.
195 // WebstoreDataFetcherDelegate interface implementation.
196 void OnWebstoreRequestFailure() override
;
198 void OnWebstoreResponseParseSuccess(
199 scoped_ptr
<base::DictionaryValue
> webstore_data
) override
;
201 void OnWebstoreResponseParseFailure(const std::string
& error
) override
;
203 // WebstoreInstallHelper::Delegate interface implementation.
204 void OnWebstoreParseSuccess(const std::string
& id
,
205 const SkBitmap
& icon
,
206 base::DictionaryValue
* parsed_manifest
) override
;
207 void OnWebstoreParseFailure(const std::string
& id
,
208 InstallHelperResultCode result_code
,
209 const std::string
& error_message
) override
;
211 // WebstoreInstaller::Delegate interface implementation.
212 void OnExtensionInstallSuccess(const std::string
& id
) override
;
213 void OnExtensionInstallFailure(
214 const std::string
& id
,
215 const std::string
& error
,
216 WebstoreInstaller::FailureReason reason
) override
;
218 void ShowInstallUI();
219 void OnWebStoreDataFetcherDone();
221 // Input configuration.
225 WebstoreInstaller::InstallSource install_source_
;
227 // Installation dialog and its underlying prompt.
228 scoped_ptr
<ExtensionInstallPrompt
> install_ui_
;
229 scoped_refptr
<ExtensionInstallPrompt::Prompt
> install_prompt_
;
231 // For fetching webstore JSON data.
232 scoped_ptr
<WebstoreDataFetcher
> webstore_data_fetcher_
;
234 // Extracted from the webstore JSON data response.
235 std::string localized_name_
;
236 std::string localized_description_
;
237 bool show_user_count_
;
238 std::string localized_user_count_
;
239 double average_rating_
;
241 scoped_ptr
<base::DictionaryValue
> webstore_data_
;
242 scoped_ptr
<base::DictionaryValue
> manifest_
;
245 // Active install registered with the InstallTracker.
246 scoped_ptr
<ScopedActiveInstall
> scoped_active_install_
;
248 // Created by ShowInstallUI() when a prompt is shown (if
249 // the implementor returns a non-NULL in CreateInstallPrompt()).
250 scoped_refptr
<Extension
> localized_extension_for_display_
;
252 DISALLOW_IMPLICIT_CONSTRUCTORS(WebstoreStandaloneInstaller
);
255 } // namespace extensions
257 #endif // CHROME_BROWSER_EXTENSIONS_WEBSTORE_STANDALONE_INSTALLER_H_