Android13 WindowManagerService relayoutWindow流程分析

WindowManagerService的relayoutWindow用于计算窗口的大小以及内容区域边衬大小和可见区域边衬大小,代码如下:

//frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
public class WindowManagerService extends IWindowManager.Stub
        implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {
    public int relayoutWindow(Session session, IWindow client, LayoutParams attrs,
            int requestedWidth, int requestedHeight, int viewVisibility, int flags, int seq,
            int lastSyncSeqId, ClientWindowFrames outFrames,
            MergedConfiguration outMergedConfiguration, SurfaceControl outSurfaceControl,
            InsetsState outInsetsState, InsetsSourceControl[] outActiveControls,
            Bundle outSyncIdBundle) {
        if (outActiveControls != null) {
            Arrays.fill(outActiveControls, null);
        }
        int result = 0;
        boolean configChanged = false;
        final int pid = Binder.getCallingPid();
        final int uid = Binder.getCallingUid();
        final long origId = Binder.clearCallingIdentity();
        synchronized (mGlobalLock) {
            final WindowState win = windowForClientLocked(session, client, false);
            if (win == null) {
                return 0;
            }
            if (win.mRelayoutSeq < seq) {
                win.mRelayoutSeq = seq;
            } else if (win.mRelayoutSeq > seq) {
                return 0;
            }


            if (win.cancelAndRedraw() && win.mPrepareSyncSeqId <= lastSyncSeqId) {
                // The client has reported the sync draw, but we haven't finished it yet.
                // Don't let the client perform a non-sync draw at this time.
                result |= RELAYOUT_RES_CANCEL_AND_REDRAW;
            }


            final DisplayContent displayContent = win.getDisplayContent();
            final DisplayPolicy displayPolicy = displayContent.getDisplayPolicy();


            WindowStateAnimator winAnimator = win.mWinAnimator;
            if (viewVisibility != View.GONE) {
                win.setRequestedSize(requestedWidth, requestedHeight);
            }


            int attrChanges = 0;
            int flagChanges = 0;
            int privateFlagChanges = 0;
            if (attrs != null) {
                displayPolicy.adjustWindowParamsLw(win, attrs);
                attrs.flags = sanitizeFlagSlippery(attrs.flags, win.getName(), uid, pid);
                attrs.inputFeatures = sanitizeSpyWindow(attrs.inputFeatures, win.getName(), uid,
                        pid);
                int disableFlags =
                        (attrs.systemUiVisibility | attrs.subtreeSystemUiVisibility) & DISABLE_MASK;
                if (disableFlags != 0 && !hasStatusBarPermission(pid, uid)) {
                    disableFlags = 0;
                }
                win.mDisableFlags = disableFlags;
                if (win.mAttrs.type != attrs.type) {
                    throw new IllegalArgumentException(
                            "Window type can not be changed after the window is added.");
                }
                if (!(win.mAttrs.providedInsets == null && attrs.providedInsets == null)) {
                    if (win.mAttrs.providedInsets == null || attrs.providedInsets == null
                            || (win.mAttrs.providedInsets.length != attrs.providedInsets.length)) {
                        throw new IllegalArgumentException(
                                "Insets types can not be changed after the window is added.");
                    } else {
                        final int insetsTypes = attrs.providedInsets.length;
                        for (int i = 0; i < insetsTypes; i++) {
                            if (win.mAttrs.providedInsets[i].type != attrs.providedInsets[i].type) {
                                throw new IllegalArgumentException(
                                        "Insets types can not be changed after the window is "
                                                + "added.");
                            }
                        }
                    }
                }


                flagChanges = win.mAttrs.flags ^ attrs.flags;
                privateFlagChanges = win.mAttrs.privateFlags ^ attrs.privateFlags;
                attrChanges = win.mAttrs.copyFrom(attrs);
                final boolean layoutChanged =
                        (attrChanges & WindowManager.LayoutParams.LAYOUT_CHANGED) != 0;
                if (layoutChanged || (attrChanges
                        & WindowManager.LayoutParams.SYSTEM_UI_VISIBILITY_CHANGED) != 0) {
                    win.mLayoutNeeded = true;
                }
                if (layoutChanged && win.providesNonDecorInsets()) {
                    configChanged = displayPolicy.updateDecorInsetsInfo();
                }
                if (win.mActivityRecord != null && ((flagChanges & FLAG_SHOW_WHEN_LOCKED) != 0
                        || (flagChanges & FLAG_DISMISS_KEYGUARD) != 0)) {
                    win.mActivityRecord.checkKeyguardFlagsChanged();
                }
                if (((attrChanges & LayoutParams.ACCESSIBILITY_TITLE_CHANGED) != 0)
                        && (mAccessibilityController.hasCallbacks())) {
                    // No move or resize, but the controller checks for title changes as well
                    mAccessibilityController.onSomeWindowResizedOrMovedWithCallingUid(
                            uid, win.getDisplayContent().getDisplayId());
                }


                if ((privateFlagChanges & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS) != 0) {
                    updateNonSystemOverlayWindowsVisibilityIfNeeded(
                            win, win.mWinAnimator.getShown());
                }
                if ((attrChanges & (WindowManager.LayoutParams.PRIVATE_FLAGS_CHANGED)) != 0) {
                    winAnimator.setColorSpaceAgnosticLocked((win.mAttrs.privateFlags
                            & WindowManager.LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC) != 0);
                }
                if (win.mActivityRecord != null
                        && !displayContent.mDwpcHelper.keepActivityOnWindowFlagsChanged(
                                win.mActivityRecord.info, flagChanges, privateFlagChanges)) {
                    mH.sendMessage(mH.obtainMessage(H.REPARENT_TASK_TO_DEFAULT_DISPLAY,
                            win.mActivityRecord.getTask()));
                    Slog.w(TAG_WM, "Activity " + win.mActivityRecord + " window flag changed,"
                            + " can't remain on display " + displayContent.getDisplayId());
                    return 0;
                }
            }


            if (DEBUG_LAYOUT) Slog.v(TAG_WM, "Relayout " + win + ": viewVisibility=" + viewVisibility
                    + " req=" + requestedWidth + "x" + requestedHeight + " " + win.mAttrs);
            if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
                winAnimator.mAlpha = attrs.alpha;
            }
            win.setWindowScale(win.mRequestedWidth, win.mRequestedHeight);


            if (win.mAttrs.surfaceInsets.left != 0
                    || win.mAttrs.surfaceInsets.top != 0
                    || win.mAttrs.surfaceInsets.right != 0
                    || win.mAttrs.surfaceInsets.bottom != 0) {
                winAnimator.setOpaqueLocked(false);
            }


            final int oldVisibility = win.mViewVisibility;


            // If the window is becoming visible, visibleOrAdding may change which may in turn
            // change the IME target.
            final boolean becameVisible =
                    (oldVisibility == View.INVISIBLE || oldVisibility == View.GONE)
                            && viewVisibility == View.VISIBLE;
            boolean imMayMove = (flagChanges & (FLAG_ALT_FOCUSABLE_IM | FLAG_NOT_FOCUSABLE)) != 0
                    || becameVisible;
            boolean focusMayChange = win.mViewVisibility != viewVisibility
                    || ((flagChanges & FLAG_NOT_FOCUSABLE) != 0)
                    || (!win.mRelayoutCalled);


            boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
                    && win.hasWallpaper();
            wallpaperMayMove |= (flagChanges & FLAG_SHOW_WALLPAPER) != 0;
            if ((flagChanges & FLAG_SECURE) != 0 && winAnimator.mSurfaceController != null) {
                winAnimator.mSurfaceController.setSecure(win.isSecureLocked());
            }


            win.mRelayoutCalled = true;
            win.mInRelayout = true;


            win.setViewVisibility(viewVisibility);
            ProtoLog.i(WM_DEBUG_SCREEN_ON,
                    "Relayout %s: oldVis=%d newVis=%d. %s", win, oldVisibility,
                            viewVisibility, new RuntimeException().fillInStackTrace());




            win.setDisplayLayoutNeeded();
            win.mGivenInsetsPending = (flags & WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0;


            // We should only relayout if the view is visible, it is a starting window, or the
            // associated appToken is not hidden.
            final boolean shouldRelayout = viewVisibility == View.VISIBLE &&
                    (win.mActivityRecord == null || win.mAttrs.type == TYPE_APPLICATION_STARTING
                            || win.mActivityRecord.isClientVisible());


            // If we are not currently running the exit animation, we need to see about starting
            // one.
            // We don't want to animate visibility of windows which are pending replacement.
            // In the case of activity relaunch child windows could request visibility changes as
            // they are detached from the main application window during the tear down process.
            // If we satisfied these visibility changes though, we would cause a visual glitch
            // hiding the window before it's replacement was available. So we just do nothing on
            // our side.
            // This must be called before the call to performSurfacePlacement.
            if (!shouldRelayout && winAnimator.hasSurface() && !win.mAnimatingExit) {
                if (DEBUG_VISIBILITY) {
                    Slog.i(TAG_WM,
                            "Relayout invis " + win + ": mAnimatingExit=" + win.mAnimatingExit);
                }
                result |= RELAYOUT_RES_SURFACE_CHANGED;
                if (!win.mWillReplaceWindow) {
                    // When FLAG_SHOW_WALLPAPER flag is removed from a window, we usually set a flag
                    // in DC#pendingLayoutChanges and update the wallpaper target later.
                    // However it's possible that FLAG_SHOW_WALLPAPER flag is removed from a window
                    // when the window is about to exit, so we update the wallpaper target
                    // immediately here. Otherwise this window will be stuck in exiting and its
                    // surface remains on the screen.
                    // TODO(b/189856716): Allow destroying surface even if it belongs to the
                    //  keyguard target.
                    if (wallpaperMayMove) {
                        displayContent.mWallpaperController.adjustWallpaperWindows();
                    }
                    focusMayChange = tryStartExitingAnimation(win, winAnimator, focusMayChange);
                }
            }


            // Create surfaceControl before surface placement otherwise layout will be skipped
            // (because WS.isGoneForLayout() is true when there is no surface.
            if (shouldRelayout && outSurfaceControl != null) {
                try {
                    result = createSurfaceControl(outSurfaceControl, result, win, winAnimator);
                } catch (Exception e) {
                    displayContent.getInputMonitor().updateInputWindowsLw(true /*force*/);


                    ProtoLog.w(WM_ERROR,
                            "Exception thrown when creating surface for client %s (%s). %s",
                            client, win.mAttrs.getTitle(), e);
                    Binder.restoreCallingIdentity(origId);
                    return 0;
                }
            }


            // We may be deferring layout passes at the moment, but since the client is interested
            // in the new out values right now we need to force a layout.
            mWindowPlacerLocked.performSurfacePlacement(true /* force */);


            if (shouldRelayout) {
                Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: viewVisibility_1");


                result = win.relayoutVisibleWindow(result);


                if ((result & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) {
                    focusMayChange = true;
                }
                if (win.mAttrs.type == TYPE_INPUT_METHOD
                        && displayContent.mInputMethodWindow == null) {
                    displayContent.setInputMethodWindowLocked(win);
                    imMayMove = true;
                }
                win.adjustStartingWindowFlags();
                Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
            } else {
                Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: viewVisibility_2");


                winAnimator.mEnterAnimationPending = false;
                winAnimator.mEnteringAnimation = false;


                if (outSurfaceControl != null) {
                    if (viewVisibility == View.VISIBLE && winAnimator.hasSurface()) {
                        // We already told the client to go invisible, but the message may not be
                        // handled yet, or it might want to draw a last frame. If we already have a
                        // surface, let the client use that, but don't create new surface at this
                        // point.
                        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: getSurface");
                        winAnimator.mSurfaceController.getSurfaceControl(outSurfaceControl);
                        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
                    } else {
                        if (DEBUG_VISIBILITY) Slog.i(TAG_WM, "Releasing surface in: " + win);


                        try {
                            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "wmReleaseOutSurface_"
                                    + win.mAttrs.getTitle());
                            outSurfaceControl.release();
                        } finally {
                            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
                        }
                    }
                }


                Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
            }


            if (focusMayChange) {
                if (updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/)) {
                    imMayMove = false;
                }
            }


            // updateFocusedWindowLocked() already assigned layers so we only need to
            // reassign them at this point if the IM window state gets shuffled
            boolean toBeDisplayed = (result & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0;
            if (imMayMove) {
                displayContent.computeImeTarget(true /* updateImeTarget */);
                if (toBeDisplayed) {
                    // Little hack here -- we -should- be able to rely on the function to return
                    // true if the IME has moved and needs its layer recomputed. However, if the IME
                    // was hidden and isn't actually moved in the list, its layer may be out of data
                    // so we make sure to recompute it.
                    displayContent.assignWindowLayers(false /* setLayoutNeeded */);
                }
            }


            if (wallpaperMayMove) {
                displayContent.pendingLayoutChanges |=
                        WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
            }


            if (win.mActivityRecord != null) {
                displayContent.mUnknownAppVisibilityController.notifyRelayouted(win.mActivityRecord);
            }


            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: updateOrientation");
            configChanged |= displayContent.updateOrientation();
            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);


            if (toBeDisplayed && win.mIsWallpaper) {
                displayContent.mWallpaperController.updateWallpaperOffset(win, false /* sync */);
            }
            if (win.mActivityRecord != null) {
                win.mActivityRecord.updateReportedVisibilityLocked();
            }
            if (displayPolicy.areSystemBarsForcedConsumedLw()) {
                result |= WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS;
            }
            if (!win.isGoneForLayout()) {
                win.mResizedWhileGone = false;
            }


            if (outFrames != null && outMergedConfiguration != null) {
                win.fillClientWindowFramesAndConfiguration(outFrames, outMergedConfiguration,
                        false /* useLatestConfig */, shouldRelayout);


                // Set resize-handled here because the values are sent back to the client.
                win.onResizeHandled();
            }


            if (outInsetsState != null) {
                outInsetsState.set(win.getCompatInsetsState(), true /* copySources */);
            }


            ProtoLog.v(WM_DEBUG_FOCUS, "Relayout of %s: focusMayChange=%b",
                    win, focusMayChange);


            if (DEBUG_LAYOUT) {
                Slog.v(TAG_WM, "Relayout complete " + win + ": outFrames=" + outFrames);
            }
            win.mInRelayout = false;


            if (outSyncIdBundle != null) {
                final int maybeSyncSeqId;
                if (USE_BLAST_SYNC && win.useBLASTSync() && viewVisibility == View.VISIBLE
                        && win.mSyncSeqId > lastSyncSeqId) {
                    maybeSyncSeqId = win.shouldSyncWithBuffers() ? win.mSyncSeqId : -1;
                    win.markRedrawForSyncReported();
                } else {
                    maybeSyncSeqId = -1;
                }
                outSyncIdBundle.putInt("seqid", maybeSyncSeqId);
            }


            if (configChanged) {
                Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER,
                        "relayoutWindow: postNewConfigurationToHandler");
                displayContent.sendNewConfiguration();
                Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
            }
            if (outActiveControls != null) {
                getInsetsSourceControls(win, outActiveControls);
            }
        }


        Binder.restoreCallingIdentity(origId);
        return result;
    }
}

