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 20class GURL; 21 22namespace base { 23class DictionaryValue; 24} 25 26namespace net { 27class URLFetcher; 28} 29 30namespace extensions { 31class Extension; 32class 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 43class 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. 125 bool show_user_count() const { return show_user_count_; } 126 const std::string& localized_user_count() const { 127 return localized_user_count_; 128 } 129 double average_rating() const { return average_rating_; } 130 int rating_count() const { return rating_count_; } 131 void set_install_source(WebstoreInstaller::InstallSource source) { 132 install_source_ = source; 133 } 134 WebstoreInstaller::InstallSource install_source() const { 135 return install_source_; 136 } 137 Profile* profile() const { return profile_; } 138 const std::string& id() const { return id_; } 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