Remove InputManager#getInstance
Replace all instances of InputManager with instances of InputManagerGlobal. Add the context field in InputManager. All methods previously accessed through instances of InputManager have been refactored to be accessed through InputManagerGlobal, which is a singleton class. The SystemServiceRegistry no longer returns an instance of InputManager. Bug: b/267758905 Test: Pre-submit Change-Id: I2f3db1f5f4e27be9eb11d0d307aaee16a33f014d
This commit is contained in:
@@ -506,10 +506,10 @@ public final class SystemServiceRegistry {
|
||||
|
||||
// InputManager stores its own static instance for historical purposes.
|
||||
registerService(Context.INPUT_SERVICE, InputManager.class,
|
||||
new ServiceFetcher<InputManager>() {
|
||||
new CachedServiceFetcher<InputManager>() {
|
||||
@Override
|
||||
public InputManager getService(ContextImpl ctx) {
|
||||
return InputManager.getInstance(ctx.getOuterContext());
|
||||
public InputManager createService(ContextImpl ctx) {
|
||||
return new InputManager(ctx.getOuterContext());
|
||||
}});
|
||||
|
||||
registerService(Context.DISPLAY_SERVICE, DisplayManager.class,
|
||||
|
||||
@@ -53,11 +53,8 @@ import android.view.WindowManager.LayoutParams;
|
||||
import android.view.inputmethod.InputMethodInfo;
|
||||
import android.view.inputmethod.InputMethodSubtype;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -73,19 +70,9 @@ public final class InputManager {
|
||||
// To enable these logs, run: 'adb shell setprop log.tag.InputManager DEBUG' (requires restart)
|
||||
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||||
|
||||
private static InputManager sInstance;
|
||||
|
||||
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
|
||||
private final IInputManager mIm;
|
||||
|
||||
/**
|
||||
* We hold a weak reference to the context to avoid leaking it indefinitely,
|
||||
* since we currently store the input manager instance as a static variable that
|
||||
* will outlive any context.
|
||||
*/
|
||||
@Nullable
|
||||
private WeakReference<Context> mWeakContext;
|
||||
|
||||
/**
|
||||
* Whether a PointerIcon is shown for stylus pointers.
|
||||
* Obtain using {@link #isStylusPointerIconEnabled()}.
|
||||
@@ -255,99 +242,43 @@ public final class InputManager {
|
||||
*/
|
||||
public static final int SWITCH_STATE_ON = 1;
|
||||
|
||||
private static String sVelocityTrackerStrategy;
|
||||
private final InputManagerGlobal mGlobal;
|
||||
private final Context mContext;
|
||||
|
||||
private InputManagerGlobal mGlobal;
|
||||
|
||||
private InputManager() {
|
||||
/** @hide */
|
||||
public InputManager(Context context) {
|
||||
mGlobal = InputManagerGlobal.getInstance();
|
||||
mIm = mGlobal.getInputManagerService();
|
||||
try {
|
||||
sVelocityTrackerStrategy = mIm.getVelocityTrackerStrategy();
|
||||
} catch (RemoteException ex) {
|
||||
Log.w(TAG, "Could not get VelocityTracker strategy: " + ex);
|
||||
}
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an instance of the input manager.
|
||||
*
|
||||
* @return The input manager instance.
|
||||
* Warning: The usage of this method is not supported!
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public static InputManager resetInstance(IInputManager inputManagerService) {
|
||||
synchronized (InputManager.class) {
|
||||
InputManagerGlobal.resetInstance(inputManagerService);
|
||||
sInstance = new InputManager();
|
||||
return sInstance;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the instance of the input manager.
|
||||
* @return The input manager instance.
|
||||
* Use {@link Context#getSystemService(Class)}
|
||||
* to obtain the InputManager instance.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public static void clearInstance() {
|
||||
synchronized (InputManager.class) {
|
||||
InputManagerGlobal.clearInstance();
|
||||
sInstance = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an instance of the input manager.
|
||||
* TODO (b/277717573): Soft remove this API in version V.
|
||||
* TODO (b/277039664): Migrate app usage off this API.
|
||||
*
|
||||
* @return The input manager instance.
|
||||
* @deprecated Use {@link Context#getSystemService(Class)} or {@link #getInstance(Context)}
|
||||
* to obtain the InputManager instance.
|
||||
* @hide
|
||||
*/
|
||||
@Deprecated
|
||||
@UnsupportedAppUsage
|
||||
public static InputManager getInstance() {
|
||||
return getInstance(ActivityThread.currentApplication());
|
||||
return Objects.requireNonNull(ActivityThread.currentApplication())
|
||||
.getSystemService(InputManager.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an instance of the input manager.
|
||||
*
|
||||
* @return The input manager instance.
|
||||
* @hide
|
||||
*/
|
||||
public static InputManager getInstance(Context context) {
|
||||
synchronized (InputManager.class) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new InputManager();
|
||||
}
|
||||
if (sInstance.mWeakContext == null || sInstance.mWeakContext.get() == null) {
|
||||
sInstance.mWeakContext = new WeakReference(context);
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private Context getContext() {
|
||||
WeakReference<Context> weakContext = Objects.requireNonNull(mWeakContext,
|
||||
"A context is required for InputManager. Get the InputManager instance using "
|
||||
+ "Context#getSystemService before calling this method.");
|
||||
// If we get at this point, an app calling this function could potentially expect a
|
||||
// Context that has disappeared due to garbage collection. Holding a weak reference
|
||||
// is a temporary solution that should be resolved before the release of a
|
||||
// production version. This is being tracked in b/267758905
|
||||
return Objects.requireNonNull(weakContext.get(), "missing Context");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current VelocityTracker strategy. Only works when the system has fully booted up.
|
||||
* Get the current VelocityTracker strategy.
|
||||
* @hide
|
||||
*/
|
||||
public String getVelocityTrackerStrategy() {
|
||||
return sVelocityTrackerStrategy;
|
||||
return mGlobal.getVelocityTrackerStrategy();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -584,11 +515,7 @@ public final class InputManager {
|
||||
@NonNull
|
||||
public KeyboardLayout[] getKeyboardLayoutsForInputDevice(
|
||||
@NonNull InputDeviceIdentifier identifier) {
|
||||
try {
|
||||
return mIm.getKeyboardLayoutsForInputDevice(identifier);
|
||||
} catch (RemoteException ex) {
|
||||
throw ex.rethrowFromSystemServer();
|
||||
}
|
||||
return mGlobal.getKeyboardLayoutsForInputDevice(identifier);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -647,19 +574,8 @@ public final class InputManager {
|
||||
@RequiresPermission(Manifest.permission.SET_KEYBOARD_LAYOUT)
|
||||
public void setCurrentKeyboardLayoutForInputDevice(@NonNull InputDeviceIdentifier identifier,
|
||||
@NonNull String keyboardLayoutDescriptor) {
|
||||
if (identifier == null) {
|
||||
throw new IllegalArgumentException("identifier must not be null");
|
||||
}
|
||||
if (keyboardLayoutDescriptor == null) {
|
||||
throw new IllegalArgumentException("keyboardLayoutDescriptor must not be null");
|
||||
}
|
||||
|
||||
try {
|
||||
mIm.setCurrentKeyboardLayoutForInputDevice(identifier,
|
||||
keyboardLayoutDescriptor);
|
||||
} catch (RemoteException ex) {
|
||||
throw ex.rethrowFromSystemServer();
|
||||
}
|
||||
mGlobal.setCurrentKeyboardLayoutForInputDevice(identifier,
|
||||
keyboardLayoutDescriptor);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -956,8 +872,7 @@ public final class InputManager {
|
||||
*/
|
||||
@FloatRange(from = 0, to = 1)
|
||||
public float getMaximumObscuringOpacityForTouch() {
|
||||
Context context = ActivityThread.currentApplication();
|
||||
return InputSettings.getMaximumObscuringOpacityForTouch(context);
|
||||
return InputSettings.getMaximumObscuringOpacityForTouch(mContext);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1123,7 +1038,7 @@ public final class InputManager {
|
||||
*/
|
||||
public boolean isStylusPointerIconEnabled() {
|
||||
if (mIsStylusPointerIconEnabled == null) {
|
||||
mIsStylusPointerIconEnabled = getContext().getResources()
|
||||
mIsStylusPointerIconEnabled = mContext.getResources()
|
||||
.getBoolean(com.android.internal.R.bool.config_enableStylusPointerIcon)
|
||||
|| InputProperties.force_enable_stylus_pointer_icon().orElse(false);
|
||||
}
|
||||
|
||||
@@ -102,17 +102,26 @@ public final class InputManagerGlobal {
|
||||
|
||||
private static InputManagerGlobal sInstance;
|
||||
|
||||
private final String mVelocityTrackerStrategy;
|
||||
|
||||
private final IInputManager mIm;
|
||||
|
||||
public InputManagerGlobal(IInputManager im) {
|
||||
mIm = im;
|
||||
String strategy = null;
|
||||
try {
|
||||
strategy = mIm.getVelocityTrackerStrategy();
|
||||
} catch (RemoteException ex) {
|
||||
Log.w(TAG, "Could not get VelocityTracker strategy: " + ex);
|
||||
}
|
||||
mVelocityTrackerStrategy = strategy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an instance of the input manager global singleton.
|
||||
*
|
||||
* @return The display manager instance, may be null early in system startup
|
||||
* before the display manager has been fully initialized.
|
||||
* @return The input manager instance, may be null early in system startup
|
||||
* before the input manager has been fully initialized.
|
||||
*/
|
||||
public static InputManagerGlobal getInstance() {
|
||||
synchronized (InputManagerGlobal.class) {
|
||||
@@ -151,6 +160,14 @@ public final class InputManagerGlobal {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current VelocityTracker strategy.
|
||||
* Only works when the system has fully booted up.
|
||||
*/
|
||||
public String getVelocityTrackerStrategy() {
|
||||
return mVelocityTrackerStrategy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see InputManager#getInputDevice(int)
|
||||
*/
|
||||
@@ -309,9 +326,7 @@ public final class InputManagerGlobal {
|
||||
* @see InputManager#registerInputDeviceListener
|
||||
*/
|
||||
public void registerInputDeviceListener(InputDeviceListener listener, Handler handler) {
|
||||
if (listener == null) {
|
||||
throw new IllegalArgumentException("listener must not be null");
|
||||
}
|
||||
Objects.requireNonNull(listener, "listener must not be null");
|
||||
|
||||
synchronized (mInputDeviceListeners) {
|
||||
populateInputDevicesLocked();
|
||||
@@ -407,9 +422,7 @@ public final class InputManagerGlobal {
|
||||
* @see InputManager#getInputDeviceByDescriptor
|
||||
*/
|
||||
InputDevice getInputDeviceByDescriptor(String descriptor) {
|
||||
if (descriptor == null) {
|
||||
throw new IllegalArgumentException("descriptor must not be null.");
|
||||
}
|
||||
Objects.requireNonNull(descriptor, "descriptor must not be null.");
|
||||
|
||||
synchronized (mInputDeviceListeners) {
|
||||
populateInputDevicesLocked();
|
||||
@@ -526,9 +539,8 @@ public final class InputManagerGlobal {
|
||||
*/
|
||||
void registerOnTabletModeChangedListener(
|
||||
OnTabletModeChangedListener listener, Handler handler) {
|
||||
if (listener == null) {
|
||||
throw new IllegalArgumentException("listener must not be null");
|
||||
}
|
||||
Objects.requireNonNull(listener, "listener must not be null");
|
||||
|
||||
synchronized (mOnTabletModeChangedListeners) {
|
||||
if (mOnTabletModeChangedListeners == null) {
|
||||
initializeTabletModeListenerLocked();
|
||||
@@ -546,9 +558,8 @@ public final class InputManagerGlobal {
|
||||
* @see InputManager#unregisterOnTabletModeChangedListener(OnTabletModeChangedListener)
|
||||
*/
|
||||
void unregisterOnTabletModeChangedListener(OnTabletModeChangedListener listener) {
|
||||
if (listener == null) {
|
||||
throw new IllegalArgumentException("listener must not be null");
|
||||
}
|
||||
Objects.requireNonNull(listener, "listener must not be null");
|
||||
|
||||
synchronized (mOnTabletModeChangedListeners) {
|
||||
int idx = findOnTabletModeChangedListenerLocked(listener);
|
||||
if (idx >= 0) {
|
||||
@@ -603,7 +614,7 @@ public final class InputManagerGlobal {
|
||||
/**
|
||||
* @see InputManager#addInputDeviceBatteryListener(int, Executor, InputDeviceBatteryListener)
|
||||
*/
|
||||
void addInputDeviceBatteryListener(int deviceId, @NonNull Executor executor,
|
||||
public void addInputDeviceBatteryListener(int deviceId, @NonNull Executor executor,
|
||||
@NonNull InputDeviceBatteryListener listener) {
|
||||
Objects.requireNonNull(executor, "executor should not be null");
|
||||
Objects.requireNonNull(listener, "listener should not be null");
|
||||
@@ -714,7 +725,7 @@ public final class InputManagerGlobal {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see InputManager#getInputDeviceBatteryState(int, boolean)
|
||||
* @see #getInputDeviceBatteryState(int, boolean)
|
||||
*/
|
||||
@NonNull
|
||||
public BatteryState getInputDeviceBatteryState(int deviceId, boolean hasBattery) {
|
||||
@@ -876,6 +887,38 @@ public final class InputManagerGlobal {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see InputManager#getKeyboardLayoutsForInputDevice(InputDeviceIdentifier)
|
||||
*/
|
||||
@NonNull
|
||||
public KeyboardLayout[] getKeyboardLayoutsForInputDevice(
|
||||
@NonNull InputDeviceIdentifier identifier) {
|
||||
try {
|
||||
return mIm.getKeyboardLayoutsForInputDevice(identifier);
|
||||
} catch (RemoteException ex) {
|
||||
throw ex.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see InputManager#setCurrentKeyboardLayoutForInputDevice
|
||||
* (InputDeviceIdentifier, String)
|
||||
*/
|
||||
@RequiresPermission(Manifest.permission.SET_KEYBOARD_LAYOUT)
|
||||
public void setCurrentKeyboardLayoutForInputDevice(
|
||||
@NonNull InputDeviceIdentifier identifier,
|
||||
@NonNull String keyboardLayoutDescriptor) {
|
||||
Objects.requireNonNull(identifier, "identifier must not be null");
|
||||
Objects.requireNonNull(keyboardLayoutDescriptor,
|
||||
"keyboardLayoutDescriptor must not be null");
|
||||
try {
|
||||
mIm.setCurrentKeyboardLayoutForInputDevice(identifier,
|
||||
keyboardLayoutDescriptor);
|
||||
} catch (RemoteException ex) {
|
||||
throw ex.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see InputDevice#getSensorManager()
|
||||
*/
|
||||
@@ -1162,9 +1205,8 @@ public final class InputManagerGlobal {
|
||||
*/
|
||||
|
||||
public boolean injectInputEvent(InputEvent event, int mode, int targetUid) {
|
||||
if (event == null) {
|
||||
throw new IllegalArgumentException("event must not be null");
|
||||
}
|
||||
Objects.requireNonNull(event , "event must not be null");
|
||||
|
||||
if (mode != InputEventInjectionSync.NONE
|
||||
&& mode != InputEventInjectionSync.WAIT_FOR_FINISHED
|
||||
&& mode != InputEventInjectionSync.WAIT_FOR_RESULT) {
|
||||
|
||||
@@ -18,7 +18,7 @@ package android.view;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.hardware.input.InputManager;
|
||||
import android.hardware.input.InputManagerGlobal;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Pools.SynchronizedPool;
|
||||
|
||||
@@ -286,7 +286,8 @@ public final class VelocityTracker {
|
||||
private VelocityTracker(@VelocityTrackerStrategy int strategy) {
|
||||
// If user has not selected a specific strategy
|
||||
if (strategy == VELOCITY_TRACKER_STRATEGY_DEFAULT) {
|
||||
final String strategyProperty = InputManager.getInstance().getVelocityTrackerStrategy();
|
||||
final String strategyProperty = InputManagerGlobal.getInstance()
|
||||
.getVelocityTrackerStrategy();
|
||||
// Check if user specified strategy by overriding system property.
|
||||
if (strategyProperty == null || strategyProperty.isEmpty()) {
|
||||
mStrategy = strategy;
|
||||
|
||||
@@ -15,11 +15,14 @@
|
||||
*/
|
||||
package android.hardware.input
|
||||
|
||||
import android.content.Context
|
||||
import android.content.ContextWrapper
|
||||
import android.hardware.BatteryState
|
||||
import android.os.Handler
|
||||
import android.os.HandlerExecutor
|
||||
import android.os.test.TestLooper
|
||||
import android.platform.test.annotations.Presubmit
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import com.android.server.testutils.any
|
||||
import java.util.concurrent.Executor
|
||||
import kotlin.test.assertEquals
|
||||
@@ -32,8 +35,10 @@ import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito
|
||||
import org.mockito.Mockito.anyInt
|
||||
import org.mockito.Mockito.doAnswer
|
||||
import org.mockito.Mockito.`when`
|
||||
import org.mockito.junit.MockitoJUnit
|
||||
import org.mockito.junit.MockitoJUnitRunner
|
||||
|
||||
@@ -53,6 +58,7 @@ class InputDeviceBatteryListenerTest {
|
||||
private var registeredListener: IInputDeviceBatteryListener? = null
|
||||
private val monitoredDevices = mutableListOf<Int>()
|
||||
private lateinit var executor: Executor
|
||||
private lateinit var context: Context
|
||||
private lateinit var inputManager: InputManager
|
||||
|
||||
@Mock
|
||||
@@ -60,11 +66,15 @@ class InputDeviceBatteryListenerTest {
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
context = Mockito.spy(ContextWrapper(ApplicationProvider.getApplicationContext()))
|
||||
testLooper = TestLooper()
|
||||
executor = HandlerExecutor(Handler(testLooper.looper))
|
||||
registeredListener = null
|
||||
monitoredDevices.clear()
|
||||
inputManager = InputManager.resetInstance(iInputManagerMock)
|
||||
InputManagerGlobal.resetInstance(iInputManagerMock)
|
||||
inputManager = InputManager(context)
|
||||
`when`(context.getSystemService(Mockito.eq(Context.INPUT_SERVICE)))
|
||||
.thenReturn(inputManager)
|
||||
|
||||
// Handle battery listener registration.
|
||||
doAnswer {
|
||||
@@ -102,7 +112,7 @@ class InputDeviceBatteryListenerTest {
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
InputManager.clearInstance()
|
||||
InputManagerGlobal.clearInstance()
|
||||
}
|
||||
|
||||
private fun notifyBatteryStateChanged(
|
||||
|
||||
@@ -28,9 +28,12 @@ import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
import android.hardware.lights.Light;
|
||||
import android.hardware.lights.LightState;
|
||||
import android.hardware.lights.LightsManager;
|
||||
@@ -40,6 +43,8 @@ import android.platform.test.annotations.Presubmit;
|
||||
import android.util.ArrayMap;
|
||||
import android.view.InputDevice;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
@@ -76,12 +81,15 @@ public class InputDeviceLightsManagerTest {
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
final Context context = spy(new ContextWrapper(InstrumentationRegistry.getContext()));
|
||||
when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{DEVICE_ID});
|
||||
|
||||
when(mIInputManagerMock.getInputDevice(eq(DEVICE_ID))).thenReturn(
|
||||
createInputDevice(DEVICE_ID));
|
||||
|
||||
mInputManager = InputManager.resetInstance(mIInputManagerMock);
|
||||
InputManagerGlobal.resetInstance(mIInputManagerMock);
|
||||
mInputManager = new InputManager(context);
|
||||
when(context.getSystemService(eq(Context.INPUT_SERVICE))).thenReturn(mInputManager);
|
||||
|
||||
ArrayMap<Integer, LightState> lightStatesById = new ArrayMap<>();
|
||||
doAnswer(invocation -> {
|
||||
@@ -106,7 +114,7 @@ public class InputDeviceLightsManagerTest {
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
InputManager.clearInstance();
|
||||
InputManagerGlobal.clearInstance();
|
||||
}
|
||||
|
||||
private InputDevice createInputDevice(int id) {
|
||||
|
||||
@@ -81,9 +81,9 @@ public class InputDeviceSensorManagerTest {
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
final Context context = spy(new ContextWrapper(InstrumentationRegistry.getContext()));
|
||||
InputManager inputManager = InputManager.resetInstance(mIInputManagerMock);
|
||||
|
||||
when(context.getSystemService(eq(Context.INPUT_SERVICE))).thenReturn(inputManager);
|
||||
InputManagerGlobal.resetInstance(mIInputManagerMock);
|
||||
mInputManager = new InputManager(context);
|
||||
when(context.getSystemService(eq(Context.INPUT_SERVICE))).thenReturn(mInputManager);
|
||||
|
||||
when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[]{DEVICE_ID});
|
||||
|
||||
@@ -98,13 +98,11 @@ public class InputDeviceSensorManagerTest {
|
||||
.thenReturn(true);
|
||||
|
||||
when(mIInputManagerMock.registerSensorListener(any())).thenReturn(true);
|
||||
|
||||
mInputManager = context.getSystemService(InputManager.class);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
InputManager.clearInstance();
|
||||
InputManagerGlobal.clearInstance();
|
||||
}
|
||||
|
||||
private class InputTestSensorEventListener implements SensorEventListener {
|
||||
|
||||
@@ -15,11 +15,14 @@
|
||||
*/
|
||||
package android.hardware.input
|
||||
|
||||
import android.content.Context
|
||||
import android.content.ContextWrapper
|
||||
import android.content.res.Resources
|
||||
import android.platform.test.annotations.Presubmit
|
||||
import android.view.Display
|
||||
import android.view.DisplayInfo
|
||||
import android.view.InputDevice
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import org.junit.After
|
||||
import org.junit.Assert.assertNotNull
|
||||
import org.junit.Assert.assertEquals
|
||||
@@ -28,6 +31,7 @@ import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito
|
||||
import org.mockito.Mockito.eq
|
||||
import org.mockito.Mockito.`when`
|
||||
import org.mockito.junit.MockitoJUnit
|
||||
@@ -52,17 +56,20 @@ class InputManagerTest {
|
||||
@get:Rule
|
||||
val rule = MockitoJUnit.rule()!!
|
||||
|
||||
private lateinit var inputManager: InputManager
|
||||
|
||||
private lateinit var devicesChangedListener: IInputDevicesChangedListener
|
||||
private val deviceGenerationMap = mutableMapOf<Int /*deviceId*/, Int /*generation*/>()
|
||||
private lateinit var context: Context
|
||||
private lateinit var inputManager: InputManager
|
||||
|
||||
@Mock
|
||||
private lateinit var iInputManager: IInputManager
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
inputManager = InputManager.resetInstance(iInputManager)
|
||||
context = Mockito.spy(ContextWrapper(ApplicationProvider.getApplicationContext()))
|
||||
InputManagerGlobal.resetInstance(iInputManager)
|
||||
inputManager = InputManager(context)
|
||||
`when`(context.getSystemService(eq(Context.INPUT_SERVICE))).thenReturn(inputManager)
|
||||
`when`(iInputManager.inputDeviceIds).then {
|
||||
deviceGenerationMap.keys.toIntArray()
|
||||
}
|
||||
@@ -70,7 +77,7 @@ class InputManagerTest {
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
InputManager.clearInstance()
|
||||
InputManagerGlobal.clearInstance()
|
||||
}
|
||||
|
||||
private fun notifyDeviceChanged(
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
|
||||
package android.hardware.input
|
||||
|
||||
import android.content.Context
|
||||
import android.content.ContextWrapper
|
||||
import android.os.Handler
|
||||
import android.os.HandlerExecutor
|
||||
import android.os.test.TestLooper
|
||||
import android.platform.test.annotations.Presubmit
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import com.android.server.testutils.any
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
@@ -27,7 +30,9 @@ import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito
|
||||
import org.mockito.Mockito.doAnswer
|
||||
import org.mockito.Mockito.`when`
|
||||
import org.mockito.junit.MockitoJUnit
|
||||
import org.mockito.junit.MockitoJUnitRunner
|
||||
import java.util.concurrent.Executor
|
||||
@@ -51,6 +56,7 @@ class KeyboardBacklightListenerTest {
|
||||
private lateinit var testLooper: TestLooper
|
||||
private var registeredListener: IKeyboardBacklightListener? = null
|
||||
private lateinit var executor: Executor
|
||||
private lateinit var context: Context
|
||||
private lateinit var inputManager: InputManager
|
||||
|
||||
@Mock
|
||||
@@ -58,10 +64,14 @@ class KeyboardBacklightListenerTest {
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
context = Mockito.spy(ContextWrapper(ApplicationProvider.getApplicationContext()))
|
||||
InputManagerGlobal.resetInstance(iInputManagerMock)
|
||||
testLooper = TestLooper()
|
||||
executor = HandlerExecutor(Handler(testLooper.looper))
|
||||
registeredListener = null
|
||||
inputManager = InputManager.resetInstance(iInputManagerMock)
|
||||
inputManager = InputManager(context)
|
||||
`when`(context.getSystemService(Mockito.eq(Context.INPUT_SERVICE)))
|
||||
.thenReturn(inputManager)
|
||||
|
||||
// Handle keyboard backlight listener registration.
|
||||
doAnswer {
|
||||
@@ -89,7 +99,7 @@ class KeyboardBacklightListenerTest {
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
InputManager.clearInstance()
|
||||
InputManagerGlobal.clearInstance()
|
||||
}
|
||||
|
||||
private fun notifyKeyboardBacklightChanged(
|
||||
|
||||
@@ -36,7 +36,7 @@ import android.content.Context;
|
||||
import android.content.pm.PackageManagerInternal;
|
||||
import android.hardware.display.DisplayManagerInternal;
|
||||
import android.hardware.input.IInputManager;
|
||||
import android.hardware.input.InputManager;
|
||||
import android.hardware.input.InputManagerGlobal;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
import android.os.Process;
|
||||
@@ -178,7 +178,7 @@ public class InputMethodManagerServiceTestBase {
|
||||
|
||||
// Injecting and mocked InputMethodBindingController and InputMethod.
|
||||
mMockInputMethodInvoker = IInputMethodInvoker.create(mMockInputMethod);
|
||||
InputManager.resetInstance(mMockIInputManager);
|
||||
InputManagerGlobal.resetInstance(mMockIInputManager);
|
||||
synchronized (ImfLock.class) {
|
||||
when(mMockInputMethodBindingController.getCurMethod())
|
||||
.thenReturn(mMockInputMethodInvoker);
|
||||
|
||||
@@ -25,7 +25,7 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
import android.hardware.input.IInputDevicesChangedListener;
|
||||
import android.hardware.input.IInputManager;
|
||||
import android.hardware.input.InputManager;
|
||||
import android.hardware.input.InputManagerGlobal;
|
||||
import android.os.RemoteException;
|
||||
import android.testing.TestableLooper;
|
||||
import android.view.InputDevice;
|
||||
@@ -38,7 +38,8 @@ import java.util.Objects;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
/**
|
||||
* A test utility class used to share the logic for setting up {@link InputManager}'s callback for
|
||||
* A test utility class used to share the logic for setting up
|
||||
* {@link android.hardware.input.InputManager}'s callback for
|
||||
* when a virtual input device being added.
|
||||
*/
|
||||
class InputManagerMockHelper {
|
||||
@@ -76,7 +77,7 @@ class InputManagerMockHelper {
|
||||
|
||||
// Set a new instance of InputManager for testing that uses the IInputManager mock as the
|
||||
// interface to the server.
|
||||
InputManager.resetInstance(mIInputManagerMock);
|
||||
InputManagerGlobal.resetInstance(mIInputManagerMock);
|
||||
}
|
||||
|
||||
private long handleNativeOpenInputDevice(InvocationOnMock inv) {
|
||||
|
||||
@@ -19,8 +19,6 @@ package com.android.server.input
|
||||
import android.bluetooth.BluetoothAdapter
|
||||
import android.bluetooth.BluetoothDevice
|
||||
import android.bluetooth.BluetoothManager
|
||||
import android.content.Context
|
||||
import android.content.ContextWrapper
|
||||
import android.hardware.BatteryState.STATUS_CHARGING
|
||||
import android.hardware.BatteryState.STATUS_DISCHARGING
|
||||
import android.hardware.BatteryState.STATUS_FULL
|
||||
@@ -31,12 +29,14 @@ import android.hardware.input.IInputDeviceBatteryState
|
||||
import android.hardware.input.IInputDevicesChangedListener
|
||||
import android.hardware.input.IInputManager
|
||||
import android.hardware.input.InputManager
|
||||
import android.hardware.input.InputManagerGlobal
|
||||
import android.os.Binder
|
||||
import android.os.IBinder
|
||||
import android.os.test.TestLooper
|
||||
import android.platform.test.annotations.Presubmit
|
||||
import android.testing.TestableContext
|
||||
import android.view.InputDevice
|
||||
import androidx.test.InstrumentationRegistry
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import com.android.server.input.BatteryController.BluetoothBatteryManager
|
||||
import com.android.server.input.BatteryController.BluetoothBatteryManager.BluetoothBatteryListener
|
||||
import com.android.server.input.BatteryController.POLLING_PERIOD_MILLIS
|
||||
@@ -66,7 +66,6 @@ import org.mockito.Mockito.clearInvocations
|
||||
import org.mockito.Mockito.eq
|
||||
import org.mockito.Mockito.mock
|
||||
import org.mockito.Mockito.never
|
||||
import org.mockito.Mockito.spy
|
||||
import org.mockito.Mockito.times
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.Mockito.verifyNoMoreInteractions
|
||||
@@ -197,17 +196,18 @@ class BatteryControllerTests {
|
||||
private lateinit var bluetoothBatteryManager: BluetoothBatteryManager
|
||||
|
||||
private lateinit var batteryController: BatteryController
|
||||
private lateinit var context: Context
|
||||
private lateinit var context: TestableContext
|
||||
private lateinit var testLooper: TestLooper
|
||||
private lateinit var devicesChangedListener: IInputDevicesChangedListener
|
||||
private val deviceGenerationMap = mutableMapOf<Int /*deviceId*/, Int /*generation*/>()
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
context = spy(ContextWrapper(InstrumentationRegistry.getContext()))
|
||||
context = TestableContext(ApplicationProvider.getApplicationContext())
|
||||
testLooper = TestLooper()
|
||||
val inputManager = InputManager.resetInstance(iInputManager)
|
||||
`when`(context.getSystemService(eq(Context.INPUT_SERVICE))).thenReturn(inputManager)
|
||||
InputManagerGlobal.resetInstance(iInputManager)
|
||||
val inputManager = InputManager(context)
|
||||
context.addMockSystemService(InputManager::class.java, inputManager)
|
||||
`when`(iInputManager.inputDeviceIds).then {
|
||||
deviceGenerationMap.keys.toIntArray()
|
||||
}
|
||||
@@ -256,7 +256,7 @@ class BatteryControllerTests {
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
InputManager.clearInstance()
|
||||
InputManagerGlobal.clearInstance()
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -20,6 +20,7 @@ import android.content.Context
|
||||
import android.content.ContextWrapper
|
||||
import android.hardware.input.IInputManager
|
||||
import android.hardware.input.InputManager
|
||||
import android.hardware.input.InputManagerGlobal
|
||||
import android.os.test.TestLooper
|
||||
import android.platform.test.annotations.Presubmit
|
||||
import android.provider.Settings
|
||||
@@ -102,7 +103,8 @@ class KeyRemapperTests {
|
||||
dataStore,
|
||||
testLooper.looper
|
||||
)
|
||||
val inputManager = InputManager.resetInstance(iInputManager)
|
||||
InputManagerGlobal.resetInstance(iInputManager)
|
||||
val inputManager = InputManager(context)
|
||||
Mockito.`when`(context.getSystemService(Mockito.eq(Context.INPUT_SERVICE)))
|
||||
.thenReturn(inputManager)
|
||||
Mockito.`when`(iInputManager.inputDeviceIds).thenReturn(intArrayOf(DEVICE_ID))
|
||||
@@ -110,7 +112,7 @@ class KeyRemapperTests {
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
InputManager.clearInstance()
|
||||
InputManagerGlobal.clearInstance()
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.hardware.input.IInputManager
|
||||
import android.hardware.input.IKeyboardBacklightListener
|
||||
import android.hardware.input.IKeyboardBacklightState
|
||||
import android.hardware.input.InputManager
|
||||
import android.hardware.input.InputManagerGlobal
|
||||
import android.hardware.lights.Light
|
||||
import android.os.UEventObserver
|
||||
import android.os.test.TestLooper
|
||||
@@ -116,7 +117,8 @@ class KeyboardBacklightControllerTests {
|
||||
testLooper = TestLooper()
|
||||
keyboardBacklightController =
|
||||
KeyboardBacklightController(context, native, dataStore, testLooper.looper)
|
||||
val inputManager = InputManager.resetInstance(iInputManager)
|
||||
InputManagerGlobal.resetInstance(iInputManager)
|
||||
val inputManager = InputManager(context)
|
||||
`when`(context.getSystemService(eq(Context.INPUT_SERVICE))).thenReturn(inputManager)
|
||||
`when`(iInputManager.inputDeviceIds).thenReturn(intArrayOf(DEVICE_ID))
|
||||
`when`(native.setLightColor(anyInt(), anyInt(), anyInt())).then {
|
||||
@@ -131,7 +133,7 @@ class KeyboardBacklightControllerTests {
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
InputManager.clearInstance()
|
||||
InputManagerGlobal.clearInstance()
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -25,6 +25,7 @@ import android.content.pm.ResolveInfo
|
||||
import android.content.pm.ServiceInfo
|
||||
import android.hardware.input.IInputManager
|
||||
import android.hardware.input.InputManager
|
||||
import android.hardware.input.InputManagerGlobal
|
||||
import android.hardware.input.KeyboardLayout
|
||||
import android.icu.util.ULocale
|
||||
import android.os.Bundle
|
||||
@@ -144,7 +145,8 @@ class KeyboardLayoutManagerTests {
|
||||
}
|
||||
|
||||
private fun setupInputDevices() {
|
||||
val inputManager = InputManager.resetInstance(iInputManager)
|
||||
InputManagerGlobal.resetInstance(iInputManager)
|
||||
val inputManager = InputManager(context)
|
||||
Mockito.`when`(context.getSystemService(Mockito.eq(Context.INPUT_SERVICE)))
|
||||
.thenReturn(inputManager)
|
||||
|
||||
@@ -852,4 +854,4 @@ class KeyboardLayoutManagerTests {
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,16 +77,19 @@ public class InputDeviceDelegateTest {
|
||||
|
||||
private TestLooper mTestLooper;
|
||||
private ContextWrapper mContextSpy;
|
||||
private InputManager mInputManager;
|
||||
private InputDeviceDelegate mInputDeviceDelegate;
|
||||
private IInputDevicesChangedListener mIInputDevicesChangedListener;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
mTestLooper = new TestLooper();
|
||||
InputManager inputManager = InputManager.resetInstance(mIInputManagerMock);
|
||||
InputManagerGlobal.resetInstance(mIInputManagerMock);
|
||||
mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getContext()));
|
||||
|
||||
when(mContextSpy.getSystemService(eq(Context.INPUT_SERVICE))).thenReturn(inputManager);
|
||||
mInputManager = new InputManager(mContextSpy);
|
||||
when(mContextSpy.getSystemService(eq(Context.INPUT_SERVICE)))
|
||||
.thenReturn(mInputManager);
|
||||
doAnswer(invocation -> mIInputDevicesChangedListener = invocation.getArgument(0))
|
||||
.when(mIInputManagerMock).registerInputDevicesChangedListener(any());
|
||||
|
||||
@@ -97,7 +100,7 @@ public class InputDeviceDelegateTest {
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
InputManager.clearInstance();
|
||||
InputManagerGlobal.clearInstance();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -47,6 +47,7 @@ import android.content.ContextWrapper;
|
||||
import android.content.pm.PackageManagerInternal;
|
||||
import android.hardware.input.IInputManager;
|
||||
import android.hardware.input.InputManager;
|
||||
import android.hardware.input.InputManagerGlobal;
|
||||
import android.hardware.vibrator.IVibrator;
|
||||
import android.hardware.vibrator.IVibratorManager;
|
||||
import android.media.AudioAttributes;
|
||||
@@ -184,11 +185,13 @@ public class VibratorManagerServiceTest {
|
||||
private VirtualDeviceManagerInternal.AppsOnVirtualDeviceListener
|
||||
mRegisteredAppsOnVirtualDeviceListener;
|
||||
|
||||
private InputManager mInputManager;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
mTestLooper = new TestLooper();
|
||||
mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getContext()));
|
||||
InputManager inputManager = InputManager.resetInstance(mIInputManagerMock);
|
||||
InputManagerGlobal.resetInstance(mIInputManagerMock);
|
||||
mVibrationConfig = new VibrationConfig(mContextSpy.getResources());
|
||||
|
||||
ContentResolver contentResolver = mSettingsProviderRule.mockContentResolver(mContextSpy);
|
||||
@@ -196,7 +199,10 @@ public class VibratorManagerServiceTest {
|
||||
|
||||
mVibrator = new FakeVibrator(mContextSpy);
|
||||
when(mContextSpy.getSystemService(eq(Context.VIBRATOR_SERVICE))).thenReturn(mVibrator);
|
||||
when(mContextSpy.getSystemService(eq(Context.INPUT_SERVICE))).thenReturn(inputManager);
|
||||
|
||||
mInputManager = new InputManager(mContextSpy);
|
||||
when(mContextSpy.getSystemService(eq(Context.INPUT_SERVICE)))
|
||||
.thenReturn(mInputManager);
|
||||
when(mContextSpy.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOpsManagerMock);
|
||||
when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[0]);
|
||||
when(mPackageManagerInternalMock.getSystemUiServiceComponent())
|
||||
@@ -259,6 +265,7 @@ public class VibratorManagerServiceTest {
|
||||
LocalServices.removeServiceForTest(PowerManagerInternal.class);
|
||||
// Ignore potential exceptions about the looper having never dispatched any messages.
|
||||
mTestLooper.stopAutoDispatchAndIgnoreExceptions();
|
||||
InputManagerGlobal.clearInstance();
|
||||
}
|
||||
|
||||
private VibratorManagerService createSystemReadyService() {
|
||||
|
||||
Reference in New Issue
Block a user