Home | History | Annotate | Download | only in extensions
      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.
    124   bool show_user_count() const { return show_user_count_; }
    125   const std::string& localized_user_count() const {
    126     return localized_user_count_;
    127   }
    128   double average_rating() const { return average_rating_; }
    129   int rating_count() const { return rating_count_; }
    130   void set_install_source(WebstoreInstaller::InstallSource source) {
    131     install_source_ = source;
    132   }
    133   WebstoreInstaller::InstallSource install_source() const {
    134     return install_source_;
    135   }
    136   Profile* profile() const { return profile_; }
    137   const std::string& id() const { return id_; }
    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