Merge "Update user related fields when InputMethodSettings#switchCurrentUser"

This commit is contained in:
TreeHugger Robot
2022-12-10 03:13:50 +00:00
committed by Android (Google) Code Review
2 changed files with 117 additions and 6 deletions

View File

@@ -212,9 +212,9 @@ final class InputMethodUtils {
new TextUtils.SimpleStringSplitter(INPUT_METHOD_SUBTYPE_SEPARATOR);
@NonNull
private final Context mUserAwareContext;
private final Resources mRes;
private final ContentResolver mResolver;
private Context mUserAwareContext;
private Resources mRes;
private ContentResolver mResolver;
private final ArrayMap<String, InputMethodInfo> mMethodMap;
/**
@@ -272,15 +272,19 @@ final class InputMethodUtils {
return imsList;
}
InputMethodSettings(@NonNull Context context,
ArrayMap<String, InputMethodInfo> methodMap, @UserIdInt int userId,
boolean copyOnWrite) {
private void initContentWithUserContext(@NonNull Context context, @UserIdInt int userId) {
mUserAwareContext = context.getUserId() == userId
? context
: context.createContextAsUser(UserHandle.of(userId), 0 /* flags */);
mRes = mUserAwareContext.getResources();
mResolver = mUserAwareContext.getContentResolver();
}
InputMethodSettings(@NonNull Context context,
ArrayMap<String, InputMethodInfo> methodMap, @UserIdInt int userId,
boolean copyOnWrite) {
mMethodMap = methodMap;
initContentWithUserContext(context, userId);
switchCurrentUser(userId, copyOnWrite);
}
@@ -301,6 +305,9 @@ final class InputMethodUtils {
mEnabledInputMethodsStrCache = "";
// TODO: mCurrentProfileIds should be cleared here.
}
if (mUserAwareContext.getUserId() != userId) {
initContentWithUserContext(mUserAwareContext, userId);
}
mCurrentUserId = userId;
mCopyOnWrite = copyOnWrite;
// TODO: mCurrentProfileIds should be updated here.

View File

@@ -25,8 +25,16 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.ContentResolver;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.IContentProvider;
import android.content.pm.ApplicationInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
@@ -35,6 +43,9 @@ import android.content.res.Resources;
import android.os.Build;
import android.os.LocaleList;
import android.os.Parcel;
import android.os.UserHandle;
import android.provider.Settings;
import android.test.mock.MockContentResolver;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.IntArray;
@@ -1214,6 +1225,42 @@ public class InputMethodUtilsTest {
StartInputFlags.VIEW_HAS_FOCUS | StartInputFlags.IS_TEXT_EDITOR));
}
@Test
public void testInputMethodSettings_SwitchCurrentUser() {
TestContext ownerUserContext = createMockContext(0 /* userId */);
final InputMethodInfo systemIme = createFakeInputMethodInfo(
"SystemIme", "fake.latin", true /* isSystem */);
final InputMethodInfo nonSystemIme = createFakeInputMethodInfo("NonSystemIme",
"fake.voice0", false /* isSystem */);
final ArrayMap<String, InputMethodInfo> methodMap = new ArrayMap<>();
methodMap.put(systemIme.getId(), systemIme);
// Init InputMethodSettings for the owner user (userId=0), verify calls can get the
// corresponding user's context, contentResolver and the resources configuration.
InputMethodUtils.InputMethodSettings settings = new InputMethodUtils.InputMethodSettings(
ownerUserContext, methodMap, 0 /* userId */, true);
assertEquals(0, settings.getCurrentUserId());
settings.isShowImeWithHardKeyboardEnabled();
verify(ownerUserContext.getContentResolver(), atLeastOnce()).getAttributionSource();
settings.getEnabledInputMethodSubtypeListLocked(nonSystemIme, true);
verify(ownerUserContext.getResources(), atLeastOnce()).getConfiguration();
// Calling switchCurrentUser to the secondary user (userId=10), verify calls can get the
// corresponding user's context, contentResolver and the resources configuration.
settings.switchCurrentUser(10 /* userId */, true);
assertEquals(10, settings.getCurrentUserId());
settings.isShowImeWithHardKeyboardEnabled();
verify(TestContext.getSecondaryUserContext().getContentResolver(),
atLeastOnce()).getAttributionSource();
settings.getEnabledInputMethodSubtypeListLocked(nonSystemIme, true);
verify(TestContext.getSecondaryUserContext().getResources(),
atLeastOnce()).getConfiguration();
}
private static IntArray createSubtypeHashCodeArrayFromStr(String subtypeHashCodesStr) {
final IntArray subtypes = new IntArray();
final TextUtils.SimpleStringSplitter imeSubtypeSplitter =
@@ -1236,6 +1283,63 @@ public class InputMethodUtilsTest {
imeId, createSubtypeHashCodeArrayFromStr(enabledSubtypeHashCodesStr)));
}
private static TestContext createMockContext(int userId) {
return new TestContext(InstrumentationRegistry.getInstrumentation()
.getTargetContext(), userId);
}
private static class TestContext extends ContextWrapper {
private int mUserId;
private ContentResolver mResolver;
private Resources mResources;
private static TestContext sSecondaryUserContext;
TestContext(@NonNull Context context, int userId) {
super(context);
mUserId = userId;
mResolver = mock(MockContentResolver.class);
when(mResolver.acquireProvider(Settings.Secure.CONTENT_URI)).thenReturn(
mock(IContentProvider.class));
mResources = mock(Resources.class);
final Configuration configuration = new Configuration();
if (userId == 0) {
configuration.setLocale(LOCALE_EN_US);
} else {
configuration.setLocale(LOCALE_FR_CA);
}
doReturn(configuration).when(mResources).getConfiguration();
}
@Override
public Context createContextAsUser(UserHandle user, int flags) {
if (user.getIdentifier() != UserHandle.USER_SYSTEM) {
return sSecondaryUserContext = new TestContext(this, user.getIdentifier());
}
return this;
}
@Override
public int getUserId() {
return mUserId;
}
@Override
public ContentResolver getContentResolver() {
return mResolver;
}
@Override
public Resources getResources() {
return mResources;
}
static Context getSecondaryUserContext() {
return sSecondaryUserContext;
}
}
@Test
public void updateEnabledImeStringTest() {
// No change cases