InputManagerService: Refactor native methods to be testable

We move the native methods of InputManagerService to a separate class
and interface, which allows it to be mocked for unit testing.

We also add an Injector class to allow for test depenedency injection.

Bug: 195528323
Test: build and flash
Change-Id: I9ae42a85addeac5ccf1aa1ed23956bdabd615531
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 385aa69..603d012 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -74,7 +74,6 @@
 import android.os.LocaleList;
 import android.os.Looper;
 import android.os.Message;
-import android.os.MessageQueue;
 import android.os.Process;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
@@ -112,6 +111,7 @@
 
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.internal.notification.SystemNotificationChannels;
 import com.android.internal.os.SomeArgs;
@@ -147,9 +147,7 @@
 import java.util.Objects;
 import java.util.OptionalInt;
 
-/*
- * Wraps the C++ InputManager and provides its callbacks.
- */
+/** The system implementation of {@link IInputManager} that manages input devices. */
 public class InputManagerService extends IInputManager.Stub
         implements Watchdog.Monitor {
     static final String TAG = "InputManager";
@@ -183,8 +181,7 @@
     /** TODO(b/169067926): Remove this. */
     private static final boolean UNTRUSTED_TOUCHES_TOAST = false;
 
-    // Pointer to native input manager service object.
-    private final long mPtr;
+    private final NativeInputManagerService mNative;
 
     private final Context mContext;
     private final InputManagerHandler mHandler;
@@ -299,91 +296,6 @@
     @GuardedBy("mInputMonitors")
     final Map<IBinder, GestureMonitorSpyWindow> mInputMonitors = new HashMap<>();
 
-    private static native long nativeInit(InputManagerService service,
-            Context context, MessageQueue messageQueue);
-    private static native void nativeStart(long ptr);
-    private static native void nativeSetDisplayViewports(long ptr,
-            DisplayViewport[] viewports);
-
-    private static native int nativeGetScanCodeState(long ptr,
-            int deviceId, int sourceMask, int scanCode);
-    private static native int nativeGetKeyCodeState(long ptr,
-            int deviceId, int sourceMask, int keyCode);
-    private static native int nativeGetSwitchState(long ptr,
-            int deviceId, int sourceMask, int sw);
-    private static native boolean nativeHasKeys(long ptr,
-            int deviceId, int sourceMask, int[] keyCodes, boolean[] keyExists);
-    private static native int nativeGetKeyCodeForKeyLocation(long ptr, int deviceId,
-            int locationKeyCode);
-    private static native InputChannel nativeCreateInputChannel(long ptr, String name);
-    private static native InputChannel nativeCreateInputMonitor(long ptr, int displayId,
-            String name, int pid);
-    private static native void nativeRemoveInputChannel(long ptr, IBinder connectionToken);
-    private static native void nativePilferPointers(long ptr, IBinder token);
-    private static native void nativeSetInputFilterEnabled(long ptr, boolean enable);
-    private static native boolean nativeSetInTouchMode(long ptr, boolean inTouchMode, int pid,
-            int uid, boolean hasPermission);
-    private static native void nativeSetMaximumObscuringOpacityForTouch(long ptr, float opacity);
-    private static native void nativeSetBlockUntrustedTouchesMode(long ptr, int mode);
-    private static native int nativeInjectInputEvent(long ptr, InputEvent event,
-            boolean injectIntoUid, int uid, int syncMode, int timeoutMillis, int policyFlags);
-    private static native VerifiedInputEvent nativeVerifyInputEvent(long ptr, InputEvent event);
-    private static native void nativeToggleCapsLock(long ptr, int deviceId);
-    private static native void nativeDisplayRemoved(long ptr, int displayId);
-    private static native void nativeSetInputDispatchMode(long ptr, boolean enabled, boolean frozen);
-    private static native void nativeSetSystemUiLightsOut(long ptr, boolean lightsOut);
-    private static native void nativeSetFocusedApplication(long ptr,
-            int displayId, InputApplicationHandle application);
-    private static native void nativeSetFocusedDisplay(long ptr, int displayId);
-    private static native boolean nativeTransferTouchFocus(long ptr,
-            IBinder fromChannelToken, IBinder toChannelToken, boolean isDragDrop);
-    private static native boolean nativeTransferTouch(long ptr, IBinder destChannelToken);
-    private static native void nativeSetPointerSpeed(long ptr, int speed);
-    private static native void nativeSetPointerAcceleration(long ptr, float acceleration);
-    private static native void nativeSetShowTouches(long ptr, boolean enabled);
-    private static native void nativeSetInteractive(long ptr, boolean interactive);
-    private static native void nativeReloadCalibration(long ptr);
-    private static native void nativeVibrate(long ptr, int deviceId, long[] pattern,
-            int[] amplitudes, int repeat, int token);
-    private static native void nativeVibrateCombined(long ptr, int deviceId, long[] pattern,
-            SparseArray<int[]> amplitudes, int repeat, int token);
-    private static native void nativeCancelVibrate(long ptr, int deviceId, int token);
-    private static native boolean nativeIsVibrating(long ptr, int deviceId);
-    private static native int[] nativeGetVibratorIds(long ptr, int deviceId);
-    private static native int nativeGetBatteryCapacity(long ptr, int deviceId);
-    private static native int nativeGetBatteryStatus(long ptr, int deviceId);
-    private static native List<Light> nativeGetLights(long ptr, int deviceId);
-    private static native int nativeGetLightPlayerId(long ptr, int deviceId, int lightId);
-    private static native int nativeGetLightColor(long ptr, int deviceId, int lightId);
-    private static native void nativeSetLightPlayerId(long ptr, int deviceId, int lightId,
-            int playerId);
-    private static native void nativeSetLightColor(long ptr, int deviceId, int lightId, int color);
-    private static native void nativeReloadKeyboardLayouts(long ptr);
-    private static native void nativeReloadDeviceAliases(long ptr);
-    private static native String nativeDump(long ptr);
-    private static native void nativeMonitor(long ptr);
-    private static native boolean nativeIsInputDeviceEnabled(long ptr, int deviceId);
-    private static native void nativeEnableInputDevice(long ptr, int deviceId);
-    private static native void nativeDisableInputDevice(long ptr, int deviceId);
-    private static native void nativeSetPointerIconType(long ptr, int iconId);
-    private static native void nativeReloadPointerIcons(long ptr);
-    private static native void nativeSetCustomPointerIcon(long ptr, PointerIcon icon);
-    private static native void nativeRequestPointerCapture(long ptr, IBinder windowToken,
-            boolean enabled);
-    private static native boolean nativeCanDispatchToDisplay(long ptr, int deviceId, int displayId);
-    private static native void nativeNotifyPortAssociationsChanged(long ptr);
-    private static native void nativeChangeUniqueIdAssociation(long ptr);
-    private static native void nativeNotifyPointerDisplayIdChanged(long ptr);
-    private static native void nativeSetDisplayEligibilityForPointerCapture(long ptr, int displayId,
-            boolean enabled);
-    private static native void nativeSetMotionClassifierEnabled(long ptr, boolean enabled);
-    private static native InputSensorInfo[] nativeGetSensorList(long ptr, int deviceId);
-    private static native boolean nativeFlushSensor(long ptr, int deviceId, int sensorType);
-    private static native boolean nativeEnableSensor(long ptr, int deviceId, int sensorType,
-            int samplingPeriodUs, int maxBatchReportLatencyUs);
-    private static native void nativeDisableSensor(long ptr, int deviceId, int sensorType);
-    private static native void nativeCancelCurrentTouch(long ptr);
-
     // Maximum number of milliseconds to wait for input event injection.
     private static final int INJECTION_TIMEOUT_MILLIS = 30 * 1000;
 
@@ -450,18 +362,47 @@
     /** Whether to use the dev/input/event or uevent subsystem for the audio jack. */
     final boolean mUseDevInputEventForAudioJack;
 
+    /** Point of injection for test dependencies. */
+    @VisibleForTesting
+    static class Injector {
+        private final Context mContext;
+        private final Looper mLooper;
+
+        Injector(Context context, Looper looper) {
+            mContext = context;
+            mLooper = looper;
+        }
+
+        Context getContext() {
+            return mContext;
+        }
+
+        Looper getLooper() {
+            return mLooper;
+        }
+
+        NativeInputManagerService getNativeService(InputManagerService service) {
+            return new NativeInputManagerService.NativeImpl(service, mContext, mLooper.getQueue());
+        }
+    }
+
     public InputManagerService(Context context) {
-        this.mContext = context;
-        this.mHandler = new InputManagerHandler(DisplayThread.get().getLooper());
+        this(new Injector(context, DisplayThread.get().getLooper()));
+    }
+
+    @VisibleForTesting
+    InputManagerService(Injector injector) {
+        mContext = injector.getContext();
+        mHandler = new InputManagerHandler(injector.getLooper());
+        mNative = injector.getNativeService(this);
 
         mStaticAssociations = loadStaticInputPortAssociations();
         mUseDevInputEventForAudioJack =
-                context.getResources().getBoolean(R.bool.config_useDevInputEventForAudioJack);
+                mContext.getResources().getBoolean(R.bool.config_useDevInputEventForAudioJack);
         Slog.i(TAG, "Initializing input manager, mUseDevInputEventForAudioJack="
                 + mUseDevInputEventForAudioJack);
-        mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());
 
-        String doubleTouchGestureEnablePath = context.getResources().getString(
+        String doubleTouchGestureEnablePath = mContext.getResources().getString(
                 R.string.config_doubleTouchGestureEnableFile);
         mDoubleTouchGestureEnableFile = TextUtils.isEmpty(doubleTouchGestureEnablePath) ? null :
             new File(doubleTouchGestureEnablePath);
@@ -504,9 +445,9 @@
 
     public void start() {
         Slog.i(TAG, "Starting input manager");
-        nativeStart(mPtr);
+        mNative.start();
 
-        // Add ourself to the Watchdog monitors.
+        // Add ourselves to the Watchdog monitors.
         Watchdog.getInstance().addMonitor(this);
 
         registerPointerSpeedSettingObserver();
@@ -599,14 +540,14 @@
         if (DEBUG) {
             Slog.d(TAG, "Reloading keyboard layouts.");
         }
-        nativeReloadKeyboardLayouts(mPtr);
+        mNative.reloadKeyboardLayouts();
     }
 
     private void reloadDeviceAliases() {
         if (DEBUG) {
             Slog.d(TAG, "Reloading device names.");
         }
-        nativeReloadDeviceAliases(mPtr);
+        mNative.reloadDeviceAliases();
     }
 
     private void setDisplayViewportsInternal(List<DisplayViewport> viewports) {
@@ -615,7 +556,7 @@
             for (int i = viewports.size() - 1; i >= 0; --i) {
                 vArray[i] = viewports.get(i);
             }
-            nativeSetDisplayViewports(mPtr, vArray);
+            mNative.setDisplayViewports(vArray);
 
             if (mOverriddenPointerDisplayId != Display.INVALID_DISPLAY) {
                 final AdditionalDisplayInputProperties properties =
@@ -642,7 +583,7 @@
      * @return The key state.
      */
     public int getKeyCodeState(int deviceId, int sourceMask, int keyCode) {
-        return nativeGetKeyCodeState(mPtr, deviceId, sourceMask, keyCode);
+        return mNative.getKeyCodeState(deviceId, sourceMask, keyCode);
     }
 
     /**
@@ -655,7 +596,7 @@
      * @return The key state.
      */
     public int getScanCodeState(int deviceId, int sourceMask, int scanCode) {
-        return nativeGetScanCodeState(mPtr, deviceId, sourceMask, scanCode);
+        return mNative.getScanCodeState(deviceId, sourceMask, scanCode);
     }
 
     /**
@@ -668,7 +609,7 @@
      * @return The switch state.
      */
     public int getSwitchState(int deviceId, int sourceMask, int switchCode) {
-        return nativeGetSwitchState(mPtr, deviceId, sourceMask, switchCode);
+        return mNative.getSwitchState(deviceId, sourceMask, switchCode);
     }
 
     /**
@@ -691,7 +632,7 @@
             throw new IllegalArgumentException("keyExists must be at least as large as keyCodes");
         }
 
-        return nativeHasKeys(mPtr, deviceId, sourceMask, keyCodes, keyExists);
+        return mNative.hasKeys(deviceId, sourceMask, keyCodes, keyExists);
     }
 
     /**
@@ -707,7 +648,7 @@
         if (locationKeyCode <= KEYCODE_UNKNOWN || locationKeyCode > KeyEvent.getMaxKeyCode()) {
             return KEYCODE_UNKNOWN;
         }
-        return nativeGetKeyCodeForKeyLocation(mPtr, deviceId, locationKeyCode);
+        return mNative.getKeyCodeForKeyLocation(deviceId, locationKeyCode);
     }
 
     /**
@@ -720,7 +661,7 @@
     public boolean transferTouch(IBinder destChannelToken) {
         // TODO(b/162194035): Replace this with a SPY window
         Objects.requireNonNull(destChannelToken, "destChannelToken must not be null");
-        return nativeTransferTouch(mPtr, destChannelToken);
+        return mNative.transferTouch(destChannelToken);
     }
 
     /**
@@ -736,7 +677,7 @@
             throw new IllegalArgumentException("displayId must >= 0.");
         }
 
-        return nativeCreateInputMonitor(mPtr, displayId, inputChannelName, Binder.getCallingPid());
+        return mNative.createInputMonitor(displayId, inputChannelName, Binder.getCallingPid());
     }
 
     @NonNull
@@ -818,7 +759,7 @@
      * @param name The name of this input channel
      */
     public InputChannel createInputChannel(String name) {
-        return nativeCreateInputChannel(mPtr, name);
+        return mNative.createInputChannel(name);
     }
 
     /**
@@ -827,7 +768,7 @@
      */
     public void removeInputChannel(IBinder connectionToken) {
         Objects.requireNonNull(connectionToken, "connectionToken must not be null");
-        nativeRemoveInputChannel(mPtr, connectionToken);
+        mNative.removeInputChannel(connectionToken);
     }
 
     /**
@@ -869,7 +810,7 @@
                 }
             }
 
-            nativeSetInputFilterEnabled(mPtr, filter != null);
+            mNative.setInputFilterEnabled(filter != null);
         }
     }
 
@@ -893,7 +834,7 @@
      * @return {@code true} if the touch mode was successfully changed, {@code false} otherwise
      */
     public boolean setInTouchMode(boolean inTouchMode, int pid, int uid, boolean hasPermission) {
-        return nativeSetInTouchMode(mPtr, inTouchMode, pid, uid, hasPermission);
+        return mNative.setInTouchMode(inTouchMode, pid, uid, hasPermission);
     }
 
     @Override // Binder call
@@ -918,7 +859,7 @@
         final boolean injectIntoUid = targetUid != Process.INVALID_UID;
         final int result;
         try {
-            result = nativeInjectInputEvent(mPtr, event, injectIntoUid,
+            result = mNative.injectInputEvent(event, injectIntoUid,
                     targetUid, mode, INJECTION_TIMEOUT_MILLIS,
                     WindowManagerPolicy.FLAG_DISABLE_KEY_REPEAT);
         } finally {
@@ -962,7 +903,7 @@
     @Override // Binder call
     public VerifiedInputEvent verifyInputEvent(InputEvent event) {
         Objects.requireNonNull(event, "event must not be null");
-        return nativeVerifyInputEvent(mPtr, event);
+        return mNative.verifyInputEvent(event);
     }
 
     /**
@@ -985,7 +926,7 @@
     // Binder call
     @Override
     public boolean isInputDeviceEnabled(int deviceId) {
-        return nativeIsInputDeviceEnabled(mPtr, deviceId);
+        return mNative.isInputDeviceEnabled(deviceId);
     }
 
     // Binder call
@@ -995,7 +936,7 @@
                 "enableInputDevice()")) {
             throw new SecurityException("Requires DISABLE_INPUT_DEVICE permission");
         }
-        nativeEnableInputDevice(mPtr, deviceId);
+        mNative.enableInputDevice(deviceId);
     }
 
     // Binder call
@@ -1005,7 +946,7 @@
                 "disableInputDevice()")) {
             throw new SecurityException("Requires DISABLE_INPUT_DEVICE permission");
         }
-        nativeDisableInputDevice(mPtr, deviceId);
+        mNative.disableInputDevice(deviceId);
     }
 
     /**
@@ -1251,7 +1192,7 @@
             try {
                 if (mDataStore.setTouchCalibration(inputDeviceDescriptor, surfaceRotation,
                         calibration)) {
-                    nativeReloadCalibration(mPtr);
+                    mNative.reloadCalibration();
                 }
             } finally {
                 mDataStore.saveIfNeeded();
@@ -1763,11 +1704,11 @@
     }
 
     public void setFocusedApplication(int displayId, InputApplicationHandle application) {
-        nativeSetFocusedApplication(mPtr, displayId, application);
+        mNative.setFocusedApplication(displayId, application);
     }
 
     public void setFocusedDisplay(int displayId) {
-        nativeSetFocusedDisplay(mPtr, displayId);
+        mNative.setFocusedDisplay(displayId);
     }
 
     /** Clean up input window handles of the given display. */
@@ -1777,22 +1718,22 @@
             mPointerIconDisplayContext = null;
         }
 
-        nativeDisplayRemoved(mPtr, displayId);
+        mNative.displayRemoved(displayId);
     }
 
     @Override
     public void requestPointerCapture(IBinder inputChannelToken, boolean enabled) {
         Objects.requireNonNull(inputChannelToken, "event must not be null");
 
-        nativeRequestPointerCapture(mPtr, inputChannelToken, enabled);
+        mNative.requestPointerCapture(inputChannelToken, enabled);
     }
 
     public void setInputDispatchMode(boolean enabled, boolean frozen) {
-        nativeSetInputDispatchMode(mPtr, enabled, frozen);
+        mNative.setInputDispatchMode(enabled, frozen);
     }
 
     public void setSystemUiLightsOut(boolean lightsOut) {
-        nativeSetSystemUiLightsOut(mPtr, lightsOut);
+        mNative.setSystemUiLightsOut(lightsOut);
     }
 
     /**
@@ -1811,7 +1752,7 @@
      */
     public boolean transferTouchFocus(@NonNull InputChannel fromChannel,
             @NonNull InputChannel toChannel, boolean isDragDrop) {
-        return nativeTransferTouchFocus(mPtr, fromChannel.getToken(), toChannel.getToken(),
+        return mNative.transferTouchFocus(fromChannel.getToken(), toChannel.getToken(),
                 isDragDrop);
     }
 
@@ -1832,7 +1773,7 @@
             @NonNull IBinder toChannelToken) {
         Objects.nonNull(fromChannelToken);
         Objects.nonNull(toChannelToken);
-        return nativeTransferTouchFocus(mPtr, fromChannelToken, toChannelToken,
+        return mNative.transferTouchFocus(fromChannelToken, toChannelToken,
                 false /* isDragDrop */);
     }
 
@@ -1858,7 +1799,7 @@
     private void setPointerSpeedUnchecked(int speed) {
         speed = Math.min(Math.max(speed, InputManager.MIN_POINTER_SPEED),
                 InputManager.MAX_POINTER_SPEED);
-        nativeSetPointerSpeed(mPtr, speed);
+        mNative.setPointerSpeed(speed);
     }
 
     private void setPointerAcceleration(float acceleration, int displayId) {
@@ -1881,7 +1822,7 @@
 
     @GuardedBy("mAdditionalDisplayInputPropertiesLock")
     private void updatePointerAccelerationLocked(float acceleration) {
-        nativeSetPointerAcceleration(mPtr, acceleration);
+        mNative.setPointerAcceleration(acceleration);
     }
 
     private void setPointerIconVisible(boolean visible, int displayId) {
@@ -1906,12 +1847,12 @@
     private void updatePointerIconVisibleLocked(boolean visible) {
         if (visible) {
             if (mIconType == PointerIcon.TYPE_CUSTOM) {
-                nativeSetCustomPointerIcon(mPtr, mIcon);
+                mNative.setCustomPointerIcon(mIcon);
             } else {
-                nativeSetPointerIconType(mPtr, mIconType);
+                mNative.setPointerIconType(mIconType);
             }
         } else {
-            nativeSetPointerIconType(mPtr, PointerIcon.TYPE_NULL);
+            mNative.setPointerIconType(PointerIcon.TYPE_NULL);
         }
     }
 
@@ -1938,7 +1879,7 @@
 
     private void updateShowTouchesFromSettings() {
         int setting = getShowTouchesSetting(0);
-        nativeSetShowTouches(mPtr, setting != 0);
+        mNative.setShowTouches(setting != 0);
     }
 
     private void registerShowTouchesSettingObserver() {
@@ -1957,7 +1898,7 @@
                 mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON,
                 0, UserHandle.USER_CURRENT);
         PointerIcon.setUseLargeIcons(accessibilityConfig == 1);
-        nativeReloadPointerIcons(mPtr);
+        mNative.reloadPointerIcons();
     }
 
     private void registerAccessibilityLargePointerSettingObserver() {
@@ -1985,7 +1926,7 @@
                 (enabled ? "Enabling" : "Disabling") + " motion classifier because " + reason
                 + ": feature " + (featureEnabledFlag ? "enabled" : "disabled")
                 + ", long press timeout = " + timeout);
-        nativeSetMotionClassifierEnabled(mPtr, enabled);
+        mNative.setMotionClassifierEnabled(enabled);
     }
 
     private void registerLongPressTimeoutObserver() {
@@ -2013,7 +1954,7 @@
 
     private void updateBlockUntrustedTouchesModeFromSettings() {
         final int mode = InputManager.getInstance().getBlockUntrustedTouchesMode(mContext);
-        nativeSetBlockUntrustedTouchesMode(mPtr, mode);
+        mNative.setBlockUntrustedTouchesMode(mode);
     }
 
     private void registerMaximumObscuringOpacityForTouchSettingObserver() {
@@ -2035,7 +1976,7 @@
                     + ", it should be >= 0 and <= 1, rejecting update.");
             return;
         }
-        nativeSetMaximumObscuringOpacityForTouch(mPtr, opacity);
+        mNative.setMaximumObscuringOpacityForTouch(opacity);
     }
 
     private int getShowTouchesSetting(int defaultValue) {
@@ -2061,7 +2002,7 @@
             }
         }
         // TODO(b/215597605): trigger MousePositionTracker update
-        nativeNotifyPointerDisplayIdChanged(mPtr);
+        mNative.notifyPointerDisplayIdChanged();
     }
 
     private int getVirtualMousePointerDisplayId() {
@@ -2071,7 +2012,7 @@
     }
 
     private void setDisplayEligibilityForPointerCapture(int displayId, boolean isEligible) {
-        nativeSetDisplayEligibilityForPointerCapture(mPtr, displayId, isEligible);
+        mNative.setDisplayEligibilityForPointerCapture(displayId, isEligible);
     }
 
     private static class VibrationInfo {
@@ -2170,7 +2111,7 @@
         VibratorToken v = getVibratorToken(deviceId, token);
         synchronized (v) {
             v.mVibrating = true;
-            nativeVibrate(mPtr, deviceId, info.getPattern(), info.getAmplitudes(),
+            mNative.vibrate(deviceId, info.getPattern(), info.getAmplitudes(),
                     info.getRepeatIndex(), v.mTokenValue);
         }
     }
@@ -2178,13 +2119,13 @@
     // Binder call
     @Override
     public int[] getVibratorIds(int deviceId) {
-        return nativeGetVibratorIds(mPtr, deviceId);
+        return mNative.getVibratorIds(deviceId);
     }
 
     // Binder call
     @Override
     public boolean isVibrating(int deviceId) {
-        return nativeIsVibrating(mPtr, deviceId);
+        return mNative.isVibrating(deviceId);
     }
 
     // Binder call
@@ -2202,7 +2143,7 @@
             if (effect instanceof CombinedVibration.Mono) {
                 CombinedVibration.Mono mono = (CombinedVibration.Mono) effect;
                 VibrationInfo info = new VibrationInfo(mono.getEffect());
-                nativeVibrate(mPtr, deviceId, info.getPattern(), info.getAmplitudes(),
+                mNative.vibrate(deviceId, info.getPattern(), info.getAmplitudes(),
                         info.getRepeatIndex(), v.mTokenValue);
             } else if (effect instanceof CombinedVibration.Stereo) {
                 CombinedVibration.Stereo stereo = (CombinedVibration.Stereo) effect;
@@ -2221,7 +2162,7 @@
                     }
                     amplitudes.put(effects.keyAt(i), info.getAmplitudes());
                 }
-                nativeVibrateCombined(mPtr, deviceId, pattern, amplitudes, repeat,
+                mNative.vibrateCombined(deviceId, pattern, amplitudes, repeat,
                         v.mTokenValue);
             }
         }
@@ -2252,7 +2193,7 @@
     private void cancelVibrateIfNeeded(VibratorToken v) {
         synchronized (v) {
             if (v.mVibrating) {
-                nativeCancelVibrate(mPtr, v.mDeviceId, v.mTokenValue);
+                mNative.cancelVibrate(v.mDeviceId, v.mTokenValue);
                 v.mVibrating = false;
             }
         }
@@ -2348,13 +2289,13 @@
     // Binder call
     @Override
     public int getBatteryStatus(int deviceId) {
-        return nativeGetBatteryStatus(mPtr, deviceId);
+        return mNative.getBatteryStatus(deviceId);
     }
 
     // Binder call
     @Override
     public int getBatteryCapacity(int deviceId) {
-        return nativeGetBatteryCapacity(mPtr, deviceId);
+        return mNative.getBatteryCapacity(deviceId);
     }
 
     // Binder call
@@ -2370,10 +2311,10 @@
                 final AdditionalDisplayInputProperties properties =
                         mAdditionalDisplayInputProperties.get(mOverriddenPointerDisplayId);
                 if (properties == null || properties.pointerIconVisible) {
-                    nativeSetPointerIconType(mPtr, mIconType);
+                    mNative.setPointerIconType(mIconType);
                 }
             } else {
-                nativeSetPointerIconType(mPtr, mIconType);
+                mNative.setPointerIconType(mIconType);
             }
         }
     }
