diff options
51 files changed, 1136 insertions, 753 deletions
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp index 08d4657a48..42887359d1 100644 --- a/cmds/installd/InstalldNativeService.cpp +++ b/cmds/installd/InstalldNativeService.cpp @@ -2684,7 +2684,7 @@ binder::Status InstalldNativeService::invalidateMounts() { } // Mount volume's CE and DE storage to mirror -binder::Status InstalldNativeService::onPrivateVolumeMounted( +binder::Status InstalldNativeService::tryMountDataMirror( const std::unique_ptr<std::string>& uuid) { ENFORCE_UID(AID_SYSTEM); CHECK_ARGUMENT_UUID(uuid); @@ -2696,24 +2696,50 @@ binder::Status InstalldNativeService::onPrivateVolumeMounted( } const char* uuid_ = uuid->c_str(); - // Mount CE mirror + std::string mirrorVolCePath(StringPrintf("%s/%s", kDataMirrorCePath, uuid_)); std::lock_guard<std::recursive_mutex> lock(mLock); - if (fs_prepare_dir(mirrorVolCePath.c_str(), 0700, AID_ROOT, AID_ROOT) != 0) { + if (fs_prepare_dir(mirrorVolCePath.c_str(), 0711, AID_SYSTEM, AID_SYSTEM) != 0) { return error("Failed to create CE mirror"); } - auto cePath = StringPrintf("%s/user_ce", create_data_path(uuid_).c_str()); + + std::string mirrorVolDePath(StringPrintf("%s/%s", kDataMirrorDePath, uuid_)); + if (fs_prepare_dir(mirrorVolDePath.c_str(), 0711, AID_SYSTEM, AID_SYSTEM) != 0) { + return error("Failed to create DE mirror"); + } + + auto cePath = StringPrintf("%s/user", create_data_path(uuid_).c_str()); + auto dePath = StringPrintf("%s/user_de", create_data_path(uuid_).c_str()); + + if (access(cePath.c_str(), F_OK) != 0) { + return error("Cannot access CE path: " + cePath); + } + if (access(dePath.c_str(), F_OK) != 0) { + return error("Cannot access DE path: " + dePath); + } + + struct stat ceStat, mirrorCeStat; + if (stat(cePath.c_str(), &ceStat) != 0) { + return error("Failed to stat " + cePath); + } + if (stat(mirrorVolCePath.c_str(), &mirrorCeStat) != 0) { + return error("Failed to stat " + mirrorVolCePath); + } + + if (mirrorCeStat.st_ino == ceStat.st_ino) { + // As it's being called by prepareUserStorage, it can be called multiple times. + // Hence, we if we mount it already, we should skip it. + LOG(WARNING) << "CE dir is mounted already: " + cePath; + return ok(); + } + + // Mount CE mirror if (TEMP_FAILURE_RETRY(mount(cePath.c_str(), mirrorVolCePath.c_str(), NULL, MS_NOSUID | MS_NODEV | MS_NOATIME | MS_BIND | MS_NOEXEC, nullptr)) == -1) { return error("Failed to mount " + mirrorVolCePath); } // Mount DE mirror - std::string mirrorVolDePath(StringPrintf("%s/%s", kDataMirrorDePath, uuid_)); - if (fs_prepare_dir(mirrorVolDePath.c_str(), 0700, AID_ROOT, AID_ROOT) != 0) { - return error("Failed to create DE mirror"); - } - auto dePath = StringPrintf("%s/user_de", create_data_path(uuid_).c_str()); if (TEMP_FAILURE_RETRY(mount(dePath.c_str(), mirrorVolDePath.c_str(), NULL, MS_NOSUID | MS_NODEV | MS_NOATIME | MS_BIND | MS_NOEXEC, nullptr)) == -1) { return error("Failed to mount " + mirrorVolDePath); diff --git a/cmds/installd/InstalldNativeService.h b/cmds/installd/InstalldNativeService.h index eb35fd3126..27c59b054f 100644 --- a/cmds/installd/InstalldNativeService.h +++ b/cmds/installd/InstalldNativeService.h @@ -155,7 +155,7 @@ public: binder::Status invalidateMounts(); binder::Status isQuotaSupported(const std::unique_ptr<std::string>& volumeUuid, bool* _aidl_return); - binder::Status onPrivateVolumeMounted(const std::unique_ptr<std::string>& volumeUuid); + binder::Status tryMountDataMirror(const std::unique_ptr<std::string>& volumeUuid); binder::Status onPrivateVolumeRemoved(const std::unique_ptr<std::string>& volumeUuid); binder::Status prepareAppProfile(const std::string& packageName, diff --git a/cmds/installd/binder/android/os/IInstalld.aidl b/cmds/installd/binder/android/os/IInstalld.aidl index 80d97038b4..f2e86baabb 100644 --- a/cmds/installd/binder/android/os/IInstalld.aidl +++ b/cmds/installd/binder/android/os/IInstalld.aidl @@ -116,7 +116,7 @@ interface IInstalld { int appId, @utf8InCpp String seInfo, int user, int snapshotId, int storageflags); void destroyAppDataSnapshot(@nullable @utf8InCpp String uuid, @utf8InCpp String packageName, int userId, long ceSnapshotInode, int snapshotId, int storageFlags); - void onPrivateVolumeMounted(@nullable @utf8InCpp String volumeUuid); + void tryMountDataMirror(@nullable @utf8InCpp String volumeUuid); void onPrivateVolumeRemoved(@nullable @utf8InCpp String volumeUuid); void migrateLegacyObbData(); diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp index e2f5d31d00..f6493bf9c7 100644 --- a/libs/gui/BLASTBufferQueue.cpp +++ b/libs/gui/BLASTBufferQueue.cpp @@ -174,7 +174,9 @@ void BLASTBufferQueue::transactionCallback(nsecs_t /*latchTime*/, const sp<Fence } mPendingReleaseItem.item = std::move(mSubmitted.front()); mSubmitted.pop(); - processNextBufferLocked(); + if (mNextTransaction == nullptr) { + processNextBufferLocked(); + } mCallbackCV.notify_all(); decStrong((void*)transactionCallbackThunk); } @@ -252,8 +254,13 @@ Rect BLASTBufferQueue::computeCrop(const BufferItem& item) { void BLASTBufferQueue::onFrameAvailable(const BufferItem& /*item*/) { ATRACE_CALL(); - std::lock_guard _lock{mMutex}; + std::unique_lock _lock{mMutex}; + if (mNextTransaction != nullptr) { + while (mNumFrameAvailable > 0 || mNumAcquired == MAX_ACQUIRED_BUFFERS) { + mCallbackCV.wait(_lock); + } + } // add to shadow queue mNumFrameAvailable++; processNextBufferLocked(); diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index 23532e7e38..278cc593b7 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -1180,6 +1180,9 @@ int Surface::perform(int operation, va_list args) allocateBuffers(); res = NO_ERROR; break; + case NATIVE_WINDOW_GET_LAST_QUEUED_BUFFER: + res = dispatchGetLastQueuedBuffer(args); + break; default: res = NAME_NOT_FOUND; break; @@ -1452,6 +1455,30 @@ int Surface::dispatchAddQueueInterceptor(va_list args) { return NO_ERROR; } +int Surface::dispatchGetLastQueuedBuffer(va_list args) { + AHardwareBuffer** buffer = va_arg(args, AHardwareBuffer**); + int* fence = va_arg(args, int*); + float* matrix = va_arg(args, float*); + sp<GraphicBuffer> graphicBuffer; + sp<Fence> spFence; + + int result = mGraphicBufferProducer->getLastQueuedBuffer(&graphicBuffer, &spFence, matrix); + + if (graphicBuffer != nullptr) { + *buffer = reinterpret_cast<AHardwareBuffer*>(graphicBuffer.get()); + AHardwareBuffer_acquire(*buffer); + } else { + *buffer = nullptr; + } + + if (spFence != nullptr) { + *fence = spFence->dup(); + } else { + *fence = -1; + } + return result; +} + bool Surface::transformToDisplayInverse() { return (mTransform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) == NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY; diff --git a/libs/gui/include/gui/ISurfaceComposerClient.h b/libs/gui/include/gui/ISurfaceComposerClient.h index 2b65d2f42d..6366529a10 100644 --- a/libs/gui/include/gui/ISurfaceComposerClient.h +++ b/libs/gui/include/gui/ISurfaceComposerClient.h @@ -44,7 +44,7 @@ public: eCursorWindow = 0x00002000, eFXSurfaceBufferQueue = 0x00000000, - eFXSurfaceColor = 0x00020000, + eFXSurfaceEffect = 0x00020000, eFXSurfaceBufferState = 0x00040000, eFXSurfaceContainer = 0x00080000, eFXSurfaceMask = 0x000F0000, diff --git a/libs/gui/include/gui/Surface.h b/libs/gui/include/gui/Surface.h index 0139507101..4a353fc659 100644 --- a/libs/gui/include/gui/Surface.h +++ b/libs/gui/include/gui/Surface.h @@ -262,6 +262,7 @@ private: int dispatchAddDequeueInterceptor(va_list args); int dispatchAddPerformInterceptor(va_list args); int dispatchAddQueueInterceptor(va_list args); + int dispatchGetLastQueuedBuffer(va_list args); bool transformToDisplayInverse(); protected: diff --git a/libs/gui/tests/BLASTBufferQueue_test.cpp b/libs/gui/tests/BLASTBufferQueue_test.cpp index e184c7f33b..a87ccd664e 100644 --- a/libs/gui/tests/BLASTBufferQueue_test.cpp +++ b/libs/gui/tests/BLASTBufferQueue_test.cpp @@ -403,7 +403,7 @@ TEST_F(BLASTBufferQueueTest, SetCrop_ScalingModeScaleCrop) { int32_t finalCropSideLength = bufferSideLength / 2; auto bg = mClient->createSurface(String8("BGTest"), 0, 0, PIXEL_FORMAT_RGBA_8888, - ISurfaceComposerClient::eFXSurfaceColor); + ISurfaceComposerClient::eFXSurfaceEffect); ASSERT_NE(nullptr, bg.get()); Transaction t; t.setLayerStack(bg, 0) diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp index 1a623e21dc..c59afba87c 100644 --- a/libs/gui/tests/EndToEndNativeInputTest.cpp +++ b/libs/gui/tests/EndToEndNativeInputTest.cpp @@ -82,7 +82,8 @@ public: int width, int height) { sp<SurfaceControl> surfaceControl = scc->createSurface(String8("Test Surface"), 0 /* bufHeight */, 0 /* bufWidth */, - PIXEL_FORMAT_RGBA_8888, ISurfaceComposerClient::eFXSurfaceColor); + PIXEL_FORMAT_RGBA_8888, + ISurfaceComposerClient::eFXSurfaceEffect); return std::make_unique<InputSurface>(surfaceControl, width, height); } diff --git a/libs/gui/tests/RegionSampling_test.cpp b/libs/gui/tests/RegionSampling_test.cpp index c9de37d957..dbd4ef9d7e 100644 --- a/libs/gui/tests/RegionSampling_test.cpp +++ b/libs/gui/tests/RegionSampling_test.cpp @@ -183,7 +183,7 @@ protected: mBackgroundLayer = mSurfaceComposerClient->createSurface(String8("Background RegionSamplingTest"), 0, 0, PIXEL_FORMAT_RGBA_8888, - ISurfaceComposerClient::eFXSurfaceColor); + ISurfaceComposerClient::eFXSurfaceEffect); uint32_t layerPositionBottom = 0x7E000000; SurfaceComposerClient::Transaction{} .setLayer(mBackgroundLayer, layerPositionBottom) diff --git a/libs/gui/tests/SamplingDemo.cpp b/libs/gui/tests/SamplingDemo.cpp index 9891587fe2..5c1bebb960 100644 --- a/libs/gui/tests/SamplingDemo.cpp +++ b/libs/gui/tests/SamplingDemo.cpp @@ -39,7 +39,7 @@ public: sp<SurfaceComposerClient> client = new SurfaceComposerClient; mButton = client->createSurface(String8(name), 0, 0, PIXEL_FORMAT_RGBA_8888, - ISurfaceComposerClient::eFXSurfaceColor); + ISurfaceComposerClient::eFXSurfaceEffect); const int32_t width = samplingArea.getWidth(); const int32_t height = samplingArea.getHeight(); @@ -55,7 +55,7 @@ public: .apply(); mButtonBlend = client->createSurface(String8(name) + "Blend", 0, 0, PIXEL_FORMAT_RGBA_8888, - ISurfaceComposerClient::eFXSurfaceColor); + ISurfaceComposerClient::eFXSurfaceEffect); SurfaceComposerClient::Transaction{} .setLayer(mButtonBlend, 0x7ffffffe) @@ -73,7 +73,7 @@ public: if (HIGHLIGHT_SAMPLING_AREA) { mSamplingArea = client->createSurface(String8("SamplingArea"), 0, 0, PIXEL_FORMAT_RGBA_8888, - ISurfaceComposerClient::eFXSurfaceColor); + ISurfaceComposerClient::eFXSurfaceEffect); SurfaceComposerClient::Transaction{} .setLayer(mSamplingArea, 0x7ffffffd) diff --git a/libs/nativewindow/include/system/window.h b/libs/nativewindow/include/system/window.h index 121374b1d5..f686147a5f 100644 --- a/libs/nativewindow/include/system/window.h +++ b/libs/nativewindow/include/system/window.h @@ -253,6 +253,7 @@ enum { NATIVE_WINDOW_SET_PERFORM_INTERCEPTOR = 43, /* private */ NATIVE_WINDOW_SET_QUEUE_INTERCEPTOR = 44, /* private */ NATIVE_WINDOW_ALLOCATE_BUFFERS = 45, /* private */ + NATIVE_WINDOW_GET_LAST_QUEUED_BUFFER = 46, /* private */ // clang-format on }; @@ -1018,4 +1019,34 @@ static inline int native_window_set_frame_rate(struct ANativeWindow* window, flo return window->perform(window, NATIVE_WINDOW_SET_FRAME_RATE, (double)frameRate); } +// ------------------------------------------------------------------------------------------------ +// Candidates for APEX visibility +// These functions are planned to be made stable for APEX modules, but have not +// yet been stabilized to a specific api version. +// ------------------------------------------------------------------------------------------------ + +/** + * Retrieves the last queued buffer for this window, along with the fence that + * fires when the buffer is ready to be read, and the 4x4 coordinate + * transform matrix that should be applied to the buffer's content. The + * transform matrix is represented in column-major order. + * + * If there was no buffer previously queued, then outBuffer will be NULL and + * the value of outFence will be -1. + * + * Note that if outBuffer is not NULL, then the caller will hold a reference + * onto the buffer. Accordingly, the caller must call AHardwareBuffer_release + * when the buffer is no longer needed so that the system may reclaim the + * buffer. + * + * \return NO_ERROR on success. + * \return NO_MEMORY if there was insufficient memory. + */ +static inline int ANativeWindow_getLastQueuedBuffer(ANativeWindow* window, + AHardwareBuffer** outBuffer, int* outFence, + float outTransformMatrix[16]) { + return window->perform(window, NATIVE_WINDOW_GET_LAST_QUEUED_BUFFER, outBuffer, outFence, + outTransformMatrix); +} + __END_DECLS diff --git a/services/inputflinger/Android.bp b/services/inputflinger/Android.bp index 308e93aa48..5c80d551b8 100644 --- a/services/inputflinger/Android.bp +++ b/services/inputflinger/Android.bp @@ -40,6 +40,7 @@ cc_library_shared { "libinputreporter", "libinputreader", "libbinder", + "libcrypto", "libcutils", "libhidlbase", "libinput", diff --git a/services/inputflinger/dispatcher/Android.bp b/services/inputflinger/dispatcher/Android.bp index a556aad553..3f956a88fb 100644 --- a/services/inputflinger/dispatcher/Android.bp +++ b/services/inputflinger/dispatcher/Android.bp @@ -28,6 +28,7 @@ cc_library_static { ], shared_libs: [ "libbase", + "libcrypto", "libcutils", "libinput", "libinputreporter", diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index a8158ba3cf..75bc0aa7c8 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -60,7 +60,10 @@ static constexpr bool DEBUG_FOCUS = false; #include <android-base/chrono_utils.h> #include <android-base/stringprintf.h> #include <binder/Binder.h> +#include <input/InputDevice.h> #include <log/log.h> +#include <openssl/hmac.h> +#include <openssl/rand.h> #include <powermanager/PowerManager.h> #include <utils/Trace.h> @@ -325,6 +328,55 @@ static std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inp return dispatchEntry; } +static std::array<uint8_t, 128> getRandomKey() { + std::array<uint8_t, 128> key; + if (RAND_bytes(key.data(), key.size()) != 1) { + LOG_ALWAYS_FATAL("Can't generate HMAC key"); + } + return key; +} + +// --- HmacKeyManager --- + +HmacKeyManager::HmacKeyManager() : mHmacKey(getRandomKey()) {} + +std::array<uint8_t, 32> HmacKeyManager::sign(const VerifiedInputEvent& event) const { + size_t size; + switch (event.type) { + case VerifiedInputEvent::Type::KEY: { + size = sizeof(VerifiedKeyEvent); + break; + } + case VerifiedInputEvent::Type::MOTION: { + size = sizeof(VerifiedMotionEvent); + break; + } + } + std::vector<uint8_t> data; + const uint8_t* start = reinterpret_cast<const uint8_t*>(&event); + data.assign(start, start + size); + return sign(data); +} + +std::array<uint8_t, 32> HmacKeyManager::sign(const std::vector<uint8_t>& data) const { + // SHA256 always generates 32-bytes result + std::array<uint8_t, 32> hash; + unsigned int hashLen = 0; + uint8_t* result = HMAC(EVP_sha256(), mHmacKey.data(), mHmacKey.size(), data.data(), data.size(), + hash.data(), &hashLen); + if (result == nullptr) { + ALOGE("Could not sign the data using HMAC"); + return INVALID_HMAC; + } + + if (hashLen != hash.size()) { + ALOGE("HMAC-SHA256 has unexpected length"); + return INVALID_HMAC; + } + + return hash; +} + // --- InputDispatcher --- InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) @@ -3153,22 +3205,22 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event, int32_t injec std::queue<EventEntry*> injectedEntries; switch (event->getType()) { case AINPUT_EVENT_TYPE_KEY: { - KeyEvent keyEvent; - keyEvent.initialize(*static_cast<const KeyEvent*>(event)); - int32_t action = keyEvent.getAction(); + const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event); + int32_t action = incomingKey.getAction(); if (!validateKeyEvent(action)) { return INPUT_EVENT_INJECTION_FAILED; } - int32_t flags = keyEvent.getFlags(); - int32_t keyCode = keyEvent.getKeyCode(); - int32_t metaState = keyEvent.getMetaState(); - accelerateMetaShortcuts(keyEvent.getDeviceId(), action, + int32_t flags = incomingKey.getFlags(); + int32_t keyCode = incomingKey.getKeyCode(); + int32_t metaState = incomingKey.getMetaState(); + accelerateMetaShortcuts(VIRTUAL_KEYBOARD_ID, action, /*byref*/ keyCode, /*byref*/ metaState); - keyEvent.initialize(keyEvent.getDeviceId(), keyEvent.getSource(), - keyEvent.getDisplayId(), INVALID_HMAC, action, flags, keyCode, - keyEvent.getScanCode(), metaState, keyEvent.getRepeatCount(), - keyEvent.getDownTime(), keyEvent.getEventTime()); + KeyEvent keyEvent; + keyEvent.initialize(VIRTUAL_KEYBOARD_ID, incomingKey.getSource(), + incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode, + incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(), + incomingKey.getDownTime(), incomingKey.getEventTime()); if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) { policyFlags |= POLICY_FLAG_VIRTUAL; @@ -3186,11 +3238,10 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event, int32_t injec mLock.lock(); KeyEntry* injectedEntry = new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, keyEvent.getEventTime(), - keyEvent.getDeviceId(), keyEvent.getSource(), - keyEvent.getDisplayId(), policyFlags, action, flags, - keyEvent.getKeyCode(), keyEvent.getScanCode(), - keyEvent.getMetaState(), keyEvent.getRepeatCount(), - keyEvent.getDownTime()); + VIRTUAL_KEYBOARD_ID, keyEvent.getSource(), keyEvent.getDisplayId(), + policyFlags, action, flags, keyEvent.getKeyCode(), + keyEvent.getScanCode(), keyEvent.getMetaState(), + keyEvent.getRepeatCount(), keyEvent.getDownTime()); injectedEntries.push(injectedEntry); break; } @@ -3221,7 +3272,7 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event, int32_t injec const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords(); MotionEntry* injectedEntry = new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, *sampleEventTimes, - motionEvent->getDeviceId(), motionEvent->getSource(), + VIRTUAL_KEYBOARD_ID, motionEvent->getSource(), motionEvent->getDisplayId(), policyFlags, action, actionButton, motionEvent->getFlags(), motionEvent->getMetaState(), motionEvent->getButtonState(), motionEvent->getClassification(), @@ -3238,7 +3289,7 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event, int32_t injec samplePointerCoords += pointerCount; MotionEntry* nextInjectedEntry = new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, *sampleEventTimes, - motionEvent->getDeviceId(), motionEvent->getSource(), + VIRTUAL_KEYBOARD_ID, motionEvent->getSource(), motionEvent->getDisplayId(), policyFlags, action, actionButton, motionEvent->getFlags(), motionEvent->getMetaState(), motionEvent->getButtonState(), diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h index 72511e9bf2..ded59a595c 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.h +++ b/services/inputflinger/dispatcher/InputDispatcher.h @@ -56,6 +56,16 @@ namespace android::inputdispatcher { class Connection; +class HmacKeyManager { +public: + HmacKeyManager(); + std::array<uint8_t, 32> sign(const VerifiedInputEvent& event) const; + +private: + std::array<uint8_t, 32> sign(const std::vector<uint8_t>& data) const; + const std::array<uint8_t, 128> mHmacKey; +}; + /* Dispatches events to input targets. Some functions of the input dispatcher, such as * identifying input targets, are controlled by a separate policy object. * diff --git a/services/inputflinger/reader/InputDevice.cpp b/services/inputflinger/reader/InputDevice.cpp index 7fed61f09d..1c08ab1ed2 100644 --- a/services/inputflinger/reader/InputDevice.cpp +++ b/services/inputflinger/reader/InputDevice.cpp @@ -18,7 +18,16 @@ #include "InputDevice.h" -#include "InputMapper.h" +#include "CursorInputMapper.h" +#include "ExternalStylusInputMapper.h" +#include "InputReaderContext.h" +#include "JoystickInputMapper.h" +#include "KeyboardInputMapper.h" +#include "MultiTouchInputMapper.h" +#include "RotaryEncoderInputMapper.h" +#include "SingleTouchInputMapper.h" +#include "SwitchInputMapper.h" +#include "VibratorInputMapper.h" namespace android { @@ -36,13 +45,7 @@ InputDevice::InputDevice(InputReaderContext* context, int32_t id, int32_t genera mHasMic(false), mDropUntilNextSync(false) {} -InputDevice::~InputDevice() { - size_t numMappers = mMappers.size(); - for (size_t i = 0; i < numMappers; i++) { - delete mMappers[i]; - } - mMappers.clear(); -} +InputDevice::~InputDevice() {} bool InputDevice::isEnabled() { return getEventHub()->isDeviceEnabled(mId); @@ -110,15 +113,80 @@ void InputDevice::dump(std::string& dump) { } } - size_t numMappers = mMappers.size(); - for (size_t i = 0; i < numMappers; i++) { - InputMapper* mapper = mMappers[i]; - mapper->dump(dump); - } + for_each_mapper([&dump](InputMapper& mapper) { mapper.dump(dump); }); } -void InputDevice::addMapper(InputMapper* mapper) { - mMappers.push_back(mapper); +void InputDevice::populateMappers() { + uint32_t classes = mClasses; + std::vector<std::unique_ptr<InputMapper>>& mappers = mMappers; + + // External devices. + if (classes & INPUT_DEVICE_CLASS_EXTERNAL) { + setExternal(true); + } + + // Devices with mics. + if (classes & INPUT_DEVICE_CLASS_MIC) { + setMic(true); + } + + // Switch-like devices. + if (classes & INPUT_DEVICE_CLASS_SWITCH) { + mappers.push_back(std::make_unique<SwitchInputMapper>(this)); + } + + // Scroll wheel-like devices. + if (classes & INPUT_DEVICE_CLASS_ROTARY_ENCODER) { + mappers.push_back(std::make_unique<RotaryEncoderInputMapper>(this)); + } + + // Vibrator-like devices. + if (classes & INPUT_DEVICE_CLASS_VIBRATOR) { + mappers.push_back(std::make_unique<VibratorInputMapper>(this)); + } + + // Keyboard-like devices. + uint32_t keyboardSource = 0; + int32_t keyboardType = AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC; + if (classes & INPUT_DEVICE_CLASS_KEYBOARD) { + keyboardSource |= AINPUT_SOURCE_KEYBOARD; + } + if (classes & INPUT_DEVICE_CLASS_ALPHAKEY) { + keyboardType = AINPUT_KEYBOARD_TYPE_ALPHABETIC; + } + if (classes & INPUT_DEVICE_CLASS_DPAD) { + keyboardSource |= AINPUT_SOURCE_DPAD; + } + if (classes & INPUT_DEVICE_CLASS_GAMEPAD) { + keyboardSource |= AINPUT_SOURCE_GAMEPAD; + } + + if (keyboardSource != 0) { + mappers.push_back( + std::make_unique<KeyboardInputMapper>(this, keyboardSource, keyboardType)); + } + + // Cursor-like devices. + if (classes & INPUT_DEVICE_CLASS_CURSOR) { + mappers.push_back(std::make_unique<CursorInputMapper>(this)); + } + + // Touchscreens and touchpad devices. + if (classes & INPUT_DEVICE_CLASS_TOUCH_MT) { + mappers.push_back(std::make_unique<MultiTouchInputMapper>(this)); + } else if (classes & INPUT_DEVICE_CLASS_TOUCH) { + mappers.push_back(std::make_unique<SingleTouchInputMapper>(this)); + } + + // Joystick-like devices. + if (classes & INPUT_DEVICE_CLASS_JOYSTICK) { + mappers.push_back(std::make_unique<JoystickInputMapper>(this)); + } + + // External stylus-like devices. + if (classes & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS) { + mappers.push_back(std::make_unique<ExternalStylusInputMapper>(this)); + } } void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config, @@ -193,10 +261,10 @@ void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config } } - for (InputMapper* mapper : mMappers) { - mapper->configure(when, config, changes); - mSources |= mapper->getSources(); - } + for_each_mapper([this, when, config, changes](InputMapper& mapper) { + mapper.configure(when, config, changes); + mSources |= mapper.getSources(); + }); // If a device is just plugged but it might be disabled, we need to update some info like // axis range of touch from each InputMapper first, then disable it. @@ -207,9 +275,7 @@ void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config } void InputDevice::reset(nsecs_t when) { - for (InputMapper* mapper : mMappers) { - mapper->reset(when); - } + for_each_mapper([when](InputMapper& mapper) { mapper.reset(when); }); mContext->updateGlobalMetaState(); @@ -244,32 +310,25 @@ void InputDevice::process(const RawEvent* rawEvents, size_t count) { mDropUntilNextSync = true; reset(rawEvent->when); } else { - for (InputMapper* mapper : mMappers) { - mapper->process(rawEvent); - } + for_each_mapper([rawEvent](InputMapper& mapper) { mapper.process(rawEvent); }); } --count; } } void InputDevice::timeoutExpired(nsecs_t when) { - for (InputMapper* mapper : mMappers) { - mapper->timeoutExpired(when); - } + for_each_mapper([when](InputMapper& mapper) { mapper.timeoutExpired(when); }); } void InputDevice::updateExternalStylusState(const StylusState& state) { - for (InputMapper* mapper : mMappers) { - mapper->updateExternalStylusState(state); - } + for_each_mapper([state](InputMapper& mapper) { mapper.updateExternalStylusState(state); }); } void InputDevice::getDeviceInfo(InputDeviceInfo* outDeviceInfo) { outDeviceInfo->initialize(mId, mGeneration, mControllerNumber, mIdentifier, mAlias, mIsExternal, mHasMic); - for (InputMapper* mapper : mMappers) { - mapper->populateDeviceInfo(outDeviceInfo); - } + for_each_mapper( + [outDeviceInfo](InputMapper& mapper) { mapper.populateDeviceInfo(outDeviceInfo); }); } int32_t InputDevice::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) { @@ -286,11 +345,12 @@ int32_t InputDevice::getSwitchState(uint32_t sourceMask, int32_t switchCode) { int32_t InputDevice::getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc) { int32_t result = AKEY_STATE_UNKNOWN; - for (InputMapper* mapper : mMappers) { - if (sourcesMatchMask(mapper->getSources(), sourceMask)) { + for (auto& mapperPtr : mMappers) { + InputMapper& mapper = *mapperPtr; + if (sourcesMatchMask(mapper.getSources(), sourceMask)) { // If any mapper reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that // value. Otherwise, return AKEY_STATE_UP as long as one mapper reports it. - int32_t currentResult = (mapper->*getStateFunc)(sourceMask, code); + int32_t currentResult = (mapper.*getStateFunc)(sourceMask, code); if (currentResult >= AKEY_STATE_DOWN) { return currentResult; } else if (currentResult == AKEY_STATE_UP) { @@ -304,51 +364,41 @@ int32_t InputDevice::getState(uint32_t sourceMask, int32_t code, GetStateFunc ge bool InputDevice::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) { bool result = false; - for (InputMapper* mapper : mMappers) { - if (sourcesMatchMask(mapper->getSources(), sourceMask)) { - result |= mapper->markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags); + for_each_mapper([&result, sourceMask, numCodes, keyCodes, outFlags](InputMapper& mapper) { + if (sourcesMatchMask(mapper.getSources(), sourceMask)) { + result |= mapper.markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags); } - } + }); return result; } void InputDevice::vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat, int32_t token) { - for (InputMapper* mapper : mMappers) { - mapper->vibrate(pattern, patternSize, repeat, token); - } + for_each_mapper([pattern, patternSize, repeat, token](InputMapper& mapper) { + mapper.vibrate(pattern, patternSize, repeat, token); + }); } void InputDevice::cancelVibrate(int32_t token) { - for (InputMapper* mapper : mMappers) { - mapper->cancelVibrate(token); - } + for_each_mapper([token](InputMapper& mapper) { mapper.cancelVibrate(token); }); } void InputDevice::cancelTouch(nsecs_t when) { - for (InputMapper* mapper : mMappers) { - mapper->cancelTouch(when); - } + for_each_mapper([when](InputMapper& mapper) { mapper.cancelTouch(when); }); } int32_t InputDevice::getMetaState() { int32_t result = 0; - for (InputMapper* mapper : mMappers) { - result |= mapper->getMetaState(); - } + for_each_mapper([&result](InputMapper& mapper) { result |= mapper.getMetaState(); }); return result; } void InputDevice::updateMetaState(int32_t keyCode) { - for (InputMapper* mapper : mMappers) { - mapper->updateMetaState(keyCode); - } + for_each_mapper([keyCode](InputMapper& mapper) { mapper.updateMetaState(keyCode); }); } void InputDevice::fadePointer() { - for (InputMapper* mapper : mMappers) { - mapper->fadePointer(); - } + for_each_mapper([](InputMapper& mapper) { mapper.fadePointer(); }); } void InputDevice::bumpGeneration() { @@ -367,14 +417,8 @@ std::optional<int32_t> InputDevice::getAssociatedDisplayId() { } // No associated display port, check if some InputMapper is associated. - for (InputMapper* mapper : mMappers) { - std::optional<int32_t> associatedDisplayId = mapper->getAssociatedDisplayId(); - if (associatedDisplayId) { - return associatedDisplayId; - } - } - - return std::nullopt; + return first_in_mappers<int32_t>( + [](InputMapper& mapper) { return mapper.getAssociatedDisplayId(); }); } } // namespace android diff --git a/services/inputflinger/reader/InputReader.cpp b/services/inputflinger/reader/InputReader.cpp index 2023c6e8da..010729a6d3 100644 --- a/services/inputflinger/reader/InputReader.cpp +++ b/services/inputflinger/reader/InputReader.cpp @@ -18,33 +18,22 @@ #include "InputReader.h" -#include "CursorInputMapper.h" -#include "ExternalStylusInputMapper.h" -#include "InputReaderContext.h" -#include "JoystickInputMapper.h" -#include "KeyboardInputMapper.h" -#include "MultiTouchInputMapper.h" -#include "RotaryEncoderInputMapper.h" -#include "SingleTouchInputMapper.h" -#include "SwitchInputMapper.h" -#include "VibratorInputMapper.h" - +#include <android-base/stringprintf.h> #include <errno.h> +#include <input/Keyboard.h> +#include <input/VirtualKeyMap.h> #include <inttypes.h> #include <limits.h> +#include <log/log.h> #include <math.h> #include <stddef.h> #include <stdlib.h> #include <unistd.h> - -#include <log/log.h> #include <utils/Errors.h> - -#include <android-base/stringprintf.h> -#include <input/Keyboard.h> -#include <input/VirtualKeyMap.h> #include <utils/Thread.h> +#include "InputDevice.h" + using android::base::StringPrintf; namespace android { @@ -261,74 +250,7 @@ InputDevice* InputReader::createDeviceLocked(int32_t deviceId, int32_t controlle uint32_t classes) { InputDevice* device = new InputDevice(&mContext, deviceId, bumpGenerationLocked(), controllerNumber, identifier, classes); - - // External devices. - if (classes & INPUT_DEVICE_CLASS_EXTERNAL) { - device->setExternal(true); - } - - // Devices with mics. - if (classes & INPUT_DEVICE_CLASS_MIC) { - device->setMic(true); - } - - // Switch-like devices. - if (classes & INPUT_DEVICE_CLASS_SWITCH) { - device->addMapper(new SwitchInputMapper(device)); - } - - // Scroll wheel-like devices. - if (classes & INPUT_DEVICE_CLASS_ROTARY_ENCODER) { - device->addMapper(new RotaryEncoderInputMapper(device)); - } - - // Vibrator-like devices. - if (classes & INPUT_DEVICE_CLASS_VIBRATOR) { - device->addMapper(new VibratorInputMapper(device)); - } - - // Keyboard-like devices. - uint32_t keyboardSource = 0; - int32_t keyboardType = AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC; - if (classes & INPUT_DEVICE_CLASS_KEYBOARD) { - keyboardSource |= AINPUT_SOURCE_KEYBOARD; - } - if (classes & INPUT_DEVICE_CLASS_ALPHAKEY) { - keyboardType = AINPUT_KEYBOARD_TYPE_ALPHABETIC; - } - if (classes & INPUT_DEVICE_CLASS_DPAD) { - keyboardSource |= AINPUT_SOURCE_DPAD; - } - if (classes & INPUT_DEVICE_CLASS_GAMEPAD) { - keyboardSource |= AINPUT_SOURCE_GAMEPAD; - } - - if (keyboardSource != 0) { - device->addMapper(new KeyboardInputMapper(device, keyboardSource, keyboardType)); - } - - // Cursor-like devices. - if (classes & INPUT_DEVICE_CLASS_CURSOR) { - device->addMapper(new CursorInputMapper(device)); - } - - // Touchscreens and touchpad devices. - if (classes & INPUT_DEVICE_CLASS_TOUCH_MT) { - device->addMapper(new MultiTouchInputMapper(device)); - } else if (classes & INPUT_DEVICE_CLASS_TOUCH) { - device->addMapper(new SingleTouchInputMapper(device)); - } - - // Joystick-like devices. - if (classes & INPUT_DEVICE_CLASS_JOYSTICK) { - device->addMapper(new JoystickInputMapper(device)); - } - - // External stylus-like devices. - if (classes & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS) { - device->addMapper(new ExternalStylusInputMapper(device)); - } - + device->populateMappers(); return device; } diff --git a/services/inputflinger/reader/include/InputDevice.h b/services/inputflinger/reader/include/InputDevice.h index 882407dd20..d06cc20719 100644 --- a/services/inputflinger/reader/include/InputDevice.h +++ b/services/inputflinger/reader/include/InputDevice.h @@ -67,7 +67,7 @@ public: void setEnabled(bool enabled, nsecs_t when); void dump(std::string& dump); - void addMapper(InputMapper* mapper); + void populateMappers(); void configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes); void reset(nsecs_t when); void process(const RawEvent* rawEvents, size_t count); @@ -116,6 +116,14 @@ public: std::optional<int32_t> getAssociatedDisplayId(); + // construct and add a mapper to the input device + template <class T, typename... Args> + T& addMapper(Args... args) { + T* mapper = new T(this, args...); + mMappers.emplace_back(mapper); + return *mapper; + } + private: InputReaderContext* mContext; int32_t mId; @@ -125,7 +133,7 @@ private: std::string mAlias; uint32_t mClasses; - std::vector<InputMapper*> mMappers; + std::vector<std::unique_ptr<InputMapper>> mMappers; uint32_t mSources; bool mIsExternal; @@ -138,6 +146,26 @@ private: int32_t getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc); PropertyMap mConfiguration; + + // run a function against every mapper + inline void for_each_mapper(std::function<void(InputMapper&)> f) { + for (auto& mapperPtr : mMappers) { + f(*mapperPtr); + } + } + + // return the first value returned by a function over every mapper. + // if all mappers return nullopt, return nullopt. + template <typename T> + inline std::optional<T> first_in_mappers(std::function<std::optional<T>(InputMapper&)> f) { + for (auto& mapperPtr : mMappers) { + std::optional<T> ret = f(*mapperPtr); + if (ret) { + return ret; + } + } + return std::nullopt; + } }; } // namespace android diff --git a/services/inputflinger/tests/Android.bp b/services/inputflinger/tests/Android.bp index 09ecb13b0a..f913d826bc 100644 --- a/services/inputflinger/tests/Android.bp +++ b/services/inputflinger/tests/Android.bp @@ -10,6 +10,7 @@ cc_test { "InputClassifierConverter_test.cpp", "InputDispatcher_test.cpp", "InputReader_test.cpp", + "UinputDevice.cpp", ], cflags: [ "-Wall", diff --git a/services/inputflinger/tests/EventHub_test.cpp b/services/inputflinger/tests/EventHub_test.cpp index 6504738fc7..be2e19e7df 100644 --- a/services/inputflinger/tests/EventHub_test.cpp +++ b/services/inputflinger/tests/EventHub_test.cpp @@ -16,7 +16,8 @@ #include "EventHub.h" -#include <android-base/stringprintf.h> +#include "UinputDevice.h" + #include <gtest/gtest.h> #include <inttypes.h> #include <linux/uinput.h> @@ -25,16 +26,16 @@ #define TAG "EventHub_test" +using android::createUinputDevice; using android::EventHub; using android::EventHubInterface; using android::InputDeviceIdentifier; using android::RawEvent; using android::sp; -using android::base::StringPrintf; +using android::UinputHomeKey; using std::chrono_literals::operator""ms; static constexpr bool DEBUG = false; -static const char* DEVICE_NAME = "EventHub Test Device"; static void dumpEvents(const std::vector<RawEvent>& events) { for (const RawEvent& event : events) { @@ -62,27 +63,26 @@ class EventHubTest : public testing::Test { protected: std::unique_ptr<EventHubInterface> mEventHub; // We are only going to emulate a single input device currently. - android::base::unique_fd mDeviceFd; + std::unique_ptr<UinputHomeKey> mKeyboard; int32_t mDeviceId; + virtual void SetUp() override { mEventHub = std::make_unique<EventHub>(); consumeInitialDeviceAddedEvents(); - createDevice(); + mKeyboard = createUinputDevice<UinputHomeKey>(); mDeviceId = waitForDeviceCreation(); } virtual void TearDown() override { - mDeviceFd.reset(); + mKeyboard.reset(); waitForDeviceClose(mDeviceId); } - void createDevice(); /** * Return the device id of the created device. */ int32_t waitForDeviceCreation(); void waitForDeviceClose(int32_t deviceId); void consumeInitialDeviceAddedEvents(); - void sendEvent(uint16_t type, uint16_t code, int32_t value); std::vector<RawEvent> getEvents(std::chrono::milliseconds timeout = 5ms); }; @@ -105,48 +105,6 @@ std::vector<RawEvent> EventHubTest::getEvents(std::chrono::milliseconds timeout) return events; } -void EventHubTest::createDevice() { - mDeviceFd = android::base::unique_fd(open("/dev/uinput", O_WRONLY | O_NONBLOCK)); - if (mDeviceFd < 0) { - FAIL() << "Can't open /dev/uinput :" << strerror(errno); - } - - /** - * Signal which type of events this input device supports. - * We will emulate a keyboard here. - */ - // enable key press/release event - if (ioctl(mDeviceFd, UI_SET_EVBIT, EV_KEY)) { - ADD_FAILURE() << "Error in ioctl : UI_SET_EVBIT : EV_KEY: " << strerror(errno); - } - - // enable set of KEY events - if (ioctl(mDeviceFd, UI_SET_KEYBIT, KEY_HOME)) { - ADD_FAILURE() << "Error in ioctl : UI_SET_KEYBIT : KEY_HOME: " << strerror(errno); - } - - // enable synchronization event - if (ioctl(mDeviceFd, UI_SET_EVBIT, EV_SYN)) { - ADD_FAILURE() << "Error in ioctl : UI_SET_EVBIT : EV_SYN: " << strerror(errno); - } - - struct uinput_user_dev keyboard = {}; - strlcpy(keyboard.name, DEVICE_NAME, UINPUT_MAX_NAME_SIZE); - keyboard.id.bustype = BUS_USB; - keyboard.id.vendor = 0x01; - keyboard.id.product = 0x01; - keyboard.id.version = 1; - - if (write(mDeviceFd, &keyboard, sizeof(keyboard)) < 0) { - FAIL() << "Could not write uinput_user_dev struct into uinput file descriptor: " - << strerror(errno); - } - - if (ioctl(mDeviceFd, UI_DEV_CREATE)) { - FAIL() << "Error in ioctl : UI_DEV_CREATE: " << strerror(errno); - } -} - /** * Since the test runs on a real platform, there will be existing devices * in addition to the test devices being added. Therefore, when EventHub is first created, @@ -176,7 +134,7 @@ int32_t EventHubTest::waitForDeviceCreation() { EXPECT_EQ(static_cast<int32_t>(EventHubInterface::DEVICE_ADDED), deviceAddedEvent.type); InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(deviceAddedEvent.deviceId); const int32_t deviceId = deviceAddedEvent.deviceId; - EXPECT_EQ(identifier.name, DEVICE_NAME); + EXPECT_EQ(identifier.name, mKeyboard->getName()); const RawEvent& finishedDeviceScanEvent = events[1]; EXPECT_EQ(static_cast<int32_t>(EventHubInterface::FINISHED_DEVICE_SCAN), finishedDeviceScanEvent.type); @@ -194,22 +152,6 @@ void EventHubTest::waitForDeviceClose(int32_t deviceId) { finishedDeviceScanEvent.type); } -void EventHubTest::sendEvent(uint16_t type, uint16_t code, int32_t value) { - struct input_event event = {}; - event.type = type; - event.code = code; - event.value = value; - event.time = {}; // uinput ignores the timestamp - - if (write(mDeviceFd, &event, sizeof(input_event)) < 0) { - std::string msg = StringPrintf("Could not write event %" PRIu16 " %" PRIu16 - " with value %" PRId32 " : %s", - type, code, value, strerror(errno)); - ALOGE("%s", msg.c_str()); - ADD_FAILURE() << msg.c_str(); - } -} - /** * Ensure that input_events are generated with monotonic clock. * That means input_event should receive a timestamp that is in the future of the time @@ -218,13 +160,7 @@ void EventHubTest::sendEvent(uint16_t type, uint16_t code, int32_t value) { */ TEST_F(EventHubTest, InputEvent_TimestampIsMonotonic) { nsecs_t lastEventTime = systemTime(SYSTEM_TIME_MONOTONIC); - // key press - sendEvent(EV_KEY, KEY_HOME, 1); - sendEvent(EV_SYN, SYN_REPORT, 0); - - // key release - sendEvent(EV_KEY, KEY_HOME, 0); - sendEvent(EV_SYN, SYN_REPORT, 0); + ASSERT_NO_FATAL_FAILURE(mKeyboard->pressAndReleaseHomeKey()); std::vector<RawEvent> events = getEvents(); ASSERT_EQ(4U, events.size()) << "Expected to receive 2 keys and 2 syncs, total of 4 events"; diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp index 27db8f5534..c4092cd696 100644 --- a/services/inputflinger/tests/InputDispatcher_test.cpp +++ b/services/inputflinger/tests/InputDispatcher_test.cpp @@ -43,6 +43,18 @@ struct PointF { float y; }; +/** + * Return a DOWN key event with KEYCODE_A. + */ +static KeyEvent getTestKeyEvent() { + KeyEvent event; + + event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE, INVALID_HMAC, + AKEY_EVENT_ACTION_DOWN, 0, AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, + ARBITRARY_TIME); + return event; +} + // --- FakeInputDispatcherPolicy --- class FakeInputDispatcherPolicy : public InputDispatcherPolicyInterface { @@ -197,6 +209,69 @@ private: } }; +// --- HmacKeyManagerTest --- + +class HmacKeyManagerTest : public testing::Test { +protected: + HmacKeyManager mHmacKeyManager; +}; + +/** + * Ensure that separate calls to sign the same data are generating the same key. + * We avoid asserting against INVALID_HMAC. Since the key is random, there is a non-zero chance + * that a specific key and data combination would produce INVALID_HMAC, which would cause flaky + * tests. + */ +TEST_F(HmacKeyManagerTest, GeneratedHmac_IsConsistent) { + KeyEvent event = getTestKeyEvent(); + VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEvent(event); + + std::array<uint8_t, 32> hmac1 = mHmacKeyManager.sign(verifiedEvent); + std::array<uint8_t, 32> hmac2 = mHmacKeyManager.sign(verifiedEvent); + ASSERT_EQ(hmac1, hmac2); +} + +/** + * Ensure that changes in VerifiedKeyEvent produce a different hmac. + */ +TEST_F(HmacKeyManagerTest, GeneratedHmac_ChangesWhenFieldsChange) { + KeyEvent event = getTestKeyEvent(); + VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEvent(event); + std::array<uint8_t, 32> initialHmac = mHmacKeyManager.sign(verifiedEvent); + + verifiedEvent.deviceId += 1; + ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent)); + + verifiedEvent.source += 1; + ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent)); + + verifiedEvent.eventTimeNanos += 1; + ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent)); + + verifiedEvent.displayId += 1; + ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent)); + + verifiedEvent.action += 1; + ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent)); + + verifiedEvent.downTimeNanos += 1; + ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent)); + + verifiedEvent.flags += 1; + ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent)); + + verifiedEvent.keyCode += 1; + ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent)); + + verifiedEvent.scanCode += 1; + ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent)); + + verifiedEvent.metaState += 1; + ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent)); + + verifiedEvent.repeatCount += 1; + ASSERT_NE(initialHmac, mHmacKeyManager.sign(verifiedEvent)); +} // --- InputDispatcherTest --- diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp index 8ca7e4a893..7cd8793d5a 100644 --- a/services/inputflinger/tests/InputReader_test.cpp +++ b/services/inputflinger/tests/InputReader_test.cpp @@ -1354,22 +1354,22 @@ protected: ASSERT_NO_FATAL_FAILURE(mFakeEventHub->assertQueueIsEmpty()); } - void disableDevice(int32_t deviceId, InputDevice* device) { + void disableDevice(int32_t deviceId) { mFakePolicy->addDisabledDevice(deviceId); mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_ENABLED_STATE); } - void enableDevice(int32_t deviceId, InputDevice* device) { + void enableDevice(int32_t deviceId) { mFakePolicy->removeDisabledDevice(deviceId); mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_ENABLED_STATE); } - FakeInputMapper* addDeviceWithFakeInputMapper(int32_t deviceId, int32_t controllerNumber, - const std::string& name, uint32_t classes, uint32_t sources, - const PropertyMap* configuration) { + FakeInputMapper& addDeviceWithFakeInputMapper(int32_t deviceId, int32_t controllerNumber, + const std::string& name, uint32_t classes, + uint32_t sources, + const PropertyMap* configuration) { InputDevice* device = mReader->newDevice(deviceId, controllerNumber, name, classes); - FakeInputMapper* mapper = new FakeInputMapper(device, sources); - device->addMapper(mapper); + FakeInputMapper& mapper = device->addMapper<FakeInputMapper>(sources); mReader->setNextDevice(device); addDevice(deviceId, name, classes, configuration); return mapper; @@ -1406,8 +1406,7 @@ TEST_F(InputReaderTest, WhenEnabledChanges_SendsDeviceResetNotification) { constexpr uint32_t deviceClass = INPUT_DEVICE_CLASS_KEYBOARD; InputDevice* device = mReader->newDevice(deviceId, 0 /*controllerNumber*/, "fake", deviceClass); // Must add at least one mapper or the device will be ignored! - FakeInputMapper* mapper = new FakeInputMapper(device, AINPUT_SOURCE_KEYBOARD); - device->addMapper(mapper); + device->addMapper<FakeInputMapper>(AINPUT_SOURCE_KEYBOARD); mReader->setNextDevice(device); ASSERT_NO_FATAL_FAILURE(addDevice(deviceId, "fake", deviceClass, nullptr)); @@ -1418,20 +1417,20 @@ TEST_F(InputReaderTest, WhenEnabledChanges_SendsDeviceResetNotification) { ASSERT_EQ(deviceId, resetArgs.deviceId); ASSERT_EQ(device->isEnabled(), true); - disableDevice(deviceId, device); + disableDevice(deviceId); mReader->loopOnce(); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs)); ASSERT_EQ(deviceId, resetArgs.deviceId); ASSERT_EQ(device->isEnabled(), false); - disableDevice(deviceId, device); + disableDevice(deviceId); mReader->loopOnce(); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasNotCalled()); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasNotCalled()); ASSERT_EQ(device->isEnabled(), false); - enableDevice(deviceId, device); + enableDevice(deviceId); mReader->loopOnce(); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs)); ASSERT_EQ(deviceId, resetArgs.deviceId); @@ -1439,10 +1438,10 @@ TEST_F(InputReaderTest, WhenEnabledChanges_SendsDeviceResetNotification) { } TEST_F(InputReaderTest, GetKeyCodeState_ForwardsRequestsToMappers) { - FakeInputMapper* mapper = nullptr; - ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, 0, "fake", - INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, nullptr)); - mapper->setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN); + FakeInputMapper& mapper = + addDeviceWithFakeInputMapper(1, 0, "fake", INPUT_DEVICE_CLASS_KEYBOARD, + AINPUT_SOURCE_KEYBOARD, nullptr); + mapper.setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN); ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getKeyCodeState(0, AINPUT_SOURCE_ANY, AKEYCODE_A)) @@ -1466,10 +1465,10 @@ TEST_F(InputReaderTest, GetKeyCodeState_ForwardsRequestsToMappers) { } TEST_F(InputReaderTest, GetScanCodeState_ForwardsRequestsToMappers) { - FakeInputMapper* mapper = nullptr; - ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, 0, "fake", - INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, nullptr)); - mapper->setScanCodeState(KEY_A, AKEY_STATE_DOWN); + FakeInputMapper& mapper = + addDeviceWithFakeInputMapper(1, 0, "fake", INPUT_DEVICE_CLASS_KEYBOARD, + AINPUT_SOURCE_KEYBOARD, nullptr); + mapper.setScanCodeState(KEY_A, AKEY_STATE_DOWN); ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getScanCodeState(0, AINPUT_SOURCE_ANY, KEY_A)) @@ -1493,10 +1492,10 @@ TEST_F(InputReaderTest, GetScanCodeState_ForwardsRequestsToMappers) { } TEST_F(InputReaderTest, GetSwitchState_ForwardsRequestsToMappers) { - FakeInputMapper* mapper = nullptr; - ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, 0, "fake", - INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, nullptr)); - mapper->setSwitchState(SW_LID, AKEY_STATE_DOWN); + FakeInputMapper& mapper = + addDeviceWithFakeInputMapper(1, 0, "fake", INPUT_DEVICE_CLASS_KEYBOARD, + AINPUT_SOURCE_KEYBOARD, nullptr); + mapper.setSwitchState(SW_LID, AKEY_STATE_DOWN); ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getSwitchState(0, AINPUT_SOURCE_ANY, SW_LID)) @@ -1520,12 +1519,12 @@ TEST_F(InputReaderTest, GetSwitchState_ForwardsRequestsToMappers) { } TEST_F(InputReaderTest, MarkSupportedKeyCodes_ForwardsRequestsToMappers) { - FakeInputMapper* mapper = nullptr; - ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, 0, "fake", - INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, nullptr)); + FakeInputMapper& mapper = + addDeviceWithFakeInputMapper(1, 0, "fake", INPUT_DEVICE_CLASS_KEYBOARD, + AINPUT_SOURCE_KEYBOARD, nullptr); - mapper->addSupportedKeyCode(AKEYCODE_A); - mapper->addSupportedKeyCode(AKEYCODE_B); + mapper.addSupportedKeyCode(AKEYCODE_A); + mapper.addSupportedKeyCode(AKEYCODE_B); const int32_t keyCodes[4] = { AKEYCODE_A, AKEYCODE_B, AKEYCODE_1, AKEYCODE_2 }; uint8_t flags[4] = { 0, 0, 0, 1 }; @@ -1565,16 +1564,16 @@ TEST_F(InputReaderTest, LoopOnce_WhenDeviceScanFinished_SendsConfigurationChange } TEST_F(InputReaderTest, LoopOnce_ForwardsRawEventsToMappers) { - FakeInputMapper* mapper = nullptr; - ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, 0, "fake", - INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, nullptr)); + FakeInputMapper& mapper = + addDeviceWithFakeInputMapper(1, 0, "fake", INPUT_DEVICE_CLASS_KEYBOARD, + AINPUT_SOURCE_KEYBOARD, nullptr); mFakeEventHub->enqueueEvent(0, 1, EV_KEY, KEY_A, 1); mReader->loopOnce(); ASSERT_NO_FATAL_FAILURE(mFakeEventHub->assertQueueIsEmpty()); RawEvent event; - ASSERT_NO_FATAL_FAILURE(mapper->assertProcessWasCalled(&event)); + ASSERT_NO_FATAL_FAILURE(mapper.assertProcessWasCalled(&event)); ASSERT_EQ(0, event.when); ASSERT_EQ(1, event.deviceId); ASSERT_EQ(EV_KEY, event.type); @@ -1587,8 +1586,7 @@ TEST_F(InputReaderTest, DeviceReset_IncrementsSequenceNumber) { constexpr uint32_t deviceClass = INPUT_DEVICE_CLASS_KEYBOARD; InputDevice* device = mReader->newDevice(deviceId, 0 /*controllerNumber*/, "fake", deviceClass); // Must add at least one mapper or the device will be ignored! - FakeInputMapper* mapper = new FakeInputMapper(device, AINPUT_SOURCE_KEYBOARD); - device->addMapper(mapper); + device->addMapper<FakeInputMapper>(AINPUT_SOURCE_KEYBOARD); mReader->setNextDevice(device); ASSERT_NO_FATAL_FAILURE(addDevice(deviceId, "fake", deviceClass, nullptr)); @@ -1596,19 +1594,19 @@ TEST_F(InputReaderTest, DeviceReset_IncrementsSequenceNumber) { ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs)); uint32_t prevSequenceNum = resetArgs.sequenceNum; - disableDevice(deviceId, device); + disableDevice(deviceId); mReader->loopOnce(); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs)); ASSERT_TRUE(prevSequenceNum < resetArgs.sequenceNum); prevSequenceNum = resetArgs.sequenceNum; - enableDevice(deviceId, device); + enableDevice(deviceId); mReader->loopOnce(); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs)); ASSERT_TRUE(prevSequenceNum < resetArgs.sequenceNum); prevSequenceNum = resetArgs.sequenceNum; - disableDevice(deviceId, device); + disableDevice(deviceId); mReader->loopOnce(); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs)); ASSERT_TRUE(prevSequenceNum < resetArgs.sequenceNum); @@ -1621,8 +1619,7 @@ TEST_F(InputReaderTest, Device_CanDispatchToDisplay) { const char* DEVICE_LOCATION = "USB1"; InputDevice* device = mReader->newDevice(deviceId, 0 /*controllerNumber*/, "fake", deviceClass, DEVICE_LOCATION); - FakeInputMapper* mapper = new FakeInputMapper(device, AINPUT_SOURCE_TOUCHSCREEN); - device->addMapper(mapper); + FakeInputMapper& mapper = device->addMapper<FakeInputMapper>(AINPUT_SOURCE_TOUCHSCREEN); mReader->setNextDevice(device); const uint8_t hdmi1 = 1; @@ -1645,7 +1642,7 @@ TEST_F(InputReaderTest, Device_CanDispatchToDisplay) { ASSERT_NO_FATAL_FAILURE(addDevice(deviceId, "fake", deviceClass, nullptr)); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled()); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled()); - ASSERT_NO_FATAL_FAILURE(mapper->assertConfigureWasCalled()); + ASSERT_NO_FATAL_FAILURE(mapper.assertConfigureWasCalled()); // Device should only dispatch to the specified display. ASSERT_EQ(deviceId, device->getId()); @@ -1653,14 +1650,13 @@ TEST_F(InputReaderTest, Device_CanDispatchToDisplay) { ASSERT_TRUE(mReader->canDispatchToDisplay(deviceId, SECONDARY_DISPLAY_ID)); // Can't dispatch event from a disabled device. - disableDevice(deviceId, device); + disableDevice(deviceId); mReader->loopOnce(); ASSERT_FALSE(mReader->canDispatchToDisplay(deviceId, SECONDARY_DISPLAY_ID)); } // --- InputDeviceTest --- - class InputDeviceTest : public testing::Test { protected: static const char* DEVICE_NAME; @@ -1764,21 +1760,19 @@ TEST_F(InputDeviceTest, WhenMappersAreRegistered_DeviceIsNotIgnoredAndForwardsRe // Configuration. mFakeEventHub->addConfigurationProperty(DEVICE_ID, String8("key"), String8("value")); - FakeInputMapper* mapper1 = new FakeInputMapper(mDevice, AINPUT_SOURCE_KEYBOARD); - mapper1->setKeyboardType(AINPUT_KEYBOARD_TYPE_ALPHABETIC); - mapper1->setMetaState(AMETA_ALT_ON); - mapper1->addSupportedKeyCode(AKEYCODE_A); - mapper1->addSupportedKeyCode(AKEYCODE_B); - mapper1->setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN); - mapper1->setKeyCodeState(AKEYCODE_B, AKEY_STATE_UP); - mapper1->setScanCodeState(2, AKEY_STATE_DOWN); - mapper1->setScanCodeState(3, AKEY_STATE_UP); - mapper1->setSwitchState(4, AKEY_STATE_DOWN); - mDevice->addMapper(mapper1); - - FakeInputMapper* mapper2 = new FakeInputMapper(mDevice, AINPUT_SOURCE_TOUCHSCREEN); - mapper2->setMetaState(AMETA_SHIFT_ON); - mDevice->addMapper(mapper2); + FakeInputMapper& mapper1 = mDevice->addMapper<FakeInputMapper>(AINPUT_SOURCE_KEYBOARD); + mapper1.setKeyboardType(AINPUT_KEYBOARD_TYPE_ALPHABETIC); + mapper1.setMetaState(AMETA_ALT_ON); + mapper1.addSupportedKeyCode(AKEYCODE_A); + mapper1.addSupportedKeyCode(AKEYCODE_B); + mapper1.setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN); + mapper1.setKeyCodeState(AKEYCODE_B, AKEY_STATE_UP); + mapper1.setScanCodeState(2, AKEY_STATE_DOWN); + mapper1.setScanCodeState(3, AKEY_STATE_UP); + mapper1.setSwitchState(4, AKEY_STATE_DOWN); + + FakeInputMapper& mapper2 = mDevice->addMapper<FakeInputMapper>(AINPUT_SOURCE_TOUCHSCREEN); + mapper2.setMetaState(AMETA_SHIFT_ON); InputReaderConfiguration config; mDevice->configure(ARBITRARY_TIME, &config, 0); @@ -1788,13 +1782,13 @@ TEST_F(InputDeviceTest, WhenMappersAreRegistered_DeviceIsNotIgnoredAndForwardsRe << "Device should have read configuration during configuration phase."; ASSERT_STREQ("value", propertyValue.string()); - ASSERT_NO_FATAL_FAILURE(mapper1->assertConfigureWasCalled()); - ASSERT_NO_FATAL_FAILURE(mapper2->assertConfigureWasCalled()); + ASSERT_NO_FATAL_FAILURE(mapper1.assertConfigureWasCalled()); + ASSERT_NO_FATAL_FAILURE(mapper2.assertConfigureWasCalled()); // Reset mDevice->reset(ARBITRARY_TIME); - ASSERT_NO_FATAL_FAILURE(mapper1->assertResetWasCalled()); - ASSERT_NO_FATAL_FAILURE(mapper2->assertResetWasCalled()); + ASSERT_NO_FATAL_FAILURE(mapper1.assertResetWasCalled()); + ASSERT_NO_FATAL_FAILURE(mapper2.assertResetWasCalled()); NotifyDeviceResetArgs resetArgs; ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs)); @@ -1850,16 +1844,15 @@ TEST_F(InputDeviceTest, WhenMappersAreRegistered_DeviceIsNotIgnoredAndForwardsRe RawEvent event; mDevice->process(&event, 1); - ASSERT_NO_FATAL_FAILURE(mapper1->assertProcessWasCalled()); - ASSERT_NO_FATAL_FAILURE(mapper2->assertProcessWasCalled()); + ASSERT_NO_FATAL_FAILURE(mapper1.assertProcessWasCalled()); + ASSERT_NO_FATAL_FAILURE(mapper2.assertProcessWasCalled()); } // A single input device is associated with a specific display. Check that: // 1. Device is disabled if the viewport corresponding to the associated display is not found // 2. Device is disabled when setEnabled API is called TEST_F(InputDeviceTest, Configure_AssignsDisplayPort) { - FakeInputMapper* mapper = new FakeInputMapper(mDevice, AINPUT_SOURCE_TOUCHSCREEN); - mDevice->addMapper(mapper); + mDevice->addMapper<FakeInputMapper>(AINPUT_SOURCE_TOUCHSCREEN); // First Configuration. mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), 0); @@ -1944,10 +1937,12 @@ protected: mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), changes); } - void addMapperAndConfigure(InputMapper* mapper) { - mDevice->addMapper(mapper); + template <class T, typename... Args> + T& addMapperAndConfigure(Args... args) { + T& mapper = mDevice->addMapper<T>(args...); configureDevice(0); mDevice->reset(ARBITRARY_TIME); + return mapper; } void setDisplayInfoAndReconfigure(int32_t displayId, int32_t width, int32_t height, @@ -1962,15 +1957,15 @@ protected: mFakePolicy->clearViewports(); } - static void process(InputMapper* mapper, nsecs_t when, int32_t type, - int32_t code, int32_t value) { + static void process(InputMapper& mapper, nsecs_t when, int32_t type, int32_t code, + int32_t value) { RawEvent event; event.when = when; - event.deviceId = mapper->getDeviceId(); + event.deviceId = mapper.getDeviceId(); event.type = type; event.code = code; event.value = value; - mapper->process(&event); + mapper.process(&event); } static void assertMotionRange(const InputDeviceInfo& info, @@ -2024,26 +2019,23 @@ protected: }; TEST_F(SwitchInputMapperTest, GetSources) { - SwitchInputMapper* mapper = new SwitchInputMapper(mDevice); - addMapperAndConfigure(mapper); + SwitchInputMapper& mapper = addMapperAndConfigure<SwitchInputMapper>(); - ASSERT_EQ(uint32_t(AINPUT_SOURCE_SWITCH), mapper->getSources()); + ASSERT_EQ(uint32_t(AINPUT_SOURCE_SWITCH), mapper.getSources()); } TEST_F(SwitchInputMapperTest, GetSwitchState) { - SwitchInputMapper* mapper = new SwitchInputMapper(mDevice); - addMapperAndConfigure(mapper); + SwitchInputMapper& mapper = addMapperAndConfigure<SwitchInputMapper>(); mFakeEventHub->setSwitchState(DEVICE_ID, SW_LID, 1); - ASSERT_EQ(1, mapper->getSwitchState(AINPUT_SOURCE_ANY, SW_LID)); + ASSERT_EQ(1, mapper.getSwitchState(AINPUT_SOURCE_ANY, SW_LID)); mFakeEventHub->setSwitchState(DEVICE_ID, SW_LID, 0); - ASSERT_EQ(0, mapper->getSwitchState(AINPUT_SOURCE_ANY, SW_LID)); + ASSERT_EQ(0, mapper.getSwitchState(AINPUT_SOURCE_ANY, SW_LID)); } TEST_F(SwitchInputMapperTest, Process) { - SwitchInputMapper* mapper = new SwitchInputMapper(mDevice); - addMapperAndConfigure(mapper); + SwitchInputMapper& mapper = addMapperAndConfigure<SwitchInputMapper>(); process(mapper, ARBITRARY_TIME, EV_SW, SW_LID, 1); process(mapper, ARBITRARY_TIME, EV_SW, SW_JACK_PHYSICAL_INSERT, 1); @@ -2068,7 +2060,7 @@ protected: void prepareDisplay(int32_t orientation); - void testDPadKeyRotation(KeyboardInputMapper* mapper, int32_t originalScanCode, + void testDPadKeyRotation(KeyboardInputMapper& mapper, int32_t originalScanCode, int32_t originalKeyCode, int32_t rotatedKeyCode, int32_t displayId = ADISPLAY_ID_NONE); }; @@ -2081,7 +2073,7 @@ void KeyboardInputMapperTest::prepareDisplay(int32_t orientation) { orientation, UNIQUE_ID, NO_PORT, ViewportType::VIEWPORT_INTERNAL); } -void KeyboardInputMapperTest::testDPadKeyRotation(KeyboardInputMapper* mapper, +void KeyboardInputMapperTest::testDPadKeyRotation(KeyboardInputMapper& mapper, int32_t originalScanCode, int32_t originalKeyCode, int32_t rotatedKeyCode, int32_t displayId) { NotifyKeyArgs args; @@ -2102,11 +2094,11 @@ void KeyboardInputMapperTest::testDPadKeyRotation(KeyboardInputMapper* mapper, } TEST_F(KeyboardInputMapperTest, GetSources) { - KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, - AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); - addMapperAndConfigure(mapper); + KeyboardInputMapper& mapper = + addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD, + AINPUT_KEYBOARD_TYPE_ALPHABETIC); - ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, mapper->getSources()); + ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, mapper.getSources()); } TEST_F(KeyboardInputMapperTest, Process_SimpleKeyPress) { @@ -2115,9 +2107,9 @@ TEST_F(KeyboardInputMapperTest, Process_SimpleKeyPress) { mFakeEventHub->addKey(DEVICE_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE); mFakeEventHub->addKey(DEVICE_ID, 0, USAGE_A, AKEYCODE_A, POLICY_FLAG_WAKE); - KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, - AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); - addMapperAndConfigure(mapper); + KeyboardInputMapper& mapper = + addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD, + AINPUT_KEYBOARD_TYPE_ALPHABETIC); // Key down by scan code. process(mapper, ARBITRARY_TIME, EV_KEY, KEY_HOME, 1); @@ -2213,38 +2205,38 @@ TEST_F(KeyboardInputMapperTest, Process_ShouldUpdateMetaState) { mFakeEventHub->addKey(DEVICE_ID, KEY_LEFTSHIFT, 0, AKEYCODE_SHIFT_LEFT, 0); mFakeEventHub->addKey(DEVICE_ID, KEY_A, 0, AKEYCODE_A, 0); - KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, - AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); - addMapperAndConfigure(mapper); + KeyboardInputMapper& mapper = + addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD, + AINPUT_KEYBOARD_TYPE_ALPHABETIC); // Initial metastate. - ASSERT_EQ(AMETA_NONE, mapper->getMetaState()); + ASSERT_EQ(AMETA_NONE, mapper.getMetaState()); // Metakey down. process(mapper, ARBITRARY_TIME, EV_KEY, KEY_LEFTSHIFT, 1); NotifyKeyArgs args; ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args)); ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState); - ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper->getMetaState()); + ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper.getMetaState()); ASSERT_NO_FATAL_FAILURE(mFakeContext->assertUpdateGlobalMetaStateWasCalled()); // Key down. process(mapper, ARBITRARY_TIME + 1, EV_KEY, KEY_A, 1); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args)); ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState); - ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper->getMetaState()); + ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper.getMetaState()); // Key up. process(mapper, ARBITRARY_TIME + 2, EV_KEY, KEY_A, 0); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args)); ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState); - ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper->getMetaState()); + ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper.getMetaState()); // Metakey up. process(mapper, ARBITRARY_TIME + 3, EV_KEY, KEY_LEFTSHIFT, 0); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args)); ASSERT_EQ(AMETA_NONE, args.metaState); - ASSERT_EQ(AMETA_NONE, mapper->getMetaState()); + ASSERT_EQ(AMETA_NONE, mapper.getMetaState()); ASSERT_NO_FATAL_FAILURE(mFakeContext->assertUpdateGlobalMetaStateWasCalled()); } @@ -2254,9 +2246,9 @@ TEST_F(KeyboardInputMapperTest, Process_WhenNotOrientationAware_ShouldNotRotateD mFakeEventHub->addKey(DEVICE_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0); mFakeEventHub->addKey(DEVICE_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0); - KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, - AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); - addMapperAndConfigure(mapper); + KeyboardInputMapper& mapper = + addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD, + AINPUT_KEYBOARD_TYPE_ALPHABETIC); prepareDisplay(DISPLAY_ORIENTATION_90); ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, @@ -2275,10 +2267,10 @@ TEST_F(KeyboardInputMapperTest, Process_WhenOrientationAware_ShouldRotateDPad) { mFakeEventHub->addKey(DEVICE_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0); mFakeEventHub->addKey(DEVICE_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0); - KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, - AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); addConfigurationProperty("keyboard.orientationAware", "1"); - addMapperAndConfigure(mapper); + KeyboardInputMapper& mapper = + addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD, + AINPUT_KEYBOARD_TYPE_ALPHABETIC); prepareDisplay(DISPLAY_ORIENTATION_0); ASSERT_NO_FATAL_FAILURE( @@ -2348,9 +2340,9 @@ TEST_F(KeyboardInputMapperTest, DisplayIdConfigurationChange_NotOrientationAware // key events should not be associated with a specific display id mFakeEventHub->addKey(DEVICE_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0); - KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, - AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); - addMapperAndConfigure(mapper); + KeyboardInputMapper& mapper = + addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD, + AINPUT_KEYBOARD_TYPE_ALPHABETIC); NotifyKeyArgs args; // Display id should be ADISPLAY_ID_NONE without any display configuration. @@ -2373,10 +2365,10 @@ TEST_F(KeyboardInputMapperTest, DisplayIdConfigurationChange_OrientationAware) { // key events should be associated with the internal viewport mFakeEventHub->addKey(DEVICE_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0); - KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, - AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); addConfigurationProperty("keyboard.orientationAware", "1"); - addMapperAndConfigure(mapper); + KeyboardInputMapper& mapper = + addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD, + AINPUT_KEYBOARD_TYPE_ALPHABETIC); NotifyKeyArgs args; // Display id should be ADISPLAY_ID_NONE without any display configuration. @@ -2402,39 +2394,39 @@ TEST_F(KeyboardInputMapperTest, DisplayIdConfigurationChange_OrientationAware) { } TEST_F(KeyboardInputMapperTest, GetKeyCodeState) { - KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, - AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); - addMapperAndConfigure(mapper); + KeyboardInputMapper& mapper = + addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD, + AINPUT_KEYBOARD_TYPE_ALPHABETIC); mFakeEventHub->setKeyCodeState(DEVICE_ID, AKEYCODE_A, 1); - ASSERT_EQ(1, mapper->getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A)); + ASSERT_EQ(1, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A)); mFakeEventHub->setKeyCodeState(DEVICE_ID, AKEYCODE_A, 0); - ASSERT_EQ(0, mapper->getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A)); + ASSERT_EQ(0, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A)); } TEST_F(KeyboardInputMapperTest, GetScanCodeState) { - KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, - AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); - addMapperAndConfigure(mapper); + KeyboardInputMapper& mapper = + addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD, + AINPUT_KEYBOARD_TYPE_ALPHABETIC); mFakeEventHub->setScanCodeState(DEVICE_ID, KEY_A, 1); - ASSERT_EQ(1, mapper->getScanCodeState(AINPUT_SOURCE_ANY, KEY_A)); + ASSERT_EQ(1, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_A)); mFakeEventHub->setScanCodeState(DEVICE_ID, KEY_A, 0); - ASSERT_EQ(0, mapper->getScanCodeState(AINPUT_SOURCE_ANY, KEY_A)); + ASSERT_EQ(0, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_A)); } TEST_F(KeyboardInputMapperTest, MarkSupportedKeyCodes) { - KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, - AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); - addMapperAndConfigure(mapper); + KeyboardInputMapper& mapper = + addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD, + AINPUT_KEYBOARD_TYPE_ALPHABETIC); mFakeEventHub->addKey(DEVICE_ID, KEY_A, 0, AKEYCODE_A, 0); const int32_t keyCodes[2] = { AKEYCODE_A, AKEYCODE_B }; uint8_t flags[2] = { 0, 0 }; - ASSERT_TRUE(mapper->markSupportedKeyCodes(AINPUT_SOURCE_ANY, 1, keyCodes, flags)); + ASSERT_TRUE(mapper.markSupportedKeyCodes(AINPUT_SOURCE_ANY, 1, keyCodes, flags)); ASSERT_TRUE(flags[0]); ASSERT_FALSE(flags[1]); } @@ -2447,9 +2439,9 @@ TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleMetaStateAndLeds) mFakeEventHub->addKey(DEVICE_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0); mFakeEventHub->addKey(DEVICE_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0); - KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, - AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); - addMapperAndConfigure(mapper); + KeyboardInputMapper& mapper = + addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD, + AINPUT_KEYBOARD_TYPE_ALPHABETIC); // Initialization should have turned all of the lights off. ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL)); @@ -2462,7 +2454,7 @@ TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleMetaStateAndLeds) ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL)); ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML)); ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL)); - ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper->getMetaState()); + ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper.getMetaState()); // Toggle num lock on. process(mapper, ARBITRARY_TIME, EV_KEY, KEY_NUMLOCK, 1); @@ -2470,7 +2462,7 @@ TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleMetaStateAndLeds) ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL)); ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML)); ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL)); - ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON, mapper->getMetaState()); + ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON, mapper.getMetaState()); // Toggle caps lock off. process(mapper, ARBITRARY_TIME, EV_KEY, KEY_CAPSLOCK, 1); @@ -2478,7 +2470,7 @@ TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleMetaStateAndLeds) ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL)); ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML)); ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL)); - ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper->getMetaState()); + ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper.getMetaState()); // Toggle scroll lock on. process(mapper, ARBITRARY_TIME, EV_KEY, KEY_SCROLLLOCK, 1); @@ -2486,7 +2478,7 @@ TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleMetaStateAndLeds) ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL)); ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML)); ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL)); - ASSERT_EQ(AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON, mapper->getMetaState()); + ASSERT_EQ(AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON, mapper.getMetaState()); // Toggle num lock off. process(mapper, ARBITRARY_TIME, EV_KEY, KEY_NUMLOCK, 1); @@ -2494,7 +2486,7 @@ TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleMetaStateAndLeds) ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL)); ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML)); ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL)); - ASSERT_EQ(AMETA_SCROLL_LOCK_ON, mapper->getMetaState()); + ASSERT_EQ(AMETA_SCROLL_LOCK_ON, mapper.getMetaState()); // Toggle scroll lock off. process(mapper, ARBITRARY_TIME, EV_KEY, KEY_SCROLLLOCK, 1); @@ -2502,7 +2494,7 @@ TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleMetaStateAndLeds) ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL)); ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML)); ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL)); - ASSERT_EQ(AMETA_NONE, mapper->getMetaState()); + ASSERT_EQ(AMETA_NONE, mapper.getMetaState()); } TEST_F(KeyboardInputMapperTest, Configure_AssignsDisplayPort) { @@ -2527,13 +2519,13 @@ TEST_F(KeyboardInputMapperTest, Configure_AssignsDisplayPort) { mFakeEventHub->addKey(SECOND_DEVICE_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0); mFakeEventHub->addKey(SECOND_DEVICE_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0); - KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, AINPUT_SOURCE_KEYBOARD, - AINPUT_KEYBOARD_TYPE_ALPHABETIC); - addMapperAndConfigure(mapper); + KeyboardInputMapper& mapper = + addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD, + AINPUT_KEYBOARD_TYPE_ALPHABETIC); - KeyboardInputMapper* mapper2 = new KeyboardInputMapper(device2.get(), AINPUT_SOURCE_KEYBOARD, - AINPUT_KEYBOARD_TYPE_ALPHABETIC); - device2->addMapper(mapper2); + KeyboardInputMapper& mapper2 = + device2->addMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD, + AINPUT_KEYBOARD_TYPE_ALPHABETIC); device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), 0 /*changes*/); device2->reset(ARBITRARY_TIME); @@ -2593,9 +2585,9 @@ TEST_F(KeyboardInputMapperTest, ExternalDevice_WakeBehavior) { mFakeEventHub->addKey(DEVICE_ID, KEY_PLAY, 0, AKEYCODE_MEDIA_PLAY, 0); mFakeEventHub->addKey(DEVICE_ID, KEY_PLAYPAUSE, 0, AKEYCODE_MEDIA_PLAY_PAUSE, POLICY_FLAG_WAKE); - KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, AINPUT_SOURCE_KEYBOARD, - AINPUT_KEYBOARD_TYPE_ALPHABETIC); - addMapperAndConfigure(mapper); + KeyboardInputMapper& mapper = + addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD, + AINPUT_KEYBOARD_TYPE_ALPHABETIC); process(mapper, ARBITRARY_TIME, EV_KEY, KEY_HOME, 1); NotifyKeyArgs args; @@ -2631,10 +2623,10 @@ TEST_F(KeyboardInputMapperTest, ExternalDevice_DoNotWakeByDefaultBehavior) { mFakeEventHub->addKey(DEVICE_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0); mFakeEventHub->addKey(DEVICE_ID, KEY_PLAY, 0, AKEYCODE_MEDIA_PLAY, POLICY_FLAG_WAKE); - KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, AINPUT_SOURCE_KEYBOARD, - AINPUT_KEYBOARD_TYPE_ALPHABETIC); addConfigurationProperty("keyboard.doNotWakeByDefault", "1"); - addMapperAndConfigure(mapper); + KeyboardInputMapper& mapper = + addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD, + AINPUT_KEYBOARD_TYPE_ALPHABETIC); process(mapper, ARBITRARY_TIME, EV_KEY, KEY_HOME, 1); NotifyKeyArgs args; @@ -2677,8 +2669,8 @@ protected: mFakePolicy->setPointerController(mDevice->getId(), mFakePointerController); } - void testMotionRotation(CursorInputMapper* mapper, - int32_t originalX, int32_t originalY, int32_t rotatedX, int32_t rotatedY); + void testMotionRotation(CursorInputMapper& mapper, int32_t originalX, int32_t originalY, + int32_t rotatedX, int32_t rotatedY); void prepareDisplay(int32_t orientation) { const std::string uniqueId = "local:0"; @@ -2690,8 +2682,9 @@ protected: const int32_t CursorInputMapperTest::TRACKBALL_MOVEMENT_THRESHOLD = 6; -void CursorInputMapperTest::testMotionRotation(CursorInputMapper* mapper, - int32_t originalX, int32_t originalY, int32_t rotatedX, int32_t rotatedY) { +void CursorInputMapperTest::testMotionRotation(CursorInputMapper& mapper, int32_t originalX, + int32_t originalY, int32_t rotatedX, + int32_t rotatedY) { NotifyMotionArgs args; process(mapper, ARBITRARY_TIME, EV_REL, REL_X, originalX); @@ -2706,28 +2699,25 @@ void CursorInputMapperTest::testMotionRotation(CursorInputMapper* mapper, } TEST_F(CursorInputMapperTest, WhenModeIsPointer_GetSources_ReturnsMouse) { - CursorInputMapper* mapper = new CursorInputMapper(mDevice); addConfigurationProperty("cursor.mode", "pointer"); - addMapperAndConfigure(mapper); + CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>(); - ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper->getSources()); + ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper.getSources()); } TEST_F(CursorInputMapperTest, WhenModeIsNavigation_GetSources_ReturnsTrackball) { - CursorInputMapper* mapper = new CursorInputMapper(mDevice); addConfigurationProperty("cursor.mode", "navigation"); - addMapperAndConfigure(mapper); + CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>(); - ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, mapper->getSources()); + ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, mapper.getSources()); } TEST_F(CursorInputMapperTest, WhenModeIsPointer_PopulateDeviceInfo_ReturnsRangeFromPointerController) { - CursorInputMapper* mapper = new CursorInputMapper(mDevice); addConfigurationProperty("cursor.mode", "pointer"); - addMapperAndConfigure(mapper); + CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>(); InputDeviceInfo info; - mapper->populateDeviceInfo(&info); + mapper.populateDeviceInfo(&info); // Initially there may not be a valid motion range. ASSERT_EQ(nullptr, info.getMotionRange(AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_MOUSE)); @@ -2739,7 +2729,7 @@ TEST_F(CursorInputMapperTest, WhenModeIsPointer_PopulateDeviceInfo_ReturnsRangeF mFakePointerController->setBounds(1, 2, 800 - 1, 480 - 1); InputDeviceInfo info2; - mapper->populateDeviceInfo(&info2); + mapper.populateDeviceInfo(&info2); ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2, AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_MOUSE, @@ -2753,12 +2743,11 @@ TEST_F(CursorInputMapperTest, WhenModeIsPointer_PopulateDeviceInfo_ReturnsRangeF } TEST_F(CursorInputMapperTest, WhenModeIsNavigation_PopulateDeviceInfo_ReturnsScaledRange) { - CursorInputMapper* mapper = new CursorInputMapper(mDevice); addConfigurationProperty("cursor.mode", "navigation"); - addMapperAndConfigure(mapper); + CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>(); InputDeviceInfo info; - mapper->populateDeviceInfo(&info); + mapper.populateDeviceInfo(&info); ASSERT_NO_FATAL_FAILURE(assertMotionRange(info, AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_TRACKBALL, @@ -2772,9 +2761,8 @@ TEST_F(CursorInputMapperTest, WhenModeIsNavigation_PopulateDeviceInfo_ReturnsSca } TEST_F(CursorInputMapperTest, Process_ShouldSetAllFieldsAndIncludeGlobalMetaState) { - CursorInputMapper* mapper = new CursorInputMapper(mDevice); addConfigurationProperty("cursor.mode", "navigation"); - addMapperAndConfigure(mapper); + CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>(); mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON); @@ -2865,9 +2853,8 @@ TEST_F(CursorInputMapperTest, Process_ShouldSetAllFieldsAndIncludeGlobalMetaStat } TEST_F(CursorInputMapperTest, Process_ShouldHandleIndependentXYUpdates) { - CursorInputMapper* mapper = new CursorInputMapper(mDevice); addConfigurationProperty("cursor.mode", "navigation"); - addMapperAndConfigure(mapper); + CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>(); NotifyMotionArgs args; @@ -2889,9 +2876,8 @@ TEST_F(CursorInputMapperTest, Process_ShouldHandleIndependentXYUpdates) { } TEST_F(CursorInputMapperTest, Process_ShouldHandleIndependentButtonUpdates) { - CursorInputMapper* mapper = new CursorInputMapper(mDevice); addConfigurationProperty("cursor.mode", "navigation"); - addMapperAndConfigure(mapper); + CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>(); NotifyMotionArgs args; @@ -2923,9 +2909,8 @@ TEST_F(CursorInputMapperTest, Process_ShouldHandleIndependentButtonUpdates) { } TEST_F(CursorInputMapperTest, Process_ShouldHandleCombinedXYAndButtonUpdates) { - CursorInputMapper* mapper = new CursorInputMapper(mDevice); addConfigurationProperty("cursor.mode", "navigation"); - addMapperAndConfigure(mapper); + CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>(); NotifyMotionArgs args; @@ -2971,9 +2956,8 @@ TEST_F(CursorInputMapperTest, Process_ShouldHandleCombinedXYAndButtonUpdates) { } TEST_F(CursorInputMapperTest, Process_WhenNotOrientationAware_ShouldNotRotateMotions) { - CursorInputMapper* mapper = new CursorInputMapper(mDevice); addConfigurationProperty("cursor.mode", "navigation"); - addMapperAndConfigure(mapper); + CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>(); prepareDisplay(DISPLAY_ORIENTATION_90); ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, 0, 1)); @@ -2987,10 +2971,9 @@ TEST_F(CursorInputMapperTest, Process_WhenNotOrientationAware_ShouldNotRotateMot } TEST_F(CursorInputMapperTest, Process_WhenOrientationAware_ShouldRotateMotions) { - CursorInputMapper* mapper = new CursorInputMapper(mDevice); addConfigurationProperty("cursor.mode", "navigation"); addConfigurationProperty("cursor.orientationAware", "1"); - addMapperAndConfigure(mapper); + CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>(); prepareDisplay(DISPLAY_ORIENTATION_0); ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, 0, 1)); @@ -3034,9 +3017,8 @@ TEST_F(CursorInputMapperTest, Process_WhenOrientationAware_ShouldRotateMotions) } TEST_F(CursorInputMapperTest, Process_ShouldHandleAllButtons) { - CursorInputMapper* mapper = new CursorInputMapper(mDevice); addConfigurationProperty("cursor.mode", "pointer"); - addMapperAndConfigure(mapper); + CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>(); mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1); mFakePointerController->setPosition(100, 200); @@ -3322,9 +3304,8 @@ TEST_F(CursorInputMapperTest, Process_ShouldHandleAllButtons) { } TEST_F(CursorInputMapperTest, Process_WhenModeIsPointer_ShouldMoveThePointerAround) { - CursorInputMapper* mapper = new CursorInputMapper(mDevice); addConfigurationProperty("cursor.mode", "pointer"); - addMapperAndConfigure(mapper); + CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>(); mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1); mFakePointerController->setPosition(100, 200); @@ -3344,10 +3325,9 @@ TEST_F(CursorInputMapperTest, Process_WhenModeIsPointer_ShouldMoveThePointerArou } TEST_F(CursorInputMapperTest, Process_PointerCapture) { - CursorInputMapper* mapper = new CursorInputMapper(mDevice); addConfigurationProperty("cursor.mode", "pointer"); mFakePolicy->setPointerCapture(true); - addMapperAndConfigure(mapper); + CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>(); NotifyDeviceResetArgs resetArgs; ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs)); @@ -3433,8 +3413,7 @@ TEST_F(CursorInputMapperTest, Process_PointerCapture) { } TEST_F(CursorInputMapperTest, Process_ShouldHandleDisplayId) { - CursorInputMapper* mapper = new CursorInputMapper(mDevice); - addMapperAndConfigure(mapper); + CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>(); // Setup for second display. constexpr int32_t SECOND_DISPLAY_ID = 1; @@ -3462,7 +3441,6 @@ TEST_F(CursorInputMapperTest, Process_ShouldHandleDisplayId) { ASSERT_EQ(SECOND_DISPLAY_ID, args.displayId); } - // --- TouchInputMapperTest --- class TouchInputMapperTest : public InputMapperTest { @@ -3637,15 +3615,15 @@ protected: void prepareButtons(); void prepareAxes(int axes); - void processDown(SingleTouchInputMapper* mapper, int32_t x, int32_t y); - void processMove(SingleTouchInputMapper* mapper, int32_t x, int32_t y); - void processUp(SingleTouchInputMapper* mappery); - void processPressure(SingleTouchInputMapper* mapper, int32_t pressure); - void processToolMajor(SingleTouchInputMapper* mapper, int32_t toolMajor); - void processDistance(SingleTouchInputMapper* mapper, int32_t distance); - void processTilt(SingleTouchInputMapper* mapper, int32_t tiltX, int32_t tiltY); - void processKey(SingleTouchInputMapper* mapper, int32_t code, int32_t value); - void processSync(SingleTouchInputMapper* mapper); + void processDown(SingleTouchInputMapper& mapper, int32_t x, int32_t y); + void processMove(SingleTouchInputMapper& mapper, int32_t x, int32_t y); + void processUp(SingleTouchInputMapper& mappery); + void processPressure(SingleTouchInputMapper& mapper, int32_t pressure); + void processToolMajor(SingleTouchInputMapper& mapper, int32_t toolMajor); + void processDistance(SingleTouchInputMapper& mapper, int32_t distance); + void processTilt(SingleTouchInputMapper& mapper, int32_t tiltX, int32_t tiltY); + void processKey(SingleTouchInputMapper& mapper, int32_t code, int32_t value); + void processSync(SingleTouchInputMapper& mapper); }; void SingleTouchInputMapperTest::prepareButtons() { @@ -3679,103 +3657,95 @@ void SingleTouchInputMapperTest::prepareAxes(int axes) { } } -void SingleTouchInputMapperTest::processDown(SingleTouchInputMapper* mapper, int32_t x, int32_t y) { +void SingleTouchInputMapperTest::processDown(SingleTouchInputMapper& mapper, int32_t x, int32_t y) { process(mapper, ARBITRARY_TIME, EV_KEY, BTN_TOUCH, 1); process(mapper, ARBITRARY_TIME, EV_ABS, ABS_X, x); process(mapper, ARBITRARY_TIME, EV_ABS, ABS_Y, y); } -void SingleTouchInputMapperTest::processMove(SingleTouchInputMapper* mapper, int32_t x, int32_t y) { +void SingleTouchInputMapperTest::processMove(SingleTouchInputMapper& mapper, int32_t x, int32_t y) { process(mapper, ARBITRARY_TIME, EV_ABS, ABS_X, x); process(mapper, ARBITRARY_TIME, EV_ABS, ABS_Y, y); } -void SingleTouchInputMapperTest::processUp(SingleTouchInputMapper* mapper) { +void SingleTouchInputMapperTest::processUp(SingleTouchInputMapper& mapper) { process(mapper, ARBITRARY_TIME, EV_KEY, BTN_TOUCH, 0); } -void SingleTouchInputMapperTest::processPressure( - SingleTouchInputMapper* mapper, int32_t pressure) { +void SingleTouchInputMapperTest::processPressure(SingleTouchInputMapper& mapper, int32_t pressure) { process(mapper, ARBITRARY_TIME, EV_ABS, ABS_PRESSURE, pressure); } -void SingleTouchInputMapperTest::processToolMajor( - SingleTouchInputMapper* mapper, int32_t toolMajor) { +void SingleTouchInputMapperTest::processToolMajor(SingleTouchInputMapper& mapper, + int32_t toolMajor) { process(mapper, ARBITRARY_TIME, EV_ABS, ABS_TOOL_WIDTH, toolMajor); } -void SingleTouchInputMapperTest::processDistance( - SingleTouchInputMapper* mapper, int32_t distance) { +void SingleTouchInputMapperTest::processDistance(SingleTouchInputMapper& mapper, int32_t distance) { process(mapper, ARBITRARY_TIME, EV_ABS, ABS_DISTANCE, distance); } -void SingleTouchInputMapperTest::processTilt( - SingleTouchInputMapper* mapper, int32_t tiltX, int32_t tiltY) { +void SingleTouchInputMapperTest::processTilt(SingleTouchInputMapper& mapper, int32_t tiltX, + int32_t tiltY) { process(mapper, ARBITRARY_TIME, EV_ABS, ABS_TILT_X, tiltX); process(mapper, ARBITRARY_TIME, EV_ABS, ABS_TILT_Y, tiltY); } -void SingleTouchInputMapperTest::processKey( - SingleTouchInputMapper* mapper, int32_t code, int32_t value) { +void SingleTouchInputMapperTest::processKey(SingleTouchInputMapper& mapper, int32_t code, + int32_t value) { process(mapper, ARBITRARY_TIME, EV_KEY, code, value); } -void SingleTouchInputMapperTest::processSync(SingleTouchInputMapper* mapper) { +void SingleTouchInputMapperTest::processSync(SingleTouchInputMapper& mapper) { process(mapper, ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0); } - TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsNotSpecifiedAndNotACursor_ReturnsPointer) { - SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); prepareButtons(); prepareAxes(POSITION); - addMapperAndConfigure(mapper); + SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>(); - ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper->getSources()); + ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper.getSources()); } TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsNotSpecifiedAndIsACursor_ReturnsTouchPad) { - SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); mFakeEventHub->addRelativeAxis(DEVICE_ID, REL_X); mFakeEventHub->addRelativeAxis(DEVICE_ID, REL_Y); prepareButtons(); prepareAxes(POSITION); - addMapperAndConfigure(mapper); + SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>(); - ASSERT_EQ(AINPUT_SOURCE_TOUCHPAD, mapper->getSources()); + ASSERT_EQ(AINPUT_SOURCE_TOUCHPAD, mapper.getSources()); } TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsTouchPad_ReturnsTouchPad) { - SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); prepareButtons(); prepareAxes(POSITION); addConfigurationProperty("touch.deviceType", "touchPad"); - addMapperAndConfigure(mapper); + SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>(); - ASSERT_EQ(AINPUT_SOURCE_TOUCHPAD, mapper->getSources()); + ASSERT_EQ(AINPUT_SOURCE_TOUCHPAD, mapper.getSources()); } TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsTouchScreen_ReturnsTouchScreen) { - SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); prepareButtons(); prepareAxes(POSITION); addConfigurationProperty("touch.deviceType", "touchScreen"); - addMapperAndConfigure(mapper); + SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>(); - ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper->getSources()); + ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper.getSources()); } TEST_F(SingleTouchInputMapperTest, GetKeyCodeState) { - SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); addConfigurationProperty("touch.deviceType", "touchScreen"); prepareDisplay(DISPLAY_ORIENTATION_0); prepareButtons(); prepareAxes(POSITION); prepareVirtualKeys(); - addMapperAndConfigure(mapper); + SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>(); // Unknown key. - ASSERT_EQ(AKEY_STATE_UNKNOWN, mapper->getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A)); + ASSERT_EQ(AKEY_STATE_UNKNOWN, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A)); // Virtual key is down. int32_t x = toRawX(VIRTUAL_KEYS[0].centerX); @@ -3784,27 +3754,26 @@ TEST_F(SingleTouchInputMapperTest, GetKeyCodeState) { processSync(mapper); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled()); - ASSERT_EQ(AKEY_STATE_VIRTUAL, mapper->getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_HOME)); + ASSERT_EQ(AKEY_STATE_VIRTUAL, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_HOME)); // Virtual key is up. processUp(mapper); processSync(mapper); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled()); - ASSERT_EQ(AKEY_STATE_UP, mapper->getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_HOME)); + ASSERT_EQ(AKEY_STATE_UP, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_HOME)); } TEST_F(SingleTouchInputMapperTest, GetScanCodeState) { - SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); addConfigurationProperty("touch.deviceType", "touchScreen"); prepareDisplay(DISPLAY_ORIENTATION_0); prepareButtons(); prepareAxes(POSITION); prepareVirtualKeys(); - addMapperAndConfigure(mapper); + SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>(); // Unknown key. - ASSERT_EQ(AKEY_STATE_UNKNOWN, mapper->getScanCodeState(AINPUT_SOURCE_ANY, KEY_A)); + ASSERT_EQ(AKEY_STATE_UNKNOWN, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_A)); // Virtual key is down. int32_t x = toRawX(VIRTUAL_KEYS[0].centerX); @@ -3813,40 +3782,38 @@ TEST_F(SingleTouchInputMapperTest, GetScanCodeState) { processSync(mapper); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled()); - ASSERT_EQ(AKEY_STATE_VIRTUAL, mapper->getScanCodeState(AINPUT_SOURCE_ANY, KEY_HOME)); + ASSERT_EQ(AKEY_STATE_VIRTUAL, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_HOME)); // Virtual key is up. processUp(mapper); processSync(mapper); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled()); - ASSERT_EQ(AKEY_STATE_UP, mapper->getScanCodeState(AINPUT_SOURCE_ANY, KEY_HOME)); + ASSERT_EQ(AKEY_STATE_UP, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_HOME)); } TEST_F(SingleTouchInputMapperTest, MarkSupportedKeyCodes) { - SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); addConfigurationProperty("touch.deviceType", "touchScreen"); prepareDisplay(DISPLAY_ORIENTATION_0); prepareButtons(); prepareAxes(POSITION); prepareVirtualKeys(); - addMapperAndConfigure(mapper); + SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>(); const int32_t keys[2] = { AKEYCODE_HOME, AKEYCODE_A }; uint8_t flags[2] = { 0, 0 }; - ASSERT_TRUE(mapper->markSupportedKeyCodes(AINPUT_SOURCE_ANY, 2, keys, flags)); + ASSERT_TRUE(mapper.markSupportedKeyCodes(AINPUT_SOURCE_ANY, 2, keys, flags)); ASSERT_TRUE(flags[0]); ASSERT_FALSE(flags[1]); } TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndReleasedNormally_SendsKeyDownAndKeyUp) { - SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); addConfigurationProperty("touch.deviceType", "touchScreen"); prepareDisplay(DISPLAY_ORIENTATION_0); prepareButtons(); prepareAxes(POSITION); prepareVirtualKeys(); - addMapperAndConfigure(mapper); + SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>(); mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON); @@ -3891,13 +3858,12 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndReleasedNor } TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndMovedOutOfBounds_SendsKeyDownAndKeyCancel) { - SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); addConfigurationProperty("touch.deviceType", "touchScreen"); prepareDisplay(DISPLAY_ORIENTATION_0); prepareButtons(); prepareAxes(POSITION); prepareVirtualKeys(); - addMapperAndConfigure(mapper); + SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>(); mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON); @@ -4013,13 +3979,12 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndMovedOutOfB } TEST_F(SingleTouchInputMapperTest, Process_WhenTouchStartsOutsideDisplayAndMovesIn_SendsDownAsTouchEntersDisplay) { - SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); addConfigurationProperty("touch.deviceType", "touchScreen"); prepareDisplay(DISPLAY_ORIENTATION_0); prepareButtons(); prepareAxes(POSITION); prepareVirtualKeys(); - addMapperAndConfigure(mapper); + SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>(); mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON); @@ -4087,7 +4052,6 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenTouchStartsOutsideDisplayAndMoves } TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture_VirtualDisplay) { - SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); addConfigurationProperty("touch.deviceType", "touchScreen"); addConfigurationProperty("touch.displayId", VIRTUAL_DISPLAY_UNIQUE_ID); @@ -4095,7 +4059,7 @@ TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture_VirtualDispl prepareButtons(); prepareAxes(POSITION); prepareVirtualKeys(); - addMapperAndConfigure(mapper); + SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>(); mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON); @@ -4186,13 +4150,12 @@ TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture_VirtualDispl } TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture) { - SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); addConfigurationProperty("touch.deviceType", "touchScreen"); prepareDisplay(DISPLAY_ORIENTATION_0); prepareButtons(); prepareAxes(POSITION); prepareVirtualKeys(); - addMapperAndConfigure(mapper); + SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>(); mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON); @@ -4277,12 +4240,11 @@ TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture) { } TEST_F(SingleTouchInputMapperTest, Process_WhenNotOrientationAware_DoesNotRotateMotions) { - SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); addConfigurationProperty("touch.deviceType", "touchScreen"); prepareButtons(); prepareAxes(POSITION); addConfigurationProperty("touch.orientationAware", "0"); - addMapperAndConfigure(mapper); + SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>(); NotifyMotionArgs args; @@ -4301,11 +4263,10 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenNotOrientationAware_DoesNotRotate } TEST_F(SingleTouchInputMapperTest, Process_WhenOrientationAware_RotatesMotions) { - SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); addConfigurationProperty("touch.deviceType", "touchScreen"); prepareButtons(); prepareAxes(POSITION); - addMapperAndConfigure(mapper); + SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>(); NotifyMotionArgs args; @@ -4367,12 +4328,11 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenOrientationAware_RotatesMotions) } TEST_F(SingleTouchInputMapperTest, Process_AllAxes_DefaultCalibration) { - SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); addConfigurationProperty("touch.deviceType", "touchScreen"); prepareDisplay(DISPLAY_ORIENTATION_0); prepareButtons(); prepareAxes(POSITION | PRESSURE | TOOL | DISTANCE | TILT); - addMapperAndConfigure(mapper); + SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>(); // These calculations are based on the input device calibration documentation. int32_t rawX = 100; @@ -4412,13 +4372,12 @@ TEST_F(SingleTouchInputMapperTest, Process_AllAxes_DefaultCalibration) { } TEST_F(SingleTouchInputMapperTest, Process_XYAxes_AffineCalibration) { - SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); addConfigurationProperty("touch.deviceType", "touchScreen"); prepareDisplay(DISPLAY_ORIENTATION_0); prepareLocationCalibration(); prepareButtons(); prepareAxes(POSITION); - addMapperAndConfigure(mapper); + SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>(); int32_t rawX = 100; int32_t rawY = 200; @@ -4436,12 +4395,11 @@ TEST_F(SingleTouchInputMapperTest, Process_XYAxes_AffineCalibration) { } TEST_F(SingleTouchInputMapperTest, Process_ShouldHandleAllButtons) { - SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); addConfigurationProperty("touch.deviceType", "touchScreen"); prepareDisplay(DISPLAY_ORIENTATION_0); prepareButtons(); prepareAxes(POSITION); - addMapperAndConfigure(mapper); + SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>(); NotifyMotionArgs motionArgs; NotifyKeyArgs keyArgs; @@ -4680,12 +4638,11 @@ TEST_F(SingleTouchInputMapperTest, Process_ShouldHandleAllButtons) { } TEST_F(SingleTouchInputMapperTest, Process_ShouldHandleAllToolTypes) { - SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); addConfigurationProperty("touch.deviceType", "touchScreen"); prepareDisplay(DISPLAY_ORIENTATION_0); prepareButtons(); prepareAxes(POSITION); - addMapperAndConfigure(mapper); + SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>(); NotifyMotionArgs motionArgs; @@ -4816,13 +4773,12 @@ TEST_F(SingleTouchInputMapperTest, Process_ShouldHandleAllToolTypes) { } TEST_F(SingleTouchInputMapperTest, Process_WhenBtnTouchPresent_HoversIfItsValueIsZero) { - SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); addConfigurationProperty("touch.deviceType", "touchScreen"); prepareDisplay(DISPLAY_ORIENTATION_0); prepareButtons(); prepareAxes(POSITION); mFakeEventHub->addKey(DEVICE_ID, BTN_TOOL_FINGER, 0, AKEYCODE_UNKNOWN, 0); - addMapperAndConfigure(mapper); + SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>(); NotifyMotionArgs motionArgs; @@ -4889,12 +4845,11 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenBtnTouchPresent_HoversIfItsValueI } TEST_F(SingleTouchInputMapperTest, Process_WhenAbsPressureIsPresent_HoversIfItsValueIsZero) { - SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); addConfigurationProperty("touch.deviceType", "touchScreen"); prepareDisplay(DISPLAY_ORIENTATION_0); prepareButtons(); prepareAxes(POSITION | PRESSURE); - addMapperAndConfigure(mapper); + SingleTouchInputMapper& mapper = addMapperAndConfigure<SingleTouchInputMapper>(); NotifyMotionArgs motionArgs; @@ -4960,27 +4915,26 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenAbsPressureIsPresent_HoversIfItsV toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0)); } - // --- MultiTouchInputMapperTest --- class MultiTouchInputMapperTest : public TouchInputMapperTest { protected: void prepareAxes(int axes); - void processPosition(MultiTouchInputMapper* mapper, int32_t x, int32_t y); - void processTouchMajor(MultiTouchInputMapper* mapper, int32_t touchMajor); - void processTouchMinor(MultiTouchInputMapper* mapper, int32_t touchMinor); - void processToolMajor(MultiTouchInputMapper* mapper, int32_t toolMajor); - void processToolMinor(MultiTouchInputMapper* mapper, int32_t toolMinor); - void processOrientation(MultiTouchInputMapper* mapper, int32_t orientation); - void processPressure(MultiTouchInputMapper* mapper, int32_t pressure); - void processDistance(MultiTouchInputMapper* mapper, int32_t distance); - void processId(MultiTouchInputMapper* mapper, int32_t id); - void processSlot(MultiTouchInputMapper* mapper, int32_t slot); - void processToolType(MultiTouchInputMapper* mapper, int32_t toolType); - void processKey(MultiTouchInputMapper* mapper, int32_t code, int32_t value); - void processMTSync(MultiTouchInputMapper* mapper); - void processSync(MultiTouchInputMapper* mapper); + void processPosition(MultiTouchInputMapper& mapper, int32_t x, int32_t y); + void processTouchMajor(MultiTouchInputMapper& mapper, int32_t touchMajor); + void processTouchMinor(MultiTouchInputMapper& mapper, int32_t touchMinor); + void processToolMajor(MultiTouchInputMapper& mapper, int32_t toolMajor); + void processToolMinor(MultiTouchInputMapper& mapper, int32_t toolMinor); + void processOrientation(MultiTouchInputMapper& mapper, int32_t orientation); + void processPressure(MultiTouchInputMapper& mapper, int32_t pressure); + void processDistance(MultiTouchInputMapper& mapper, int32_t distance); + void processId(MultiTouchInputMapper& mapper, int32_t id); + void processSlot(MultiTouchInputMapper& mapper, int32_t slot); + void processToolType(MultiTouchInputMapper& mapper, int32_t toolType); + void processKey(MultiTouchInputMapper& mapper, int32_t code, int32_t value); + void processMTSync(MultiTouchInputMapper& mapper); + void processSync(MultiTouchInputMapper& mapper); }; void MultiTouchInputMapperTest::prepareAxes(int axes) { @@ -5033,83 +4987,74 @@ void MultiTouchInputMapperTest::prepareAxes(int axes) { } } -void MultiTouchInputMapperTest::processPosition( - MultiTouchInputMapper* mapper, int32_t x, int32_t y) { +void MultiTouchInputMapperTest::processPosition(MultiTouchInputMapper& mapper, int32_t x, + int32_t y) { process(mapper, ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, x); process(mapper, ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, y); } -void MultiTouchInputMapperTest::processTouchMajor( - MultiTouchInputMapper* mapper, int32_t touchMajor) { +void MultiTouchInputMapperTest::processTouchMajor(MultiTouchInputMapper& mapper, + int32_t touchMajor) { process(mapper, ARBITRARY_TIME, EV_ABS, ABS_MT_TOUCH_MAJOR, touchMajor); } -void MultiTouchInputMapperTest::processTouchMinor( - MultiTouchInputMapper* mapper, int32_t touchMinor) { +void MultiTouchInputMapperTest::processTouchMinor(MultiTouchInputMapper& mapper, + int32_t touchMinor) { process(mapper, ARBITRARY_TIME, EV_ABS, ABS_MT_TOUCH_MINOR, touchMinor); } -void MultiTouchInputMapperTest::processToolMajor( - MultiTouchInputMapper* mapper, int32_t toolMajor) { +void MultiTouchInputMapperTest::processToolMajor(MultiTouchInputMapper& mapper, int32_t toolMajor) { process(mapper, ARBITRARY_TIME, EV_ABS, ABS_MT_WIDTH_MAJOR, toolMajor); } -void MultiTouchInputMapperTest::processToolMinor( - MultiTouchInputMapper* mapper, int32_t toolMinor) { +void MultiTouchInputMapperTest::processToolMinor(MultiTouchInputMapper& mapper, int32_t toolMinor) { process(mapper, ARBITRARY_TIME, EV_ABS, ABS_MT_WIDTH_MINOR, toolMinor); } -void MultiTouchInputMapperTest::processOrientation( - MultiTouchInputMapper* mapper, int32_t orientation) { +void MultiTouchInputMapperTest::processOrientation(MultiTouchInputMapper& mapper, + int32_t orientation) { process(mapper, ARBITRARY_TIME, EV_ABS, ABS_MT_ORIENTATION, orientation); } -void MultiTouchInputMapperTest::processPressure( - MultiTouchInputMapper* mapper, int32_t pressure) { +void MultiTouchInputMapperTest::processPressure(MultiTouchInputMapper& mapper, int32_t pressure) { process(mapper, ARBITRARY_TIME, EV_ABS, ABS_MT_PRESSURE, pressure); } -void MultiTouchInputMapperTest::processDistance( - MultiTouchInputMapper* mapper, int32_t distance) { +void MultiTouchInputMapperTest::processDistance(MultiTouchInputMapper& mapper, int32_t distance) { process(mapper, ARBITRARY_TIME, EV_ABS, ABS_MT_DISTANCE, distance); } -void MultiTouchInputMapperTest::processId( - MultiTouchInputMapper* mapper, int32_t id) { +void MultiTouchInputMapperTest::processId(MultiTouchInputMapper& mapper, int32_t id) { process(mapper, ARBITRARY_TIME, EV_ABS, ABS_MT_TRACKING_ID, id); } -void MultiTouchInputMapperTest::processSlot( - MultiTouchInputMapper* mapper, int32_t slot) { +void MultiTouchInputMapperTest::processSlot(MultiTouchInputMapper& mapper, int32_t slot) { process(mapper, ARBITRARY_TIME, EV_ABS, ABS_MT_SLOT, slot); } -void MultiTouchInputMapperTest::processToolType( - MultiTouchInputMapper* mapper, int32_t toolType) { +void MultiTouchInputMapperTest::processToolType(MultiTouchInputMapper& mapper, int32_t toolType) { process(mapper, ARBITRARY_TIME, EV_ABS, ABS_MT_TOOL_TYPE, toolType); } -void MultiTouchInputMapperTest::processKey( - MultiTouchInputMapper* mapper, int32_t code, int32_t value) { +void MultiTouchInputMapperTest::processKey(MultiTouchInputMapper& mapper, int32_t code, + int32_t value) { process(mapper, ARBITRARY_TIME, EV_KEY, code, value); } -void MultiTouchInputMapperTest::processMTSync(MultiTouchInputMapper* mapper) { +void MultiTouchInputMapperTest::processMTSync(MultiTouchInputMapper& mapper) { process(mapper, ARBITRARY_TIME, EV_SYN, SYN_MT_REPORT, 0); } -void MultiTouchInputMapperTest::processSync(MultiTouchInputMapper* mapper) { +void MultiTouchInputMapperTest::processSync(MultiTouchInputMapper& mapper) { process(mapper, ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0); } - TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithoutTrackingIds) { - MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); addConfigurationProperty("touch.deviceType", "touchScreen"); prepareDisplay(DISPLAY_ORIENTATION_0); prepareAxes(POSITION); prepareVirtualKeys(); - addMapperAndConfigure(mapper); + MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>(); mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON); @@ -5381,12 +5326,11 @@ TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithoutTrackin } TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithTrackingIds) { - MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); addConfigurationProperty("touch.deviceType", "touchScreen"); prepareDisplay(DISPLAY_ORIENTATION_0); prepareAxes(POSITION | ID); prepareVirtualKeys(); - addMapperAndConfigure(mapper); + MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>(); mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON); @@ -5557,12 +5501,11 @@ TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithTrackingId } TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithSlots) { - MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); addConfigurationProperty("touch.deviceType", "touchScreen"); prepareDisplay(DISPLAY_ORIENTATION_0); prepareAxes(POSITION | ID | SLOT); prepareVirtualKeys(); - addMapperAndConfigure(mapper); + MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>(); mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON); @@ -5728,11 +5671,10 @@ TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithSlots) { } TEST_F(MultiTouchInputMapperTest, Process_AllAxes_WithDefaultCalibration) { - MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); addConfigurationProperty("touch.deviceType", "touchScreen"); prepareDisplay(DISPLAY_ORIENTATION_0); prepareAxes(POSITION | TOUCH | TOOL | PRESSURE | ORIENTATION | ID | MINOR | DISTANCE); - addMapperAndConfigure(mapper); + MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>(); // These calculations are based on the input device calibration documentation. int32_t rawX = 100; @@ -5778,12 +5720,11 @@ TEST_F(MultiTouchInputMapperTest, Process_AllAxes_WithDefaultCalibration) { } TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_GeometricCalibration) { - MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); addConfigurationProperty("touch.deviceType", "touchScreen"); prepareDisplay(DISPLAY_ORIENTATION_0); prepareAxes(POSITION | TOUCH | TOOL | MINOR); addConfigurationProperty("touch.size.calibration", "geometric"); - addMapperAndConfigure(mapper); + MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>(); // These calculations are based on the input device calibration documentation. int32_t rawX = 100; @@ -5816,7 +5757,6 @@ TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_GeometricCalibration) } TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_SummedLinearCalibration) { - MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); addConfigurationProperty("touch.deviceType", "touchScreen"); prepareDisplay(DISPLAY_ORIENTATION_0); prepareAxes(POSITION | TOUCH | TOOL); @@ -5824,7 +5764,7 @@ TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_SummedLinearCalibrati addConfigurationProperty("touch.size.scale", "10"); addConfigurationProperty("touch.size.bias", "160"); addConfigurationProperty("touch.size.isSummed", "1"); - addMapperAndConfigure(mapper); + MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>(); // These calculations are based on the input device calibration documentation. // Note: We only provide a single common touch/tool value because the device is assumed @@ -5869,14 +5809,13 @@ TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_SummedLinearCalibrati } TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_AreaCalibration) { - MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); addConfigurationProperty("touch.deviceType", "touchScreen"); prepareDisplay(DISPLAY_ORIENTATION_0); prepareAxes(POSITION | TOUCH | TOOL); addConfigurationProperty("touch.size.calibration", "area"); addConfigurationProperty("touch.size.scale", "43"); addConfigurationProperty("touch.size.bias", "3"); - addMapperAndConfigure(mapper); + MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>(); // These calculations are based on the input device calibration documentation. int32_t rawX = 100; @@ -5903,16 +5842,15 @@ TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_AreaCalibration) { } TEST_F(MultiTouchInputMapperTest, Process_PressureAxis_AmplitudeCalibration) { - MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); addConfigurationProperty("touch.deviceType", "touchScreen"); prepareDisplay(DISPLAY_ORIENTATION_0); prepareAxes(POSITION | PRESSURE); addConfigurationProperty("touch.pressure.calibration", "amplitude"); addConfigurationProperty("touch.pressure.scale", "0.01"); - addMapperAndConfigure(mapper); + MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>(); InputDeviceInfo info; - mapper->populateDeviceInfo(&info); + mapper.populateDeviceInfo(&info); ASSERT_NO_FATAL_FAILURE(assertMotionRange(info, AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_TOUCHSCREEN, 0.0f, RAW_PRESSURE_MAX * 0.01, 0.0f, 0.0f)); @@ -5938,11 +5876,10 @@ TEST_F(MultiTouchInputMapperTest, Process_PressureAxis_AmplitudeCalibration) { } TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleAllButtons) { - MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); addConfigurationProperty("touch.deviceType", "touchScreen"); prepareDisplay(DISPLAY_ORIENTATION_0); prepareAxes(POSITION | ID | SLOT); - addMapperAndConfigure(mapper); + MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>(); NotifyMotionArgs motionArgs; NotifyKeyArgs keyArgs; @@ -6182,11 +6119,10 @@ TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleAllButtons) { } TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleAllToolTypes) { - MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); addConfigurationProperty("touch.deviceType", "touchScreen"); prepareDisplay(DISPLAY_ORIENTATION_0); prepareAxes(POSITION | ID | SLOT | TOOL_TYPE); - addMapperAndConfigure(mapper); + MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>(); NotifyMotionArgs motionArgs; @@ -6333,12 +6269,11 @@ TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleAllToolTypes) { } TEST_F(MultiTouchInputMapperTest, Process_WhenBtnTouchPresent_HoversIfItsValueIsZero) { - MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); addConfigurationProperty("touch.deviceType", "touchScreen"); prepareDisplay(DISPLAY_ORIENTATION_0); prepareAxes(POSITION | ID | SLOT); mFakeEventHub->addKey(DEVICE_ID, BTN_TOUCH, 0, AKEYCODE_UNKNOWN, 0); - addMapperAndConfigure(mapper); + MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>(); NotifyMotionArgs motionArgs; @@ -6405,11 +6340,10 @@ TEST_F(MultiTouchInputMapperTest, Process_WhenBtnTouchPresent_HoversIfItsValueIs } TEST_F(MultiTouchInputMapperTest, Process_WhenAbsMTPressureIsPresent_HoversIfItsValueIsZero) { - MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); addConfigurationProperty("touch.deviceType", "touchScreen"); prepareDisplay(DISPLAY_ORIENTATION_0); prepareAxes(POSITION | ID | SLOT | PRESSURE); - addMapperAndConfigure(mapper); + MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>(); NotifyMotionArgs motionArgs; @@ -6482,7 +6416,6 @@ TEST_F(MultiTouchInputMapperTest, Process_WhenAbsMTPressureIsPresent_HoversIfIts * This can be checked by looking at the displayId of the resulting NotifyMotionArgs. */ TEST_F(MultiTouchInputMapperTest, Configure_AssignsDisplayPort) { - MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); const std::string usb2 = "USB2"; const uint8_t hdmi1 = 0; const uint8_t hdmi2 = 1; @@ -6491,7 +6424,7 @@ TEST_F(MultiTouchInputMapperTest, Configure_AssignsDisplayPort) { addConfigurationProperty("touch.deviceType", "touchScreen"); prepareAxes(POSITION); - addMapperAndConfigure(mapper); + MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>(); mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi1); mFakePolicy->addInputPortAssociation(usb2, hdmi2); @@ -6522,14 +6455,13 @@ TEST_F(MultiTouchInputMapperTest, Configure_AssignsDisplayPort) { * Expect fallback to internal viewport if device is external and external viewport is not present. */ TEST_F(MultiTouchInputMapperTest, Viewports_Fallback) { - MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); prepareAxes(POSITION); addConfigurationProperty("touch.deviceType", "touchScreen"); prepareDisplay(DISPLAY_ORIENTATION_0); mDevice->setExternal(true); - addMapperAndConfigure(mapper); + MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>(); - ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper->getSources()); + ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper.getSources()); NotifyMotionArgs motionArgs; @@ -6559,13 +6491,12 @@ TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShouldHandleDisplayId) { mFakePolicy->setDefaultPointerDisplayId(SECONDARY_DISPLAY_ID); prepareSecondaryDisplay(ViewportType::VIEWPORT_EXTERNAL); - MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); prepareDisplay(DISPLAY_ORIENTATION_0); prepareAxes(POSITION); - addMapperAndConfigure(mapper); + MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>(); // Check source is mouse that would obtain the PointerController. - ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper->getSources()); + ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper.getSources()); NotifyMotionArgs motionArgs; processPosition(mapper, 100, 100); @@ -6578,10 +6509,9 @@ TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShouldHandleDisplayId) { TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShowTouches) { // Setup the first touch screen device. - MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); prepareAxes(POSITION | ID | SLOT); addConfigurationProperty("touch.deviceType", "touchScreen"); - addMapperAndConfigure(mapper); + MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>(); // Create the second touch screen device, and enable multi fingers. const std::string USB2 = "USB2"; @@ -6606,8 +6536,7 @@ TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShowTouches) { String8("touchScreen")); // Setup the second touch screen device. - MultiTouchInputMapper* mapper2 = new MultiTouchInputMapper(device2.get()); - device2->addMapper(mapper2); + MultiTouchInputMapper& mapper2 = device2->addMapper<MultiTouchInputMapper>(); device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), 0 /*changes*/); device2->reset(ARBITRARY_TIME); @@ -6659,11 +6588,10 @@ TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShowTouches) { } TEST_F(MultiTouchInputMapperTest, VideoFrames_ReceivedByListener) { - MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); prepareAxes(POSITION); addConfigurationProperty("touch.deviceType", "touchScreen"); prepareDisplay(DISPLAY_ORIENTATION_0); - addMapperAndConfigure(mapper); + MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>(); NotifyMotionArgs motionArgs; // Unrotated video frame @@ -6685,10 +6613,9 @@ TEST_F(MultiTouchInputMapperTest, VideoFrames_ReceivedByListener) { } TEST_F(MultiTouchInputMapperTest, VideoFrames_AreRotated) { - MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); prepareAxes(POSITION); addConfigurationProperty("touch.deviceType", "touchScreen"); - addMapperAndConfigure(mapper); + MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>(); // Unrotated video frame TouchVideoFrame frame(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2}); NotifyMotionArgs motionArgs; @@ -6710,10 +6637,9 @@ TEST_F(MultiTouchInputMapperTest, VideoFrames_AreRotated) { } TEST_F(MultiTouchInputMapperTest, VideoFrames_MultipleFramesAreRotated) { - MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); prepareAxes(POSITION); addConfigurationProperty("touch.deviceType", "touchScreen"); - addMapperAndConfigure(mapper); + MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>(); // Unrotated video frames. There's no rule that they must all have the same dimensions, // so mix these. TouchVideoFrame frame1(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2}); @@ -6737,7 +6663,6 @@ TEST_F(MultiTouchInputMapperTest, VideoFrames_MultipleFramesAreRotated) { * expected to be disabled, and it should be enabled after the viewport has found. */ TEST_F(MultiTouchInputMapperTest, Configure_EnabledForAssociatedDisplay) { - MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); constexpr uint8_t hdmi2 = 1; const std::string secondaryUniqueId = "uniqueId2"; constexpr ViewportType type = ViewportType::VIEWPORT_EXTERNAL; @@ -6746,7 +6671,7 @@ TEST_F(MultiTouchInputMapperTest, Configure_EnabledForAssociatedDisplay) { addConfigurationProperty("touch.deviceType", "touchScreen"); prepareAxes(POSITION); - addMapperAndConfigure(mapper); + MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>(); ASSERT_EQ(mDevice->isEnabled(), false); @@ -6767,11 +6692,10 @@ TEST_F(MultiTouchInputMapperTest, Configure_EnabledForAssociatedDisplay) { * Test touch should not work if outside of surface. */ TEST_F(MultiTouchInputMapperTest, Viewports_SurfaceRange) { - MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); addConfigurationProperty("touch.deviceType", "touchScreen"); prepareDisplay(DISPLAY_ORIENTATION_0); prepareAxes(POSITION); - addMapperAndConfigure(mapper); + MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>(); // Touch on left-top area should work. int32_t rawX = DISPLAY_WIDTH / 2 - 1; @@ -6783,7 +6707,7 @@ TEST_F(MultiTouchInputMapperTest, Viewports_SurfaceRange) { ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args)); // Reset. - mapper->reset(ARBITRARY_TIME); + mapper.reset(ARBITRARY_TIME); // Let logical display be different to physical display and rotate 90-degrees. std::optional<DisplayViewport> internalViewport = @@ -6811,11 +6735,10 @@ TEST_F(MultiTouchInputMapperTest, Viewports_SurfaceRange) { } TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleSingleTouch) { - MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); addConfigurationProperty("touch.deviceType", "touchScreen"); prepareDisplay(DISPLAY_ORIENTATION_0); prepareAxes(POSITION | ID | SLOT | TOOL_TYPE); - addMapperAndConfigure(mapper); + MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>(); NotifyMotionArgs motionArgs; @@ -6857,11 +6780,10 @@ TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleSingleTouch) { * UP events should be ignored. */ TEST_F(MultiTouchInputMapperTest, Process_ShouldHandlePalmToolType) { - MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); addConfigurationProperty("touch.deviceType", "touchScreen"); prepareDisplay(DISPLAY_ORIENTATION_0); prepareAxes(POSITION | ID | SLOT | TOOL_TYPE); - addMapperAndConfigure(mapper); + MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>(); NotifyMotionArgs motionArgs; diff --git a/services/inputflinger/tests/UinputDevice.cpp b/services/inputflinger/tests/UinputDevice.cpp new file mode 100644 index 0000000000..2775d21ce2 --- /dev/null +++ b/services/inputflinger/tests/UinputDevice.cpp @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "UinputDevice.h" + +#include <android-base/stringprintf.h> + +namespace android { + +// --- UinputDevice --- + +UinputDevice::UinputDevice(const char* name) : mName(name) {} + +UinputDevice::~UinputDevice() { + if (ioctl(mDeviceFd, UI_DEV_DESTROY)) { + ALOGE("Error while destroying uinput device: %s", strerror(errno)); + } + mDeviceFd.reset(); +} + +void UinputDevice::init() { + mDeviceFd = android::base::unique_fd(open("/dev/uinput", O_WRONLY | O_NONBLOCK)); + if (mDeviceFd < 0) { + FAIL() << "Can't open /dev/uinput :" << strerror(errno); + } + + struct uinput_user_dev device = {}; + strlcpy(device.name, mName, UINPUT_MAX_NAME_SIZE); + device.id.bustype = BUS_USB; + device.id.vendor = 0x01; + device.id.product = 0x01; + device.id.version = 1; + + // Using EXPECT instead of ASSERT to allow the device creation to continue even when + // some failures are reported when configuring the device. + EXPECT_NO_FATAL_FAILURE(configureDevice(mDeviceFd, &device)); + + if (write(mDeviceFd, &device, sizeof(device)) < 0) { + FAIL() << "Could not write uinput_user_dev struct into uinput file descriptor: " + << strerror(errno); + } + + if (ioctl(mDeviceFd, UI_DEV_CREATE)) { + FAIL() << "Error in ioctl : UI_DEV_CREATE: " << strerror(errno); + } +} + +void UinputDevice::injectEvent(uint16_t type, uint16_t code, int32_t value) { + struct input_event event = {}; + event.type = type; + event.code = code; + event.value = value; + event.time = {}; // uinput ignores the timestamp + + if (write(mDeviceFd, &event, sizeof(input_event)) < 0) { + std::string msg = base::StringPrintf("Could not write event %" PRIu16 " %" PRIu16 + " with value %" PRId32 " : %s", + type, code, value, strerror(errno)); + ALOGE("%s", msg.c_str()); + ADD_FAILURE() << msg.c_str(); + } +} + +// --- UinputKeyboard --- + +UinputKeyboard::UinputKeyboard(std::initializer_list<int> keys) + : UinputDevice(UinputKeyboard::KEYBOARD_NAME), mKeys(keys.begin(), keys.end()) {} + +void UinputKeyboard::configureDevice(int fd, uinput_user_dev* device) { + // enable key press/release event + if (ioctl(fd, UI_SET_EVBIT, EV_KEY)) { + ADD_FAILURE() << "Error in ioctl : UI_SET_EVBIT : EV_KEY: " << strerror(errno); + } + + // enable set of KEY events + std::for_each(mKeys.begin(), mKeys.end(), [fd](int key) { + if (ioctl(fd, UI_SET_KEYBIT, key)) { + ADD_FAILURE() << "Error in ioctl : UI_SET_KEYBIT : " << key << " : " << strerror(errno); + } + }); + + // enable synchronization event + if (ioctl(fd, UI_SET_EVBIT, EV_SYN)) { + ADD_FAILURE() << "Error in ioctl : UI_SET_EVBIT : EV_SYN: " << strerror(errno); + } +} + +void UinputKeyboard::pressKey(int key) { + if (mKeys.find(key) == mKeys.end()) { + ADD_FAILURE() << mName << ": Cannot inject key press: Key not found: " << key; + } + EXPECT_NO_FATAL_FAILURE(injectEvent(EV_KEY, key, 1)); + EXPECT_NO_FATAL_FAILURE(injectEvent(EV_SYN, SYN_REPORT, 0)); +} + +void UinputKeyboard::releaseKey(int key) { + if (mKeys.find(key) == mKeys.end()) { + ADD_FAILURE() << mName << ": Cannot inject key release: Key not found: " << key; + } + EXPECT_NO_FATAL_FAILURE(injectEvent(EV_KEY, key, 0)); + EXPECT_NO_FATAL_FAILURE(injectEvent(EV_SYN, SYN_REPORT, 0)); +} + +void UinputKeyboard::pressAndReleaseKey(int key) { + EXPECT_NO_FATAL_FAILURE(pressKey(key)); + EXPECT_NO_FATAL_FAILURE(releaseKey(key)); +} + +// --- UinputHomeKey--- + +UinputHomeKey::UinputHomeKey() : UinputKeyboard({KEY_HOME}) {} + +void UinputHomeKey::pressAndReleaseHomeKey() { + EXPECT_NO_FATAL_FAILURE(pressAndReleaseKey(KEY_HOME)); +} + +} // namespace android diff --git a/services/inputflinger/tests/UinputDevice.h b/services/inputflinger/tests/UinputDevice.h new file mode 100644 index 0000000000..57d9011695 --- /dev/null +++ b/services/inputflinger/tests/UinputDevice.h @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _UI_TEST_INPUT_UINPUT_INJECTOR_H +#define _UI_TEST_INPUT_UINPUT_INJECTOR_H + +#include <android-base/unique_fd.h> +#include <gtest/gtest.h> +#include <inttypes.h> +#include <linux/uinput.h> +#include <log/log.h> + +#include <memory> + +namespace android { + +// This is the factory method that must be used to create a UinputDevice. +template <class D, class... Ts> +std::unique_ptr<D> createUinputDevice(Ts... args) { + // Using `new` to access non-public constructors. + std::unique_ptr<D> dev(new D(&args...)); + EXPECT_NO_FATAL_FAILURE(dev->init()); + return dev; +} + +// --- UinputDevice --- + +class UinputDevice { +public: + virtual ~UinputDevice(); + + inline const char* getName() const { return mName; } + + // Subclasses must either provide a public constructor or must be-friend the factory method. + template <class D, class... Ts> + friend std::unique_ptr<D> createUinputDevice(Ts... args); + +protected: + const char* mName; + + UinputDevice(const char* name); + + // Signals which types of events this device supports before it is created. + // This must be overridden by subclasses. + virtual void configureDevice(int fd, uinput_user_dev* device) = 0; + + void injectEvent(uint16_t type, uint16_t code, int32_t value); + +private: + base::unique_fd mDeviceFd; + + // This is called once by the factory method createUinputDevice(). + void init(); +}; + +// --- UinputKeyboard --- + +class UinputKeyboard : public UinputDevice { +public: + static constexpr const char* KEYBOARD_NAME = "Test Keyboard Device"; + + // Injects key press and sync. + void pressKey(int key); + // Injects key release and sync. + void releaseKey(int key); + // Injects 4 events: key press, sync, key release, and sync. + void pressAndReleaseKey(int key); + + template <class D, class... Ts> + friend std::unique_ptr<D> createUinputDevice(Ts... args); + +protected: + UinputKeyboard(std::initializer_list<int> keys = {}); + +private: + void configureDevice(int fd, uinput_user_dev* device) override; + + std::set<int> mKeys; +}; + +// --- UinputHomeKey--- + +// A keyboard device that has a single HOME key. +class UinputHomeKey : public UinputKeyboard { +public: + // Injects 4 events: key press, sync, key release, and sync. + void pressAndReleaseHomeKey(); + + template <class D, class... Ts> + friend std::unique_ptr<D> createUinputDevice(Ts... args); + +private: + UinputHomeKey(); +}; + +} // namespace android + +#endif // _UI_TEST_INPUT_UINPUT_INJECTOR_H diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp index 914a4cb54d..22a15c6df8 100644 --- a/services/sensorservice/SensorService.cpp +++ b/services/sensorservice/SensorService.cpp @@ -210,12 +210,6 @@ void SensorService::onFirstRef() { registerSensor(new RotationVectorSensor(), !needRotationVector, true); registerSensor(new OrientationSensor(), !needRotationVector, true); - bool needLinearAcceleration = - (virtualSensorsNeeds & (1<<SENSOR_TYPE_LINEAR_ACCELERATION)) != 0; - - registerSensor(new LinearAccelerationSensor(list, count), - !needLinearAcceleration, true); - // virtual debugging sensors are not for user registerSensor( new CorrectedGyroSensor(list, count), true, true); registerSensor( new GyroDriftSensor(), true, true); @@ -225,6 +219,11 @@ void SensorService::onFirstRef() { bool needGravitySensor = (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) != 0; registerSensor(new GravitySensor(list, count), !needGravitySensor, true); + bool needLinearAcceleration = + (virtualSensorsNeeds & (1<<SENSOR_TYPE_LINEAR_ACCELERATION)) != 0; + registerSensor(new LinearAccelerationSensor(list, count), + !needLinearAcceleration, true); + bool needGameRotationVector = (virtualSensorsNeeds & (1<<SENSOR_TYPE_GAME_ROTATION_VECTOR)) != 0; registerSensor(new GameRotationVectorSensor(), !needGameRotationVector, true); diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp index 1b1e8890ab..4ffdf9761e 100644 --- a/services/surfaceflinger/Android.bp +++ b/services/surfaceflinger/Android.bp @@ -136,7 +136,7 @@ filegroup { "BufferStateLayer.cpp", "ClientCache.cpp", "Client.cpp", - "ColorLayer.cpp", + "EffectLayer.cpp", "ContainerLayer.cpp", "DisplayDevice.cpp", "DisplayHardware/ComposerHal.cpp", diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp index 371b80227b..1188dfeec2 100644 --- a/services/surfaceflinger/BufferStateLayer.cpp +++ b/services/surfaceflinger/BufferStateLayer.cpp @@ -32,7 +32,7 @@ #include <private/gui/SyncFeatures.h> #include <renderengine/Image.h> -#include "ColorLayer.h" +#include "EffectLayer.h" #include "FrameTracer/FrameTracer.h" #include "TimeStats/TimeStats.h" diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/EffectLayer.cpp index 83050c4774..e928c57929 100644 --- a/services/surfaceflinger/ColorLayer.cpp +++ b/services/surfaceflinger/EffectLayer.cpp @@ -20,9 +20,9 @@ // #define LOG_NDEBUG 0 #undef LOG_TAG -#define LOG_TAG "ColorLayer" +#define LOG_TAG "EffectLayer" -#include "ColorLayer.h" +#include "EffectLayer.h" #include <stdint.h> #include <stdlib.h> @@ -41,13 +41,13 @@ namespace android { // --------------------------------------------------------------------------- -ColorLayer::ColorLayer(const LayerCreationArgs& args) +EffectLayer::EffectLayer(const LayerCreationArgs& args) : Layer(args), mCompositionState{mFlinger->getCompositionEngine().createLayerFECompositionState()} {} -ColorLayer::~ColorLayer() = default; +EffectLayer::~EffectLayer() = default; -std::optional<compositionengine::LayerFE::LayerSettings> ColorLayer::prepareClientComposition( +std::optional<compositionengine::LayerFE::LayerSettings> EffectLayer::prepareClientComposition( compositionengine::LayerFE::ClientCompositionTargetSettings& targetSettings) { auto result = Layer::prepareClientComposition(targetSettings); if (!result) { @@ -57,11 +57,11 @@ std::optional<compositionengine::LayerFE::LayerSettings> ColorLayer::prepareClie return result; } -bool ColorLayer::isVisible() const { +bool EffectLayer::isVisible() const { return !isHiddenByPolicy() && getAlpha() > 0.0_hf; } -bool ColorLayer::setColor(const half3& color) { +bool EffectLayer::setColor(const half3& color) { if (mCurrentState.color.r == color.r && mCurrentState.color.g == color.g && mCurrentState.color.b == color.b) { return false; @@ -76,7 +76,7 @@ bool ColorLayer::setColor(const half3& color) { return true; } -bool ColorLayer::setDataspace(ui::Dataspace dataspace) { +bool EffectLayer::setDataspace(ui::Dataspace dataspace) { if (mCurrentState.dataspace == dataspace) { return false; } @@ -88,7 +88,7 @@ bool ColorLayer::setDataspace(ui::Dataspace dataspace) { return true; } -void ColorLayer::preparePerFrameCompositionState() { +void EffectLayer::preparePerFrameCompositionState() { Layer::preparePerFrameCompositionState(); auto* compositionState = editCompositionState(); @@ -96,30 +96,30 @@ void ColorLayer::preparePerFrameCompositionState() { compositionState->compositionType = Hwc2::IComposerClient::Composition::SOLID_COLOR; } -sp<compositionengine::LayerFE> ColorLayer::getCompositionEngineLayerFE() const { +sp<compositionengine::LayerFE> EffectLayer::getCompositionEngineLayerFE() const { return asLayerFE(); } -compositionengine::LayerFECompositionState* ColorLayer::editCompositionState() { +compositionengine::LayerFECompositionState* EffectLayer::editCompositionState() { return mCompositionState.get(); } -const compositionengine::LayerFECompositionState* ColorLayer::getCompositionState() const { +const compositionengine::LayerFECompositionState* EffectLayer::getCompositionState() const { return mCompositionState.get(); } -bool ColorLayer::isOpaque(const Layer::State& s) const { +bool EffectLayer::isOpaque(const Layer::State& s) const { // Consider the layer to be opaque if its opaque flag is set or its effective // alpha (considering the alpha of its parents as well) is 1.0; return (s.flags & layer_state_t::eLayerOpaque) != 0 || getAlpha() == 1.0_hf; } -ui::Dataspace ColorLayer::getDataSpace() const { +ui::Dataspace EffectLayer::getDataSpace() const { return mDrawingState.dataspace; } -sp<Layer> ColorLayer::createClone() { - sp<ColorLayer> layer = mFlinger->getFactory().createColorLayer( +sp<Layer> EffectLayer::createClone() { + sp<EffectLayer> layer = mFlinger->getFactory().createEffectLayer( LayerCreationArgs(mFlinger.get(), nullptr, mName + " (Mirror)", 0, 0, 0, LayerMetadata())); layer->setInitialValuesForClone(this); diff --git a/services/surfaceflinger/ColorLayer.h b/services/surfaceflinger/EffectLayer.h index 4deb162191..8694283760 100644 --- a/services/surfaceflinger/ColorLayer.h +++ b/services/surfaceflinger/EffectLayer.h @@ -23,15 +23,19 @@ namespace android { -class ColorLayer : public Layer { +// A layer that can render a combination of the following effects. +// * fill the bounds of the layer with a color +// * render a shadow cast by the bounds of the layer +// If no effects are enabled, the layer is considered to be invisible. +class EffectLayer : public Layer { public: - explicit ColorLayer(const LayerCreationArgs&); - ~ColorLayer() override; + explicit EffectLayer(const LayerCreationArgs&); + ~EffectLayer() override; sp<compositionengine::LayerFE> getCompositionEngineLayerFE() const override; compositionengine::LayerFECompositionState* editCompositionState() override; - const char* getType() const override { return "ColorLayer"; } + const char* getType() const override { return "EffectLayer"; } bool isVisible() const override; bool setColor(const half3& color) override; diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 6ff23c5f51..fd86da85a0 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -56,10 +56,10 @@ #include <sstream> #include "BufferLayer.h" -#include "ColorLayer.h" #include "Colorizer.h" #include "DisplayDevice.h" #include "DisplayHardware/HWComposer.h" +#include "EffectLayer.h" #include "FrameTracer/FrameTracer.h" #include "LayerProtoHelper.h" #include "LayerRejecter.h" @@ -164,7 +164,7 @@ LayerCreationArgs::LayerCreationArgs(SurfaceFlinger* flinger, const sp<Client> c /* * onLayerDisplayed is only meaningful for BufferLayer, but, is called through * Layer. So, the implementation is done in BufferLayer. When called on a - * ColorLayer object, it's essentially a NOP. + * EffectLayer object, it's essentially a NOP. */ void Layer::onLayerDisplayed(const sp<Fence>& /*releaseFence*/) {} @@ -1091,9 +1091,9 @@ bool Layer::setBackgroundColor(const half3& color, float alpha, ui::Dataspace da if (!mCurrentState.bgColorLayer && alpha != 0) { // create background color layer if one does not yet exist - uint32_t flags = ISurfaceComposerClient::eFXSurfaceColor; + uint32_t flags = ISurfaceComposerClient::eFXSurfaceEffect; std::string name = mName + "BackgroundColorLayer"; - mCurrentState.bgColorLayer = mFlinger->getFactory().createColorLayer( + mCurrentState.bgColorLayer = mFlinger->getFactory().createEffectLayer( LayerCreationArgs(mFlinger.get(), nullptr, std::move(name), 0, 0, flags, LayerMetadata())); diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index c110462d61..c2dbd142b4 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -212,7 +212,7 @@ public: InputWindowInfo inputInfo; wp<Layer> touchableRegionCrop; - // dataspace is only used by BufferStateLayer and ColorLayer + // dataspace is only used by BufferStateLayer and EffectLayer ui::Dataspace dataspace; // The fields below this point are only used by BufferStateLayer diff --git a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp index b467f24207..399da19c75 100644 --- a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp +++ b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp @@ -53,15 +53,15 @@ inline void VSyncPredictor::traceInt64If(const char* name, int64_t value) const } inline size_t VSyncPredictor::next(int i) const { - return (i + 1) % timestamps.size(); + return (i + 1) % mTimestamps.size(); } bool VSyncPredictor::validate(nsecs_t timestamp) const { - if (lastTimestampIndex < 0 || timestamps.empty()) { + if (mLastTimestampIndex < 0 || mTimestamps.empty()) { return true; } - auto const aValidTimestamp = timestamps[lastTimestampIndex]; + auto const aValidTimestamp = mTimestamps[mLastTimestampIndex]; auto const percent = (timestamp - aValidTimestamp) % mIdealPeriod * kMaxPercent / mIdealPeriod; return percent < kOutlierTolerancePercent || percent > (kMaxPercent - kOutlierTolerancePercent); } @@ -79,15 +79,15 @@ bool VSyncPredictor::addVsyncTimestamp(nsecs_t timestamp) { return false; } - if (timestamps.size() != kHistorySize) { - timestamps.push_back(timestamp); - lastTimestampIndex = next(lastTimestampIndex); + if (mTimestamps.size() != kHistorySize) { + mTimestamps.push_back(timestamp); + mLastTimestampIndex = next(mLastTimestampIndex); } else { - lastTimestampIndex = next(lastTimestampIndex); - timestamps[lastTimestampIndex] = timestamp; + mLastTimestampIndex = next(mLastTimestampIndex); + mTimestamps[mLastTimestampIndex] = timestamp; } - if (timestamps.size() < kMinimumSamplesForPrediction) { + if (mTimestamps.size() < kMinimumSamplesForPrediction) { mRateMap[mIdealPeriod] = {mIdealPeriod, 0}; return true; } @@ -107,11 +107,11 @@ bool VSyncPredictor::addVsyncTimestamp(nsecs_t timestamp) { // // intercept = mean(Y) - slope * mean(X) // - std::vector<nsecs_t> vsyncTS(timestamps.size()); - std::vector<nsecs_t> ordinals(timestamps.size()); + std::vector<nsecs_t> vsyncTS(mTimestamps.size()); + std::vector<nsecs_t> ordinals(mTimestamps.size()); // normalizing to the oldest timestamp cuts down on error in calculating the intercept. - auto const oldest_ts = *std::min_element(timestamps.begin(), timestamps.end()); + auto const oldest_ts = *std::min_element(mTimestamps.begin(), mTimestamps.end()); auto it = mRateMap.find(mIdealPeriod); auto const currentPeriod = std::get<0>(it->second); // TODO (b/144707443): its important that there's some precision in the mean of the ordinals @@ -120,10 +120,10 @@ bool VSyncPredictor::addVsyncTimestamp(nsecs_t timestamp) { // scheduler::utils::calculate_mean to have a fixed point fractional part. static constexpr int kScalingFactor = 10; - for (auto i = 0u; i < timestamps.size(); i++) { - traceInt64If("VSP-ts", timestamps[i]); + for (auto i = 0u; i < mTimestamps.size(); i++) { + traceInt64If("VSP-ts", mTimestamps[i]); - vsyncTS[i] = timestamps[i] - oldest_ts; + vsyncTS[i] = mTimestamps[i] - oldest_ts; ordinals[i] = ((vsyncTS[i] + (currentPeriod / 2)) / currentPeriod) * kScalingFactor; } @@ -143,12 +143,20 @@ bool VSyncPredictor::addVsyncTimestamp(nsecs_t timestamp) { if (CC_UNLIKELY(bottom == 0)) { it->second = {mIdealPeriod, 0}; + clearTimestamps(); return false; } nsecs_t const anticipatedPeriod = top / bottom * kScalingFactor; nsecs_t const intercept = meanTS - (anticipatedPeriod * meanOrdinal / kScalingFactor); + auto const percent = std::abs(anticipatedPeriod - mIdealPeriod) * kMaxPercent / mIdealPeriod; + if (percent >= kOutlierTolerancePercent) { + it->second = {mIdealPeriod, 0}; + clearTimestamps(); + return false; + } + traceInt64If("VSP-period", anticipatedPeriod); traceInt64If("VSP-intercept", intercept); @@ -164,14 +172,14 @@ nsecs_t VSyncPredictor::nextAnticipatedVSyncTimeFrom(nsecs_t timePoint) const { auto const [slope, intercept] = getVSyncPredictionModel(lk); - if (timestamps.empty()) { + if (mTimestamps.empty()) { traceInt64If("VSP-mode", 1); auto const knownTimestamp = mKnownTimestamp ? *mKnownTimestamp : timePoint; auto const numPeriodsOut = ((timePoint - knownTimestamp) / mIdealPeriod) + 1; return knownTimestamp + numPeriodsOut * mIdealPeriod; } - auto const oldest = *std::min_element(timestamps.begin(), timestamps.end()); + auto const oldest = *std::min_element(mTimestamps.begin(), mTimestamps.end()); // See b/145667109, the ordinal calculation must take into account the intercept. auto const zeroPoint = oldest + intercept; @@ -225,10 +233,10 @@ void VSyncPredictor::setPeriod(nsecs_t period) { } void VSyncPredictor::clearTimestamps() { - if (!timestamps.empty()) { - mKnownTimestamp = *std::max_element(timestamps.begin(), timestamps.end()); - timestamps.clear(); - lastTimestampIndex = 0; + if (!mTimestamps.empty()) { + mKnownTimestamp = *std::max_element(mTimestamps.begin(), mTimestamps.end()); + mTimestamps.clear(); + mLastTimestampIndex = 0; } } @@ -236,11 +244,11 @@ bool VSyncPredictor::needsMoreSamples(nsecs_t now) const { using namespace std::literals::chrono_literals; std::lock_guard<std::mutex> lk(mMutex); bool needsMoreSamples = true; - if (timestamps.size() >= kMinimumSamplesForPrediction) { + if (mTimestamps.size() >= kMinimumSamplesForPrediction) { nsecs_t constexpr aLongTime = std::chrono::duration_cast<std::chrono::nanoseconds>(500ms).count(); - if (!(lastTimestampIndex < 0 || timestamps.empty())) { - auto const lastTimestamp = timestamps[lastTimestampIndex]; + if (!(mLastTimestampIndex < 0 || mTimestamps.empty())) { + auto const lastTimestamp = mTimestamps[mLastTimestampIndex]; needsMoreSamples = !((lastTimestamp + aLongTime) > now); } } diff --git a/services/surfaceflinger/Scheduler/VSyncPredictor.h b/services/surfaceflinger/Scheduler/VSyncPredictor.h index 532fe9e928..ef1d88ac27 100644 --- a/services/surfaceflinger/Scheduler/VSyncPredictor.h +++ b/services/surfaceflinger/Scheduler/VSyncPredictor.h @@ -83,8 +83,8 @@ private: std::unordered_map<nsecs_t, std::tuple<nsecs_t, nsecs_t>> mutable mRateMap GUARDED_BY(mMutex); - int lastTimestampIndex GUARDED_BY(mMutex) = 0; - std::vector<nsecs_t> timestamps GUARDED_BY(mMutex); + int mLastTimestampIndex GUARDED_BY(mMutex) = 0; + std::vector<nsecs_t> mTimestamps GUARDED_BY(mMutex); }; } // namespace android::scheduler diff --git a/services/surfaceflinger/Scheduler/VSyncReactor.cpp b/services/surfaceflinger/Scheduler/VSyncReactor.cpp index da73e4e194..949ba4ca52 100644 --- a/services/surfaceflinger/Scheduler/VSyncReactor.cpp +++ b/services/surfaceflinger/Scheduler/VSyncReactor.cpp @@ -98,6 +98,9 @@ private: { std::lock_guard<std::mutex> lk(mMutex); + if (mStopped) { + return; + } auto const schedule_result = mRegistration.schedule(calculateWorkload(), vsynctime); LOG_ALWAYS_FATAL_IF((schedule_result != ScheduleResult::Scheduled), "Error rescheduling callback: rc %X", schedule_result); diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index d971625ef4..67c3d52f81 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -83,10 +83,10 @@ #include "BufferQueueLayer.h" #include "BufferStateLayer.h" #include "Client.h" -#include "ColorLayer.h" #include "Colorizer.h" #include "ContainerLayer.h" #include "DisplayDevice.h" +#include "EffectLayer.h" #include "Layer.h" #include "LayerVector.h" #include "MonitoredProducer.h" @@ -2081,7 +2081,8 @@ void SurfaceFlinger::postComposition() } }); - if (presentFenceTime->isValid()) { + if (displayDevice && displayDevice->isPrimary() && + displayDevice->getPowerMode() == HWC_POWER_MODE_NORMAL && presentFenceTime->isValid()) { mScheduler->addPresentFence(presentFenceTime); } @@ -3699,7 +3700,7 @@ status_t SurfaceFlinger::createLayer(const String8& name, const sp<Client>& clie result = createBufferStateLayer(client, std::move(uniqueName), w, h, flags, std::move(metadata), handle, outTransformHint, &layer); break; - case ISurfaceComposerClient::eFXSurfaceColor: + case ISurfaceComposerClient::eFXSurfaceEffect: // check if buffer size is set for color layer. if (w > 0 || h > 0) { ALOGE("createLayer() failed, w or h cannot be set for color layer (w=%d, h=%d)", @@ -3707,8 +3708,8 @@ status_t SurfaceFlinger::createLayer(const String8& name, const sp<Client>& clie return BAD_VALUE; } - result = createColorLayer(client, std::move(uniqueName), w, h, flags, - std::move(metadata), handle, &layer); + result = createEffectLayer(client, std::move(uniqueName), w, h, flags, + std::move(metadata), handle, &layer); break; case ISurfaceComposerClient::eFXSurfaceContainer: // check if buffer size is set for container layer. @@ -3826,10 +3827,10 @@ status_t SurfaceFlinger::createBufferStateLayer(const sp<Client>& client, std::s return NO_ERROR; } -status_t SurfaceFlinger::createColorLayer(const sp<Client>& client, std::string name, uint32_t w, - uint32_t h, uint32_t flags, LayerMetadata metadata, - sp<IBinder>* handle, sp<Layer>* outLayer) { - *outLayer = getFactory().createColorLayer( +status_t SurfaceFlinger::createEffectLayer(const sp<Client>& client, std::string name, uint32_t w, + uint32_t h, uint32_t flags, LayerMetadata metadata, + sp<IBinder>* handle, sp<Layer>* outLayer) { + *outLayer = getFactory().createEffectLayer( {this, client, std::move(name), w, h, flags, std::move(metadata)}); *handle = (*outLayer)->getHandle(); return NO_ERROR; diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 8cabcf0ef6..0d43215ba5 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -653,9 +653,9 @@ private: sp<IBinder>* outHandle, uint32_t* outTransformHint, sp<Layer>* outLayer); - status_t createColorLayer(const sp<Client>& client, std::string name, uint32_t w, uint32_t h, - uint32_t flags, LayerMetadata metadata, sp<IBinder>* outHandle, - sp<Layer>* outLayer); + status_t createEffectLayer(const sp<Client>& client, std::string name, uint32_t w, uint32_t h, + uint32_t flags, LayerMetadata metadata, sp<IBinder>* outHandle, + sp<Layer>* outLayer); status_t createContainerLayer(const sp<Client>& client, std::string name, uint32_t w, uint32_t h, uint32_t flags, LayerMetadata metadata, diff --git a/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp b/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp index f9658a78d6..d49133d1fc 100644 --- a/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp +++ b/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp @@ -25,9 +25,9 @@ #include "BufferLayerConsumer.h" #include "BufferQueueLayer.h" #include "BufferStateLayer.h" -#include "ColorLayer.h" #include "ContainerLayer.h" #include "DisplayDevice.h" +#include "EffectLayer.h" #include "Layer.h" #include "MonitoredProducer.h" #include "NativeWindowSurface.h" @@ -139,8 +139,8 @@ sp<BufferStateLayer> DefaultFactory::createBufferStateLayer(const LayerCreationA return new BufferStateLayer(args); } -sp<ColorLayer> DefaultFactory::createColorLayer(const LayerCreationArgs& args) { - return new ColorLayer(args); +sp<EffectLayer> DefaultFactory::createEffectLayer(const LayerCreationArgs& args) { + return new EffectLayer(args); } } // namespace android::surfaceflinger diff --git a/services/surfaceflinger/SurfaceFlingerDefaultFactory.h b/services/surfaceflinger/SurfaceFlingerDefaultFactory.h index 36fae217ce..89194c7ad1 100644 --- a/services/surfaceflinger/SurfaceFlingerDefaultFactory.h +++ b/services/surfaceflinger/SurfaceFlingerDefaultFactory.h @@ -55,7 +55,7 @@ public: std::unique_ptr<compositionengine::CompositionEngine> createCompositionEngine() override; sp<BufferQueueLayer> createBufferQueueLayer(const LayerCreationArgs& args) override; sp<BufferStateLayer> createBufferStateLayer(const LayerCreationArgs& args) override; - sp<ColorLayer> createColorLayer(const LayerCreationArgs& args) override; + sp<EffectLayer> createEffectLayer(const LayerCreationArgs& args) override; sp<ContainerLayer> createContainerLayer(const LayerCreationArgs& args) override; }; diff --git a/services/surfaceflinger/SurfaceFlingerFactory.h b/services/surfaceflinger/SurfaceFlingerFactory.h index c7da730c64..209bd0caba 100644 --- a/services/surfaceflinger/SurfaceFlingerFactory.h +++ b/services/surfaceflinger/SurfaceFlingerFactory.h @@ -31,7 +31,7 @@ typedef int32_t PixelFormat; class BufferQueueLayer; class BufferStateLayer; class BufferLayerConsumer; -class ColorLayer; +class EffectLayer; class ContainerLayer; class DisplayDevice; class DispSync; @@ -104,7 +104,7 @@ public: virtual sp<BufferQueueLayer> createBufferQueueLayer(const LayerCreationArgs& args) = 0; virtual sp<BufferStateLayer> createBufferStateLayer(const LayerCreationArgs& args) = 0; - virtual sp<ColorLayer> createColorLayer(const LayerCreationArgs& args) = 0; + virtual sp<EffectLayer> createEffectLayer(const LayerCreationArgs& args) = 0; virtual sp<ContainerLayer> createContainerLayer(const LayerCreationArgs& args) = 0; protected: diff --git a/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp b/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp index 24874b010b..6c8eb27bd0 100644 --- a/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp +++ b/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp @@ -531,7 +531,7 @@ TEST_P(LayerRenderTypeTransactionTest, SetColorBasic) { ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(bufferLayer, Color::RED, 32, 32)); ASSERT_NO_FATAL_FAILURE(colorLayer = createLayer("test", 0 /* buffer width */, 0 /* buffer height */, - ISurfaceComposerClient::eFXSurfaceColor)); + ISurfaceComposerClient::eFXSurfaceEffect)); Transaction() .setCrop_legacy(colorLayer, Rect(0, 0, 32, 32)) @@ -570,7 +570,7 @@ void LayerRenderTypeTransactionTest::setBackgroundColorHelper(uint32_t layerType Color priorBgColor = Color::BLUE; Color expectedColor = Color::BLACK; switch (layerType) { - case ISurfaceComposerClient::eFXSurfaceColor: + case ISurfaceComposerClient::eFXSurfaceEffect: ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 0, 0, layerType)); Transaction() .setCrop_legacy(layer, Rect(0, 0, width, height)) @@ -599,7 +599,7 @@ void LayerRenderTypeTransactionTest::setBackgroundColorHelper(uint32_t layerType return; } - if (priorColor && layerType != ISurfaceComposerClient::eFXSurfaceColor) { + if (priorColor && layerType != ISurfaceComposerClient::eFXSurfaceEffect) { Transaction() .setBackgroundColor(layer, half3(0, 0, 1.0f), 1.0f, ui::Dataspace::UNKNOWN) .apply(); @@ -628,7 +628,7 @@ TEST_P(LayerRenderTypeTransactionTest, SetBackgroundColor_Color_NoEffect) { bool bufferFill = false; float alpha = 1.0f; Color finalColor = Color::RED; - ASSERT_NO_FATAL_FAILURE(setBackgroundColorHelper(ISurfaceComposerClient::eFXSurfaceColor, + ASSERT_NO_FATAL_FAILURE(setBackgroundColorHelper(ISurfaceComposerClient::eFXSurfaceEffect, priorColor, bufferFill, alpha, finalColor)); } @@ -744,7 +744,7 @@ TEST_P(LayerRenderTypeTransactionTest, SetColorClamped) { sp<SurfaceControl> colorLayer; ASSERT_NO_FATAL_FAILURE(colorLayer = createLayer("test", 0 /* buffer width */, 0 /* buffer height */, - ISurfaceComposerClient::eFXSurfaceColor)); + ISurfaceComposerClient::eFXSurfaceEffect)); Transaction() .setCrop_legacy(colorLayer, Rect(0, 0, 32, 32)) .setColor(colorLayer, half3(2.0f, -1.0f, 0.0f)) @@ -760,7 +760,7 @@ TEST_P(LayerRenderTypeTransactionTest, SetColorWithAlpha) { ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(bufferLayer, Color::RED, 32, 32)); ASSERT_NO_FATAL_FAILURE(colorLayer = createLayer("test", 0 /* buffer width */, 0 /* buffer height */, - ISurfaceComposerClient::eFXSurfaceColor)); + ISurfaceComposerClient::eFXSurfaceEffect)); Transaction().setCrop_legacy(colorLayer, Rect(0, 0, 32, 32)).apply(); const half3 color(15.0f / 255.0f, 51.0f / 255.0f, 85.0f / 255.0f); @@ -787,7 +787,7 @@ TEST_P(LayerRenderTypeTransactionTest, SetColorWithParentAlpha_Bug74220420) { ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(bufferLayer, Color::RED, 32, 32)); ASSERT_NO_FATAL_FAILURE(colorLayer = createLayer("childWithColor", 0 /* buffer width */, 0 /* buffer height */, - ISurfaceComposerClient::eFXSurfaceColor)); + ISurfaceComposerClient::eFXSurfaceEffect)); Transaction().setCrop_legacy(colorLayer, Rect(0, 0, 32, 32)).apply(); const half3 color(15.0f / 255.0f, 51.0f / 255.0f, 85.0f / 255.0f); const float alpha = 0.25f; @@ -1663,7 +1663,7 @@ TEST_P(LayerRenderTypeTransactionTest, SetColorTransformBasic) { sp<SurfaceControl> colorLayer; ASSERT_NO_FATAL_FAILURE(colorLayer = createLayer("test", 0 /* buffer width */, 0 /* buffer height */, - ISurfaceComposerClient::eFXSurfaceColor)); + ISurfaceComposerClient::eFXSurfaceEffect)); Transaction() .setCrop_legacy(colorLayer, Rect(0, 0, 32, 32)) .setLayer(colorLayer, mLayerZBase + 1) @@ -1719,7 +1719,7 @@ TEST_P(LayerRenderTypeTransactionTest, SetColorTransformOnParent) { ISurfaceComposerClient::eFXSurfaceContainer)); ASSERT_NO_FATAL_FAILURE( colorLayer = createLayer("test", 0 /* buffer width */, 0 /* buffer height */, - ISurfaceComposerClient::eFXSurfaceColor, parentLayer.get())); + ISurfaceComposerClient::eFXSurfaceEffect, parentLayer.get())); Transaction() .setCrop_legacy(parentLayer, Rect(0, 0, 100, 100)) @@ -1780,7 +1780,7 @@ TEST_P(LayerRenderTypeTransactionTest, SetColorTransformOnChildAndParent) { ISurfaceComposerClient::eFXSurfaceContainer)); ASSERT_NO_FATAL_FAILURE( colorLayer = createLayer("test", 0 /* buffer width */, 0 /* buffer height */, - ISurfaceComposerClient::eFXSurfaceColor, parentLayer.get())); + ISurfaceComposerClient::eFXSurfaceEffect, parentLayer.get())); Transaction() .setCrop_legacy(parentLayer, Rect(0, 0, 100, 100)) diff --git a/services/surfaceflinger/tests/LayerTransactionTest.h b/services/surfaceflinger/tests/LayerTransactionTest.h index 5eb1739219..932c7c86fa 100644 --- a/services/surfaceflinger/tests/LayerTransactionTest.h +++ b/services/surfaceflinger/tests/LayerTransactionTest.h @@ -89,7 +89,7 @@ protected: SurfaceControl* parent = nullptr) { auto colorLayer = createSurface(mClient, name, 0 /* buffer width */, 0 /* buffer height */, PIXEL_FORMAT_RGBA_8888, - ISurfaceComposerClient::eFXSurfaceColor, parent); + ISurfaceComposerClient::eFXSurfaceEffect, parent); asTransaction([&](Transaction& t) { t.setColor(colorLayer, half3{color.r / 255.0f, color.g / 255.0f, color.b / 255.0f}); t.setAlpha(colorLayer, color.a / 255.0f); @@ -268,7 +268,7 @@ private: mBlackBgSurface = createSurface(mClient, "BaseSurface", 0 /* buffer width */, 0 /* buffer height */, - PIXEL_FORMAT_RGBA_8888, ISurfaceComposerClient::eFXSurfaceColor); + PIXEL_FORMAT_RGBA_8888, ISurfaceComposerClient::eFXSurfaceEffect); // set layer stack (b/68888219) Transaction t; diff --git a/services/surfaceflinger/tests/LayerTypeTransaction_test.cpp b/services/surfaceflinger/tests/LayerTypeTransaction_test.cpp index 7e9202bb82..84780ba73b 100644 --- a/services/surfaceflinger/tests/LayerTypeTransaction_test.cpp +++ b/services/surfaceflinger/tests/LayerTypeTransaction_test.cpp @@ -69,13 +69,13 @@ TEST_P(LayerTypeTransactionTest, SetRelativeZNegative) { TEST_P(LayerTypeTransactionTest, SetLayerAndRelative) { sp<SurfaceControl> parent = LayerTransactionTest::createLayer("Parent", 0 /* buffer width */, 0 /* buffer height */, - ISurfaceComposerClient::eFXSurfaceColor); + ISurfaceComposerClient::eFXSurfaceEffect); sp<SurfaceControl> childLayer; ASSERT_NO_FATAL_FAILURE( childLayer = LayerTransactionTest::createLayer("childLayer", 0 /* buffer width */, 0 /* buffer height */, - ISurfaceComposerClient::eFXSurfaceColor, + ISurfaceComposerClient::eFXSurfaceEffect, parent.get())); Transaction() .setColor(childLayer, half3{1.0f, 0.0f, 0.0f}) @@ -116,17 +116,17 @@ TEST_P(LayerTypeTransactionTest, SetLayerAndRelative) { TEST_P(LayerTypeTransactionTest, HideRelativeParentHidesLayer) { sp<SurfaceControl> parent = LayerTransactionTest::createLayer("Parent", 0 /* buffer width */, 0 /* buffer height */, - ISurfaceComposerClient::eFXSurfaceColor); + ISurfaceComposerClient::eFXSurfaceEffect); sp<SurfaceControl> relativeParent = LayerTransactionTest::createLayer("RelativeParent", 0 /* buffer width */, 0 /* buffer height */, - ISurfaceComposerClient::eFXSurfaceColor); + ISurfaceComposerClient::eFXSurfaceEffect); sp<SurfaceControl> childLayer; ASSERT_NO_FATAL_FAILURE( childLayer = LayerTransactionTest::createLayer("childLayer", 0 /* buffer width */, 0 /* buffer height */, - ISurfaceComposerClient::eFXSurfaceColor, + ISurfaceComposerClient::eFXSurfaceEffect, parent.get())); Transaction() .setColor(childLayer, half3{1.0f, 0.0f, 0.0f}) diff --git a/services/surfaceflinger/tests/LayerUpdate_test.cpp b/services/surfaceflinger/tests/LayerUpdate_test.cpp index a1c412801d..cf3f8e8865 100644 --- a/services/surfaceflinger/tests/LayerUpdate_test.cpp +++ b/services/surfaceflinger/tests/LayerUpdate_test.cpp @@ -1114,7 +1114,7 @@ TEST_F(BoundlessLayerTest, BufferLayerIgnoresSize) { TEST_F(BoundlessLayerTest, BoundlessColorLayerFillsParentBufferBounds) { sp<SurfaceControl> colorLayer = createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888, - ISurfaceComposerClient::eFXSurfaceColor, mFGSurfaceControl.get()); + ISurfaceComposerClient::eFXSurfaceEffect, mFGSurfaceControl.get()); ASSERT_TRUE(colorLayer->isValid()); asTransaction([&](Transaction& t) { t.setColor(colorLayer, half3{0, 0, 0}); @@ -1139,7 +1139,7 @@ TEST_F(BoundlessLayerTest, BoundlessColorLayerFillsParentCropBounds) { ASSERT_TRUE(cropLayer->isValid()); sp<SurfaceControl> colorLayer = createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888, - ISurfaceComposerClient::eFXSurfaceColor, cropLayer.get()); + ISurfaceComposerClient::eFXSurfaceEffect, cropLayer.get()); ASSERT_TRUE(colorLayer->isValid()); asTransaction([&](Transaction& t) { t.setCrop_legacy(cropLayer, Rect(5, 5, 10, 10)); @@ -1164,7 +1164,7 @@ TEST_F(BoundlessLayerTest, BoundlessColorLayerFillsParentCropBounds) { TEST_F(BoundlessLayerTest, BoundlessColorLayerTransformHasNoEffect) { sp<SurfaceControl> colorLayer = createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888, - ISurfaceComposerClient::eFXSurfaceColor, mFGSurfaceControl.get()); + ISurfaceComposerClient::eFXSurfaceEffect, mFGSurfaceControl.get()); ASSERT_TRUE(colorLayer->isValid()); asTransaction([&](Transaction& t) { t.setPosition(colorLayer, 320, 320); @@ -1195,7 +1195,7 @@ TEST_F(BoundlessLayerTest, IntermediateBoundlessLayerCanSetTransform) { ASSERT_TRUE(boundlessLayerDownShift->isValid()); sp<SurfaceControl> colorLayer = createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888, - ISurfaceComposerClient::eFXSurfaceColor, boundlessLayerDownShift.get()); + ISurfaceComposerClient::eFXSurfaceEffect, boundlessLayerDownShift.get()); ASSERT_TRUE(colorLayer->isValid()); asTransaction([&](Transaction& t) { t.setPosition(boundlessLayerRightShift, 32, 0); @@ -1229,7 +1229,7 @@ TEST_F(BoundlessLayerTest, IntermediateBoundlessLayerDoNotCrop) { ASSERT_TRUE(boundlessLayer->isValid()); sp<SurfaceControl> colorLayer = mClient->createSurface(String8("ColorLayer"), 0, 0, PIXEL_FORMAT_RGBA_8888, - ISurfaceComposerClient::eFXSurfaceColor, boundlessLayer.get()); + ISurfaceComposerClient::eFXSurfaceEffect, boundlessLayer.get()); ASSERT_TRUE(colorLayer != nullptr); ASSERT_TRUE(colorLayer->isValid()); asTransaction([&](Transaction& t) { @@ -1261,7 +1261,7 @@ TEST_F(BoundlessLayerTest, RootBoundlessLayerCanSetTransform) { ASSERT_TRUE(rootBoundlessLayer->isValid()); sp<SurfaceControl> colorLayer = createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888, - ISurfaceComposerClient::eFXSurfaceColor, rootBoundlessLayer.get()); + ISurfaceComposerClient::eFXSurfaceEffect, rootBoundlessLayer.get()); ASSERT_TRUE(colorLayer->isValid()); asTransaction([&](Transaction& t) { diff --git a/services/surfaceflinger/tests/MultiDisplayLayerBounds_test.cpp b/services/surfaceflinger/tests/MultiDisplayLayerBounds_test.cpp index c9fdc3b799..f8a5b4094d 100644 --- a/services/surfaceflinger/tests/MultiDisplayLayerBounds_test.cpp +++ b/services/surfaceflinger/tests/MultiDisplayLayerBounds_test.cpp @@ -66,7 +66,7 @@ protected: void createColorLayer(uint32_t layerStack) { mColorLayer = createSurface(mClient, "ColorLayer", 0 /* buffer width */, 0 /* buffer height */, - PIXEL_FORMAT_RGBA_8888, ISurfaceComposerClient::eFXSurfaceColor); + PIXEL_FORMAT_RGBA_8888, ISurfaceComposerClient::eFXSurfaceEffect); ASSERT_TRUE(mColorLayer != nullptr); ASSERT_TRUE(mColorLayer->isValid()); asTransaction([&](Transaction& t) { diff --git a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp b/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp index e75149653c..32c58ad390 100644 --- a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp +++ b/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp @@ -1827,10 +1827,11 @@ class ChildColorLayerTest : public ChildLayerTest<FakeComposerService> { protected: void SetUp() override { Base::SetUp(); - Base::mChild = Base::mComposerClient->createSurface(String8("Child surface"), 0, 0, - PIXEL_FORMAT_RGBA_8888, - ISurfaceComposerClient::eFXSurfaceColor, - Base::mFGSurfaceControl.get()); + Base::mChild = + Base::mComposerClient->createSurface(String8("Child surface"), 0, 0, + PIXEL_FORMAT_RGBA_8888, + ISurfaceComposerClient::eFXSurfaceEffect, + Base::mFGSurfaceControl.get()); { TransactionScope ts(*Base::sFakeComposer); ts.setColor(Base::mChild, diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp index 888e009282..6e83166a80 100644 --- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp +++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp @@ -35,7 +35,7 @@ #include <utils/String8.h> #include "BufferQueueLayer.h" -#include "ColorLayer.h" +#include "EffectLayer.h" #include "Layer.h" #include "TestableSurfaceFlinger.h" #include "mock/DisplayHardware/MockComposer.h" @@ -713,7 +713,7 @@ struct BaseLayerProperties { struct DefaultLayerProperties : public BaseLayerProperties<DefaultLayerProperties> {}; -struct ColorLayerProperties : public BaseLayerProperties<ColorLayerProperties> { +struct EffectLayerProperties : public BaseLayerProperties<EffectLayerProperties> { static constexpr IComposerClient::BlendMode BLENDMODE = IComposerClient::BlendMode::NONE; }; @@ -866,16 +866,16 @@ struct BaseLayerVariant { }; template <typename LayerProperties> -struct ColorLayerVariant : public BaseLayerVariant<LayerProperties> { +struct EffectLayerVariant : public BaseLayerVariant<LayerProperties> { using Base = BaseLayerVariant<LayerProperties>; - using FlingerLayerType = sp<ColorLayer>; + using FlingerLayerType = sp<EffectLayer>; static FlingerLayerType createLayer(CompositionTest* test) { - FlingerLayerType layer = Base::template createLayerWithFactory<ColorLayer>(test, [test]() { - return new ColorLayer(LayerCreationArgs(test->mFlinger.mFlinger.get(), sp<Client>(), - "test-layer", LayerProperties::WIDTH, - LayerProperties::HEIGHT, - LayerProperties::LAYER_FLAGS, LayerMetadata())); + FlingerLayerType layer = Base::template createLayerWithFactory<EffectLayer>(test, [test]() { + return new EffectLayer( + LayerCreationArgs(test->mFlinger.mFlinger.get(), sp<Client>(), "test-layer", + LayerProperties::WIDTH, LayerProperties::HEIGHT, + LayerProperties::LAYER_FLAGS, LayerMetadata())); }); auto& layerDrawingState = test->mFlinger.mutableLayerDrawingState(layer); @@ -1228,31 +1228,31 @@ TEST_F(CompositionTest, captureScreenNormalBufferLayer) { * Single-color layers */ -TEST_F(CompositionTest, HWCComposedColorLayerWithDirtyGeometry) { +TEST_F(CompositionTest, HWCComposedEffectLayerWithDirtyGeometry) { displayRefreshCompositionDirtyGeometry< - CompositionCase<DefaultDisplaySetupVariant, ColorLayerVariant<ColorLayerProperties>, + CompositionCase<DefaultDisplaySetupVariant, EffectLayerVariant<EffectLayerProperties>, KeepCompositionTypeVariant<IComposerClient::Composition::SOLID_COLOR>, HwcCompositionResultVariant>>(); } -TEST_F(CompositionTest, HWCComposedColorLayerWithDirtyFrame) { +TEST_F(CompositionTest, HWCComposedEffectLayerWithDirtyFrame) { displayRefreshCompositionDirtyFrame< - CompositionCase<DefaultDisplaySetupVariant, ColorLayerVariant<ColorLayerProperties>, + CompositionCase<DefaultDisplaySetupVariant, EffectLayerVariant<EffectLayerProperties>, KeepCompositionTypeVariant<IComposerClient::Composition::SOLID_COLOR>, HwcCompositionResultVariant>>(); } -TEST_F(CompositionTest, REComposedColorLayer) { +TEST_F(CompositionTest, REComposedEffectLayer) { displayRefreshCompositionDirtyFrame< - CompositionCase<DefaultDisplaySetupVariant, ColorLayerVariant<ColorLayerProperties>, + CompositionCase<DefaultDisplaySetupVariant, EffectLayerVariant<EffectLayerProperties>, ChangeCompositionTypeVariant<IComposerClient::Composition::SOLID_COLOR, IComposerClient::Composition::CLIENT>, RECompositionResultVariant>>(); } -TEST_F(CompositionTest, captureScreenColorLayer) { +TEST_F(CompositionTest, captureScreenEffectLayer) { captureScreenComposition< - CompositionCase<DefaultDisplaySetupVariant, ColorLayerVariant<ColorLayerProperties>, + CompositionCase<DefaultDisplaySetupVariant, EffectLayerVariant<EffectLayerProperties>, NoCompositionTypeVariant, REScreenshotResultVariant>>(); } diff --git a/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp index cffdc14df7..edd9de46ab 100644 --- a/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp +++ b/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp @@ -27,7 +27,7 @@ #include "BufferQueueLayer.h" #include "BufferStateLayer.h" -#include "ColorLayer.h" +#include "EffectLayer.h" #include "Layer.h" #include "TestableSurfaceFlinger.h" #include "mock/DisplayHardware/MockComposer.h" @@ -68,7 +68,7 @@ protected: void setupComposer(int virtualDisplayCount); sp<BufferQueueLayer> createBufferQueueLayer(); sp<BufferStateLayer> createBufferStateLayer(); - sp<ColorLayer> createColorLayer(); + sp<EffectLayer> createEffectLayer(); void setParent(Layer* child, Layer* parent); void commitTransaction(Layer* layer); @@ -111,11 +111,11 @@ sp<BufferStateLayer> RefreshRateSelectionTest::createBufferStateLayer() { return new BufferStateLayer(args); } -sp<ColorLayer> RefreshRateSelectionTest::createColorLayer() { +sp<EffectLayer> RefreshRateSelectionTest::createEffectLayer() { sp<Client> client; LayerCreationArgs args(mFlinger.flinger(), client, "color-layer", WIDTH, HEIGHT, LAYER_FLAGS, LayerMetadata()); - return new ColorLayer(args); + return new EffectLayer(args); } void RefreshRateSelectionTest::setParent(Layer* child, Layer* parent) { @@ -244,11 +244,11 @@ TEST_F(RefreshRateSelectionTest, testPriorityOnBufferStateLayers) { ASSERT_EQ(1, mGrandChild->getFrameRateSelectionPriority()); } -TEST_F(RefreshRateSelectionTest, testPriorityOnColorLayers) { - mParent = createColorLayer(); - mChild = createColorLayer(); +TEST_F(RefreshRateSelectionTest, testPriorityOnEffectLayers) { + mParent = createEffectLayer(); + mChild = createEffectLayer(); setParent(mChild.get(), mParent.get()); - mGrandChild = createColorLayer(); + mGrandChild = createEffectLayer(); setParent(mGrandChild.get(), mChild.get()); ASSERT_EQ(PRIORITY_UNSET, mParent->getFrameRateSelectionPriority()); diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h index 798ba766fc..685cfaf450 100644 --- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h +++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h @@ -25,9 +25,9 @@ #include "BufferQueueLayer.h" #include "BufferStateLayer.h" -#include "ColorLayer.h" #include "ContainerLayer.h" #include "DisplayDevice.h" +#include "EffectLayer.h" #include "FakePhaseOffsets.h" #include "Layer.h" #include "NativeWindowSurface.h" @@ -147,9 +147,7 @@ public: return nullptr; } - sp<ColorLayer> createColorLayer(const LayerCreationArgs&) override { - return nullptr; - } + sp<EffectLayer> createEffectLayer(const LayerCreationArgs&) override { return nullptr; } sp<ContainerLayer> createContainerLayer(const LayerCreationArgs&) override { return nullptr; diff --git a/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp b/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp index 6ec3844f25..f834af895c 100644 --- a/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp +++ b/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp @@ -36,7 +36,7 @@ using namespace std::literals; namespace android::scheduler { MATCHER_P2(IsCloseTo, value, tolerance, "is within tolerance") { - return arg <= value + tolerance && value >= value - tolerance; + return arg <= value + tolerance && arg >= value - tolerance; } std::vector<nsecs_t> generateVsyncTimestamps(size_t count, nsecs_t period, nsecs_t bias) { @@ -370,6 +370,26 @@ TEST_F(VSyncPredictorTest, resetsWhenInstructed) { IsCloseTo(idealPeriod, mMaxRoundingError)); } +TEST_F(VSyncPredictorTest, slopeAlwaysValid) { + constexpr auto kNumVsyncs = 100; + auto invalidPeriod = mPeriod; + auto now = 0; + for (int i = 0; i < kNumVsyncs; i++) { + tracker.addVsyncTimestamp(now); + now += invalidPeriod; + invalidPeriod *= 0.9f; + + auto [slope, intercept] = tracker.getVSyncPredictionModel(); + EXPECT_THAT(slope, IsCloseTo(mPeriod, mPeriod * kOutlierTolerancePercent / 100.f)); + + // When VsyncPredictor returns the period it means that it doesn't know how to predict and + // it needs to get more samples + if (slope == mPeriod && intercept == 0) { + EXPECT_TRUE(tracker.needsMoreSamples(now)); + } + } +} + } // namespace android::scheduler // TODO(b/129481165): remove the #pragma below and fix conversion issues diff --git a/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp b/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp index 2f36bb2941..ac959388c2 100644 --- a/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp +++ b/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp @@ -534,6 +534,30 @@ TEST_F(VSyncReactorTest, eventListenersRemovedOnDestruction) { mReactor.addEventListener(mName, mPhase, &outerCb, lastCallbackTime); } +// b/149221293 +TEST_F(VSyncReactorTest, selfRemovingEventListenerStopsCallbacks) { + class SelfRemovingCallback : public DispSync::Callback { + public: + SelfRemovingCallback(VSyncReactor& vsr) : mVsr(vsr) {} + void onDispSyncEvent(nsecs_t when) final { mVsr.removeEventListener(this, &when); } + + private: + VSyncReactor& mVsr; + } selfRemover(mReactor); + + Sequence seq; + EXPECT_CALL(*mMockDispatch, registerCallback(_, std::string(mName))) + .InSequence(seq) + .WillOnce(DoAll(SaveArg<0>(&innerCb), Return(mFakeToken))); + EXPECT_CALL(*mMockDispatch, schedule(mFakeToken, computeWorkload(period, mPhase), mFakeNow)) + .InSequence(seq); + EXPECT_CALL(*mMockDispatch, cancel(mFakeToken)).Times(2).InSequence(seq); + EXPECT_CALL(*mMockDispatch, unregisterCallback(mFakeToken)).InSequence(seq); + + mReactor.addEventListener(mName, mPhase, &selfRemover, lastCallbackTime); + innerCb(0, 0); +} + TEST_F(VSyncReactorTest, addEventListenerChangePeriod) { Sequence seq; EXPECT_CALL(*mMockDispatch, registerCallback(_, std::string(mName))) |