WindowManagerService createSurfaceControl

调用WindowManagerService的createSurfaceControl方法:

//frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
public class WindowManagerService extends IWindowManager.Stub
        implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {
    private int createSurfaceControl(SurfaceControl outSurfaceControl, int result,
            WindowState win, WindowStateAnimator winAnimator) {
        if (!win.mHasSurface) {
            result |= RELAYOUT_RES_SURFACE_CHANGED;
        }


        WindowSurfaceController surfaceController;
        try {
            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "createSurfaceControl");
            surfaceController = winAnimator.createSurfaceLocked();
        } finally {
            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
        }
        if (surfaceController != null) {
            surfaceController.getSurfaceControl(outSurfaceControl);
            ProtoLog.i(WM_SHOW_TRANSACTIONS, "OUT SURFACE %s: copied", outSurfaceControl);


        } else {
            // For some reason there isn't a surface.  Clear the
            // caller's object so they see the same state.
            ProtoLog.w(WM_ERROR, "Failed to create surface control for %s", win);
            outSurfaceControl.release();
        }


        return result;
    }
}

WindowStateAnimator createSurfaceLocked

调用winAnimator(WindowStateAnimator)的createSurfaceLocked方法:

//frameworks/base/service/java/com/android/server/wm/WindowStateAnimator.java
class WindowStateAnimator {
    WindowSurfaceController createSurfaceLocked() {
        final WindowState w = mWin;


 //一个WindowStateAnimator对象只会创建一个WindowSurfaceController
        if (mSurfaceController != null) {
            return mSurfaceController;
        }


        w.setHasSurface(false);


        ProtoLog.i(WM_DEBUG_ANIM, "createSurface %s: mDrawState=DRAW_PENDING", this);


        resetDrawState();


        mService.makeWindowFreezingScreenIfNeededLocked(w);


        int flags = SurfaceControl.HIDDEN;
        final WindowManager.LayoutParams attrs = w.mAttrs;


        if (w.isSecureLocked()) {
            flags |= SurfaceControl.SECURE;
        }


        if ((mWin.mAttrs.privateFlags & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0) {
            flags |= SurfaceControl.SKIP_SCREENSHOT;
        }


        if (DEBUG_VISIBILITY) {
            Slog.v(TAG, "Creating surface in session "
                    + mSession.mSurfaceSession + " window " + this
                    + " format=" + attrs.format + " flags=" + flags);
        }


        // Set up surface control with initial size.
        try {


            // This can be removed once we move all Buffer Layers to use BLAST.
            final boolean isHwAccelerated = (attrs.flags & FLAG_HARDWARE_ACCELERATED) != 0;
            final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : attrs.format;


     //这里直接通过new的方式创建了一个WindowSurfaceController对象
            mSurfaceController = new WindowSurfaceController(attrs.getTitle().toString(), format,
                    flags, this, attrs.type);
            mSurfaceController.setColorSpaceAgnostic((attrs.privateFlags
                    & WindowManager.LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC) != 0);


            w.setHasSurface(true);
            // The surface instance is changed. Make sure the input info can be applied to the
            // new surface, e.g. relaunch activity.
            w.mInputWindowHandle.forceChange();


            ProtoLog.i(WM_SHOW_SURFACE_ALLOC,
                        "  CREATE SURFACE %s IN SESSION %s: pid=%d format=%d flags=0x%x / %s",
                        mSurfaceController, mSession.mSurfaceSession, mSession.mPid, attrs.format,
                        flags, this);
        } catch (OutOfResourcesException e) {
            Slog.w(TAG, "OutOfResourcesException creating surface");
            mService.mRoot.reclaimSomeSurfaceMemory(this, "create", true);
            mDrawState = NO_SURFACE;
            return null;
        } catch (Exception e) {
            Slog.e(TAG, "Exception creating surface (parent dead?)", e);
            mDrawState = NO_SURFACE;
            return null;
        }


        if (DEBUG) {
            Slog.v(TAG, "Got surface: " + mSurfaceController
                    + ", set left=" + w.getFrame().left + " top=" + w.getFrame().top);
        }


        if (SHOW_LIGHT_TRANSACTIONS) {
            Slog.i(TAG, ">>> OPEN TRANSACTION createSurfaceLocked");
            WindowManagerService.logSurface(w, "CREATE pos=("
                    + w.getFrame().left + "," + w.getFrame().top + ") HIDE", false);
        }


        mLastHidden = true;


        if (DEBUG) Slog.v(TAG, "Created surface " + this);
        return mSurfaceController;
    }
}

上面方法的主要处理如下:

1、调用WindowStateAnimator的resetDrawState方法。

2、通过new的方式创建WindowSurfaceController对象。

分析分别进行分析:

WindowStateAnimator resetDrawState

调用WindowStateAnimator的resetDrawState方法:

//frameworks/base/service/java/com/android/server/wm/WindowStateAnimator.java
class WindowStateAnimator {
    void resetDrawState() {
        mDrawState = DRAW_PENDING;


        if (mWin.mActivityRecord == null) {
            return;
        }


        if (!mWin.mActivityRecord.isAnimating(TRANSITION)) {
            mWin.mActivityRecord.clearAllDrawn();
        }
    }
}

将DrawState设置为DRAW_PENDING状态,DRAW_PENDING表示窗口的绘制请求已经提交,但surface还没有真正显示。

new WindowSurfaceController

通过new的方式创建WindowSurfaceController对象,WindowSurfaceController构造方法中其实就是通过SurfaceControl的内部Builder类来创建SurfaceControl对象的,并且将SurfaceControl的Name,BufferSize,Format,Flags等等一并保存到内部Builder中,WindowSurfaceController构造方法如下:

//frameworks/base/service/java/com/android/server/wm/WindowSurfaceController.java
class WindowSurfaceController {
    WindowSurfaceController(String name, int format, int flags, WindowStateAnimator animator,
            int windowType) {
        mAnimator = animator;


        title = name;


        mService = animator.mService;
        final WindowState win = animator.mWin;
        mWindowType = windowType;
        mWindowSession = win.mSession;


        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "new SurfaceControl");
        final SurfaceControl.Builder b = win.makeSurface()
                .setParent(win.getSurfaceControl())
                .setName(name)
                .setFormat(format)
                .setFlags(flags)
                .setMetadata(METADATA_WINDOW_TYPE, windowType)
                .setMetadata(METADATA_OWNER_UID, mWindowSession.mUid)
                .setMetadata(METADATA_OWNER_PID, mWindowSession.mPid)
                .setCallsite("WindowSurfaceController");