@@ -2391,10 +2332,10 @@
                 if (properties == null || properties.pointerIconVisible) {
                     // Only set the icon if it is not currently hidden; otherwise, it will be set
                     // once it's no longer hidden.
-                    nativeSetCustomPointerIcon(mPtr, mIcon);
+                    mNative.setCustomPointerIcon(mIcon);
                 }
             } else {
-                nativeSetCustomPointerIcon(mPtr, mIcon);
+                mNative.setCustomPointerIcon(mIcon);
             }
         }
     }
@@ -2418,7 +2359,7 @@
         synchronized (mAssociationsLock) {
             mRuntimeAssociations.put(inputPort, displayPort);
         }
-        nativeNotifyPortAssociationsChanged(mPtr);
+        mNative.notifyPortAssociationsChanged();
     }
 
     /**
@@ -2439,7 +2380,7 @@
         synchronized (mAssociationsLock) {
             mRuntimeAssociations.remove(inputPort);
         }
-        nativeNotifyPortAssociationsChanged(mPtr);
+        mNative.notifyPortAssociationsChanged();
     }
 
     @Override // Binder call
@@ -2456,7 +2397,7 @@
         synchronized (mAssociationsLock) {
             mUniqueIdAssociations.put(inputPort, displayUniqueId);
         }
-        nativeChangeUniqueIdAssociation(mPtr);
+        mNative.changeUniqueIdAssociation();
     }
 
     @Override // Binder call
@@ -2472,12 +2413,12 @@
         synchronized (mAssociationsLock) {
             mUniqueIdAssociations.remove(inputPort);
         }
-        nativeChangeUniqueIdAssociation(mPtr);
+        mNative.changeUniqueIdAssociation();
     }
 
     @Override // Binder call
     public InputSensorInfo[] getSensorList(int deviceId) {
-        return nativeGetSensorList(mPtr, deviceId);
+        return mNative.getSensorList(deviceId);
     }
 
     @Override // Binder call
@@ -2538,7 +2479,7 @@
             int callingPid = Binder.getCallingPid();
             SensorEventListenerRecord listener = mSensorEventListeners.get(callingPid);
             if (listener != null) {
-                return nativeFlushSensor(mPtr, deviceId, sensorType);
+                return mNative.flushSensor(deviceId, sensorType);
             }
             return false;
         }
@@ -2548,7 +2489,7 @@
     public boolean enableSensor(int deviceId, int sensorType, int samplingPeriodUs,
             int maxBatchReportLatencyUs) {
         synchronized (mInputDevicesLock) {
-            return nativeEnableSensor(mPtr, deviceId, sensorType, samplingPeriodUs,
+            return mNative.enableSensor(deviceId, sensorType, samplingPeriodUs,
                     maxBatchReportLatencyUs);
         }
     }
@@ -2556,7 +2497,7 @@
     @Override // Binder call
     public void disableSensor(int deviceId, int sensorType) {
         synchronized (mInputDevicesLock) {
-            nativeDisableSensor(mPtr, deviceId, sensorType);
+            mNative.disableSensor(deviceId, sensorType);
         }
     }
 
@@ -2595,7 +2536,7 @@
      */
     @Override // Binder call
     public List<Light> getLights(int deviceId) {
-        return nativeGetLights(mPtr, deviceId);
+        return mNative.getLights(deviceId);
     }
 
     /**
@@ -2608,11 +2549,11 @@
                     + "lightState " + lightState);
         }
         if (light.getType() == Light.LIGHT_TYPE_PLAYER_ID) {
-            nativeSetLightPlayerId(mPtr, deviceId, light.getId(), lightState.getPlayerId());
+            mNative.setLightPlayerId(deviceId, light.getId(), lightState.getPlayerId());
         } else {
             // Set ARGB format color to input device light
             // Refer to https://developer.android.com/reference/kotlin/android/graphics/Color
-            nativeSetLightColor(mPtr, deviceId, light.getId(), lightState.getColor());
+            mNative.setLightColor(deviceId, light.getId(), lightState.getColor());
         }
     }
 
@@ -2620,7 +2561,7 @@
      * Set multiple light states with multiple light ids for a specific input device.
      */
     private void setLightStatesInternal(int deviceId, int[] lightIds, LightState[] lightStates) {
-        final List<Light> lights = nativeGetLights(mPtr, deviceId);
+        final List<Light> lights = mNative.getLights(deviceId);
         SparseArray<Light> lightArray = new SparseArray<>();
         for (int i = 0; i < lights.size(); i++) {
             lightArray.put(lights.get(i).getId(), lights.get(i));
@@ -2656,8 +2597,8 @@
     @Override
     public @Nullable LightState getLightState(int deviceId, int lightId) {
         synchronized (mLightLock) {
-            int color = nativeGetLightColor(mPtr, deviceId, lightId);
-            int playerId = nativeGetLightPlayerId(mPtr, deviceId, lightId);
+            int color = mNative.getLightColor(deviceId, lightId);
+            int playerId = mNative.getLightPlayerId(deviceId, lightId);
 
             return new LightState(color, playerId);
         }
@@ -2709,7 +2650,7 @@
             throw new SecurityException("Requires MONITOR_INPUT permission");
         }
 
-        nativeCancelCurrentTouch(mPtr);
+        mNative.cancelCurrentTouch();
     }
 
     @Override
@@ -2717,7 +2658,7 @@
         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
 
         pw.println("INPUT MANAGER (dumpsys input)\n");
-        String dumpStr = nativeDump(mPtr);
+        String dumpStr = mNative.dump();
         if (dumpStr != null) {
             pw.println(dumpStr);
         }
@@ -2826,7 +2767,7 @@
         synchronized (mLidSwitchLock) { /* Test if blocked by lid switch lock. */ }
         synchronized (mInputMonitors) { /* Test if blocked by input monitor lock. */ }
         synchronized (mAdditionalDisplayInputPropertiesLock) { /* Test if blocked by props lock */ }
-        nativeMonitor(mPtr);
+        mNative.monitor();
     }
 
     // Native callback.
