WindowManagerService的启动

本次源码基于Android11分析

相关源码:

/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/policy/PhoneWindowManager.java

1. WMS的启动过程

WindowManagerService服务在system_server进程中被启动,在其startOtherServices()方法中调用WMS.main()方法开始实例化WMS,如下是WMS的整体启动流程:

wms的启动过程
public final class SystemServer {

  private void run() {
      try {
          // 启动服务
          startBootstrapServices(t);
          startCoreServices(t);
          startOtherServices(t);
      } catch (Throwable ex) {
          throw ex;
      }
  }

  private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
      try {
          //...
          // 1. WindowManagerService启动
          wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore,
                  new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
          // 2. 调用WindowManagerService的onInitReady()方法
          wm.onInitReady();
          //...
          // 3.调用WindowManagerService的displayReady()方法
          wm.displayReady();
          // 4.调用WindowManagerService的systemReady()方法
          wm.systemReady(
      }
  }
}

首先调用WMS.main()实例化WindowManagerService对象,之后分别调用WMS.onInitReady()WMS.displayReady()WMS.systemReady()方法做后续的初始化操作。

1.2 WMS.main()

public class WindowManagerService extends IWindowManager.Stub
      implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {

  @VisibleForTesting
  public static WindowManagerService main(final Context context, final InputManagerService im,
                                          final boolean showBootMsgs, final boolean onlyCore, WindowManagerPolicy policy,
                                          ActivityTaskManagerService atm, Supplier<SurfaceControl.Transaction> transactionFactory,
                                          Supplier<Surface> surfaceFactory,
                                          Function<SurfaceSession, SurfaceControl.Builder> surfaceControlFactory) {
      // DisplayThread线程的创建WindowManagerService
      DisplayThread.getHandler().runWithScissors(() ->
              // 创建WindowManagerService()实例,
              sInstance = new WindowManagerService(context, im, showBootMsgs, onlyCore, policy,
                      atm, transactionFactory, surfaceFactory, surfaceControlFactory), 0);
      return sInstance;
  }

private WindowManagerService(Context context, InputManagerService inputManager,
                               boolean showBootMsgs, boolean onlyCore, WindowManagerPolicy policy,
                               ActivityTaskManagerService atm, Supplier<SurfaceControl.Transaction> transactionFactory,
                               Supplier<Surface> surfaceFactory,
                               Function<SurfaceSession, SurfaceControl.Builder> surfaceControlFactory) {
      installLock(this, INDEX_WINDOW);
      mGlobalLock = atm.getGlobalLock();
      mAtmService = atm;
      mContext = context;
      mIsPc = mContext.getPackageManager().hasSystemFeature(FEATURE_PC);
      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);
      inputManager.setInTouchMode(mInTouchMode);
      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);
      mAssistantOnTopOfDream = context.getResources().getBoolean(
              com.android.internal.R.bool.config_assistantOnTopOfDream);
      mInputManager = inputManager; // Must be before createDisplayContentLocked.
      mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);

      mSurfaceControlFactory = surfaceControlFactory;
      mTransactionFactory = transactionFactory;
      mSurfaceFactory = surfaceFactory;
      mTransaction = mTransactionFactory.get();

      mDisplayWindowSettings = new DisplayWindowSettings(this);
      mPolicy = policy;
      mAnimator = new WindowAnimator(this);
      mRoot = new RootWindowContainer(this);

      mUseBLAST = DeviceConfig.getBoolean(
              DeviceConfig.NAMESPACE_WINDOW_MANAGER_NATIVE_BOOT,
              WM_USE_BLAST_ADAPTER_FLAG, false);

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

      mDisplayNotificationController = new DisplayWindowListenerController(this);

      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(mTransactionFactory,
              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());

      mHighRefreshRateBlacklist = HighRefreshRateBlacklist.create(context.getResources());

      mConstants = new WindowManagerConstants(this, DeviceConfigInterface.REAL);
      mConstants.start(new HandlerExecutor(mH));

      LocalServices.addService(WindowManagerInternal.class, new LocalService());
      mEmbeddedWindowController = new EmbeddedWindowController(mAtmService);

      mDisplayAreaPolicyProvider = DisplayAreaPolicy.Provider.fromResources(
              mContext.getResources());

      setGlobalShadowSettings();
  }

}

通过DisplayThread线程的Handler,并调用其runWithScissors()方法,该方法会将当前的执行线程阻塞,并直到要执行的任务完成后,在重新唤醒被阻塞的线程:

public class Handler {

