Android14 WMS启动流程

news2024/9/22 23:28:38

一 概述

本文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博客

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

智慧工地管理系统源码-数字孪生智慧工地可视化解决方案

一、智慧工地建设背景 我国经济发展正从传统粗放式的高速增长阶段&#xff0c;进入高效率、低成本、可持续的中高速增长阶段。随着现代建筑的复杂度和体量等不断增加&#xff0c;施工现场管理的内容越来越多&#xff0c;管理的技术难度和要求在不断提高。传统的施工现场管理模…

用超声波清洗机洗眼镜的有哪些?清洁力强的超声波清洗机不能错过

超声波清洗机在清洗眼镜方面表现出色&#xff0c;其强大的清洁能力可以彻底清除眼镜上的污垢和细菌。这种清洗方式被认为是一种高效且卫生的清洁方式&#xff0c;因为它利用高频振动和微射流打击力来清除污垢和细菌&#xff0c;而不是使用化学物质。对于那些长时间佩戴眼镜或者…

windows + ubuntu + vscode开发环境配置安装

一、卸载WSL/WSL2 如果安装了windows子系统的朋友&#xff0c;可以选择继续使用。或者提前卸载WSL&#xff0c;再选择安装虚拟机。虚拟机占用内存较大&#xff0c;WSL可能对于开发的一些需求还有欠缺。根据自己的实际情况进行选择。 WIN10/11安装WSL(请参考官方资料&#xff0c…

TSINGSEE青犀智慧仓储可视化视频智能监管系统方案

一、背景与需求 对于现在很多大型工厂或者物流基地来说&#xff0c;仓库无疑是存放物品的重点场所。仓储存放着大量货物&#xff0c;同时存在大量的辅助设备&#xff0c;需要进行全方位的监管&#xff0c;以避免发生安全事故&#xff0c;造成财产损失。原有的人工巡检方式已无…

Ubuntu安装AdGuardhome(树莓派安装AdGuardhome)

Ubuntu安装AdGuardhome&树莓派安装AdGuardhome 1.什么是AdGuardhome2.设备情况3.3.1.下载AdGuardhome3.2.解压3.3.安装3.4.仪表盘配置3.5.dns黑名单添加3.6.DNS白名单设置3.7常规设置3.8. dns设置3.9.加密设置 4.客户端设置 1.什么是AdGuardhome AdGuard Home 是网络范围的…

传奇服务器配置如何搭建

传奇服务器在中国页游发展中作为一个经典制作吸引了很多玩家的喜欢&#xff0c;很多人也想搭建一个属于自己团队的传奇游戏服务器&#xff0c;今天就让小编来讲一讲该如何搭建吧&#xff01; 首先是硬件配置&#xff0c;传奇游戏的服务器需要较高的硬件配置&#xff0c;选择双路…

Kubernetes数据卷Volume和数据卷分类(emptyDir、nfs、hostPath、ConfigMap)详解

Kubernetes数据卷Volume和数据卷分类详解 数据卷概述 Kubernetes Volume&#xff08;数据卷&#xff09;主要解决了如下两方面问题&#xff1a; 数据持久性&#xff1a;通常情况下&#xff0c;容器运行起来之后&#xff0c;写入到其文件系统的文件暂时性的。当容器崩溃后&am…

window系统修改rabbitmq 默认端口

安装完rabbitmq之后&#xff0c;默认的client端口是5672, 控制台访问端口是15672&#xff0c;rabbitmq管理工具启动之后在浏览器中输入地址&#xff1a; ​ ​http://localhost:15672/​​​ 就可以访问后台​ ​​​&#xff0c; 默认管理员账号&#xff1a;guest 密码&#x…

移动云获取推拉流地址

一&#xff1a;帮助文档&#xff1a; 移动云帮助中心https://ecloud.10086.cn/op-help-center/doc/category/753 二&#xff1a;准备工作&#xff1a; 1&#xff1a;进入移动云首页&#xff0c;点击【产品】>【视频服务】>【视频服务】>【视频直播】 点击【立即订购…

图纸管理制度 《五》

