summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Andrii Kulian <akulian@google.com> 2019-10-10 15:15:36 -0700
committer Andrii Kulian <akulian@google.com> 2020-01-13 22:51:28 -0800
commitfa23a9ee1f4b3409feb34b1f29e78b83ae74970a (patch)
treef9b8786c6e4b0360bff03d5d2c703ab2dee4f94b
parent60ebe763fe37f67d9b496db6f3cb2e3caabc7e2a (diff)
Override process config to match activity config
Some apps use Application context to get display configuration and metrics for their activities. This leads to incorrect configuration used for activities on secondary screens. This is an issue on the application side, but the framework can provide some compatibility - override process-level config to match the display where the first activity was launched. This CL makes the process follow the activity configuration. For simplicity, it will always follow the configuration of the activity that was last added to the process. Additional optimizations might be added in future. This CL also adds new merged override configuration listener interface to report the combined config overrides from the current node and its parents. This is necessary for cases like sending a config override to WindowProcessController, when the subscriber is interested in a complete override vs the override on the current level of the hierarchy. E.g. when an Activity is registered as a config override provider for WPC, then we should also send the overrides from Task, Stack and Display levels. Bug: 131179060 Bug: 132986140 Bug: 131915789 Test: atest WmTests:ActivityRecordTests#testSetProcessOverridesConfig Test: Launch GMail on secondary screen Change-Id: I5c4342646858a77aeebc274265aab41dc753fbca
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java10
-rw-r--r--services/core/java/com/android/server/wm/ActivityStackSupervisor.java2
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java3
-rw-r--r--services/core/java/com/android/server/wm/ConfigurationContainer.java7
-rw-r--r--services/core/java/com/android/server/wm/ConfigurationContainerListener.java5
-rw-r--r--services/core/java/com/android/server/wm/WindowProcessController.java70
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java159
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java20
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java14
9 files changed, 265 insertions, 25 deletions
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 320be2d7cdbd..89c23f4eb31d 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -1673,6 +1673,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
if (root == this) {
task.setRootProcess(proc);
}
+ proc.addActivityIfNeeded(this);
}
boolean hasProcess() {
@@ -6901,7 +6902,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// Update last reported values.
final Configuration newMergedOverrideConfig = getMergedOverrideConfiguration();
- setLastReportedConfiguration(mAtmService.getGlobalConfiguration(), newMergedOverrideConfig);
+ setLastReportedConfiguration(getProcessGlobalConfiguration(), newMergedOverrideConfig);
if (mState == INITIALIZING) {
// No need to relaunch or schedule new config for activity that hasn't been launched
@@ -7000,6 +7001,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
return true;
}
+ /** Get process configuration, or global config if the process is not set. */
+ private Configuration getProcessGlobalConfiguration() {
+ return app != null ? app.getConfiguration() : mAtmService.getGlobalConfiguration();
+ }
+
/**
* When assessing a configuration change, decide if the changes flags and the new configurations
* should cause the Activity to relaunch.
@@ -7112,7 +7118,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
startRelaunching();
final ClientTransactionItem callbackItem = ActivityRelaunchItem.obtain(pendingResults,
pendingNewIntents, configChangeFlags,
- new MergedConfiguration(mAtmService.getGlobalConfiguration(),
+ new MergedConfiguration(getProcessGlobalConfiguration(),
getMergedOverrideConfiguration()),
preserveWindow);
final ActivityLifecycleItem lifecycleItem;
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index aa90248b97f8..0a68408d49a5 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -848,8 +848,6 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
if (DEBUG_ALL) Slog.v(TAG, "Launching: " + r);
- proc.addActivityIfNeeded(r);
-
final LockTaskController lockTaskController = mService.getLockTaskController();
if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE
|| task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE_PRIV
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index ded603c9fd77..ea7a62a618c2 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -248,7 +248,6 @@ import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.internal.policy.KeyguardDismissCallback;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastPrintWriter;
-import com.android.internal.util.Preconditions;
import com.android.internal.util.function.pooled.PooledConsumer;
import com.android.internal.util.function.pooled.PooledFunction;
import com.android.internal.util.function.pooled.PooledLambda;
@@ -6697,7 +6696,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
return;
}
process.mIsImeProcess = true;
- process.registerDisplayConfigurationListenerLocked(displayContent);
+ process.registerDisplayConfigurationListener(displayContent);
}
}
diff --git a/services/core/java/com/android/server/wm/ConfigurationContainer.java b/services/core/java/com/android/server/wm/ConfigurationContainer.java
index d0310f1a7607..85d7ec99ad0b 100644
--- a/services/core/java/com/android/server/wm/ConfigurationContainer.java
+++ b/services/core/java/com/android/server/wm/ConfigurationContainer.java
@@ -134,8 +134,8 @@ public abstract class ConfigurationContainer<E extends ConfigurationContainer> {
resolveOverrideConfiguration(newParentConfig);
mFullConfiguration.setTo(newParentConfig);
mFullConfiguration.updateFrom(mResolvedOverrideConfiguration);
+ onMergedOverrideConfigurationChanged();
if (!mResolvedTmpConfig.equals(mResolvedOverrideConfiguration)) {
- onMergedOverrideConfigurationChanged();
// This depends on the assumption that change-listeners don't do
// their own override resolution. This way, dependent hierarchies
// can stay properly synced-up with a primary hierarchy's constraints.
@@ -147,6 +147,10 @@ public abstract class ConfigurationContainer<E extends ConfigurationContainer> {
mResolvedOverrideConfiguration);
}
}
+ for (int i = mChangeListeners.size() - 1; i >= 0; --i) {
+ mChangeListeners.get(i).onMergedOverrideConfigurationChanged(
+ mMergedOverrideConfiguration);
+ }
if (forwardToChildren) {
for (int i = getChildCount() - 1; i >= 0; --i) {
final ConfigurationContainer child = getChildAt(i);
@@ -545,6 +549,7 @@ public abstract class ConfigurationContainer<E extends ConfigurationContainer> {
}
mChangeListeners.add(listener);
listener.onRequestedOverrideConfigurationChanged(mResolvedOverrideConfiguration);
+ listener.onMergedOverrideConfigurationChanged(mMergedOverrideConfiguration);
}
void unregisterConfigurationChangeListener(ConfigurationContainerListener listener) {
diff --git a/services/core/java/com/android/server/wm/ConfigurationContainerListener.java b/services/core/java/com/android/server/wm/ConfigurationContainerListener.java
index dc4939d55bfa..3d84e1752e6a 100644
--- a/services/core/java/com/android/server/wm/ConfigurationContainerListener.java
+++ b/services/core/java/com/android/server/wm/ConfigurationContainerListener.java
@@ -24,5 +24,8 @@ import android.content.res.Configuration;
public interface ConfigurationContainerListener {
/** {@see ConfigurationContainer#onRequestedOverrideConfigurationChanged} */
- void onRequestedOverrideConfigurationChanged(Configuration overrideConfiguration);
+ default void onRequestedOverrideConfigurationChanged(Configuration overrideConfiguration) {}
+
+ /** Called when new merged override configuration is reported. */
+ default void onMergedOverrideConfigurationChanged(Configuration mergedOverrideConfiguration) {}
}
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index ad4677a26512..ceb38f7d9789 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -17,6 +17,7 @@
package com.android.server.wm;
import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.os.Build.VERSION_CODES.Q;
import static android.view.Display.INVALID_DISPLAY;
@@ -178,8 +179,10 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
// Last configuration that was reported to the process.
private final Configuration mLastReportedConfiguration;
+ private final Configuration mNewOverrideConfig = new Configuration();
// Registered display id as a listener to override config change
private int mDisplayId;
+ private ActivityRecord mConfigActivityRecord;
/** Whether our process is currently running a {@link RecentsAnimation} */
private boolean mRunningRecentsAnimation;
@@ -327,6 +330,12 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
return mDisplayId != INVALID_DISPLAY;
}
+ /** @return {@code true} if the process registered to an activity as a config listener. */
+ @VisibleForTesting
+ boolean registeredForActivityConfigChanges() {
+ return mConfigActivityRecord != null;
+ }
+
void postPendingUiCleanMsg(boolean pendingUiClean) {
if (mListener == null) return;
// Posting on handler so WM lock isn't held when we call into AM.
@@ -510,10 +519,12 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
return;
}
mActivities.add(r);
+ updateActivityConfigurationListener();
}
void removeActivity(ActivityRecord r) {
mActivities.remove(r);
+ updateActivityConfigurationListener();
}
void makeFinishingForProcessRemoved() {
@@ -524,6 +535,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
void clearActivities() {
mActivities.clear();
+ updateActivityConfigurationListener();
}
@HotPath(caller = HotPath.OOM_ADJUSTMENT)
@@ -967,19 +979,20 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
mAtm.mH.sendMessage(m);
}
- void registerDisplayConfigurationListenerLocked(DisplayContent displayContent) {
+ void registerDisplayConfigurationListener(DisplayContent displayContent) {
if (displayContent == null) {
return;
}
- // A process can only register to one display to listener to the override configuration
+ // A process can only register to one display to listen to the override configuration
// change. Unregister existing listener if it has one before register the new one.
- unregisterDisplayConfigurationListenerLocked();
+ unregisterDisplayConfigurationListener();
+ unregisterActivityConfigurationListener();
mDisplayId = displayContent.mDisplayId;
displayContent.registerConfigurationChangeListener(this);
}
@VisibleForTesting
- void unregisterDisplayConfigurationListenerLocked() {
+ void unregisterDisplayConfigurationListener() {
if (mDisplayId == INVALID_DISPLAY) {
return;
}
@@ -989,6 +1002,48 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
displayContent.unregisterConfigurationChangeListener(this);
}
mDisplayId = INVALID_DISPLAY;
+ onMergedOverrideConfigurationChanged(Configuration.EMPTY);
+ }
+
+ private void registerActivityConfigurationListener(ActivityRecord activityRecord) {
+ if (activityRecord == null) {
+ return;
+ }
+ // A process can only register to one activityRecord to listen to the override configuration
+ // change. Unregister existing listener if it has one before register the new one.
+ unregisterDisplayConfigurationListener();
+ unregisterActivityConfigurationListener();
+ mConfigActivityRecord = activityRecord;
+ activityRecord.registerConfigurationChangeListener(this);
+ }
+
+ private void unregisterActivityConfigurationListener() {
+ if (mConfigActivityRecord == null) {
+ return;
+ }
+ mConfigActivityRecord.unregisterConfigurationChangeListener(this);
+ mConfigActivityRecord = null;
+ onMergedOverrideConfigurationChanged(Configuration.EMPTY);
+ }
+
+ /**
+ * Check if activity configuration override for the activity process needs an update and perform
+ * if needed. By default we try to override the process configuration to match the top activity
+ * config to increase app compatibility with multi-window and multi-display. The process will
+ * always track the configuration of the non-finishing activity last added to the process.
+ */
+ private void updateActivityConfigurationListener() {
+ for (int i = mActivities.size() - 1; i >= 0; i--) {
+ final ActivityRecord activityRecord = mActivities.get(i);
+ if (!activityRecord.finishing && !activityRecord.containsListener(this)) {
+ // Eligible activity is found, update listener.
+ registerActivityConfigurationListener(activityRecord);
+ return;
+ }
+ }
+
+ // No eligible activities found, let's remove the configuration listener.
+ unregisterActivityConfigurationListener();
}
@Override
@@ -998,8 +1053,11 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
}
@Override
- public void onRequestedOverrideConfigurationChanged(Configuration newOverrideConfig) {
- super.onRequestedOverrideConfigurationChanged(newOverrideConfig);
+ public void onMergedOverrideConfigurationChanged(Configuration mergedOverrideConfig) {
+ // Make sure that we don't accidentally override the activity type.
+ mNewOverrideConfig.setTo(mergedOverrideConfig);
+ mNewOverrideConfig.windowConfiguration.setActivityType(ACTIVITY_TYPE_UNDEFINED);
+ super.onRequestedOverrideConfigurationChanged(mNewOverrideConfig);
updateConfiguration();
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index a3e94599cad3..ad63d078fa67 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -16,6 +16,8 @@
package com.android.server.wm;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
@@ -56,6 +58,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@@ -1175,4 +1178,160 @@ public class ActivityRecordTests extends ActivityTestsBase {
verify(mActivity).removeFromHistory(anyString());
}
+
+ @Test
+ public void testActivityOverridesProcessConfig() {
+ final WindowProcessController wpc = mActivity.app;
+ assertTrue(wpc.registeredForActivityConfigChanges());
+ assertFalse(wpc.registeredForDisplayConfigChanges());
+
+ final ActivityRecord secondaryDisplayActivity =
+ createActivityOnDisplay(false /* defaultDisplay */, null /* process */);
+
+ assertTrue(wpc.registeredForActivityConfigChanges());
+ assertEquals(0, mActivity.getMergedOverrideConfiguration()
+ .diff(wpc.getRequestedOverrideConfiguration()));
+ assertNotEquals(mActivity.getConfiguration(),
+ secondaryDisplayActivity.getConfiguration());
+ }
+
+ @Test
+ public void testActivityOverridesProcessConfig_TwoActivities() {
+ final WindowProcessController wpc = mActivity.app;
+ assertTrue(wpc.registeredForActivityConfigChanges());
+
+ final Task firstTaskRecord = mActivity.getTask();
+ final ActivityRecord secondActivityRecord =
+ new ActivityBuilder(mService).setTask(firstTaskRecord).setUseProcess(wpc).build();
+
+ assertTrue(wpc.registeredForActivityConfigChanges());
+ assertEquals(0, secondActivityRecord.getMergedOverrideConfiguration()
+ .diff(wpc.getRequestedOverrideConfiguration()));
+ }
+
+ @Test
+ public void testActivityOverridesProcessConfig_TwoActivities_SecondaryDisplay() {
+ final WindowProcessController wpc = mActivity.app;
+ assertTrue(wpc.registeredForActivityConfigChanges());
+
+ final ActivityRecord secondActivityRecord =
+ new ActivityBuilder(mService).setTask(mTask).setUseProcess(wpc).build();
+
+ assertTrue(wpc.registeredForActivityConfigChanges());
+ assertEquals(0, secondActivityRecord.getMergedOverrideConfiguration()
+ .diff(wpc.getRequestedOverrideConfiguration()));
+ }
+
+ @Test
+ public void testActivityOverridesProcessConfig_TwoActivities_DifferentTasks() {
+ final WindowProcessController wpc = mActivity.app;
+ assertTrue(wpc.registeredForActivityConfigChanges());
+
+ final ActivityRecord secondActivityRecord =
+ createActivityOnDisplay(true /* defaultDisplay */, wpc);
+
+ assertTrue(wpc.registeredForActivityConfigChanges());
+ assertEquals(0, secondActivityRecord.getMergedOverrideConfiguration()
+ .diff(wpc.getRequestedOverrideConfiguration()));
+ }
+
+ @Test
+ public void testActivityOnDifferentDisplayUpdatesProcessOverride() {
+ final ActivityRecord secondaryDisplayActivity =
+ createActivityOnDisplay(false /* defaultDisplay */, null /* process */);
+ final WindowProcessController wpc = secondaryDisplayActivity.app;
+ assertTrue(wpc.registeredForActivityConfigChanges());
+
+ final ActivityRecord secondActivityRecord =
+ createActivityOnDisplay(true /* defaultDisplay */, wpc);
+
+ assertTrue(wpc.registeredForActivityConfigChanges());
+ assertEquals(0, secondActivityRecord.getMergedOverrideConfiguration()
+ .diff(wpc.getRequestedOverrideConfiguration()));
+ assertFalse(wpc.registeredForDisplayConfigChanges());
+ }
+
+ @Test
+ public void testActivityReparentChangesProcessOverride() {
+ final WindowProcessController wpc = mActivity.app;
+ final Task initialTask = mActivity.getTask();
+ final Configuration initialConf =
+ new Configuration(mActivity.getMergedOverrideConfiguration());
+ assertEquals(0, mActivity.getMergedOverrideConfiguration()
+ .diff(wpc.getRequestedOverrideConfiguration()));
+ assertTrue(wpc.registeredForActivityConfigChanges());
+
+ // Create a new task with custom config to reparent the activity to.
+ final Task newTask =
+ new TaskBuilder(mSupervisor).setStack(initialTask.getStack()).build();
+ final Configuration newConfig = newTask.getConfiguration();
+ newConfig.densityDpi += 100;
+ newTask.onRequestedOverrideConfigurationChanged(newConfig);
+ assertEquals(newTask.getConfiguration().densityDpi, newConfig.densityDpi);
+
+ // Reparent the activity and verify that config override changed.
+ mActivity.reparent(newTask, 0 /* top */, "test");
+ assertEquals(mActivity.getConfiguration().densityDpi, newConfig.densityDpi);
+ assertEquals(mActivity.getMergedOverrideConfiguration().densityDpi, newConfig.densityDpi);
+
+ assertTrue(wpc.registeredForActivityConfigChanges());
+ assertNotEquals(initialConf, wpc.getRequestedOverrideConfiguration());
+ assertEquals(0, mActivity.getMergedOverrideConfiguration()
+ .diff(wpc.getRequestedOverrideConfiguration()));
+ }
+
+ @Test
+ public void testActivityReparentDoesntClearProcessOverride_TwoActivities() {
+ final WindowProcessController wpc = mActivity.app;
+ final Configuration initialConf =
+ new Configuration(mActivity.getMergedOverrideConfiguration());
+ final Task initialTask = mActivity.getTask();
+ final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(initialTask)
+ .setUseProcess(wpc).build();
+
+ assertTrue(wpc.registeredForActivityConfigChanges());
+ assertEquals(0, secondActivity.getMergedOverrideConfiguration()
+ .diff(wpc.getRequestedOverrideConfiguration()));
+
+ // Create a new task with custom config to reparent the second activity to.
+ final Task newTask =
+ new TaskBuilder(mSupervisor).setStack(initialTask.getStack()).build();
+ final Configuration newConfig = newTask.getConfiguration();
+ newConfig.densityDpi += 100;
+ newTask.onRequestedOverrideConfigurationChanged(newConfig);
+
+ // Reparent the activity and verify that config override changed.
+ secondActivity.reparent(newTask, 0 /* top */, "test");
+
+ assertTrue(wpc.registeredForActivityConfigChanges());
+ assertEquals(0, secondActivity.getMergedOverrideConfiguration()
+ .diff(wpc.getRequestedOverrideConfiguration()));
+ assertNotEquals(initialConf, wpc.getRequestedOverrideConfiguration());
+
+ // Reparent the first activity and verify that config override didn't change.
+ mActivity.reparent(newTask, 1 /* top */, "test");
+ assertTrue(wpc.registeredForActivityConfigChanges());
+ assertEquals(0, secondActivity.getMergedOverrideConfiguration()
+ .diff(wpc.getRequestedOverrideConfiguration()));
+ assertNotEquals(initialConf, wpc.getRequestedOverrideConfiguration());
+ }
+
+ /**
+ * Creates an activity on display. For non-default display request it will also create a new
+ * display with custom DisplayInfo.
+ */
+ private ActivityRecord createActivityOnDisplay(boolean defaultDisplay,
+ WindowProcessController process) {
+ final DisplayContent display;
+ if (defaultDisplay) {
+ display = mRootWindowContainer.getDefaultDisplay();
+ } else {
+ display = new TestDisplayContent.Builder(mService, 2000, 1000).setDensityDpi(300)
+ .setPosition(DisplayContent.POSITION_TOP).build();
+ }
+ final ActivityStack stack = display.createStack(WINDOWING_MODE_UNDEFINED,
+ ACTIVITY_TYPE_STANDARD, true /* onTop */);
+ final Task task = new TaskBuilder(mSupervisor).setStack(stack).build();
+ return new ActivityBuilder(mService).setTask(task).setUseProcess(process).build();
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
index 0f227246b468..4beede93aea2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
@@ -111,6 +111,7 @@ class ActivityTestsBase extends SystemServiceTestsBase {
private int mConfigChanges;
private int mLaunchedFromPid;
private int mLaunchedFromUid;
+ private WindowProcessController mWpc;
ActivityBuilder(ActivityTaskManagerService service) {
mService = service;
@@ -201,6 +202,11 @@ class ActivityTestsBase extends SystemServiceTestsBase {
return this;
}
+ ActivityBuilder setUseProcess(WindowProcessController wpc) {
+ mWpc = wpc;
+ return this;
+ }
+
ActivityRecord build() {
try {
mService.deferWindowLayout();
@@ -263,10 +269,16 @@ class ActivityTestsBase extends SystemServiceTestsBase {
activity.setVisible(true);
}
- final WindowProcessController wpc = new WindowProcessController(mService,
- mService.mContext.getApplicationInfo(), mProcessName, mUid,
- UserHandle.getUserId(12345), mock(Object.class),
- mock(WindowProcessListener.class));
+ final WindowProcessController wpc;
+ if (mWpc != null) {
+ wpc = mWpc;
+ } else {
+ wpc = new WindowProcessController(mService,
+ mService.mContext.getApplicationInfo(), mProcessName, mUid,
+ UserHandle.getUserId(12345), mock(Object.class),
+ mock(WindowProcessListener.class));
+ wpc.setThread(mock(IApplicationThread.class));
+ }
wpc.setThread(mock(IApplicationThread.class));
activity.setProcess(wpc);
doReturn(wpc).when(mService).getProcessController(
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
index f4a1af41ba8e..db4fdc77064b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
@@ -63,33 +63,33 @@ public class WindowProcessControllerTests extends ActivityTestsBase {
// Register to display 1 as a listener.
TestDisplayContent testDisplayContent1 = createTestDisplayContentInContainer();
- mWpc.registerDisplayConfigurationListenerLocked(testDisplayContent1);
+ mWpc.registerDisplayConfigurationListener(testDisplayContent1);
assertTrue(testDisplayContent1.containsListener(mWpc));
assertEquals(testDisplayContent1.mDisplayId, mWpc.getDisplayId());
// Move to display 2.
TestDisplayContent testDisplayContent2 = createTestDisplayContentInContainer();
- mWpc.registerDisplayConfigurationListenerLocked(testDisplayContent2);
+ mWpc.registerDisplayConfigurationListener(testDisplayContent2);
assertFalse(testDisplayContent1.containsListener(mWpc));
assertTrue(testDisplayContent2.containsListener(mWpc));
assertEquals(testDisplayContent2.mDisplayId, mWpc.getDisplayId());
// Null DisplayContent will not change anything.
- mWpc.registerDisplayConfigurationListenerLocked(null);
+ mWpc.registerDisplayConfigurationListener(null);
assertTrue(testDisplayContent2.containsListener(mWpc));
assertEquals(testDisplayContent2.mDisplayId, mWpc.getDisplayId());
// Unregister listener will remove the wpc from registered displays.
- mWpc.unregisterDisplayConfigurationListenerLocked();
+ mWpc.unregisterDisplayConfigurationListener();
assertFalse(testDisplayContent1.containsListener(mWpc));
assertFalse(testDisplayContent2.containsListener(mWpc));
assertEquals(INVALID_DISPLAY, mWpc.getDisplayId());
// Unregistration still work even if the display was removed.
- mWpc.registerDisplayConfigurationListenerLocked(testDisplayContent1);
+ mWpc.registerDisplayConfigurationListener(testDisplayContent1);
assertEquals(testDisplayContent1.mDisplayId, mWpc.getDisplayId());
mRootWindowContainer.removeChild(testDisplayContent1);
- mWpc.unregisterDisplayConfigurationListenerLocked();
+ mWpc.unregisterDisplayConfigurationListener();
assertEquals(INVALID_DISPLAY, mWpc.getDisplayId());
}
@@ -140,7 +140,7 @@ public class WindowProcessControllerTests extends ActivityTestsBase {
// Register to a new display as a listener.
final DisplayContent display = new TestDisplayContent.Builder(mService, 2000, 1000)
.setDensityDpi(300).setPosition(DisplayContent.POSITION_TOP).build();
- wpc.registerDisplayConfigurationListenerLocked(display);
+ wpc.registerDisplayConfigurationListener(display);
assertEquals(display.mDisplayId, wpc.getDisplayId());
final Configuration expectedConfig = mService.mRootWindowContainer.getConfiguration();