  public final boolean runWithScissors(@NonNull Runnable r, long timeout) {
      // 对runnable和time进行检查
      if (r == null) {
          throw new IllegalArgumentException("runnable must not be null");
      }
      if (timeout < 0) {
          throw new IllegalArgumentException("timeout must be non-negative");
      }

      // 检查当前线程的Looper是否等于此mLooper
      if (Looper.myLooper() == mLooper) {
          r.run(); // 直接运行Runnable.run
          return true;
      }

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

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

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

      @Override
      public void run() {
          try {
              // 执行Runnable创建WMS
              mTask.run();
          } finally {
              synchronized (this) {
                  mDone = true;
                  notifyAll();
              }
          }
      }

      public boolean postAndWait(Handler handler, long timeout) {
          // 将BlockingRunnable加入到handler中
          if (!handler.post(this)) {
              return false;
          }

          // 没执行完run()方法则调用wait()让调用的线程等待
          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 {
                  // 没执行完run()方法则调用
                  while (!mDone) {
                      try {
                          wait();
                      } catch (InterruptedException ex) {
                      }
                  }
              }
          }
          return true;
      }
  }
}

会判断当前执行的线程跟调用的Handler线程是否相等,相等则执行Runnable。如果不想等,则在封装一个Runnable,并在这个Runnable类中判断是否执行了run()方法,如果没有则阻塞当前的执行线程,直到执行完Run方法后才重新唤醒。
所以在DisplayThread线程中创建了WindowManagerService实例对象。

1.3 WMS.onInitReady()

public class WindowManagerService extends IWindowManager.Stub
      implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {


  public void onInitReady() {
      // 调用initPolicy()方法
      initPolicy();
      //...
  }

  private void initPolicy() {
      UiThread.getHandler().runWithScissors(new Runnable() {
          @Override
          public void run() {
              WindowManagerPolicyThread.set(Thread.currentThread(), Looper.myLooper());
              // 此mPolicy在构造函数中赋值,由SystemServer类中传入,为PhoneWindowManager()
              mPolicy.init(mContext, WindowManagerService.this, WindowManagerService.this);
          }
      }, 0);
  }

}


public class PhoneWindowManager implements WindowManagerPolicy {

  // 在UiThread线程中执行
  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);
      ...

      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");
      ...

      mGlobalKeyManager = new GlobalKeyManager(mContext);


      if (!mPowerManager.isInteractive()) {
          startedGoingToSleep(WindowManagerPolicy.OFF_BECAUSE_OF_USER);
          finishedGoingToSleep(WindowManagerPolicy.OFF_BECAUSE_OF_USER);
      }

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

}

在UiThread线程的Handler中执行PhoneWindowManager.init()方法,进行一些变量的的初始化操作。

1.4 WMS.displayReady()、systemReady()

public class WindowManagerService extends IWindowManager.Stub
      implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {

  // 继续在system_server进程中执行WMS.displayReady()方法
  public void displayReady() {
      synchronized (mGlobalLock) {
          if (mMaxUiWidth > 0) {
              mRoot.forAllDisplays(displayContent -> displayContent.setMaxUiWidth(mMaxUiWidth));
          }
          applyForcedPropertiesForDefaultDisplay();
          mAnimator.ready();
          mDisplayReady = true;
          // Reconfigure all displays to make sure that forced properties and
          // DisplayWindowSettings are applied.
          mRoot.forAllDisplays(DisplayContent::reconfigureDisplayLocked);
          mIsTouchDevice = mContext.getPackageManager().hasSystemFeature(
                  PackageManager.FEATURE_TOUCHSCREEN);
      }

      try {
          mActivityTaskManager.updateConfiguration(null);
      } catch (RemoteException e) {
      }
  }

  // 继续在system_server进程中执行WMS.systemReady()方法
  public void systemReady() {
      mSystemReady = true;
      // 执行PhoneWindowManager.systemReady()方法
      mPolicy.systemReady();
      mRoot.forAllDisplayPolicies(DisplayPolicy::systemReady);
      mTaskSnapshotController.systemReady();
      mHasWideColorGamutSupport = queryWideColorGamutSupport();
      mHasHdrSupport = queryHdrSupport();
      UiThread.getHandler().post(mSettingsObserver::loadSettings);
      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
          }
      }
  }
}

WMS.systemReady()方法会调用PhoneWindowManager.systemReady()方法:

public class PhoneWindowManager implements WindowManagerPolicy {

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

      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在system_server进程的启动就完成了,WMS主要有四大功能:

  1. Window窗口的管理
  2. Surface的管理
  3. Input系统的管理
  4. 窗口动画

如下是WindowManagerService的关联图:


©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容