Loading services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +10 −3 Original line number Diff line number Diff line Loading @@ -2572,14 +2572,21 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { wpc.computeProcessActivityState(); } void computeProcessActivityStateBatch() { boolean computeProcessActivityStateBatch() { if (mActivityStateChangedProcs.isEmpty()) { return; return false; } boolean changed = false; for (int i = mActivityStateChangedProcs.size() - 1; i >= 0; i--) { mActivityStateChangedProcs.get(i).computeProcessActivityState(); final WindowProcessController wpc = mActivityStateChangedProcs.get(i); final int prevState = wpc.getActivityStateFlags(); wpc.computeProcessActivityState(); if (!changed && prevState != wpc.getActivityStateFlags()) { changed = true; } } mActivityStateChangedProcs.clear(); return changed; } /** Loading services/core/java/com/android/server/wm/RootWindowContainer.java +51 −5 Original line number Diff line number Diff line Loading @@ -105,6 +105,7 @@ import android.content.pm.ResolveInfo; import android.content.pm.UserProperties; import android.content.res.Configuration; import android.graphics.Rect; import android.graphics.Region; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManagerInternal; import android.hardware.power.Mode; Loading Loading @@ -153,6 +154,7 @@ import com.android.server.pm.UserManagerInternal; import com.android.server.policy.PermissionPolicyInternal; import com.android.server.policy.WindowManagerPolicy; import com.android.server.utils.Slogf; import com.android.server.wm.utils.RegionUtils; import java.io.FileDescriptor; import java.io.PrintWriter; Loading Loading @@ -270,6 +272,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent> private boolean mTaskLayersChanged = true; private int mTmpTaskLayerRank; private final RankTaskLayersRunnable mRankTaskLayersRunnable = new RankTaskLayersRunnable(); private Region mTmpOccludingRegion; private Region mTmpTaskRegion; private String mDestroyAllActivitiesReason; private final Runnable mDestroyAllActivitiesRunnable = new Runnable() { Loading Loading @@ -2921,6 +2925,11 @@ class RootWindowContainer extends WindowContainer<DisplayContent> }); } void invalidateTaskLayersAndUpdateOomAdjIfNeeded() { mRankTaskLayersRunnable.mCheckUpdateOomAdj = true; invalidateTaskLayers(); } void invalidateTaskLayers() { if (!mTaskLayersChanged) { mTaskLayersChanged = true; Loading @@ -2938,13 +2947,18 @@ class RootWindowContainer extends WindowContainer<DisplayContent> // Only rank for leaf tasks because the score of activity is based on immediate parent. forAllLeafTasks(task -> { final int oldRank = task.mLayerRank; final ActivityRecord r = task.topRunningActivityLocked(); if (r != null && r.isVisibleRequested()) { final int oldRatio = task.mNonOccludedFreeformAreaRatio; task.mNonOccludedFreeformAreaRatio = 0; if (task.isVisibleRequested()) { task.mLayerRank = ++mTmpTaskLayerRank; if (task.inFreeformWindowingMode()) { computeNonOccludedFreeformAreaRatio(task); } } else { task.mLayerRank = Task.LAYER_RANK_INVISIBLE; } if (task.mLayerRank != oldRank) { if (task.mLayerRank != oldRank || task.mNonOccludedFreeformAreaRatio != oldRatio) { task.forAllActivities(activity -> { if (activity.hasProcess()) { mTaskSupervisor.onProcessActivityStateChanged(activity.app, Loading @@ -2953,12 +2967,42 @@ class RootWindowContainer extends WindowContainer<DisplayContent> }); } }, true /* traverseTopToBottom */); if (mTmpOccludingRegion != null) { mTmpOccludingRegion.setEmpty(); } boolean changed = false; if (!mTaskSupervisor.inActivityVisibilityUpdate()) { mTaskSupervisor.computeProcessActivityStateBatch(); changed = mTaskSupervisor.computeProcessActivityStateBatch(); } if (mRankTaskLayersRunnable.mCheckUpdateOomAdj) { mRankTaskLayersRunnable.mCheckUpdateOomAdj = false; if (changed) { mService.updateOomAdj(); } } } /** This method is called for visible freeform task from top to bottom. */ private void computeNonOccludedFreeformAreaRatio(@NonNull Task task) { if (!com.android.window.flags.Flags.processPriorityPolicyForMultiWindowMode()) { return; } if (mTmpOccludingRegion == null) { mTmpOccludingRegion = new Region(); mTmpTaskRegion = new Region(); } final Rect taskBounds = task.getBounds(); mTmpTaskRegion.set(taskBounds); // Exclude the area outside the display. mTmpTaskRegion.op(task.mDisplayContent.getBounds(), Region.Op.INTERSECT); // Exclude the area covered by the above tasks. mTmpTaskRegion.op(mTmpOccludingRegion, Region.Op.DIFFERENCE); task.mNonOccludedFreeformAreaRatio = 100 * RegionUtils.getAreaSize(mTmpTaskRegion) / (taskBounds.width() * taskBounds.height()); // Accumulate the occluding region for other visible tasks behind. mTmpOccludingRegion.op(taskBounds, Region.Op.UNION); } void clearOtherAppTimeTrackers(AppTimeTracker except) { forAllActivities(r -> { if (r.appTimeTracker != except) { Loading Loading @@ -3862,6 +3906,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } private class RankTaskLayersRunnable implements Runnable { boolean mCheckUpdateOomAdj; @Override public void run() { synchronized (mService.mGlobalLock) { Loading services/core/java/com/android/server/wm/Task.java +29 −0 Original line number Diff line number Diff line Loading @@ -432,6 +432,9 @@ class Task extends TaskFragment { // This number will be assigned when we evaluate OOM scores for all visible tasks. int mLayerRank = LAYER_RANK_INVISIBLE; /** A 0~100 ratio to indicate the percentage of visible area on screen of a freeform task. */ int mNonOccludedFreeformAreaRatio; /* Unique identifier for this task. */ final int mTaskId; /* User for which this task was created. */ Loading Loading @@ -1206,6 +1209,28 @@ class Task extends TaskFragment { forAllActivities(ActivityRecord::updateAnimatingActivityRegistry); } @Override void onResize() { super.onResize(); updateTaskLayerForFreeform(); } @Override void onMovedByResize() { super.onMovedByResize(); updateTaskLayerForFreeform(); } private void updateTaskLayerForFreeform() { if (!com.android.window.flags.Flags.processPriorityPolicyForMultiWindowMode()) { return; } if (!isVisibleRequested() || !inFreeformWindowingMode()) { return; } mRootWindowContainer.invalidateTaskLayersAndUpdateOomAdjIfNeeded(); } @Override @Nullable ActivityRecord getTopResumedActivity() { Loading Loading @@ -5949,6 +5974,10 @@ class Task extends TaskFragment { pw.print(prefix); pw.print(" mLastNonFullscreenBounds="); pw.println(mLastNonFullscreenBounds); } if (mNonOccludedFreeformAreaRatio != 0) { pw.print(prefix); pw.print(" mNonOccludedFreeformAreaRatio="); pw.println(mNonOccludedFreeformAreaRatio); } if (isLeafTask()) { pw.println(prefix + " isSleeping=" + shouldSleepActivities()); printThisActivity(pw, getTopPausingActivity(), dumpPackage, false, Loading services/core/java/com/android/server/wm/WindowProcessController.java +10 −1 Original line number Diff line number Diff line Loading @@ -121,6 +121,11 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio */ private static final int MAX_NUM_PERCEPTIBLE_FREEFORM = SystemProperties.getInt("persist.wm.max_num_perceptible_freeform", 1); /** * If the visible area percentage of a resumed freeform task is greater than or equal to this * ratio, its process will have a higher priority. */ private static final int PERCEPTIBLE_FREEFORM_VISIBLE_RATIO = 90; private static final int MAX_RAPID_ACTIVITY_LAUNCH_COUNT = 200; private static final long RAPID_ACTIVITY_LAUNCH_MS = 500; Loading Loading @@ -1234,6 +1239,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio boolean hasResumedFreeform = false; int minTaskLayer = Integer.MAX_VALUE; int stateFlags = 0; int nonOccludedRatio = 0; final boolean wasResumed = hasResumedActivity(); final boolean wasAnyVisible = (mActivityStateFlags & (ACTIVITY_STATE_FLAG_IS_VISIBLE | ACTIVITY_STATE_FLAG_IS_WINDOW_VISIBLE)) != 0; Loading Loading @@ -1261,6 +1267,8 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio stateFlags |= ACTIVITY_STATE_FLAG_RESUMED_SPLIT_SCREEN; } else if (windowingMode == WINDOWING_MODE_FREEFORM) { hasResumedFreeform = true; nonOccludedRatio = Math.max(task.mNonOccludedFreeformAreaRatio, nonOccludedRatio); } } if (minTaskLayer > 0) { Loading Loading @@ -1298,7 +1306,8 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio && com.android.window.flags.Flags.processPriorityPolicyForMultiWindowMode() // Exclude task layer 1 because it is already the top most. && minTaskLayer > 1) { if (minTaskLayer <= 1 + MAX_NUM_PERCEPTIBLE_FREEFORM) { if (minTaskLayer <= 1 + MAX_NUM_PERCEPTIBLE_FREEFORM || nonOccludedRatio >= PERCEPTIBLE_FREEFORM_VISIBLE_RATIO) { stateFlags |= ACTIVITY_STATE_FLAG_PERCEPTIBLE_FREEFORM; } else { stateFlags |= ACTIVITY_STATE_FLAG_VISIBLE_MULTI_WINDOW_MODE; Loading services/core/java/com/android/server/wm/utils/RegionUtils.java +11 −0 Original line number Diff line number Diff line Loading @@ -81,4 +81,15 @@ public class RegionUtils { Collections.reverse(rects); rects.forEach(rectConsumer); } /** Returns the area size of the region. */ public static int getAreaSize(Region region) { final RegionIterator regionIterator = new RegionIterator(region); int area = 0; final Rect rect = new Rect(); while (regionIterator.next(rect)) { area += rect.width() * rect.height(); } return area; } } Loading
services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +10 −3 Original line number Diff line number Diff line Loading @@ -2572,14 +2572,21 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { wpc.computeProcessActivityState(); } void computeProcessActivityStateBatch() { boolean computeProcessActivityStateBatch() { if (mActivityStateChangedProcs.isEmpty()) { return; return false; } boolean changed = false; for (int i = mActivityStateChangedProcs.size() - 1; i >= 0; i--) { mActivityStateChangedProcs.get(i).computeProcessActivityState(); final WindowProcessController wpc = mActivityStateChangedProcs.get(i); final int prevState = wpc.getActivityStateFlags(); wpc.computeProcessActivityState(); if (!changed && prevState != wpc.getActivityStateFlags()) { changed = true; } } mActivityStateChangedProcs.clear(); return changed; } /** Loading
services/core/java/com/android/server/wm/RootWindowContainer.java +51 −5 Original line number Diff line number Diff line Loading @@ -105,6 +105,7 @@ import android.content.pm.ResolveInfo; import android.content.pm.UserProperties; import android.content.res.Configuration; import android.graphics.Rect; import android.graphics.Region; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManagerInternal; import android.hardware.power.Mode; Loading Loading @@ -153,6 +154,7 @@ import com.android.server.pm.UserManagerInternal; import com.android.server.policy.PermissionPolicyInternal; import com.android.server.policy.WindowManagerPolicy; import com.android.server.utils.Slogf; import com.android.server.wm.utils.RegionUtils; import java.io.FileDescriptor; import java.io.PrintWriter; Loading Loading @@ -270,6 +272,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent> private boolean mTaskLayersChanged = true; private int mTmpTaskLayerRank; private final RankTaskLayersRunnable mRankTaskLayersRunnable = new RankTaskLayersRunnable(); private Region mTmpOccludingRegion; private Region mTmpTaskRegion; private String mDestroyAllActivitiesReason; private final Runnable mDestroyAllActivitiesRunnable = new Runnable() { Loading Loading @@ -2921,6 +2925,11 @@ class RootWindowContainer extends WindowContainer<DisplayContent> }); } void invalidateTaskLayersAndUpdateOomAdjIfNeeded() { mRankTaskLayersRunnable.mCheckUpdateOomAdj = true; invalidateTaskLayers(); } void invalidateTaskLayers() { if (!mTaskLayersChanged) { mTaskLayersChanged = true; Loading @@ -2938,13 +2947,18 @@ class RootWindowContainer extends WindowContainer<DisplayContent> // Only rank for leaf tasks because the score of activity is based on immediate parent. forAllLeafTasks(task -> { final int oldRank = task.mLayerRank; final ActivityRecord r = task.topRunningActivityLocked(); if (r != null && r.isVisibleRequested()) { final int oldRatio = task.mNonOccludedFreeformAreaRatio; task.mNonOccludedFreeformAreaRatio = 0; if (task.isVisibleRequested()) { task.mLayerRank = ++mTmpTaskLayerRank; if (task.inFreeformWindowingMode()) { computeNonOccludedFreeformAreaRatio(task); } } else { task.mLayerRank = Task.LAYER_RANK_INVISIBLE; } if (task.mLayerRank != oldRank) { if (task.mLayerRank != oldRank || task.mNonOccludedFreeformAreaRatio != oldRatio) { task.forAllActivities(activity -> { if (activity.hasProcess()) { mTaskSupervisor.onProcessActivityStateChanged(activity.app, Loading @@ -2953,12 +2967,42 @@ class RootWindowContainer extends WindowContainer<DisplayContent> }); } }, true /* traverseTopToBottom */); if (mTmpOccludingRegion != null) { mTmpOccludingRegion.setEmpty(); } boolean changed = false; if (!mTaskSupervisor.inActivityVisibilityUpdate()) { mTaskSupervisor.computeProcessActivityStateBatch(); changed = mTaskSupervisor.computeProcessActivityStateBatch(); } if (mRankTaskLayersRunnable.mCheckUpdateOomAdj) { mRankTaskLayersRunnable.mCheckUpdateOomAdj = false; if (changed) { mService.updateOomAdj(); } } } /** This method is called for visible freeform task from top to bottom. */ private void computeNonOccludedFreeformAreaRatio(@NonNull Task task) { if (!com.android.window.flags.Flags.processPriorityPolicyForMultiWindowMode()) { return; } if (mTmpOccludingRegion == null) { mTmpOccludingRegion = new Region(); mTmpTaskRegion = new Region(); } final Rect taskBounds = task.getBounds(); mTmpTaskRegion.set(taskBounds); // Exclude the area outside the display. mTmpTaskRegion.op(task.mDisplayContent.getBounds(), Region.Op.INTERSECT); // Exclude the area covered by the above tasks. mTmpTaskRegion.op(mTmpOccludingRegion, Region.Op.DIFFERENCE); task.mNonOccludedFreeformAreaRatio = 100 * RegionUtils.getAreaSize(mTmpTaskRegion) / (taskBounds.width() * taskBounds.height()); // Accumulate the occluding region for other visible tasks behind. mTmpOccludingRegion.op(taskBounds, Region.Op.UNION); } void clearOtherAppTimeTrackers(AppTimeTracker except) { forAllActivities(r -> { if (r.appTimeTracker != except) { Loading Loading @@ -3862,6 +3906,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } private class RankTaskLayersRunnable implements Runnable { boolean mCheckUpdateOomAdj; @Override public void run() { synchronized (mService.mGlobalLock) { Loading
services/core/java/com/android/server/wm/Task.java +29 −0 Original line number Diff line number Diff line Loading @@ -432,6 +432,9 @@ class Task extends TaskFragment { // This number will be assigned when we evaluate OOM scores for all visible tasks. int mLayerRank = LAYER_RANK_INVISIBLE; /** A 0~100 ratio to indicate the percentage of visible area on screen of a freeform task. */ int mNonOccludedFreeformAreaRatio; /* Unique identifier for this task. */ final int mTaskId; /* User for which this task was created. */ Loading Loading @@ -1206,6 +1209,28 @@ class Task extends TaskFragment { forAllActivities(ActivityRecord::updateAnimatingActivityRegistry); } @Override void onResize() { super.onResize(); updateTaskLayerForFreeform(); } @Override void onMovedByResize() { super.onMovedByResize(); updateTaskLayerForFreeform(); } private void updateTaskLayerForFreeform() { if (!com.android.window.flags.Flags.processPriorityPolicyForMultiWindowMode()) { return; } if (!isVisibleRequested() || !inFreeformWindowingMode()) { return; } mRootWindowContainer.invalidateTaskLayersAndUpdateOomAdjIfNeeded(); } @Override @Nullable ActivityRecord getTopResumedActivity() { Loading Loading @@ -5949,6 +5974,10 @@ class Task extends TaskFragment { pw.print(prefix); pw.print(" mLastNonFullscreenBounds="); pw.println(mLastNonFullscreenBounds); } if (mNonOccludedFreeformAreaRatio != 0) { pw.print(prefix); pw.print(" mNonOccludedFreeformAreaRatio="); pw.println(mNonOccludedFreeformAreaRatio); } if (isLeafTask()) { pw.println(prefix + " isSleeping=" + shouldSleepActivities()); printThisActivity(pw, getTopPausingActivity(), dumpPackage, false, Loading
services/core/java/com/android/server/wm/WindowProcessController.java +10 −1 Original line number Diff line number Diff line Loading @@ -121,6 +121,11 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio */ private static final int MAX_NUM_PERCEPTIBLE_FREEFORM = SystemProperties.getInt("persist.wm.max_num_perceptible_freeform", 1); /** * If the visible area percentage of a resumed freeform task is greater than or equal to this * ratio, its process will have a higher priority. */ private static final int PERCEPTIBLE_FREEFORM_VISIBLE_RATIO = 90; private static final int MAX_RAPID_ACTIVITY_LAUNCH_COUNT = 200; private static final long RAPID_ACTIVITY_LAUNCH_MS = 500; Loading Loading @@ -1234,6 +1239,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio boolean hasResumedFreeform = false; int minTaskLayer = Integer.MAX_VALUE; int stateFlags = 0; int nonOccludedRatio = 0; final boolean wasResumed = hasResumedActivity(); final boolean wasAnyVisible = (mActivityStateFlags & (ACTIVITY_STATE_FLAG_IS_VISIBLE | ACTIVITY_STATE_FLAG_IS_WINDOW_VISIBLE)) != 0; Loading Loading @@ -1261,6 +1267,8 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio stateFlags |= ACTIVITY_STATE_FLAG_RESUMED_SPLIT_SCREEN; } else if (windowingMode == WINDOWING_MODE_FREEFORM) { hasResumedFreeform = true; nonOccludedRatio = Math.max(task.mNonOccludedFreeformAreaRatio, nonOccludedRatio); } } if (minTaskLayer > 0) { Loading Loading @@ -1298,7 +1306,8 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio && com.android.window.flags.Flags.processPriorityPolicyForMultiWindowMode() // Exclude task layer 1 because it is already the top most. && minTaskLayer > 1) { if (minTaskLayer <= 1 + MAX_NUM_PERCEPTIBLE_FREEFORM) { if (minTaskLayer <= 1 + MAX_NUM_PERCEPTIBLE_FREEFORM || nonOccludedRatio >= PERCEPTIBLE_FREEFORM_VISIBLE_RATIO) { stateFlags |= ACTIVITY_STATE_FLAG_PERCEPTIBLE_FREEFORM; } else { stateFlags |= ACTIVITY_STATE_FLAG_VISIBLE_MULTI_WINDOW_MODE; Loading
services/core/java/com/android/server/wm/utils/RegionUtils.java +11 −0 Original line number Diff line number Diff line Loading @@ -81,4 +81,15 @@ public class RegionUtils { Collections.reverse(rects); rects.forEach(rectConsumer); } /** Returns the area size of the region. */ public static int getAreaSize(Region region) { final RegionIterator regionIterator = new RegionIterator(region); int area = 0; final Rect rect = new Rect(); while (regionIterator.next(rect)) { area += rect.width() * rect.height(); } return area; } }