Android14 WMS启动流程

一 概述

本文Android14源代码可参考:Search

在 Android 系统中,从设计的角度来看,窗口管理系统是基于 C/S 模式的。整个窗口系统分为服务端和客户端两大部分,客户端负责请求创建窗口和使用窗口,服务端完成窗口的维护,窗口显示等。

WMS 在 Android 系统的地位,它作为中间层,连接了上层的 View 框架和下层的 SurfaceFingler。

SurfaceFingler在systrace的表现可以参考:Perfetto详细解析-CSDN博客

WMS 主要职责

窗口管理:负责启动、添加、删除窗口,管理窗口大小、层级,核心成员有:WindowContainer、RootWindowContainer、DisplayContent、TaskStack、Task、AppWindowToken、WindowState;

窗口动画:由其子系统 WindowAnimator 管理;

输入系统中转站:通过对窗口的触摸从而产生触摸事件,由 InputMethodService(IMS)对触摸事件进行处理,它会寻找一个最合适的窗口处理触摸反馈信息;

Surface 管理:为每个窗口分配一块 Surface,用于绘制要显示的内容。

二、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 类,用于将任务加入到主线程的消息队列中,这样代码逻辑就会在主线程中执行。

三、WMS 的启动流程

3.1 SystemServer.java

3.1.1 main(String[] args)

/**
 * The main entry point from zygote.
 */
public static void main(String[] args) {
    new SystemServer().run();
}

main方法中只调用了SystemServer的run方法,如下所示。

3.1.2 run()

从下面的注释中可以看到,官方把系统服务分为了三种类型,分别是引导服务、核心服务和其他服务,其中其他服务是一些非紧要和一些不需要立即启动的服务。系统服务总共大约有80多个,我们主要来查看引导服务WMS是如何启动的。

private void run() {
      		 // Initialize native services.
         	//1.加载了动态库libandroid_servers.so
           System.loadLibrary("android_servers");
       ......
	         // Create the system service manager.
        	 //2.创建SystemServiceManager,它会对系统的服务进行创建、启动和生命周期管理。
	         mSystemServiceManager = new SystemServiceManager(mSystemContext);
	         mSystemServiceManager.setStartInfo(mRuntimeRestart,
	                 mRuntimeStartElapsedTime, mRuntimeStartUptime);
	         mDumper.addDumpable(mSystemServiceManager);
	     ......   
			    	// Start services.
        try {
           t.traceBegin("StartServices");
           //用SystemServiceManager启动了ActivityManagerService、PowerManagerService、PackageManagerService等服务。
			 		 startBootstrapServices(t);
           //启动了BatteryService、UsageStatsService和WebViewUpdateService。
           startCoreServices(t);
        	 //启动了CameraService、WindowManagerService、VrManagerService等服务。这些服务的父类均为SystemService。
           startOtherServices(t);
        	 startApexServices(t);
           // Only update the timeout after starting all the services so that we use
           // the default timeout to start system server.
           updateWatchdogTimeout(t);
       } catch (Throwable ex) {
           Slog.e("System", "******************************************");
           Slog.e("System", "************ Failure starting system services", ex);
           throw ex;
       } finally {
           t.traceEnd(); // StartServices
       }
       ...
   }

3.1.3 startOtherServices(@NonNull TimingsTraceAndSlog t)

private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
			t.traceBegin("startOtherServices");
			mSystemServiceManager.updateOtherServicesStartIndex();
......
			t.traceBegin("StartInputManagerService");
		  // wms与 InputManagerService 息息相关,创建 InputManagerService 对象
			inputManager = new InputManagerService(context);
			t.traceEnd();
