1 #include "VirtualTouchpadEvdev.h" 2 3 #include <android/input.h> 4 #include <inttypes.h> 5 #include <linux/input.h> 6 #include <log/log.h> 7 8 // References: 9 // [0] Multi-touch (MT) Protocol, 10 // https://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt 11 12 namespace android { 13 namespace dvr { 14 15 namespace { 16 17 // Virtual evdev device properties. The name is arbitrary, but Android can 18 // use it to look up device configuration, so it must be unique. Vendor and 19 // product values must be 0 to indicate an internal device and prevent a 20 // similar lookup that could conflict with a physical device. 21 static const char* const kDeviceNameFormat = "vr-virtual-touchpad-%d"; 22 static constexpr int16_t kDeviceBusType = BUS_VIRTUAL; 23 static constexpr int16_t kDeviceVendor = 0; 24 static constexpr int16_t kDeviceProduct = 0; 25 static constexpr int16_t kDeviceVersion = 0x0001; 26 27 static constexpr int32_t kWidth = 0x10000; 28 static constexpr int32_t kHeight = 0x10000; 29 static constexpr int32_t kSlots = 2; 30 31 } // anonymous namespace 32 33 std::unique_ptr<VirtualTouchpad> VirtualTouchpadEvdev::Create() { 34 std::unique_ptr<VirtualTouchpadEvdev> touchpad(new VirtualTouchpadEvdev()); 35 touchpad->Reset(); 36 return touchpad; 37 } 38 39 void VirtualTouchpadEvdev::Reset() { 40 for (auto& touchpad : touchpad_) { 41 if (touchpad.injector) { 42 touchpad.injector->Close(); 43 } 44 touchpad.injector = nullptr; 45 touchpad.owned_injector.reset(); 46 touchpad.last_device_x = INT32_MIN; 47 touchpad.last_device_y = INT32_MIN; 48 touchpad.touches = 0; 49 touchpad.last_motion_event_buttons = 0; 50 } 51 } 52 53 status_t VirtualTouchpadEvdev::Attach() { 54 status_t status = OK; 55 for (int i = 0; i < kTouchpads; ++i) { 56 Touchpad& touchpad = touchpad_[i]; 57 if (!touchpad.injector) { 58 touchpad.owned_injector.reset(new EvdevInjector()); 59 touchpad.injector = touchpad.owned_injector.get(); 60 } 61 String8 DeviceName; 62 DeviceName.appendFormat(kDeviceNameFormat, i); 63 touchpad.injector->ConfigureBegin(DeviceName, kDeviceBusType, 64 kDeviceVendor, kDeviceProduct, 65 kDeviceVersion); 66 touchpad.injector->ConfigureInputProperty(INPUT_PROP_DIRECT); 67 touchpad.injector->ConfigureMultiTouchXY(0, 0, kWidth - 1, kHeight - 1); 68 touchpad.injector->ConfigureAbsSlots(kSlots); 69 touchpad.injector->ConfigureKey(BTN_TOUCH); 70 touchpad.injector->ConfigureKey(BTN_BACK); 71 touchpad.injector->ConfigureEnd(); 72 if (const status_t configuration_status = touchpad.injector->GetError()) { 73 status = configuration_status; 74 } 75 } 76 return status; 77 } 78 79 status_t VirtualTouchpadEvdev::Detach() { 80 Reset(); 81 return OK; 82 } 83 84 int VirtualTouchpadEvdev::Touch(int touchpad_id, float x, float y, 85 float pressure) { 86 if (touchpad_id < 0 || touchpad_id >= kTouchpads) { 87 return EINVAL; 88 } 89 if ((x < 0.0f) || (x >= 1.0f) || (y < 0.0f) || (y >= 1.0f)) { 90 return EINVAL; 91 } 92 int32_t device_x = x * kWidth; 93 int32_t device_y = y * kHeight; 94 Touchpad& touchpad = touchpad_[touchpad_id]; 95 touchpad.touches = ((touchpad.touches & 1) << 1) | (pressure > 0); 96 ALOGV("(%f,%f) %f -> (%" PRId32 ",%" PRId32 ") %d", x, y, pressure, device_x, 97 device_y, touchpad.touches); 98 99 if (!touchpad.injector) { 100 return EvdevInjector::ERROR_SEQUENCING; 101 } 102 touchpad.injector->ResetError(); 103 switch (touchpad.touches) { 104 case 0b00: // Hover continues. 105 if (device_x != touchpad.last_device_x || 106 device_y != touchpad.last_device_y) { 107 touchpad.injector->SendMultiTouchXY(0, 0, device_x, device_y); 108 touchpad.injector->SendSynReport(); 109 } 110 break; 111 case 0b01: // Touch begins. 112 // Press. 113 touchpad.injector->SendMultiTouchXY(0, 0, device_x, device_y); 114 touchpad.injector->SendKey(BTN_TOUCH, EvdevInjector::KEY_PRESS); 115 touchpad.injector->SendSynReport(); 116 break; 117 case 0b10: // Touch ends. 118 touchpad.injector->SendKey(BTN_TOUCH, EvdevInjector::KEY_RELEASE); 119 touchpad.injector->SendMultiTouchLift(0); 120 touchpad.injector->SendSynReport(); 121 break; 122 case 0b11: // Touch continues. 123 if (device_x != touchpad.last_device_x || 124 device_y != touchpad.last_device_y) { 125 touchpad.injector->SendMultiTouchXY(0, 0, device_x, device_y); 126 touchpad.injector->SendSynReport(); 127 } 128 break; 129 } 130 touchpad.last_device_x = device_x; 131 touchpad.last_device_y = device_y; 132 133 return touchpad.injector->GetError(); 134 } 135 136 int VirtualTouchpadEvdev::ButtonState(int touchpad_id, int buttons) { 137 if (touchpad_id < 0 || touchpad_id >= kTouchpads) { 138 return EINVAL; 139 } 140 Touchpad& touchpad = touchpad_[touchpad_id]; 141 const int changes = touchpad.last_motion_event_buttons ^ buttons; 142 if (!changes) { 143 return 0; 144 } 145 if (buttons & ~AMOTION_EVENT_BUTTON_BACK) { 146 return ENOTSUP; 147 } 148 ALOGV("change %X from %X to %X", changes, touchpad.last_motion_event_buttons, 149 buttons); 150 151 if (!touchpad.injector) { 152 return EvdevInjector::ERROR_SEQUENCING; 153 } 154 touchpad.injector->ResetError(); 155 if (changes & AMOTION_EVENT_BUTTON_BACK) { 156 touchpad.injector->SendKey(BTN_BACK, (buttons & AMOTION_EVENT_BUTTON_BACK) 157 ? EvdevInjector::KEY_PRESS 158 : EvdevInjector::KEY_RELEASE); 159 touchpad.injector->SendSynReport(); 160 } 161 touchpad.last_motion_event_buttons = buttons; 162 return touchpad.injector->GetError(); 163 } 164 165 void VirtualTouchpadEvdev::dumpInternal(String8& result) { 166 for (int i = 0; i < kTouchpads; ++i) { 167 const auto& touchpad = touchpad_[i]; 168 result.appendFormat("[virtual touchpad %d]\n", i); 169 if (!touchpad.injector) { 170 result.append("injector = none\n"); 171 return; 172 } 173 result.appendFormat("injector = %s\n", 174 touchpad.owned_injector ? "normal" : "test"); 175 result.appendFormat("touches = %d\n", touchpad.touches); 176 result.appendFormat("last_position = (%" PRId32 ", %" PRId32 ")\n", 177 touchpad.last_device_x, touchpad.last_device_y); 178 result.appendFormat("last_buttons = 0x%" PRIX32 "\n", 179 touchpad.last_motion_event_buttons); 180 touchpad.injector->dumpInternal(result); 181 result.append("\n"); 182 } 183 } 184 185 } // namespace dvr 186 } // namespace android 187