Android P WMS(2) -- wms初始化

本文详细剖析了Android系统中Window Manager Service(WMS)的初始化过程,从SystemServer的startOtherServices方法开始,介绍了WMS如何创建并注册到ServiceManager,以及与InputManagerService的交互。同时,分析了WMS的main方法和initPolicy方法的执行线程及其优先级,为理解Android窗口管理和输入事件处理提供了深入视角。

Android P WMS(1) -- wms简介

Android P WMS(2) -- wms初始化

Android O WMS(3) -- addwindow

Android P WMS(4) -- removewindow

Android P WMS(5) -- relayoutWindow

Android P WMS(6) -- windowanimator

Android P WMS(7) --wms 问题种类和debug技巧

Android P WMS(8) --View SYstem 简介

Android P WMS(9) --Surface

 

WMS的初始化

@/frameworks/base/services/java/com/android/server/SystemServer.java
private void startOtherServices() {
       WindowManagerService wm = null;
       InputManagerService inputManager = null;

           traceBeginAndSlog("InitWatchdog");
           final Watchdog watchdog = Watchdog.getInstance();
           watchdog.init(context, mActivityManagerService);
           traceEnd();

           traceBeginAndSlog("StartInputManagerService");
           inputManager = new InputManagerService(context);  //4  需要input,因此才有事件输入
           traceEnd();

           traceBeginAndSlog("StartWindowManagerService");
           // WMS needs sensor service ready
           ConcurrentUtils.waitForFutureNoInterrupt(mSensorServiceStart, START_SENSOR_SERVICE);
           mSensorServiceStart = null;
           wm = WindowManagerService.main(context, inputManager,
                   mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
                   !mFirstBoot, mOnlyCore, new PhoneWindowManager());
           ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
                   DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
           ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
                   /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
           traceEnd();

           traceBeginAndSlog("SetWindowManagerService");
           mActivityManagerService.setWindowManager(wm);
           traceEnd();

           traceBeginAndSlog("WindowManagerServiceOnInitReady");
           wm.onInitReady();  //android o没有
           traceEnd();

   
           traceBeginAndSlog("StartInputManager");
           inputManager.setWindowManagerCallbacks(wm.getInputMonitor());
           inputManager.start();
           traceEnd();

           // TODO: Use service dependencies instead.
           traceBeginAndSlog("DisplayManagerWindowManagerAndInputReady");
           mDisplayManagerService.windowManagerAndInputReady();
           traceEnd();


        traceBeginAndSlog("MakeWindowManagerServiceReady");
        try {
            wm.systemReady();
        } catch (Throwable e) {
            reportWtf("making Window Manager Service ready", e);
        }
        traceEnd();

 
        // Update the configuration for this context by hand, because we're going
        // to start using it before the config change done in wm.systemReady() will
        // propagate to it.
        final Configuration config = wm.computeNewConfiguration(DEFAULT_DISPLAY);
        DisplayMetrics metrics = new DisplayMetrics();
        WindowManager w = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
        w.getDefaultDisplay().getMetrics(metrics);
        context.getResources().updateConfiguration(config, metrics);

} 

startOtherServices方法用于启动其他服务,其他服务大概有70多个,上面的代码只列出了WMS以及和它相关的IMS的启动逻辑,剩余的其他服务的启动逻辑也都大同小异。 
在注释1、2处分别得到Watchdog实例并对它进行初始化,Watchdog用来监控系统的一些关键服务的运行状况,后文会再次提到它。在注释3处创建了IMS,并赋值给IMS类型的inputManager对象。注释4处执行了WMS的main方法,其内部会创建WMS,需要注意的是main方法其中一个传入的参数就是注释1处创建的IMS,WMS是输入事件的中转站,其内部包含了IMS引用并不意外。结合上文,我们可以得知WMS的main方法是运行在SystemServer的run方法中,换句话说就是运行在”system_server”线程”中,后面会再次提到”system_server”线程。 
注释5和注释6处分别将WMS和IMS注册到ServiceManager中,这样如果某个客户端想要使用WMS,就需要先去ServiceManager中查询信息,然后根据信息与WMS所在的进程建立通信通路,客户端就可以使用WMS了。注释7处用来初始化显示信息,注释8处则用来通知WMS,系统的初始化工作已经完成,其内部调用了WindowManagerPolicy的systemReady方法。 
 

