Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 06291c77 authored by Asmita Poddar's avatar Asmita Poddar Committed by Automerger Merge Worker
Browse files

Merge "Remove InputManager#getInstance" into udc-dev am: ef0421cf

parents dd231177 ef0421cf
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -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,
+20 −105
Original line number Diff line number Diff line
@@ -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.
     *
     * @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.
     *
     * @hide
     */
    @VisibleForTesting
    public static void clearInstance() {
        synchronized (InputManager.class) {
            InputManagerGlobal.clearInstance();
            sInstance = null;
        }
    }

    /**
     * Gets an instance of the input manager.
     *  Warning: The usage of this method is not supported!
     *
     *  @return The input manager instance.
     * @deprecated Use {@link Context#getSystemService(Class)} or {@link #getInstance(Context)}
     *  Use {@link Context#getSystemService(Class)}
     *  to obtain the InputManager instance.
     *
     * TODO (b/277717573): Soft remove this API in version V.
     * TODO (b/277039664): Migrate app usage off this API.
     *
     * @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,
        mGlobal.setCurrentKeyboardLayoutForInputDevice(identifier,
                keyboardLayoutDescriptor);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
    }

    /**
@@ -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);
        }
+61 −19
Original line number Diff line number Diff line
@@ -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) {
+3 −2
Original line number Diff line number Diff line
@@ -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;
+12 −2
Original line number Diff line number Diff line
@@ -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(
Loading