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 31 class ExtensionService; 32 33 namespace base { 34 class DictionaryValue; 35 class FilePath; 36 class ListValue; 37 } 38 39 namespace content { 40 class WebUIDataSource; 41 } 42 43 namespace user_prefs { 44 class PrefRegistrySyncable; 45 } 46 47 namespace extensions { 48 class Extension; 49 class ExtensionRegistry; 50 class ManagementPolicy; 51 52 // Information about a page running in an extension, for example a popup bubble, 53 // a background page, or a tab contents. 54 struct 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. 68 class 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 // Utility for calling JavaScript window.alert in the page. 199 void ShowAlert(const std::string& message); 200 201 // Utility for callbacks that get an extension ID as the sole argument. 202 // Returns NULL if the extension isn't active. 203 const Extension* GetActiveExtension(const base::ListValue* args); 204 205 // Forces a UI update if appropriate after a notification is received. 206 void MaybeUpdateAfterNotification(); 207 208 // Register for notifications that we need to reload the page. 209 void MaybeRegisterForNotifications(); 210 211 // Helper that lists the current inspectable html pages for an extension. 212 std::vector<ExtensionPage> GetInspectablePagesForExtension( 213 const Extension* extension, bool extension_is_enabled); 214 void GetInspectablePagesForExtensionProcess( 215 const Extension* extension, 216 const std::set<content::RenderViewHost*>& views, 217 std::vector<ExtensionPage>* result); 218 void GetAppWindowPagesForExtensionProfile(const Extension* extension, 219 Profile* profile, 220 std::vector<ExtensionPage>* result); 221 222 // Returns the ExtensionUninstallDialog object for this class, creating it if 223 // needed. 224 ExtensionUninstallDialog* GetExtensionUninstallDialog(); 225 226 // Callback for RequirementsChecker. 227 void OnRequirementsChecked(std::string extension_id, 228 std::vector<std::string> requirement_errors); 229 230 // Handles the load retry notification sent from 231 // ExtensionService::ReportExtensionLoadError. Attempts to retry loading 232 // extension from |path| if retry is true, otherwise removes |path| from the 233 // vector of currently loading extensions. 234 // 235 // Does nothing if |path| is not a currently loading extension this object is 236 // tracking. 237 void HandleLoadRetryMessage(bool retry, const base::FilePath& path); 238 239 // Our model. Outlives us since it's owned by our containing profile. 240 ExtensionService* extension_service_; 241 242 // A convenience member, filled once the extension_service_ is known. 243 ManagementPolicy* management_policy_; 244 245 // Used to show confirmation UI for uninstalling extensions in incognito mode. 246 scoped_ptr<ExtensionUninstallDialog> extension_uninstall_dialog_; 247 248 // The id of the extension we are prompting the user about. 249 std::string extension_id_prompting_; 250 251 // If true, we will ignore notifications in ::Observe(). This is needed 252 // to prevent reloading the page when we were the cause of the 253 // notification. 254 bool ignore_notifications_; 255 256 // The page may be refreshed in response to a RenderViewHost being destroyed, 257 // but the iteration over RenderViewHosts will include the host because the 258 // notification is sent when it is in the process of being deleted (and before 259 // it is removed from the process). Keep a pointer to it so we can exclude 260 // it from the active views. 261 content::RenderViewHost* deleting_rvh_; 262 // Do the same for a deleting RenderWidgetHost ID and RenderProcessHost ID. 263 int deleting_rwh_id_; 264 int deleting_rph_id_; 265 266 // We want to register for notifications only after we've responded at least 267 // once to the page, otherwise we'd be calling JavaScript functions on objects 268 // that don't exist yet when notifications come in. This variable makes sure 269 // we do so only once. 270 bool registered_for_notifications_; 271 272 content::NotificationRegistrar registrar_; 273 274 PrefChangeRegistrar pref_registrar_; 275 276 // This will not be empty when a requirements check is in progress. Doing 277 // another Check() before the previous one is complete will cause the first 278 // one to abort. 279 scoped_ptr<RequirementsChecker> requirements_checker_; 280 281 // The UI for showing what permissions the extension has. 282 scoped_ptr<ExtensionInstallPrompt> prompt_; 283 284 ScopedObserver<ExtensionWarningService, ExtensionWarningService::Observer> 285 warning_service_observer_; 286 287 // An observer to listen for when Extension errors are reported. 288 ScopedObserver<ErrorConsole, ErrorConsole::Observer> error_console_observer_; 289 290 // An observer to listen for notable changes in the ExtensionPrefs, like 291 // a change in Disable Reasons. 292 ScopedObserver<ExtensionPrefs, ExtensionPrefsObserver> 293 extension_prefs_observer_; 294 295 ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> 296 extension_registry_observer_; 297 298 // Whether we found any DISABLE_NOT_VERIFIED extensions and want to kick off 299 // a verification check to try and rescue them. 300 bool should_do_verification_check_; 301 302 DISALLOW_COPY_AND_ASSIGN(ExtensionSettingsHandler); 303 }; 304 305 } // namespace extensions 306 307 #endif // CHROME_BROWSER_UI_WEBUI_EXTENSIONS_EXTENSION_SETTINGS_HANDLER_H_ 308