• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
set_cookie_storeAutomationDetails40     void set_cookie_store(net::CookieStore* cookie_store) {
41       cookie_store_ = cookie_store;
42     }
43 
cookie_storeAutomationDetails44     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.
NewAutomationRequestId()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 
GetNextCompletionCallbackId()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 
RendererIdRendererId171     RendererId() : pid_(0), id_(0) {}
RendererIdRendererId172     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