Merge "Enabling ClientControllerTest as hostside test" into main
diff --git a/core/java/android/view/inputmethod/InputBinding.java b/core/java/android/view/inputmethod/InputBinding.java
index 2bfeb5a..fedee9d 100644
--- a/core/java/android/view/inputmethod/InputBinding.java
+++ b/core/java/android/view/inputmethod/InputBinding.java
@@ -19,11 +19,13 @@
 import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
 
 /**
  * Information given to an {@link InputMethod} about a client connecting
  * to it.
  */
+@RavenwoodKeepWholeClass
 public final class InputBinding implements Parcelable {
     static final String TAG = "InputBinding";
     
diff --git a/ravenwood/ravenwood-annotation-allowed-classes.txt b/ravenwood/ravenwood-annotation-allowed-classes.txt
index 4a4c290..eb3c55c 100644
--- a/ravenwood/ravenwood-annotation-allowed-classes.txt
+++ b/ravenwood/ravenwood-annotation-allowed-classes.txt
@@ -255,6 +255,7 @@
 android.view.Display$HdrCapabilities
 android.view.Display$Mode
 android.view.DisplayInfo
+android.view.inputmethod.InputBinding
 
 android.hardware.SerialManager
 android.hardware.SerialManagerInternal
diff --git a/services/core/java/com/android/server/inputmethod/IInputMethodClientInvoker.java b/services/core/java/com/android/server/inputmethod/IInputMethodClientInvoker.java
index 84a59b4..7251ac4 100644
--- a/services/core/java/com/android/server/inputmethod/IInputMethodClientInvoker.java
+++ b/services/core/java/com/android/server/inputmethod/IInputMethodClientInvoker.java
@@ -43,6 +43,9 @@
  * the given {@link Handler} thread if {@link IInputMethodClient} is not a proxy object. Be careful
  * about its call ordering characteristics.</p>
  */
+// TODO(b/322895594) Mark this class to be host side test compatible once enabling fw/services in
+//     Ravenwood (mark this class with @RavenwoodKeepWholeClass and #create with @RavenwoodReplace,
+//     so Ravenwood can properly swap create method during test execution).
 final class IInputMethodClientInvoker {
     private static final String TAG = InputMethodManagerService.TAG;
     private static final boolean DEBUG = InputMethodManagerService.DEBUG;
@@ -64,6 +67,16 @@
         return new IInputMethodClientInvoker(inputMethodClient, isProxy, isProxy ? null : handler);
     }
 
+    @AnyThread
+    @Nullable
+    static IInputMethodClientInvoker create$ravenwood(
+            @Nullable IInputMethodClient inputMethodClient, @NonNull Handler handler) {
+        if (inputMethodClient == null) {
+            return null;
+        }
+        return new IInputMethodClientInvoker(inputMethodClient, true, null);
+    }
+
     private IInputMethodClientInvoker(@NonNull IInputMethodClient target,
             boolean isProxy, @Nullable Handler handler) {
         mTarget = target;
diff --git a/services/tests/InputMethodSystemServerTests/Android.bp b/services/tests/InputMethodSystemServerTests/Android.bp
index afd6dbd..b7af58c 100644
--- a/services/tests/InputMethodSystemServerTests/Android.bp
+++ b/services/tests/InputMethodSystemServerTests/Android.bp
@@ -85,7 +85,6 @@
     srcs: [
         "src/com/android/server/inputmethod/**/ClientControllerTest.java",
     ],
-    sdk_version: "test_current",
     auto_gen_config: true,
 }
 
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/ClientControllerTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/ClientControllerTest.java
index dc9631a..9e3d9ec 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/ClientControllerTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/ClientControllerTest.java
@@ -32,10 +32,8 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 import android.view.Display;
-import android.view.inputmethod.InputBinding;
 
 import com.android.internal.inputmethod.IInputMethodClient;
 import com.android.internal.inputmethod.IRemoteInputConnection;
@@ -53,7 +51,7 @@
 public final class ClientControllerTest {
     private static final int ANY_DISPLAY_ID = Display.DEFAULT_DISPLAY;
     private static final int ANY_CALLER_UID = 1;
-    private static final int ANY_CALLER_PID = 1;
+    private static final int ANY_CALLER_PID = 2;
     private static final String SOME_PACKAGE_NAME = "some.package";
 
     @Rule
@@ -82,13 +80,16 @@
         mController = new ClientController(mMockPackageManagerInternal);
     }
 
-    @Test
-    // TODO(b/314150112): Enable host side mode for this test once Ravenwood is enabled for
-    //  inputmethod server classes.
-    @IgnoreUnderRavenwood(blockedBy = {InputBinding.class, IInputMethodClientInvoker.class})
-    public void testAddClient_cannotAddTheSameClientTwice() {
-        var invoker = IInputMethodClientInvoker.create(mClient, mHandler);
+    // TODO(b/322895594): No need to directly invoke create$ravenwood once b/322895594 is fixed.
+    private IInputMethodClientInvoker createInvoker(IInputMethodClient client, Handler handler) {
+        return RavenwoodRule.isOnRavenwood()
+                ? IInputMethodClientInvoker.create$ravenwood(client, handler) :
+                IInputMethodClientInvoker.create(client, handler);
+    }
 
+    @Test
+    public void testAddClient_cannotAddTheSameClientTwice() {
+        final var invoker = createInvoker(mClient, mHandler);
         synchronized (ImfLock.class) {
             mController.addClient(invoker, mConnection, ANY_DISPLAY_ID, ANY_CALLER_UID,
                     ANY_CALLER_PID);
@@ -101,18 +102,17 @@
                         }
                     });
             assertThat(thrown.getMessage()).isEqualTo(
-                    "uid=1/pid=1/displayId=0 is already registered");
+                    "uid=" + ANY_CALLER_UID + "/pid=" + ANY_CALLER_PID
+                            + "/displayId=0 is already registered");
         }
     }
 
     @Test
