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

Commit 81dfc082 authored by Craig Mautner's avatar Craig Mautner Committed by Android (Google) Code Review
Browse files

Merge "Force all windows to redraw before unblanking screen" into klp-modular-dev

parents 2e78de7f 228742d2
Loading
Loading
Loading
Loading
+0 −6
Original line number Diff line number Diff line
@@ -214,12 +214,6 @@ interface IWindowManager
     */
    oneway void statusBarVisibilityChanged(int visibility);

    /**
     * Block until the given window has been drawn to the screen.
     * Returns true if really waiting, false if the window does not exist.
     */
    boolean waitForWindowDrawn(IBinder token, in IRemoteCallback callback);

    /**
     * Device has a software navigation bar (separate from the status bar).
     */
+6 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.view;

import android.hardware.display.DisplayManagerInternal;
import android.os.IRemoteCallback;

/**
 * Window manager local system service interface.
@@ -30,4 +31,9 @@ public abstract class WindowManagerInternal {
     * within a surface transaction at a later time.
     */
    public abstract void requestTraversalFromDisplayManager();
    /**
     * Invalidate all visible windows. Then report back on the callback once all windows have
     * redrawn.
     */
    public abstract void waitForAllWindowsDrawn(IRemoteCallback callback, long timeout);
}
 No newline at end of file
+76 −47
Original line number Diff line number Diff line
@@ -89,6 +89,7 @@ import android.view.ViewConfiguration;
import android.view.Window;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.view.WindowManagerInternal;
import android.view.WindowManagerPolicy;
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.Animation;
@@ -97,14 +98,17 @@ import android.view.animation.AnimationUtils;
import com.android.internal.R;
import com.android.internal.policy.PolicyManager;
import com.android.internal.policy.impl.keyguard.KeyguardServiceDelegate;
import com.android.internal.policy.impl.keyguard.KeyguardServiceDelegate.ShowListener;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.telephony.ITelephony;
import com.android.internal.widget.PointerLocationView;
import com.android.server.LocalServices;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashSet;

import static android.view.WindowManager.LayoutParams.*;
@@ -126,6 +130,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    static final boolean DEBUG_LAYOUT = false;
    static final boolean DEBUG_INPUT = false;
    static final boolean DEBUG_STARTING_WINDOW = false;
    static final boolean DEBUG_WAKEUP = false;
    static final boolean SHOW_STARTING_ANIMATIONS = true;
    static final boolean SHOW_PROCESSES_ON_ALT_MENU = false;

@@ -212,6 +217,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    Context mContext;
    IWindowManager mWindowManager;
    WindowManagerFuncs mWindowManagerFuncs;
    WindowManagerInternal mWindowManagerInternal;
    PowerManager mPowerManager;
    IStatusBarService mStatusBarService;
    boolean mPreloadedRecentApps;
@@ -250,6 +256,25 @@ public class PhoneWindowManager implements WindowManagerPolicy {

    WindowState mKeyguard = null;
    KeyguardServiceDelegate mKeyguardDelegate;
    // The following are only accessed on the mHandler thread.
    boolean mKeyguardDrawComplete;
    boolean mWindowManagerDrawComplete;
    ArrayList<ScreenOnListener> mScreenOnListeners = new ArrayList<ScreenOnListener>();
    final IRemoteCallback mWindowManagerDrawCallback = new IRemoteCallback.Stub() {
        @Override
        public void sendResult(Bundle data) {
            if (DEBUG_WAKEUP) Slog.i(TAG, "All windows ready for display!");
            mHandler.sendEmptyMessage(MSG_WINDOW_MANAGER_DRAWN_COMPLETE);
        }
    };
    final ShowListener mKeyguardDelegateCallback = new ShowListener() {
        @Override
        public void onShown(IBinder windowToken) {
            if (DEBUG_WAKEUP) Slog.d(TAG, "mKeyguardDelegate.ShowListener.onShown.");
            mHandler.sendEmptyMessage(MSG_KEYGUARD_DRAWN_COMPLETE);
        }
    };

    GlobalActions mGlobalActions;
    volatile boolean mPowerKeyHandled; // accessed from input reader and handler thread
    boolean mPendingPowerKeyUpCanceled;
@@ -483,6 +508,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    private static final int MSG_DISABLE_POINTER_LOCATION = 2;
    private static final int MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK = 3;
    private static final int MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK = 4;
    private static final int MSG_KEYGUARD_DRAWN_COMPLETE = 5;
    private static final int MSG_KEYGUARD_DRAWN_TIMEOUT = 6;
    private static final int MSG_WINDOW_MANAGER_DRAWN_COMPLETE = 7;
    private static final int MSG_WAKING_UP = 8;

    private class PolicyHandler extends Handler {
        @Override
@@ -500,6 +529,25 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                case MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK:
                    dispatchMediaKeyRepeatWithWakeLock((KeyEvent)msg.obj);
                    break;
                case MSG_KEYGUARD_DRAWN_COMPLETE:
                    if (DEBUG_WAKEUP) Slog.w(TAG, "Setting mKeyguardDrawComplete");
                    mKeyguardDrawComplete = true;
                    finishScreenTurningOn();
                    break;
                case MSG_KEYGUARD_DRAWN_TIMEOUT:
                    Slog.w(TAG, "Keyguard drawn timeout. Setting mKeyguardDrawComplete");
                    mKeyguardDrawComplete = true;
                    finishScreenTurningOn();
                    break;
                case MSG_WINDOW_MANAGER_DRAWN_COMPLETE:
                    if (DEBUG_WAKEUP) Slog.w(TAG, "Setting mWindowManagerDrawComplete");
                    mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT);
                    mWindowManagerDrawComplete = true;
                    finishScreenTurningOn();
                    break;
                case MSG_WAKING_UP:
                    handleWakingUp((ScreenOnListener) msg.obj);
                    break;
            }
        }
    }
