• 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   void InvokeCallback(const std::string& error);
65   virtual void CompleteInstall(const std::string& error);
66 
67   // Template Method's hooks to be implemented by subclasses.
68 
69   // Called at certain check points of the workflow to decide whether it makes
70   // sense to proceed with installation. A requestor can be a website that
71   // initiated an inline installation, or a command line option.
72   virtual bool CheckRequestorAlive() const = 0;
73 
74   // Requestor's URL, if any. Should be an empty GURL if URL is meaningless
75   // (e.g. for a command line option).
76   virtual const GURL& GetRequestorURL() const = 0;
77 
78   // Should a new tab be opened after installation to show the newly installed
79   // extension's icon?
80   virtual bool ShouldShowPostInstallUI() const = 0;
81 
82   // Should pop up an "App installed" bubble after installation?
83   virtual bool ShouldShowAppInstalledBubble() const = 0;
84 
85   // In the very least this should return a dummy WebContents (required
86   // by some calls even when no prompt or other UI is shown). A non-dummy
87   // WebContents is required if the prompt returned by CreateInstallPromt()
88   // contains a navigable link(s). Returned WebContents should correspond
89   // to |profile| passed into the constructor.
90   virtual content::WebContents* GetWebContents() const = 0;
91 
92   // Should return an installation prompt with desired properties or NULL if
93   // no prompt should be shown.
94   virtual scoped_refptr<ExtensionInstallPrompt::Prompt> CreateInstallPrompt()
95       const = 0;
96 
97   // Perform all necessary checks to make sure inline install is permitted,
98   // e.g. in the extension's properties in the store. The implementation may
99   // choose to ignore such properties.
100   virtual bool CheckInlineInstallPermitted(
101       const base::DictionaryValue& webstore_data,
102       std::string* error) const = 0;
103 
104   // Perform all necessary checks to make sure that requestor is allowed to
105   // initiate this install (e.g. that the requestor's URL matches the verified
106   // author's site specified in the extension's properties in the store).
107   virtual bool CheckRequestorPermitted(
108       const base::DictionaryValue& webstore_data,
109       std::string* error) const = 0;
110 
111   // Perform all necessary checks after the manifest has been parsed to make
112   // sure that the install should still proceed.
113   virtual bool CheckInstallValid(
114       const base::DictionaryValue& manifest,
115       std::string* error);
116 
117   // Returns an install UI to be shown. By default, this returns an install UI
118   // that is a transient child of the host window for GetWebContents().
119   virtual scoped_ptr<ExtensionInstallPrompt> CreateInstallUI();
120 
121   // Create an approval to pass installation parameters to the CrxInstaller.
122   virtual scoped_ptr<WebstoreInstaller::Approval> CreateApproval() const;
123 
124   // Accessors to be used by subclasses.
show_user_count()125   bool show_user_count() const { return show_user_count_; }
localized_user_count()126   const std::string& localized_user_count() const {
127     return localized_user_count_;
128   }
average_rating()129   double average_rating() const { return average_rating_; }
rating_count()130   int rating_count() const { return rating_count_; }
set_install_source(WebstoreInstaller::InstallSource source)131   void set_install_source(WebstoreInstaller::InstallSource source) {
132     install_source_ = source;
133   }
install_source()134   WebstoreInstaller::InstallSource install_source() const {
135     return install_source_;
136   }
profile()137   Profile* profile() const { return profile_; }
id()138   const std::string& id() const { return id_; }
manifest()139   const base::DictionaryValue* manifest() const { return manifest_.get(); }
140 
141  private:
142   friend class base::RefCountedThreadSafe<WebstoreStandaloneInstaller>;
143   FRIEND_TEST_ALL_PREFIXES(WebstoreStandaloneInstallerTest, DomainVerification);
144 
145   // Several delegate/client interface implementations follow. The normal flow
146   // (for successful installs) is:
147   //
148   // 1. BeginInstall: starts the fetch of data from the webstore
149   // 2. OnURLFetchComplete: starts the parsing of data from the webstore
150   // 3. OnWebstoreResponseParseSuccess: starts the parsing of the manifest and
151   //    fetching of icon data.
152   // 4. OnWebstoreParseSuccess: shows the install UI
153   // 5. InstallUIProceed: initiates the .crx download/install
154   //
155   // All flows (whether successful or not) end up in CompleteInstall, which
156   // informs our delegate of success/failure.
157 
158   // WebstoreDataFetcherDelegate interface implementation.
159   virtual void OnWebstoreRequestFailure() OVERRIDE;
160 
161   virtual void OnWebstoreResponseParseSuccess(
162       scoped_ptr<base::DictionaryValue> webstore_data) OVERRIDE;
163 
164   virtual void OnWebstoreResponseParseFailure(
165       const std::string& error) OVERRIDE;
166 
167   // WebstoreInstallHelper::Delegate interface implementation.
168   virtual void OnWebstoreParseSuccess(
169       const std::string& id,
170       const SkBitmap& icon,
171       base::DictionaryValue* parsed_manifest) OVERRIDE;
172   virtual void OnWebstoreParseFailure(
173       const std::string& id,
174       InstallHelperResultCode result_code,
175       const std::string& error_message) OVERRIDE;
176 
177   // ExtensionInstallPrompt::Delegate interface implementation.
178   virtual void InstallUIProceed() OVERRIDE;
179   virtual void InstallUIAbort(bool user_initiated) OVERRIDE;
180 
181   // WebstoreInstaller::Delegate interface implementation.
182   virtual void OnExtensionInstallSuccess(const std::string& id) OVERRIDE;
183   virtual void OnExtensionInstallFailure(
184       const std::string& id,
185       const std::string& error,
186       WebstoreInstaller::FailureReason reason) OVERRIDE;
187 
188   void ShowInstallUI();
189   void OnWebStoreDataFetcherDone();
190 
191   // Input configuration.
192   std::string id_;
193   Callback callback_;
194   Profile* profile_;
195   WebstoreInstaller::InstallSource install_source_;
196 
197   // Installation dialog and its underlying prompt.
198   scoped_ptr<ExtensionInstallPrompt> install_ui_;
199   scoped_refptr<ExtensionInstallPrompt::Prompt> install_prompt_;
200 
201   // For fetching webstore JSON data.
202   scoped_ptr<WebstoreDataFetcher> webstore_data_fetcher_;
203 
204   // Extracted from the webstore JSON data response.
205   std::string localized_name_;
206   std::string localized_description_;
207   bool show_user_count_;
208   std::string localized_user_count_;
209   double average_rating_;
210   int rating_count_;
211   scoped_ptr<base::DictionaryValue> webstore_data_;
212   scoped_ptr<base::DictionaryValue> manifest_;
213   SkBitmap icon_;
214 
215   // Created by ShowInstallUI() when a prompt is shown (if
216   // the implementor returns a non-NULL in CreateInstallPrompt()).
217   scoped_refptr<Extension> localized_extension_for_display_;
218 
219   DISALLOW_IMPLICIT_CONSTRUCTORS(WebstoreStandaloneInstaller);
220 };
221 
222 }  // namespace extensions
223 
224 #endif  // CHROME_BROWSER_EXTENSIONS_WEBSTORE_STANDALONE_INSTALLER_H_
225