......
			t.traceBegin("StartWindowManagerService");
			// WMS needs sensor service ready
			mSystemServiceManager.startBootPhase(t, SystemService.PHASE_WAIT_FOR_SENSOR_SERVICE);
			 3.2. 创建 WindowManagerService 对象
			wm = WindowManagerService.main(context, inputManager, !mFirstBoot,
			        new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
    	// 将WindowManagerService添加到服务中
			ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
			        DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
    	// 将InputManagerService 添加到服务中
			ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
			        /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
			t.traceEnd();
    	
			t.traceBegin("SetWindowManagerService");
    	 3.3. wms 与 ams 关联
			mActivityManagerService.setWindowManager(wm);
			t.traceEnd();
    
			t.traceBegin("WindowManagerServiceOnInitReady");
    	// 3.4 初始化完成
			wm.onInitReady();
			t.traceEnd();
			t.traceBegin("StartInputManager");
    	// 3.5 InputManagerService 设置回调,并启动 InputManagerService 
			inputManager.setWindowManagerCallbacks(wm.getInputManagerCallback());
			inputManager.start();
			t.traceEnd();
......
      t.traceBegin("MakeDisplayReady");
      try {
        	// 3.6 调用 displayReady 方法
          wm.displayReady();
      } catch (Throwable e) {
          reportWtf("making display ready", e);
      }
      t.traceEnd();
			t.traceBegin("MakeDisplayReady");
			try {
			    wm.displayReady();
			} catch (Throwable e) {
			    reportWtf("making display ready", e);
			}
			t.traceEnd();
      ......
			try {
        	//3.7 系统准备完毕,调用 systemReady
			    wm.systemReady();
			} catch (Throwable e) {
			    reportWtf("making Window Manager Service ready", e);
			}
			t.traceEnd();
......
}

下面根据注释的1-6跟进源码查看

3.2 创建 WindowManagerService 对象

3.2.1 WindowManagerService.java & WindowManagerService main(...)

public static WindowManagerService main(final Context context, final InputManagerService im,
        final boolean showBootMsgs, WindowManagerPolicy policy,
        ActivityTaskManagerService atm) {
    return main(context, im, showBootMsgs, policy, atm, new DisplayWindowSettingsProvider(),
            SurfaceControl.Transaction::new, SurfaceControl.Builder::new);
}
//PhoneWindowManager,主要是负责窗口管理的各种策略。在 android.display 实例化 wms,所以wms 跑在android.display线程中

// 一个Supplier可以通过lambda表达式、方法引用或默认构造函数来实例化。

// Supplier在Java 8中被引入,属于java.util.function包

// transactionFactory 为 SurfaceControl.Transaction::new,创建 Transaction 对象

// 通过get 可以获取到对象 Transaction



/**
 * Creates and returns an instance of the WindowManagerService. This call allows the caller
 * to override factories that can be used to stub native calls during test.
 */
@VisibleForTesting
public static WindowManagerService main(final Context context, final InputManagerService im,
        final boolean showBootMsgs, WindowManagerPolicy policy, ActivityTaskManagerService atm,
        DisplayWindowSettingsProvider displayWindowSettingsProvider,
        Supplier<SurfaceControl.Transaction> transactionFactory,
        Function<SurfaceSession, SurfaceControl.Builder> surfaceControlFactory) {
    final WindowManagerService[] wms = new WindowManagerService[1];
  	//3.2.2运行在"android.display"线程
  	//3.2.4运行 runWithScissors
    DisplayThread.getHandler().runWithScissors(() ->
						//执行WindowManagerService构造函数
            wms[0] = new WindowManagerService(context, im, showBootMsgs, policy, atm,
                    displayWindowSettingsProvider, transactionFactory,
                    surfaceControlFactory), 0);
    return wms[0];
}

3.2.2 DisplayThread.java & getHandler()

DisplayThread 给系统使用的共享单例前台线程类,线程名字为 android.display,专门提供给WindowManager, DisplayManager, InputManager来执行快速响应的实时操作。

public final class DisplayThread extends ServiceThread {
    private static DisplayThread sInstance;
    private static Handler sHandler;

    private DisplayThread() {
        // DisplayThread runs important stuff, but these are not as important as things running in
        // AnimationThread. Thus, set the priority to one lower.
 
// 线程名字为 "android.display",优先级为 -3
        super("android.display", Process.THREAD_PRIORITY_DISPLAY + 1, false /*allowIo*/);
    }

    private static void ensureThreadLocked() {
        if (sInstance == null) {
            sInstance = new DisplayThread();
            sInstance.start();
            sInstance.getLooper().setTraceTag(Trace.TRACE_TAG_SYSTEM_SERVER);
						// 调用makeSharedHandler,跟进代码
            sHandler = makeSharedHandler(sInstance.getLooper());
        }
    }

