blob: c3fee9dd67a809b5065bf31e8554a0eb6412ef64 [file] [log] [blame]
[email protected]39ef0a7c52014-05-11 01:40:001// 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]ac02ac52014-05-20 01:11:2611#include <vector>
[email protected]39ef0a7c52014-05-11 01:40:0012
[email protected]ac02ac52014-05-20 01:11:2613#include "base/callback.h"
[email protected]39ef0a7c52014-05-11 01:40:0014#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]23a85362014-07-07 23:26:1918#include "extensions/common/permissions/permissions_data.h"
19#include "extensions/common/user_script.h"
[email protected]39ef0a7c52014-05-11 01:40:0020
21namespace content {
22class WebContents;
23}
24
25namespace IPC {
26class Message;
27}
28
29class ExtensionAction;
30
31namespace extensions {
32class 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.cronin50942232014-08-27 17:40:5637// with LocationBar"Controller".
38class ActiveScriptController : public content::WebContentsObserver {
[email protected]39ef0a7c52014-05-11 01:40:0039 public:
40 explicit ActiveScriptController(content::WebContents* web_contents);
41 virtual ~ActiveScriptController();
42
[email protected]eac223a2014-05-13 17:39:5743 // 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]11814f52014-05-23 06:50:3548 // 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]39ef0a7c52014-05-11 01:40:0053 // Notifies the ActiveScriptController of detected ad injection.
[email protected]0d8d6972014-06-03 22:41:0254 void OnAdInjectionDetected(const std::set<std::string>& ad_injectors);
[email protected]39ef0a7c52014-05-11 01:40:0055
[email protected]e1670582014-08-15 23:05:4156 // 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.cronine9c71122014-08-25 23:47:2160 // 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]e1670582014-08-15 23:05:4164 // Returns true if there is an active script injection action for |extension|.
65 bool HasActiveScriptAction(const Extension* extension);
66
rdevlin.cronin50942232014-08-27 17:40:5667 // 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]39ef0a7c52014-05-11 01:40:0074
[email protected]23a85362014-07-07 23:26:1975#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]39ef0a7c52014-05-11 01:40:0088 private:
[email protected]d2056002014-07-03 06:18:0689 typedef std::vector<base::Closure> PendingRequestList;
[email protected]ac02ac52014-05-20 01:11:2690 typedef std::map<std::string, PendingRequestList> PendingRequestMap;
91
[email protected]23a85362014-07-07 23:26:1992 // 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]11814f52014-05-23 06:50:35104 // Runs any pending injections for the corresponding extension.
105 void RunPendingForExtension(const Extension* extension);
106
[email protected]ac2f89372014-06-23 21:44:25107 // Handle the RequestScriptInjectionPermission message.
[email protected]23a85362014-07-07 23:26:19108 void OnRequestScriptInjectionPermission(
109 const std::string& extension_id,
110 UserScript::InjectionType script_type,
111 int64 request_id);
[email protected]0d8d6972014-06-03 22:41:02112
113 // Grants permission for the given request to run.
[email protected]d2056002014-07-03 06:18:06114 void PermitScriptInjection(int64 request_id);
[email protected]39ef0a7c52014-05-11 01:40:00115
[email protected]ac02ac52014-05-20 01:11:26116 // content::WebContentsObserver implementation.
117 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
rdevlin.cronin50942232014-08-27 17:40:56118 virtual void DidNavigateMainFrame(
119 const content::LoadCommittedDetails& details,
120 const content::FrameNavigateParams& params) OVERRIDE;
[email protected]ac02ac52014-05-20 01:11:26121
[email protected]39ef0a7c52014-05-11 01:40:00122 // 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]ac02ac52014-05-20 01:11:26130 // The map of extension_id:pending_request of all pending requests.
131 PendingRequestMap pending_requests_;
[email protected]39ef0a7c52014-05-11 01:40:00132
[email protected]ac02ac52014-05-20 01:11:26133 // 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]39ef0a7c52014-05-11 01:40:00138
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_