C++程序  |  207行  |  6.91 KB

// 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_BUNDLE_INSTALLER_H_
#define CHROME_BROWSER_EXTENSIONS_BUNDLE_INSTALLER_H_

#include <string>
#include <vector>

#include "base/memory/linked_ptr.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string16.h"
#include "chrome/browser/extensions/extension_install_prompt.h"
#include "chrome/browser/extensions/webstore_install_helper.h"
#include "chrome/browser/extensions/webstore_installer.h"
#include "chrome/browser/ui/browser_list_observer.h"
#include "chrome/browser/ui/host_desktop.h"
#include "extensions/common/extension.h"

namespace base {
class DictionaryValue;
}  // namespace base

namespace content {
class NavigationController;
}  // namespace content

class Browser;
class Profile;

namespace extensions {

// Manages the installation life cycle for extension bundles.
//
// We install bundles in two steps:
//  1) PromptForApproval: parse manifests and prompt the user
//  2) CompleteInstall: install the CRXs and show confirmation bubble
//
class BundleInstaller : public WebstoreInstallHelper::Delegate,
                        public ExtensionInstallPrompt::Delegate,
                        public WebstoreInstaller::Delegate,
                        public chrome::BrowserListObserver,
                        public base::RefCountedThreadSafe<BundleInstaller> {
 public:
  // Auto approve or cancel the permission prompt.
  static void SetAutoApproveForTesting(bool approve);

  class Delegate {
   public:
    virtual void OnBundleInstallApproved() {}
    virtual void OnBundleInstallCanceled(bool user_initiated) {}
    virtual void OnBundleInstallCompleted() {}

   protected:
    virtual ~Delegate() {}
  };

  // Represents an individual member of the bundle.
  struct Item {
    // Items are in the PENDING state until they've been installed, or the
    // install has failed or been canceled.
    enum State {
      STATE_PENDING,
      STATE_INSTALLED,
      STATE_FAILED
    };

    Item();

    // Gets the localized name, formatted for display in the prompt or bubble.
    base::string16 GetNameForDisplay();

    std::string id;
    std::string manifest;
    std::string localized_name;
    State state;
  };

  typedef std::vector<Item> ItemList;

  BundleInstaller(Browser* browser, const ItemList& items);

  // Returns true if the user has approved the bundle's permissions.
  bool approved() const { return approved_; }

  // Gets the items in the given state.
  ItemList GetItemsWithState(Item::State state) const;

  // Parses the extension manifests and then prompts the user to approve their
  // permissions. One of OnBundleInstallApproved or OnBundleInstallCanceled
  // will be called when complete if |delegate| is not NULL.
  // Note: the |delegate| must stay alive until receiving the callback.
  void PromptForApproval(Delegate* delegate);

  // If the bundle has been approved, this downloads and installs the member
  // extensions. OnBundleInstallComplete will be called when the process is
  // complete and |delegate| is not NULL. The download process uses the
  // specified |controller|. When complete, we show a confirmation bubble in
  // the specified |browser|.
  // Note: the |delegate| must stay alive until receiving the callback.
  void CompleteInstall(content::NavigationController* controller,
                       Delegate* delegate);

  // We change the headings in the install prompt and installed bubble depending
  // on whether the bundle contains apps, extensions or both. This method gets
  // the correct heading for the items in the specified |state|, or an empty
  // string if no items are in the |state|.
  //   STATE_PENDING   - install prompt
  //   STATE_INSTALLED - installed bubble successful installs list
  //   STATE_FAILED    - installed bubble failed installs list
  base::string16 GetHeadingTextFor(Item::State state) const;

 private:
  friend class base::RefCountedThreadSafe<BundleInstaller>;

  typedef std::map<std::string, Item> ItemMap;
  typedef std::map<std::string, linked_ptr<base::DictionaryValue> > ManifestMap;

  virtual ~BundleInstaller();

  // Displays the install bubble for |bundle| on |browser|.
  // Note: this is a platform specific implementation.
  static void ShowInstalledBubble(const BundleInstaller* bundle,
                                  Browser* browser);

  // Parses the manifests using WebstoreInstallHelper.
  void ParseManifests();

  // Notifies the delegate that the installation has been approved.
  void ReportApproved();

  // Notifies the delegate that the installation was canceled.
  void ReportCanceled(bool user_initiated);

  // Notifies the delegate that the installation is complete.
  void ReportComplete();

  // Prompts the user to install the bundle once we have dummy extensions for
  // all the pending items.
  void ShowPromptIfDoneParsing();

  // Prompts the user to install the bundle.
  void ShowPrompt();

  // Displays the installed bubble once all items have installed or failed.
  void ShowInstalledBubbleIfDone();

  // WebstoreInstallHelper::Delegate implementation:
  virtual void OnWebstoreParseSuccess(
      const std::string& id,
      const SkBitmap& icon,
      base::DictionaryValue* parsed_manifest) OVERRIDE;
  virtual void OnWebstoreParseFailure(
      const std::string& id,
      InstallHelperResultCode result_code,
      const std::string& error_message) OVERRIDE;

  // ExtensionInstallPrompt::Delegate implementation:
  virtual void InstallUIProceed() OVERRIDE;
  virtual void InstallUIAbort(bool user_initiated) OVERRIDE;

  // WebstoreInstaller::Delegate implementation:
  virtual void OnExtensionInstallSuccess(const std::string& id) OVERRIDE;
  virtual void OnExtensionInstallFailure(
      const std::string& id,
      const std::string& error,
      WebstoreInstaller::FailureReason reason) OVERRIDE;

  // chrome::BrowserListObserver implementation:
  virtual void OnBrowserAdded(Browser* browser) OVERRIDE;
  virtual void OnBrowserRemoved(Browser* browser) OVERRIDE;
  virtual void OnBrowserSetLastActive(Browser* browser) OVERRIDE;

  // Holds the Extensions used to generate the permission warnings.
  ExtensionList dummy_extensions_;

  // Holds the parsed manifests, indexed by the extension ids.
  ManifestMap parsed_manifests_;

  // True if the user has approved the bundle.
  bool approved_;

  // Holds the bundle's Items, indexed by their ids.
  ItemMap items_;

  // The browser to show the confirmation bubble for.
  Browser* browser_;

  // The desktop type of the browser.
  chrome::HostDesktopType host_desktop_type_;

  // The profile that the bundle should be installed in.
  Profile* profile_;

  // The UI that shows the confirmation prompt.
  scoped_ptr<ExtensionInstallPrompt> install_ui_;

  Delegate* delegate_;

  DISALLOW_COPY_AND_ASSIGN(BundleInstaller);
};

}  // namespace extensions

#endif  // CHROME_BROWSER_EXTENSIONS_BUNDLE_INSTALLER_H_