diff options
| author | George Zacharia <george.zcharia@gmail.com> | 2022-12-11 20:20:25 +0300 |
|---|---|---|
| committer | Semavi Ulusoy <doc.divxm@gmail.com> | 2022-12-15 20:02:27 +0300 |
| commit | 998f28a8e5fad5d2cb3c779b97e471f1480a33e5 (patch) | |
| tree | 45e7d172b25e1a27f66182c9c305f26b4532d6b3 /core/java/android/view/ViewRootImpl.java | |
| parent | 84cc160548e9af3019df4691fb6ae2f7f12ef8e8 (diff) | |
| parent | 7556c20276d2b96346fbf30b6631babde90aba0b (diff) | |
Merge tag 'android-13.0.0_r16' into t13.0
Android 13.0.0 Release 16 (TQ1A.221205.011)
Also included the following reverts:
1. Revert "fw/b: Import Wi-Fi standard icon [1/2]"
2. Revert "Add preference for toggling the wallpaper zooming animation"
Co-authored-by: Semavi Ulusoy <doc.divxm@gmail.com>
Change-Id: I9a6b51e452c28d10411712c59778bb54da5783e9
Diffstat (limited to 'core/java/android/view/ViewRootImpl.java')
| -rw-r--r-- | core/java/android/view/ViewRootImpl.java | 316 |
1 files changed, 225 insertions, 91 deletions
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index ce7cf192725c..07a2504335a4 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -60,13 +60,11 @@ import static android.view.WindowInsetsController.BEHAVIOR_DEFAULT; import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE; import static android.view.WindowLayout.UNSPECIFIED_LENGTH; import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW; -import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW; import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION; import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS; import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW; -import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_APPEARANCE_CONTROLLED; @@ -77,13 +75,13 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INSET_PARENT_ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST; -import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; 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; @@ -279,7 +277,7 @@ public final class ViewRootImpl implements ViewParent, * @hide */ public static final boolean CAPTION_ON_SHELL = - SystemProperties.getBoolean("persist.debug.caption_on_shell", false); + SystemProperties.getBoolean("persist.wm.debug.caption_on_shell", false); /** * Whether the client should compute the window frame on its own. @@ -564,9 +562,7 @@ public final class ViewRootImpl implements ViewParent, private final Rect mVisRect = new Rect(); // used to retrieve visible rect of focused view. private final Rect mTempRect = new Rect(); - private final WindowLayout mWindowLayout = new WindowLayout(); - - private ViewRootImpl mParentViewRoot; + private final WindowLayout mWindowLayout; // This is used to reduce the race between window focus changes being dispatched from // the window manager and input events coming through the input system. @@ -591,8 +587,21 @@ public final class ViewRootImpl implements ViewParent, int mContentCaptureEnabled = CONTENT_CAPTURE_ENABLED_NOT_CHECKED; boolean mPerformContentCapture; - boolean mReportNextDraw; + /** Set only while mReportNextDraw=true, indicating the last reason that was triggered */ + String mLastReportNextDrawReason; + /** The reaason the last call to performDraw() returned false */ + String mLastPerformDrawSkippedReason; + /** The reason the last call to performTraversals() returned without drawing */ + String mLastPerformTraversalsSkipDrawReason; + /** The state of the local sync, if one is in progress. Can be one of the states below. */ + int mLocalSyncState; + + // The possible states of the local sync, see createSyncIfNeeded() + private final int LOCAL_SYNC_NONE = 0; + private final int LOCAL_SYNC_PENDING = 1; + private final int LOCAL_SYNC_RETURNED = 2; + private final int LOCAL_SYNC_MERGED = 3; /** * Set whether the draw should send the buffer to system server. When set to true, VRI will @@ -601,9 +610,20 @@ 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; + + private boolean mDrewOnceForSync = false; + int mSyncSeqId = 0; int mLastSyncSeqId = 0; + private boolean mUpdateSurfaceNeeded; boolean mFullRedrawNeeded; boolean mNewSurfaceNeeded; boolean mForceNextWindowRelayout; @@ -687,8 +707,12 @@ public final class ViewRootImpl implements ViewParent, final Rect mPendingBackDropFrame = new Rect(); boolean mPendingAlwaysConsumeSystemBars; + private int mRelayoutSeq; + private final Rect mWinFrameInScreen = new Rect(); private final InsetsState mTempInsets = new InsetsState(); private final InsetsSourceControl[] mTempControls = new InsetsSourceControl[SIZE]; + private final WindowConfiguration mTempWinConfig = new WindowConfiguration(); + private float mInvSizeCompatScale = 1f; final ViewTreeObserver.InternalInsetsInfo mLastGivenInsets = new ViewTreeObserver.InternalInsetsInfo(); @@ -881,18 +905,14 @@ public final class ViewRootImpl implements ViewParent, private String mTag = TAG; public ViewRootImpl(Context context, Display display) { - this(context, display, WindowManagerGlobal.getWindowSession(), - false /* useSfChoreographer */); - } - - public ViewRootImpl(@UiContext Context context, Display display, IWindowSession session) { - this(context, display, session, false /* useSfChoreographer */); + this(context, display, WindowManagerGlobal.getWindowSession(), new WindowLayout()); } public ViewRootImpl(@UiContext Context context, Display display, IWindowSession session, - boolean useSfChoreographer) { + WindowLayout windowLayout) { mContext = context; mWindowSession = session; + mWindowLayout = windowLayout; mDisplay = display; mBasePackageName = context.getBasePackageName(); mThread = Thread.currentThread(); @@ -921,8 +941,7 @@ public final class ViewRootImpl implements ViewParent, mNoncompatDensity = context.getResources().getDisplayMetrics().noncompatDensityDpi; mFallbackEventHandler = new PhoneFallbackEventHandler(context); // TODO(b/222696368): remove getSfInstance usage and use vsyncId for transactions - mChoreographer = useSfChoreographer - ? Choreographer.getSfInstance() : Choreographer.getInstance(); + mChoreographer = Choreographer.getInstance(); mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE); mInsetsController = new InsetsController(new ViewRootInsetsControllerHost(this)); mHandwritingInitiator = new HandwritingInitiator(mViewConfiguration, @@ -1086,6 +1105,16 @@ public final class ViewRootImpl implements ViewParent, return mContext.getResources().getConfiguration(); } + private WindowConfiguration getCompatWindowConfiguration() { + final WindowConfiguration winConfig = getConfiguration().windowConfiguration; + if (mInvSizeCompatScale == 1f) { + return winConfig; + } + mTempWinConfig.setTo(winConfig); + mTempWinConfig.scale(mInvSizeCompatScale); + return mTempWinConfig; + } + /** * We have one child */ @@ -1184,7 +1213,6 @@ public final class ViewRootImpl implements ViewParent, if (panelParentView != null) { mAttachInfo.mPanelParentWindowToken = panelParentView.getApplicationWindowToken(); - mParentViewRoot = panelParentView.getViewRootImpl(); } mAdded = true; int res; /* = WindowManagerImpl.ADD_OKAY; */ @@ -1215,14 +1243,24 @@ public final class ViewRootImpl implements ViewParent, collectViewAttributes(); adjustLayoutParamsForCompatibility(mWindowAttributes); controlInsetsForCompatibility(mWindowAttributes); + + Rect attachedFrame = new Rect(); + final float[] sizeCompatScale = { 1f }; res = mWindowSession.addToDisplayAsUser(mWindow, mWindowAttributes, getHostVisibility(), mDisplay.getDisplayId(), userId, mInsetsController.getRequestedVisibilities(), inputChannel, mTempInsets, - mTempControls); + mTempControls, attachedFrame, sizeCompatScale); + if (!attachedFrame.isValid()) { + attachedFrame = null; + } if (mTranslator != null) { mTranslator.translateInsetsStateInScreenToAppWindow(mTempInsets); mTranslator.translateSourceControlsInScreenToAppWindow(mTempControls); + mTranslator.translateRectInScreenToAppWindow(attachedFrame); } + mTmpFrames.attachedFrame = attachedFrame; + mTmpFrames.sizeCompatScale = sizeCompatScale[0]; + mInvSizeCompatScale = 1f / sizeCompatScale[0]; } catch (RemoteException e) { mAdded = false; mView = null; @@ -1245,12 +1283,12 @@ public final class ViewRootImpl implements ViewParent, final InsetsState state = mInsetsController.getState(); final Rect displayCutoutSafe = mTempRect; state.getDisplayCutoutSafe(displayCutoutSafe); - final WindowConfiguration winConfig = getConfiguration().windowConfiguration; + final WindowConfiguration winConfig = getCompatWindowConfiguration(); mWindowLayout.computeFrames(mWindowAttributes, state, displayCutoutSafe, winConfig.getBounds(), winConfig.getWindowingMode(), UNSPECIFIED_LENGTH, UNSPECIFIED_LENGTH, - mInsetsController.getRequestedVisibilities(), - getAttachedWindowFrame(), 1f /* compactScale */, mTmpFrames); + mInsetsController.getRequestedVisibilities(), 1f /* compactScale */, + mTmpFrames); setFrame(mTmpFrames.frame); registerBackCallbackOnWindow(); if (!WindowOnBackInvokedDispatcher.isOnBackInvokedCallbackEnabled(mContext)) { @@ -1368,14 +1406,6 @@ public final class ViewRootImpl implements ViewParent, } } - private Rect getAttachedWindowFrame() { - final int type = mWindowAttributes.type; - final boolean layoutAttached = (mParentViewRoot != null - && type >= FIRST_SUB_WINDOW && type <= LAST_SUB_WINDOW - && type != TYPE_APPLICATION_ATTACHED_DIALOG); - return layoutAttached ? mParentViewRoot.mWinFrame : null; - } - /** * Register any kind of listeners if setView was success. */ @@ -1733,21 +1763,30 @@ public final class ViewRootImpl implements ViewParent, final Rect frame = frames.frame; final Rect displayFrame = frames.displayFrame; + final Rect attachedFrame = frames.attachedFrame; if (mTranslator != null) { mTranslator.translateRectInScreenToAppWindow(frame); mTranslator.translateRectInScreenToAppWindow(displayFrame); + mTranslator.translateRectInScreenToAppWindow(attachedFrame); } + final float sizeCompatScale = frames.sizeCompatScale; final boolean frameChanged = !mWinFrame.equals(frame); final boolean configChanged = !mLastReportedMergedConfiguration.equals(mergedConfiguration); + final boolean attachedFrameChanged = LOCAL_LAYOUT + && !Objects.equals(mTmpFrames.attachedFrame, attachedFrame); final boolean displayChanged = mDisplay.getDisplayId() != displayId; final boolean resizeModeChanged = mResizeMode != resizeMode; - if (msg == MSG_RESIZED && !frameChanged && !configChanged && !displayChanged - && !resizeModeChanged && !forceNextWindowRelayout) { + final boolean sizeCompatScaleChanged = mTmpFrames.sizeCompatScale != sizeCompatScale; + if (msg == MSG_RESIZED && !frameChanged && !configChanged && !attachedFrameChanged + && !displayChanged && !resizeModeChanged && !forceNextWindowRelayout + && !sizeCompatScaleChanged) { return; } mPendingDragResizing = resizeMode != RESIZE_MODE_INVALID; mResizeMode = resizeMode; + mTmpFrames.sizeCompatScale = sizeCompatScale; + mInvSizeCompatScale = 1f / sizeCompatScale; if (configChanged) { // If configuration changed - notify about that and, maybe, about move to display. @@ -1760,6 +1799,9 @@ public final class ViewRootImpl implements ViewParent, setFrame(frame); mTmpFrames.displayFrame.set(displayFrame); + if (mTmpFrames.attachedFrame != null && attachedFrame != null) { + mTmpFrames.attachedFrame.set(attachedFrame); + } if (mDragResizing && mUseMTRenderer) { boolean fullscreen = frame.equals(mPendingBackDropFrame); @@ -1769,12 +1811,12 @@ public final class ViewRootImpl implements ViewParent, } } - mForceNextWindowRelayout = forceNextWindowRelayout; + mForceNextWindowRelayout |= forceNextWindowRelayout; mPendingAlwaysConsumeSystemBars = args.argi2 != 0; mSyncSeqId = args.argi4 > mSyncSeqId ? args.argi4 : mSyncSeqId; if (msg == MSG_RESIZED_REPORT) { - reportNextDraw(); + reportNextDraw("resized"); } if (mView != null && (frameChanged || configChanged)) { @@ -2679,6 +2721,8 @@ public final class ViewRootImpl implements ViewParent, } private void performTraversals() { + mLastPerformTraversalsSkipDrawReason = null; + // cache mView since it is used so much below... final View host = mView; if (DBG) { @@ -2688,11 +2732,16 @@ public final class ViewRootImpl implements ViewParent, } if (host == null || !mAdded) { + mLastPerformTraversalsSkipDrawReason = host == null ? "no_host" : "not_added"; return; } mIsInTraversal = true; mWillDrawSoon = true; + boolean cancelDraw = false; + String cancelReason = null; + boolean isSyncRequest = false; + boolean windowSizeMayChange = false; WindowManager.LayoutParams lp = mWindowAttributes; @@ -2781,6 +2830,7 @@ public final class ViewRootImpl implements ViewParent, if (viewVisibilityChanged) { mAttachInfo.mWindowVisibility = viewVisibility; host.dispatchWindowVisibilityChanged(viewVisibility); + mAttachInfo.mTreeObserver.dispatchOnWindowVisibilityChange(viewVisibility); if (viewUserVisibilityChanged) { host.dispatchVisibilityAggregated(viewVisibility == View.VISIBLE); } @@ -2907,7 +2957,6 @@ public final class ViewRootImpl implements ViewParent, final int surfaceGenerationId = mSurface.getGenerationId(); final boolean isViewVisible = viewVisibility == View.VISIBLE; - final boolean windowRelayoutWasForced = mForceNextWindowRelayout; boolean surfaceSizeChanged = false; boolean surfaceCreated = false; boolean surfaceDestroyed = false; @@ -2971,14 +3020,21 @@ 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; + cancelReason = "relayout"; final boolean dragResizing = mPendingDragResizing; if (mSyncSeqId > mLastSyncSeqId) { mLastSyncSeqId = mSyncSeqId; if (DEBUG_BLAST) { Log.d(mTag, "Relayout called with blastSync"); } - reportNextDraw(); + reportNextDraw("relayout"); mSyncBuffer = true; + isSyncRequest = true; + if (!cancelDraw) { + mDrewOnceForSync = false; + } } final boolean surfaceControlChanged = @@ -3004,13 +3060,16 @@ public final class ViewRootImpl implements ViewParent, // WindowManagerService has reported back a frame from a configuration not yet // handled by the client. In this case, we need to accept the configuration so we // do not lay out and draw with the wrong configuration. - if (!mPendingMergedConfiguration.equals(mLastReportedMergedConfiguration)) { + if (mRelayoutRequested + && !mPendingMergedConfiguration.equals(mLastReportedMergedConfiguration)) { if (DEBUG_CONFIGURATION) Log.v(mTag, "Visible with new config: " + mPendingMergedConfiguration.getMergedConfiguration()); performConfigurationChange(new MergedConfiguration(mPendingMergedConfiguration), !mFirst, INVALID_DISPLAY /* same display */); updatedConfiguration = true; } + final boolean updateSurfaceNeeded = mUpdateSurfaceNeeded; + mUpdateSurfaceNeeded = false; surfaceSizeChanged = false; if (!mLastSurfaceSize.equals(mSurfaceSize)) { @@ -3069,6 +3128,7 @@ public final class ViewRootImpl implements ViewParent, } } catch (OutOfResourcesException e) { handleOutOfResourcesException(e); + mLastPerformTraversalsSkipDrawReason = "oom_initialize_renderer"; return; } } @@ -3089,8 +3149,7 @@ public final class ViewRootImpl implements ViewParent, if (isHardwareEnabled()) { mAttachInfo.mThreadedRenderer.destroy(); } - } else if ((surfaceReplaced - || surfaceSizeChanged || windowRelayoutWasForced) + } else if ((surfaceReplaced || surfaceSizeChanged || updateSurfaceNeeded) && mSurfaceHolder == null && mAttachInfo.mThreadedRenderer != null && mSurface.isValid()) { @@ -3107,6 +3166,7 @@ public final class ViewRootImpl implements ViewParent, mAttachInfo.mThreadedRenderer.updateSurface(mSurface); } catch (OutOfResourcesException e) { handleOutOfResourcesException(e); + mLastPerformTraversalsSkipDrawReason = "oom_update_surface"; return; } } @@ -3274,6 +3334,20 @@ public final class ViewRootImpl implements ViewParent, maybeHandleWindowMove(frame); } + if (!mRelayoutRequested && mCheckIfCanDraw) { + // We had a sync previously, but we didn't call IWindowSession#relayout in this + // traversal. So we don't know if the sync is complete that we can continue to draw. + // Here invokes cancelDraw to obtain the information. + try { + cancelDraw = mWindowSession.cancelDraw(mWindow); + cancelReason = "wm_sync"; + if (DEBUG_BLAST) { + Log.d(mTag, "cancelDraw returned " + cancelDraw); + } + } catch (RemoteException e) { + } + } + if (surfaceSizeChanged || surfaceReplaced || surfaceCreated || windowAttributesChanged) { // If the surface has been replaced, there's a chance the bounds layer is not parented // to the new layer. When updating bounds layer, also reparent to the main VRI @@ -3481,15 +3555,21 @@ public final class ViewRootImpl implements ViewParent, mImeFocusController.onTraversal(hasWindowFocus, mWindowAttributes); if ((relayoutResult & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) { - reportNextDraw(); + reportNextDraw("first_relayout"); } - boolean cancelAndRedraw = mAttachInfo.mTreeObserver.dispatchOnPreDraw(); + mCheckIfCanDraw = isSyncRequest || cancelDraw; + + boolean cancelDueToPreDrawListener = mAttachInfo.mTreeObserver.dispatchOnPreDraw(); + boolean cancelAndRedraw = cancelDueToPreDrawListener + || (cancelDraw && mDrewOnceForSync); if (!cancelAndRedraw) { createSyncIfNeeded(); + mDrewOnceForSync = true; } if (!isViewVisible) { + mLastPerformTraversalsSkipDrawReason = "view_not_visible"; if (mPendingTransitions != null && mPendingTransitions.size() > 0) { for (int i = 0; i < mPendingTransitions.size(); ++i) { mPendingTransitions.get(i).endChangingAnimations(); @@ -3501,6 +3581,9 @@ public final class ViewRootImpl implements ViewParent, mSyncBufferCallback.onBufferReady(null); } } else if (cancelAndRedraw) { + mLastPerformTraversalsSkipDrawReason = cancelDueToPreDrawListener + ? "predraw_" + mAttachInfo.mTreeObserver.getLastDispatchOnPreDrawCanceledReason() + : "cancel_" + cancelReason; // Try again scheduleTraversals(); } else { @@ -3524,11 +3607,13 @@ public final class ViewRootImpl implements ViewParent, if (!cancelAndRedraw) { mReportNextDraw = false; + mLastReportNextDrawReason = null; mSyncBufferCallback = null; mSyncBuffer = false; if (isInLocalSync()) { mSurfaceSyncer.markSyncReady(mSyncId); mSyncId = UNSET_SYNC_ID; + mLocalSyncState = LOCAL_SYNC_NONE; } } } @@ -3540,9 +3625,12 @@ public final class ViewRootImpl implements ViewParent, } final int seqId = mSyncSeqId; + mLocalSyncState = LOCAL_SYNC_PENDING; mSyncId = mSurfaceSyncer.setupSync(transaction -> { + mLocalSyncState = LOCAL_SYNC_RETURNED; // Callback will be invoked on executor thread so post to main thread. mHandler.postAtFrontOfQueue(() -> { + mLocalSyncState = LOCAL_SYNC_MERGED; mSurfaceChangedTransaction.merge(transaction); reportDrawFinished(seqId); }); @@ -4257,9 +4345,12 @@ public final class ViewRootImpl implements ViewParent, } private boolean performDraw() { + mLastPerformDrawSkippedReason = null; if (mAttachInfo.mDisplayState == Display.STATE_OFF && !mReportNextDraw) { + mLastPerformDrawSkippedReason = "screen_off"; return false; } else if (mView == null) { + mLastPerformDrawSkippedReason = "no_root_view"; return false; } @@ -5224,6 +5315,21 @@ public final class ViewRootImpl implements ViewParent, throw new IllegalArgumentException("No merged config provided."); } + final int lastRotation = mLastReportedMergedConfiguration.getMergedConfiguration() + .windowConfiguration.getRotation(); + final int newRotation = mergedConfiguration.getMergedConfiguration() + .windowConfiguration.getRotation(); + if (lastRotation != newRotation) { + // Trigger ThreadedRenderer#updateSurface() if the surface control doesn't change. + // Because even if the actual surface size is not changed, e.g. flip 180 degrees, + // the buffers may still have content in previous rotation. And the next draw may + // not update all regions, that causes some afterimages to flicker. + mUpdateSurfaceNeeded = true; + if (!mIsInTraversal) { + mForceNextWindowRelayout = true; + } + } + Configuration globalConfig = mergedConfiguration.getGlobalConfiguration(); final Configuration overrideConfig = mergedConfiguration.getOverrideConfiguration(); if (DEBUG_CONFIGURATION) Log.v(mTag, @@ -7976,7 +8082,44 @@ public final class ViewRootImpl implements ViewParent, private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility, boolean insetsPending) throws RemoteException { - mRelayoutRequested = true; + final WindowConfiguration winConfigFromAm = getConfiguration().windowConfiguration; + final WindowConfiguration winConfigFromWm = + mLastReportedMergedConfiguration.getGlobalConfiguration().windowConfiguration; + final WindowConfiguration winConfig = getCompatWindowConfiguration(); + final int measuredWidth = mView.getMeasuredWidth(); + final int measuredHeight = mView.getMeasuredHeight(); + final boolean relayoutAsync; + if (LOCAL_LAYOUT + && (mViewFrameInfo.flags & FrameInfo.FLAG_WINDOW_VISIBILITY_CHANGED) == 0 + && mWindowAttributes.type != TYPE_APPLICATION_STARTING + && mSyncSeqId <= mLastSyncSeqId + && winConfigFromAm.diff(winConfigFromWm, false /* compareUndefined */) == 0) { + final InsetsState state = mInsetsController.getState(); + final Rect displayCutoutSafe = mTempRect; + state.getDisplayCutoutSafe(displayCutoutSafe); + mWindowLayout.computeFrames(mWindowAttributes.forRotation(winConfig.getRotation()), + state, displayCutoutSafe, winConfig.getBounds(), winConfig.getWindowingMode(), + measuredWidth, measuredHeight, mInsetsController.getRequestedVisibilities(), + 1f /* compatScale */, mTmpFrames); + mWinFrameInScreen.set(mTmpFrames.frame); + if (mTranslator != null) { + mTranslator.translateRectInAppWindowToScreen(mWinFrameInScreen); + } + + // If the position and the size of the frame are both changed, it will trigger a BLAST + // sync, and we still need to call relayout to obtain the syncSeqId. Otherwise, we just + // need to send attributes via relayoutAsync. + final Rect oldFrame = mWinFrame; + final Rect newFrame = mTmpFrames.frame; + final boolean positionChanged = + newFrame.top != oldFrame.top || newFrame.left != oldFrame.left; + final boolean sizeChanged = + newFrame.width() != oldFrame.width() || newFrame.height() != oldFrame.height(); + relayoutAsync = !positionChanged || !sizeChanged; + } else { + relayoutAsync = false; + } + float appScale = mAttachInfo.mApplicationScale; boolean restore = false; if (params != null && mTranslator != null) { @@ -7998,62 +8141,35 @@ public final class ViewRootImpl implements ViewParent, } } - final int requestedWidth = (int) (mView.getMeasuredWidth() * appScale + 0.5f); - final int requestedHeight = (int) (mView.getMeasuredHeight() * appScale + 0.5f); - + final int requestedWidth = (int) (measuredWidth * appScale + 0.5f); + final int requestedHeight = (int) (measuredHeight * appScale + 0.5f); int relayoutResult = 0; - WindowConfiguration winConfig = getConfiguration().windowConfiguration; - if (LOCAL_LAYOUT) { - if (mFirst || viewVisibility != mViewVisibility) { - relayoutResult = mWindowSession.updateVisibility(mWindow, params, viewVisibility, - mPendingMergedConfiguration, mSurfaceControl, mTempInsets, mTempControls); - if (mTranslator != null) { - mTranslator.translateInsetsStateInScreenToAppWindow(mTempInsets); - mTranslator.translateSourceControlsInScreenToAppWindow(mTempControls); - } - mInsetsController.onStateChanged(mTempInsets); - mInsetsController.onControlsChanged(mTempControls); - - mPendingAlwaysConsumeSystemBars = - (relayoutResult & RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS) != 0; - } - final InsetsState state = mInsetsController.getState(); - final Rect displayCutoutSafe = mTempRect; - state.getDisplayCutoutSafe(displayCutoutSafe); - if (mWindowAttributes.type == TYPE_APPLICATION_STARTING) { - // TODO(b/210378379): Remove the special logic. - // Letting starting window use the window bounds from the pending config is for the - // fixed rotation, because the config is not overridden before the starting window - // is created. - winConfig = mPendingMergedConfiguration.getMergedConfiguration() - .windowConfiguration; - } - mWindowLayout.computeFrames(mWindowAttributes, state, displayCutoutSafe, - winConfig.getBounds(), winConfig.getWindowingMode(), requestedWidth, - requestedHeight, mInsetsController.getRequestedVisibilities(), - getAttachedWindowFrame(), 1f /* compatScale */, mTmpFrames); - - mWindowSession.updateLayout(mWindow, params, - insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, mTmpFrames, - requestedWidth, requestedHeight); - + mRelayoutSeq++; + if (relayoutAsync) { + mWindowSession.relayoutAsync(mWindow, params, + requestedWidth, requestedHeight, viewVisibility, + insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, mRelayoutSeq, + mLastSyncSeqId); } else { relayoutResult = mWindowSession.relayout(mWindow, params, requestedWidth, requestedHeight, viewVisibility, - insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, - mTmpFrames, mPendingMergedConfiguration, mSurfaceControl, mTempInsets, - mTempControls, mRelayoutBundle); + insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, mRelayoutSeq, + mLastSyncSeqId, mTmpFrames, mPendingMergedConfiguration, mSurfaceControl, + mTempInsets, mTempControls, mRelayoutBundle); + mRelayoutRequested = true; final int maybeSyncSeqId = mRelayoutBundle.getInt("seqid"); if (maybeSyncSeqId > 0) { mSyncSeqId = maybeSyncSeqId; } - + mWinFrameInScreen.set(mTmpFrames.frame); if (mTranslator != null) { mTranslator.translateRectInScreenToAppWindow(mTmpFrames.frame); mTranslator.translateRectInScreenToAppWindow(mTmpFrames.displayFrame); + mTranslator.translateRectInScreenToAppWindow(mTmpFrames.attachedFrame); mTranslator.translateInsetsStateInScreenToAppWindow(mTempInsets); mTranslator.translateSourceControlsInScreenToAppWindow(mTempControls); } + mInvSizeCompatScale = 1f / mTmpFrames.sizeCompatScale; mInsetsController.onStateChanged(mTempInsets); mInsetsController.onControlsChanged(mTempControls); @@ -8065,7 +8181,7 @@ public final class ViewRootImpl implements ViewParent, (mDisplayInstallOrientation + mDisplay.getRotation()) % 4); WindowLayout.computeSurfaceSize(mWindowAttributes, winConfig.getMaxBounds(), requestedWidth, - requestedHeight, mTmpFrames.frame, mPendingDragResizing, mSurfaceSize); + requestedHeight, mWinFrameInScreen, mPendingDragResizing, mSurfaceSize); final boolean transformHintChanged = transformHint != mLastTransformHint; final boolean sizeChanged = !mLastSurfaceSize.equals(mSurfaceSize); @@ -8115,6 +8231,7 @@ public final class ViewRootImpl implements ViewParent, if (restore) { params.restore(); } + setFrame(mTmpFrames.frame); return relayoutResult; } @@ -8153,7 +8270,7 @@ public final class ViewRootImpl implements ViewParent, private void setFrame(Rect frame) { mWinFrame.set(frame); - final WindowConfiguration winConfig = getConfiguration().windowConfiguration; + final WindowConfiguration winConfig = getCompatWindowConfiguration(); mPendingBackDropFrame.set(mPendingDragResizing && !winConfig.useWindowFrameForBackdrop() ? winConfig.getMaxBounds() : frame); @@ -8353,6 +8470,21 @@ public final class ViewRootImpl implements ViewParent, if (mTraversalScheduled) { writer.println(innerPrefix + " (barrier=" + mTraversalBarrier + ")"); } + writer.println(innerPrefix + "mReportNextDraw=" + mReportNextDraw); + if (mReportNextDraw) { + writer.println(innerPrefix + " (reason=" + mLastReportNextDrawReason + ")"); + } + if (mLastPerformTraversalsSkipDrawReason != null) { + writer.println(innerPrefix + "mLastPerformTraversalsFailedReason=" + + mLastPerformTraversalsSkipDrawReason); + } + if (mLastPerformDrawSkippedReason != null) { + writer.println(innerPrefix + "mLastPerformDrawFailedReason=" + + mLastPerformDrawSkippedReason); + } + if (mLocalSyncState != LOCAL_SYNC_NONE) { + writer.println(innerPrefix + "mLocalSyncState=" + mLocalSyncState); + } writer.println(innerPrefix + "mIsAmbientMode=" + mIsAmbientMode); writer.println(innerPrefix + "mUnbufferedInputSource=" + Integer.toHexString(mUnbufferedInputSource)); @@ -9861,11 +9993,12 @@ public final class ViewRootImpl implements ViewParent, } } - private void reportNextDraw() { + private void reportNextDraw(String reason) { if (DEBUG_BLAST) { Log.d(mTag, "reportNextDraw " + Debug.getCallers(5)); } mReportNextDraw = true; + mLastReportNextDrawReason = reason; } /** @@ -9878,11 +10011,12 @@ public final class ViewRootImpl implements ViewParent, * @param syncBuffer If true, the transaction that contains the buffer from the draw should be * sent to system to be synced. If false, VRI will not try to sync the buffer, * but only report back that a buffer was drawn. + * @param reason A debug string indicating the reason for reporting the next draw * @hide */ - public void setReportNextDraw(boolean syncBuffer) { + public void setReportNextDraw(boolean syncBuffer, String reason) { mSyncBuffer = syncBuffer; - reportNextDraw(); + reportNextDraw(reason); invalidate(); } @@ -10850,8 +10984,8 @@ public final class ViewRootImpl implements ViewParent, private void registerCompatOnBackInvokedCallback() { mCompatOnBackInvokedCallback = () -> { - sendBackKeyEvent(KeyEvent.ACTION_DOWN); - sendBackKeyEvent(KeyEvent.ACTION_UP); + sendBackKeyEvent(KeyEvent.ACTION_DOWN); + sendBackKeyEvent(KeyEvent.ACTION_UP); }; mOnBackInvokedDispatcher.registerOnBackInvokedCallback( OnBackInvokedDispatcher.PRIORITY_DEFAULT, mCompatOnBackInvokedCallback); |
