Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / webstore_installer.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_WEBSTORE_INSTALLER_H_
6 #define CHROME_BROWSER_EXTENSIONS_WEBSTORE_INSTALLER_H_
7
8 #include <list>
9 #include <string>
10
11 #include "base/compiler_specific.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/supports_user_data.h"
15 #include "base/timer/timer.h"
16 #include "base/values.h"
17 #include "base/version.h"
18 #include "chrome/browser/extensions/extension_install_prompt.h"
19 #include "content/public/browser/browser_thread.h"
20 #include "content/public/browser/download_interrupt_reasons.h"
21 #include "content/public/browser/download_item.h"
22 #include "content/public/browser/notification_observer.h"
23 #include "content/public/browser/notification_registrar.h"
24 #include "content/public/browser/web_contents_observer.h"
25 #include "extensions/common/manifest_handlers/shared_module_info.h"
26 #include "ui/gfx/image/image_skia.h"
27 #include "url/gurl.h"
28
29 class Profile;
30
31 namespace base {
32 class FilePath;
33 }
34
35 namespace content {
36 class WebContents;
37 }
38
39 namespace extensions {
40
41 class CrxInstaller;
42 class Extension;
43 class Manifest;
44
45 // Downloads and installs extensions from the web store.
46 class WebstoreInstaller : public content::NotificationObserver,
47                           public content::DownloadItem::Observer,
48                           public content::WebContentsObserver,
49                           public base::RefCountedThreadSafe<
50   WebstoreInstaller, content::BrowserThread::DeleteOnUIThread> {
51  public:
52   enum InstallSource {
53     // Inline installs trigger slightly different behavior (install source
54     // is different, download referrers are the item's page in the gallery).
55     INSTALL_SOURCE_INLINE,
56     INSTALL_SOURCE_APP_LAUNCHER,
57     INSTALL_SOURCE_OTHER
58   };
59
60   enum FailureReason {
61     FAILURE_REASON_CANCELLED,
62     FAILURE_REASON_DEPENDENCY_NOT_FOUND,
63     FAILURE_REASON_DEPENDENCY_NOT_SHARED_MODULE,
64     FAILURE_REASON_OTHER
65   };
66
67   enum ManifestCheckLevel {
68     // Do not check for any manifest equality.
69     MANIFEST_CHECK_LEVEL_NONE,
70
71     // Only check that the expected and actual permissions have the same
72     // effective permissions.
73     MANIFEST_CHECK_LEVEL_LOOSE,
74
75     // All data in the expected and actual manifests must match.
76     MANIFEST_CHECK_LEVEL_STRICT,
77   };
78
79   class Delegate {
80    public:
81     virtual void OnExtensionDownloadStarted(const std::string& id,
82                                             content::DownloadItem* item);
83     virtual void OnExtensionDownloadProgress(const std::string& id,
84                                              content::DownloadItem* item);
85     virtual void OnExtensionInstallSuccess(const std::string& id) = 0;
86     virtual void OnExtensionInstallFailure(const std::string& id,
87                                            const std::string& error,
88                                            FailureReason reason) = 0;
89
90    protected:
91     virtual ~Delegate() {}
92   };
93
94   // Contains information about what parts of the extension install process can
95   // be skipped or modified. If one of these is present, it means that a CRX
96   // download was initiated by WebstoreInstaller. The Approval instance should
97   // be checked further for additional details.
98   struct Approval : public base::SupportsUserData::Data {
99     static scoped_ptr<Approval> CreateWithInstallPrompt(Profile* profile);
100
101     // Creates an Approval for installing a shared module.
102     static scoped_ptr<Approval> CreateForSharedModule(Profile* profile);
103
104     // Creates an Approval that will skip putting up an install confirmation
105     // prompt if the actual manifest from the extension to be installed matches
106     // |parsed_manifest|. The |strict_manifest_check| controls whether we want
107     // to require an exact manifest match, or are willing to tolerate a looser
108     // check just that the effective permissions are the same.
109     static scoped_ptr<Approval> CreateWithNoInstallPrompt(
110         Profile* profile,
111         const std::string& extension_id,
112         scoped_ptr<base::DictionaryValue> parsed_manifest,
113         bool strict_manifest_check);
114
115     virtual ~Approval();
116
117     // The extension id that was approved for installation.
118     std::string extension_id;
119
120     // The profile the extension should be installed into.
121     Profile* profile;
122
123     // The expected manifest, before localization.
124     scoped_ptr<Manifest> manifest;
125
126     // Whether to use a bubble notification when an app is installed, instead of
127     // the default behavior of transitioning to the new tab page.
128     bool use_app_installed_bubble;
129
130     // Whether to skip the post install UI like the extension installed bubble.
131     bool skip_post_install_ui;
132
133     // Whether to skip the install dialog once the extension has been downloaded
134     // and unpacked. One reason this can be true is that in the normal webstore
135     // installation, the dialog is shown earlier, before any download is done,
136     // so there's no need to show it again.
137     bool skip_install_dialog;
138
139     // Whether we should enable the launcher before installing the app.
140     bool enable_launcher;
141
142     // Manifest check level for checking actual manifest against expected
143     // manifest.
144     ManifestCheckLevel manifest_check_level;
145
146     // Used to show the install dialog.
147     ExtensionInstallPrompt::ShowDialogCallback show_dialog_callback;
148
149     // The icon to use to display the extension while it is installing.
150     gfx::ImageSkia installing_icon;
151
152     // A dummy extension created from |manifest|;
153     scoped_refptr<Extension> dummy_extension;
154
155     // Required minimum version.
156     scoped_ptr<Version> minimum_version;
157
158     // Ephemeral apps (experimental) are not permanently installed in Chrome.
159     bool is_ephemeral;
160
161     // The authuser index required to download the item being installed. May be
162     // the empty string, in which case no authuser parameter is used.
163     std::string authuser;
164
165    private:
166     Approval();
167   };
168
169   // Gets the Approval associated with the |download|, or NULL if there's none.
170   // Note that the Approval is owned by |download|.
171   static const Approval* GetAssociatedApproval(
172       const content::DownloadItem& download);
173
174   // Creates a WebstoreInstaller for downloading and installing the extension
175   // with the given |id| from the Chrome Web Store. If |delegate| is not NULL,
176   // it will be notified when the install succeeds or fails. The installer will
177   // use the specified |controller| to download the extension. Only one
178   // WebstoreInstaller can use a specific controller at any given time. This
179   // also associates the |approval| with this install.
180   // Note: the delegate should stay alive until being called back.
181   WebstoreInstaller(Profile* profile,
182                     Delegate* delegate,
183                     content::WebContents* web_contents,
184                     const std::string& id,
185                     scoped_ptr<Approval> approval,
186                     InstallSource source);
187
188   // Starts downloading and installing the extension.
189   void Start();
190
191   // content::NotificationObserver
192   virtual void Observe(int type,
193                        const content::NotificationSource& source,
194                        const content::NotificationDetails& details) OVERRIDE;
195
196   // Removes the reference to the delegate passed in the constructor. Used when
197   // the delegate object must be deleted before this object.
198   void InvalidateDelegate();
199
200   // Instead of using the default download directory, use |directory| instead.
201   // This does *not* transfer ownership of |directory|.
202   static void SetDownloadDirectoryForTests(base::FilePath* directory);
203
204  private:
205   FRIEND_TEST_ALL_PREFIXES(WebstoreInstallerTest, PlatformParams);
206   friend struct content::BrowserThread::DeleteOnThread<
207    content::BrowserThread::UI>;
208   friend class base::DeleteHelper<WebstoreInstaller>;
209   virtual ~WebstoreInstaller();
210
211   // Helper to get install URL.
212   static GURL GetWebstoreInstallURL(const std::string& extension_id,
213                                     InstallSource source);
214
215   // DownloadManager::DownloadUrl callback.
216   void OnDownloadStarted(content::DownloadItem* item,
217                          content::DownloadInterruptReason interrupt_reason);
218
219   // DownloadItem::Observer implementation:
220   virtual void OnDownloadUpdated(content::DownloadItem* download) OVERRIDE;
221   virtual void OnDownloadDestroyed(content::DownloadItem* download) OVERRIDE;
222
223   // Downloads next pending module in |pending_modules_|.
224   void DownloadNextPendingModule();
225
226   // Downloads and installs a single Crx with the given |extension_id|.
227   // This function is used for both the extension Crx and dependences.
228   void DownloadCrx(const std::string& extension_id, InstallSource source);
229
230   // Starts downloading the extension to |file_path|.
231   void StartDownload(const base::FilePath& file_path);
232
233   // Updates the InstallTracker with the latest download progress.
234   void UpdateDownloadProgress();
235
236   // Creates and starts CrxInstaller for the downloaded extension package.
237   void StartCrxInstaller(const content::DownloadItem& item);
238
239   // Reports an install |error| to the delegate for the given extension if this
240   // managed its installation. This also removes the associated PendingInstall.
241   void ReportFailure(const std::string& error, FailureReason reason);
242
243   // Reports a successful install to the delegate for the given extension if
244   // this managed its installation. This also removes the associated
245   // PendingInstall.
246   void ReportSuccess();
247
248   // Records stats regarding an interrupted webstore download item.
249   void RecordInterrupt(const content::DownloadItem* download) const;
250
251   content::NotificationRegistrar registrar_;
252   Profile* profile_;
253   Delegate* delegate_;
254   std::string id_;
255   InstallSource install_source_;
256   // The DownloadItem is owned by the DownloadManager and is valid from when
257   // OnDownloadStarted is called (with no error) until OnDownloadDestroyed().
258   content::DownloadItem* download_item_;
259   // Used to periodically update the extension's download status. This will
260   // trigger at least every second, though sometimes more frequently (depending
261   // on number of modules, etc).
262   base::OneShotTimer<WebstoreInstaller> download_progress_timer_;
263   scoped_ptr<Approval> approval_;
264   GURL download_url_;
265   scoped_refptr<CrxInstaller> crx_installer_;
266
267   // Pending modules.
268   std::list<SharedModuleInfo::ImportInfo> pending_modules_;
269   // Total extension modules we need download and install (the main module and
270   // depedences).
271   int total_modules_;
272   bool download_started_;
273 };
274
275 }  // namespace extensions
276
277 #endif  // CHROME_BROWSER_EXTENSIONS_WEBSTORE_INSTALLER_H_