// Copyright 2014 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 <string> #include "chrome/browser/extensions/extension_apitest.h" #include "device/serial/test_serial_io_handler.h" #include "extensions/browser/api/serial/serial_api.h" #include "extensions/browser/api/serial/serial_connection.h" #include "extensions/browser/extension_function.h" #include "extensions/common/api/serial.h" #include "extensions/test/result_catcher.h" #include "testing/gmock/include/gmock/gmock.h" using testing::_; using testing::Return; namespace { class SerialApiTest : public ExtensionApiTest { public: SerialApiTest() {} }; } // namespace namespace extensions { class FakeSerialGetDevicesFunction : public AsyncExtensionFunction { public: virtual bool RunAsync() OVERRIDE { base::ListValue* devices = new base::ListValue(); base::DictionaryValue* device0 = new base::DictionaryValue(); device0->SetString("path", "/dev/fakeserial"); base::DictionaryValue* device1 = new base::DictionaryValue(); device1->SetString("path", "\\\\COM800\\"); devices->Append(device0); devices->Append(device1); SetResult(devices); SendResponse(true); return true; } protected: virtual ~FakeSerialGetDevicesFunction() {} }; class FakeEchoSerialIoHandler : public device::TestSerialIoHandler { public: explicit FakeEchoSerialIoHandler() { device_control_signals()->dcd = true; device_control_signals()->cts = true; device_control_signals()->ri = true; device_control_signals()->dsr = true; } MOCK_METHOD1(SetControlSignals, bool(const device::serial::HostControlSignals&)); protected: virtual ~FakeEchoSerialIoHandler() {} private: DISALLOW_COPY_AND_ASSIGN(FakeEchoSerialIoHandler); }; class FakeSerialConnectFunction : public core_api::SerialConnectFunction { protected: virtual SerialConnection* CreateSerialConnection( const std::string& port, const std::string& owner_extension_id) const OVERRIDE { scoped_refptr<FakeEchoSerialIoHandler> io_handler = new FakeEchoSerialIoHandler; EXPECT_CALL(*io_handler.get(), SetControlSignals(_)).Times(1).WillOnce( Return(true)); SerialConnection* serial_connection = new SerialConnection(port, owner_extension_id); serial_connection->SetIoHandlerForTest(io_handler); return serial_connection; } protected: virtual ~FakeSerialConnectFunction() {} }; } // namespace extensions ExtensionFunction* FakeSerialGetDevicesFunctionFactory() { return new extensions::FakeSerialGetDevicesFunction(); } ExtensionFunction* FakeSerialConnectFunctionFactory() { return new extensions::FakeSerialConnectFunction(); } // Disable SIMULATE_SERIAL_PORTS only if all the following are true: // // 1. You have an Arduino or compatible board attached to your machine and // properly appearing as the first virtual serial port ("first" is very loosely // defined as whichever port shows up in serial.getPorts). We've tested only // the Atmega32u4 Breakout Board and Arduino Leonardo; note that both these // boards are based on the Atmel ATmega32u4, rather than the more common // Arduino '328p with either FTDI or '8/16u2 USB interfaces. TODO: test more // widely. // // 2. Your user has permission to read/write the port. For example, this might // mean that your user is in the "tty" or "uucp" group on Ubuntu flavors of // Linux, or else that the port's path (e.g., /dev/ttyACM0) has global // read/write permissions. // // 3. You have uploaded a program to the board that does a byte-for-byte echo // on the virtual serial port at 57600 bps. An example is at // chrome/test/data/extensions/api_test/serial/api/serial_arduino_test.ino. // #define SIMULATE_SERIAL_PORTS (1) IN_PROC_BROWSER_TEST_F(SerialApiTest, SerialFakeHardware) { extensions::ResultCatcher catcher; catcher.RestrictToBrowserContext(browser()->profile()); #if SIMULATE_SERIAL_PORTS ASSERT_TRUE(extensions::ExtensionFunctionDispatcher::OverrideFunction( "serial.getDevices", FakeSerialGetDevicesFunctionFactory)); ASSERT_TRUE(extensions::ExtensionFunctionDispatcher::OverrideFunction( "serial.connect", FakeSerialConnectFunctionFactory)); #endif ASSERT_TRUE(RunExtensionTest("serial/api")) << message_; } IN_PROC_BROWSER_TEST_F(SerialApiTest, SerialRealHardware) { extensions::ResultCatcher catcher; catcher.RestrictToBrowserContext(browser()->profile()); ASSERT_TRUE(RunExtensionTest("serial/real_hardware")) << message_; }