Loading services/core/java/com/android/server/grammaticalinflection/GrammaticalInflectionBackupHelper.java +9 −10 Original line number Diff line number Diff line Loading @@ -123,8 +123,7 @@ public class GrammaticalInflectionBackupHelper { * Returns the system-gender to be backed up as a data-blob. */ public byte[] getSystemBackupPayload(int userId) { int gender = mGrammaticalGenderService.getSystemGrammaticalGender(mAttributionSource, userId); int gender = mGrammaticalGenderService.getSystemGrammaticalGender(userId); return intToByteArray(gender); } Loading Loading @@ -167,7 +166,7 @@ public class GrammaticalInflectionBackupHelper { BackupManager.dataChanged(SYSTEM_BACKUP_PACKAGE_KEY); } private byte[] convertToByteArray(HashMap<String, Integer> pkgGenderInfo) { private static byte[] convertToByteArray(HashMap<String, Integer> pkgGenderInfo) { try (final ByteArrayOutputStream out = new ByteArrayOutputStream(); final ObjectOutputStream objStream = new ObjectOutputStream(out)) { objStream.writeObject(pkgGenderInfo); Loading @@ -178,22 +177,22 @@ public class GrammaticalInflectionBackupHelper { } } private byte[] intToByteArray(final int gender) { private static byte[] intToByteArray(final int gender) { ByteBuffer bb = ByteBuffer.allocate(4); bb.putInt(gender); return bb.array(); } private int convertByteArrayToInt(byte[] intBytes) { private static int convertByteArrayToInt(byte[] intBytes) { ByteBuffer byteBuffer = ByteBuffer.wrap(intBytes); return byteBuffer.getInt(); } private HashMap<String, Integer> readFromByteArray(byte[] payload) { private static HashMap<String, Integer> readFromByteArray(byte[] payload) { HashMap<String, Integer> data = new HashMap<>(); try (ByteArrayInputStream byteIn = new ByteArrayInputStream(payload); ObjectInputStream in = new ObjectInputStream(byteIn)) { try (var byteIn = new ByteArrayInputStream(payload); var in = new ObjectInputStream(byteIn)) { data = (HashMap<String, Integer>) in.readObject(); } catch (IOException | ClassNotFoundException e) { Log.e(TAG, "cannot convert payload to HashMap.", e); Loading @@ -205,10 +204,10 @@ public class GrammaticalInflectionBackupHelper { private void cleanStagedDataForOldEntries() { for (int i = 0; i < mCache.size(); i++) { int userId = mCache.keyAt(i); StagedData stagedData = mCache.get(userId); StagedData stagedData = mCache.valueAt(userId); if (stagedData.mCreationTimeMillis < mClock.millis() - STAGE_DATA_RETENTION_PERIOD.toMillis()) { mCache.remove(userId); mCache.removeAt(i--); } } } Loading services/core/java/com/android/server/grammaticalinflection/GrammaticalInflectionManagerInternal.java +12 −7 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ package com.android.server.grammaticalinflection; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.res.Configuration; Loading @@ -41,7 +40,7 @@ public abstract class GrammaticalInflectionManagerInternal { public abstract void stageAndApplyRestoredPayload(byte[] payload, int userId); /** * Get the current system grammatical gender of privileged application. * Get the current system grammatical gender for the particular user. * * @return the value of grammatical gender * Loading @@ -50,18 +49,25 @@ public abstract class GrammaticalInflectionManagerInternal { public abstract @Configuration.GrammaticalGender int getSystemGrammaticalGender(int userId); /** * Retrieve the system grammatical gender. * Get the final merged value of the global grammatical gender, user- or devsettings-set. * * @return the value of grammatical gender * */ public abstract @Configuration.GrammaticalGender int retrieveSystemGrammaticalGender( @NonNull Configuration configuration); public abstract @Configuration.GrammaticalGender int mergedFinalSystemGrammaticalGender(); /** * Get the grammatical gender from developer settings global override. * * @return the value of grammatical gender */ public abstract @Configuration.GrammaticalGender int getGrammaticalGenderFromDeveloperSettings(); /** * Whether the package can get the system grammatical gender or not. */ public abstract boolean canGetSystemGrammaticalGender(int uid, @Nullable String packageName); public abstract boolean canGetSystemGrammaticalGender(int uid); /** Loading @@ -74,4 +80,3 @@ public abstract class GrammaticalInflectionManagerInternal { */ public abstract void applyRestoredSystemPayload(byte[] payload, int userId); } services/core/java/com/android/server/grammaticalinflection/GrammaticalInflectionService.java +100 −99 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ package com.android.server.grammaticalinflection; import static android.app.Flags.systemTermsOfAddressEnabled; import static android.content.res.Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED; import static com.android.server.grammaticalinflection.GrammaticalInflectionUtils.checkSystemGrammaticalGenderPermission; Loading @@ -43,6 +42,7 @@ import android.util.Log; import android.util.SparseIntArray; 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; Loading Loading @@ -126,7 +126,7 @@ public class GrammaticalInflectionService extends SystemService { @Override public void setSystemWideGrammaticalGender(int grammaticalGender, int userId) { isCallerAllowed(); enforceCallerPermissions(); GrammaticalInflectionService.this.setSystemWideGrammaticalGender(grammaticalGender, userId); } Loading @@ -138,18 +138,16 @@ public class GrammaticalInflectionService extends SystemService { + " does not have READ_SYSTEM_GRAMMATICAL_GENDER permission."); } return checkSystemTermsOfAddressIsEnabled() ? GrammaticalInflectionService.this.getSystemGrammaticalGender( attributionSource, userId) : GRAMMATICAL_GENDER_NOT_SPECIFIED; ? GrammaticalInflectionService.this.getSystemGrammaticalGender(userId) : Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED; } @Override public int peekSystemGrammaticalGenderByUserId(AttributionSource attributionSource, int userId) { return canGetSystemGrammaticalGender(attributionSource) ? GrammaticalInflectionService.this.getSystemGrammaticalGender( attributionSource, userId) : GRAMMATICAL_GENDER_NOT_SPECIFIED; ? GrammaticalInflectionService.this.getSystemGrammaticalGender(userId) : Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED; } @Override Loading @@ -163,11 +161,10 @@ public class GrammaticalInflectionService extends SystemService { private final class GrammaticalInflectionManagerInternalImpl extends GrammaticalInflectionManagerInternal { @Override @Nullable public byte[] getBackupPayload(int userId) { isCallerAllowed(); enforceCallerPermissions(); return mBackupHelper.getBackupPayload(userId); } Loading @@ -179,7 +176,7 @@ public class GrammaticalInflectionService extends SystemService { @Override @Nullable public byte[] getSystemBackupPayload(int userId) { isCallerAllowed(); enforceCallerPermissions(); return mBackupHelper.getSystemBackupPayload(userId); } Loading @@ -191,30 +188,35 @@ public class GrammaticalInflectionService extends SystemService { @Override public int getSystemGrammaticalGender(int userId) { return checkSystemTermsOfAddressIsEnabled() ? GrammaticalInflectionService.this.getSystemGrammaticalGender( mContext.getAttributionSource(), userId) : GRAMMATICAL_GENDER_NOT_SPECIFIED; ? GrammaticalInflectionService.this.getSystemGrammaticalGender(userId) : Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED; } @Override public int retrieveSystemGrammaticalGender(Configuration configuration) { public int mergedFinalSystemGrammaticalGender() { int systemGrammaticalGender = getSystemGrammaticalGender(mContext.getUserId()); // Retrieve the grammatical gender from system property, set it into // configuration which will get updated later if the grammatical gender raw value of // current configuration is {@link Configuration#GRAMMATICAL_GENDER_UNDEFINED}. if (configuration.getGrammaticalGenderRaw() == Configuration.GRAMMATICAL_GENDER_UNDEFINED || systemGrammaticalGender <= Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED) { systemGrammaticalGender = SystemProperties.getInt(GRAMMATICAL_GENDER_PROPERTY, Configuration.GRAMMATICAL_GENDER_UNDEFINED); if (systemGrammaticalGender == Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED) { systemGrammaticalGender = getGrammaticalGenderFromDeveloperSettings(); } return systemGrammaticalGender; return systemGrammaticalGender == Configuration.GRAMMATICAL_GENDER_UNDEFINED ? Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED : systemGrammaticalGender; } @Override public boolean canGetSystemGrammaticalGender(int uid, String packageName) { AttributionSource attributionSource = new AttributionSource.Builder( uid).setPackageName(packageName).build(); public int getGrammaticalGenderFromDeveloperSettings() { return SystemProperties.getInt(GRAMMATICAL_GENDER_PROPERTY, Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED); } @Override public boolean canGetSystemGrammaticalGender(int uid) { if (uid == Process.SYSTEM_UID) { return true; } var attributionSource = new AttributionSource.Builder(uid).build(); return GrammaticalInflectionService.this.canGetSystemGrammaticalGender( attributionSource); } Loading @@ -225,7 +227,7 @@ public class GrammaticalInflectionService extends SystemService { mActivityTaskManagerInternal.getApplicationConfig(appPackageName, userId); if (appConfig == null || appConfig.mGrammaticalGender == null) { return GRAMMATICAL_GENDER_NOT_SPECIFIED; return Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED; } else { return appConfig.mGrammaticalGender; } Loading @@ -239,9 +241,10 @@ public class GrammaticalInflectionService extends SystemService { userId); if (!SystemProperties.getBoolean(GRAMMATICAL_INFLECTION_ENABLED, true)) { if (preValue != GRAMMATICAL_GENDER_NOT_SPECIFIED) { if (preValue != Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED) { Log.d(TAG, "Clearing the user's grammatical gender setting"); updater.setGrammaticalGender(GRAMMATICAL_GENDER_NOT_SPECIFIED).commit(); updater.setGrammaticalGender( Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED).commit(); } return; } Loading @@ -250,29 +253,26 @@ public class GrammaticalInflectionService extends SystemService { FrameworkStatsLog.write(FrameworkStatsLog.APPLICATION_GRAMMATICAL_INFLECTION_CHANGED, FrameworkStatsLog.APPLICATION_GRAMMATICAL_INFLECTION_CHANGED__SOURCE_ID__OTHERS, uid, gender != GRAMMATICAL_GENDER_NOT_SPECIFIED, preValue != GRAMMATICAL_GENDER_NOT_SPECIFIED); gender != Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED, preValue != Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED); updater.setGrammaticalGender(gender).commit(); } protected void setSystemWideGrammaticalGender(int grammaticalGender, int userId) { try { if (!checkSystemTermsOfAddressIsEnabled()) { return; // Nothing to do, and the flag can't get flipped at the runtime. } Trace.beginSection("GrammaticalInflectionService.setSystemWideGrammaticalGender"); if (!GrammaticalInflectionManager.VALID_GRAMMATICAL_GENDER_VALUES.contains( grammaticalGender)) { throw new IllegalArgumentException("Unknown grammatical gender"); } if (!checkSystemTermsOfAddressIsEnabled()) { if (grammaticalGender == GRAMMATICAL_GENDER_NOT_SPECIFIED) { return; } Log.d(TAG, "Clearing the system grammatical gender setting"); grammaticalGender = GRAMMATICAL_GENDER_NOT_SPECIFIED; } synchronized (mLock) { final File file = getGrammaticalGenderFile(userId); synchronized (mLock) { final AtomicFile atomicFile = new AtomicFile(file); FileOutputStream stream = null; try { Loading @@ -289,10 +289,12 @@ public class GrammaticalInflectionService extends SystemService { } } updateConfiguration(grammaticalGender, userId); } finally { Trace.endSection(); } } private void updateConfiguration(int grammaticalGender, int userId) { private static void updateConfiguration(int grammaticalGender, int userId) { try { Configuration config = new Configuration(); int preValue = config.getGrammaticalGender(); Loading @@ -301,37 +303,35 @@ public class GrammaticalInflectionService extends SystemService { FrameworkStatsLog.write(FrameworkStatsLog.SYSTEM_GRAMMATICAL_INFLECTION_CHANGED, FrameworkStatsLog.SYSTEM_GRAMMATICAL_INFLECTION_CHANGED__SOURCE_ID__SYSTEM, userId, grammaticalGender != GRAMMATICAL_GENDER_NOT_SPECIFIED, preValue != GRAMMATICAL_GENDER_NOT_SPECIFIED); grammaticalGender != Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED, preValue != Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED); GrammaticalInflectionBackupHelper.notifyBackupManager(); } catch (RemoteException e) { Log.w(TAG, "Can not update configuration", e); } } public int getSystemGrammaticalGender(AttributionSource attributionSource, int userId) { String packageName = attributionSource.getPackageName(); if (packageName == null) { Log.d(TAG, "Package name is null."); return GRAMMATICAL_GENDER_NOT_SPECIFIED; } /** * Returns the system global grammatical gender value for the requested user. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PROTECTED) public int getSystemGrammaticalGender(int userId) { synchronized (mLock) { int grammaticalGender = mGrammaticalGenderCache.get(userId); return grammaticalGender < 0 ? GRAMMATICAL_GENDER_NOT_SPECIFIED : grammaticalGender; return grammaticalGender < 0 ? Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED : grammaticalGender; } } private File getGrammaticalGenderFile(int userId) { private static File getGrammaticalGenderFile(int userId) { final File dir = new File(Environment.getDataSystemCeDirectory(userId), TAG_GRAMMATICAL_INFLECTION); return new File(dir, USER_SETTINGS_FILE_NAME); } private byte[] toXmlByteArray(int grammaticalGender, FileOutputStream fileStream) { try { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); private static byte[] toXmlByteArray(int grammaticalGender, FileOutputStream fileStream) throws IOException { var outputStream = new ByteArrayOutputStream(); TypedXmlSerializer out = Xml.resolveSerializer(fileStream); out.setOutput(outputStream, StandardCharsets.UTF_8.name()); out.startDocument(/* encoding= */ null, /* standalone= */ true); Loading @@ -339,16 +339,11 @@ public class GrammaticalInflectionService extends SystemService { out.attributeInt(null, ATTR_NAME, grammaticalGender); out.endTag(null, TAG_GRAMMATICAL_INFLECTION); out.endDocument(); return outputStream.toByteArray(); } catch (IOException e) { return null; } } private int getGrammaticalGenderFromXml(TypedXmlPullParser parser) private static int getGrammaticalGenderFromXml(TypedXmlPullParser parser) throws IOException, XmlPullParserException { XmlUtils.nextElement(parser); while (parser.getEventType() != XmlPullParser.END_DOCUMENT) { String tagName = parser.getName(); Loading @@ -359,20 +354,20 @@ public class GrammaticalInflectionService extends SystemService { } } return GRAMMATICAL_GENDER_NOT_SPECIFIED; return Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED; } private void isCallerAllowed() { private void enforceCallerPermissions() { int callingUid = Binder.getCallingUid(); if (callingUid != Process.SYSTEM_UID && callingUid != Process.SHELL_UID && callingUid != Process.ROOT_UID) { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.CHANGE_CONFIGURATION, "Caller must be system, shell, root or has CHANGE_CONFIGURATION permission."); "Caller must be system, shell, root or hold CHANGE_CONFIGURATION permission."); } } private boolean checkSystemTermsOfAddressIsEnabled() { private static boolean checkSystemTermsOfAddressIsEnabled() { if (!systemTermsOfAddressEnabled()) { Log.d(TAG, "The flag must be enabled to allow calling the API."); return false; Loading @@ -387,25 +382,31 @@ public class GrammaticalInflectionService extends SystemService { @Override public void onUserUnlocked(TargetUser user) { if (!checkSystemTermsOfAddressIsEnabled()) { return; } IoThread.getHandler().post(() -> { int userId = user.getUserIdentifier(); final int userId = user.getUserIdentifier(); final File file = getGrammaticalGenderFile(userId); final int grammaticalGender; synchronized (mLock) { if (!file.exists()) { Log.d(TAG, "User " + userId + " doesn't have the grammatical gender file."); return; } if (mGrammaticalGenderCache.indexOfKey(userId) < 0) { if (mGrammaticalGenderCache.indexOfKey(userId) >= 0) { return; } try (FileInputStream in = new FileInputStream(file)) { final TypedXmlPullParser parser = Xml.resolvePullParser(in); int grammaticalGender = getGrammaticalGenderFromXml(parser); grammaticalGender = getGrammaticalGenderFromXml(parser); mGrammaticalGenderCache.put(userId, grammaticalGender); updateConfiguration(grammaticalGender, userId); } catch (IOException | XmlPullParserException e) { Log.e(TAG, "Failed to parse XML configuration from " + file, e); return; } } } updateConfiguration(grammaticalGender, userId); }); } } services/core/java/com/android/server/wm/ActivityRecord.java +6 −0 Original line number Diff line number Diff line Loading @@ -9492,6 +9492,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return false; } @Override protected boolean setOverrideGender(Configuration requestsTmpConfig, int gender) { return WindowProcessController.applyConfigGenderOverride( requestsTmpConfig, gender, mAtmService.mGrammaticalManagerInternal, getUid()); } @VisibleForTesting @Override Rect getAnimationBounds(int appRootTaskClipMode) { Loading services/core/java/com/android/server/wm/ActivityTaskManagerService.java +1 −1 Original line number Diff line number Diff line Loading @@ -949,7 +949,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } configuration.setGrammaticalGender( mGrammaticalManagerInternal.retrieveSystemGrammaticalGender(configuration)); mGrammaticalManagerInternal.mergedFinalSystemGrammaticalGender()); synchronized (mGlobalLock) { mForceResizableActivities = forceResizable; Loading Loading
services/core/java/com/android/server/grammaticalinflection/GrammaticalInflectionBackupHelper.java +9 −10 Original line number Diff line number Diff line Loading @@ -123,8 +123,7 @@ public class GrammaticalInflectionBackupHelper { * Returns the system-gender to be backed up as a data-blob. */ public byte[] getSystemBackupPayload(int userId) { int gender = mGrammaticalGenderService.getSystemGrammaticalGender(mAttributionSource, userId); int gender = mGrammaticalGenderService.getSystemGrammaticalGender(userId); return intToByteArray(gender); } Loading Loading @@ -167,7 +166,7 @@ public class GrammaticalInflectionBackupHelper { BackupManager.dataChanged(SYSTEM_BACKUP_PACKAGE_KEY); } private byte[] convertToByteArray(HashMap<String, Integer> pkgGenderInfo) { private static byte[] convertToByteArray(HashMap<String, Integer> pkgGenderInfo) { try (final ByteArrayOutputStream out = new ByteArrayOutputStream(); final ObjectOutputStream objStream = new ObjectOutputStream(out)) { objStream.writeObject(pkgGenderInfo); Loading @@ -178,22 +177,22 @@ public class GrammaticalInflectionBackupHelper { } } private byte[] intToByteArray(final int gender) { private static byte[] intToByteArray(final int gender) { ByteBuffer bb = ByteBuffer.allocate(4); bb.putInt(gender); return bb.array(); } private int convertByteArrayToInt(byte[] intBytes) { private static int convertByteArrayToInt(byte[] intBytes) { ByteBuffer byteBuffer = ByteBuffer.wrap(intBytes); return byteBuffer.getInt(); } private HashMap<String, Integer> readFromByteArray(byte[] payload) { private static HashMap<String, Integer> readFromByteArray(byte[] payload) { HashMap<String, Integer> data = new HashMap<>(); try (ByteArrayInputStream byteIn = new ByteArrayInputStream(payload); ObjectInputStream in = new ObjectInputStream(byteIn)) { try (var byteIn = new ByteArrayInputStream(payload); var in = new ObjectInputStream(byteIn)) { data = (HashMap<String, Integer>) in.readObject(); } catch (IOException | ClassNotFoundException e) { Log.e(TAG, "cannot convert payload to HashMap.", e); Loading @@ -205,10 +204,10 @@ public class GrammaticalInflectionBackupHelper { private void cleanStagedDataForOldEntries() { for (int i = 0; i < mCache.size(); i++) { int userId = mCache.keyAt(i); StagedData stagedData = mCache.get(userId); StagedData stagedData = mCache.valueAt(userId); if (stagedData.mCreationTimeMillis < mClock.millis() - STAGE_DATA_RETENTION_PERIOD.toMillis()) { mCache.remove(userId); mCache.removeAt(i--); } } } Loading
services/core/java/com/android/server/grammaticalinflection/GrammaticalInflectionManagerInternal.java +12 −7 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ package com.android.server.grammaticalinflection; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.res.Configuration; Loading @@ -41,7 +40,7 @@ public abstract class GrammaticalInflectionManagerInternal { public abstract void stageAndApplyRestoredPayload(byte[] payload, int userId); /** * Get the current system grammatical gender of privileged application. * Get the current system grammatical gender for the particular user. * * @return the value of grammatical gender * Loading @@ -50,18 +49,25 @@ public abstract class GrammaticalInflectionManagerInternal { public abstract @Configuration.GrammaticalGender int getSystemGrammaticalGender(int userId); /** * Retrieve the system grammatical gender. * Get the final merged value of the global grammatical gender, user- or devsettings-set. * * @return the value of grammatical gender * */ public abstract @Configuration.GrammaticalGender int retrieveSystemGrammaticalGender( @NonNull Configuration configuration); public abstract @Configuration.GrammaticalGender int mergedFinalSystemGrammaticalGender(); /** * Get the grammatical gender from developer settings global override. * * @return the value of grammatical gender */ public abstract @Configuration.GrammaticalGender int getGrammaticalGenderFromDeveloperSettings(); /** * Whether the package can get the system grammatical gender or not. */ public abstract boolean canGetSystemGrammaticalGender(int uid, @Nullable String packageName); public abstract boolean canGetSystemGrammaticalGender(int uid); /** Loading @@ -74,4 +80,3 @@ public abstract class GrammaticalInflectionManagerInternal { */ public abstract void applyRestoredSystemPayload(byte[] payload, int userId); }
services/core/java/com/android/server/grammaticalinflection/GrammaticalInflectionService.java +100 −99 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ package com.android.server.grammaticalinflection; import static android.app.Flags.systemTermsOfAddressEnabled; import static android.content.res.Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED; import static com.android.server.grammaticalinflection.GrammaticalInflectionUtils.checkSystemGrammaticalGenderPermission; Loading @@ -43,6 +42,7 @@ import android.util.Log; import android.util.SparseIntArray; 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; Loading Loading @@ -126,7 +126,7 @@ public class GrammaticalInflectionService extends SystemService { @Override public void setSystemWideGrammaticalGender(int grammaticalGender, int userId) { isCallerAllowed(); enforceCallerPermissions(); GrammaticalInflectionService.this.setSystemWideGrammaticalGender(grammaticalGender, userId); } Loading @@ -138,18 +138,16 @@ public class GrammaticalInflectionService extends SystemService { + " does not have READ_SYSTEM_GRAMMATICAL_GENDER permission."); } return checkSystemTermsOfAddressIsEnabled() ? GrammaticalInflectionService.this.getSystemGrammaticalGender( attributionSource, userId) : GRAMMATICAL_GENDER_NOT_SPECIFIED; ? GrammaticalInflectionService.this.getSystemGrammaticalGender(userId) : Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED; } @Override public int peekSystemGrammaticalGenderByUserId(AttributionSource attributionSource, int userId) { return canGetSystemGrammaticalGender(attributionSource) ? GrammaticalInflectionService.this.getSystemGrammaticalGender( attributionSource, userId) : GRAMMATICAL_GENDER_NOT_SPECIFIED; ? GrammaticalInflectionService.this.getSystemGrammaticalGender(userId) : Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED; } @Override Loading @@ -163,11 +161,10 @@ public class GrammaticalInflectionService extends SystemService { private final class GrammaticalInflectionManagerInternalImpl extends GrammaticalInflectionManagerInternal { @Override @Nullable public byte[] getBackupPayload(int userId) { isCallerAllowed(); enforceCallerPermissions(); return mBackupHelper.getBackupPayload(userId); } Loading @@ -179,7 +176,7 @@ public class GrammaticalInflectionService extends SystemService { @Override @Nullable public byte[] getSystemBackupPayload(int userId) { isCallerAllowed(); enforceCallerPermissions(); return mBackupHelper.getSystemBackupPayload(userId); } Loading @@ -191,30 +188,35 @@ public class GrammaticalInflectionService extends SystemService { @Override public int getSystemGrammaticalGender(int userId) { return checkSystemTermsOfAddressIsEnabled() ? GrammaticalInflectionService.this.getSystemGrammaticalGender( mContext.getAttributionSource(), userId) : GRAMMATICAL_GENDER_NOT_SPECIFIED; ? GrammaticalInflectionService.this.getSystemGrammaticalGender(userId) : Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED; } @Override public int retrieveSystemGrammaticalGender(Configuration configuration) { public int mergedFinalSystemGrammaticalGender() { int systemGrammaticalGender = getSystemGrammaticalGender(mContext.getUserId()); // Retrieve the grammatical gender from system property, set it into // configuration which will get updated later if the grammatical gender raw value of // current configuration is {@link Configuration#GRAMMATICAL_GENDER_UNDEFINED}. if (configuration.getGrammaticalGenderRaw() == Configuration.GRAMMATICAL_GENDER_UNDEFINED || systemGrammaticalGender <= Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED) { systemGrammaticalGender = SystemProperties.getInt(GRAMMATICAL_GENDER_PROPERTY, Configuration.GRAMMATICAL_GENDER_UNDEFINED); if (systemGrammaticalGender == Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED) { systemGrammaticalGender = getGrammaticalGenderFromDeveloperSettings(); } return systemGrammaticalGender; return systemGrammaticalGender == Configuration.GRAMMATICAL_GENDER_UNDEFINED ? Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED : systemGrammaticalGender; } @Override public boolean canGetSystemGrammaticalGender(int uid, String packageName) { AttributionSource attributionSource = new AttributionSource.Builder( uid).setPackageName(packageName).build(); public int getGrammaticalGenderFromDeveloperSettings() { return SystemProperties.getInt(GRAMMATICAL_GENDER_PROPERTY, Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED); } @Override public boolean canGetSystemGrammaticalGender(int uid) { if (uid == Process.SYSTEM_UID) { return true; } var attributionSource = new AttributionSource.Builder(uid).build(); return GrammaticalInflectionService.this.canGetSystemGrammaticalGender( attributionSource); } Loading @@ -225,7 +227,7 @@ public class GrammaticalInflectionService extends SystemService { mActivityTaskManagerInternal.getApplicationConfig(appPackageName, userId); if (appConfig == null || appConfig.mGrammaticalGender == null) { return GRAMMATICAL_GENDER_NOT_SPECIFIED; return Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED; } else { return appConfig.mGrammaticalGender; } Loading @@ -239,9 +241,10 @@ public class GrammaticalInflectionService extends SystemService { userId); if (!SystemProperties.getBoolean(GRAMMATICAL_INFLECTION_ENABLED, true)) { if (preValue != GRAMMATICAL_GENDER_NOT_SPECIFIED) { if (preValue != Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED) { Log.d(TAG, "Clearing the user's grammatical gender setting"); updater.setGrammaticalGender(GRAMMATICAL_GENDER_NOT_SPECIFIED).commit(); updater.setGrammaticalGender( Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED).commit(); } return; } Loading @@ -250,29 +253,26 @@ public class GrammaticalInflectionService extends SystemService { FrameworkStatsLog.write(FrameworkStatsLog.APPLICATION_GRAMMATICAL_INFLECTION_CHANGED, FrameworkStatsLog.APPLICATION_GRAMMATICAL_INFLECTION_CHANGED__SOURCE_ID__OTHERS, uid, gender != GRAMMATICAL_GENDER_NOT_SPECIFIED, preValue != GRAMMATICAL_GENDER_NOT_SPECIFIED); gender != Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED, preValue != Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED); updater.setGrammaticalGender(gender).commit(); } protected void setSystemWideGrammaticalGender(int grammaticalGender, int userId) { try { if (!checkSystemTermsOfAddressIsEnabled()) { return; // Nothing to do, and the flag can't get flipped at the runtime. } Trace.beginSection("GrammaticalInflectionService.setSystemWideGrammaticalGender"); if (!GrammaticalInflectionManager.VALID_GRAMMATICAL_GENDER_VALUES.contains( grammaticalGender)) { throw new IllegalArgumentException("Unknown grammatical gender"); } if (!checkSystemTermsOfAddressIsEnabled()) { if (grammaticalGender == GRAMMATICAL_GENDER_NOT_SPECIFIED) { return; } Log.d(TAG, "Clearing the system grammatical gender setting"); grammaticalGender = GRAMMATICAL_GENDER_NOT_SPECIFIED; } synchronized (mLock) { final File file = getGrammaticalGenderFile(userId); synchronized (mLock) { final AtomicFile atomicFile = new AtomicFile(file); FileOutputStream stream = null; try { Loading @@ -289,10 +289,12 @@ public class GrammaticalInflectionService extends SystemService { } } updateConfiguration(grammaticalGender, userId); } finally { Trace.endSection(); } } private void updateConfiguration(int grammaticalGender, int userId) { private static void updateConfiguration(int grammaticalGender, int userId) { try { Configuration config = new Configuration(); int preValue = config.getGrammaticalGender(); Loading @@ -301,37 +303,35 @@ public class GrammaticalInflectionService extends SystemService { FrameworkStatsLog.write(FrameworkStatsLog.SYSTEM_GRAMMATICAL_INFLECTION_CHANGED, FrameworkStatsLog.SYSTEM_GRAMMATICAL_INFLECTION_CHANGED__SOURCE_ID__SYSTEM, userId, grammaticalGender != GRAMMATICAL_GENDER_NOT_SPECIFIED, preValue != GRAMMATICAL_GENDER_NOT_SPECIFIED); grammaticalGender != Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED, preValue != Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED); GrammaticalInflectionBackupHelper.notifyBackupManager(); } catch (RemoteException e) { Log.w(TAG, "Can not update configuration", e); } } public int getSystemGrammaticalGender(AttributionSource attributionSource, int userId) { String packageName = attributionSource.getPackageName(); if (packageName == null) { Log.d(TAG, "Package name is null."); return GRAMMATICAL_GENDER_NOT_SPECIFIED; } /** * Returns the system global grammatical gender value for the requested user. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PROTECTED) public int getSystemGrammaticalGender(int userId) { synchronized (mLock) { int grammaticalGender = mGrammaticalGenderCache.get(userId); return grammaticalGender < 0 ? GRAMMATICAL_GENDER_NOT_SPECIFIED : grammaticalGender; return grammaticalGender < 0 ? Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED : grammaticalGender; } } private File getGrammaticalGenderFile(int userId) { private static File getGrammaticalGenderFile(int userId) { final File dir = new File(Environment.getDataSystemCeDirectory(userId), TAG_GRAMMATICAL_INFLECTION); return new File(dir, USER_SETTINGS_FILE_NAME); } private byte[] toXmlByteArray(int grammaticalGender, FileOutputStream fileStream) { try { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); private static byte[] toXmlByteArray(int grammaticalGender, FileOutputStream fileStream) throws IOException { var outputStream = new ByteArrayOutputStream(); TypedXmlSerializer out = Xml.resolveSerializer(fileStream); out.setOutput(outputStream, StandardCharsets.UTF_8.name()); out.startDocument(/* encoding= */ null, /* standalone= */ true); Loading @@ -339,16 +339,11 @@ public class GrammaticalInflectionService extends SystemService { out.attributeInt(null, ATTR_NAME, grammaticalGender); out.endTag(null, TAG_GRAMMATICAL_INFLECTION); out.endDocument(); return outputStream.toByteArray(); } catch (IOException e) { return null; } } private int getGrammaticalGenderFromXml(TypedXmlPullParser parser) private static int getGrammaticalGenderFromXml(TypedXmlPullParser parser) throws IOException, XmlPullParserException { XmlUtils.nextElement(parser); while (parser.getEventType() != XmlPullParser.END_DOCUMENT) { String tagName = parser.getName(); Loading @@ -359,20 +354,20 @@ public class GrammaticalInflectionService extends SystemService { } } return GRAMMATICAL_GENDER_NOT_SPECIFIED; return Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED; } private void isCallerAllowed() { private void enforceCallerPermissions() { int callingUid = Binder.getCallingUid(); if (callingUid != Process.SYSTEM_UID && callingUid != Process.SHELL_UID && callingUid != Process.ROOT_UID) { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.CHANGE_CONFIGURATION, "Caller must be system, shell, root or has CHANGE_CONFIGURATION permission."); "Caller must be system, shell, root or hold CHANGE_CONFIGURATION permission."); } } private boolean checkSystemTermsOfAddressIsEnabled() { private static boolean checkSystemTermsOfAddressIsEnabled() { if (!systemTermsOfAddressEnabled()) { Log.d(TAG, "The flag must be enabled to allow calling the API."); return false; Loading @@ -387,25 +382,31 @@ public class GrammaticalInflectionService extends SystemService { @Override public void onUserUnlocked(TargetUser user) { if (!checkSystemTermsOfAddressIsEnabled()) { return; } IoThread.getHandler().post(() -> { int userId = user.getUserIdentifier(); final int userId = user.getUserIdentifier(); final File file = getGrammaticalGenderFile(userId); final int grammaticalGender; synchronized (mLock) { if (!file.exists()) { Log.d(TAG, "User " + userId + " doesn't have the grammatical gender file."); return; } if (mGrammaticalGenderCache.indexOfKey(userId) < 0) { if (mGrammaticalGenderCache.indexOfKey(userId) >= 0) { return; } try (FileInputStream in = new FileInputStream(file)) { final TypedXmlPullParser parser = Xml.resolvePullParser(in); int grammaticalGender = getGrammaticalGenderFromXml(parser); grammaticalGender = getGrammaticalGenderFromXml(parser); mGrammaticalGenderCache.put(userId, grammaticalGender); updateConfiguration(grammaticalGender, userId); } catch (IOException | XmlPullParserException e) { Log.e(TAG, "Failed to parse XML configuration from " + file, e); return; } } } updateConfiguration(grammaticalGender, userId); }); } }
services/core/java/com/android/server/wm/ActivityRecord.java +6 −0 Original line number Diff line number Diff line Loading @@ -9492,6 +9492,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return false; } @Override protected boolean setOverrideGender(Configuration requestsTmpConfig, int gender) { return WindowProcessController.applyConfigGenderOverride( requestsTmpConfig, gender, mAtmService.mGrammaticalManagerInternal, getUid()); } @VisibleForTesting @Override Rect getAnimationBounds(int appRootTaskClipMode) { Loading
services/core/java/com/android/server/wm/ActivityTaskManagerService.java +1 −1 Original line number Diff line number Diff line Loading @@ -949,7 +949,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } configuration.setGrammaticalGender( mGrammaticalManagerInternal.retrieveSystemGrammaticalGender(configuration)); mGrammaticalManagerInternal.mergedFinalSystemGrammaticalGender()); synchronized (mGlobalLock) { mForceResizableActivities = forceResizable; Loading