MacViews: Get c/b/ui/views/tabs to build on Mac
[chromium-blink-merge.git] / chrome / browser / extensions / extension_install_prompt.h
blobdca96db147899d21778338bf474598c78a85bccd
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.
5 #ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_INSTALL_PROMPT_H_
6 #define CHROME_BROWSER_EXTENSIONS_EXTENSION_INSTALL_PROMPT_H_
8 #include <string>
9 #include <vector>
11 #include "base/callback.h"
12 #include "base/compiler_specific.h"
13 #include "base/files/file_path.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/memory/weak_ptr.h"
17 #include "base/strings/string16.h"
18 #include "chrome/browser/extensions/extension_install_prompt_experiment.h"
19 #include "extensions/common/url_pattern.h"
20 #include "third_party/skia/include/core/SkBitmap.h"
21 #include "ui/gfx/image/image.h"
22 #include "ui/gfx/image/image_skia.h"
23 #include "ui/gfx/native_widget_types.h"
25 class Profile;
27 namespace base {
28 class DictionaryValue;
29 class MessageLoop;
30 } // namespace base
32 namespace content {
33 class WebContents;
36 namespace extensions {
37 class BundleInstaller;
38 class CrxInstallerError;
39 class Extension;
40 class ExtensionInstallUI;
41 class ExtensionWebstorePrivateApiTest;
42 class MockGetAuthTokenFunction;
43 class PermissionSet;
44 } // namespace extensions
46 namespace infobars {
47 class InfoBarDelegate;
50 // Displays all the UI around extension installation.
51 class ExtensionInstallPrompt
52 : public base::SupportsWeakPtr<ExtensionInstallPrompt> {
53 public:
54 // A setting to cause extension/app installs from the webstore skip the normal
55 // confirmation dialog. This should only be used in tests.
56 enum AutoConfirmForTests {
57 NONE, // The prompt will show normally.
58 ACCEPT, // The prompt will always accept.
59 CANCEL, // The prompt will always cancel.
61 static AutoConfirmForTests g_auto_confirm_for_tests;
63 // This enum is associated with Extensions.InstallPrompt_Type UMA histogram.
64 // Do not modify existing values and add new values only to the end.
65 enum PromptType {
66 UNSET_PROMPT_TYPE = -1,
67 INSTALL_PROMPT = 0,
68 INLINE_INSTALL_PROMPT,
69 BUNDLE_INSTALL_PROMPT,
70 RE_ENABLE_PROMPT,
71 PERMISSIONS_PROMPT,
72 EXTERNAL_INSTALL_PROMPT,
73 POST_INSTALL_PERMISSIONS_PROMPT,
74 LAUNCH_PROMPT,
75 REMOTE_INSTALL_PROMPT,
76 REPAIR_PROMPT,
77 NUM_PROMPT_TYPES
80 // Enumeration for permissions and retained files details.
81 enum DetailsType {
82 PERMISSIONS_DETAILS = 0,
83 WITHHELD_PERMISSIONS_DETAILS,
84 RETAINED_FILES_DETAILS,
85 RETAINED_DEVICES_DETAILS,
88 // This enum is used to differentiate regular and withheld permissions for
89 // segregation in the install prompt.
90 enum PermissionsType {
91 REGULAR_PERMISSIONS = 0,
92 WITHHELD_PERMISSIONS,
93 ALL_PERMISSIONS,
96 static std::string PromptTypeToString(PromptType type);
98 // Extra information needed to display an installation or uninstallation
99 // prompt. Gets populated with raw data and exposes getters for formatted
100 // strings so that the GTK/views/Cocoa install dialogs don't have to repeat
101 // that logic.
102 // Ref-counted because we pass around the prompt independent of the full
103 // ExtensionInstallPrompt.
104 class Prompt : public base::RefCountedThreadSafe<Prompt> {
105 public:
106 explicit Prompt(PromptType type);
108 // Sets the permission list for this prompt.
109 void SetPermissions(const std::vector<base::string16>& permissions,
110 PermissionsType permissions_type);
111 // Sets the permission list details for this prompt.
112 void SetPermissionsDetails(const std::vector<base::string16>& details,
113 PermissionsType permissions_type);
114 void SetIsShowingDetails(DetailsType type,
115 size_t index,
116 bool is_showing_details);
117 void SetWebstoreData(const std::string& localized_user_count,
118 bool show_user_count,
119 double average_rating,
120 int rating_count);
121 void SetUserNameFromProfile(Profile* profile);
123 PromptType type() const { return type_; }
124 void set_type(PromptType type) { type_ = type; }
126 // Getters for UI element labels.
127 base::string16 GetDialogTitle() const;
128 base::string16 GetHeading() const;
129 int GetDialogButtons() const;
130 bool HasAcceptButtonLabel() const;
131 base::string16 GetAcceptButtonLabel() const;
132 bool HasAbortButtonLabel() const;
133 base::string16 GetAbortButtonLabel() const;
134 base::string16 GetPermissionsHeading(
135 PermissionsType permissions_type) const;
136 base::string16 GetRetainedFilesHeading() const;
137 base::string16 GetRetainedDevicesHeading() const;
139 bool ShouldShowPermissions() const;
140 bool ShouldShowExplanationText() const;
142 // Getters for webstore metadata. Only populated when the type is
143 // INLINE_INSTALL_PROMPT.
145 // The star display logic replicates the one used by the webstore (from
146 // components.ratingutils.setFractionalYellowStars). Callers pass in an
147 // "appender", which will be repeatedly called back with the star images
148 // that they append to the star display area.
149 typedef void(*StarAppender)(const gfx::ImageSkia*, void*);
150 void AppendRatingStars(StarAppender appender, void* data) const;
151 base::string16 GetRatingCount() const;
152 base::string16 GetUserCount() const;
153 size_t GetPermissionCount(PermissionsType permissions_type) const;
154 size_t GetPermissionsDetailsCount(PermissionsType permissions_type) const;
155 base::string16 GetPermission(size_t index,
156 PermissionsType permissions_type) const;
157 base::string16 GetPermissionsDetails(
158 size_t index,
159 PermissionsType permissions_type) const;
160 bool GetIsShowingDetails(DetailsType type, size_t index) const;
161 size_t GetRetainedFileCount() const;
162 base::string16 GetRetainedFile(size_t index) const;
163 size_t GetRetainedDeviceCount() const;
164 base::string16 GetRetainedDeviceMessageString(size_t index) const;
166 // Populated for BUNDLE_INSTALL_PROMPT.
167 const extensions::BundleInstaller* bundle() const { return bundle_; }
168 void set_bundle(const extensions::BundleInstaller* bundle) {
169 bundle_ = bundle;
172 // Populated for all other types.
173 const extensions::Extension* extension() const { return extension_; }
174 void set_extension(const extensions::Extension* extension) {
175 extension_ = extension;
178 // May be populated for POST_INSTALL_PERMISSIONS_PROMPT.
179 void set_retained_files(const std::vector<base::FilePath>& retained_files) {
180 retained_files_ = retained_files;
182 void set_retained_device_messages(
183 const std::vector<base::string16>& retained_device_messages) {
184 retained_device_messages_ = retained_device_messages;
187 const gfx::Image& icon() const { return icon_; }
188 void set_icon(const gfx::Image& icon) { icon_ = icon; }
190 bool has_webstore_data() const { return has_webstore_data_; }
192 const ExtensionInstallPromptExperiment* experiment() const {
193 return experiment_.get();
195 void set_experiment(ExtensionInstallPromptExperiment* experiment) {
196 experiment_ = experiment;
199 private:
200 friend class base::RefCountedThreadSafe<Prompt>;
202 struct InstallPromptPermissions {
203 InstallPromptPermissions();
204 ~InstallPromptPermissions();
206 std::vector<base::string16> permissions;
207 std::vector<base::string16> details;
208 std::vector<bool> is_showing_details;
211 virtual ~Prompt();
213 bool ShouldDisplayRevokeButton() const;
215 // Returns the InstallPromptPermissions corresponding to
216 // |permissions_type|.
217 InstallPromptPermissions& GetPermissionsForType(
218 PermissionsType permissions_type);
219 const InstallPromptPermissions& GetPermissionsForType(
220 PermissionsType permissions_type) const;
222 bool ShouldDisplayRevokeFilesButton() const;
224 PromptType type_;
226 // Permissions that are being requested (may not be all of an extension's
227 // permissions if only additional ones are being requested)
228 InstallPromptPermissions prompt_permissions_;
229 // Permissions that will be withheld upon install.
230 InstallPromptPermissions withheld_prompt_permissions_;
232 bool is_showing_details_for_retained_files_;
233 bool is_showing_details_for_retained_devices_;
235 // The extension or bundle being installed.
236 const extensions::Extension* extension_;
237 const extensions::BundleInstaller* bundle_;
239 // The icon to be displayed.
240 gfx::Image icon_;
242 // These fields are populated only when the prompt type is
243 // INLINE_INSTALL_PROMPT
244 // Already formatted to be locale-specific.
245 std::string localized_user_count_;
246 // Range is kMinExtensionRating to kMaxExtensionRating
247 double average_rating_;
248 int rating_count_;
250 // Whether we should display the user count (we anticipate this will be
251 // false if localized_user_count_ represents the number zero).
252 bool show_user_count_;
254 // Whether or not this prompt has been populated with data from the
255 // webstore.
256 bool has_webstore_data_;
258 std::vector<base::FilePath> retained_files_;
259 std::vector<base::string16> retained_device_messages_;
261 scoped_refptr<ExtensionInstallPromptExperiment> experiment_;
263 DISALLOW_COPY_AND_ASSIGN(Prompt);
266 static const int kMinExtensionRating = 0;
267 static const int kMaxExtensionRating = 5;
269 class Delegate {
270 public:
271 // We call this method to signal that the installation should continue.
272 virtual void InstallUIProceed() = 0;
274 // We call this method to signal that the installation should stop, with
275 // |user_initiated| true if the installation was stopped by the user.
276 virtual void InstallUIAbort(bool user_initiated) = 0;
278 protected:
279 virtual ~Delegate() {}
282 // Parameters to show a prompt dialog. Two sets of the
283 // parameters are supported: either use a parent WebContents or use a
284 // parent NativeWindow + a Profile.
285 struct ShowParams {
286 explicit ShowParams(content::WebContents* contents);
287 ShowParams(Profile* profile, gfx::NativeWindow window);
289 Profile* profile;
291 // Parent web contents of the install UI dialog. This can be NULL.
292 content::WebContents* parent_web_contents;
294 // NativeWindow parent.
295 gfx::NativeWindow parent_window;
298 typedef base::Callback<void(const ExtensionInstallPrompt::ShowParams&,
299 ExtensionInstallPrompt::Delegate*,
300 scoped_refptr<ExtensionInstallPrompt::Prompt>)>
301 ShowDialogCallback;
303 // Callback to show the default extension install dialog.
304 // The implementations of this function are platform-specific.
305 static ShowDialogCallback GetDefaultShowDialogCallback();
307 // Creates a dummy extension from the |manifest|, replacing the name and
308 // description with the localizations if provided.
309 static scoped_refptr<extensions::Extension> GetLocalizedExtensionForDisplay(
310 const base::DictionaryValue* manifest,
311 int flags, // Extension::InitFromValueFlags
312 const std::string& id,
313 const std::string& localized_name,
314 const std::string& localized_description,
315 std::string* error);
317 // Creates a prompt with a parent web content.
318 explicit ExtensionInstallPrompt(content::WebContents* contents);
320 // Creates a prompt with a profile and a native window. The most recently
321 // active browser window (or a new browser window if there are no browser
322 // windows) is used if a new tab needs to be opened.
323 ExtensionInstallPrompt(Profile* profile, gfx::NativeWindow native_window);
325 virtual ~ExtensionInstallPrompt();
327 extensions::ExtensionInstallUI* install_ui() const {
328 return install_ui_.get();
331 content::WebContents* parent_web_contents() const {
332 return show_params_.parent_web_contents;
335 // This is called by the bundle installer to verify whether the bundle
336 // should be installed.
338 // We *MUST* eventually call either Proceed() or Abort() on |delegate|.
339 virtual void ConfirmBundleInstall(
340 extensions::BundleInstaller* bundle,
341 const extensions::PermissionSet* permissions);
343 // This is called by the standalone installer to verify whether the install
344 // from the webstore should proceed.
346 // We *MUST* eventually call either Proceed() or Abort() on |delegate|.
347 virtual void ConfirmStandaloneInstall(Delegate* delegate,
348 const extensions::Extension* extension,
349 SkBitmap* icon,
350 scoped_refptr<Prompt> prompt);
352 // This is called by the installer to verify whether the installation from
353 // the webstore should proceed. |show_dialog_callback| is optional and can be
354 // NULL.
356 // We *MUST* eventually call either Proceed() or Abort() on |delegate|.
357 virtual void ConfirmWebstoreInstall(
358 Delegate* delegate,
359 const extensions::Extension* extension,
360 const SkBitmap* icon,
361 const ShowDialogCallback& show_dialog_callback);
363 // This is called by the installer to verify whether the installation should
364 // proceed. This is declared virtual for testing. |show_dialog_callback| is
365 // optional and can be NULL.
367 // We *MUST* eventually call either Proceed() or Abort() on |delegate|.
368 virtual void ConfirmInstall(Delegate* delegate,
369 const extensions::Extension* extension,
370 const ShowDialogCallback& show_dialog_callback);
372 // This is called by the app handler launcher to verify whether the app
373 // should be re-enabled. This is declared virtual for testing.
375 // We *MUST* eventually call either Proceed() or Abort() on |delegate|.
376 virtual void ConfirmReEnable(Delegate* delegate,
377 const extensions::Extension* extension);
379 // This is called by the external install alert UI to verify whether the
380 // extension should be enabled (external extensions are installed disabled).
382 // We *MUST* eventually call either Proceed() or Abort() on |delegate|.
383 virtual void ConfirmExternalInstall(
384 Delegate* delegate,
385 const extensions::Extension* extension,
386 const ShowDialogCallback& show_dialog_callback,
387 scoped_refptr<Prompt> prompt);
389 // This is called by the extension permissions API to verify whether an
390 // extension may be granted additional permissions.
392 // We *MUST* eventually call either Proceed() or Abort() on |delegate|.
393 virtual void ConfirmPermissions(Delegate* delegate,
394 const extensions::Extension* extension,
395 const extensions::PermissionSet* permissions);
397 // This is called by the app handler launcher to review what permissions the
398 // extension or app currently has.
400 // We *MUST* eventually call either Proceed() or Abort() on |delegate|.
401 virtual void ReviewPermissions(
402 Delegate* delegate,
403 const extensions::Extension* extension,
404 const std::vector<base::FilePath>& retained_file_paths,
405 const std::vector<base::string16>& retained_device_messages);
407 // Installation was successful. This is declared virtual for testing.
408 virtual void OnInstallSuccess(const extensions::Extension* extension,
409 SkBitmap* icon);
411 // Installation failed. This is declared virtual for testing.
412 virtual void OnInstallFailure(const extensions::CrxInstallerError& error);
414 void set_callback_for_test(const ShowDialogCallback& show_dialog_callback) {
415 show_dialog_callback_ = show_dialog_callback;
418 protected:
419 friend class extensions::ExtensionWebstorePrivateApiTest;
420 friend class WebstoreStartupInstallUnpackFailureTest;
422 // Whether or not we should record the oauth2 grant upon successful install.
423 bool record_oauth2_grant_;
425 private:
426 friend class GalleryInstallApiTestObserver;
428 // Sets the icon that will be used in any UI. If |icon| is NULL, or contains
429 // an empty bitmap, then a default icon will be used instead.
430 void SetIcon(const SkBitmap* icon);
432 // ImageLoader callback.
433 void OnImageLoaded(const gfx::Image& image);
435 // Starts the process of showing a confirmation UI, which is split into two.
436 // 1) Set off a 'load icon' task.
437 // 2) Handle the load icon response and show the UI (OnImageLoaded).
438 void LoadImageIfNeeded();
440 // Shows the actual UI (the icon should already be loaded).
441 void ShowConfirmation();
443 Profile* profile_;
445 base::MessageLoop* ui_loop_;
447 // The extensions installation icon.
448 SkBitmap icon_;
450 // The extension we are showing the UI for, if type is not
451 // BUNDLE_INSTALL_PROMPT.
452 const extensions::Extension* extension_;
454 // The bundle we are showing the UI for, if type BUNDLE_INSTALL_PROMPT.
455 const extensions::BundleInstaller* bundle_;
457 // A custom set of permissions to show in the install prompt instead of the
458 // extension's active permissions.
459 scoped_refptr<const extensions::PermissionSet> custom_permissions_;
461 // The object responsible for doing the UI specific actions.
462 scoped_ptr<extensions::ExtensionInstallUI> install_ui_;
464 // Parameters to show the confirmation UI.
465 ShowParams show_params_;
467 // The delegate we will call Proceed/Abort on after confirmation UI.
468 Delegate* delegate_;
470 // A pre-filled prompt.
471 scoped_refptr<Prompt> prompt_;
473 // Used to show the confirm dialog.
474 ShowDialogCallback show_dialog_callback_;
477 #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_INSTALL_PROMPT_H_