• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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>
11 #include <vector>
12 
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"
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 class ExtensionRegistry;
34 
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 {
41  public:
42   explicit ActiveScriptController(content::WebContents* web_contents);
43   virtual ~ActiveScriptController();
44 
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);
49 
50   // Notifies the ActiveScriptController that an extension has been granted
51   // active tab permissions. This will run any pending injections for that
52   // extension.
53   void OnActiveTabPermissionGranted(const Extension* extension);
54 
55   // Notifies the ActiveScriptController of detected ad injection.
56   void OnAdInjectionDetected(const std::set<std::string>& ad_injectors);
57 
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);
61 
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);
65 
66   // Returns true if the given |extension| has a pending script that wants to
67   // run.
68   bool WantsToRun(const Extension* extension);
69 
70 #if defined(UNIT_TEST)
71   // Only used in tests.
RequiresUserConsentForScriptInjectionForTesting(const Extension * extension,UserScript::InjectionType type)72   PermissionsData::AccessType RequiresUserConsentForScriptInjectionForTesting(
73       const Extension* extension,
74       UserScript::InjectionType type) {
75     return RequiresUserConsentForScriptInjection(extension, type);
76   }
RequestScriptInjectionForTesting(const Extension * extension,const base::Closure & callback)77   void RequestScriptInjectionForTesting(const Extension* extension,
78                                         const base::Closure& callback) {
79     return RequestScriptInjection(extension, callback);
80   }
81 #endif  // defined(UNIT_TEST)
82 
83  private:
84   typedef std::vector<base::Closure> PendingRequestList;
85   typedef std::map<std::string, PendingRequestList> PendingRequestMap;
86 
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);
93 
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);
98 
99   // Runs any pending injections for the corresponding extension.
100   void RunPendingForExtension(const Extension* extension);
101 
102   // Handle the RequestScriptInjectionPermission message.
103   void OnRequestScriptInjectionPermission(
104       const std::string& extension_id,
105       UserScript::InjectionType script_type,
106       int64 request_id);
107 
108   // Grants permission for the given request to run.
109   void PermitScriptInjection(int64 request_id);
110 
111   // Log metrics.
112   void LogUMA() const;
113 
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;
119 
120   // ExtensionRegistryObserver:
121   virtual void OnExtensionUnloaded(
122       content::BrowserContext* browser_context,
123       const Extension* extension,
124       UnloadedExtensionInfo::Reason reason) OVERRIDE;
125 
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.
129   bool enabled_;
130 
131   // The map of extension_id:pending_request of all pending requests.
132   PendingRequestMap pending_requests_;
133 
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_;
139 
140   ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
141       extension_registry_observer_;
142 
143   DISALLOW_COPY_AND_ASSIGN(ActiveScriptController);
144 };
145 
146 }  // namespace extensions
147 
148 #endif  // CHROME_BROWSER_EXTENSIONS_ACTIVE_SCRIPT_CONTROLLER_H_
149