PowerManagerService的启动流程

Posted zhenjie_chang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PowerManagerService的启动流程相关的知识,希望对你有一定的参考价值。

PowerManagerServcie是android系统电源管理的核心服务,它在Framework层建立起一个策略控制方案,向下决策HAL层以及kernel层来控制设备待机状态,控制显示屏,背光灯,距离传感器,光线传感器等硬件设备的状态。向上提供给应用程序相应的操作接口,比如听音乐时持续保持系统唤醒,应用通知来临唤醒手机屏幕等场景等,PMS也是系统的核心服务,启动流程的时序图如下:

启动流程时序图


根据PowerManagerService的启动流程时序图,可以简单的将启动过程分为图中的几个步骤。

根据代码来详细分析

  PowerManagerService是系统的核心服务,在SystemServer中启动。SystemServer在系统启动的时候会启动三种服务,引导关键服务,核心服务和其他服务。

startBootstrapServices(); //启动引导服务
startCoreServices();//启动核心服务
 startOtherServices();//其他服务

在启动引导关键服务的方法中,创建PowerManagerService对象,并将它启动了起来

mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);

接着我们看下startService相关的代码实现。

public <T extends SystemService> T startService(Class<T> serviceClass) 
        ……
        final T service;
        try 
            Constructor<T> constructor = serviceClass.getConstructor(Context.class);
            service = constructor.newInstance(mContext);
            //构造PowerManangerService对象
         catch (InstantiationException ex) 
            ……
        
        // Register it.
        mServices.add(service); //将PowerManangerService添加到LocalService中
        // Start it.
        try 
            service.onStart(); //调用PowerManagerService的onStart方法
         catch (RuntimeException ex) 
           ……
        
        return service;
    

在startService方法中,利用反射方法构造PowerManagerService的对象,将它添加到本地service变量中,然后调用了PowerManagerService的onStart方法。

那么我们首先来分析PowerManagerService的构造方法,然后在分析PowerManagerService的onStart方法。

PowerManagerService的构造方法分析

public PowerManagerService(Context context) 
        super(context);
        mContext = context;
        mHandlerThread = new ServiceThread(TAG,
                Process.THREAD_PRIORITY_DISPLAY, false /*allowIo*/);
        mHandlerThread.start();
        //创建一个HandlerThread,并启动
        mHandler = new PowerManagerHandler(mHandlerThread.getLooper());
        //基于这个HandlerThread创建一个相关的Handler对象,用于向handlerThread中发送消息
        synchronized (mLock) 
            mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService.WakeLocks");
            //该WakeLock用于控制CPU
            mDisplaySuspendBlocker = createSuspendBlockerLocked("PowerManagerService.Display");
            //该wakeLock用于控制屏幕
            mDisplaySuspendBlocker.acquire();
            mHoldingDisplaySuspendBlocker = true;
            mHalAutoSuspendModeEnabled = false;
            mHalInteractiveModeEnabled = true;

            mWakefulness = WAKEFULNESS_AWAKE;
            //初始化wakefulness的状态
            nativeInit();
            //调用native层初始化
            nativeSetAutoSuspend(false);
            nativeSetInteractive(true);
            nativeSetFeature(POWER_FEATURE_DOUBLE_TAP_TO_WAKE, 0);
        
    

第一步:

在PowerManagerService的构造方法中,首先创建了一个消息发送和处理的Handler和两种WakeLock锁

1. PowerManagerService.WakeLocks,主要用于控制CPU的唤醒

2. PowerManagerService.Display 主要用于控制屏幕的点亮和熄灭

关于createSuspendBlockerLocked方法的实现

    private SuspendBlocker createSuspendBlockerLocked(String name) 
        SuspendBlocker suspendBlocker = new SuspendBlockerImpl(name);
        mSuspendBlockers.add(suspendBlocker);
        return suspendBlocker;
    

在该方法中创建了一个SuspendBlockerImpl对象,下面我们再来看下的acquire()方法如何实现

public void acquire()   
        synchronized (this)   
            mReferenceCount += 1;  
            if (mReferenceCount == 1)   
                nativeAcquireSuspendBlocker(mName);  
              
          
     

计数加1,然后nativeAcquireSuspendBlocker(mName)方法通过JNI调用native层的nativeAcquireSuspendBlocker方法。

static void nativeAcquireSuspendBlocker(JNIEnv *env, jclass clazz, jstring nameStr)   
    ScopedUtfChars name(env, nameStr);  
    acquire_wake_lock(PARTIAL_WAKE_LOCK, name.c_str());  
  

acquire_wake_lock()调用的是power.c文件中的acquire_wake_lock()方法。在该方法中通过往/sys/power/wake_lock,/sys/power/wake_unlock等文件中写入数据来进行底层持锁

第二步:

将mWakefulness变量初始化为WAKEFULNESS_AWAKE状态,mWakefulness 标识系统当前状态共有四种定义:

