Loading core/api/test-current.txt +4 −1 Original line number Diff line number Diff line Loading @@ -1497,10 +1497,13 @@ package android.hardware.input { method @RequiresPermission(android.Manifest.permission.SET_KEYBOARD_LAYOUT) public void removeKeyboardLayoutForInputDevice(@NonNull android.hardware.input.InputDeviceIdentifier, @NonNull String); method public void removeUniqueIdAssociation(@NonNull String); method @RequiresPermission(android.Manifest.permission.SET_KEYBOARD_LAYOUT) public void setCurrentKeyboardLayoutForInputDevice(@NonNull android.hardware.input.InputDeviceIdentifier, @NonNull String); method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setMaximumObscuringOpacityForTouch(@FloatRange(from=0, to=1) float); field public static final long BLOCK_UNTRUSTED_TOUCHES = 158002302L; // 0x96aec7eL } public class InputSettings { method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public static void setMaximumObscuringOpacityForTouch(@NonNull android.content.Context, @FloatRange(from=0, to=1) float); } } package android.hardware.lights { Loading core/java/android/hardware/input/InputManager.java +5 −321 Original line number Diff line number Diff line Loading @@ -51,11 +51,9 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceManager.ServiceNotFoundException; import android.os.SystemClock; import android.os.UserHandle; import android.os.VibrationEffect; import android.os.Vibrator; import android.os.VibratorManager; import android.provider.Settings; import android.util.Log; import android.util.SparseArray; import android.view.Display; Loading Loading @@ -214,30 +212,6 @@ public final class InputManager { public static final String META_DATA_KEYBOARD_LAYOUTS = "android.hardware.input.metadata.KEYBOARD_LAYOUTS"; /** * Pointer Speed: The minimum (slowest) pointer speed (-7). * @hide */ public static final int MIN_POINTER_SPEED = -7; /** * Pointer Speed: The maximum (fastest) pointer speed (7). * @hide */ public static final int MAX_POINTER_SPEED = 7; /** * Pointer Speed: The default pointer speed (0). * @hide */ public static final int DEFAULT_POINTER_SPEED = 0; /** * The maximum allowed obscuring opacity by UID to propagate touches (0 <= x <= 1). * @hide */ public static final float DEFAULT_MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH = .8f; /** * Prevent touches from being consumed by apps if these touches passed through a non-trusted * window from a different UID and are considered unsafe. Loading Loading @@ -1134,59 +1108,19 @@ public final class InputManager { } } /** * Gets the mouse pointer speed. * <p> * Only returns the permanent mouse pointer speed. Ignores any temporary pointer * speed set by {@link #tryPointerSpeed}. * </p> * * @param context The application context. * @return The pointer speed as a value between {@link #MIN_POINTER_SPEED} and * {@link #MAX_POINTER_SPEED}, or the default value {@link #DEFAULT_POINTER_SPEED}. * * @hide */ public int getPointerSpeed(Context context) { return Settings.System.getInt(context.getContentResolver(), Settings.System.POINTER_SPEED, DEFAULT_POINTER_SPEED); } /** * Sets the mouse pointer speed. * <p> * Requires {@link android.Manifest.permission#WRITE_SETTINGS}. * </p> * * @param context The application context. * @param speed The pointer speed as a value between {@link #MIN_POINTER_SPEED} and * {@link #MAX_POINTER_SPEED}, or the default value {@link #DEFAULT_POINTER_SPEED}. * * @hide */ @RequiresPermission(Manifest.permission.WRITE_SETTINGS) public void setPointerSpeed(Context context, int speed) { if (speed < MIN_POINTER_SPEED || speed > MAX_POINTER_SPEED) { throw new IllegalArgumentException("speed out of range"); } Settings.System.putInt(context.getContentResolver(), Settings.System.POINTER_SPEED, speed); } /** * Changes the mouse pointer speed temporarily, but does not save the setting. * <p> * Requires {@link android.Manifest.permission#SET_POINTER_SPEED}. * </p> * * @param speed The pointer speed as a value between {@link #MIN_POINTER_SPEED} and * {@link #MAX_POINTER_SPEED}, or the default value {@link #DEFAULT_POINTER_SPEED}. * @param speed The pointer speed as a value between {@link InputSettings#MIN_POINTER_SPEED} and * {@link InputSettings#MAX_POINTER_SPEED}, or the default value {@link InputSettings#DEFAULT_POINTER_SPEED}. * * @hide */ public void tryPointerSpeed(int speed) { if (speed < MIN_POINTER_SPEED || speed > MAX_POINTER_SPEED) { if (speed < InputSettings.MIN_POINTER_SPEED || speed > InputSettings.MAX_POINTER_SPEED) { throw new IllegalArgumentException("speed out of range"); } Loading @@ -1211,44 +1145,8 @@ public final class InputManager { */ @FloatRange(from = 0, to = 1) public float getMaximumObscuringOpacityForTouch() { return Settings.Global.getFloat(getContext().getContentResolver(), Settings.Global.MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH, DEFAULT_MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH); } /** * Sets the maximum allowed obscuring opacity by UID to propagate touches. * * <p>For certain window types (eg. SAWs), the decision of honoring {@link LayoutParams * #FLAG_NOT_TOUCHABLE} or not depends on the combined obscuring opacity of the windows * above the touch-consuming window. * * <p>For a certain UID: * <ul> * <li>If it's the same as the UID of the touch-consuming window, allow it to propagate * the touch. * <li>Otherwise take all its windows of eligible window types above the touch-consuming * window, compute their combined obscuring opacity considering that {@code * opacity(A, B) = 1 - (1 - opacity(A))*(1 - opacity(B))}. If the computed value is * lesser than or equal to this setting and there are no other windows preventing the * touch, allow the UID to propagate the touch. * </ul> * * <p>This value should be between 0 (inclusive) and 1 (inclusive). * * @see #getMaximumObscuringOpacityForTouch() * * @hide */ @TestApi @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS) public void setMaximumObscuringOpacityForTouch(@FloatRange(from = 0, to = 1) float opacity) { if (opacity < 0 || opacity > 1) { throw new IllegalArgumentException( "Maximum obscuring opacity for touch should be >= 0 and <= 1"); } Settings.Global.putFloat(getContext().getContentResolver(), Settings.Global.MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH, opacity); Context context = ActivityThread.currentApplication(); return InputSettings.getMaximumObscuringOpacityForTouch(context); } /** Loading Loading @@ -2144,26 +2042,6 @@ public final class InputManager { } } /** * Whether stylus has ever been used on device (false by default). * @hide */ public boolean isStylusEverUsed(@NonNull Context context) { return Settings.Global.getInt(context.getContentResolver(), Settings.Global.STYLUS_EVER_USED, 0) == 1; } /** * Set whether stylus has ever been used on device. * Should only ever be set to true once after stylus first usage. * @hide */ @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS) public void setStylusEverUsed(@NonNull Context context, boolean stylusEverUsed) { Settings.Global.putInt(context.getContentResolver(), Settings.Global.STYLUS_EVER_USED, stylusEverUsed ? 1 : 0); } /** * Whether there is a gesture-compatible touchpad connected to the device. * @hide Loading @@ -2173,200 +2051,6 @@ public final class InputManager { return true; } /** * Gets the touchpad pointer speed. * * The returned value only applies to gesture-compatible touchpads. * * @param context The application context. * @return The pointer speed as a value between {@link #MIN_POINTER_SPEED} and * {@link #MAX_POINTER_SPEED}, or the default value {@link #DEFAULT_POINTER_SPEED}. * * @hide */ public int getTouchpadPointerSpeed(@NonNull Context context) { return Settings.System.getIntForUser(context.getContentResolver(), Settings.System.TOUCHPAD_POINTER_SPEED, DEFAULT_POINTER_SPEED, UserHandle.USER_CURRENT); } /** * Sets the touchpad pointer speed, and saves it in the settings. * * The new speed will only apply to gesture-compatible touchpads. * * @param context The application context. * @param speed The pointer speed as a value between {@link #MIN_POINTER_SPEED} and * {@link #MAX_POINTER_SPEED}, or the default value {@link #DEFAULT_POINTER_SPEED}. * * @hide */ @RequiresPermission(Manifest.permission.WRITE_SETTINGS) public void setTouchpadPointerSpeed(@NonNull Context context, int speed) { if (speed < MIN_POINTER_SPEED || speed > MAX_POINTER_SPEED) { throw new IllegalArgumentException("speed out of range"); } Settings.System.putIntForUser(context.getContentResolver(), Settings.System.TOUCHPAD_POINTER_SPEED, speed, UserHandle.USER_CURRENT); } /** * Returns true if the touchpad should use pointer acceleration. * * The returned value only applies to gesture-compatible touchpads. * * @param context The application context. * @return Whether the touchpad should use pointer acceleration. * * @hide */ public boolean useTouchpadPointerAcceleration(@NonNull Context context) { // TODO: obtain the actual behavior from the settings return true; } /** * Sets the pointer acceleration behavior for the touchpad. * * The new behavior is only applied to gesture-compatible touchpads. * * @param context The application context. * @param enabled Will enable pointer acceleration if true, disable it if false * * @hide */ public void setTouchpadPointerAcceleration(@NonNull Context context, boolean enabled) { // TODO: set the right setting } /** * Returns true if moving two fingers upwards on the touchpad should * scroll down, which is known as natural scrolling. * * The returned value only applies to gesture-compatible touchpads. * * @param context The application context. * @return Whether the touchpad should use natural scrolling. * * @hide */ public boolean useTouchpadNaturalScrolling(@NonNull Context context) { return Settings.System.getIntForUser(context.getContentResolver(), Settings.System.TOUCHPAD_NATURAL_SCROLLING, 0, UserHandle.USER_CURRENT) == 1; } /** * Sets the natural scroll behavior for the touchpad. * * If natural scrolling is enabled, moving two fingers upwards on the * touchpad will scroll down. * * @param context The application context. * @param enabled Will enable natural scroll if true, disable it if false * * @hide */ @RequiresPermission(Manifest.permission.WRITE_SETTINGS) public void setTouchpadNaturalScrolling(@NonNull Context context, boolean enabled) { Settings.System.putIntForUser(context.getContentResolver(), Settings.System.TOUCHPAD_NATURAL_SCROLLING, enabled ? 1 : 0, UserHandle.USER_CURRENT); } /** * Returns true if the touchpad should use tap to click. * * The returned value only applies to gesture-compatible touchpads. * * @param context The application context. * @return Whether the touchpad should use tap to click. * * @hide */ public boolean useTouchpadTapToClick(@NonNull Context context) { return Settings.System.getIntForUser(context.getContentResolver(), Settings.System.TOUCHPAD_TAP_TO_CLICK, 0, UserHandle.USER_CURRENT) == 1; } /** * Sets the tap to click behavior for the touchpad. * * The new behavior is only applied to gesture-compatible touchpads. * * @param context The application context. * @param enabled Will enable tap to click if true, disable it if false * * @hide */ @RequiresPermission(Manifest.permission.WRITE_SETTINGS) public void setTouchpadTapToClick(@NonNull Context context, boolean enabled) { Settings.System.putIntForUser(context.getContentResolver(), Settings.System.TOUCHPAD_TAP_TO_CLICK, enabled ? 1 : 0, UserHandle.USER_CURRENT); } /** * Returns true if the touchpad should use tap dragging. * * The returned value only applies to gesture-compatible touchpads. * * @param context The application context. * @return Whether the touchpad should use tap dragging. * * @hide */ public boolean useTouchpadTapDragging(@NonNull Context context) { // TODO: obtain the actual behavior from the settings return true; } /** * Sets the tap dragging behavior for the touchpad. * * The new behavior is only applied to gesture-compatible touchpads. * * @param context The application context. * @param enabled Will enable tap dragging if true, disable it if false * * @hide */ public void setTouchpadTapDragging(@NonNull Context context, boolean enabled) { // TODO: set the right setting } /** * Returns true if the touchpad should use the right click zone. * * The returned value only applies to gesture-compatible touchpads. * * @param context The application context. * @return Whether the touchpad should use the right click zone. * * @hide */ public boolean useTouchpadRightClickZone(@NonNull Context context) { return Settings.System.getIntForUser(context.getContentResolver(), Settings.System.TOUCHPAD_RIGHT_CLICK_ZONE, 0, UserHandle.USER_CURRENT) == 1; } /** * Sets the right click zone behavior for the touchpad. * * The new behavior is only applied to gesture-compatible touchpads. * * @param context The application context. * @param enabled Will enable the right click zone if true, disable it if false * * @hide */ @RequiresPermission(Manifest.permission.WRITE_SETTINGS) public void setTouchpadRightClickZone(@NonNull Context context, boolean enabled) { Settings.System.putIntForUser(context.getContentResolver(), Settings.System.TOUCHPAD_RIGHT_CLICK_ZONE, enabled ? 1 : 0, UserHandle.USER_CURRENT); } /** * Registers a Keyboard backlight change listener to be notified about {@link * KeyboardBacklightState} changes for connected keyboard devices. Loading core/java/android/hardware/input/InputSettings.java 0 → 100644 +319 −0 File added.Preview size limit exceeded, changes collapsed. Show changes packages/SystemUI/src/com/android/systemui/stylus/StylusManager.kt +3 −2 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.bluetooth.BluetoothDevice import android.content.Context import android.hardware.BatteryState import android.hardware.input.InputManager import android.hardware.input.InputSettings import android.os.Handler import android.util.ArrayMap import android.util.Log Loading Loading @@ -235,9 +236,9 @@ constructor( */ private fun onStylusUsed() { if (!featureFlags.isEnabled(Flags.TRACK_STYLUS_EVER_USED)) return if (inputManager.isStylusEverUsed(context)) return if (InputSettings.isStylusEverUsed(context)) return inputManager.setStylusEverUsed(context, true) InputSettings.setStylusEverUsed(context, true) executeStylusCallbacks { cb -> cb.onStylusFirstUsed() } } Loading packages/SystemUI/tests/src/com/android/systemui/stylus/StylusManagerTest.kt +26 −9 Original line number Diff line number Diff line Loading @@ -19,10 +19,16 @@ import android.bluetooth.BluetoothAdapter import android.bluetooth.BluetoothDevice import android.hardware.BatteryState import android.hardware.input.InputManager import android.hardware.input.InputSettings import android.os.Handler import android.testing.AndroidTestingRunner import android.view.InputDevice import androidx.test.filters.SmallTest import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession import com.android.dx.mockito.inline.extended.ExtendedMockito.never import com.android.dx.mockito.inline.extended.ExtendedMockito.times import com.android.dx.mockito.inline.extended.ExtendedMockito.verify import com.android.dx.mockito.inline.extended.StaticMockitoSession import com.android.internal.logging.UiEventLogger import com.android.systemui.SysuiTestCase import com.android.systemui.flags.FeatureFlags Loading @@ -30,18 +36,17 @@ import com.android.systemui.flags.Flags import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.whenever import java.util.concurrent.Executor import org.junit.After import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.Mockito.clearInvocations import org.mockito.Mockito.inOrder import org.mockito.Mockito.never import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.Mockito.verifyNoMoreInteractions import org.mockito.Mockito.verifyZeroInteractions import org.mockito.MockitoAnnotations import org.mockito.quality.Strictness @RunWith(AndroidTestingRunner::class) @SmallTest Loading @@ -67,11 +72,17 @@ class StylusManagerTest : SysuiTestCase() { @Mock lateinit var otherStylusBatteryCallback: StylusManager.StylusBatteryCallback private lateinit var mockitoSession: StaticMockitoSession private lateinit var stylusManager: StylusManager @Before fun setUp() { MockitoAnnotations.initMocks(this) mockitoSession = mockitoSession() .mockStatic(InputSettings::class.java) .strictness(Strictness.LENIENT) .startMocking() whenever(handler.post(any())).thenAnswer { (it.arguments[0] as Runnable).run() Loading Loading @@ -103,19 +114,25 @@ class StylusManagerTest : SysuiTestCase() { whenever(inputManager.getInputDevice(STYLUS_DEVICE_ID)).thenReturn(stylusDevice) whenever(inputManager.getInputDevice(BT_STYLUS_DEVICE_ID)).thenReturn(btStylusDevice) whenever(inputManager.inputDeviceIds).thenReturn(intArrayOf(STYLUS_DEVICE_ID)) whenever(inputManager.isStylusEverUsed(mContext)).thenReturn(false) whenever(bluetoothAdapter.getRemoteDevice(STYLUS_BT_ADDRESS)).thenReturn(bluetoothDevice) whenever(bluetoothDevice.address).thenReturn(STYLUS_BT_ADDRESS) whenever(featureFlags.isEnabled(Flags.TRACK_STYLUS_EVER_USED)).thenReturn(true) whenever(InputSettings.isStylusEverUsed(mContext)).thenReturn(false) stylusManager.startListener() stylusManager.registerCallback(stylusCallback) stylusManager.registerBatteryCallback(stylusBatteryCallback) clearInvocations(inputManager) } @After fun tearDown() { mockitoSession.finishMocking() } @Test fun startListener_hasNotStarted_registersInputDeviceListener() { stylusManager = Loading Loading @@ -209,8 +226,7 @@ class StylusManagerTest : SysuiTestCase() { @Test fun onInputDeviceAdded_btStylus_firstUsed_setsFlag() { stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID) verify(inputManager, times(1)).setStylusEverUsed(mContext, true) verify({ InputSettings.setStylusEverUsed(mContext, true) }, times(1)) } @Test Loading Loading @@ -484,7 +500,7 @@ class StylusManagerTest : SysuiTestCase() { stylusManager.onBatteryStateChanged(STYLUS_DEVICE_ID, 1, batteryState) verify(inputManager).setStylusEverUsed(mContext, true) verify({ InputSettings.setStylusEverUsed(mContext, true) }, times(1)) } @Test Loading Loading @@ -539,12 +555,13 @@ class StylusManagerTest : SysuiTestCase() { @Test fun onBatteryStateChanged_batteryPresent_stylusUsed_doesNotUpdateEverUsedFlag() { whenever(inputManager.isStylusEverUsed(mContext)).thenReturn(true) whenever(InputSettings.isStylusEverUsed(mContext)).thenReturn(true) whenever(batteryState.isPresent).thenReturn(true) stylusManager.onBatteryStateChanged(STYLUS_DEVICE_ID, 1, batteryState) verify(inputManager, never()).setStylusEverUsed(mContext, true) verify({ InputSettings.setStylusEverUsed(mContext, true) }, never()) } @Test Loading Loading
core/api/test-current.txt +4 −1 Original line number Diff line number Diff line Loading @@ -1497,10 +1497,13 @@ package android.hardware.input { method @RequiresPermission(android.Manifest.permission.SET_KEYBOARD_LAYOUT) public void removeKeyboardLayoutForInputDevice(@NonNull android.hardware.input.InputDeviceIdentifier, @NonNull String); method public void removeUniqueIdAssociation(@NonNull String); method @RequiresPermission(android.Manifest.permission.SET_KEYBOARD_LAYOUT) public void setCurrentKeyboardLayoutForInputDevice(@NonNull android.hardware.input.InputDeviceIdentifier, @NonNull String); method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setMaximumObscuringOpacityForTouch(@FloatRange(from=0, to=1) float); field public static final long BLOCK_UNTRUSTED_TOUCHES = 158002302L; // 0x96aec7eL } public class InputSettings { method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public static void setMaximumObscuringOpacityForTouch(@NonNull android.content.Context, @FloatRange(from=0, to=1) float); } } package android.hardware.lights { Loading
core/java/android/hardware/input/InputManager.java +5 −321 Original line number Diff line number Diff line Loading @@ -51,11 +51,9 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceManager.ServiceNotFoundException; import android.os.SystemClock; import android.os.UserHandle; import android.os.VibrationEffect; import android.os.Vibrator; import android.os.VibratorManager; import android.provider.Settings; import android.util.Log; import android.util.SparseArray; import android.view.Display; Loading Loading @@ -214,30 +212,6 @@ public final class InputManager { public static final String META_DATA_KEYBOARD_LAYOUTS = "android.hardware.input.metadata.KEYBOARD_LAYOUTS"; /** * Pointer Speed: The minimum (slowest) pointer speed (-7). * @hide */ public static final int MIN_POINTER_SPEED = -7; /** * Pointer Speed: The maximum (fastest) pointer speed (7). * @hide */ public static final int MAX_POINTER_SPEED = 7; /** * Pointer Speed: The default pointer speed (0). * @hide */ public static final int DEFAULT_POINTER_SPEED = 0; /** * The maximum allowed obscuring opacity by UID to propagate touches (0 <= x <= 1). * @hide */ public static final float DEFAULT_MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH = .8f; /** * Prevent touches from being consumed by apps if these touches passed through a non-trusted * window from a different UID and are considered unsafe. Loading Loading @@ -1134,59 +1108,19 @@ public final class InputManager { } } /** * Gets the mouse pointer speed. * <p> * Only returns the permanent mouse pointer speed. Ignores any temporary pointer * speed set by {@link #tryPointerSpeed}. * </p> * * @param context The application context. * @return The pointer speed as a value between {@link #MIN_POINTER_SPEED} and * {@link #MAX_POINTER_SPEED}, or the default value {@link #DEFAULT_POINTER_SPEED}. * * @hide */ public int getPointerSpeed(Context context) { return Settings.System.getInt(context.getContentResolver(), Settings.System.POINTER_SPEED, DEFAULT_POINTER_SPEED); } /** * Sets the mouse pointer speed. * <p> * Requires {@link android.Manifest.permission#WRITE_SETTINGS}. * </p> * * @param context The application context. * @param speed The pointer speed as a value between {@link #MIN_POINTER_SPEED} and * {@link #MAX_POINTER_SPEED}, or the default value {@link #DEFAULT_POINTER_SPEED}. * * @hide */ @RequiresPermission(Manifest.permission.WRITE_SETTINGS) public void setPointerSpeed(Context context, int speed) { if (speed < MIN_POINTER_SPEED || speed > MAX_POINTER_SPEED) { throw new IllegalArgumentException("speed out of range"); } Settings.System.putInt(context.getContentResolver(), Settings.System.POINTER_SPEED, speed); } /** * Changes the mouse pointer speed temporarily, but does not save the setting. * <p> * Requires {@link android.Manifest.permission#SET_POINTER_SPEED}. * </p> * * @param speed The pointer speed as a value between {@link #MIN_POINTER_SPEED} and * {@link #MAX_POINTER_SPEED}, or the default value {@link #DEFAULT_POINTER_SPEED}. * @param speed The pointer speed as a value between {@link InputSettings#MIN_POINTER_SPEED} and * {@link InputSettings#MAX_POINTER_SPEED}, or the default value {@link InputSettings#DEFAULT_POINTER_SPEED}. * * @hide */ public void tryPointerSpeed(int speed) { if (speed < MIN_POINTER_SPEED || speed > MAX_POINTER_SPEED) { if (speed < InputSettings.MIN_POINTER_SPEED || speed > InputSettings.MAX_POINTER_SPEED) { throw new IllegalArgumentException("speed out of range"); } Loading @@ -1211,44 +1145,8 @@ public final class InputManager { */ @FloatRange(from = 0, to = 1) public float getMaximumObscuringOpacityForTouch() { return Settings.Global.getFloat(getContext().getContentResolver(), Settings.Global.MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH, DEFAULT_MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH); } /** * Sets the maximum allowed obscuring opacity by UID to propagate touches. * * <p>For certain window types (eg. SAWs), the decision of honoring {@link LayoutParams * #FLAG_NOT_TOUCHABLE} or not depends on the combined obscuring opacity of the windows * above the touch-consuming window. * * <p>For a certain UID: * <ul> * <li>If it's the same as the UID of the touch-consuming window, allow it to propagate * the touch. * <li>Otherwise take all its windows of eligible window types above the touch-consuming * window, compute their combined obscuring opacity considering that {@code * opacity(A, B) = 1 - (1 - opacity(A))*(1 - opacity(B))}. If the computed value is * lesser than or equal to this setting and there are no other windows preventing the * touch, allow the UID to propagate the touch. * </ul> * * <p>This value should be between 0 (inclusive) and 1 (inclusive). * * @see #getMaximumObscuringOpacityForTouch() * * @hide */ @TestApi @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS) public void setMaximumObscuringOpacityForTouch(@FloatRange(from = 0, to = 1) float opacity) { if (opacity < 0 || opacity > 1) { throw new IllegalArgumentException( "Maximum obscuring opacity for touch should be >= 0 and <= 1"); } Settings.Global.putFloat(getContext().getContentResolver(), Settings.Global.MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH, opacity); Context context = ActivityThread.currentApplication(); return InputSettings.getMaximumObscuringOpacityForTouch(context); } /** Loading Loading @@ -2144,26 +2042,6 @@ public final class InputManager { } } /** * Whether stylus has ever been used on device (false by default). * @hide */ public boolean isStylusEverUsed(@NonNull Context context) { return Settings.Global.getInt(context.getContentResolver(), Settings.Global.STYLUS_EVER_USED, 0) == 1; } /** * Set whether stylus has ever been used on device. * Should only ever be set to true once after stylus first usage. * @hide */ @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS) public void setStylusEverUsed(@NonNull Context context, boolean stylusEverUsed) { Settings.Global.putInt(context.getContentResolver(), Settings.Global.STYLUS_EVER_USED, stylusEverUsed ? 1 : 0); } /** * Whether there is a gesture-compatible touchpad connected to the device. * @hide Loading @@ -2173,200 +2051,6 @@ public final class InputManager { return true; } /** * Gets the touchpad pointer speed. * * The returned value only applies to gesture-compatible touchpads. * * @param context The application context. * @return The pointer speed as a value between {@link #MIN_POINTER_SPEED} and * {@link #MAX_POINTER_SPEED}, or the default value {@link #DEFAULT_POINTER_SPEED}. * * @hide */ public int getTouchpadPointerSpeed(@NonNull Context context) { return Settings.System.getIntForUser(context.getContentResolver(), Settings.System.TOUCHPAD_POINTER_SPEED, DEFAULT_POINTER_SPEED, UserHandle.USER_CURRENT); } /** * Sets the touchpad pointer speed, and saves it in the settings. * * The new speed will only apply to gesture-compatible touchpads. * * @param context The application context. * @param speed The pointer speed as a value between {@link #MIN_POINTER_SPEED} and * {@link #MAX_POINTER_SPEED}, or the default value {@link #DEFAULT_POINTER_SPEED}. * * @hide */ @RequiresPermission(Manifest.permission.WRITE_SETTINGS) public void setTouchpadPointerSpeed(@NonNull Context context, int speed) { if (speed < MIN_POINTER_SPEED || speed > MAX_POINTER_SPEED) { throw new IllegalArgumentException("speed out of range"); } Settings.System.putIntForUser(context.getContentResolver(), Settings.System.TOUCHPAD_POINTER_SPEED, speed, UserHandle.USER_CURRENT); } /** * Returns true if the touchpad should use pointer acceleration. * * The returned value only applies to gesture-compatible touchpads. * * @param context The application context. * @return Whether the touchpad should use pointer acceleration. * * @hide */ public boolean useTouchpadPointerAcceleration(@NonNull Context context) { // TODO: obtain the actual behavior from the settings return true; } /** * Sets the pointer acceleration behavior for the touchpad. * * The new behavior is only applied to gesture-compatible touchpads. * * @param context The application context. * @param enabled Will enable pointer acceleration if true, disable it if false * * @hide */ public void setTouchpadPointerAcceleration(@NonNull Context context, boolean enabled) { // TODO: set the right setting } /** * Returns true if moving two fingers upwards on the touchpad should * scroll down, which is known as natural scrolling. * * The returned value only applies to gesture-compatible touchpads. * * @param context The application context. * @return Whether the touchpad should use natural scrolling. * * @hide */ public boolean useTouchpadNaturalScrolling(@NonNull Context context) { return Settings.System.getIntForUser(context.getContentResolver(), Settings.System.TOUCHPAD_NATURAL_SCROLLING, 0, UserHandle.USER_CURRENT) == 1; } /** * Sets the natural scroll behavior for the touchpad. * * If natural scrolling is enabled, moving two fingers upwards on the * touchpad will scroll down. * * @param context The application context. * @param enabled Will enable natural scroll if true, disable it if false * * @hide */ @RequiresPermission(Manifest.permission.WRITE_SETTINGS) public void setTouchpadNaturalScrolling(@NonNull Context context, boolean enabled) { Settings.System.putIntForUser(context.getContentResolver(), Settings.System.TOUCHPAD_NATURAL_SCROLLING, enabled ? 1 : 0, UserHandle.USER_CURRENT); } /** * Returns true if the touchpad should use tap to click. * * The returned value only applies to gesture-compatible touchpads. * * @param context The application context. * @return Whether the touchpad should use tap to click. * * @hide */ public boolean useTouchpadTapToClick(@NonNull Context context) { return Settings.System.getIntForUser(context.getContentResolver(), Settings.System.TOUCHPAD_TAP_TO_CLICK, 0, UserHandle.USER_CURRENT) == 1; } /** * Sets the tap to click behavior for the touchpad. * * The new behavior is only applied to gesture-compatible touchpads. * * @param context The application context. * @param enabled Will enable tap to click if true, disable it if false * * @hide */ @RequiresPermission(Manifest.permission.WRITE_SETTINGS) public void setTouchpadTapToClick(@NonNull Context context, boolean enabled) { Settings.System.putIntForUser(context.getContentResolver(), Settings.System.TOUCHPAD_TAP_TO_CLICK, enabled ? 1 : 0, UserHandle.USER_CURRENT); } /** * Returns true if the touchpad should use tap dragging. * * The returned value only applies to gesture-compatible touchpads. * * @param context The application context. * @return Whether the touchpad should use tap dragging. * * @hide */ public boolean useTouchpadTapDragging(@NonNull Context context) { // TODO: obtain the actual behavior from the settings return true; } /** * Sets the tap dragging behavior for the touchpad. * * The new behavior is only applied to gesture-compatible touchpads. * * @param context The application context. * @param enabled Will enable tap dragging if true, disable it if false * * @hide */ public void setTouchpadTapDragging(@NonNull Context context, boolean enabled) { // TODO: set the right setting } /** * Returns true if the touchpad should use the right click zone. * * The returned value only applies to gesture-compatible touchpads. * * @param context The application context. * @return Whether the touchpad should use the right click zone. * * @hide */ public boolean useTouchpadRightClickZone(@NonNull Context context) { return Settings.System.getIntForUser(context.getContentResolver(), Settings.System.TOUCHPAD_RIGHT_CLICK_ZONE, 0, UserHandle.USER_CURRENT) == 1; } /** * Sets the right click zone behavior for the touchpad. * * The new behavior is only applied to gesture-compatible touchpads. * * @param context The application context. * @param enabled Will enable the right click zone if true, disable it if false * * @hide */ @RequiresPermission(Manifest.permission.WRITE_SETTINGS) public void setTouchpadRightClickZone(@NonNull Context context, boolean enabled) { Settings.System.putIntForUser(context.getContentResolver(), Settings.System.TOUCHPAD_RIGHT_CLICK_ZONE, enabled ? 1 : 0, UserHandle.USER_CURRENT); } /** * Registers a Keyboard backlight change listener to be notified about {@link * KeyboardBacklightState} changes for connected keyboard devices. Loading
core/java/android/hardware/input/InputSettings.java 0 → 100644 +319 −0 File added.Preview size limit exceeded, changes collapsed. Show changes
packages/SystemUI/src/com/android/systemui/stylus/StylusManager.kt +3 −2 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.bluetooth.BluetoothDevice import android.content.Context import android.hardware.BatteryState import android.hardware.input.InputManager import android.hardware.input.InputSettings import android.os.Handler import android.util.ArrayMap import android.util.Log Loading Loading @@ -235,9 +236,9 @@ constructor( */ private fun onStylusUsed() { if (!featureFlags.isEnabled(Flags.TRACK_STYLUS_EVER_USED)) return if (inputManager.isStylusEverUsed(context)) return if (InputSettings.isStylusEverUsed(context)) return inputManager.setStylusEverUsed(context, true) InputSettings.setStylusEverUsed(context, true) executeStylusCallbacks { cb -> cb.onStylusFirstUsed() } } Loading
packages/SystemUI/tests/src/com/android/systemui/stylus/StylusManagerTest.kt +26 −9 Original line number Diff line number Diff line Loading @@ -19,10 +19,16 @@ import android.bluetooth.BluetoothAdapter import android.bluetooth.BluetoothDevice import android.hardware.BatteryState import android.hardware.input.InputManager import android.hardware.input.InputSettings import android.os.Handler import android.testing.AndroidTestingRunner import android.view.InputDevice import androidx.test.filters.SmallTest import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession import com.android.dx.mockito.inline.extended.ExtendedMockito.never import com.android.dx.mockito.inline.extended.ExtendedMockito.times import com.android.dx.mockito.inline.extended.ExtendedMockito.verify import com.android.dx.mockito.inline.extended.StaticMockitoSession import com.android.internal.logging.UiEventLogger import com.android.systemui.SysuiTestCase import com.android.systemui.flags.FeatureFlags Loading @@ -30,18 +36,17 @@ import com.android.systemui.flags.Flags import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.whenever import java.util.concurrent.Executor import org.junit.After import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.Mockito.clearInvocations import org.mockito.Mockito.inOrder import org.mockito.Mockito.never import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.Mockito.verifyNoMoreInteractions import org.mockito.Mockito.verifyZeroInteractions import org.mockito.MockitoAnnotations import org.mockito.quality.Strictness @RunWith(AndroidTestingRunner::class) @SmallTest Loading @@ -67,11 +72,17 @@ class StylusManagerTest : SysuiTestCase() { @Mock lateinit var otherStylusBatteryCallback: StylusManager.StylusBatteryCallback private lateinit var mockitoSession: StaticMockitoSession private lateinit var stylusManager: StylusManager @Before fun setUp() { MockitoAnnotations.initMocks(this) mockitoSession = mockitoSession() .mockStatic(InputSettings::class.java) .strictness(Strictness.LENIENT) .startMocking() whenever(handler.post(any())).thenAnswer { (it.arguments[0] as Runnable).run() Loading Loading @@ -103,19 +114,25 @@ class StylusManagerTest : SysuiTestCase() { whenever(inputManager.getInputDevice(STYLUS_DEVICE_ID)).thenReturn(stylusDevice) whenever(inputManager.getInputDevice(BT_STYLUS_DEVICE_ID)).thenReturn(btStylusDevice) whenever(inputManager.inputDeviceIds).thenReturn(intArrayOf(STYLUS_DEVICE_ID)) whenever(inputManager.isStylusEverUsed(mContext)).thenReturn(false) whenever(bluetoothAdapter.getRemoteDevice(STYLUS_BT_ADDRESS)).thenReturn(bluetoothDevice) whenever(bluetoothDevice.address).thenReturn(STYLUS_BT_ADDRESS) whenever(featureFlags.isEnabled(Flags.TRACK_STYLUS_EVER_USED)).thenReturn(true) whenever(InputSettings.isStylusEverUsed(mContext)).thenReturn(false) stylusManager.startListener() stylusManager.registerCallback(stylusCallback) stylusManager.registerBatteryCallback(stylusBatteryCallback) clearInvocations(inputManager) } @After fun tearDown() { mockitoSession.finishMocking() } @Test fun startListener_hasNotStarted_registersInputDeviceListener() { stylusManager = Loading Loading @@ -209,8 +226,7 @@ class StylusManagerTest : SysuiTestCase() { @Test fun onInputDeviceAdded_btStylus_firstUsed_setsFlag() { stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID) verify(inputManager, times(1)).setStylusEverUsed(mContext, true) verify({ InputSettings.setStylusEverUsed(mContext, true) }, times(1)) } @Test Loading Loading @@ -484,7 +500,7 @@ class StylusManagerTest : SysuiTestCase() { stylusManager.onBatteryStateChanged(STYLUS_DEVICE_ID, 1, batteryState) verify(inputManager).setStylusEverUsed(mContext, true) verify({ InputSettings.setStylusEverUsed(mContext, true) }, times(1)) } @Test Loading Loading @@ -539,12 +555,13 @@ class StylusManagerTest : SysuiTestCase() { @Test fun onBatteryStateChanged_batteryPresent_stylusUsed_doesNotUpdateEverUsedFlag() { whenever(inputManager.isStylusEverUsed(mContext)).thenReturn(true) whenever(InputSettings.isStylusEverUsed(mContext)).thenReturn(true) whenever(batteryState.isPresent).thenReturn(true) stylusManager.onBatteryStateChanged(STYLUS_DEVICE_ID, 1, batteryState) verify(inputManager, never()).setStylusEverUsed(mContext, true) verify({ InputSettings.setStylusEverUsed(mContext, true) }, never()) } @Test Loading