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