@@ -3153,7 +3094,7 @@
      * @return True if the device could dispatch to the given display, false otherwise.
      */
     public boolean canDispatchToDisplay(int deviceId, int displayId) {
-        return nativeCanDispatchToDisplay(mPtr, deviceId, displayId);
+        return mNative.canDispatchToDisplay(deviceId, displayId);
     }
 
     // Native callback.
@@ -3504,7 +3445,7 @@
 
             synchronized (mInputFilterLock) {
                 if (!mDisconnected) {
-                    nativeInjectInputEvent(mPtr, event, false /* injectIntoUid */, -1 /* uid */,
+                    mNative.injectInputEvent(event, false /* injectIntoUid */, -1 /* uid */,
                             InputManager.INJECT_INPUT_EVENT_MODE_ASYNC, 0 /* timeout */,
                             policyFlags | WindowManagerPolicy.FLAG_FILTERED);
                 }
@@ -3524,7 +3465,7 @@
 
         @Override
         public void pilferPointers() {
-            nativePilferPointers(mPtr, mInputChannelToken);
+            mNative.pilferPointers(mInputChannelToken);
         }
 
         @Override
@@ -3702,12 +3643,12 @@
 
         @Override
         public void setInteractive(boolean interactive) {
-            nativeSetInteractive(mPtr, interactive);
+            mNative.setInteractive(interactive);
         }
 
         @Override
         public void toggleCapsLock(int deviceId) {
-            nativeToggleCapsLock(mPtr, deviceId);
+            mNative.toggleCapsLock(deviceId);
         }
 
         @Override
@@ -3778,7 +3719,7 @@
 
         @Override
         public void pilferPointers(IBinder token) {
-            nativePilferPointers(mPtr, token);
+            mNative.pilferPointers(token);
         }
     }
 
diff --git a/services/core/java/com/android/server/input/NativeInputManagerService.java b/services/core/java/com/android/server/input/NativeInputManagerService.java
new file mode 100644
index 0000000..7178d20
--- /dev/null
+++ b/services/core/java/com/android/server/input/NativeInputManagerService.java
@@ -0,0 +1,389 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.input;
+
+import android.content.Context;
+import android.hardware.display.DisplayViewport;
+import android.hardware.input.InputSensorInfo;
+import android.hardware.lights.Light;
+import android.os.IBinder;
+import android.os.MessageQueue;
+import android.util.SparseArray;
+import android.view.InputApplicationHandle;
+import android.view.InputChannel;
+import android.view.InputEvent;
+import android.view.PointerIcon;
+import android.view.VerifiedInputEvent;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.List;
+
+/**
+ * An interface for the native methods of InputManagerService. We use a public interface so that
+ * this can be mocked for testing by Mockito.
+ */
+@VisibleForTesting
+public interface NativeInputManagerService {
+
+    void start();
+
+    void setDisplayViewports(DisplayViewport[] viewports);
+
+    int getScanCodeState(int deviceId, int sourceMask, int scanCode);
+
+    int getKeyCodeState(int deviceId, int sourceMask, int keyCode);
+
+    int getSwitchState(int deviceId, int sourceMask, int sw);
+
+    boolean hasKeys(int deviceId, int sourceMask, int[] keyCodes, boolean[] keyExists);
+
+    int getKeyCodeForKeyLocation(int deviceId, int locationKeyCode);
+
+    InputChannel createInputChannel(String name);
+
+    InputChannel createInputMonitor(int displayId, String name, int pid);
+
+    void removeInputChannel(IBinder connectionToken);
+
+    void pilferPointers(IBinder token);
+
+    void setInputFilterEnabled(boolean enable);
+
+    boolean setInTouchMode(boolean inTouchMode, int pid, int uid, boolean hasPermission);
+
+    void setMaximumObscuringOpacityForTouch(float opacity);
+
+    void setBlockUntrustedTouchesMode(int mode);
+
+    int injectInputEvent(InputEvent event, boolean injectIntoUid, int uid, int syncMode,
+            int timeoutMillis, int policyFlags);
+
+    VerifiedInputEvent verifyInputEvent(InputEvent event);
+
+    void toggleCapsLock(int deviceId);
+
+    void displayRemoved(int displayId);
+
+    void setInputDispatchMode(boolean enabled, boolean frozen);
+
+    void setSystemUiLightsOut(boolean lightsOut);
+
+    void setFocusedApplication(int displayId, InputApplicationHandle application);
+
+    void setFocusedDisplay(int displayId);
+
+    boolean transferTouchFocus(IBinder fromChannelToken, IBinder toChannelToken,
+            boolean isDragDrop);
+
+    boolean transferTouch(IBinder destChannelToken);
+
+    void setPointerSpeed(int speed);
+
+    void setPointerAcceleration(float acceleration);
+
+    void setShowTouches(boolean enabled);
+
+    void setInteractive(boolean interactive);
+
+    void reloadCalibration();
+
+    void vibrate(int deviceId, long[] pattern, int[] amplitudes, int repeat, int token);
+
+    void vibrateCombined(int deviceId, long[] pattern, SparseArray<int[]> amplitudes,
+            int repeat, int token);
+
+    void cancelVibrate(int deviceId, int token);
+
+    boolean isVibrating(int deviceId);
+
+    int[] getVibratorIds(int deviceId);
+
+    int getBatteryCapacity(int deviceId);
+
+    int getBatteryStatus(int deviceId);
+
+    List<Light> getLights(int deviceId);
+
+    int getLightPlayerId(int deviceId, int lightId);
+
+    int getLightColor(int deviceId, int lightId);
+
+    void setLightPlayerId(int deviceId, int lightId, int playerId);
+
+    void setLightColor(int deviceId, int lightId, int color);
+
+    void reloadKeyboardLayouts();
+
+    void reloadDeviceAliases();
+
+    String dump();
+
+    void monitor();
+
+    boolean isInputDeviceEnabled(int deviceId);
+
+    void enableInputDevice(int deviceId);
+
+    void disableInputDevice(int deviceId);
+
+    void setPointerIconType(int iconId);
+
+    void reloadPointerIcons();
+
+    void setCustomPointerIcon(PointerIcon icon);
+
+    void requestPointerCapture(IBinder windowToken, boolean enabled);
+
+    boolean canDispatchToDisplay(int deviceId, int displayId);
+
+    void notifyPortAssociationsChanged();
+
+    void changeUniqueIdAssociation();
+
+    void notifyPointerDisplayIdChanged();
+
+    void setDisplayEligibilityForPointerCapture(int displayId, boolean enabled);
+
+    void setMotionClassifierEnabled(boolean enabled);
+
+    InputSensorInfo[] getSensorList(int deviceId);
+
+    boolean flushSensor(int deviceId, int sensorType);
+
+    boolean enableSensor(int deviceId, int sensorType, int samplingPeriodUs,
+            int maxBatchReportLatencyUs);
+
+    void disableSensor(int deviceId, int sensorType);
+
+    void cancelCurrentTouch();
+
+    /** The native implementation of InputManagerService methods. */
+    class NativeImpl implements NativeInputManagerService {
+        /** Pointer to native input manager service object, used by native code. */
+        @SuppressWarnings({"unused", "FieldCanBeLocal"})
+        private final long mPtr;
+
+        NativeImpl(InputManagerService service, Context context, MessageQueue messageQueue) {
+            mPtr = init(service, context, messageQueue);
+        }
+
+        private native long init(InputManagerService service, Context context,
+                MessageQueue messageQueue);
+
+        @Override
+        public native void start();
+
+        @Override
+        public native void setDisplayViewports(DisplayViewport[] viewports);
+
+        @Override
+        public native int getScanCodeState(int deviceId, int sourceMask, int scanCode);
+
+        @Override
+        public native int getKeyCodeState(int deviceId, int sourceMask, int keyCode);
+
+        @Override
+        public native int getSwitchState(int deviceId, int sourceMask, int sw);
+
+        @Override
+        public native boolean hasKeys(int deviceId, int sourceMask, int[] keyCodes,
+                boolean[] keyExists);
+
+        @Override
+        public native int getKeyCodeForKeyLocation(int deviceId, int locationKeyCode);
+
+        @Override
+        public native InputChannel createInputChannel(String name);
+
+        @Override
+        public native InputChannel createInputMonitor(int displayId, String name, int pid);
+
+        @Override
+        public native void removeInputChannel(IBinder connectionToken);
+
+        @Override
+        public native void pilferPointers(IBinder token);
+
+        @Override
+        public native void setInputFilterEnabled(boolean enable);
+
+        @Override
+        public native boolean setInTouchMode(boolean inTouchMode, int pid, int uid,
+                boolean hasPermission);
+
+        @Override
+        public native void setMaximumObscuringOpacityForTouch(float opacity);
+
+        @Override
+        public native void setBlockUntrustedTouchesMode(int mode);
+
+        @Override
+        public native int injectInputEvent(InputEvent event, boolean injectIntoUid, int uid,
+                int syncMode,
+                int timeoutMillis, int policyFlags);
+
+        @Override
+        public native VerifiedInputEvent verifyInputEvent(InputEvent event);
+
+        @Override
+        public native void toggleCapsLock(int deviceId);
+
+        @Override
+        public native void displayRemoved(int displayId);
+
+        @Override
+        public native void setInputDispatchMode(boolean enabled, boolean frozen);
+
+        @Override
+        public native void setSystemUiLightsOut(boolean lightsOut);
+
+        @Override
+        public native void setFocusedApplication(int displayId, InputApplicationHandle application);
+
+        @Override
+        public native void setFocusedDisplay(int displayId);
+
+        @Override
+        public native boolean transferTouchFocus(IBinder fromChannelToken, IBinder toChannelToken,
+                boolean isDragDrop);
+
+        @Override
+        public native boolean transferTouch(IBinder destChannelToken);
+
+        @Override
+        public native void setPointerSpeed(int speed);
+
+        @Override
+        public native void setPointerAcceleration(float acceleration);
+
+        @Override
+        public native void setShowTouches(boolean enabled);
+
+        @Override
+        public native void setInteractive(boolean interactive);
+
+        @Override
+        public native void reloadCalibration();
+
+        @Override
+        public native void vibrate(int deviceId, long[] pattern, int[] amplitudes, int repeat,
+                int token);
+
+        @Override
+        public native void vibrateCombined(int deviceId, long[] pattern,
+                SparseArray<int[]> amplitudes,
+                int repeat, int token);
+
+        @Override
+        public native void cancelVibrate(int deviceId, int token);
+
+        @Override
+        public native boolean isVibrating(int deviceId);
+
+        @Override
+        public native int[] getVibratorIds(int deviceId);
+
+        @Override
+        public native int getBatteryCapacity(int deviceId);
+
+        @Override
+        public native int getBatteryStatus(int deviceId);
+
+        @Override
+        public native List<Light> getLights(int deviceId);
+
+        @Override
+        public native int getLightPlayerId(int deviceId, int lightId);
+
+        @Override
+        public native int getLightColor(int deviceId, int lightId);
+
+        @Override
+        public native void setLightPlayerId(int deviceId, int lightId, int playerId);
+
+        @Override
+        public native void setLightColor(int deviceId, int lightId, int color);
+
+        @Override
+        public native void reloadKeyboardLayouts();
+
+        @Override
+        public native void reloadDeviceAliases();
+
+        @Override
+        public native String dump();
+
+        @Override
+        public native void monitor();
+
+        @Override
+        public native boolean isInputDeviceEnabled(int deviceId);
+
+        @Override
+        public native void enableInputDevice(int deviceId);
+
+        @Override
+        public native void disableInputDevice(int deviceId);
+
+        @Override
+        public native void setPointerIconType(int iconId);
+
+        @Override
+        public native void reloadPointerIcons();
+
+        @Override
+        public native void setCustomPointerIcon(PointerIcon icon);
+
+        @Override
+        public native void requestPointerCapture(IBinder windowToken, boolean enabled);
+
+        @Override
+        public native boolean canDispatchToDisplay(int deviceId, int displayId);
+
+        @Override
+        public native void notifyPortAssociationsChanged();
+
+        @Override
+        public native void changeUniqueIdAssociation();
+
+        @Override
+        public native void notifyPointerDisplayIdChanged();
+
+        @Override
+        public native void setDisplayEligibilityForPointerCapture(int displayId, boolean enabled);
+
+        @Override
+        public native void setMotionClassifierEnabled(boolean enabled);
+
+        @Override
+        public native InputSensorInfo[] getSensorList(int deviceId);
+
+        @Override
+        public native boolean flushSensor(int deviceId, int sensorType);
+
+        @Override
+        public native boolean enableSensor(int deviceId, int sensorType, int samplingPeriodUs,
+                int maxBatchReportLatencyUs);
+
+        @Override
+        public native void disableSensor(int deviceId, int sensorType);
+
+        @Override
+        public native void cancelCurrentTouch();
+    }
+}
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index 17016a6..fa5e450 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -130,6 +130,11 @@
 
 static struct {
     jclass clazz;
+    jfieldID mPtr;
+} gNativeInputManagerServiceImpl;
+
+static struct {
+    jclass clazz;
 } gInputDeviceClassInfo;
 
 static struct {
@@ -259,17 +264,16 @@
 
     void setDisplayViewports(JNIEnv* env, jobjectArray viewportObjArray);
 
-    base::Result<std::unique_ptr<InputChannel>> createInputChannel(JNIEnv* env,
-                                                                   const std::string& name);
-    base::Result<std::unique_ptr<InputChannel>> createInputMonitor(JNIEnv* env, int32_t displayId,
+    base::Result<std::unique_ptr<InputChannel>> createInputChannel(const std::string& name);
+    base::Result<std::unique_ptr<InputChannel>> createInputMonitor(int32_t displayId,
                                                                    const std::string& name,
                                                                    int32_t pid);
-    status_t removeInputChannel(JNIEnv* env, const sp<IBinder>& connectionToken);
+    status_t removeInputChannel(const sp<IBinder>& connectionToken);
     status_t pilferPointers(const sp<IBinder>& token);
 
     void displayRemoved(JNIEnv* env, int32_t displayId);
     void setFocusedApplication(JNIEnv* env, int32_t displayId, jobject applicationHandleObj);
-    void setFocusedDisplay(JNIEnv* env, int32_t displayId);
+    void setFocusedDisplay(int32_t displayId);
     void setInputDispatchMode(bool enabled, bool frozen);
     void setSystemUiLightsOut(bool lightsOut);
     void setPointerSpeed(int32_t speed);
@@ -510,19 +514,18 @@
 }
 
 base::Result<std::unique_ptr<InputChannel>> NativeInputManager::createInputChannel(
-        JNIEnv* /* env */, const std::string& name) {
+        const std::string& name) {
     ATRACE_CALL();
     return mInputManager->getDispatcher().createInputChannel(name);
 }
 
 base::Result<std::unique_ptr<InputChannel>> NativeInputManager::createInputMonitor(
-        JNIEnv* /* env */, int32_t displayId, const std::string& name, int32_t pid) {
+        int32_t displayId, const std::string& name, int32_t pid) {
     ATRACE_CALL();
     return mInputManager->getDispatcher().createInputMonitor(displayId, name, pid);
 }
 
-status_t NativeInputManager::removeInputChannel(JNIEnv* /* env */,
-                                                const sp<IBinder>& connectionToken) {
+status_t NativeInputManager::removeInputChannel(const sp<IBinder>& connectionToken) {
     ATRACE_CALL();
     return mInputManager->getDispatcher().removeInputChannel(connectionToken);
 }
@@ -1000,7 +1003,7 @@
     mInputManager->getDispatcher().setFocusedApplication(displayId, applicationHandle);
 }
 
-void NativeInputManager::setFocusedDisplay(JNIEnv* env, int32_t displayId) {
+void NativeInputManager::setFocusedDisplay(int32_t displayId) {
     mInputManager->getDispatcher().setFocusedDisplay(displayId);
 }
 
@@ -1490,6 +1493,11 @@
 
 // ----------------------------------------------------------------------------
 
+static NativeInputManager* getNativeInputManager(JNIEnv* env, jobject clazz) {
+    return reinterpret_cast<NativeInputManager*>(
+            env->GetLongField(clazz, gNativeInputManagerServiceImpl.mPtr));
+}
+
 static jlong nativeInit(JNIEnv* env, jclass /* clazz */,
         jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
     sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
@@ -1504,8 +1512,8 @@
     return reinterpret_cast<jlong>(im);
 }
 
-static void nativeStart(JNIEnv* env, jclass /* clazz */, jlong ptr) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static void nativeStart(JNIEnv* env, jobject nativeImplObj) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     status_t result = im->getInputManager()->start();
     if (result) {
@@ -1513,39 +1521,39 @@
     }
 }
 
-static void nativeSetDisplayViewports(JNIEnv* env, jclass /* clazz */, jlong ptr,
-        jobjectArray viewportObjArray) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static void nativeSetDisplayViewports(JNIEnv* env, jobject nativeImplObj,
+                                      jobjectArray viewportObjArray) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
     im->setDisplayViewports(env, viewportObjArray);
 }
 
-static jint nativeGetScanCodeState(JNIEnv* /* env */, jclass /* clazz */,
-        jlong ptr, jint deviceId, jint sourceMask, jint scanCode) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static jint nativeGetScanCodeState(JNIEnv* env, jobject nativeImplObj, jint deviceId,
+                                   jint sourceMask, jint scanCode) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     return (jint)im->getInputManager()->getReader().getScanCodeState(deviceId, uint32_t(sourceMask),
                                                                      scanCode);
 }
 
