Android 12系统源码_窗口管理(一)WindowManagerService的启动流程

这篇具有很好参考价值的文章主要介绍了Android 12系统源码_窗口管理(一)WindowManagerService的启动流程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

WindowManagerService是Android系统中重要的服务,它是WindowManager的管理者,WindowManagerService无论对于应用开发还是Framework开发都是重要的知识点,究其原因是因为WindowManagerService有很多职责,每个职责都会涉及重要且复杂的系统,这使得WindowManagerService就像一个十字路口的交通灯一样,没有了这个交通灯,十字路口就无法正常通车,WindowManagerService的职责只要有以下几点。

1)窗口管理
WindowManagerService是窗口的管理者,它负责窗口的启动、添加和删除,另外窗口的大小和层级也是由WMS进行管理的。窗口管理的核心成员由DisplayContent、WindowToken和WindowState。
2)窗口动画
窗口间进行切换时,使用窗口动画可以显得更炫一些,窗口动画由WMS的动画子系统来负责,动画子系统的管理者为WindowAnimator。
3)输入系统的中转站
通过对窗口的触摸从而产生触摸事件,InputManagerService(IMS)会对触摸事件进行处理,它会寻找一个最合适的窗口来处理触摸反馈信息,WindowManagerService是窗口的管理者,它作为输入系统的中转站再合适不过。
4)Surface管理
窗口并不具备绘制的功能,因此每个窗口都需要有一块Surface来供自己绘制,为每个窗口分配Surface时由WMS来完成的。
windowmanagerservice,Framework12源码,android
从上图可以看出WindowManagerService很复杂,与它关联的有窗口管理、窗口动画、输入系统和Surface,它们每一个都是重要且负责的系统,在具体讲述这些功能之前,我们需要先梳理一下WindowManagerService的启动流程,这样才能更好的理解这个服务。

一、SystemServer的启动WindowManagerService

1、系统启动后会启动JVM虚拟机,SystemServer 是虚拟机的第一个进程,由init 进程fork 产生。主要用来启动frameworks层中的服务。SystemServer进程里面有个main()方法,main 方法如下:

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

public final class SystemServer {
    public static void main(String[] args) {
        new SystemServer().run();
    }
}

2、main 方法里启动了 run() 方法,而在 run 方法中调用了startOtherServices() 方法:

public final class SystemServer {
   private void run() {
    	...代码省略...
        try {
            t.traceBegin("StartServices");
            startBootstrapServices(t);//引导服务
            startCoreServices(t);//核心服务
            startOtherServices(t);//其他服务
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        } finally {
            t.traceEnd(); // StartServices
        }
    	...代码省略...
    }
}

3、startOtherServices方法和WindowManagerService服务启动相关的代码如下所示。

public final class SystemServer {
  
  private ActivityManagerService mActivityManagerService;
  private boolean mOnlyCore;
  private boolean mFirstBoot;

  private void startOtherServices() {
           ...代码省略...
           WindowManagerService wm = null;
           InputManagerService inputManager = null;
           ...代码省略...
           boolean isWatch = context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH);
           ...代码省略...
           traceBeginAndSlog("StartInputManagerService");
           inputManager = new InputManagerService(context);//创建InputManagerService
           traceEnd();
           traceBeginAndSlog("StartWindowManagerService");
           // WMS needs sensor service ready
           ConcurrentUtils.waitForFutureNoInterrupt(mSensorServiceStart, START_SENSOR_SERVICE);
           mSensorServiceStart = null;
           //执行WMS的main方法,其内部会创建WMS对象实例
           wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore,
                    new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
           //将WMS注册到服务管理器中        
           ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
                    DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
           //将IMS注册到服务管理器中        
          ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
                    /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
           traceEnd();
           traceBeginAndSlog("SetWindowManagerService");
           mActivityManagerService.setWindowManager(wm);
           traceEnd();
           traceBeginAndSlog("WindowManagerServiceOnInitReady");
           wm.onInitReady();//调用WMS的onInitReady方法
           traceEnd();
           ...代码省略...        
        try {
            wm.displayReady();//初始化屏幕显示信息
        } catch (Throwable e) {
            reportWtf("making display ready", e);
        }
          ...代码省略...      
         if (!isWatch) {
              t.traceBegin("StartStatusBarManagerService");
              try {
              	  //状态栏管理服务
                  statusBar = new StatusBarManagerService(context);
                  ServiceManager.addService(Context.STATUS_BAR_SERVICE, statusBar);
              } catch (Throwable e) {
                  reportWtf("starting StatusBarManagerService", e);
              }
              t.traceEnd();
          }
         ...代码省略...       
        try {
            wm.systemReady();//通知WMS,系统的初始化工作已经完成
        } catch (Throwable e) {
            reportWtf("making Window Manager Service ready", e);
        }
         ...代码省略...       
    }
}     

