Loading core/java/android/view/WindowManager.java +27 −0 Original line number Diff line number Diff line Loading @@ -1004,6 +1004,23 @@ public interface WindowManager extends ViewManager { */ public boolean hasSystemUiListeners; /** * When this window has focus, disable touch pad pointer gesture processing. * The window will receive raw position updates from the touch pad instead * of pointer movements and synthetic touch events. * * @hide */ public static final int INPUT_FEATURE_DISABLE_POINTER_GESTURES = 0x00000001; /** * Control special features of the input subsystem. * * @see #INPUT_FEATURE_DISABLE_TOUCH_PAD_GESTURES * @hide */ public int inputFeatures; public LayoutParams() { super(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); type = TYPE_APPLICATION; Loading Loading @@ -1086,6 +1103,7 @@ public interface WindowManager extends ViewManager { out.writeInt(systemUiVisibility); out.writeInt(subtreeSystemUiVisibility); out.writeInt(hasSystemUiListeners ? 1 : 0); out.writeInt(inputFeatures); } public static final Parcelable.Creator<LayoutParams> CREATOR Loading Loading @@ -1124,6 +1142,7 @@ public interface WindowManager extends ViewManager { systemUiVisibility = in.readInt(); subtreeSystemUiVisibility = in.readInt(); hasSystemUiListeners = in.readInt() != 0; inputFeatures = in.readInt(); } @SuppressWarnings({"PointlessBitwiseExpression"}) Loading @@ -1145,6 +1164,8 @@ public interface WindowManager extends ViewManager { public static final int SYSTEM_UI_VISIBILITY_CHANGED = 1<<13; /** {@hide} */ public static final int SYSTEM_UI_LISTENER_CHANGED = 1<<14; /** {@hide} */ public static final int INPUT_FEATURES_CHANGED = 1<<15; // internal buffer to backup/restore parameters under compatibility mode. private int[] mCompatibilityParamsBackup = null; Loading Loading @@ -1256,6 +1277,11 @@ public interface WindowManager extends ViewManager { changes |= SYSTEM_UI_LISTENER_CHANGED; } if (inputFeatures != o.inputFeatures) { inputFeatures = o.inputFeatures; changes |= INPUT_FEATURES_CHANGED; } return changes; } Loading Loading @@ -1340,6 +1366,7 @@ public interface WindowManager extends ViewManager { sb.append(" sysuil="); sb.append(hasSystemUiListeners); } sb.append(" if=0x").append(Integer.toHexString(inputFeatures)); sb.append('}'); return sb.toString(); } Loading services/input/InputDispatcher.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -3395,6 +3395,7 @@ void InputDispatcher::dumpDispatchStateLocked(String8& dump) { window.frameRight, window.frameBottom, window.scaleFactor); dumpRegion(dump, window.touchableRegion); dump.appendFormat(", inputFeatures=0x%08x", window.inputFeatures); dump.appendFormat(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n", window.ownerPid, window.ownerUid, window.dispatchingTimeout / 1000000.0); Loading services/input/InputReader.cpp +254 −201 Original line number Diff line number Diff line Loading @@ -38,7 +38,6 @@ #include "InputReader.h" #include <cutils/atomic.h> #include <cutils/log.h> #include <ui/Keyboard.h> #include <ui/VirtualKeyMap.h> Loading Loading @@ -245,8 +244,8 @@ InputReader::InputReader(const sp<EventHubInterface>& eventHub, const sp<InputDispatcherInterface>& dispatcher) : mEventHub(eventHub), mPolicy(policy), mDispatcher(dispatcher), mGlobalMetaState(0), mDisableVirtualKeysTimeout(LLONG_MIN), mNextTimeout(LLONG_MAX), mRefreshConfiguration(0) { configure(true /*firstTime*/); mConfigurationChangesToRefresh(0) { refreshConfiguration(0); updateGlobalMetaState(); updateInputConfiguration(); } Loading @@ -258,9 +257,16 @@ InputReader::~InputReader() { } void InputReader::loopOnce() { if (android_atomic_acquire_load(&mRefreshConfiguration)) { android_atomic_release_store(0, &mRefreshConfiguration); configure(false /*firstTime*/); uint32_t changes; { // acquire lock AutoMutex _l(mStateLock); changes = mConfigurationChangesToRefresh; mConfigurationChangesToRefresh = 0; } // release lock if (changes) { refreshConfiguration(changes); } int32_t timeoutMillis = -1; Loading Loading @@ -326,7 +332,7 @@ void InputReader::addDevice(int32_t deviceId) { uint32_t classes = mEventHub->getDeviceClasses(deviceId); InputDevice* device = createDevice(deviceId, name, classes); device->configure(); device->configure(&mConfig, 0); if (device->isIgnored()) { LOGI("Device added: id=%d, name='%s' (ignored non-input device)", deviceId, name.string()); Loading Loading @@ -483,12 +489,25 @@ void InputReader::handleConfigurationChanged(nsecs_t when) { mDispatcher->notifyConfigurationChanged(when); } void InputReader::configure(bool firstTime) { void InputReader::refreshConfiguration(uint32_t changes) { mPolicy->getReaderConfiguration(&mConfig); mEventHub->setExcludedDevices(mConfig.excludedDeviceNames); if (!firstTime) { if (changes) { LOGI("Reconfiguring input devices. changes=0x%08x", changes); if (changes & InputReaderConfiguration::CHANGE_MUST_REOPEN) { mEventHub->requestReopenDevices(); } else { { // acquire device registry reader lock RWLock::AutoRLock _rl(mDeviceRegistryLock); for (size_t i = 0; i < mDevices.size(); i++) { InputDevice* device = mDevices.valueAt(i); device->configure(&mConfig, changes); } } // release device registry reader lock } } } Loading Loading @@ -709,11 +728,21 @@ bool InputReader::markSupportedKeyCodes(int32_t deviceId, uint32_t sourceMask, s } // release device registy reader lock } void InputReader::refreshConfiguration() { android_atomic_release_store(1, &mRefreshConfiguration); void InputReader::requestRefreshConfiguration(uint32_t changes) { if (changes) { bool needWake; { // acquire lock AutoMutex _l(mStateLock); needWake = !mConfigurationChangesToRefresh; mConfigurationChangesToRefresh |= changes; } // release lock if (needWake) { mEventHub->wake(); } } } void InputReader::dump(String8& dump) { mEventHub->dump(dump); Loading Loading @@ -760,6 +789,8 @@ void InputReader::dump(String8& dump) { mConfig.wheelVelocityControlParameters.acceleration); dump.appendFormat(INDENT2 "PointerGesture:\n"); dump.appendFormat(INDENT3 "Enabled: %s\n", toString(mConfig.pointerGesturesEnabled)); dump.appendFormat(INDENT3 "QuietInterval: %0.1fms\n", mConfig.pointerGestureQuietInterval * 0.000001f); dump.appendFormat(INDENT3 "DragMinSwitchSpeed: %0.1fpx/s\n", Loading Loading @@ -855,20 +886,22 @@ void InputDevice::addMapper(InputMapper* mapper) { mMappers.add(mapper); } void InputDevice::configure() { void InputDevice::configure(const InputReaderConfiguration* config, uint32_t changes) { mSources = 0; if (!isIgnored()) { if (!changes) { // first time only mContext->getEventHub()->getConfiguration(mId, &mConfiguration); } mSources = 0; size_t numMappers = mMappers.size(); for (size_t i = 0; i < numMappers; i++) { InputMapper* mapper = mMappers[i]; mapper->configure(); mapper->configure(config, changes); mSources |= mapper->getSources(); } } } void InputDevice::reset() { size_t numMappers = mMappers.size(); Loading Loading @@ -1010,7 +1043,7 @@ void InputMapper::populateDeviceInfo(InputDeviceInfo* info) { void InputMapper::dump(String8& dump) { } void InputMapper::configure() { void InputMapper::configure(const InputReaderConfiguration* config, uint32_t changes) { } void InputMapper::reset() { Loading Loading @@ -1124,9 +1157,10 @@ void KeyboardInputMapper::dump(String8& dump) { } void KeyboardInputMapper::configure() { InputMapper::configure(); void KeyboardInputMapper::configure(const InputReaderConfiguration* config, uint32_t changes) { InputMapper::configure(config, changes); if (!changes) { // first time only // Configure basic parameters. configureParameters(); Loading @@ -1136,6 +1170,7 @@ void KeyboardInputMapper::configure() { resetLedStateLocked(); } } } void KeyboardInputMapper::configureParameters() { mParameters.orientationAware = false; Loading Loading @@ -1411,9 +1446,10 @@ void CursorInputMapper::dump(String8& dump) { } // release lock } void CursorInputMapper::configure() { InputMapper::configure(); void CursorInputMapper::configure(const InputReaderConfiguration* config, uint32_t changes) { InputMapper::configure(config, changes); if (!changes) { // first time only // Configure basic parameters. configureParameters(); Loading Loading @@ -1441,10 +1477,13 @@ void CursorInputMapper::configure() { mHaveVWheel = getEventHub()->hasRelativeAxis(getDeviceId(), REL_WHEEL); mHaveHWheel = getEventHub()->hasRelativeAxis(getDeviceId(), REL_HWHEEL); } mPointerVelocityControl.setParameters(getConfig()->pointerVelocityControlParameters); mWheelXVelocityControl.setParameters(getConfig()->wheelVelocityControlParameters); mWheelYVelocityControl.setParameters(getConfig()->wheelVelocityControlParameters); if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) { mPointerVelocityControl.setParameters(config->pointerVelocityControlParameters); mWheelXVelocityControl.setParameters(config->wheelVelocityControlParameters); mWheelYVelocityControl.setParameters(config->wheelVelocityControlParameters); } } void CursorInputMapper::configureParameters() { Loading Loading @@ -1787,8 +1826,6 @@ void CursorInputMapper::fadePointer() { TouchInputMapper::TouchInputMapper(InputDevice* device) : InputMapper(device) { mConfig = getConfig(); mLocked.surfaceOrientation = -1; mLocked.surfaceWidth = -1; mLocked.surfaceHeight = -1; Loading Loading @@ -1925,12 +1962,14 @@ void TouchInputMapper::initializeLocked() { mLocked.orientedRanges.haveDistance = false; mPointerGesture.reset(); mPointerGesture.pointerVelocityControl.setParameters(mConfig->pointerVelocityControlParameters); } void TouchInputMapper::configure() { InputMapper::configure(); void TouchInputMapper::configure(const InputReaderConfiguration* config, uint32_t changes) { InputMapper::configure(config, changes); mConfig = *config; if (!changes) { // first time only // Configure basic parameters. configureParameters(); Loading Loading @@ -1967,10 +2006,21 @@ void TouchInputMapper::configure() { } // release lock } if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) { mPointerGesture.pointerVelocityControl.setParameters( mConfig.pointerVelocityControlParameters); } if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_GESTURE_ENABLEMENT)) { // Reset the touch screen when pointer gesture enablement changes. reset(); } } void TouchInputMapper::configureParameters() { mParameters.useBadTouchFilter = mConfig->filterTouchEvents; mParameters.useAveragingTouchFilter = mConfig->filterTouchEvents; mParameters.useJumpyTouchFilter = mConfig->filterJumpyTouchEvents; mParameters.useBadTouchFilter = mConfig.filterTouchEvents; mParameters.useAveragingTouchFilter = mConfig.filterTouchEvents; mParameters.useJumpyTouchFilter = mConfig.filterJumpyTouchEvents; // Use the pointer presentation mode for devices that do not support distinct // multitouch. The spot-based presentation relies on being able to accurately Loading Loading @@ -2401,14 +2451,14 @@ bool TouchInputMapper::configureSurfaceLocked() { // is applied. // Assume that the touch pad has a square aspect ratio such that movements in // X and Y of the same number of raw units cover the same physical distance. mLocked.pointerGestureXMovementScale = mConfig->pointerGestureMovementSpeedRatio mLocked.pointerGestureXMovementScale = mConfig.pointerGestureMovementSpeedRatio * displayDiagonal / rawDiagonal; mLocked.pointerGestureYMovementScale = mLocked.pointerGestureXMovementScale; // Scale zooms to cover a smaller range of the display than movements do. // This value determines the area around the pointer that is affected by freeform // pointer gestures. mLocked.pointerGestureXZoomScale = mConfig->pointerGestureZoomSpeedRatio mLocked.pointerGestureXZoomScale = mConfig.pointerGestureZoomSpeedRatio * displayDiagonal / rawDiagonal; mLocked.pointerGestureYZoomScale = mLocked.pointerGestureXZoomScale; Loading @@ -2416,7 +2466,7 @@ bool TouchInputMapper::configureSurfaceLocked() { // of the diagonal axis of the touch pad. Touches that are wider than this are // translated into freeform gestures. mLocked.pointerGestureMaxSwipeWidth = mConfig->pointerGestureSwipeMaxWidthRatio * rawDiagonal; mConfig.pointerGestureSwipeMaxWidthRatio * rawDiagonal; // Reset the current pointer gesture. mPointerGesture.reset(); Loading Loading @@ -2902,6 +2952,7 @@ void TouchInputMapper::reset() { if (mPointerController != NULL && mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) { mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL); mPointerController->clearSpots(); } } // release lock Loading Loading @@ -2982,7 +3033,7 @@ void TouchInputMapper::syncTouch(nsecs_t when, bool havePointerIds) { touchResult = consumeOffScreenTouches(when, policyFlags); if (touchResult == DISPATCH_TOUCH) { suppressSwipeOntoVirtualKeys(when); if (mPointerController != NULL) { if (mPointerController != NULL && mConfig.pointerGesturesEnabled) { dispatchPointerGestures(when, policyFlags, false /*isTimeout*/); } dispatchTouches(when, policyFlags); Loading Loading @@ -3139,8 +3190,8 @@ void TouchInputMapper::suppressSwipeOntoVirtualKeys(nsecs_t when) { // area and accidentally triggers a virtual key. This often happens when virtual keys // are layed out below the screen near to where the on screen keyboard's space bar // is displayed. if (mConfig->virtualKeyQuietTime > 0 && mCurrentTouch.pointerCount != 0) { mContext->disableVirtualKeysUntil(when + mConfig->virtualKeyQuietTime); if (mConfig.virtualKeyQuietTime > 0 && mCurrentTouch.pointerCount != 0) { mContext->disableVirtualKeysUntil(when + mConfig.virtualKeyQuietTime); } } Loading Loading @@ -3688,10 +3739,10 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, #endif if (mPointerGesture.lastGestureMode == PointerGesture::TAP) { if (when <= mPointerGesture.tapUpTime + mConfig->pointerGestureTapDragInterval) { if (when <= mPointerGesture.tapUpTime + mConfig.pointerGestureTapDragInterval) { // The tap/drag timeout has not yet expired. getContext()->requestTimeoutAtTime(mPointerGesture.tapUpTime + mConfig->pointerGestureTapDragInterval); + mConfig.pointerGestureTapDragInterval); } else { // The tap is finished. #if DEBUG_GESTURES Loading Loading @@ -3756,7 +3807,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, if (activeTouchId < 0) { mPointerGesture.resetQuietTime(); } else { isQuietTime = when < mPointerGesture.quietTime + mConfig->pointerGestureQuietInterval; isQuietTime = when < mPointerGesture.quietTime + mConfig.pointerGestureQuietInterval; if (!isQuietTime) { if ((mPointerGesture.lastGestureMode == PointerGesture::PRESS || mPointerGesture.lastGestureMode == PointerGesture::SWIPE Loading Loading @@ -3785,7 +3836,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, // Case 1: Quiet time. (QUIET) #if DEBUG_GESTURES LOGD("Gestures: QUIET for next %0.3fms", (mPointerGesture.quietTime + mConfig->pointerGestureQuietInterval - when) * 0.000001f); + mConfig.pointerGestureQuietInterval - when) * 0.000001f); #endif if (mPointerGesture.lastGestureMode != PointerGesture::QUIET) { *outFinishPreviousGesture = true; Loading Loading @@ -3824,7 +3875,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, // Find the fastest pointer and follow it. if (activeTouchId >= 0 && mCurrentTouch.pointerCount > 1) { int32_t bestId = -1; float bestSpeed = mConfig->pointerGestureDragMinSwitchSpeed; float bestSpeed = mConfig.pointerGestureDragMinSwitchSpeed; for (uint32_t i = 0; i < mCurrentTouch.pointerCount; i++) { uint32_t id = mCurrentTouch.pointers[i].id; float vx, vy; Loading Loading @@ -3893,18 +3944,18 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, if ((mPointerGesture.lastGestureMode == PointerGesture::HOVER || mPointerGesture.lastGestureMode == PointerGesture::TAP_DRAG) && mLastTouch.pointerCount == 1) { if (when <= mPointerGesture.tapDownTime + mConfig->pointerGestureTapInterval) { if (when <= mPointerGesture.tapDownTime + mConfig.pointerGestureTapInterval) { float x, y; mPointerController->getPosition(&x, &y); if (fabs(x - mPointerGesture.tapX) <= mConfig->pointerGestureTapSlop && fabs(y - mPointerGesture.tapY) <= mConfig->pointerGestureTapSlop) { if (fabs(x - mPointerGesture.tapX) <= mConfig.pointerGestureTapSlop && fabs(y - mPointerGesture.tapY) <= mConfig.pointerGestureTapSlop) { #if DEBUG_GESTURES LOGD("Gestures: TAP"); #endif mPointerGesture.tapUpTime = when; getContext()->requestTimeoutAtTime(when + mConfig->pointerGestureTapDragInterval); + mConfig.pointerGestureTapDragInterval); mPointerGesture.activeGestureId = 0; mPointerGesture.currentGestureMode = PointerGesture::TAP; Loading Loading @@ -3961,11 +4012,11 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, mPointerGesture.currentGestureMode = PointerGesture::HOVER; if (mPointerGesture.lastGestureMode == PointerGesture::TAP) { if (when <= mPointerGesture.tapUpTime + mConfig->pointerGestureTapDragInterval) { if (when <= mPointerGesture.tapUpTime + mConfig.pointerGestureTapDragInterval) { float x, y; mPointerController->getPosition(&x, &y); if (fabs(x - mPointerGesture.tapX) <= mConfig->pointerGestureTapSlop && fabs(y - mPointerGesture.tapY) <= mConfig->pointerGestureTapSlop) { if (fabs(x - mPointerGesture.tapX) <= mConfig.pointerGestureTapSlop && fabs(y - mPointerGesture.tapY) <= mConfig.pointerGestureTapSlop) { mPointerGesture.currentGestureMode = PointerGesture::TAP_DRAG; } else { #if DEBUG_GESTURES Loading Loading @@ -4059,7 +4110,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, LOG_ASSERT(activeTouchId >= 0); bool settled = when >= mPointerGesture.firstTouchTime + mConfig->pointerGestureMultitouchSettleInterval; + mConfig.pointerGestureMultitouchSettleInterval; if (mPointerGesture.lastGestureMode != PointerGesture::PRESS && mPointerGesture.lastGestureMode != PointerGesture::SWIPE && mPointerGesture.lastGestureMode != PointerGesture::FREEFORM) { Loading @@ -4070,7 +4121,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, #if DEBUG_GESTURES LOGD("Gestures: Resetting gesture since additional pointers went down for MULTITOUCH, " "settle time remaining %0.3fms", (mPointerGesture.firstTouchTime + mConfig->pointerGestureMultitouchSettleInterval - when) + mConfig.pointerGestureMultitouchSettleInterval - when) * 0.000001f); #endif *outCancelPreviousGesture = true; Loading @@ -4089,7 +4140,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, #if DEBUG_GESTURES LOGD("Gestures: Using centroid as reference for MULTITOUCH, " "settle time remaining %0.3fms", (mPointerGesture.firstTouchTime + mConfig->pointerGestureMultitouchSettleInterval - when) + mConfig.pointerGestureMultitouchSettleInterval - when) * 0.000001f); #endif mCurrentTouch.getCentroid(&mPointerGesture.referenceTouchX, Loading Loading @@ -4143,7 +4194,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id]; dist[id] = hypotf(delta.dx * mLocked.pointerGestureXZoomScale, delta.dy * mLocked.pointerGestureYZoomScale); if (dist[id] > mConfig->pointerGestureMultitouchMinDistance) { if (dist[id] > mConfig.pointerGestureMultitouchMinDistance) { distOverThreshold += 1; } } Loading Loading @@ -4179,8 +4230,8 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, uint32_t id2 = mCurrentTouch.pointers[1].id; float dist1 = dist[id1]; float dist2 = dist[id2]; if (dist1 >= mConfig->pointerGestureMultitouchMinDistance && dist2 >= mConfig->pointerGestureMultitouchMinDistance) { if (dist1 >= mConfig.pointerGestureMultitouchMinDistance && dist2 >= mConfig.pointerGestureMultitouchMinDistance) { // Calculate the dot product of the displacement vectors. // When the vectors are oriented in approximately the same direction, // the angle betweeen them is near zero and the cosine of the angle Loading @@ -4193,15 +4244,15 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, float dy2 = delta2.dy * mLocked.pointerGestureYZoomScale; float dot = dx1 * dx2 + dy1 * dy2; float cosine = dot / (dist1 * dist2); // denominator always > 0 if (cosine >= mConfig->pointerGestureSwipeTransitionAngleCosine) { if (cosine >= mConfig.pointerGestureSwipeTransitionAngleCosine) { // Pointers are moving in the same direction. Switch to SWIPE. #if DEBUG_GESTURES LOGD("Gestures: PRESS transitioned to SWIPE, " "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, " "cosine %0.3f >= %0.3f", dist1, mConfig->pointerGestureMultitouchMinDistance, dist2, mConfig->pointerGestureMultitouchMinDistance, cosine, mConfig->pointerGestureSwipeTransitionAngleCosine); dist1, mConfig.pointerGestureMultitouchMinDistance, dist2, mConfig.pointerGestureMultitouchMinDistance, cosine, mConfig.pointerGestureSwipeTransitionAngleCosine); #endif mPointerGesture.currentGestureMode = PointerGesture::SWIPE; } else { Loading @@ -4210,9 +4261,9 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, LOGD("Gestures: PRESS transitioned to FREEFORM, " "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, " "cosine %0.3f < %0.3f", dist1, mConfig->pointerGestureMultitouchMinDistance, dist2, mConfig->pointerGestureMultitouchMinDistance, cosine, mConfig->pointerGestureSwipeTransitionAngleCosine); dist1, mConfig.pointerGestureMultitouchMinDistance, dist2, mConfig.pointerGestureMultitouchMinDistance, cosine, mConfig.pointerGestureSwipeTransitionAngleCosine); #endif *outCancelPreviousGesture = true; mPointerGesture.currentGestureMode = PointerGesture::FREEFORM; Loading Loading @@ -5665,9 +5716,10 @@ void JoystickInputMapper::dump(String8& dump) { } } void JoystickInputMapper::configure() { InputMapper::configure(); void JoystickInputMapper::configure(const InputReaderConfiguration* config, uint32_t changes) { InputMapper::configure(config, changes); if (!changes) { // first time only // Collect all axes. for (int32_t abs = 0; abs <= ABS_MAX; abs++) { RawAbsoluteAxisInfo rawAxisInfo; Loading Loading @@ -5748,6 +5800,7 @@ void JoystickInputMapper::configure() { } } } } bool JoystickInputMapper::haveAxis(int32_t axisId) { size_t numAxes = mAxes.size(); Loading Loading
core/java/android/view/WindowManager.java +27 −0 Original line number Diff line number Diff line Loading @@ -1004,6 +1004,23 @@ public interface WindowManager extends ViewManager { */ public boolean hasSystemUiListeners; /** * When this window has focus, disable touch pad pointer gesture processing. * The window will receive raw position updates from the touch pad instead * of pointer movements and synthetic touch events. * * @hide */ public static final int INPUT_FEATURE_DISABLE_POINTER_GESTURES = 0x00000001; /** * Control special features of the input subsystem. * * @see #INPUT_FEATURE_DISABLE_TOUCH_PAD_GESTURES * @hide */ public int inputFeatures; public LayoutParams() { super(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); type = TYPE_APPLICATION; Loading Loading @@ -1086,6 +1103,7 @@ public interface WindowManager extends ViewManager { out.writeInt(systemUiVisibility); out.writeInt(subtreeSystemUiVisibility); out.writeInt(hasSystemUiListeners ? 1 : 0); out.writeInt(inputFeatures); } public static final Parcelable.Creator<LayoutParams> CREATOR Loading Loading @@ -1124,6 +1142,7 @@ public interface WindowManager extends ViewManager { systemUiVisibility = in.readInt(); subtreeSystemUiVisibility = in.readInt(); hasSystemUiListeners = in.readInt() != 0; inputFeatures = in.readInt(); } @SuppressWarnings({"PointlessBitwiseExpression"}) Loading @@ -1145,6 +1164,8 @@ public interface WindowManager extends ViewManager { public static final int SYSTEM_UI_VISIBILITY_CHANGED = 1<<13; /** {@hide} */ public static final int SYSTEM_UI_LISTENER_CHANGED = 1<<14; /** {@hide} */ public static final int INPUT_FEATURES_CHANGED = 1<<15; // internal buffer to backup/restore parameters under compatibility mode. private int[] mCompatibilityParamsBackup = null; Loading Loading @@ -1256,6 +1277,11 @@ public interface WindowManager extends ViewManager { changes |= SYSTEM_UI_LISTENER_CHANGED; } if (inputFeatures != o.inputFeatures) { inputFeatures = o.inputFeatures; changes |= INPUT_FEATURES_CHANGED; } return changes; } Loading Loading @@ -1340,6 +1366,7 @@ public interface WindowManager extends ViewManager { sb.append(" sysuil="); sb.append(hasSystemUiListeners); } sb.append(" if=0x").append(Integer.toHexString(inputFeatures)); sb.append('}'); return sb.toString(); } Loading
services/input/InputDispatcher.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -3395,6 +3395,7 @@ void InputDispatcher::dumpDispatchStateLocked(String8& dump) { window.frameRight, window.frameBottom, window.scaleFactor); dumpRegion(dump, window.touchableRegion); dump.appendFormat(", inputFeatures=0x%08x", window.inputFeatures); dump.appendFormat(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n", window.ownerPid, window.ownerUid, window.dispatchingTimeout / 1000000.0); Loading
services/input/InputReader.cpp +254 −201 Original line number Diff line number Diff line Loading @@ -38,7 +38,6 @@ #include "InputReader.h" #include <cutils/atomic.h> #include <cutils/log.h> #include <ui/Keyboard.h> #include <ui/VirtualKeyMap.h> Loading Loading @@ -245,8 +244,8 @@ InputReader::InputReader(const sp<EventHubInterface>& eventHub, const sp<InputDispatcherInterface>& dispatcher) : mEventHub(eventHub), mPolicy(policy), mDispatcher(dispatcher), mGlobalMetaState(0), mDisableVirtualKeysTimeout(LLONG_MIN), mNextTimeout(LLONG_MAX), mRefreshConfiguration(0) { configure(true /*firstTime*/); mConfigurationChangesToRefresh(0) { refreshConfiguration(0); updateGlobalMetaState(); updateInputConfiguration(); } Loading @@ -258,9 +257,16 @@ InputReader::~InputReader() { } void InputReader::loopOnce() { if (android_atomic_acquire_load(&mRefreshConfiguration)) { android_atomic_release_store(0, &mRefreshConfiguration); configure(false /*firstTime*/); uint32_t changes; { // acquire lock AutoMutex _l(mStateLock); changes = mConfigurationChangesToRefresh; mConfigurationChangesToRefresh = 0; } // release lock if (changes) { refreshConfiguration(changes); } int32_t timeoutMillis = -1; Loading Loading @@ -326,7 +332,7 @@ void InputReader::addDevice(int32_t deviceId) { uint32_t classes = mEventHub->getDeviceClasses(deviceId); InputDevice* device = createDevice(deviceId, name, classes); device->configure(); device->configure(&mConfig, 0); if (device->isIgnored()) { LOGI("Device added: id=%d, name='%s' (ignored non-input device)", deviceId, name.string()); Loading Loading @@ -483,12 +489,25 @@ void InputReader::handleConfigurationChanged(nsecs_t when) { mDispatcher->notifyConfigurationChanged(when); } void InputReader::configure(bool firstTime) { void InputReader::refreshConfiguration(uint32_t changes) { mPolicy->getReaderConfiguration(&mConfig); mEventHub->setExcludedDevices(mConfig.excludedDeviceNames); if (!firstTime) { if (changes) { LOGI("Reconfiguring input devices. changes=0x%08x", changes); if (changes & InputReaderConfiguration::CHANGE_MUST_REOPEN) { mEventHub->requestReopenDevices(); } else { { // acquire device registry reader lock RWLock::AutoRLock _rl(mDeviceRegistryLock); for (size_t i = 0; i < mDevices.size(); i++) { InputDevice* device = mDevices.valueAt(i); device->configure(&mConfig, changes); } } // release device registry reader lock } } } Loading Loading @@ -709,11 +728,21 @@ bool InputReader::markSupportedKeyCodes(int32_t deviceId, uint32_t sourceMask, s } // release device registy reader lock } void InputReader::refreshConfiguration() { android_atomic_release_store(1, &mRefreshConfiguration); void InputReader::requestRefreshConfiguration(uint32_t changes) { if (changes) { bool needWake; { // acquire lock AutoMutex _l(mStateLock); needWake = !mConfigurationChangesToRefresh; mConfigurationChangesToRefresh |= changes; } // release lock if (needWake) { mEventHub->wake(); } } } void InputReader::dump(String8& dump) { mEventHub->dump(dump); Loading Loading @@ -760,6 +789,8 @@ void InputReader::dump(String8& dump) { mConfig.wheelVelocityControlParameters.acceleration); dump.appendFormat(INDENT2 "PointerGesture:\n"); dump.appendFormat(INDENT3 "Enabled: %s\n", toString(mConfig.pointerGesturesEnabled)); dump.appendFormat(INDENT3 "QuietInterval: %0.1fms\n", mConfig.pointerGestureQuietInterval * 0.000001f); dump.appendFormat(INDENT3 "DragMinSwitchSpeed: %0.1fpx/s\n", Loading Loading @@ -855,20 +886,22 @@ void InputDevice::addMapper(InputMapper* mapper) { mMappers.add(mapper); } void InputDevice::configure() { void InputDevice::configure(const InputReaderConfiguration* config, uint32_t changes) { mSources = 0; if (!isIgnored()) { if (!changes) { // first time only mContext->getEventHub()->getConfiguration(mId, &mConfiguration); } mSources = 0; size_t numMappers = mMappers.size(); for (size_t i = 0; i < numMappers; i++) { InputMapper* mapper = mMappers[i]; mapper->configure(); mapper->configure(config, changes); mSources |= mapper->getSources(); } } } void InputDevice::reset() { size_t numMappers = mMappers.size(); Loading Loading @@ -1010,7 +1043,7 @@ void InputMapper::populateDeviceInfo(InputDeviceInfo* info) { void InputMapper::dump(String8& dump) { } void InputMapper::configure() { void InputMapper::configure(const InputReaderConfiguration* config, uint32_t changes) { } void InputMapper::reset() { Loading Loading @@ -1124,9 +1157,10 @@ void KeyboardInputMapper::dump(String8& dump) { } void KeyboardInputMapper::configure() { InputMapper::configure(); void KeyboardInputMapper::configure(const InputReaderConfiguration* config, uint32_t changes) { InputMapper::configure(config, changes); if (!changes) { // first time only // Configure basic parameters. configureParameters(); Loading @@ -1136,6 +1170,7 @@ void KeyboardInputMapper::configure() { resetLedStateLocked(); } } } void KeyboardInputMapper::configureParameters() { mParameters.orientationAware = false; Loading Loading @@ -1411,9 +1446,10 @@ void CursorInputMapper::dump(String8& dump) { } // release lock } void CursorInputMapper::configure() { InputMapper::configure(); void CursorInputMapper::configure(const InputReaderConfiguration* config, uint32_t changes) { InputMapper::configure(config, changes); if (!changes) { // first time only // Configure basic parameters. configureParameters(); Loading Loading @@ -1441,10 +1477,13 @@ void CursorInputMapper::configure() { mHaveVWheel = getEventHub()->hasRelativeAxis(getDeviceId(), REL_WHEEL); mHaveHWheel = getEventHub()->hasRelativeAxis(getDeviceId(), REL_HWHEEL); } mPointerVelocityControl.setParameters(getConfig()->pointerVelocityControlParameters); mWheelXVelocityControl.setParameters(getConfig()->wheelVelocityControlParameters); mWheelYVelocityControl.setParameters(getConfig()->wheelVelocityControlParameters); if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) { mPointerVelocityControl.setParameters(config->pointerVelocityControlParameters); mWheelXVelocityControl.setParameters(config->wheelVelocityControlParameters); mWheelYVelocityControl.setParameters(config->wheelVelocityControlParameters); } } void CursorInputMapper::configureParameters() { Loading Loading @@ -1787,8 +1826,6 @@ void CursorInputMapper::fadePointer() { TouchInputMapper::TouchInputMapper(InputDevice* device) : InputMapper(device) { mConfig = getConfig(); mLocked.surfaceOrientation = -1; mLocked.surfaceWidth = -1; mLocked.surfaceHeight = -1; Loading Loading @@ -1925,12 +1962,14 @@ void TouchInputMapper::initializeLocked() { mLocked.orientedRanges.haveDistance = false; mPointerGesture.reset(); mPointerGesture.pointerVelocityControl.setParameters(mConfig->pointerVelocityControlParameters); } void TouchInputMapper::configure() { InputMapper::configure(); void TouchInputMapper::configure(const InputReaderConfiguration* config, uint32_t changes) { InputMapper::configure(config, changes); mConfig = *config; if (!changes) { // first time only // Configure basic parameters. configureParameters(); Loading Loading @@ -1967,10 +2006,21 @@ void TouchInputMapper::configure() { } // release lock } if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) { mPointerGesture.pointerVelocityControl.setParameters( mConfig.pointerVelocityControlParameters); } if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_GESTURE_ENABLEMENT)) { // Reset the touch screen when pointer gesture enablement changes. reset(); } } void TouchInputMapper::configureParameters() { mParameters.useBadTouchFilter = mConfig->filterTouchEvents; mParameters.useAveragingTouchFilter = mConfig->filterTouchEvents; mParameters.useJumpyTouchFilter = mConfig->filterJumpyTouchEvents; mParameters.useBadTouchFilter = mConfig.filterTouchEvents; mParameters.useAveragingTouchFilter = mConfig.filterTouchEvents; mParameters.useJumpyTouchFilter = mConfig.filterJumpyTouchEvents; // Use the pointer presentation mode for devices that do not support distinct // multitouch. The spot-based presentation relies on being able to accurately Loading Loading @@ -2401,14 +2451,14 @@ bool TouchInputMapper::configureSurfaceLocked() { // is applied. // Assume that the touch pad has a square aspect ratio such that movements in // X and Y of the same number of raw units cover the same physical distance. mLocked.pointerGestureXMovementScale = mConfig->pointerGestureMovementSpeedRatio mLocked.pointerGestureXMovementScale = mConfig.pointerGestureMovementSpeedRatio * displayDiagonal / rawDiagonal; mLocked.pointerGestureYMovementScale = mLocked.pointerGestureXMovementScale; // Scale zooms to cover a smaller range of the display than movements do. // This value determines the area around the pointer that is affected by freeform // pointer gestures. mLocked.pointerGestureXZoomScale = mConfig->pointerGestureZoomSpeedRatio mLocked.pointerGestureXZoomScale = mConfig.pointerGestureZoomSpeedRatio * displayDiagonal / rawDiagonal; mLocked.pointerGestureYZoomScale = mLocked.pointerGestureXZoomScale; Loading @@ -2416,7 +2466,7 @@ bool TouchInputMapper::configureSurfaceLocked() { // of the diagonal axis of the touch pad. Touches that are wider than this are // translated into freeform gestures. mLocked.pointerGestureMaxSwipeWidth = mConfig->pointerGestureSwipeMaxWidthRatio * rawDiagonal; mConfig.pointerGestureSwipeMaxWidthRatio * rawDiagonal; // Reset the current pointer gesture. mPointerGesture.reset(); Loading Loading @@ -2902,6 +2952,7 @@ void TouchInputMapper::reset() { if (mPointerController != NULL && mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) { mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL); mPointerController->clearSpots(); } } // release lock Loading Loading @@ -2982,7 +3033,7 @@ void TouchInputMapper::syncTouch(nsecs_t when, bool havePointerIds) { touchResult = consumeOffScreenTouches(when, policyFlags); if (touchResult == DISPATCH_TOUCH) { suppressSwipeOntoVirtualKeys(when); if (mPointerController != NULL) { if (mPointerController != NULL && mConfig.pointerGesturesEnabled) { dispatchPointerGestures(when, policyFlags, false /*isTimeout*/); } dispatchTouches(when, policyFlags); Loading Loading @@ -3139,8 +3190,8 @@ void TouchInputMapper::suppressSwipeOntoVirtualKeys(nsecs_t when) { // area and accidentally triggers a virtual key. This often happens when virtual keys // are layed out below the screen near to where the on screen keyboard's space bar // is displayed. if (mConfig->virtualKeyQuietTime > 0 && mCurrentTouch.pointerCount != 0) { mContext->disableVirtualKeysUntil(when + mConfig->virtualKeyQuietTime); if (mConfig.virtualKeyQuietTime > 0 && mCurrentTouch.pointerCount != 0) { mContext->disableVirtualKeysUntil(when + mConfig.virtualKeyQuietTime); } } Loading Loading @@ -3688,10 +3739,10 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, #endif if (mPointerGesture.lastGestureMode == PointerGesture::TAP) { if (when <= mPointerGesture.tapUpTime + mConfig->pointerGestureTapDragInterval) { if (when <= mPointerGesture.tapUpTime + mConfig.pointerGestureTapDragInterval) { // The tap/drag timeout has not yet expired. getContext()->requestTimeoutAtTime(mPointerGesture.tapUpTime + mConfig->pointerGestureTapDragInterval); + mConfig.pointerGestureTapDragInterval); } else { // The tap is finished. #if DEBUG_GESTURES Loading Loading @@ -3756,7 +3807,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, if (activeTouchId < 0) { mPointerGesture.resetQuietTime(); } else { isQuietTime = when < mPointerGesture.quietTime + mConfig->pointerGestureQuietInterval; isQuietTime = when < mPointerGesture.quietTime + mConfig.pointerGestureQuietInterval; if (!isQuietTime) { if ((mPointerGesture.lastGestureMode == PointerGesture::PRESS || mPointerGesture.lastGestureMode == PointerGesture::SWIPE Loading Loading @@ -3785,7 +3836,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, // Case 1: Quiet time. (QUIET) #if DEBUG_GESTURES LOGD("Gestures: QUIET for next %0.3fms", (mPointerGesture.quietTime + mConfig->pointerGestureQuietInterval - when) * 0.000001f); + mConfig.pointerGestureQuietInterval - when) * 0.000001f); #endif if (mPointerGesture.lastGestureMode != PointerGesture::QUIET) { *outFinishPreviousGesture = true; Loading Loading @@ -3824,7 +3875,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, // Find the fastest pointer and follow it. if (activeTouchId >= 0 && mCurrentTouch.pointerCount > 1) { int32_t bestId = -1; float bestSpeed = mConfig->pointerGestureDragMinSwitchSpeed; float bestSpeed = mConfig.pointerGestureDragMinSwitchSpeed; for (uint32_t i = 0; i < mCurrentTouch.pointerCount; i++) { uint32_t id = mCurrentTouch.pointers[i].id; float vx, vy; Loading Loading @@ -3893,18 +3944,18 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, if ((mPointerGesture.lastGestureMode == PointerGesture::HOVER || mPointerGesture.lastGestureMode == PointerGesture::TAP_DRAG) && mLastTouch.pointerCount == 1) { if (when <= mPointerGesture.tapDownTime + mConfig->pointerGestureTapInterval) { if (when <= mPointerGesture.tapDownTime + mConfig.pointerGestureTapInterval) { float x, y; mPointerController->getPosition(&x, &y); if (fabs(x - mPointerGesture.tapX) <= mConfig->pointerGestureTapSlop && fabs(y - mPointerGesture.tapY) <= mConfig->pointerGestureTapSlop) { if (fabs(x - mPointerGesture.tapX) <= mConfig.pointerGestureTapSlop && fabs(y - mPointerGesture.tapY) <= mConfig.pointerGestureTapSlop) { #if DEBUG_GESTURES LOGD("Gestures: TAP"); #endif mPointerGesture.tapUpTime = when; getContext()->requestTimeoutAtTime(when + mConfig->pointerGestureTapDragInterval); + mConfig.pointerGestureTapDragInterval); mPointerGesture.activeGestureId = 0; mPointerGesture.currentGestureMode = PointerGesture::TAP; Loading Loading @@ -3961,11 +4012,11 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, mPointerGesture.currentGestureMode = PointerGesture::HOVER; if (mPointerGesture.lastGestureMode == PointerGesture::TAP) { if (when <= mPointerGesture.tapUpTime + mConfig->pointerGestureTapDragInterval) { if (when <= mPointerGesture.tapUpTime + mConfig.pointerGestureTapDragInterval) { float x, y; mPointerController->getPosition(&x, &y); if (fabs(x - mPointerGesture.tapX) <= mConfig->pointerGestureTapSlop && fabs(y - mPointerGesture.tapY) <= mConfig->pointerGestureTapSlop) { if (fabs(x - mPointerGesture.tapX) <= mConfig.pointerGestureTapSlop && fabs(y - mPointerGesture.tapY) <= mConfig.pointerGestureTapSlop) { mPointerGesture.currentGestureMode = PointerGesture::TAP_DRAG; } else { #if DEBUG_GESTURES Loading Loading @@ -4059,7 +4110,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, LOG_ASSERT(activeTouchId >= 0); bool settled = when >= mPointerGesture.firstTouchTime + mConfig->pointerGestureMultitouchSettleInterval; + mConfig.pointerGestureMultitouchSettleInterval; if (mPointerGesture.lastGestureMode != PointerGesture::PRESS && mPointerGesture.lastGestureMode != PointerGesture::SWIPE && mPointerGesture.lastGestureMode != PointerGesture::FREEFORM) { Loading @@ -4070,7 +4121,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, #if DEBUG_GESTURES LOGD("Gestures: Resetting gesture since additional pointers went down for MULTITOUCH, " "settle time remaining %0.3fms", (mPointerGesture.firstTouchTime + mConfig->pointerGestureMultitouchSettleInterval - when) + mConfig.pointerGestureMultitouchSettleInterval - when) * 0.000001f); #endif *outCancelPreviousGesture = true; Loading @@ -4089,7 +4140,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, #if DEBUG_GESTURES LOGD("Gestures: Using centroid as reference for MULTITOUCH, " "settle time remaining %0.3fms", (mPointerGesture.firstTouchTime + mConfig->pointerGestureMultitouchSettleInterval - when) + mConfig.pointerGestureMultitouchSettleInterval - when) * 0.000001f); #endif mCurrentTouch.getCentroid(&mPointerGesture.referenceTouchX, Loading Loading @@ -4143,7 +4194,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id]; dist[id] = hypotf(delta.dx * mLocked.pointerGestureXZoomScale, delta.dy * mLocked.pointerGestureYZoomScale); if (dist[id] > mConfig->pointerGestureMultitouchMinDistance) { if (dist[id] > mConfig.pointerGestureMultitouchMinDistance) { distOverThreshold += 1; } } Loading Loading @@ -4179,8 +4230,8 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, uint32_t id2 = mCurrentTouch.pointers[1].id; float dist1 = dist[id1]; float dist2 = dist[id2]; if (dist1 >= mConfig->pointerGestureMultitouchMinDistance && dist2 >= mConfig->pointerGestureMultitouchMinDistance) { if (dist1 >= mConfig.pointerGestureMultitouchMinDistance && dist2 >= mConfig.pointerGestureMultitouchMinDistance) { // Calculate the dot product of the displacement vectors. // When the vectors are oriented in approximately the same direction, // the angle betweeen them is near zero and the cosine of the angle Loading @@ -4193,15 +4244,15 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, float dy2 = delta2.dy * mLocked.pointerGestureYZoomScale; float dot = dx1 * dx2 + dy1 * dy2; float cosine = dot / (dist1 * dist2); // denominator always > 0 if (cosine >= mConfig->pointerGestureSwipeTransitionAngleCosine) { if (cosine >= mConfig.pointerGestureSwipeTransitionAngleCosine) { // Pointers are moving in the same direction. Switch to SWIPE. #if DEBUG_GESTURES LOGD("Gestures: PRESS transitioned to SWIPE, " "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, " "cosine %0.3f >= %0.3f", dist1, mConfig->pointerGestureMultitouchMinDistance, dist2, mConfig->pointerGestureMultitouchMinDistance, cosine, mConfig->pointerGestureSwipeTransitionAngleCosine); dist1, mConfig.pointerGestureMultitouchMinDistance, dist2, mConfig.pointerGestureMultitouchMinDistance, cosine, mConfig.pointerGestureSwipeTransitionAngleCosine); #endif mPointerGesture.currentGestureMode = PointerGesture::SWIPE; } else { Loading @@ -4210,9 +4261,9 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, LOGD("Gestures: PRESS transitioned to FREEFORM, " "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, " "cosine %0.3f < %0.3f", dist1, mConfig->pointerGestureMultitouchMinDistance, dist2, mConfig->pointerGestureMultitouchMinDistance, cosine, mConfig->pointerGestureSwipeTransitionAngleCosine); dist1, mConfig.pointerGestureMultitouchMinDistance, dist2, mConfig.pointerGestureMultitouchMinDistance, cosine, mConfig.pointerGestureSwipeTransitionAngleCosine); #endif *outCancelPreviousGesture = true; mPointerGesture.currentGestureMode = PointerGesture::FREEFORM; Loading Loading @@ -5665,9 +5716,10 @@ void JoystickInputMapper::dump(String8& dump) { } } void JoystickInputMapper::configure() { InputMapper::configure(); void JoystickInputMapper::configure(const InputReaderConfiguration* config, uint32_t changes) { InputMapper::configure(config, changes); if (!changes) { // first time only // Collect all axes. for (int32_t abs = 0; abs <= ABS_MAX; abs++) { RawAbsoluteAxisInfo rawAxisInfo; Loading Loading @@ -5748,6 +5800,7 @@ void JoystickInputMapper::configure() { } } } } bool JoystickInputMapper::haveAxis(int32_t axisId) { size_t numAxes = mAxes.size(); Loading