Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / extension_install_prompt.h
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_EXTENSION_INSTALL_PROMPT_H_
6 #define CHROME_BROWSER_EXTENSIONS_EXTENSION_INSTALL_PROMPT_H_
7
8 #include <string>
9 #include <vector>
10
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"
25
26 class Browser;
27 class ExtensionInstallUI;
28 class InfoBarDelegate;
29 class Profile;
30
31 namespace base {
32 class DictionaryValue;
33 class MessageLoop;
34 }  // namespace base
35
36 namespace content {
37 class PageNavigator;
38 class WebContents;
39 }
40
41 namespace extensions {
42 class BundleInstaller;
43 class Extension;
44 class ExtensionWebstorePrivateApiTest;
45 class MockGetAuthTokenFunction;
46 class PermissionSet;
47 }  // namespace extensions
48
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
68   };
69
70   enum DetailsType {
71     PERMISSIONS_DETAILS = 0,
72     OAUTH_DETAILS,
73     RETAINED_FILES_DETAILS,
74   };
75
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();
84
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);
98
99     PromptType type() const { return type_; }
100     void set_type(PromptType type) { type_ = type; }
101
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;
113
114     bool ShouldShowPermissions() const;
115     bool ShouldShowExplanationText() const;
116
117     // Getters for webstore metadata. Only populated when the type is
118     // INLINE_INSTALL_PROMPT.
119
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;
137
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;
142     }
143
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;
148     }
149
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;
153     }
154
155     const gfx::Image& icon() const { return icon_; }
156     void set_icon(const gfx::Image& icon) { icon_ = icon; }
157
158     bool has_webstore_data() const { return has_webstore_data_; }
159
160     const ExtensionInstallPromptExperiment* experiment() const {
161       return experiment_;
162     }
163     void set_experiment(ExtensionInstallPromptExperiment* experiment) {
164       experiment_ = experiment;
165     }
166
167    private:
168     bool ShouldDisplayRevokeFilesButton() const;
169
170     PromptType type_;
171
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_;
179
180     // Descriptions and details for OAuth2 permissions to display to the user.
181     // These correspond to permission scopes.
182     IssueAdviceInfo oauth_issue_advice_;
183
184     // User name to be used in Oauth heading label.
185     base::string16 oauth_user_name_;
186
187     // The extension or bundle being installed.
188     const extensions::Extension* extension_;
189     const extensions::BundleInstaller* bundle_;
190
191     // The icon to be displayed.
192     gfx::Image icon_;
193
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_;
201
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_;
205
206     // Whether or not this prompt has been populated with data from the
207     // webstore.
208     bool has_webstore_data_;
209
210     std::vector<base::FilePath> retained_files_;
211
212     scoped_refptr<ExtensionInstallPromptExperiment> experiment_;
213   };
214
215   static const int kMinExtensionRating = 0;
216   static const int kMaxExtensionRating = 5;
217
218   class Delegate {
219    public:
220     // We call this method to signal that the installation should continue.
221     virtual void InstallUIProceed() = 0;
222
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;
226
227    protected:
228     virtual ~Delegate() {}
229   };
230
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);
237
238     // Parent web contents of the install UI dialog. This can be NULL.
239     content::WebContents* parent_web_contents;
240
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;
245   };
246
247   typedef base::Callback<void(const ExtensionInstallPrompt::ShowParams&,
248                               ExtensionInstallPrompt::Delegate*,
249                               const ExtensionInstallPrompt::Prompt&)>
250       ShowDialogCallback;
251
252   // Callback to show the default extension install dialog.
253   // The implementations of this function are platform-specific.
254   static ShowDialogCallback GetDefaultShowDialogCallback();
255
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);
265
266   // Creates a prompt with a parent web content.
267   explicit ExtensionInstallPrompt(content::WebContents* contents);
268
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);
273
274   virtual ~ExtensionInstallPrompt();
275
276   ExtensionInstallUI* install_ui() const { return install_ui_.get(); }
277
278   bool record_oauth2_grant() const { return record_oauth2_grant_; }
279
280   content::WebContents* parent_web_contents() const {
281     return show_params_.parent_web_contents;
282   }
283
284   // This is called by the bundle installer to verify whether the bundle
285   // should be installed.
286   //
287   // We *MUST* eventually call either Proceed() or Abort() on |delegate|.
288   virtual void ConfirmBundleInstall(
289       extensions::BundleInstaller* bundle,
290       const extensions::PermissionSet* permissions);
291
292   // This is called by the standalone installer to verify whether the install
293   // from the webstore should proceed.
294   //
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);
300
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.
304   //
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);
311
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.
315   //
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);
320
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.
323   //
324   // We *MUST* eventually call either Proceed() or Abort() on |delegate|.
325   virtual void ConfirmReEnable(Delegate* delegate,
326                                const extensions::Extension* extension);
327
328   // This is called by the external install alert UI to verify whether the
329   // extension should be enabled (external extensions are installed disabled).
330   //
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);
337
338   // This is called by the extension permissions API to verify whether an
339   // extension may be granted additional permissions.
340   //
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);
345
346   // This is called by the extension identity API to verify whether an
347   // extension can be granted an OAuth2 token.
348   //
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);
353
354   // This is called by the app handler launcher to review what permissions the
355   // extension or app currently has.
356   //
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);
362
363   // Installation was successful. This is declared virtual for testing.
364   virtual void OnInstallSuccess(const extensions::Extension* extension,
365                                 SkBitmap* icon);
366
367   // Installation failed. This is declared virtual for testing.
368   virtual void OnInstallFailure(const extensions::CrxInstallerError& error);
369
370  protected:
371   friend class extensions::ExtensionWebstorePrivateApiTest;
372   friend class extensions::MockGetAuthTokenFunction;
373   friend class WebstoreStartupInstallUnpackFailureTest;
374
375   // Whether or not we should record the oauth2 grant upon successful install.
376   bool record_oauth2_grant_;
377
378  private:
379   friend class GalleryInstallApiTestObserver;
380
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);
384
385   // ImageLoader callback.
386   void OnImageLoaded(const gfx::Image& image);
387
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();
392
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;
399
400   // OAuth2MintTokenFlow::Delegate implementation:
401   virtual void OnIssueAdviceSuccess(
402       const IssueAdviceInfo& issue_advice) OVERRIDE;
403   virtual void OnMintTokenFailure(
404       const GoogleServiceAuthError& error) OVERRIDE;
405
406   // Shows the actual UI (the icon should already be loaded).
407   void ShowConfirmation();
408
409   base::MessageLoop* ui_loop_;
410
411   // The extensions installation icon.
412   SkBitmap icon_;
413
414   // The extension we are showing the UI for, if type is not
415   // BUNDLE_INSTALL_PROMPT.
416   const extensions::Extension* extension_;
417
418   // The bundle we are showing the UI for, if type BUNDLE_INSTALL_PROMPT.
419   const extensions::BundleInstaller* bundle_;
420
421   // The permissions being prompted for.
422   scoped_refptr<const extensions::PermissionSet> permissions_;
423
424   // The object responsible for doing the UI specific actions.
425   scoped_ptr<ExtensionInstallUI> install_ui_;
426
427   // Parameters to show the confirmation UI.
428   ShowParams show_params_;
429
430   // The delegate we will call Proceed/Abort on after confirmation UI.
431   Delegate* delegate_;
432
433   // A pre-filled prompt.
434   Prompt prompt_;
435
436   scoped_ptr<OAuth2TokenService::Request> login_token_request_;
437   scoped_ptr<OAuth2MintTokenFlow> token_flow_;
438
439   // Used to show the confirm dialog.
440   ShowDialogCallback show_dialog_callback_;
441 };
442
443 #endif  // CHROME_BROWSER_EXTENSIONS_EXTENSION_INSTALL_PROMPT_H_