1 // Copyright (c) 2006-2009 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_AUTOMATION_AUTOMATION_RESOURCE_MESSAGE_FILTER_H_ 6 #define CHROME_BROWSER_AUTOMATION_AUTOMATION_RESOURCE_MESSAGE_FILTER_H_ 7 #pragma once 8 9 #include <map> 10 11 #include "base/atomicops.h" 12 #include "base/lazy_instance.h" 13 #include "ipc/ipc_channel_proxy.h" 14 #include "net/base/completion_callback.h" 15 #include "net/base/cookie_store.h" 16 17 class URLRequestAutomationJob; 18 class GURL; 19 20 namespace net { 21 class CookieStore; 22 } // namespace net 23 24 // This class filters out incoming automation IPC messages for network 25 // requests and processes them on the IPC thread. As a result, network 26 // requests are not delayed by costly UI processing that may be occurring 27 // on the main thread of the browser. It also means that any hangs in 28 // starting a network request will not interfere with browser UI. 29 class AutomationResourceMessageFilter 30 : public IPC::ChannelProxy::MessageFilter, 31 public IPC::Message::Sender { 32 public: 33 // Information needed to send IPCs through automation. 34 struct AutomationDetails { 35 AutomationDetails(); 36 AutomationDetails(int tab, AutomationResourceMessageFilter* flt, 37 bool pending_view); 38 ~AutomationDetails(); 39 40 void set_cookie_store(net::CookieStore* cookie_store) { 41 cookie_store_ = cookie_store; 42 } 43 44 net::CookieStore* cookie_store() { 45 return cookie_store_.get(); 46 } 47 48 int tab_handle; 49 int ref_count; 50 scoped_refptr<AutomationResourceMessageFilter> filter; 51 // Indicates whether network requests issued by this render view need to 52 // be executed later. 53 bool is_pending_render_view; 54 55 // The cookie store associated with this render view. 56 scoped_refptr<net::CookieStore> cookie_store_; 57 }; 58 59 // Create the filter. 60 AutomationResourceMessageFilter(); 61 virtual ~AutomationResourceMessageFilter(); 62 63 // Returns a new automation request id. This is unique across all instances 64 // of AutomationResourceMessageFilter. 65 int NewAutomationRequestId() { 66 return base::subtle::Barrier_AtomicIncrement(&unique_request_id_, 1); 67 } 68 69 // IPC::ChannelProxy::MessageFilter methods: 70 virtual void OnFilterAdded(IPC::Channel* channel); 71 virtual void OnFilterRemoved(); 72 73 virtual void OnChannelConnected(int32 peer_pid); 74 virtual void OnChannelClosing(); 75 virtual bool OnMessageReceived(const IPC::Message& message); 76 77 // ResourceDispatcherHost::Receiver methods: 78 virtual bool Send(IPC::Message* message); 79 80 // Add request to the list of outstanding requests. 81 virtual bool RegisterRequest(URLRequestAutomationJob* job); 82 83 // Remove request from the list of outstanding requests. 84 virtual void UnRegisterRequest(URLRequestAutomationJob* job); 85 86 // Can be called from the UI thread. 87 // The pending_view parameter should be true if network requests initiated by 88 // this render view need to be paused waiting for an acknowledgement from 89 // the external host. 90 static bool RegisterRenderView(int renderer_pid, int renderer_id, 91 int tab_handle, AutomationResourceMessageFilter* filter, 92 bool pending_view); 93 static void UnRegisterRenderView(int renderer_pid, int renderer_id); 94 95 // Can be called from the UI thread. 96 // Resumes pending render views, i.e. network requests issued by this view 97 // can now be serviced. 98 static bool ResumePendingRenderView(int renderer_pid, int renderer_id, 99 int tab_handle, AutomationResourceMessageFilter* filter); 100 101 // Called only on the IO thread. 102 static bool LookupRegisteredRenderView( 103 int renderer_pid, int renderer_id, AutomationDetails* details); 104 105 // Sends the download request to the automation host. 106 bool SendDownloadRequestToHost(int routing_id, int tab_handle, 107 int request_id); 108 109 // Retrieves cookies for the url passed in from the external host. The 110 // callback passed in is notified on success or failure asynchronously. 111 // Returns true on success. 112 static bool GetCookiesForUrl(const GURL& url, 113 net::CompletionCallback* callback); 114 115 // Sets cookies on the URL in the external host. Returns true on success. 116 static bool SetCookiesForUrl(const GURL& url, const std::string& cookie_line, 117 net::CompletionCallback* callback); 118 119 // This function gets invoked when we receive a response from the external 120 // host for the cookie request sent in GetCookiesForUrl above. It sets the 121 // cookie temporarily on the cookie store and executes the completion 122 // callback which reads the cookie from the store. The cookie value is reset 123 // after the callback finishes executing. 124 void OnGetCookiesHostResponse(int tab_handle, bool success, const GURL& url, 125 const std::string& cookies, int cookie_id); 126 127 protected: 128 // Retrieves the automation request id for the passed in chrome request 129 // id and returns it in the automation_request_id parameter. 130 // Returns true on success. 131 bool GetAutomationRequestId(int request_id, int* automation_request_id); 132 133 static void RegisterRenderViewInIOThread(int renderer_pid, int renderer_id, 134 int tab_handle, AutomationResourceMessageFilter* filter, 135 bool pending_view); 136 static void UnRegisterRenderViewInIOThread(int renderer_pid, int renderer_id); 137 138 static bool ResumePendingRenderViewInIOThread( 139 int renderer_pid, int renderer_id, int tab_handle, 140 AutomationResourceMessageFilter* filter); 141 142 // Helper function to execute the GetCookies completion callback with the 143 // response for the GetCookies request from the renderer. 144 static void OnGetCookiesHostResponseInternal( 145 int tab_handle, bool success, const GURL& url, 146 const std::string& cookies, net::CompletionCallback* callback, 147 net::CookieStore* cookie_store); 148 149 private: 150 void OnSetFilteredInet(bool enable); 151 void OnGetFilteredInetHitCount(int* hit_count); 152 void OnRecordHistograms(const std::vector<std::string>& histogram_list); 153 154 // Resumes pending jobs from the old AutomationResourceMessageFilter instance 155 // passed in. 156 static void ResumeJobsForPendingView( 157 int tab_handle, 158 AutomationResourceMessageFilter* old_filter, 159 AutomationResourceMessageFilter* new_filter); 160 161 static int GetNextCompletionCallbackId() { 162 return ++next_completion_callback_id_; 163 } 164 165 // A unique renderer id is a combination of renderer process id and 166 // it's routing id. 167 struct RendererId { 168 int pid_; 169 int id_; 170 171 RendererId() : pid_(0), id_(0) {} 172 RendererId(int pid, int id) : pid_(pid), id_(id) {} 173 174 bool operator < (const RendererId& rhs) const { 175 return ((pid_ == rhs.pid_) ? (id_ < rhs.id_) : (pid_ < rhs.pid_)); 176 } 177 }; 178 179 typedef std::map<RendererId, AutomationDetails> RenderViewMap; 180 typedef std::map<int, scoped_refptr<URLRequestAutomationJob> > RequestMap; 181 182 // The channel associated with the automation connection. This pointer is not 183 // owned by this class. 184 IPC::Channel* channel_; 185 186 // A unique request id per process. 187 static int unique_request_id_; 188 189 // Map of outstanding requests. 190 RequestMap request_map_; 191 192 // Map of pending requests, i.e. requests which were waiting for the external 193 // host to connect back. 194 RequestMap pending_request_map_; 195 196 // Map of render views interested in diverting url requests over automation. 197 static base::LazyInstance<RenderViewMap> filtered_render_views_; 198 199 // Contains information used for completing the request to read cookies from 200 // the host coming in from the renderer. 201 struct CookieCompletionInfo; 202 203 // Map of completion callback id to CookieCompletionInfo, which contains the 204 // actual callback which is invoked on successful retrieval of cookies from 205 // host. The mapping is setup when GetCookiesForUrl is invoked to retrieve 206 // cookies from the host and is removed when we receive a response from the 207 // host. Please see the OnGetCookiesHostResponse function. 208 typedef std::map<int, CookieCompletionInfo> CompletionCallbackMap; 209 static base::LazyInstance<CompletionCallbackMap> completion_callback_map_; 210 211 // Contains the id of the next completion callback. This is passed to the the 212 // external host as a cookie referring to the completion callback. 213 static int next_completion_callback_id_; 214 215 DISALLOW_COPY_AND_ASSIGN(AutomationResourceMessageFilter); 216 }; 217 218 #endif // CHROME_BROWSER_AUTOMATION_AUTOMATION_RESOURCE_MESSAGE_FILTER_H_ 219 220