1 // Copyright 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.
9 #include "base/memory/scoped_ptr.h"
10 #include "chrome/browser/extensions/api/serial/serial_api.h"
11 #include "chrome/browser/extensions/api/serial/serial_connection.h"
12 #include "chrome/browser/extensions/extension_apitest.h"
13 #include "chrome/browser/extensions/extension_function_test_utils.h"
14 #include "chrome/browser/extensions/extension_test_message_listener.h"
15 #include "chrome/browser/ui/browser.h"
16 #include "chrome/common/extensions/api/serial.h"
17 #include "content/public/browser/browser_thread.h"
18 #include "extensions/browser/extension_function.h"
19 #include "testing/gmock/include/gmock/gmock.h"
22 using testing::Return;
24 using content::BrowserThread;
28 class SerialApiTest : public ExtensionApiTest {
35 namespace extensions {
37 class FakeSerialGetDevicesFunction : public AsyncExtensionFunction {
39 virtual bool RunAsync() OVERRIDE {
40 base::ListValue* devices = new base::ListValue();
41 base::DictionaryValue* device0 = new base::DictionaryValue();
42 device0->SetString("path", "/dev/fakeserial");
43 base::DictionaryValue* device1 = new base::DictionaryValue();
44 device1->SetString("path", "\\\\COM800\\");
45 devices->Append(device0);
46 devices->Append(device1);
52 virtual ~FakeSerialGetDevicesFunction() {}
55 class FakeEchoSerialConnection : public SerialConnection {
57 explicit FakeEchoSerialConnection(
58 const std::string& port,
59 const std::string& owner_extension_id)
60 : SerialConnection(port, owner_extension_id),
64 virtual ~FakeEchoSerialConnection() {
67 virtual void Open(const OpenCompleteCallback& callback) {
73 virtual bool Configure(const api::serial::ConnectionOptions& options) {
77 virtual void Close() {
81 virtual bool Receive(const ReceiveCompleteCallback& callback) {
82 read_callback_ = callback;
86 virtual bool Send(const std::string& data,
87 const SendCompleteCallback& callback) {
88 callback.Run(data.length(), api::serial::SEND_ERROR_NONE);
89 if (!read_callback_.is_null()) {
90 read_callback_.Run(data, api::serial::RECEIVE_ERROR_NONE);
95 virtual bool GetControlSignals(api::serial::DeviceControlSignals* signals)
104 virtual bool GetInfo(api::serial::ConnectionInfo* info) const {
105 info->paused = false;
106 info->persistent = false;
107 info->buffer_size = 4096;
108 info->receive_timeout = 0;
109 info->send_timeout = 0;
110 info->bitrate.reset(new int(9600));
111 info->data_bits = api::serial::DATA_BITS_EIGHT;
112 info->parity_bit = api::serial::PARITY_BIT_NO;
113 info->stop_bits = api::serial::STOP_BITS_ONE;
114 info->cts_flow_control.reset(new bool(false));
118 MOCK_METHOD1(SetControlSignals, bool(const api::serial::HostControlSignals&));
122 ReceiveCompleteCallback read_callback_;
124 DISALLOW_COPY_AND_ASSIGN(FakeEchoSerialConnection);
127 class FakeSerialConnectFunction : public api::SerialConnectFunction {
129 virtual SerialConnection* CreateSerialConnection(
130 const std::string& port,
131 const std::string& owner_extension_id) const OVERRIDE {
132 FakeEchoSerialConnection* serial_connection =
133 new FakeEchoSerialConnection(port, owner_extension_id);
134 EXPECT_CALL(*serial_connection, SetControlSignals(_)).
135 Times(1).WillOnce(Return(true));
136 return serial_connection;
140 virtual ~FakeSerialConnectFunction() {}
143 } // namespace extensions
145 ExtensionFunction* FakeSerialGetDevicesFunctionFactory() {
146 return new extensions::FakeSerialGetDevicesFunction();
149 ExtensionFunction* FakeSerialConnectFunctionFactory() {
150 return new extensions::FakeSerialConnectFunction();
153 // Disable SIMULATE_SERIAL_PORTS only if all the following are true:
155 // 1. You have an Arduino or compatible board attached to your machine and
156 // properly appearing as the first virtual serial port ("first" is very loosely
157 // defined as whichever port shows up in serial.getPorts). We've tested only
158 // the Atmega32u4 Breakout Board and Arduino Leonardo; note that both these
159 // boards are based on the Atmel ATmega32u4, rather than the more common
160 // Arduino '328p with either FTDI or '8/16u2 USB interfaces. TODO: test more
163 // 2. Your user has permission to read/write the port. For example, this might
164 // mean that your user is in the "tty" or "uucp" group on Ubuntu flavors of
165 // Linux, or else that the port's path (e.g., /dev/ttyACM0) has global
166 // read/write permissions.
168 // 3. You have uploaded a program to the board that does a byte-for-byte echo
169 // on the virtual serial port at 57600 bps. An example is at
170 // chrome/test/data/extensions/api_test/serial/api/serial_arduino_test.ino.
172 #define SIMULATE_SERIAL_PORTS (1)
173 IN_PROC_BROWSER_TEST_F(SerialApiTest, SerialFakeHardware) {
174 ResultCatcher catcher;
175 catcher.RestrictToProfile(browser()->profile());
177 #if SIMULATE_SERIAL_PORTS
178 ASSERT_TRUE(extensions::ExtensionFunctionDispatcher::OverrideFunction(
179 "serial.getDevices", FakeSerialGetDevicesFunctionFactory));
180 ASSERT_TRUE(extensions::ExtensionFunctionDispatcher::OverrideFunction(
181 "serial.connect", FakeSerialConnectFunctionFactory));
184 ASSERT_TRUE(RunExtensionTest("serial/api")) << message_;
187 IN_PROC_BROWSER_TEST_F(SerialApiTest, SerialRealHardware) {
188 ResultCatcher catcher;
189 catcher.RestrictToProfile(browser()->profile());
191 ASSERT_TRUE(RunExtensionTest("serial/real_hardware")) << message_;