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