IT评测·应用市场-qidao123.com
标题:
WMSHELL 架构阐明
[打印本页]
作者:
千千梦丶琪
时间:
2025-3-6 21:36
标题:
WMSHELL 架构阐明
在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企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/)
Powered by Discuz! X3.4