From 221907c91e86334a30d26ebb408b82ad7434fddc Mon Sep 17 00:00:00 2001 From: Josh Hou Date: Wed, 26 Oct 2022 14:40:30 +0800 Subject: [PATCH] [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 --- .../server/locales/LocaleManagerService.java | 11 +++++--- .../locales/LocaleManagerServiceTest.java | 26 ++++++++++++++++++- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/services/core/java/com/android/server/locales/LocaleManagerService.java b/services/core/java/com/android/server/locales/LocaleManagerService.java index 364f6db28f03a..4ce03205fc1c9 100644 --- a/services/core/java/com/android/server/locales/LocaleManagerService.java +++ b/services/core/java/com/android/server/locales/LocaleManagerService.java @@ -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(); diff --git a/services/tests/servicestests/src/com/android/server/locales/LocaleManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/locales/LocaleManagerServiceTest.java index dbcd38c35958d..dc9f907377138 100644 --- a/services/tests/servicestests/src/com/android/server/locales/LocaleManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/locales/LocaleManagerServiceTest.java @@ -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(