WAKEFULNESS_ASLEEP:表示系统当前处于休眠状态,只能被wakeUp()调用唤醒。
WAKEFULNESS_AWAKE:表示系统目前处于正常运行状态。

WAKEFULNESS_DREAMING:表示系统当前正处于互动屏保的状态。

WAKEFULNESS_DOZING:表示系统正处于“doze”状态

第三步:

然后调用nativieInit()方法,通过JNI方法在native层初始化相关资源。

static void nativeInit(JNIEnv* env, jobject obj) 
    gPowerManagerServiceObj = env->NewGlobalRef(obj);

    status_t err = hw_get_module(POWER_HARDWARE_MODULE_ID,
            (hw_module_t const**)&gPowerModule);
    if (!err) 
        gPowerModule->init(gPowerModule);
     else 
        ALOGE("Couldn't load %s module (%s)", POWER_HARDWARE_MODULE_ID, strerror(-err));
    

在nativeInit()方法中,创建了一个对应的Native层PowerManagerService,然后调用了gPowerModule的init函数。以下是power_module的结构类型

struct power_module HAL_MODULE_INFO_SYM = 
    .common = 
        .tag = HARDWARE_MODULE_TAG,
        .module_api_version = POWER_MODULE_API_VERSION_0_2,
        .hal_api_version = HARDWARE_HAL_API_VERSION,
        .id = POWER_HARDWARE_MODULE_ID,
        .name = "Default Power HAL",
        .author = "The Android Open Source Project",
        .methods = &power_module_methods,
    ,

    .init = power_init,
    .setInteractive = power_set_interactive,
    .powerHint = power_hint,
;

Power_module的初始化代码,gPowerModule->init方法对应的是power_init 这个应该是由硬件厂商来实现的,不同的硬件初始化方式也不一样,我们看先htc相关的实现方式. Power_init实际就是在cpu的节点中写入了一些初始化的值。

static void power_init(struct power_module __unused *module)

    sysfs_write("/sys/devices/system/cpu/cpufreq/interactive/timer_rate",
                "20000");
    sysfs_write("/sys/devices/system/cpu/cpufreq/interactive/timer_slack",
                "20000");
    sysfs_write("/sys/devices/system/cpu/cpufreq/interactive/min_sample_time",
                "80000");
    sysfs_write("/sys/devices/system/cpu/cpufreq/interactive/hispeed_freq",
                "1530000");
    sysfs_write("/sys/devices/system/cpu/cpufreq/interactive/go_hispeed_load",
                "99");
    sysfs_write("/sys/devices/system/cpu/cpufreq/interactive/target_loads",
                "65 228000:75 624000:85");
    sysfs_write("/sys/devices/system/cpu/cpufreq/interactive/above_hispeed_delay",
                "20000");
    sysfs_write("/sys/devices/system/cpu/cpufreq/interactive/boostpulse_duration",
                "1000000");
    sysfs_write("/sys/devices/system/cpu/cpufreq/interactive/io_is_busy", "0");

    calculate_max_cpu_freq();

onStart函数分析:

public void onStart() 
        publishBinderService(Context.POWER_SERVICE, new BinderService());
        publishLocalService(PowerManagerInternal.class, new LocalService());
    

onStart方法实现比较简单,就是将PowerManagerService对象注册到ServiceManager中和LocalService中。

SystemReady函数分析

根据分析,当System系统准备完成后,SystemServer会回调systemReady函数。先看PMS的systemReady函数具体干了些什么。

public void systemReady(IAppOpsService appOps) 
        synchronized (mLock) 
			//第一步:初始化相关的变量
            mSystemReady = true;
            mAppOps = appOps;
            mDreamManager = getLocalService(DreamManagerInternal.class);
//初始化互动屏保管理
            mDisplayManagerInternal = getLocalService(DisplayManagerInternal.class);
//初始化屏幕显示管理服务
            mPolicy = getLocalService(WindowManagerPolicy.class);
            mBatteryManagerInternal = getLocalService(BatteryManagerInternal.class);
//初始化电池管理服务

            PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
            mScreenBrightnessSettingMinimum = pm.getMinimumScreenBrightnessSetting();
            mScreenBrightnessSettingMaximum = pm.getMaximumScreenBrightnessSetting();
            mScreenBrightnessSettingDefault = pm.getDefaultScreenBrightnessSetting();
//获取屏幕的亮度值,最大亮度,最小亮度,默认亮度
            SensorManager sensorManager = new SystemSensorManager(mContext, mHandler.getLooper());
//获取传感器管理服务
            mBatteryStats = BatteryStatsService.getService();
