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 Vakulenkovoid DumpDifference(const char* expect, const char* actual) { 114e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko printf(" common: "); 115e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko while (*expect && *expect == *actual) { 116e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko putchar(*expect); 117e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ++expect; 118e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ++actual; 119e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 120e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko printf("\n expect: %s\n", expect); 121e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko printf(" actual: %s\n", actual); 122e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 123e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 124e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // anonymous namespace 125e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 12689af70bce420f011adfeb0f80984b3895c4d7d9bKevin Schoedelclass VirtualTouchpadTest : public testing::Test {}; 127e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 128e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoTEST_F(VirtualTouchpadTest, Goodness) { 129de1cdaebc9b8fdbc5348e6c07f849b74bacc485dKevin Schoedel std::unique_ptr<VirtualTouchpadForTesting> touchpad( 130de1cdaebc9b8fdbc5348e6c07f849b74bacc485dKevin Schoedel VirtualTouchpadForTesting::New()); 131e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko UInputRecorder expect; 132e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 1334b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel status_t touch_status = touchpad->Attach(); 1344b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel EXPECT_EQ(0, touch_status); 1354b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel 136e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Check some aspects of uinput_user_dev. 1370108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel const uinput_user_dev* uidev; 1380108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) { 1390108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel SCOPED_TRACE(t); 1400108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel uidev = touchpad->injector[t].GetUiDev(); 1410108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel String8 name; 142fa5cf46ac7b84cc20bf29e5b8c298a84b407b1e3Santos Cordon name.appendFormat("vr-virtual-touchpad-%d", t); 1430108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(name, uidev->name); 1440108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel for (int i = 0; i < ABS_CNT; ++i) { 1450108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(0, uidev->absmin[i]); 1460108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(0, uidev->absfuzz[i]); 1470108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(0, uidev->absflat[i]); 1480108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel if (i != ABS_MT_POSITION_X && i != ABS_MT_POSITION_Y && 1490108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel i != ABS_MT_SLOT) { 1500108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(0, uidev->absmax[i]); 1510108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel } 152e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 153e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 154e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const int32_t width = 1 + uidev->absmax[ABS_MT_POSITION_X]; 155e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const int32_t height = 1 + uidev->absmax[ABS_MT_POSITION_Y]; 156e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const int32_t slots = uidev->absmax[ABS_MT_SLOT]; 157e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 1580108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) { 1590108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel SCOPED_TRACE(t); 1600108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel // Check the system calls performed by initialization. 1610108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel expect.Reset(); 1620108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel // From ConfigureBegin(): 1630108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel expect.Open(); 1640108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel // From ConfigureInputProperty(INPUT_PROP_DIRECT): 1650108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel expect.IoctlSetInt(UI_SET_PROPBIT, INPUT_PROP_DIRECT); 1660108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel // From ConfigureMultiTouchXY(0, 0, kWidth - 1, kHeight - 1): 1670108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel expect.IoctlSetInt(UI_SET_EVBIT, EV_ABS); 1680108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel expect.IoctlSetInt(UI_SET_ABSBIT, ABS_MT_POSITION_X); 1690108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel expect.IoctlSetInt(UI_SET_ABSBIT, ABS_MT_POSITION_Y); 1700108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel // From ConfigureAbsSlots(kSlots): 1710108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel expect.IoctlSetInt(UI_SET_ABSBIT, ABS_MT_SLOT); 172b2990034866e4f2cce6166b1c1d77dec27770686Kevin Schoedel // From ConfigureRel(REL_WHEEL): 173b2990034866e4f2cce6166b1c1d77dec27770686Kevin Schoedel expect.IoctlSetInt(UI_SET_EVBIT, EV_REL); 174b2990034866e4f2cce6166b1c1d77dec27770686Kevin Schoedel expect.IoctlSetInt(UI_SET_RELBIT, REL_WHEEL); 175b2990034866e4f2cce6166b1c1d77dec27770686Kevin Schoedel // From ConfigureRel(REL_HWHEEL): 176b2990034866e4f2cce6166b1c1d77dec27770686Kevin Schoedel expect.IoctlSetInt(UI_SET_RELBIT, REL_HWHEEL); 1770108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel // From ConfigureKey(BTN_TOUCH): 1780108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel expect.IoctlSetInt(UI_SET_EVBIT, EV_KEY); 1790108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel expect.IoctlSetInt(UI_SET_KEYBIT, BTN_TOUCH); 1800108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel expect.IoctlSetInt(UI_SET_KEYBIT, BTN_BACK); 1810108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel // From ConfigureEnd(): 1820108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel expect.Write(touchpad->injector[t].GetUiDev(), sizeof(uinput_user_dev)); 1830108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel expect.IoctlVoid(UI_DEV_CREATE); 1840108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString()); 1850108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel } 186e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 187e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.Reset(); 188e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.WriteInputEvent(EV_ABS, ABS_MT_SLOT, 0); 189e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.WriteInputEvent(EV_ABS, ABS_MT_TRACKING_ID, 0); 190e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.WriteInputEvent(EV_ABS, ABS_MT_POSITION_X, 0); 191e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.WriteInputEvent(EV_ABS, ABS_MT_POSITION_Y, 0); 192e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.WriteInputEvent(EV_SYN, SYN_REPORT, 0); 1930108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) { 1940108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel SCOPED_TRACE(t); 1950108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad->injector[t].record.Reset(); 1960108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touch_status = touchpad->Touch(t, 0, 0, 0); 1970108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(0, touch_status); 1980108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString()); 1990108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel } 200e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 201e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.Reset(); 202e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.WriteInputEvent(EV_ABS, ABS_MT_TRACKING_ID, 0); 203e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.WriteInputEvent(EV_ABS, ABS_MT_POSITION_X, 0.25f * width); 204e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.WriteInputEvent(EV_ABS, ABS_MT_POSITION_Y, 0.75f * height); 205e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.WriteInputEvent(EV_KEY, BTN_TOUCH, EvdevInjector::KEY_PRESS); 206e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.WriteInputEvent(EV_SYN, SYN_REPORT, 0); 2070108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) { 2080108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel SCOPED_TRACE(t); 2090108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad->injector[t].record.Reset(); 2100108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touch_status = touchpad->Touch(t, 0.25f, 0.75f, 0.5f); 2110108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(0, touch_status); 2120108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString()); 2130108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel } 214e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 215e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.Reset(); 216e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.WriteInputEvent(EV_ABS, ABS_MT_TRACKING_ID, 0); 2174b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel expect.WriteInputEvent(EV_ABS, ABS_MT_POSITION_X, 0.99f * width); 2184b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel expect.WriteInputEvent(EV_ABS, ABS_MT_POSITION_Y, 0.99f * height); 219e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.WriteInputEvent(EV_SYN, SYN_REPORT, 0); 2200108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) { 2210108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel SCOPED_TRACE(t); 2220108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad->injector[t].record.Reset(); 2230108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touch_status = touchpad->Touch(t, 0.99f, 0.99f, 0.99f); 2240108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(0, touch_status); 2250108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString()); 2260108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel } 227e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 228e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.Reset(); 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, 1.0f, 1.0f, 1.0f); 2330108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(EINVAL, touch_status); 2340108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString()); 2350108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel } 2364b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel 2374b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel expect.Reset(); 238e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.WriteInputEvent(EV_KEY, BTN_TOUCH, EvdevInjector::KEY_RELEASE); 239e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.WriteInputEvent(EV_ABS, ABS_MT_TRACKING_ID, -1); 240e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.WriteInputEvent(EV_SYN, SYN_REPORT, 0); 2410108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) { 2420108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel SCOPED_TRACE(t); 2430108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad->injector[t].record.Reset(); 2440108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touch_status = touchpad->Touch(t, 0.25f, 0.75f, -0.01f); 2450108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(0, touch_status); 2460108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString()); 2470108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel } 248e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 249e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko expect.Reset(); 25043b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel expect.WriteInputEvent(EV_KEY, BTN_BACK, EvdevInjector::KEY_PRESS); 25143b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel expect.WriteInputEvent(EV_SYN, SYN_REPORT, 0); 2520108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) { 2530108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel SCOPED_TRACE(t); 2540108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad->injector[t].record.Reset(); 2550108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touch_status = touchpad->ButtonState(t, AMOTION_EVENT_BUTTON_BACK); 2560108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(0, touch_status); 2570108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString()); 2580108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel } 25943b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel 26043b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel expect.Reset(); 2610108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) { 2620108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel SCOPED_TRACE(t); 2630108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad->injector[t].record.Reset(); 2640108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touch_status = touchpad->ButtonState(t, AMOTION_EVENT_BUTTON_BACK); 2650108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(0, touch_status); 2660108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString()); 2670108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel } 26843b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel 26943b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel expect.Reset(); 27043b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel expect.WriteInputEvent(EV_KEY, BTN_BACK, EvdevInjector::KEY_RELEASE); 27143b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel expect.WriteInputEvent(EV_SYN, SYN_REPORT, 0); 2720108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) { 2730108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel SCOPED_TRACE(t); 2740108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad->injector[t].record.Reset(); 2750108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touch_status = touchpad->ButtonState(t, 0); 2760108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(0, touch_status); 2770108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString()); 2780108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel } 27943b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel 28043b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel expect.Reset(); 2810108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel expect.Close(); 2820108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) { 2830108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel SCOPED_TRACE(t); 2840108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touchpad->injector[t].record.Reset(); 2850108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel } 2864b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel touch_status = touchpad->Detach(); 2874b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel EXPECT_EQ(0, touch_status); 2880108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) { 2890108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel SCOPED_TRACE(t); 2900108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString()); 2910108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel } 292e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 293e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 294e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoTEST_F(VirtualTouchpadTest, Badness) { 295de1cdaebc9b8fdbc5348e6c07f849b74bacc485dKevin Schoedel std::unique_ptr<VirtualTouchpadForTesting> touchpad( 296de1cdaebc9b8fdbc5348e6c07f849b74bacc485dKevin Schoedel VirtualTouchpadForTesting::New()); 297e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko UInputRecorder expect; 2980108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel UInputRecorder& record = touchpad->injector[VirtualTouchpad::PRIMARY].record; 29943b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel 3004b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel status_t touch_status = touchpad->Attach(); 3014b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel EXPECT_EQ(0, touch_status); 3024b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel 30343b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel // Touch off-screen should return an error, 30443b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel // and should not result in any system calls. 30543b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel expect.Reset(); 30643b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel record.Reset(); 3070108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touch_status = touchpad->Touch(VirtualTouchpad::PRIMARY, -0.25f, 0.75f, 1.0f); 30889af70bce420f011adfeb0f80984b3895c4d7d9bKevin Schoedel EXPECT_NE(OK, touch_status); 3090108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel touch_status = touchpad->Touch(VirtualTouchpad::PRIMARY, 0.25f, -0.75f, 1.0f); 31089af70bce420f011adfeb0f80984b3895c4d7d9bKevin Schoedel EXPECT_NE(OK, touch_status); 3113002b8a74431dd7c005269cf9306443a4b4963f1Kevin Schoedel touch_status = touchpad->Touch(VirtualTouchpad::PRIMARY, 1.25f, 0.75f, 1.0f); 31289af70bce420f011adfeb0f80984b3895c4d7d9bKevin Schoedel EXPECT_NE(OK, touch_status); 3133002b8a74431dd7c005269cf9306443a4b4963f1Kevin Schoedel touch_status = touchpad->Touch(VirtualTouchpad::PRIMARY, 0.25f, 1.75f, 1.0f); 31489af70bce420f011adfeb0f80984b3895c4d7d9bKevin Schoedel EXPECT_NE(OK, touch_status); 31543b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel EXPECT_EQ(expect.GetString(), record.GetString()); 31643b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel 31743b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel // Unsupported button should return an error, 31843b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel // and should not result in any system calls. 31943b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel expect.Reset(); 32043b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel record.Reset(); 3213002b8a74431dd7c005269cf9306443a4b4963f1Kevin Schoedel touch_status = touchpad->ButtonState(VirtualTouchpad::PRIMARY, 3223002b8a74431dd7c005269cf9306443a4b4963f1Kevin Schoedel AMOTION_EVENT_BUTTON_FORWARD); 32389af70bce420f011adfeb0f80984b3895c4d7d9bKevin Schoedel EXPECT_NE(OK, touch_status); 32443b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel EXPECT_EQ(expect.GetString(), record.GetString()); 3254b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel 3264b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel // Repeated attach is an error. 3274b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel touch_status = touchpad->Attach(); 3284b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel EXPECT_NE(0, touch_status); 329e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 330e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 331e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace dvr 332e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace android 333