143b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel#include <android/input.h> 289af70bce420f011adfeb0f80984b3895c4d7d9bKevin Schoedel#include <gtest/gtest.h> 389af70bce420f011adfeb0f80984b3895c4d7d9bKevin Schoedel#include <linux/input.h> 4e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <cstdio> 5e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <cstdlib> 6e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <cstring> 7e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 8e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include "EvdevInjector.h" 989af70bce420f011adfeb0f80984b3895c4d7d9bKevin Schoedel#include "VirtualTouchpadEvdev.h" 10e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 11e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace android { 12e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace dvr { 13e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 14e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace { 15e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 16e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass UInputForTesting : public EvdevInjector::UInput { 17e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public: 183002b8a74431dd7c005269cf9306443a4b4963f1Kevin Schoedel ~UInputForTesting() override {} 19e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void WriteInputEvent(uint16_t type, uint16_t code, int32_t value) { 20e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko struct input_event event; 21e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko memset(&event, 0, sizeof(event)); 22e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko event.type = type; 23e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko event.code = code; 24e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko event.value = value; 2589af70bce420f011adfeb0f80984b3895c4d7d9bKevin Schoedel Write(&event, sizeof(event)); 26e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 27e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 28e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 29e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Recording test implementation of UInput. 30e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// 31e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass UInputRecorder : public UInputForTesting { 32e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public: 33e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko UInputRecorder() {} 343002b8a74431dd7c005269cf9306443a4b4963f1Kevin Schoedel ~UInputRecorder() override {} 35e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 36e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const std::string& GetString() const { return s_; } 37e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void Reset() { s_.clear(); } 38e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 39e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // UInput overrides: 40e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 41e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int Open() override { 42e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko s_ += "o;"; 43e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return 0; 44e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 45e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 46e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int Close() override { 47e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko s_ += "c;"; 48e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return 0; 49e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 50e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 51e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int Write(const void* buf, size_t count) override { 52e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko s_ += "w("; 53e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko s_ += Encode(&count, sizeof(count)); 54e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko s_ += ","; 55e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko s_ += Encode(buf, count); 56e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko s_ += ");"; 57e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return 0; 58e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 59e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 60e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int IoctlVoid(int request) override { 61e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko s_ += "i("; 62e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko s_ += Encode(&request, sizeof(request)); 63e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko s_ += ");"; 64e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return 0; 65e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 66e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 67e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int IoctlSetInt(int request, int value) override { 68e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko s_ += "i("; 69e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko s_ += Encode(&request, sizeof(request)); 70e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko s_ += ","; 71e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko s_ += Encode(&value, sizeof(value)); 72e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko s_ += ");"; 73e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return 0; 74e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 75e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 76e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko private: 77e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::string s_; 78e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 79e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::string Encode(const void* buf, size_t count) { 80e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const char* in = static_cast<const char*>(buf); 81e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko char out[2 * count + 1]; 82e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko for (size_t i = 0; i < count; ++i) { 83e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko snprintf(&out[2 * i], 3, "%02X", in[i]); 84e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 85e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return out; 86e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 87e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 88e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 89e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass EvdevInjectorForTesting : public EvdevInjector { 90e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public: 910108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EvdevInjectorForTesting() { SetUInputForTesting(&record); } 92e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const uinput_user_dev* GetUiDev() const { return GetUiDevForTesting(); } 930108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel UInputRecorder record; 94e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 95e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 9689af70bce420f011adfeb0f80984b3895c4d7d9bKevin Schoedelclass VirtualTouchpadForTesting : public VirtualTouchpadEvdev { 97e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public: 98de1cdaebc9b8fdbc5348e6c07f849b74bacc485dKevin Schoedel static std::unique_ptr<VirtualTouchpad> Create() { 99de1cdaebc9b8fdbc5348e6c07f849b74bacc485dKevin Schoedel return std::unique_ptr<VirtualTouchpad>(New()); 100de1cdaebc9b8fdbc5348e6c07f849b74bacc485dKevin Schoedel } 1010108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel static VirtualTouchpadForTesting* New() { 10289af70bce420f011adfeb0f80984b3895c4d7d9bKevin Schoedel VirtualTouchpadForTesting* const touchpad = new VirtualTouchpadForTesting(); 1030108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad->Reset(); 1040108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel for (int t = 0; t < kTouchpads; ++t) { 1050108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad->SetEvdevInjectorForTesting(t, &touchpad->injector[t]); 1060108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel } 1070108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel return touchpad; 108e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 1090108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel int GetTouchpadCount() const { return kTouchpads; } 1100108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EvdevInjectorForTesting injector[kTouchpads]; 111e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 112e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 113e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // anonymous namespace 114e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 11589af70bce420f011adfeb0f80984b3895c4d7d9bKevin Schoedelclass VirtualTouchpadTest : public testing::Test {}; 116e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 117e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoTEST_F(VirtualTouchpadTest, Goodness) { 118de1cdaebc9b8fdbc5348e6c07f849b74bacc485dKevin Schoedel std::unique_ptr<VirtualTouchpadForTesting> touchpad( 119de1cdaebc9b8fdbc5348e6c07f849b74bacc485dKevin Schoedel VirtualTouchpadForTesting::New()); 120e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko UInputRecorder expect; 121e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 1224b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel status_t touch_status = touchpad->Attach(); 1234b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel EXPECT_EQ(0, touch_status); 1244b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel 125e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Check some aspects of uinput_user_dev. 1260108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel const uinput_user_dev* uidev; 1270108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) { 1280108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel SCOPED_TRACE(t); 1290108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel uidev = touchpad->injector[t].GetUiDev(); 1300108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel String8 name; 131fa5cf46ac7b84cc20bf29e5b8c298a84b407b1e3Santos Cordon name.appendFormat("vr-virtual-touchpad-%d", t); 1320108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(name, uidev->name); 1330108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel for (int i = 0; i < ABS_CNT; ++i) { 1340108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(0, uidev->absmin[i]); 1350108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(0, uidev->absfuzz[i]); 1360108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(0, uidev->absflat[i]); 1370108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel if (i != ABS_MT_POSITION_X && i != ABS_MT_POSITION_Y && 1380108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel i != ABS_MT_SLOT) { 1390108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(0, uidev->absmax[i]); 1400108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel } 141e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 142e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 143e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const int32_t width = 1 + uidev->absmax[ABS_MT_POSITION_X]; 144e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const int32_t height = 1 + uidev->absmax[ABS_MT_POSITION_Y]; 145e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 1460108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) { 1470108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel SCOPED_TRACE(t); 1480108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel // Check the system calls performed by initialization. 1490108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel expect.Reset(); 1500108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel // From ConfigureBegin(): 1510108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel expect.Open(); 1520108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel // From ConfigureInputProperty(INPUT_PROP_DIRECT): 1530108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel expect.IoctlSetInt(UI_SET_PROPBIT, INPUT_PROP_DIRECT); 1540108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel // From ConfigureMultiTouchXY(0, 0, kWidth - 1, kHeight - 1): 1550108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel expect.IoctlSetInt(UI_SET_EVBIT, EV_ABS); 1560108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel expect.IoctlSetInt(UI_SET_ABSBIT, ABS_MT_POSITION_X); 1570108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel expect.IoctlSetInt(UI_SET_ABSBIT, ABS_MT_POSITION_Y); 1580108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel // From ConfigureAbsSlots(kSlots): 1590108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel expect.IoctlSetInt(UI_SET_ABSBIT, ABS_MT_SLOT); 160b2990034866e4f2cce6166b1c1d77dec27770686Kevin Schoedel // From ConfigureRel(REL_WHEEL): 161b2990034866e4f2cce6166b1c1d77dec27770686Kevin Schoedel expect.IoctlSetInt(UI_SET_EVBIT, EV_REL); 162b2990034866e4f2cce6166b1c1d77dec27770686Kevin Schoedel expect.IoctlSetInt(UI_SET_RELBIT, REL_WHEEL); 163b2990034866e4f2cce6166b1c1d77dec27770686Kevin Schoedel // From ConfigureRel(REL_HWHEEL): 164b2990034866e4f2cce6166b1c1d77dec27770686Kevin Schoedel expect.IoctlSetInt(UI_SET_RELBIT, REL_HWHEEL); 1650108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel // From ConfigureKey(BTN_TOUCH): 1660108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel expect.IoctlSetInt(UI_SET_EVBIT, EV_KEY); 1670108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel expect.IoctlSetInt(UI_SET_KEYBIT, BTN_TOUCH); 1680108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel expect.IoctlSetInt(UI_SET_KEYBIT, BTN_BACK); 1690108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel // From ConfigureEnd(): 1700108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel expect.Write(touchpad->injector[t].GetUiDev(), sizeof(uinput_user_dev)); 1710108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel expect.IoctlVoid(UI_DEV_CREATE); 1720108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString()); 1730108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel } 174e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 175e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.Reset(); 176e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.WriteInputEvent(EV_ABS, ABS_MT_SLOT, 0); 177e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.WriteInputEvent(EV_ABS, ABS_MT_TRACKING_ID, 0); 178e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.WriteInputEvent(EV_ABS, ABS_MT_POSITION_X, 0); 179e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.WriteInputEvent(EV_ABS, ABS_MT_POSITION_Y, 0); 180e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.WriteInputEvent(EV_SYN, SYN_REPORT, 0); 1810108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) { 1820108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel SCOPED_TRACE(t); 1830108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad->injector[t].record.Reset(); 1840108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touch_status = touchpad->Touch(t, 0, 0, 0); 1850108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(0, touch_status); 1860108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString()); 1870108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel } 188e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 189e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.Reset(); 190e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.WriteInputEvent(EV_ABS, ABS_MT_TRACKING_ID, 0); 191e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.WriteInputEvent(EV_ABS, ABS_MT_POSITION_X, 0.25f * width); 192e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.WriteInputEvent(EV_ABS, ABS_MT_POSITION_Y, 0.75f * height); 193e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.WriteInputEvent(EV_KEY, BTN_TOUCH, EvdevInjector::KEY_PRESS); 194e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.WriteInputEvent(EV_SYN, SYN_REPORT, 0); 1950108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) { 1960108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel SCOPED_TRACE(t); 1970108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad->injector[t].record.Reset(); 1980108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touch_status = touchpad->Touch(t, 0.25f, 0.75f, 0.5f); 1990108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(0, touch_status); 2000108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString()); 2010108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel } 202e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 203e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.Reset(); 204e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.WriteInputEvent(EV_ABS, ABS_MT_TRACKING_ID, 0); 2054b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel expect.WriteInputEvent(EV_ABS, ABS_MT_POSITION_X, 0.99f * width); 2064b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel expect.WriteInputEvent(EV_ABS, ABS_MT_POSITION_Y, 0.99f * height); 207e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.WriteInputEvent(EV_SYN, SYN_REPORT, 0); 2080108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) { 2090108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel SCOPED_TRACE(t); 2100108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad->injector[t].record.Reset(); 2110108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touch_status = touchpad->Touch(t, 0.99f, 0.99f, 0.99f); 2120108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(0, touch_status); 2130108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString()); 2140108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel } 215e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 216e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.Reset(); 2170108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) { 2180108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel SCOPED_TRACE(t); 2190108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad->injector[t].record.Reset(); 2200108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touch_status = touchpad->Touch(t, 1.0f, 1.0f, 1.0f); 2210108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(EINVAL, touch_status); 2220108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString()); 2230108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel } 2244b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel 2254b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel expect.Reset(); 226e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.WriteInputEvent(EV_KEY, BTN_TOUCH, EvdevInjector::KEY_RELEASE); 227e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.WriteInputEvent(EV_ABS, ABS_MT_TRACKING_ID, -1); 228e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.WriteInputEvent(EV_SYN, SYN_REPORT, 0); 2290108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) { 2300108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel SCOPED_TRACE(t); 2310108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad->injector[t].record.Reset(); 2320108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touch_status = touchpad->Touch(t, 0.25f, 0.75f, -0.01f); 2330108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(0, touch_status); 2340108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString()); 2350108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel } 236e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 237e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.Reset(); 23843b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel expect.WriteInputEvent(EV_KEY, BTN_BACK, EvdevInjector::KEY_PRESS); 23943b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel expect.WriteInputEvent(EV_SYN, SYN_REPORT, 0); 2400108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) { 2410108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel SCOPED_TRACE(t); 2420108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad->injector[t].record.Reset(); 2430108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touch_status = touchpad->ButtonState(t, AMOTION_EVENT_BUTTON_BACK); 2440108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(0, touch_status); 2450108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString()); 2460108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel } 24743b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel 24843b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel expect.Reset(); 2490108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) { 2500108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel SCOPED_TRACE(t); 2510108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad->injector[t].record.Reset(); 2520108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touch_status = touchpad->ButtonState(t, AMOTION_EVENT_BUTTON_BACK); 2530108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(0, touch_status); 2540108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString()); 2550108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel } 25643b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel 25743b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel expect.Reset(); 25843b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel expect.WriteInputEvent(EV_KEY, BTN_BACK, EvdevInjector::KEY_RELEASE); 25943b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel expect.WriteInputEvent(EV_SYN, SYN_REPORT, 0); 2600108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) { 2610108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel SCOPED_TRACE(t); 2620108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad->injector[t].record.Reset(); 2630108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touch_status = touchpad->ButtonState(t, 0); 2640108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(0, touch_status); 2650108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString()); 2660108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel } 26743b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel 26843b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel expect.Reset(); 2690108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel expect.Close(); 2700108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) { 2710108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel SCOPED_TRACE(t); 2720108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad->injector[t].record.Reset(); 2730108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel } 2744b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel touch_status = touchpad->Detach(); 2754b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel EXPECT_EQ(0, touch_status); 2760108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) { 2770108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel SCOPED_TRACE(t); 2780108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString()); 2790108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel } 280e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 281e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 282e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoTEST_F(VirtualTouchpadTest, Badness) { 283de1cdaebc9b8fdbc5348e6c07f849b74bacc485dKevin Schoedel std::unique_ptr<VirtualTouchpadForTesting> touchpad( 284de1cdaebc9b8fdbc5348e6c07f849b74bacc485dKevin Schoedel VirtualTouchpadForTesting::New()); 285e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko UInputRecorder expect; 2860108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel UInputRecorder& record = touchpad->injector[VirtualTouchpad::PRIMARY].record; 28743b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel 2884b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel status_t touch_status = touchpad->Attach(); 2894b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel EXPECT_EQ(0, touch_status); 2904b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel 29143b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel // Touch off-screen should return an error, 29243b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel // and should not result in any system calls. 29343b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel expect.Reset(); 29443b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel record.Reset(); 2950108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touch_status = touchpad->Touch(VirtualTouchpad::PRIMARY, -0.25f, 0.75f, 1.0f); 29689af70bce420f011adfeb0f80984b3895c4d7d9bKevin Schoedel EXPECT_NE(OK, touch_status); 2970108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touch_status = touchpad->Touch(VirtualTouchpad::PRIMARY, 0.25f, -0.75f, 1.0f); 29889af70bce420f011adfeb0f80984b3895c4d7d9bKevin Schoedel EXPECT_NE(OK, touch_status); 2993002b8a74431dd7c005269cf9306443a4b4963f1Kevin Schoedel touch_status = touchpad->Touch(VirtualTouchpad::PRIMARY, 1.25f, 0.75f, 1.0f); 30089af70bce420f011adfeb0f80984b3895c4d7d9bKevin Schoedel EXPECT_NE(OK, touch_status); 3013002b8a74431dd7c005269cf9306443a4b4963f1Kevin Schoedel touch_status = touchpad->Touch(VirtualTouchpad::PRIMARY, 0.25f, 1.75f, 1.0f); 30289af70bce420f011adfeb0f80984b3895c4d7d9bKevin Schoedel EXPECT_NE(OK, touch_status); 30343b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel EXPECT_EQ(expect.GetString(), record.GetString()); 30443b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel 30543b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel // Unsupported button should return an error, 30643b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel // and should not result in any system calls. 30743b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel expect.Reset(); 30843b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel record.Reset(); 3093002b8a74431dd7c005269cf9306443a4b4963f1Kevin Schoedel touch_status = touchpad->ButtonState(VirtualTouchpad::PRIMARY, 3103002b8a74431dd7c005269cf9306443a4b4963f1Kevin Schoedel AMOTION_EVENT_BUTTON_FORWARD); 31189af70bce420f011adfeb0f80984b3895c4d7d9bKevin Schoedel EXPECT_NE(OK, touch_status); 31243b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel EXPECT_EQ(expect.GetString(), record.GetString()); 3134b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel 3144b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel // Repeated attach is an error. 3154b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel touch_status = touchpad->Attach(); 3164b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel EXPECT_NE(0, touch_status); 317e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 318e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 319e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace dvr 320e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace android 321