Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 983a6814 authored by Josh Hou's avatar Josh Hou Committed by Automerger Merge Worker
Browse files

Merge "Log data to ApplicationLocalesChanged atom" into udc-dev am: 55adc206

parents 850e4d6e 55adc206
Loading
Loading
Loading
Loading
+24 −4
Original line number Diff line number Diff line
@@ -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;
    }
}
+6 −2
Original line number Diff line number Diff line
@@ -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);
        }
+21 −8
Original line number Diff line number Diff line
@@ -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);
            }
+23 −13
Original line number Diff line number Diff line
@@ -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,
+13 −6
Original line number Diff line number Diff line
@@ -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());