• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #ifndef CHROME_BROWSER_EXTENSIONS_WEBSTORE_STANDALONE_INSTALLER_H_
6 #define CHROME_BROWSER_EXTENSIONS_WEBSTORE_STANDALONE_INSTALLER_H_
7 
8 #include <string>
9 
10 #include "base/callback.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "chrome/browser/extensions/extension_install_prompt.h"
14 #include "chrome/browser/extensions/webstore_data_fetcher_delegate.h"
15 #include "chrome/browser/extensions/webstore_install_helper.h"
16 #include "chrome/browser/extensions/webstore_installer.h"
17 #include "net/url_request/url_fetcher_delegate.h"
18 #include "third_party/skia/include/core/SkBitmap.h"
19 
20 class GURL;
21 
22 namespace base {
23 class DictionaryValue;
24 }
25 
26 namespace net {
27 class URLFetcher;
28 }
29 
30 namespace extensions {
31 class Extension;
32 class WebstoreDataFetcher;
33 
34 // A a purely abstract base for concrete classes implementing various types of
35 // standalone installs:
36 // 1) Downloads and parses metadata from the webstore.
37 // 2) Optionally shows an install dialog.
38 // 3) Starts download once the user confirms (if confirmation was requested).
39 // 4) Optionally shows a post-install UI.
40 // Follows the Template Method pattern. Implementing subclasses must override
41 // the primitive hooks in the corresponding section below.
42 
43 class WebstoreStandaloneInstaller
44     : public base::RefCountedThreadSafe<WebstoreStandaloneInstaller>,
45       public ExtensionInstallPrompt::Delegate,
46       public WebstoreDataFetcherDelegate,
47       public WebstoreInstaller::Delegate,
48       public WebstoreInstallHelper::Delegate {
49  public:
50   // A callback for when the install process completes, successfully or not. If
51   // there was a failure, |success| will be false and |error| may contain a
52   // developer-readable error message about why it failed.
53   typedef base::Callback<void(bool success, const std::string& error)> Callback;
54 
55   WebstoreStandaloneInstaller(const std::string& webstore_item_id,
56                               Profile* profile,
57                               const Callback& callback);
58   void BeginInstall();
59 
60  protected:
61   virtual ~WebstoreStandaloneInstaller();
62 
63   void AbortInstall();
64   virtual void CompleteInstall(const std::string& error);
65 
66   // Template Method's hooks to be implemented by subclasses.
67 
68   // Called at certain check points of the workflow to decide whether it makes
69   // sense to proceed with installation. A requestor can be a website that
70   // initiated an inline installation, or a command line option.
71   virtual bool CheckRequestorAlive() const = 0;
72 
73   // Requestor's URL, if any. Should be an empty GURL if URL is meaningless
74   // (e.g. for a command line option).
75   virtual const GURL& GetRequestorURL() const = 0;
76 
77   // Should a new tab be opened after installation to show the newly installed
78   // extension's icon?
79   virtual bool ShouldShowPostInstallUI() const = 0;
80 
81   // Should pop up an "App installed" bubble after installation?
82   virtual bool ShouldShowAppInstalledBubble() const = 0;
83 
84   // In the very least this should return a dummy WebContents (required
85   // by some calls even when no prompt or other UI is shown). A non-dummy
86   // WebContents is required if the prompt returned by CreateInstallPromt()
87   // contains a navigable link(s). Returned WebContents should correspond
88   // to |profile| passed into the constructor.
89   virtual content::WebContents* GetWebContents() const = 0;
90 
91   // Should return an installation prompt with desired properties or NULL if
92   // no prompt should be shown.
93   virtual scoped_ptr<ExtensionInstallPrompt::Prompt>
94       CreateInstallPrompt() const = 0;
95 
96   // Perform all necessary checks to make sure inline install is permitted,
97   // e.g. in the extension's properties in the store. The implementation may
98   // choose to ignore such properties.
99   virtual bool CheckInlineInstallPermitted(
100       const base::DictionaryValue& webstore_data,
101       std::string* error) const = 0;
102 
103   // Perform all necessary checks to make sure that requestor is allowed to
104   // initiate this install (e.g. that the requestor's URL matches the verified
105   // author's site specified in the extension's properties in the store).
106   virtual bool CheckRequestorPermitted(
107       const base::DictionaryValue& webstore_data,
108       std::string* error) const = 0;
109 
110   // Perform all necessary checks after the manifest has been parsed to make
111   // sure that the install should still proceed.
112   virtual bool CheckInstallValid(
113       const base::DictionaryValue& manifest,
114       std::string* error);
115 
116   // Returns an install UI to be shown. By default, this returns an install UI
117   // that is a transient child of the host window for GetWebContents().
118   virtual scoped_ptr<ExtensionInstallPrompt> CreateInstallUI();
119 
120   // Create an approval to pass installation parameters to the CrxInstaller.
121   virtual scoped_ptr<WebstoreInstaller::Approval> CreateApproval() const;
122 
123   // Accessors to be used by subclasses.
show_user_count()124   bool show_user_count() const { return show_user_count_; }
localized_user_count()125   const std::string& localized_user_count() const {
126     return localized_user_count_;
127   }
average_rating()128   double average_rating() const { return average_rating_; }
rating_count()129   int rating_count() const { return rating_count_; }
set_install_source(WebstoreInstaller::InstallSource source)130   void set_install_source(WebstoreInstaller::InstallSource source) {
131     install_source_ = source;
132   }
install_source()133   WebstoreInstaller::InstallSource install_source() const {
134     return install_source_;
135   }
profile()136   Profile* profile() const { return profile_; }
id()137   const std::string& id() const { return id_; }
manifest()138   const DictionaryValue* manifest() const { return manifest_.get(); }
139 
140  private:
141   friend class base::RefCountedThreadSafe<WebstoreStandaloneInstaller>;
142   FRIEND_TEST_ALL_PREFIXES(WebstoreStandaloneInstallerTest, DomainVerification);
143 
144   // Several delegate/client interface implementations follow. The normal flow
145   // (for successful installs) is:
146   //
147   // 1. BeginInstall: starts the fetch of data from the webstore
148   // 2. OnURLFetchComplete: starts the parsing of data from the webstore
149   // 3. OnWebstoreResponseParseSuccess: starts the parsing of the manifest and
150   //    fetching of icon data.
151   // 4. OnWebstoreParseSuccess: shows the install UI
152   // 5. InstallUIProceed: initiates the .crx download/install
153   //
154   // All flows (whether successful or not) end up in CompleteInstall, which
155   // informs our delegate of success/failure.
156 
157   // WebstoreDataFetcherDelegate interface implementation.
158   virtual void OnWebstoreRequestFailure() OVERRIDE;
159 
160   virtual void OnWebstoreResponseParseSuccess(
161       scoped_ptr<base::DictionaryValue> webstore_data) OVERRIDE;
162 
163   virtual void OnWebstoreResponseParseFailure(
164       const std::string& error) OVERRIDE;
165 
166   // WebstoreInstallHelper::Delegate interface implementation.
167   virtual void OnWebstoreParseSuccess(
168       const std::string& id,
169       const SkBitmap& icon,
170       base::DictionaryValue* parsed_manifest) OVERRIDE;
171   virtual void OnWebstoreParseFailure(
172       const std::string& id,
173       InstallHelperResultCode result_code,
174       const std::string& error_message) OVERRIDE;
175 
176   // ExtensionInstallPrompt::Delegate interface implementation.
177   virtual void InstallUIProceed() OVERRIDE;
178   virtual void InstallUIAbort(bool user_initiated) OVERRIDE;
179 
180   // WebstoreInstaller::Delegate interface implementation.
181   virtual void OnExtensionInstallSuccess(const std::string& id) OVERRIDE;
182   virtual void OnExtensionInstallFailure(
183       const std::string& id,
184       const std::string& error,
185       WebstoreInstaller::FailureReason reason) OVERRIDE;
186 
187   void ShowInstallUI();
188 
189   // Input configuration.
190   std::string id_;
191   Callback callback_;
192   Profile* profile_;
193   WebstoreInstaller::InstallSource install_source_;
194 
195   // Installation dialog and its underlying prompt.
196   scoped_ptr<ExtensionInstallPrompt> install_ui_;
197   scoped_ptr<ExtensionInstallPrompt::Prompt> install_prompt_;
198 
199   // For fetching webstore JSON data.
200   scoped_ptr<WebstoreDataFetcher> webstore_data_fetcher_;
201 
202   // Extracted from the webstore JSON data response.
203   std::string localized_name_;
204   std::string localized_description_;
205   bool show_user_count_;
206   std::string localized_user_count_;
207   double average_rating_;
208   int rating_count_;
209   scoped_ptr<DictionaryValue> webstore_data_;
210   scoped_ptr<DictionaryValue> manifest_;
211   SkBitmap icon_;
212 
213   // Created by ShowInstallUI() when a prompt is shown (if
214   // the implementor returns a non-NULL in CreateInstallPrompt()).
215   scoped_refptr<Extension> localized_extension_for_display_;
216 
217   DISALLOW_IMPLICIT_CONSTRUCTORS(WebstoreStandaloneInstaller);
218 };
219 
220 }  // namespace extensions
221 
222 #endif  // CHROME_BROWSER_EXTENSIONS_WEBSTORE_STANDALONE_INSTALLER_H_
223