-static jint nativeGetKeyCodeState(JNIEnv* /* env */, jclass /* clazz */,
-        jlong ptr, jint deviceId, jint sourceMask, jint keyCode) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static jint nativeGetKeyCodeState(JNIEnv* env, jobject nativeImplObj, jint deviceId,
+                                  jint sourceMask, jint keyCode) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     return (jint)im->getInputManager()->getReader().getKeyCodeState(deviceId, uint32_t(sourceMask),
                                                                     keyCode);
 }
 
-static jint nativeGetSwitchState(JNIEnv* /* env */, jclass /* clazz */,
-        jlong ptr, jint deviceId, jint sourceMask, jint sw) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static jint nativeGetSwitchState(JNIEnv* env, jobject nativeImplObj, jint deviceId, jint sourceMask,
+                                 jint sw) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     return (jint)im->getInputManager()->getReader().getSwitchState(deviceId, uint32_t(sourceMask),
                                                                    sw);
 }
 
-static jboolean nativeHasKeys(JNIEnv* env, jclass /* clazz */,
-        jlong ptr, jint deviceId, jint sourceMask, jintArray keyCodes, jbooleanArray outFlags) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static jboolean nativeHasKeys(JNIEnv* env, jobject nativeImplObj, jint deviceId, jint sourceMask,
+                              jintArray keyCodes, jbooleanArray outFlags) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     int32_t* codes = env->GetIntArrayElements(keyCodes, nullptr);
     uint8_t* flags = env->GetBooleanArrayElements(outFlags, nullptr);
