1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// found in the LICENSE file. 4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#ifndef CHROME_BROWSER_EXTENSIONS_ACTIVE_SCRIPT_CONTROLLER_H_ 6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#define CHROME_BROWSER_EXTENSIONS_ACTIVE_SCRIPT_CONTROLLER_H_ 7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <map> 9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <set> 10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <string> 11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <vector> 12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/callback.h" 14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/compiler_specific.h" 151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/scoped_observer.h" 16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/browser/web_contents_observer.h" 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/extension_registry_observer.h" 18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "extensions/common/permissions/permissions_data.h" 19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "extensions/common/user_script.h" 20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace content { 22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class WebContents; 23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace IPC { 26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class Message; 27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class ExtensionAction; 30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace extensions { 32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class Extension; 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass ExtensionRegistry; 34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// The provider for ExtensionActions corresponding to scripts which are actively 36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// running or need permission. 37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// TODO(rdevlin.cronin): This isn't really a controller, but it has good parity 381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// with LocationBar"Controller". 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass ActiveScriptController : public content::WebContentsObserver, 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public ExtensionRegistryObserver { 41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public: 42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) explicit ActiveScriptController(content::WebContents* web_contents); 43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual ~ActiveScriptController(); 44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Returns the ActiveScriptController for the given |web_contents|, or NULL 46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // if one does not exist. 47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) static ActiveScriptController* GetForWebContents( 48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) content::WebContents* web_contents); 49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Notifies the ActiveScriptController that an extension has been granted 51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // active tab permissions. This will run any pending injections for that 52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // extension. 53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void OnActiveTabPermissionGranted(const Extension* extension); 54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Notifies the ActiveScriptController of detected ad injection. 56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void OnAdInjectionDetected(const std::set<std::string>& ad_injectors); 57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Adds the visible origin to |extension|'s active permissions, granting 596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // |extension| permission to always run script injections on the origin. 606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) void AlwaysRunOnVisibleOrigin(const Extension* extension); 616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Notifies the ActiveScriptController that the action for |extension| has 631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // been clicked, running any pending tasks that were previously shelved. 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void OnClicked(const Extension* extension); 656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Returns true if the given |extension| has a pending script that wants to 671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // run. 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool WantsToRun(const Extension* extension); 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(UNIT_TEST) 71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Only used in tests. 72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PermissionsData::AccessType RequiresUserConsentForScriptInjectionForTesting( 73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const Extension* extension, 74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch UserScript::InjectionType type) { 75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return RequiresUserConsentForScriptInjection(extension, type); 76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void RequestScriptInjectionForTesting(const Extension* extension, 78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const base::Closure& callback) { 79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return RequestScriptInjection(extension, callback); 80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif // defined(UNIT_TEST) 82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private: 84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch typedef std::vector<base::Closure> PendingRequestList; 85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) typedef std::map<std::string, PendingRequestList> PendingRequestMap; 86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Returns true if the extension requesting script injection requires 88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // user consent. If this is true, the caller should then register a request 89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // via RequestScriptInjection(). 90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PermissionsData::AccessType RequiresUserConsentForScriptInjection( 91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const Extension* extension, 92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch UserScript::InjectionType type); 93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // |callback|. The only assumption that can be made about when (or if) 95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // |callback| is run is that, if it is run, it will run on the current page. 96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void RequestScriptInjection(const Extension* extension, 97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const base::Closure& callback); 98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Runs any pending injections for the corresponding extension. 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void RunPendingForExtension(const Extension* extension); 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Handle the RequestScriptInjectionPermission message. 103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void OnRequestScriptInjectionPermission( 104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::string& extension_id, 105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch UserScript::InjectionType script_type, 106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int64 request_id); 107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Grants permission for the given request to run. 109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void PermitScriptInjection(int64 request_id); 110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Log metrics. 1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void LogUMA() const; 1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // content::WebContentsObserver implementation. 115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; 1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void DidNavigateMainFrame( 1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const content::LoadCommittedDetails& details, 1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const content::FrameNavigateParams& params) OVERRIDE; 119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // ExtensionRegistryObserver: 1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void OnExtensionUnloaded( 1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci content::BrowserContext* browser_context, 1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const Extension* extension, 1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci UnloadedExtensionInfo::Reason reason) OVERRIDE; 125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Whether or not the ActiveScriptController is enabled (corresponding to the 127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // kActiveScriptEnforcement switch). If it is not, it acts as an empty shell, 128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // always allowing scripts to run and never displaying actions. 129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool enabled_; 130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // The map of extension_id:pending_request of all pending requests. 132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PendingRequestMap pending_requests_; 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // The extensions which have been granted permission to run on the given page. 135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // TODO(rdevlin.cronin): Right now, this just keeps track of extensions that 136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // have been permitted to run on the page via this interface. Instead, it 137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // should incorporate more fully with ActiveTab. 138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::set<std::string> permitted_extensions_; 139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> 1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci extension_registry_observer_; 142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ActiveScriptController); 144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} // namespace extensions 147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif // CHROME_BROWSER_EXTENSIONS_ACTIVE_SCRIPT_CONTROLLER_H_ 149