在Android12之后,体系的ui 处理不断的外放到应用上,自己不再参与ui方面的显示,好比转场动效,decorview, startwindow; 而whshell是运行于systemui 下的一个独立的部分。wmshell下存放了所有task的巨细,负责多窗交互,悬浮窗管理等。是一个重要的窗口管理中心。我们做多窗开发要纯熟把握wmshell的具体架构及交互方式,这样才气够举行具体的需求实现。
下面plantuml脚本在可通过安装markdown插件直接查看
Shell与 core 交互架构
- @startuml
- skinparam groupInheritance 4
- package window {
- interface aidl.IWindowOrganizerController {
- applyTransaction(wct);
- startNewTransition(type, wct);
- startTransition()
- }
- WindowOrganizer <|-- TaskOrganizer
- WindowOrganizer<|--TaskFragmentOrganizer
- WindowOrganizer <|- DisplayAreaOrganizer
- WindowOrganizer -> IWindowOrganizerController : startNewTransition
- class DisplayAreaOrganizer {
- <有四个子类:
- RootDisplayAreaOrganizer
- HideDisplayCutoutOrganizer
- RootTaskDisplayAreaOrganizer
- OneHandedDisplayAreaOrganizer
- >
- }
- class TaskFragmentOrganizer{
- <子类:androidx.JetpackTaskFragmentOrganizer>
- }
- interface aidl.ITransitionPlayer
- interface aidl.ITaskOrganizer
- }
- window.TaskOrganizer<|-down- wmshell.ShellTaskOrganizer
- ITransitionPlayer "Stub"<|... wmshell.TransitionPlayerImpl :onTransitionReady
- wmshell.Transitions -up-> WindowOrganizer: startNewTransition(type, wct);
- class wmshell.ShellTaskOrganizer{
- }
- ITaskOrganizer "Stub"<|...TaskOrganizer:addStartingWindow(windowInfo)
- package core {
- IWindowOrganizerController "Stub"<|...WindowOrganizerController:startNewTransition
- WindowOrganizerController-> ITransitionPlayer
- WindowOrganizerController-> ITaskOrganizer
- }
- @enduml
复制代码 对于shell开发,暂时只关注ShellTaskOrganizer,
Transitions 调用 mOrganizer.startNewTransition 发起一个事务,
WindowOrganizer 调用 IWindowOrganizerController aidl 接口调用到core
WindowOrganizerController 是体系服务的一个重要类,实现来自shell 侧的窗口调用
TransitionPlayerImpl 是Transitions 的内部类,用于在实现 core 到shell 这边的调用,当窗口事务准备好了后,就会通过onTransitionReady 让wmshell 这边举行转场动效处理。
当 task 事务发生时,core 会把一些转场事务交由shell处理,好比启动事startwindow的创建, task appeared, task vanished。
Shell xxxHandler
- @startuml
- package wmshell {
- interface ShellCommandHandler.ShellCommandActionHandler {
- onShellCommand(String[] args, PrintWriter pw);
- printShellCommandHelp(PrintWriter pw, String prefix);
- }
- ShellCommandHandler.ShellCommandActionHandler <|.. Transitions
- class Transitions {
- ShellExecutor mMainExecutor, mAnimExecutor; 用于添加装饰器,执行过度动效等
- onTransitionReady(iBinder, transitionInfo, t, finishT)); 响应core 的调用
- }
- Transitions --> WindowOrganizer
- class WindowOrganizer
- ITransitionPlayer.Stub <|-- TransitionPlayerImpl
- class TransitionPlayerImpl {
- onTransitionReady(iBinder, transitionInfo, t, finishT));
- requestStartTransition(iBinder, request)
- }
- Transitions "1"-->"*"TransitionHandler: processReadyQueue
- interface TransitionHandler {
- <<原生下有handler22个实现,对应各种不同场景>>
- startAnimation(active.mToken, active.mInfo,active.mStartT, active.mFinishT, (wct, cb) -> onFinish(active, wct, cb));
- mergeAnimation(ready.mToken, ready.mInfo, ready.mStartT,
- handleRequest(transition, request);
- onTransitionConsumed(merged.mToken, false /* abort */, merged.mFinishT);
- }
- TransitionPlayerImpl->Transitions : onTransitionReady
- Transitions -->TransitionObserver: onTransitionReady
- TransitionObserver <|.. FreeformTaskTransitionObserver
- TransitionHandler <|.. FreeformTaskTransitionHandler
- TransitionHandler<|.. DesktopModeController
- class DesktopModeController{
- <<此即所谓的自由窗模式,桌面模式>>
- }
- class FreeformTaskTransitionHandler {
- <<悬浮窗相关hanlder:最大化,最小化>>
- WindowDecorViewModel mWindowDecorViewModel;
- List<IBinder> mPendingTransitionTokens
- startAnimation(....) :主要处理悬浮窗变化及关闭
- }
- interface TransitionObserver{
- <<目前只有悬浮窗实现这个,你可以增加监听者,来监听窗口变化>>
- onTransitionReady(active.mToken, info, active.mStartT, active.mFinishT);
- onTransitionStarting(active.mToken);
- onTransitionMerged(merged.mToken, playing.mToken);
- onTransitionFinished(@NonNull IBinder transition, boolean aborted);
- }
- TaskOperations --> FreeformTaskTransitionStarter:minimizeTask->startMinimizedModeTransition(wct)
- FreeformTaskTransitionStarter<|.. FreeformTaskTransitionHandler
- ShellTaskOrganizer --> TaskListener
- TaskListener<|.. FreeformTaskListener
- TaskListener<|.. StageCoordinator:分屏管理类
- FreeformTaskListener --> WindowDecorViewModel :onTaskOpening(shell不作用动效时)
- FreeformTaskListener --> DesktopModeTaskRepository:addOrMoveFreeformTaskToTop(桌面模式)
- StageCoordinator-->ShellTaskOrganizer:applyTransaction(wct)
- TransitionHandler<|.. StageCoordinator
- @enduml
复制代码 TransitionHandler 是 Transitions 下定义的接口,当Transitions 收到onTransitionReady 时,解析将要处理的事务,会调用对应的handler 举行处理,startAnimation 用于举行各个场景下转场动效的处理。
好比FreeformTaskTransitionHandler 会处理悬浮窗的最大化变化,最小化变化,关闭变化(通常最大化和最小化都是由wmshell 响应的点击变乱,也就是由它发起悬浮窗 transition, 所以它会保存一个mPendingTransitionTokens, 所以如果token 没有保存,它也不会执行相干动效)
通常,shell 会负责一些应用启动,则它会实现现些TransitionHandler 来实现相应的启动效,设置task的scale 和位置。
startwindow 创建,桌面模式decorview 创建,全局拖拽分屏的分隔线创建,等等
ShellTaskOrganizer也会收到来自core的调用,它也有自己的调用接口: FreeformTaskListener, 有些类即实现了FreeformTaskListener,又实现了TransitionHandler, 它们同时接收两边的回调。
在分屏执行分屏动效时,StageCoordinator 会调用ShellTaskOrganizer 的applyTransaction 来实现一些task操作。
如果走的是shell 动效机制,那会走onTransitionReady -》onToFrontTransitionReady -》onTaskChanging来执行decorview 等的创建,如果不走shell动效机制,则由ShellTaskOrganizer onTaskAppeared -》 onTaskOpening来执行decorview 等的创建。
Shell DecorView
- @startuml
- package wmshell {
- interface WindowDecorViewModel {
- <<定义窗口 decorview 各种方法,有2个子类>>
- onTaskOpening(taskInfo, leash, t, t);
- onTaskInfoChanged(taskInfo);
- onTaskChanging(change.getTaskInfo(), change.getLeash(), startT, finishT);
- onTransitionReady(transition, info, change);
- onTransitionMerged(merged, playing);
- onTransitionFinished(transition);
- }
- class WindowDecoration{
- <<窗口装饰条基类,涉及到窗口的ui>>
- }
- WindowDecoration<|--CaptionWindowDecoration
- WindowDecoration<|-- DesktopModeWindowDecoration
- class DesktopModeWindowDecoration {
- <<桌面模式场景>>
- }
- class CaptionWindowDecorViewModel {
- <<悬浮窗装饰条处理类,装饰条可以改变窗口大小位置等属性>>
- SparseArray<CaptionWindowDecoration> mWindowDecorByTaskId;存放所有task装饰条
- }
- CaptionWindowDecorViewModel -->TaskOperations : onClick
- CaptionWindowDecorViewModel *- CaptionWindowDecoration
- ShellTaskOrganizer->TaskListener:onTaskAppeared
- TaskListener <|..FreeformTaskListener
- TaskListener <|..FullscreenTaskListener
- WindowDecorViewModel<|.. CaptionWindowDecorViewModel
- WindowDecorViewModel<|.. DesktopModeWindowDecorViewModel
- FreeformTaskListener-->WindowDecorViewModel:onTaskInfoChanged
- FullscreenTaskListener-->WindowDecorViewModel:onTaskInfoChanged
- Transitions -->TransitionObserver
- TransitionObserver <|..FreeformTaskTransitionObserver
- FreeformTaskTransitionObserver ->WindowDecorViewModel:onTaskChanging
- CaptionWindowDecorViewModel -> TaskOperations:closeTask\n minimizeTask \n maximizeTask
- DesktopModeWindowDecorViewModel --> DesktopModeController: setDesktopModeActive \n moveTaskToFront 等
- DesktopModeWindowDecorViewModel --> DesktopTasksController: moveToDesktop(mTaskId) \n moveToFullscreen \n moveToNextDisplay等
- DesktopModeWindowDecorViewModel *- DesktopModeWindowDecoration
- DesktopModeWindowDecorViewModel --> SplitScreenController: moveTaskToFullscreen
- }
- @enduml
复制代码 当task显示, 隐藏或bounds发生改变时,都会涉及到decorview操作,如果走的是shell 动效机制,那会走onTransitionReady -》onToFrontTransitionReady -》onTaskChanging来执行decorview 等的创建,如果不走shell动效机制,则由ShellTaskOrganizer nTaskAppeared -》 onTaskOpening来执行decorview 等的创建。
DesktopModeWindowDecorViewModel 和 CaptionWindowDecorViewModel 分别是两种模式下的悬浮窗管理类
core 下 onTransitionReady 架构
- @startuml
- package core {
- abstract class Transition {
- }
- class ActivityTaskManagerService {
- <<Q 引入的一个新功能,用来管理Activity的启动、调度等功能,其先于AMS启动>>
- WindowManagerService mWindowManager; 存放+操作
- RootWindowContainer mRootWindowContainer;
- WindowOrganizerController mWindowOrganizerController;存放
- TaskOrganizerController mTaskOrganizerController; 存放,
- }
- ActivityTaskManagerService -->RootWindowContainer: ensureActivitiesVisible 等各种操作
- ActivityTaskManagerService ->WindowManagerService : computeNewConfiguration 等
- interface TransactionReadyListener {
- onTransactionReady(SyncId, transaction);
- }
- class WindowManagerService {
- BLASTSyncEngine mSyncEngine; 存放
- RootWindowContainer mRoot; // 各种get
- WindowState mWindowMap, mInputToWindowMap, mResizingWindows, mDestroySurface
- }
- WindowManagerService ->RootWindowContainer :getDisplayContent等
- class RootWindowContainer {
- <<窗口树的根窗口,窗口的改变都会对窗口树进行修改>>
- }
- class Transition
- TransactionReadyListener <|..Transition
- Transition -->BLASTSyncEngine:addToSyncSet \n setReady(mSyncId, ready)
- WindowOrganizerController -->BLASTSyncEngine: addToSyncSet\n startSyncSet \n prepareSyncSet
- RootWindowContainer -->Transition: playNow
- BLASTSyncEngine-->SyncGroup:tryFinish->finishNow
- SyncGroup -left-> TransactionReadyListener: finishNow->onTransactionReady(mSyncId, merged)
- class TransitionController {
- <<主要提供requestStartTransition 方法,供其他模块调用>>
- }
- TransitionController -->WindowOrganizerController:requestStartTransition->startTransition
- TransitionController ->Transition : collect
- RootWindowContainer -up->TaskOrganizerController :dispatchPendingEvents
- WindowAnimator -->TaskOrganizerController :dispatchPendingEvents
- }
- namespace aidl {
- interface IWindowOrganizerController{
- <<shell 端通过此接口启动窗口打开事务,WCT 中存放了窗口事务的pendintent>>
- applyTransaction(WCT t);
- startNewTransition(type,wct t);
- startTransition(transitionToken,wct t);
- finishTransition(transitionToken,wct t, callback);
- registerTransitionPlayer(in ITransitionPlayer player);
- }
- interface ITransitionPlayer
- interface ITaskOrganizerController
- interface ITaskOrganizer
- IWindowOrganizerController -- ITransitionPlayer:register
- ITaskOrganizerController --ITaskOrganizer:regitster
- }
- ITaskOrganizerController "Stub"<|..TaskOrganizerController
- IWindowOrganizerController "Stub"<|..WindowOrganizerController
- WindowOrganizerController -up->ITransitionPlayer:requestStartTransition
- ITransitionPlayer--> wmshell.Transitions:requestStartTransition \n onTransactionReady
- TaskOrganizerController --> ITaskOrganizer: onTaskAppeared
- wmshell.Transitions-down->IWindowOrganizerController : registerTransitionPlayer
- ITaskOrganizer <|.. wmshell.ShellTaskOrganizer:onTaskAppeared
- @enduml
- @enduml
复制代码 如图所示,当window中要起来一个task,或者其他改变时,都会触发WMS举行重新布局,然后调用TransitionController 举行requestStartTransition,TransitionController 生成 TransitionRequestInfo 和Transition,然后调用 ITransitionPlayer举行requestStartTransition,然后由wmshell举行处理。然后窗口树举行刷新,创建子节点,Transition对相干的task举行网络,在完成网络(窗口树完成)后,会调用 ITransitionPlayer 举行onTransitionReady,然后由wmshell举行处理。
如果当前是在灭屏状态,requestStartTransition 和 onTransitionReady 是挨着调用的,具体可以看RootWindowContainer#applySleepTokens
WindowOrganizerController 会调用BLASTSyncEngine 举行各种同步,Transition通过syncId关联BLASTSyncEngine,当 Transition完成时,会调用setReady, BLASTSyncEngine 会调用Transition 下的onTransactionReady
wmshell下,Transitions 创建之后, 会拿到WindowOrganizer,把mPlayerImpl 注册到core,这样就可以实现core到wmshell的调用. 而ShellTaskOrganizer创建完后,会拿到ITaskOrganizerController , 把自己注册到core, 也可以实现core到wmshell的调用。除此之外,还有一些厂家,会在这里面添加各种core到wmshell的接口。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |