[Panlingual] Expose the API for the current IME to get locales of the

foreground app

Give the current IME the ability to fetch locales of the foreground app in order to enable the corresponding keyboard

Bug: 248406206
Test: atest LocaleManagerServiceTest
      atest LocaleManagerTests
Change-Id: I159ea4d94799e32b9f3e17a09deb5ffad06b2a71
This commit is contained in:
Josh Hou
2022-10-26 14:40:30 +08:00
parent 1c5c28968a
commit 221907c91e
2 changed files with 32 additions and 5 deletions

View File

@@ -364,16 +364,19 @@ public class LocaleManagerService extends SystemService {
// 1.) A normal, non-privileged app querying its own locale.
// 2.) The installer of the given app querying locales of a package installed by said
// installer.
// 3.) The current input method querying locales of another package.
// 3.) The current input method querying locales of the current foreground app.
// 4.) A privileged system service querying locales of another package.
// The least privileged case is a normal app performing a query, so check that first and get
// locales if the package name is owned by the app. Next check if the calling app is the
// installer of the given app and get locales. Finally check if the calling app is the
// current input method. If neither conditions matched, check if the caller has the
// necessary permission and fetch locales.
// current input method, and that app is querying locales of the current foreground app. If
// neither conditions matched, check if the caller has the necessary permission and fetch
// locales.
if (!isPackageOwnedByCaller(appPackageName, userId)
&& !isCallerInstaller(appPackageName, userId)
&& !isCallerFromCurrentInputMethod(userId)) {
&& !(isCallerFromCurrentInputMethod(userId)
&& mActivityManagerInternal.isAppForeground(
getPackageUid(appPackageName, userId)))) {
enforceReadAppSpecificLocalesPermission();
}
final long token = Binder.clearCallingIdentity();

View File

@@ -229,6 +229,29 @@ public class LocaleManagerServiceTest {
}
}
@Test(expected = SecurityException.class)
public void testGetApplicationLocales_currentImeQueryNonForegroundAppLocales_fails()
throws Exception {
doReturn(DEFAULT_UID).when(mMockPackageManager)
.getPackageUidAsUser(anyString(), any(), anyInt());
doReturn(new PackageConfig(/* nightMode = */ 0, DEFAULT_LOCALES))
.when(mMockActivityTaskManager).getApplicationConfig(anyString(), anyInt());
String imPkgName = getCurrentInputMethodPackageName();
doReturn(Binder.getCallingUid()).when(mMockPackageManager)
.getPackageUidAsUser(eq(imPkgName), any(), anyInt());
doReturn(false).when(mMockActivityManager).isAppForeground(anyInt());
setUpFailingPermissionCheckFor(Manifest.permission.READ_APP_SPECIFIC_LOCALES);
try {
mLocaleManagerService.getApplicationLocales(DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID);
fail("Expected SecurityException");
} finally {
verify(mMockContext).enforceCallingOrSelfPermission(
eq(android.Manifest.permission.READ_APP_SPECIFIC_LOCALES),
anyString());
}
}
@Test
public void testGetApplicationLocales_appSpecificConfigAbsent_returnsEmptyList()
throws Exception {
@@ -307,7 +330,7 @@ public class LocaleManagerServiceTest {
}
@Test
public void testGetApplicationLocales_callerIsCurrentInputMethod_returnsLocales()
public void testGetApplicationLocales_currentImeQueryForegroundAppLocales_returnsLocales()
throws Exception {
doReturn(DEFAULT_UID).when(mMockPackageManager)
.getPackageUidAsUser(anyString(), any(), anyInt());
@@ -316,6 +339,7 @@ public class LocaleManagerServiceTest {
String imPkgName = getCurrentInputMethodPackageName();
doReturn(Binder.getCallingUid()).when(mMockPackageManager)
.getPackageUidAsUser(eq(imPkgName), any(), anyInt());
doReturn(true).when(mMockActivityManager).isAppForeground(anyInt());
LocaleList locales =
mLocaleManagerService.getApplicationLocales(