Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(71)

Side by Side Diff: chrome/browser/extensions/webstore_bundle.h

Issue 8391004: Add webstorePrivate API for installing bundles of extensions. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 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_WEBSTORE_BUNDLE_H_
6 #define CHROME_BROWSER_EXTENSIONS_WEBSTORE_BUNDLE_H_
7 #pragma once
8
9 #include <string>
10 #include <vector>
11
12 #include "base/memory/scoped_vector.h"
13 #include "chrome/browser/extensions/extension_install_ui.h"
14 #include "chrome/browser/extensions/webstore_installer.h"
15 #include "chrome/browser/extensions/webstore_install_helper.h"
16 #include "chrome/common/extensions/extension.h"
17 #include "content/public/browser/notification_registrar.h"
18
19 class Browser;
20 class Profile;
21
22 // Manages the installation life cycle for bundles of extensions.
23 //
24 // The normal flow for successful installs is:
25 //
26 // Part A: user approval
27 // 1. A WebstoreBundle is created with a list of items in STATE_INITIAL.
28 // 2. PromptForApproval: starts parsing all the extension manifest data.
29 // 3. OnWebstoreParseSuccess: creates the dummy extension out of the parsed
30 // manifest data, moving items into STATE_PARSED. If no more items are in
31 // STATE_INITIAL, calls ShowPrompt to display the install prompt.
32 // 4. ShowPrompt: calculates the total permissions for items in STATE_PARSED,
33 // and displays the install prompt.
34 // 5. InstallUIProceed: transitions all STATE_PARSED items to STATE_APPROVED and
35 // notifies the delegate via OnBundleInstallApproved.
36 //
37 // Part B: download and install
38 // 1. CompleteInstall: starts installing the items by calling InstallNextItem.
39 // 2. InstallNextItem: downloads and installs the first item in STATE_APPROVED.
40 // 3. OnExtensionInstallSuccess: moves the item to STATE_INSTALLED and starts
41 // installing the next item via InstallNextItem.
42 // 4. InstallNextItem: when no more items are in STATE_APPROVED, this calls
43 // ShowInstalledBubble to display the status bubble.
44 // 5. ShowInstalledBubble: platform specific implementation that shows which
45 // items succeeded and failed via the installed bubble.
46 //
47 // The normal state transitions for items are:
48 // STATE_INITIAL -> STATE_PARSED -> STATE_APPROVED -> STATE_INSTALLED
49 //
50 // Items transition to STATE_NOT_INSTALLED if they fail any step of the flow.
51 //
52 class WebstoreBundle : public WebstoreInstallHelper::Delegate,
53 public ExtensionInstallUI::Delegate,
54 public WebstoreInstaller::Delegate,
55 public base::RefCounted<WebstoreBundle> {
56 public:
57 // Auto approve or cancel the permission prompt.
58 // Note: this should only be used for testing!
59 static void SetAutoApproveForTesting(bool approve);
60
61 class Delegate {
62 public:
63 virtual void OnBundleInstallApproved() {}
64 virtual void OnBundleInstallCanceled(bool user_initiated) {}
65 virtual void OnBundleInstallCompleted() {}
66 };
67
68 // Represents an individual member of the bundle.
69 // TODO(jstritar): we can probably combine this with WebstoreInstaller, and
70 // have one class that handles the life cycle of a single extension install.
71 class Item {
72 public:
73 enum State {
74 STATE_INITIAL = 0,
75
76 // The item's manfiest has been parsed and dummy extension created.
77 STATE_PARSED,
78
79 // The user has approved the item's permissions.
80 STATE_APPROVED,
81
82 // The item has been downloaded and installed successfully.
83 STATE_INSTALLED,
84
85 // The item has failed at any step.
86 STATE_NOT_INSTALLED
87 };
88
89 Item(const std::string& id,
90 const std::string& manifest,
91 const std::string& localized_name);
92 ~Item();
93
94 // Parses a dummy extension from the |parsed_manifest|.
95 void SetDummyExtension(base::DictionaryValue* parsed_manifest);
96
97 void MarkApproved() { state_ = STATE_APPROVED; }
98 void MarkInstalled() { state_ = STATE_INSTALLED; }
99 void MarkNotInstalled() { state_ = STATE_NOT_INSTALLED; }
100
101 State state() const { return state_; }
102
103 const std::string& id() const { return id_; }
104 const std::string& manifest() const { return manifest_; }
105 const std::string& localized_name() const { return localized_name_; }
106
107 // These two fields are only available after the STATE_PARSED stage.
108 // The dummy extension is created from the parsed manifest, and is used
109 // when displaying the install prompt.
110 scoped_refptr<Extension> dummy_extension() const {
111 return dummy_extension_;
112 }
113 base::DictionaryValue* parsed_manifest() const {
114 return parsed_manifest_.get();
115 }
116
117 private:
118 std::string id_;
119 std::string manifest_;
120 std::string localized_name_;
121
122 State state_;
123 scoped_ptr<base::DictionaryValue> parsed_manifest_;
124 scoped_refptr<Extension> dummy_extension_;
125
126 DISALLOW_COPY_AND_ASSIGN(Item);
127 };
128
129 enum ItemMatcher {
130 MATCH_EXTENSIONS = 1 << 0,
131 MATCH_APPS = 1 << 1,
132 MATCH_ALL = (1 << 2) - 1
133 };
134
135 typedef ScopedVector<Item> ItemList;
136
137 // Passes ownership of the items.
138 WebstoreBundle(Profile* profile, ItemList* items);
139 virtual ~WebstoreBundle();
140
141 // Parses the extension manifests and then prompts the user to approve their
142 // permissions. One of OnBundleInstallApproved or OnBundleInstallCanceled
143 // will be called when complete if |delegate| is not NULL.
144 // Note: the |delegate| must stay alive until receiving the callback.
145 void PromptForApproval(Delegate* delegate);
146
147 // If the bundle has been approved, this downloads and installs the member
148 // extensions. OnBundleInstallComplete will be called when the process is
149 // complete and |delegate| is not NULL. The download process uses the
150 // specified |controller|.
151 // Note: the |delegate| must stay alive until receiving the callback.
152 void CompleteInstall(NavigationController* controller, Delegate* delegate);
153
154 // Returns true if this is the same bundle as |ids|.
155 bool IsSameBundle(const std::vector<std::string>& ids);
156
157 // Returns the list of member items in the given |state| that match
158 // the specified |matcher| flags.
159 // Note: the WebstoreBundle retains ownership of the items.
160 std::vector<const Item*> GetItemsInState(
161 Item::State state, int matcher) const;
162
163 // Gets the prompt heading text for the bundle of items to be installed.
164 string16 GetHeadingTextForPrompt() const;
165
166 // Gets the installed bubble heading text for the bundle items that were
167 // successfully installed, or an empty string if none were.
168 string16 GetInstalledHeadingTextForBubble() const;
169
170 // Gets the installed bubble heading text for the bundle items that failed to
171 // install, or an empty string if they all succeeded.
172 string16 GetFailedHeadingTextForBubble() const;
173
174 // Returns true if this has apps that are in |state|.
175 bool HasAppsInState(Item::State state) const;
176
177 // Returns true if this has extensions that are in |state|.
178 bool HasExtensionsInState(Item::State state) const;
179
180 // WebstoreInstallHelper::Delegate implementation:
181 virtual void OnWebstoreParseSuccess(
182 const std::string& id,
183 const SkBitmap& icon,
184 base::DictionaryValue* parsed_manifest) OVERRIDE;
185 virtual void OnWebstoreParseFailure(
186 const std::string& id,
187 InstallHelperResultCode result_code,
188 const std::string& error_message) OVERRIDE;
189
190 // ExtensionInstallUI::Delegate implementation:
191 virtual void InstallUIProceed() OVERRIDE;
192 virtual void InstallUIAbort(bool user_initiated) OVERRIDE;
193
194 // WebstoreInstaller::Delegate implementation:
195 virtual void OnExtensionInstallSuccess(const std::string& id) OVERRIDE;
196 virtual void OnExtensionInstallFailure(const std::string& id,
197 const std::string& error) OVERRIDE;
198
199 private:
200 // Gets the item for the given extension |id|.
201 Item* GetItemById(const std::string& id);
202
203 // Parses the member item's manifests using the WebstoreInstallHelper.
204 void ParseManifests();
205
206 // Only one WebstoreInstaller can be active for a given controller, so
207 // we install extensions in series. This method starts downloading the next
208 // extension in STATE_APPROVED.
209 void InstallNextItem();
210
211 // Notifies the delegate that the installation has been approved.
212 void ReportApproved();
213
214 // Notifies the delegate that the installation was canceled.
215 void ReportCanceled(bool user_initiated);
216
217 // Notifies the delegate that the installation is complete.
218 void ReportComplete();
219
220 // Prompts the user to install the bundle if there are no more member items in
221 // STATE_INITIAL.
222 void ShowPromptIfDoneParsing();
223
224 // Prompts the user to install the bundle.
225 void ShowPrompt();
226
227 // Displays the install bubble if all member items are in STATE_INSTALLED or
228 // STATE_NOT_INSTALLED.
229 void ShowInstalledBubbleIfDone();
230
231 // Displays the install bubble for |bundle| on |browser|.
232 // Note: this is a platform specific implementation.
233 static void ShowInstalledBubble(const WebstoreBundle* bundle,
234 Browser* browser);
235
236 ItemList items_;
237
238 // The profile that the bundle should be installed in.
239 Profile* profile_;
240
241 // The controller that the webstore installer should use.
242 NavigationController* controller_;
243
244 Delegate* delegate_;
245
246 DISALLOW_COPY_AND_ASSIGN(WebstoreBundle);
247 };
248
249 #endif // CHROME_BROWSER_EXTENSIONS_WEBSTORE_BUNDLE_H_
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_webstore_private_api.cc ('k') | chrome/browser/extensions/webstore_bundle.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698