extension_settings_handler.h revision 116680a4aac90f2aa7413d9095a592090648e557
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_UI_WEBUI_EXTENSIONS_EXTENSION_SETTINGS_HANDLER_H_
6#define CHROME_BROWSER_UI_WEBUI_EXTENSIONS_EXTENSION_SETTINGS_HANDLER_H_
7
8#include <set>
9#include <string>
10#include <vector>
11
12#include "base/memory/scoped_ptr.h"
13#include "base/prefs/pref_change_registrar.h"
14#include "base/scoped_observer.h"
15#include "chrome/browser/extensions/error_console/error_console.h"
16#include "chrome/browser/extensions/extension_install_prompt.h"
17#include "chrome/browser/extensions/extension_install_ui.h"
18#include "chrome/browser/extensions/extension_uninstall_dialog.h"
19#include "chrome/browser/extensions/extension_warning_service.h"
20#include "chrome/browser/extensions/requirements_checker.h"
21#include "content/public/browser/navigation_controller.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 "content/public/browser/web_ui_message_handler.h"
26#include "extensions/browser/extension_prefs.h"
27#include "extensions/browser/extension_prefs_observer.h"
28#include "extensions/browser/extension_registry_observer.h"
29#include "url/gurl.h"
30
31class ExtensionService;
32
33namespace base {
34class DictionaryValue;
35class FilePath;
36class ListValue;
37}
38
39namespace content {
40class WebUIDataSource;
41}
42
43namespace user_prefs {
44class PrefRegistrySyncable;
45}
46
47namespace extensions {
48class Extension;
49class ExtensionRegistry;
50class ManagementPolicy;
51
52// Information about a page running in an extension, for example a popup bubble,
53// a background page, or a tab contents.
54struct ExtensionPage {
55  ExtensionPage(const GURL& url,
56                int render_process_id,
57                int render_view_id,
58                bool incognito,
59                bool generated_background_page);
60  GURL url;
61  int render_process_id;
62  int render_view_id;
63  bool incognito;
64  bool generated_background_page;
65};
66
67// Extension Settings UI handler.
68class ExtensionSettingsHandler
69    : public content::WebUIMessageHandler,
70      public content::NotificationObserver,
71      public content::WebContentsObserver,
72      public ErrorConsole::Observer,
73      public ExtensionInstallPrompt::Delegate,
74      public ExtensionPrefsObserver,
75      public ExtensionRegistryObserver,
76      public ExtensionUninstallDialog::Delegate,
77      public ExtensionWarningService::Observer,
78      public base::SupportsWeakPtr<ExtensionSettingsHandler> {
79 public:
80  ExtensionSettingsHandler();
81  virtual ~ExtensionSettingsHandler();
82
83  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
84
85  // Extension Detail JSON Struct for page. |pages| is injected for unit
86  // testing.
87  // Note: |warning_service| can be NULL in unit tests.
88  base::DictionaryValue* CreateExtensionDetailValue(
89      const Extension* extension,
90      const std::vector<ExtensionPage>& pages,
91      const ExtensionWarningService* warning_service);
92
93  void GetLocalizedValues(content::WebUIDataSource* source);
94
95 private:
96  friend class ExtensionUITest;
97  friend class BrokerDelegate;
98
99  // content::WebContentsObserver implementation.
100  virtual void RenderViewDeleted(
101      content::RenderViewHost* render_view_host) OVERRIDE;
102  virtual void DidStartNavigationToPendingEntry(
103      const GURL& url,
104      content::NavigationController::ReloadType reload_type) OVERRIDE;
105
106  // Allows injection for testing by friend classes.
107  ExtensionSettingsHandler(ExtensionService* service,
108                           ManagementPolicy* policy);
109
110  // WebUIMessageHandler implementation.
111  virtual void RegisterMessages() OVERRIDE;
112
113  // ErrorConsole::Observer implementation.
114  virtual void OnErrorAdded(const ExtensionError* error) OVERRIDE;
115
116  // content::NotificationObserver implementation.
117  virtual void Observe(int type,
118                       const content::NotificationSource& source,
119                       const content::NotificationDetails& details) OVERRIDE;
120
121  // ExtensionRegistryObserver implementation.
122  virtual void OnExtensionLoaded(content::BrowserContext* browser_context,
123                                 const Extension* extension) OVERRIDE;
124  virtual void OnExtensionUnloaded(
125      content::BrowserContext* browser_context,
126      const Extension* extension,
127      UnloadedExtensionInfo::Reason reason) OVERRIDE;
128  virtual void OnExtensionUninstalled(content::BrowserContext* browser_context,
129                                      const Extension* extension) OVERRIDE;
130
131  // ExtensionPrefsObserver implementation.
132  virtual void OnExtensionDisableReasonsChanged(const std::string& extension_id,
133                                                int disable_reasons) OVERRIDE;
134
135  // ExtensionUninstallDialog::Delegate implementation, used for receiving
136  // notification about uninstall confirmation dialog selections.
137  virtual void ExtensionUninstallAccepted() OVERRIDE;
138  virtual void ExtensionUninstallCanceled() OVERRIDE;
139
140  // ExtensionWarningService::Observer implementation.
141  virtual void ExtensionWarningsChanged() OVERRIDE;
142
143  // ExtensionInstallPrompt::Delegate implementation.
144  virtual void InstallUIProceed() OVERRIDE;
145  virtual void InstallUIAbort(bool user_initiated) OVERRIDE;
146
147  // Helper method that reloads all unpacked extensions.
148  void ReloadUnpackedExtensions();
149
150  // Callback for "requestExtensionsData" message.
151  void HandleRequestExtensionsData(const base::ListValue* args);
152
153  // Callback for "toggleDeveloperMode" message.
154  void HandleToggleDeveloperMode(const base::ListValue* args);
155
156  // Callback for "inspect" message.
157  void HandleInspectMessage(const base::ListValue* args);
158
159  // Callback for "launch" message.
160  void HandleLaunchMessage(const base::ListValue* args);
161
162  // Callback for "reload" message.
163  void HandleReloadMessage(const base::ListValue* args);
164
165  // Callback for "enable" message.
166  void HandleEnableMessage(const base::ListValue* args);
167
168  // Callback for "enableIncognito" message.
169  void HandleEnableIncognitoMessage(const base::ListValue* args);
170
171  // Callback for "enableErrorCollection" message.
172  void HandleEnableErrorCollectionMessage(const base::ListValue* args);
173
174  // Callback for "allowFileAcces" message.
175  void HandleAllowFileAccessMessage(const base::ListValue* args);
176
177  // Callback for "allowOnAllUrls" message.
178  void HandleAllowOnAllUrlsMessage(const base::ListValue* args);
179
180  // Callback for "uninstall" message.
181  void HandleUninstallMessage(const base::ListValue* args);
182
183  // Callback for "options" message.
184  void HandleOptionsMessage(const base::ListValue* args);
185
186  // Callback for "permissions" message.
187  void HandlePermissionsMessage(const base::ListValue* args);
188
189  // Callback for "showButton" message.
190  void HandleShowButtonMessage(const base::ListValue* args);
191
192  // Callback for "autoupdate" message.
193  void HandleAutoUpdateMessage(const base::ListValue* args);
194
195  // Callback for the "dismissADTPromo" message.
196  void HandleDismissADTPromoMessage(const base::ListValue* args);
197
198  // Callback for the "showPath" message.
199  void HandleShowPath(const base::ListValue* args);
200
201  // Utility for calling JavaScript window.alert in the page.
202  void ShowAlert(const std::string& message);
203
204  // Utility for callbacks that get an extension ID as the sole argument.
205  // Returns NULL if the extension isn't active.
206  const Extension* GetActiveExtension(const base::ListValue* args);
207
208  // Forces a UI update if appropriate after a notification is received.
209  void MaybeUpdateAfterNotification();
210
211  // Register for notifications that we need to reload the page.
212  void MaybeRegisterForNotifications();
213
214  // Helper that lists the current inspectable html pages for an extension.
215  std::vector<ExtensionPage> GetInspectablePagesForExtension(
216      const Extension* extension, bool extension_is_enabled);
217  void GetInspectablePagesForExtensionProcess(
218      const Extension* extension,
219      const std::set<content::RenderViewHost*>& views,
220      std::vector<ExtensionPage>* result);
221  void GetAppWindowPagesForExtensionProfile(const Extension* extension,
222                                            Profile* profile,
223                                            std::vector<ExtensionPage>* result);
224
225  // Returns the ExtensionUninstallDialog object for this class, creating it if
226  // needed.
227  ExtensionUninstallDialog* GetExtensionUninstallDialog();
228
229  // Callback for RequirementsChecker.
230  void OnRequirementsChecked(std::string extension_id,
231                             std::vector<std::string> requirement_errors);
232
233  // Handles the load retry notification sent from
234  // ExtensionService::ReportExtensionLoadError. Attempts to retry loading
235  // extension from |path| if retry is true, otherwise removes |path| from the
236  // vector of currently loading extensions.
237  //
238  // Does nothing if |path| is not a currently loading extension this object is
239  // tracking.
240  void HandleLoadRetryMessage(bool retry, const base::FilePath& path);
241
242  // Our model.  Outlives us since it's owned by our containing profile.
243  ExtensionService* extension_service_;
244
245  // A convenience member, filled once the extension_service_ is known.
246  ManagementPolicy* management_policy_;
247
248  // Used to show confirmation UI for uninstalling extensions in incognito mode.
249  scoped_ptr<ExtensionUninstallDialog> extension_uninstall_dialog_;
250
251  // The id of the extension we are prompting the user about.
252  std::string extension_id_prompting_;
253
254  // If true, we will ignore notifications in ::Observe(). This is needed
255  // to prevent reloading the page when we were the cause of the
256  // notification.
257  bool ignore_notifications_;
258
259  // The page may be refreshed in response to a RenderViewHost being destroyed,
260  // but the iteration over RenderViewHosts will include the host because the
261  // notification is sent when it is in the process of being deleted (and before
262  // it is removed from the process). Keep a pointer to it so we can exclude
263  // it from the active views.
264  content::RenderViewHost* deleting_rvh_;
265  // Do the same for a deleting RenderWidgetHost ID and RenderProcessHost ID.
266  int deleting_rwh_id_;
267  int deleting_rph_id_;
268
269  // We want to register for notifications only after we've responded at least
270  // once to the page, otherwise we'd be calling JavaScript functions on objects
271  // that don't exist yet when notifications come in. This variable makes sure
272  // we do so only once.
273  bool registered_for_notifications_;
274
275  content::NotificationRegistrar registrar_;
276
277  PrefChangeRegistrar pref_registrar_;
278
279  // This will not be empty when a requirements check is in progress. Doing
280  // another Check() before the previous one is complete will cause the first
281  // one to abort.
282  scoped_ptr<RequirementsChecker> requirements_checker_;
283
284  // The UI for showing what permissions the extension has.
285  scoped_ptr<ExtensionInstallPrompt> prompt_;
286
287  ScopedObserver<ExtensionWarningService, ExtensionWarningService::Observer>
288      warning_service_observer_;
289
290  // An observer to listen for when Extension errors are reported.
291  ScopedObserver<ErrorConsole, ErrorConsole::Observer> error_console_observer_;
292
293  // An observer to listen for notable changes in the ExtensionPrefs, like
294  // a change in Disable Reasons.
295  ScopedObserver<ExtensionPrefs, ExtensionPrefsObserver>
296      extension_prefs_observer_;
297
298  ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
299      extension_registry_observer_;
300
301  // Whether we found any DISABLE_NOT_VERIFIED extensions and want to kick off
302  // a verification check to try and rescue them.
303  bool should_do_verification_check_;
304
305  DISALLOW_COPY_AND_ASSIGN(ExtensionSettingsHandler);
306};
307
308}  // namespace extensions
309
310#endif  // CHROME_BROWSER_UI_WEBUI_EXTENSIONS_EXTENSION_SETTINGS_HANDLER_H_
311