1// Copyright (c) 2011 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_UI_WEBUI_OPTIONS_EXTENSION_SETTINGS_HANDLER_H_
6#define CHROME_BROWSER_UI_WEBUI_OPTIONS_EXTENSION_SETTINGS_HANDLER_H_
7#pragma once
8
9#include <string>
10#include <vector>
11
12#include "base/memory/scoped_ptr.h"
13#include "chrome/browser/extensions/extension_uninstall_dialog.h"
14#include "chrome/browser/extensions/pack_extension_job.h"
15#include "chrome/browser/ui/shell_dialogs.h"
16#include "chrome/browser/ui/webui/chrome_url_data_manager.h"
17#include "chrome/common/extensions/extension_resource.h"
18#include "content/browser/webui/web_ui.h"
19#include "content/common/notification_observer.h"
20#include "content/common/notification_registrar.h"
21#include "googleurl/src/gurl.h"
22
23class DictionaryValue;
24class Extension;
25class ExtensionService;
26class FilePath;
27class ListValue;
28class PrefService;
29class RenderProcessHost;
30class UserScript;
31
32// Information about a page running in an extension, for example a toolstrip,
33// a background page, or a tab contents.
34struct ExtensionPage {
35  ExtensionPage(const GURL& url, int render_process_id, int render_view_id,
36                bool incognito)
37    : url(url),
38      render_process_id(render_process_id),
39      render_view_id(render_view_id),
40      incognito(incognito) {}
41  GURL url;
42  int render_process_id;
43  int render_view_id;
44  bool incognito;
45};
46
47class ExtensionsUIHTMLSource : public ChromeURLDataManager::DataSource {
48 public:
49  ExtensionsUIHTMLSource();
50
51  // Called when the network layer has requested a resource underneath
52  // the path we registered.
53  virtual void StartDataRequest(const std::string& path,
54                                bool is_incognito,
55                                int request_id);
56  virtual std::string GetMimeType(const std::string&) const;
57
58 private:
59  ~ExtensionsUIHTMLSource() {}
60
61  DISALLOW_COPY_AND_ASSIGN(ExtensionsUIHTMLSource);
62};
63
64// The handler for JavaScript messages related to the "extensions" view.
65class ExtensionsDOMHandler : public WebUIMessageHandler,
66                             public NotificationObserver,
67                             public PackExtensionJob::Client,
68                             public SelectFileDialog::Listener,
69                             public ExtensionUninstallDialog::Delegate {
70 public:
71
72  // Helper class that loads the icons for the extensions in the management UI.
73  // We do this with native code instead of just using chrome-extension:// URLs
74  // for two reasons:
75  //
76  // 1. We need to support the disabled extensions, too, and using URLs won't
77  //    work for them.
78  // 2. We want to desaturate the icons of the disabled extensions to make them
79  //    look disabled.
80  class IconLoader : public base::RefCountedThreadSafe<IconLoader> {
81   public:
82    explicit IconLoader(ExtensionsDOMHandler* handler);
83
84    // Load |icons|. Will call handler->OnIconsLoaded when complete. IconLoader
85    // takes ownership of both arguments.
86    void LoadIcons(std::vector<ExtensionResource>* icons,
87                   DictionaryValue* json);
88
89    // Cancel the load. IconLoader won't try to call back to the handler after
90    // this.
91    void Cancel();
92
93   private:
94    // Load the icons and call ReportResultOnUIThread when done. This method
95    // takes ownership of both arguments.
96    void LoadIconsOnFileThread(std::vector<ExtensionResource>* icons,
97                               DictionaryValue* json);
98
99    // Report back to the handler. This method takes ownership of |json|.
100    void ReportResultOnUIThread(DictionaryValue* json);
101
102    // The handler we will report back to.
103    ExtensionsDOMHandler* handler_;
104  };
105
106  explicit ExtensionsDOMHandler(ExtensionService* extension_service);
107  virtual ~ExtensionsDOMHandler();
108
109  // WebUIMessageHandler implementation.
110  virtual void RegisterMessages();
111
112  // Extension Detail JSON Struct for page. (static for ease of testing).
113  // Note: service can be NULL in unit tests.
114  static DictionaryValue* CreateExtensionDetailValue(
115      ExtensionService* service,
116      const Extension* extension,
117      const std::vector<ExtensionPage>& pages,
118      bool enabled,
119      bool terminated);
120
121  // ContentScript JSON Struct for page. (static for ease of testing).
122  static DictionaryValue* CreateContentScriptDetailValue(
123      const UserScript& script,
124      const FilePath& extension_path);
125
126  // ExtensionPackJob::Client
127  virtual void OnPackSuccess(const FilePath& crx_file,
128                             const FilePath& key_file);
129
130  virtual void OnPackFailure(const std::string& error);
131
132  // ExtensionUninstallDialog::Delegate:
133  virtual void ExtensionDialogAccepted();
134  virtual void ExtensionDialogCanceled();
135
136 private:
137  // Callback for "requestExtensionsData" message.
138  void HandleRequestExtensionsData(const ListValue* args);
139
140  // Callback for "toggleDeveloperMode" message.
141  void HandleToggleDeveloperMode(const ListValue* args);
142
143  // Callback for "inspect" message.
144  void HandleInspectMessage(const ListValue* args);
145
146  // Callback for "reload" message.
147  void HandleReloadMessage(const ListValue* args);
148
149  // Callback for "enable" message.
150  void HandleEnableMessage(const ListValue* args);
151
152  // Callback for "enableIncognito" message.
153  void HandleEnableIncognitoMessage(const ListValue* args);
154
155  // Callback for "allowFileAcces" message.
156  void HandleAllowFileAccessMessage(const ListValue* args);
157
158  // Callback for "uninstall" message.
159  void HandleUninstallMessage(const ListValue* args);
160
161  // Callback for "options" message.
162  void HandleOptionsMessage(const ListValue* args);
163
164  // Callback for "showButton" message.
165  void HandleShowButtonMessage(const ListValue* args);
166
167  // Callback for "load" message.
168  void HandleLoadMessage(const ListValue* args);
169
170  // Callback for "pack" message.
171  void HandlePackMessage(const ListValue* args);
172
173  // Callback for "autoupdate" message.
174  void HandleAutoUpdateMessage(const ListValue* args);
175
176  // Utility for calling javascript window.alert in the page.
177  void ShowAlert(const std::string& message);
178
179  // Callback for "selectFilePath" message.
180  void HandleSelectFilePathMessage(const ListValue* args);
181
182  // Utility for callbacks that get an extension ID as the sole argument.
183  const Extension* GetExtension(const ListValue* args);
184
185  // Forces a UI update if appropriate after a notification is received.
186  void MaybeUpdateAfterNotification();
187
188  // SelectFileDialog::Listener
189  virtual void FileSelected(const FilePath& path,
190                            int index, void* params);
191  virtual void MultiFilesSelected(
192      const std::vector<FilePath>& files, void* params);
193  virtual void FileSelectionCanceled(void* params) {}
194
195  // NotificationObserver
196  virtual void Observe(NotificationType type,
197                       const NotificationSource& source,
198                       const NotificationDetails& details);
199
200  // Helper that lists the current active html pages for an extension.
201  std::vector<ExtensionPage> GetActivePagesForExtension(
202      const Extension* extension);
203  void GetActivePagesForExtensionProcess(
204      RenderProcessHost* process,
205      const Extension* extension,
206      std::vector<ExtensionPage> *result);
207
208  // Returns the best icon to display in the UI for an extension, or an empty
209  // ExtensionResource if no good icon exists.
210  ExtensionResource PickExtensionIcon(const Extension* extension);
211
212  // Loads the extension resources into the json data, then calls OnIconsLoaded.
213  // Takes ownership of |icons|.
214  // Called on the file thread.
215  void LoadExtensionIcons(std::vector<ExtensionResource>* icons,
216                          DictionaryValue* json_data);
217
218  // Takes ownership of |json_data| and tells HTML about it.
219  // Called on the UI thread.
220  void OnIconsLoaded(DictionaryValue* json_data);
221
222  // Returns the ExtensionUninstallDialog object for this class, creating it if
223  // needed.
224  ExtensionUninstallDialog* GetExtensionUninstallDialog();
225
226  // Our model.
227  scoped_refptr<ExtensionService> extensions_service_;
228
229  // Used to pick the directory when loading an extension.
230  scoped_refptr<SelectFileDialog> load_extension_dialog_;
231
232  // Used to package the extension.
233  scoped_refptr<PackExtensionJob> pack_job_;
234
235  // Used to load icons asynchronously on the file thread.
236  scoped_refptr<IconLoader> icon_loader_;
237
238  // Used to show confirmation UI for uninstalling extensions in incognito mode.
239  scoped_ptr<ExtensionUninstallDialog> extension_uninstall_dialog_;
240
241  // The id of the extension we are prompting the user about.
242  std::string extension_id_prompting_;
243
244  // We monitor changes to the extension system so that we can reload when
245  // necessary.
246  NotificationRegistrar registrar_;
247
248  // If true, we will ignore notifications in ::Observe(). This is needed
249  // to prevent reloading the page when we were the cause of the
250  // notification.
251  bool ignore_notifications_;
252
253  // The page may be refreshed in response to a RENDER_VIEW_HOST_DELETED,
254  // but the iteration over RenderViewHosts will include the host because the
255  // notification is sent when it is in the process of being deleted (and before
256  // it is removed from the process). Keep a pointer to it so we can exclude
257  // it from the active views.
258  RenderViewHost* deleting_rvh_;
259
260  DISALLOW_COPY_AND_ASSIGN(ExtensionsDOMHandler);
261};
262
263class ExtensionsUI : public WebUI {
264 public:
265  explicit ExtensionsUI(TabContents* contents);
266
267  static RefCountedMemory* GetFaviconResourceBytes();
268
269  static void RegisterUserPrefs(PrefService* prefs);
270
271 private:
272  DISALLOW_COPY_AND_ASSIGN(ExtensionsUI);
273};
274
275#endif  // CHROME_BROWSER_UI_WEBUI_OPTIONS_EXTENSION_SETTINGS_HANDLER_H_
276