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