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