Loading include/android/input.h +2 −0 Original line number Diff line number Diff line Loading @@ -835,6 +835,8 @@ enum { AINPUT_SOURCE_BLUETOOTH_STYLUS = 0x00008000 | AINPUT_SOURCE_STYLUS, /** trackball */ AINPUT_SOURCE_TRACKBALL = 0x00010000 | AINPUT_SOURCE_CLASS_NAVIGATION, /** mouse relative */ AINPUT_SOURCE_MOUSE_RELATIVE = 0x00020000 | AINPUT_SOURCE_CLASS_NAVIGATION, /** touchpad */ AINPUT_SOURCE_TOUCHPAD = 0x00100000 | AINPUT_SOURCE_CLASS_POSITION, /** navigation */ Loading services/inputflinger/InputDispatcher.cpp +2 −4 Original line number Diff line number Diff line Loading @@ -902,7 +902,7 @@ void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const M ALOGD(" Pointer %d: id=%d, toolType=%d, " "x=%f, y=%f, pressure=%f, size=%f, " "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, " "orientation=%f, relativeX=%f, relativeY=%f", "orientation=%f", i, entry->pointerProperties[i].id, entry->pointerProperties[i].toolType, entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X), Loading @@ -913,9 +913,7 @@ void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const M entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR), entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR), entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR), entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION), entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X), entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y)); entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION)); } #endif } Loading services/inputflinger/InputReader.cpp +36 −19 Original line number Diff line number Diff line Loading @@ -2478,6 +2478,11 @@ void CursorInputMapper::configure(nsecs_t when, // Configure device mode. switch (mParameters.mode) { case Parameters::MODE_POINTER_RELATIVE: // Should not happen during first time configuration. ALOGE("Cannot start a device in MODE_POINTER_RELATIVE, starting in MODE_POINTER"); mParameters.mode = Parameters::MODE_POINTER; // fall through. case Parameters::MODE_POINTER: mSource = AINPUT_SOURCE_MOUSE; mXPrecision = 1.0f; Loading @@ -2499,6 +2504,31 @@ void CursorInputMapper::configure(nsecs_t when, mHWheelScale = 1.0f; } if ((!changes && config->pointerCapture) || (changes & InputReaderConfiguration::CHANGE_POINTER_CAPTURE)) { if (config->pointerCapture) { if (mParameters.mode == Parameters::MODE_POINTER) { mParameters.mode = Parameters::MODE_POINTER_RELATIVE; mSource = AINPUT_SOURCE_MOUSE_RELATIVE; // Keep PointerController around in order to preserve the pointer position. mPointerController->fade(PointerControllerInterface::TRANSITION_IMMEDIATE); } else { ALOGE("Cannot request pointer capture, device is not in MODE_POINTER"); } } else { if (mParameters.mode == Parameters::MODE_POINTER_RELATIVE) { mParameters.mode = Parameters::MODE_POINTER; mSource = AINPUT_SOURCE_MOUSE; } else { ALOGE("Cannot release pointer capture, device is not in MODE_POINTER_RELATIVE"); } } bumpGeneration(); if (changes) { getDevice()->notifyReset(when); } } if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) { mPointerVelocityControl.setParameters(config->pointerVelocityControlParameters); mWheelXVelocityControl.setParameters(config->wheelVelocityControlParameters); Loading Loading @@ -2550,6 +2580,9 @@ void CursorInputMapper::dumpParameters(String8& dump) { case Parameters::MODE_POINTER: dump.append(INDENT4 "Mode: pointer\n"); break; case Parameters::MODE_POINTER_RELATIVE: dump.append(INDENT4 "Mode: relative pointer\n"); break; case Parameters::MODE_NAVIGATION: dump.append(INDENT4 "Mode: navigation\n"); break; Loading Loading @@ -2636,7 +2669,7 @@ void CursorInputMapper::sync(nsecs_t when) { mPointerVelocityControl.move(when, &deltaX, &deltaY); int32_t displayId; if (mPointerController != NULL) { if (mSource == AINPUT_SOURCE_MOUSE) { if (moved || scrolled || buttonsChanged) { mPointerController->setPresentation( PointerControllerInterface::PRESENTATION_POINTER); Loading Loading @@ -2687,7 +2720,7 @@ void CursorInputMapper::sync(nsecs_t when) { int32_t motionEventAction; if (downChanged) { motionEventAction = down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP; } else if (down || mPointerController == NULL) { } else if (down || (mSource != AINPUT_SOURCE_MOUSE)) { motionEventAction = AMOTION_EVENT_ACTION_MOVE; } else { motionEventAction = AMOTION_EVENT_ACTION_HOVER_MOVE; Loading Loading @@ -2732,7 +2765,7 @@ void CursorInputMapper::sync(nsecs_t when) { // Send hover move after UP to tell the application that the mouse is hovering now. if (motionEventAction == AMOTION_EVENT_ACTION_UP && mPointerController != NULL) { && (mSource == AINPUT_SOURCE_MOUSE)) { NotifyMotionArgs hoverArgs(when, getDeviceId(), mSource, policyFlags, AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0, metaState, currentButtonState, AMOTION_EVENT_EDGE_FLAG_NONE, Loading Loading @@ -5422,8 +5455,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x); mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y); mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f); mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, deltaX); mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, deltaY); } else if (currentFingerCount == 0) { // Case 3. No fingers down and button is not pressed. (NEUTRAL) if (mPointerGesture.lastGestureMode != PointerGesture::NEUTRAL) { Loading Loading @@ -5582,10 +5613,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y); mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, down ? 1.0f : 0.0f); mPointerGesture.currentGestureCoords[0].setAxisValue( AMOTION_EVENT_AXIS_RELATIVE_X, deltaX); mPointerGesture.currentGestureCoords[0].setAxisValue( AMOTION_EVENT_AXIS_RELATIVE_Y, deltaY); if (lastFingerCount == 0 && currentFingerCount != 0) { mPointerGesture.resetTap(); Loading Loading @@ -5832,10 +5859,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, mPointerGesture.referenceGestureX); mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, mPointerGesture.referenceGestureY); mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, commonDeltaX); mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, commonDeltaY); mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f); } else if (mPointerGesture.currentGestureMode == PointerGesture::FREEFORM) { // FREEFORM mode. Loading Loading @@ -5932,10 +5955,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, AMOTION_EVENT_AXIS_Y, mPointerGesture.referenceGestureY + deltaY); mPointerGesture.currentGestureCoords[i].setAxisValue( AMOTION_EVENT_AXIS_PRESSURE, 1.0f); mPointerGesture.currentGestureCoords[i].setAxisValue( AMOTION_EVENT_AXIS_RELATIVE_X, deltaX); mPointerGesture.currentGestureCoords[i].setAxisValue( AMOTION_EVENT_AXIS_RELATIVE_Y, deltaY); } if (mPointerGesture.activeGestureId < 0) { Loading Loading @@ -6058,8 +6077,6 @@ void TouchInputMapper::dispatchPointerMouse(nsecs_t when, uint32_t policyFlags) mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y); mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, hovering ? 0.0f : 1.0f); mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, x); mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, y); mPointerSimple.currentProperties.id = 0; mPointerSimple.currentProperties.toolType = mCurrentCookedState.cookedPointerData.pointerProperties[currentIndex].toolType; Loading services/inputflinger/InputReader.h +7 −0 Original line number Diff line number Diff line Loading @@ -144,6 +144,9 @@ struct InputReaderConfiguration { // The presence of an external stylus has changed. CHANGE_EXTERNAL_STYLUS_PRESENCE = 1 << 7, // The pointer capture mode has changed. CHANGE_POINTER_CAPTURE = 1 << 8, // All devices must be reopened. CHANGE_MUST_REOPEN = 1 << 31, }; Loading Loading @@ -231,6 +234,9 @@ struct InputReaderConfiguration { // True to show the location of touches on the touch screen as spots. bool showTouches; // True if pointer capture is enabled. bool pointerCapture; InputReaderConfiguration() : virtualKeyQuietTime(0), pointerVelocityControlParameters(1.0f, 500.0f, 3000.0f, 3.0f), Loading Loading @@ -1200,6 +1206,7 @@ private: struct Parameters { enum Mode { MODE_POINTER, MODE_POINTER_RELATIVE, MODE_NAVIGATION, }; Loading services/inputflinger/tests/InputReader_test.cpp +104 −3 Original line number Diff line number Diff line Loading @@ -182,6 +182,10 @@ public: transform = t; } void setPointerCapture(bool enabled) { mConfig.pointerCapture = enabled; } private: virtual void getReaderConfiguration(InputReaderConfiguration* outConfig) { *outConfig = mConfig; Loading Loading @@ -744,6 +748,10 @@ public: mGlobalMetaState = state; } uint32_t getGeneration() { return mGeneration; } private: virtual void updateGlobalMetaState() { mUpdateGlobalMetaStateWasCalled = true; Loading Loading @@ -1425,17 +1433,20 @@ protected: mFakeEventHub->addConfigurationProperty(DEVICE_ID, String8(key), String8(value)); } void configureDevice(uint32_t changes) { mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), changes); } void addMapperAndConfigure(InputMapper* mapper) { mDevice->addMapper(mapper); mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), 0); configureDevice(0); mDevice->reset(ARBITRARY_TIME); } void setDisplayInfoAndReconfigure(int32_t displayId, int32_t width, int32_t height, int32_t orientation) { mFakePolicy->setDisplayInfo(displayId, width, height, orientation); mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), InputReaderConfiguration::CHANGE_DISPLAY_INFO); configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO); } static void process(InputMapper* mapper, nsecs_t when, int32_t deviceId, int32_t type, Loading Loading @@ -2617,6 +2628,96 @@ TEST_F(CursorInputMapperTest, Process_WhenModeIsPointer_ShouldMoveThePointerArou process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 20); process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args)); ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source); ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 110.0f, 220.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)); ASSERT_NO_FATAL_FAILURE(assertPosition(mFakePointerController, 110.0f, 220.0f)); } TEST_F(CursorInputMapperTest, Process_PointerCapture) { CursorInputMapper* mapper = new CursorInputMapper(mDevice); addConfigurationProperty("cursor.mode", "pointer"); mFakePolicy->setPointerCapture(true); addMapperAndConfigure(mapper); NotifyDeviceResetArgs resetArgs; ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs)); ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime); ASSERT_EQ(DEVICE_ID, resetArgs.deviceId); mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1); mFakePointerController->setPosition(100, 200); mFakePointerController->setButtonState(0); NotifyMotionArgs args; // Move. process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 10); process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 20); process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args)); ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source); ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 10.0f, 20.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)); ASSERT_NO_FATAL_FAILURE(assertPosition(mFakePointerController, 100.0f, 200.0f)); // Button press. process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 1); process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args)); ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source); ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args)); ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source); ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, args.action); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)); // Button release. process(mapper, ARBITRARY_TIME + 2, DEVICE_ID, EV_KEY, BTN_MOUSE, 0); process(mapper, ARBITRARY_TIME + 2, DEVICE_ID, EV_SYN, SYN_REPORT, 0); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args)); ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source); ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args)); ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source); ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)); // Another move. process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 30); process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 40); process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args)); ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source); ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 30.0f, 40.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)); ASSERT_NO_FATAL_FAILURE(assertPosition(mFakePointerController, 100.0f, 200.0f)); // Disable pointer capture and check that the device generation got bumped // and events are generated the usual way. const uint32_t generation = mFakeContext->getGeneration(); mFakePolicy->setPointerCapture(false); configureDevice(InputReaderConfiguration::CHANGE_POINTER_CAPTURE); ASSERT_TRUE(mFakeContext->getGeneration() != generation); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs)); ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime); ASSERT_EQ(DEVICE_ID, resetArgs.deviceId); process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 10); process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 20); process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args)); ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source); ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 110.0f, 220.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)); Loading Loading
include/android/input.h +2 −0 Original line number Diff line number Diff line Loading @@ -835,6 +835,8 @@ enum { AINPUT_SOURCE_BLUETOOTH_STYLUS = 0x00008000 | AINPUT_SOURCE_STYLUS, /** trackball */ AINPUT_SOURCE_TRACKBALL = 0x00010000 | AINPUT_SOURCE_CLASS_NAVIGATION, /** mouse relative */ AINPUT_SOURCE_MOUSE_RELATIVE = 0x00020000 | AINPUT_SOURCE_CLASS_NAVIGATION, /** touchpad */ AINPUT_SOURCE_TOUCHPAD = 0x00100000 | AINPUT_SOURCE_CLASS_POSITION, /** navigation */ Loading
services/inputflinger/InputDispatcher.cpp +2 −4 Original line number Diff line number Diff line Loading @@ -902,7 +902,7 @@ void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const M ALOGD(" Pointer %d: id=%d, toolType=%d, " "x=%f, y=%f, pressure=%f, size=%f, " "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, " "orientation=%f, relativeX=%f, relativeY=%f", "orientation=%f", i, entry->pointerProperties[i].id, entry->pointerProperties[i].toolType, entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X), Loading @@ -913,9 +913,7 @@ void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const M entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR), entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR), entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR), entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION), entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X), entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y)); entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION)); } #endif } Loading
services/inputflinger/InputReader.cpp +36 −19 Original line number Diff line number Diff line Loading @@ -2478,6 +2478,11 @@ void CursorInputMapper::configure(nsecs_t when, // Configure device mode. switch (mParameters.mode) { case Parameters::MODE_POINTER_RELATIVE: // Should not happen during first time configuration. ALOGE("Cannot start a device in MODE_POINTER_RELATIVE, starting in MODE_POINTER"); mParameters.mode = Parameters::MODE_POINTER; // fall through. case Parameters::MODE_POINTER: mSource = AINPUT_SOURCE_MOUSE; mXPrecision = 1.0f; Loading @@ -2499,6 +2504,31 @@ void CursorInputMapper::configure(nsecs_t when, mHWheelScale = 1.0f; } if ((!changes && config->pointerCapture) || (changes & InputReaderConfiguration::CHANGE_POINTER_CAPTURE)) { if (config->pointerCapture) { if (mParameters.mode == Parameters::MODE_POINTER) { mParameters.mode = Parameters::MODE_POINTER_RELATIVE; mSource = AINPUT_SOURCE_MOUSE_RELATIVE; // Keep PointerController around in order to preserve the pointer position. mPointerController->fade(PointerControllerInterface::TRANSITION_IMMEDIATE); } else { ALOGE("Cannot request pointer capture, device is not in MODE_POINTER"); } } else { if (mParameters.mode == Parameters::MODE_POINTER_RELATIVE) { mParameters.mode = Parameters::MODE_POINTER; mSource = AINPUT_SOURCE_MOUSE; } else { ALOGE("Cannot release pointer capture, device is not in MODE_POINTER_RELATIVE"); } } bumpGeneration(); if (changes) { getDevice()->notifyReset(when); } } if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) { mPointerVelocityControl.setParameters(config->pointerVelocityControlParameters); mWheelXVelocityControl.setParameters(config->wheelVelocityControlParameters); Loading Loading @@ -2550,6 +2580,9 @@ void CursorInputMapper::dumpParameters(String8& dump) { case Parameters::MODE_POINTER: dump.append(INDENT4 "Mode: pointer\n"); break; case Parameters::MODE_POINTER_RELATIVE: dump.append(INDENT4 "Mode: relative pointer\n"); break; case Parameters::MODE_NAVIGATION: dump.append(INDENT4 "Mode: navigation\n"); break; Loading Loading @@ -2636,7 +2669,7 @@ void CursorInputMapper::sync(nsecs_t when) { mPointerVelocityControl.move(when, &deltaX, &deltaY); int32_t displayId; if (mPointerController != NULL) { if (mSource == AINPUT_SOURCE_MOUSE) { if (moved || scrolled || buttonsChanged) { mPointerController->setPresentation( PointerControllerInterface::PRESENTATION_POINTER); Loading Loading @@ -2687,7 +2720,7 @@ void CursorInputMapper::sync(nsecs_t when) { int32_t motionEventAction; if (downChanged) { motionEventAction = down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP; } else if (down || mPointerController == NULL) { } else if (down || (mSource != AINPUT_SOURCE_MOUSE)) { motionEventAction = AMOTION_EVENT_ACTION_MOVE; } else { motionEventAction = AMOTION_EVENT_ACTION_HOVER_MOVE; Loading Loading @@ -2732,7 +2765,7 @@ void CursorInputMapper::sync(nsecs_t when) { // Send hover move after UP to tell the application that the mouse is hovering now. if (motionEventAction == AMOTION_EVENT_ACTION_UP && mPointerController != NULL) { && (mSource == AINPUT_SOURCE_MOUSE)) { NotifyMotionArgs hoverArgs(when, getDeviceId(), mSource, policyFlags, AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0, metaState, currentButtonState, AMOTION_EVENT_EDGE_FLAG_NONE, Loading Loading @@ -5422,8 +5455,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x); mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y); mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f); mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, deltaX); mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, deltaY); } else if (currentFingerCount == 0) { // Case 3. No fingers down and button is not pressed. (NEUTRAL) if (mPointerGesture.lastGestureMode != PointerGesture::NEUTRAL) { Loading Loading @@ -5582,10 +5613,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y); mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, down ? 1.0f : 0.0f); mPointerGesture.currentGestureCoords[0].setAxisValue( AMOTION_EVENT_AXIS_RELATIVE_X, deltaX); mPointerGesture.currentGestureCoords[0].setAxisValue( AMOTION_EVENT_AXIS_RELATIVE_Y, deltaY); if (lastFingerCount == 0 && currentFingerCount != 0) { mPointerGesture.resetTap(); Loading Loading @@ -5832,10 +5859,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, mPointerGesture.referenceGestureX); mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, mPointerGesture.referenceGestureY); mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, commonDeltaX); mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, commonDeltaY); mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f); } else if (mPointerGesture.currentGestureMode == PointerGesture::FREEFORM) { // FREEFORM mode. Loading Loading @@ -5932,10 +5955,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, AMOTION_EVENT_AXIS_Y, mPointerGesture.referenceGestureY + deltaY); mPointerGesture.currentGestureCoords[i].setAxisValue( AMOTION_EVENT_AXIS_PRESSURE, 1.0f); mPointerGesture.currentGestureCoords[i].setAxisValue( AMOTION_EVENT_AXIS_RELATIVE_X, deltaX); mPointerGesture.currentGestureCoords[i].setAxisValue( AMOTION_EVENT_AXIS_RELATIVE_Y, deltaY); } if (mPointerGesture.activeGestureId < 0) { Loading Loading @@ -6058,8 +6077,6 @@ void TouchInputMapper::dispatchPointerMouse(nsecs_t when, uint32_t policyFlags) mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y); mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, hovering ? 0.0f : 1.0f); mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, x); mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, y); mPointerSimple.currentProperties.id = 0; mPointerSimple.currentProperties.toolType = mCurrentCookedState.cookedPointerData.pointerProperties[currentIndex].toolType; Loading
services/inputflinger/InputReader.h +7 −0 Original line number Diff line number Diff line Loading @@ -144,6 +144,9 @@ struct InputReaderConfiguration { // The presence of an external stylus has changed. CHANGE_EXTERNAL_STYLUS_PRESENCE = 1 << 7, // The pointer capture mode has changed. CHANGE_POINTER_CAPTURE = 1 << 8, // All devices must be reopened. CHANGE_MUST_REOPEN = 1 << 31, }; Loading Loading @@ -231,6 +234,9 @@ struct InputReaderConfiguration { // True to show the location of touches on the touch screen as spots. bool showTouches; // True if pointer capture is enabled. bool pointerCapture; InputReaderConfiguration() : virtualKeyQuietTime(0), pointerVelocityControlParameters(1.0f, 500.0f, 3000.0f, 3.0f), Loading Loading @@ -1200,6 +1206,7 @@ private: struct Parameters { enum Mode { MODE_POINTER, MODE_POINTER_RELATIVE, MODE_NAVIGATION, }; Loading
services/inputflinger/tests/InputReader_test.cpp +104 −3 Original line number Diff line number Diff line Loading @@ -182,6 +182,10 @@ public: transform = t; } void setPointerCapture(bool enabled) { mConfig.pointerCapture = enabled; } private: virtual void getReaderConfiguration(InputReaderConfiguration* outConfig) { *outConfig = mConfig; Loading Loading @@ -744,6 +748,10 @@ public: mGlobalMetaState = state; } uint32_t getGeneration() { return mGeneration; } private: virtual void updateGlobalMetaState() { mUpdateGlobalMetaStateWasCalled = true; Loading Loading @@ -1425,17 +1433,20 @@ protected: mFakeEventHub->addConfigurationProperty(DEVICE_ID, String8(key), String8(value)); } void configureDevice(uint32_t changes) { mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), changes); } void addMapperAndConfigure(InputMapper* mapper) { mDevice->addMapper(mapper); mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), 0); configureDevice(0); mDevice->reset(ARBITRARY_TIME); } void setDisplayInfoAndReconfigure(int32_t displayId, int32_t width, int32_t height, int32_t orientation) { mFakePolicy->setDisplayInfo(displayId, width, height, orientation); mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), InputReaderConfiguration::CHANGE_DISPLAY_INFO); configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO); } static void process(InputMapper* mapper, nsecs_t when, int32_t deviceId, int32_t type, Loading Loading @@ -2617,6 +2628,96 @@ TEST_F(CursorInputMapperTest, Process_WhenModeIsPointer_ShouldMoveThePointerArou process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 20); process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args)); ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source); ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 110.0f, 220.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)); ASSERT_NO_FATAL_FAILURE(assertPosition(mFakePointerController, 110.0f, 220.0f)); } TEST_F(CursorInputMapperTest, Process_PointerCapture) { CursorInputMapper* mapper = new CursorInputMapper(mDevice); addConfigurationProperty("cursor.mode", "pointer"); mFakePolicy->setPointerCapture(true); addMapperAndConfigure(mapper); NotifyDeviceResetArgs resetArgs; ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs)); ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime); ASSERT_EQ(DEVICE_ID, resetArgs.deviceId); mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1); mFakePointerController->setPosition(100, 200); mFakePointerController->setButtonState(0); NotifyMotionArgs args; // Move. process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 10); process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 20); process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args)); ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source); ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 10.0f, 20.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)); ASSERT_NO_FATAL_FAILURE(assertPosition(mFakePointerController, 100.0f, 200.0f)); // Button press. process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 1); process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args)); ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source); ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args)); ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source); ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, args.action); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)); // Button release. process(mapper, ARBITRARY_TIME + 2, DEVICE_ID, EV_KEY, BTN_MOUSE, 0); process(mapper, ARBITRARY_TIME + 2, DEVICE_ID, EV_SYN, SYN_REPORT, 0); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args)); ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source); ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args)); ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source); ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)); // Another move. process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 30); process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 40); process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args)); ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source); ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 30.0f, 40.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)); ASSERT_NO_FATAL_FAILURE(assertPosition(mFakePointerController, 100.0f, 200.0f)); // Disable pointer capture and check that the device generation got bumped // and events are generated the usual way. const uint32_t generation = mFakeContext->getGeneration(); mFakePolicy->setPointerCapture(false); configureDevice(InputReaderConfiguration::CHANGE_POINTER_CAPTURE); ASSERT_TRUE(mFakeContext->getGeneration() != generation); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs)); ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime); ASSERT_EQ(DEVICE_ID, resetArgs.deviceId); process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 10); process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 20); process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args)); ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source); ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 110.0f, 220.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)); Loading