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