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 EXTENSIONS_BROWSER_EXTENSION_FUNCTION_DISPATCHER_H_ 6 #define EXTENSIONS_BROWSER_EXTENSION_FUNCTION_DISPATCHER_H_ 7 8 #include <map> 9 #include <string> 10 #include <vector> 11 12 #include "base/memory/weak_ptr.h" 13 #include "extensions/browser/extension_function.h" 14 #include "ipc/ipc_sender.h" 15 16 struct ExtensionHostMsg_Request_Params; 17 18 namespace content { 19 class BrowserContext; 20 class RenderFrameHost; 21 class RenderViewHost; 22 class WebContents; 23 } 24 25 namespace extensions { 26 27 class Extension; 28 class ExtensionAPI; 29 class ExtensionMessageFilter; 30 class InfoMap; 31 class ProcessMap; 32 class WindowController; 33 34 // A factory function for creating new ExtensionFunction instances. 35 typedef ExtensionFunction* (*ExtensionFunctionFactory)(); 36 37 // ExtensionFunctionDispatcher receives requests to execute functions from 38 // Chrome extensions running in a RenderViewHost and dispatches them to the 39 // appropriate handler. It lives entirely on the UI thread. 40 // 41 // ExtensionFunctionDispatcher should be a member of some class that hosts 42 // RenderViewHosts and wants them to be able to display extension content. 43 // This class should also implement ExtensionFunctionDispatcher::Delegate. 44 // 45 // Note that a single ExtensionFunctionDispatcher does *not* correspond to a 46 // single RVH, a single extension, or a single URL. This is by design so that 47 // we can gracefully handle cases like WebContents, where the RVH, extension, 48 // and URL can all change over the lifetime of the tab. Instead, these items 49 // are all passed into each request. 50 class ExtensionFunctionDispatcher 51 : public base::SupportsWeakPtr<ExtensionFunctionDispatcher> { 52 public: 53 class Delegate { 54 public: 55 // Returns the WindowController associated with this delegate, or NULL if no 56 // window is associated with the delegate. 57 virtual WindowController* GetExtensionWindowController() const; 58 59 // Asks the delegate for any relevant WebContents associated with this 60 // context. For example, the WebContents in which an infobar or 61 // chrome-extension://<id> URL are being shown. Callers must check for a 62 // NULL return value (as in the case of a background page). 63 virtual content::WebContents* GetAssociatedWebContents() const; 64 65 // If the associated web contents is not null, returns that. Otherwise, 66 // returns the next most relevant visible web contents. Callers must check 67 // for a NULL return value (as in the case of a background page). 68 virtual content::WebContents* GetVisibleWebContents() const; 69 70 protected: ~Delegate()71 virtual ~Delegate() {} 72 }; 73 74 // Gets a list of all known extension function names. 75 static void GetAllFunctionNames(std::vector<std::string>* names); 76 77 // Override a previously registered function. Returns true if successful, 78 // false if no such function was registered. 79 static bool OverrideFunction(const std::string& name, 80 ExtensionFunctionFactory factory); 81 82 // Dispatches an IO-thread extension function. Only used for specific 83 // functions that must be handled on the IO-thread. 84 static void DispatchOnIOThread( 85 InfoMap* extension_info_map, 86 void* profile_id, 87 int render_process_id, 88 base::WeakPtr<ExtensionMessageFilter> ipc_sender, 89 int routing_id, 90 const ExtensionHostMsg_Request_Params& params); 91 92 // Public constructor. Callers must ensure that: 93 // - |delegate| outlives this object. 94 // - This object outlives any RenderViewHost's passed to created 95 // ExtensionFunctions. 96 ExtensionFunctionDispatcher(content::BrowserContext* browser_context, 97 Delegate* delegate); 98 99 ~ExtensionFunctionDispatcher(); 100 delegate()101 Delegate* delegate() { return delegate_; } 102 103 // Message handlers. 104 // The response is sent to the corresponding render view in an 105 // ExtensionMsg_Response message. 106 // TODO (jam): convert all callers to use RenderFrameHost. 107 void Dispatch(const ExtensionHostMsg_Request_Params& params, 108 content::RenderViewHost* render_view_host); 109 // Dispatch an extension function and calls |callback| when the execution 110 // completes. 111 void DispatchWithCallback( 112 const ExtensionHostMsg_Request_Params& params, 113 content::RenderFrameHost* render_frame_host, 114 const ExtensionFunction::ResponseCallback& callback); 115 116 // Called when an ExtensionFunction is done executing, after it has sent 117 // a response (if any) to the extension. 118 void OnExtensionFunctionCompleted(const Extension* extension); 119 120 // The BrowserContext that this dispatcher is associated with. browser_context()121 content::BrowserContext* browser_context() { return browser_context_; } 122 123 private: 124 // For a given RenderViewHost instance, UIThreadResponseCallbackWrapper 125 // creates ExtensionFunction::ResponseCallback instances which send responses 126 // to the corresponding render view in ExtensionMsg_Response messages. 127 // This class tracks the lifespan of the RenderViewHost instance, and will be 128 // destroyed automatically when it goes away. 129 class UIThreadResponseCallbackWrapper; 130 131 // Helper to check whether an ExtensionFunction has the required permissions. 132 // This should be called after the function is fully initialized. 133 // If the check fails, |callback| is run with an access-denied error and false 134 // is returned. |function| must not be run in that case. 135 static bool CheckPermissions( 136 ExtensionFunction* function, 137 const Extension* extension, 138 const ExtensionHostMsg_Request_Params& params, 139 const ExtensionFunction::ResponseCallback& callback); 140 141 // Helper to create an ExtensionFunction to handle the function given by 142 // |params|. Can be called on any thread. 143 // Does not set subclass properties, or include_incognito. 144 static ExtensionFunction* CreateExtensionFunction( 145 const ExtensionHostMsg_Request_Params& params, 146 const Extension* extension, 147 int requesting_process_id, 148 const ProcessMap& process_map, 149 ExtensionAPI* api, 150 void* profile_id, 151 const ExtensionFunction::ResponseCallback& callback); 152 153 // Helper to run the response callback with an access denied error. Can be 154 // called on any thread. 155 static void SendAccessDenied( 156 const ExtensionFunction::ResponseCallback& callback); 157 158 void DispatchWithCallbackInternal( 159 const ExtensionHostMsg_Request_Params& params, 160 content::RenderViewHost* render_view_host, 161 content::RenderFrameHost* render_frame_host, 162 const ExtensionFunction::ResponseCallback& callback); 163 164 content::BrowserContext* browser_context_; 165 166 Delegate* delegate_; 167 168 // This map doesn't own either the keys or the values. When a RenderViewHost 169 // instance goes away, the corresponding entry in this map (if exists) will be 170 // removed. 171 typedef std::map<content::RenderViewHost*, UIThreadResponseCallbackWrapper*> 172 UIThreadResponseCallbackWrapperMap; 173 UIThreadResponseCallbackWrapperMap ui_thread_response_callback_wrappers_; 174 }; 175 176 } // namespace extensions 177 178 #endif // EXTENSIONS_BROWSER_EXTENSION_FUNCTION_DISPATCHER_H_ 179