summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornirnimesh@chromium.org <nirnimesh@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-24 20:13:22 +0000
committernirnimesh@chromium.org <nirnimesh@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-24 20:13:22 +0000
commitb45d80311bc50f2d6251f2fd38feaa53f5c25276 (patch)
treeaa3c70780ad6d7750a2eb7ce27f1c9f18de9b8bc
parent52a2432b71c9bcf344954b8487f00c1e2c403226 (diff)
downloadchromium_src-b45d80311bc50f2d6251f2fd38feaa53f5c25276.zip
chromium_src-b45d80311bc50f2d6251f2fd38feaa53f5c25276.tar.gz
chromium_src-b45d80311bc50f2d6251f2fd38feaa53f5c25276.tar.bz2
Add named testing interface. This allows you to connect to a pre-existing Chrome process and run tests on it. This is an addition to the low level interface underlying testing frameworks like PyAuto and WebDriver.
Normally, test frameworks communicate with Chrome over an unnamed socket pair on POSIX. The test creates the socket pair and then launches the browser as a child process, passing an open file descriptor for one end of the socket to the browser. This change adds a command line switch that, when passed to the browser, causes it to listen on a named socket instead, eliminating this parent/child process requirement. Therefore, you can potentially connect any number of tests to a preexisting browser process. For ChromeOS, this allows you to run tests on the instance of Chrome that is launched on startup, which controls things like the login and lock screens, the battery meter, the wireless UI, etc. Currently there is no way to run tests on a pre-existing Chrome instance. Eventually this will also allow you to connect both PyAuto and WebDriver to the same Chrome instance and run both in the same test. If you pass the browser the following command line switch: ./chrome --testing-channel=NamedTestingInterface:/path/to/file This causes the browser to listen for incoming connections. An AutomationProxy can connect to the browser by connecting a Unix domain socket to the specified path and control the browser over the socket. This is currently only for POSIX. Windows support will come in a future change. Also, this initial change only allows one connection; multiple connection support will come in a future change. BUG=chromium-os:8512 TEST=Run Chrome with --testing-interface=/var/tmp/NamedTestingInterface, then run NamedInterfaceTest.BasicNamedInterface under ui_tests. Review URL: http://codereview.chromium.org/4202004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@67300 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/automation/automation_provider.cc63
-rw-r--r--chrome/browser/automation/automation_provider.h24
-rw-r--r--chrome/browser/automation/automation_provider_observers.cc2
-rw-r--r--chrome/browser/ui/browser_init.cc23
-rw-r--r--chrome/browser/ui/browser_init.h2
-rw-r--r--chrome/chrome_tests.gypi9
-rw-r--r--chrome/common/automation_constants.cc9
-rw-r--r--chrome/common/automation_constants.h10
-rw-r--r--chrome/test/automation/automation_proxy.cc14
-rw-r--r--chrome/test/automation/automation_proxy.h18
-rw-r--r--chrome/test/automation/automation_proxy_uitest.cc35
-rw-r--r--chrome/test/automation/automation_proxy_uitest.h7
-rw-r--r--chrome/test/automation/proxy_launcher.cc75
-rw-r--r--chrome/test/automation/proxy_launcher.h78
-rw-r--r--chrome/test/ui/named_interface_uitest.cc42
-rw-r--r--chrome/test/ui/ui_test.cc60
-rw-r--r--chrome/test/ui/ui_test.h27
-rw-r--r--chrome_frame/chrome_frame.gyp6
-rw-r--r--chrome_frame/chrome_frame_automation.cc11
-rw-r--r--chrome_frame/chrome_frame_automation.h1
-rw-r--r--chrome_frame/test/automation_client_mock.cc4
-rw-r--r--chrome_frame/test/net/test_automation_provider.cc2
-rw-r--r--ipc/ipc_channel.h4
-rw-r--r--ipc/ipc_channel_posix.cc16
24 files changed, 449 insertions, 93 deletions
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc
index ec48e7a..65dc5a3 100644
--- a/chrome/browser/automation/automation_provider.cc
+++ b/chrome/browser/automation/automation_provider.cc
@@ -113,7 +113,9 @@ using base::Time;
AutomationProvider::AutomationProvider(Profile* profile)
: profile_(profile),
- reply_message_(NULL) {
+ reply_message_(NULL),
+ is_connected_(false),
+ initial_loads_complete_(false) {
TRACE_EVENT_BEGIN("AutomationProvider::AutomationProvider", 0, "");
browser_tracker_.reset(new AutomationBrowserTracker(this));
@@ -149,23 +151,38 @@ AutomationProvider::~AutomationProvider() {
g_browser_process->ReleaseModule();
}
-void AutomationProvider::ConnectToChannel(const std::string& channel_id) {
- TRACE_EVENT_BEGIN("AutomationProvider::ConnectToChannel", 0, "");
+bool AutomationProvider::InitializeChannel(const std::string& channel_id) {
+ TRACE_EVENT_BEGIN("AutomationProvider::InitializeChannel", 0, "");
+
+ std::string effective_channel_id = channel_id;
+
+ // If the channel_id starts with kNamedInterfacePrefix, create a named IPC
+ // server and listen on it, else connect as client to an existing IPC server
+ bool use_named_interface =
+ channel_id.find(automation::kNamedInterfacePrefix) == 0;
+ if (use_named_interface) {
+ effective_channel_id = channel_id.substr(
+ strlen(automation::kNamedInterfacePrefix));
+ if (effective_channel_id.length() <= 0)
+ return false;
+ }
if (!automation_resource_message_filter_.get()) {
automation_resource_message_filter_ = new AutomationResourceMessageFilter;
}
- channel_.reset(
- new IPC::SyncChannel(channel_id, IPC::Channel::MODE_CLIENT, this,
- automation_resource_message_filter_,
- g_browser_process->io_thread()->message_loop(),
- true, g_browser_process->shutdown_event()));
+ channel_.reset(new IPC::SyncChannel(
+ effective_channel_id,
+ use_named_interface ? IPC::Channel::MODE_NAMED_SERVER
+ : IPC::Channel::MODE_CLIENT,
+ this,
+ automation_resource_message_filter_,
+ g_browser_process->io_thread()->message_loop(),
+ true, g_browser_process->shutdown_event()));
- // Send a hello message with our current automation protocol version.
- channel_->Send(new AutomationMsg_Hello(0, GetProtocolVersion().c_str()));
+ TRACE_EVENT_END("AutomationProvider::InitializeChannel", 0, "");
- TRACE_EVENT_END("AutomationProvider::ConnectToChannel", 0, "");
+ return true;
}
std::string AutomationProvider::GetProtocolVersion() {
@@ -174,11 +191,16 @@ std::string AutomationProvider::GetProtocolVersion() {
}
void AutomationProvider::SetExpectedTabCount(size_t expected_tabs) {
- if (expected_tabs == 0) {
- Send(new AutomationMsg_InitialLoadsComplete(0));
- } else {
+ if (expected_tabs == 0)
+ OnInitialLoadsComplete();
+ else
initial_load_observer_.reset(new InitialLoadObserver(expected_tabs, this));
- }
+}
+
+void AutomationProvider::OnInitialLoadsComplete() {
+ initial_loads_complete_ = true;
+ if (is_connected_)
+ Send(new AutomationMsg_InitialLoadsComplete(0));
}
NotificationObserver* AutomationProvider::AddNavigationStatusListener(
@@ -327,6 +349,17 @@ const Extension* AutomationProvider::GetDisabledExtension(
return NULL;
}
+void AutomationProvider::OnChannelConnected(int pid) {
+ is_connected_ = true;
+ LOG(INFO) << "Testing channel connected, sending hello message";
+
+ // Send a hello message with our current automation protocol version.
+ chrome::VersionInfo version_info;
+ channel_->Send(new AutomationMsg_Hello(0, version_info.Version()));
+ if (initial_loads_complete_)
+ Send(new AutomationMsg_InitialLoadsComplete(0));
+}
+
void AutomationProvider::OnMessageReceived(const IPC::Message& message) {
IPC_BEGIN_MESSAGE_MAP(AutomationProvider, message)
#if !defined(OS_MACOSX)
diff --git a/chrome/browser/automation/automation_provider.h b/chrome/browser/automation/automation_provider.h
index 0da77a1..c30fb97 100644
--- a/chrome/browser/automation/automation_provider.h
+++ b/chrome/browser/automation/automation_provider.h
@@ -17,6 +17,7 @@
#include <vector>
#include "base/basictypes.h"
+#include "base/compiler_specific.h"
#include "base/observer_list.h"
#include "base/scoped_ptr.h"
#include "base/string16.h"
@@ -82,15 +83,23 @@ class AutomationProvider : public base::RefCounted<AutomationProvider>,
Profile* profile() const { return profile_; }
- // Establishes a connection to an automation client, if present.
- // An AutomationProxy should be established (probably in a different process)
- // before calling this.
- void ConnectToChannel(const std::string& channel_id);
+ // Initializes a channel for a connection to an AutomationProxy.
+ // If channel_id starts with kNamedInterfacePrefix, it will act
+ // as a server, create a named IPC socket with channel_id as its
+ // path, and will listen on the socket for incoming connections.
+ // If channel_id does not, it will act as a client and establish
+ // a connection on its primary IPC channel. See ipc/ipc_channel_posix.cc
+ // for more information about kPrimaryIPCChannel.
+ bool InitializeChannel(const std::string& channel_id) WARN_UNUSED_RESULT;
// Sets the number of tabs that we expect; when this number of tabs has
// loaded, an AutomationMsg_InitialLoadsComplete message is sent.
void SetExpectedTabCount(size_t expected_tabs);
+ // Called when the inital set of tabs has finished loading.
+ // Call SetExpectedTabCount(0) to set this to true immediately.
+ void OnInitialLoadsComplete();
+
// Add a listener for navigation status notification. Currently only
// navigation completion is observed; when the |number_of_navigations|
// complete, the completed_response object is sent; if the server requires
@@ -138,6 +147,7 @@ class AutomationProvider : public base::RefCounted<AutomationProvider>,
// IPC implementations
virtual bool Send(IPC::Message* msg);
+ virtual void OnChannelConnected(int pid);
virtual void OnMessageReceived(const IPC::Message& msg);
virtual void OnChannelError();
@@ -406,6 +416,12 @@ class AutomationProvider : public base::RefCounted<AutomationProvider>,
scoped_ptr<AutomationExtensionTracker> extension_tracker_;
PortContainerMap port_containers_;
+ // True iff connected to an AutomationProxy.
+ bool is_connected_;
+
+ // True iff browser finished loading initial set of tabs.
+ bool initial_loads_complete_;
+
DISALLOW_COPY_AND_ASSIGN(AutomationProvider);
};
diff --git a/chrome/browser/automation/automation_provider_observers.cc b/chrome/browser/automation/automation_provider_observers.cc
index 0bdb00d..779b6eb 100644
--- a/chrome/browser/automation/automation_provider_observers.cc
+++ b/chrome/browser/automation/automation_provider_observers.cc
@@ -140,7 +140,7 @@ DictionaryValue* InitialLoadObserver::GetTimingInformation() const {
void InitialLoadObserver::ConditionMet() {
registrar_.RemoveAll();
- automation_->Send(new AutomationMsg_InitialLoadsComplete(0));
+ automation_->OnInitialLoadsComplete();
}
NewTabUILoadObserver::NewTabUILoadObserver(AutomationProvider* automation)
diff --git a/chrome/browser/ui/browser_init.cc b/chrome/browser/ui/browser_init.cc
index d4b0d5d..e0a7ff5 100644
--- a/chrome/browser/ui/browser_init.cc
+++ b/chrome/browser/ui/browser_init.cc
@@ -973,10 +973,11 @@ bool BrowserInit::ProcessCmdLineImpl(const CommandLine& command_line,
expected_tab_count =
std::max(1, static_cast<int>(command_line.args().size()));
}
- CreateAutomationProvider<TestingAutomationProvider>(
+ if (!CreateAutomationProvider<TestingAutomationProvider>(
testing_channel_id,
profile,
- static_cast<size_t>(expected_tab_count));
+ static_cast<size_t>(expected_tab_count)))
+ return false;
}
}
@@ -993,11 +994,13 @@ bool BrowserInit::ProcessCmdLineImpl(const CommandLine& command_line,
silent_launch = true;
if (command_line.HasSwitch(switches::kChromeFrame)) {
- CreateAutomationProvider<ChromeFrameAutomationProvider>(
- automation_channel_id, profile, expected_tabs);
+ if (!CreateAutomationProvider<ChromeFrameAutomationProvider>(
+ automation_channel_id, profile, expected_tabs))
+ return false;
} else {
- CreateAutomationProvider<AutomationProvider>(automation_channel_id,
- profile, expected_tabs);
+ if (!CreateAutomationProvider<AutomationProvider>(
+ automation_channel_id, profile, expected_tabs))
+ return false;
}
}
@@ -1056,16 +1059,20 @@ bool BrowserInit::ProcessCmdLineImpl(const CommandLine& command_line,
}
template <class AutomationProviderClass>
-void BrowserInit::CreateAutomationProvider(const std::string& channel_id,
+bool BrowserInit::CreateAutomationProvider(const std::string& channel_id,
Profile* profile,
size_t expected_tabs) {
scoped_refptr<AutomationProviderClass> automation =
new AutomationProviderClass(profile);
- automation->ConnectToChannel(channel_id);
+
+ if (!automation->InitializeChannel(channel_id))
+ return false;
automation->SetExpectedTabCount(expected_tabs);
AutomationProviderList* list =
g_browser_process->InitAutomationProviderList();
DCHECK(list);
list->AddProvider(automation);
+
+ return true;
}
diff --git a/chrome/browser/ui/browser_init.h b/chrome/browser/ui/browser_init.h
index 07e99e9..746320c 100644
--- a/chrome/browser/ui/browser_init.h
+++ b/chrome/browser/ui/browser_init.h
@@ -53,7 +53,7 @@ class BrowserInit {
}
template <class AutomationProviderClass>
- static void CreateAutomationProvider(const std::string& channel_id,
+ static bool CreateAutomationProvider(const std::string& channel_id,
Profile* profile,
size_t expected_tabs);
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index bdd161a..03347f5 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -168,6 +168,8 @@
'sources': [
'test/automated_ui_tests/automated_ui_test_base.cc',
'test/automated_ui_tests/automated_ui_test_base.h',
+ 'test/automation/proxy_launcher.cc',
+ 'test/automation/proxy_launcher.h',
'test/testing_browser_process.h',
'test/ui/javascript_test_util.cc',
'test/ui/npapi_test_helper.cc',
@@ -515,6 +517,7 @@
'test/ui/dromaeo_benchmark_uitest.cc',
'test/ui/history_uitest.cc',
'test/ui/layout_plugin_uitest.cc',
+ 'test/ui/named_interface_uitest.cc',
'test/ui/npapi_uitest.cc',
'test/ui/omnibox_uitest.cc',
'test/ui/pepper_uitest.cc',
@@ -600,6 +603,10 @@
},
},
},
+ 'sources!': [
+ # TODO(dtu): port to windows http://crosbug.com/8515
+ 'test/ui/named_interface_uitest.cc',
+ ],
}, { # else: OS != "win"
'sources!': [
# TODO(port): http://crbug.com/45770
@@ -3109,6 +3116,8 @@
'-Wno-uninitialized',
],
'sources': [
+ 'test/automation/proxy_launcher.cc',
+ 'test/automation/proxy_launcher.h',
'test/pyautolib/pyautolib.cc',
'test/pyautolib/pyautolib.h',
'test/ui/ui_test.cc',
diff --git a/chrome/common/automation_constants.cc b/chrome/common/automation_constants.cc
index c253871..9480254 100644
--- a/chrome/common/automation_constants.cc
+++ b/chrome/common/automation_constants.cc
@@ -5,6 +5,7 @@
#include "chrome/common/automation_constants.h"
namespace automation {
+
// JSON value labels for proxy settings that are passed in via
// AutomationMsg_SetProxyConfig.
const char kJSONProxyAutoconfig[] = "proxy.autoconfig";
@@ -12,4 +13,10 @@ const char kJSONProxyNoProxy[] = "proxy.no_proxy";
const char kJSONProxyPacUrl[] = "proxy.pac_url";
const char kJSONProxyBypassList[] = "proxy.bypass_list";
const char kJSONProxyServer[] = "proxy.server";
-}
+
+// Named testing interface is used when you want to connect an
+// AutomationProxy to an already-running browser instance.
+const char kNamedInterfacePrefix[] = "NamedTestingInterface:";
+
+} // namespace automation
+
diff --git a/chrome/common/automation_constants.h b/chrome/common/automation_constants.h
index 13b120e..6579776 100644
--- a/chrome/common/automation_constants.h
+++ b/chrome/common/automation_constants.h
@@ -7,6 +7,7 @@
#pragma once
namespace automation {
+
// JSON value labels for proxy settings that are passed in via
// AutomationMsg_SetProxyConfig. These are here since they are used by both
// AutomationProvider and AutomationProxy.
@@ -16,9 +17,16 @@ extern const char kJSONProxyPacUrl[];
extern const char kJSONProxyBypassList[];
extern const char kJSONProxyServer[];
+// When passing the kTestingChannelID switch to the browser, prepend
+// this prefix to the channel id to enable the named testing interface.
+// Named testing interface is used when you want to connect an
+// AutomationProxy to an already-running browser instance.
+extern const char kNamedInterfacePrefix[];
+
// Amount of time to wait before querying the browser.
static const int kSleepTime = 250;
-}
+
+} // namespace automation
// Used by AutomationProxy, declared here so that other headers don't need
// to include automation_proxy.h.
diff --git a/chrome/test/automation/automation_proxy.cc b/chrome/test/automation/automation_proxy.cc
index fbdde25..a33f095 100644
--- a/chrome/test/automation/automation_proxy.cc
+++ b/chrome/test/automation/automation_proxy.cc
@@ -107,10 +107,8 @@ AutomationProxy::AutomationProxy(int command_execution_timeout_ms,
// least it is legal... ;-)
DCHECK_GE(command_execution_timeout_ms, 0);
listener_thread_id_ = PlatformThread::CurrentId();
- InitializeChannelID();
InitializeHandleTracker();
InitializeThread();
- InitializeChannel();
}
AutomationProxy::~AutomationProxy() {
@@ -122,7 +120,7 @@ AutomationProxy::~AutomationProxy() {
tracker_.reset();
}
-void AutomationProxy::InitializeChannelID() {
+std::string AutomationProxy::GenerateChannelID() {
// The channel counter keeps us out of trouble if we create and destroy
// several AutomationProxies sequentially over the course of a test run.
// (Creating the channel sometimes failed before when running a lot of
@@ -133,7 +131,7 @@ void AutomationProxy::InitializeChannelID() {
std::ostringstream buf;
buf << "ChromeTestingInterface:" << base::GetCurrentProcId() <<
"." << ++channel_counter;
- channel_id_ = buf.str();
+ return buf.str();
}
void AutomationProxy::InitializeThread() {
@@ -146,7 +144,8 @@ void AutomationProxy::InitializeThread() {
thread_.swap(thread);
}
-void AutomationProxy::InitializeChannel() {
+void AutomationProxy::InitializeChannel(const std::string& channel_id,
+ bool use_named_interface) {
DCHECK(shutdown_event_.get() != NULL);
// TODO(iyengar)
@@ -154,8 +153,9 @@ void AutomationProxy::InitializeChannel() {
// provider, where we use the shutdown event provided by the chrome browser
// process.
channel_.reset(new IPC::SyncChannel(
- channel_id_,
- IPC::Channel::MODE_SERVER,
+ channel_id,
+ use_named_interface ? IPC::Channel::MODE_NAMED_CLIENT
+ : IPC::Channel::MODE_SERVER,
this, // we are the listener
new AutomationMessageFilter(this),
thread_->message_loop(),
diff --git a/chrome/test/automation/automation_proxy.h b/chrome/test/automation/automation_proxy.h
index 853a6d3..7902ef0 100644
--- a/chrome/test/automation/automation_proxy.h
+++ b/chrome/test/automation/automation_proxy.h
@@ -61,6 +61,17 @@ class AutomationProxy : public IPC::Channel::Listener,
AutomationProxy(int command_execution_timeout_ms, bool disconnect_on_failure);
virtual ~AutomationProxy();
+ // Creates a previously unused channel id.
+ static std::string GenerateChannelID();
+
+ // Initializes a channel for a connection to an AutomationProvider.
+ // If use_named_interface is false, it will act as a client
+ // and connect to the named IPC socket with channel_id as its path.
+ // If use_named_interface is true, it will act as a server and
+ // use an anonymous socketpair instead.
+ void InitializeChannel(const std::string& channel_id,
+ bool use_named_interface);
+
// IPC callback
virtual void OnMessageReceived(const IPC::Message& msg);
virtual void OnChannelError();
@@ -208,10 +219,6 @@ class AutomationProxy : public IPC::Channel::Listener,
const std::string& password) WARN_UNUSED_RESULT;
#endif
- // Returns the ID of the automation IPC channel, so that it can be
- // passed to the app as a launch parameter.
- const std::string& channel_id() const { return channel_id_; }
-
#if defined(OS_POSIX)
base::file_handle_mapping_vector fds_to_map() const;
#endif
@@ -263,12 +270,9 @@ class AutomationProxy : public IPC::Channel::Listener,
protected:
template <class T> scoped_refptr<T> ProxyObjectFromHandle(int handle);
- void InitializeChannelID();
void InitializeThread();
- void InitializeChannel();
void InitializeHandleTracker();
- std::string channel_id_;
scoped_ptr<base::Thread> thread_;
scoped_ptr<IPC::SyncChannel> channel_;
scoped_ptr<AutomationHandleTracker> tracker_;
diff --git a/chrome/test/automation/automation_proxy_uitest.cc b/chrome/test/automation/automation_proxy_uitest.cc
index db6a18e4..f96de59 100644
--- a/chrome/test/automation/automation_proxy_uitest.cc
+++ b/chrome/test/automation/automation_proxy_uitest.cc
@@ -29,6 +29,7 @@
#include "chrome/test/automation/autocomplete_edit_proxy.h"
#include "chrome/test/automation/automation_proxy_uitest.h"
#include "chrome/test/automation/browser_proxy.h"
+#include "chrome/test/automation/proxy_launcher.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/window_proxy.h"
#include "chrome/test/ui_test_utils.h"
@@ -47,6 +48,34 @@ using testing::CreateFunctor;
using testing::StrEq;
using testing::_;
+
+// Replace the default automation proxy with our mock client.
+class ExternalTabUITestMockLauncher : public ProxyLauncher {
+ public:
+ explicit ExternalTabUITestMockLauncher(ExternalTabUITestMockClient **mock)
+ : mock_(mock) {
+ channel_id_ = AutomationProxy::GenerateChannelID();
+ }
+
+ AutomationProxy* CreateAutomationProxy(int execution_timeout) {
+ *mock_ = new ExternalTabUITestMockClient(execution_timeout);
+ (*mock_)->InitializeChannel(channel_id_, false);
+ return *mock_;
+ }
+
+ void InitializeConnection(UITestBase* ui_test_base) const {
+ ui_test_base->LaunchBrowserAndServer();
+ }
+
+ std::string PrefixedChannelID() const {
+ return channel_id_;
+ }
+
+ private:
+ ExternalTabUITestMockClient **mock_;
+ std::string channel_id_; // Channel id of automation proxy.
+};
+
class AutomationProxyTest : public UITest {
protected:
AutomationProxyTest() {
@@ -841,9 +870,9 @@ template <typename T> T** ReceivePointer(scoped_refptr<T>& p) { // NOLINT
return reinterpret_cast<T**>(&p);
}
-AutomationProxy* ExternalTabUITest::CreateAutomationProxy(int exec_timeout) {
- mock_ = new ExternalTabUITestMockClient(exec_timeout);
- return mock_;
+// Replace the default automation proxy with our mock client.
+ProxyLauncher* ExternalTabUITest::CreateProxyLauncher() {
+ return new ExternalTabUITestMockLauncher(&mock_);
}
// Create with specifying a url
diff --git a/chrome/test/automation/automation_proxy_uitest.h b/chrome/test/automation/automation_proxy_uitest.h
index 55da8cc..4e6d095 100644
--- a/chrome/test/automation/automation_proxy_uitest.h
+++ b/chrome/test/automation/automation_proxy_uitest.h
@@ -112,16 +112,17 @@ class ExternalTabUITestMockClient : public AutomationProxy {
class ExternalTabUITest : public UITest {
public:
ExternalTabUITest() : UITest(MessageLoop::TYPE_UI) {}
- // Override UITest's CreateAutomationProxy to provide the unit test
+ // Override UITest's CreateProxyLauncher to provide the unit test
// with our special implementation of AutomationProxy.
- // This function is called from within UITest::LaunchBrowserAndServer.
- virtual AutomationProxy* CreateAutomationProxy(int execution_timeout);
+ // This function is called from within UITest::SetUp().
+ virtual ProxyLauncher* CreateProxyLauncher();
protected:
// Filtered Inet will override automation callbacks for network resources.
virtual bool ShouldFilterInet() {
return false;
}
ExternalTabUITestMockClient* mock_;
+ std::string channel_id_; // Channel id of automation proxy.
};
#endif // CHROME_TEST_AUTOMATION_AUTOMATION_PROXY_UITEST_H_
diff --git a/chrome/test/automation/proxy_launcher.cc b/chrome/test/automation/proxy_launcher.cc
new file mode 100644
index 0000000..2325958
--- /dev/null
+++ b/chrome/test/automation/proxy_launcher.cc
@@ -0,0 +1,75 @@
+// Copyright (c) 2010 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.
+
+#include "chrome/test/automation/proxy_launcher.h"
+
+#include "chrome/common/automation_constants.h"
+#include "chrome/common/logging_chrome.h"
+#include "chrome/test/automation/automation_proxy.h"
+#include "chrome/test/ui/ui_test.h"
+
+// Default path of named testing interface.
+static const char kInterfacePath[] = "/var/tmp/ChromeTestingInterface";
+
+// NamedProxyLauncher functions
+
+NamedProxyLauncher::NamedProxyLauncher(bool launch_browser,
+ bool disconnect_on_failure)
+ : launch_browser_(launch_browser),
+ disconnect_on_failure_(disconnect_on_failure) {
+ channel_id_ = kInterfacePath;
+}
+
+AutomationProxy* NamedProxyLauncher::CreateAutomationProxy(
+ int execution_timeout) {
+ AutomationProxy* proxy = new AutomationProxy(execution_timeout,
+ disconnect_on_failure_);
+ proxy->InitializeChannel(channel_id_, true);
+ return proxy;
+}
+
+void NamedProxyLauncher::InitializeConnection(UITestBase* ui_test_base) const {
+ if (launch_browser_) {
+ // Set up IPC testing interface as a client.
+ ui_test_base->LaunchBrowser();
+
+ // Wait for browser to be ready for connections.
+ struct stat file_info;
+ while (stat(kInterfacePath, &file_info))
+ PlatformThread::Sleep(automation::kSleepTime);
+ }
+
+ ui_test_base->ConnectToRunningBrowser();
+}
+
+std::string NamedProxyLauncher::PrefixedChannelID() const {
+ std::string channel_id;
+ channel_id.append(automation::kNamedInterfacePrefix).append(channel_id_);
+ return channel_id;
+}
+
+// AnonymousProxyLauncher functions
+
+AnonymousProxyLauncher::AnonymousProxyLauncher(bool disconnect_on_failure)
+ : disconnect_on_failure_(disconnect_on_failure) {
+ channel_id_ = AutomationProxy::GenerateChannelID();
+}
+
+AutomationProxy* AnonymousProxyLauncher::CreateAutomationProxy(
+ int execution_timeout) {
+ AutomationProxy* proxy = new AutomationProxy(execution_timeout,
+ disconnect_on_failure_);
+ proxy->InitializeChannel(channel_id_, false);
+ return proxy;
+}
+
+void AnonymousProxyLauncher::InitializeConnection(
+ UITestBase* ui_test_base) const {
+ ui_test_base->LaunchBrowserAndServer();
+}
+
+std::string AnonymousProxyLauncher::PrefixedChannelID() const {
+ return channel_id_;
+}
+
diff --git a/chrome/test/automation/proxy_launcher.h b/chrome/test/automation/proxy_launcher.h
new file mode 100644
index 0000000..0f4d04d
--- /dev/null
+++ b/chrome/test/automation/proxy_launcher.h
@@ -0,0 +1,78 @@
+// Copyright (c) 2010 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_TEST_AUTOMATION_PROXY_LAUNCHER_H_
+#define CHROME_TEST_AUTOMATION_PROXY_LAUNCHER_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+
+class AutomationProxy;
+class UITestBase;
+
+// Subclass from this class to use a different implementation of AutomationProxy
+// or to use different channel IDs inside a class that derives from UITest.
+class ProxyLauncher {
+ public:
+ ProxyLauncher() {}
+ virtual ~ProxyLauncher() {}
+
+ // Creates an automation proxy.
+ virtual AutomationProxy* CreateAutomationProxy(
+ int execution_timeout) = 0;
+
+ // Launches the browser if needed and establishes a connection
+ // connection with it using the specified UITestBase.
+ virtual void InitializeConnection(UITestBase* ui_test_base) const = 0;
+
+ // Returns the automation proxy's channel with any prefixes prepended,
+ // for passing as a command line parameter over to the browser.
+ virtual std::string PrefixedChannelID() const = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ProxyLauncher);
+};
+
+// Uses an automation proxy that communicates over a named socket.
+// This is used if you want to connect an AutomationProxy
+// to a browser process that is already running.
+// The channel id of the proxy is a constant specified by kInterfacePath.
+class NamedProxyLauncher : public ProxyLauncher {
+ public:
+ // If launch_browser is true, launches Chrome with named interface enabled.
+ // Otherwise, there should be an existing instance the proxy can connect to.
+ NamedProxyLauncher(bool launch_browser, bool disconnect_on_failure);
+
+ virtual AutomationProxy* CreateAutomationProxy(int execution_timeout);
+ virtual void InitializeConnection(UITestBase* ui_test_base) const;
+ virtual std::string PrefixedChannelID() const;
+
+ protected:
+ std::string channel_id_; // Channel id of automation proxy.
+ bool launch_browser_; // True if we should launch the browser too.
+ bool disconnect_on_failure_; // True if we disconnect on IPC channel failure.
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(NamedProxyLauncher);
+};
+
+// Uses an automation proxy that communicates over an anonymous socket.
+class AnonymousProxyLauncher : public ProxyLauncher {
+ public:
+ explicit AnonymousProxyLauncher(bool disconnect_on_failure);
+ virtual AutomationProxy* CreateAutomationProxy(int execution_timeout);
+ virtual void InitializeConnection(UITestBase* ui_test_base) const;
+ virtual std::string PrefixedChannelID() const;
+
+ protected:
+ std::string channel_id_; // Channel id of automation proxy.
+ bool disconnect_on_failure_; // True if we disconnect on IPC channel failure.
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(AnonymousProxyLauncher);
+};
+
+#endif // CHROME_TEST_AUTOMATION_PROXY_LAUNCHER_H_
+
diff --git a/chrome/test/ui/named_interface_uitest.cc b/chrome/test/ui/named_interface_uitest.cc
new file mode 100644
index 0000000..ee44820
--- /dev/null
+++ b/chrome/test/ui/named_interface_uitest.cc
@@ -0,0 +1,42 @@
+// Copyright (c) 2010 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.
+
+#include "chrome/test/ui/ui_test.h"
+
+#include "chrome/common/url_constants.h"
+#include "chrome/test/automation/proxy_launcher.h"
+
+// The named testing interface enables the use of a named socket for controlling
+// the browser. This eliminates the dependency that the browser must be forked
+// from the controlling process.
+namespace {
+
+class NamedInterfaceTest : public UITest {
+ public:
+ NamedInterfaceTest() {
+ show_window_ = true;
+ }
+
+ virtual ProxyLauncher *CreateProxyLauncher() {
+ return new NamedProxyLauncher(true, true);
+ }
+};
+
+// Basic sanity test for named testing interface which
+// launches a browser instance that uses a named socket, then
+// sends it some commands to open some tabs over that socket.
+TEST_F(NamedInterfaceTest, BasicNamedInterface) {
+ scoped_refptr<BrowserProxy> browser_proxy(
+ automation()->GetBrowserWindow(0));
+ ASSERT_TRUE(browser_proxy.get());
+
+ for (int i = 0; i < 10; ++i)
+ ASSERT_TRUE(browser_proxy->AppendTab(GURL(chrome::kAboutBlankURL)));
+}
+
+// TODO(dtu): crosbug.com/8514: Write a test that makes sure you can disconnect,
+// then reconnect with a new connection and continue automation.
+
+} // namespace
+
diff --git a/chrome/test/ui/ui_test.cc b/chrome/test/ui/ui_test.cc
index 9fbb857..e6aff60 100644
--- a/chrome/test/ui/ui_test.cc
+++ b/chrome/test/ui/ui_test.cc
@@ -43,6 +43,7 @@
#include "chrome/test/automation/automation_proxy.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/javascript_execution_controller.h"
+#include "chrome/test/automation/proxy_launcher.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/window_proxy.h"
#include "chrome/test/chrome_process_util.h"
@@ -140,7 +141,9 @@ void UITestBase::SetUp() {
JavaScriptExecutionController::set_timeout(
TestTimeouts::action_max_timeout_ms());
test_start_time_ = Time::NowFromSystemTime();
- LaunchBrowserAndServer();
+
+ launcher_.reset(CreateProxyLauncher());
+ launcher_->InitializeConnection(this);
}
void UITestBase::TearDown() {
@@ -175,24 +178,39 @@ void UITestBase::TearDown() {
// TODO(phajdan.jr): get rid of set_command_execution_timeout_ms.
void UITestBase::set_command_execution_timeout_ms(int timeout) {
- server_->set_command_execution_timeout_ms(timeout);
+ automation_proxy_->set_command_execution_timeout_ms(timeout);
VLOG(1) << "Automation command execution timeout set to " << timeout << " ms";
}
-AutomationProxy* UITestBase::CreateAutomationProxy(int execution_timeout) {
- return new AutomationProxy(execution_timeout, false);
+ProxyLauncher* UITestBase::CreateProxyLauncher() {
+ return new AnonymousProxyLauncher(false);
+}
+
+void UITestBase::LaunchBrowser() {
+ LaunchBrowser(launch_arguments_, clear_profile_);
}
void UITestBase::LaunchBrowserAndServer() {
- // Set up IPC testing interface server.
- server_.reset(CreateAutomationProxy(
- TestTimeouts::command_execution_timeout_ms()));
+ // Set up IPC testing interface as a server.
+ automation_proxy_.reset(launcher_->CreateAutomationProxy(
+ TestTimeouts::command_execution_timeout_ms()));
LaunchBrowser(launch_arguments_, clear_profile_);
- ASSERT_EQ(AUTOMATION_SUCCESS, server_->WaitForAppLaunch())
+ WaitForBrowserLaunch();
+}
+
+void UITestBase::ConnectToRunningBrowser() {
+ // Set up IPC testing interface as a client.
+ automation_proxy_.reset(launcher_->CreateAutomationProxy(
+ TestTimeouts::command_execution_timeout_ms()));
+ WaitForBrowserLaunch();
+}
+
+void UITestBase::WaitForBrowserLaunch() {
+ ASSERT_EQ(AUTOMATION_SUCCESS, automation_proxy_->WaitForAppLaunch())
<< "Error while awaiting automation ping from browser process";
if (wait_for_initial_loads_)
- ASSERT_TRUE(server_->WaitForInitialLoads());
+ ASSERT_TRUE(automation_proxy_->WaitForInitialLoads());
else
PlatformThread::Sleep(sleep_timeout_ms());
@@ -210,7 +228,7 @@ void UITestBase::CloseBrowserAndServer() {
AssertAppNotRunning(StringPrintf(
L"Unable to quit all browser processes. Original PID %d", process_id_));
- server_.reset(); // Shut down IPC testing interface.
+ automation_proxy_.reset(); // Shut down IPC testing interface.
}
void UITestBase::LaunchBrowser(const CommandLine& arguments,
@@ -567,7 +585,7 @@ FilePath UITestBase::GetDownloadDirectory() {
}
void UITestBase::CloseBrowserAsync(BrowserProxy* browser) const {
- ASSERT_TRUE(server_->Send(
+ ASSERT_TRUE(automation_proxy_->Send(
new AutomationMsg_CloseBrowserRequestAsync(0, browser->handle())));
}
@@ -579,7 +597,7 @@ bool UITestBase::CloseBrowser(BrowserProxy* browser,
bool result = true;
- bool succeeded = server_->Send(new AutomationMsg_CloseBrowser(
+ bool succeeded = automation_proxy_->Send(new AutomationMsg_CloseBrowser(
0, browser->handle(), &result, application_closed));
if (!succeeded)
@@ -694,10 +712,9 @@ void UITestBase::PrepareTestCommandline(CommandLine* command_line) {
if (dom_automation_enabled_)
command_line->AppendSwitch(switches::kDomAutomationController);
- if (include_testing_id_) {
+ if (include_testing_id_)
command_line->AppendSwitchASCII(switches::kTestingChannelID,
- server_->channel_id());
- }
+ launcher_->PrefixedChannelID());
if (!show_error_dialogs_ &&
!CommandLine::ForCurrentProcess()->HasSwitch(
@@ -786,10 +803,11 @@ bool UITestBase::LaunchBrowserHelper(const CommandLine& arguments,
<< browser_wrapper;
}
- bool started = base::LaunchApp(command_line.argv(),
- server_->fds_to_map(),
- wait,
- process);
+ base::file_handle_mapping_vector fds;
+ if (automation_proxy_.get())
+ fds = automation_proxy_->fds_to_map();
+
+ bool started = base::LaunchApp(command_line.argv(), fds, wait, process);
#endif
return started;
@@ -867,11 +885,11 @@ void UITest::TearDown() {
PlatformTest::TearDown();
}
-AutomationProxy* UITest::CreateAutomationProxy(int execution_timeout) {
+ProxyLauncher* UITest::CreateProxyLauncher() {
// Make the AutomationProxy disconnect the channel on the first error,
// so that we avoid spending a lot of time in timeouts. The browser is likely
// hosed if we hit those errors.
- return new AutomationProxy(execution_timeout, true);
+ return new AnonymousProxyLauncher(true);
}
static CommandLine* CreatePythonCommandLine() {
diff --git a/chrome/test/ui/ui_test.h b/chrome/test/ui/ui_test.h
index ced9f34..3305cc5 100644
--- a/chrome/test/ui/ui_test.h
+++ b/chrome/test/ui/ui_test.h
@@ -38,6 +38,7 @@ class BrowserProxy;
class DictionaryValue;
class FilePath;
class GURL;
+class ProxyLauncher;
class ScopedTempDir;
class TabProxy;
@@ -68,14 +69,21 @@ class UITestBase {
public:
// ********* Utility functions *********
- // Launches the browser and IPC testing server.
+ // Launches the browser only.
+ void LaunchBrowser();
+
+ // Launches the browser and IPC testing connection in server mode.
void LaunchBrowserAndServer();
+ // Launches the IPC testing connection in client mode,
+ // which then attempts to connect to a browser.
+ void ConnectToRunningBrowser();
+
// Only for pyauto.
void set_command_execution_timeout_ms(int timeout);
- // Overridable so that derived classes can provide their own AutomationProxy.
- virtual AutomationProxy* CreateAutomationProxy(int execution_timeout);
+ // Overridable so that derived classes can provide their own ProxyLauncher.
+ virtual ProxyLauncher* CreateProxyLauncher();
// Closes the browser and IPC testing server.
void CloseBrowserAndServer();
@@ -102,7 +110,7 @@ class UITestBase {
// Terminates the browser, simulates end of session.
void TerminateBrowser();
- // Tells the browser to navigato to the givne URL in the active tab
+ // Tells the browser to navigate to the given URL in the active tab
// of the first app window.
// Does not wait for the navigation to complete to return.
void NavigateToURLAsync(const GURL& url);
@@ -361,8 +369,8 @@ class UITestBase {
protected:
AutomationProxy* automation() {
- EXPECT_TRUE(server_.get());
- return server_.get();
+ EXPECT_TRUE(automation_proxy_.get());
+ return automation_proxy_.get();
}
virtual bool ShouldFilterInet() {
@@ -412,6 +420,7 @@ class UITestBase {
// id on the command line? Default is
// true.
bool enable_file_cookies_; // Enable file cookies, default is true.
+ scoped_ptr<ProxyLauncher> launcher_; // Launches browser and AutomationProxy.
ProfileType profile_type_; // Are we using a profile with a
// complex theme?
FilePath websocket_pid_file_; // PID file for websocket server.
@@ -419,6 +428,8 @@ class UITestBase {
// the browser. Used in ShutdownTest.
private:
+ void WaitForBrowserLaunch();
+
bool LaunchBrowserHelper(const CommandLine& arguments,
bool wait,
base::ProcessHandle* process);
@@ -450,7 +461,7 @@ class UITestBase {
static std::string js_flags_; // Flags passed to the JS engine.
static std::string log_level_; // Logging level.
- scoped_ptr<AutomationProxy> server_;
+ scoped_ptr<AutomationProxy> automation_proxy_;
std::string ui_test_name_;
@@ -468,7 +479,7 @@ class UITest : public UITestBase, public PlatformTest {
virtual void SetUp();
virtual void TearDown();
- virtual AutomationProxy* CreateAutomationProxy(int execution_timeout);
+ virtual ProxyLauncher* CreateProxyLauncher();
// Synchronously launches local http server normally used to run LayoutTests.
void StartHttpServer(const FilePath& root_directory);
diff --git a/chrome_frame/chrome_frame.gyp b/chrome_frame/chrome_frame.gyp
index 39d5063..66d1dad 100644
--- a/chrome_frame/chrome_frame.gyp
+++ b/chrome_frame/chrome_frame.gyp
@@ -550,7 +550,10 @@
'test/win_event_receiver.h',
'chrome_tab.h',
'../base/test/test_file_util_win.cc',
+ '../chrome/test/automation/proxy_launcher.cc',
+ '../chrome/test/automation/proxy_launcher.h',
'../chrome/test/ui/ui_test.cc',
+ '../chrome/test/ui/ui_test.h',
'../chrome/test/ui/ui_test_suite.cc',
'../chrome/test/ui/ui_test_suite.h',
'../chrome/test/chrome_process_util.cc',
@@ -809,7 +812,8 @@
],
'process_outputs_as_sources': 0,
'message':
- 'Assembling <(RULE_INPUT_PATH) to <(INTERMEDIATE_DIR)\<(RULE_INPUT_ROOT).obj.',
+ 'Assembling <(RULE_INPUT_PATH) to ' \
+ '<(INTERMEDIATE_DIR)\<(RULE_INPUT_ROOT).obj.',
},
],
'msvs_settings': {
diff --git a/chrome_frame/chrome_frame_automation.cc b/chrome_frame/chrome_frame_automation.cc
index 7a49f18..94d30b8 100644
--- a/chrome_frame/chrome_frame_automation.cc
+++ b/chrome_frame/chrome_frame_automation.cc
@@ -144,10 +144,13 @@ class ChromeFrameAutomationProxyImpl::CFMsgDispatcher
};
ChromeFrameAutomationProxyImpl::ChromeFrameAutomationProxyImpl(
- AutomationProxyCacheEntry* entry, int launch_timeout)
+ AutomationProxyCacheEntry* entry,
+ std::string channel_id, int launch_timeout)
: AutomationProxy(launch_timeout, false), proxy_entry_(entry) {
TRACE_EVENT_BEGIN("chromeframe.automationproxy", this, "");
+ InitializeChannel(channel_id, false);
+
sync_ = new CFMsgDispatcher();
message_filter_ = new TabProxyNotificationMessageFilter(tracker_.get());
@@ -271,8 +274,10 @@ void AutomationProxyCacheEntry::CreateProxy(ChromeFrameLaunchParams* params,
// destruction notification.
// At same time we must destroy/stop the thread from another thread.
+ std::string channel_id = AutomationProxy::GenerateChannelID();
ChromeFrameAutomationProxyImpl* proxy =
- new ChromeFrameAutomationProxyImpl(this, params->launch_timeout());
+ new ChromeFrameAutomationProxyImpl(this, channel_id,
+ params->launch_timeout());
// Ensure that the automation proxy actually respects our choice on whether
// or not to check the version.
@@ -282,7 +287,7 @@ void AutomationProxyCacheEntry::CreateProxy(ChromeFrameLaunchParams* params,
scoped_ptr<CommandLine> command_line(
chrome_launcher::CreateLaunchCommandLine());
command_line->AppendSwitchASCII(switches::kAutomationClientChannelID,
- proxy->channel_id());
+ channel_id);
// Run Chrome in Chrome Frame mode. In practice, this modifies the paths
// and registry keys that Chrome looks in via the BrowserDistribution
diff --git a/chrome_frame/chrome_frame_automation.h b/chrome_frame/chrome_frame_automation.h
index cb1b282..5cf1304 100644
--- a/chrome_frame/chrome_frame_automation.h
+++ b/chrome_frame/chrome_frame_automation.h
@@ -92,6 +92,7 @@ class ChromeFrameAutomationProxyImpl
protected:
friend class AutomationProxyCacheEntry;
ChromeFrameAutomationProxyImpl(AutomationProxyCacheEntry* entry,
+ std::string channel_id,
int launch_timeout);
class CFMsgDispatcher;
diff --git a/chrome_frame/test/automation_client_mock.cc b/chrome_frame/test/automation_client_mock.cc
index 7e8f317..2cf981b 100644
--- a/chrome_frame/test/automation_client_mock.cc
+++ b/chrome_frame/test/automation_client_mock.cc
@@ -315,7 +315,8 @@ class TestChromeFrameAutomationProxyImpl
public:
TestChromeFrameAutomationProxyImpl()
// 1 is an unneeded timeout.
- : ChromeFrameAutomationProxyImpl(NULL, 1) {
+ : ChromeFrameAutomationProxyImpl(
+ NULL, AutomationProxy::GenerateChannelID(), 1) {
}
MOCK_METHOD3(
SendAsAsync,
@@ -469,4 +470,3 @@ TEST_F(CFACMockTest, NavigateTwiceAfterInitToSameUrl) {
EXPECT_CALL(mock_proxy_, ReleaseTabProxy(testing::Eq(tab_handle_))).Times(1);
client_->Uninitialize();
}
-
diff --git a/chrome_frame/test/net/test_automation_provider.cc b/chrome_frame/test/net/test_automation_provider.cc
index 5b8a9a6..d6a0676 100644
--- a/chrome_frame/test/net/test_automation_provider.cc
+++ b/chrome_frame/test/net/test_automation_provider.cc
@@ -119,7 +119,7 @@ TestAutomationProvider* TestAutomationProvider::NewAutomationProvider(
Profile* p, const std::string& channel,
TestAutomationProviderDelegate* delegate) {
TestAutomationProvider* automation = new TestAutomationProvider(p, delegate);
- automation->ConnectToChannel(channel);
+ automation->InitializeChannel(channel);
automation->SetExpectedTabCount(1);
return automation;
}
diff --git a/ipc/ipc_channel.h b/ipc/ipc_channel.h
index 2445e51..27b055c1 100644
--- a/ipc/ipc_channel.h
+++ b/ipc/ipc_channel.h
@@ -38,7 +38,9 @@ class Channel : public Message::Sender {
enum Mode {
MODE_NONE,
MODE_SERVER,
- MODE_CLIENT
+ MODE_CLIENT,
+ MODE_NAMED_SERVER,
+ MODE_NAMED_CLIENT
};
enum {
diff --git a/ipc/ipc_channel_posix.cc b/ipc/ipc_channel_posix.cc
index 86d1673..65a04e1 100644
--- a/ipc/ipc_channel_posix.cc
+++ b/ipc/ipc_channel_posix.cc
@@ -273,8 +273,9 @@ Channel::ChannelImpl::ChannelImpl(const std::string& channel_id, Mode mode,
: mode_(mode),
is_blocked_on_write_(false),
message_send_bytes_written_(0),
- uses_fifo_(CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kIPCUseFIFO)),
+ uses_fifo_(
+ CommandLine::ForCurrentProcess()->HasSwitch(switches::kIPCUseFIFO) ||
+ mode == MODE_NAMED_SERVER || mode == MODE_NAMED_CLIENT),
server_listen_pipe_(-1),
pipe_(-1),
client_pipe_(-1),
@@ -285,10 +286,15 @@ Channel::ChannelImpl::ChannelImpl(const std::string& channel_id, Mode mode,
listener_(listener),
waiting_connect_(true),
factory_(this) {
- if (!CreatePipe(channel_id, mode)) {
+ if (mode_ == MODE_NAMED_SERVER)
+ mode_ = MODE_SERVER;
+ if (mode_ == MODE_NAMED_CLIENT)
+ mode_ = MODE_CLIENT;
+
+ if (!CreatePipe(channel_id, mode_)) {
// The pipe may have been closed already.
PLOG(WARNING) << "Unable to create pipe named \"" << channel_id
- << "\" in " << (mode == MODE_SERVER ? "server" : "client")
+ << "\" in " << (mode_ == MODE_SERVER ? "server" : "client")
<< " mode";
}
}
@@ -346,7 +352,7 @@ bool Channel::ChannelImpl::CreatePipe(const std::string& channel_id,
// TODO(playmobil): We shouldn't need to create fifos on disk.
// TODO(playmobil): If we do, they should be in the user data directory.
// TODO(playmobil): Cleanup any stale fifos.
- pipe_name_ = "/var/tmp/chrome_" + channel_id;
+ pipe_name_ = channel_id;
if (mode == MODE_SERVER) {
if (!CreateServerFifo(pipe_name_, &server_listen_pipe_)) {
return false;