1 // Copyright 2014 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.
7 #include "chrome/browser/extensions/extension_apitest.h"
8 #include "content/public/browser/browser_thread.h"
9 #include "device/serial/serial_device_enumerator.h"
10 #include "device/serial/serial_service_impl.h"
11 #include "device/serial/test_serial_io_handler.h"
12 #include "extensions/browser/api/serial/serial_api.h"
13 #include "extensions/browser/api/serial/serial_connection.h"
14 #include "extensions/browser/extension_function.h"
15 #include "extensions/common/api/serial.h"
16 #include "extensions/common/switches.h"
17 #include "extensions/test/result_catcher.h"
18 #include "extensions/test/test_service_registration_manager.h"
19 #include "testing/gmock/include/gmock/gmock.h"
22 using testing::Return
;
24 namespace extensions
{
27 class FakeSerialGetDevicesFunction
: public AsyncExtensionFunction
{
29 bool RunAsync() override
{
30 base::ListValue
* devices
= new base::ListValue();
31 base::DictionaryValue
* device0
= new base::DictionaryValue();
32 device0
->SetString("path", "/dev/fakeserial");
33 base::DictionaryValue
* device1
= new base::DictionaryValue();
34 device1
->SetString("path", "\\\\COM800\\");
35 devices
->Append(device0
);
36 devices
->Append(device1
);
43 ~FakeSerialGetDevicesFunction() {}
46 class FakeSerialDeviceEnumerator
: public device::SerialDeviceEnumerator
{
48 ~FakeSerialDeviceEnumerator() override
{}
50 mojo::Array
<device::serial::DeviceInfoPtr
> GetDevices() override
{
51 mojo::Array
<device::serial::DeviceInfoPtr
> devices
;
52 device::serial::DeviceInfoPtr
device0(device::serial::DeviceInfo::New());
53 device0
->path
= "/dev/fakeserialmojo";
54 device::serial::DeviceInfoPtr
device1(device::serial::DeviceInfo::New());
55 device1
->path
= "\\\\COM800\\";
56 devices
.push_back(device0
.Pass());
57 devices
.push_back(device1
.Pass());
58 return devices
.Pass();
62 class FakeEchoSerialIoHandler
: public device::TestSerialIoHandler
{
64 FakeEchoSerialIoHandler() {
65 device_control_signals()->dcd
= true;
66 device_control_signals()->cts
= true;
67 device_control_signals()->ri
= true;
68 device_control_signals()->dsr
= true;
69 EXPECT_CALL(*this, SetControlSignals(_
)).Times(1).WillOnce(Return(true));
72 static scoped_refptr
<device::SerialIoHandler
> Create() {
73 return new FakeEchoSerialIoHandler();
76 MOCK_METHOD1(SetControlSignals
,
77 bool(const device::serial::HostControlSignals
&));
80 ~FakeEchoSerialIoHandler() override
{}
83 DISALLOW_COPY_AND_ASSIGN(FakeEchoSerialIoHandler
);
86 class FakeSerialConnectFunction
: public core_api::SerialConnectFunction
{
88 SerialConnection
* CreateSerialConnection(
89 const std::string
& port
,
90 const std::string
& owner_extension_id
) const override
{
91 scoped_refptr
<FakeEchoSerialIoHandler
> io_handler
=
92 new FakeEchoSerialIoHandler
;
93 SerialConnection
* serial_connection
=
94 new SerialConnection(port
, owner_extension_id
);
95 serial_connection
->SetIoHandlerForTest(io_handler
);
96 return serial_connection
;
100 ~FakeSerialConnectFunction() {}
103 class SerialApiTest
: public ExtensionApiTest
,
104 public testing::WithParamInterface
<bool> {
108 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
109 ExtensionApiTest::SetUpCommandLine(command_line
);
111 command_line
->AppendSwitch(switches::kEnableMojoSerialService
);
112 test_service_registration_manager_
.reset(
113 new TestServiceRegistrationManager
);
117 scoped_ptr
<TestServiceRegistrationManager
> test_service_registration_manager_
;
120 ExtensionFunction
* FakeSerialGetDevicesFunctionFactory() {
121 return new FakeSerialGetDevicesFunction();
124 ExtensionFunction
* FakeSerialConnectFunctionFactory() {
125 return new FakeSerialConnectFunction();
128 void CreateTestSerialServiceOnFileThread(
129 mojo::InterfaceRequest
<device::serial::SerialService
> request
) {
130 auto io_handler_factory
= base::Bind(&FakeEchoSerialIoHandler::Create
);
131 auto connection_factory
= new device::SerialConnectionFactory(
133 content::BrowserThread::GetMessageLoopProxyForThread(
134 content::BrowserThread::IO
));
135 scoped_ptr
<device::SerialDeviceEnumerator
> device_enumerator(
136 new FakeSerialDeviceEnumerator
);
137 mojo::BindToRequest(new device::SerialServiceImpl(connection_factory
,
138 device_enumerator
.Pass()),
142 void CreateTestSerialService(
143 mojo::InterfaceRequest
<device::serial::SerialService
> request
) {
144 content::BrowserThread::PostTask(
145 content::BrowserThread::FILE,
147 base::Bind(&CreateTestSerialServiceOnFileThread
, base::Passed(&request
)));
152 // Disable SIMULATE_SERIAL_PORTS only if all the following are true:
154 // 1. You have an Arduino or compatible board attached to your machine and
155 // properly appearing as the first virtual serial port ("first" is very loosely
156 // defined as whichever port shows up in serial.getPorts). We've tested only
157 // the Atmega32u4 Breakout Board and Arduino Leonardo; note that both these
158 // boards are based on the Atmel ATmega32u4, rather than the more common
159 // Arduino '328p with either FTDI or '8/16u2 USB interfaces. TODO: test more
162 // 2. Your user has permission to read/write the port. For example, this might
163 // mean that your user is in the "tty" or "uucp" group on Ubuntu flavors of
164 // Linux, or else that the port's path (e.g., /dev/ttyACM0) has global
165 // read/write permissions.
167 // 3. You have uploaded a program to the board that does a byte-for-byte echo
168 // on the virtual serial port at 57600 bps. An example is at
169 // chrome/test/data/extensions/api_test/serial/api/serial_arduino_test.ino.
171 #define SIMULATE_SERIAL_PORTS (1)
172 IN_PROC_BROWSER_TEST_P(SerialApiTest
, SerialFakeHardware
) {
173 ResultCatcher catcher
;
174 catcher
.RestrictToBrowserContext(browser()->profile());
176 #if SIMULATE_SERIAL_PORTS
178 test_service_registration_manager_
->OverrideServiceFactoryForTest(
179 base::Bind(&CreateTestSerialService
));
181 ASSERT_TRUE(ExtensionFunctionDispatcher::OverrideFunction(
182 "serial.getDevices", FakeSerialGetDevicesFunctionFactory
));
183 ASSERT_TRUE(ExtensionFunctionDispatcher::OverrideFunction(
184 "serial.connect", FakeSerialConnectFunctionFactory
));
188 ASSERT_TRUE(RunExtensionTest("serial/api")) << message_
;
191 IN_PROC_BROWSER_TEST_P(SerialApiTest
, SerialRealHardware
) {
192 ResultCatcher catcher
;
193 catcher
.RestrictToBrowserContext(browser()->profile());
195 ASSERT_TRUE(RunExtensionTest("serial/real_hardware")) << message_
;
198 INSTANTIATE_TEST_CASE_P(SerialApiTest
, SerialApiTest
, testing::Bool());
200 } // namespace extensions