文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Wms 启动流程分析和介绍

2024-12-02 18:11

关注

对于 Android 应用来说这个交互是透明的,应用感觉不到 WindowManagerService 的存在;

我们来介绍分析下窗口管理服务 WindowManagerService 的启动过程;

一、WindowManagerService的相关类

1、WindowManagerService概念

Framework层的窗口管理服务,职责是管理Android系统中所有window;窗口管理服务,继承IWindowManager.Stub,Binder服务端,因此WM与WMS的交互也是一个IPC过程。WMS主要做的事情如下:

2、WindowManager

应用与窗口管理服务WindowManagerService交互的接口

3、PhoneWindowManager

实现了窗口的各种策略,定义了窗口相关策略;

4、Choreographer

用户控制窗口动画、屏幕选择等操作,它拥有从显示子系统获取Vsync同步事件的能力,从而可以在合适的时机通知渲染动作,避免在渲染的过程中因为发生屏幕重绘而导致的画面撕裂。WMS使用Choreographer负责驱动所有的窗口动画、屏幕旋转动画、墙纸动画的渲染;

5、DisplayContent

6、WindowState

描述窗口的状态信息以及和WindowManagerService进行通信,一般一个窗口对应一个WindowState。它用来表示一个窗口的所有属性;

7、WindowToken

8、Session

App进程通过建立Session代理对象和Session对象通信,进而和WMS建立连接;

9、SurfaceFlinger

SurfaceFlinger负责管理Android系统的帧缓冲区(Frame Buffer),Android设备的显示屏被抽象为一个帧缓冲区,而Android系统中的SurfaceFlinger服务就是通过向这个帧缓冲区写入内容来绘制应用程序中的用户界面的;

10、InputManager

IMS实例。管理每个窗口的输入事件通道(InputChannel)以及向通道上派发事件

11、Animator

所有窗口动画的总管(WindowStateAnimator对象)。在Choreographer的驱动下,逐个渲染所有的动画

二、WMS启动流程

WMS的启动,依然是由SystemServer进行启动,在SystemServer的main函数中调用startOtherServices方法创建WMS;

1、SystemServer#startOtherServices

  1. private void startOtherServices() { 
  2.         ... 
  3.         try { 
  4.             ... 
  5.             // 创建WMS对象 
  6.             // 创建WMS对象需要依赖于InputManager、PhoneWindowManager、和AMS 
  7.             // IMS是用来管理每个窗口的输入事件通道以及向通道上派发事件 
  8.             // PhoneWindowManager是实现了窗口的各种策略,定义了窗口相关策略 
  9.             // 比如:告诉WMS某一个类型Window的Z-Order的值是多少,帮助WMS矫正不合理的窗口属性, 
  10.             // 为WMS监听屏幕旋转的状态,预处理一些系统按键事件(例如HOME、BACK键等的默认行为就是在这里实现的)等 
  11.             wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore, 
  12.                     new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager); 
  13.             ServiceManager.addService(Context.WINDOW_SERVICE, wm,  false
  14.                     DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO); 
  15.             ServiceManager.addService(Context.INPUT_SERVICE, inputManager, 
  16.                      false, DUMP_FLAG_PRIORITY_CRITICAL); 
  17.             traceEnd(); 
  18.             traceBeginAndSlog("SetWindowManagerService"); 
  19.             // 将AMS与WMS做绑定 
  20.             mActivityManagerService.setWindowManager(wm); 
  21.             traceEnd(); 
  22.             traceBeginAndSlog("WindowManagerServiceOnInitReady"); 
  23.             // 这里主要是调用initPolicy用来初始化PhoneWindowManager 
  24.             wm.onInitReady(); 
  25.             traceEnd(); 
  26.             ... 
  27.         } 
  28.         ... 
  29.         traceBeginAndSlog("MakeDisplayReady"); 
  30.         try { 
  31.             // 主要是初始化UI尺寸 
  32.             wm.displayReady(); 
  33.         } catch (Throwable e) { 
  34.             reportWtf("making display ready", e); 
  35.         } 
  36.         traceEnd(); 
  37.         ... 
  38.         traceBeginAndSlog("MakeWindowManagerServiceReady"); 
  39.         try { 
  40.             // 准备工作已经完成 
  41.             wm.systemReady(); 
  42.         } catch (Throwable e) { 
  43.             reportWtf("making Window Manager Service ready", e); 
  44.         } 
  45.         traceEnd(); 
  46.         ... 
  47.     } 

