NaCl: Update revision in DEPS, r12770 -> r12773
[chromium-blink-merge.git] / chrome / browser / extensions / extension_install_prompt.h
blob85ab0f671a015b39492bae057fc9e53449e07e77
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/scoped_ptr.h"
15 #include "base/strings/string16.h"
16 #include "chrome/browser/extensions/crx_installer_error.h"
17 #include "chrome/browser/extensions/extension_install_prompt_experiment.h"
18 #include "extensions/common/url_pattern.h"
19 #include "google_apis/gaia/oauth2_mint_token_flow.h"
20 #include "google_apis/gaia/oauth2_token_service.h"
21 #include "third_party/skia/include/core/SkBitmap.h"
22 #include "ui/gfx/image/image.h"
23 #include "ui/gfx/image/image_skia.h"
24 #include "ui/gfx/native_widget_types.h"
26 class Browser;
27 class ExtensionInstallUI;
28 class InfoBarDelegate;
29 class Profile;
31 namespace base {
32 class DictionaryValue;
33 class MessageLoop;
34 } // namespace base
36 namespace content {
37 class PageNavigator;
38 class WebContents;
41 namespace extensions {
42 class BundleInstaller;
43 class Extension;
44 class ExtensionWebstorePrivateApiTest;
45 class MockGetAuthTokenFunction;
46 class PermissionSet;
47 } // namespace extensions
49 // Displays all the UI around extension installation.
50 class ExtensionInstallPrompt
51 : public OAuth2MintTokenFlow::Delegate,
52 public OAuth2TokenService::Consumer,
53 public base::SupportsWeakPtr<ExtensionInstallPrompt> {
54 public:
55 // This enum is associated with Extensions.InstallPrompt_Type UMA histogram.
56 // Do not modify existing values and add new values only to the end.
57 enum PromptType {
58 UNSET_PROMPT_TYPE = -1,
59 INSTALL_PROMPT = 0,
60 INLINE_INSTALL_PROMPT,
61 BUNDLE_INSTALL_PROMPT,
62 RE_ENABLE_PROMPT,
63 PERMISSIONS_PROMPT,
64 EXTERNAL_INSTALL_PROMPT,
65 POST_INSTALL_PERMISSIONS_PROMPT,
66 LAUNCH_PROMPT,
67 NUM_PROMPT_TYPES
70 enum DetailsType {
71 PERMISSIONS_DETAILS = 0,
72 OAUTH_DETAILS,
73 RETAINED_FILES_DETAILS,
76 // Extra information needed to display an installation or uninstallation
77 // prompt. Gets populated with raw data and exposes getters for formatted
78 // strings so that the GTK/views/Cocoa install dialogs don't have to repeat
79 // that logic.
80 class Prompt {
81 public:
82 explicit Prompt(PromptType type);
83 ~Prompt();
85 // Sets the permission list for this prompt.
86 void SetPermissions(const std::vector<base::string16>& permissions);
87 // Sets the permission list details for this prompt.
88 void SetPermissionsDetails(const std::vector<base::string16>& details);
89 void SetIsShowingDetails(DetailsType type,
90 size_t index,
91 bool is_showing_details);
92 void SetWebstoreData(const std::string& localized_user_count,
93 bool show_user_count,
94 double average_rating,
95 int rating_count);
96 void SetOAuthIssueAdvice(const IssueAdviceInfo& issue_advice);
97 void SetUserNameFromProfile(Profile* profile);
99 PromptType type() const { return type_; }
100 void set_type(PromptType type) { type_ = type; }
102 // Getters for UI element labels.
103 base::string16 GetDialogTitle() const;
104 base::string16 GetHeading() const;
105 int GetDialogButtons() const;
106 bool HasAcceptButtonLabel() const;
107 base::string16 GetAcceptButtonLabel() const;
108 bool HasAbortButtonLabel() const;
109 base::string16 GetAbortButtonLabel() const;
110 base::string16 GetPermissionsHeading() const;
111 base::string16 GetOAuthHeading() const;
112 base::string16 GetRetainedFilesHeading() const;
114 bool ShouldShowPermissions() const;
115 bool ShouldShowExplanationText() const;
117 // Getters for webstore metadata. Only populated when the type is
118 // INLINE_INSTALL_PROMPT.
120 // The star display logic replicates the one used by the webstore (from
121 // components.ratingutils.setFractionalYellowStars). Callers pass in an
122 // "appender", which will be repeatedly called back with the star images
123 // that they append to the star display area.
124 typedef void(*StarAppender)(const gfx::ImageSkia*, void*);
125 void AppendRatingStars(StarAppender appender, void* data) const;
126 base::string16 GetRatingCount() const;
127 base::string16 GetUserCount() const;
128 size_t GetPermissionCount() const;
129 size_t GetPermissionsDetailsCount() const;
130 base::string16 GetPermission(size_t index) const;
131 base::string16 GetPermissionsDetails(size_t index) const;
132 bool GetIsShowingDetails(DetailsType type, size_t index) const;
133 size_t GetOAuthIssueCount() const;
134 const IssueAdviceInfoEntry& GetOAuthIssue(size_t index) const;
135 size_t GetRetainedFileCount() const;
136 base::string16 GetRetainedFile(size_t index) const;
138 // Populated for BUNDLE_INSTALL_PROMPT.
139 const extensions::BundleInstaller* bundle() const { return bundle_; }
140 void set_bundle(const extensions::BundleInstaller* bundle) {
141 bundle_ = bundle;
144 // Populated for all other types.
145 const extensions::Extension* extension() const { return extension_; }
146 void set_extension(const extensions::Extension* extension) {
147 extension_ = extension;
150 // May be populated for POST_INSTALL_PERMISSIONS_PROMPT.
151 void set_retained_files(const std::vector<base::FilePath>& retained_files) {
152 retained_files_ = retained_files;
155 const gfx::Image& icon() const { return icon_; }
156 void set_icon(const gfx::Image& icon) { icon_ = icon; }
158 bool has_webstore_data() const { return has_webstore_data_; }
160 const ExtensionInstallPromptExperiment* experiment() const {
161 return experiment_;
163 void set_experiment(ExtensionInstallPromptExperiment* experiment) {
164 experiment_ = experiment;
167 private:
168 bool ShouldDisplayRevokeFilesButton() const;
170 PromptType type_;
172 // Permissions that are being requested (may not be all of an extension's
173 // permissions if only additional ones are being requested)
174 std::vector<base::string16> permissions_;
175 std::vector<base::string16> details_;
176 std::vector<bool> is_showing_details_for_permissions_;
177 std::vector<bool> is_showing_details_for_oauth_;
178 bool is_showing_details_for_retained_files_;
180 // Descriptions and details for OAuth2 permissions to display to the user.
181 // These correspond to permission scopes.
182 IssueAdviceInfo oauth_issue_advice_;
184 // User name to be used in Oauth heading label.
185 base::string16 oauth_user_name_;
187 // The extension or bundle being installed.
188 const extensions::Extension* extension_;
189 const extensions::BundleInstaller* bundle_;
191 // The icon to be displayed.
192 gfx::Image icon_;
194 // These fields are populated only when the prompt type is
195 // INLINE_INSTALL_PROMPT
196 // Already formatted to be locale-specific.
197 std::string localized_user_count_;
198 // Range is kMinExtensionRating to kMaxExtensionRating
199 double average_rating_;
200 int rating_count_;
202 // Whether we should display the user count (we anticipate this will be
203 // false if localized_user_count_ represents the number zero).
204 bool show_user_count_;
206 // Whether or not this prompt has been populated with data from the
207 // webstore.
208 bool has_webstore_data_;
210 std::vector<base::FilePath> retained_files_;
212 scoped_refptr<ExtensionInstallPromptExperiment> experiment_;
215 static const int kMinExtensionRating = 0;
216 static const int kMaxExtensionRating = 5;
218 class Delegate {
219 public:
220 // We call this method to signal that the installation should continue.
221 virtual void InstallUIProceed() = 0;
223 // We call this method to signal that the installation should stop, with
224 // |user_initiated| true if the installation was stopped by the user.
225 virtual void InstallUIAbort(bool user_initiated) = 0;
227 protected:
228 virtual ~Delegate() {}
231 // Parameters to show a prompt dialog. Two sets of the
232 // parameters are supported: either use a parent WebContents or use a
233 // parent NativeWindow + a PageNavigator.
234 struct ShowParams {
235 explicit ShowParams(content::WebContents* contents);
236 ShowParams(gfx::NativeWindow window, content::PageNavigator* navigator);
238 // Parent web contents of the install UI dialog. This can be NULL.
239 content::WebContents* parent_web_contents;
241 // NativeWindow parent and navigator. If initialized using a parent web
242 // contents, these are derived from it.
243 gfx::NativeWindow parent_window;
244 content::PageNavigator* navigator;
247 typedef base::Callback<void(const ExtensionInstallPrompt::ShowParams&,
248 ExtensionInstallPrompt::Delegate*,
249 const ExtensionInstallPrompt::Prompt&)>
250 ShowDialogCallback;
252 // Callback to show the default extension install dialog.
253 // The implementations of this function are platform-specific.
254 static ShowDialogCallback GetDefaultShowDialogCallback();
256 // Creates a dummy extension from the |manifest|, replacing the name and
257 // description with the localizations if provided.
258 static scoped_refptr<extensions::Extension> GetLocalizedExtensionForDisplay(
259 const base::DictionaryValue* manifest,
260 int flags, // Extension::InitFromValueFlags
261 const std::string& id,
262 const std::string& localized_name,
263 const std::string& localized_description,
264 std::string* error);
266 // Creates a prompt with a parent web content.
267 explicit ExtensionInstallPrompt(content::WebContents* contents);
269 // Creates a prompt with a profile, a native window and a page navigator.
270 ExtensionInstallPrompt(Profile* profile,
271 gfx::NativeWindow native_window,
272 content::PageNavigator* navigator);
274 virtual ~ExtensionInstallPrompt();
276 ExtensionInstallUI* install_ui() const { return install_ui_.get(); }
278 bool record_oauth2_grant() const { return record_oauth2_grant_; }
280 content::WebContents* parent_web_contents() const {
281 return show_params_.parent_web_contents;
284 // This is called by the bundle installer to verify whether the bundle
285 // should be installed.
287 // We *MUST* eventually call either Proceed() or Abort() on |delegate|.
288 virtual void ConfirmBundleInstall(
289 extensions::BundleInstaller* bundle,
290 const extensions::PermissionSet* permissions);
292 // This is called by the standalone installer to verify whether the install
293 // from the webstore should proceed.
295 // We *MUST* eventually call either Proceed() or Abort() on |delegate|.
296 virtual void ConfirmStandaloneInstall(Delegate* delegate,
297 const extensions::Extension* extension,
298 SkBitmap* icon,
299 const Prompt& prompt);
301 // This is called by the installer to verify whether the installation from
302 // the webstore should proceed. |show_dialog_callback| is optional and can be
303 // NULL.
305 // We *MUST* eventually call either Proceed() or Abort() on |delegate|.
306 virtual void ConfirmWebstoreInstall(
307 Delegate* delegate,
308 const extensions::Extension* extension,
309 const SkBitmap* icon,
310 const ShowDialogCallback& show_dialog_callback);
312 // This is called by the installer to verify whether the installation should
313 // proceed. This is declared virtual for testing. |show_dialog_callback| is
314 // optional and can be NULL.
316 // We *MUST* eventually call either Proceed() or Abort() on |delegate|.
317 virtual void ConfirmInstall(Delegate* delegate,
318 const extensions::Extension* extension,
319 const ShowDialogCallback& show_dialog_callback);
321 // This is called by the app handler launcher to verify whether the app
322 // should be re-enabled. This is declared virtual for testing.
324 // We *MUST* eventually call either Proceed() or Abort() on |delegate|.
325 virtual void ConfirmReEnable(Delegate* delegate,
326 const extensions::Extension* extension);
328 // This is called by the external install alert UI to verify whether the
329 // extension should be enabled (external extensions are installed disabled).
331 // We *MUST* eventually call either Proceed() or Abort() on |delegate|.
332 virtual void ConfirmExternalInstall(
333 Delegate* delegate,
334 const extensions::Extension* extension,
335 const ShowDialogCallback& show_dialog_callback,
336 const Prompt& prompt);
338 // This is called by the extension permissions API to verify whether an
339 // extension may be granted additional permissions.
341 // We *MUST* eventually call either Proceed() or Abort() on |delegate|.
342 virtual void ConfirmPermissions(Delegate* delegate,
343 const extensions::Extension* extension,
344 const extensions::PermissionSet* permissions);
346 // This is called by the extension identity API to verify whether an
347 // extension can be granted an OAuth2 token.
349 // We *MUST* eventually call either Proceed() or Abort() on |delegate|.
350 virtual void ConfirmIssueAdvice(Delegate* delegate,
351 const extensions::Extension* extension,
352 const IssueAdviceInfo& issue_advice);
354 // This is called by the app handler launcher to review what permissions the
355 // extension or app currently has.
357 // We *MUST* eventually call either Proceed() or Abort() on |delegate|.
358 virtual void ReviewPermissions(
359 Delegate* delegate,
360 const extensions::Extension* extension,
361 const std::vector<base::FilePath>& retained_file_paths);
363 // Installation was successful. This is declared virtual for testing.
364 virtual void OnInstallSuccess(const extensions::Extension* extension,
365 SkBitmap* icon);
367 // Installation failed. This is declared virtual for testing.
368 virtual void OnInstallFailure(const extensions::CrxInstallerError& error);
370 protected:
371 friend class extensions::ExtensionWebstorePrivateApiTest;
372 friend class extensions::MockGetAuthTokenFunction;
373 friend class WebstoreStartupInstallUnpackFailureTest;
375 // Whether or not we should record the oauth2 grant upon successful install.
376 bool record_oauth2_grant_;
378 private:
379 friend class GalleryInstallApiTestObserver;
381 // Sets the icon that will be used in any UI. If |icon| is NULL, or contains
382 // an empty bitmap, then a default icon will be used instead.
383 void SetIcon(const SkBitmap* icon);
385 // ImageLoader callback.
386 void OnImageLoaded(const gfx::Image& image);
388 // Starts the process of showing a confirmation UI, which is split into two.
389 // 1) Set off a 'load icon' task.
390 // 2) Handle the load icon response and show the UI (OnImageLoaded).
391 void LoadImageIfNeeded();
393 // OAuth2TokenService::Consumer implementation:
394 virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
395 const std::string& access_token,
396 const base::Time& expiration_time) OVERRIDE;
397 virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request,
398 const GoogleServiceAuthError& error) OVERRIDE;
400 // OAuth2MintTokenFlow::Delegate implementation:
401 virtual void OnIssueAdviceSuccess(
402 const IssueAdviceInfo& issue_advice) OVERRIDE;
403 virtual void OnMintTokenFailure(
404 const GoogleServiceAuthError& error) OVERRIDE;
406 // Shows the actual UI (the icon should already be loaded).
407 void ShowConfirmation();
409 base::MessageLoop* ui_loop_;
411 // The extensions installation icon.
412 SkBitmap icon_;
414 // The extension we are showing the UI for, if type is not
415 // BUNDLE_INSTALL_PROMPT.
416 const extensions::Extension* extension_;
418 // The bundle we are showing the UI for, if type BUNDLE_INSTALL_PROMPT.
419 const extensions::BundleInstaller* bundle_;
421 // The permissions being prompted for.
422 scoped_refptr<const extensions::PermissionSet> permissions_;
424 // The object responsible for doing the UI specific actions.
425 scoped_ptr<ExtensionInstallUI> install_ui_;
427 // Parameters to show the confirmation UI.
428 ShowParams show_params_;
430 // The delegate we will call Proceed/Abort on after confirmation UI.
431 Delegate* delegate_;
433 // A pre-filled prompt.
434 Prompt prompt_;
436 scoped_ptr<OAuth2TokenService::Request> login_token_request_;
437 scoped_ptr<OAuth2MintTokenFlow> token_flow_;
439 // Used to show the confirm dialog.
440 ShowDialogCallback show_dialog_callback_;
443 #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_INSTALL_PROMPT_H_