15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CHROME_BROWSER_EXTENSIONS_WEBSTORE_STANDALONE_INSTALLER_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_BROWSER_EXTENSIONS_WEBSTORE_STANDALONE_INSTALLER_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_install_prompt.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/webstore_data_fetcher_delegate.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/webstore_install_helper.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/webstore_installer.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_fetcher_delegate.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class GURL;
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace base {
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class DictionaryValue;
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class URLFetcher;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Extension;
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class WebstoreDataFetcher;
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A a purely abstract base for concrete classes implementing various types of
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// standalone installs:
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 1) Downloads and parses metadata from the webstore.
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 2) Optionally shows an install dialog.
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 3) Starts download once the user confirms (if confirmation was requested).
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 4) Optionally shows a post-install UI.
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Follows the Template Method pattern. Implementing subclasses must override
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// the primitive hooks in the corresponding section below.
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WebstoreStandaloneInstaller
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public base::RefCountedThreadSafe<WebstoreStandaloneInstaller>,
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      public ExtensionInstallPrompt::Delegate,
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      public WebstoreDataFetcherDelegate,
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      public WebstoreInstaller::Delegate,
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      public WebstoreInstallHelper::Delegate {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // A callback for when the install process completes, successfully or not. If
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // there was a failure, |success| will be false and |error| may contain a
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // developer-readable error message about why it failed.
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef base::Callback<void(bool success, const std::string& error)> Callback;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebstoreStandaloneInstaller(const std::string& webstore_item_id,
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              Profile* profile,
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              const Callback& callback);
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void BeginInstall();
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~WebstoreStandaloneInstaller();
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AbortInstall();
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void CompleteInstall(const std::string& error);
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Template Method's hooks to be implemented by subclasses.
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Called at certain check points of the workflow to decide whether it makes
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // sense to proceed with installation. A requestor can be a website that
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // initiated an inline installation, or a command line option.
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool CheckRequestorAlive() const = 0;
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Requestor's URL, if any. Should be an empty GURL if URL is meaningless
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // (e.g. for a command line option).
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual const GURL& GetRequestorURL() const = 0;
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Should a new tab be opened after installation to show the newly installed
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // extension's icon?
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool ShouldShowPostInstallUI() const = 0;
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Should pop up an "App installed" bubble after installation?
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool ShouldShowAppInstalledBubble() const = 0;
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // In the very least this should return a dummy WebContents (required
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // by some calls even when no prompt or other UI is shown). A non-dummy
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // WebContents is required if the prompt returned by CreateInstallPromt()
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // contains a navigable link(s). Returned WebContents should correspond
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to |profile| passed into the constructor.
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual content::WebContents* GetWebContents() const = 0;
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Should return an installation prompt with desired properties or NULL if
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // no prompt should be shown.
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual scoped_ptr<ExtensionInstallPrompt::Prompt>
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateInstallPrompt() const = 0;
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Perform all necessary checks to make sure inline install is permitted,
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // e.g. in the extension's properties in the store. The implementation may
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // choose to ignore such properties.
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool CheckInlineInstallPermitted(
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const base::DictionaryValue& webstore_data,
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      std::string* error) const = 0;
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Perform all necessary checks to make sure that requestor is allowed to
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // initiate this install (e.g. that the requestor's URL matches the verified
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // author's site specified in the extension's properties in the store).
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool CheckRequestorPermitted(
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const base::DictionaryValue& webstore_data,
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      std::string* error) const = 0;
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Returns an install UI to be shown. By default, this returns an install UI
111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // that is a transient child of the host window for GetWebContents().
112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  virtual scoped_ptr<ExtensionInstallPrompt> CreateInstallUI();
113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Accessors to be used by subclasses.
115a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  bool show_user_count() const { return show_user_count_; }
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const std::string& localized_user_count() const {
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return localized_user_count_;
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  double average_rating() const { return average_rating_; }
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int rating_count() const { return rating_count_; }
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class base::RefCountedThreadSafe<WebstoreStandaloneInstaller>;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(WebstoreStandaloneInstallerTest, DomainVerification);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Several delegate/client interface implementations follow. The normal flow
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (for successful installs) is:
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 1. BeginInstall: starts the fetch of data from the webstore
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 2. OnURLFetchComplete: starts the parsing of data from the webstore
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 3. OnWebstoreResponseParseSuccess: starts the parsing of the manifest and
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    fetching of icon data.
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 4. OnWebstoreParseSuccess: shows the install UI
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 5. InstallUIProceed: initiates the .crx download/install
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // All flows (whether successful or not) end up in CompleteInstall, which
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // informs our delegate of success/failure.
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // WebstoreDataFetcherDelegate interface implementation.
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnWebstoreRequestFailure() OVERRIDE;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnWebstoreResponseParseSuccess(
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::DictionaryValue* webstore_data) OVERRIDE;
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnWebstoreResponseParseFailure(
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& error) OVERRIDE;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // WebstoreInstallHelper::Delegate interface implementation.
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnWebstoreParseSuccess(
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& id,
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const SkBitmap& icon,
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::DictionaryValue* parsed_manifest) OVERRIDE;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnWebstoreParseFailure(
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& id,
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      InstallHelperResultCode result_code,
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& error_message) OVERRIDE;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ExtensionInstallPrompt::Delegate interface implementation.
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void InstallUIProceed() OVERRIDE;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void InstallUIAbort(bool user_initiated) OVERRIDE;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // WebstoreInstaller::Delegate interface implementation.
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnExtensionInstallSuccess(const std::string& id) OVERRIDE;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnExtensionInstallFailure(
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& id,
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& error,
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WebstoreInstaller::FailureReason reason) OVERRIDE;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void ShowInstallUI();
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Input configuration.
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string id_;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Callback callback_;
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Profile* profile_;
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Installation dialog and its underlying prompt.
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ExtensionInstallPrompt> install_ui_;
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ExtensionInstallPrompt::Prompt> install_prompt_;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For fetching webstore JSON data.
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<WebstoreDataFetcher> webstore_data_fetcher_;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Extracted from the webstore JSON data response.
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string localized_name_;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string localized_description_;
186a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  bool show_user_count_;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string localized_user_count_;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  double average_rating_;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rating_count_;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DictionaryValue> webstore_data_;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DictionaryValue> manifest_;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkBitmap icon_;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
194eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Created by ShowInstallUI() when a prompt is shown (if
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the implementor returns a non-NULL in CreateInstallPrompt()).
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<Extension> localized_extension_for_display_;
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_IMPLICIT_CONSTRUCTORS(WebstoreStandaloneInstaller);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace extensions
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // CHROME_BROWSER_EXTENSIONS_WEBSTORE_STANDALONE_INSTALLER_H_
204