From 70eafe06dab93f22d51424a830301bdb3ecffbfb Mon Sep 17 00:00:00 2001 From: Prabir Pradhan Date: Wed, 21 Dec 2022 20:53:24 +0000 Subject: [PATCH] Add configuration for disabling stylus button motion events This adds an option for disabling stylus buttons from being reported as part of a motion gesture. When disabled, all reported motion events' button state will not include any stylus buttons. Key events are unaffected. This configuration is toggled through PhoneWindowManager based on user-facing settings. Since this configuration does not affect KeyEvents generated from stylus buttons, this gives a chance for the policy to react to stylus button presses even when motion events are disabled. For example, the policy can still be notified of stylus button presses just as with any other key press, allowing the policy to make decisions such as whether or not the device should be woken up. The policy can also choose to ignore key presses and prevent them from being sent to apps. DD: go/android-stylus-buttons Bug: 263256832 Test: atest inputflinger_tests Change-Id: I68edaef5e6228aadf645586fbc1c4afcd499f712 --- .../server/input/InputManagerInternal.java | 7 +++++ .../server/input/InputManagerService.java | 5 ++++ .../input/NativeInputManagerService.java | 6 ++++ .../server/policy/PhoneWindowManager.java | 1 + ...droid_server_input_InputManagerService.cpp | 29 +++++++++++++++++++ 5 files changed, 48 insertions(+) diff --git a/services/core/java/com/android/server/input/InputManagerInternal.java b/services/core/java/com/android/server/input/InputManagerInternal.java index 30f6145f77e3c..ca42614624ea1 100644 --- a/services/core/java/com/android/server/input/InputManagerInternal.java +++ b/services/core/java/com/android/server/input/InputManagerInternal.java @@ -206,4 +206,11 @@ public abstract class InputManagerInternal { * @param inputPort The port of the input device. */ public abstract void removeKeyboardLayoutAssociation(@NonNull String inputPort); + + /** + * Set whether stylus button reporting through motion events should be enabled. + * + * @param enabled When true, stylus buttons will not be reported through motion events. + */ + public abstract void setStylusButtonMotionEventsEnabled(boolean enabled); } diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index e1e99a1cb3b78..db416961a8ecc 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -3364,6 +3364,11 @@ public class InputManagerService extends IInputManager.Stub public void removeKeyboardLayoutAssociation(@NonNull String inputPort) { InputManagerService.this.removeKeyboardLayoutAssociation(inputPort); } + + @Override + public void setStylusButtonMotionEventsEnabled(boolean enabled) { + mNative.setStylusButtonMotionEventsEnabled(enabled); + } } @Override diff --git a/services/core/java/com/android/server/input/NativeInputManagerService.java b/services/core/java/com/android/server/input/NativeInputManagerService.java index 157c957ee8173..6fca9cc4c590b 100644 --- a/services/core/java/com/android/server/input/NativeInputManagerService.java +++ b/services/core/java/com/android/server/input/NativeInputManagerService.java @@ -213,6 +213,9 @@ interface NativeInputManagerService { /** Get the bluetooth address of an input device if known, otherwise return null. */ String getBluetoothAddress(int deviceId); + /** Set whether stylus button reporting through motion events should be enabled. */ + void setStylusButtonMotionEventsEnabled(boolean enabled); + /** The native implementation of InputManagerService methods. */ class NativeImpl implements NativeInputManagerService { /** Pointer to native input manager service object, used by native code. */ @@ -439,5 +442,8 @@ interface NativeInputManagerService { @Override public native String getBluetoothAddress(int deviceId); + + @Override + public native void setStylusButtonMotionEventsEnabled(boolean enabled); } } diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index fe0fe29d7b50d..e1aa070ddc9a1 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -2577,6 +2577,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { mStylusButtonsDisabled = Settings.Secure.getIntForUser(resolver, Secure.STYLUS_BUTTONS_DISABLED, 0, UserHandle.USER_CURRENT) == 1; + mInputManagerInternal.setStylusButtonMotionEventsEnabled(!mStylusButtonsDisabled); } if (updateRotation) { updateRotation(true); diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp index d6cf4735e5853..40e74b1fe7d49 100644 --- a/services/core/jni/com_android_server_input_InputManagerService.cpp +++ b/services/core/jni/com_android_server_input_InputManagerService.cpp @@ -302,6 +302,7 @@ public: void setCustomPointerIcon(const SpriteIcon& icon); void setMotionClassifierEnabled(bool enabled); std::optional getBluetoothAddress(int32_t deviceId); + void setStylusButtonMotionEventsEnabled(bool enabled); /* --- InputReaderPolicyInterface implementation --- */ @@ -405,6 +406,9 @@ private: // Associated Pointer controller display. int32_t pointerDisplayId{ADISPLAY_ID_DEFAULT}; + + // True if stylus button reporting through motion events is enabled. + bool stylusButtonMotionEventsEnabled{true}; } mLocked GUARDED_BY(mLock); std::atomic mInteractive; @@ -654,6 +658,8 @@ void NativeInputManager::getReaderConfiguration(InputReaderConfiguration* outCon outConfig->defaultPointerDisplayId = mLocked.pointerDisplayId; outConfig->disabledDevices = mLocked.disabledInputDevices; + + outConfig->stylusButtonMotionEventsEnabled = mLocked.stylusButtonMotionEventsEnabled; } // release lock } @@ -1524,6 +1530,21 @@ std::optional NativeInputManager::getBluetoothAddress(int32_t devic return mInputManager->getReader().getBluetoothAddress(deviceId); } +void NativeInputManager::setStylusButtonMotionEventsEnabled(bool enabled) { + { // acquire lock + AutoMutex _l(mLock); + + if (mLocked.stylusButtonMotionEventsEnabled == enabled) { + return; + } + + mLocked.stylusButtonMotionEventsEnabled = enabled; + } // release lock + + mInputManager->getReader().requestRefreshConfiguration( + InputReaderConfiguration::CHANGE_STYLUS_BUTTON_REPORTING); +} + bool NativeInputManager::isPerDisplayTouchModeEnabled() { JNIEnv* env = jniEnv(); jboolean enabled = @@ -2393,6 +2414,12 @@ static jstring nativeGetBluetoothAddress(JNIEnv* env, jobject nativeImplObj, jin return address ? env->NewStringUTF(address->c_str()) : nullptr; } +static void nativeSetStylusButtonMotionEventsEnabled(JNIEnv* env, jobject nativeImplObj, + jboolean enabled) { + NativeInputManager* im = getNativeInputManager(env, nativeImplObj); + im->setStylusButtonMotionEventsEnabled(enabled); +} + // ---------------------------------------------------------------------------- static const JNINativeMethod gInputManagerMethods[] = { @@ -2479,6 +2506,8 @@ static const JNINativeMethod gInputManagerMethods[] = { {"cancelCurrentTouch", "()V", (void*)nativeCancelCurrentTouch}, {"setPointerDisplayId", "(I)V", (void*)nativeSetPointerDisplayId}, {"getBluetoothAddress", "(I)Ljava/lang/String;", (void*)nativeGetBluetoothAddress}, + {"setStylusButtonMotionEventsEnabled", "(Z)V", + (void*)nativeSetStylusButtonMotionEventsEnabled}, }; #define FIND_CLASS(var, className) \