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