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

Commit 91b69014 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add some tests for concurrent multi-user IME settings" into main

parents 698233b4 c01cae4a
Loading
Loading
Loading
Loading
+157 −1
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.server.inputmethod.multisessiontest;

import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;

import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;

import static com.android.compatibility.common.util.concurrentuser.ConcurrentUserActivityUtils.getResponderUserId;
@@ -28,13 +30,21 @@ import static com.android.server.inputmethod.multisessiontest.TestRequestConstan

import static com.google.common.truth.Truth.assertWithMessage;

import static org.junit.Assume.assumeTrue;

import android.app.UiAutomation;
import android.content.ComponentName;
import android.content.Context;
import android.os.Bundle;
import android.os.UserHandle;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;

import androidx.test.core.app.ActivityScenario;

import com.android.bedstead.harrier.BedsteadJUnit4;
import com.android.bedstead.harrier.DeviceState;
import com.android.compatibility.common.util.SystemUtil;

import org.junit.After;
import org.junit.Before;
@@ -44,8 +54,10 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.io.IOException;
import java.util.List;

@RunWith(BedsteadJUnit4.class)
@Ignore("b/345557347")
public final class ConcurrentMultiUserTest {

    @ClassRule
@@ -55,6 +67,10 @@ public final class ConcurrentMultiUserTest {
    private static final ComponentName TEST_ACTIVITY = new ComponentName(
            getInstrumentation().getTargetContext().getPackageName(),
            MainActivity.class.getName());
    private final Context mContext = getInstrumentation().getTargetContext();
    private final InputMethodManager mInputMethodManager =
            mContext.getSystemService(InputMethodManager.class);
    private final UiAutomation mUiAutomation = getInstrumentation().getUiAutomation();

    private ActivityScenario<MainActivity> mActivityScenario;
    private MainActivity mActivity;
@@ -69,15 +85,18 @@ public final class ConcurrentMultiUserTest {
        // Launch driver activity.
        mActivityScenario = ActivityScenario.launch(MainActivity.class);
        mActivityScenario.onActivity(activity -> mActivity = activity);
        mUiAutomation.adoptShellPermissionIdentity(INTERACT_ACROSS_USERS_FULL);
    }

    @After
    public void tearDown() {
        mUiAutomation.dropShellPermissionIdentity();
        if (mActivityScenario != null) {
            mActivityScenario.close();
        }
    }

    @Ignore("b/345557347")
    @Test
    public void driverShowImeNotAffectPassenger() {
        assertDriverImeHidden();
@@ -87,6 +106,58 @@ public final class ConcurrentMultiUserTest {
        assertPassengerImeHidden();
    }

    @Test
    public void imeListNotEmpty() {
        List<InputMethodInfo> driverImeList = mInputMethodManager.getInputMethodList();
        assertWithMessage("Driver IME list shouldn't be empty")
                .that(driverImeList.isEmpty()).isFalse();

        List<InputMethodInfo> passengerImeList =
                mInputMethodManager.getInputMethodListAsUser(mPeerUserId);
        assertWithMessage("Passenger IME list shouldn't be empty")
                .that(passengerImeList.isEmpty()).isFalse();
    }

    @Test
    public void enabledImeListNotEmpty() {
        List<InputMethodInfo> driverEnabledImeList =
                mInputMethodManager.getEnabledInputMethodList();
        assertWithMessage("Driver enabled IME list shouldn't be empty")
                .that(driverEnabledImeList.isEmpty()).isFalse();

        List<InputMethodInfo> passengerEnabledImeList =
                mInputMethodManager.getEnabledInputMethodListAsUser(UserHandle.of(mPeerUserId));
        assertWithMessage("Passenger enabled IME list shouldn't be empty")
                .that(passengerEnabledImeList.isEmpty()).isFalse();
    }

    @Test
    public void currentImeNotNull() {
        InputMethodInfo driverIme = mInputMethodManager.getCurrentInputMethodInfo();
        assertWithMessage("Driver IME shouldn't be null").that(driverIme).isNotNull();

        InputMethodInfo passengerIme =
                mInputMethodManager.getCurrentInputMethodInfoAsUser(UserHandle.of(mPeerUserId));
        assertWithMessage("Passenger IME shouldn't be null")
                .that(passengerIme).isNotNull();
    }

    @Test
    public void enableDisableImePerUser() throws IOException {
        UserHandle driver = UserHandle.of(mContext.getUserId());
        UserHandle passenger = UserHandle.of(mPeerUserId);
        enableDisableImeForUser(driver, passenger);
        enableDisableImeForUser(passenger, driver);
    }

    @Test
    public void setImePerUser() throws IOException {
        UserHandle driver = UserHandle.of(mContext.getUserId());
        UserHandle passenger = UserHandle.of(mPeerUserId);
        setImeForUser(driver, passenger);
        setImeForUser(passenger, driver);
    }

    private void assertDriverImeHidden() {
        assertWithMessage("Driver IME should be hidden")
                .that(mActivity.isMyImeVisible()).isFalse();
@@ -104,4 +175,89 @@ public final class ConcurrentMultiUserTest {
    private void showDriverImeAndAssert() {
        mActivity.showMyImeAndWait();
    }

    /**
     * Disables/enables IME for {@code user1}, then verifies that the IME settings for {@code user1}
     * has changed as expected and {@code user2} stays the same.
     */
    private void enableDisableImeForUser(UserHandle user1, UserHandle user2) throws IOException {
        List<InputMethodInfo> user1EnabledImeList =
                mInputMethodManager.getEnabledInputMethodListAsUser(user1);
        List<InputMethodInfo> user2EnabledImeList =
                mInputMethodManager.getEnabledInputMethodListAsUser(user2);

        // Disable an IME for user1.
        InputMethodInfo imeToDisable = user1EnabledImeList.get(0);
        SystemUtil.runShellCommand(mUiAutomation,
                "ime disable --user " + user1.getIdentifier() + " " + imeToDisable.getId());
        List<InputMethodInfo> user1EnabledImeList2 =
                mInputMethodManager.getEnabledInputMethodListAsUser(user1);
        List<InputMethodInfo> user2EnabledImeList2 =
                mInputMethodManager.getEnabledInputMethodListAsUser(user2);
        assertWithMessage("User " + user1.getIdentifier() + " IME " + imeToDisable.getId()
                + " should be disabled")
                .that(user1EnabledImeList2.contains(imeToDisable)).isFalse();
        assertWithMessage("Disabling user " + user1.getIdentifier()
                + " IME shouldn't affect user " + user2.getIdentifier())
                .that(user2EnabledImeList2.containsAll(user2EnabledImeList)
                        && user2EnabledImeList.containsAll(user2EnabledImeList2))
                .isTrue();

        // Enable the IME.
        SystemUtil.runShellCommand(mUiAutomation,
                "ime enable --user " + user1.getIdentifier() + " " + imeToDisable.getId());
        List<InputMethodInfo> user1EnabledImeList3 =
                mInputMethodManager.getEnabledInputMethodListAsUser(user1);
        List<InputMethodInfo> user2EnabledImeList3 =
                mInputMethodManager.getEnabledInputMethodListAsUser(user2);
        assertWithMessage("User " + user1.getIdentifier() + " IME " + imeToDisable.getId()
                + " should be enabled").that(user1EnabledImeList3.contains(imeToDisable)).isTrue();
        assertWithMessage("Enabling user " + user1.getIdentifier()
                + " IME shouldn't affect user " + user2.getIdentifier())
                .that(user2EnabledImeList2.containsAll(user2EnabledImeList3)
                        && user2EnabledImeList3.containsAll(user2EnabledImeList2))
                .isTrue();
    }

    /**
     * Sets/resets IME for {@code user1}, then verifies that the IME settings for {@code user1}
     * has changed as expected and {@code user2} stays the same.
     */
    private void setImeForUser(UserHandle user1, UserHandle user2) throws IOException {
        // Reset IME for user1.
        SystemUtil.runShellCommand(mUiAutomation,
                "ime reset --user " + user1.getIdentifier());

        List<InputMethodInfo> user1EnabledImeList =
                mInputMethodManager.getEnabledInputMethodListAsUser(user1);
        assumeTrue("There must be at least two IME to test", user1EnabledImeList.size() >= 2);
        InputMethodInfo user1Ime = mInputMethodManager.getCurrentInputMethodInfoAsUser(user1);
        InputMethodInfo user2Ime = mInputMethodManager.getCurrentInputMethodInfoAsUser(user2);

        // Set to another IME for user1.
        InputMethodInfo anotherIme = null;
        for (InputMethodInfo info : user1EnabledImeList) {
            if (!info.equals(user1Ime)) {
                anotherIme = info;
            }
        }
        SystemUtil.runShellCommand(mUiAutomation,
                "ime set --user " + user1.getIdentifier() + " " + anotherIme.getId());
        InputMethodInfo user1Ime2 = mInputMethodManager.getCurrentInputMethodInfoAsUser(user1);
        InputMethodInfo user2Ime2 = mInputMethodManager.getCurrentInputMethodInfoAsUser(user2);
        assertWithMessage("The current IME for user " + user1.getIdentifier() + " is wrong")
                .that(user1Ime2).isEqualTo(anotherIme);
        assertWithMessage("The current IME for user " + user2.getIdentifier() + " shouldn't change")
                .that(user2Ime2).isEqualTo(user2Ime);

        // Reset IME for user1.
        SystemUtil.runShellCommand(mUiAutomation,
                "ime reset --user " + user1.getIdentifier());
        InputMethodInfo user1Ime3 = mInputMethodManager.getCurrentInputMethodInfoAsUser(user1);
        InputMethodInfo user2Ime3 = mInputMethodManager.getCurrentInputMethodInfoAsUser(user2);
        assertWithMessage("The current IME for user " + user1.getIdentifier() + " is wrong")
                .that(user1Ime3).isEqualTo(user1Ime);
        assertWithMessage("The current IME for user " + user2.getIdentifier() + " shouldn't change")
                .that(user2Ime3).isEqualTo(user2Ime);
    }
}
+4 −2
Original line number Diff line number Diff line
@@ -87,11 +87,13 @@ public final class MainActivity extends ConcurrentUserActivityBase {
            }
            if (!mImm.showSoftInput(mEditor, /* flags= */ 0)) {
                Log.e(TAG, String.format("Failed to show my IME as user %d, "
                                + "mEditor:focused=%b,hasWindowFocus=%b", getUserId(),
                                + "mEditor:focused=%b,hasWindowFocus=%b",
                        Process.myUserHandle().getIdentifier(),
                        mEditor.isFocused(), mEditor.hasWindowFocus()));
            }
        });
        PollingCheck.waitFor(WAIT_IME_TIMEOUT_MS, () -> isMyImeVisible(),
                String.format("My IME (user %d) didn't show up", getUserId()));
                String.format("My IME (user %d) didn't show up",
                        Process.myUserHandle().getIdentifier()));
    }
}