• 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 WebContents;
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   // NavigationController of the specified |web_contents|. When complete, we
100   // show a confirmation bubble in the specified |browser|.
101   // Note: the |delegate| must stay alive until receiving the callback.
102   void CompleteInstall(content::WebContents* web_contents, Delegate* delegate);
103 
104   // We change the headings in the install prompt and installed bubble depending
105   // on whether the bundle contains apps, extensions or both. This method gets
106   // the correct heading for the items in the specified |state|, or an empty
107   // string if no items are in the |state|.
108   //   STATE_PENDING   - install prompt
109   //   STATE_INSTALLED - installed bubble successful installs list
110   //   STATE_FAILED    - installed bubble failed installs list
111   base::string16 GetHeadingTextFor(Item::State state) const;
112 
113  private:
114   friend class base::RefCountedThreadSafe<BundleInstaller>;
115 
116   typedef std::map<std::string, Item> ItemMap;
117   typedef std::map<std::string, linked_ptr<base::DictionaryValue> > ManifestMap;
118 
119   virtual ~BundleInstaller();
120 
121   // Displays the install bubble for |bundle| on |browser|.
122   // Note: this is a platform specific implementation.
123   static void ShowInstalledBubble(const BundleInstaller* bundle,
124                                   Browser* browser);
125 
126   // Parses the manifests using WebstoreInstallHelper.
127   void ParseManifests();
128 
129   // Notifies the delegate that the installation has been approved.
130   void ReportApproved();
131 
132   // Notifies the delegate that the installation was canceled.
133   void ReportCanceled(bool user_initiated);
134 
135   // Notifies the delegate that the installation is complete.
136   void ReportComplete();
137 
138   // Prompts the user to install the bundle once we have dummy extensions for
139   // all the pending items.
140   void ShowPromptIfDoneParsing();
141 
142   // Prompts the user to install the bundle.
143   void ShowPrompt();
144 
145   // Displays the installed bubble once all items have installed or failed.
146   void ShowInstalledBubbleIfDone();
147 
148   // WebstoreInstallHelper::Delegate implementation:
149   virtual void OnWebstoreParseSuccess(
150       const std::string& id,
151       const SkBitmap& icon,
152       base::DictionaryValue* parsed_manifest) OVERRIDE;
153   virtual void OnWebstoreParseFailure(
154       const std::string& id,
155       InstallHelperResultCode result_code,
156       const std::string& error_message) OVERRIDE;
157 
158   // ExtensionInstallPrompt::Delegate implementation:
159   virtual void InstallUIProceed() OVERRIDE;
160   virtual void InstallUIAbort(bool user_initiated) OVERRIDE;
161 
162   // WebstoreInstaller::Delegate implementation:
163   virtual void OnExtensionInstallSuccess(const std::string& id) OVERRIDE;
164   virtual void OnExtensionInstallFailure(
165       const std::string& id,
166       const std::string& error,
167       WebstoreInstaller::FailureReason reason) OVERRIDE;
168 
169   // chrome::BrowserListObserver implementation:
170   virtual void OnBrowserAdded(Browser* browser) OVERRIDE;
171   virtual void OnBrowserRemoved(Browser* browser) OVERRIDE;
172   virtual void OnBrowserSetLastActive(Browser* browser) OVERRIDE;
173 
174   // Holds the Extensions used to generate the permission warnings.
175   ExtensionList dummy_extensions_;
176 
177   // Holds the parsed manifests, indexed by the extension ids.
178   ManifestMap parsed_manifests_;
179 
180   // True if the user has approved the bundle.
181   bool approved_;
182 
183   // Holds the bundle's Items, indexed by their ids.
184   ItemMap items_;
185 
186   // The browser to show the confirmation bubble for.
187   Browser* browser_;
188 
189   // The desktop type of the browser.
190   chrome::HostDesktopType host_desktop_type_;
191 
192   // The profile that the bundle should be installed in.
193   Profile* profile_;
194 
195   // The UI that shows the confirmation prompt.
196   scoped_ptr<ExtensionInstallPrompt> install_ui_;
197 
198   Delegate* delegate_;
199 
200   DISALLOW_COPY_AND_ASSIGN(BundleInstaller);
201 };
202 
203 }  // namespace extensions
204 
205 #endif  // CHROME_BROWSER_EXTENSIONS_BUNDLE_INSTALLER_H_
206