WMS系列:层级树的surface 的创建

WMS 创建的surface 与 surfaceflinger 创建的Layer 是一一对应的,只不过可能是创建不同的 Layer

在这里插入图片描述

 

1. DefaultTaskDisplayArea 对应的surface 的创建

DefaultTaskDisplayArea 的调用栈如下,是在系统进程启动服务的时候,去创建对应的SurfaceControl。

I test1   : android.view.SurfaceControl$Builder@c7e3d28setName DefaultTaskDisplayArea
I test1   : java.lang.Exception
at android.view.SurfaceControl$Builder.setName(SurfaceControl.java:1249)
at com.android.server.wm.DisplayContent.makeChildSurface(DisplayContent.java:5036)
at com.android.server.wm.WindowContainer.makeChildSurface(WindowContainer.java:2419)
at com.android.server.wm.WindowContainer.makeChildSurface(WindowContainer.java:2419)
at com.android.server.wm.WindowContainer.makeChildSurface(WindowContainer.java:2419)
at com.android.server.wm.WindowContainer.makeChildSurface(WindowContainer.java:2419)
at com.android.server.wm.WindowContainer.makeSurface(WindowContainer.java:2408)
at com.android.server.wm.WindowContainer.createSurfaceControl(WindowContainer.java:613)
at com.android.server.wm.WindowContainer.onParentChanged(WindowContainer.java:594)
at com.android.server.wm.TaskDisplayArea.onParentChanged(TaskDisplayArea.java:818)
at com.android.server.wm.WindowContainer.setParent(WindowContainer.java:571)
at com.android.server.wm.WindowContainer.addChild(WindowContainer.java:745)
at com.android.server.wm.DisplayAreaPolicyBuilder$PendingArea.instantiateChildren(DisplayAreaPolicyBuilder.java:922)
at com.android.server.wm.DisplayAreaPolicyBuilder$PendingArea.instantiateChildren(DisplayAreaPolicyBuilder.java:926)
at com.android.server.wm.DisplayAreaPolicyBuilder$PendingArea.instantiateChildren(DisplayAreaPolicyBuilder.java:926)
at com.android.server.wm.DisplayAreaPolicyBuilder$PendingArea.instantiateChildren(DisplayAreaPolicyBuilder.java:926)
at com.android.server.wm.DisplayAreaPolicyBuilder$PendingArea.instantiateChildren(DisplayAreaPolicyBuilder.java:926)
at com.android.server.wm.DisplayAreaPolicyBuilder$HierarchyBuilder.build(DisplayAreaPolicyBuilder.java:588)
at com.android.server.wm.DisplayAreaPolicyBuilder$HierarchyBuilder.-$$Nest$mbuild(Unknown Source:0)
at com.android.server.wm.DisplayAreaPolicyBuilder.build(DisplayAreaPolicyBuilder.java:333)
at com.android.server.wm.DisplayAreaPolicy$DefaultProvider.instantiate(DisplayAreaPolicy.java:117)
at com.android.server.wm.DisplayContent.configureSurfaces(DisplayContent.java:1143)
at com.android.server.wm.DisplayContent.<init>(DisplayContent.java:1093)
at com.android.server.wm.RootWindowContainer.setWindowManager(RootWindowContainer.java:1313)
at com.android.server.wm.ActivityTaskManagerService.setWindowManager(ActivityTaskManagerService.java:1006)
at com.android.server.am.ActivityManagerService.setWindowManager(ActivityManagerService.java:1923)
at com.android.server.SystemServer.startOtherServices(SystemServer.java:1595)
at com.android.server.SystemServer.run(SystemServer.java:939)
at com.android.server.SystemServer.main(SystemServer.java:649)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:914)

 从 .wm.DisplayAreaPolicy$DefaultProvider.instantiate 开始追踪调用栈:

/frameworks/base/services/core/java/com/android/server/wm/DisplayAreaPolicy.java

    static final class DefaultProvider implements DisplayAreaPolicy.Provider {@Overridepublic DisplayAreaPolicy instantiate(WindowManagerService wmService,DisplayContent content, RootDisplayArea root,DisplayArea.Tokens imeContainer) {。。。。// Instantiate the policy with the hierarchy defined above. This will create and attach// all the necessary DisplayAreas to the root.// 这里去创建节点树return new DisplayAreaPolicyBuilder().setRootHierarchy(rootHierarchy).build(wmService);}

/frameworks/base/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java

    Result build(WindowManagerService wmService) {validate();// Attach DA group roots to screen hierarchy before adding windows to group hierarchies.// mRootHierarchyBuilder 为 HierarchyBuilder 对象,去创建buildmRootHierarchyBuilder.build(mDisplayAreaGroupHierarchyBuilders);

// mRootHierarchyBuilder 为 HierarchyBuilder 对象,去创建build

    static class HierarchyBuilder {private static final int LEAF_TYPE_TASK_CONTAINERS = 1;private static final int LEAF_TYPE_IME_CONTAINERS = 2;private static final int LEAF_TYPE_TOKENS = 0;。。。private void build(@Nullable List<HierarchyBuilder> displayAreaGroupHierarchyBuilders) {final WindowManagerPolicy policy = mRoot.mWmService.mPolicy;final int maxWindowLayerCount = policy.getMaxWindowLayer() + 1;final DisplayArea.Tokens[] displayAreaForLayer =new DisplayArea.Tokens[maxWindowLayerCount];。。。PendingArea[] areaForLayer = new PendingArea[maxWindowLayerCount];final PendingArea root = new PendingArea(null, 0, null);Arrays.fill(areaForLayer, root);。。。。。// root 的值是 PendingArea,调用instantiateChildren,mRoot 是DisplayContentroot.instantiateChildren(mRoot, displayAreaForLayer, 0, featureAreas);mRoot.onHierarchyBuilt(mFeatures, displayAreaForLayer, featureAreas);}

// root 的值是 PendingArea,调用instantiateChildren,mRoot 是DisplayContent

调用的是根节点:new PendingArea(null, 0, null),在 build( 的时候,设置了对应的孩子节点

    static class PendingArea {final int mMinLayer;final ArrayList<PendingArea> mChildren = new ArrayList<>();final Feature mFeature;final PendingArea mParent;int mMaxLayer;。。。void instantiateChildren(DisplayArea<DisplayArea> parent, DisplayArea.Tokens[] areaForLayer,int level, Map<Feature, List<DisplayArea<WindowContainer>>> areas) {// 对孩子节点进行排序。依据 mMinLayer 最小的layer 值进行排序。由创建的层级树知道,孩子节点有 3 个mChildren.sort(Comparator.comparingInt(pendingArea -> pendingArea.mMinLayer));// 遍历 3 个节点for (int i = 0; i < mChildren.size(); i++) {final PendingArea child = mChildren.get(i);// 1)先以 parent 为 DisplayContent 作为父亲节点。调用方法 createArea
// areaForLayer 的值是:new DisplayArea.Tokens[maxWindowLayerCount],创建 36层的数组final DisplayArea area = child.createArea(parent, areaForLayer);if (area == null) {// TaskDisplayArea and ImeContainer
设置了 mSkipTokens 为 true,这里的返回值为 null// TaskDisplayArea and ImeContainer can be set at different hierarchy, so it can// be null.continue;}// 2)建立父子关系parent.addChild(area, WindowContainer.POSITION_TOP);if (child.mFeature != null) {// 递归保存所有features 的 DisplayArea 。对应是保存在 featureAreasareas.get(child.mFeature).add(area);}// 3)child 孩子节点递归调用,area 新创建的为父亲节点child.instantiateChildren(area, areaForLayer, level + 1, areas);}}

// 1)先以 parent 为 DisplayContent 作为父亲节点。areaForLayer 的值是:new DisplayArea.Tokens[maxWindowLayerCount],创建 36层的数组。

DisplayContent 下面有 3 个孩子节点,调用孩子节点的方法 createArea

 private NewDisplayAreaSupplier mNewDisplayAreaSupplier = DisplayArea::new;@Nullableprivate DisplayArea createArea(DisplayArea<DisplayArea> parent,DisplayArea.Tokens[] areaForLayer) {// mExisting 存在的是app layer 的 TaskDisplayAreaif (mExisting != null) {// TaskDisplayArea 的 asTokens( 返回值为空if (mExisting.asTokens() != null) {// Store the WindowToken container for layersfillAreaForLayers(mExisting.asTokens(), areaForLayer);}// 所以这里直接返回 TaskDisplayArea return mExisting;}if (mSkipTokens) {return null;}// 设置对应的 DisplayArea 的 类型DisplayArea.Type type;if (mMinLayer > APPLICATION_LAYER) {type = DisplayArea.Type.ABOVE_TASKS;} else if (mMaxLayer < APPLICATION_LAYER) {type = DisplayArea.Type.BELOW_TASKS;} else {type = DisplayArea.Type.ANY;}// 如果 mFeature == null 则表示是叶子节点,创建叶子节点if (mFeature == null) {// 在dump 中会打印:Leaf:32:32 对应的值,所以叶子节点的对象是:DisplayArea.Tokensfinal DisplayArea.Tokens leaf = new DisplayArea.Tokens(parent.mWmService, type,"Leaf:" + mMinLayer + ":" + mMaxLayer);fillAreaForLayers(leaf, areaForLayer);return leaf;// 如果有featurs ,则创建 DisplayArea 对象,
// dump 的值为:创建 DisplayArea 对象,WindowedMagnification:0:31} else {return mFeature.mNewDisplayAreaSupplier.create(parent.mWmService, type,mFeature.mName + ":" + mMinLayer + ":" + mMaxLayer, mFeature.mId);}}

因为是创建app 应用的defaulttast,所以 createArea  先创建 DisplayArea 对象,WindowedMagnification:0:31

// 2)建立父子关系
                parent.addChild(area, WindowContainer.POSITION_TOP)

parent 为 DisplayContent,are 为创建的 DisplayArea 对象,WindowedMagnification:0:31,设置父子关系。

// 3)child 孩子节点递归调用,area 新创建的为父亲节点

child 是对象 PendingArea, area 此时也是对应的 DisplayArea 对象,为:WindowedMagnification:0:31,child 也是:WindowedMagnification:0:31

由调用栈可以知道,调用了 5 次 instantiateChildren 方法,即走了下列 5 次,递归调用孩子节点:

 

走到最后一次 的 instantiateChildren 方法时,会调用 createArea ,这里返回 TaskDisplayArea 对象,其名字为:defaultTaskDisplayArea。mExisting 存在的是app layer 的 TaskDisplayArea

然后往下走:parent 为对象 上一个 createArea 创建的 DisplayArea,area 为:TaskDisplayArea

parent.addChild(area, WindowContainer.POSITION_TOP)

调用父类 WindowContainer 的方法:

/frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java

    /** Adds the input window container has a child of this container at the input index. */@CallSupervoid addChild(E child, int index) {// 如果孩子节点有父亲的话,则报错if (!child.mReparenting && child.getParent() != null) {throw new IllegalArgumentException("addChild: container=" + child.getName()+ " is already a child of container=" + child.getParent().getName()+ " can't add to container=" + getName()+ "\n callers=" + Debug.getCallers(15, "\n"));}if ((index < 0 && index != POSITION_BOTTOM)|| (index > mChildren.size() && index != POSITION_TOP)) {throw new IllegalArgumentException("addChild: invalid position=" + index+ ", children number=" + mChildren.size());}// 为最顶层的 POSITION_TOP,为最大值if (index == POSITION_TOP) {// 获取孩子节点的最大值index = mChildren.size();} else if (index == POSITION_BOTTOM) {index = 0;}// 将其保存到数组中的最后mChildren.add(index, child);// Set the parent after we've actually added a child in case a subclass depends on this.// 调用 TaskDisplayArea 设置父亲节点为DisplayArea:setParentchild.setParent(this);}

// 调用 TaskDisplayArea 设置父亲节点为DisplayArea:setParent

    final protected void setParent(WindowContainer<WindowContainer> parent) {final WindowContainer oldParent = mParent;
// 缓存当前的节点mParent = parent;if (mParent != null) {
// 通知到父亲节点孩子增加了 mParent.onChildAdded(this);}if (!mReparenting) {onSyncReparent(oldParent, mParent);if (mParent != null && mParent.mDisplayContent != null&& mDisplayContent != mParent.mDisplayContent) {onDisplayChanged(mParent.mDisplayContent);}
// 调用父亲节点变化函数onParentChanged(mParent, oldParent);}}=============void onParentChanged(ConfigurationContainer newParent, ConfigurationContainer oldParent) {onParentChanged(newParent, oldParent, null);}void onParentChanged(ConfigurationContainer newParent, ConfigurationContainer oldParent,PreAssignChildLayersCallback callback) {super.onParentChanged(newParent, oldParent);if (mParent == null) {return;}// mSurfaceControl  为空,这里去创建 surfacecontrolif (mSurfaceControl == null) {// If we don't yet have a surface, but we now have a parent, we should// build a surface.
// 1)创建 surfacecontrol:createSurfaceControlcreateSurfaceControl(false /*force*/);} else {
。。。。
// callback 为空if (callback != null) {callback.onPreAssignChildLayers();}// 分配孩子节点 z-order 的大小// Either way we need to ask the parent to assign us a Z-order.mParent.assignChildLayers();scheduleAnimation();}

// 1)创建 surfacecontrol:createSurfaceControl

    void createSurfaceControl(boolean force) {// 1-1)调用 makeSurface 创建 surfacecontrolsetInitialSurfaceControlProperties(makeSurface());}======
// 1-2)然后调用 setInitialSurfaceControlProperties 方法void setInitialSurfaceControlProperties(SurfaceControl.Builder b) {setSurfaceControl(b.setCallsite("WindowContainer.setInitialSurfaceControlProperties").build());if (showSurfaceOnCreation()) {getSyncTransaction().show(mSurfaceControl);}onSurfaceShown(getSyncTransaction());updateSurfacePositionNonOrganized();}

// 调用 makeSurface 创建 surfacecontrol

    SurfaceControl.Builder makeSurface() {final WindowContainer p = getParent();
// 调用父亲节点去创建surface,为创建的 DisplayAreareturn p.makeChildSurface(this);}=========SurfaceControl.Builder makeChildSurface(WindowContainer child) {
// 再次获取DisplayArea 的父亲节点final WindowContainer p = getParent();return p.makeChildSurface(child).setParent(mSurfaceControl);}

 同样的,makeChildSurface 方法也是调用了 5 次,第1次时调用父亲DisplayArea ,即0:12节点的 makeChildSurface 方法,然后继续往上回调到 DisplayContent ,依次设置setparent 的 surfacecontrol 

 /frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java

    @OverrideSurfaceControl.Builder makeChildSurface(WindowContainer child) {
// 从孩子获取到session,该接口调用父亲节点获取session,所以最后获取的时DC 的SurfaceSession s = child != null ? child.getSession() : getSession();// 通过wms 去创建surfacecontrol,并设置是 ContainerLayer
// 创建 SurfaceControl.Builderfinal SurfaceControl.Builder b = mWmService.makeSurfaceBuilder(s).setContainerLayer();if (child == null) {return b;}// 设置名字,并设置为当前的 mSurfaceControl,这里可以忽略,在递归的时候会重新设置return b.setName(child.getName()).setParent(mSurfaceControl);}========@OverrideSurfaceSession getSession() {return mSession;}

// 1-2)然后调用 setInitialSurfaceControlProperties 方法

    void setInitialSurfaceControlProperties(SurfaceControl.Builder b) {//   调用 build 方法,创建 surfacecontrol 对象  
// setSurfaceControl 方法去缓存 mSurfaceControl    setSurfaceControl(b.setCallsite("WindowContainer.setInitialSurfaceControlProperties").build());
// showSurfaceOnCreation 默认是true 的if (showSurfaceOnCreation()) {
// Transaction 去显示 SurfaceControlgetSyncTransaction().show(mSurfaceControl);}onSurfaceShown(getSyncTransaction());updateSurfacePositionNonOrganized();}========
// 缓存 mSurfaceControl   void setSurfaceControl(SurfaceControl sc) {mSurfaceControl = sc;}

1. 非孩子节点创建的对象是 DisplayArea

2. 孩子节点创建的对象是 DisplayArea.Tokens 或者是 TaskDisplayArea,创建的Layer 是ContainerLayer

3. 只能在孩子节点下继续挂载 windowstate 显示对应的bufferLayer

setparent(SurfaceControl) 对surfacecontrol 设置父亲节点,同步设置到 surfaceflinger 的Layer 中

/frameworks/base/core/java/android/view/SurfaceControl.java

  // Build 先设置parent 的值@NonNullpublic Builder setParent(@Nullable SurfaceControl parent) {mParent = parent;return this;}============
// 调用 Build 函数创建 SurfaceControl 对象@NonNullpublic SurfaceControl build() {if (mWidth < 0 || mHeight < 0) {throw new IllegalStateException("width and height must be positive or unset");}if ((mWidth > 0 || mHeight > 0) && (isEffectLayer() || isContainerLayer())) {throw new IllegalStateException("Only buffer layers can set a valid buffer size.");}if ((mFlags & FX_SURFACE_MASK) == FX_SURFACE_NORMAL) {setBLASTLayer();}// 这里传入了 mParent 对象return new SurfaceControl(mSession, mName, mWidth, mHeight, mFormat, mFlags, mParent, mMetadata,mLocalOwnerView, mCallsite);}

SurfaceControl 的构造方法:

    private SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags,SurfaceControl parent, SparseIntArray metadata, WeakReference<View> localOwnerView,mName = name;mWidth = w;mHeight = h;mLocalOwnerView = localOwnerView;Parcel metaParcel = Parcel.obtain();try {if (metadata != null && metadata.size() > 0) {metaParcel.writeInt(metadata.size());for (int i = 0; i < metadata.size(); ++i) {metaParcel.writeInt(metadata.keyAt(i));metaParcel.writeByteArray(ByteBuffer.allocate(4).order(ByteOrder.nativeOrder()).putInt(metadata.valueAt(i)).array());}metaParcel.setDataPosition(0);}// 通过native 层去创建底层的 SurfaceControl
// 这里参数转换为 父亲的对象 parent.mNativeObjectmNativeObject = nativeCreate(session, name, w, h, format, flags,parent != null ? parent.mNativeObject : 0, metaParcel);} finally {metaParcel.recycle();}if (mNativeObject == 0) {throw new OutOfResourcesException("Couldn't allocate SurfaceControl native object");}mNativeHandle = nativeGetHandle(mNativeObject);mCloseGuard.openWithCallSite("release", callsite);}

// 通过native 层去创建底层的 SurfaceControl

/frameworks/base/core/jni/android_view_SurfaceControl.cpp

static jlong nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj,jstring nameStr, jint w, jint h, jint format, jint flags, jlong parentObject,jobject metadataParcel) {ScopedUtfChars name(env, nameStr);sp<SurfaceComposerClient> client;if (sessionObj != NULL) {client = android_view_SurfaceSession_getClient(env, sessionObj);} else {client = SurfaceComposerClient::getDefault();}SurfaceControl *parent = reinterpret_cast<SurfaceControl*>(parentObject);sp<SurfaceControl> surface;LayerMetadata metadata;Parcel* parcel = parcelForJavaObject(env, metadataParcel);if (parcel && !parcel->objectsCount()) {status_t err = metadata.readFromParcel(parcel);if (err != NO_ERROR) {jniThrowException(env, "java/lang/IllegalArgumentException","Metadata parcel has wrong format");}}sp<IBinder> parentHandle;// parent  不是空的,这里获取到父亲的 Handleif (parent != nullptr) {parentHandle = parent->getHandle();}// 调用 SurfaceComposerClient 去创建surface:createSurfaceCheckedstatus_t err = client->createSurfaceChecked(String8(name.c_str()), w, h, format, &surface,flags, parentHandle, std::move(metadata));if (err == NAME_NOT_FOUND) {jniThrowException(env, "java/lang/IllegalArgumentException", NULL);return 0;} else if (err != NO_ERROR) {jniThrowException(env, OutOfResourcesException, NULL);return 0;}surface->incStrong((void *)nativeCreate);return reinterpret_cast<jlong>(surface.get());
}

// 调用 SurfaceComposerClient 去创建surface:createSurfaceChecked

/frameworks/native/libs/gui/SurfaceComposerClient.cpp

status_t SurfaceComposerClient::createSurfaceChecked(const String8& name, uint32_t w, uint32_t h,PixelFormat format,sp<SurfaceControl>* outSurface, uint32_t flags,const sp<IBinder>& parentHandle,LayerMetadata metadata,uint32_t* outTransformHint) {sp<SurfaceControl> sur;status_t err = mStatus;if (mStatus == NO_ERROR) {sp<IBinder> handle;sp<IGraphicBufferProducer> gbp;uint32_t transformHint = 0;int32_t id = -1;// client 是binder 通信与 sf 通信的客户端:createSurface
// 通过sf 服务器端获取到 handleerr = mClient->createSurface(name, w, h, format, flags, parentHandle, std::move(metadata),&handle, &gbp, &id, &transformHint);if (outTransformHint) {*outTransformHint = transformHint;}ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));if (err == NO_ERROR) {// 这里去创建 SurfaceControl 对象*outSurface =new SurfaceControl(this, handle, gbp, id, w, h, format, transformHint, flags);}}return err;
}=======
// client 是binder 通信与 sf 通信的客户端
void SurfaceComposerClient::onFirstRef() {sp<ISurfaceComposer> sf(ComposerService::getComposerService());if (sf != nullptr && mStatus == NO_INIT) {sp<ISurfaceComposerClient> conn;conn = sf->createConnection();if (conn != nullptr) {mClient = conn;

// client 是binder 通信与 sf 通信的客户端:createSurface

/frameworks/native/services/surfaceflinger/Client.cpp

status_t Client::createSurface(const String8& name, uint32_t w, uint32_t h, PixelFormat format,uint32_t flags, const sp<IBinder>& parentHandle,LayerMetadata metadata, sp<IBinder>* handle,sp<IGraphicBufferProducer>* gbp, int32_t* outLayerId,uint32_t* outTransformHint) {// We rely on createLayer to check permissions.return mFlinger->createLayer(name, this, w, h, format, flags, std::move(metadata), handle, gbp,parentHandle, outLayerId, nullptr, outTransformHint);

/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp


status_t SurfaceFlinger::createLayer(const String8& name, const sp<Client>& client, uint32_t w,uint32_t h, PixelFormat format, uint32_t flags,LayerMetadata metadata, sp<IBinder>* handle,sp<IGraphicBufferProducer>* gbp,const sp<IBinder>& parentHandle, int32_t* outLayerId,// parentLayer 传入的值是空的const sp<Layer>& parentLayer, uint32_t* outTransformHint) {if (int32_t(w|h) < 0) {。。。switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {case ISurfaceComposerClient::eFXSurfaceBufferQueue:case ISurfaceComposerClient::eFXSurfaceBufferState: {result = createBufferStateLayer(client, std::move(uniqueName), w, h, flags,std::move(metadata), handle, &layer);std::atomic<int32_t>* pendingBufferCounter = layer->getPendingBufferCounter();if (pendingBufferCounter) {std::string counterName = layer->getPendingBufferCounterName();mBufferCountTracker.add((*handle)->localBinder(), counterName,pendingBufferCounter);}} break;// 这次是创建ContainerLayercase ISurfaceComposerClient::eFXSurfaceContainer:// check if buffer size is set for container layer.if (w > 0 || h > 0) {ALOGE("createLayer() failed, w or h cannot be set for container layer (w=%d, h=%d)",int(w), int(h));return BAD_VALUE;}result = createContainerLayer(client, std::move(uniqueName), w, h, flags,std::move(metadata), handle, &layer);break;
。。。
// 这里去增加layerresult = addClientLayer(client, *handle, *gbp, layer, parentHandle, parentLayer, addToRoot,outTransformHint);
// 设置layer 的状态是创建的composerState.state.what = layer_state_t::eLayerCreated;
status_t SurfaceFlinger::addClientLayer(const sp<Client>& client, const sp<IBinder>& handle,const sp<IGraphicBufferProducer>& gbc, const sp<Layer>& lbc,const sp<IBinder>& parentHandle,const sp<Layer>& parentLayer, bool addToRoot,uint32_t* outTransformHint) {if (mNumLayers >= ISurfaceComposer::MAX_LAYERS) {ALOGE("AddClientLayer failed, mNumLayers (%zu) >= MAX_LAYERS (%zu)", mNumLayers.load(),ISurfaceComposer::MAX_LAYERS);return NO_MEMORY;}wp<IBinder> initialProducer;if (gbc != nullptr) {initialProducer = IInterface::asBinder(gbc);}setLayerCreatedState(handle, lbc, parentHandle, parentLayer, initialProducer, addToRoot);=========
void SurfaceFlinger::setLayerCreatedState(const sp<IBinder>& handle, const wp<Layer>& layer,const wp<IBinder>& parent, const wp<Layer> parentLayer,const wp<IBinder>& producer, bool addToRoot) {Mutex::Autolock lock(mCreatedLayersLock);// 去保存layer 创建的状态 LayerCreatedState,设置了 initialParent 的值为 parentmCreatedLayers[handle->localBinder()] =std::make_unique<LayerCreatedState>(layer, parent, parentLayer, producer, addToRoot);

在 Layer 创建后会申请 Vsync,走到 handleLayerCreatedLocked 方法

sp<Layer> SurfaceFlinger::handleLayerCreatedLocked(const sp<IBinder>& handle) {const auto& state = getLayerCreatedState(handle);if (!state) {return nullptr;}
。。。sp<Layer> layer = state->layer.promote();if (!layer) {ALOGE("Invalid layer %p", state->layer.unsafe_get());return nullptr;}sp<Layer> parent;bool allowAddRoot = state->addToRoot;// 如上设置了 initialParent if (state->initialParent != nullptr) {// 这里去通过 handle 去获取到 父亲节点的 Layerparent = fromHandleLocked(state->initialParent.promote()).promote();if (parent == nullptr) {ALOGE("Invalid parent %p", state->initialParent.unsafe_get());allowAddRoot = false;}} else if (state->initialParentLayer != nullptr) {parent = state->initialParentLayer.promote();allowAddRoot = false;}if (parent == nullptr && allowAddRoot) {layer->setIsAtRoot(true);mCurrentState.layersSortedByZ.add(layer);} else if (parent == nullptr) {layer->onRemovedFromCurrentState();} else if (parent->isRemovedFromCurrentState()) {parent->addChild(layer);layer->onRemovedFromCurrentState();} else {// 父亲的Layer 去增加孩子节点parent->addChild(layer);}

// 父亲的Layer 去增加孩子节点

/frameworks/native/services/surfaceflinger/Layer.cpp


void Layer::addChild(const sp<Layer>& layer) {mFlinger->mSomeChildrenChanged = true;setTransactionFlags(eTransactionNeeded);
// 保存到 mCurrentChildren 数组中mCurrentChildren.add(layer);// 孩子Layer 节点设置当前对象为父亲节点,两者建立联系layer->setParent(this);layer->setGameModeForTree(mGameMode);updateTreeHasFrameRateVote();
}

参考:

android 13 WMS/AMS系统开发-窗口层级相关SurfaceFlinger图层创建 第三节_千里马学框架的博客-CSDN博客

2. Task 的创建与 建立DefaultTaskDisplayArea 的父子关系

setting 的task 节点的挂载调用栈

: DefaultTaskDisplayArea@243571827 addChild child = Task{4fbc455 #7 type=standard ?? U=0 visible=false visibleRequested=false mode=undefined translucent=true sz=0}
: java.lang.Exception
:     at com.android.server.wm.WindowContainer.addChild(WindowContainer.java:727)
:     at com.android.server.wm.TaskDisplayArea.addChildTask(TaskDisplayArea.java:334)
:     at com.android.server.wm.TaskDisplayArea.addChild(TaskDisplayArea.java:320)
:     at com.android.server.wm.Task$Builder.build(Task.java:6551)
:     at com.android.server.wm.TaskDisplayArea.getOrCreateRootTask(TaskDisplayArea.java:1005)
:     at com.android.server.wm.TaskDisplayArea.getOrCreateRootTask(TaskDisplayArea.java:1030)
:     at com.android.server.wm.RootWindowContainer.getOrCreateRootTask(RootWindowContainer.java:2838)
:     at com.android.server.wm.ActivityStarter.getOrCreateRootTask(ActivityStarter.java:3017)
:     at com.android.server.wm.ActivityStarter.startActivityInner(ActivityStarter.java:1858)
:     at com.android.server.wm.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1661)
:     at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:1216)
:     at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:702)
:     at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1240)
:     at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1203)
:     at com.android.server.wm.ActivityTaskManagerService.startActivity(ActivityTaskManagerService.java:1178)
:     at android.app.IActivityTaskManager$Stub.onTransact(IActivityTaskManager.java:893)
:     at com.android.server.wm.ActivityTaskManagerService.onTransact(ActivityTaskManagerService.java:5183)
:     at android.os.Binder.execTransactInternal(Binder.java:1280)
:     at android.os.Binder.execTransact(Binder.java:1244)

binder 通信:从 wm.ActivityTaskManagerService.startActivity 开始分析:

/frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java

1143      @Override
1144      public final int startActivity(IApplicationThread caller, String callingPackage,
1145              String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
1146              String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
1147              Bundle bOptions) {
1148          return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
1149                  resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
1150                  UserHandle.getCallingUserId());
1151      }==========
1168      @Override
1169      public int startActivityAsUser(IApplicationThread caller, String callingPackage,
1170              String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
1171              String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
1172              Bundle bOptions, int userId) {
1173          return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
1174                  resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
1175                  true /*validateIncomingUser*/);
1176      }
1177  
1178      private int startActivityAsUser(IApplicationThread caller, String callingPackage,
1179              @Nullable String callingFeatureId, Intent intent, String resolvedType,
1180              IBinder resultTo, String resultWho, int requestCode, int startFlags,
1181              ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
1182          assertPackageMatchesCallingUid(callingPackage);
1183          enforceNotIsolatedCaller("startActivityAsUser");
1184  
1185          userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
1186                  Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
1187  // getActivityStartController 为 ActivityStartController 对象: obtainStarter
1188          // TODO: Switch to user app stacks here.
1189          return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
1190                  .setCaller(caller)
1191                  .setCallingPackage(callingPackage)
1192                  .setCallingFeatureId(callingFeatureId)
1193                  .setResolvedType(resolvedType)
1194                  .setResultTo(resultTo)
1195                  .setResultWho(resultWho)
1196                  .setRequestCode(requestCode)
1197                  .setStartFlags(startFlags)
1198                  .setProfilerInfo(profilerInfo)
1199                  .setActivityOptions(bOptions)
1200                  .setUserId(userId)
1201                  .execute();
1202  

看下 ActivityStartController 对象: obtainStarter 方法

/frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java

53  import com.android.server.wm.ActivityStarter.DefaultFactory;98      ActivityStartController(ActivityTaskManagerService service) {
99          this(service, service.mTaskSupervisor,// 这里创建了 DefaultFactory,为 ActivityStarter 的内部类
100                  new DefaultFactory(service, service.mTaskSupervisor,
101                      new ActivityStartInterceptor(service, service.mTaskSupervisor)));
102      }
103  
104      @VisibleForTesting
105      ActivityStartController(ActivityTaskManagerService service, ActivityTaskSupervisor supervisor,
106              Factory factory) {
107          mService = service;
108          mSupervisor = supervisor;
109          mFactory = factory;
110          mFactory.setController(this);
111          mPendingRemoteAnimationRegistry = new PendingRemoteAnimationRegistry(service.mGlobalLock,
112                  service.mH);
113      }==========
120      ActivityStarter obtainStarter(Intent intent, String reason) {
121          return mFactory.obtain().setIntent(intent).setReason(reason);
122      }

 /frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java

obatain 方法返回了 ActivityStarter 对象

252      static class DefaultFactory implements Factory {
253          /**281          @Override
282          public ActivityStarter obtain() {
283              ActivityStarter starter = mStarterPool.acquire();
284  
285              if (starter == null) {
286                  if (mService.mRootWindowContainer == null) {
287                      throw new IllegalStateException("Too early to start activity.");
288                  }
289                  starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor);
290              }
291  
292              return starter;
293          }

设置了一些参数,然后执行 execute( 方法

2779      ActivityStarter setIntent(Intent intent) {
// 设置的参数都保存到了 mRequest 中
2780          mRequest.intent = intent;
2781          return this;
2782      }============
611      int execute() {
612          try {
613              // Refuse possible leaked file descriptors
614              if (mRequest.intent != null && mRequest.intent.hasFileDescriptors()) {
615                  throw new IllegalArgumentException("File descriptors passed in Intent");
616              }...
648              int res;
649              synchronized (mService.mGlobalLock) {
650                  final boolean globalConfigWillChange = mRequest.globalConfig != null
651                          && mService.getGlobalConfiguration().diff(mRequest.globalConfig) != 0;
652                  final Task rootTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
653                  if (rootTask != null) {
654                      rootTask.mConfigWillChange = globalConfigWillChange;
655                  }
656                  ProtoLog.v(WM_DEBUG_CONFIGURATION, "Starting activity when config "
657                          + "will change = %b", globalConfigWillChange);
658  
659                  final long origId = Binder.clearCallingIdentity();
660  
661                  res = resolveToHeavyWeightSwitcherIfNeeded();
662                  if (res != START_SUCCESS) {
663                      return res;
664                  }// 执行请求的函数
665                  res = executeRequest(mRequest);
811      private int executeRequest(Request request) {
812          if (TextUtils.isEmpty(request.reason)) {
813              throw new IllegalArgumentException("Need to specify a reason.");
814          }
。。。。。。。。
// 这里执行创建了 ActivityRecord 对象
1137          final ActivityRecord r = new ActivityRecord.Builder(mService)
1138                  .setCaller(callerApp)
1139                  .setLaunchedFromPid(callingPid)
1140                  .setLaunchedFromUid(callingUid)
1141                  .setLaunchedFromPackage(callingPackage)
1142                  .setLaunchedFromFeature(callingFeatureId)
1143                  .setIntent(intent)
1144                  .setResolvedType(resolvedType)
1145                  .setActivityInfo(aInfo)
1146                  .setConfiguration(mService.getGlobalConfiguration())
1147                  .setResultTo(resultRecord)
1148                  .setResultWho(resultWho)
1149                  .setRequestCode(requestCode)
1150                  .setComponentSpecified(request.componentSpecified)
1151                  .setRootVoiceInteraction(voiceSession != null)
1152                  .setActivityOptions(checkedOptions)
1153                  .setSourceRecord(sourceRecord)
1154                  .build();
1155  
1156          mLastStartActivityRecord = r;。。。。
// 然后执行 startActivityUnchecked
1177          mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
1178                  request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
1179                  restrictedBgActivity, intentGrants);================
1548      private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
1549                  IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1550                  int startFlags, boolean doResume, ActivityOptions options, Task inTask,
1551                  boolean restrictedBgActivity, NeededUriGrants intentGrants) {
1552          int result = START_CANCELED;
1553          final Task startedActivityRootTask;。。
1567          try {
1568              mService.deferWindowLayout();
1569              Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");// 然后执行 startActivityInner 方法
1570              result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
1571                      startFlags, doResume, options, inTask, restrictedBgActivity, intentGrants);
1572          } finally {==============
1670      @VisibleForTesting
1671      int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
1672              IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1673              int startFlags, boolean doResume, ActivityOptions options, Task inTask,
1674              boolean restrictedBgActivity, NeededUriGrants intentGrants) {
1675          setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
1676                  voiceInteractor, restrictedBgActivity);
。。。
1729          if (mTargetRootTask == null) {
// 这里去创建 root task:getLaunchRootTask
1730              mTargetRootTask = getLaunchRootTask(mStartActivity, mLaunchFlags, targetTask, mOptions);
1731          }

创建 root task:getLaunchRootTask

2753      private Task getLaunchRootTask(ActivityRecord r, int launchFlags, Task task,
2754              ActivityOptions aOptions) {
2755          // We are reusing a task, keep the root task!
2756          if (mReuseTask != null) {
2757              return mReuseTask.getRootTask();
2758          }
2759  
2760          final boolean onTop =
2761                  (aOptions == null || !aOptions.getAvoidMoveToFront()) && !mLaunchTaskBehind;// 调用 RootWindowContainer.java 的方法
2762          return mRootWindowContainer.getLaunchRootTask(r, aOptions, task, mSourceRootTask, onTop,
2763                  mLaunchParams, launchFlags, mRequest.realCallingPid, mRequest.realCallingUid);
2764      }

// 调用 RootWindowContainer.java 的方法

 /frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java

2875      Task getLaunchRootTask(@Nullable ActivityRecord r,
2876              @Nullable ActivityOptions options, @Nullable Task candidateTask,
2877              @Nullable Task sourceTask, boolean onTop,
2878              @Nullable LaunchParamsController.LaunchParams launchParams, int launchFlags,
2879              int realCallingPid, int realCallingUid) {。。。。
2932              if (canLaunchOnDisplayFromStartRequest || canLaunchOnDisplay(r, tdaDisplayId)) {
2933                  if (r != null) {
2934                      final Task result = getValidLaunchRootTaskInTaskDisplayArea(
2935                              taskDisplayArea, r, candidateTask, options, launchParams);
2936                      if (result != null) {
2937                          return result;
2938                      }
2939                  }
2940                  // Falling back to default task container
2941                  taskDisplayArea = taskDisplayArea.mDisplayContent.getDefaultTaskDisplayArea();// 调用 TaskDisplayArea的 方法 getOrCreateRootTask
2942                  rootTask = taskDisplayArea.getOrCreateRootTask(r, options, candidateTask,
2943                          sourceTask, launchParams, launchFlags, activityType, onTop);

// 调用 TaskDisplayArea的 方法 getOrCreateRootTask

/frameworks/base/services/core/java/com/android/server/wm/TaskDisplayArea.java

1141      Task getOrCreateRootTask(@Nullable ActivityRecord r, @Nullable ActivityOptions options,
1142              @Nullable Task candidateTask, @Nullable Task sourceTask,
1143              @Nullable LaunchParams launchParams, int launchFlags, int activityType, boolean onTop) {
1144          int windowingMode = WINDOWING_MODE_UNDEFINED;
1145          if (launchParams != null) {
1146              // If launchParams isn't null, windowing mode is already resolved.
1147              windowingMode = launchParams.mWindowingMode;
1148          } else if (options != null) {
1149              // If launchParams is null and options isn't let's use the windowing mode in the
1150              // options.
1151              windowingMode = options.getLaunchWindowingMode();
1152          }
1153          // Validate that our desired windowingMode will work under the current conditions.
1154          // UNDEFINED windowing mode is a valid result and means that the new root task will inherit
1155          // it's display's windowing mode.
1156          windowingMode = validateWindowingMode(windowingMode, r, candidateTask, activityType);
1157          return getOrCreateRootTask(windowingMode, activityType, onTop, candidateTask, sourceTask,
1158                  options, launchFlags);
1159      }========
1087      Task getOrCreateRootTask(int windowingMode, int activityType, boolean onTop,
1088              @Nullable Task candidateTask, @Nullable Task sourceTask,
1089              @Nullable ActivityOptions options, int launchFlags) {
。。。
// 这里去创建 Task
1124          return new Task.Builder(mAtmService)
1125                  .setWindowingMode(windowingMode)
1126                  .setActivityType(activityType)
// 设置了ontop
1127                  .setOnTop(onTop)// 这里设置父亲为:TaskDisplayArea
1128                  .setParent(this)
1129                  .setSourceTask(sourceTask)
1130                  .setActivityOptions(options)
1131                  .setLaunchFlags(launchFlags)
1132                  .build();
1133      }

/frameworks/base/services/core/java/com/android/server/wm/Task.java

8193          Task build() {
8194              if (mParent != null && mParent instanceof TaskDisplayArea) {
8195                  validateRootTask((TaskDisplayArea) mParent);
8196              }
8197  
。。。。。
// 调用 buildInner 创建 Task 对象
8215              final Task task = buildInner();
8216              task.mHasBeenVisible = mHasBeenVisible;
8217  
8218              // Set activity type before adding the root task to TaskDisplayArea, so home task can
8219              // be cached, see TaskDisplayArea#addRootTaskReferenceIfNeeded().
8220              if (mActivityType != ACTIVITY_TYPE_UNDEFINED) {
8221                  task.setActivityType(mActivityType);
8222              }
8223  // 前面有调用 setparent 为 TaskDisplayArea
8224              if (mParent != null) {
8225                  if (mParent instanceof Task) {
8226                      final Task parentTask = (Task) mParent;
8227                      parentTask.addChild(task, mOnTop ? POSITION_TOP : POSITION_BOTTOM,
8228                              (mActivityInfo.flags & FLAG_SHOW_FOR_ALL_USERS) != 0);
8229                  } else {// TaskDisplayArea 去增加孩子节点
8230                      mParent.addChild(task, mOnTop ? POSITION_TOP : POSITION_BOTTOM);
8231                  }
8232              }

// TaskDisplayArea 去增加孩子节点 addChild

/frameworks/base/services/core/java/com/android/server/wm/TaskDisplayArea.java

    @Overridevoid addChild(WindowContainer child, int position) {if (child.asTaskDisplayArea() != null) {if (DEBUG_ROOT_TASK) {Slog.d(TAG_WM, "Set TaskDisplayArea=" + child + " on taskDisplayArea=" + this);}super.addChild(child, position);// 孩子节点是 asTask} else if (child.asTask() != null) {addChildTask(child.asTask(), position);} else {throw new IllegalArgumentException("TaskDisplayArea can only add Task and TaskDisplayArea, but found "+ child);}}============private void addChildTask(Task task, int position) {if (DEBUG_ROOT_TASK) Slog.d(TAG_WM, "Set task=" + task + " on taskDisplayArea=" + this);addRootTaskReferenceIfNeeded(task);position = findPositionForRootTask(position, task, true /* adding */);// 调用父类的addChild 方法super.addChild(task, position);if (mPreferredTopFocusableRootTask != null&& task.isFocusable()&& mPreferredTopFocusableRootTask.compareTo(task) < 0) {// Clear preferred top because the adding focusable task has a higher z-order.mPreferredTopFocusableRootTask = null;}mAtmService.updateSleepIfNeededLocked();onRootTaskOrderChanged(task);}

// 调用父类的addChild 方法

/frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java

    @CallSupervoid addChild(E child, int index) {if (!child.mReparenting && child.getParent() != null) {throw new IllegalArgumentException("addChild: container=" + child.getName()+ " is already a child of container=" + child.getParent().getName()+ " can't add to container=" + getName()+ "\n callers=" + Debug.getCallers(15, "\n"));}if ((index < 0 && index != POSITION_BOTTOM)|| (index > mChildren.size() && index != POSITION_TOP)) {throw new IllegalArgumentException("addChild: invalid position=" + index+ ", children number=" + mChildren.size());}if (index == POSITION_TOP) {index = mChildren.size();} else if (index == POSITION_BOTTOM) {index = 0;}mChildren.add(index, child);// Set the parent after we've actually added a child in case a subclass depends on this.child.setParent(this);}

同样走前面的流程,走到 onParentChanged,然后去创建对应的ContainerLayer

ActivityRecord 作为叶子节点的挂载

ActivityRecord 挂载在 Task 下面 

: Task{4fbc455 #7 type=standard A=1000:com.android.settings U=0 visible=false visibleRequested=false mode=fullscreen translucent=true sz=0} addChild child = ActivityRecord{4d8c7a4 u0 com.android.settings/.sim.SimDialogActivity}
: java.lang.Exception
: 	at com.android.server.wm.WindowContainer.addChild(WindowContainer.java:727)
: 	at com.android.server.wm.TaskFragment.addChild(TaskFragment.java:1835)
: 	at com.android.server.wm.Task.addChild(Task.java:1429)
: 	at com.android.server.wm.ActivityStarter.addOrReparentStartingActivity(ActivityStarter.java:2927)
: 	at com.android.server.wm.ActivityStarter.setNewTask(ActivityStarter.java:2877)
: 	at com.android.server.wm.ActivityStarter.startActivityInner(ActivityStarter.java:1864)
: 	at com.android.server.wm.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1661)
: 	at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:1216)
: 	at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:702)
: 	at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1240)
: 	at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1203)
: 	at com.android.server.wm.ActivityTaskManagerService.startActivity(ActivityTaskManagerService.java:1178)
: 	at android.app.IActivityTaskManager$Stub.onTransact(IActivityTaskManager.java:893)
: 	at com.android.server.wm.ActivityTaskManagerService.onTransact(ActivityTaskManagerService.java:5183)
: 	at android.os.Binder.execTransactInternal(Binder.java:1280)
: 	at android.os.Binder.execTransact(Binder.java:1244)

在前面ActivityStarter 执行 getLaunchRootTask 后创建了  Task,然后往下执行  setNewTask

/frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java

1671      int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
1672              IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1673              int startFlags, boolean doResume, ActivityOptions options, Task inTask,
1674              boolean restrictedBgActivity, NeededUriGrants intentGrants) {。。。。。
1729          if (mTargetRootTask == null) {
1730              mTargetRootTask = getLaunchRootTask(mStartActivity, mLaunchFlags, targetTask, mOptions);
1731          }
1732          if (newTask) {
1733              final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
1734                      ? mSourceRecord.getTask() : null;// 这里去设置 Task
1735              setNewTask(taskToAffiliate);============
2675      private void setNewTask(Task taskToAffiliate) {
2676          final boolean toTop = !mLaunchTaskBehind && !mAvoidMoveToFront;
2677          final Task task = mTargetRootTask.reuseOrCreateTask(
2678                  mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
2679                  mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
2680                  mVoiceInteractor, toTop, mStartActivity, mSourceRecord, mOptions);
2681          mService.getTransitionController().collectExistenceChange(task);// 调用下列方法
2682          addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask");
2683  
2684          ProtoLog.v(WM_DEBUG_TASKS, "Starting new activity %s in new task %s",
2685                  mStartActivity, mStartActivity.getTask());
2686  
2687          if (taskToAffiliate != null) {
2688              mStartActivity.setTaskToAffiliateWith(taskToAffiliate);
2689          }
2690      }=========
2703      private void addOrReparentStartingActivity(Task parent, String reason) {// mStartActivity 是 ActivityRecord,这里获取到 task的值是为空的,还没有分配到 task
2704          if (mStartActivity.getTask() == null || mStartActivity.getTask() == parent) {
2705              parent.addChild(mStartActivity);
2706          } else {
2707              mStartActivity.reparent(parent, parent.getChildCount() /* top */, reason);
2708          }
2709      }

WindowState 作为叶子节点的挂载

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/29839.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Flutter:屏幕适配

flutter_screenutil flutter_screenutil是一个用于在Flutter应用程序中进行屏幕适配的工具包。它旨在帮助开发者在不同屏幕尺寸和密度的设备上创建响应式的UI布局。 flutter_screenutil提供了一些用于处理尺寸和间距的方法&#xff0c;使得开发者可以根据设备的屏幕尺寸和密度…

Segment Anything(SAM) 计算过程

给定输入图像 I ∈ R 3 H W I \in R^{3 \times H \times W} I∈R3HW。给定需要的prompts&#xff1a; M ∈ R 1 H W M \in R^{1 \times H \times W} M∈R1HW&#xff0c;代表图片的前背景信息。 P ∈ R N 2 P \in R^{N \times 2} P∈RN2&#xff0c;其中 N N N 是点的个数…

vscode 搭建STM32开发环境

1.需要软件 1.1 vscode 1.2 STM32CubeMX&#xff0c;这个不是必须的&#xff0c;我是为了方便生成STM32代码 2.vscode配置 2.1安装keil Assistant 2.2配置keil Assistant 3.STMCUBE生成个STM32代码 &#xff0c;如果有自己的代码可以忽略 4.代码添加到vscode&#xff0c;并…

模拟出栈的所有顺序(dfs+回溯)

题目&#xff1a; 已知某一个字母序列&#xff0c;把序列中的字母按出现顺序压入一个栈&#xff0c;在入栈的任意过程中&#xff0c;允许栈中的字母出栈&#xff0c;求所有可能的出栈顺序 示例&#xff1a; 输入abc 输出abc、acb、bac、bca、cba 代码如下 #define _CRT_SECURE…

JAVA集合框架 一:Collection(LIst,Set)和Iterator(迭代器)

目录 一、Java 集合框架体系 1.Collection接口&#xff1a;用于存储一个一个的数据&#xff0c;也称单列数据集合&#xff08;single&#xff09;。 2.Map接口&#xff1a;用于存储具有映射关系“key-value对”的集合&#xff08;couple&#xff09; 3.Iterator接口&#…

【ChatGPT 指令大全】怎么使用ChatGPT来辅助学习英语

在当今全球化的社会中&#xff0c;英语已成为一门世界性的语言&#xff0c;掌握良好的英语技能对个人和职业发展至关重要。而借助人工智能的力量&#xff0c;ChatGPT为学习者提供了一个有价值的工具&#xff0c;可以在学习过程中提供即时的帮助和反馈。在本文中&#xff0c;我们…

Android 视频播放器dkplayer

列表播放如图所示&#xff1a; 一、依赖 //添加RecyclerView的依赖包implementation androidx.recyclerview:recyclerview:1.2.1// 异步加载图片依赖implementation com.squareup.picasso:picasso:2.5.2// 上拉刷新、下来加载依赖implementation com.scwang.smartrefresh:Smart…

Kubernetes工作原理

一、案例概述 传统部署时代&#xff1a; 早期是在物理服务器上运行应用程序。无法为物理服务器中的应用程序定义资源边界&#xff0c;这会导致资源分配出现问题。例如&#xff1a;如果在物理服务器上运行多个应用程序&#xff0c;则可能会出现一个应用程序占用大部分资源的情况…

ffplay简介

本文为相关课程的学习记录&#xff0c;相关分析均来源于课程的讲解&#xff0c;主要学习音视频相关的操作&#xff0c;对字幕的处理不做分析 ffplay播放器的意义 ffplay.c是FFmpeg源码⾃带的播放器&#xff0c;调⽤FFmpeg和SDL API实现⼀个⾮常有⽤的播放器。 ffplay实现了播…

Spring Data学习笔记Day01-SpringData入门

Spring Data基本介绍 目录 Spring Data Redis 官方API参考手册&#xff01;★ Spring Data的价值★ Spring Data及其子项目★ 强大的Spring Data★ Repository接口★ 具体Repository接口★ Spring Data JPA开发★ Spring Boot如何选择DataSource★ 数据源相关配置★ 配置第三方…

爬虫014_文件操作_打开关闭_读写_序列化_反序列化---python工作笔记033

报错,没有指定路径,没有指定路径无法创建文件 这样可以在当前目录下创建一个可写的文件 可以看到找到刚才生成的文件,看看内容

Android进阶之SeekBar动态显示进度

SeekBar 在开发中并不陌生,默认的SeekBar是不显示进度的,当然用吐司或者文案在旁边实时显示也是可以的,那能不能移动的时候才显示&#xff0c;默认不显示呢,当然网上花哨的三方工具类太多了&#xff0c;但是我只是单纯的想在SeekBar的基础上去添加一个可以跟随移动显示的气泡而…

虹科新闻 | 虹科与Power-MI正式建立合作伙伴关系

近日&#xff0c;虹科与Power-MI正式建立合作伙伴关系&#xff0c;双方就工业预测性维护领域进行深入的交流与合作&#xff0c;未来将共同致力于为亚洲市场提供完整的、更高质量的预测性维护解决方案&#xff0c;解决亚洲客户的工业自动化挑战。 虹科与Power-MI都表示十分期待…

MySQL的查询方法

单表查询 素材&#xff1a; 表名&#xff1a;worker-- 表中字段均为中文&#xff0c;比如 部门号 工资 职工号 参加工作 要求&#xff1a; 1、显示所有职工的基本信息。 2、查询所有职工所属部门的部门号&#xff0c;不显示重复的部门号。 3、求出所有职工的人数。 4、…

【MySql】RR有幻读问题吗?MVCC能否解决幻读?

文章目录 前言RR 隔离级别MVCCRR MVCC 有幻读问题吗&#xff1f;幻读问题演示如何彻底解决幻读&#xff1f;小结 前言 幻读是 MySQL 中一个非常普遍&#xff0c;且面试中经常被问到的问题&#xff0c;如果你还搞不懂什么是幻读&#xff1f;什么是 MVCC&#xff1f;以及 MySQL…

RabbitMQ 发布确认机制

发布确认模式是避免消息由生产者到RabbitMQ消息丢失的一种手段 发布确认模式 原理说明实现方式开启confirm&#xff08;确认&#xff09;模式阻塞确认异步确认 总结 原理说明 生产者通过调用channel.confirmSelect方法将信道设置为confirm模式&#xff0c;之后RabbitMQ会返回Co…

R语言APSIM模型高级应用及批量模拟

随着数字农业和智慧农业的发展&#xff0c;基于过程的农业生产系统模型在模拟作物对气候变化的响应与适应、农田管理优化、作物品种和株型筛选、农田固碳和温室气体排放等领域扮演着越来越重要的作用。APSIM (Agricultural Production Systems sIMulator)模型是世界知名的作物生…

云服务器SVN仓库搭建(以阿里云为例)

远程连接阿里云服务器 安装svn(注意需要root权限使用命令sudo su) yum install subversion 安装成功后查看svn版本 svnserve --version 创建版本库的根目录 mkdir /var/svn 创建代码仓库 svnadmin create /var/svn/test 当前生成的目录结构 此处为svn的配置文件 创建用户名…

信创环境下 FTP如何进行国产化替代?

一、政策驱动&#xff0c;倡导自主、创新、协同 信创&#xff0c;即信息技术应用创新产业&#xff0c;其是数据安全、网络安全的基础&#xff0c;也是新基建的重要组成部分。为打破国外巨头的垄断&#xff0c;解决核心技术关键环节“卡脖子”问题&#xff0c;在核心芯片、基础…

C++项目:在线五子棋对战(网页版)

项目介绍 本项⽬主要实现⼀个⽹⻚版的五⼦棋对战游戏&#xff0c;其主要⽀持以下核⼼功能&#xff1a; • 用户管理:实现用户注册&#xff0c;用户登录、获取用户信息、用户天梯分数记录、用户比赛场次记录等。 • 匹配对战:实现两个玩家在网页端根据天梯分数匹配游戏对⼿&…