@@ -1567,9 +1575,9 @@
     return result;
 }
 
-static jint nativeGetKeyCodeForKeyLocation(JNIEnv* env, jclass /* clazz */, jlong ptr,
-                                           jint deviceId, jint locationKeyCode) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static jint nativeGetKeyCodeForKeyLocation(JNIEnv* env, jobject nativeImplObj, jint deviceId,
+                                           jint locationKeyCode) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
     return (jint)im->getInputManager()->getReader().getKeyCodeForKeyLocation(deviceId,
                                                                              locationKeyCode);
 }
@@ -1582,17 +1590,16 @@
     ALOGW("Input channel object '%s' was disposed without first being removed with "
           "the input manager!",
           inputChannel->getName().c_str());
-    im->removeInputChannel(env, inputChannel->getConnectionToken());
+    im->removeInputChannel(inputChannel->getConnectionToken());
 }
 
-static jobject nativeCreateInputChannel(JNIEnv* env, jclass /* clazz */, jlong ptr,
-                                        jstring nameObj) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static jobject nativeCreateInputChannel(JNIEnv* env, jobject nativeImplObj, jstring nameObj) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     ScopedUtfChars nameChars(env, nameObj);
     std::string name = nameChars.c_str();
 
-    base::Result<std::unique_ptr<InputChannel>> inputChannel = im->createInputChannel(env, name);
+    base::Result<std::unique_ptr<InputChannel>> inputChannel = im->createInputChannel(name);
 
     if (!inputChannel.ok()) {
         std::string message = inputChannel.error().message();
@@ -1612,9 +1619,9 @@
     return inputChannelObj;
 }
 
-static jobject nativeCreateInputMonitor(JNIEnv* env, jclass /* clazz */, jlong ptr, jint displayId,
+static jobject nativeCreateInputMonitor(JNIEnv* env, jobject nativeImplObj, jint displayId,
                                         jstring nameObj, jint pid) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     if (displayId == ADISPLAY_ID_NONE) {
         std::string message = "InputChannel used as a monitor must be associated with a display";
@@ -1626,7 +1633,7 @@
     std::string name = nameChars.c_str();
 
     base::Result<std::unique_ptr<InputChannel>> inputChannel =
-            im->createInputMonitor(env, displayId, name, pid);
+            im->createInputMonitor(displayId, name, pid);
 
     if (!inputChannel.ok()) {
         std::string message = inputChannel.error().message();
@@ -1643,11 +1650,11 @@
     return inputChannelObj;
 }
 
-static void nativeRemoveInputChannel(JNIEnv* env, jclass /* clazz */, jlong ptr, jobject tokenObj) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static void nativeRemoveInputChannel(JNIEnv* env, jobject nativeImplObj, jobject tokenObj) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
     sp<IBinder> token = ibinderForJavaObject(env, tokenObj);
 
-    status_t status = im->removeInputChannel(env, token);
+    status_t status = im->removeInputChannel(token);
     if (status && status != BAD_VALUE) { // ignore already removed channel
         std::string message;
         message += StringPrintf("Failed to remove input channel.  status=%d", status);
@@ -1655,47 +1662,44 @@
     }
 }
 
-static void nativePilferPointers(JNIEnv* env, jclass /* clazz */, jlong ptr, jobject tokenObj) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static void nativePilferPointers(JNIEnv* env, jobject nativeImplObj, jobject tokenObj) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
     sp<IBinder> token = ibinderForJavaObject(env, tokenObj);
     im->pilferPointers(token);
 }
 
-static void nativeSetInputFilterEnabled(JNIEnv* /* env */, jclass /* clazz */,
-        jlong ptr, jboolean enabled) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static void nativeSetInputFilterEnabled(JNIEnv* env, jobject nativeImplObj, jboolean enabled) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     im->getInputManager()->getDispatcher().setInputFilterEnabled(enabled);
 }
 
-static jboolean nativeSetInTouchMode(JNIEnv* /* env */, jclass /* clazz */, jlong ptr,
-                                     jboolean inTouchMode, jint pid, jint uid,
-                                     jboolean hasPermission) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static jboolean nativeSetInTouchMode(JNIEnv* env, jobject nativeImplObj, jboolean inTouchMode,
+                                     jint pid, jint uid, jboolean hasPermission) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     return im->getInputManager()->getDispatcher().setInTouchMode(inTouchMode, pid, uid,
                                                                  hasPermission);
 }
 
-static void nativeSetMaximumObscuringOpacityForTouch(JNIEnv* /* env */, jclass /* clazz */,
-                                                     jlong ptr, jfloat opacity) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static void nativeSetMaximumObscuringOpacityForTouch(JNIEnv* env, jobject nativeImplObj,
+                                                     jfloat opacity) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     im->getInputManager()->getDispatcher().setMaximumObscuringOpacityForTouch(opacity);
 }
 
-static void nativeSetBlockUntrustedTouchesMode(JNIEnv* env, jclass /* clazz */, jlong ptr,
-                                               jint mode) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static void nativeSetBlockUntrustedTouchesMode(JNIEnv* env, jobject nativeImplObj, jint mode) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     im->getInputManager()->getDispatcher().setBlockUntrustedTouchesMode(
             static_cast<BlockUntrustedTouchesMode>(mode));
 }
 
