Merge "Enable Window Manager to store app-specific locales and apply them." into sc-v2-dev
This commit is contained in:
@@ -30,6 +30,7 @@ import android.content.pm.ApplicationInfo;
|
|||||||
import android.content.res.CompatibilityInfo;
|
import android.content.res.CompatibilityInfo;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.os.LocaleList;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.service.voice.IVoiceInteractionSession;
|
import android.service.voice.IVoiceInteractionSession;
|
||||||
import android.util.IntArray;
|
import android.util.IntArray;
|
||||||
@@ -610,6 +611,14 @@ public abstract class ActivityTaskManagerInternal {
|
|||||||
*/
|
*/
|
||||||
PackageConfigurationUpdater setNightMode(int nightMode);
|
PackageConfigurationUpdater setNightMode(int nightMode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the app-specific locales for the application referenced by this updater.
|
||||||
|
* This setting is persisted and will overlay on top of the system locales for
|
||||||
|
* the said application.
|
||||||
|
* @return the current {@link PackageConfigurationUpdater} updated with the provided locale.
|
||||||
|
*/
|
||||||
|
PackageConfigurationUpdater setLocales(LocaleList locales);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Commit changes.
|
* Commit changes.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -956,7 +956,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
|||||||
setRecentTasks(new RecentTasks(this, mTaskSupervisor));
|
setRecentTasks(new RecentTasks(this, mTaskSupervisor));
|
||||||
mVrController = new VrController(mGlobalLock);
|
mVrController = new VrController(mGlobalLock);
|
||||||
mKeyguardController = mTaskSupervisor.getKeyguardController();
|
mKeyguardController = mTaskSupervisor.getKeyguardController();
|
||||||
mPackageConfigPersister = new PackageConfigPersister(mTaskSupervisor.mPersisterQueue);
|
mPackageConfigPersister = new PackageConfigPersister(mTaskSupervisor.mPersisterQueue, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onActivityManagerInternalAdded() {
|
public void onActivityManagerInternalAdded() {
|
||||||
@@ -6575,7 +6575,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
|||||||
final class PackageConfigurationUpdaterImpl implements
|
final class PackageConfigurationUpdaterImpl implements
|
||||||
ActivityTaskManagerInternal.PackageConfigurationUpdater {
|
ActivityTaskManagerInternal.PackageConfigurationUpdater {
|
||||||
private final int mPid;
|
private final int mPid;
|
||||||
private int mNightMode;
|
private Integer mNightMode;
|
||||||
|
private LocaleList mLocales;
|
||||||
|
|
||||||
PackageConfigurationUpdaterImpl(int pid) {
|
PackageConfigurationUpdaterImpl(int pid) {
|
||||||
mPid = pid;
|
mPid = pid;
|
||||||
@@ -6587,6 +6588,13 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ActivityTaskManagerInternal.PackageConfigurationUpdater
|
||||||
|
setLocales(LocaleList locales) {
|
||||||
|
mLocales = locales;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void commit() {
|
public void commit() {
|
||||||
synchronized (mGlobalLock) {
|
synchronized (mGlobalLock) {
|
||||||
@@ -6597,8 +6605,10 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
|||||||
Slog.w(TAG, "Override application configuration: cannot find pid " + mPid);
|
Slog.w(TAG, "Override application configuration: cannot find pid " + mPid);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
wpc.setOverrideNightMode(mNightMode);
|
LocaleList localesOverride = LocaleOverlayHelper.combineLocalesIfOverlayExists(
|
||||||
wpc.updateNightModeForAllActivities(mNightMode);
|
mLocales, getGlobalConfiguration().getLocales());
|
||||||
|
wpc.applyAppSpecificConfig(mNightMode, localesOverride);
|
||||||
|
wpc.updateAppSpecificSettingsForAllActivities(mNightMode, localesOverride);
|
||||||
mPackageConfigPersister.updateFromImpl(wpc.mName, wpc.mUserId, this);
|
mPackageConfigPersister.updateFromImpl(wpc.mName, wpc.mUserId, this);
|
||||||
} finally {
|
} finally {
|
||||||
Binder.restoreCallingIdentity(ident);
|
Binder.restoreCallingIdentity(ident);
|
||||||
@@ -6606,8 +6616,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int getNightMode() {
|
Integer getNightMode() {
|
||||||
return mNightMode;
|
return mNightMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LocaleList getLocales() {
|
||||||
|
return mLocales;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import android.app.WindowConfiguration;
|
|||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
|
import android.os.LocaleList;
|
||||||
import android.util.proto.ProtoOutputStream;
|
import android.util.proto.ProtoOutputStream;
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
@@ -512,7 +513,7 @@ public abstract class ConfigurationContainer<E extends ConfigurationContainer> {
|
|||||||
return mFullConfiguration.windowConfiguration.getWindowingMode() == WINDOWING_MODE_FREEFORM;
|
return mFullConfiguration.windowConfiguration.getWindowingMode() == WINDOWING_MODE_FREEFORM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the activity type associated with the the configuration container. */
|
/** Returns the activity type associated with the configuration container. */
|
||||||
/*@WindowConfiguration.ActivityType*/
|
/*@WindowConfiguration.ActivityType*/
|
||||||
public int getActivityType() {
|
public int getActivityType() {
|
||||||
return mFullConfiguration.windowConfiguration.getActivityType();
|
return mFullConfiguration.windowConfiguration.getActivityType();
|
||||||
@@ -545,21 +546,49 @@ public abstract class ConfigurationContainer<E extends ConfigurationContainer> {
|
|||||||
return getActivityType() == ACTIVITY_TYPE_ASSISTANT;
|
return getActivityType() == ACTIVITY_TYPE_ASSISTANT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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) {
|
||||||
|
mRequestsTmpConfig.setTo(getRequestedOverrideConfiguration());
|
||||||
|
boolean newNightModeSet = (nightMode != null) && setOverrideNightMode(mRequestsTmpConfig,
|
||||||
|
nightMode);
|
||||||
|
boolean newLocalesSet = (locales != null) && setOverrideLocales(mRequestsTmpConfig,
|
||||||
|
locales);
|
||||||
|
if (newNightModeSet || newLocalesSet) {
|
||||||
|
onRequestedOverrideConfigurationChanged(mRequestsTmpConfig);
|
||||||
|
}
|
||||||
|
return newNightModeSet || newLocalesSet;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides the night mode applied to this ConfigurationContainer.
|
* Overrides the night mode applied to this ConfigurationContainer.
|
||||||
* @return true if the nightMode has been changed.
|
* @return true if the nightMode has been changed.
|
||||||
*/
|
*/
|
||||||
public boolean setOverrideNightMode(int nightMode) {
|
private boolean setOverrideNightMode(Configuration requestsTmpConfig, int nightMode) {
|
||||||
final int currentUiMode = mRequestedOverrideConfiguration.uiMode;
|
final int currentUiMode = mRequestedOverrideConfiguration.uiMode;
|
||||||
final int currentNightMode = currentUiMode & Configuration.UI_MODE_NIGHT_MASK;
|
final int currentNightMode = currentUiMode & Configuration.UI_MODE_NIGHT_MASK;
|
||||||
final int validNightMode = nightMode & Configuration.UI_MODE_NIGHT_MASK;
|
final int validNightMode = nightMode & Configuration.UI_MODE_NIGHT_MASK;
|
||||||
if (currentNightMode == validNightMode) {
|
if (currentNightMode == validNightMode) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
mRequestsTmpConfig.setTo(getRequestedOverrideConfiguration());
|
requestsTmpConfig.uiMode = validNightMode
|
||||||
mRequestsTmpConfig.uiMode = validNightMode
|
|
||||||
| (currentUiMode & ~Configuration.UI_MODE_NIGHT_MASK);
|
| (currentUiMode & ~Configuration.UI_MODE_NIGHT_MASK);
|
||||||
onRequestedOverrideConfigurationChanged(mRequestsTmpConfig);
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides the locales applied to this ConfigurationContainer.
|
||||||
|
* @return true if the LocaleList has been changed.
|
||||||
|
*/
|
||||||
|
private boolean setOverrideLocales(Configuration requestsTmpConfig,
|
||||||
|
@NonNull LocaleList overrideLocales) {
|
||||||
|
if (mRequestedOverrideConfiguration.getLocales().equals(overrideLocales)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
requestsTmpConfig.setLocales(overrideLocales);
|
||||||
|
requestsTmpConfig.userSetLocale = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.server.wm;
|
||||||
|
|
||||||
|
import android.os.LocaleList;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Static utilities to overlay locales on top of another localeList.
|
||||||
|
*
|
||||||
|
* <p>This is used to overlay application-specific locales in
|
||||||
|
* {@link com.android.server.wm.ActivityTaskManagerInternal.PackageConfigurationUpdater} on top of
|
||||||
|
* system locales.
|
||||||
|
*/
|
||||||
|
final class LocaleOverlayHelper {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Combines the overlay locales and base locales.
|
||||||
|
* @return the combined {@link LocaleList} if the overlay locales is not empty/null else
|
||||||
|
* returns the empty/null LocaleList.
|
||||||
|
*/
|
||||||
|
static LocaleList combineLocalesIfOverlayExists(LocaleList overlayLocales,
|
||||||
|
LocaleList baseLocales) {
|
||||||
|
if (overlayLocales == null || overlayLocales.isEmpty()) {
|
||||||
|
return overlayLocales;
|
||||||
|
}
|
||||||
|
return combineLocales(overlayLocales, baseLocales);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a combined {@link LocaleList} by placing overlay locales before base locales and
|
||||||
|
* dropping duplicates from the base locales.
|
||||||
|
*/
|
||||||
|
private static LocaleList combineLocales(LocaleList overlayLocales, LocaleList baseLocales) {
|
||||||
|
Locale[] combinedLocales = new Locale[overlayLocales.size() + baseLocales.size()];
|
||||||
|
for (int i = 0; i < overlayLocales.size(); i++) {
|
||||||
|
combinedLocales[i] = overlayLocales.get(i);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < baseLocales.size(); i++) {
|
||||||
|
combinedLocales[i + overlayLocales.size()] = baseLocales.get(i);
|
||||||
|
}
|
||||||
|
// Constructor of {@link LocaleList} removes duplicates
|
||||||
|
return new LocaleList(combinedLocales);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -21,6 +21,7 @@ import static android.app.UiModeManager.MODE_NIGHT_CUSTOM;
|
|||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
|
import android.os.LocaleList;
|
||||||
import android.util.AtomicFile;
|
import android.util.AtomicFile;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
@@ -54,12 +55,14 @@ public class PackageConfigPersister {
|
|||||||
private static final String TAG_CONFIG = "config";
|
private static final String TAG_CONFIG = "config";
|
||||||
private static final String ATTR_PACKAGE_NAME = "package_name";
|
private static final String ATTR_PACKAGE_NAME = "package_name";
|
||||||
private static final String ATTR_NIGHT_MODE = "night_mode";
|
private static final String ATTR_NIGHT_MODE = "night_mode";
|
||||||
|
private static final String ATTR_LOCALES = "locale_list";
|
||||||
|
|
||||||
private static final String PACKAGE_DIRNAME = "package_configs";
|
private static final String PACKAGE_DIRNAME = "package_configs";
|
||||||
private static final String SUFFIX_FILE_NAME = "_config.xml";
|
private static final String SUFFIX_FILE_NAME = "_config.xml";
|
||||||
|
|
||||||
private final PersisterQueue mPersisterQueue;
|
private final PersisterQueue mPersisterQueue;
|
||||||
private final Object mLock = new Object();
|
private final Object mLock = new Object();
|
||||||
|
private final ActivityTaskManagerService mAtm;
|
||||||
|
|
||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
private final SparseArray<HashMap<String, PackageConfigRecord>> mPendingWrite =
|
private final SparseArray<HashMap<String, PackageConfigRecord>> mPendingWrite =
|
||||||
@@ -72,8 +75,9 @@ public class PackageConfigPersister {
|
|||||||
return new File(Environment.getDataSystemCeDirectory(userId), PACKAGE_DIRNAME);
|
return new File(Environment.getDataSystemCeDirectory(userId), PACKAGE_DIRNAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
PackageConfigPersister(PersisterQueue queue) {
|
PackageConfigPersister(PersisterQueue queue, ActivityTaskManagerService atm) {
|
||||||
mPersisterQueue = queue;
|
mPersisterQueue = queue;
|
||||||
|
mAtm = atm;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
@@ -100,7 +104,8 @@ public class PackageConfigPersister {
|
|||||||
final TypedXmlPullParser in = Xml.resolvePullParser(is);
|
final TypedXmlPullParser in = Xml.resolvePullParser(is);
|
||||||
int event;
|
int event;
|
||||||
String packageName = null;
|
String packageName = null;
|
||||||
int nightMode = MODE_NIGHT_AUTO;
|
Integer nightMode = null;
|
||||||
|
LocaleList locales = null;
|
||||||
while (((event = in.next()) != XmlPullParser.END_DOCUMENT)
|
while (((event = in.next()) != XmlPullParser.END_DOCUMENT)
|
||||||
&& event != XmlPullParser.END_TAG) {
|
&& event != XmlPullParser.END_TAG) {
|
||||||
final String name = in.getName();
|
final String name = in.getName();
|
||||||
@@ -120,6 +125,9 @@ public class PackageConfigPersister {
|
|||||||
case ATTR_NIGHT_MODE:
|
case ATTR_NIGHT_MODE:
|
||||||
nightMode = Integer.parseInt(attrValue);
|
nightMode = Integer.parseInt(attrValue);
|
||||||
break;
|
break;
|
||||||
|
case ATTR_LOCALES:
|
||||||
|
locales = LocaleList.forLanguageTags(attrValue);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -130,6 +138,7 @@ public class PackageConfigPersister {
|
|||||||
final PackageConfigRecord initRecord =
|
final PackageConfigRecord initRecord =
|
||||||
findRecordOrCreate(mModified, packageName, userId);
|
findRecordOrCreate(mModified, packageName, userId);
|
||||||
initRecord.mNightMode = nightMode;
|
initRecord.mNightMode = nightMode;
|
||||||
|
initRecord.mLocales = locales;
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Slog.d(TAG, "loadPackages: load one package " + initRecord);
|
Slog.d(TAG, "loadPackages: load one package " + initRecord);
|
||||||
}
|
}
|
||||||
@@ -155,7 +164,9 @@ public class PackageConfigPersister {
|
|||||||
"updateConfigIfNeeded record " + container + " find? " + modifiedRecord);
|
"updateConfigIfNeeded record " + container + " find? " + modifiedRecord);
|
||||||
}
|
}
|
||||||
if (modifiedRecord != null) {
|
if (modifiedRecord != null) {
|
||||||
container.setOverrideNightMode(modifiedRecord.mNightMode);
|
container.applyAppSpecificConfig(modifiedRecord.mNightMode,
|
||||||
|
LocaleOverlayHelper.combineLocalesIfOverlayExists(
|
||||||
|
modifiedRecord.mLocales, mAtm.getGlobalConfiguration().getLocales()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -165,10 +176,16 @@ public class PackageConfigPersister {
|
|||||||
ActivityTaskManagerService.PackageConfigurationUpdaterImpl impl) {
|
ActivityTaskManagerService.PackageConfigurationUpdaterImpl impl) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
PackageConfigRecord record = findRecordOrCreate(mModified, packageName, userId);
|
PackageConfigRecord record = findRecordOrCreate(mModified, packageName, userId);
|
||||||
record.mNightMode = impl.getNightMode();
|
if (impl.getNightMode() != null) {
|
||||||
|
record.mNightMode = impl.getNightMode();
|
||||||
if (record.isResetNightMode()) {
|
}
|
||||||
removePackage(record.mName, record.mUserId);
|
if (impl.getLocales() != null) {
|
||||||
|
record.mLocales = impl.getLocales();
|
||||||
|
}
|
||||||
|
if ((record.mNightMode == null || record.isResetNightMode())
|
||||||
|
&& (record.mLocales == null || record.mLocales.isEmpty())) {
|
||||||
|
// if all values default to system settings, we can remove the package.
|
||||||
|
removePackage(packageName, userId);
|
||||||
} else {
|
} else {
|
||||||
final PackageConfigRecord pendingRecord =
|
final PackageConfigRecord pendingRecord =
|
||||||
findRecord(mPendingWrite, record.mName, record.mUserId);
|
findRecord(mPendingWrite, record.mName, record.mUserId);
|
||||||
@@ -179,10 +196,11 @@ public class PackageConfigPersister {
|
|||||||
} else {
|
} else {
|
||||||
writeRecord = pendingRecord;
|
writeRecord = pendingRecord;
|
||||||
}
|
}
|
||||||
if (writeRecord.mNightMode == record.mNightMode) {
|
|
||||||
|
if (!updateNightMode(record, writeRecord) && !updateLocales(record, writeRecord)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
writeRecord.mNightMode = record.mNightMode;
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Slog.d(TAG, "PackageConfigUpdater save config " + writeRecord);
|
Slog.d(TAG, "PackageConfigUpdater save config " + writeRecord);
|
||||||
}
|
}
|
||||||
@@ -191,6 +209,22 @@ public class PackageConfigPersister {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean updateNightMode(PackageConfigRecord record, PackageConfigRecord writeRecord) {
|
||||||
|
if (record.mNightMode == null || record.mNightMode.equals(writeRecord.mNightMode)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
writeRecord.mNightMode = record.mNightMode;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean updateLocales(PackageConfigRecord record, PackageConfigRecord writeRecord) {
|
||||||
|
if (record.mLocales == null || record.mLocales.equals(writeRecord.mLocales)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
writeRecord.mLocales = record.mLocales;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
void removeUser(int userId) {
|
void removeUser(int userId) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
@@ -210,7 +244,7 @@ public class PackageConfigPersister {
|
|||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
void onPackageUninstall(String packageName) {
|
void onPackageUninstall(String packageName) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
for (int i = mModified.size() - 1; i > 0; i--) {
|
for (int i = mModified.size() - 1; i >= 0; i--) {
|
||||||
final int userId = mModified.keyAt(i);
|
final int userId = mModified.keyAt(i);
|
||||||
removePackage(packageName, userId);
|
removePackage(packageName, userId);
|
||||||
}
|
}
|
||||||
@@ -242,7 +276,8 @@ public class PackageConfigPersister {
|
|||||||
static class PackageConfigRecord {
|
static class PackageConfigRecord {
|
||||||
final String mName;
|
final String mName;
|
||||||
final int mUserId;
|
final int mUserId;
|
||||||
int mNightMode;
|
Integer mNightMode;
|
||||||
|
LocaleList mLocales;
|
||||||
|
|
||||||
PackageConfigRecord(String name, int userId) {
|
PackageConfigRecord(String name, int userId) {
|
||||||
mName = name;
|
mName = name;
|
||||||
@@ -256,7 +291,7 @@ public class PackageConfigPersister {
|
|||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "PackageConfigRecord package name: " + mName + " userId " + mUserId
|
return "PackageConfigRecord package name: " + mName + " userId " + mUserId
|
||||||
+ " nightMode " + mNightMode;
|
+ " nightMode " + mNightMode + " locales " + mLocales;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -369,7 +404,13 @@ public class PackageConfigPersister {
|
|||||||
}
|
}
|
||||||
xmlSerializer.startTag(null, TAG_CONFIG);
|
xmlSerializer.startTag(null, TAG_CONFIG);
|
||||||
xmlSerializer.attribute(null, ATTR_PACKAGE_NAME, mRecord.mName);
|
xmlSerializer.attribute(null, ATTR_PACKAGE_NAME, mRecord.mName);
|
||||||
xmlSerializer.attributeInt(null, ATTR_NIGHT_MODE, mRecord.mNightMode);
|
if (mRecord.mNightMode != null) {
|
||||||
|
xmlSerializer.attributeInt(null, ATTR_NIGHT_MODE, mRecord.mNightMode);
|
||||||
|
}
|
||||||
|
if (mRecord.mLocales != null) {
|
||||||
|
xmlSerializer.attribute(null, ATTR_LOCALES, mRecord.mLocales
|
||||||
|
.toLanguageTags());
|
||||||
|
}
|
||||||
xmlSerializer.endTag(null, TAG_CONFIG);
|
xmlSerializer.endTag(null, TAG_CONFIG);
|
||||||
xmlSerializer.endDocument();
|
xmlSerializer.endDocument();
|
||||||
xmlSerializer.flush();
|
xmlSerializer.flush();
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ import android.content.res.Configuration;
|
|||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.os.LocaleList;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
@@ -817,10 +818,13 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateNightModeForAllActivities(int nightMode) {
|
// TODO(b/199277065): Re-assess how app-specific locales are applied based on UXR
|
||||||
|
// TODO(b/199277729): Consider whether we need to add special casing for edge cases like
|
||||||
|
// activity-embeddings etc.
|
||||||
|
void updateAppSpecificSettingsForAllActivities(Integer nightMode, LocaleList localesOverride) {
|
||||||
for (int i = mActivities.size() - 1; i >= 0; --i) {
|
for (int i = mActivities.size() - 1; i >= 0; --i) {
|
||||||
final ActivityRecord r = mActivities.get(i);
|
final ActivityRecord r = mActivities.get(i);
|
||||||
if (r.setOverrideNightMode(nightMode) && r.mVisibleRequested) {
|
if (r.applyAppSpecificConfig(nightMode, localesOverride) && r.mVisibleRequested) {
|
||||||
r.ensureActivityConfiguration(0 /* globalChanges */, true /* preserveWindow */);
|
r.ensureActivityConfiguration(0 /* globalChanges */, true /* preserveWindow */);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,13 +43,17 @@ import static org.mockito.Mockito.when;
|
|||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
|
import android.app.IApplicationThread;
|
||||||
import android.app.PictureInPictureParams;
|
import android.app.PictureInPictureParams;
|
||||||
import android.app.servertransaction.ClientTransaction;
|
import android.app.servertransaction.ClientTransaction;
|
||||||
import android.app.servertransaction.EnterPipRequestedItem;
|
import android.app.servertransaction.EnterPipRequestedItem;
|
||||||
import android.content.pm.ActivityInfo;
|
import android.content.pm.ActivityInfo;
|
||||||
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
|
import android.os.Binder;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.os.LocaleList;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.platform.test.annotations.Presubmit;
|
import android.platform.test.annotations.Presubmit;
|
||||||
@@ -61,6 +65,7 @@ import org.junit.Before;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.Mockito;
|
||||||
import org.mockito.MockitoSession;
|
import org.mockito.MockitoSession;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -80,6 +85,9 @@ public class ActivityTaskManagerServiceTests extends WindowTestsBase {
|
|||||||
private final ArgumentCaptor<ClientTransaction> mClientTransactionCaptor =
|
private final ArgumentCaptor<ClientTransaction> mClientTransactionCaptor =
|
||||||
ArgumentCaptor.forClass(ClientTransaction.class);
|
ArgumentCaptor.forClass(ClientTransaction.class);
|
||||||
|
|
||||||
|
private static final String DEFAULT_PACKAGE_NAME = "my.application.package";
|
||||||
|
private static final int DEFAULT_USER_ID = 100;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
setBooted(mAtm);
|
setBooted(mAtm);
|
||||||
@@ -489,5 +497,269 @@ public class ActivityTaskManagerServiceTests extends WindowTestsBase {
|
|||||||
assertTrue(activity.supportsMultiWindow());
|
assertTrue(activity.supportsMultiWindow());
|
||||||
assertTrue(task.supportsMultiWindow());
|
assertTrue(task.supportsMultiWindow());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPackageConfigUpdate_locales_successfullyApplied() {
|
||||||
|
Configuration config = mAtm.getGlobalConfiguration();
|
||||||
|
config.setLocales(LocaleList.forLanguageTags("en-XC"));
|
||||||
|
mAtm.updateGlobalConfigurationLocked(config, true, true, DEFAULT_USER_ID);
|
||||||
|
mAtm.mProcessMap.put(Binder.getCallingPid(), createWindowProcessController(
|
||||||
|
DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID));
|
||||||
|
|
||||||
|
ActivityTaskManagerInternal.PackageConfigurationUpdater packageConfigUpdater =
|
||||||
|
mAtm.mInternal.createPackageConfigurationUpdater();
|
||||||
|
packageConfigUpdater.setLocales(LocaleList.forLanguageTags("en-XA,ar-XB")).commit();
|
||||||
|
|
||||||
|
WindowProcessController wpcAfterConfigChange = createWindowProcessController(
|
||||||
|
DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID);
|
||||||
|
|
||||||
|
assertEquals(LocaleList.forLanguageTags("en-XA,ar-XB,en-XC"),
|
||||||
|
wpcAfterConfigChange.getConfiguration().getLocales());
|
||||||
|
assertFalse(wpcAfterConfigChange.getConfiguration().isNightModeActive());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPackageConfigUpdate_nightMode_successfullyApplied() {
|
||||||
|
Configuration config = mAtm.getGlobalConfiguration();
|
||||||
|
config.setLocales(LocaleList.forLanguageTags("en-XC"));
|
||||||
|
mAtm.updateGlobalConfigurationLocked(config, true, true, DEFAULT_USER_ID);
|
||||||
|
mAtm.mProcessMap.put(Binder.getCallingPid(), createWindowProcessController(
|
||||||
|
DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID));
|
||||||
|
ActivityTaskManagerInternal.PackageConfigurationUpdater packageConfigUpdater =
|
||||||
|
mAtm.mInternal.createPackageConfigurationUpdater();
|
||||||
|
|
||||||
|
packageConfigUpdater.setNightMode(Configuration.UI_MODE_NIGHT_YES).commit();
|
||||||
|
|
||||||
|
WindowProcessController wpcAfterConfigChange = createWindowProcessController(
|
||||||
|
DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID);
|
||||||
|
assertTrue(wpcAfterConfigChange.getConfiguration().isNightModeActive());
|
||||||
|
assertEquals(LocaleList.forLanguageTags("en-XC"),
|
||||||
|
wpcAfterConfigChange.getConfiguration().getLocales());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPackageConfigUpdate_multipleLocaleUpdates_successfullyApplied() {
|
||||||
|
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);
|
||||||
|
ActivityTaskManagerInternal.PackageConfigurationUpdater packageConfigUpdater =
|
||||||
|
mAtm.mInternal.createPackageConfigurationUpdater();
|
||||||
|
|
||||||
|
packageConfigUpdater.setLocales(LocaleList.forLanguageTags("en-XA,ar-XB"))
|
||||||
|
.setNightMode(Configuration.UI_MODE_NIGHT_YES).commit();
|
||||||
|
|
||||||
|
WindowProcessController wpcAfterConfigChange1 = createWindowProcessController(
|
||||||
|
DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID);
|
||||||
|
assertEquals(LocaleList.forLanguageTags("en-XA,ar-XB,en-XC"),
|
||||||
|
wpcAfterConfigChange1.getConfiguration().getLocales());
|
||||||
|
assertTrue(wpcAfterConfigChange1.getConfiguration().isNightModeActive());
|
||||||
|
assertEquals(LocaleList.forLanguageTags("en-XA,ar-XB,en-XC"),
|
||||||
|
wpc.getConfiguration().getLocales());
|
||||||
|
|
||||||
|
packageConfigUpdater.setLocales(LocaleList.forLanguageTags("ja-XC,en-XC")).commit();
|
||||||
|
|
||||||
|
WindowProcessController wpcAfterConfigChange2 = createWindowProcessController(
|
||||||
|
DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID);
|
||||||
|
|
||||||
|
assertEquals(LocaleList.forLanguageTags("ja-XC,en-XC"),
|
||||||
|
wpcAfterConfigChange2.getConfiguration().getLocales());
|
||||||
|
assertTrue(wpcAfterConfigChange1.getConfiguration().isNightModeActive());
|
||||||
|
assertEquals(LocaleList.forLanguageTags("ja-XC,en-XC"),
|
||||||
|
wpc.getConfiguration().getLocales());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPackageConfigUpdate_multipleNightModeUpdates_successfullyApplied() {
|
||||||
|
Configuration config = mAtm.getGlobalConfiguration();
|
||||||
|
config.setLocales(LocaleList.forLanguageTags("en-XC"));
|
||||||
|
mAtm.updateGlobalConfigurationLocked(config, true, true, DEFAULT_USER_ID);
|
||||||
|
mAtm.mProcessMap.put(Binder.getCallingPid(), createWindowProcessController(
|
||||||
|
DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID));
|
||||||
|
ActivityTaskManagerInternal.PackageConfigurationUpdater packageConfigUpdater =
|
||||||
|
mAtm.mInternal.createPackageConfigurationUpdater();
|
||||||
|
|
||||||
|
packageConfigUpdater.setLocales(LocaleList.forLanguageTags("en-XA,ar-XB"))
|
||||||
|
.setNightMode(Configuration.UI_MODE_NIGHT_YES).commit();
|
||||||
|
|
||||||
|
WindowProcessController wpcAfterConfigChange1 = createWindowProcessController(
|
||||||
|
DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID);
|
||||||
|
assertEquals(LocaleList.forLanguageTags("en-XA,ar-XB,en-XC"),
|
||||||
|
wpcAfterConfigChange1.getConfiguration().getLocales());
|
||||||
|
assertTrue(wpcAfterConfigChange1.getConfiguration().isNightModeActive());
|
||||||
|
|
||||||
|
packageConfigUpdater.setNightMode(Configuration.UI_MODE_NIGHT_NO).commit();
|
||||||
|
|
||||||
|
WindowProcessController wpcAfterConfigChange2 = createWindowProcessController(
|
||||||
|
DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID);
|
||||||
|
assertEquals(LocaleList.forLanguageTags("en-XA,ar-XB,en-XC"),
|
||||||
|
wpcAfterConfigChange2.getConfiguration().getLocales());
|
||||||
|
assertFalse(wpcAfterConfigChange2.getConfiguration().isNightModeActive());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPackageConfigUpdate_onPackageUninstall_configShouldNotApply() {
|
||||||
|
Configuration config = mAtm.getGlobalConfiguration();
|
||||||
|
config.setLocales(LocaleList.forLanguageTags("en-XC"));
|
||||||
|
mAtm.updateGlobalConfigurationLocked(config, true, true, DEFAULT_USER_ID);
|
||||||
|
mAtm.mProcessMap.put(Binder.getCallingPid(), createWindowProcessController(
|
||||||
|
DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID));
|
||||||
|
ActivityTaskManagerInternal.PackageConfigurationUpdater packageConfigUpdater =
|
||||||
|
mAtm.mInternal.createPackageConfigurationUpdater();
|
||||||
|
|
||||||
|
packageConfigUpdater.setLocales(LocaleList.forLanguageTags("en-XA,ar-XB"))
|
||||||
|
.setNightMode(Configuration.UI_MODE_NIGHT_YES).commit();
|
||||||
|
|
||||||
|
WindowProcessController wpcAfterConfigChange1 = createWindowProcessController(
|
||||||
|
DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID);
|
||||||
|
assertEquals(LocaleList.forLanguageTags("en-XA,ar-XB,en-XC"),
|
||||||
|
wpcAfterConfigChange1.getConfiguration().getLocales());
|
||||||
|
assertTrue(wpcAfterConfigChange1.getConfiguration().isNightModeActive());
|
||||||
|
|
||||||
|
mAtm.mInternal.onPackageUninstalled(DEFAULT_PACKAGE_NAME);
|
||||||
|
|
||||||
|
WindowProcessController wpcAfterConfigChange2 = createWindowProcessController(
|
||||||
|
DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID);
|
||||||
|
assertEquals(LocaleList.forLanguageTags("en-XC"),
|
||||||
|
wpcAfterConfigChange2.getConfiguration().getLocales());
|
||||||
|
assertFalse(wpcAfterConfigChange2.getConfiguration().isNightModeActive());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPackageConfigUpdate_LocalesEmptyAndNightModeUndefined_configShouldNotApply() {
|
||||||
|
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);
|
||||||
|
ActivityTaskManagerInternal.PackageConfigurationUpdater packageConfigUpdater =
|
||||||
|
mAtm.mInternal.createPackageConfigurationUpdater();
|
||||||
|
|
||||||
|
packageConfigUpdater.setLocales(LocaleList.forLanguageTags("en-XA,ar-XB"))
|
||||||
|
.setNightMode(Configuration.UI_MODE_NIGHT_YES).commit();
|
||||||
|
WindowProcessController wpcAfterConfigChange1 = createWindowProcessController(
|
||||||
|
DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID);
|
||||||
|
|
||||||
|
assertEquals(LocaleList.forLanguageTags("en-XA,ar-XB,en-XC"),
|
||||||
|
wpcAfterConfigChange1.getConfiguration().getLocales());
|
||||||
|
assertTrue(wpcAfterConfigChange1.getConfiguration().isNightModeActive());
|
||||||
|
assertEquals(LocaleList.forLanguageTags("en-XA,ar-XB,en-XC"),
|
||||||
|
wpc.getConfiguration().getLocales());
|
||||||
|
|
||||||
|
packageConfigUpdater.setLocales(LocaleList.getEmptyLocaleList())
|
||||||
|
.setNightMode(Configuration.UI_MODE_NIGHT_UNDEFINED).commit();
|
||||||
|
|
||||||
|
WindowProcessController wpcAfterConfigChange2 = createWindowProcessController(
|
||||||
|
DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID);
|
||||||
|
assertEquals(LocaleList.forLanguageTags("en-XC"),
|
||||||
|
wpcAfterConfigChange2.getConfiguration().getLocales());
|
||||||
|
assertFalse(wpcAfterConfigChange2.getConfiguration().isNightModeActive());
|
||||||
|
assertEquals(LocaleList.forLanguageTags("en-XC"),
|
||||||
|
wpc.getConfiguration().getLocales());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPackageConfigUpdate_WhenUserRemoved_configShouldNotApply() {
|
||||||
|
Configuration config = mAtm.getGlobalConfiguration();
|
||||||
|
config.setLocales(LocaleList.forLanguageTags("en-XC"));
|
||||||
|
mAtm.updateGlobalConfigurationLocked(config, true, true, DEFAULT_USER_ID);
|
||||||
|
mAtm.mProcessMap.put(Binder.getCallingPid(), createWindowProcessController(
|
||||||
|
DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID));
|
||||||
|
|
||||||
|
ActivityTaskManagerInternal.PackageConfigurationUpdater packageConfigUpdater =
|
||||||
|
mAtm.mInternal.createPackageConfigurationUpdater();
|
||||||
|
|
||||||
|
packageConfigUpdater.setLocales(LocaleList.forLanguageTags("en-XA,ar-XB"))
|
||||||
|
.setNightMode(Configuration.UI_MODE_NIGHT_YES).commit();
|
||||||
|
|
||||||
|
WindowProcessController wpcAfterConfigChange1 = createWindowProcessController(
|
||||||
|
DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID);
|
||||||
|
assertEquals(LocaleList.forLanguageTags("en-XA,ar-XB,en-XC"),
|
||||||
|
wpcAfterConfigChange1.getConfiguration().getLocales());
|
||||||
|
assertTrue(wpcAfterConfigChange1.getConfiguration().isNightModeActive());
|
||||||
|
|
||||||
|
mAtm.mInternal.removeUser(DEFAULT_USER_ID);
|
||||||
|
|
||||||
|
WindowProcessController wpcAfterConfigChange2 = createWindowProcessController(
|
||||||
|
DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID);
|
||||||
|
assertEquals(LocaleList.forLanguageTags("en-XC"),
|
||||||
|
wpcAfterConfigChange2.getConfiguration().getLocales());
|
||||||
|
assertFalse(wpcAfterConfigChange2.getConfiguration().isNightModeActive());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPackageConfigUpdate_setLocaleListToEmpty_doesNotOverlayLocaleListInWpc() {
|
||||||
|
Configuration config = mAtm.getGlobalConfiguration();
|
||||||
|
config.setLocales(LocaleList.forLanguageTags("en-XC"));
|
||||||
|
mAtm.updateGlobalConfigurationLocked(config, true, true, DEFAULT_USER_ID);
|
||||||
|
mAtm.mProcessMap.put(Binder.getCallingPid(), createWindowProcessController(
|
||||||
|
DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID));
|
||||||
|
|
||||||
|
ActivityTaskManagerInternal.PackageConfigurationUpdater packageConfigUpdater =
|
||||||
|
mAtm.mInternal.createPackageConfigurationUpdater();
|
||||||
|
|
||||||
|
packageConfigUpdater.setLocales(LocaleList.forLanguageTags("en-XA,ar-XB"))
|
||||||
|
.setNightMode(Configuration.UI_MODE_NIGHT_YES).commit();
|
||||||
|
|
||||||
|
WindowProcessController wpcAfterConfigChange1 = createWindowProcessController(
|
||||||
|
DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID);
|
||||||
|
assertEquals(LocaleList.forLanguageTags("en-XA,ar-XB,en-XC"),
|
||||||
|
wpcAfterConfigChange1.getConfiguration().getLocales());
|
||||||
|
assertTrue(wpcAfterConfigChange1.getConfiguration().isNightModeActive());
|
||||||
|
|
||||||
|
packageConfigUpdater.setLocales(LocaleList.getEmptyLocaleList()).commit();
|
||||||
|
|
||||||
|
WindowProcessController wpcAfterConfigChange2 = createWindowProcessController(
|
||||||
|
DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID);
|
||||||
|
assertEquals(LocaleList.forLanguageTags("en-XC"),
|
||||||
|
wpcAfterConfigChange2.getConfiguration().getLocales());
|
||||||
|
assertTrue(wpcAfterConfigChange2.getConfiguration().isNightModeActive());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPackageConfigUpdate_resetNightMode_doesNotOverrideNightModeInWpc() {
|
||||||
|
Configuration config = mAtm.getGlobalConfiguration();
|
||||||
|
config.setLocales(LocaleList.forLanguageTags("en-XC"));
|
||||||
|
mAtm.updateGlobalConfigurationLocked(config, true, true, DEFAULT_USER_ID);
|
||||||
|
mAtm.mProcessMap.put(Binder.getCallingPid(), createWindowProcessController(
|
||||||
|
DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID));
|
||||||
|
|
||||||
|
ActivityTaskManagerInternal.PackageConfigurationUpdater packageConfigUpdater =
|
||||||
|
mAtm.mInternal.createPackageConfigurationUpdater();
|
||||||
|
|
||||||
|
packageConfigUpdater.setLocales(LocaleList.forLanguageTags("en-XA,ar-XB"))
|
||||||
|
.setNightMode(Configuration.UI_MODE_NIGHT_YES).commit();
|
||||||
|
|
||||||
|
WindowProcessController wpcAfterConfigChange1 = createWindowProcessController(
|
||||||
|
DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID);
|
||||||
|
assertEquals(LocaleList.forLanguageTags("en-XA,ar-XB,en-XC"),
|
||||||
|
wpcAfterConfigChange1.getConfiguration().getLocales());
|
||||||
|
assertTrue(wpcAfterConfigChange1.getConfiguration().isNightModeActive());
|
||||||
|
|
||||||
|
packageConfigUpdater.setNightMode(Configuration.UI_MODE_NIGHT_UNDEFINED).commit();
|
||||||
|
|
||||||
|
WindowProcessController wpcAfterConfigChange2 = createWindowProcessController(
|
||||||
|
DEFAULT_PACKAGE_NAME, DEFAULT_USER_ID);
|
||||||
|
assertEquals(LocaleList.forLanguageTags("en-XA,ar-XB,en-XC"),
|
||||||
|
wpcAfterConfigChange2.getConfiguration().getLocales());
|
||||||
|
assertFalse(wpcAfterConfigChange2.getConfiguration().isNightModeActive());
|
||||||
|
}
|
||||||
|
|
||||||
|
private WindowProcessController createWindowProcessController(String packageName,
|
||||||
|
int userId) {
|
||||||
|
WindowProcessListener mMockListener = Mockito.mock(WindowProcessListener.class);
|
||||||
|
ApplicationInfo info = mock(ApplicationInfo.class);
|
||||||
|
info.packageName = packageName;
|
||||||
|
WindowProcessController wpc = new WindowProcessController(
|
||||||
|
mAtm, info, packageName, 0, userId, null, mMockListener);
|
||||||
|
wpc.setThread(mock(IApplicationThread.class));
|
||||||
|
return wpc;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import static org.junit.Assert.assertEquals;
|
|||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
@@ -49,6 +50,7 @@ import android.content.pm.ApplicationInfo;
|
|||||||
import android.content.pm.ServiceInfo;
|
import android.content.pm.ServiceInfo;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
|
import android.os.LocaleList;
|
||||||
import android.platform.test.annotations.Presubmit;
|
import android.platform.test.annotations.Presubmit;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@@ -371,8 +373,9 @@ public class WindowProcessControllerTests extends WindowTestsBase {
|
|||||||
public void testTopActivityUiModeChangeScheduleConfigChange() {
|
public void testTopActivityUiModeChangeScheduleConfigChange() {
|
||||||
final ActivityRecord activity = createActivityRecord(mWpc);
|
final ActivityRecord activity = createActivityRecord(mWpc);
|
||||||
activity.mVisibleRequested = true;
|
activity.mVisibleRequested = true;
|
||||||
doReturn(true).when(activity).setOverrideNightMode(anyInt());
|
doReturn(true).when(activity).applyAppSpecificConfig(anyInt(), any());
|
||||||
mWpc.updateNightModeForAllActivities(Configuration.UI_MODE_NIGHT_YES);
|
mWpc.updateAppSpecificSettingsForAllActivities(Configuration.UI_MODE_NIGHT_YES,
|
||||||
|
LocaleList.forLanguageTags("en-XA"));
|
||||||
verify(activity).ensureActivityConfiguration(anyInt(), anyBoolean());
|
verify(activity).ensureActivityConfiguration(anyInt(), anyBoolean());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user