        final boolean useBLAST = mService.mUseBLAST && ((win.getAttrs().privateFlags
                & WindowManager.LayoutParams.PRIVATE_FLAG_USE_BLAST) != 0);


        if (useBLAST) {
            b.setBLASTLayer();
        }


        mSurfaceControl = b.build();


        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
    }
}

上面方法主要处理如下:

1、调用WindowState的makeSurface方法获取SurfaceControl的构造器。

2、调用构造器(SurfaceControl.Builder)的build方法构造SurfaceControl对象。

下面分别进行分析:

WindowContainer makeSurface

调用win(WindowState的makeSurface方法,该方法在WindowState的父类WindowContainer中实现:

//frameworks/base/service/java/com/android/server/wm/WindowContainer.java
class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<E>
        implements Comparable<WindowContainer>, Animatable, SurfaceFreezer.Freezable,
        InsetsControlTarget {
    SurfaceControl.Builder makeSurface() {
        final WindowContainer p = getParent();
        return p.makeChildSurface(this);
    }
}

调用WindowContainer的makeChildSurface方法:

//frameworks/base/service/java/com/android/server/wm/WindowContainer.java
class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<E>
        implements Comparable<WindowContainer>, Animatable, SurfaceFreezer.Freezable,
        InsetsControlTarget {
    SurfaceControl.Builder makeChildSurface(WindowContainer child) {
        final WindowContainer p = getParent();
        // Give the parent a chance to set properties. In hierarchy v1 we rely
        // on this to set full-screen dimensions on all our Surface-less Layers.
        return p.makeChildSurface(child)
                .setParent(mSurfaceControl);
    }
}

返回WindowContainer对象,WindowContainer的构造方法如下:

//frameworks/base/service/java/com/android/server/wm/WindowContainer.java
class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<E>
        implements Comparable<WindowContainer>, Animatable, SurfaceFreezer.Freezable,
        InsetsControlTarget {
    final TransitionController mTransitionController;
    private final Transaction mPendingTransaction;
    final SurfaceControl.Transaction mSyncTransaction;
    protected final SurfaceAnimator mSurfaceAnimator;
    final SurfaceFreezer mSurfaceFreezer;
    WindowContainer(WindowManagerService wms) {
        mWmService = wms;
        mTransitionController = mWmService.mAtmService.getTransitionController();
        mPendingTransaction = wms.mTransactionFactory.get();
        mSyncTransaction = wms.mTransactionFactory.get();
        mSurfaceAnimator = new SurfaceAnimator(this, this::onAnimationFinished, wms);
        mSurfaceFreezer = new SurfaceFreezer(this, wms);
    }
}
SurfaceControl.Builder build

调用构造器(SurfaceControl.Builder)的build方法构造SurfaceControl对象:

待更新

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值