OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
| 5 #include <string> |
| 6 |
5 #include "base/memory/scoped_ptr.h" | 7 #include "base/memory/scoped_ptr.h" |
| 8 #include "chrome/browser/extensions/api/api_resource_event_notifier.h" |
6 #include "chrome/browser/extensions/api/serial/serial_api.h" | 9 #include "chrome/browser/extensions/api/serial/serial_api.h" |
| 10 #include "chrome/browser/extensions/api/serial/serial_connection.h" |
7 #include "chrome/browser/extensions/extension_apitest.h" | 11 #include "chrome/browser/extensions/extension_apitest.h" |
| 12 #include "chrome/browser/extensions/extension_function.h" |
8 #include "chrome/browser/extensions/extension_function_test_utils.h" | 13 #include "chrome/browser/extensions/extension_function_test_utils.h" |
9 #include "chrome/browser/extensions/extension_test_message_listener.h" | 14 #include "chrome/browser/extensions/extension_test_message_listener.h" |
10 #include "chrome/browser/ui/browser.h" | 15 #include "chrome/browser/ui/browser.h" |
11 #include "content/public/browser/browser_thread.h" | 16 #include "content/public/browser/browser_thread.h" |
12 | 17 |
13 using content::BrowserThread; | 18 using content::BrowserThread; |
14 | 19 |
15 namespace { | 20 namespace { |
16 | 21 |
17 class SerialApiTest : public PlatformAppApiTest { | 22 class SerialApiTest : public PlatformAppApiTest { |
18 public: | 23 public: |
19 SerialApiTest() {} | 24 SerialApiTest() {} |
20 }; | 25 }; |
21 | 26 |
22 } // namespace | 27 } // namespace |
23 | 28 |
| 29 namespace extensions { |
| 30 |
| 31 class FakeSerialGetPortsFunction : public AsyncExtensionFunction { |
| 32 public: |
| 33 virtual bool RunImpl() { |
| 34 ListValue* ports = new ListValue(); |
| 35 ports->Append(Value::CreateStringValue("/dev/fakeserial")); |
| 36 ports->Append(Value::CreateStringValue("\\\\COM800\\")); |
| 37 result_.reset(ports); |
| 38 SendResponse(true); |
| 39 return true; |
| 40 } |
| 41 }; |
| 42 |
| 43 class FakeEchoSerialConnection : public SerialConnection { |
| 44 public: |
| 45 explicit FakeEchoSerialConnection( |
| 46 const std::string& port, |
| 47 int bitrate, |
| 48 APIResourceEventNotifier* event_notifier) |
| 49 : SerialConnection(port, bitrate, event_notifier), |
| 50 opened_(true) { |
| 51 Flush(); |
| 52 opened_ = false; |
| 53 } |
| 54 |
| 55 virtual bool Open() { |
| 56 DCHECK(!opened_); |
| 57 opened_ = true; |
| 58 return true; |
| 59 } |
| 60 |
| 61 virtual void Close() { |
| 62 DCHECK(opened_); |
| 63 } |
| 64 |
| 65 virtual void Flush() { |
| 66 DCHECK(opened_); |
| 67 read_index_ = write_index_ = 0; |
| 68 } |
| 69 |
| 70 virtual int Read(uint8* byte) { |
| 71 DCHECK(byte); |
| 72 |
| 73 if (read_index_ >= write_index_) { |
| 74 return 0; |
| 75 } |
| 76 *byte = ring_buffer_[read_index_++]; |
| 77 if (read_index_ == BUFFER_SIZE) |
| 78 read_index_ = 0; |
| 79 return 1; |
| 80 } |
| 81 |
| 82 virtual int Write(scoped_refptr<net::IOBuffer> io_buffer, int byte_count) { |
| 83 DCHECK(io_buffer.get()); |
| 84 DCHECK(byte_count >= 0); |
| 85 |
| 86 char *data = io_buffer->data(); |
| 87 int count = byte_count; |
| 88 while (count--) { |
| 89 ring_buffer_[write_index_++] = *data++; |
| 90 if (write_index_ == BUFFER_SIZE) |
| 91 write_index_ = 0; |
| 92 } |
| 93 return byte_count; |
| 94 } |
| 95 |
| 96 private: |
| 97 enum { BUFFER_SIZE = 256 }; |
| 98 bool opened_; |
| 99 char ring_buffer_[BUFFER_SIZE]; |
| 100 int read_index_; |
| 101 int write_index_; |
| 102 |
| 103 DISALLOW_COPY_AND_ASSIGN(FakeEchoSerialConnection); |
| 104 }; |
| 105 |
| 106 class FakeSerialOpenFunction : public SerialOpenFunction { |
| 107 protected: |
| 108 virtual SerialConnection* CreateSerialConnection( |
| 109 const std::string& port, |
| 110 int bitrate, |
| 111 APIResourceEventNotifier* event_notifier) OVERRIDE { |
| 112 return new FakeEchoSerialConnection(port, bitrate, event_notifier); |
| 113 } |
| 114 virtual bool DoesPortExist(const std::string& port) OVERRIDE { |
| 115 return true; |
| 116 } |
| 117 }; |
| 118 |
| 119 } // namespace extensions |
| 120 |
| 121 ExtensionFunction* FakeSerialGetPortsFunctionFactory() { |
| 122 return new extensions::FakeSerialGetPortsFunction(); |
| 123 } |
| 124 |
| 125 ExtensionFunction* FakeSerialOpenFunctionFactory() { |
| 126 return new extensions::FakeSerialOpenFunction(); |
| 127 } |
| 128 |
| 129 // Disable SIMULATE_SERIAL_PORTS only if all the following are true: |
| 130 // |
| 131 // 1. You have an Arduino or compatible board attached to your machine and |
| 132 // properly appearing as the first virtual serial port ("first" is very loosely |
| 133 // defined as whichever port shows up in serial.getPorts). We've tested only |
| 134 // the Atmega32u4 Breakout Board and Arduino Leonardo; note that both these |
| 135 // boards are based on the Atmel ATmega32u4, rather than the more common |
| 136 // Arduino '328p with either FTDI or '8/16u2 USB interfaces. TODO: test more |
| 137 // widely. |
| 138 // |
| 139 // 2. Your user has permission to read/write the port. For example, this might |
| 140 // mean that your user is in the "tty" or "uucp" group on Ubuntu flavors of |
| 141 // Linux, or else that the port's path (e.g., /dev/ttyACM0) has global |
| 142 // read/write permissions. |
| 143 // |
| 144 // 3. You have uploaded a program to the board that does a byte-for-byte echo |
| 145 // on the virtual serial port at 57600 bps. An example is at |
| 146 // chrome/test/data/extensions/api_test/serial/api/serial_arduino_test.ino. |
| 147 // |
| 148 #define SIMULATE_SERIAL_PORTS (1) |
24 IN_PROC_BROWSER_TEST_F(SerialApiTest, SerialExtension) { | 149 IN_PROC_BROWSER_TEST_F(SerialApiTest, SerialExtension) { |
25 ResultCatcher catcher; | 150 ResultCatcher catcher; |
26 catcher.RestrictToProfile(browser()->profile()); | 151 catcher.RestrictToProfile(browser()->profile()); |
27 | 152 |
28 ExtensionTestMessageListener listener("serial_port", true); | 153 #if SIMULATE_SERIAL_PORTS |
29 | 154 ASSERT_TRUE(ExtensionFunctionDispatcher::OverrideFunction( |
30 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("serial/api"))); | 155 "experimental.serial.getPorts", |
31 EXPECT_TRUE(listener.WaitUntilSatisfied()); | 156 FakeSerialGetPortsFunctionFactory)); |
32 | 157 ASSERT_TRUE(ExtensionFunctionDispatcher::OverrideFunction( |
33 #if 0 | 158 "experimental.serial.open", |
34 // Enable this path only if all the following are true: | 159 FakeSerialOpenFunctionFactory)); |
35 // | |
36 // 1. You have an Arduino or compatible board attached to your machine and | |
37 // properly appearing as the first virtual serial port ("first" is very | |
38 // loosely defined as whichever port shows up in serial.getPorts). We've | |
39 // tested only the Atmega32u4 Breakout Board and Arduino Leonardo; note that | |
40 // both these boards are based on the Atmel ATmega32u4, rather than the more | |
41 // common Arduino '328p with either FTDI or '8/16u2 USB interfaces. TODO: | |
42 // test more widely. | |
43 // | |
44 // 2. Your user has permission to read/write the port. For example, this | |
45 // might mean that your user is in the "tty" or "uucp" group on Ubuntu | |
46 // flavors of Linux, or else that the port's path (e.g., /dev/ttyACM0) has | |
47 // global read/write permissions. | |
48 // | |
49 // 3. You have uploaded a program to the board that does a byte-for-byte echo | |
50 // on the virtual serial port at 57600 bps. An example is at | |
51 // chrome/test/data/extensions/api_test/serial/api/serial_arduino_test.ino. | |
52 // | |
53 listener.Reply("echo_device_attached"); | |
54 #else | |
55 listener.Reply("false"); | |
56 #endif | 160 #endif |
57 | 161 |
58 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); | 162 ASSERT_TRUE(RunExtensionTest("serial/api")) << message_; |
59 } | 163 } |
OLD | NEW |