-static jint nativeInjectInputEvent(JNIEnv* env, jclass /* clazz */, jlong ptr,
-                                   jobject inputEventObj, jboolean injectIntoUid, jint uid,
-                                   jint syncMode, jint timeoutMillis, jint policyFlags) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static jint nativeInjectInputEvent(JNIEnv* env, jobject nativeImplObj, jobject inputEventObj,
+                                   jboolean injectIntoUid, jint uid, jint syncMode,
+                                   jint timeoutMillis, jint policyFlags) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     const std::optional<int32_t> targetUid = injectIntoUid ? std::make_optional(uid) : std::nullopt;
     // static_cast is safe because the value was already checked at the Java layer
@@ -1735,9 +1739,8 @@
     }
 }
 
-static jobject nativeVerifyInputEvent(JNIEnv* env, jclass /* clazz */, jlong ptr,
-                                      jobject inputEventObj) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static jobject nativeVerifyInputEvent(JNIEnv* env, jobject nativeImplObj, jobject inputEventObj) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) {
         KeyEvent keyEvent;
@@ -1778,56 +1781,53 @@
     }
 }
 
-static void nativeToggleCapsLock(JNIEnv* env, jclass /* clazz */,
-         jlong ptr, jint deviceId) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static void nativeToggleCapsLock(JNIEnv* env, jobject nativeImplObj, jint deviceId) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     im->getInputManager()->getReader().toggleCapsLockState(deviceId);
 }
 
-static void nativeDisplayRemoved(JNIEnv* env, jclass /* clazz */, jlong ptr, jint displayId) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static void nativeDisplayRemoved(JNIEnv* env, jobject nativeImplObj, jint displayId) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     im->displayRemoved(env, displayId);
 }
 
-static void nativeSetFocusedApplication(JNIEnv* env, jclass /* clazz */,
-        jlong ptr, jint displayId, jobject applicationHandleObj) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static void nativeSetFocusedApplication(JNIEnv* env, jobject nativeImplObj, jint displayId,
+                                        jobject applicationHandleObj) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     im->setFocusedApplication(env, displayId, applicationHandleObj);
 }
 
-static void nativeSetFocusedDisplay(JNIEnv* env, jclass /* clazz */,
-        jlong ptr, jint displayId) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static void nativeSetFocusedDisplay(JNIEnv* env, jobject nativeImplObj, jint displayId) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
-    im->setFocusedDisplay(env, displayId);
+    im->setFocusedDisplay(displayId);
 }
 
-static void nativeRequestPointerCapture(JNIEnv* env, jclass /* clazz */, jlong ptr,
-                                        jobject tokenObj, jboolean enabled) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static void nativeRequestPointerCapture(JNIEnv* env, jobject nativeImplObj, jobject tokenObj,
+                                        jboolean enabled) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
     sp<IBinder> windowToken = ibinderForJavaObject(env, tokenObj);
 
     im->requestPointerCapture(windowToken, enabled);
 }
 
-static void nativeSetInputDispatchMode(JNIEnv* /* env */,
-        jclass /* clazz */, jlong ptr, jboolean enabled, jboolean frozen) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static void nativeSetInputDispatchMode(JNIEnv* env, jobject nativeImplObj, jboolean enabled,
+                                       jboolean frozen) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     im->setInputDispatchMode(enabled, frozen);
 }
 
-static void nativeSetSystemUiLightsOut(JNIEnv* /* env */, jclass /* clazz */, jlong ptr,
-                                       jboolean lightsOut) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static void nativeSetSystemUiLightsOut(JNIEnv* env, jobject nativeImplObj, jboolean lightsOut) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     im->setSystemUiLightsOut(lightsOut);
 }
 
-static jboolean nativeTransferTouchFocus(JNIEnv* env, jclass /* clazz */, jlong ptr,
+static jboolean nativeTransferTouchFocus(JNIEnv* env, jobject nativeImplObj,
                                          jobject fromChannelTokenObj, jobject toChannelTokenObj,
                                          jboolean isDragDrop) {
     if (fromChannelTokenObj == nullptr || toChannelTokenObj == nullptr) {
@@ -1837,7 +1837,7 @@
     sp<IBinder> fromChannelToken = ibinderForJavaObject(env, fromChannelTokenObj);
     sp<IBinder> toChannelToken = ibinderForJavaObject(env, toChannelTokenObj);
 
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
     if (im->getInputManager()->getDispatcher().transferTouchFocus(fromChannelToken, toChannelToken,
                                                                   isDragDrop)) {
         return JNI_TRUE;
@@ -1846,11 +1846,11 @@
     }
 }
 
-static jboolean nativeTransferTouch(JNIEnv* env, jclass /* clazz */, jlong ptr,
+static jboolean nativeTransferTouch(JNIEnv* env, jobject nativeImplObj,
                                     jobject destChannelTokenObj) {
     sp<IBinder> destChannelToken = ibinderForJavaObject(env, destChannelTokenObj);
 
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
     if (im->getInputManager()->getDispatcher().transferTouch(destChannelToken)) {
         return JNI_TRUE;
     } else {
@@ -1858,42 +1858,39 @@
     }
 }
 
-static void nativeSetPointerSpeed(JNIEnv* /* env */, jclass /* clazz */, jlong ptr, jint speed) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static void nativeSetPointerSpeed(JNIEnv* env, jobject nativeImplObj, jint speed) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     im->setPointerSpeed(speed);
 }
 
-static void nativeSetPointerAcceleration(JNIEnv* /* env */, jclass /* clazz */, jlong ptr,
-                                         jfloat acceleration) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static void nativeSetPointerAcceleration(JNIEnv* env, jobject nativeImplObj, jfloat acceleration) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     im->setPointerAcceleration(acceleration);
 }
 
-static void nativeSetShowTouches(JNIEnv* /* env */,
-        jclass /* clazz */, jlong ptr, jboolean enabled) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static void nativeSetShowTouches(JNIEnv* env, jobject nativeImplObj, jboolean enabled) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     im->setShowTouches(enabled);
 }
 
-static void nativeSetInteractive(JNIEnv* env,
-        jclass clazz, jlong ptr, jboolean interactive) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static void nativeSetInteractive(JNIEnv* env, jobject nativeImplObj, jboolean interactive) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     im->setInteractive(interactive);
 }
 
-static void nativeReloadCalibration(JNIEnv* env, jclass clazz, jlong ptr) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static void nativeReloadCalibration(JNIEnv* env, jobject nativeImplObj) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     im->reloadCalibration();
 }
 
-static void nativeVibrate(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId,
-                          jlongArray patternObj, jintArray amplitudesObj, jint repeat, jint token) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static void nativeVibrate(JNIEnv* env, jobject nativeImplObj, jint deviceId, jlongArray patternObj,
+                          jintArray amplitudesObj, jint repeat, jint token) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     size_t patternSize = env->GetArrayLength(patternObj);
     if (patternSize > MAX_VIBRATE_PATTERN_SIZE) {
@@ -1926,10 +1923,10 @@
     im->getInputManager()->getReader().vibrate(deviceId, sequence, repeat, token);
 }
 
-static void nativeVibrateCombined(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId,
+static void nativeVibrateCombined(JNIEnv* env, jobject nativeImplObj, jint deviceId,
                                   jlongArray patternObj, jobject amplitudesObj, jint repeat,
                                   jint token) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     size_t patternSize = env->GetArrayLength(patternObj);
 
@@ -1976,21 +1973,20 @@
     im->getInputManager()->getReader().vibrate(deviceId, sequence, repeat, token);
 }
 
-static void nativeCancelVibrate(JNIEnv* /* env */,
-        jclass /* clazz */, jlong ptr, jint deviceId, jint token) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static void nativeCancelVibrate(JNIEnv* env, jobject nativeImplObj, jint deviceId, jint token) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     im->getInputManager()->getReader().cancelVibrate(deviceId, token);
 }
 
-static bool nativeIsVibrating(JNIEnv* /* env */, jclass /* clazz */, jlong ptr, jint deviceId) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static bool nativeIsVibrating(JNIEnv* env, jobject nativeImplObj, jint deviceId) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     return im->getInputManager()->getReader().isVibrating(deviceId);
 }
 
-static jintArray nativeGetVibratorIds(JNIEnv* env, jclass clazz, jlong ptr, jint deviceId) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static jintArray nativeGetVibratorIds(JNIEnv* env, jobject nativeImplObj, jint deviceId) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
     std::vector<int32_t> vibrators = im->getInputManager()->getReader().getVibratorIds(deviceId);
 
     jintArray vibIdArray = env->NewIntArray(vibrators.size());
@@ -2000,8 +1996,8 @@
     return vibIdArray;
 }
 
-static jobject nativeGetLights(JNIEnv* env, jclass clazz, jlong ptr, jint deviceId) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static jobject nativeGetLights(JNIEnv* env, jobject nativeImplObj, jint deviceId) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
     jobject jLights = env->NewObject(gArrayListClassInfo.clazz, gArrayListClassInfo.constructor);
 
     std::vector<InputDeviceLightInfo> lights =
@@ -2045,9 +2041,9 @@
     return jLights;
 }
 
-static jint nativeGetLightPlayerId(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId,
+static jint nativeGetLightPlayerId(JNIEnv* env, jobject nativeImplObj, jint deviceId,
                                    jint lightId) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     std::optional<int32_t> ret =
             im->getInputManager()->getReader().getLightPlayerId(deviceId, lightId);
@@ -2055,54 +2051,51 @@
     return static_cast<jint>(ret.value_or(0));
 }
 
-static jint nativeGetLightColor(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId,
-                                jint lightId) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static jint nativeGetLightColor(JNIEnv* env, jobject nativeImplObj, jint deviceId, jint lightId) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     std::optional<int32_t> ret =
             im->getInputManager()->getReader().getLightColor(deviceId, lightId);
     return static_cast<jint>(ret.value_or(0));
 }
 
-static void nativeSetLightPlayerId(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId,
-                                   jint lightId, jint playerId) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static void nativeSetLightPlayerId(JNIEnv* env, jobject nativeImplObj, jint deviceId, jint lightId,
+                                   jint playerId) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     im->getInputManager()->getReader().setLightPlayerId(deviceId, lightId, playerId);
 }
 
-static void nativeSetLightColor(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId,
-                                jint lightId, jint color) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static void nativeSetLightColor(JNIEnv* env, jobject nativeImplObj, jint deviceId, jint lightId,
+                                jint color) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     im->getInputManager()->getReader().setLightColor(deviceId, lightId, color);
 }
 
-static jint nativeGetBatteryCapacity(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static jint nativeGetBatteryCapacity(JNIEnv* env, jobject nativeImplObj, jint deviceId) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     std::optional<int32_t> ret = im->getInputManager()->getReader().getBatteryCapacity(deviceId);
     return static_cast<jint>(ret.value_or(android::os::IInputConstants::INVALID_BATTERY_CAPACITY));
 }
 
-static jint nativeGetBatteryStatus(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static jint nativeGetBatteryStatus(JNIEnv* env, jobject nativeImplObj, jint deviceId) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     std::optional<int32_t> ret = im->getInputManager()->getReader().getBatteryStatus(deviceId);
     return static_cast<jint>(ret.value_or(BATTERY_STATUS_UNKNOWN));
 }
 
