PowerManagerService的启动流程

来源:互联网 发布:js在div中追加内容 编辑:程序博客网 时间:2024/05/16 04:45

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

启动流程时序图

AAA


根据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启动流程图如下。


BBB

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






1 0