Add a new field in Configuration and persist the field

Bug: 259175720
Test: atest and get/set the API
Change-Id: I938ededd94473d1e7c4c3b58982ca1ec04bc5977
This commit is contained in:
Calvin Pan
2022-12-22 01:50:01 +08:00
parent fdaffd24f7
commit a50fde1060
6 changed files with 88 additions and 13 deletions

View File

@@ -1027,6 +1027,9 @@
<flag name="layoutDirection" value="0x2000" />
<!-- The color mode of the screen has changed (color gamut or dynamic range). -->
<flag name="colorMode" value="0x4000" />
<!-- The grammatical gender has changed, for example the user set the grammatical gender
from the UI. -->
<flag name="grammaticalGender" value="0x8000" />
<!-- The font scaling factor has changed, that is the user has
selected a new global font size. -->
<flag name="fontScale" value="0x40000000" />

View File

@@ -29,6 +29,7 @@ import android.content.IIntentSender;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.IBinder;
import android.os.LocaleList;
@@ -622,10 +623,19 @@ public abstract class ActivityTaskManagerInternal {
@Nullable
public final LocaleList mLocales;
/**
* Gender for the application, null if app-specific grammatical gender is not set.
*/
@Nullable
public final @Configuration.GrammaticalGender
Integer mGrammaticalGender;
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
public PackageConfig(Integer nightMode, LocaleList locales) {
public PackageConfig(Integer nightMode, LocaleList locales,
@Configuration.GrammaticalGender Integer grammaticalGender) {
mNightMode = nightMode;
mLocales = locales;
mGrammaticalGender = grammaticalGender;
}
/**
@@ -659,6 +669,13 @@ public abstract class ActivityTaskManagerInternal {
*/
PackageConfigurationUpdater setLocales(LocaleList locales);
/**
* Sets the gender for the current application. This setting is persisted and will
* override the system configuration for this application.
*/
PackageConfigurationUpdater setGrammaticalGender(
@Configuration.GrammaticalGender int gender);
/**
* Commit changes.
* @return true if the configuration changes were persisted,

View File

@@ -536,16 +536,19 @@ public abstract class ConfigurationContainer<E extends ConfigurationContainer> {
* Applies app-specific nightMode and {@link LocaleList} on requested configuration.
* @return true if any of the requested configuration has been updated.
*/
public boolean applyAppSpecificConfig(Integer nightMode, LocaleList locales) {
public boolean applyAppSpecificConfig(Integer nightMode, LocaleList locales,
@Configuration.GrammaticalGender Integer gender) {
mRequestsTmpConfig.setTo(getRequestedOverrideConfiguration());
boolean newNightModeSet = (nightMode != null) && setOverrideNightMode(mRequestsTmpConfig,
nightMode);
boolean newLocalesSet = (locales != null) && setOverrideLocales(mRequestsTmpConfig,
locales);
if (newNightModeSet || newLocalesSet) {
boolean newGenderSet = (gender != null) && setOverrideGender(mRequestsTmpConfig,
gender);
if (newNightModeSet || newLocalesSet || newGenderSet) {
onRequestedOverrideConfigurationChanged(mRequestsTmpConfig);
}
return newNightModeSet || newLocalesSet;
return newNightModeSet || newLocalesSet || newGenderSet;
}
/**
@@ -578,6 +581,21 @@ public abstract class ConfigurationContainer<E extends ConfigurationContainer> {
return true;
}
/**
* Overrides the gender to this ConfigurationContainer.
*
* @return true if the grammatical gender has been changed.
*/
private boolean setOverrideGender(Configuration requestsTmpConfig,
@Configuration.GrammaticalGender int gender) {
if (mRequestedOverrideConfiguration.getGrammaticalGender() == gender) {
return false;
} else {
requestsTmpConfig.setGrammaticalGender(gender);
return true;
}
}
public boolean isActivityTypeDream() {
return getActivityType() == ACTIVITY_TYPE_DREAM;
}

View File

@@ -16,6 +16,8 @@
package com.android.server.wm;
import static android.content.res.Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED;
import android.annotation.NonNull;
import android.content.res.Configuration;
import android.os.Environment;
@@ -165,7 +167,8 @@ public class PackageConfigPersister {
if (modifiedRecord != null) {
container.applyAppSpecificConfig(modifiedRecord.mNightMode,
LocaleOverlayHelper.combineLocalesIfOverlayExists(
modifiedRecord.mLocales, mAtm.getGlobalConfiguration().getLocales()));
modifiedRecord.mLocales, mAtm.getGlobalConfiguration().getLocales()),
modifiedRecord.mGrammaticalGender);
}
}
}
@@ -188,16 +191,19 @@ public class PackageConfigPersister {
}
boolean isNightModeChanged = updateNightMode(impl.getNightMode(), record);
boolean isLocalesChanged = updateLocales(impl.getLocales(), record);
boolean isGenderChanged = updateGender(impl.getGrammaticalGender(), record);
if ((record.mNightMode == null || record.isResetNightMode())
&& (record.mLocales == null || record.mLocales.isEmpty())) {
&& (record.mLocales == null || record.mLocales.isEmpty())
&& (record.mGrammaticalGender == null
|| record.mGrammaticalGender == GRAMMATICAL_GENDER_NOT_SPECIFIED)) {
// if all values default to system settings, we can remove the package.
removePackage(packageName, userId);
// if there was a pre-existing record for the package that was deleted,
// we return true (since it was successfully deleted), else false (since there was
// no change to the previous state).
return isRecordPresent;
} else if (!isNightModeChanged && !isLocalesChanged) {
} else if (!isNightModeChanged && !isLocalesChanged && !isGenderChanged) {
return false;
} else {
final PackageConfigRecord pendingRecord =
@@ -211,7 +217,8 @@ public class PackageConfigPersister {
}
if (!updateNightMode(record.mNightMode, writeRecord)
&& !updateLocales(record.mLocales, writeRecord)) {
&& !updateLocales(record.mLocales, writeRecord)
&& !updateGender(record.mGrammaticalGender, writeRecord)) {
return false;
}
@@ -240,6 +247,15 @@ public class PackageConfigPersister {
return true;
}
private boolean updateGender(@Configuration.GrammaticalGender Integer requestedGender,
PackageConfigRecord record) {
if (requestedGender == null || requestedGender.equals(record.mGrammaticalGender)) {
return false;
}
record.mGrammaticalGender = requestedGender;
return true;
}
@GuardedBy("mLock")
void removeUser(int userId) {
synchronized (mLock) {
@@ -305,7 +321,9 @@ public class PackageConfigPersister {
return null;
}
return new ActivityTaskManagerInternal.PackageConfig(
packageConfigRecord.mNightMode, packageConfigRecord.mLocales);
packageConfigRecord.mNightMode,
packageConfigRecord.mLocales,
packageConfigRecord.mGrammaticalGender);
}
}
@@ -336,6 +354,8 @@ public class PackageConfigPersister {
final int mUserId;
Integer mNightMode;
LocaleList mLocales;
@Configuration.GrammaticalGender
Integer mGrammaticalGender;
PackageConfigRecord(String name, int userId) {
mName = name;

View File

@@ -17,6 +17,7 @@
package com.android.server.wm;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.os.Binder;
import android.os.LocaleList;
import android.util.ArraySet;
@@ -33,6 +34,8 @@ final class PackageConfigurationUpdaterImpl implements
private final Optional<Integer> mPid;
private Integer mNightMode;
private LocaleList mLocales;
private @Configuration.GrammaticalGender
int mGrammaticalGender;
private String mPackageName;
private int mUserId;
private ActivityTaskManagerService mAtm;
@@ -67,6 +70,15 @@ final class PackageConfigurationUpdaterImpl implements
return this;
}
@Override
public ActivityTaskManagerInternal.PackageConfigurationUpdater setGrammaticalGender(
@Configuration.GrammaticalGender int gender) {
synchronized (this) {
mGrammaticalGender = gender;
}
return this;
}
@Override
public boolean commit() {
synchronized (this) {
@@ -112,12 +124,12 @@ final class PackageConfigurationUpdaterImpl implements
for (int i = processes.size() - 1; i >= 0; i--) {
final WindowProcessController wpc = processes.valueAt(i);
if (wpc.mInfo.packageName.equals(packageName)) {
wpc.applyAppSpecificConfig(mNightMode, localesOverride);
wpc.applyAppSpecificConfig(mNightMode, localesOverride, mGrammaticalGender);
}
// Always inform individual activities about the update, since activities from other
// packages may be sharing this process
wpc.updateAppSpecificSettingsForAllActivitiesInPackage(packageName, mNightMode,
localesOverride);
localesOverride, mGrammaticalGender);
}
}
@@ -128,4 +140,9 @@ final class PackageConfigurationUpdaterImpl implements
LocaleList getLocales() {
return mLocales;
}
@Configuration.GrammaticalGender
Integer getGrammaticalGender() {
return mGrammaticalGender;
}
}

View File

@@ -867,13 +867,13 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
// TODO(b/199277729): Consider whether we need to add special casing for edge cases like
// activity-embeddings etc.
void updateAppSpecificSettingsForAllActivitiesInPackage(String packageName, Integer nightMode,
LocaleList localesOverride) {
LocaleList localesOverride, @Configuration.GrammaticalGender int gender) {
for (int i = mActivities.size() - 1; i >= 0; --i) {
final ActivityRecord r = mActivities.get(i);
// Activities from other packages could be sharing this process. Only propagate updates
// to those activities that are part of the package whose app-specific settings changed
if (packageName.equals(r.packageName)
&& r.applyAppSpecificConfig(nightMode, localesOverride)
&& r.applyAppSpecificConfig(nightMode, localesOverride, gender)
&& r.isVisibleRequested()) {
r.ensureActivityConfiguration(0 /* globalChanges */, true /* preserveWindow */);
}