Loading services/core/java/com/android/server/locales/LocaleManagerService.java +7 −4 Original line number Original line Diff line number Diff line Loading @@ -364,16 +364,19 @@ public class LocaleManagerService extends SystemService { // 1.) A normal, non-privileged app querying its own locale. // 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 // 2.) The installer of the given app querying locales of a package installed by said // installer. // 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. // 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 // 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 // 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 // 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 // current input method, and that app is querying locales of the current foreground app. If // necessary permission and fetch locales. // neither conditions matched, check if the caller has the necessary permission and fetch // locales. if (!isPackageOwnedByCaller(appPackageName, userId) if (!isPackageOwnedByCaller(appPackageName, userId) && !isCallerInstaller(appPackageName, userId) && !isCallerInstaller(appPackageName, userId) && !isCallerFromCurrentInputMethod(userId)) { && !(isCallerFromCurrentInputMethod(userId) && mActivityManagerInternal.isAppForeground( getPackageUid(appPackageName, userId)))) { enforceReadAppSpecificLocalesPermission(); enforceReadAppSpecificLocalesPermission(); } } final long token = Binder.clearCallingIdentity(); final long token = Binder.clearCallingIdentity(); Loading services/tests/servicestests/src/com/android/server/locales/LocaleManagerServiceTest.java +25 −1 Original line number Original line Diff line number Diff line Loading @@ -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 @Test public void testGetApplicationLocales_appSpecificConfigAbsent_returnsEmptyList() public void testGetApplicationLocales_appSpecificConfigAbsent_returnsEmptyList() throws Exception { throws Exception { Loading Loading @@ -307,7 +330,7 @@ public class LocaleManagerServiceTest { } } @Test @Test public void testGetApplicationLocales_callerIsCurrentInputMethod_returnsLocales() public void testGetApplicationLocales_currentImeQueryForegroundAppLocales_returnsLocales() throws Exception { throws Exception { doReturn(DEFAULT_UID).when(mMockPackageManager) doReturn(DEFAULT_UID).when(mMockPackageManager) .getPackageUidAsUser(anyString(), any(), anyInt()); .getPackageUidAsUser(anyString(), any(), anyInt()); Loading @@ -316,6 +339,7 @@ public class LocaleManagerServiceTest { String imPkgName = getCurrentInputMethodPackageName(); String imPkgName = getCurrentInputMethodPackageName(); doReturn(Binder.getCallingUid()).when(mMockPackageManager) doReturn(Binder.getCallingUid()).when(mMockPackageManager) .getPackageUidAsUser(eq(imPkgName), any(), anyInt()); .getPackageUidAsUser(eq(imPkgName), any(), anyInt()); doReturn(true).when(mMockActivityManager).isAppForeground(anyInt()); LocaleList locales = LocaleList locales = mLocaleManagerService.getApplicationLocales( mLocaleManagerService.getApplicationLocales( Loading Loading
services/core/java/com/android/server/locales/LocaleManagerService.java +7 −4 Original line number Original line Diff line number Diff line Loading @@ -364,16 +364,19 @@ public class LocaleManagerService extends SystemService { // 1.) A normal, non-privileged app querying its own locale. // 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 // 2.) The installer of the given app querying locales of a package installed by said // installer. // 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. // 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 // 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 // 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 // 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 // current input method, and that app is querying locales of the current foreground app. If // necessary permission and fetch locales. // neither conditions matched, check if the caller has the necessary permission and fetch // locales. if (!isPackageOwnedByCaller(appPackageName, userId) if (!isPackageOwnedByCaller(appPackageName, userId) && !isCallerInstaller(appPackageName, userId) && !isCallerInstaller(appPackageName, userId) && !isCallerFromCurrentInputMethod(userId)) { && !(isCallerFromCurrentInputMethod(userId) && mActivityManagerInternal.isAppForeground( getPackageUid(appPackageName, userId)))) { enforceReadAppSpecificLocalesPermission(); enforceReadAppSpecificLocalesPermission(); } } final long token = Binder.clearCallingIdentity(); final long token = Binder.clearCallingIdentity(); Loading
services/tests/servicestests/src/com/android/server/locales/LocaleManagerServiceTest.java +25 −1 Original line number Original line Diff line number Diff line Loading @@ -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 @Test public void testGetApplicationLocales_appSpecificConfigAbsent_returnsEmptyList() public void testGetApplicationLocales_appSpecificConfigAbsent_returnsEmptyList() throws Exception { throws Exception { Loading Loading @@ -307,7 +330,7 @@ public class LocaleManagerServiceTest { } } @Test @Test public void testGetApplicationLocales_callerIsCurrentInputMethod_returnsLocales() public void testGetApplicationLocales_currentImeQueryForegroundAppLocales_returnsLocales() throws Exception { throws Exception { doReturn(DEFAULT_UID).when(mMockPackageManager) doReturn(DEFAULT_UID).when(mMockPackageManager) .getPackageUidAsUser(anyString(), any(), anyInt()); .getPackageUidAsUser(anyString(), any(), anyInt()); Loading @@ -316,6 +339,7 @@ public class LocaleManagerServiceTest { String imPkgName = getCurrentInputMethodPackageName(); String imPkgName = getCurrentInputMethodPackageName(); doReturn(Binder.getCallingUid()).when(mMockPackageManager) doReturn(Binder.getCallingUid()).when(mMockPackageManager) .getPackageUidAsUser(eq(imPkgName), any(), anyInt()); .getPackageUidAsUser(eq(imPkgName), any(), anyInt()); doReturn(true).when(mMockActivityManager).isAppForeground(anyInt()); LocaleList locales = LocaleList locales = mLocaleManagerService.getApplicationLocales( mLocaleManagerService.getApplicationLocales( Loading