diff options
| author | 2024-12-03 17:09:34 +0800 | |
|---|---|---|
| committer | 2024-12-17 22:17:04 -0800 | |
| commit | 4f26be3a00ba220b427832e229b79ecbc57b57c1 (patch) | |
| tree | 78f252946c6e858116334c8e8af8c155a0a76f3d | |
| parent | 7ad12f9f1b013c4e651500b3d78299329776070f (diff) | |
Demote top-app when notification shade is expanded
If the top app is busy, it may cause potential jank when expanding
notification shade because CPU contention.
If there is top app switch, the demote will be canceled. Because it
is usually an app launch which needs top priority for startup latency.
Bug: 362467878
Flag: com.android.window.flags.scheduling_for_notification_shade
Test: Expand/collapse notification shade and check
adb shell dumpsys activity o | grep -e "A.*top-activity"
Expanded: intermediate-top-activity
Collapsed: top-activity
Change-Id: Ic82cb3235f93f01db382d355c98f7aef2f1ef783
5 files changed, 69 insertions, 0 deletions
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index 5da49857dda5..0766e3976457 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -722,6 +722,9 @@ interface IWindowManager */ void setDisplayImePolicy(int displayId, int imePolicy); + /** Called when the expanded state of notification shade is changed. */ + void onNotificationShadeExpanded(IBinder token, boolean expanded); + /** * Waits until input information has been sent from WindowManager to native InputManager, * optionally waiting for animations to complete. diff --git a/core/java/android/window/flags/windowing_frontend.aconfig b/core/java/android/window/flags/windowing_frontend.aconfig index 30f0c7371270..3b1b3647b7e9 100644 --- a/core/java/android/window/flags/windowing_frontend.aconfig +++ b/core/java/android/window/flags/windowing_frontend.aconfig @@ -265,6 +265,17 @@ flag { } flag { + name: "scheduling_for_notification_shade" + namespace: "windowing_frontend" + description: "Demote top-app when notification shade is expanded" + bug: "362467878" + is_fixed_read_only: true + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { name: "release_snapshot_aggressively" namespace: "windowing_frontend" description: "Actively release task snapshot memory" diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java index 69b3cc8cf4f4..e4cd7ea098af 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java @@ -27,6 +27,7 @@ import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.graphics.Rect; import android.graphics.Region; +import android.os.IBinder; import android.os.RemoteException; import android.os.Trace; import android.os.UserHandle; @@ -252,6 +253,19 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW if (mCurrentState.shadeOrQsExpanded != isExpanded) { mCurrentState.shadeOrQsExpanded = isExpanded; apply(mCurrentState); + + final IBinder token; + if (com.android.window.flags.Flags.schedulingForNotificationShade() + && (token = mWindowRootView.getWindowToken()) != null) { + mBackgroundExecutor.execute(() -> { + try { + WindowManagerGlobal.getWindowManagerService() + .onNotificationShadeExpanded(token, isExpanded); + } catch (RemoteException e) { + Log.e(TAG, "Failed to call onNotificationShadeExpanded", e); + } + }); + } } } diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index afa7ea136c77..8a552741213a 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -437,10 +437,13 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { /** It is set from keyguard-going-away to set-keyguard-shown. */ static final int DEMOTE_TOP_REASON_DURING_UNLOCKING = 1; + /** It is set when notification shade occludes the foreground app. */ + static final int DEMOTE_TOP_REASON_EXPANDED_NOTIFICATION_SHADE = 1 << 1; @Retention(RetentionPolicy.SOURCE) @IntDef({ DEMOTE_TOP_REASON_DURING_UNLOCKING, + DEMOTE_TOP_REASON_EXPANDED_NOTIFICATION_SHADE, }) @interface DemoteTopReason {} @@ -5239,6 +5242,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { : mRootWindowContainer.getTopResumedActivity(); mTopApp = top != null ? top.app : null; if (mTopApp == mPreviousProcess) mPreviousProcess = null; + + final int demoteReasons = mDemoteTopAppReasons; + if ((demoteReasons & DEMOTE_TOP_REASON_EXPANDED_NOTIFICATION_SHADE) != 0) { + Trace.instant(TRACE_TAG_WINDOW_MANAGER, "cancel-demote-top-for-ns-switch"); + mDemoteTopAppReasons = demoteReasons & ~DEMOTE_TOP_REASON_EXPANDED_NOTIFICATION_SHADE; + } } /** diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index bf4cb4543e44..a946b295b8d1 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -121,6 +121,7 @@ import static com.android.server.LockGuard.INDEX_WINDOW; import static com.android.server.LockGuard.installLock; import static com.android.server.policy.PhoneWindowManager.TRACE_WAIT_FOR_ALL_WINDOWS_DRAWN_METHOD; import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; +import static com.android.server.wm.ActivityTaskManagerService.DEMOTE_TOP_REASON_EXPANDED_NOTIFICATION_SHADE; import static com.android.server.wm.ActivityTaskManagerService.POWER_MODE_REASON_CHANGE_DISPLAY; import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND; import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING; @@ -7779,6 +7780,37 @@ public class WindowManagerService extends IWindowManager.Stub } @Override + public void onNotificationShadeExpanded(IBinder token, boolean expanded) { + synchronized (mGlobalLock) { + final WindowState w = mWindowMap.get(token); + if (w == null || w != w.mDisplayContent.getDisplayPolicy().getNotificationShade()) { + return; + } + final WindowProcessController topApp = mAtmService.mTopApp; + // Demotes the priority of top app if notification shade is expanded to occlude the app. + // So the notification shade may have more capacity to draw and animate. + final int demoteTopAppReasons = mAtmService.mDemoteTopAppReasons; + if (expanded && mAtmService.mTopProcessState == ActivityManager.PROCESS_STATE_TOP + && (demoteTopAppReasons & DEMOTE_TOP_REASON_EXPANDED_NOTIFICATION_SHADE) == 0) { + mAtmService.mDemoteTopAppReasons = + demoteTopAppReasons | DEMOTE_TOP_REASON_EXPANDED_NOTIFICATION_SHADE; + Trace.instant(TRACE_TAG_WINDOW_MANAGER, "demote-top-for-ns"); + if (topApp != null) { + topApp.scheduleUpdateOomAdj(); + } + } else if (!expanded + && (demoteTopAppReasons & DEMOTE_TOP_REASON_EXPANDED_NOTIFICATION_SHADE) != 0) { + mAtmService.mDemoteTopAppReasons = + demoteTopAppReasons & ~DEMOTE_TOP_REASON_EXPANDED_NOTIFICATION_SHADE; + Trace.instant(TRACE_TAG_WINDOW_MANAGER, "cancel-demote-top-for-ns"); + if (topApp != null) { + topApp.scheduleUpdateOomAdj(); + } + } + } + } + + @Override public void registerShortcutKey(long shortcutCode, IShortcutService shortcutKeyReceiver) throws RemoteException { if (!checkCallingPermission(REGISTER_WINDOW_MANAGER_LISTENERS, "registerShortcutKey")) { |