    public static DisplayThread get() {
        synchronized (DisplayThread.class) {
            ensureThreadLocked();
            return sInstance;
        }
    }
// 获取到handler
    public static Handler getHandler() {
        synchronized (DisplayThread.class) {
            ensureThreadLocked();
            return sHandler;
        }
    }

    /**
     * Disposes current display thread if it's initialized. Should only be used in tests to set up a
     * new environment.
     */
    @VisibleForTesting
    public static void dispose() {
        synchronized (DisplayThread.class) {
            if (sInstance == null) {
                return;
            }
          	//handler 执行 runWithScissors 方法
            getHandler().runWithScissors(() -> sInstance.quit(), 0 /* timeout */);
            sInstance = null;
        }
    }
}

3.2.3 ServiceThread.java $ makeSharedHandler()

public class ServiceThread extends HandlerThread {
    private static final String TAG = "ServiceThread";

    private final boolean mAllowIo;

    public ServiceThread(String name, int priority, boolean allowIo) {
        super(name, priority);
        mAllowIo = allowIo;
    }

    @Override
    public void run() {
        Process.setCanSelfBackground(false);

        if (!mAllowIo) {
            StrictMode.initThreadDefaults(null);
        }

        super.run();
    }

		//创建handler,looper 为 thread "android.display" 的looper
    protected static Handler makeSharedHandler(Looper looper) {
        return new Handler(looper, /*callback=*/ null, /* async=*/ false, /* shared=*/ true);
    }
}

3.2.4 Handler.java & runWithScissors()

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

    if (Looper.myLooper() == mLooper) {
        r.run();
        return true;
    }

    BlockingRunnable br = new BlockingRunnable(r);
// 返回BlockingRunnable的postAndWait
    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 {
               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 {
													 // 阻塞systemserver 主线程
                           wait();
                       } catch (InterruptedException ex) {
                       }
                   }
               }
            }
            return true;
        }
    }
}

3.2.5 WindowManagerService构造函数

private WindowManagerService(Context context, InputManagerService inputManager,
        boolean showBootMsgs, boolean onlyCore, WindowManagerPolicy policy,
        ActivityTaskManagerService atm, DisplayWindowSettingsProvider
        displayWindowSettingsProvider, Supplier<SurfaceControl.Transaction> transactionFactory,
        Supplier<Surface> surfaceFactory,
        Function<SurfaceSession, SurfaceControl.Builder> surfaceControlFactory) {
    installLock(this, INDEX_WINDOW);
		// 锁机制与 atm 一致
    mGlobalLock = atm.getGlobalLock();
		// 缓存 AtmS
    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, myPid(), myUid(), /* hasPermission = */ true);
    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);

    mLetterboxConfiguration = new LetterboxConfiguration(
            // Using SysUI context to have access to Material colors extracted from Wallpaper.
            ActivityThread.currentActivityThread().getSystemUiContext());
		// Must be before createDisplayContentLocked.
    mInputManager = inputManager; 
    mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
    mPossibleDisplayInfoMapper = new PossibleDisplayInfoMapper(mDisplayManagerInternal);

    mSurfaceControlFactory = surfaceControlFactory;
    mTransactionFactory = transactionFactory;
    mSurfaceFactory = surfaceFactory;
		// 获取 Transaction  对象
    mTransaction = mTransactionFactory.get();

    mPolicy = policy;
		// 创建 WindowAnimator 对象
    mAnimator = new WindowAnimator(this);
		// 创建 RootWindowContainer 对象
    mRoot = new RootWindowContainer(this);

    final ContentResolver resolver = context.getContentResolver();
    mUseBLAST = Settings.Global.getInt(resolver,
        Settings.Global.DEVELOPMENT_USE_BLAST_ADAPTER_VR, 1) == 1;

    mSyncEngine = new BLASTSyncEngine(this);

    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);
		// mH 为  final H mH = new H();
    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);
    mTaskSystemBarsListenerController = new TaskSystemBarsListenerController();

    mActivityManager = ActivityManager.getService();
    mAmInternal = LocalServices.getService(ActivityManagerInternal.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);
    mTestUtilityService = LocalServices.getService(TestUtilityService.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);

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

    final String displaySettingsPath = Settings.Global.getString(resolver,
            DEVELOPMENT_WM_DISPLAY_SETTINGS_PATH);
    mDisplayWindowSettingsProvider = displayWindowSettingsProvider;
    if (displaySettingsPath != null) {
        mDisplayWindowSettingsProvider.setBaseSettingsFilePath(displaySettingsPath);
    }
    mDisplayWindowSettings = new DisplayWindowSettings(this, mDisplayWindowSettingsProvider);

    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);
    mDragDropController = new DragDropController(this, mH.getLooper());

    mHighRefreshRateDenylist = HighRefreshRateDenylist.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());

    mDisplayHashController = new DisplayHashController(mContext);
    setGlobalShadowSettings();
    mAnrController = new AnrController(this);
    mStartingSurfaceController = new StartingSurfaceController(this);
		// anr 控制类,无响应,无焦点等
    mBlurController = new BlurController(mContext, mPowerManager);
    mTaskFpsCallbackController = new TaskFpsCallbackController(mContext);
    mAccessibilityController = new AccessibilityController(this);
}