-static void nativeReloadKeyboardLayouts(JNIEnv* /* env */,
-        jclass /* clazz */, jlong ptr) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static void nativeReloadKeyboardLayouts(JNIEnv* env, jobject nativeImplObj) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     im->getInputManager()->getReader().requestRefreshConfiguration(
             InputReaderConfiguration::CHANGE_KEYBOARD_LAYOUTS);
 }
 
-static void nativeReloadDeviceAliases(JNIEnv* /* env */,
-        jclass /* clazz */, jlong ptr) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static void nativeReloadDeviceAliases(JNIEnv* env, jobject nativeImplObj) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     im->getInputManager()->getReader().requestRefreshConfiguration(
             InputReaderConfiguration::CHANGE_DEVICE_ALIAS);
@@ -2117,58 +2110,54 @@
     return out;
 }
 
-static jstring nativeDump(JNIEnv* env, jclass /* clazz */, jlong ptr) {
+static jstring nativeDump(JNIEnv* env, jobject nativeImplObj) {
     std::string dump = dumpInputProperties();
 
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
     im->dump(dump);
 
     return env->NewStringUTF(dump.c_str());
 }
 
-static void nativeMonitor(JNIEnv* /* env */, jclass /* clazz */, jlong ptr) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static void nativeMonitor(JNIEnv* env, jobject nativeImplObj) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     im->getInputManager()->getReader().monitor();
     im->getInputManager()->getDispatcher().monitor();
 }
 
-static jboolean nativeIsInputDeviceEnabled(JNIEnv* env /* env */,
-        jclass /* clazz */, jlong ptr, jint deviceId) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static jboolean nativeIsInputDeviceEnabled(JNIEnv* env, jobject nativeImplObj, jint deviceId) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     return im->getInputManager()->getReader().isInputDeviceEnabled(deviceId);
 }
 
-static void nativeEnableInputDevice(JNIEnv* /* env */,
-        jclass /* clazz */, jlong ptr, jint deviceId) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static void nativeEnableInputDevice(JNIEnv* env, jobject nativeImplObj, jint deviceId) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     im->setInputDeviceEnabled(deviceId, true);
 }
 
-static void nativeDisableInputDevice(JNIEnv* /* env */,
-        jclass /* clazz */, jlong ptr, jint deviceId) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static void nativeDisableInputDevice(JNIEnv* env, jobject nativeImplObj, jint deviceId) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     im->setInputDeviceEnabled(deviceId, false);
 }
 
-static void nativeSetPointerIconType(JNIEnv* /* env */, jclass /* clazz */, jlong ptr, jint iconId) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static void nativeSetPointerIconType(JNIEnv* env, jobject nativeImplObj, jint iconId) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     im->setPointerIconType(iconId);
 }
 
-static void nativeReloadPointerIcons(JNIEnv* /* env */, jclass /* clazz */, jlong ptr) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static void nativeReloadPointerIcons(JNIEnv* env, jobject nativeImplObj) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     im->reloadPointerIcons();
 }
 
-static void nativeSetCustomPointerIcon(JNIEnv* env, jclass /* clazz */,
-                                       jlong ptr, jobject iconObj) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static void nativeSetCustomPointerIcon(JNIEnv* env, jobject nativeImplObj, jobject iconObj) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     PointerIcon pointerIcon;
     status_t result = android_view_PointerIcon_getLoadedIcon(env, iconObj, &pointerIcon);
@@ -2182,40 +2171,38 @@
     im->setCustomPointerIcon(spriteIcon);
 }
 
-static jboolean nativeCanDispatchToDisplay(JNIEnv* env, jclass /* clazz */, jlong ptr,
-        jint deviceId, jint displayId) {
-
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static jboolean nativeCanDispatchToDisplay(JNIEnv* env, jobject nativeImplObj, jint deviceId,
+                                           jint displayId) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
     return im->getInputManager()->getReader().canDispatchToDisplay(deviceId, displayId);
 }
 
-static void nativeNotifyPortAssociationsChanged(JNIEnv* env, jclass /* clazz */, jlong ptr) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static void nativeNotifyPortAssociationsChanged(JNIEnv* env, jobject nativeImplObj) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
     im->getInputManager()->getReader().requestRefreshConfiguration(
             InputReaderConfiguration::CHANGE_DISPLAY_INFO);
 }
 
-static void nativeNotifyPointerDisplayIdChanged(JNIEnv* env, jclass /* clazz */, jlong ptr) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static void nativeNotifyPointerDisplayIdChanged(JNIEnv* env, jobject nativeImplObj) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
     im->notifyPointerDisplayIdChanged();
 }
 
-static void nativeSetDisplayEligibilityForPointerCapture(JNIEnv* env, jclass /* clazz */, jlong ptr,
+static void nativeSetDisplayEligibilityForPointerCapture(JNIEnv* env, jobject nativeImplObj,
                                                          jint displayId, jboolean isEligible) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
     im->getInputManager()->getDispatcher().setDisplayEligibilityForPointerCapture(displayId,
                                                                                   isEligible);
 }
 
-static void nativeChangeUniqueIdAssociation(JNIEnv* env, jclass /* clazz */, jlong ptr) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static void nativeChangeUniqueIdAssociation(JNIEnv* env, jobject nativeImplObj) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
     im->getInputManager()->getReader().requestRefreshConfiguration(
             InputReaderConfiguration::CHANGE_DISPLAY_INFO);
 }
 
-static void nativeSetMotionClassifierEnabled(JNIEnv* /* env */, jclass /* clazz */, jlong ptr,
-                                             jboolean enabled) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static void nativeSetMotionClassifierEnabled(JNIEnv* env, jobject nativeImplObj, jboolean enabled) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     im->setMotionClassifierEnabled(enabled);
 }
@@ -2251,8 +2238,8 @@
     return sensorInfo;
 }
 
-static jobjectArray nativeGetSensorList(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static jobjectArray nativeGetSensorList(JNIEnv* env, jobject nativeImplObj, jint deviceId) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
     std::vector<InputDeviceSensorInfo> sensors =
             im->getInputManager()->getReader().getSensors(deviceId);
 
@@ -2281,10 +2268,10 @@
     return arr;
 }
 
-static jboolean nativeEnableSensor(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId,
+static jboolean nativeEnableSensor(JNIEnv* env, jobject nativeImplObj, jint deviceId,
                                    jint sensorType, jint samplingPeriodUs,
                                    jint maxBatchReportLatencyUs) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     return im->getInputManager()
             ->getReader()
@@ -2293,18 +2280,18 @@
                           std::chrono::microseconds(maxBatchReportLatencyUs));
 }
 
-static void nativeDisableSensor(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId,
+static void nativeDisableSensor(JNIEnv* env, jobject nativeImplObj, jint deviceId,
                                 jint sensorType) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     im->getInputManager()->getReader().disableSensor(deviceId,
                                                      static_cast<InputDeviceSensorType>(
                                                              sensorType));
 }
 
-static jboolean nativeFlushSensor(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId,
+static jboolean nativeFlushSensor(JNIEnv* env, jobject nativeImplObj, jint deviceId,
                                   jint sensorType) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
 
     im->getInputManager()->getReader().flushSensor(deviceId,
                                                    static_cast<InputDeviceSensorType>(sensorType));
@@ -2313,8 +2300,8 @@
                                                                       sensorType));
 }
 
-static void nativeCancelCurrentTouch(JNIEnv* env, jclass /* clazz */, jlong ptr) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+static void nativeCancelCurrentTouch(JNIEnv* env, jobject nativeImplObj) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
     im->getInputManager()->getDispatcher().cancelCurrentTouch();
 }
 
