WMSHELL 架构阐明

打印 上一主题 下一主题

主题 951|帖子 951|积分 2853

在Android12之后,体系的ui 处理不断的外放到应用上,自己不再参与ui方面的显示,好比转场动效,decorview, startwindow; 而whshell是运行于systemui 下的一个独立的部分。wmshell下存放了所有task的巨细,负责多窗交互,悬浮窗管理等。是一个重要的窗口管理中心。我们做多窗开发要纯熟把握wmshell的具体架构及交互方式,这样才气够举行具体的需求实现。
下面plantuml脚本在可通过安装markdown插件直接查看
Shell与 core 交互架构

  1. @startuml
  2. skinparam groupInheritance 4
  3. package window {
  4. interface aidl.IWindowOrganizerController {
  5. applyTransaction(wct);
  6. startNewTransition(type, wct);
  7. startTransition()
  8. }
  9. WindowOrganizer <|-- TaskOrganizer
  10. WindowOrganizer<|--TaskFragmentOrganizer
  11. WindowOrganizer <|- DisplayAreaOrganizer
  12. WindowOrganizer  -> IWindowOrganizerController : startNewTransition
  13. class DisplayAreaOrganizer {
  14. <有四个子类:
  15. RootDisplayAreaOrganizer
  16. HideDisplayCutoutOrganizer
  17. RootTaskDisplayAreaOrganizer
  18. OneHandedDisplayAreaOrganizer
  19. >
  20. }
  21. class TaskFragmentOrganizer{
  22. <子类:androidx.JetpackTaskFragmentOrganizer>
  23. }
  24. interface aidl.ITransitionPlayer
  25. interface aidl.ITaskOrganizer
  26. }
  27. window.TaskOrganizer<|-down- wmshell.ShellTaskOrganizer
  28. ITransitionPlayer "Stub"<|... wmshell.TransitionPlayerImpl :onTransitionReady
  29. wmshell.Transitions -up-> WindowOrganizer: startNewTransition(type, wct);
  30. class  wmshell.ShellTaskOrganizer{
  31. }
  32. ITaskOrganizer "Stub"<|...TaskOrganizer:addStartingWindow(windowInfo)
  33. package core {
  34. IWindowOrganizerController "Stub"<|...WindowOrganizerController:startNewTransition
  35. WindowOrganizerController-> ITransitionPlayer
  36. WindowOrganizerController-> ITaskOrganizer
  37. }
  38. @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

  1. @startuml
  2. package wmshell {
  3. interface ShellCommandHandler.ShellCommandActionHandler {
  4. onShellCommand(String[] args, PrintWriter pw);
  5. printShellCommandHelp(PrintWriter pw, String prefix);
  6. }
  7. ShellCommandHandler.ShellCommandActionHandler <|.. Transitions
  8. class Transitions {
  9. ShellExecutor mMainExecutor, mAnimExecutor; 用于添加装饰器,执行过度动效等
  10. onTransitionReady(iBinder, transitionInfo, t, finishT));  响应core 的调用
  11. }
  12. Transitions --> WindowOrganizer
  13. class WindowOrganizer
  14. ITransitionPlayer.Stub <|--  TransitionPlayerImpl
  15. class TransitionPlayerImpl {
  16. onTransitionReady(iBinder, transitionInfo, t, finishT));
  17. requestStartTransition(iBinder, request)
  18. }
  19. Transitions "1"-->"*"TransitionHandler: processReadyQueue
  20. interface TransitionHandler {
  21. <<原生下有handler22个实现,对应各种不同场景>>
  22. startAnimation(active.mToken, active.mInfo,active.mStartT, active.mFinishT, (wct, cb) -> onFinish(active, wct, cb));
  23. mergeAnimation(ready.mToken, ready.mInfo, ready.mStartT,
  24. handleRequest(transition, request);
  25. onTransitionConsumed(merged.mToken, false /* abort */, merged.mFinishT);
  26. }
  27. TransitionPlayerImpl->Transitions : onTransitionReady
  28. Transitions -->TransitionObserver: onTransitionReady
  29. TransitionObserver <|.. FreeformTaskTransitionObserver
  30. TransitionHandler <|.. FreeformTaskTransitionHandler
  31.   TransitionHandler<|.. DesktopModeController
  32.   class DesktopModeController{
  33.   <<此即所谓的自由窗模式,桌面模式>>
  34.   }
  35. class FreeformTaskTransitionHandler {
  36. <<悬浮窗相关hanlder:最大化,最小化>>
  37. WindowDecorViewModel mWindowDecorViewModel;
  38. List<IBinder> mPendingTransitionTokens
  39. startAnimation(....) :主要处理悬浮窗变化及关闭
  40. }
  41. interface TransitionObserver{
  42. <<目前只有悬浮窗实现这个,你可以增加监听者,来监听窗口变化>>
  43. onTransitionReady(active.mToken, info, active.mStartT, active.mFinishT);
  44. onTransitionStarting(active.mToken);
  45. onTransitionMerged(merged.mToken, playing.mToken);
  46. onTransitionFinished(@NonNull IBinder transition, boolean aborted);
  47. }
  48. TaskOperations --> FreeformTaskTransitionStarter:minimizeTask->startMinimizedModeTransition(wct)
  49. FreeformTaskTransitionStarter<|.. FreeformTaskTransitionHandler
  50. ShellTaskOrganizer --> TaskListener
  51.   TaskListener<|.. FreeformTaskListener
  52.   TaskListener<|.. StageCoordinator:分屏管理类
  53. FreeformTaskListener --> WindowDecorViewModel :onTaskOpening(shell不作用动效时)
  54.   FreeformTaskListener --> DesktopModeTaskRepository:addOrMoveFreeformTaskToTop(桌面模式)  
  55.   StageCoordinator-->ShellTaskOrganizer:applyTransaction(wct)
  56.   TransitionHandler<|.. StageCoordinator
  57. @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

  1. @startuml
  2. package wmshell {
  3. interface WindowDecorViewModel {
  4. <<定义窗口 decorview 各种方法,有2个子类>>
  5. onTaskOpening(taskInfo, leash, t, t);
  6. onTaskInfoChanged(taskInfo);
  7. onTaskChanging(change.getTaskInfo(), change.getLeash(), startT, finishT);
  8. onTransitionReady(transition, info, change);
  9. onTransitionMerged(merged, playing);
  10. onTransitionFinished(transition);
  11. }
  12. class WindowDecoration{
  13. <<窗口装饰条基类,涉及到窗口的ui>>
  14. }
  15. WindowDecoration<|--CaptionWindowDecoration
  16. WindowDecoration<|-- DesktopModeWindowDecoration
  17. class DesktopModeWindowDecoration {
  18. <<桌面模式场景>>
  19. }
  20. class CaptionWindowDecorViewModel {
  21. <<悬浮窗装饰条处理类,装饰条可以改变窗口大小位置等属性>>
  22. SparseArray<CaptionWindowDecoration> mWindowDecorByTaskId;存放所有task装饰条
  23. }
  24. CaptionWindowDecorViewModel -->TaskOperations : onClick
  25. CaptionWindowDecorViewModel *- CaptionWindowDecoration
  26. ShellTaskOrganizer->TaskListener:onTaskAppeared
  27. TaskListener <|..FreeformTaskListener
  28. TaskListener <|..FullscreenTaskListener
  29. WindowDecorViewModel<|.. CaptionWindowDecorViewModel
  30. WindowDecorViewModel<|.. DesktopModeWindowDecorViewModel
  31. FreeformTaskListener-->WindowDecorViewModel:onTaskInfoChanged
  32. FullscreenTaskListener-->WindowDecorViewModel:onTaskInfoChanged
  33. Transitions -->TransitionObserver
  34. TransitionObserver <|..FreeformTaskTransitionObserver
  35. FreeformTaskTransitionObserver ->WindowDecorViewModel:onTaskChanging
  36. CaptionWindowDecorViewModel -> TaskOperations:closeTask\n minimizeTask \n maximizeTask
  37. DesktopModeWindowDecorViewModel  --> DesktopModeController: setDesktopModeActive \n moveTaskToFront 等
  38. DesktopModeWindowDecorViewModel  --> DesktopTasksController:  moveToDesktop(mTaskId) \n moveToFullscreen \n moveToNextDisplay等
  39. DesktopModeWindowDecorViewModel  *- DesktopModeWindowDecoration
  40. DesktopModeWindowDecorViewModel  --> SplitScreenController: moveTaskToFullscreen
  41. }
  42. @enduml
复制代码
当task显示, 隐藏或bounds发生改变时,都会涉及到decorview操作,如果走的是shell 动效机制,那会走onTransitionReady -》onToFrontTransitionReady -》onTaskChanging来执行decorview 等的创建,如果不走shell动效机制,则由ShellTaskOrganizer nTaskAppeared -》 onTaskOpening来执行decorview 等的创建。
DesktopModeWindowDecorViewModel 和 CaptionWindowDecorViewModel 分别是两种模式下的悬浮窗管理类
core 下 onTransitionReady 架构

  1. @startuml
  2. package core {
  3. abstract class Transition {
  4. }
  5. class ActivityTaskManagerService {
  6. <<Q 引入的一个新功能,用来管理Activity的启动、调度等功能,其先于AMS启动>>
  7. WindowManagerService mWindowManager; 存放+操作
  8. RootWindowContainer mRootWindowContainer;
  9. WindowOrganizerController mWindowOrganizerController;存放
  10. TaskOrganizerController mTaskOrganizerController; 存放,
  11. }
  12. ActivityTaskManagerService  -->RootWindowContainer: ensureActivitiesVisible 等各种操作
  13. ActivityTaskManagerService  ->WindowManagerService : computeNewConfiguration 等
  14. interface TransactionReadyListener {
  15. onTransactionReady(SyncId, transaction);
  16. }
  17. class WindowManagerService {
  18. BLASTSyncEngine mSyncEngine; 存放
  19. RootWindowContainer mRoot; // 各种get
  20. WindowState mWindowMap, mInputToWindowMap, mResizingWindows, mDestroySurface
  21. }
  22. WindowManagerService ->RootWindowContainer :getDisplayContent等
  23. class RootWindowContainer {
  24. <<窗口树的根窗口,窗口的改变都会对窗口树进行修改>>
  25. }
  26. class Transition
  27. TransactionReadyListener <|..Transition
  28. Transition -->BLASTSyncEngine:addToSyncSet  \n setReady(mSyncId, ready)
  29. WindowOrganizerController -->BLASTSyncEngine: addToSyncSet\n startSyncSet \n prepareSyncSet
  30. RootWindowContainer -->Transition: playNow
  31. BLASTSyncEngine-->SyncGroup:tryFinish->finishNow
  32. SyncGroup -left-> TransactionReadyListener: finishNow->onTransactionReady(mSyncId, merged)
  33. class TransitionController  {
  34. <<主要提供requestStartTransition 方法,供其他模块调用>>
  35. }
  36. TransitionController -->WindowOrganizerController:requestStartTransition->startTransition
  37. TransitionController ->Transition : collect
  38. RootWindowContainer -up->TaskOrganizerController :dispatchPendingEvents
  39. WindowAnimator -->TaskOrganizerController :dispatchPendingEvents
  40. }
  41. namespace aidl {
  42. interface IWindowOrganizerController{
  43. <<shell 端通过此接口启动窗口打开事务,WCT 中存放了窗口事务的pendintent>>
  44. applyTransaction(WCT t);
  45. startNewTransition(type,wct t);
  46. startTransition(transitionToken,wct t);
  47. finishTransition(transitionToken,wct t, callback);
  48. registerTransitionPlayer(in ITransitionPlayer player);
  49. }
  50. interface ITransitionPlayer
  51. interface ITaskOrganizerController
  52. interface ITaskOrganizer
  53. IWindowOrganizerController -- ITransitionPlayer:register
  54. ITaskOrganizerController --ITaskOrganizer:regitster
  55. }
  56. ITaskOrganizerController "Stub"<|..TaskOrganizerController
  57. IWindowOrganizerController "Stub"<|..WindowOrganizerController
  58. WindowOrganizerController -up->ITransitionPlayer:requestStartTransition
  59. ITransitionPlayer--> wmshell.Transitions:requestStartTransition \n onTransactionReady
  60. TaskOrganizerController --> ITaskOrganizer: onTaskAppeared
  61. wmshell.Transitions-down->IWindowOrganizerController : registerTransitionPlayer
  62. ITaskOrganizer <|.. wmshell.ShellTaskOrganizer:onTaskAppeared
  63. @enduml
  64. @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企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

千千梦丶琪

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表