3.3 关联wms 与 ams

3.3.1 ActivityTaskManagerService.java & setWindowManager()

public void setWindowManager(WindowManagerService wm) {
   synchronized (mGlobalLock) {
       mWindowManager = wm;
    	 // 缓存 RootWindowContainer
       mRootWindowContainer = wm.mRoot;
       mWindowOrganizerController.setWindowManager(wm);
        mTempConfig.setToDefaults();
        mTempConfig.setLocales(LocaleList.getDefault());
        mConfigurationSeq = mTempConfig.seq = 1;
        mRootWindowContainer.onConfigurationChanged(mTempConfig);
        mLockTaskController.setWindowManager(wm);
        mTaskSupervisor.setWindowManager(wm);
				// RootWindowContainer 设置 WindowManager
        mRootWindowContainer.setWindowManager(wm);
        if (mBackNavigationController != null) {
            mBackNavigationController.setTaskSnapshotController(wm.mTaskSnapshotController);
        }
    }
}

3.4 初始化完成 onInitReady

3.4.1 WindowManagerService.java & onInitReady

//3.4.1 初始化完成 onInitReady
public void onInitReady() {
    initPolicy();

    // Add ourself to the Watchdog monitors.
    Watchdog.getInstance().addMonitor(this);
    createWatermark();
    showEmulatorDisplayOverlayIfNeeded();
}

private void initPolicy() {
		// 在ui 线程执行下列函数,"android.ui"
    UiThread.getHandler().runWithScissors(new Runnable() {
        @Override
        public void run() {
            WindowManagerPolicyThread.set(Thread.currentThread(), Looper.myLooper());
            //3.4.2 初始化 PhoneWindowManager
						mPolicy.init(mContext, WindowManagerService.this);
        }
    }, 0);
}

3.4.2 PhoneWindowManager.java & init()

mHandler = new PolicyHandler();

public void init(Context context, WindowManagerFuncs funcs) {
    init(new Injector(context, funcs));
}

