summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/window/flags/windowing_frontend.aconfig7
-rw-r--r--services/core/java/com/android/server/am/OomAdjuster.java21
-rw-r--r--services/core/java/com/android/server/am/ProcessStateRecord.java21
-rw-r--r--services/core/java/com/android/server/wm/WindowProcessController.java62
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java27
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java55
6 files changed, 94 insertions, 99 deletions
diff --git a/core/java/android/window/flags/windowing_frontend.aconfig b/core/java/android/window/flags/windowing_frontend.aconfig
index 985dc102b31b..53e75f4be32a 100644
--- a/core/java/android/window/flags/windowing_frontend.aconfig
+++ b/core/java/android/window/flags/windowing_frontend.aconfig
@@ -146,6 +146,13 @@ flag {
}
flag {
+ name: "process_priority_policy_for_multi_window_mode"
+ namespace: "windowing_frontend"
+ description: "Use higher priority for top-like processes"
+ bug: "200769420"
+}
+
+flag {
name: "insets_decoupled_configuration"
namespace: "windowing_frontend"
description: "Configuration decoupled from insets"
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index 27c194b6b556..b058bd8eb3d6 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -1653,8 +1653,7 @@ public class OomAdjuster {
new ComputeOomAdjWindowCallback();
/** These methods are called inline during computeOomAdjLSP(), on the same thread */
- final class ComputeOomAdjWindowCallback
- implements WindowProcessController.ComputeOomAdjCallback {
+ final class ComputeOomAdjWindowCallback {
ProcessRecord app;
int adj;
@@ -1684,8 +1683,7 @@ public class OomAdjuster {
this.mState = app.mState;
}
- @Override
- public void onVisibleActivity() {
+ void onVisibleActivity(int flags) {
// App has a visible activity; only upgrade adjustment.
if (adj > VISIBLE_APP_ADJ) {
adj = VISIBLE_APP_ADJ;
@@ -1705,12 +1703,17 @@ public class OomAdjuster {
if (schedGroup < SCHED_GROUP_DEFAULT) {
schedGroup = SCHED_GROUP_DEFAULT;
}
+ if ((flags & WindowProcessController.ACTIVITY_STATE_FLAG_RESUMED_SPLIT_SCREEN) != 0) {
+ // Another side of split should be the current global top. Use the same top
+ // priority for this non-top split.
+ schedGroup = SCHED_GROUP_TOP_APP;
+ mAdjType = "resumed-split-screen-activity";
+ }
foregroundActivities = true;
mHasVisibleActivities = true;
}
- @Override
- public void onPausedActivity() {
+ void onPausedActivity() {
if (adj > PERCEPTIBLE_APP_ADJ) {
adj = PERCEPTIBLE_APP_ADJ;
mAdjType = "pause-activity";
@@ -1733,8 +1736,7 @@ public class OomAdjuster {
mHasVisibleActivities = false;
}
- @Override
- public void onStoppingActivity(boolean finishing) {
+ void onStoppingActivity(boolean finishing) {
if (adj > PERCEPTIBLE_APP_ADJ) {
adj = PERCEPTIBLE_APP_ADJ;
mAdjType = "stop-activity";
@@ -1764,8 +1766,7 @@ public class OomAdjuster {
mHasVisibleActivities = false;
}
- @Override
- public void onOtherActivity() {
+ void onOtherActivity() {
if (procState > PROCESS_STATE_CACHED_ACTIVITY) {
procState = PROCESS_STATE_CACHED_ACTIVITY;
mAdjType = "cch-act";
diff --git a/services/core/java/com/android/server/am/ProcessStateRecord.java b/services/core/java/com/android/server/am/ProcessStateRecord.java
index 7c64298a6053..bc990d9c5ef9 100644
--- a/services/core/java/com/android/server/am/ProcessStateRecord.java
+++ b/services/core/java/com/android/server/am/ProcessStateRecord.java
@@ -27,6 +27,11 @@ import static android.app.ProcessMemoryState.HOSTING_COMPONENT_TYPE_STARTED_SERV
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
import static com.android.server.am.ProcessList.CACHED_APP_MIN_ADJ;
import static com.android.server.am.ProcessRecord.TAG;
+import static com.android.server.wm.WindowProcessController.ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED;
+import static com.android.server.wm.WindowProcessController.ACTIVITY_STATE_FLAG_IS_STOPPING;
+import static com.android.server.wm.WindowProcessController.ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING;
+import static com.android.server.wm.WindowProcessController.ACTIVITY_STATE_FLAG_IS_VISIBLE;
+import static com.android.server.wm.WindowProcessController.ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER;
import android.annotation.ElapsedRealtimeLong;
import android.app.ActivityManager;
@@ -1108,6 +1113,7 @@ final class ProcessStateRecord {
return mCachedCompatChanges[cachedCompatChangeId] == VALUE_TRUE;
}
+ /** This is only called if the process contains activities and is not the global top. */
@GuardedBy("mService")
void computeOomAdjFromActivitiesIfNecessary(OomAdjuster.ComputeOomAdjWindowCallback callback,
int adj, boolean foregroundActivities, boolean hasVisibleActivities, int procState,
@@ -1117,8 +1123,17 @@ final class ProcessStateRecord {
}
callback.initialize(mApp, adj, foregroundActivities, hasVisibleActivities, procState,
schedGroup, appUid, logUid, processCurTop);
- final int minLayer = Math.min(ProcessList.VISIBLE_APP_LAYER_MAX,
- mApp.getWindowProcessController().computeOomAdjFromActivities(callback));
+ final int flags = mApp.getWindowProcessController().getActivityStateFlags();
+
+ if ((flags & ACTIVITY_STATE_FLAG_IS_VISIBLE) != 0) {
+ callback.onVisibleActivity(flags);
+ } else if ((flags & ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED) != 0) {
+ callback.onPausedActivity();
+ } else if ((flags & ACTIVITY_STATE_FLAG_IS_STOPPING) != 0) {
+ callback.onStoppingActivity((flags & ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING) != 0);
+ } else {
+ callback.onOtherActivity();
+ }
mCachedAdj = callback.adj;
mCachedForegroundActivities = callback.foregroundActivities;
@@ -1128,6 +1143,8 @@ final class ProcessStateRecord {
mCachedAdjType = callback.mAdjType;
if (mCachedAdj == ProcessList.VISIBLE_APP_ADJ) {
+ final int taskLayer = flags & ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER;
+ final int minLayer = Math.min(ProcessList.VISIBLE_APP_LAYER_MAX, taskLayer);
mCachedAdj += minLayer;
}
}
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index 1c00fbbf5c92..b8780726f992 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -19,6 +19,7 @@ package com.android.server.wm;
import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.content.res.Configuration.ASSETS_SEQ_UNDEFINED;
import static android.os.Build.VERSION_CODES.Q;
import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
@@ -309,14 +310,15 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
private volatile boolean mWasStoppedLogged;
// The bits used for mActivityStateFlags.
- private static final int ACTIVITY_STATE_FLAG_IS_VISIBLE = 1 << 16;
- private static final int ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED = 1 << 17;
- private static final int ACTIVITY_STATE_FLAG_IS_STOPPING = 1 << 18;
- private static final int ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING = 1 << 19;
- private static final int ACTIVITY_STATE_FLAG_IS_WINDOW_VISIBLE = 1 << 20;
- private static final int ACTIVITY_STATE_FLAG_HAS_RESUMED = 1 << 21;
- private static final int ACTIVITY_STATE_FLAG_HAS_ACTIVITY_IN_VISIBLE_TASK = 1 << 22;
- private static final int ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER = 0x0000ffff;
+ public static final int ACTIVITY_STATE_FLAG_IS_VISIBLE = 1 << 16;
+ public static final int ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED = 1 << 17;
+ public static final int ACTIVITY_STATE_FLAG_IS_STOPPING = 1 << 18;
+ public static final int ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING = 1 << 19;
+ public static final int ACTIVITY_STATE_FLAG_IS_WINDOW_VISIBLE = 1 << 20;
+ public static final int ACTIVITY_STATE_FLAG_HAS_RESUMED = 1 << 21;
+ public static final int ACTIVITY_STATE_FLAG_HAS_ACTIVITY_IN_VISIBLE_TASK = 1 << 22;
+ public static final int ACTIVITY_STATE_FLAG_RESUMED_SPLIT_SCREEN = 1 << 23;
+ public static final int ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER = 0x0000ffff;
/**
* The state for oom-adjustment calculation. The higher 16 bits are the activity states, and the
@@ -1211,31 +1213,13 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
}
}
- public interface ComputeOomAdjCallback {
- void onVisibleActivity();
- void onPausedActivity();
- void onStoppingActivity(boolean finishing);
- void onOtherActivity();
- }
-
/**
- * Returns the minimum task layer rank. It should only be called if {@link #hasActivities}
- * returns {@code true}.
+ * Returns the current ACTIVITY_STATE_FLAG_* of this process. It should only be called if
+ * {@link #hasActivities} returns {@code true}.
*/
@HotPath(caller = HotPath.OOM_ADJUSTMENT)
- public int computeOomAdjFromActivities(ComputeOomAdjCallback callback) {
- final int flags = mActivityStateFlags;
- if ((flags & ACTIVITY_STATE_FLAG_IS_VISIBLE) != 0) {
- callback.onVisibleActivity();
- } else if ((flags & ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED) != 0) {
- callback.onPausedActivity();
- } else if ((flags & ACTIVITY_STATE_FLAG_IS_STOPPING) != 0) {
- callback.onStoppingActivity(
- (flags & ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING) != 0);
- } else {
- callback.onOtherActivity();
- }
- return flags & ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER;
+ public int getActivityStateFlags() {
+ return mActivityStateFlags;
}
void computeProcessActivityState() {
@@ -1256,14 +1240,25 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
stateFlags |= ACTIVITY_STATE_FLAG_IS_WINDOW_VISIBLE;
}
final Task task = r.getTask();
- if (task != null && task.mLayerRank != Task.LAYER_RANK_INVISIBLE) {
+ if (task == null) {
+ Slog.e(TAG, "Unexpected detached " + r + " in " + this);
+ continue;
+ }
+ if (task.mLayerRank != Task.LAYER_RANK_INVISIBLE) {
stateFlags |= ACTIVITY_STATE_FLAG_HAS_ACTIVITY_IN_VISIBLE_TASK;
}
if (r.isVisibleRequested()) {
if (r.isState(RESUMED)) {
stateFlags |= ACTIVITY_STATE_FLAG_HAS_RESUMED;
+ final int windowingMode = r.getWindowingMode();
+ if (windowingMode == WINDOWING_MODE_MULTI_WINDOW
+ && com.android.window.flags.Flags
+ .processPriorityPolicyForMultiWindowMode()
+ && task.getAdjacentTask() != null) {
+ stateFlags |= ACTIVITY_STATE_FLAG_RESUMED_SPLIT_SCREEN;
+ }
}
- if (task != null && minTaskLayer > 0) {
+ if (minTaskLayer > 0) {
final int layer = task.mLayerRank;
if (layer >= 0 && minTaskLayer > layer) {
minTaskLayer = layer;
@@ -2107,6 +2102,9 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
pw.print("V|");
if ((stateFlags & ACTIVITY_STATE_FLAG_HAS_RESUMED) != 0) {
pw.print("R|");
+ if ((stateFlags & ACTIVITY_STATE_FLAG_RESUMED_SPLIT_SCREEN) != 0) {
+ pw.print("RS|");
+ }
}
} else if ((stateFlags & ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED) != 0) {
pw.print("P|");
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
index 488ce66ca99b..6366f24a27e1 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
@@ -72,14 +72,12 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
-import static org.mockito.AdditionalAnswers.answer;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doCallRealMethod;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
@@ -486,27 +484,22 @@ public class MockingOomAdjusterTests {
MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true));
WindowProcessController wpc = app.getWindowProcessController();
doReturn(true).when(wpc).hasActivities();
- doAnswer(answer(callback -> {
- Field field = callback.getClass().getDeclaredField("adj");
- field.set(callback, VISIBLE_APP_ADJ);
- field = callback.getClass().getDeclaredField("foregroundActivities");
- field.set(callback, true);
- field = callback.getClass().getDeclaredField("procState");
- field.set(callback, PROCESS_STATE_TOP);
- field = callback.getClass().getDeclaredField("schedGroup");
- field.set(callback, SCHED_GROUP_TOP_APP);
- field = callback.getClass().getDeclaredField("mAdjType");
- field.set(callback, "vis-activity");
- return 0;
- })).when(wpc).computeOomAdjFromActivities(
- any(WindowProcessController.ComputeOomAdjCallback.class));
+ doReturn(WindowProcessController.ACTIVITY_STATE_FLAG_IS_VISIBLE)
+ .when(wpc).getActivityStateFlags();
mService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
updateOomAdj(app);
- assertProcStates(app, PROCESS_STATE_TOP, VISIBLE_APP_ADJ, SCHED_GROUP_TOP_APP);
+ assertProcStates(app, PROCESS_STATE_TOP, VISIBLE_APP_ADJ, SCHED_GROUP_DEFAULT);
assertFalse(app.mState.isCached());
assertFalse(app.mState.isEmpty());
assertEquals("vis-activity", app.mState.getAdjType());
+
+ doReturn(WindowProcessController.ACTIVITY_STATE_FLAG_IS_VISIBLE
+ | WindowProcessController.ACTIVITY_STATE_FLAG_RESUMED_SPLIT_SCREEN)
+ .when(wpc).getActivityStateFlags();
+ updateOomAdj(app);
+ assertProcStates(app, PROCESS_STATE_TOP, VISIBLE_APP_ADJ, SCHED_GROUP_TOP_APP);
+ assertEquals("resumed-split-screen-activity", app.mState.getAdjType());
}
@SuppressWarnings("GuardedBy")
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 059fed20c38d..e6648dad4bbe 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
@@ -340,54 +340,33 @@ public class WindowProcessControllerTests extends WindowTestsBase {
public void testComputeOomAdjFromActivities() {
final ActivityRecord activity = createActivityRecord(mWpc);
activity.setVisibleRequested(true);
- final int[] callbackResult = { 0 };
- final int visible = 1;
- final int paused = 2;
- final int stopping = 4;
- final int other = 8;
- final WindowProcessController.ComputeOomAdjCallback callback =
- new WindowProcessController.ComputeOomAdjCallback() {
- @Override
- public void onVisibleActivity() {
- callbackResult[0] |= visible;
- }
-
- @Override
- public void onPausedActivity() {
- callbackResult[0] |= paused;
- }
-
- @Override
- public void onStoppingActivity(boolean finishing) {
- callbackResult[0] |= stopping;
- }
-
- @Override
- public void onOtherActivity() {
- callbackResult[0] |= other;
- }
- };
// onStartActivity should refresh the state immediately.
mWpc.onStartActivity(0 /* topProcessState */, activity.info);
- assertEquals(1 /* minTaskLayer */, mWpc.computeOomAdjFromActivities(callback));
- assertEquals(visible, callbackResult[0]);
+ int flags = mWpc.getActivityStateFlags();
+ assertEquals(1 /* minTaskLayer */,
+ flags & WindowProcessController.ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER);
+ final int visibleFlags = WindowProcessController.ACTIVITY_STATE_FLAG_IS_VISIBLE
+ | WindowProcessController.ACTIVITY_STATE_FLAG_IS_WINDOW_VISIBLE
+ | WindowProcessController.ACTIVITY_STATE_FLAG_HAS_ACTIVITY_IN_VISIBLE_TASK;
+ assertEquals(visibleFlags,
+ flags & ~WindowProcessController.ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER);
- callbackResult[0] = 0;
activity.setVisibleRequested(false);
activity.setState(PAUSED, "test");
- mWpc.computeOomAdjFromActivities(callback);
- assertEquals(paused, callbackResult[0]);
+ final int exclusiveFlags = WindowProcessController.ACTIVITY_STATE_FLAG_IS_VISIBLE
+ | WindowProcessController.ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED
+ | WindowProcessController.ACTIVITY_STATE_FLAG_IS_STOPPING;
+ flags = mWpc.getActivityStateFlags() & exclusiveFlags;
+ assertEquals(WindowProcessController.ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED, flags);
- callbackResult[0] = 0;
activity.setState(STOPPING, "test");
- mWpc.computeOomAdjFromActivities(callback);
- assertEquals(stopping, callbackResult[0]);
+ flags = mWpc.getActivityStateFlags() & exclusiveFlags;
+ assertEquals(WindowProcessController.ACTIVITY_STATE_FLAG_IS_STOPPING, flags);
- callbackResult[0] = 0;
activity.setState(STOPPED, "test");
- mWpc.computeOomAdjFromActivities(callback);
- assertEquals(other, callbackResult[0]);
+ flags = mWpc.getActivityStateFlags() & exclusiveFlags;
+ assertEquals(0, flags);
}
@Test