Home | History | Annotate | Download | only in automation
      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 
     40     void set_cookie_store(net::CookieStore* cookie_store) {
     41       cookie_store_ = cookie_store;
     42     }
     43 
     44     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.
     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 
    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 
    171     RendererId() : pid_(0), id_(0) {}
    172     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