Merge "Log data to ApplicationLocalesChanged atom" into udc-dev
This commit is contained in:
@@ -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) {
|
||||
@@ -45,7 +53,7 @@ public final class AppLocaleChangedAtomRecord {
|
||||
}
|
||||
|
||||
void setPrevLocales(String prevLocales) {
|
||||
this.mPrevLocales = prevLocales;
|
||||
this.mPrevLocales = convertEmptyLocales(prevLocales);
|
||||
}
|
||||
|
||||
void setStatus(int status) {
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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(
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
@@ -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,
|
||||
@@ -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,
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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(
|
||||
@@ -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();
|
||||
@@ -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();
|
||||
@@ -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();
|
||||
@@ -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();
|
||||
@@ -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());
|
||||
|
||||
Reference in New Issue
Block a user