Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 62aecf34 authored by Antony Sargent's avatar Antony Sargent
Browse files

Make FLAG_KEEP_SCREEN_ON use per-display wakelocks

This moves from having a single global wakelock held by
WindowManagerService whenever any window on any display has
FLAG_KEEP_SCREEN_ON set, to having one per DisplayContent that is only
held when a window on that Display has the flag set.

Bug: 185157739
Test: atest WmTests
Change-Id: I82dcb693ad2bea0a243be4299dae836a1f53930c
parent 77338a2c
Loading
Loading
Loading
Loading
+18 −18
Original line number Diff line number Diff line
{
  "version": "1.0.0",
  "messages": {
    "-2146181682": {
      "message": "Releasing screen wakelock, obscured by %s",
      "level": "DEBUG",
      "group": "WM_DEBUG_KEEP_SCREEN_ON",
      "at": "com\/android\/server\/wm\/WindowManagerService.java"
    },
    "-2127842445": {
      "message": "Clearing startingData for token=%s",
      "level": "VERBOSE",
@@ -1759,6 +1753,12 @@
      "group": "WM_ERROR",
      "at": "com\/android\/server\/wm\/WindowManagerService.java"
    },
    "-384639879": {
      "message": "Acquiring screen wakelock due to %s",
      "level": "DEBUG",
      "group": "WM_DEBUG_KEEP_SCREEN_ON",
      "at": "com\/android\/server\/wm\/DisplayContent.java"
    },
    "-381522987": {
      "message": "Display %d state is now (%d), so update recording?",
      "level": "VERBOSE",
@@ -2365,6 +2365,12 @@
      "group": "WM_DEBUG_STATES",
      "at": "com\/android\/server\/wm\/ActivityRecord.java"
    },
    "191486492": {
      "message": "handleNotObscuredLocked: %s was holding screen wakelock but no longer has FLAG_KEEP_SCREEN_ON!!! called by%s",
      "level": "DEBUG",
      "group": "WM_DEBUG_KEEP_SCREEN_ON",
      "at": "com\/android\/server\/wm\/DisplayContent.java"
    },
    "200829729": {
      "message": "ScreenRotationAnimation onAnimationEnd",
      "level": "DEBUG",
@@ -3031,6 +3037,12 @@
      "group": "WM_ERROR",
      "at": "com\/android\/server\/wm\/WindowManagerService.java"
    },
    "782864973": {
      "message": "Releasing screen wakelock, obscured by %s",
      "level": "DEBUG",
      "group": "WM_DEBUG_KEEP_SCREEN_ON",
      "at": "com\/android\/server\/wm\/DisplayContent.java"
    },
    "791468751": {
      "message": "Pausing rotation during re-position",
      "level": "DEBUG",
@@ -4285,18 +4297,6 @@
      "group": "WM_ERROR",
      "at": "com\/android\/server\/wm\/WindowManagerService.java"
    },
    "2088592090": {
      "message": "handleNotObscuredLocked: %s was holding screen wakelock but no longer has FLAG_KEEP_SCREEN_ON!!! called by%s",
      "level": "DEBUG",
      "group": "WM_DEBUG_KEEP_SCREEN_ON",
      "at": "com\/android\/server\/wm\/RootWindowContainer.java"
    },
    "2096635066": {
      "message": "Acquiring screen wakelock due to %s",
      "level": "DEBUG",
      "group": "WM_DEBUG_KEEP_SCREEN_ON",
      "at": "com\/android\/server\/wm\/WindowManagerService.java"
    },
    "2100457473": {
      "message": "Task=%d contains embedded TaskFragment. Disabled all input during TaskFragment remote animation.",
      "level": "DEBUG",
+89 −3
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@ import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL;
import static android.view.WindowManager.LayoutParams;
import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
@@ -94,6 +95,7 @@ import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONTENT_RECOR
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_FOCUS;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_IME;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_KEEP_SCREEN_ON;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_SCREEN_ON;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WALLPAPER;
@@ -182,11 +184,13 @@ import android.os.Debug;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.PowerManager;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.Trace;
import android.os.UserHandle;
import android.os.WorkSource;
import android.provider.Settings;
import android.util.ArraySet;
import android.util.DisplayMetrics;
@@ -698,10 +702,33 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
     */
    private boolean mInEnsureActivitiesVisible = false;

    // Used to indicate that the movement of child tasks to top will not move the display to top as
    // well and thus won't change the top resumed / focused record
    /**
     * Used to indicate that the movement of child tasks to top will not move the display to top as
     * well and thus won't change the top resumed / focused record
     */
    boolean mDontMoveToTop;

    /** Used for windows that want to keep the screen awake. */
    private PowerManager.WakeLock mHoldScreenWakeLock;

    /** The current window causing mHoldScreenWakeLock to be held. */
    private WindowState mHoldScreenWindow;

    /**
     * Used during updates to temporarily store what will become the next value for
     * mHoldScreenWindow.
     */
    private WindowState mTmpHoldScreenWindow;

    /** Last window that obscures all windows below. */
    private WindowState mObscuringWindow;

    /** Last window which obscured a window holding the screen locked. */
    private WindowState mLastWakeLockObscuringWindow;

    /** Last window to hold the screen locked. */
    private WindowState mLastWakeLockHoldingWindow;

    /**
     * The helper of policy controller.
     *
@@ -914,7 +941,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
            if (isDisplayed && w.isObscuringDisplay()) {
                // This window completely covers everything behind it, so we want to leave all
                // of them as undimmed (for performance reasons).
                root.mObscuringWindow = w;
                mObscuringWindow = w;
                mTmpApplySurfaceChangesTransactionState.obscured = true;
            }

@@ -928,6 +955,15 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
            }

            if (w.mHasSurface && isDisplayed) {
                if ((w.mAttrs.flags & FLAG_KEEP_SCREEN_ON) != 0) {
                    mTmpHoldScreenWindow = w;
                } else if (w == mLastWakeLockHoldingWindow) {
                    ProtoLog.d(WM_DEBUG_KEEP_SCREEN_ON,
                            "handleNotObscuredLocked: %s was holding screen wakelock but no longer "
                                    + "has FLAG_KEEP_SCREEN_ON!!! called by%s",
                            w, Debug.getCallers(10));
                }

                final int type = w.mAttrs.type;
                if (type == TYPE_SYSTEM_DIALOG
                        || type == TYPE_SYSTEM_ERROR
@@ -1047,6 +1083,11 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
                calculatePrivacyIndicatorBoundsForRotation(mDisplayInfo.rotation));
        initializeDisplayBaseInfo();

        mHoldScreenWakeLock = mWmService.mPowerManager.newWakeLock(
                PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE,
                TAG_WM + "/displayId:" + mDisplayId, mDisplayId);
        mHoldScreenWakeLock.setReferenceCounted(false);

        mAppTransition = new AppTransition(mWmService.mContext, mWmService, this);
        mAppTransition.registerListenerLocked(mWmService.mActivityManagerAppTransitionNotifier);
        mAppTransition.registerListenerLocked(mFixedRotationTransitionListener);
@@ -1107,6 +1148,37 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        mWmService.mDisplayWindowSettings.applySettingsToDisplayLocked(this);
    }

    private void beginHoldScreenUpdate() {
        mTmpHoldScreenWindow = null;
        mObscuringWindow = null;
    }

    private void finishHoldScreenUpdate() {
        final boolean hold = mTmpHoldScreenWindow != null;
        if (hold && mTmpHoldScreenWindow != mHoldScreenWindow) {
            mHoldScreenWakeLock.setWorkSource(new WorkSource(mTmpHoldScreenWindow.mSession.mUid));
        }
        mHoldScreenWindow = mTmpHoldScreenWindow;
        mTmpHoldScreenWindow = null;

        final boolean state = mHoldScreenWakeLock.isHeld();
        if (hold != state) {
            if (hold) {
                ProtoLog.d(WM_DEBUG_KEEP_SCREEN_ON, "Acquiring screen wakelock due to %s",
                        mHoldScreenWindow);
                mLastWakeLockHoldingWindow = mHoldScreenWindow;
                mLastWakeLockObscuringWindow = null;
                mHoldScreenWakeLock.acquire();
            } else {
                ProtoLog.d(WM_DEBUG_KEEP_SCREEN_ON, "Releasing screen wakelock, obscured by %s",
                        mObscuringWindow);
                mLastWakeLockHoldingWindow = null;
                mLastWakeLockObscuringWindow = mObscuringWindow;
                mHoldScreenWakeLock.release();
            }
        }
    }

    @Override
    void migrateToNewSurfaceControl(Transaction t) {
        t.remove(mSurfaceControl);
@@ -3443,6 +3515,16 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
            pw.println("  mFixedRotationLaunchingApp=" + mFixedRotationLaunchingApp);
        }

        pw.println();
        pw.print(prefix + "mHoldScreenWindow="); pw.print(mHoldScreenWindow);
        pw.println();
        pw.print(prefix + "mObscuringWindow="); pw.print(mObscuringWindow);
        pw.println();
        pw.print(prefix + "mLastWakeLockHoldingWindow="); pw.print(mLastWakeLockHoldingWindow);
        pw.println();
        pw.print(prefix + "mLastWakeLockObscuringWindow=");
        pw.println(mLastWakeLockObscuringWindow);

        pw.println();
        mWallpaperController.dump(pw, "  ");

@@ -4664,6 +4746,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
    void applySurfaceChangesTransaction() {
        final WindowSurfacePlacer surfacePlacer = mWmService.mWindowPlacerLocked;

        beginHoldScreenUpdate();

        mTmpUpdateAllDrawn.clear();

        if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats("On entry to LockedInner",
@@ -4739,6 +4823,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
            // can now be shown.
            activity.updateAllDrawn();
        }

        finishHoldScreenUpdate();
    }

    private void getBounds(Rect out, @Rotation int rotation) {
+0 −21
Original line number Diff line number Diff line
@@ -28,7 +28,6 @@ import static android.content.res.Configuration.EMPTY;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE;
import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
@@ -178,15 +177,9 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;

    private Object mLastWindowFreezeSource = null;
    private Session mHoldScreen = null;
    private float mScreenBrightnessOverride = PowerManager.BRIGHTNESS_INVALID_FLOAT;
    private long mUserActivityTimeout = -1;
    private boolean mUpdateRotation = false;
    // Following variables are for debugging screen wakelock only.
    // Last window that requires screen wakelock
    WindowState mHoldScreenWindow = null;
    // Last window that obscures all windows below
    WindowState mObscuringWindow = null;
    // Only set while traversing the default display based on its content.
    // Affects the behavior of mirroring on secondary displays.
    private boolean mObscureApplicationContentOnSecondaryDisplays = false;
@@ -803,7 +796,6 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
                    UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);
        }

        mHoldScreen = null;
        mScreenBrightnessOverride = PowerManager.BRIGHTNESS_INVALID_FLOAT;
        mUserActivityTimeout = -1;
        mObscureApplicationContentOnSecondaryDisplays = false;
@@ -920,7 +912,6 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
            }
        }

        mWmService.setHoldScreenLocked(mHoldScreen);
        if (!mWmService.mDisplayFrozen) {
            final float brightnessOverride = mScreenBrightnessOverride < PowerManager.BRIGHTNESS_MIN
                    || mScreenBrightnessOverride > PowerManager.BRIGHTNESS_MAX
@@ -1000,9 +991,6 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
    }

    private void applySurfaceChangesTransaction() {
        mHoldScreenWindow = null;
        mObscuringWindow = null;

        // TODO(multi-display): Support these features on secondary screens.
        final DisplayContent defaultDc = mDefaultDisplay;
        final DisplayInfo defaultInfo = defaultDc.getDisplayInfo();
@@ -1077,15 +1065,6 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
            }
        }
        if (w.mHasSurface && canBeSeen) {
            if ((attrFlags & FLAG_KEEP_SCREEN_ON) != 0) {
                mHoldScreen = w.mSession;
                mHoldScreenWindow = w;
            } else if (w == mWmService.mLastWakeLockHoldingWindow) {
                ProtoLog.d(WM_DEBUG_KEEP_SCREEN_ON,
                        "handleNotObscuredLocked: %s was holding screen wakelock but no longer "
                                + "has FLAG_KEEP_SCREEN_ON!!! called by%s",
                        w, Debug.getCallers(10));
            }
            if (!syswin && w.mAttrs.screenBrightness >= 0
                    && Float.isNaN(mScreenBrightnessOverride)) {
                mScreenBrightnessOverride = w.mAttrs.screenBrightness;
+0 −45
Original line number Diff line number Diff line
@@ -104,7 +104,6 @@ import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_BOOT;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_FOCUS;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_IME;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_KEEP_SCREEN_ON;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_SCREEN_ON;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STARTING_WINDOW;
@@ -219,7 +218,6 @@ import android.os.SystemProperties;
import android.os.SystemService;
import android.os.Trace;
import android.os.UserHandle;
import android.os.WorkSource;
import android.provider.DeviceConfigInterface;
import android.provider.Settings;
import android.service.vr.IVrManager;
@@ -643,10 +641,6 @@ public class WindowManagerService extends IWindowManager.Stub
    boolean mBootAnimationStopped = false;
    long mBootWaitForWindowsStartTime = -1;

    // Following variables are for debugging screen wakelock only.
    WindowState mLastWakeLockHoldingWindow = null;
    WindowState mLastWakeLockObscuringWindow = null;

    /** Dump of the windows and app tokens at the time of the last ANR. Cleared after
     * LAST_ANR_LIFETIME_DURATION_MSECS */
    String mLastANRState;
@@ -1011,10 +1005,6 @@ public class WindowManagerService extends IWindowManager.Stub
    private boolean mHasWideColorGamutSupport;
    private boolean mHasHdrSupport;

    /** Who is holding the screen on. */
    private Session mHoldingScreenOn;
    private PowerManager.WakeLock mHoldingScreenWakeLock;

    /** Whether or not a layout can cause a wake up when theater mode is enabled. */
    boolean mAllowTheaterModeWakeFromLayout;

@@ -1349,10 +1339,6 @@ public class WindowManagerService extends IWindowManager.Stub

        mSettingsObserver = new SettingsObserver();

        mHoldingScreenWakeLock = mPowerManager.newWakeLock(
                PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, TAG_WM);
        mHoldingScreenWakeLock.setReferenceCounted(false);

        mSurfaceAnimationRunner = new SurfaceAnimationRunner(mTransactionFactory,
                mPowerManagerInternal);

@@ -6038,34 +6024,6 @@ public class WindowManagerService extends IWindowManager.Stub
        });
    }

    void setHoldScreenLocked(final Session newHoldScreen) {
        final boolean hold = newHoldScreen != null;

        if (hold && mHoldingScreenOn != newHoldScreen) {
            mHoldingScreenWakeLock.setWorkSource(new WorkSource(newHoldScreen.mUid));
        }
        mHoldingScreenOn = newHoldScreen;

        final boolean state = mHoldingScreenWakeLock.isHeld();
        if (hold != state) {
            if (hold) {
                ProtoLog.d(WM_DEBUG_KEEP_SCREEN_ON, "Acquiring screen wakelock due to %s",
                            mRoot.mHoldScreenWindow);
                mLastWakeLockHoldingWindow = mRoot.mHoldScreenWindow;
                mLastWakeLockObscuringWindow = null;
                mHoldingScreenWakeLock.acquire();
                mPolicy.keepScreenOnStartedLw();
            } else {
                ProtoLog.d(WM_DEBUG_KEEP_SCREEN_ON, "Releasing screen wakelock, obscured by %s",
                            mRoot.mObscuringWindow);
                mLastWakeLockHoldingWindow = null;
                mLastWakeLockObscuringWindow = mRoot.mObscuringWindow;
                mPolicy.keepScreenOnStoppedLw();
                mHoldingScreenWakeLock.release();
            }
        }
    }

    void requestTraversal() {
        mWindowPlacerLocked.requestTraversal();
    }
@@ -6699,9 +6657,6 @@ public class WindowManagerService extends IWindowManager.Stub
                    pw.print(mLastFinishedFreezeSource);
                }
                pw.println();
        pw.print("  mLastWakeLockHoldingWindow=");pw.print(mLastWakeLockHoldingWindow);
                pw.print(" mLastWakeLockObscuringWindow="); pw.print(mLastWakeLockObscuringWindow);
                pw.println();

        mInputManagerCallback.dump(pw, "  ");
        mTaskSnapshotController.dump(pw, "  ");
+0 −2
Original line number Diff line number Diff line
@@ -228,7 +228,5 @@ class WindowSurfacePlacer {

    public void dump(PrintWriter pw, String prefix) {
        pw.println(prefix + "mTraversalScheduled=" + mTraversalScheduled);
        pw.println(prefix + "mHoldScreenWindow=" + mService.mRoot.mHoldScreenWindow);
        pw.println(prefix + "mObscuringWindow=" + mService.mRoot.mObscuringWindow);
    }
}
Loading