Android窗口管理2 WMS启动过程

一 概述

在 Android 系统中,从设计的角度来看,窗口管理系统是基于 C/S 模式的。整个窗口系统分为服务端和客户端两大部分,客户端负责请求创建窗口和使用窗口,服务端完成窗口的维护,窗口显示等。
在这里插入图片描述
在 Client 端,并不是直接和 WindowManagerService 交互,而是直接和本地对象 WindowManager 交互,然后由 WindowManager 完成和 WindowManagerService 的交互。对于 Android 应用来说这个交互是透明的,应用感觉不到 WindowManagerService 的存在。本篇文章我们来介绍窗口管理服务 WindowManagerService 的启动过程。

1.1 WMS全貌

在这里插入图片描述

1.2 WMS功能

窗口管理
WMS 是窗口的管理者,它负责窗口的启动、添加和删除,另外窗口的大小和层级也是由 WMS 进行管理的。窗口管理的核心成员有 DisplayContent、WindowToken 和 WindowState。

窗口动画
窗口间进行切换时,使用窗口动画可以显得更炫一些,窗口动画由 WMS 的动画子系统来负责,动画子系统的管理者为 WindowAnimator。

输入系统的中转站
通过对窗口的触摸从而产生触摸事件,InputManagerService(IMS)会对触摸事件进行处理,它会寻找一个最合适的窗口来处理触摸反馈信息,WMS 是窗口的管理者,因此,WMS “理所应当” 的成为了输入系统的中转站。

Surface管理
窗口并不具备有绘制的功能,因此每个窗口都需要有一块 Surface 来供自己绘制。为每个窗口分配 Surface 是由 WMS 来完成的。

WMS 的职责可以简单总结为下图。
在这里插入图片描述

1.3 WMS重要成员

说明:

  • WMS
    继承于 IWindowManager.Stub,作为 Binder 服务端
  • mSessions
    ArraySet 类型的变量,元素类型为 Session,保存着所有的 Session 对象,Session 继承于 IWindowSession.Stub,作为 Binder 服务端,它主要用于进程间通信,其他的应用程序进程想要和 WMS 进程进行通信就需要经过 Session,并且每个应用程序进程都会对应一个Session,WMS 保存这些 Session 用来记录所有向 WMS 提出窗口管理服务的客户端。
  • mPolicy
    WindowManagerPolicy 类型的变量,是窗口管理策略的接口类,用来定义一个窗口策略所要遵循的通用规范,并提供了 WindowManager 所有的特定的 UI 行为。具体实现类为 PhoneWindowManager,这个实现类在 WMS 创建时被创建。WMP 允许定制窗口层级和特殊窗口类型以及关键的调度和布局。
  • DisplayContent 的成员变量 mTokenMap,保存所有的 WindowToken 对象,以 IBinder 为 key,可以是 IAppWindowToken 或者其他 Binder 的 Bp 端;另一端情况:ActivityRecord.Token extends IApplicationToken.Stub
  • mWindowMap
    WindowHashMap 类型的变量,WindowHashMap 继承了 HashMap,它限制了 HashMap 的 key 值的类型为 IBinder,value 值的类型为 WindowState。保存 WMS 中所有的 WindowState 对象
  • mResizingWindows
    ArrayList 类型的变量,元素类型为 WindowState。mResizingWindows 是用来存储正在调整大小的窗口的列表。
  • mAnimator
    WindowAnimator 类型的变量,用于管理窗口的动画以及特效动画。
  • mH
    H 类型的变量,系统的 Handler 类,用于将任务加入到主线程的消息队列中,这样代码逻辑就会在主线程中执行。

涉及代码如下:

frameworks/base/services/java/com/android/server/SystemServer.java
frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
frameworks/base/services/core/java/com/android/server/DisplayThread.java
frameworks/base/services/core/java/com/android/server/wm/WindowState.java
frameworks/base/services/core/java/com/android/server/wm/AppWindowToken.java
frameworks/base/services/core/java/com/android/server/input/InputManagerService.java
frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
frameworks/base/services/core/java/com/android/server/policy/WindowManagerPolicy.java
frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
frameworks/base/services/core/java/com/android/server/wm/WindowAnimator.java
frameworks/base/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
frameworks/base/services/core/java/com/android/server/wm/TaskSnapshotController.java
frameworks/base/services/core/java/com/android/server/wm/TaskPositioningController.java
frameworks/base/services/core/java/com/android/server/wm/DragDropController.java

二 SystemServer

frameworks/base/services/java/com/android/server/SystemServer.java

2.1 main

/**
 * The main entry point from zygote.
 */