@VisibleForTesting
void init(Injector injector) {
  mContext = injector.getContext();
  mWindowManagerFuncs = injector.getWindowManagerFuncs();
  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);
  mSensorPrivacyManager = mContext.getSystemService(SensorPrivacyManager.class);
  mDisplayManager = mContext.getSystemService(DisplayManager.class);
  mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
  mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
  mPackageManager = mContext.getPackageManager();
  mHasFeatureWatch = mPackageManager.hasSystemFeature(FEATURE_WATCH);
  mHasFeatureLeanback = mPackageManager.hasSystemFeature(FEATURE_LEANBACK);
  mHasFeatureAuto = mPackageManager.hasSystemFeature(FEATURE_AUTOMOTIVE);
  mHasFeatureHdmiCec = mPackageManager.hasSystemFeature(FEATURE_HDMI_CEC);
  mAccessibilityShortcutController = injector.getAccessibilityShortcutController(
          mContext, new Handler(), mCurrentUserId);
  mGlobalActionsFactory = injector.getGlobalActionsFactory();
  mLockPatternUtils = new LockPatternUtils(mContext);
  mLogger = new MetricsLogger();

  mScreenOffSleepTokenAcquirer = mActivityTaskManagerInternal
          .createSleepTokenAcquirer("ScreenOff");

  Resources res = mContext.getResources();
  mWakeOnDpadKeyPress =
          res.getBoolean(com.android.internal.R.bool.config_wakeOnDpadKeyPress);
  mWakeOnAssistKeyPress =
          res.getBoolean(com.android.internal.R.bool.config_wakeOnAssistKeyPress);
  mWakeOnBackKeyPress =
          res.getBoolean(com.android.internal.R.bool.config_wakeOnBackKeyPress);

  // Init display burn-in protection
  boolean burnInProtectionEnabled = mContext.getResources().getBoolean(
          com.android.internal.R.bool.config_enableBurnInProtection);
  // Allow a system property to override this. Used by developer settings.
  boolean burnInProtectionDevMode =
          SystemProperties.getBoolean("persist.debug.force_burn_in", false);
  if (burnInProtectionEnabled || burnInProtectionDevMode) {
      final int minHorizontal;
      final int maxHorizontal;
      final int minVertical;
      final int maxVertical;
      final int maxRadius;
      if (burnInProtectionDevMode) {
          minHorizontal = -8;
          maxHorizontal = 8;
          minVertical = -8;
          maxVertical = -4;
          maxRadius = (isRoundWindow()) ? 6 : -1;
      } else {
          Resources resources = mContext.getResources();
          minHorizontal = resources.getInteger(
                  com.android.internal.R.integer.config_burnInProtectionMinHorizontalOffset);
          maxHorizontal = resources.getInteger(
                  com.android.internal.R.integer.config_burnInProtectionMaxHorizontalOffset);
          minVertical = resources.getInteger(
                  com.android.internal.R.integer.config_burnInProtectionMinVerticalOffset);
          maxVertical = resources.getInteger(
                  com.android.internal.R.integer.config_burnInProtectionMaxVerticalOffset);
          maxRadius = resources.getInteger(
                  com.android.internal.R.integer.config_burnInProtectionMaxRadius);
      }
      mBurnInProtectionHelper = new BurnInProtectionHelper(
              mContext, minHorizontal, maxHorizontal, minVertical, maxVertical, maxRadius);
  }
....
// handler是跑在ui 线程
 mSideFpsEventHandler = new SideFpsEventHandler(mContext, mHandler, mPowerManager);

3.5 InputManagerService 设置回调,并启InputManagerService

3.5.1 InputManagerService.java & setWindowManagerCallbacks

public void setWindowManagerCallbacks(WindowManagerCallbacks callbacks) {
		// 保证只有一个 callback
    if (mWindowManagerCallbacks != null) {
        unregisterLidSwitchCallbackInternal(mWindowManagerCallbacks);
    }
    mWindowManagerCallbacks = callbacks;
    registerLidSwitchCallbackInternal(mWindowManagerCallbacks);
}

3.5.2 InputManagerService.java & registerLidSwitchCallbackInternal()

void registerLidSwitchCallbackInternal(@NonNull LidSwitchCallback callback) {
    synchronized (mLidSwitchLock) {
				// 将 callback 保存到 mLidSwitchCallbacks
        mLidSwitchCallbacks.add(callback);
        // Skip triggering the initial callback if the system is not yet ready as the switch
        // state will be reported as KEY_STATE_UNKNOWN. The callback will be triggered in
        // systemRunning().
        if (mSystemReady) {
            boolean lidOpen = getSwitchState(-1 /* deviceId */, InputDevice.SOURCE_ANY, SW_LID)
                    == KEY_STATE_UP;
            callback.notifyLidSwitchChanged(0 /* whenNanos */, lidOpen);
        }
    }
}

3.5.3 InputManagerService.java & start()

public void start() {
    Slog.i(TAG, "Starting input manager");
    mNative.start();
    // Add ourselves to the Watchdog monitors.
    Watchdog.getInstance().addMonitor(this);
}

3.6 调用 displayReady 方法

