Upstream version 11.40.271.0
[platform/framework/web/crosswalk.git] / src / extensions / browser / api / hid / hid_apitest.cc
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 "base/run_loop.h"
6 #include "base/thread_task_runner_handle.h"
7 #include "content/public/browser/browser_thread.h"
8 #include "device/hid/hid_collection_info.h"
9 #include "device/hid/hid_connection.h"
10 #include "device/hid/hid_device_info.h"
11 #include "device/hid/hid_service.h"
12 #include "device/hid/hid_usage_and_page.h"
13 #include "extensions/shell/test/shell_apitest.h"
14 #include "net/base/io_buffer.h"
15
16 namespace extensions {
17
18 namespace {
19
20 using base::ThreadTaskRunnerHandle;
21 using content::BrowserThread;
22 using device::HidCollectionInfo;
23 using device::HidConnection;
24 using device::HidDeviceId;
25 using device::HidDeviceInfo;
26 using device::HidService;
27 using device::HidUsageAndPage;
28 using net::IOBuffer;
29
30 class MockHidConnection : public HidConnection {
31  public:
32   MockHidConnection(const HidDeviceInfo& device_info)
33       : HidConnection(device_info) {}
34
35   void PlatformClose() override {}
36
37   void PlatformRead(const ReadCallback& callback) override {
38     const char kResult[] = "This is a HID input report.";
39     uint8_t report_id = device_info().has_report_id ? 1 : 0;
40     scoped_refptr<IOBuffer> buffer(new IOBuffer(sizeof(kResult)));
41     buffer->data()[0] = report_id;
42     memcpy(buffer->data() + 1, kResult, sizeof(kResult) - 1);
43     ThreadTaskRunnerHandle::Get()->PostTask(
44         FROM_HERE, base::Bind(callback, true, buffer, sizeof(kResult)));
45   }
46
47   void PlatformWrite(scoped_refptr<net::IOBuffer> buffer,
48                      size_t size,
49                      const WriteCallback& callback) override {
50     const char kExpected[] = "This is a HID output report.";
51     bool result = false;
52     if (size == sizeof(kExpected)) {
53       uint8_t report_id = buffer->data()[0];
54       uint8_t expected_report_id = device_info().has_report_id ? 1 : 0;
55       if (report_id == expected_report_id) {
56         if (memcmp(buffer->data() + 1, kExpected, sizeof(kExpected) - 1) == 0) {
57           result = true;
58         }
59       }
60     }
61     ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
62                                             base::Bind(callback, result));
63   }
64
65   void PlatformGetFeatureReport(uint8_t report_id,
66                                 const ReadCallback& callback) override {
67     const char kResult[] = "This is a HID feature report.";
68     scoped_refptr<IOBuffer> buffer(new IOBuffer(sizeof(kResult)));
69     size_t offset = 0;
70     if (device_info().has_report_id) {
71       buffer->data()[offset++] = report_id;
72     }
73     memcpy(buffer->data() + offset, kResult, sizeof(kResult) - 1);
74     ThreadTaskRunnerHandle::Get()->PostTask(
75         FROM_HERE,
76         base::Bind(callback, true, buffer, sizeof(kResult) - 1 + offset));
77   }
78
79   void PlatformSendFeatureReport(scoped_refptr<net::IOBuffer> buffer,
80                                  size_t size,
81                                  const WriteCallback& callback) override {
82     const char kExpected[] = "The app is setting this HID feature report.";
83     bool result = false;
84     if (size == sizeof(kExpected)) {
85       uint8_t report_id = buffer->data()[0];
86       uint8_t expected_report_id = device_info().has_report_id ? 1 : 0;
87       if (report_id == expected_report_id &&
88           memcmp(buffer->data() + 1, kExpected, sizeof(kExpected) - 1) == 0) {
89         result = true;
90       }
91     }
92     ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
93                                             base::Bind(callback, result));
94   }
95
96  private:
97   ~MockHidConnection() {}
98 };
99
100 class MockHidService : public HidService {
101  public:
102   MockHidService() : HidService() {
103     {
104       HidDeviceInfo device_info;
105       device_info.device_id = "Device A";
106       device_info.vendor_id = 0x18D1;
107       device_info.product_id = 0x58F0;
108       device_info.max_input_report_size = 128;
109       device_info.max_output_report_size = 128;
110       device_info.max_feature_report_size = 128;
111       {
112         HidCollectionInfo collection_info;
113         device_info.collections.push_back(collection_info);
114       }
115       AddDevice(device_info);
116     }
117
118     {
119       HidDeviceInfo device_info;
120       device_info.device_id = "Device B";
121       device_info.vendor_id = 0x18D1;
122       device_info.product_id = 0x58F0;
123       device_info.max_input_report_size = 128;
124       device_info.max_output_report_size = 128;
125       device_info.max_feature_report_size = 128;
126       {
127         HidCollectionInfo collection_info;
128         collection_info.usage =
129             HidUsageAndPage(0, HidUsageAndPage::kPageVendor);
130         collection_info.report_ids.insert(1);
131         device_info.has_report_id = true;
132         device_info.collections.push_back(collection_info);
133       }
134       AddDevice(device_info);
135     }
136
137     {
138       HidDeviceInfo device_info;
139       device_info.device_id = "Device C";
140       device_info.vendor_id = 0x18D1;
141       device_info.product_id = 0x58F1;
142       device_info.max_input_report_size = 128;
143       device_info.max_output_report_size = 128;
144       device_info.max_feature_report_size = 128;
145       {
146         HidCollectionInfo collection_info;
147         device_info.collections.push_back(collection_info);
148       }
149       AddDevice(device_info);
150     }
151   }
152
153   void Connect(const HidDeviceId& device_id,
154                const ConnectCallback& callback) override {
155     const auto& device_entry = devices().find(device_id);
156     scoped_refptr<HidConnection> connection;
157     if (device_entry != devices().end()) {
158       connection = new MockHidConnection(device_entry->second);
159     }
160
161     ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
162                                             base::Bind(callback, connection));
163   }
164 };
165
166 }  // namespace
167
168 class HidApiTest : public ShellApiTest {
169  public:
170   void SetUpOnMainThread() override {
171     ShellApiTest::SetUpOnMainThread();
172     base::RunLoop run_loop;
173     BrowserThread::PostTaskAndReply(BrowserThread::FILE,
174                                     FROM_HERE,
175                                     base::Bind(&HidApiTest::SetUpService, this),
176                                     run_loop.QuitClosure());
177     run_loop.Run();
178   }
179
180   void SetUpService() { HidService::SetInstanceForTest(new MockHidService()); }
181 };
182
183 IN_PROC_BROWSER_TEST_F(HidApiTest, HidApp) {
184   ASSERT_TRUE(RunAppTest("api_test/hid/api")) << message_;
185 }
186
187 }  // namespace extensions