Loading core/java/android/view/IWindowSession.aidl +5 −0 Original line number Diff line number Diff line Loading @@ -384,4 +384,9 @@ interface IWindowSession { * Clears a touchable region set by {@link #setInsets}. */ void clearTouchableRegion(IWindow window); /** * Returns whether this window needs to cancel draw and retry later. */ boolean cancelDraw(IWindow window); } core/java/android/view/ViewRootImpl.java +31 −1 Original line number Diff line number Diff line Loading @@ -84,6 +84,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT; import static android.view.WindowManager.LayoutParams.TYPE_TOAST; import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY; import static android.view.WindowManagerGlobal.RELAYOUT_RES_CANCEL_AND_REDRAW; import static android.view.WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS; import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED; import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.IME_FOCUS_CONTROLLER; Loading Loading @@ -601,6 +602,14 @@ public final class ViewRootImpl implements ViewParent, */ private boolean mSyncBuffer = false; /** * Flag to determine whether the client needs to check with WMS if it can draw. WMS will notify * the client that it can't draw if we're still in the middle of a sync set that includes this * window. Once the sync is complete, the window can resume drawing. This is to ensure we don't * deadlock the client by trying to request draws when there may not be any buffers available. */ private boolean mCheckIfCanDraw = false; int mSyncSeqId = 0; int mLastSyncSeqId = 0; Loading Loading @@ -2700,6 +2709,9 @@ public final class ViewRootImpl implements ViewParent, mIsInTraversal = true; mWillDrawSoon = true; boolean cancelDraw = false; boolean isSyncRequest = false; boolean windowSizeMayChange = false; WindowManager.LayoutParams lp = mWindowAttributes; Loading Loading @@ -2969,6 +2981,8 @@ public final class ViewRootImpl implements ViewParent, mViewFrameInfo.flags |= FrameInfo.FLAG_WINDOW_VISIBILITY_CHANGED; } relayoutResult = relayoutWindow(params, viewVisibility, insetsPending); cancelDraw = (relayoutResult & RELAYOUT_RES_CANCEL_AND_REDRAW) == RELAYOUT_RES_CANCEL_AND_REDRAW; final boolean dragResizing = mPendingDragResizing; if (mSyncSeqId > mLastSyncSeqId) { mLastSyncSeqId = mSyncSeqId; Loading @@ -2977,6 +2991,7 @@ public final class ViewRootImpl implements ViewParent, } reportNextDraw(); mSyncBuffer = true; isSyncRequest = true; } final boolean surfaceControlChanged = Loading Loading @@ -3265,6 +3280,19 @@ public final class ViewRootImpl implements ViewParent, } } } else { // If a relayout isn't going to happen, we still need to check if this window can draw // when mCheckIfCanDraw is set. This is because it means we had a sync in the past, but // have not been told by WMS that the sync is complete and that we can continue to draw if (mCheckIfCanDraw) { try { cancelDraw = mWindowSession.cancelDraw(mWindow); if (DEBUG_BLAST) { Log.d(mTag, "cancelDraw returned " + cancelDraw); } } catch (RemoteException e) { } } // Not the first pass and no window/insets/visibility change but the window // may have moved and we need check that and if so to update the left and right // in the attach info. We translate only the window frame since on window move Loading Loading @@ -3483,7 +3511,9 @@ public final class ViewRootImpl implements ViewParent, reportNextDraw(); } boolean cancelAndRedraw = mAttachInfo.mTreeObserver.dispatchOnPreDraw(); mCheckIfCanDraw = isSyncRequest || cancelDraw; boolean cancelAndRedraw = mAttachInfo.mTreeObserver.dispatchOnPreDraw() || cancelDraw; if (!cancelAndRedraw) { createSyncIfNeeded(); } Loading core/java/android/view/WindowManagerGlobal.java +5 −0 Original line number Diff line number Diff line Loading @@ -82,6 +82,11 @@ public final class WindowManagerGlobal { */ public static final int RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS = 1 << 3; /** * The window manager has told the window it cannot draw this frame and should retry again. */ public static final int RELAYOUT_RES_CANCEL_AND_REDRAW = 1 << 4; /** * Flag for relayout: the client will be later giving * internal insets; as a result, the window will not impact other window Loading core/java/android/view/WindowlessWindowManager.java +5 −0 Original line number Diff line number Diff line Loading @@ -552,4 +552,9 @@ public class WindowlessWindowManager implements IWindowSession { } } } @Override public boolean cancelDraw(IWindow window) { return false; } } services/core/java/com/android/server/wm/Session.java +5 −0 Original line number Diff line number Diff line Loading @@ -249,6 +249,11 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { mService.setWillReplaceWindows(appToken, childrenOnly); } @Override public boolean cancelDraw(IWindow window) { return mService.cancelDraw(this, window); } @Override public int relayout(IWindow window, WindowManager.LayoutParams attrs, int requestedWidth, int requestedHeight, int viewFlags, int flags, Loading Loading
core/java/android/view/IWindowSession.aidl +5 −0 Original line number Diff line number Diff line Loading @@ -384,4 +384,9 @@ interface IWindowSession { * Clears a touchable region set by {@link #setInsets}. */ void clearTouchableRegion(IWindow window); /** * Returns whether this window needs to cancel draw and retry later. */ boolean cancelDraw(IWindow window); }
core/java/android/view/ViewRootImpl.java +31 −1 Original line number Diff line number Diff line Loading @@ -84,6 +84,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT; import static android.view.WindowManager.LayoutParams.TYPE_TOAST; import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY; import static android.view.WindowManagerGlobal.RELAYOUT_RES_CANCEL_AND_REDRAW; import static android.view.WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS; import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED; import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.IME_FOCUS_CONTROLLER; Loading Loading @@ -601,6 +602,14 @@ public final class ViewRootImpl implements ViewParent, */ private boolean mSyncBuffer = false; /** * Flag to determine whether the client needs to check with WMS if it can draw. WMS will notify * the client that it can't draw if we're still in the middle of a sync set that includes this * window. Once the sync is complete, the window can resume drawing. This is to ensure we don't * deadlock the client by trying to request draws when there may not be any buffers available. */ private boolean mCheckIfCanDraw = false; int mSyncSeqId = 0; int mLastSyncSeqId = 0; Loading Loading @@ -2700,6 +2709,9 @@ public final class ViewRootImpl implements ViewParent, mIsInTraversal = true; mWillDrawSoon = true; boolean cancelDraw = false; boolean isSyncRequest = false; boolean windowSizeMayChange = false; WindowManager.LayoutParams lp = mWindowAttributes; Loading Loading @@ -2969,6 +2981,8 @@ public final class ViewRootImpl implements ViewParent, mViewFrameInfo.flags |= FrameInfo.FLAG_WINDOW_VISIBILITY_CHANGED; } relayoutResult = relayoutWindow(params, viewVisibility, insetsPending); cancelDraw = (relayoutResult & RELAYOUT_RES_CANCEL_AND_REDRAW) == RELAYOUT_RES_CANCEL_AND_REDRAW; final boolean dragResizing = mPendingDragResizing; if (mSyncSeqId > mLastSyncSeqId) { mLastSyncSeqId = mSyncSeqId; Loading @@ -2977,6 +2991,7 @@ public final class ViewRootImpl implements ViewParent, } reportNextDraw(); mSyncBuffer = true; isSyncRequest = true; } final boolean surfaceControlChanged = Loading Loading @@ -3265,6 +3280,19 @@ public final class ViewRootImpl implements ViewParent, } } } else { // If a relayout isn't going to happen, we still need to check if this window can draw // when mCheckIfCanDraw is set. This is because it means we had a sync in the past, but // have not been told by WMS that the sync is complete and that we can continue to draw if (mCheckIfCanDraw) { try { cancelDraw = mWindowSession.cancelDraw(mWindow); if (DEBUG_BLAST) { Log.d(mTag, "cancelDraw returned " + cancelDraw); } } catch (RemoteException e) { } } // Not the first pass and no window/insets/visibility change but the window // may have moved and we need check that and if so to update the left and right // in the attach info. We translate only the window frame since on window move Loading Loading @@ -3483,7 +3511,9 @@ public final class ViewRootImpl implements ViewParent, reportNextDraw(); } boolean cancelAndRedraw = mAttachInfo.mTreeObserver.dispatchOnPreDraw(); mCheckIfCanDraw = isSyncRequest || cancelDraw; boolean cancelAndRedraw = mAttachInfo.mTreeObserver.dispatchOnPreDraw() || cancelDraw; if (!cancelAndRedraw) { createSyncIfNeeded(); } Loading
core/java/android/view/WindowManagerGlobal.java +5 −0 Original line number Diff line number Diff line Loading @@ -82,6 +82,11 @@ public final class WindowManagerGlobal { */ public static final int RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS = 1 << 3; /** * The window manager has told the window it cannot draw this frame and should retry again. */ public static final int RELAYOUT_RES_CANCEL_AND_REDRAW = 1 << 4; /** * Flag for relayout: the client will be later giving * internal insets; as a result, the window will not impact other window Loading
core/java/android/view/WindowlessWindowManager.java +5 −0 Original line number Diff line number Diff line Loading @@ -552,4 +552,9 @@ public class WindowlessWindowManager implements IWindowSession { } } } @Override public boolean cancelDraw(IWindow window) { return false; } }
services/core/java/com/android/server/wm/Session.java +5 −0 Original line number Diff line number Diff line Loading @@ -249,6 +249,11 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { mService.setWillReplaceWindows(appToken, childrenOnly); } @Override public boolean cancelDraw(IWindow window) { return mService.cancelDraw(this, window); } @Override public int relayout(IWindow window, WindowManager.LayoutParams attrs, int requestedWidth, int requestedHeight, int viewFlags, int flags, Loading