1、存档文件应由专人管理&#xff0c;其他人未征得管理人员同意&#xff0c;不得随意翻阅查看。 2、档案管理人员要认真贯彻执行公司相关制度&#xff0c;严禁泄露档案材料中的秘密。 彩虹图纸管理软件_图纸管理系统_图纸文档管理软件系统_彩虹EDM【官网】彩虹EDM图纸管理软件…

Linux进程控制/进程终止

一、系统调用fork函数 1、fork返回值及内核操作 #include <unistd.h> pid_t fork(void); 返回值&#xff1a;自进程中返回 0 &#xff0c;父进程返回子进程 id &#xff0c;出错返回 -1 进程调用fork&#xff0c;当控制转移到内核中的fork代码后&#xff0c;内核做&am…

UE4 体积云制作 学习笔记

首先Noise本来就是一张噪点图 云的扰动不能太大&#xff0c;将Scale调小&#xff0c;并将InputMin调整为0 形成这样一张扰动图 扰动需要根据材质在世界的位置进行调整&#xff0c;所以Position需要加上WorldPosition 材质在不同世界位置&#xff0c;噪点不同 除以一个数&#…

会声会影2024(Corel VideoStudio)正式版安装下载步骤教程

众所周知会声会影(Corel VideoStudio)2024为加拿大Corel公司发布的一款功能丰富的视频编辑软件。实际上我们可以这样讲添加样子和款式&#xff1a;使用数百种创意拖放效果和滤镜增个性和艺术格调。值得肯定的是添加趣味性3D标题&#xff0c;内置NewBlueFX和proDAD转场和防抖插件…

基于头脑风暴算法的无人机航迹规划-附代码

基于头脑风暴算法的无人机航迹规划 文章目录 基于头脑风暴算法的无人机航迹规划1.头脑风暴搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要&#xff1a;本文主要介绍利用头脑风暴算法来优化无人机航迹规划。 …

矩阵特征值与特征向量的理解

各位朋友大家好&#xff0c;我是小C哈哈哈&#xff0c;很高兴认识大家&#xff0c;在这里&#xff0c;我会将一些枯燥难懂的数学和算法知识以图片或动画的形式通俗易懂的展现给大家&#xff0c;希望大家喜欢。 线性代数中的矩阵特征值与特征向量这两个基本概念总是让很多人摸不…

接口自动化框架篇:流程封装与基于加密接口的测试用例设计

​接口测试仅仅掌握 Requests 或者其他一些功能强大的库的用法&#xff0c;是远远不够的&#xff0c;还需要具备能根据公司的业务流程以及需求去定制化一个接口自动化测试框架的能力。所以&#xff0c;接下来&#xff0c;我们主要介绍下接口测试用例分析以及通用的流程封装是如…

nginx配置域名(ssl和非ssl形式)

概要 本文以阿里云为例&#xff0c;浅要介绍如何将域名指向你的服务器&#xff0c;以及如何配置ssl和非ssl的方式。 购买域名 购买域名不做描述&#xff0c;本文域名以helloword.com为例 域名实名与备案 购买后&#xff0c;不实名和备案是无法使用的&#xff0c;这里不展开…

Games 103 作业二

Games 103 作业二 作业二其实就是要使用隐式积分和PBD两种方式来实现布料求解。难度相对于作业一来说要简单一些&#xff0c;在文档中基本把步骤都写清楚了。主要逻辑首先参考Lecture 05 PPT的第18页&#xff1a; 然后我们按照文档的步骤一步一步地来。注意0号顶点和20号顶点是…

JSX基础语法

文章目录 认识JSX语法JSX是什么为什么Rect选择了JSXJSX书写规范JSX注释编写 JSX的基本使用JSX的事件绑定this绑定问题参数传递问题 JSX的条件渲染常见的条件渲染方式 JSX的列表渲染JSX的原理和本质JSX的本质虚拟DOM的创建过程 案例练习 认识JSX语法 // 1. 定义根组件 const el…

【Truffle】一、Truffle的安装与部署

目录 一、准备安装 二、安装truffle 三、创建 Truffle 项目工程 1.为 Truffle 项目创建新目录&#xff1a; 2.下载 (“unbox”) MetaCoin box: 四、项目分析 五、测试合约 一、准备安装 安装truffle必须要提前配置Nodejs环境&#xff0c;关于Nodejs的配置&#xff0c;我在…