@http://androidxref.com/9.0.0_r3/xref/frameworks/base/services/java/com/android/server/SystemServer.java#875    
private WindowManagerService(Context context, InputManagerService inputManager,
            boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore,
            WindowManagerPolicy policy) {
   
        mInputManager = inputManager; // Must be before createDisplayContentLocked.
        mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
        mDisplaySettings = new DisplaySettings();
        mDisplaySettings.readSettingsLocked();

        mPolicy = policy;
        mAnimator = new WindowAnimator(this);  //创建了WindowAnimator,它用于管理所有的窗口动画
        mRoot = new RootWindowContainer(this);

        mWindowPlacerLocked = new WindowSurfacePlacer(this);
        mTaskSnapshotController = new TaskSnapshotController(this);

        mWindowTracing = WindowTracing.createDefaultAndStartLooper(context);

        LocalServices.addService(WindowManagerPolicy.class, mPolicy);

        if(mInputManager != null) {
            final InputChannel inputChannel = mInputManager.monitorInput(TAG_WM);
            mPointerEventDispatcher = inputChannel != null
                    ? new PointerEventDispatcher(inputChannel) : null;
        } else {
            mPointerEventDispatcher = null;
        }

        mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);

        mKeyguardDisableHandler = new KeyguardDisableHandler(mContext, mPolicy);

        ...
 
        //得到AMS实例,并赋值给mActivityManager ,这样WMS就持有了AMS的引用            
        mActivityManager = ActivityManager.getService();
        mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
      
        IntentFilter filter = new IntentFilter();
        // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
        filter.addAction(ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
        mContext.registerReceiver(mBroadcastReceiver, filter);

        mLatencyTracker = LatencyTracker.getInstance(context);

        mSettingsObserver = new SettingsObserver();

        mHoldingScreenWakeLock = mPowerManager.newWakeLock(
                PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, TAG_WM);
        mHoldingScreenWakeLock.setReferenceCounted(false);

        mSurfaceAnimationRunner = new SurfaceAnimationRunner();



        LocalServices.addService(WindowManagerInternal.class, new LocalService());
    }
    

public void onInitReady() {
    initPolicy(); //初始化了窗口管理策略的接口类WindowManagerPolicy(WMP)

    // Add ourself to the Watchdog monitors.
    Watchdog.getInstance().addMonitor(this);  //加入到watchdog

    openSurfaceTransaction();
    try {
        createWatermarkInTransaction();
    } finally {
        closeSurfaceTransaction("createWatermarkInTransaction");
    }

    showEmulatorDisplayOverlayIfNeeded();
}
    private void initPolicy() {
        UiThread.getHandler().runWithScissors(new Runnable() {
            @Override
            public void run() {
                WindowManagerPolicyThread.set(Thread.currentThread(), Looper.myLooper());
                mPolicy.init(mContext, WindowManagerService.this, WindowManagerService.this);
            }
        }, 0);
    }

 

运行线程状态

 

initPolicy方法和此前讲的WMS的main方法的实现类似,注释1处执行了WMP的init方法,WMP是一个接口,init方法的具体实现在PhoneWindowManager(PWM)中。PWM的init方法运行在”android.ui”线程中,它的优先级要高于initPolicy方法所在的”android.display”线程,因此”android.display”线程要等PWM的init方法执行完毕后,处于等待状态的”android.display”线程才会被唤醒从而继续执行下面的代码。

在本文中共提到了3个线程,分别是”system_server”、”android.display”和”android.ui”,为了便于理解,下面给出这三个线程之间的关系。
 

 

main运行在DisplayThread(android.display),initPolicy运行在UiThread(android.ui)

//android.display thread
public static WindowManagerService main(final Context context, final InputManagerService im,
        final boolean haveInputMethods, final boolean showBootMsgs, final boolean onlyCore,
        WindowManagerPolicy policy) {
    DisplayThread.getHandler().runWithScissors(() ->
            sInstance = new WindowManagerService(context, im, haveInputMethods, showBootMsgs,
                    onlyCore, policy), 0);
    return sInstance;
}


//android.ui thread
private void initPolicy() {
    UiThread.getHandler().runWithScissors(new Runnable() {
        @Override
        public void run() {
            WindowManagerPolicyThread.set(Thread.currentThread(), Looper.myLooper());
            mPolicy.init(mContext, WindowManagerService.this, WindowManagerService.this);
        }
    }, 0);
}
//DisplayThread  android.display
/frameworks/base/services/core/java/com/android/server/
H A D	DisplayThread.java	36 super("android.display", Process.THREAD_PRIORITY_DISPLAY + 1, false /*allowIo*/);

//UiThread android.ui
/frameworks/base/services/core/java/com/android/server/
H A D	UiThread.java	36 super("android.ui", Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);

 

“system_server”线程中会调用WMS的main方法,main方法中会创建WMS,创建WMS的过程运行在”android.display”线程中,它的优先级更高一些,因此要等创建WMS完毕后才会唤醒处于等待状态的”system_server”线程。 
WMS初始化时会执行initPolicy方法,initPolicy方法会调用PWM的init方法,这个init方法运行在”android.ui”线程,并且优先级更高,因此要先执行完PWM的init方法后,才会唤醒处于等待状态的”android.display”线程。 
PWM的init方法执行完毕后会接着执行运行在”system_server”线程的代码,比如本文前部分提到WMS的 
systemReady方法。
 

总结

wms初始化和前面的android版本变化不是很大,可以进行对比分析

 

源码路径: http://androidxref.com/9.0.0_r3/

参考书籍: Android解析WindowManager系列

                 Android解析WindowManagerService(一)WMS的诞生

              《深入理解Android:卷III》 

 

 

 

 

 

