189af70bce420f011adfeb0f80984b3895c4d7d9bKevin Schoedel#include "VirtualTouchpadEvdev.h" 2e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 343b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel#include <android/input.h> 4e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <inttypes.h> 5e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <linux/input.h> 64fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko#include <log/log.h> 7e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 843b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel// References: 943b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel// [0] Multi-touch (MT) Protocol, 1043b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel// https://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt 1143b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel 12e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace android { 13e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace dvr { 14e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 15e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace { 16e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 1743b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel// Virtual evdev device properties. The name is arbitrary, but Android can 1843b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel// use it to look up device configuration, so it must be unique. Vendor and 1943b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel// product values must be 0 to indicate an internal device and prevent a 2043b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel// similar lookup that could conflict with a physical device. 21fa5cf46ac7b84cc20bf29e5b8c298a84b407b1e3Santos Cordonstatic const char* const kDeviceNameFormat = "vr-virtual-touchpad-%d"; 22e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostatic constexpr int16_t kDeviceBusType = BUS_VIRTUAL; 2343b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedelstatic constexpr int16_t kDeviceVendor = 0; 2443b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedelstatic constexpr int16_t kDeviceProduct = 0; 25e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostatic constexpr int16_t kDeviceVersion = 0x0001; 2643b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel 27e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostatic constexpr int32_t kWidth = 0x10000; 28e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostatic constexpr int32_t kHeight = 0x10000; 29e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostatic constexpr int32_t kSlots = 2; 30e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 31b2990034866e4f2cce6166b1c1d77dec27770686Kevin Schoedelstatic constexpr float kScrollScale = 100.0f; 32b2990034866e4f2cce6166b1c1d77dec27770686Kevin Schoedel 33d8fccf0124b78230ae2071fecc6bc6aebe8c540cKevin Schoedelint32_t scale_relative_scroll(float x) { 34b2990034866e4f2cce6166b1c1d77dec27770686Kevin Schoedel return kScrollScale * x; 35d8fccf0124b78230ae2071fecc6bc6aebe8c540cKevin Schoedel} 36d8fccf0124b78230ae2071fecc6bc6aebe8c540cKevin Schoedel 37e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // anonymous namespace 38e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 39de1cdaebc9b8fdbc5348e6c07f849b74bacc485dKevin Schoedelstd::unique_ptr<VirtualTouchpad> VirtualTouchpadEvdev::Create() { 40de1cdaebc9b8fdbc5348e6c07f849b74bacc485dKevin Schoedel std::unique_ptr<VirtualTouchpadEvdev> touchpad(new VirtualTouchpadEvdev()); 410108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad->Reset(); 42de1cdaebc9b8fdbc5348e6c07f849b74bacc485dKevin Schoedel return touchpad; 4389af70bce420f011adfeb0f80984b3895c4d7d9bKevin Schoedel} 4489af70bce420f011adfeb0f80984b3895c4d7d9bKevin Schoedel 450108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedelvoid VirtualTouchpadEvdev::Reset() { 460108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel for (auto& touchpad : touchpad_) { 470108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel if (touchpad.injector) { 480108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.injector->Close(); 490108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel } 500108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.injector = nullptr; 510108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.owned_injector.reset(); 520108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.last_device_x = INT32_MIN; 530108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.last_device_y = INT32_MIN; 540108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.touches = 0; 550108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.last_motion_event_buttons = 0; 560108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel } 570108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel} 580108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel 594b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedelstatus_t VirtualTouchpadEvdev::Attach() { 600108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel status_t status = OK; 610108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel for (int i = 0; i < kTouchpads; ++i) { 620108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel Touchpad& touchpad = touchpad_[i]; 630108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel if (!touchpad.injector) { 640108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.owned_injector.reset(new EvdevInjector()); 650108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.injector = touchpad.owned_injector.get(); 660108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel } 670108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel String8 DeviceName; 680108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel DeviceName.appendFormat(kDeviceNameFormat, i); 690108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.injector->ConfigureBegin(DeviceName, kDeviceBusType, 700108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel kDeviceVendor, kDeviceProduct, 710108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel kDeviceVersion); 720108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.injector->ConfigureInputProperty(INPUT_PROP_DIRECT); 730108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.injector->ConfigureMultiTouchXY(0, 0, kWidth - 1, kHeight - 1); 740108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.injector->ConfigureAbsSlots(kSlots); 75b2990034866e4f2cce6166b1c1d77dec27770686Kevin Schoedel touchpad.injector->ConfigureRel(REL_WHEEL); 76b2990034866e4f2cce6166b1c1d77dec27770686Kevin Schoedel touchpad.injector->ConfigureRel(REL_HWHEEL); 770108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.injector->ConfigureKey(BTN_TOUCH); 780108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.injector->ConfigureKey(BTN_BACK); 790108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.injector->ConfigureEnd(); 800108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel if (const status_t configuration_status = touchpad.injector->GetError()) { 810108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel status = configuration_status; 820108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel } 83e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 840108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel return status; 85e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 86e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 874b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedelstatus_t VirtualTouchpadEvdev::Detach() { 880108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel Reset(); 894b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel return OK; 904b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel} 914b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel 920108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedelint VirtualTouchpadEvdev::Touch(int touchpad_id, float x, float y, 933002b8a74431dd7c005269cf9306443a4b4963f1Kevin Schoedel float pressure) { 940108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel if (touchpad_id < 0 || touchpad_id >= kTouchpads) { 950108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel return EINVAL; 960108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel } 97e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int32_t device_x = x * kWidth; 98e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int32_t device_y = y * kHeight; 990108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel Touchpad& touchpad = touchpad_[touchpad_id]; 1000108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.touches = ((touchpad.touches & 1) << 1) | (pressure > 0); 1013002b8a74431dd7c005269cf9306443a4b4963f1Kevin Schoedel ALOGV("(%f,%f) %f -> (%" PRId32 ",%" PRId32 ") %d", x, y, pressure, device_x, 1020108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel device_y, touchpad.touches); 103e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 1040108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel if (!touchpad.injector) { 10543b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel return EvdevInjector::ERROR_SEQUENCING; 10643b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel } 1070108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.injector->ResetError(); 1080108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel switch (touchpad.touches) { 109e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case 0b00: // Hover continues. 1100108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel if (device_x != touchpad.last_device_x || 1110108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel device_y != touchpad.last_device_y) { 1120108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.injector->SendMultiTouchXY(0, 0, device_x, device_y); 1130108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.injector->SendSynReport(); 114e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 115e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko break; 116e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case 0b01: // Touch begins. 117e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Press. 1180108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.injector->SendMultiTouchXY(0, 0, device_x, device_y); 1190108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.injector->SendKey(BTN_TOUCH, EvdevInjector::KEY_PRESS); 1200108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.injector->SendSynReport(); 121e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko break; 122e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case 0b10: // Touch ends. 1230108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.injector->SendKey(BTN_TOUCH, EvdevInjector::KEY_RELEASE); 1240108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.injector->SendMultiTouchLift(0); 1250108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.injector->SendSynReport(); 126e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko break; 127e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case 0b11: // Touch continues. 1280108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel if (device_x != touchpad.last_device_x || 1290108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel device_y != touchpad.last_device_y) { 1300108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.injector->SendMultiTouchXY(0, 0, device_x, device_y); 1310108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.injector->SendSynReport(); 132e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 133e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko break; 134e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 1350108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.last_device_x = device_x; 1360108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.last_device_y = device_y; 137e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 1380108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel return touchpad.injector->GetError(); 139e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 140e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 1410108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedelint VirtualTouchpadEvdev::ButtonState(int touchpad_id, int buttons) { 1420108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel if (touchpad_id < 0 || touchpad_id >= kTouchpads) { 1430108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel return EINVAL; 1440108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel } 1450108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel Touchpad& touchpad = touchpad_[touchpad_id]; 1460108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel const int changes = touchpad.last_motion_event_buttons ^ buttons; 14743b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel if (!changes) { 14843b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel return 0; 14943b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel } 15043b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel if (buttons & ~AMOTION_EVENT_BUTTON_BACK) { 15143b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel return ENOTSUP; 15243b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel } 1530108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel ALOGV("change %X from %X to %X", changes, touchpad.last_motion_event_buttons, 15443b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel buttons); 15543b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel 1560108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel if (!touchpad.injector) { 15743b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel return EvdevInjector::ERROR_SEQUENCING; 15843b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel } 1590108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.injector->ResetError(); 16043b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel if (changes & AMOTION_EVENT_BUTTON_BACK) { 1610108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.injector->SendKey(BTN_BACK, (buttons & AMOTION_EVENT_BUTTON_BACK) 1620108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel ? EvdevInjector::KEY_PRESS 1630108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel : EvdevInjector::KEY_RELEASE); 1640108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.injector->SendSynReport(); 16543b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel } 1660108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.last_motion_event_buttons = buttons; 1670108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel return touchpad.injector->GetError(); 16843b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel} 16943b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel 170d8fccf0124b78230ae2071fecc6bc6aebe8c540cKevin Schoedelint VirtualTouchpadEvdev::Scroll(int touchpad_id, float x, float y) { 171d8fccf0124b78230ae2071fecc6bc6aebe8c540cKevin Schoedel if (touchpad_id < 0 || touchpad_id >= kTouchpads) { 172d8fccf0124b78230ae2071fecc6bc6aebe8c540cKevin Schoedel return EINVAL; 173d8fccf0124b78230ae2071fecc6bc6aebe8c540cKevin Schoedel } 174d8fccf0124b78230ae2071fecc6bc6aebe8c540cKevin Schoedel if ((x < -1.0f) || (x > 1.0f) || (y < -1.0f) || (y > 1.0f)) { 175d8fccf0124b78230ae2071fecc6bc6aebe8c540cKevin Schoedel return EINVAL; 176d8fccf0124b78230ae2071fecc6bc6aebe8c540cKevin Schoedel } 177d8fccf0124b78230ae2071fecc6bc6aebe8c540cKevin Schoedel Touchpad& touchpad = touchpad_[touchpad_id]; 178d8fccf0124b78230ae2071fecc6bc6aebe8c540cKevin Schoedel if (!touchpad.injector) { 179d8fccf0124b78230ae2071fecc6bc6aebe8c540cKevin Schoedel return EvdevInjector::ERROR_SEQUENCING; 180d8fccf0124b78230ae2071fecc6bc6aebe8c540cKevin Schoedel } 181d8fccf0124b78230ae2071fecc6bc6aebe8c540cKevin Schoedel touchpad.injector->ResetError(); 182d8fccf0124b78230ae2071fecc6bc6aebe8c540cKevin Schoedel const int32_t scaled_x = scale_relative_scroll(x); 183d8fccf0124b78230ae2071fecc6bc6aebe8c540cKevin Schoedel const int32_t scaled_y = scale_relative_scroll(y); 184b2990034866e4f2cce6166b1c1d77dec27770686Kevin Schoedel ALOGV("(%f,%f) -> (%" PRId32 ",%" PRId32 ")", x, y, scaled_x, scaled_y); 185d8fccf0124b78230ae2071fecc6bc6aebe8c540cKevin Schoedel if (scaled_x) { 186d8fccf0124b78230ae2071fecc6bc6aebe8c540cKevin Schoedel touchpad.injector->SendRel(REL_HWHEEL, scaled_x); 187d8fccf0124b78230ae2071fecc6bc6aebe8c540cKevin Schoedel } 188d8fccf0124b78230ae2071fecc6bc6aebe8c540cKevin Schoedel if (scaled_y) { 189d8fccf0124b78230ae2071fecc6bc6aebe8c540cKevin Schoedel touchpad.injector->SendRel(REL_WHEEL, scaled_y); 190d8fccf0124b78230ae2071fecc6bc6aebe8c540cKevin Schoedel } 191d8fccf0124b78230ae2071fecc6bc6aebe8c540cKevin Schoedel if (scaled_x || scaled_y) { 192d8fccf0124b78230ae2071fecc6bc6aebe8c540cKevin Schoedel touchpad.injector->SendSynReport(); 193d8fccf0124b78230ae2071fecc6bc6aebe8c540cKevin Schoedel } 194d8fccf0124b78230ae2071fecc6bc6aebe8c540cKevin Schoedel return touchpad.injector->GetError(); 195d8fccf0124b78230ae2071fecc6bc6aebe8c540cKevin Schoedel} 196d8fccf0124b78230ae2071fecc6bc6aebe8c540cKevin Schoedel 1974b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedelvoid VirtualTouchpadEvdev::dumpInternal(String8& result) { 1980108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel for (int i = 0; i < kTouchpads; ++i) { 1990108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel const auto& touchpad = touchpad_[i]; 2000108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel result.appendFormat("[virtual touchpad %d]\n", i); 2010108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel if (!touchpad.injector) { 2020108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel result.append("injector = none\n"); 2030108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel return; 2040108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel } 2050108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel result.appendFormat("injector = %s\n", 2060108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.owned_injector ? "normal" : "test"); 2070108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel result.appendFormat("touches = %d\n", touchpad.touches); 2080108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel result.appendFormat("last_position = (%" PRId32 ", %" PRId32 ")\n", 2090108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.last_device_x, touchpad.last_device_y); 2100108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel result.appendFormat("last_buttons = 0x%" PRIX32 "\n", 2110108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.last_motion_event_buttons); 2120108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad.injector->dumpInternal(result); 2130108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel result.append("\n"); 2144b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel } 2154b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel} 2164b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel 217e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace dvr 218e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace android 219