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

Commit 22af5b84 authored by Craig Mautner's avatar Craig Mautner Committed by Android Git Automerger
Browse files

am 81dfc082: Merge "Force all windows to redraw before unblanking screen" into klp-modular-dev

* commit '81dfc082':
  Force all windows to redraw before unblanking screen
parents fbd6fe04 81dfc082
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();
    }

@@ -7199,6 +7202,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) {
@@ -7581,18 +7585,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;
                }

@@ -7649,6 +7654,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");
@@ -9583,55 +9601,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;

@@ -10521,9 +10516,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();
@@ -10989,5 +10983,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