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