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_BUNDLE_INSTALLER_H_
      6 #define CHROME_BROWSER_EXTENSIONS_BUNDLE_INSTALLER_H_
      7 
      8 #include <string>
      9 #include <vector>
     10 
     11 #include "base/memory/linked_ptr.h"
     12 #include "base/memory/scoped_ptr.h"
     13 #include "base/strings/string16.h"
     14 #include "chrome/browser/extensions/extension_install_prompt.h"
     15 #include "chrome/browser/extensions/webstore_install_helper.h"
     16 #include "chrome/browser/extensions/webstore_installer.h"
     17 #include "chrome/browser/ui/browser_list_observer.h"
     18 #include "chrome/browser/ui/host_desktop.h"
     19 #include "chrome/common/extensions/extension.h"
     20 
     21 namespace base {
     22 class DictionaryValue;
     23 }  // namespace base
     24 
     25 namespace content {
     26 class NavigationController;
     27 }  // namespace content
     28 
     29 class Browser;
     30 class Profile;
     31 
     32 namespace extensions {
     33 
     34 // Manages the installation life cycle for extension bundles.
     35 //
     36 // We install bundles in two steps:
     37 //  1) PromptForApproval: parse manifests and prompt the user
     38 //  2) CompleteInstall: install the CRXs and show confirmation bubble
     39 //
     40 class BundleInstaller : public WebstoreInstallHelper::Delegate,
     41                         public ExtensionInstallPrompt::Delegate,
     42                         public WebstoreInstaller::Delegate,
     43                         public chrome::BrowserListObserver,
     44                         public base::RefCountedThreadSafe<BundleInstaller> {
     45  public:
     46   // Auto approve or cancel the permission prompt.
     47   static void SetAutoApproveForTesting(bool approve);
     48 
     49   class Delegate {
     50    public:
     51     virtual void OnBundleInstallApproved() {}
     52     virtual void OnBundleInstallCanceled(bool user_initiated) {}
     53     virtual void OnBundleInstallCompleted() {}
     54 
     55    protected:
     56     virtual ~Delegate() {}
     57   };
     58 
     59   // Represents an individual member of the bundle.
     60   struct Item {
     61     // Items are in the PENDING state until they've been installed, or the
     62     // install has failed or been canceled.
     63     enum State {
     64       STATE_PENDING,
     65       STATE_INSTALLED,
     66       STATE_FAILED
     67     };
     68 
     69     Item();
     70 
     71     // Gets the localized name, formatted for display in the prompt or bubble.
     72     string16 GetNameForDisplay();
     73 
     74     std::string id;
     75     std::string manifest;
     76     std::string localized_name;
     77     State state;
     78   };
     79 
     80   typedef std::vector<Item> ItemList;
     81 
     82   BundleInstaller(Browser* browser, const ItemList& items);
     83 
     84   // Returns true if the user has approved the bundle's permissions.
     85   bool approved() const { return approved_; }
     86 
     87   // Gets the items in the given state.
     88   ItemList GetItemsWithState(Item::State state) const;
     89 
     90   // Parses the extension manifests and then prompts the user to approve their
     91   // permissions. One of OnBundleInstallApproved or OnBundleInstallCanceled
     92   // will be called when complete if |delegate| is not NULL.
     93   // Note: the |delegate| must stay alive until receiving the callback.
     94   void PromptForApproval(Delegate* delegate);
     95 
     96   // If the bundle has been approved, this downloads and installs the member
     97   // extensions. OnBundleInstallComplete will be called when the process is
     98   // complete and |delegate| is not NULL. The download process uses the
     99   // specified |controller|. When complete, we show a confirmation bubble in
    100   // the specified |browser|.
    101   // Note: the |delegate| must stay alive until receiving the callback.
    102   void CompleteInstall(content::NavigationController* controller,
    103                        Delegate* delegate);
    104 
    105   // We change the headings in the install prompt and installed bubble depending
    106   // on whether the bundle contains apps, extensions or both. This method gets
    107   // the correct heading for the items in the specified |state|, or an empty
    108   // string if no items are in the |state|.
    109   //   STATE_PENDING   - install prompt
    110   //   STATE_INSTALLED - installed bubble successful installs list
    111   //   STATE_FAILED    - installed bubble failed installs list
    112   string16 GetHeadingTextFor(Item::State state) const;
    113 
    114  private:
    115   friend class base::RefCountedThreadSafe<BundleInstaller>;
    116 
    117   typedef std::map<std::string, Item> ItemMap;
    118   typedef std::map<std::string, linked_ptr<base::DictionaryValue> > ManifestMap;
    119 
    120   virtual ~BundleInstaller();
    121 
    122   // Displays the install bubble for |bundle| on |browser|.
    123   // Note: this is a platform specific implementation.
    124   static void ShowInstalledBubble(const BundleInstaller* bundle,
    125                                   Browser* browser);
    126 
    127   // Parses the manifests using WebstoreInstallHelper.
    128   void ParseManifests();
    129 
    130   // Notifies the delegate that the installation has been approved.
    131   void ReportApproved();
    132 
    133   // Notifies the delegate that the installation was canceled.
    134   void ReportCanceled(bool user_initiated);
    135 
    136   // Notifies the delegate that the installation is complete.
    137   void ReportComplete();
    138 
    139   // Prompts the user to install the bundle once we have dummy extensions for
    140   // all the pending items.
    141   void ShowPromptIfDoneParsing();
    142 
    143   // Prompts the user to install the bundle.
    144   void ShowPrompt();
    145 
    146   // Displays the installed bubble once all items have installed or failed.
    147   void ShowInstalledBubbleIfDone();
    148 
    149   // WebstoreInstallHelper::Delegate implementation:
    150   virtual void OnWebstoreParseSuccess(
    151       const std::string& id,
    152       const SkBitmap& icon,
    153       base::DictionaryValue* parsed_manifest) OVERRIDE;
    154   virtual void OnWebstoreParseFailure(
    155       const std::string& id,
    156       InstallHelperResultCode result_code,
    157       const std::string& error_message) OVERRIDE;
    158 
    159   // ExtensionInstallPrompt::Delegate implementation:
    160   virtual void InstallUIProceed() OVERRIDE;
    161   virtual void InstallUIAbort(bool user_initiated) OVERRIDE;
    162 
    163   // WebstoreInstaller::Delegate implementation:
    164   virtual void OnExtensionInstallSuccess(const std::string& id) OVERRIDE;
    165   virtual void OnExtensionInstallFailure(
    166       const std::string& id,
    167       const std::string& error,
    168       WebstoreInstaller::FailureReason reason) OVERRIDE;
    169 
    170   // chrome::BrowserListObserver implementation:
    171   virtual void OnBrowserAdded(Browser* browser) OVERRIDE;
    172   virtual void OnBrowserRemoved(Browser* browser) OVERRIDE;
    173   virtual void OnBrowserSetLastActive(Browser* browser) OVERRIDE;
    174 
    175   // Holds the Extensions used to generate the permission warnings.
    176   ExtensionList dummy_extensions_;
    177 
    178   // Holds the parsed manifests, indexed by the extension ids.
    179   ManifestMap parsed_manifests_;
    180 
    181   // True if the user has approved the bundle.
    182   bool approved_;
    183 
    184   // Holds the bundle's Items, indexed by their ids.
    185   ItemMap items_;
    186 
    187   // The browser to show the confirmation bubble for.
    188   Browser* browser_;
    189 
    190   // The desktop type of the browser.
    191   chrome::HostDesktopType host_desktop_type_;
    192 
    193   // The profile that the bundle should be installed in.
    194   Profile* profile_;
    195 
    196   // The UI that shows the confirmation prompt.
    197   scoped_ptr<ExtensionInstallPrompt> install_ui_;
    198 
    199   Delegate* delegate_;
    200 
    201   DISALLOW_COPY_AND_ASSIGN(BundleInstaller);
    202 };
    203 
    204 }  // namespace extensions
    205 
    206 #endif  // CHROME_BROWSER_EXTENSIONS_BUNDLE_INSTALLER_H_
    207