public static void main(String[] args) {
    new SystemServer().run();
}
 
private void run() {
    ......
    // 初始化系统上下文
    createSystemContext();
    // 初始化SystemServiceManager
    mSystemServiceManager = new SystemServiceManager(mSystemContext);
    ......
    // 启动相互依赖关系复杂的服务
    startBootstrapServices();
    // 启动相互独立的基本服务
    startCoreServices();
    // 启动其他服务
    startOtherServices();
    ......
}

2.2 startOtherServices

private void startOtherServices() {
    // 启动WMS前, 需要先启动SensorService
   ConcurrentUtils.waitForFutureNoInterrupt(
   mSensorServiceStart, START_SENSOR_SERVICE);
    mSensorServiceStart = null;
    WindowManagerService wm = WindowManagerService.main(context,
    inputManager, !mFirstBoot, mOnlyCore, new PhoneWindowManager(),
    mActivityManagerService.mActivityTaskManager);
    
    ServiceManager.addService(Context.WINDOW_SERVICE, wm, false,
    DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
    ......
    // 所有WMS相关的实体对象初始化完成
    wm.onInitReady();
    ......
    // Display ready
    wm.displayReady();
    ......
    // WMS ready
    wm.systemReady();
    ......
    final WindowManagerService windowManagerF = wm;
    // 启动SystemUIService服务
    startSystemUi(context, windowManagerF);
    ......
}
 
private static void startSystemUi(Context context,
        WindowManagerService windowManager) {
    Intent intent = new Intent();
    intent.setComponent(new ComponentName("com.android.systemui",
    "com.android.systemui.SystemUIService"));
    
    intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
    context.startServiceAsUser(intent, UserHandle.SYSTEM);
    // System UI已启动
    windowManager.onSystemUiStarted();
}

三 WindowManagerService

frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java

3.1 组成元素

// ActivityTaskManager服务相关
// 管理Activity和其容器(如task/stacks/displays)的系统服务
final IActivityTaskManager mActivityTaskManager;
final ActivityTaskManagerService mAtmService;
  
// DisplayManager服务相关, 管理Display属性
final DisplayManagerInternal mDisplayManagerInternal;
final DisplayManager mDisplayManager;
final DisplayWindowSettings mDisplayWindowSettings;
  
// ActivityManager服务相关, 用于和四大组件交互
final IActivityManager mActivityManager;
final ActivityManagerInternal mAmInternal;
  
// PowerManager服务相关, 管理电源状态
PowerManager mPowerManager;
PowerManagerInternal mPowerManagerInternal;
  
// 输入管理服务
final InputManagerService mInputManager;
// 包管理本地系统服务
final PackageManagerInternal mPmInternal;
  
// 根窗口容器
RootWindowContainer mRoot;
// 提供UI相关行为的策略类, 其实现类为PhoneWindowManager
WindowManagerPolicy mPolicy;
// 在一个单独的task中执行动画和Surface操作的类
final WindowAnimator mAnimator;
// 用来确定Window和Surface位置的类
final WindowSurfacePlacer mWindowPlacerLocked;
// 任务快照管理器(当App不可见时, 会将Task的快照以Bitmap形式存在缓存中)
final TaskSnapshotController mTaskSnapshotController;
// Task定位控制器
final TaskPositioningController mTaskPositioningController;
// View的拖/拉操作控制器
final DragDropController mDragDropController;
  
// 当前活跃状态的Session连接队列(通常一个进程中包含一个Session, 用于和WindowManager交互)
final ArraySet<Session> mSessions = new ArraySet<>();
// <IBinder, WindowState>客户端Window token和服务端WindowState的映射
final WindowHashMap mWindowMap = new WindowHashMap();
  
// AppWindowToken是一个窗口容器类, 可以理解为正在显示Window的App
// 或Activity的窗口令牌(继承于WindowToken)
// replace超时的AppWindowToken令牌列表
final ArrayList<AppWindowToken> mWindowReplacementTimeouts = new ArrayList<>();
// WindowState表示服务端描述的Window
final ArrayList<WindowState> mResizingWindows = new ArrayList<>();
final ArrayList<WindowState> mPendingRemove = new ArrayList<>();
final ArrayList<WindowState> mDestroySurface = new ArrayList<>();
final ArrayList<WindowState> mDestroyPreservedSurface = new ArrayList<>();
final ArrayList<WindowState> mForceRemoves = new ArrayList<>();
ArrayList<WindowState> mWaitingForDrawn = new ArrayList<>();
private ArrayList<WindowState> mHidingNonSystemOverlayWindows = new ArrayList<>();
WindowState[] mPendingRemoveTmp = new WindowState[20];

// 主线程Handler
final H mH = new H();

3.2 启动过程

3.2.1 main

public static WindowManagerService main(final Context context,
        final InputManagerService im, final boolean showBootMsgs,
        final boolean onlyCore, WindowManagerPolicy policy,
        ActivityTaskManagerService atm) {
    return main(context, im, showBootMsgs, onlyCore, 
            policy, atm, SurfaceControl.Transaction::new);
}
 
public static WindowManagerService main(final Context context,
        final InputManagerService im, final boolean showBootMsgs,
        final boolean onlyCore, WindowManagerPolicy policy,
        ActivityTaskManagerService atm, TransactionFactory transactionFactory) {
    //运行在"android.display"线程
    DisplayThread.getHandler().runWithScissors(() ->
            sInstance = new WindowManagerService(context, im, showBootMsgs, 
                    onlyCore, policy, atm, transactionFactory), 0);
    return sInstance;
}

在 “android.display” 线程中执行 WindowManagerService 对象的初始化过程,其中 final H mH = new H();此处 H 继承于 Handler,无参初始化的过程,便会采用当前所在线程的 Looper。那就是说WindowManagerService.H.handleMessage() 方法运行在 “android.display” 线程。

3.2.2 Handler.runWithScissors

Handler.java

public final boolean runWithScissors(final Runnable r, long timeout) {
    //当前线程跟当前Handler都指向同一个Looper,则直接运行
    if (Looper.myLooper() == mLooper) {
        r.run();
        return true;
    }

    BlockingRunnable br = new BlockingRunnable(r);
    return br.postAndWait(this, timeout);
}

3.2.3 postAndWait

Handler.java ::BlockingRunnable

private static final class BlockingRunnable implements Runnable {
    private final Runnable mTask;
    private boolean mDone;

    public BlockingRunnable(Runnable task) {
        mTask = task;
    }

    public void run() {
        try {
            mTask.run();
        } finally {
            synchronized (this) {
                mDone = true;
                notifyAll();
            }
        }
    }

    public boolean postAndWait(Handler handler, long timeout) {
        if (!handler.post(this)) {
            return false;
        }
        synchronized (this) {
            if (timeout > 0) {
                final long expirationTime = SystemClock.uptimeMillis() + timeout;
                while (!mDone) {
                    long delay = expirationTime - SystemClock.uptimeMillis();
                    if (delay <= 0) {
                        return false; // timeout
                    }
                    try {
                        wait(delay);
                    } catch (InterruptedException ex) {
                    }
                }
            } else {
                while (!mDone) {
                    try {
                        wait();
                    } catch (InterruptedException ex) {
                    }
                }
            }
        }
        return true;
    }
}

由此可见,BlockingRunnable.postAndWait() 方法是阻塞操作,就是先将消息放入 Handler 所指向的线程,此处是指 ”android.display” 线程,由于该方法本身运行在 system_server 主线程。也就意味着 system_server 主线程会进入等待状态,直到 handler 线程执行完成后再唤醒 system_server 主线程。所以在 WindowManagerService 启动完成之后,SystemServer 主线程才能继续往下走。

WMS 所在的线程就是 DisplayThread 这个显示线程,这个线程不仅被 WMS 使用,DisplayManagerService、InputManagerService 也会使用。当实例化 WindowManagerService 时,它的成员变量 mH 就与 DisplayThread 产生了关联,后期可以通过 mH 这个 handler 投递事件到 DisplayThread 的 looper 队列中。mH 是 WMS 的内部类 final class H extends Handler {}。

3.2.4 构造方法

private WindowManagerService(Context context, InputManagerService inputManager,
        boolean showBootMsgs, boolean onlyCore, WindowManagerPolicy policy,
        ActivityTaskManagerService atm, TransactionFactory transactionFactory) {
    installLock(this, INDEX_WINDOW);
    mGlobalLock = atm.getGlobalLock();
    mAtmService = atm;
    mContext = context;
    mAllowBootMessages = showBootMsgs;
    mOnlyCore = onlyCore;
    // 各种变量读取
    mLimitedAlphaCompositing = context.getResources().getBoolean(
            com.android.internal.R.bool.config_sf_limitedAlpha);
    mHasPermanentDpad = context.getResources().getBoolean(
            com.android.internal.R.bool.config_hasPermanentDpad);
    mInTouchMode = context.getResources().getBoolean(
            com.android.internal.R.bool.config_defaultInTouchMode);
    ......
    mInputManager = inputManager;
    mDisplayManagerInternal =
        LocalServices.getService(DisplayManagerInternal.class);
    // Display设置
    mDisplayWindowSettings = new DisplayWindowSettings(this);
 
    mTransactionFactory = transactionFactory;
    mTransaction = mTransactionFactory.make();
    //PhoneWindowManager(继承于WindowManagerPolicy, 用来提供UI相关的一些行为)
    mPolicy = policy;
    // 在一个单独的task中执行动画和Surface操作的类
    mAnimator = new WindowAnimator(this);
    // 根Window容器
    mRoot = new RootWindowContainer(this);
 
    // 用来确定Window和Surface的位置
    mWindowPlacerLocked = new WindowSurfacePlacer(this);
    // 任务快照管理器(当App不可见时, 会将Task的快照以Bitmap形式存在缓存中)
    mTaskSnapshotController = new TaskSnapshotController(this);

    LocalServices.addService(WindowManagerPolicy.class, mPolicy);
 
    mDisplayManager = 
    (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
 
    // Keyguard处理器
    mKeyguardDisableHandler =
        KeyguardDisableHandler.create(mContext, mPolicy, mH);
 
    // PowerManager是控制设备电池状态的管理器
    mPowerManager = 
        (PowerManager)context.getSystemService(Context.POWER_SERVICE);
    // PowerManagerInternal是PowerMananger的本地服务
    mPowerManagerInternal =
        LocalServices.getService(PowerManagerInternal.class);
 
    if (mPowerManagerInternal != null) {
        mPowerManagerInternal.registerLowPowerModeObserver(
                new PowerManagerInternal.LowPowerModeListener() {
            @Override
            public int getServiceType() {
                return ServiceType.ANIMATION;
            }
 
            @Override
            public void onLowPowerModeChanged(PowerSaveState result) {
                synchronized (mGlobalLock) {
                    // 低电量模式发生变化时, 需要调整对应的动画
                    final boolean enabled = result.batterySaverEnabled;
if (mAnimationsDisabled != enabled && !mAllowAnimationsInLowPowerMode) {
                        mAnimationsDisabled = enabled;
                        dispatchNewAnimatorScaleLocked(null);
                    }
                }
            }
        });
        // 获取是否允许动画
        mAnimationsDisabled =
            mPowerManagerInternal.getLowPowerState(
            ServiceType.ANIMATION).batterySaverEnabled;
    }
    mScreenFrozenLock =
    mPowerManager.newWakeLock(
        PowerManager.PARTIAL_WAKE_LOCK, "SCREEN_FROZEN");
    mScreenFrozenLock.setReferenceCounted(false);
 
    // 获取IActivity.Stub.Proxy(new BinderProxy())
    mActivityManager = ActivityManager.getService();
    // 获取IActivityTaskManager.Stub.Proxy
    mActivityTaskManager = ActivityTaskManager.getService();
    // ActivityManagerInternal是ActivityManager的本地服务
    mAmInternal =
        LocalServices.getService(ActivityManagerInternal.class);
    // ActivityTaskManagerInternal是ActivityTaskManager的本地服务
    mAtmInternal =
        LocalServices.getService(ActivityTaskManagerInternal.class);
    mAppOps = 
    (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
    AppOpsManager.OnOpChangedInternalListener opListener =
            new AppOpsManager.OnOpChangedInternalListener() {
                @Override 
                public void onOpChanged(int op, String packageName) {
                    updateAppOpsState();
                }
            };
    mAppOps.startWatchingMode(OP_SYSTEM_ALERT_WINDOW, null, opListener);
    mAppOps.startWatchingMode(AppOpsManager.OP_TOAST_WINDOW,
        null, opListener);
 
    // PackageManagerInternal是PackageManager的本地服务
    mPmInternal = LocalServices.getService(PackageManagerInternal.class);
    // 注册Package suspend/unsuspend广播
    final IntentFilter suspendPackagesFilter = new IntentFilter();
    suspendPackagesFilter.addAction(Intent.ACTION_PACKAGES_SUSPENDED);
    suspendPackagesFilter.addAction(Intent.ACTION_PACKAGES_UNSUSPENDED);
    context.registerReceiverAsUser(new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String[] affectedPackages =
            intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
            final boolean suspended =
            Intent.ACTION_PACKAGES_SUSPENDED.equals(intent.getAction());
            updateHiddenWhileSuspendedState(
            new ArraySet<>(Arrays.asList(affectedPackages)), suspended);
        }
    }, UserHandle.ALL, suspendPackagesFilter, null, null);
 
    // 获取并设置window scale设置
    final ContentResolver resolver = context.getContentResolver();
    mWindowAnimationScaleSetting = Settings.Global.getFloat(resolver,
		Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScaleSetting);
    ......
 
    // 注册广播, 当DevicePolicyManager状态发生变化时设置keyguard属性是否可用
    IntentFilter filter = new IntentFilter();
    filter.addAction(ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
    mContext.registerReceiverAsUser(mBroadcastReceiver,
        UserHandle.ALL, filter, null, null);
 
    mLatencyTracker = LatencyTracker.getInstance(context);
 
    mSettingsObserver = new SettingsObserver(); 
    ...... 
    mSurfaceAnimationRunner = new SurfaceAnimationRunner(mPowerManagerInternal);
 
    mAllowTheaterModeWakeFromLayout = context.getResources().getBoolean(
	com.android.internal.R.bool.config_allowTheaterModeWakeFromWindowLayout);
 
    // Task定位控制器
    mTaskPositioningController = new TaskPositioningController(this,
        mInputManager, mActivityTaskManager, mH.getLooper());
    // View的拖/拉操作控制器
    mDragDropController = new DragDropController(this, mH.getLooper()); 
    ......
    // 注册WindowManager的本地服务WindowManagerInternal
    LocalServices.addService(WindowManagerInternal.class, new LocalService());
}

3.2.5 onInitReady

public void onInitReady() {
    // 初始化PhoneWindowManager
    initPolicy();
 
    // 添加Watchdog monitor
    Watchdog.getInstance().addMonitor(this); 
    // 调用SurfaceControl.openTransaction(), 启动一个事务
    openSurfaceTransaction();
    // 创建水印
    createWatermarkInTransaction();
    // 结束事务
	closeSurfaceTransaction("createWatermarkInTransaction"); 
    // 显示模拟器显示层
    showEmulatorDisplayOverlayIfNeeded();
}

3.2.6 initPolicy

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);
    }

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