//初始化电量统计服务
            mNotifier = new Notifier(Looper.getMainLooper(), mContext, mBatteryStats,
                    mAppOps, createSuspendBlockerLocked("PowerManagerService.Broadcasts"),
                    mPolicy);

            mWirelessChargerDetector = new WirelessChargerDetector(sensorManager,
                    createSuspendBlockerLocked("PowerManagerService.WirelessChargerDetector"),
                    mHandler);
            mSettingsObserver = new SettingsObserver(mHandler);
//settings的监听器
            mLightsManager = getLocalService(LightsManager.class);
//LED指示灯管理服务
            mAttentionLight = mLightsManager.getLight(LightsManager.LIGHT_ID_ATTENTION);

            // 初始化屏幕显示服务
            mDisplayManagerInternal.initPowerManagement(
                    mDisplayPowerCallbacks, mHandler, sensorManager);
			//第二步:注册相关的BroadCastReceiver
            IntentFilter filter = new IntentFilter();
            filter.addAction(Intent.ACTION_BATTERY_CHANGED);
            filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
            mContext.registerReceiver(new BatteryReceiver(), filter, null, mHandler);
            //注册电池变化的接收器
            filter = new IntentFilter();
            filter.addAction(Intent.ACTION_DREAMING_STARTED);
            filter.addAction(Intent.ACTION_DREAMING_STOPPED);
            mContext.registerReceiver(new DreamReceiver(), filter, null, mHandler);
            //注册屏保开始和结束的接收器
            filter = new IntentFilter();
            filter.addAction(Intent.ACTION_USER_SWITCHED);
            mContext.registerReceiver(new UserSwitchedReceiver(), filter, null, mHandler);
            //注册切换用户的接收器
            filter = new IntentFilter();
            filter.addAction(Intent.ACTION_DOCK_EVENT);
            mContext.registerReceiver(new DockReceiver(), filter, null, mHandler);
			
            //第三步.注册设置变化的监听器
            final ContentResolver resolver = mContext.getContentResolver();
            resolver.registerContentObserver(Settings.Secure.getUriFor(
                    Settings.Secure.SCREENSAVER_ENABLED),
                    false, mSettingsObserver, UserHandle.USER_ALL);
            
            ……
            resolver.registerContentObserver(Settings.Secure.getUriFor(
                    Settings.Secure.DOUBLE_TAP_TO_WAKE),
                    false, mSettingsObserver, UserHandle.USER_ALL);
            //双击唤醒屏幕
            // 第四步: 从文件读取默认的配置信息
            readConfigurationLocked();
            //读取设置信息,并更新相关的变量
            updateSettingsLocked();
			// 第五步
            mDirty |= DIRTY_BATTERY_STATE;
            //更新电源的相关信息
            updatePowerStateLocked();
        
    

systemReady方法代码虽然很长,但是逻辑大致可以分为五个步骤

第一步:初始化相关的变量和服务

初始化了DreamManager,DisplayManager,PowerManager,BatteryStats,LightManager等相关的变量,初始化了屏幕亮度最大、最小和默认三个数值。

第二步:注册相关的广播接收器

注册了电量变化、用户切换和Dream等相关的广播接收器

当电量发生变化,调用handleBatteryStateChangedLocked方法处理电源变化的逻辑。

private void handleBatteryStateChangedLocked() 
        mDirty |= DIRTY_BATTERY_STATE;
        updatePowerStateLocked();
    

最终调用updatePowerStateLocked更新电源状态,该方法稍后分析

第三步:注册相关设置的变化监听

监听设置中相关信息的变化,例如灭屏时间,屏幕亮度,低电量的值,双击唤醒等

当settings中的关于电量的设置发生变化的时候,settingsObserver接收到变化监听,调用handleSettingsChangedLocked方法来处理settings变化的逻辑。

private void handleSettingsChangedLocked() 
        updateSettingsLocked();
        updatePowerStateLocked();
    

调用updateSettingsLocked方法,从新读取设置信息,更新设置信息,调用updatePowerStateLocked更新电源状态信息。

第四步:配置文件中读取相关的配置信息,更新setting中设置的信息

 调用readConfigurationLocked方法,从xml文件中读取预置的配置信息,并赋值给相应的变量。

调用updateSettingLocked方法,根据预置的变量信息和Settings中配置的信息来初始化Setting的相关变量。

第五步:更新电源的状态信息

调用updatePowerStateLocked来更新电源状态信息。该方法是PowerManagerService的核心方法,后面会详细分析。

总结:PowerManagerService启动流程图如下。




到此PowerManagerService的启动流程就分析完成了。下面分析PMS的核心方法updatePowerStateLocked()方法。






以上是关于PowerManagerService的启动流程的主要内容,如果未能解决你的问题,请参考以下文章

PowerManagerService流程分析

PowerManagerService启动-Android12

PowerManagerService启动-Android12

深入了解PowerManagerService之Android 11.0 Power 键亮屏灭屏流程分析

[RK3568][Android11]Android关机Framework 代码流程

[RK3568][Android11]Android关机Framework 代码流程