aosp15 shelltransition之桌面点击启动app部分-systemserver部分

背景:

本节课开始带大家来开始分析ShellTransition的最开始的WMCore端启动Transition部分的相关的内容及源码剖析。
在这里插入图片描述

源码分析部分:

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

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        int startFlags, ActivityOptions options, Task inTask,
        TaskFragment inTaskFragment,
        BalVerdict balVerdict,
        NeededUriGrants intentGrants, int realCallingUid) {
   

    // Create a transition now to record the original intent of actions taken within
    // startActivityInner. Otherwise, logic in startActivityInner could start a different
    // transition based on a sub-action.
    // Only do the create here (and defer requestStart) since startActivityInner might abort.
    final TransitionController transitionController = r.mTransitionController;
    //创建对应的Transition
    Transition newTransition = transitionController.isShellTransitionsEnabled()
            ? transitionController.createAndStartCollecting(TRANSIT_OPEN) : null;
    RemoteTransition remoteTransition = r.takeRemoteTransition();

        mService.deferWindowLayout();
        
    //把ActivityRecord进行collect收集处理
        transitionController.collect(r);
        try {
            Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
            result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, options, inTask, inTaskFragment, balVerdict,
                    intentGrants, realCallingUid);
        } catch (Exception ex) {
            Slog.e(TAG, "Exception on startActivityInner", ex);
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
            
    //handleStartResult中会对transition进行requestStartTransition处理
            startedActivityRootTask = handleStartResult(r, options, result, newTransition,
                    remoteTransition);
}

上面startActivityUnchecked中主要有3个部分和transition相关步骤

1、创建并启动收集对应的Transition

Transition newTransition = transitionController.isShellTransitionsEnabled()
            ? transitionController.createAndStartCollecting(TRANSIT_OPEN) : null;

这里transitionController.createAndStartCollecting(TRANSIT_OPEN)就是创建出对应的Transition

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

Transition createAndStartCollecting(int type) {
 //构建Transition
    Transition transit = new Transition(type, 0 /* flags */, this, mSyncEngine);
 //调用moveToCollecting
    moveToCollecting(transit);
    return transit;
}
  /** Starts Collecting */
   void moveToCollecting(@NonNull Transition transition) {
      
       mCollectingTransition = transition;
	//实际调用了Transition的startCollecting
       mCollectingTransition.startCollecting(timeoutMs);
    
   }

核心重点就是startCollecting方法
frameworks/base/services/core/java/com/android/server/wm/Transition.java

    /** Starts collecting phase. Once this starts, all relevant surface operations are sync. */
    void startCollecting(long timeoutMs) {
      
        //设置状态为COLLECTING
        mState = STATE_COLLECTING;
        //调用mSyncEngine方法获取mSyncId
        mSyncId = mSyncEngine.startSyncSet(this, timeoutMs,
                TAG + "-" + transitTypeToString(mType),
                mParallelCollectType != PARALLEL_TYPE_NONE);
        mSyncEngine.setSyncMethod(mSyncId, TransitionController.SYNC_METHOD);
    }

这里主要看看mSyncEngine.startSyncSet方法
frameworks/base/services/core/java/com/android/server/wm/BLASTSyncEngine.java

   int startSyncSet(TransactionReadyListener listener, long timeoutMs, String name,
            boolean parallel) {
        final SyncGroup s = prepareSyncSet(listener, name);
        startSyncSet(s, timeoutMs, parallel);
        return s.mSyncId;
    }
      /**
     * Prepares a {@link SyncGroup} that is not active yet. Caller must call {@link #startSyncSet}
     * before calling {@link #addToSyncSet(int, WindowContainer)} on any {@link WindowContainer}.
     */
    SyncGroup prepareSyncSet(TransactionReadyListener listener, String name) {
        return new SyncGroup(listener, mNextSyncId++, name);
    }
    
   void startSyncSet(SyncGroup s, long timeoutMs, boolean parallel) {
    	//新建的SyncGroup放入到mActiveSyncs
        mActiveSyncs.add(s);
        // For now, parallel implies this.
        s.mIgnoreIndirectMembers = parallel;
        scheduleTimeout(s, timeoutMs);
    }

总结一下transitionController.createAndStartCollecting干的事情
1、创建出systemserver层面的一个Transition
2、调用Transition的startCollecting设置Transition的mState为STATE_COLLECTING
3、调用BLASTSyncEngine创建一个SyncGroup,每个SyncGroup有一个固定的SyncId
4、把创建的SyncGroup放入到BLASTSyncEngine的mActiveSyncs集合中

2、正式收集collect对应WindowContainer

