• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "extensions/common/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:
OnBundleInstallApproved()51     virtual void OnBundleInstallApproved() {}
OnBundleInstallCanceled(bool user_initiated)52     virtual void OnBundleInstallCanceled(bool user_initiated) {}
OnBundleInstallCompleted()53     virtual void OnBundleInstallCompleted() {}
54 
55    protected:
~Delegate()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     base::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.
approved()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   base::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