OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_INSTALL_UI_H_ | 5 #ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_INSTALL_UI_H_ |
6 #define CHROME_BROWSER_EXTENSIONS_EXTENSION_INSTALL_UI_H_ | 6 #define CHROME_BROWSER_EXTENSIONS_EXTENSION_INSTALL_UI_H_ |
7 #pragma once | 7 #pragma once |
8 | 8 |
9 #include <string> | 9 #include <string> |
10 #include <vector> | |
11 | 10 |
12 #include "base/compiler_specific.h" | 11 #include "base/compiler_specific.h" |
13 #include "base/string16.h" | 12 #include "base/string16.h" |
14 #include "chrome/browser/extensions/image_loading_tracker.h" | |
15 #include "chrome/common/extensions/url_pattern.h" | |
16 #include "third_party/skia/include/core/SkBitmap.h" | |
17 #include "ui/gfx/image/image.h" | |
18 #include "ui/gfx/image/image_skia.h" | |
19 #include "ui/gfx/native_widget_types.h" | |
20 | 13 |
21 class Browser; | 14 class Browser; |
22 class ExtensionPermissionSet; | |
23 class MessageLoop; | |
24 class Profile; | 15 class Profile; |
25 class InfoBarDelegate; | 16 class SkBitmap; |
26 class TabContents; | |
27 typedef TabContents TabContentsWrapper; | |
28 | |
29 namespace base { | |
30 class DictionaryValue; | |
31 } | |
32 | 17 |
33 namespace extensions { | 18 namespace extensions { |
34 class BundleInstaller; | |
35 class Extension; | 19 class Extension; |
36 class ExtensionWebstorePrivateApiTest; | 20 class ExtensionWebstorePrivateApiTest; |
37 } // namespace extensions | 21 } // namespace extensions |
38 | 22 |
39 // Displays all the UI around extension installation. | 23 // Interface that should be implemented for each platform to display all the UI |
40 class ExtensionInstallUI : public ImageLoadingTracker::Observer { | 24 // around extension installation. |
| 25 class ExtensionInstallUI { |
41 public: | 26 public: |
42 enum PromptType { | 27 static ExtensionInstallUI* Create(Profile* profile); |
43 UNSET_PROMPT_TYPE = -1, | |
44 INSTALL_PROMPT = 0, | |
45 INLINE_INSTALL_PROMPT, | |
46 BUNDLE_INSTALL_PROMPT, | |
47 RE_ENABLE_PROMPT, | |
48 PERMISSIONS_PROMPT, | |
49 NUM_PROMPT_TYPES | |
50 }; | |
51 | 28 |
52 // Extra information needed to display an installation or uninstallation | 29 virtual ~ExtensionInstallUI(); |
53 // prompt. Gets populated with raw data and exposes getters for formatted | |
54 // strings so that the GTK/views/Cocoa install dialogs don't have to repeat | |
55 // that logic. | |
56 class Prompt { | |
57 public: | |
58 explicit Prompt(PromptType type); | |
59 ~Prompt(); | |
60 | 30 |
61 void SetPermissions(const std::vector<string16>& permissions); | 31 // Called when an extension was installed. |
62 void SetInlineInstallWebstoreData(const std::string& localized_user_count, | 32 virtual void OnInstallSuccess(const extensions::Extension* extension, |
63 double average_rating, | 33 SkBitmap* icon) = 0; |
64 int rating_count); | 34 // Called when an extension failed to install. |
| 35 virtual void OnInstallFailure(const string16& error) = 0; |
65 | 36 |
66 PromptType type() const { return type_; } | 37 // Whether or not to show the default UI after completing the installation. |
67 void set_type(PromptType type) { type_ = type; } | 38 virtual void SetSkipPostInstallUI(bool skip_ui) = 0; |
68 | |
69 // Getters for UI element labels. | |
70 string16 GetDialogTitle() const; | |
71 string16 GetHeading() const; | |
72 string16 GetAcceptButtonLabel() const; | |
73 bool HasAbortButtonLabel() const; | |
74 string16 GetAbortButtonLabel() const; | |
75 string16 GetPermissionsHeading() const; | |
76 | |
77 // Getters for webstore metadata. Only populated when the type is | |
78 // INLINE_INSTALL_PROMPT. | |
79 | |
80 // The star display logic replicates the one used by the webstore (from | |
81 // components.ratingutils.setFractionalYellowStars). Callers pass in an | |
82 // "appender", which will be repeatedly called back with the star images | |
83 // that they append to the star display area. | |
84 typedef void(*StarAppender)(const gfx::ImageSkia*, void*); | |
85 void AppendRatingStars(StarAppender appender, void* data) const; | |
86 string16 GetRatingCount() const; | |
87 string16 GetUserCount() const; | |
88 size_t GetPermissionCount() const; | |
89 string16 GetPermission(size_t index) const; | |
90 | |
91 // Populated for BUNDLE_INSTALL_PROMPT. | |
92 const extensions::BundleInstaller* bundle() const { return bundle_; } | |
93 void set_bundle(const extensions::BundleInstaller* bundle) { | |
94 bundle_ = bundle; | |
95 } | |
96 | |
97 // Populated for all other types. | |
98 const extensions::Extension* extension() const { return extension_; } | |
99 void set_extension(const extensions::Extension* extension) { | |
100 extension_ = extension; | |
101 } | |
102 | |
103 const gfx::Image& icon() const { return icon_; } | |
104 void set_icon(const gfx::Image& icon) { icon_ = icon; } | |
105 | |
106 private: | |
107 PromptType type_; | |
108 // Permissions that are being requested (may not be all of an extension's | |
109 // permissions if only additional ones are being requested) | |
110 std::vector<string16> permissions_; | |
111 | |
112 // The extension or bundle being installed. | |
113 const extensions::Extension* extension_; | |
114 const extensions::BundleInstaller* bundle_; | |
115 | |
116 // The icon to be displayed. | |
117 gfx::Image icon_; | |
118 | |
119 // These fields are populated only when the prompt type is | |
120 // INLINE_INSTALL_PROMPT | |
121 // Already formatted to be locale-specific. | |
122 std::string localized_user_count_; | |
123 // Range is kMinExtensionRating to kMaxExtensionRating | |
124 double average_rating_; | |
125 int rating_count_; | |
126 }; | |
127 | |
128 static const int kMinExtensionRating = 0; | |
129 static const int kMaxExtensionRating = 5; | |
130 | |
131 class Delegate { | |
132 public: | |
133 // We call this method to signal that the installation should continue. | |
134 virtual void InstallUIProceed() = 0; | |
135 | |
136 // We call this method to signal that the installation should stop, with | |
137 // |user_initiated| true if the installation was stopped by the user. | |
138 virtual void InstallUIAbort(bool user_initiated) = 0; | |
139 | |
140 protected: | |
141 virtual ~Delegate() {} | |
142 }; | |
143 | |
144 // Creates a dummy extension from the |manifest|, replacing the name and | |
145 // description with the localizations if provided. | |
146 static scoped_refptr<extensions::Extension> GetLocalizedExtensionForDisplay( | |
147 const base::DictionaryValue* manifest, | |
148 const std::string& id, | |
149 const std::string& localized_name, | |
150 const std::string& localized_description, | |
151 std::string* error); | |
152 | |
153 explicit ExtensionInstallUI(Profile* profile); | |
154 virtual ~ExtensionInstallUI(); | |
155 | 39 |
156 // TODO(asargent) Normally we navigate to the new tab page when an app is | 40 // TODO(asargent) Normally we navigate to the new tab page when an app is |
157 // installed, but we're experimenting with instead showing a bubble when | 41 // installed, but we're experimenting with instead showing a bubble when |
158 // an app is installed which points to the new tab button. This may become | 42 // an app is installed which points to the new tab button. This may become |
159 // the default behavior in the future. | 43 // the default behavior in the future. |
160 void set_use_app_installed_bubble(bool use_bubble) { | 44 virtual void SetUseAppInstalledBubble(bool use_bubble) = 0; |
161 use_app_installed_bubble_ = use_bubble; | |
162 } | |
163 | |
164 // Whether or not to show the default UI after completing the installation. | |
165 void set_skip_post_install_ui(bool skip_ui) { | |
166 skip_post_install_ui_ = skip_ui; | |
167 } | |
168 | |
169 // This is called by the bundle installer to verify whether the bundle | |
170 // should be installed. | |
171 // | |
172 // We *MUST* eventually call either Proceed() or Abort() on |delegate|. | |
173 virtual void ConfirmBundleInstall(extensions::BundleInstaller* bundle, | |
174 const ExtensionPermissionSet* permissions); | |
175 | |
176 // This is called by the inline installer to verify whether the inline | |
177 // install from the webstore should proceed. | |
178 // | |
179 // We *MUST* eventually call either Proceed() or Abort() on |delegate|. | |
180 virtual void ConfirmInlineInstall(Delegate* delegate, | |
181 const extensions::Extension* extension, | |
182 SkBitmap* icon, | |
183 const Prompt& prompt); | |
184 | |
185 // This is called by the installer to verify whether the installation from | |
186 // the webstore should proceed. | |
187 // | |
188 // We *MUST* eventually call either Proceed() or Abort() on |delegate|. | |
189 virtual void ConfirmWebstoreInstall(Delegate* delegate, | |
190 const extensions::Extension* extension, | |
191 const SkBitmap* icon); | |
192 | |
193 // This is called by the installer to verify whether the installation should | |
194 // proceed. This is declared virtual for testing. | |
195 // | |
196 // We *MUST* eventually call either Proceed() or Abort() on |delegate|. | |
197 virtual void ConfirmInstall(Delegate* delegate, | |
198 const extensions::Extension* extension); | |
199 | |
200 // This is called by the app handler launcher to verify whether the app | |
201 // should be re-enabled. This is declared virtual for testing. | |
202 // | |
203 // We *MUST* eventually call either Proceed() or Abort() on |delegate|. | |
204 virtual void ConfirmReEnable(Delegate* delegate, | |
205 const extensions::Extension* extension); | |
206 | |
207 // This is called by the extension permissions API to verify whether an | |
208 // extension may be granted additional permissions. | |
209 // | |
210 // We *MUST* eventually call either Proceed() or Abort() on |delegate|. | |
211 virtual void ConfirmPermissions(Delegate* delegate, | |
212 const extensions::Extension* extension, | |
213 const ExtensionPermissionSet* permissions); | |
214 | |
215 // Installation was successful. This is declared virtual for testing. | |
216 virtual void OnInstallSuccess(const extensions::Extension* extension, | |
217 SkBitmap* icon); | |
218 | |
219 // Installation failed. This is declared virtual for testing. | |
220 virtual void OnInstallFailure(const string16& error); | |
221 | |
222 // ImageLoadingTracker::Observer: | |
223 virtual void OnImageLoaded(const gfx::Image& image, | |
224 const std::string& extension_id, | |
225 int index) OVERRIDE; | |
226 | 45 |
227 // Opens apps UI and animates the app icon for the app with id |app_id|. | 46 // Opens apps UI and animates the app icon for the app with id |app_id|. |
228 static void OpenAppInstalledUI(Browser* browser, const std::string& app_id); | 47 static void OpenAppInstalledUI(Browser* browser, const std::string& app_id); |
229 | 48 |
230 protected: | |
231 friend class extensions::ExtensionWebstorePrivateApiTest; | |
232 friend class WebstoreInlineInstallUnpackFailureTest; | |
233 | |
234 // Disables showing UI (ErrorBox, etc.) for install failures. To be used only | 49 // Disables showing UI (ErrorBox, etc.) for install failures. To be used only |
235 // in tests. | 50 // in tests. |
236 static void DisableFailureUIForTests(); | 51 static void DisableFailureUIForTests(); |
237 | 52 |
238 private: | 53 protected: |
239 friend class GalleryInstallApiTestObserver; | 54 ExtensionInstallUI(); |
240 | |
241 // Show an infobar for a newly-installed theme. previous_theme_id | |
242 // should be empty if the previous theme was the system/default | |
243 // theme. | |
244 static void ShowThemeInfoBar( | |
245 const std::string& previous_theme_id, bool previous_using_native_theme, | |
246 const extensions::Extension* new_theme, Profile* profile); | |
247 | |
248 // Sets the icon that will be used in any UI. If |icon| is NULL, or contains | |
249 // an empty bitmap, then a default icon will be used instead. | |
250 void SetIcon(const SkBitmap* icon); | |
251 | |
252 // Starts the process of showing a confirmation UI, which is split into two. | |
253 // 1) Set off a 'load icon' task. | |
254 // 2) Handle the load icon response and show the UI (OnImageLoaded). | |
255 void LoadImageIfNeeded(); | |
256 | |
257 // Shows the actual UI (the icon should already be loaded). | |
258 void ShowConfirmation(); | |
259 | |
260 // Returns the delegate to control the browser's info bar. This is | |
261 // within its own function due to its platform-specific nature. | |
262 static InfoBarDelegate* GetNewThemeInstalledInfoBarDelegate( | |
263 TabContentsWrapper* tab_contents, | |
264 const extensions::Extension* new_theme, | |
265 const std::string& previous_theme_id, | |
266 bool previous_using_native_theme); | |
267 | |
268 Profile* profile_; | |
269 MessageLoop* ui_loop_; | |
270 | |
271 // Used to undo theme installation. | |
272 std::string previous_theme_id_; | |
273 bool previous_using_native_theme_; | |
274 | |
275 // The extensions installation icon. | |
276 SkBitmap icon_; | |
277 | |
278 // The extension we are showing the UI for. | |
279 const extensions::Extension* extension_; | |
280 | |
281 // The bundle we are showing the UI for, if type BUNDLE_INSTALL_PROMPT. | |
282 const extensions::BundleInstaller* bundle_; | |
283 | |
284 // The permissions being prompted for. | |
285 scoped_refptr<const ExtensionPermissionSet> permissions_; | |
286 | |
287 // The delegate we will call Proceed/Abort on after confirmation UI. | |
288 Delegate* delegate_; | |
289 | |
290 // A pre-filled prompt. | |
291 Prompt prompt_; | |
292 | |
293 // The type of prompt we are going to show. | |
294 PromptType prompt_type_; | |
295 | |
296 // Keeps track of extension images being loaded on the File thread for the | |
297 // purpose of showing the install UI. | |
298 ImageLoadingTracker tracker_; | |
299 | |
300 // Whether to show an installed bubble on app install, or use the default | |
301 // action of opening a new tab page. | |
302 bool use_app_installed_bubble_; | |
303 | |
304 // Whether or not to show the default UI after completing the installation. | |
305 bool skip_post_install_ui_; | |
306 }; | 55 }; |
307 | 56 |
308 #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_INSTALL_UI_H_ | 57 #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_INSTALL_UI_H_ |
OLD | NEW |