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.
5 #ifndef CHROME_BROWSER_EXTENSIONS_ACTIVE_SCRIPT_CONTROLLER_H_
6 #define CHROME_BROWSER_EXTENSIONS_ACTIVE_SCRIPT_CONTROLLER_H_
13 #include "base/callback.h"
14 #include "base/compiler_specific.h"
15 #include "base/scoped_observer.h"
16 #include "content/public/browser/web_contents_observer.h"
17 #include "extensions/browser/extension_registry_observer.h"
18 #include "extensions/common/permissions/permissions_data.h"
19 #include "extensions/common/user_script.h"
29 class ExtensionAction;
31 namespace extensions {
33 class ExtensionRegistry;
35 // The provider for ExtensionActions corresponding to scripts which are actively
36 // running or need permission.
37 // TODO(rdevlin.cronin): This isn't really a controller, but it has good parity
38 // with LocationBar"Controller".
39 class ActiveScriptController : public content::WebContentsObserver,
40 public ExtensionRegistryObserver {
42 explicit ActiveScriptController(content::WebContents* web_contents);
43 virtual ~ActiveScriptController();
45 // Returns the ActiveScriptController for the given |web_contents|, or NULL
46 // if one does not exist.
47 static ActiveScriptController* GetForWebContents(
48 content::WebContents* web_contents);
50 // Notifies the ActiveScriptController that an extension has been granted
51 // active tab permissions. This will run any pending injections for that
53 void OnActiveTabPermissionGranted(const Extension* extension);
55 // Notifies the ActiveScriptController of detected ad injection.
56 void OnAdInjectionDetected(const std::set<std::string>& ad_injectors);
58 // Adds the visible origin to |extension|'s active permissions, granting
59 // |extension| permission to always run script injections on the origin.
60 void AlwaysRunOnVisibleOrigin(const Extension* extension);
62 // Notifies the ActiveScriptController that the action for |extension| has
63 // been clicked, running any pending tasks that were previously shelved.
64 void OnClicked(const Extension* extension);
66 // Returns true if the given |extension| has a pending script that wants to
68 bool WantsToRun(const Extension* extension);
70 #if defined(UNIT_TEST)
71 // Only used in tests.
72 PermissionsData::AccessType RequiresUserConsentForScriptInjectionForTesting(
73 const Extension* extension,
74 UserScript::InjectionType type) {
75 return RequiresUserConsentForScriptInjection(extension, type);
77 void RequestScriptInjectionForTesting(const Extension* extension,
78 const base::Closure& callback) {
79 return RequestScriptInjection(extension, callback);
81 #endif // defined(UNIT_TEST)
84 typedef std::vector<base::Closure> PendingRequestList;
85 typedef std::map<std::string, PendingRequestList> PendingRequestMap;
87 // Returns true if the extension requesting script injection requires
88 // user consent. If this is true, the caller should then register a request
89 // via RequestScriptInjection().
90 PermissionsData::AccessType RequiresUserConsentForScriptInjection(
91 const Extension* extension,
92 UserScript::InjectionType type);
94 // |callback|. The only assumption that can be made about when (or if)
95 // |callback| is run is that, if it is run, it will run on the current page.
96 void RequestScriptInjection(const Extension* extension,
97 const base::Closure& callback);
99 // Runs any pending injections for the corresponding extension.
100 void RunPendingForExtension(const Extension* extension);
102 // Handle the RequestScriptInjectionPermission message.
103 void OnRequestScriptInjectionPermission(
104 const std::string& extension_id,
105 UserScript::InjectionType script_type,
108 // Grants permission for the given request to run.
109 void PermitScriptInjection(int64 request_id);
114 // content::WebContentsObserver implementation.
115 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
116 virtual void DidNavigateMainFrame(
117 const content::LoadCommittedDetails& details,
118 const content::FrameNavigateParams& params) OVERRIDE;
120 // ExtensionRegistryObserver:
121 virtual void OnExtensionUnloaded(
122 content::BrowserContext* browser_context,
123 const Extension* extension,
124 UnloadedExtensionInfo::Reason reason) OVERRIDE;
126 // Whether or not the ActiveScriptController is enabled (corresponding to the
127 // kActiveScriptEnforcement switch). If it is not, it acts as an empty shell,
128 // always allowing scripts to run and never displaying actions.
131 // The map of extension_id:pending_request of all pending requests.
132 PendingRequestMap pending_requests_;
134 // The extensions which have been granted permission to run on the given page.
135 // TODO(rdevlin.cronin): Right now, this just keeps track of extensions that
136 // have been permitted to run on the page via this interface. Instead, it
137 // should incorporate more fully with ActiveTab.
138 std::set<std::string> permitted_extensions_;
140 ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
141 extension_registry_observer_;
143 DISALLOW_COPY_AND_ASSIGN(ActiveScriptController);
146 } // namespace extensions
148 #endif // CHROME_BROWSER_EXTENSIONS_ACTIVE_SCRIPT_CONTROLLER_H_