3.6.1 WindowManagerService.java & 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);
        mIsFakeTouchDevice = mContext.getPackageManager().hasSystemFeature(
                PackageManager.FEATURE_FAKETOUCH);
    }

    mAtmService.updateConfiguration(null /* request to compute config */);
}

3.7 系统准备完毕,调用 systemReady

public void systemReady() {
    mSystemReady = true;
		// 调用 PhoneWindowManager的systemReady
    mPolicy.systemReady();
    mRoot.forAllDisplayPolicies(DisplayPolicy::systemReady);
  	// 快照控制类
    mSnapshotController.systemReady();
    mHasWideColorGamutSupport = queryWideColorGamutSupport();
    mHasHdrSupport = queryHdrSupport();
  	// ui线程执行 loadSettings
    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
        }
    }
}

整个启动过程有3个线程,systemserver主线程,”android.display”,”android.ui”,整个过程采用阻塞的方式(利用runWithScissors)执行,WMS.mH的Looper运行在”android.display”进程。

参考:

WMS启动流程分析 | Skytoby

WMS—启动过程 - Gityuan博客 | 袁辉辉的技术博客

Android渲染(一)_系统服务WMS启动过程(基于Android10) - 掘金

Android窗口管理2 WMS启动过程_postandwait-CSDN博客

【安卓12源码】WMS的作用及其启动流程_android wms_蜘蛛侠不会飞的博客-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/108908.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

解决找不到vcruntime140.dll,无法继续执行代码方法

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“找不到vcruntime140.dll”。这个错误通常发生在运行某些程序或游戏时&#xff0c;它会导致程序无法正常启动或运行。那么&#xff0c;找不到vcruntime140.dll&#xff0c;无法继续执行代码…

kafka入门03——简单实战

目录 安装Java 安装Zookeeper 安装Kafka 生产与消费 主要是记录下Kafka的安装配置过程&#xff0c;前置条件需要安装jdk和zookeeper。 安装Java 1.Oracle官网下载对应jdk安装包 官网地址&#xff1a;Java Downloads | Oracle 好人分享了下载需要的oracle账号&#xff0c…

C# Socket通信从入门到精通(6)——单个同步TCP服务器监听多个客户端C#代码实现

前言: 我们在C# Socket通信从入门到精通(5)——单个同步TCP服务器监听一个客户端C#代码实现这篇文章中讲述了一个服务器如何与一个客户端进行交互,但是有时候我们需要一个服务器与多个客户端进行交互,这时候上一篇文章介绍的方法就不足以实现这个功能,本篇文章就是介绍如…

flask 实践

flask框架研究&#xff1a; https://blog.csdn.net/shifengboy/article/details/114274271 https://blog.csdn.net/weixin_67531112/article/details/128256170 实现下载文件功能 vim test.py import io from flask import Flask, send_fileapp Flask(__name__) app.route(/…

【数据结构】模拟实现栈和队列

文章目录 栈&#xff08;Stack&#xff09;栈的概念栈的常用方法模拟实现栈 队列&#xff08;Queue&#xff09;队列的概念队列的常用方法队列的模拟实现循环队列模拟实现 栈&#xff08;Stack&#xff09; 栈的概念 栈是一种特殊的线性表&#xff0c;只允许在固定的一端进行…

私有云:【12】使用connention托管虚拟桌面

私有云&#xff1a;【12】使用connention托管虚拟桌面 1、使用connention托管虚拟桌面 1、使用connention托管虚拟桌面 使用cloudadmin用户登录connection服务器 登录connection客户端 创建桌面池 选择手动桌面池 选择vcenter虚拟机 选择vcenter.test.com 按如下选择下一步 设…

uniapp 在 Android Studio 模拟器中运行项目

在开发App时&#xff0c;无论是使用 Flutter 还是 React native&#xff0c;还是使用uni-app 开发跨端App时&#xff0c;总是需要运行调试。一般调试分为两种。 第一&#xff1a;真机调试 第二&#xff1a;模拟器调试 真机调试的好处是可以看到更好的效果&#xff0c;缺点就是…

JavaScript对象与原型

