美文网首页
WMS 启动流程

WMS 启动流程

作者: 沪漂意哥哥 | 来源:发表于2022-05-22 20:11 被阅读0次

    概述

    WMS作为系统的一个关键服务其是在SystemServer.java::startOtherServices中启动的
    WMS主要有下面几个作用:
    1:应用程序通过WMS向SurfaceFinger申请surface,surface代表的是绘图表面,应用程序绘制都必须在绘图表面上.
    2:管理窗口的层级,一个窗口一般在WMS端都是一个WindowState,其是有层级区分的,其有baseLayer和subLayer两个值共同确定.
    3:窗口动画:WindowAnimator

    WMS的启动

    WindowManagerService.java的创建
     wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore,
                        new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);//taskManager对象
    ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
     ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
                        /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
     mActivityManagerService.setWindowManager(wm);//ams持有wms对象
      wm.onInitReady();//准备初始化
    

    其中上面有一个比较重要的对象PhoneWindowManager,主要是负责窗口管理的各种策略

    WindowManagerService.java::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);//调用的内部的main方法
        }
        public static WindowManagerService main(final Context context, final InputManagerService im,
                final boolean showBootMsgs, final boolean onlyCore, WindowManagerPolicy policy,
                ActivityTaskManagerService atm, TransactionFactory transactionFactory) {
            DisplayThread.getHandler().runWithScissors(() ->
                    sInstance = new WindowManagerService(context, im, showBootMsgs, onlyCore, policy,
                            atm, transactionFactory), 0);//wms是运行在android.display线程
            return sInstance;
        }
    
    WindowManagerService
    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);
            mDrawLockTimeoutMillis = context.getResources().getInteger(
                    com.android.internal.R.integer.config_drawLockTimeoutMillis);
            mAllowAnimationsInLowPowerMode = context.getResources().getBoolean(
                    com.android.internal.R.bool.config_allowAnimationsInLowPowerMode);
            mMaxUiWidth = context.getResources().getInteger(
                    com.android.internal.R.integer.config_maxUiWidth);
            mDisableTransitionAnimation = context.getResources().getBoolean(
                    com.android.internal.R.bool.config_disableTransitionAnimation);
            mPerDisplayFocusEnabled = context.getResources().getBoolean(
                    com.android.internal.R.bool.config_perDisplayFocusEnabled);
            mLowRamTaskSnapshotsAndRecents = context.getResources().getBoolean(
                    com.android.internal.R.bool.config_lowRamTaskSnapshotsAndRecents);
            mInputManager = inputManager; // Must be before createDisplayContentLocked.
            mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
            mDisplayWindowSettings = new DisplayWindowSettings(this);
            mTransactionFactory = transactionFactory;
            mTransaction = mTransactionFactory.make();
            mPolicy = policy;
            mAnimator = new WindowAnimator(this);//窗口动画,管理系统里所有的动画
            mRoot = new RootWindowContainer(this);//总管家,对应于ActivityDisplay,用来管理DisplayContent
            mWindowPlacerLocked = new WindowSurfacePlacer(this);
            mTaskSnapshotController = new TaskSnapshotController(this);
            mWindowTracing = WindowTracing.createDefaultAndStartLooper(this,
                    Choreographer.getInstance());
            LocalServices.addService(WindowManagerPolicy.class, mPolicy);
            mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
            mKeyguardDisableHandler = KeyguardDisableHandler.create(mContext, mPolicy, mH);
            mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
            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);
            mActivityManager = ActivityManager.getService();
            mActivityTaskManager = ActivityTaskManager.getService();
            mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
            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);
            mPmInternal = LocalServices.getService(PackageManagerInternal.class);
            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);
            final ContentResolver resolver = context.getContentResolver();
            // Get persisted window scale setting
            mWindowAnimationScaleSetting = Settings.Global.getFloat(resolver,
                    Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScaleSetting);//窗口动画缩放的比例
            mTransitionAnimationScaleSetting = Settings.Global.getFloat(resolver,
                    Settings.Global.TRANSITION_ANIMATION_SCALE,
                    context.getResources().getFloat(
                            R.dimen.config_appTransitionAnimationDurationScaleDefault));
            setAnimatorDurationScale(Settings.Global.getFloat(resolver,
                    Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScaleSetting));//动画时长缩放比例
            mForceDesktopModeOnExternalDisplays = Settings.Global.getInt(resolver,
                    DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, 0) != 0;
            IntentFilter filter = new IntentFilter();
            // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
            filter.addAction(ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
            mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null);
            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(mPowerManagerInternal);
            mAllowTheaterModeWakeFromLayout = context.getResources().getBoolean(
                com.android.internal.R.bool.config_allowTheaterModeWakeFromWindowLayout);
            mTaskPositioningController = new TaskPositioningController(
                    this, mInputManager, mActivityTaskManager, mH.getLooper());
            mDragDropController = new DragDropController(this, mH.getLooper());
            mSystemGestureExclusionLimitDp = Math.max(MIN_GESTURE_EXCLUSION_LIMIT_DP,
                    DeviceConfig.getInt(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
                            KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP, 0));
            mSystemGestureExcludedByPreQStickyImmersive =
          DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
                 KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE, false);
         DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
                    new HandlerExecutor(mH), properties -> {
                        synchronized (mGlobalLock) {
                            final int exclusionLimitDp = Math.max(MIN_GESTURE_EXCLUSION_LIMIT_DP,
                                    properties.getInt(KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP, 0));
                            final boolean excludedByPreQSticky = DeviceConfig.getBoolean(
                                    DeviceConfig.NAMESPACE_WINDOW_MANAGER,
                                    KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE, false);
                            if (mSystemGestureExcludedByPreQStickyImmersive != excludedByPreQSticky
                                    || mSystemGestureExclusionLimitDp != exclusionLimitDp) {
                                mSystemGestureExclusionLimitDp = exclusionLimitDp;
                                mSystemGestureExcludedByPreQStickyImmersive = excludedByPreQSticky;
                               mRoot.forAllDisplays(DisplayContent::updateSystemGestureExclusionLimit);
                            }
                        }
                    });
            LocalServices.addService(WindowManagerInternal.class, new LocalService());
        }
    
    PhoneWindowManager的初始化
       traceBeginAndSlog("WindowManagerServiceOnInitReady");
       wm.onInitReady();
       traceEnd();
       public void onInitReady() {
            initPolicy();
            // 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);//运行在android.ui线程
                }
            }, 0);
        }
    
    PhoneWindowManager::init
     public void init(Context context, IWindowManager windowManager,
                WindowManagerFuncs windowManagerFuncs) {
            mContext = context;
            mWindowManager = windowManager;
            mWindowManagerFuncs = windowManagerFuncs;
            mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
            mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
            mActivityTaskManagerInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
            mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
            mDreamManagerInternal = LocalServices.getService(DreamManagerInternal.class);
            mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
            mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
            mHandler = new PolicyHandler();
            mWakeGestureListener = new MyWakeGestureListener(mContext, mHandler);
            mSettingsObserver = new SettingsObserver(mHandler);
            mSettingsObserver.observe();
            mShortcutManager = new ShortcutManager(context);
            mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
            mBroadcastWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                    "PhoneWindowManager.mBroadcastWakeLock");
            mPowerKeyWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                    "PhoneWindowManager.mPowerKeyWakeLock");
            mEnableShiftMenuBugReports = "1".equals(SystemProperties.get("ro.debuggable"));
            mAllowStartActivityForLongPressOnPowerDuringSetup = 
            readConfigurationDependentBehaviors();
            if (mLidControlsDisplayFold) {
                mDisplayFoldController = DisplayFoldController.create(context, DEFAULT_DISPLAY);
            } else if (SystemProperties.getBoolean("persist.debug.force_foldable", false)) {
                mDisplayFoldController = DisplayFoldController.createWithProxSensor(context,
                        DEFAULT_DISPLAY);
            }
            mAccessibilityManager = (AccessibilityManager) context.getSystemService(
                    Context.ACCESSIBILITY_SERVICE);
            // register for dock events
            .............................................
            mWindowManagerInternal.registerAppTransitionListener(new AppTransitionListener() {
                @Override
                public int onAppTransitionStartingLocked(int transit, long duration,
                        long statusBarAnimationStartTime, long statusBarAnimationDuration) {
                    return handleStartTransitionForKeyguardLw(transit, duration);
                }
                @Override
                public void onAppTransitionCancelledLocked(int transit) {
                    handleStartTransitionForKeyguardLw(transit, 0 /* duration */);
                }
            });
            mKeyguardDelegate = new KeyguardServiceDelegate(mContext,
                    new StateCallback() {
                        @Override
                        public void onTrustedChanged() {
                            mWindowManagerFuncs.notifyKeyguardTrustedChanged();
                        }
                        @Override
                        public void onShowingChanged() {
                            mWindowManagerFuncs.onKeyguardShowingAndNotOccludedChanged();
                        }
                    });
        }
    
    WindowManagerService::displayReady
    traceBeginAndSlog("MakeDisplayReady");
          try {
              wm.displayReady();
          } catch (Throwable e) {
            reportWtf("making display ready", e);
         }
         traceEnd();
      public void displayReady() {
            synchronized (mGlobalLock) {
                if (mMaxUiWidth > 0) {
                    mRoot.forAllDisplays(displayContent -> displayContent.setMaxUiWidth(mMaxUiWidth));
                }
                final boolean changed = applyForcedPropertiesForDefaultDisplay();
                mAnimator.ready();//WindowAnimator
                mDisplayReady = true;
                if (changed) {
                    reconfigureDisplayLocked(getDefaultDisplayContentLocked());
                }
                mIsTouchDevice = mContext.getPackageManager().hasSystemFeature(
                        PackageManager.FEATURE_TOUCHSCREEN);
            }
            try {
                mActivityTaskManager.updateConfiguration(null);
            } catch (RemoteException e) {
            }
            updateCircularDisplayMaskIfNeeded();
        }
    
    WindowManagerService::systemReady
        traceBeginAndSlog("MakeWindowManagerServiceReady");
            try {
                wm.systemReady();
            } catch (Throwable e) {
                reportWtf("making Window Manager Service ready", e);
            }
            traceEnd();
     public void systemReady() {
            mSystemReady = true;
            mPolicy.systemReady();//PhoneWindowManager对象
            mRoot.forAllDisplayPolicies(DisplayPolicy::systemReady);
            mTaskSnapshotController.systemReady();
            mHasWideColorGamutSupport = queryWideColorGamutSupport();
            mHasHdrSupport = queryHdrSupport();
            UiThread.getHandler().post(mSettingsObserver::updateSystemUiSettings);
            UiThread.getHandler().post(mSettingsObserver::updatePointerLocation);
            IVrManager vrManager = IVrManager.Stub.asInterface(
                    ServiceManager.getService(Context.VR_SERVICE));
            if (vrManager != null) {
                try {
                    final boolean vrModeEnabled = vrManager.getVrModeState();
                    synchronized (mGlobalLock) {
                        vrManager.registerListener(mVrStateCallbacks);
                        if (vrModeEnabled) {
                            mVrModeEnabled = vrModeEnabled;
                            mVrStateCallbacks.onVrStateChanged(vrModeEnabled);
                        }
                    }
                } catch (RemoteException e) {
                    // Ignore, we cannot do anything if we failed to register VR mode listener
                }
            }
        }
    
    PhoneWindowManager.java::systemReady
     public void systemReady() {
            // In normal flow, systemReady is called before other system services are ready.
            // So it is better not to bind keyguard here.
            mKeyguardDelegate.onSystemReady();//keyguard
            mVrManagerInternal = LocalServices.getService(VrManagerInternal.class);
            if (mVrManagerInternal != null) {
              mVrManagerInternal.addPersistentVrModeStateListener(mPersistentVrModeListener);
            }
            readCameraLensCoverState();
            updateUiMode();
            mDefaultDisplayRotation.updateOrientationListener();
            synchronized (mLock) {
                mSystemReady = true;
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        updateSettings();
                    }
                });
                // If this happens, for whatever reason, systemReady came later than systemBooted.
                // And keyguard should be already bound from systemBooted
                if (mSystemBooted) {
                    mKeyguardDelegate.onBootCompleted();
                }
            }
            mAutofillManagerInternal = LocalServices.getService(AutofillManagerInternal.class);
        }
    
    WindowManagerService.java中重要的变量
    • WindowManagerPolicy mPolicy
      对应的实现类PhoneWindowManager,主要是窗口管理的策略和按键的处理

    • final ActivityManagerInternal mAmInternal;
      对应的是AMS,持有AMS对象

    • final ActivityTaskManagerInternal mAtmInternal;
      管理Task的,android10.0新增

    • final ArraySet<Session> mSessions = new ArraySet<>();
      会话,主要是建立和surfaceFinger的连接

    • final WindowHashMap mWindowMap = new WindowHashMap();
      缓存windowstate

    AMS,WMS之间数据是对应的,通过token值可以在AMS,WMS,应用程序之后来唯一确定一组Window,token是关联着一组窗口的,可能有多个WindowState的token值是相同的.

    小结

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

    相关文章

      网友评论

          本文标题:WMS 启动流程

          本文链接:https://www.haomeiwen.com/subject/uomqprtx.html