3.2.7 displayReady

public void displayReady() {
    synchronized (mGlobalLock) {
        // 设置RootWindowContainer的Window列表的最大宽度
        if (mMaxUiWidth > 0) {
            mRoot.forAllDisplays(
            displayContent -> displayContent.setMaxUiWidth(mMaxUiWidth));
        }
        final boolean changed = applyForcedPropertiesForDefaultDisplay();
        mAnimator.ready();
        mDisplayReady = true;
        if (changed) {
            // 重新配置DiaplayContent属性
            reconfigureDisplayLocked(getDefaultDisplayContentLocked());
        }
        mIsTouchDevice = mContext.getPackageManager().hasSystemFeature(
        PackageManager.FEATURE_TOUCHSCREEN);
    }
 
    // 1.修改当前configuration 2.确保当前Activity正在运行当前configuration
    mActivityTaskManager.updateConfiguration(null);
    // 更新CircularDisplayMask
    updateCircularDisplayMaskIfNeeded();
}

3.2.8 systemReady

public void systemReady() {
    mSystemReady = true;
    mPolicy.systemReady();
    mRoot.forAllDisplayPolicies(DisplayPolicy::systemReady);
    mTaskSnapshotController.systemReady();
    // 是否支持色域
    mHasWideColorGamutSupport = queryWideColorGamutSupport();
    // 是否支持HDR渲染
    mHasHdrSupport = queryHdrSupport();
    UiThread.getHandler().post(mSettingsObserver::updateSystemUiSettings);
    UiThread.getHandler().post(mSettingsObserver::updatePointerLocation);
    // 获取IVrManager.Stub.Proxy, 并注册状态变化listener
    IVrManager vrManager = IVrManager.Stub.asInterface(
            ServiceManager.getService(Context.VR_SERVICE));
    if (vrManager != null) {
        final boolean vrModeEnabled = vrManager.getVrModeState();
        synchronized (mGlobalLock) {
            vrManager.registerListener(mVrStateCallbacks);
            if (vrModeEnabled) {
                mVrModeEnabled = vrModeEnabled;
                mVrStateCallbacks.onVrStateChanged(vrModeEnabled);
            }
        }
    }
}

3.3 主要功能

WMS 主要用于窗口的添加和移除操作,其对应的方法是 addWindow 和 removeWindow,关于窗口的添加和删除过程,放到后面文章去分析。

四 总结

整个启动过程涉及3个线程:system_server 主线程,“android.display”,“android.ui”,整个过程是采用阻塞方式(利用 Handler.runWithScissors) 执行的。其中 WindowManagerService.mH 的 Looper 运行在 “android.display” 进程,也就意味着 WMS.H.handleMessage() 在该线程执行。 流程如下:
在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值