blob: fb184c409870b42b05b5cab000783749a00b6420 [file] [log] [blame]
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_AUTOMATION_AUTOMATION_RESOURCE_MESSAGE_FILTER_H_
#define CHROME_BROWSER_AUTOMATION_AUTOMATION_RESOURCE_MESSAGE_FILTER_H_
#pragma once
#include <map>
#include <string>
#include <vector>
#include "base/atomicops.h"
#include "base/lazy_instance.h"
#include "ipc/ipc_channel_proxy.h"
#include "net/base/completion_callback.h"
class GURL;
class BrowserMessageFilter;
class URLRequestAutomationJob;
namespace net {
class URLRequestContext;
} // namespace net
// This class filters out incoming automation IPC messages for network
// requests and processes them on the IPC thread. As a result, network
// requests are not delayed by costly UI processing that may be occurring
// on the main thread of the browser. It also means that any hangs in
// starting a network request will not interfere with browser UI.
class AutomationResourceMessageFilter
: public IPC::ChannelProxy::MessageFilter,
public IPC::Message::Sender {
public:
// Information needed to send IPCs through automation.
struct AutomationDetails {
AutomationDetails();
AutomationDetails(int tab, AutomationResourceMessageFilter* flt,
bool pending_view);
~AutomationDetails();
int tab_handle;
int ref_count;
scoped_refptr<AutomationResourceMessageFilter> filter;
// Indicates whether network requests issued by this render view need to
// be executed later.
bool is_pending_render_view;
};
// Create the filter.
AutomationResourceMessageFilter();
virtual ~AutomationResourceMessageFilter();
// Returns a new automation request id. This is unique across all instances
// of AutomationResourceMessageFilter.
int NewAutomationRequestId() {
return base::subtle::Barrier_AtomicIncrement(&unique_request_id_, 1);
}
// IPC::ChannelProxy::MessageFilter methods:
virtual void OnFilterAdded(IPC::Channel* channel);
virtual void OnFilterRemoved();
virtual void OnChannelConnected(int32 peer_pid);
virtual void OnChannelClosing();
virtual bool OnMessageReceived(const IPC::Message& message);
// ResourceDispatcherHost::Receiver methods:
virtual bool Send(IPC::Message* message);
// Add request to the list of outstanding requests.
virtual bool RegisterRequest(URLRequestAutomationJob* job);
// Remove request from the list of outstanding requests.
virtual void UnRegisterRequest(URLRequestAutomationJob* job);
// Can be called from the UI thread.
// The pending_view parameter should be true if network requests initiated by
// this render view need to be paused waiting for an acknowledgement from
// the external host.
static bool RegisterRenderView(int renderer_pid,
int renderer_id,
int tab_handle,
AutomationResourceMessageFilter* filter,
bool pending_view);
static void UnRegisterRenderView(int renderer_pid, int renderer_id);
// Can be called from the UI thread.
// Resumes pending render views, i.e. network requests issued by this view
// can now be serviced.
static bool ResumePendingRenderView(int renderer_pid,
int renderer_id,
int tab_handle,
AutomationResourceMessageFilter* filter);
// Called only on the IO thread.
static bool LookupRegisteredRenderView(
int renderer_pid, int renderer_id, AutomationDetails* details);
// Sends the download request to the automation host.
bool SendDownloadRequestToHost(int routing_id, int tab_handle,
int request_id);
// If this returns true, then the get and set cookie IPCs should be sent to
// the following two functions.
static bool ShouldFilterCookieMessages(int render_process_id,
int render_view_id);
// Retrieves cookies for the url passed in from the external host. The
// callback passed in is notified on success or failure asynchronously.
static void GetCookiesForUrl(BrowserMessageFilter* filter,
net::URLRequestContext* context,
int render_process_id,
IPC::Message* reply_msg,
const GURL& url);
// Sets cookies on the URL in the external host.
static void SetCookiesForUrl(int render_process_id,
int render_view_id,
const GURL& url,
const std::string& cookie_line);
// This function gets invoked when we receive a response from the external
// host for the cookie request sent in GetCookiesForUrl above. It sets the
// cookie temporarily on the cookie store and executes the completion
// callback which reads the cookie from the store. The cookie value is reset
// after the callback finishes executing.
void OnGetCookiesHostResponse(int tab_handle, bool success, const GURL& url,
const std::string& cookies, int cookie_id);
protected:
// Retrieves the automation request id for the passed in chrome request
// id and returns it in the automation_request_id parameter.
// Returns true on success.
bool GetAutomationRequestId(int request_id, int* automation_request_id);
static void RegisterRenderViewInIOThread(int renderer_pid, int renderer_id,
int tab_handle, AutomationResourceMessageFilter* filter,
bool pending_view);
static void UnRegisterRenderViewInIOThread(int renderer_pid, int renderer_id);
static bool ResumePendingRenderViewInIOThread(
int renderer_pid, int renderer_id, int tab_handle,
AutomationResourceMessageFilter* filter);
private:
void OnSetFilteredInet(bool enable);
void OnGetFilteredInetHitCount(int* hit_count);
void OnRecordHistograms(const std::vector<std::string>& histogram_list);
// Resumes pending jobs from the old AutomationResourceMessageFilter instance
// passed in.
static void ResumeJobsForPendingView(
int tab_handle,
AutomationResourceMessageFilter* old_filter,
AutomationResourceMessageFilter* new_filter);
static int GetNextCompletionCallbackId() {
return ++next_completion_callback_id_;
}
// A unique renderer id is a combination of renderer process id and
// it's routing id.
struct RendererId {
int pid_;
int id_;
RendererId() : pid_(0), id_(0) {}
RendererId(int pid, int id) : pid_(pid), id_(id) {}
bool operator < (const RendererId& rhs) const {
return ((pid_ == rhs.pid_) ? (id_ < rhs.id_) : (pid_ < rhs.pid_));
}
};
typedef std::map<RendererId, AutomationDetails> RenderViewMap;
typedef std::map<int, URLRequestAutomationJob*> RequestMap;
// The channel associated with the automation connection. This pointer is not
// owned by this class.
IPC::Channel* channel_;
// A unique request id per process.
static int unique_request_id_;
// Map of outstanding requests.
RequestMap request_map_;
// Map of pending requests, i.e. requests which were waiting for the external
// host to connect back.
RequestMap pending_request_map_;
// Map of render views interested in diverting url requests over automation.
static base::LazyInstance<RenderViewMap> filtered_render_views_;
// Contains information used for completing the request to read cookies from
// the host coming in from the renderer.
struct CookieCompletionInfo;
// Map of completion callback id to CookieCompletionInfo, which contains the
// actual callback which is invoked on successful retrieval of cookies from
// host. The mapping is setup when GetCookiesForUrl is invoked to retrieve
// cookies from the host and is removed when we receive a response from the
// host. Please see the OnGetCookiesHostResponse function.
typedef std::map<int, CookieCompletionInfo> CompletionCallbackMap;
static base::LazyInstance<CompletionCallbackMap> completion_callback_map_;
// Contains the id of the next completion callback. This is passed to the the
// external host as a cookie referring to the completion callback.
static int next_completion_callback_id_;
DISALLOW_COPY_AND_ASSIGN(AutomationResourceMessageFilter);
};
#endif // CHROME_BROWSER_AUTOMATION_AUTOMATION_RESOURCE_MESSAGE_FILTER_H_