• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 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 #include "chrome_frame/test/net/test_automation_provider.h"
6 
7 #include "base/command_line.h"
8 #include "base/file_version_info.h"
9 #include "base/path_service.h"
10 #include "chrome/common/automation_messages.h"
11 #include "chrome_frame/test/net/test_automation_resource_message_filter.h"
12 #include "net/url_request/url_request_context.h"
13 
14 namespace {
15 
16 // A special command line switch to just run the unit tests without CF in
17 // the picture.  Can be useful when the harness itself needs to be debugged.
18 const char kNoCfTestRun[] = "no-cf-test-run";
19 
CFTestsDisabled()20 bool CFTestsDisabled() {
21   static bool switch_present = CommandLine::ForCurrentProcess()->
22       HasSwitch(kNoCfTestRun);
23   return switch_present;
24 }
25 
26 }  // end namespace
27 
28 TestAutomationProvider* TestAutomationProvider::g_provider_instance_ = NULL;
29 
TestAutomationProvider(Profile * profile,TestAutomationProviderDelegate * delegate)30 TestAutomationProvider::TestAutomationProvider(
31     Profile* profile,
32     TestAutomationProviderDelegate* delegate)
33     : AutomationProvider(profile), tab_handle_(-1), delegate_(delegate) {
34   // We need to register the protocol factory before the
35   // AutomationResourceMessageFilter registers the automation job factory to
36   // ensure that we don't inadvarently end up handling http requests which
37   // we don't expect. The initial chrome frame page for the network tests
38   // issues http requests which our test factory should not handle.
39   net::URLRequest::Deprecated::RegisterProtocolFactory(
40       "http", TestAutomationProvider::Factory);
41   net::URLRequest::Deprecated::RegisterProtocolFactory(
42       "https", TestAutomationProvider::Factory);
43   automation_resource_message_filter_ =
44       new TestAutomationResourceMessageFilter(this);
45   g_provider_instance_ = this;
46 }
47 
~TestAutomationProvider()48 TestAutomationProvider::~TestAutomationProvider() {
49   delegate_->OnProviderDestroyed();
50   g_provider_instance_ = NULL;
51 }
52 
OnMessageReceived(const IPC::Message & msg)53 bool TestAutomationProvider::OnMessageReceived(const IPC::Message& msg) {
54   if (automation_resource_message_filter_->OnMessageReceived(msg))
55     return true;  // Message handled by the filter.
56 
57   return __super::OnMessageReceived(msg);
58 }
59 
60 // IPC override to grab the tab handle.
Send(IPC::Message * msg)61 bool TestAutomationProvider::Send(IPC::Message* msg) {
62   if (msg->type() == AutomationMsg_TabLoaded::ID) {
63     DCHECK(tab_handle_ == -1) << "Currently only support one tab";
64     tab_handle_ = msg->routing_id();
65     DVLOG(1) << "Got tab handle: " << tab_handle_;
66     DCHECK(tab_handle_ != -1 && tab_handle_ != 0);
67     delegate_->OnInitialTabLoaded();
68   }
69 
70   return AutomationProvider::Send(msg);
71 }
72 
Factory(net::URLRequest * request,net::NetworkDelegate * network_delegate,const std::string & scheme)73 net::URLRequestJob* TestAutomationProvider::Factory(
74     net::URLRequest* request,
75     net::NetworkDelegate* network_delegate,
76     const std::string& scheme) {
77   if (CFTestsDisabled())
78     return NULL;
79 
80   if (request->url().SchemeIsHTTPOrHTTPS()) {
81     // Only look at requests that don't have any user data.
82     // ResourceDispatcherHost uses the user data for requests that it manages.
83     // We don't want to mess with those.
84 
85     // We could also check if the current thread is our TestUrlRequest thread
86     // and only intercept requests that belong to that thread.
87     if (g_provider_instance_ && request->GetUserData(NULL) == NULL &&
88         g_provider_instance_->tab_handle_ != -1) {
89       // We generate our own request id which is also what
90       // ResourceDispatcherHost does (well, the id is actually generated by
91       // ResourceDispatcher).  Since these requests are divided into with
92       // and without userdata, we're OK.  However, just to make debugging
93       // a little easier, we have a significantly higher start value.
94       static int new_id = 0x00100000;
95       URLRequestAutomationJob* job = new URLRequestAutomationJob(
96           request, network_delegate,
97           request->context()->http_user_agent_settings(),
98           g_provider_instance_->tab_handle_, new_id++,
99           g_provider_instance_->automation_resource_message_filter_, false);
100       return job;
101     }
102   }
103 
104   return NULL;
105 }
106 
GetProtocolVersion()107 std::string TestAutomationProvider::GetProtocolVersion() {
108   // Return the version of npchrome_frame.dll.  We used to use
109   // chrome.dll, but the other end of the pipe in this case is
110   // actually npchrome_frame.dll (which fetches its version info from
111   // itself), and occasionally we run into RC dependency problems in
112   // incremental builds so that the version information does not get
113   // updated in one module but does in another, so better to use the
114   // exact same version to avoid hard-to-debug problems in development
115   // builds.
116   base::FilePath path;
117   PathService::Get(base::DIR_MODULE, &path);
118   path = path.AppendASCII("npchrome_frame.dll");
119 
120   std::string version;
121   scoped_ptr<FileVersionInfo> version_info(
122       FileVersionInfo::CreateFileVersionInfo(path));
123   if (version_info.get()) {
124     version = WideToASCII(version_info->product_version());
125   }
126   return version;
127 }
128 
129 // static
NewAutomationProvider(Profile * p,const std::string & channel,TestAutomationProviderDelegate * delegate)130 TestAutomationProvider* TestAutomationProvider::NewAutomationProvider(
131     Profile* p, const std::string& channel,
132     TestAutomationProviderDelegate* delegate) {
133   TestAutomationProvider* automation = new TestAutomationProvider(p, delegate);
134   automation->InitializeChannel(channel);
135   automation->SetExpectedTabCount(1);
136   return automation;
137 }
138