diff options
4 files changed, 150 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java index 4149980c7d45..9db13ba825f4 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java @@ -608,6 +608,44 @@ public abstract class ActivityTaskManagerInternal { String packageName, int userId); /** + * Retrieves and returns the app-specific configuration for an arbitrary application specified + * by its packageName and userId. Returns null if no app-specific configuration has been set. + */ + @Nullable + public abstract PackageConfig getApplicationConfig(String packageName, + int userId); + + /** + * Holds app-specific configurations. + */ + public static class PackageConfig { + /** + * nightMode for the application, null if app-specific nightMode is not set. + */ + @Nullable + public final Integer mNightMode; + + /** + * {@link LocaleList} for the application, null if app-specific locales are not set. + */ + @Nullable + public final LocaleList mLocales; + + PackageConfig(Integer nightMode, LocaleList locales) { + mNightMode = nightMode; + mLocales = locales; + } + + /** + * Returns the string representation of the app-specific configuration. + */ + @Override + public String toString() { + return "PackageConfig: nightMode " + mNightMode + " locales " + mLocales; + } + } + + /** * An interface to update configuration for an application, and will persist override * configuration for this package. */ diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index f278e3e22982..89f7d92b2087 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -6564,6 +6564,13 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } @Override + @Nullable + public ActivityTaskManagerInternal.PackageConfig getApplicationConfig(String packageName, + int userId) { + return mPackageConfigPersister.findPackageConfiguration(packageName, userId); + } + + @Override public boolean hasSystemAlertWindowPermission(int callingUid, int callingPid, String callingPackage) { return ActivityTaskManagerService.this.hasSystemAlertWindowPermission(callingUid, diff --git a/services/core/java/com/android/server/wm/PackageConfigPersister.java b/services/core/java/com/android/server/wm/PackageConfigPersister.java index 52eea4d3d6e1..081a53e7bd05 100644 --- a/services/core/java/com/android/server/wm/PackageConfigPersister.java +++ b/services/core/java/com/android/server/wm/PackageConfigPersister.java @@ -272,6 +272,24 @@ public class PackageConfigPersister { } } + /** + * Retrieves and returns application configuration from persisted records if it exists, else + * returns null. + */ + ActivityTaskManagerInternal.PackageConfig findPackageConfiguration(String packageName, + int userId) { + synchronized (mLock) { + PackageConfigRecord packageConfigRecord = findRecord(mModified, packageName, userId); + if (packageConfigRecord == null) { + Slog.w(TAG, "App-specific configuration not found for packageName: " + packageName + + " and userId: " + userId); + return null; + } + return new ActivityTaskManagerInternal.PackageConfig( + packageConfigRecord.mNightMode, packageConfigRecord.mLocales); + } + } + // store a changed data so we don't need to get the process static class PackageConfigRecord { final String mName; diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java index 764f63dcd013..5de4fcbb5aa7 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java @@ -33,6 +33,7 @@ import static com.android.server.wm.ActivityRecord.State.STOPPING; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyBoolean; @@ -748,6 +749,92 @@ public class ActivityTaskManagerServiceTests extends WindowTestsBase { assertFalse(wpcAfterConfigChange2.getConfiguration().isNightModeActive()); } + @Test + public void testPackageConfigUpdate_localesNotSet_localeConfigRetrievedNull() { + Configuration config = mAtm.getGlobalConfiguration(); + config.setLocales(LocaleList.forLanguageTags("en-XC")); + mAtm.updateGlobalConfigurationLocked(config, true, true, + DEFAULT_USER_ID); + WindowProcessController wpc = createWindowProcessController( + DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID); + mAtm.mProcessMap.put(Binder.getCallingPid(), wpc); + mAtm.mInternal.onProcessAdded(wpc); + + ActivityTaskManagerInternal.PackageConfig appSpecificConfig = mAtm.mInternal + .getApplicationConfig(DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID); + // when no configuration is set we get a null object. + assertNull(appSpecificConfig); + + ActivityTaskManagerInternal.PackageConfigurationUpdater packageConfigUpdater = + mAtm.mInternal.createPackageConfigurationUpdater(DEFAULT_PACKAGE_NAME, + DEFAULT_USER_ID); + packageConfigUpdater.setNightMode(Configuration.UI_MODE_NIGHT_YES).commit(); + + ActivityTaskManagerInternal.PackageConfig appSpecificConfig2 = mAtm.mInternal + .getApplicationConfig(DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID); + assertNotNull(appSpecificConfig2); + assertNull(appSpecificConfig2.mLocales); + assertEquals(appSpecificConfig2.mNightMode.intValue(), Configuration.UI_MODE_NIGHT_YES); + } + + @Test + public void testPackageConfigUpdate_appNotRunning_configSuccessfullyApplied() { + Configuration config = mAtm.getGlobalConfiguration(); + config.setLocales(LocaleList.forLanguageTags("en-XC")); + mAtm.updateGlobalConfigurationLocked(config, true, true, + DEFAULT_USER_ID); + + ActivityTaskManagerInternal.PackageConfigurationUpdater packageConfigUpdater = + mAtm.mInternal.createPackageConfigurationUpdater(DEFAULT_PACKAGE_NAME, + DEFAULT_USER_ID); + packageConfigUpdater.setLocales(LocaleList.forLanguageTags("en-XA,ar-XB")).commit(); + + // Verifies if the persisted app-specific configuration is same as the committed + // configuration. + ActivityTaskManagerInternal.PackageConfig appSpecificConfig = mAtm.mInternal + .getApplicationConfig(DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID); + assertNotNull(appSpecificConfig); + assertEquals(LocaleList.forLanguageTags("en-XA,ar-XB"), appSpecificConfig.mLocales); + + // Verifies if the persisted configuration for an arbitrary app is applied correctly when + // a new WindowProcessController is created for it. + WindowProcessController wpcAfterConfigChange = createWindowProcessController( + DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID); + assertEquals(LocaleList.forLanguageTags("en-XA,ar-XB,en-XC"), + wpcAfterConfigChange.getConfiguration().getLocales()); + } + + @Test + public void testPackageConfigUpdate_appRunning_configSuccessfullyApplied() { + Configuration config = mAtm.getGlobalConfiguration(); + config.setLocales(LocaleList.forLanguageTags("en-XC")); + mAtm.updateGlobalConfigurationLocked(config, true, true, + DEFAULT_USER_ID); + WindowProcessController wpc = createWindowProcessController( + DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID); + mAtm.mProcessMap.put(Binder.getCallingPid(), wpc); + mAtm.mInternal.onProcessAdded(wpc); + + ActivityTaskManagerInternal.PackageConfigurationUpdater packageConfigUpdater = + mAtm.mInternal.createPackageConfigurationUpdater(DEFAULT_PACKAGE_NAME, + DEFAULT_USER_ID); + + packageConfigUpdater.setLocales(LocaleList.forLanguageTags("en-XA,ar-XB")).commit(); + + ActivityTaskManagerInternal.PackageConfig appSpecificConfig = mAtm.mInternal + .getApplicationConfig(DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID); + + // Verifies if the persisted app-specific configuration is same as the committed + // configuration. + assertNotNull(appSpecificConfig); + assertEquals(LocaleList.forLanguageTags("en-XA,ar-XB"), appSpecificConfig.mLocales); + + // Verifies if the committed configuration is successfully applied to the required + // application while it is currently running. + assertEquals(LocaleList.forLanguageTags("en-XA,ar-XB,en-XC"), + wpc.getConfiguration().getLocales()); + } + private WindowProcessController createWindowProcessController(String packageName, int userId) { WindowProcessListener mMockListener = Mockito.mock(WindowProcessListener.class); |