2、WindowManagerService#main

  1. public static WindowManagerService main(final Context context, final InputManagerService im, 
  2.             final boolean showBootMsgs, final boolean onlyCore, WindowManagerPolicy policy, 
  3.             ActivityTaskManagerService atm) { 
  4.         return main(context, im, showBootMsgs, onlyCore, policy, atm, 
  5.                 SurfaceControl.Transaction::new); 
  6.     } 
  1. @VisibleForTesting 
  2.     public static WindowManagerService main(final Context context, final InputManagerService im, 
  3.             final boolean showBootMsgs, final boolean onlyCore, WindowManagerPolicy policy, 
  4.             ActivityTaskManagerService atm, TransactionFactory transactionFactory) { 
  5.         // wms是运行在android.display线程 
  6.         DisplayThread.getHandler().runWithScissors(() -> 
  7.                 sInstance = new WindowManagerService(context, im, showBootMsgs, onlyCore, policy, 
  8.                         atm, transactionFactory), 0); 
  9.         return sInstance; 
  10.     } 

3、Handler#runWithScissors

上面的runWithScissors传入的就是一个Runnable实例,只不过是采用了lambda表达式的做法,所以Runnable的run()方法的方法体是就是:

  1. sInstance = new WindowManagerService(context, im, showBootMsgs, onlyCore, policy, 
  2. atm, transactionFactory), 0); 
  3. public final boolean runWithScissors(@NonNull Runnable r, long timeout) { 
  4.     if (r == null) { 
  5.         throw new IllegalArgumentException("runnable must not be null"); 
  6.     } 
  7.     if (timeout < 0) { 
  8.         throw new IllegalArgumentException("timeout must be non-negative"); 
  9.     } 
  10.     // 如果调用runWithScissors方法的线程是与消息处理线程在同一个线程 
  11.     // 则直接执行Runnable的run方法。 
  12.     if (Looper.myLooper() == mLooper) { 
  13.         r.run(); 
  14.         return true
  15.     } 
  16.     // 如果调用runWithScissors方法的线程与消息处理线程不是同一个,则创建一个BlockingRunnable 
  17.     BlockingRunnable br = new BlockingRunnable(r); 
  18.     return br.postAndWait(this, timeout); 

4、BlockingRunnable方法介绍

  1. private static final class BlockingRunnable implements Runnable { 
  2.     private final Runnable mTask; 
  3.     private boolean mDone; 
  4.     public BlockingRunnable(Runnable task) { 
  5.         mTask = task; 
  6.     } 
  7.     @Override 
  8.     public void run() { 
  9.         try { 
  10.             mTask.run(); 
  11.         } finally { 
  12.             synchronized (this) { 
  13.                 mDone = true
  14.                 notifyAll(); 
  15.             } 
  16.         } 
  17.     } 
  18.     public boolean postAndWait(Handler handler, long timeout) { 
  19.         // 调用postAndWait的时候,先调用handler对象的post将消息发送出 
  20.         // 如果入队成功,则为true,则开始阻塞 
  21.         if (!handler.post(this)) { 
  22.             return false
  23.         } 
  24.         // 在上面的方法调用中,timeout=0,则阻塞。 
  25.         synchronized (this) { 
  26.             if (timeout > 0) { 
  27.                 final long expirationTime = SystemClock.uptimeMillis() + timeout; 
  28.                 // 如果mDone为false的时候,则会等待,只有为true的时候,会执行 
  29.                 while (!mDone) { 
  30.                     long delay = expirationTime - SystemClock.uptimeMillis(); 
  31.                     if (delay <= 0) { 
  32.                         return false; // timeout 
  33.                     } 
  34.                     try { 
  35.                         wait(delay); 
  36.                     } catch (InterruptedException ex) { 
  37.                     } 
  38.                 } 
  39.             } else { 
  40.                 while (!mDone) { 
  41.                     try { 
  42.                         wait(); 
  43.                     } catch (InterruptedException ex) { 
  44.                     } 
  45.                 } 
  46.             } 
  47.         } 
  48.         return true
  49.     } 

5、WindowManagerService构造器

  1. private WindowManagerService(Context context, InputManagerService inputManager, 
  2.         boolean showBootMsgs, boolean onlyCore, WindowManagerPolicy policy, 
  3.         ActivityTaskManagerService atm, TransactionFactory transactionFactory) { 
  4.     installLock(this, INDEX_WINDOW); 
  5.     mGlobalLock = atm.getGlobalLock(); 
  6.     mAtmService = atm; 
  7.     mContext = context; 
  8.     mAllowBootMessages = showBootMsgs; 
  9.     mOnlyCore = onlyCore; 
  10.     // 各种变量读取 
  11.     mLimitedAlphaCompositing = context.getResources().getBoolean( 
  12.             com.android.internal.R.bool.config_sf_limitedAlpha); 
  13.     mHasPermanentDpad = context.getResources().getBoolean( 
  14.             com.android.internal.R.bool.config_hasPermanentDpad); 
  15.     mInTouchMode = context.getResources().getBoolean( 
  16.             com.android.internal.R.bool.config_defaultInTouchMode); 
  17.     ...... 
  18.     mInputManager = inputManager; 
  19.     mDisplayManagerInternal = 
  20.         LocalServices.getService(DisplayManagerInternal.class); 
  21.     // Display设置 
  22.     mDisplayWindowSettings = new DisplayWindowSettings(this); 
  23.     mTransactionFactory = transactionFactory; 
  24.     mTransaction = mTransactionFactory.make(); 
  25.     //PhoneWindowManager(继承于WindowManagerPolicy, 用来提供UI相关的一些行为) 
  26.     mPolicy = policy; 
  27.     // 在一个单独的task中执行动画和Surface操作的类 
  28.     mAnimator = new WindowAnimator(this); 
  29.     // 根Window容器 
  30.     mRoot = new RootWindowContainer(this); 
  31.     // 用来确定Window和Surface的位置 
  32.     mWindowPlacerLocked = new WindowSurfacePlacer(this); 
  33.     // 任务快照管理器(当App不可见时, 会将Task的快照以Bitmap形式存在缓存中) 
  34.     mTaskSnapshotController = new TaskSnapshotController(this); 
  35.     LocalServices.addService(WindowManagerPolicy.class, mPolicy); 
  36.     mDisplayManager =  
  37.     (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE); 
  38.     // Keyguard处理器 
  39.     mKeyguardDisableHandler = 
  40.         KeyguardDisableHandler.create(mContext, mPolicy, mH); 
  41.     // PowerManager是控制设备电池状态的管理器 
  42.     mPowerManager =  
  43.         (PowerManager)context.getSystemService(Context.POWER_SERVICE); 
  44.     // PowerManagerInternal是PowerMananger的本地服务 
  45.     mPowerManagerInternal = 
  46.         LocalServices.getService(PowerManagerInternal.class); 
  47.     if (mPowerManagerInternal != null) { 
  48.         mPowerManagerInternal.registerLowPowerModeObserver( 
  49.                 new PowerManagerInternal.LowPowerModeListener() { 
  50.             @Override 
  51.             public int getServiceType() { 
  52.                 return ServiceType.ANIMATION; 
  53.             } 
  54.             @Override 
  55.             public void onLowPowerModeChanged(PowerSaveState result) { 
  56.                 synchronized (mGlobalLock) { 
  57.                     // 低电量模式发生变化时, 需要调整对应的动画 
  58.                     final boolean enabled = result.batterySaverEnabled; 
  59. if (mAnimationsDisabled != enabled && !mAllowAnimationsInLowPowerMode) { 
  60.                         mAnimationsDisabled = enabled; 
  61.                         dispatchNewAnimatorScaleLocked(null); 
  62.                     } 
  63.                 } 
  64.             } 
  65.         }); 
  66.         // 获取是否允许动画 
  67.         mAnimationsDisabled = 
  68.             mPowerManagerInternal.getLowPowerState( 
  69.             ServiceType.ANIMATION).batterySaverEnabled; 
  70.     } 
  71.     mScreenFrozenLock = 
  72.     mPowerManager.newWakeLock( 
  73.         PowerManager.PARTIAL_WAKE_LOCK, "SCREEN_FROZEN"); 
  74.     mScreenFrozenLock.setReferenceCounted(false); 
  75.     // 获取IActivity.Stub.Proxy(new BinderProxy()) 
  76.     mActivityManager = ActivityManager.getService(); 
  77.     // 获取IActivityTaskManager.Stub.Proxy 
  78.     mActivityTaskManager = ActivityTaskManager.getService(); 
  79.     // ActivityManagerInternal是ActivityManager的本地服务 
  80.     mAmInternal = 
  81.         LocalServices.getService(ActivityManagerInternal.class); 
  82.     // ActivityTaskManagerInternal是ActivityTaskManager的本地服务 
  83.     mAtmInternal = 
  84.         LocalServices.getService(ActivityTaskManagerInternal.class); 
  85.     mAppOps =  
  86.     (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE); 
  87.     AppOpsManager.OnOpChangedInternalListener opListener = 
  88.             new AppOpsManager.OnOpChangedInternalListener() { 
  89.                 @Override  
  90.                 public void onOpChanged(int op, String packageName) { 
  91.                     updateAppOpsState(); 
  92.                 } 
  93.             }; 
  94.     mAppOps.startWatchingMode(OP_SYSTEM_ALERT_WINDOW, null, opListener); 
  95.     mAppOps.startWatchingMode(AppOpsManager.OP_TOAST_WINDOW, 
  96.         null, opListener); 
  97.     // PackageManagerInternal是PackageManager的本地服务 
  98.     mPmInternal = LocalServices.getService(PackageManagerInternal.class); 
  99.     // 注册Package suspend/unsuspend广播 
  100.     final IntentFilter suspendPackagesFilter = new IntentFilter(); 
  101.     suspendPackagesFilter.addAction(Intent.ACTION_PACKAGES_SUSPENDED); 
  102.     suspendPackagesFilter.addAction(Intent.ACTION_PACKAGES_UNSUSPENDED); 
  103.     context.registerReceiverAsUser(new BroadcastReceiver() { 
  104.         @Override 
  105.         public void onReceive(Context context, Intent intent) { 
  106.             final String[] affectedPackages = 
  107.             intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 
  108.             final boolean suspended = 
  109.             Intent.ACTION_PACKAGES_SUSPENDED.equals(intent.getAction()); 
  110.             updateHiddenWhileSuspendedState( 
  111.             new ArraySet<>(Arrays.asList(affectedPackages)), suspended); 
  112.         } 
  113.     }, UserHandle.ALL, suspendPackagesFilter, nullnull); 
  114.     // 获取并设置window scale设置 
  115.     final ContentResolver resolver = context.getContentResolver(); 
  116.     mWindowAnimationScaleSetting = Settings.Global.getFloat(resolver, 
  117. Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScaleSetting); 
  118.     ...... 
  119.     // 注册广播, 当DevicePolicyManager状态发生变化时设置keyguard属性是否可用 
  120.     IntentFilter filter = new IntentFilter(); 
  121.     filter.addAction(ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED); 
  122.     mContext.registerReceiverAsUser(mBroadcastReceiver, 
  123.         UserHandle.ALL, filter, nullnull); 
  124.     mLatencyTracker = LatencyTracker.getInstance(context); 
  125.     mSettingsObserver = new SettingsObserver();  
  126.     ......  
  127.     mSurfaceAnimationRunner = new SurfaceAnimationRunner(mPowerManagerInternal); 
  128.     mAllowTheaterModeWakeFromLayout = context.getResources().getBoolean( 
  129. com.android.internal.R.bool.config_allowTheaterModeWakeFromWindowLayout); 
  130.     // Task定位控制器 
  131.     mTaskPositioningController = new TaskPositioningController(this, 
  132.         mInputManager, mActivityTaskManager, mH.getLooper()); 
  133.     // View的拖/拉操作控制器 
  134.     mDragDropController = new DragDropController(this, mH.getLooper());  
  135.     ...... 
  136.     // 注册WindowManager的本地服务WindowManagerInternal 
  137.     LocalServices.addService(WindowManagerInternal.class, new LocalService()); 

LocalServices与ServiceManager类似,但是LocalServices只能是在同一个进程中使用;

并且LocalServices中注册的并不是一个Binder对象,注册进的都是对应的Service的静态内部类;

也就是LocalService,比如WMS有一个WindowManagerInternal,LocalService就是其子类实现;

6、onInitReady

  1. public void onInitReady() { 
  2.     // 初始化PhoneWindowManager 
  3.     initPolicy(); 
  4.     // 添加Watchdog monitor 
  5.     Watchdog.getInstance().addMonitor(this);  
  6.     // 调用SurfaceControl.openTransaction(), 启动一个事务 
  7.     openSurfaceTransaction(); 
  8.     // 创建水印 
  9.     createWatermarkInTransaction(); 
  10.     // 结束事务 
  11. closeSurfaceTransaction("createWatermarkInTransaction");  
  12.     // 显示模拟器显示层 
  13.     showEmulatorDisplayOverlayIfNeeded(); 

7、 initPolicy

  1. private void initPolicy() { 
  2.         UiThread.getHandler().runWithScissors(new Runnable() { 
  3.             @Override 
  4.             public void run() { 
  5.                 WindowManagerPolicyThread.set(Thread.currentThread(), 
  6.                     Looper.myLooper()); 
  7.                 mPolicy.init(mContext, WindowManagerService.this, 
  8.                     WindowManagerService.this); 
  9.             } 
  10.         }, 0); 
  11.     } 

PhoneWindowManager 的初始化运行在 “android.ui” 线程;

8、 displayReady

  1. public void displayReady() { 
  2.     synchronized (mGlobalLock) { 
  3.         // 设置RootWindowContainer的Window列表的最大宽度 
  4.         if (mMaxUiWidth > 0) { 
  5.             mRoot.forAllDisplays( 
  6.             displayContent -> displayContent.setMaxUiWidth(mMaxUiWidth)); 
  7.         } 
  8.         final boolean changed = applyForcedPropertiesForDefaultDisplay(); 
  9.         mAnimator.ready(); 
  10.         mDisplayReady = true
  11.         if (changed) { 
  12.             // 重新配置DiaplayContent属性 
  13.             reconfigureDisplayLocked(getDefaultDisplayContentLocked()); 
  14.         } 
  15.         mIsTouchDevice = mContext.getPackageManager().hasSystemFeature( 
  16.         PackageManager.FEATURE_TOUCHSCREEN); 
  17.     } 
  18.     // 1.修改当前configuration 2.确保当前Activity正在运行当前configuration 
  19.     mActivityTaskManager.updateConfiguration(null); 
  20.     // 更新CircularDisplayMask 
  21.     updateCircularDisplayMaskIfNeeded(); 

9、systemReady

  1. public void systemReady() { 
  2.     mSystemReady = true
  3.     mPolicy.systemReady(); 
  4.     mRoot.forAllDisplayPolicies(DisplayPolicy::systemReady); 
  5.     mTaskSnapshotController.systemReady(); 
  6.     // 是否支持色域 
  7.     mHasWideColorGamutSupport = queryWideColorGamutSupport(); 
  8.     // 是否支持HDR渲染 
  9.     mHasHdrSupport = queryHdrSupport(); 
  10.     UiThread.getHandler().post(mSettingsObserver::updateSystemUiSettings); 
  11.     UiThread.getHandler().post(mSettingsObserver::updatePointerLocation); 
  12.     // 获取IVrManager.Stub.Proxy, 并注册状态变化listener 
  13.     IVrManager vrManager = IVrManager.Stub.asInterface( 
  14.             ServiceManager.getService(Context.VR_SERVICE)); 
  15.     if (vrManager != null) { 
  16.         final boolean vrModeEnabled = vrManager.getVrModeState(); 
  17.         synchronized (mGlobalLock) { 
  18.             vrManager.registerListener(mVrStateCallbacks); 
  19.             if (vrModeEnabled) { 
  20.                 mVrModeEnabled = vrModeEnabled; 
  21.                 mVrStateCallbacks.onVrStateChanged(vrModeEnabled); 
  22.             } 
  23.         } 
  24.     } 

整个启动过程涉及3个线程: system_server主线程, “android.display”, “android.ui”;

整个过程是采用阻塞方式(利用Handler.runWithScissors)执行的;

其中WindowManagerService.mH的Looper运行在 “android.display”进程,也就意味着WMS.H.handleMessage()在该线程执行;

WMS 主要用于窗口的添加和移除操作,其对应的方法是 addWindow 和 removeWindow,关于窗口的添加和删除过程

总结

快年底了,一起加油努力

 

来源: Android开发编程内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