二、WindowManagerService的启动

1、WindowManagerService的main方法如下

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

public class WindowManagerService extends IWindowManager.Stub
        implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {
        
     public static WindowManagerService main(final Context context, final InputManagerService im,
            final boolean showBootMsgs, final boolean onlyCore, WindowManagerPolicy policy,
            ActivityTaskManagerService atm) {
        return main(context, im, showBootMsgs, onlyCore, policy, atm,
                new DisplayWindowSettingsProvider(), SurfaceControl.Transaction::new, Surface::new,
                SurfaceControl.Builder::new);
    }

    /**
     * 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, final boolean onlyCore, WindowManagerPolicy policy,
            ActivityTaskManagerService atm, DisplayWindowSettingsProvider
            displayWindowSettingsProvider, Supplier<SurfaceControl.Transaction> transactionFactory,
            Supplier<Surface> surfaceFactory,
            Function<SurfaceSession, SurfaceControl.Builder> surfaceControlFactory) {
        DisplayThread.getHandler().runWithScissors(() ->
        		//创建WMS实例对象
                sInstance = new WindowManagerService(context, im, showBootMsgs, onlyCore, policy,
                        atm, displayWindowSettingsProvider, transactionFactory, surfaceFactory,
                        surfaceControlFactory), 0);
        return sInstance;
    }
}

DisplayThread的run方法中创建了WMS的实例,这就意味着WMS的创建是运行在android.display线程中的。
关于DisplayThread对象我们主要关注以下几点:
1)DisplayThread其实是一个名为android.display的单例前台线程。

frameworks/base/services/core/java/com/android/server/DisplayThread.java

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

    private DisplayThread() {
        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);
            sHandler = new Handler(sInstance.getLooper());
        }
    }

    public static DisplayThread get() {
        synchronized (DisplayThread.class) {
            ensureThreadLocked();
            return sInstance;
        }
    }

    public static Handler getHandler() {
        synchronized (DisplayThread.class) {
            ensureThreadLocked();
            return sHandler;
        }
    }
}

DisplayThread线程主要用来处理需要低延时显示的相关操作,并只能由WindowManager、DisplayManager和InputManager实时执行快速操作。
2)DisplayThread调用静态方法getHandler返回一个Handler对象实例,并调用了该对象的runWithScissors方法。

frameworks/base/core/java/android/os/Handler.java

public class Handler {
    public final boolean runWithScissors(final Runnable r, long timeout) {
        if (r == null) {
            throw new IllegalArgumentException("runnable must not be null");
        }
        //对传入的Runnable的timeout进行判断,如果Runnable为null或者timeout小于0则抛出异常。
        if (timeout < 0) {
            throw new IllegalArgumentException("timeout must be non-negative");
        }
		//根据每个线程只有一个Looper的原理来判断当前线程(system_server线程)是否是Handler所指向的线程(android.display线程),如果是则直接执行Runnable的run方法。
        if (Looper.myLooper() == mLooper) {
            r.run();
            return true;
        }
		//否则调用BlockingRunnable的postAndWait方法,并将当前线程的Runnable作为参数传递进去。
        BlockingRunnable br = new BlockingRunnable(r);
        return br.postAndWait(this, timeout);
    }
}

runWithScissors方法会对传入的Runnable的timeout进行判断,如果Runnable为null或者timeout小于0则抛出异常;并根据每个线程只有一个Looper的原理来判断当前线程(system_server线程)是否是Handler所指向的线程(android.display线程),如果是则直接执行Runnable的run方法;否则调用BlockingRunnable的postAndWait方法,并将当前线程的Runnable作为参数传递进去。

3)BlockingRunnable是Handler的内部类。

public class Handler {
 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的run方法,其实就是执行前面创建WindowManagerService对象实例的那段代码
                mTask.run();
            } finally {
                synchronized (this) {
                    mDone = true;
                    notifyAll();
                }
            }
        }
		
        public boolean postAndWait(Handler handler, long timeout) {
			//将当前自己发送给Handler
            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 {
                            //timeout为0,且mDone为false,则会将当前自己挂起
                            wait();
                        } catch (InterruptedException ex) {
                        }
                    }
                }
            }
            return true;
        }
    }
 }
  • BlockingRunnable的postAndWait方法首先将当前的BlockingRunnable添加到Handler的任务队列中,前面第2步我们知道runWithScissors方法的第二个参数为0,因此timeout等于0,这样如果mDone为false的话会一直调用注释3处的wait方法使得当前线程(system_server线程)进入等待状态。
  • 在BlockingRunnable将自身传给Handler之后,在合适的时机会执行传入的Runnable的run方法,其实就是创建WMS对象实例(运行在android.display线程中),执行完毕后finally代码块中将mDone设置为true,并调用noifyAll方法唤醒处于等待状态的线程,这样就不会继续调用注释3处的wait方法。

结合以上两点可以得出一个结论,system_server线程会一直等待android.display线程执行完毕才开始执行system_server线程,这是因为android.display线程内部执行了WMS的创建,而WMS的创建优先级要更高。

2、接下来我们来查看一下WMS的构造方法。

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

    private WindowManagerService(Context context, InputManagerService inputManager,
            boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore,
            WindowManagerPolicy policy) {
    
    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);
        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);

        mLetterboxConfiguration = new LetterboxConfiguration(
                // Using SysUI context to have access to Material colors extracted from Wallpaper.
                ActivityThread.currentActivityThread().getSystemUiContext());
        //保存传递进来的InputManagerService,这样WMS就持有了IMS的引用。
        mInputManager = inputManager; // Must be before createDisplayContentLocked.
        mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);

        mSurfaceControlFactory = surfaceControlFactory;
        mTransactionFactory = transactionFactory;
        mSurfaceFactory = surfaceFactory;
        mTransaction = mTransactionFactory.get();
        //policy其实就是PhoneWindowManager的对象实例,将其赋值给mPolicy
        mPolicy = policy;
        //创建WindowAnimator对象实例,用于管理所有的窗口动画
        mAnimator = new WindowAnimator(this);
        //RootWindowContainer是窗口容器的根容器,子容器是DisplayContent
        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);

        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);
        //获得AMS实例对象,并赋值给mActivityManager。
        mActivityManager = ActivityManager.getService();
        //获得ATMS实例对象,并赋值给mActivityTaskManager。
        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);
        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, mInputManager, mActivityTaskManager, mH.getLooper());
        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);

        mBlurController = new BlurController(mContext, mPowerManager);
        mAccessibilityController = new AccessibilityController(this);
    }
    }

对于WindowManagerService的构造方法主要提一下以下几点。
1)保存传递进来的IMS,这样WMS就持有了IMS的引用。
2)读取显示设备的设置。
3) 保存传递近来的policy,其实就是PhoneWindowManager的对象实例,将其赋值给mPolicy。
4)创建WindowAnimator对象实例,赋值给mAnimator,用于管理所有的窗口动画。
5)获取显示设备管理服务,并赋值给mDisplayManager。
6)获取电源管理服务,并复制给mPowerManager。
7)获得AMS和ATMS实例对象,并赋值给mActivityManager和mActivityTaskManager 。

3、结合SystemServer的startOtherServices方法,在创建WindowManagerService对象实例之后,会执行该对象的onInitReady方法。

    private WindowManagerService(Context context, InputManagerService inputManager,
            boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore,
            WindowManagerPolicy policy) {
        
	    public void onInitReady() {
	        //窗口管理策略的接口类WindowManagerPolicy(WMP),它用来定义一个窗口策略所要遵循的通用规范。
	        initPolicy();
	        // 调用addMonitor方法将自身添加到watchdog中,Watchdog用来监控系统的一些关键服务的运行状况,
	        // 这些被监控的服务都会实现Watchdog.Monitor接口。Watchdog每分钟都会对被监控的系统服务进行检查,
	        // 如果被监控的系统服务出现了死锁,就会杀死Watchdog所在的进程,也就是SystemServer进程。
	        Watchdog.getInstance().addMonitor(this);
	
	        createWatermark();
	        showEmulatorDisplayOverlayIfNeeded();
	    }
	    
}
	

调用initPolicy方法初始化窗口管理策略的接口类WindowManagerPolicy(WMP),它用来定义一个窗口策略所要遵循的通用规范。调用addMonitor方法将自身添加到watchdog中,Watchdog用来监控系统的一些关键服务的运行状况,这些被监控的服务都会实现Watchdog.Monitor接口。Watchdog每分钟都会对被监控的系统服务进行检查,如果被监控的系统服务出现了死锁,就会杀死Watchdog所在的进程,也就是SystemServer进程。

4、继续来看WindowManagerService的initPolicy方法。

    private WindowManagerService(Context context, InputManagerService inputManager,
            boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore,
            WindowManagerPolicy policy) {
	    private void initPolicy() {
	        UiThread.getHandler().runWithScissors(new Runnable() {
	            @Override
	            public void run() {
	                WindowManagerPolicyThread.set(Thread.currentThread(), Looper.myLooper());
	                //前面有提过,mPolicy其实就是PhoneWindowManager对象实例。
	                mPolicy.init(mContext, WindowManagerService.this, WindowManagerService.this);
	            }
	        }, 0);
	    }
    }

WMS的initPolicy方法和前面讲的WMS的main方法的实现类似,调用UiThread的静态方法getHandler,然后执行runWithScissors方法,传入需要执行的Runnable对象。

1)UiThread其实是一个名为android.ui的前台线程。

frameworks/base/services/core/java/com/android/server/UiThread.java

public final class UiThread extends ServiceThread {
    private static final long SLOW_DISPATCH_THRESHOLD_MS = 100;
    private static final long SLOW_DELIVERY_THRESHOLD_MS = 200;
    private static UiThread sInstance;
    private static Handler sHandler;

    private UiThread() {
        super("android.ui", Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
    }
    @Override
    public void run() {
        // Make sure UiThread is in the fg stune boost group
        Process.setThreadGroup(Process.myTid(), Process.THREAD_GROUP_TOP_APP);
        super.run();
    }

    private static void ensureThreadLocked() {
        if (sInstance == null) {
            sInstance = new UiThread();
            sInstance.start();
            final Looper looper = sInstance.getLooper();
            looper.setTraceTag(Trace.TRACE_TAG_SYSTEM_SERVER);
            looper.setSlowLogThresholdMs(
                    SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);
            sHandler = new Handler(sInstance.getLooper());
        }
    }

    public static UiThread get() {
        synchronized (UiThread.class) {
            ensureThreadLocked();
            return sInstance;
        }
    }

    public static Handler getHandler() {
        synchronized (UiThread.class) {
            ensureThreadLocked();
            return sHandler;
        }
    }
}

2)关于UiThread.getHandler().runWithScissors方法的调用流程这里不做具体分析了,请类比前面的DisplayThread.getHandler().runWithScissors。总之会执行Runnable的run方法,调用WMP的init方法,WMP是一个接口,具体实现类是PhoneWindowManager,这里调用的其实就是PhoneWindowManager的init方法。PhoneWindowManager的init方法运行在android.ui线程中,它的优先级要高于initPolicy方法所在的android.display线程,因此android.display线程要等PhoneWindowManager的init方法执行完毕后,处于等待状态的android.display线程才会被唤醒从而继续执行下面的代码。

三、WMS的创建过程的3个线程

上面WMS创建的过程中有提到3个线程,分别是system_server、android.display和android.ui,下图是关于这三个线程的三个步骤。
windowmanagerservice,Framework12源码,android

1、首先在system_server线程中执行了SystemServer的startOtherServices方法,在startOtherServices方法中会调用WMS的main方,main方法会创建WMS,创建的过程是在android.display线程中实现的,由于创建WMS的优先级更高,因此system_server线程要等WMS创建完成后,处于等待状态的system_server线程才会被唤醒从而继续执行下面的代码。

2、在WMS的构造方法中会调用WMS的initPolicy方法,在initPolicy方法中又会调用PWM的init方法,PWM的init方法在android.ui线程中运行,它的优先级要高于android.display线程,因此"android.display"线程要等PWM的init方法执行完毕后,处于等待状态的android.display线程才会被唤醒从而继续执行下面的代码。

3、PWM的init方法执行完毕后,android.display线程就完成了WMS的创建,等待的system_server线程被唤醒后继续执行WMS的main方法后的代码逻辑,比如在前面第二部分第2步的注释7的地方,WMS的displayReady方法用来初始化屏幕显示信息。

四、总结

windowmanagerservice,Framework12源码,android文章来源地址https://www.toymoban.com/news/detail-677486.html

到了这里,关于Android 12系统源码_窗口管理(一)WindowManagerService的启动流程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android 12 源码分析 —— 应用层 二(SystemUI大体组织和启动过程)

    在前一篇文章中,我们介绍了SystemUI怎么使用IDE进行编辑和调试。这是分析SystemUI的最基础,希望读者能尽量掌握。 本篇文章,将会介绍SystemUI的大概组织架构,以及它的启动过程。本篇文章读完,将会知道: SystemUI为什么选择使用Dagger2 SystemUI怎么新建一个模块 SystemUI的启动

    2024年02月06日
    浏览(81)
  • Android 12.0 系统开机自启动第三方app

      在12.0的系统rom定制化开发中,由于有些第三方app,需要在接收到开机广播后,启动app,但是在10.0以后第三方app就接收不到开机广播了 只有系统app才可以接收到开机广播了,所以在app内通过接收开机广播自启动就没法实现了 这就需要在系统中添加监听开机完成广播的功能,然

    2024年02月10日
    浏览(70)
  • Android 12系统源码_SystemUI(八)SystemUIVisibility属性

    在Android系统中,很多应用都需要根据具体情况来控制状态栏和导航栏的显示和隐藏,又或者将状态栏透明,实现诸如沉浸式、全面屏灯效果,而要实现这些效果,都离不开SystemUIVisibility属性。由于SystemUIVisibilityy属性主要用来控制系统状态栏和导航栏的行为,而状态栏和导航

    2024年02月06日
    浏览(49)
  • Android系统启动流程 源码解析

    本文链接:https://blog.csdn.net/feather_wch/article/details/132518105 有道云脑图:https://note.youdao.com/s/GZ9d8vzO 1、整体流程 Boot Room BootLoader idle kthread init init ServiceManager zygote zygote SystemServer app 1、kernel/common/init/main.c 2、andorid.mk-android.bp编译 3、init是用户空间鼻祖 属于C、C++ Framework 1.1 启动源

    2024年02月11日
    浏览(51)
  • 【Android 12】认识窗口

    该文章为窗口层级结构系列文章的总结,重新回看这方面内容的时候我自己也有了一些新的感悟,希望通过本次总结能让大家再次对窗口有一个全面的认识。 一般来说,屏幕上最起码包含三个窗口,StatusBar窗口、Activity窗口以及NavigationBar窗口: 我们想要了解窗口,可以按照

    2024年01月17日
    浏览(34)
  • Android 9系统源码_音频管理(一)按键音效源码解析

    当用户点击Android智能设备的按钮的时候,如果伴随有按键音效的话,会给用户更好的交互体验。本期我们将会结合Android系统源码来具体分析一下控件是如何发出按键音效的。 1、在TV版的Android智能设备中,我们可以通过调节设置页面的开关来控制按键音效的有无,该设置页面

    2024年02月09日
    浏览(45)
  • Android12窗口模糊(一)在Activity和Dialog中实现高斯模糊效果

    在 Android 12 中,提供了一些用于实现窗口模糊处理效果(例如背景模糊处理和模糊处理后方屏幕)的公共 API。窗口模糊处理或跨窗口模糊处理用于模糊处理给定窗口后方的屏幕。 有两种窗口模糊处理方式,可用于实现不同的视觉效果: 背景模糊处理(Background blur):可用于

    2023年04月19日
    浏览(83)
  • 命令提示符cmd窗口重新启动Windows 资源管理

    最近工作过程中碰到了电脑在使用VS2022编译VTK时,文件资源管理器崩溃的问题。 在使用任务管理器强制结束文件资源管理器的任务后,看不见文件资源管理器了,也无法找到文件资源管理器程序explorer.exe程序进行重启。因此想着通过cmd命令行输入命令的方式重启文件资源管理

    2024年02月11日
    浏览(280)
  • AOSP 源码编译android 12

    目录 一、python安装      a. python2安装     b. python3安装 二、repo管理多个git    a.第一步,   新建一个空白文件夹保存repo引导文件,并包含你的路径    b.下载启动器  c.将git-repo中的repo文件复制到 1 创建的.bin目录中  d.修改权限 e. 执行版本检查 三、初始化工程   a.执行创建文

    2024年01月16日
    浏览(54)
  • 【Linux驱动开发】编译Android12源码

    基于讯为电子rk3568教程 rk_android12.0_sdk_20220720.tar.gz 解压 设置屏幕配置 整体编译 Android 固件 使能编译环境 开始整体编译 rockdev/Image-rk3568_s // 编译成功镜像存放位置 单独编译u-boot (方法一) 编译完成后在 u-boot 目录会生成 rk356x_spl_loader_v1.13.112.bin 文件、uboot.img 文件、 resourc

    2024年02月05日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包