目录 对象的创建 原型与原型链 原型继承 总结 在JavaScript中&#xff0c;对象是非常重要的概念之一。它们允许我们以一种结构化的方式存储和组织数据&#xff0c;并提供了一种方便的方式来操作和访问这些数据。而对象的行为和属性则通过原型来定义。 对象的创建 在JavaS…

【Leetcode】【每日一题】【中等】274. H 指数

力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能&#xff0c;轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/h-index/description/?envTyped…

蚁群算法求包含34个国内城市的TSP,和最优解相差没那么大

文章目录 引言蚁群觅食算法原理代码实现ACO求解TSP整数规划求解TSP 相关阅读 引言 上一篇介绍的差分进化算法&#xff0c;很适合求解连续变量的优化问题&#xff1b;但针对组合优化问题&#xff0c;就不是很适用了。 至于哪一种智能优化算法更适合求解组合优化问题&#xff0…

vim使用

概述 vi&#xff08;visual editor&#xff09;是Unix/Linux编辑器的一种。类似于win中notepad。vim&#xff08;vi improved&#xff09;加强版 安装vim&#xff1a; $ yum install vim -y四种模式 命令模式&#xff1a;快速进行复制、粘贴、删除等操作&#xff0c;还可以…

【深度学习】Transformer、GPT、BERT、Seq2Seq什么区别?

请看vcr&#xff1a;https://transformers.run/back/transformer/

项目管理49个过程定义与作用、五大过程组

五大过程组&#xff1a; 49个过程的定义与作用&#xff1a; 1.整合管理&#xff1a; (1)制定项目章程&#xff1a;制定项目章程是编写一份正式批准项目并授予项目经理权力的文件的过程&#xff0c;其作用是①确立组织与项目的关系&#xff1b;②展示组织对项目的承诺&#xff…

超全整理,服务端性能测试-docker部署tomcat/redis(详细步骤)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、docker部署tom…

大彩串口屏读写文件问题

分区 本文使用的是大彩串口屏M系列的&#xff1a; 串口屏内部有三个分区&#xff0c;分别为A、B、C三个区&#xff1a; A区&#xff1a;系统区&#xff0c;存储组态工程文件 B区&#xff1a;数据区&#xff0c;存储配置信息&#xff0c;记录数据、历史曲线等 C区&#xff1a;备…

并发编程

什么是并发编程&#xff1f; 并行&#xff1a;在同一个时间节点上&#xff0c;多个线程同时执行(是真正意义上的同时执行) 并发&#xff1a;一个时间段内&#xff0c;多个线程依次执行。 并发编程&#xff1a;在例如买票、抢购、秒杀等等场景下&#xff0c;有大量的请求访问…

git 推送到github远程仓库细节处理(全网最良心)

我查看了很多网上的教程都不是很好 我们先在github创建一个仓库&#xff0c;且初始化 readme 我们到本地文件初始化仓库 添加远程仓库 这时候我们就 git add . , git commit ,再准备git push 的时候 显示没有指定远程的分支 我们按照提示操作 提示我们要先git pull 提示我…

激活函数作用以及 sigmoid和softmax

激活函数 激活函数在神经网络中起着非常重要的作用&#xff0c;它的主要功能是引入非线性性质&#xff0c;使得神经网络可以学习和表示更加复杂的模式和关系。下面是激活函数的几个主要作用&#xff1a; 引入非线性&#xff1a;激活函数通过引入非线性变换&#xff0c;打破了…

Kubernetes - Ingress HTTP 负载搭建部署解决方案(新版本v1.21+)

在看这一篇之前&#xff0c;如果不了解 Ingress 在 K8s 当中的职责&#xff0c;建议看之前的一篇针对旧版本 Ingress 的部署搭建&#xff0c;在开头会提到它的一些简介Kubernetes - Ingress HTTP 负载搭建部署解决方案_放羊的牧码的博客-CSDN博客 开始表演 1、kubeasz 一键安装…

M1安装OpenPLC Editor

下载OpenPLC Editor for macOS.zip文件后&#xff0c;使用tar -zvxf命令解压&#xff0c;然后将"OpenPLC Editor"拖入到"应用程序"文件夹 右键点击"OpenPLC Editor"&#xff0c;打开这个""文件&#xff0c;替换为以下内容 #!/bin/bash…