[email protected] | 39ef0a7c5 | 2014-05-11 01:40:00 | [diff] [blame] | 1 | // Copyright 2014 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_ACTIVE_SCRIPT_CONTROLLER_H_ |
| 6 | #define CHROME_BROWSER_EXTENSIONS_ACTIVE_SCRIPT_CONTROLLER_H_ |
| 7 | |
| 8 | #include <map> |
| 9 | #include <set> |
| 10 | #include <string> |
[email protected] | ac02ac5 | 2014-05-20 01:11:26 | [diff] [blame] | 11 | #include <vector> |
[email protected] | 39ef0a7c5 | 2014-05-11 01:40:00 | [diff] [blame] | 12 | |
[email protected] | ac02ac5 | 2014-05-20 01:11:26 | [diff] [blame] | 13 | #include "base/callback.h" |
[email protected] | 39ef0a7c5 | 2014-05-11 01:40:00 | [diff] [blame] | 14 | #include "base/compiler_specific.h" |
| 15 | #include "base/memory/linked_ptr.h" |
| 16 | #include "chrome/browser/extensions/location_bar_controller.h" |
| 17 | #include "content/public/browser/web_contents_observer.h" |
[email protected] | 23a8536 | 2014-07-07 23:26:19 | [diff] [blame] | 18 | #include "extensions/common/permissions/permissions_data.h" |
| 19 | #include "extensions/common/user_script.h" |
[email protected] | 39ef0a7c5 | 2014-05-11 01:40:00 | [diff] [blame] | 20 | |
| 21 | namespace content { |
| 22 | class WebContents; |
| 23 | } |
| 24 | |
| 25 | namespace IPC { |
| 26 | class Message; |
| 27 | } |
| 28 | |
| 29 | class ExtensionAction; |
| 30 | |
| 31 | namespace extensions { |
| 32 | class Extension; |
| 33 | |
| 34 | // The provider for ExtensionActions corresponding to scripts which are actively |
| 35 | // running or need permission. |
| 36 | // TODO(rdevlin.cronin): This isn't really a controller, but it has good parity |
rdevlin.cronin | 5094223 | 2014-08-27 17:40:56 | [diff] [blame^] | 37 | // with LocationBar"Controller". |
| 38 | class ActiveScriptController : public content::WebContentsObserver { |
[email protected] | 39ef0a7c5 | 2014-05-11 01:40:00 | [diff] [blame] | 39 | public: |
| 40 | explicit ActiveScriptController(content::WebContents* web_contents); |
| 41 | virtual ~ActiveScriptController(); |
| 42 | |
[email protected] | eac223a | 2014-05-13 17:39:57 | [diff] [blame] | 43 | // Returns the ActiveScriptController for the given |web_contents|, or NULL |
| 44 | // if one does not exist. |
| 45 | static ActiveScriptController* GetForWebContents( |
| 46 | content::WebContents* web_contents); |
| 47 | |
[email protected] | 11814f5 | 2014-05-23 06:50:35 | [diff] [blame] | 48 | // Notifies the ActiveScriptController that an extension has been granted |
| 49 | // active tab permissions. This will run any pending injections for that |
| 50 | // extension. |
| 51 | void OnActiveTabPermissionGranted(const Extension* extension); |
| 52 | |
[email protected] | 39ef0a7c5 | 2014-05-11 01:40:00 | [diff] [blame] | 53 | // Notifies the ActiveScriptController of detected ad injection. |
[email protected] | 0d8d697 | 2014-06-03 22:41:02 | [diff] [blame] | 54 | void OnAdInjectionDetected(const std::set<std::string>& ad_injectors); |
[email protected] | 39ef0a7c5 | 2014-05-11 01:40:00 | [diff] [blame] | 55 | |
[email protected] | e167058 | 2014-08-15 23:05:41 | [diff] [blame] | 56 | // Adds the visible origin to |extension|'s active permissions, granting |
| 57 | // |extension| permission to always run script injections on the origin. |
| 58 | void AlwaysRunOnVisibleOrigin(const Extension* extension); |
| 59 | |
rdevlin.cronin | e9c7112 | 2014-08-25 23:47:21 | [diff] [blame] | 60 | // Notifies the ActiveScriptController that the action for |extension| has |
| 61 | // been clicked, running any pending tasks that were previously shelved. |
| 62 | void OnClicked(const Extension* extension); |
| 63 | |
[email protected] | e167058 | 2014-08-15 23:05:41 | [diff] [blame] | 64 | // Returns true if there is an active script injection action for |extension|. |
| 65 | bool HasActiveScriptAction(const Extension* extension); |
| 66 | |
rdevlin.cronin | 5094223 | 2014-08-27 17:40:56 | [diff] [blame^] | 67 | // Returns the action to display for the given |extension|, or NULL if no |
| 68 | // action should be displayed. |
| 69 | ExtensionAction* GetActionForExtension(const Extension* extension); |
| 70 | |
| 71 | // Notifies that the given |extension| has been unloaded; forwarded from the |
| 72 | // ExtensionRegistryObserver method. |
| 73 | void OnExtensionUnloaded(const Extension* extension); |
[email protected] | 39ef0a7c5 | 2014-05-11 01:40:00 | [diff] [blame] | 74 | |
[email protected] | 23a8536 | 2014-07-07 23:26:19 | [diff] [blame] | 75 | #if defined(UNIT_TEST) |
| 76 | // Only used in tests. |
| 77 | PermissionsData::AccessType RequiresUserConsentForScriptInjectionForTesting( |
| 78 | const Extension* extension, |
| 79 | UserScript::InjectionType type) { |
| 80 | return RequiresUserConsentForScriptInjection(extension, type); |
| 81 | } |
| 82 | void RequestScriptInjectionForTesting(const Extension* extension, |
| 83 | const base::Closure& callback) { |
| 84 | return RequestScriptInjection(extension, callback); |
| 85 | } |
| 86 | #endif // defined(UNIT_TEST) |
| 87 | |
[email protected] | 39ef0a7c5 | 2014-05-11 01:40:00 | [diff] [blame] | 88 | private: |
[email protected] | d205600 | 2014-07-03 06:18:06 | [diff] [blame] | 89 | typedef std::vector<base::Closure> PendingRequestList; |
[email protected] | ac02ac5 | 2014-05-20 01:11:26 | [diff] [blame] | 90 | typedef std::map<std::string, PendingRequestList> PendingRequestMap; |
| 91 | |
[email protected] | 23a8536 | 2014-07-07 23:26:19 | [diff] [blame] | 92 | // Returns true if the extension requesting script injection requires |
| 93 | // user consent. If this is true, the caller should then register a request |
| 94 | // via RequestScriptInjection(). |
| 95 | PermissionsData::AccessType RequiresUserConsentForScriptInjection( |
| 96 | const Extension* extension, |
| 97 | UserScript::InjectionType type); |
| 98 | |
| 99 | // |callback|. The only assumption that can be made about when (or if) |
| 100 | // |callback| is run is that, if it is run, it will run on the current page. |
| 101 | void RequestScriptInjection(const Extension* extension, |
| 102 | const base::Closure& callback); |
| 103 | |
[email protected] | 11814f5 | 2014-05-23 06:50:35 | [diff] [blame] | 104 | // Runs any pending injections for the corresponding extension. |
| 105 | void RunPendingForExtension(const Extension* extension); |
| 106 | |
[email protected] | ac2f8937 | 2014-06-23 21:44:25 | [diff] [blame] | 107 | // Handle the RequestScriptInjectionPermission message. |
[email protected] | 23a8536 | 2014-07-07 23:26:19 | [diff] [blame] | 108 | void OnRequestScriptInjectionPermission( |
| 109 | const std::string& extension_id, |
| 110 | UserScript::InjectionType script_type, |
| 111 | int64 request_id); |
[email protected] | 0d8d697 | 2014-06-03 22:41:02 | [diff] [blame] | 112 | |
| 113 | // Grants permission for the given request to run. |
[email protected] | d205600 | 2014-07-03 06:18:06 | [diff] [blame] | 114 | void PermitScriptInjection(int64 request_id); |
[email protected] | 39ef0a7c5 | 2014-05-11 01:40:00 | [diff] [blame] | 115 | |
[email protected] | ac02ac5 | 2014-05-20 01:11:26 | [diff] [blame] | 116 | // content::WebContentsObserver implementation. |
| 117 | virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; |
rdevlin.cronin | 5094223 | 2014-08-27 17:40:56 | [diff] [blame^] | 118 | virtual void DidNavigateMainFrame( |
| 119 | const content::LoadCommittedDetails& details, |
| 120 | const content::FrameNavigateParams& params) OVERRIDE; |
[email protected] | ac02ac5 | 2014-05-20 01:11:26 | [diff] [blame] | 121 | |
[email protected] | 39ef0a7c5 | 2014-05-11 01:40:00 | [diff] [blame] | 122 | // Log metrics. |
| 123 | void LogUMA() const; |
| 124 | |
| 125 | // Whether or not the ActiveScriptController is enabled (corresponding to the |
| 126 | // kActiveScriptEnforcement switch). If it is not, it acts as an empty shell, |
| 127 | // always allowing scripts to run and never displaying actions. |
| 128 | bool enabled_; |
| 129 | |
[email protected] | ac02ac5 | 2014-05-20 01:11:26 | [diff] [blame] | 130 | // The map of extension_id:pending_request of all pending requests. |
| 131 | PendingRequestMap pending_requests_; |
[email protected] | 39ef0a7c5 | 2014-05-11 01:40:00 | [diff] [blame] | 132 | |
[email protected] | ac02ac5 | 2014-05-20 01:11:26 | [diff] [blame] | 133 | // The extensions which have been granted permission to run on the given page. |
| 134 | // TODO(rdevlin.cronin): Right now, this just keeps track of extensions that |
| 135 | // have been permitted to run on the page via this interface. Instead, it |
| 136 | // should incorporate more fully with ActiveTab. |
| 137 | std::set<std::string> permitted_extensions_; |
[email protected] | 39ef0a7c5 | 2014-05-11 01:40:00 | [diff] [blame] | 138 | |
| 139 | // Script badges that have been generated for extensions. This is both those |
| 140 | // with actions already declared that are copied and normalised, and actions |
| 141 | // that get generated for extensions that haven't declared anything. |
| 142 | typedef std::map<std::string, linked_ptr<ExtensionAction> > ActiveScriptMap; |
| 143 | ActiveScriptMap active_script_actions_; |
| 144 | |
| 145 | DISALLOW_COPY_AND_ASSIGN(ActiveScriptController); |
| 146 | }; |
| 147 | |
| 148 | } // namespace extensions |
| 149 | |
| 150 | #endif // CHROME_BROWSER_EXTENSIONS_ACTIVE_SCRIPT_CONTROLLER_H_ |