• 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/memory/linked_ptr.h"
16 #include "chrome/browser/extensions/location_bar_controller.h"
17 #include "content/public/browser/web_contents_observer.h"
18 
19 namespace content {
20 class WebContents;
21 }
22 
23 namespace IPC {
24 class Message;
25 }
26 
27 class ExtensionAction;
28 
29 namespace extensions {
30 class Extension;
31 
32 // The provider for ExtensionActions corresponding to scripts which are actively
33 // running or need permission.
34 // TODO(rdevlin.cronin): This isn't really a controller, but it has good parity
35 // with PageAction"Controller".
36 class ActiveScriptController : public LocationBarController::ActionProvider,
37                                public content::WebContentsObserver {
38  public:
39   explicit ActiveScriptController(content::WebContents* web_contents);
40   virtual ~ActiveScriptController();
41 
42   // Returns the ActiveScriptController for the given |web_contents|, or NULL
43   // if one does not exist.
44   static ActiveScriptController* GetForWebContents(
45       content::WebContents* web_contents);
46 
47   // Returns true if the extension requesting script injection requires
48   // user consent. If this is true, the caller should then register a request
49   // via RequestScriptInjection().
50   bool RequiresUserConsentForScriptInjection(const Extension* extension);
51 
52   // Register a request for a script injection, to be executed by running
53   // |callback|. The only assumption that can be made about when (or if)
54   // |callback| is run is that, if it is run, it will run on the current page.
55   void RequestScriptInjection(const Extension* extension,
56                               int page_id,
57                               const base::Closure& callback);
58 
59   // Notifies the ActiveScriptController that an extension has been granted
60   // active tab permissions. This will run any pending injections for that
61   // extension.
62   void OnActiveTabPermissionGranted(const Extension* extension);
63 
64   // Notifies the ActiveScriptController of detected ad injection.
65   void OnAdInjectionDetected(const std::set<std::string>& ad_injectors);
66 
67   // LocationBarControllerProvider implementation.
68   virtual ExtensionAction* GetActionForExtension(
69       const Extension* extension) OVERRIDE;
70   virtual LocationBarController::Action OnClicked(
71       const Extension* extension) OVERRIDE;
72   virtual void OnNavigated() OVERRIDE;
73   virtual void OnExtensionUnloaded(const Extension* extension) OVERRIDE;
74 
75  private:
76   // A single pending request. This could be a pair, but we'd have way too many
77   // stl typedefs, and "request.closure" is nicer than "request.first".
78   struct PendingRequest {
79     PendingRequest();  // For STL.
80     PendingRequest(const base::Closure& closure, int page_id);
81     ~PendingRequest();
82 
83     base::Closure closure;
84     int page_id;
85   };
86   typedef std::vector<PendingRequest> PendingRequestList;
87   typedef std::map<std::string, PendingRequestList> PendingRequestMap;
88 
89   // Runs any pending injections for the corresponding extension.
90   void RunPendingForExtension(const Extension* extension);
91 
92   // Handle the RequestContentScriptPermission message.
93   void OnRequestContentScriptPermission(const std::string& extension_id,
94                                         int page_id,
95                                         int request_id);
96 
97   // Grants permission for the given request to run.
98   void GrantContentScriptPermission(int request_id);
99 
100   // content::WebContentsObserver implementation.
101   virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
102 
103   // Log metrics.
104   void LogUMA() const;
105 
106   // Whether or not the ActiveScriptController is enabled (corresponding to the
107   // kActiveScriptEnforcement switch). If it is not, it acts as an empty shell,
108   // always allowing scripts to run and never displaying actions.
109   bool enabled_;
110 
111   // The map of extension_id:pending_request of all pending requests.
112   PendingRequestMap pending_requests_;
113 
114   // The extensions which have been granted permission to run on the given page.
115   // TODO(rdevlin.cronin): Right now, this just keeps track of extensions that
116   // have been permitted to run on the page via this interface. Instead, it
117   // should incorporate more fully with ActiveTab.
118   std::set<std::string> permitted_extensions_;
119 
120   // Script badges that have been generated for extensions. This is both those
121   // with actions already declared that are copied and normalised, and actions
122   // that get generated for extensions that haven't declared anything.
123   typedef std::map<std::string, linked_ptr<ExtensionAction> > ActiveScriptMap;
124   ActiveScriptMap active_script_actions_;
125 
126   DISALLOW_COPY_AND_ASSIGN(ActiveScriptController);
127 };
128 
129 }  // namespace extensions
130 
131 #endif  // CHROME_BROWSER_EXTENSIONS_ACTIVE_SCRIPT_CONTROLLER_H_
132