diff options
| author | 2018-09-22 11:38:53 +0000 | |
|---|---|---|
| committer | 2018-09-22 11:38:53 +0000 | |
| commit | 99c1e2783c40d2f0c5c7136a97a6d3583688b70a (patch) | |
| tree | 549fbae64354e140606f1cd7d04f7d4dfc39a5bc | |
| parent | 239e2d2476f179b702be9edce41e00b3d528b317 (diff) | |
| parent | 75157d77914565b7b6fa48292607d8e537d3a57e (diff) | |
Merge "Introduce process configuration to WindowProcessController"
18 files changed, 260 insertions, 61 deletions
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 055a91eaa1cc..14b8ae45d989 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -3379,7 +3379,7 @@ public class ActivityManager { */ public ConfigurationInfo getDeviceConfigurationInfo() { try { - return getService().getDeviceConfigurationInfo(); + return getTaskService().getDeviceConfigurationInfo(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl index c0c8b799ec3b..519a2749e5bb 100644 --- a/core/java/android/app/IActivityManager.aidl +++ b/core/java/android/app/IActivityManager.aidl @@ -208,8 +208,6 @@ interface IActivityManager { List<ActivityManager.RunningServiceInfo> getServices(int maxNum, int flags); // Retrieve running application processes in the system List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses(); - // Get device configuration - ConfigurationInfo getDeviceConfigurationInfo(); IBinder peekService(in Intent service, in String resolvedType, in String callingPackage); // Turn on/off profiling in a particular process. boolean profileControl(in String process, int userId, boolean start, diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl index abd1cca06d26..b7b6352ad5cf 100644 --- a/core/java/android/app/IActivityTaskManager.aidl +++ b/core/java/android/app/IActivityTaskManager.aidl @@ -344,6 +344,9 @@ interface IActivityTaskManager { void notifyPinnedStackAnimationStarted(); void notifyPinnedStackAnimationEnded(); + // Get device configuration + ConfigurationInfo getDeviceConfigurationInfo(); + /** * Resizes the pinned stack. * diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index f7fe9e2455f1..8c7fc849b79e 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -5895,7 +5895,8 @@ public class ActivityManagerService extends IActivityManager.Stub PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION); } if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc " - + processName + " with config " + getGlobalConfiguration()); + + processName + " with config " + + app.getWindowProcessController().getConfiguration()); ApplicationInfo appInfo = instr != null ? instr.mTargetInfo : app.info; app.compat = compatibilityInfoForPackage(appInfo); @@ -6008,8 +6009,8 @@ public class ActivityManagerService extends IActivityManager.Stub instr2.mUiAutomationConnection, testMode, mBinderTransactionTrackingEnabled, enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.isPersistent(), - new Configuration(getGlobalConfiguration()), app.compat, - getCommonServicesLocked(app.isolated), + new Configuration(app.getWindowProcessController().getConfiguration()), + app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked(), buildSerial, isAutofillCompatEnabled); } else { @@ -6017,8 +6018,8 @@ public class ActivityManagerService extends IActivityManager.Stub null, null, null, testMode, mBinderTransactionTrackingEnabled, enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.isPersistent(), - new Configuration(getGlobalConfiguration()), app.compat, - getCommonServicesLocked(app.isolated), + new Configuration(app.getWindowProcessController().getConfiguration()), + app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked(), buildSerial, isAutofillCompatEnabled); } @@ -8718,7 +8719,7 @@ public class ActivityManagerService extends IActivityManager.Stub StatsLog.write(StatsLog.ISOLATED_UID_CHANGED, info.uid, uid, StatsLog.ISOLATED_UID_CHANGED__EVENT__CREATED); } - final ProcessRecord r = new ProcessRecord(this, info, proc, uid); + final ProcessRecord r = new ProcessRecord(this, info, proc, uid, getGlobalConfiguration()); if (!mBooted && !mBooting && userId == UserHandle.USER_SYSTEM && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) { @@ -17082,30 +17083,6 @@ public class ActivityManagerService extends IActivityManager.Stub } } - // ========================================================= - // CONFIGURATION - // ========================================================= - - public ConfigurationInfo getDeviceConfigurationInfo() { - ConfigurationInfo config = new ConfigurationInfo(); - synchronized (this) { - final Configuration globalConfig = getGlobalConfiguration(); - config.reqTouchScreen = globalConfig.touchscreen; - config.reqKeyboardType = globalConfig.keyboard; - config.reqNavigation = globalConfig.navigation; - if (globalConfig.navigation == Configuration.NAVIGATION_DPAD - || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) { - config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; - } - if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED - && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) { - config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; - } - config.reqGlEsVersion = GL_ES_VERSION; - } - return config; - } - @Override public StackInfo getFocusedStackInfo() throws RemoteException { return mActivityTaskManager.getFocusedStackInfo(); diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index b24c36ad9179..4bcaf7145e60 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -2063,7 +2063,12 @@ final class ActivityManagerShellCommand extends ShellCommand { pw.print("has-secure-screen-lock: "); pw.println(kgm.isDeviceSecure()); } - ConfigurationInfo configInfo = mInternal.getDeviceConfigurationInfo(); + ConfigurationInfo configInfo = null; + try { + configInfo = mTaskInterface.getDeviceConfigurationInfo(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } if (configInfo.reqGlEsVersion != ConfigurationInfo.GL_ES_VERSION_UNDEFINED) { if (protoOutputStream != null) { protoOutputStream.write(DeviceConfigurationProto.OPENGL_VERSION, diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index c887370024ee..1127db134d66 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -1558,7 +1558,8 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D // we have to always create a new Configuration here. final MergedConfiguration mergedConfiguration = new MergedConfiguration( - mService.getGlobalConfiguration(), r.getMergedOverrideConfiguration()); + app.getWindowProcessController().getConfiguration(), + r.getMergedOverrideConfiguration()); r.setLastReportedConfiguration(mergedConfiguration); logIfTransactionTooLarge(r.intent, r.icicle); diff --git a/services/core/java/com/android/server/am/ActivityTaskManagerService.java b/services/core/java/com/android/server/am/ActivityTaskManagerService.java index 9acb04be525b..4dc28510c5ec 100644 --- a/services/core/java/com/android/server/am/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/am/ActivityTaskManagerService.java @@ -149,6 +149,7 @@ import android.content.IIntentSender; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; +import android.content.pm.ConfigurationInfo; import android.content.pm.IPackageManager; import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; @@ -649,6 +650,11 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { mUgmInternal = LocalServices.getService(UriGrantsManagerInternal.class); } + int increaseConfigurationSeqLocked() { + mConfigurationSeq = Math.max(++mConfigurationSeq, 1); + return mConfigurationSeq; + } + protected ActivityStackSupervisor createStackSupervisor() { final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mH.getLooper()); supervisor.initialize(); @@ -704,6 +710,46 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { return mLockTaskController; } + /** + * Return the global configuration used by the process corresponding to the input pid. This is + * usually the global configuration with some overrides specific to that process. + */ + Configuration getGlobalConfigurationForCallingPid() { + final int pid = Binder.getCallingPid(); + if (pid == MY_PID || pid < 0) { + return getGlobalConfiguration(); + } + synchronized (mGlobalLock) { + final WindowProcessController app = mPidMap.get(pid); + return app != null ? app.getConfiguration() : getGlobalConfiguration(); + } + } + + /** + * Return the device configuration info used by the process corresponding to the input pid. + * The value is consistent with the global configuration for the process. + */ + @Override + public ConfigurationInfo getDeviceConfigurationInfo() { + ConfigurationInfo config = new ConfigurationInfo(); + synchronized (mGlobalLock) { + final Configuration globalConfig = getGlobalConfigurationForCallingPid(); + config.reqTouchScreen = globalConfig.touchscreen; + config.reqKeyboardType = globalConfig.keyboard; + config.reqNavigation = globalConfig.navigation; + if (globalConfig.navigation == Configuration.NAVIGATION_DPAD + || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) { + config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; + } + if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED + && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) { + config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; + } + config.reqGlEsVersion = mAm.GL_ES_VERSION; + } + return config; + } + private void start() { mInternal = new LocalService(); LocalServices.addService(ActivityTaskManagerInternal.class, mInternal); @@ -4264,7 +4310,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { public Configuration getConfiguration() { Configuration ci; synchronized(mGlobalLock) { - ci = new Configuration(getGlobalConfiguration()); + ci = new Configuration(getGlobalConfigurationForCallingPid()); ci.userSetLocale = false; } return ci; @@ -4420,8 +4466,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { locales.get(bestLocaleIndex))); } - mConfigurationSeq = Math.max(++mConfigurationSeq, 1); - mTempConfig.seq = mConfigurationSeq; + mTempConfig.seq = increaseConfigurationSeqLocked(); // Update stored global config and notify everyone about the change. mStackSupervisor.onConfigurationChanged(mTempConfig); @@ -4455,6 +4500,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { mAm.mHandler.sendMessage(msg); } + // TODO: Consider using mPidMap to update configurations for processes. for (int i = mAm.mLruProcesses.size() - 1; i >= 0; i--) { ProcessRecord app = mAm.mLruProcesses.get(i); try { @@ -5596,5 +5642,47 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } } + /** + * Set the corresponding display information for the process global configuration. To be + * called when we need to show IME on a different display. + * + * @param pid The process id associated with the IME window. + * @param displayId The ID of the display showing the IME. + */ + @Override + public void onImeWindowSetOnDisplay(int pid, int displayId) { + if (pid == MY_PID || pid < 0) { + if (DEBUG_CONFIGURATION) { + Slog.w(TAG, + "Trying to update display configuration for system/invalid process."); + } + return; + } + mH.post(() -> { + synchronized (mGlobalLock) { + // Check if display is initialized in AM. + if (!mStackSupervisor.isDisplayAdded(displayId)) { + // Call come when display is not yet added or has already been removed. + if (DEBUG_CONFIGURATION) { + Slog.w(TAG, "Trying to update display configuration for non-existing " + + "displayId=" + displayId); + } + return; + } + final WindowProcessController imeProcess = mPidMap.get(pid); + if (imeProcess == null) { + if (DEBUG_CONFIGURATION) { + Slog.w(TAG, "Trying to update display configuration for invalid pid: " + + pid); + } + return; + } + // Fetch the current override configuration of the display and set it to the + // process global configuration. + imeProcess.onConfigurationChanged( + mStackSupervisor.getDisplayOverrideConfiguration(displayId)); + } + }); + } } } diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java index d3dc0f34cbf1..667d3faefc9f 100644 --- a/services/core/java/com/android/server/am/ProcessRecord.java +++ b/services/core/java/com/android/server/am/ProcessRecord.java @@ -17,18 +17,10 @@ package com.android.server.am; import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT; + import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; -import android.os.Debug; -import android.util.ArraySet; -import android.util.DebugUtils; -import android.util.EventLog; -import android.util.Slog; -import com.android.internal.app.procstats.ProcessStats; -import com.android.internal.app.procstats.ProcessState; -import com.android.internal.os.BatteryStatsImpl; - import android.app.ActivityManager; import android.app.Dialog; import android.app.IApplicationThread; @@ -36,7 +28,9 @@ import android.content.ComponentName; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.res.CompatibilityInfo; +import android.content.res.Configuration; import android.os.Binder; +import android.os.Debug; import android.os.IBinder; import android.os.Process; import android.os.RemoteException; @@ -44,10 +38,18 @@ import android.os.SystemClock; import android.os.Trace; import android.os.UserHandle; import android.util.ArrayMap; +import android.util.ArraySet; +import android.util.DebugUtils; +import android.util.EventLog; +import android.util.Slog; import android.util.StatsLog; import android.util.TimeUtils; import android.util.proto.ProtoOutputStream; +import com.android.internal.app.procstats.ProcessState; +import com.android.internal.app.procstats.ProcessStats; +import com.android.internal.os.BatteryStatsImpl; + import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; @@ -307,6 +309,7 @@ final class ProcessRecord implements WindowProcessListener { pw.print(prefix); pw.print("manageSpaceActivityName="); pw.println(info.manageSpaceActivityName); } + pw.print(prefix); pw.print("dir="); pw.print(info.sourceDir); pw.print(" publicDir="); pw.print(info.publicSourceDir); pw.print(" data="); pw.println(info.dataDir); @@ -520,7 +523,7 @@ final class ProcessRecord implements WindowProcessListener { } ProcessRecord(ActivityManagerService _service, ApplicationInfo _info, String _processName, - int _uid) { + int _uid, Configuration config) { mService = _service; info = _info; isolated = _info.uid != _uid; @@ -534,7 +537,7 @@ final class ProcessRecord implements WindowProcessListener { removed = false; lastStateTime = lastPssTime = nextPssTime = SystemClock.uptimeMillis(); mWindowProcessController = new WindowProcessController( - mService.mActivityTaskManager, info, processName, uid, userId, this, this); + mService.mActivityTaskManager, info, processName, uid, userId, this, this, config); pkgList.put(_info.packageName, new ProcessStats.ProcessStateHolder(_info.longVersionCode)); } diff --git a/services/core/java/com/android/server/am/WindowProcessController.java b/services/core/java/com/android/server/am/WindowProcessController.java index e5551b51a093..da172fb10511 100644 --- a/services/core/java/com/android/server/am/WindowProcessController.java +++ b/services/core/java/com/android/server/am/WindowProcessController.java @@ -17,7 +17,10 @@ package com.android.server.am; import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT; + +import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RELEASE; +import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION; import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RELEASE; import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; @@ -29,11 +32,12 @@ import static com.android.server.am.ActivityStack.ActivityState.RESUMED; import static com.android.server.am.ActivityStack.ActivityState.STOPPING; import android.app.Activity; -import android.app.ActivityTaskManager; import android.app.ActivityThread; import android.app.IApplicationThread; +import android.app.servertransaction.ConfigurationChangeItem; import android.content.Intent; import android.content.pm.ApplicationInfo; +import android.content.res.Configuration; import android.os.RemoteException; import android.util.ArraySet; import android.util.Log; @@ -41,7 +45,7 @@ import android.util.Slog; import com.android.internal.app.HeavyWeightSwitcherActivity; import com.android.internal.util.function.pooled.PooledLambda; -import com.android.internal.util.function.pooled.PooledRunnable; +import com.android.server.wm.ConfigurationContainer; import java.io.PrintWriter; import java.util.ArrayList; @@ -57,9 +61,10 @@ import java.util.ArrayList; * window manager so the window manager lock is held and appropriate permissions are checked before * calls are allowed to proceed. */ -public class WindowProcessController { +public class WindowProcessController extends ConfigurationContainer<ConfigurationContainer> { private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowProcessController" : TAG_AM; private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE; + private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION; // all about the first app in the process final ApplicationInfo mInfo; @@ -108,8 +113,12 @@ public class WindowProcessController { // any tasks this process had run root activities in private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<>(); + // Last configuration that was reported to the process. + private final Configuration mLastReportedConfiguration; + WindowProcessController(ActivityTaskManagerService atm, ApplicationInfo info, String name, - int uid, int userId, Object owner, WindowProcessListener listener) { + int uid, int userId, Object owner, WindowProcessListener listener, + Configuration config) { mInfo = info; mName = name; mUid = uid; @@ -117,6 +126,10 @@ public class WindowProcessController { mOwner = owner; mListener = listener; mAtm = atm; + mLastReportedConfiguration = new Configuration(); + if (config != null) { + onConfigurationChanged(config); + } } public void setPid(int pid) { @@ -219,6 +232,21 @@ public class WindowProcessController { return mInstrumenting; } + @Override + protected int getChildCount() { + return 0; + } + + @Override + protected ConfigurationContainer getChildAt(int index) { + return null; + } + + @Override + protected ConfigurationContainer getParent() { + return null; + } + public void addPackage(String packageName) { synchronized (mAtm.mGlobalLock) { mPkgList.add(packageName); @@ -526,6 +554,50 @@ public class WindowProcessController { mAtm.mH.post(r); } + @Override + public void onConfigurationChanged(Configuration newGlobalConfig) { + super.onConfigurationChanged(newGlobalConfig); + updateConfiguration(); + } + + @Override + public void onOverrideConfigurationChanged(Configuration newOverrideConfig) { + super.onOverrideConfigurationChanged(newOverrideConfig); + updateConfiguration(); + } + + private void updateConfiguration() { + final Configuration config = getConfiguration(); + if (mLastReportedConfiguration.diff(config) == 0) { + // Nothing changed. + return; + } + + try { + if (mThread == null) { + return; + } + if (DEBUG_CONFIGURATION) { + Slog.v(TAG_CONFIGURATION, "Sending to proc " + mName + + " new config " + config); + } + config.seq = mAtm.increaseConfigurationSeqLocked(); + mAtm.getLifecycleManager().scheduleTransaction(mThread, + ConfigurationChangeItem.obtain(config)); + setLastReportedConfiguration(config); + } catch (Exception e) { + Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e); + } + } + + private void setLastReportedConfiguration(Configuration config) { + mLastReportedConfiguration.setTo(config); + } + + Configuration getLastReportedConfiguration() { + return mLastReportedConfiguration; + } + /** Returns the total time (in milliseconds) spent executing in both user and system code. */ public long getCpuTime() { return (mListener != null) ? mListener.getCpuTime() : 0; @@ -574,6 +646,9 @@ public class WindowProcessController { pw.print(prefix); pw.print("mVrThreadTid="); pw.println(mVrThreadTid); } } + pw.println(prefix + " Configuration=" + getConfiguration()); + pw.println(prefix + " OverrideConfiguration=" + getOverrideConfiguration()); + pw.println(prefix + " mLastReportedConfiguration=" + mLastReportedConfiguration); } } diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java index 524ca170336f..7d2fc15a28c5 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java @@ -30,7 +30,6 @@ import android.os.IBinder; import android.os.SystemClock; import android.service.voice.IVoiceInteractionSession; import android.util.SparseIntArray; -import android.view.RemoteAnimationAdapter; import com.android.internal.app.IVoiceInteractor; import com.android.server.am.WindowProcessController; @@ -289,4 +288,13 @@ public abstract class ActivityTaskManagerInternal { public abstract void onPackageAdded(String name, boolean replacing); public abstract CompatibilityInfo compatibilityInfoForPackage(ApplicationInfo ai); + + /** + * Set the corresponding display information for the process global configuration. To be called + * when we need to show IME on a different display. + * + * @param pid The process id associated with the IME window. + * @param displayId The ID of the display showing the IME. + */ + public abstract void onImeWindowSetOnDisplay(int pid, int displayId); } diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java index 57cae399b01f..27b623bc0ec3 100644 --- a/services/core/java/com/android/server/wm/WindowManagerInternal.java +++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java @@ -19,6 +19,7 @@ package com.android.server.wm; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.ClipData; +import android.content.res.Configuration; import android.graphics.Rect; import android.graphics.Region; import android.hardware.display.DisplayManagerInternal; @@ -456,4 +457,11 @@ public abstract class WindowManagerInternal { * Return the display Id for given window. */ public abstract int getDisplayIdForWindow(IBinder windowToken); + + // TODO: use WindowProcessController once go/wm-unified is done. + /** + * Notifies the window manager that configuration of the process associated with the input pid + * changed. + */ + public abstract void onProcessConfigurationChanged(int pid, Configuration newConfig); } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 71ce1d9e2ea7..017f667756bc 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -182,6 +182,7 @@ import android.util.Log; import android.util.MergedConfiguration; import android.util.Pair; import android.util.Slog; +import android.util.SparseArray; import android.util.SparseBooleanArray; import android.util.SparseIntArray; import android.util.TimeUtils; @@ -480,6 +481,10 @@ public class WindowManagerService extends IWindowManager.Stub */ WindowState[] mPendingRemoveTmp = new WindowState[20]; + // TODO: use WindowProcessController once go/wm-unified is done. + /** Mapping of process pids to configurations */ + final SparseArray<Configuration> mProcessConfigurations = new SparseArray<>(); + /** * Windows whose surface should be destroyed. */ @@ -7430,6 +7435,19 @@ public class WindowManagerService extends IWindowManager.Stub return Display.INVALID_DISPLAY; } } + + @Override + public void onProcessConfigurationChanged(int pid, Configuration newConfig) { + synchronized (mWindowMap) { + Configuration currentConfig = mProcessConfigurations.get(pid); + if (currentConfig == null) { + currentConfig = new Configuration(newConfig); + } else { + currentConfig.setTo(newConfig); + } + mProcessConfigurations.put(pid, currentConfig); + } + } } void registerAppFreezeListener(AppFreezeListener listener) { diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 69ff815c7c6d..7161a70b08fe 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -304,6 +304,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP */ private final MergedConfiguration mLastReportedConfiguration = new MergedConfiguration(); + private final Configuration mTempConfiguration = new Configuration(); + /** * The last content insets returned to the client in relayout. We use * these in the bounds animation to ensure we only observe inset changes @@ -2250,8 +2252,17 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } } + private Configuration getProcessGlobalConfiguration() { + // For child windows we want to use the pid for the parent window in case the the child + // window was added from another process. + final int pid = isChildWindow() ? getParentWindow().mSession.mPid : mSession.mPid; + mTempConfiguration.setTo(mService.mProcessConfigurations.get( + pid, mService.mRoot.getConfiguration())); + return mTempConfiguration; + } + void getMergedConfiguration(MergedConfiguration outConfiguration) { - final Configuration globalConfig = mService.mRoot.getConfiguration(); + final Configuration globalConfig = getProcessGlobalConfiguration(); final Configuration overrideConfig = getMergedOverrideConfiguration(); outConfiguration.setConfiguration(globalConfig, overrideConfig); } @@ -2854,7 +2865,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP return mAppToken.mFrozenMergedConfig.peek(); } - return super.getConfiguration(); + // We use the process config this window is associated with as the based global config since + // the process can override it config, but isn't part of the window hierarchy. + final Configuration config = getProcessGlobalConfiguration(); + config.updateFrom(getMergedOverrideConfiguration()); + return config; } void reportResized() { diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java index 47ce8796e449..c44e492e308b 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java @@ -258,7 +258,7 @@ public class ActivityManagerServiceTest { uidRec.hasInternetPermission = true; mAms.mActiveUids.put(uid, uidRec); - final ProcessRecord appRec = new ProcessRecord(mAms, new ApplicationInfo(), TAG, uid); + final ProcessRecord appRec = new ProcessRecord(mAms, new ApplicationInfo(), TAG, uid, null); appRec.thread = Mockito.mock(IApplicationThread.class); mAms.mLruProcesses.add(appRec); diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java index e1ebbcf8f653..9192d6b84fee 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java @@ -83,7 +83,7 @@ public class ActivityStartControllerTests extends ActivityTestsBase { final WindowProcessController wpc = new WindowProcessController(mService, mService.mContext.getApplicationInfo(), "name", 12345, UserHandle.getUserId(12345), mock(Object.class), - mock(WindowProcessListener.class)); + mock(WindowProcessListener.class), null); wpc.setThread(mock(IApplicationThread.class)); mController.addPendingActivityLaunch( diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java index 749403ea4013..bac4a525b9ea 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java @@ -208,7 +208,7 @@ public class ActivityStarterTests extends ActivityTestsBase { // If no caller app, return {@code null} {@link ProcessRecord}. final ProcessRecord record = containsConditions(preconditions, PRECONDITION_NO_CALLER_APP) - ? null : new ProcessRecord(service.mAm, mock(ApplicationInfo.class), null, 0); + ? null : new ProcessRecord(service.mAm, mock(ApplicationInfo.class), null, 0, null); doReturn(record).when(service.mAm).getRecordForAppLocked(anyObject()); diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java index 0e8200992a14..22add018f570 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java @@ -281,7 +281,7 @@ public class ActivityTestsBase { final WindowProcessController wpc = new WindowProcessController(mService, mService.mContext.getApplicationInfo(), "name", 12345, UserHandle.getUserId(12345), mock(Object.class), - mock(WindowProcessListener.class)); + mock(WindowProcessListener.class), null); wpc.setThread(mock(IApplicationThread.class)); activity.setProcess(wpc); return activity; diff --git a/services/tests/servicestests/src/com/android/server/am/AppErrorDialogTest.java b/services/tests/servicestests/src/com/android/server/am/AppErrorDialogTest.java index 87d367fcb2b2..3819e2190d88 100644 --- a/services/tests/servicestests/src/com/android/server/am/AppErrorDialogTest.java +++ b/services/tests/servicestests/src/com/android/server/am/AppErrorDialogTest.java @@ -67,7 +67,7 @@ public class AppErrorDialogTest { @UiThreadTest public void testCreateWorks() throws Exception { AppErrorDialog.Data data = new AppErrorDialog.Data(); - data.proc = new ProcessRecord(null, mContext.getApplicationInfo(), "name", 12345); + data.proc = new ProcessRecord(null, mContext.getApplicationInfo(), "name", 12345, null); data.result = new AppErrorResult(); AppErrorDialog dialog = new AppErrorDialog(mContext, mService, data); |