-    // TODO(b/314150112): Enable host side mode for this test once Ravenwood is enabled for
-    //  inputmethod server classes.
-    @IgnoreUnderRavenwood(blockedBy = {InputBinding.class, IInputMethodClientInvoker.class})
     public void testAddClient() throws Exception {
+        final var invoker = createInvoker(mClient, mHandler);
         synchronized (ImfLock.class) {
-            var invoker = IInputMethodClientInvoker.create(mClient, mHandler);
-            var added = mController.addClient(invoker, mConnection, ANY_DISPLAY_ID, ANY_CALLER_UID,
+            final var added = mController.addClient(invoker, mConnection, ANY_DISPLAY_ID,
+                    ANY_CALLER_UID,
                     ANY_CALLER_PID);
 
             verify(invoker.asBinder()).linkToDeath(any(IBinder.DeathRecipient.class), eq(0));
@@ -121,16 +121,12 @@
     }
 
     @Test
-    // TODO(b/314150112): Enable host side mode for this test once Ravenwood is enabled for
-    //  inputmethod server classes.
-    @IgnoreUnderRavenwood(blockedBy = {InputBinding.class, IInputMethodClientInvoker.class})
     public void testRemoveClient() {
-        var callback = new TestClientControllerCallback();
+        final var invoker = createInvoker(mClient, mHandler);
+        final var callback = new TestClientControllerCallback();
         ClientState added;
         synchronized (ImfLock.class) {
             mController.addClientControllerCallback(callback);
-
-            var invoker = IInputMethodClientInvoker.create(mClient, mHandler);
             added = mController.addClient(invoker, mConnection, ANY_DISPLAY_ID, ANY_CALLER_UID,
                     ANY_CALLER_PID);
             assertThat(mController.getClient(invoker.asBinder())).isSameInstanceAs(added);
@@ -138,21 +134,17 @@
         }
 
         // Test callback
-        var removed = callback.waitForRemovedClient(5, TimeUnit.SECONDS);
+        final var removed = callback.waitForRemovedClient(5, TimeUnit.SECONDS);
         assertThat(removed).isSameInstanceAs(added);
     }
 
     @Test
-    // TODO(b/314150112): Enable host side mode for this test once Ravenwood is enabled for
-    //  inputmethod server classes and updated to newer Mockito with static mock support (mock
-    //  InputMethodUtils#checkIfPackageBelongsToUid instead of PackageManagerInternal#isSameApp)
-    @IgnoreUnderRavenwood(blockedBy = {InputMethodUtils.class})
     public void testVerifyClientAndPackageMatch() {
+        final var invoker = createInvoker(mClient, mHandler);
         when(mMockPackageManagerInternal.isSameApp(eq(SOME_PACKAGE_NAME),  /* flags= */
                 anyLong(), eq(ANY_CALLER_UID), /* userId= */ anyInt())).thenReturn(true);
 
         synchronized (ImfLock.class) {
-            var invoker = IInputMethodClientInvoker.create(mClient, mHandler);
             mController.addClient(invoker, mConnection, ANY_DISPLAY_ID, ANY_CALLER_UID,
                     ANY_CALLER_PID);
             assertThat(