<think>嗯,用户想了解Android的窗口管理服务(WMS)的工作原理和实现细节。首先,我需要回忆一下WMSAndroid系统中的作用。记得WMS负责窗口的创建、布局和绘制,和Surface的管理有关。可能需要参考之前提供的引用内容,比如引用[1]提到PhoneWindow处理通用逻辑,而WindowManagerImpl实际负责将View添加到WMS。这可能涉及到窗口的添加流程。 接下来,用户可能需要知道WMS的核心机制。比如窗口的层级(Z-order)和布局,还有与SurfaceFlinger的交互。需要解释WMS如何管理窗口的堆叠顺序和计算它们的可见区域。引用[4]提到了systemserver进程安装framework-res.apk,可能和系统服务的启动有关,比如WMS作为系统服务运行在system_server进程中。 另外,窗口的添加过程可能涉及跨进程通信,比如引用[2]中的ActivityManager.getService().startActivity(),虽然这更多是启动Activity,但Activity的窗口管理最终会调用到WMS。这里可能需要说明应用进程通过Binder与WMS通信,请求创建窗口。 还有,窗口的绘制和合成部分。WMS配合SurfaceFlinger处理图层,确保正确显示。需要解释Surface的作用,每个窗口对应一个Surface,由WMS分配。 用户可能还想知道WMS与其他组件的关系,比如ActivityManagerService和ViewRootImpl。比如,ViewRootImpl作为应用和WMS的中介,处理布局和输入事件。引用[3]中的bindService流程可能和Service的窗口相关,但不太确定,可能需要略过。 在实现细节方面,WMS使用WindowState来跟踪窗口状态,处理焦点和输入事件的分发。这涉及到事件传递机制,比如触摸事件如何路由到正确的窗口。 需要确保回答结构清晰,分点解释,引用提供的资料。例如,在窗口添加流程中提到PhoneWindow和WindowManagerImpl的分工,引用[1]。可能还需要提到系统服务初始化的部分,引用[4]中的内容。 另外,用户的问题可能涉及WMS的代码结构,比如WindowManagerService类的方法,如addWindow(),处理权限和窗口参数。这部分需要结合Android源码的结构,但用户可能不需要太深入的代码细节,而是整体流程。 最后,生成相关问题要考虑用户可能进一步想知道WMS与其他服务的交互、性能优化或窗口动画的实现。例如,WMS如何处理多窗口模式,或者与SurfaceFlinger的协作机制。</think>### Android窗口管理服务(WMS)实现细节 #### 1. **WMS的核心职责** - **窗口层级管理**:通过Z-order决定窗口的显示顺序,例如对话框始终位于应用主窗口之上。 - **布局计算**:根据窗口尺寸、位置和系统状态(如导航栏高度)计算最终可见区域。 - **输入事件路由**:将触摸事件分发到正确的窗口,基于窗口层级和焦点状态。 - **Surface分配**:通过SurfaceFlinger为每个窗口分配图形缓冲区,管理合成策略[^1][^4]。 #### 2. **窗口添加流程** ```java // 伪代码流程 1. ActivityThread.handleResumeActivity()2. WindowManagerImpl.addView() → 3. WindowManagerGlobal.addView() → 4. ViewRootImpl.setView() → 5. Session.addToDisplay()(跨进程调用WMS)→ 6. WMS.addWindow() ``` - **关键点**:应用通过`WindowManagerImpl`发起请求,最终由WMS在`system_server`进程中完成窗口注册[^4]。 #### 3. **窗口状态管理** - **数据结构**:使用`WindowState`对象跟踪每个窗口的: - 父/子窗口关系(如PopupWindow依附于Activity窗口) - 当前焦点状态 - Surface控制句柄 - **布局优化**:通过`performLayoutAndPlaceSurfacesLocked()`方法批量处理布局计算,减少重复计算。 #### 4. **跨进程通信机制** - **Binder接口**:`IWindowSession`用于应用进程向WMS发送请求 - **回调接口**:`IWindow`允许WMS向应用进程通知事件(如尺寸变化) ```java // WMS中的典型IPC调用 public int addWindow(Session session, IWindow client, ...) { // 权限检查(TYPE_SYSTEM_ALERT需MANAGE_APP_TOKENS权限) // 创建WindowToken关联ActivityRecord } ``` #### 5. **与图形系统的协作** - **Surface生命周期**: - WMS通过`SurfaceControl`创建/销毁Surface - Surface状态变化触发`SurfaceFlinger`图层重组 - **动画处理**:窗口动画由WMS计算帧数据,通过`Transaction.setMatrix()`提交到SurfaceFlinger。 #### 6. **特殊窗口处理** - **系统窗口**(如STATUS_BAR): - 在`PhoneWindowManager`中定义策略 - 拥有最高Z-order优先级 - **多窗口模式**: - Split-screen模式下重新计算各窗口边界 - 通过`ActivityTaskManager`协调任务栈
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值