@@ -2322,87 +2309,84 @@
 
 static const JNINativeMethod gInputManagerMethods[] = {
         /* name, signature, funcPtr */
-        {"nativeInit",
+        {"init",
          "(Lcom/android/server/input/InputManagerService;Landroid/content/Context;Landroid/os/"
          "MessageQueue;)J",
          (void*)nativeInit},
-        {"nativeStart", "(J)V", (void*)nativeStart},
-        {"nativeSetDisplayViewports", "(J[Landroid/hardware/display/DisplayViewport;)V",
+        {"start", "()V", (void*)nativeStart},
+        {"setDisplayViewports", "([Landroid/hardware/display/DisplayViewport;)V",
          (void*)nativeSetDisplayViewports},
-        {"nativeGetScanCodeState", "(JIII)I", (void*)nativeGetScanCodeState},
-        {"nativeGetKeyCodeState", "(JIII)I", (void*)nativeGetKeyCodeState},
-        {"nativeGetSwitchState", "(JIII)I", (void*)nativeGetSwitchState},
-        {"nativeHasKeys", "(JII[I[Z)Z", (void*)nativeHasKeys},
-        {"nativeGetKeyCodeForKeyLocation", "(JII)I", (void*)nativeGetKeyCodeForKeyLocation},
-        {"nativeCreateInputChannel", "(JLjava/lang/String;)Landroid/view/InputChannel;",
+        {"getScanCodeState", "(III)I", (void*)nativeGetScanCodeState},
+        {"getKeyCodeState", "(III)I", (void*)nativeGetKeyCodeState},
+        {"getSwitchState", "(III)I", (void*)nativeGetSwitchState},
+        {"hasKeys", "(II[I[Z)Z", (void*)nativeHasKeys},
+        {"getKeyCodeForKeyLocation", "(II)I", (void*)nativeGetKeyCodeForKeyLocation},
+        {"createInputChannel", "(Ljava/lang/String;)Landroid/view/InputChannel;",
          (void*)nativeCreateInputChannel},
-        {"nativeCreateInputMonitor", "(JILjava/lang/String;I)Landroid/view/InputChannel;",
+        {"createInputMonitor", "(ILjava/lang/String;I)Landroid/view/InputChannel;",
          (void*)nativeCreateInputMonitor},
-        {"nativeRemoveInputChannel", "(JLandroid/os/IBinder;)V", (void*)nativeRemoveInputChannel},
-        {"nativePilferPointers", "(JLandroid/os/IBinder;)V", (void*)nativePilferPointers},
-        {"nativeSetInputFilterEnabled", "(JZ)V", (void*)nativeSetInputFilterEnabled},
-        {"nativeSetInTouchMode", "(JZIIZ)Z", (void*)nativeSetInTouchMode},
-        {"nativeSetMaximumObscuringOpacityForTouch", "(JF)V",
+        {"removeInputChannel", "(Landroid/os/IBinder;)V", (void*)nativeRemoveInputChannel},
+        {"pilferPointers", "(Landroid/os/IBinder;)V", (void*)nativePilferPointers},
+        {"setInputFilterEnabled", "(Z)V", (void*)nativeSetInputFilterEnabled},
+        {"setInTouchMode", "(ZIIZ)Z", (void*)nativeSetInTouchMode},
+        {"setMaximumObscuringOpacityForTouch", "(F)V",
          (void*)nativeSetMaximumObscuringOpacityForTouch},
-        {"nativeSetBlockUntrustedTouchesMode", "(JI)V", (void*)nativeSetBlockUntrustedTouchesMode},
-        {"nativeInjectInputEvent", "(JLandroid/view/InputEvent;ZIIII)I",
-         (void*)nativeInjectInputEvent},
-        {"nativeVerifyInputEvent", "(JLandroid/view/InputEvent;)Landroid/view/VerifiedInputEvent;",
+        {"setBlockUntrustedTouchesMode", "(I)V", (void*)nativeSetBlockUntrustedTouchesMode},
+        {"injectInputEvent", "(Landroid/view/InputEvent;ZIIII)I", (void*)nativeInjectInputEvent},
+        {"verifyInputEvent", "(Landroid/view/InputEvent;)Landroid/view/VerifiedInputEvent;",
          (void*)nativeVerifyInputEvent},
-        {"nativeToggleCapsLock", "(JI)V", (void*)nativeToggleCapsLock},
-        {"nativeDisplayRemoved", "(JI)V", (void*)nativeDisplayRemoved},
-        {"nativeSetFocusedApplication", "(JILandroid/view/InputApplicationHandle;)V",
+        {"toggleCapsLock", "(I)V", (void*)nativeToggleCapsLock},
+        {"displayRemoved", "(I)V", (void*)nativeDisplayRemoved},
+        {"setFocusedApplication", "(ILandroid/view/InputApplicationHandle;)V",
          (void*)nativeSetFocusedApplication},
-        {"nativeSetFocusedDisplay", "(JI)V", (void*)nativeSetFocusedDisplay},
-        {"nativeRequestPointerCapture", "(JLandroid/os/IBinder;Z)V",
-         (void*)nativeRequestPointerCapture},
-        {"nativeSetInputDispatchMode", "(JZZ)V", (void*)nativeSetInputDispatchMode},
-        {"nativeSetSystemUiLightsOut", "(JZ)V", (void*)nativeSetSystemUiLightsOut},
-        {"nativeTransferTouchFocus", "(JLandroid/os/IBinder;Landroid/os/IBinder;Z)Z",
+        {"setFocusedDisplay", "(I)V", (void*)nativeSetFocusedDisplay},
+        {"requestPointerCapture", "(Landroid/os/IBinder;Z)V", (void*)nativeRequestPointerCapture},
+        {"setInputDispatchMode", "(ZZ)V", (void*)nativeSetInputDispatchMode},
+        {"setSystemUiLightsOut", "(Z)V", (void*)nativeSetSystemUiLightsOut},
+        {"transferTouchFocus", "(Landroid/os/IBinder;Landroid/os/IBinder;Z)Z",
          (void*)nativeTransferTouchFocus},
-        {"nativeTransferTouch", "(JLandroid/os/IBinder;)Z", (void*)nativeTransferTouch},
-        {"nativeSetPointerSpeed", "(JI)V", (void*)nativeSetPointerSpeed},
-        {"nativeSetPointerAcceleration", "(JF)V", (void*)nativeSetPointerAcceleration},
-        {"nativeSetShowTouches", "(JZ)V", (void*)nativeSetShowTouches},
-        {"nativeSetInteractive", "(JZ)V", (void*)nativeSetInteractive},
-        {"nativeReloadCalibration", "(J)V", (void*)nativeReloadCalibration},
-        {"nativeVibrate", "(JI[J[III)V", (void*)nativeVibrate},
-        {"nativeVibrateCombined", "(JI[JLandroid/util/SparseArray;II)V",
-         (void*)nativeVibrateCombined},
-        {"nativeCancelVibrate", "(JII)V", (void*)nativeCancelVibrate},
-        {"nativeIsVibrating", "(JI)Z", (void*)nativeIsVibrating},
-        {"nativeGetVibratorIds", "(JI)[I", (void*)nativeGetVibratorIds},
-        {"nativeGetLights", "(JI)Ljava/util/List;", (void*)nativeGetLights},
-        {"nativeGetLightPlayerId", "(JII)I", (void*)nativeGetLightPlayerId},
-        {"nativeGetLightColor", "(JII)I", (void*)nativeGetLightColor},
-        {"nativeSetLightPlayerId", "(JIII)V", (void*)nativeSetLightPlayerId},
-        {"nativeSetLightColor", "(JIII)V", (void*)nativeSetLightColor},
-        {"nativeGetBatteryCapacity", "(JI)I", (void*)nativeGetBatteryCapacity},
-        {"nativeGetBatteryStatus", "(JI)I", (void*)nativeGetBatteryStatus},
-        {"nativeReloadKeyboardLayouts", "(J)V", (void*)nativeReloadKeyboardLayouts},
-        {"nativeReloadDeviceAliases", "(J)V", (void*)nativeReloadDeviceAliases},
-        {"nativeDump", "(J)Ljava/lang/String;", (void*)nativeDump},
-        {"nativeMonitor", "(J)V", (void*)nativeMonitor},
-        {"nativeIsInputDeviceEnabled", "(JI)Z", (void*)nativeIsInputDeviceEnabled},
-        {"nativeEnableInputDevice", "(JI)V", (void*)nativeEnableInputDevice},
-        {"nativeDisableInputDevice", "(JI)V", (void*)nativeDisableInputDevice},
-        {"nativeSetPointerIconType", "(JI)V", (void*)nativeSetPointerIconType},
-        {"nativeReloadPointerIcons", "(J)V", (void*)nativeReloadPointerIcons},
-        {"nativeSetCustomPointerIcon", "(JLandroid/view/PointerIcon;)V",
+        {"transferTouch", "(Landroid/os/IBinder;)Z", (void*)nativeTransferTouch},
+        {"setPointerSpeed", "(I)V", (void*)nativeSetPointerSpeed},
+        {"setPointerAcceleration", "(F)V", (void*)nativeSetPointerAcceleration},
+        {"setShowTouches", "(Z)V", (void*)nativeSetShowTouches},
+        {"setInteractive", "(Z)V", (void*)nativeSetInteractive},
+        {"reloadCalibration", "()V", (void*)nativeReloadCalibration},
+        {"vibrate", "(I[J[III)V", (void*)nativeVibrate},
+        {"vibrateCombined", "(I[JLandroid/util/SparseArray;II)V", (void*)nativeVibrateCombined},
+        {"cancelVibrate", "(II)V", (void*)nativeCancelVibrate},
+        {"isVibrating", "(I)Z", (void*)nativeIsVibrating},
+        {"getVibratorIds", "(I)[I", (void*)nativeGetVibratorIds},
+        {"getLights", "(I)Ljava/util/List;", (void*)nativeGetLights},
+        {"getLightPlayerId", "(II)I", (void*)nativeGetLightPlayerId},
+        {"getLightColor", "(II)I", (void*)nativeGetLightColor},
+        {"setLightPlayerId", "(III)V", (void*)nativeSetLightPlayerId},
+        {"setLightColor", "(III)V", (void*)nativeSetLightColor},
+        {"getBatteryCapacity", "(I)I", (void*)nativeGetBatteryCapacity},
+        {"getBatteryStatus", "(I)I", (void*)nativeGetBatteryStatus},
+        {"reloadKeyboardLayouts", "()V", (void*)nativeReloadKeyboardLayouts},
+        {"reloadDeviceAliases", "()V", (void*)nativeReloadDeviceAliases},
+        {"dump", "()Ljava/lang/String;", (void*)nativeDump},
+        {"monitor", "()V", (void*)nativeMonitor},
+        {"isInputDeviceEnabled", "(I)Z", (void*)nativeIsInputDeviceEnabled},
+        {"enableInputDevice", "(I)V", (void*)nativeEnableInputDevice},
+        {"disableInputDevice", "(I)V", (void*)nativeDisableInputDevice},
+        {"setPointerIconType", "(I)V", (void*)nativeSetPointerIconType},
+        {"reloadPointerIcons", "()V", (void*)nativeReloadPointerIcons},
+        {"setCustomPointerIcon", "(Landroid/view/PointerIcon;)V",
          (void*)nativeSetCustomPointerIcon},
-        {"nativeCanDispatchToDisplay", "(JII)Z", (void*)nativeCanDispatchToDisplay},
-        {"nativeNotifyPortAssociationsChanged", "(J)V", (void*)nativeNotifyPortAssociationsChanged},
-        {"nativeChangeUniqueIdAssociation", "(J)V", (void*)nativeChangeUniqueIdAssociation},
-        {"nativeNotifyPointerDisplayIdChanged", "(J)V", (void*)nativeNotifyPointerDisplayIdChanged},
-        {"nativeSetDisplayEligibilityForPointerCapture", "(JIZ)V",
+        {"canDispatchToDisplay", "(II)Z", (void*)nativeCanDispatchToDisplay},
+        {"notifyPortAssociationsChanged", "()V", (void*)nativeNotifyPortAssociationsChanged},
+        {"changeUniqueIdAssociation", "()V", (void*)nativeChangeUniqueIdAssociation},
+        {"notifyPointerDisplayIdChanged", "()V", (void*)nativeNotifyPointerDisplayIdChanged},
+        {"setDisplayEligibilityForPointerCapture", "(IZ)V",
          (void*)nativeSetDisplayEligibilityForPointerCapture},
-        {"nativeSetMotionClassifierEnabled", "(JZ)V", (void*)nativeSetMotionClassifierEnabled},
-        {"nativeGetSensorList", "(JI)[Landroid/hardware/input/InputSensorInfo;",
+        {"setMotionClassifierEnabled", "(Z)V", (void*)nativeSetMotionClassifierEnabled},
+        {"getSensorList", "(I)[Landroid/hardware/input/InputSensorInfo;",
          (void*)nativeGetSensorList},
-        {"nativeEnableSensor", "(JIIII)Z", (void*)nativeEnableSensor},
-        {"nativeDisableSensor", "(JII)V", (void*)nativeDisableSensor},
-        {"nativeFlushSensor", "(JII)Z", (void*)nativeFlushSensor},
-        {"nativeCancelCurrentTouch", "(J)V", (void*)nativeCancelCurrentTouch},
+        {"enableSensor", "(IIII)Z", (void*)nativeEnableSensor},
+        {"disableSensor", "(II)V", (void*)nativeDisableSensor},
+        {"flushSensor", "(II)Z", (void*)nativeFlushSensor},
+        {"cancelCurrentTouch", "()V", (void*)nativeCancelCurrentTouch},
 };
 
 #define FIND_CLASS(var, className) \
@@ -2422,11 +2406,21 @@
         LOG_FATAL_IF(! (var), "Unable to find field " fieldName);
 
 int register_android_server_InputManager(JNIEnv* env) {
-    int res = jniRegisterNativeMethods(env, "com/android/server/input/InputManagerService",
-            gInputManagerMethods, NELEM(gInputManagerMethods));
-    (void) res;  // Faked use when LOG_NDEBUG.
+    int res = jniRegisterNativeMethods(env,
+                                       "com/android/server/input/"
+                                       "NativeInputManagerService$NativeImpl",
+                                       gInputManagerMethods, NELEM(gInputManagerMethods));
+    (void)res; // Faked use when LOG_NDEBUG.
     LOG_FATAL_IF(res < 0, "Unable to register native methods.");
 
+    FIND_CLASS(gNativeInputManagerServiceImpl.clazz,
+               "com/android/server/input/"
+               "NativeInputManagerService$NativeImpl");
+    gNativeInputManagerServiceImpl.clazz =
+            jclass(env->NewGlobalRef(gNativeInputManagerServiceImpl.clazz));
+    gNativeInputManagerServiceImpl.mPtr =
+            env->GetFieldID(gNativeInputManagerServiceImpl.clazz, "mPtr", "J");
+
     // Callbacks
 
     jclass clazz;