@@ -893,6 +941,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        mContext = context;
        mWindowManager = windowManager;
        mWindowManagerFuncs = windowManagerFuncs;
        mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);

        mHandler = new PolicyHandler();
        mOrientationListener = new MyOrientationListener(mContext, mHandler);
        try {
@@ -4327,10 +4377,15 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    @Override
    public void wakingUp(final ScreenOnListener screenOnListener) {
        EventLog.writeEvent(70000, 1);
        if (false) {
            RuntimeException here = new RuntimeException("here");
            here.fillInStackTrace();
            Slog.i(TAG, "Screen turning on...", here);
        if (DEBUG_WAKEUP) Slog.i(TAG, "Screen turning on...",
                new RuntimeException("here").fillInStackTrace());
        mHandler.obtainMessage(MSG_WAKING_UP, screenOnListener).sendToTarget();
    }

    // Called on the mHandler thread.
    private void handleWakingUp(final ScreenOnListener screenOnListener) {
        if (screenOnListener != null) {
            mScreenOnListeners.add(screenOnListener);
        }

        synchronized (mLock) {
@@ -4339,54 +4394,28 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            updateLockScreenTimeout();
        }

        waitForKeyguard(screenOnListener);
    }

    private void waitForKeyguard(final ScreenOnListener screenOnListener) {
        mKeyguardDrawComplete = false;
        mWindowManagerDrawComplete = false;
        if (mKeyguardDelegate != null) {
            if (screenOnListener != null) {
                mKeyguardDelegate.onScreenTurnedOn(new KeyguardServiceDelegate.ShowListener() {
                    @Override
                    public void onShown(IBinder windowToken) {
                        waitForKeyguardWindowDrawn(windowToken, screenOnListener);
                    }
                });
                return;
            } else {
                mKeyguardDelegate.onScreenTurnedOn(null);
            }
            mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT);
            mHandler.sendEmptyMessageDelayed(MSG_KEYGUARD_DRAWN_TIMEOUT, 1000);
            mKeyguardDelegate.onScreenTurnedOn(mKeyguardDelegateCallback);
        } else {
            Slog.i(TAG, "No keyguard interface!");
            if (DEBUG_WAKEUP) Slog.d(TAG, "null mKeyguardDelegate: setting mKeyguardDrawComplete.");
            mKeyguardDrawComplete = true;
        }
        finishScreenTurningOn(screenOnListener);
        mWindowManagerInternal.waitForAllWindowsDrawn(mWindowManagerDrawCallback, 500);
    }

    private void waitForKeyguardWindowDrawn(IBinder windowToken,
            final ScreenOnListener screenOnListener) {
        if (windowToken != null && !mHideLockScreen) {
            try {
                if (mWindowManager.waitForWindowDrawn(
                        windowToken, new IRemoteCallback.Stub() {
                    @Override
                    public void sendResult(Bundle data) {
                        Slog.i(TAG, "Lock screen displayed!");
                        finishScreenTurningOn(screenOnListener);
                    }
                })) {
    // Called on the mHandler thread.
    private void finishScreenTurningOn() {
        if (DEBUG_WAKEUP) Slog.d(TAG,
                "finishScreenTurningOn: mKeyguardDrawComplete=" + mKeyguardDrawComplete
                        + " mWindowManagerDrawComplete=" + mWindowManagerDrawComplete);
        if (!mKeyguardDrawComplete || !mWindowManagerDrawComplete) {
            return;
        }
                Slog.i(TAG, "No lock screen! waitForWindowDrawn false");

            } catch (RemoteException ex) {
                // Can't happen in system process.
            }
        }

        Slog.i(TAG, "No lock screen! windowToken=" + windowToken);
        finishScreenTurningOn(screenOnListener);
    }

    private void finishScreenTurningOn(ScreenOnListener screenOnListener) {
        synchronized (mLock) {
            mScreenOnFully = true;
        }
@@ -4396,8 +4425,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        } catch (RemoteException unhandled) {
        }

        if (screenOnListener != null) {
            screenOnListener.onScreenOn();
        for (int i = mScreenOnListeners.size() - 1; i >=0; --i) {
            mScreenOnListeners.remove(i).onScreenOn();
        }
    }

+74 −59
Original line number Diff line number Diff line
@@ -397,8 +397,11 @@ public class WindowManagerService extends IWindowManager.Stub
    /**
     * Windows that clients are waiting to have drawn.
     */
    ArrayList<Pair<WindowState, IRemoteCallback>> mWaitingForDrawn
            = new ArrayList<Pair<WindowState, IRemoteCallback>>();
    ArrayList<WindowState> mWaitingForDrawn = new ArrayList<WindowState>();
    /**
     * And the callback to make when they've all been drawn.
     */
    IRemoteCallback mWaitingForDrawnCallback;

    /**
     * Windows that have called relayout() while we were running animations,
@@ -802,6 +805,7 @@ public class WindowManagerService extends IWindowManager.Stub

        mAnimator = new WindowAnimator(this);

        LocalServices.addService(WindowManagerInternal.class, new LocalService());
        initPolicy();

        // Add ourself to the Watchdog monitors.
@@ -816,7 +820,6 @@ public class WindowManagerService extends IWindowManager.Stub
            SurfaceControl.closeTransaction();
        }

        LocalServices.addService(WindowManagerInternal.class, new LocalService());
        showCircularDisplayMaskIfNeeded();
    }

@@ -7198,6 +7201,7 @@ public class WindowManagerService extends IWindowManager.Stub
        public static final int REMOVE_STARTING_TIMEOUT = 33;

        public static final int SHOW_DISPLAY_MASK = 34;
        public static final int ALL_WINDOWS_DRAWN = 35;

        @Override
        public void handleMessage(Message msg) {
@@ -7580,18 +7584,19 @@ public class WindowManagerService extends IWindowManager.Stub
                }

                case WAITING_FOR_DRAWN_TIMEOUT: {
                    Pair<WindowState, IRemoteCallback> pair;
                    IRemoteCallback callback = null;
                    synchronized (mWindowMap) {
                        pair = (Pair<WindowState, IRemoteCallback>)msg.obj;
                        Slog.w(TAG, "Timeout waiting for drawn: " + pair.first);
                        if (!mWaitingForDrawn.remove(pair)) {
                            return;
                        }
                        Slog.w(TAG, "Timeout waiting for drawn: undrawn=" + mWaitingForDrawn);
                        mWaitingForDrawn.clear();
                        callback = mWaitingForDrawnCallback;
                        mWaitingForDrawnCallback = null;
                    }
                    if (callback != null) {
                        try {
                        pair.second.sendResult(null);
                            callback.sendResult(null);
                        } catch (RemoteException e) {
                        }
                    }
                    break;
                }

@@ -7648,6 +7653,19 @@ public class WindowManagerService extends IWindowManager.Stub
                    } catch (RemoteException e) {
                    }
                    break;
                case ALL_WINDOWS_DRAWN: {
                    IRemoteCallback callback;
                    synchronized (mWindowMap) {
                        callback = mWaitingForDrawnCallback;
                        mWaitingForDrawnCallback = null;
                    }
                    if (callback != null) {
                        try {
                            callback.sendResult(null);
                        } catch (RemoteException e) {
                        }
                    }
                }
            }
            if (DEBUG_WINDOW_TRACE) {
                Slog.v(TAG, "handleMessage: exit");
@@ -9582,55 +9600,32 @@ public class WindowManagerService extends IWindowManager.Stub
    }

    void checkDrawnWindowsLocked() {
        if (mWaitingForDrawn.size() > 0) {
        if (mWaitingForDrawn.isEmpty() || mWaitingForDrawnCallback == null) {
            return;
        }
        for (int j = mWaitingForDrawn.size() - 1; j >= 0; j--) {
                Pair<WindowState, IRemoteCallback> pair = mWaitingForDrawn.get(j);
                WindowState win = pair.first;
                //Slog.i(TAG, "Waiting for drawn " + win + ": removed="
                //        + win.mRemoved + " visible=" + win.isVisibleLw()
                //        + " shown=" + win.mSurfaceShown);
                if (win.mRemoved) {
            WindowState win = mWaitingForDrawn.get(j);
            if (DEBUG_SCREEN_ON) Slog.i(TAG, "Waiting for drawn " + win +
                    ": removed=" + win.mRemoved + " visible=" + win.isVisibleLw() +
                    " mHasSurface=" + win.mHasSurface +
                    " drawState=" + win.mWinAnimator.mDrawState);
            if (win.mRemoved || !win.mHasSurface) {
                // Window has been removed; no draw will now happen, so stop waiting.
                    Slog.w(TAG, "Aborted waiting for drawn: " + pair.first);
                    try {
                        pair.second.sendResult(null);
                    } catch (RemoteException e) {
                    }
                    mWaitingForDrawn.remove(pair);
                    mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
                } else if (win.mWinAnimator.mSurfaceShown) {
                if (DEBUG_SCREEN_ON) Slog.w(TAG, "Aborted waiting for drawn: " + win);
                mWaitingForDrawn.remove(win);
            } else if (win.hasDrawnLw()) {
                // Window is now drawn (and shown).
                    try {
                        pair.second.sendResult(null);
                    } catch (RemoteException e) {
                    }
                    mWaitingForDrawn.remove(pair);
                    mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
                if (DEBUG_SCREEN_ON) Slog.d(TAG, "Window drawn win=" + win);
                mWaitingForDrawn.remove(win);
            }
        }
        if (mWaitingForDrawn.isEmpty()) {
            if (DEBUG_SCREEN_ON) Slog.d(TAG, "All windows drawn!");
            mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT);
            mH.sendEmptyMessage(H.ALL_WINDOWS_DRAWN);
        }
    }

    @Override
    public boolean waitForWindowDrawn(IBinder token, IRemoteCallback callback) {
        if (token != null && callback != null) {
            synchronized (mWindowMap) {
                WindowState win = windowForClientLocked(null, token, true);
                if (win != null) {
                    Pair<WindowState, IRemoteCallback> pair =
                            new Pair<WindowState, IRemoteCallback>(win, callback);
                    Message m = mH.obtainMessage(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
                    mH.sendMessageDelayed(m, 2000);
                    mWaitingForDrawn.add(pair);
                    checkDrawnWindowsLocked();
                    return true;
                }
                Slog.i(TAG, "waitForWindowDrawn: win null");
            }
        }
        return false;
    }

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

@@ -10508,9 +10503,8 @@ public class WindowManagerService extends IWindowManager.Stub
            pw.println();
            pw.println("  Clients waiting for these windows to be drawn:");
            for (int i=mWaitingForDrawn.size()-1; i>=0; i--) {
                Pair<WindowState, IRemoteCallback> pair = mWaitingForDrawn.get(i);
                pw.print("  Waiting #"); pw.print(i); pw.print(' '); pw.print(pair.first);
                        pw.print(": "); pw.println(pair.second);
                WindowState win = mWaitingForDrawn.get(i);
                pw.print("  Waiting #"); pw.print(i); pw.print(' '); pw.print(win);
            }
        }
        pw.println();
@@ -10976,5 +10970,26 @@ public class WindowManagerService extends IWindowManager.Stub
        public void requestTraversalFromDisplayManager() {
            requestTraversal();
        }

        @Override
        public void waitForAllWindowsDrawn(IRemoteCallback callback, long timeout) {
            synchronized (mWindowMap) {
                mWaitingForDrawnCallback = callback;
                final WindowList windows = getDefaultWindowListLocked();
                for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
                    final WindowState win = windows.get(winNdx);
                    if (win.mHasSurface) {
                        win.mWinAnimator.mDrawState = WindowStateAnimator.DRAW_PENDING;
                        // Force add to mResizingWindows.
                        win.mLastContentInsets.set(-1, -1, -1, -1);
                        mWaitingForDrawn.add(win);
                    }
                }
                requestTraversalLocked();
                mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT);
                mH.sendEmptyMessageDelayed(H.WAITING_FOR_DRAWN_TIMEOUT, timeout);
            }
            checkDrawnWindowsLocked();
        }
    }
}
+0 −5
Original line number Diff line number Diff line
@@ -427,11 +427,6 @@ public class IWindowManagerImpl implements IWindowManager {
    public void removeRotationWatcher(IRotationWatcher arg0) throws RemoteException {
    }

    @Override
    public boolean waitForWindowDrawn(IBinder token, IRemoteCallback callback) {
        return false;
    }

    @Override
    public IBinder asBinder() {
        // TODO Auto-generated method stub