blob: c3160758a748d12ea444149a85cfe5f60b7a4482 [file] [log] [blame]
Tim Kilbourn3186e7b2015-04-16 15:32:08 -07001#include "InputMocks.h"
2
3// Private test definitions of opaque HAL structs
4
5// Not used
6struct input_property_map {};
7
8// Holds the key and value from the mock host's PropertyMap
9struct input_property {
10 android::String8 key;
11 android::String8 value;
12};
13
14namespace android {
15
16bool MockInputHost::checkAllocations() const {
17 bool ret = true;
18 if (mMapAllocations != 0) {
19 ALOGE("Leaked %d device property map allocations", mMapAllocations);
20 ret = false;
21 }
22 for (auto entry : mPropertyAllocations) {
23 if (entry.second != 0) {
24 ALOGE("Leaked %d property allocation for %s", entry.second, entry.first.c_str());
25 ret = false;
26 }
27 }
28 return ret;
29}
30
31input_device_identifier_t* MockInputHost::createDeviceIdentifier(
32 const char* name, int32_t product_id, int32_t vendor_id,
33 input_bus_t bus, const char* unique_id) {
34 mDeviceId.reset(new input_device_identifier_t{
35 .name = name,
36 .productId = product_id,
37 .vendorId = vendor_id,
38 .bus = bus,
39 .uniqueId = unique_id
40 });
41 // Just return the raw pointer. We don't have a method for deallocating
42 // device identifiers yet, and they should exist throughout the lifetime of
43 // the input process for now.
44 return mDeviceId.get();
45}
46
47input_property_map_t* MockInputHost::getDevicePropertyMap(input_device_identifier_t* id) {
48 mMapAllocations++;
49 // Handled in the MockInputHost.
50 return nullptr;
51}
52
53input_property_t* MockInputHost::getDeviceProperty(input_property_map_t* map, const char* key) {
54 mPropertyAllocations[key]++;
55 return new input_property_t{.key = String8(key)};
56}
57
58const char* MockInputHost::getPropertyKey(input_property_t* property) {
59 return property->key.string();
60}
61
62const char* MockInputHost::getPropertyValue(input_property_t* property) {
63 if (!mDevicePropertyMap.tryGetProperty(property->key, property->value)) {
64 return nullptr;
65 }
66 return property->value.string();
67}
68
69void MockInputHost::freeDeviceProperty(input_property_t* property) {
70 if (property != nullptr) {
71 mPropertyAllocations[property->key.string()]--;
72 delete property;
73 }
74}
75
76void MockInputHost::freeDevicePropertyMap(input_property_map_t* map) {
77 mMapAllocations--;
78}
79
80input_host_callbacks_t kTestCallbacks = {
81 .create_device_identifier = create_device_identifier,
82 .create_device_definition = create_device_definition,
83 .create_input_report_definition = create_input_report_definition,
84 .create_output_report_definition = create_output_report_definition,
85 .input_device_definition_add_report = input_device_definition_add_report,
86 .input_report_definition_add_collection = input_report_definition_add_collection,
87 .input_report_definition_declare_usage_int = input_report_definition_declare_usage_int,
88 .input_report_definition_declare_usages_bool = input_report_definition_declare_usages_bool,
89 .register_device = register_device,
90 .input_allocate_report = input_allocate_report,
91 .input_report_set_usage_int = input_report_set_usage_int,
92 .input_report_set_usage_bool = input_report_set_usage_bool,
93 .report_event = report_event,
94 .input_get_device_property_map = input_get_device_property_map,
95 .input_get_device_property = input_get_device_property,
96 .input_get_property_key = input_get_property_key,
97 .input_get_property_value = input_get_property_value,
98 .input_free_device_property = input_free_device_property,
99 .input_free_device_property_map = input_free_device_property_map,
100};
101
102bool MockInputDeviceNode::hasKeyInRange(int32_t startKey, int32_t endKey) const {
103 auto iter = mKeys.lower_bound(startKey);
104 if (iter == mKeys.end()) return false;
105 return *iter < endKey;
106}
107
108namespace MockNexus7v2 {
109
110MockInputDeviceNode* getElanTouchscreen() {
111 auto node = new MockInputDeviceNode();
112 node->setPath("/dev/input/event0");
113 node->setName("elan-touchscreen");
114 // Location not set
115 // UniqueId not set
116 node->setBusType(0);
117 node->setVendorId(0);
118 node->setProductId(0);
119 node->setVersion(0);
120 // No keys
121 // No relative axes
122 // TODO: set the AbsoluteAxisInfo pointers
123 node->addAbsAxis(ABS_MT_SLOT, nullptr);
124 node->addAbsAxis(ABS_MT_TOUCH_MAJOR, nullptr);
125 node->addAbsAxis(ABS_MT_POSITION_X, nullptr);
126 node->addAbsAxis(ABS_MT_POSITION_Y, nullptr);
127 node->addAbsAxis(ABS_MT_TRACKING_ID, nullptr);
128 node->addAbsAxis(ABS_MT_PRESSURE, nullptr);
129 // No switches
130 // No forcefeedback
131 node->addInputProperty(INPUT_PROP_DIRECT);
132 return node;
133}
134
135MockInputDeviceNode* getLidInput() {
136 auto node = new MockInputDeviceNode();
137 node->setPath("/dev/input/event1");
138 node->setName("lid_input");
139 node->setLocation("/dev/input/lid_indev");
140 // UniqueId not set
141 node->setBusType(0);
142 node->setVendorId(0);
143 node->setProductId(0);
144 node->setVersion(0);
145 // No keys
146 // No relative axes
147 // No absolute axes
148 node->addSwitch(SW_LID);
149 // No forcefeedback
150 node->addInputProperty(INPUT_PROP_DIRECT);
151 return node;
152}
153
154MockInputDeviceNode* getButtonJack() {
155 auto node = new MockInputDeviceNode();
156 node->setPath("/dev/input/event2");
157 node->setName("apq8064-tabla-snd-card Button Jack");
158 node->setLocation("ALSA");
159 // UniqueId not set
160 node->setBusType(0);
161 node->setVendorId(0);
162 node->setProductId(0);
163 node->setVersion(0);
164 node->addKeys(BTN_0, BTN_1, BTN_2, BTN_3, BTN_4, BTN_5, BTN_6, BTN_7);
165 // No relative axes
166 // No absolute axes
167 // No switches
168 // No forcefeedback
169 node->addInputProperty(INPUT_PROP_DIRECT);
170 return node;
171}
172
173MockInputDeviceNode* getHeadsetJack() {
174 auto node = new MockInputDeviceNode();
175 node->setPath("/dev/input/event3");
176 node->setName("apq8064-tabla-snd-card Headset Jack");
177 node->setLocation("ALSA");
178 // UniqueId not set
179 node->setBusType(0);
180 node->setVendorId(0);
181 node->setProductId(0);
182 node->setVersion(0);
183 // No keys
184 // No relative axes
185 // No absolute axes
186 node->addSwitch(SW_HEADPHONE_INSERT);
187 node->addSwitch(SW_MICROPHONE_INSERT);
188 node->addSwitch(SW_LINEOUT_INSERT);
189 // ASUS adds some proprietary switches, but we'll only see two of them.
190 node->addSwitch(0x0e); // SW_HPHL_OVERCURRENT
191 node->addSwitch(0x0f); // SW_HPHR_OVERCURRENT
192 // No forcefeedback
193 node->addInputProperty(INPUT_PROP_DIRECT);
194 return node;
195}
196
197MockInputDeviceNode* getH2wButton() {
198 auto node = new MockInputDeviceNode();
199 node->setPath("/dev/input/event4");
200 node->setName("h2w button");
201 // Location not set
202 // UniqueId not set
203 node->setBusType(0);
204 node->setVendorId(0);
205 node->setProductId(0);
206 node->setVersion(0);
207 node->addKeys(KEY_MEDIA);
208 // No relative axes
209 // No absolute axes
210 // No switches
211 node->addInputProperty(INPUT_PROP_DIRECT);
212 return node;
213}
214
215MockInputDeviceNode* getGpioKeys() {
216 auto node = new MockInputDeviceNode();
217 node->setPath("/dev/input/event5");
218 node->setName("gpio-keys");
219 node->setLocation("gpio-keys/input0");
220 // UniqueId not set
221 node->setBusType(0x0019);
222 node->setVendorId(0x0001);
223 node->setProductId(0x0001);
224 node->setVersion(0x0100);
225 node->addKeys(KEY_VOLUMEDOWN, KEY_VOLUMEUP, KEY_POWER);
226 // No relative axes
227 // No absolute axes
228 // No switches
229 node->addInputProperty(INPUT_PROP_DIRECT);
230 return node;
231}
232
233} // namespace MockNexus7v2
234
235namespace MockNexusPlayer {
236
237MockInputDeviceNode* getGpioKeys() {
238 auto node = new MockInputDeviceNode();
239 node->setPath("/dev/input/event0");
240 node->setName("gpio-keys");
241 node->setLocation("gpio-keys/input0");
242 // UniqueId not set
243 node->setBusType(0x0019);
244 node->setVendorId(0x0001);
245 node->setProductId(0x0001);
246 node->setVersion(0x0100);
247 node->addKeys(KEY_CONNECT);
248 // No relative axes
249 // No absolute axes
250 // No switches
251 node->addInputProperty(INPUT_PROP_DIRECT);
252 return node;
253}
254
255MockInputDeviceNode* getMidPowerBtn() {
256 auto node = new MockInputDeviceNode();
257 node->setPath("/dev/input/event1");
258 node->setName("mid_powerbtn");
259 node->setLocation("power-button/input0");
260 // UniqueId not set
261 node->setBusType(0x0019);
262 node->setVendorId(0);
263 node->setProductId(0);
264 node->setVersion(0);
265 node->addKeys(KEY_POWER);
266 // No relative axes
267 // No absolute axes
268 // No switches
269 node->addInputProperty(INPUT_PROP_DIRECT);
270 return node;
271}
272
273MockInputDeviceNode* getNexusRemote() {
274 auto node = new MockInputDeviceNode();
275 node->setPath("/dev/input/event2");
276 node->setName("Nexus Remote");
277 // Location not set
278 node->setUniqueId("78:86:D9:50:A0:54");
279 node->setBusType(0x0005);
280 node->setVendorId(0x18d1);
281 node->setProductId(0x2c42);
282 node->setVersion(0);
283 node->addKeys(KEY_UP, KEY_LEFT, KEY_RIGHT, KEY_DOWN, KEY_BACK, KEY_PLAYPAUSE,
284 KEY_HOMEPAGE, KEY_SEARCH, KEY_SELECT);
285 // No relative axes
286 node->addAbsAxis(ABS_MISC, nullptr);
287 // No switches
288 node->addInputProperty(INPUT_PROP_DIRECT);
289 return node;
290}
291
292MockInputDeviceNode* getAsusGamepad() {
293 auto node = new MockInputDeviceNode();
294 node->setPath("/dev/input/event3");
295 node->setName("ASUS Gamepad");
296 // Location not set
297 node->setUniqueId("C5:30:CD:50:A0:54");
298 node->setBusType(0x0005);
299 node->setVendorId(0x0b05);
300 node->setProductId(0x4500);
301 node->setVersion(0x0040);
302 node->addKeys(KEY_BACK, KEY_HOMEPAGE, BTN_A, BTN_B, BTN_X, BTN_Y, BTN_TL, BTN_TR,
303 BTN_MODE, BTN_THUMBL, BTN_THUMBR);
304 // No relative axes
305 node->addAbsAxis(ABS_X, nullptr);
306 node->addAbsAxis(ABS_Y, nullptr);
307 node->addAbsAxis(ABS_Z, nullptr);
308 node->addAbsAxis(ABS_RZ, nullptr);
309 node->addAbsAxis(ABS_GAS, nullptr);
310 node->addAbsAxis(ABS_BRAKE, nullptr);
311 node->addAbsAxis(ABS_HAT0X, nullptr);
312 node->addAbsAxis(ABS_HAT0Y, nullptr);
313 node->addAbsAxis(ABS_MISC, nullptr);
314 node->addAbsAxis(0x29, nullptr);
315 node->addAbsAxis(0x2a, nullptr);
316 // No switches
317 node->addInputProperty(INPUT_PROP_DIRECT);
318 // Note: this device has MSC and LED bitmaps as well.
319 return node;
320}
321
322} // namespace MockNexusPlayer
323
324::input_device_identifier_t* create_device_identifier(input_host_t* host,
325 const char* name, int32_t product_id, int32_t vendor_id,
326 input_bus_t bus, const char* unique_id) {
327 auto mockHost = static_cast<MockInputHost*>(host);
328 return mockHost->createDeviceIdentifier(name, product_id, vendor_id, bus, unique_id);
329}
330
331input_device_definition_t* create_device_definition(input_host_t* host) {
332 return nullptr;
333}
334
335input_report_definition_t* create_input_report_definition(input_host_t* host) {
336 return nullptr;
337}
338
339input_report_definition_t* create_output_report_definition(input_host_t* host) {
340 return nullptr;
341}
342
343void input_device_definition_add_report(input_host_t* host,
344 input_device_definition_t* d, input_report_definition_t* r) { }
345
346void input_report_definition_add_collection(input_host_t* host,
347 input_report_definition_t* report, input_collection_id_t id, int32_t arity) { }
348
349void input_report_definition_declare_usage_int(input_host_t* host,
350 input_report_definition_t* report, input_collection_id_t id,
351 input_usage_t usage, int32_t min, int32_t max, float resolution) { }
352
353void input_report_definition_declare_usages_bool(input_host_t* host,
354 input_report_definition_t* report, input_collection_id_t id,
355 input_usage_t* usage, size_t usage_count) { }
356
357
358input_device_handle_t* register_device(input_host_t* host,
359 input_device_identifier_t* id, input_device_definition_t* d) {
360 return nullptr;
361}
362
363input_report_t* input_allocate_report(input_host_t* host, input_report_definition_t* r) {
364 return nullptr;
365}
366void input_report_set_usage_int(input_host_t* host, input_report_t* r,
367 input_collection_id_t id, input_usage_t usage, int32_t value, int32_t arity_index) { }
368
369void input_report_set_usage_bool(input_host_t* host, input_report_t* r,
370 input_collection_id_t id, input_usage_t usage, bool value, int32_t arity_index) { }
371
372void report_event(input_host_t* host, input_device_handle_t* d, input_report_t* report) { }
373
374input_property_map_t* input_get_device_property_map(input_host_t* host,
375 input_device_identifier_t* id) {
376 auto mockHost = static_cast<MockInputHost*>(host);
377 return mockHost->getDevicePropertyMap(id);
378}
379
380input_property_t* input_get_device_property(input_host_t* host, input_property_map_t* map,
381 const char* key) {
382 auto mockHost = static_cast<MockInputHost*>(host);
383 return mockHost->getDeviceProperty(map, key);
384}
385
386const char* input_get_property_key(input_host_t* host, input_property_t* property) {
387 auto mockHost = static_cast<MockInputHost*>(host);
388 return mockHost->getPropertyKey(property);
389}
390
391const char* input_get_property_value(input_host_t* host, input_property_t* property) {
392 auto mockHost = static_cast<MockInputHost*>(host);
393 return mockHost->getPropertyValue(property);
394}
395
396void input_free_device_property(input_host_t* host, input_property_t* property) {
397 auto mockHost = static_cast<MockInputHost*>(host);
398 return mockHost->freeDeviceProperty(property);
399}
400
401void input_free_device_property_map(input_host_t* host, input_property_map_t* map) {
402 auto mockHost = static_cast<MockInputHost*>(host);
403 return mockHost->freeDevicePropertyMap(map);
404}
405
406} // namespace android