Loading services/core/java/com/android/server/locales/AppLocaleChangedAtomRecord.java +24 −4 Original line number Diff line number Diff line Loading @@ -20,24 +20,32 @@ import static android.os.Process.INVALID_UID; import com.android.internal.util.FrameworkStatsLog; import java.util.Locale; /** * Holds data used to report the ApplicationLocalesChanged atom. */ public final class AppLocaleChangedAtomRecord { private static final String DEFAULT_PREFIX = "default-"; final int mCallingUid; int mTargetUid = INVALID_UID; String mNewLocales = ""; String mPrevLocales = ""; String mNewLocales = DEFAULT_PREFIX; String mPrevLocales = DEFAULT_PREFIX; int mStatus = FrameworkStatsLog .APPLICATION_LOCALES_CHANGED__STATUS__STATUS_UNSPECIFIED; int mCaller = FrameworkStatsLog .APPLICATION_LOCALES_CHANGED__CALLER__CALLER_UNKNOWN; AppLocaleChangedAtomRecord(int callingUid) { this.mCallingUid = callingUid; Locale defaultLocale = Locale.getDefault(); if (defaultLocale != null) { this.mNewLocales = DEFAULT_PREFIX + defaultLocale.toLanguageTag(); this.mPrevLocales = DEFAULT_PREFIX + defaultLocale.toLanguageTag(); } } void setNewLocales(String newLocales) { this.mNewLocales = newLocales; this.mNewLocales = convertEmptyLocales(newLocales); } void setTargetUid(int targetUid) { Loading @@ -45,7 +53,7 @@ public final class AppLocaleChangedAtomRecord { } void setPrevLocales(String prevLocales) { this.mPrevLocales = prevLocales; this.mPrevLocales = convertEmptyLocales(prevLocales); } void setStatus(int status) { Loading @@ -55,4 +63,16 @@ public final class AppLocaleChangedAtomRecord { void setCaller(int caller) { this.mCaller = caller; } private String convertEmptyLocales(String locales) { String target = locales; if ("".equals(locales)) { Locale defaultLocale = Locale.getDefault(); if (defaultLocale != null) { target = DEFAULT_PREFIX + defaultLocale.toLanguageTag(); } } return target; } } services/core/java/com/android/server/locales/LocaleManagerBackupHelper.java +6 −2 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import android.util.SparseArray; import android.util.Xml; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.XmlUtils; import com.android.modules.utils.TypedXmlPullParser; import com.android.modules.utils.TypedXmlSerializer; Loading Loading @@ -377,7 +378,8 @@ class LocaleManagerBackupHelper { // Restore the locale immediately try { mLocaleManagerService.setApplicationLocales(pkgName, userId, LocaleList.forLanguageTags(localesInfo.mLocales), localesInfo.mSetFromDelegate); LocaleList.forLanguageTags(localesInfo.mLocales), localesInfo.mSetFromDelegate, FrameworkStatsLog.APPLICATION_LOCALES_CHANGED__CALLER__CALLER_BACKUP_RESTORE); if (DEBUG) { Slog.d(TAG, "Restored locales=" + localesInfo.mLocales + " fromDelegate=" + localesInfo.mSetFromDelegate + " for package=" + pkgName); Loading Loading @@ -662,7 +664,9 @@ class LocaleManagerBackupHelper { try { LocaleConfig localeConfig = new LocaleConfig( mContext.createPackageContextAsUser(packageName, 0, UserHandle.of(userId))); mLocaleManagerService.removeUnsupportedAppLocales(packageName, userId, localeConfig); mLocaleManagerService.removeUnsupportedAppLocales(packageName, userId, localeConfig, FrameworkStatsLog .APPLICATION_LOCALES_CHANGED__CALLER__CALLER_APP_UPDATE_LOCALES_CHANGE); } catch (PackageManager.NameNotFoundException e) { Slog.e(TAG, "Can not found the package name : " + packageName + " / " + e); } Loading services/core/java/com/android/server/locales/LocaleManagerService.java +21 −8 Original line number Diff line number Diff line Loading @@ -182,8 +182,11 @@ public class LocaleManagerService extends SystemService { @Override public void setApplicationLocales(@NonNull String appPackageName, @UserIdInt int userId, @NonNull LocaleList locales, boolean fromDelegate) throws RemoteException { int caller = fromDelegate ? FrameworkStatsLog.APPLICATION_LOCALES_CHANGED__CALLER__CALLER_DELEGATE : FrameworkStatsLog.APPLICATION_LOCALES_CHANGED__CALLER__CALLER_APPS; LocaleManagerService.this.setApplicationLocales(appPackageName, userId, locales, fromDelegate); fromDelegate, caller); } @Override Loading Loading @@ -226,13 +229,14 @@ public class LocaleManagerService extends SystemService { * Sets the current UI locales for a specified app. */ public void setApplicationLocales(@NonNull String appPackageName, @UserIdInt int userId, @NonNull LocaleList locales, boolean fromDelegate) @NonNull LocaleList locales, boolean fromDelegate, int caller) throws RemoteException, IllegalArgumentException { AppLocaleChangedAtomRecord atomRecordForMetrics = new AppLocaleChangedAtomRecord(Binder.getCallingUid()); try { requireNonNull(appPackageName); requireNonNull(locales); atomRecordForMetrics.setCaller(caller); atomRecordForMetrics.setNewLocales(locales.toLanguageTags()); //Allow apps with INTERACT_ACROSS_USERS permission to set locales for different user. userId = mActivityManagerInternal.handleIncomingUser( Loading Loading @@ -273,8 +277,8 @@ public class LocaleManagerService extends SystemService { + " and user " + userId); } atomRecordForMetrics.setPrevLocales(getApplicationLocalesUnchecked(appPackageName, userId) .toLanguageTags()); atomRecordForMetrics.setPrevLocales( getApplicationLocalesUnchecked(appPackageName, userId).toLanguageTags()); final ActivityTaskManagerInternal.PackageConfigurationUpdater updater = mActivityTaskManagerInternal.createPackageConfigurationUpdater(appPackageName, userId); Loading Loading @@ -619,7 +623,10 @@ public class LocaleManagerService extends SystemService { Slog.d(TAG, "remove the override LocaleConfig"); file.delete(); } removeUnsupportedAppLocales(appPackageName, userId, resLocaleConfig); removeUnsupportedAppLocales(appPackageName, userId, resLocaleConfig, FrameworkStatsLog .APPLICATION_LOCALES_CHANGED__CALLER__CALLER_DYNAMIC_LOCALES_CHANGE ); atomRecord.setOverrideRemoved(true); atomRecord.setStatus(FrameworkStatsLog .APP_SUPPORTED_LOCALES_CHANGED__STATUS__SUCCESS); Loading Loading @@ -661,7 +668,10 @@ public class LocaleManagerService extends SystemService { } atomicFile.finishWrite(stream); // Clear per-app locales if they are not in the override LocaleConfig. removeUnsupportedAppLocales(appPackageName, userId, overrideLocaleConfig); removeUnsupportedAppLocales(appPackageName, userId, overrideLocaleConfig, FrameworkStatsLog .APPLICATION_LOCALES_CHANGED__CALLER__CALLER_DYNAMIC_LOCALES_CHANGE ); if (overrideLocaleConfig.isSameLocaleConfig(resLocaleConfig)) { Slog.d(TAG, "setOverrideLocaleConfig, same as the app's LocaleConfig"); atomRecord.setSameAsResConfig(true); Loading @@ -678,9 +688,12 @@ public class LocaleManagerService extends SystemService { /** * Checks if the per-app locales are in the LocaleConfig. Per-app locales missing from the * LocaleConfig will be removed. * * <p><b>Note:</b> Check whether to remove the per-app locales when the app is upgraded or * the LocaleConfig is overridden. */ void removeUnsupportedAppLocales(String appPackageName, int userId, LocaleConfig localeConfig) { LocaleConfig localeConfig, int caller) { LocaleList appLocales = getApplicationLocalesUnchecked(appPackageName, userId); // Remove the per-app locales from the locale list if they don't exist in the LocaleConfig. boolean resetAppLocales = false; Loading @@ -707,7 +720,7 @@ public class LocaleManagerService extends SystemService { try { setApplicationLocales(appPackageName, userId, new LocaleList(newAppLocales.toArray(locales)), mBackupHelper.areLocalesSetFromDelegate(userId, appPackageName)); mBackupHelper.areLocalesSetFromDelegate(userId, appPackageName), caller); } catch (RemoteException | IllegalArgumentException e) { Slog.e(TAG, "Could not set locales for " + appPackageName, e); } Loading services/tests/servicestests/src/com/android/server/locales/LocaleManagerBackupRestoreTest.java +23 −13 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ import android.util.Xml; import androidx.test.ext.junit.runners.AndroidJUnit4; import com.android.internal.content.PackageMonitor; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.XmlUtils; import com.android.modules.utils.TypedXmlPullParser; import com.android.modules.utils.TypedXmlSerializer; Loading Loading @@ -264,7 +265,8 @@ public class LocaleManagerBackupRestoreTest { // Locales were restored verify(mMockLocaleManagerService, times(1)).setApplicationLocales(DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID, DEFAULT_LOCALES, false); DEFAULT_USER_ID, DEFAULT_LOCALES, false, FrameworkStatsLog .APPLICATION_LOCALES_CHANGED__CALLER__CALLER_BACKUP_RESTORE); checkStageDataDoesNotExist(DEFAULT_USER_ID); } Loading @@ -280,7 +282,8 @@ public class LocaleManagerBackupRestoreTest { // Locales were restored verify(mMockLocaleManagerService, times(1)).setApplicationLocales(DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID, DEFAULT_LOCALES, false); DEFAULT_USER_ID, DEFAULT_LOCALES, false, FrameworkStatsLog .APPLICATION_LOCALES_CHANGED__CALLER__CALLER_BACKUP_RESTORE); checkStageDataDoesNotExist(DEFAULT_USER_ID); mBackupHelper.persistLocalesModificationInfo(DEFAULT_USER_ID, DEFAULT_PACKAGE_NAME, false, Loading @@ -303,7 +306,8 @@ public class LocaleManagerBackupRestoreTest { // Locales were restored verify(mMockLocaleManagerService, times(1)).setApplicationLocales(DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID, DEFAULT_LOCALES, true); DEFAULT_USER_ID, DEFAULT_LOCALES, true, FrameworkStatsLog .APPLICATION_LOCALES_CHANGED__CALLER__CALLER_BACKUP_RESTORE); checkStageDataDoesNotExist(DEFAULT_USER_ID); mBackupHelper.persistLocalesModificationInfo(DEFAULT_USER_ID, DEFAULT_PACKAGE_NAME, true, Loading @@ -327,7 +331,8 @@ public class LocaleManagerBackupRestoreTest { // Locales were restored verify(mMockLocaleManagerService, times(1)).setApplicationLocales( DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID, DEFAULT_LOCALES, true); DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID, DEFAULT_LOCALES, true, FrameworkStatsLog.APPLICATION_LOCALES_CHANGED__CALLER__CALLER_BACKUP_RESTORE); checkStageDataDoesNotExist(DEFAULT_USER_ID); mBackupHelper.persistLocalesModificationInfo(DEFAULT_USER_ID, DEFAULT_PACKAGE_NAME, true, Loading Loading @@ -369,7 +374,8 @@ public class LocaleManagerBackupRestoreTest { mBackupHelper.stageAndApplyRestoredPayload(out.toByteArray(), DEFAULT_USER_ID); verify(mMockLocaleManagerService, times(1)).setApplicationLocales(pkgNameA, DEFAULT_USER_ID, LocaleList.forLanguageTags(langTagsA), true); LocaleList.forLanguageTags(langTagsA), true, FrameworkStatsLog .APPLICATION_LOCALES_CHANGED__CALLER__CALLER_BACKUP_RESTORE); pkgLocalesMap.remove(pkgNameA); Loading Loading @@ -422,11 +428,12 @@ public class LocaleManagerBackupRestoreTest { // Restore locales only for myAppB. verify(mMockLocaleManagerService, times(0)).setApplicationLocales(eq(pkgNameA), anyInt(), any(), anyBoolean()); any(), anyBoolean(), anyInt()); verify(mMockLocaleManagerService, times(1)).setApplicationLocales(pkgNameB, DEFAULT_USER_ID, LocaleList.forLanguageTags(langTagsB), true); LocaleList.forLanguageTags(langTagsB), true, FrameworkStatsLog .APPLICATION_LOCALES_CHANGED__CALLER__CALLER_BACKUP_RESTORE); verify(mMockLocaleManagerService, times(0)).setApplicationLocales(eq(pkgNameC), anyInt(), any(), anyBoolean()); any(), anyBoolean(), anyInt()); // App C is staged. pkgLocalesMap.remove(pkgNameA); Loading Loading @@ -484,7 +491,8 @@ public class LocaleManagerBackupRestoreTest { mPackageMonitor.onPackageAdded(pkgNameA, DEFAULT_UID); verify(mMockLocaleManagerService, times(1)).setApplicationLocales(pkgNameA, DEFAULT_USER_ID, LocaleList.forLanguageTags(langTagsA), false); LocaleList.forLanguageTags(langTagsA), false, FrameworkStatsLog .APPLICATION_LOCALES_CHANGED__CALLER__CALLER_BACKUP_RESTORE); mBackupHelper.persistLocalesModificationInfo(DEFAULT_USER_ID, pkgNameA, false, false); Loading @@ -499,7 +507,8 @@ public class LocaleManagerBackupRestoreTest { mPackageMonitor.onPackageAdded(pkgNameB, DEFAULT_UID); verify(mMockLocaleManagerService, times(1)).setApplicationLocales(pkgNameB, DEFAULT_USER_ID, LocaleList.forLanguageTags(langTagsB), true); LocaleList.forLanguageTags(langTagsB), true, FrameworkStatsLog .APPLICATION_LOCALES_CHANGED__CALLER__CALLER_BACKUP_RESTORE); mBackupHelper.persistLocalesModificationInfo(DEFAULT_USER_ID, pkgNameB, true, false); Loading Loading @@ -606,7 +615,8 @@ public class LocaleManagerBackupRestoreTest { mPackageMonitor.onPackageAdded(pkgNameA, DEFAULT_UID); verify(mMockLocaleManagerService, times(1)).setApplicationLocales( pkgNameA, DEFAULT_USER_ID, LocaleList.forLanguageTags(langTagsA), false); pkgNameA, DEFAULT_USER_ID, LocaleList.forLanguageTags(langTagsA), false, FrameworkStatsLog.APPLICATION_LOCALES_CHANGED__CALLER__CALLER_BACKUP_RESTORE); pkgLocalesMap.remove(pkgNameA); Loading @@ -620,7 +630,7 @@ public class LocaleManagerBackupRestoreTest { mPackageMonitor.onPackageAdded(pkgNameB, DEFAULT_UID); verify(mMockLocaleManagerService, times(0)).setApplicationLocales(eq(pkgNameB), anyInt(), any(), anyBoolean()); any(), anyBoolean(), anyInt()); checkStageDataDoesNotExist(DEFAULT_USER_ID); } Loading Loading @@ -734,7 +744,7 @@ public class LocaleManagerBackupRestoreTest { */ private void verifyNothingRestored() throws Exception { verify(mMockLocaleManagerService, times(0)).setApplicationLocales(anyString(), anyInt(), any(), anyBoolean()); any(), anyBoolean(), anyInt()); } private static void verifyPayloadForAppLocales(Map<String, LocalesInfo> expectedPkgLocalesMap, Loading services/tests/servicestests/src/com/android/server/locales/LocaleManagerServiceTest.java +13 −6 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ import androidx.test.InstrumentationRegistry; import androidx.test.ext.junit.runners.AndroidJUnit4; import com.android.internal.content.PackageMonitor; import com.android.internal.util.FrameworkStatsLog; import com.android.server.wm.ActivityTaskManagerInternal; import com.android.server.wm.ActivityTaskManagerInternal.PackageConfig; Loading Loading @@ -136,7 +137,8 @@ public class LocaleManagerServiceTest { try { mLocaleManagerService.setApplicationLocales(DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID, LocaleList.getEmptyLocaleList(), false); LocaleList.getEmptyLocaleList(), false, FrameworkStatsLog .APPLICATION_LOCALES_CHANGED__CALLER__CALLER_APPS); fail("Expected SecurityException"); } finally { verify(mMockContext).enforceCallingOrSelfPermission( Loading @@ -151,7 +153,8 @@ public class LocaleManagerServiceTest { public void testSetApplicationLocales_nullPackageName_fails() throws Exception { try { mLocaleManagerService.setApplicationLocales(/* appPackageName = */ null, DEFAULT_USER_ID, LocaleList.getEmptyLocaleList(), false); DEFAULT_USER_ID, LocaleList.getEmptyLocaleList(), false, FrameworkStatsLog.APPLICATION_LOCALES_CHANGED__CALLER__CALLER_APPS); fail("Expected NullPointerException"); } finally { verify(mMockBackupHelper, times(0)).notifyBackupManager(); Loading @@ -165,7 +168,8 @@ public class LocaleManagerServiceTest { try { mLocaleManagerService.setApplicationLocales(DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID, /* locales = */ null, false); /* locales = */ null, false, FrameworkStatsLog .APPLICATION_LOCALES_CHANGED__CALLER__CALLER_APPS); fail("Expected NullPointerException"); } finally { verify(mMockBackupHelper, times(0)).notifyBackupManager(); Loading @@ -183,7 +187,8 @@ public class LocaleManagerServiceTest { setUpPassingPermissionCheckFor(Manifest.permission.CHANGE_CONFIGURATION); mLocaleManagerService.setApplicationLocales(DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID, DEFAULT_LOCALES, true); DEFAULT_LOCALES, true, FrameworkStatsLog .APPLICATION_LOCALES_CHANGED__CALLER__CALLER_DELEGATE); assertEquals(DEFAULT_LOCALES, mFakePackageConfigurationUpdater.getStoredLocales()); verify(mMockBackupHelper, times(1)).notifyBackupManager(); Loading @@ -196,7 +201,8 @@ public class LocaleManagerServiceTest { .when(mMockPackageManager).getPackageUidAsUser(anyString(), any(), anyInt()); mLocaleManagerService.setApplicationLocales(DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID, DEFAULT_LOCALES, false); DEFAULT_LOCALES, false, FrameworkStatsLog .APPLICATION_LOCALES_CHANGED__CALLER__CALLER_APPS); assertEquals(DEFAULT_LOCALES, mFakePackageConfigurationUpdater.getStoredLocales()); verify(mMockBackupHelper, times(1)).notifyBackupManager(); Loading @@ -208,7 +214,8 @@ public class LocaleManagerServiceTest { .when(mMockPackageManager).getPackageUidAsUser(anyString(), any(), anyInt()); try { mLocaleManagerService.setApplicationLocales(DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID, LocaleList.getEmptyLocaleList(), false); LocaleList.getEmptyLocaleList(), false, FrameworkStatsLog .APPLICATION_LOCALES_CHANGED__CALLER__CALLER_APPS); fail("Expected IllegalArgumentException"); } finally { assertNoLocalesStored(mFakePackageConfigurationUpdater.getStoredLocales()); Loading Loading
services/core/java/com/android/server/locales/AppLocaleChangedAtomRecord.java +24 −4 Original line number Diff line number Diff line Loading @@ -20,24 +20,32 @@ import static android.os.Process.INVALID_UID; import com.android.internal.util.FrameworkStatsLog; import java.util.Locale; /** * Holds data used to report the ApplicationLocalesChanged atom. */ public final class AppLocaleChangedAtomRecord { private static final String DEFAULT_PREFIX = "default-"; final int mCallingUid; int mTargetUid = INVALID_UID; String mNewLocales = ""; String mPrevLocales = ""; String mNewLocales = DEFAULT_PREFIX; String mPrevLocales = DEFAULT_PREFIX; int mStatus = FrameworkStatsLog .APPLICATION_LOCALES_CHANGED__STATUS__STATUS_UNSPECIFIED; int mCaller = FrameworkStatsLog .APPLICATION_LOCALES_CHANGED__CALLER__CALLER_UNKNOWN; AppLocaleChangedAtomRecord(int callingUid) { this.mCallingUid = callingUid; Locale defaultLocale = Locale.getDefault(); if (defaultLocale != null) { this.mNewLocales = DEFAULT_PREFIX + defaultLocale.toLanguageTag(); this.mPrevLocales = DEFAULT_PREFIX + defaultLocale.toLanguageTag(); } } void setNewLocales(String newLocales) { this.mNewLocales = newLocales; this.mNewLocales = convertEmptyLocales(newLocales); } void setTargetUid(int targetUid) { Loading @@ -45,7 +53,7 @@ public final class AppLocaleChangedAtomRecord { } void setPrevLocales(String prevLocales) { this.mPrevLocales = prevLocales; this.mPrevLocales = convertEmptyLocales(prevLocales); } void setStatus(int status) { Loading @@ -55,4 +63,16 @@ public final class AppLocaleChangedAtomRecord { void setCaller(int caller) { this.mCaller = caller; } private String convertEmptyLocales(String locales) { String target = locales; if ("".equals(locales)) { Locale defaultLocale = Locale.getDefault(); if (defaultLocale != null) { target = DEFAULT_PREFIX + defaultLocale.toLanguageTag(); } } return target; } }
services/core/java/com/android/server/locales/LocaleManagerBackupHelper.java +6 −2 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import android.util.SparseArray; import android.util.Xml; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.XmlUtils; import com.android.modules.utils.TypedXmlPullParser; import com.android.modules.utils.TypedXmlSerializer; Loading Loading @@ -377,7 +378,8 @@ class LocaleManagerBackupHelper { // Restore the locale immediately try { mLocaleManagerService.setApplicationLocales(pkgName, userId, LocaleList.forLanguageTags(localesInfo.mLocales), localesInfo.mSetFromDelegate); LocaleList.forLanguageTags(localesInfo.mLocales), localesInfo.mSetFromDelegate, FrameworkStatsLog.APPLICATION_LOCALES_CHANGED__CALLER__CALLER_BACKUP_RESTORE); if (DEBUG) { Slog.d(TAG, "Restored locales=" + localesInfo.mLocales + " fromDelegate=" + localesInfo.mSetFromDelegate + " for package=" + pkgName); Loading Loading @@ -662,7 +664,9 @@ class LocaleManagerBackupHelper { try { LocaleConfig localeConfig = new LocaleConfig( mContext.createPackageContextAsUser(packageName, 0, UserHandle.of(userId))); mLocaleManagerService.removeUnsupportedAppLocales(packageName, userId, localeConfig); mLocaleManagerService.removeUnsupportedAppLocales(packageName, userId, localeConfig, FrameworkStatsLog .APPLICATION_LOCALES_CHANGED__CALLER__CALLER_APP_UPDATE_LOCALES_CHANGE); } catch (PackageManager.NameNotFoundException e) { Slog.e(TAG, "Can not found the package name : " + packageName + " / " + e); } Loading
services/core/java/com/android/server/locales/LocaleManagerService.java +21 −8 Original line number Diff line number Diff line Loading @@ -182,8 +182,11 @@ public class LocaleManagerService extends SystemService { @Override public void setApplicationLocales(@NonNull String appPackageName, @UserIdInt int userId, @NonNull LocaleList locales, boolean fromDelegate) throws RemoteException { int caller = fromDelegate ? FrameworkStatsLog.APPLICATION_LOCALES_CHANGED__CALLER__CALLER_DELEGATE : FrameworkStatsLog.APPLICATION_LOCALES_CHANGED__CALLER__CALLER_APPS; LocaleManagerService.this.setApplicationLocales(appPackageName, userId, locales, fromDelegate); fromDelegate, caller); } @Override Loading Loading @@ -226,13 +229,14 @@ public class LocaleManagerService extends SystemService { * Sets the current UI locales for a specified app. */ public void setApplicationLocales(@NonNull String appPackageName, @UserIdInt int userId, @NonNull LocaleList locales, boolean fromDelegate) @NonNull LocaleList locales, boolean fromDelegate, int caller) throws RemoteException, IllegalArgumentException { AppLocaleChangedAtomRecord atomRecordForMetrics = new AppLocaleChangedAtomRecord(Binder.getCallingUid()); try { requireNonNull(appPackageName); requireNonNull(locales); atomRecordForMetrics.setCaller(caller); atomRecordForMetrics.setNewLocales(locales.toLanguageTags()); //Allow apps with INTERACT_ACROSS_USERS permission to set locales for different user. userId = mActivityManagerInternal.handleIncomingUser( Loading Loading @@ -273,8 +277,8 @@ public class LocaleManagerService extends SystemService { + " and user " + userId); } atomRecordForMetrics.setPrevLocales(getApplicationLocalesUnchecked(appPackageName, userId) .toLanguageTags()); atomRecordForMetrics.setPrevLocales( getApplicationLocalesUnchecked(appPackageName, userId).toLanguageTags()); final ActivityTaskManagerInternal.PackageConfigurationUpdater updater = mActivityTaskManagerInternal.createPackageConfigurationUpdater(appPackageName, userId); Loading Loading @@ -619,7 +623,10 @@ public class LocaleManagerService extends SystemService { Slog.d(TAG, "remove the override LocaleConfig"); file.delete(); } removeUnsupportedAppLocales(appPackageName, userId, resLocaleConfig); removeUnsupportedAppLocales(appPackageName, userId, resLocaleConfig, FrameworkStatsLog .APPLICATION_LOCALES_CHANGED__CALLER__CALLER_DYNAMIC_LOCALES_CHANGE ); atomRecord.setOverrideRemoved(true); atomRecord.setStatus(FrameworkStatsLog .APP_SUPPORTED_LOCALES_CHANGED__STATUS__SUCCESS); Loading Loading @@ -661,7 +668,10 @@ public class LocaleManagerService extends SystemService { } atomicFile.finishWrite(stream); // Clear per-app locales if they are not in the override LocaleConfig. removeUnsupportedAppLocales(appPackageName, userId, overrideLocaleConfig); removeUnsupportedAppLocales(appPackageName, userId, overrideLocaleConfig, FrameworkStatsLog .APPLICATION_LOCALES_CHANGED__CALLER__CALLER_DYNAMIC_LOCALES_CHANGE ); if (overrideLocaleConfig.isSameLocaleConfig(resLocaleConfig)) { Slog.d(TAG, "setOverrideLocaleConfig, same as the app's LocaleConfig"); atomRecord.setSameAsResConfig(true); Loading @@ -678,9 +688,12 @@ public class LocaleManagerService extends SystemService { /** * Checks if the per-app locales are in the LocaleConfig. Per-app locales missing from the * LocaleConfig will be removed. * * <p><b>Note:</b> Check whether to remove the per-app locales when the app is upgraded or * the LocaleConfig is overridden. */ void removeUnsupportedAppLocales(String appPackageName, int userId, LocaleConfig localeConfig) { LocaleConfig localeConfig, int caller) { LocaleList appLocales = getApplicationLocalesUnchecked(appPackageName, userId); // Remove the per-app locales from the locale list if they don't exist in the LocaleConfig. boolean resetAppLocales = false; Loading @@ -707,7 +720,7 @@ public class LocaleManagerService extends SystemService { try { setApplicationLocales(appPackageName, userId, new LocaleList(newAppLocales.toArray(locales)), mBackupHelper.areLocalesSetFromDelegate(userId, appPackageName)); mBackupHelper.areLocalesSetFromDelegate(userId, appPackageName), caller); } catch (RemoteException | IllegalArgumentException e) { Slog.e(TAG, "Could not set locales for " + appPackageName, e); } Loading
services/tests/servicestests/src/com/android/server/locales/LocaleManagerBackupRestoreTest.java +23 −13 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ import android.util.Xml; import androidx.test.ext.junit.runners.AndroidJUnit4; import com.android.internal.content.PackageMonitor; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.XmlUtils; import com.android.modules.utils.TypedXmlPullParser; import com.android.modules.utils.TypedXmlSerializer; Loading Loading @@ -264,7 +265,8 @@ public class LocaleManagerBackupRestoreTest { // Locales were restored verify(mMockLocaleManagerService, times(1)).setApplicationLocales(DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID, DEFAULT_LOCALES, false); DEFAULT_USER_ID, DEFAULT_LOCALES, false, FrameworkStatsLog .APPLICATION_LOCALES_CHANGED__CALLER__CALLER_BACKUP_RESTORE); checkStageDataDoesNotExist(DEFAULT_USER_ID); } Loading @@ -280,7 +282,8 @@ public class LocaleManagerBackupRestoreTest { // Locales were restored verify(mMockLocaleManagerService, times(1)).setApplicationLocales(DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID, DEFAULT_LOCALES, false); DEFAULT_USER_ID, DEFAULT_LOCALES, false, FrameworkStatsLog .APPLICATION_LOCALES_CHANGED__CALLER__CALLER_BACKUP_RESTORE); checkStageDataDoesNotExist(DEFAULT_USER_ID); mBackupHelper.persistLocalesModificationInfo(DEFAULT_USER_ID, DEFAULT_PACKAGE_NAME, false, Loading @@ -303,7 +306,8 @@ public class LocaleManagerBackupRestoreTest { // Locales were restored verify(mMockLocaleManagerService, times(1)).setApplicationLocales(DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID, DEFAULT_LOCALES, true); DEFAULT_USER_ID, DEFAULT_LOCALES, true, FrameworkStatsLog .APPLICATION_LOCALES_CHANGED__CALLER__CALLER_BACKUP_RESTORE); checkStageDataDoesNotExist(DEFAULT_USER_ID); mBackupHelper.persistLocalesModificationInfo(DEFAULT_USER_ID, DEFAULT_PACKAGE_NAME, true, Loading @@ -327,7 +331,8 @@ public class LocaleManagerBackupRestoreTest { // Locales were restored verify(mMockLocaleManagerService, times(1)).setApplicationLocales( DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID, DEFAULT_LOCALES, true); DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID, DEFAULT_LOCALES, true, FrameworkStatsLog.APPLICATION_LOCALES_CHANGED__CALLER__CALLER_BACKUP_RESTORE); checkStageDataDoesNotExist(DEFAULT_USER_ID); mBackupHelper.persistLocalesModificationInfo(DEFAULT_USER_ID, DEFAULT_PACKAGE_NAME, true, Loading Loading @@ -369,7 +374,8 @@ public class LocaleManagerBackupRestoreTest { mBackupHelper.stageAndApplyRestoredPayload(out.toByteArray(), DEFAULT_USER_ID); verify(mMockLocaleManagerService, times(1)).setApplicationLocales(pkgNameA, DEFAULT_USER_ID, LocaleList.forLanguageTags(langTagsA), true); LocaleList.forLanguageTags(langTagsA), true, FrameworkStatsLog .APPLICATION_LOCALES_CHANGED__CALLER__CALLER_BACKUP_RESTORE); pkgLocalesMap.remove(pkgNameA); Loading Loading @@ -422,11 +428,12 @@ public class LocaleManagerBackupRestoreTest { // Restore locales only for myAppB. verify(mMockLocaleManagerService, times(0)).setApplicationLocales(eq(pkgNameA), anyInt(), any(), anyBoolean()); any(), anyBoolean(), anyInt()); verify(mMockLocaleManagerService, times(1)).setApplicationLocales(pkgNameB, DEFAULT_USER_ID, LocaleList.forLanguageTags(langTagsB), true); LocaleList.forLanguageTags(langTagsB), true, FrameworkStatsLog .APPLICATION_LOCALES_CHANGED__CALLER__CALLER_BACKUP_RESTORE); verify(mMockLocaleManagerService, times(0)).setApplicationLocales(eq(pkgNameC), anyInt(), any(), anyBoolean()); any(), anyBoolean(), anyInt()); // App C is staged. pkgLocalesMap.remove(pkgNameA); Loading Loading @@ -484,7 +491,8 @@ public class LocaleManagerBackupRestoreTest { mPackageMonitor.onPackageAdded(pkgNameA, DEFAULT_UID); verify(mMockLocaleManagerService, times(1)).setApplicationLocales(pkgNameA, DEFAULT_USER_ID, LocaleList.forLanguageTags(langTagsA), false); LocaleList.forLanguageTags(langTagsA), false, FrameworkStatsLog .APPLICATION_LOCALES_CHANGED__CALLER__CALLER_BACKUP_RESTORE); mBackupHelper.persistLocalesModificationInfo(DEFAULT_USER_ID, pkgNameA, false, false); Loading @@ -499,7 +507,8 @@ public class LocaleManagerBackupRestoreTest { mPackageMonitor.onPackageAdded(pkgNameB, DEFAULT_UID); verify(mMockLocaleManagerService, times(1)).setApplicationLocales(pkgNameB, DEFAULT_USER_ID, LocaleList.forLanguageTags(langTagsB), true); LocaleList.forLanguageTags(langTagsB), true, FrameworkStatsLog .APPLICATION_LOCALES_CHANGED__CALLER__CALLER_BACKUP_RESTORE); mBackupHelper.persistLocalesModificationInfo(DEFAULT_USER_ID, pkgNameB, true, false); Loading Loading @@ -606,7 +615,8 @@ public class LocaleManagerBackupRestoreTest { mPackageMonitor.onPackageAdded(pkgNameA, DEFAULT_UID); verify(mMockLocaleManagerService, times(1)).setApplicationLocales( pkgNameA, DEFAULT_USER_ID, LocaleList.forLanguageTags(langTagsA), false); pkgNameA, DEFAULT_USER_ID, LocaleList.forLanguageTags(langTagsA), false, FrameworkStatsLog.APPLICATION_LOCALES_CHANGED__CALLER__CALLER_BACKUP_RESTORE); pkgLocalesMap.remove(pkgNameA); Loading @@ -620,7 +630,7 @@ public class LocaleManagerBackupRestoreTest { mPackageMonitor.onPackageAdded(pkgNameB, DEFAULT_UID); verify(mMockLocaleManagerService, times(0)).setApplicationLocales(eq(pkgNameB), anyInt(), any(), anyBoolean()); any(), anyBoolean(), anyInt()); checkStageDataDoesNotExist(DEFAULT_USER_ID); } Loading Loading @@ -734,7 +744,7 @@ public class LocaleManagerBackupRestoreTest { */ private void verifyNothingRestored() throws Exception { verify(mMockLocaleManagerService, times(0)).setApplicationLocales(anyString(), anyInt(), any(), anyBoolean()); any(), anyBoolean(), anyInt()); } private static void verifyPayloadForAppLocales(Map<String, LocalesInfo> expectedPkgLocalesMap, Loading
services/tests/servicestests/src/com/android/server/locales/LocaleManagerServiceTest.java +13 −6 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ import androidx.test.InstrumentationRegistry; import androidx.test.ext.junit.runners.AndroidJUnit4; import com.android.internal.content.PackageMonitor; import com.android.internal.util.FrameworkStatsLog; import com.android.server.wm.ActivityTaskManagerInternal; import com.android.server.wm.ActivityTaskManagerInternal.PackageConfig; Loading Loading @@ -136,7 +137,8 @@ public class LocaleManagerServiceTest { try { mLocaleManagerService.setApplicationLocales(DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID, LocaleList.getEmptyLocaleList(), false); LocaleList.getEmptyLocaleList(), false, FrameworkStatsLog .APPLICATION_LOCALES_CHANGED__CALLER__CALLER_APPS); fail("Expected SecurityException"); } finally { verify(mMockContext).enforceCallingOrSelfPermission( Loading @@ -151,7 +153,8 @@ public class LocaleManagerServiceTest { public void testSetApplicationLocales_nullPackageName_fails() throws Exception { try { mLocaleManagerService.setApplicationLocales(/* appPackageName = */ null, DEFAULT_USER_ID, LocaleList.getEmptyLocaleList(), false); DEFAULT_USER_ID, LocaleList.getEmptyLocaleList(), false, FrameworkStatsLog.APPLICATION_LOCALES_CHANGED__CALLER__CALLER_APPS); fail("Expected NullPointerException"); } finally { verify(mMockBackupHelper, times(0)).notifyBackupManager(); Loading @@ -165,7 +168,8 @@ public class LocaleManagerServiceTest { try { mLocaleManagerService.setApplicationLocales(DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID, /* locales = */ null, false); /* locales = */ null, false, FrameworkStatsLog .APPLICATION_LOCALES_CHANGED__CALLER__CALLER_APPS); fail("Expected NullPointerException"); } finally { verify(mMockBackupHelper, times(0)).notifyBackupManager(); Loading @@ -183,7 +187,8 @@ public class LocaleManagerServiceTest { setUpPassingPermissionCheckFor(Manifest.permission.CHANGE_CONFIGURATION); mLocaleManagerService.setApplicationLocales(DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID, DEFAULT_LOCALES, true); DEFAULT_LOCALES, true, FrameworkStatsLog .APPLICATION_LOCALES_CHANGED__CALLER__CALLER_DELEGATE); assertEquals(DEFAULT_LOCALES, mFakePackageConfigurationUpdater.getStoredLocales()); verify(mMockBackupHelper, times(1)).notifyBackupManager(); Loading @@ -196,7 +201,8 @@ public class LocaleManagerServiceTest { .when(mMockPackageManager).getPackageUidAsUser(anyString(), any(), anyInt()); mLocaleManagerService.setApplicationLocales(DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID, DEFAULT_LOCALES, false); DEFAULT_LOCALES, false, FrameworkStatsLog .APPLICATION_LOCALES_CHANGED__CALLER__CALLER_APPS); assertEquals(DEFAULT_LOCALES, mFakePackageConfigurationUpdater.getStoredLocales()); verify(mMockBackupHelper, times(1)).notifyBackupManager(); Loading @@ -208,7 +214,8 @@ public class LocaleManagerServiceTest { .when(mMockPackageManager).getPackageUidAsUser(anyString(), any(), anyInt()); try { mLocaleManagerService.setApplicationLocales(DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID, LocaleList.getEmptyLocaleList(), false); LocaleList.getEmptyLocaleList(), false, FrameworkStatsLog .APPLICATION_LOCALES_CHANGED__CALLER__CALLER_APPS); fail("Expected IllegalArgumentException"); } finally { assertNoLocalesStored(mFakePackageConfigurationUpdater.getStoredLocales()); Loading