上面第一步只是处于收集中的一种状态,并不是真正收集,在第二步就是正式开始收集各个WindowContainer
transitionController.collect®方法进行剖析
frameworks/base/services/core/java/com/android/server/wm/TransitionController.java

/** @see Transition#collect */
void collect(@NonNull WindowContainer wc) {
    if (mCollectingTransition == null) return;
    //mCollectingTransition就是第一步new的Transition
    mCollectingTransition.collect(wc);
}

这里实际调用到了Transition的collect

/**
     * Adds wc to set of WindowContainers participating in this transition.
     */
    void collect(@NonNull WindowContainer wc) {
      //这里判断一定要属于Collecting状态
        if (!isCollecting()) {
            // Too late, transition already started playing, so don't collect.
            return;
        }
        if (!isInTransientHide(wc)) {
        //调用addToSyncSet把wc放入到SyncEngine中
            mSyncEngine.addToSyncSet(mSyncId, wc);
        }
      
        ChangeInfo info = mChanges.get(wc);
        if (info == null) {
        //针对wc构造对应的ChangeInfo
            info = new ChangeInfo(wc);
            updateTransientFlags(info);
            //加入到mChanges集合中
            mChanges.put(wc, info);
        }
        //把wc加入到Transition的mParticipants集合中
        mParticipants.add(wc);
        recordDisplay(wc.getDisplayContent());
        if (info.mShowWallpaper) {
            // Collect the wallpaper token (for isWallpaper(wc)) so it is part of the sync set.
            wc.mDisplayContent.mWallpaperController.collectTopWallpapers(this);
        }
    }
		boolean isCollecting() {
        return mState == STATE_COLLECTING || mState == STATE_STARTED;
    }

collect里面主要有3个部分,addToSyncSet添加wc,通过wc构造ChangeInfo,mParticipants集合添加wc。
这里重点来看看addToSyncSet方法
frameworks/base/services/core/java/com/android/server/wm/BLASTSyncEngine.java

   void addToSyncSet(int id, WindowContainer wc) {
        getSyncGroup(id).addToSync(wc);
    }

private void addToSync(WindowContainer wc) {
            if (mRootMembers.contains(wc)) {
                return;
            }
            final SyncGroup dependency = wc.getSyncGroup();
            if (dependency != null && dependency != this && !dependency.isIgnoring(wc)) {
              
            } else {
                mRootMembers.add(wc);//添加到mRootMembers的集合中
                wc.setSyncGroup(this);//让WindowContainer与SyncGroup产生链接
            }
            wc.prepareSync();//调用WindowContainer的prepareSync方法
        }

addToSyncSet主要就是
1、添加到mRootMembers的集合中
2、让WindowContainer与SyncGroup产生链接
3、调用WindowContainer的prepareSync方法
下面继续看看prepareSync方法
frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java

    boolean prepareSync() {
        if (mSyncState != SYNC_STATE_NONE) {
            // Already part of sync
            return false;
        }
        //这里会遍历WindowContainer的所有child,然后让child也进行prepareSync
        for (int i = getChildCount() - 1; i >= 0; --i) {
            final WindowContainer child = getChildAt(i);
            child.prepareSync();
        }
        //核心就是把WindowContainer的mSyncState设置成了SYNC_STATE_READY状态
        mSyncState = SYNC_STATE_READY;
        return true;
    }

可以看出WindowContainer的prepareSync主要就是对mSyncState变量变成SYNC_STATE_READY。

3、requestStartTransition剖析

 /** Asks the transition player (shell) to start a created but not yet started transition. */
    @NonNull
    Transition requestStartTransition(@NonNull Transition transition, @Nullable Task startTask,
            @Nullable RemoteTransition remoteTransition,
            @Nullable TransitionRequestInfo.DisplayChange displayChange) {
       //省略部分
			//构造出对应TransitionRequestInfo
            final TransitionRequestInfo request = new TransitionRequestInfo(transition.mType,
                    startTaskInfo, pipTaskInfo, remoteTransition, displayChange,
                    transition.getFlags(), transition.getSyncId());
					//跨进程通讯通知到systemui端
            mTransitionPlayers.getLast().mPlayer.requestStartTransition(
                    transition.getToken(), request);
                    //这里把remoteTransition设置给transition
            if (remoteTransition != null) {
                transition.setRemoteAnimationApp(remoteTransition.getAppThread());
            }

        return transition;
    }

这个requestStartTransition执行后,就会跨进程通讯到wmshell端,即就是systemui进程,接下来就是要systemui进程来负责相关的Transition的业务。

更多framework实战干货,请关注下面“千里马学框架”

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里马学框架

帮助你了,就请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值