| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CHROME_BROWSER_EXTENSIONS_WEBSTORE_STANDALONE_INSTALLER_H_ |
| #define CHROME_BROWSER_EXTENSIONS_WEBSTORE_STANDALONE_INSTALLER_H_ |
| |
| #include <string> |
| |
| #include "base/callback.h" |
| #include "base/memory/ref_counted.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "chrome/browser/extensions/active_install_data.h" |
| #include "chrome/browser/extensions/extension_install_prompt.h" |
| #include "chrome/browser/extensions/webstore_data_fetcher_delegate.h" |
| #include "chrome/browser/extensions/webstore_install_helper.h" |
| #include "chrome/browser/extensions/webstore_installer.h" |
| #include "chrome/common/extensions/webstore_install_result.h" |
| #include "net/url_request/url_fetcher_delegate.h" |
| #include "third_party/skia/include/core/SkBitmap.h" |
| |
| class GURL; |
| |
| namespace base { |
| class DictionaryValue; |
| } |
| |
| namespace net { |
| class URLFetcher; |
| } |
| |
| namespace extensions { |
| class Extension; |
| class WebstoreDataFetcher; |
| |
| // A a purely abstract base for concrete classes implementing various types of |
| // standalone installs: |
| // 1) Downloads and parses metadata from the webstore. |
| // 2) Optionally shows an install dialog. |
| // 3) Starts download once the user confirms (if confirmation was requested). |
| // 4) Optionally shows a post-install UI. |
| // Follows the Template Method pattern. Implementing subclasses must override |
| // the primitive hooks in the corresponding section below. |
| |
| class WebstoreStandaloneInstaller |
| : public base::RefCountedThreadSafe<WebstoreStandaloneInstaller>, |
| public ExtensionInstallPrompt::Delegate, |
| public WebstoreDataFetcherDelegate, |
| public WebstoreInstaller::Delegate, |
| public WebstoreInstallHelper::Delegate { |
| public: |
| // A callback for when the install process completes, successfully or not. If |
| // there was a failure, |success| will be false and |error| may contain a |
| // developer-readable error message about why it failed. |
| typedef base::Callback<void(bool success, |
| const std::string& error, |
| webstore_install::Result result)> Callback; |
| |
| WebstoreStandaloneInstaller(const std::string& webstore_item_id, |
| Profile* profile, |
| const Callback& callback); |
| void BeginInstall(); |
| |
| protected: |
| ~WebstoreStandaloneInstaller() override; |
| |
| // Runs the callback; primarily used for running a callback before it is |
| // cleared in AbortInstall(). |
| void RunCallback( |
| bool success, const std::string& error, webstore_install::Result result); |
| |
| // Called when the install should be aborted. The callback is cleared. |
| void AbortInstall(); |
| |
| // Checks InstallTracker and returns true if the same extension is not |
| // currently being installed. Registers this install with the InstallTracker. |
| bool EnsureUniqueInstall(webstore_install::Result* reason, |
| std::string* error); |
| |
| // Called when the install is complete. |
| virtual void CompleteInstall(webstore_install::Result result, |
| const std::string& error); |
| |
| // Called when the installer should proceed to prompt the user. |
| void ProceedWithInstallPrompt(); |
| |
| // Lazily creates a dummy extension for display from the parsed manifest. This |
| // is safe to call from OnManifestParsed() onwards. The manifest may be |
| // invalid, thus the caller must check that the return value is not NULL. |
| scoped_refptr<const Extension> GetLocalizedExtensionForDisplay(); |
| |
| // Template Method's hooks to be implemented by subclasses. |
| |
| // Called when this install is about to be registered with the InstallTracker. |
| // Allows subclasses to set properties of the install data. |
| virtual void InitInstallData(ActiveInstallData* install_data) const; |
| |
| // Called at certain check points of the workflow to decide whether it makes |
| // sense to proceed with installation. A requestor can be a website that |
| // initiated an inline installation, or a command line option. |
| virtual bool CheckRequestorAlive() const = 0; |
| |
| // Requestor's URL, if any. Should be an empty GURL if URL is meaningless |
| // (e.g. for a command line option). |
| virtual const GURL& GetRequestorURL() const = 0; |
| |
| // Should a new tab be opened after installation to show the newly installed |
| // extension's icon? |
| virtual bool ShouldShowPostInstallUI() const = 0; |
| |
| // Should pop up an "App installed" bubble after installation? |
| virtual bool ShouldShowAppInstalledBubble() const = 0; |
| |
| // In the very least this should return a dummy WebContents (required |
| // by some calls even when no prompt or other UI is shown). A non-dummy |
| // WebContents is required if the prompt returned by CreateInstallPromt() |
| // contains a navigable link(s). Returned WebContents should correspond |
| // to |profile| passed into the constructor. |
| virtual content::WebContents* GetWebContents() const = 0; |
| |
| // Should return an installation prompt with desired properties or NULL if |
| // no prompt should be shown. |
| virtual scoped_refptr<ExtensionInstallPrompt::Prompt> CreateInstallPrompt() |
| const = 0; |
| |
| // Perform all necessary checks to make sure inline install is permitted, |
| // e.g. in the extension's properties in the store. The implementation may |
| // choose to ignore such properties. |
| virtual bool CheckInlineInstallPermitted( |
| const base::DictionaryValue& webstore_data, |
| std::string* error) const = 0; |
| |
| // Perform all necessary checks to make sure that requestor is allowed to |
| // initiate this install (e.g. that the requestor's URL matches the verified |
| // author's site specified in the extension's properties in the store). |
| virtual bool CheckRequestorPermitted( |
| const base::DictionaryValue& webstore_data, |
| std::string* error) const = 0; |
| |
| // Will be called after the extension's manifest has been successfully parsed. |
| // Subclasses can perform asynchronous checks at this point and call |
| // ProceedWithInstallPrompt() to proceed with the install or otherwise call |
| // CompleteInstall() with an error code. The default implementation calls |
| // ProceedWithInstallPrompt(). |
| virtual void OnManifestParsed(); |
| |
| // Returns an install UI to be shown. By default, this returns an install UI |
| // that is a transient child of the host window for GetWebContents(). |
| virtual scoped_ptr<ExtensionInstallPrompt> CreateInstallUI(); |
| |
| // Create an approval to pass installation parameters to the CrxInstaller. |
| virtual scoped_ptr<WebstoreInstaller::Approval> CreateApproval() const; |
| |
| // ExtensionInstallPrompt::Delegate interface implementation. |
| void InstallUIProceed() override; |
| void InstallUIAbort(bool user_initiated) override; |
| |
| // Accessors to be used by subclasses. |
| bool show_user_count() const { return show_user_count_; } |
| const std::string& localized_user_count() const { |
| return localized_user_count_; |
| } |
| double average_rating() const { return average_rating_; } |
| int rating_count() const { return rating_count_; } |
| void set_install_source(WebstoreInstaller::InstallSource source) { |
| install_source_ = source; |
| } |
| WebstoreInstaller::InstallSource install_source() const { |
| return install_source_; |
| } |
| Profile* profile() const { return profile_; } |
| const std::string& id() const { return id_; } |
| const base::DictionaryValue* manifest() const { return manifest_.get(); } |
| const Extension* localized_extension_for_display() const { |
| return localized_extension_for_display_.get(); |
| } |
| |
| private: |
| friend class base::RefCountedThreadSafe<WebstoreStandaloneInstaller>; |
| FRIEND_TEST_ALL_PREFIXES(WebstoreStandaloneInstallerTest, DomainVerification); |
| |
| // Several delegate/client interface implementations follow. The normal flow |
| // (for successful installs) is: |
| // |
| // 1. BeginInstall: starts the fetch of data from the webstore |
| // 2. OnURLFetchComplete: starts the parsing of data from the webstore |
| // 3. OnWebstoreResponseParseSuccess: starts the parsing of the manifest and |
| // fetching of icon data. |
| // 4. OnWebstoreParseSuccess: shows the install UI |
| // 5. InstallUIProceed: initiates the .crx download/install |
| // |
| // All flows (whether successful or not) end up in CompleteInstall, which |
| // informs our delegate of success/failure. |
| |
| // WebstoreDataFetcherDelegate interface implementation. |
| void OnWebstoreRequestFailure() override; |
| |
| void OnWebstoreResponseParseSuccess( |
| scoped_ptr<base::DictionaryValue> webstore_data) override; |
| |
| void OnWebstoreResponseParseFailure(const std::string& error) override; |
| |
| // WebstoreInstallHelper::Delegate interface implementation. |
| void OnWebstoreParseSuccess(const std::string& id, |
| const SkBitmap& icon, |
| base::DictionaryValue* parsed_manifest) override; |
| void OnWebstoreParseFailure(const std::string& id, |
| InstallHelperResultCode result_code, |
| const std::string& error_message) override; |
| |
| // WebstoreInstaller::Delegate interface implementation. |
| void OnExtensionInstallSuccess(const std::string& id) override; |
| void OnExtensionInstallFailure( |
| const std::string& id, |
| const std::string& error, |
| WebstoreInstaller::FailureReason reason) override; |
| |
| void ShowInstallUI(); |
| void OnWebStoreDataFetcherDone(); |
| |
| // Input configuration. |
| std::string id_; |
| Callback callback_; |
| Profile* profile_; |
| WebstoreInstaller::InstallSource install_source_; |
| |
| // Installation dialog and its underlying prompt. |
| scoped_ptr<ExtensionInstallPrompt> install_ui_; |
| scoped_refptr<ExtensionInstallPrompt::Prompt> install_prompt_; |
| |
| // For fetching webstore JSON data. |
| scoped_ptr<WebstoreDataFetcher> webstore_data_fetcher_; |
| |
| // Extracted from the webstore JSON data response. |
| std::string localized_name_; |
| std::string localized_description_; |
| bool show_user_count_; |
| std::string localized_user_count_; |
| double average_rating_; |
| int rating_count_; |
| scoped_ptr<base::DictionaryValue> webstore_data_; |
| scoped_ptr<base::DictionaryValue> manifest_; |
| SkBitmap icon_; |
| |
| // Active install registered with the InstallTracker. |
| scoped_ptr<ScopedActiveInstall> scoped_active_install_; |
| |
| // Created by ShowInstallUI() when a prompt is shown (if |
| // the implementor returns a non-NULL in CreateInstallPrompt()). |
| scoped_refptr<Extension> localized_extension_for_display_; |
| |
| DISALLOW_IMPLICIT_CONSTRUCTORS(WebstoreStandaloneInstaller); |
| }; |
| |
| } // namespace extensions |
| |
| #endif // CHROME_BROWSER_EXTENSIONS_WEBSTORE_STANDALONE_INSTALLER_H_ |