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. 4 5 #include <string> 6 7 #include "chrome/browser/extensions/extension_apitest.h" 8 #include "device/serial/test_serial_io_handler.h" 9 #include "extensions/browser/api/serial/serial_api.h" 10 #include "extensions/browser/api/serial/serial_connection.h" 11 #include "extensions/browser/extension_function.h" 12 #include "extensions/common/api/serial.h" 13 #include "extensions/test/result_catcher.h" 14 #include "testing/gmock/include/gmock/gmock.h" 15 16 using testing::_; 17 using testing::Return; 18 19 namespace { 20 21 class SerialApiTest : public ExtensionApiTest { 22 public: 23 SerialApiTest() {} 24 }; 25 26 } // namespace 27 28 namespace extensions { 29 30 class FakeSerialGetDevicesFunction : public AsyncExtensionFunction { 31 public: 32 virtual bool RunAsync() OVERRIDE { 33 base::ListValue* devices = new base::ListValue(); 34 base::DictionaryValue* device0 = new base::DictionaryValue(); 35 device0->SetString("path", "/dev/fakeserial"); 36 base::DictionaryValue* device1 = new base::DictionaryValue(); 37 device1->SetString("path", "\\\\COM800\\"); 38 devices->Append(device0); 39 devices->Append(device1); 40 SetResult(devices); 41 SendResponse(true); 42 return true; 43 } 44 45 protected: 46 virtual ~FakeSerialGetDevicesFunction() {} 47 }; 48 49 class FakeEchoSerialIoHandler : public device::TestSerialIoHandler { 50 public: 51 explicit FakeEchoSerialIoHandler() { 52 device_control_signals()->dcd = true; 53 device_control_signals()->cts = true; 54 device_control_signals()->ri = true; 55 device_control_signals()->dsr = true; 56 } 57 58 MOCK_METHOD1(SetControlSignals, 59 bool(const device::serial::HostControlSignals&)); 60 61 protected: 62 virtual ~FakeEchoSerialIoHandler() {} 63 64 private: 65 DISALLOW_COPY_AND_ASSIGN(FakeEchoSerialIoHandler); 66 }; 67 68 class FakeSerialConnectFunction : public core_api::SerialConnectFunction { 69 protected: 70 virtual SerialConnection* CreateSerialConnection( 71 const std::string& port, 72 const std::string& owner_extension_id) const OVERRIDE { 73 scoped_refptr<FakeEchoSerialIoHandler> io_handler = 74 new FakeEchoSerialIoHandler; 75 EXPECT_CALL(*io_handler.get(), SetControlSignals(_)).Times(1).WillOnce( 76 Return(true)); 77 SerialConnection* serial_connection = 78 new SerialConnection(port, owner_extension_id); 79 serial_connection->SetIoHandlerForTest(io_handler); 80 return serial_connection; 81 } 82 83 protected: 84 virtual ~FakeSerialConnectFunction() {} 85 }; 86 87 } // namespace extensions 88 89 ExtensionFunction* FakeSerialGetDevicesFunctionFactory() { 90 return new extensions::FakeSerialGetDevicesFunction(); 91 } 92 93 ExtensionFunction* FakeSerialConnectFunctionFactory() { 94 return new extensions::FakeSerialConnectFunction(); 95 } 96 97 // Disable SIMULATE_SERIAL_PORTS only if all the following are true: 98 // 99 // 1. You have an Arduino or compatible board attached to your machine and 100 // properly appearing as the first virtual serial port ("first" is very loosely 101 // defined as whichever port shows up in serial.getPorts). We've tested only 102 // the Atmega32u4 Breakout Board and Arduino Leonardo; note that both these 103 // boards are based on the Atmel ATmega32u4, rather than the more common 104 // Arduino '328p with either FTDI or '8/16u2 USB interfaces. TODO: test more 105 // widely. 106 // 107 // 2. Your user has permission to read/write the port. For example, this might 108 // mean that your user is in the "tty" or "uucp" group on Ubuntu flavors of 109 // Linux, or else that the port's path (e.g., /dev/ttyACM0) has global 110 // read/write permissions. 111 // 112 // 3. You have uploaded a program to the board that does a byte-for-byte echo 113 // on the virtual serial port at 57600 bps. An example is at 114 // chrome/test/data/extensions/api_test/serial/api/serial_arduino_test.ino. 115 // 116 #define SIMULATE_SERIAL_PORTS (1) 117 IN_PROC_BROWSER_TEST_F(SerialApiTest, SerialFakeHardware) { 118 extensions::ResultCatcher catcher; 119 catcher.RestrictToBrowserContext(browser()->profile()); 120 121 #if SIMULATE_SERIAL_PORTS 122 ASSERT_TRUE(extensions::ExtensionFunctionDispatcher::OverrideFunction( 123 "serial.getDevices", FakeSerialGetDevicesFunctionFactory)); 124 ASSERT_TRUE(extensions::ExtensionFunctionDispatcher::OverrideFunction( 125 "serial.connect", FakeSerialConnectFunctionFactory)); 126 #endif 127 128 ASSERT_TRUE(RunExtensionTest("serial/api")) << message_; 129 } 130 131 IN_PROC_BROWSER_TEST_F(SerialApiTest, SerialRealHardware) { 132 extensions::ResultCatcher catcher; 133 catcher.RestrictToBrowserContext(browser()->profile()); 134 135 ASSERT_TRUE(RunExtensionTest("serial/real_hardware")) << message_; 136 } 137