Android5.1--电源管理之省电模式分析


 一、如何开启5.0省电模式

打开安卓5.0设备的设置选项,然后前往电池菜单,点击菜单键,弹出并选择“节电助手”,随后点击顶部的开关便可。

此外,要是用户运行的是原生版安卓,可以下拉安卓通知中心,然后点击电池按钮,便可进入电池界面,找到“省电模式”。

            

开启此模式后,屏幕亮度会调低,后台数据(大部分)关闭,动画全部取消,震动关闭,基本上和厂商们的省电模式行为差不多,都是以牺牲可用性来换取使用时间

不同的是,开启此模式后,Android 5.0除了一个通知图标之外,还会用无处不在的亮橙色来提醒你:顶部状态栏、底部通知栏全部变为橙色,很多图标等素材资源增加橙色,甚至一些应用的顶部栏里也会变色。

二、相关代码

设置应用入口文件:

./packages/apps/Settings/src/com/android/settings/fuelgauge/BatterySaverSettings.java

 

托盘显示:

./frameworks/base/packages/SystemUI/src/com/android/systemui/power/PowerUI.java

./frameworks/base/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java

 

托盘中callback回调函数onPowerSaveChanged():

./frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java

 

onPowerSaveChanged():(systemui内部处理)

./frameworks/base/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java

./frameworks/base/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java

./frameworks/base/packages/SystemUI/src/com/android/systemui/doze/DozeService.java

./frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java

./frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java

./frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java

./frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java

./frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java

./frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java

 

GPS根据mode 更新处理:

./frameworks/base/services/core/java/com/android/server/location/GpsLocationProvider.java:

 

发送模式切换ing/切换 广播:

./frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

 

voice根据mode 更新处理:

./frameworks/base/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerHelper.java

三、省电模式流程分析

1、设置应用入口文件:

./packages/apps/Settings/src/com/android/settings/fuelgauge/BatterySaverSettings.java

节能助手开启或关闭时,调用onSwitchChanged方法,参数isChecked表示节能助手处于开启(true)或关闭(false)状态。开启时isChecked为true,发送消息mStartMode开启新线程开启省电模式;否则关闭省电模式。

2、提供调用接口文件:

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

3、发送模式切换广播:

./frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

mIsPowered变量表示充电状态,true表示正在充电(已接入电源),否则为false;setLowPowerModeInternal方法中首先判断mIsPowered是否处于充电状态,如果正在充电则直接返回false,表示不允许设置省电模式(省电模式会在设备充电时自动关闭)。

接着根据参数mode的值设置系统变量”low_power”(LOW_POWER_MODE),并设置变量mLowPowerModeSetting(Current state of the low power mode setting.表示设置低电模式的当前状态;从系统设置中获取的值,即数据库字段“low_power”的值)。

接下来设置变量mAutoLowPowerModeSnoozing(The user turnedoff low power mode below the trigger level,表示电量低于省电模式的触发点时,关闭省电模式)。该变量值是由mAutoLowPowerModeConfigured(自动开启省电模式的当前状态,即数据库字段“low_power_trigger_level”是否为0的值;不为0时表示打开了自动开启功能,该变量为true)和mBatteryLevelLow(True if the battery level is currentlyconsidered low.如果电池电量低为true)这两个变量决定的。当电量低并且允许自动设置省电模式时,如果此时省电模式是开启的,就要设置mAutoLowPowerModeSnoozing的值为false;如果省电模式是关闭的,就要设置mAutoLowPowerModeSnoozing的值为true。就是要求mAutoLowPowerModeSnoozing变量与省电模式的逻辑保持一致。

调用updateLowPowerModeLocked方法。

最后直接返回true,表示省电模式设置成功。

首先判断如果当前正在充电并且开启了省电模式,则关闭省电模式,将“low_power”字段设置为0,mLowPowerModeSetting置为false。

接着创建两个临时变量autoLowPowerModeEnabled和lowPowerModeEnabled。autoLowPowerModeEnabled(当前没有充电,自动开启省电模式,电量低于省电模式的电量触发点时不关闭省电模式,电池电量低,以上条件均满足时为true);lowPowerModeEnabled(当mLowPowerModeSetting或autoLowPowerModeEnabled为真时,则设置为true);根据lowPowerModeEnabled临时变量值和mLowPowerModeEnabled(true表示设备处于省电模式,全局变量)判断是否执行省电模式的功能。当两者状态不一致时,更新mLowPowerModeEnabled状态值。

接着调用powerHintInternal方法;之后使用后台线程BackgroundThread处理事件,会先后发送action为ACTION_POWER_SAVE_MODE_CHANGING和ACTION_POWER_SAVE_MODE_CHANGED的广播,注意这两个广播中设置了addFlags为Intent.FLAG_RECEIVER_REGISTERED_ONLY,表示只有动态定义的广播接收器才能接收到该广播,在发送ACTION_POWER_SAVE_MODE_CHANGING广播的时候传递数据“mode”的值。在发送这两个广播中间设置LowPowerModeListener,调用该接口的onLowPowerModeChanged方法(此处下文介绍)。

这里先分析一下powerHintInternal方法的处理。

powerHintInternal(POWER_HINT_LOW_POWER,lowPowerModeEnabled ? 1 : 0)。注意:POWER_HINT_LOW_POWER是在hardware/libhardware/include/hardware/power.h中定义的。

4、JNI层函数调用

frameworks/base/services/core/jni/com_android_server_power_PowerManagerService.cpp。

调用静态方法nativeSendPowerHint,gPowerModule是power_module类型的结构体,

下面分析一下power_module(电源模块)结构体。每个硬件模块必须有一个名为HAL_MODULE_INFO_SYM的数据结构,这个数据结构的字段必须以hw_module_t开始后跟模块的详细信息。该结构体中定义了一个hw_module_t结构体(common)和三个函数(init,setInteractive,powerHint)。Power_module的定义如下:

Typedefstruct power_module {

         Struct hw_module_t common;

         Void (*init) (struct power_module*module);

         Void (*setInteractive)(structpower_module *module, int on);

         Void (*powerHint)(struct power_module*module, power_hint_t hint, void *data);

}power_module_t;

1)        (*init)():设置电源管理在运行时启动的设置动作,例如设置默认的CPU频率参数。只供由PowerManagerService加载的Power HAL实例调用。

2)        (*setInteractive)():该方法用来执行关闭屏幕后进入非交互状态,同时打开屏幕之前进入交互状态;参数on表示当系统转变为交互状态或唤醒状态时是一个非0值,当转变为非交互状态或asleep状态时为0;该方法典型的操作就是打开或关闭设备,调整CPU频率参数。当系统进入非交互状态时该函数还可以调用相应接口允许内核挂起系统进入低电睡眠状态;当系统进入交互状态时禁止低电挂起。

3)        (*powerHint)():根据电源需求传递提示信息,这可能会导致  CPU频率的调整和一些控制项的功耗/性能的调整。可能的提示是:

POWER_HINT_VSYNC(垂直同步):前台应用从SurfaceFlinger中启动或停止请求一个VSYNC脉冲。如果该应用已开始请求VSYNC,然后CPU和GPU很快加载,可能会适当加快CPU和存储器速度。该参数为非0值表示需要请求VSYNC,若为0表示不再需要请求VSYNC。

POWER_HINT_INTERACTION:用户与设备交互,例如触摸屏事件。CPU和GPU会加速加载,适当提高CPU频率,存储器总线,此参数暂时没有使用。

POWER_HINT_LOW_POWER:省电模式的激活或关闭。省电模式是以消耗性能为代价的。非0值表示开启省电模式,为0时表示已关闭省电模式。

5、Native层函数调用IPowerManager.cpp

frameworks/native/services/powermanager/IPowerManager.cpp

采用binder通信方式,将POWER_HINT_LOW_POWER和开启标志发送到服务端处理。

ACTION_POWER_SAVE_MODE_CHANGING广播接收器

1、BatteryController.java

./frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java

在BatteryController类中接收到ACTION_POWER_SAVE_MODE_CHANGING广播后获取传递的“mode”数据值,作为setPowerSave方法的参数,如果mode值与当前mPowerSave值相等,则直接返回,若不相等则赋值给当前mPowerSave值;并调用firePowerSaveChanged方法。

在firePowerSaveChanged方法中,遍历BatteryStateChangeCallback对象,并调用接口的onPowerSaveChanged方法。这里为什么是一个列表呢? (凡实现了该接口的类,均在这个列表中保存)。

ArrayList<BatteryStateChangeCallback>mChangeCallbacks =newArrayList<>();

2、BatteryMeterView.java(电池计量器)

frameworks/base/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java

BatteryMeterView类实现了BatteryController.BatteryStateChangeCallback接口,回调onPowerSaveChanged方法,在onPowerSaveChanged方法中调用invalidate方法会刷新界面。

在getColorForLevel方法中,如果处于省电模式,则返回省电模式设置的颜色值:battery_saver_mode_color(#fff4511e)。

3、PowerUI.java

在PowerUI.java中注册广播接收器,监听省电模式设置,分别接收action为POWER_SAVE_MODE_CHANGING和POWER_SAVE_MODE_CHANGED的广播,接收到广播后分别调用setSaverMode方法和updateSaverMode方法。

在setSaverMode方法中调用内部接口WarningsUI的showSaverMode方法。PowerNotificationWarning实现了WarningsUI接口,因此调用PowerNotificationWarnings的showSaverMode方法。

4、设置通知:PowerNotificationWarnings.java

frameworks/base/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarning.java

PowerNotificationWarnings中有几个变量:mSaver表示是否开启了省电模式;mInvalidCharger表示无效充电器;mWarning表示

mSaver为true时,showSaverNotification()方法被调用,显示节电助手已开启的通知。

在节电助手通知栏中添加一个Action,触发一个动作为ACTION_STOP_SAVER(PNW.stopSaver)的广播事件,这个事件用来关闭省电模式。

接着判断hasSaverSettings方法返回值,在该方法中调用了Intent.resolveActivity方法,该方法的含义是:如果当前设备上不存在可接收某种隐式Intent的应用程序,则调用startActivity()的应用程序将会崩溃。为了预先判断一下是否存在可接收Intent的应用程序,调用Intent对象的resolveActivity方法。如果结果非空,则表示至少存在一个可处理该Intent的应用程序,并且可安全调用startActivity方法。如果结果为null,请勿再使用该Intent,并尽可能关闭那些会发起该Intent的功能。

为该Notification添加一个PendingIntent(android.settings.BATTERY_SAVER_SETTINGS),因此调用Notification.Builder.setContentIntent方法。目前没有该action的广播接收器。 因此点击该通知时没有反应。

最后调用mNoMan.notifyAsUser(TAG_NOTIFICATION,ID_NOTIFICATION, nb.build(), UserHandle.CURRENT); 发出这个通知。

5、降低屏幕亮度

在PowerManagerService中更新电源状态的时候调用updateDisplayPowerStateLocked方法时,会获取省电模式状态,保存在DisplayPowerRequest的lowPowerMode属性中。

mDisplayPowerRequest.lowPowerMode =mLowPowerModeEnabled;

最终调用到DisplayPowerController类中,在updatePowerState方法中设置屏幕亮度值,如果处于省电模式状态,设置屏幕亮度值减半处理;

PowerMnagerInternal.LowPowerModeListener

此处回过头来看看PowerManagerService的updateLowPowerModeLocked方法中生成的PowerMnagerInternal.LowPowerModeListener数组。

该数组是由所有实现PowerMnagerInternal.LowPowerModeListener接口的类组成的。

1、取消震动效果:VibratorService.java

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

在systemReady方法中注册省电模式监听器,当省电模式发生改变时回调onLowPowerModeChanged方法,该方法中调用updateInputDeviceVibrators方法。

在updateInputDeviceVibrators方法中获取省电模式状态。

mLowPowerMode = mPowerManagerInternal.getLowPowerModeEnabled();

VibratorService类中startVibrationLocked方法负责震动效果,首先判断是否处于省电模式,若为省电模式直接返回,不再做震动操作。

2、取消动画设置:WindowManagerService.java

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

         在WindowManagerService的构造方法中,注册省电模式的监听器,当回调onLowPowerModeChanged方法时,比较mAnimationDisabled(窗口动画的使能状态)与省电模式使能状态,如果不相等则为mAnimationDisabled赋值并调用dispatchNewAnimatorScaleLocked方法。

在diapatchNewAnimatorScaleLocked方法中发送H.NEW_ANIMATOR_SCALE消息。

mH接收到H.NEW_ANIMATOR_SCALE消息时,是如何处理的呢?首先调用getCurrentAnimatorScale方法获取当前动画持续时间比,如果处于省电模式状态则返回0,不再开启动画效果。

ACTION_POWER_SAVE_MODE_CHANGED广播接收器

1、PowerUI.java

         接收到ACTION_POWER_SAVE_MODE_CHANGED广播后,更新省电模式状态。

此时调用到PowerNotificationWarning的setSaverMode方法中,如下

以下处理流程同接收到ACTION_POWER_SAVE_MODE_CHANGING广播后一样,只是当省电模式状态相等时就会return。

2、BatteryController.java

接收ACTION_POWER_SAVE_MODE_CHANGED广播,更新省电模式状态。

此时if语句成立,直接返回。

3、KeyguardStatusBarView.java、StatusBarHeaderView.java

./frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java

./frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java

在KeyguardStatusBarView类和StatusBarHeaderView类中onPowerSaveChanged方法中暂时没有处理。

4、PhoneStatusBar.java

./frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java

5、关闭GPS功能:GpsLocationProvider.java

./frameworks/base/services/core/java/com/android/server/location/GpsLocationProvider.java

         变量:

mDisableGps:使gps失效时为true,用来支持设置中的省电模式。

BATTERY_SAVER_GPS_MODE= “batterySaverGpsMode”;开启省电模式时安全设置GPS动作。

BATTERY_SAVER_MODE_NO_CHANGE:设置batterySaverGpsMode的值,例如不受省电模式的影响。

BATTERY_SAVER_MODE_DISABLED_WHEN_SCREEN_OFF:batterySaverGpsMode的值,例如省电模式开启并处于待机状态时使GPS功能失效。

该类中接收到广播android.os.action.POWER_SAVE_MODE_CHANGED时,调用updateLowPowerMode方法。

获取系统设置中设置的“batterySaverGpsMode”字段值,默认返回BATTERY_SAVER_MODE_DISABLED_WHEN_SCREEN_OFF的值;如果返回的是默认值,则定义临时变量disableGps,如果与全局变量mDisbaleGps不等,赋值给mDisableGps,并调用updateRequirements方法。

在updateRequirements方法中,如果开启的省电模式并待机状态下关闭GPS。

6、关闭语音识别:SoundTriggerHelper.java

./frameworks/base/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerHelper.java

PowerManagerService中发送ACTION_POWER_SAVE_MODE_CHANGED广播后,在SoundTriggerHelper中定义广播接收器,接收ACTION_POWER_SAVE_MODE_CHANGED。并获取是否处于省电模式的状态值。

如果action不为ACTION_POWER_SAVE_MODE_CHANGED,直接退出;获取省电模式的状态,并调用onPowerSaveModeChangedLocked方法。

如果省电模式状态值没有改变,直接退出;否则将新获取的状态值赋值给全局变量mIsPowerSaveMode,并调用updateRecognitionLocked(true)方法。

在updateRecognitionLocked方法中,判断如果是省电模式,则停止语音识别。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Understand是一种功能强大的软件开发工具,它提供了多种语言和平台的静态代码分析功能,用于帮助开发人员理解和改进他们的代码质量。 5.1是Understand的一个特定版本号,它表示 Understad软件的第5个大版本中的一个小更新。 Windows64表示这个Understand版本适用于运行在Windows操作系统的64位机器上。 通过使用Understand 5.1-windows64,开发人员可以对代码进行全面的分析和评估,以确保代码的质量和可维护性。它可以帮助开发人员识别潜在的代码缺陷、冗余代码和性能问题,并提供解决方案来改善代码质量。 该版本还具备了适用于Windows 64位机器的优化和兼容性,以确保在这样的机器上能够运行和运行分析任务的平稳性。 总之,Understand 5.1-windows64是一款适用于在Windows 64位操作系统上运行的强大的软件开发工具,它为开发人员提供了全面的代码分析功能,帮助他们提高代码质量和可维护性。 ### 回答2: understand 5.1-windows64 指的是一个软件的版本和系统要求。Understand 是一款用于源代码分析的软件工具,用于帮助开发人员理解和浏览复杂的代码。5.1 是这个软件的版本号,表示该软件经过一系列的更新和改进。windows64 表示该软件支持 64 位的 Windows 操作系统。 对于开发人员来说,使用 Understand 5.1-windows64 有几个优势。首先,它可以帮助他们更好地理解和分析源代码。该软件提供了多种功能,如交互式图表、图形视图和搜索功能,可以帮助开发人员深入了解代码的结构和关系,从而更高效地调试和优化代码。 其次,Understand 5.1-windows64 具有良好的兼容性,可以在 Windows 64 位系统上正常运行。64 位操作系统相比于32位操作系统具有更大的内存容量和更快的处理速度,这对于处理大型代码库和复杂的分析任务非常重要。使用 64 位系统可以提高软件工具的性能和效率。 此外,Understand 5.1-windows64 的更新版本可能还会解决了一些 bug,增加了新功能或提高了软件的稳定性。开发人员可以从该软件的版本迭代中获益。 总之,Understand 5.1-windows64 是一款功能强大的源代码分析工具,适用于 Windows 64 位系统。它可以帮助开发人员更好地理解和分析源代码,提高开发效率,并且与 64 位操作系统相对应,能够更好地支持大型代码库和复杂的分析任务。 ### 回答3: understand5.1-windows64是一款用于软件开发的工具,它是在Windows操作系统下工作的64位版本。Understand是一个功能强大的代码理解工具,它可以帮助程序员对代码进行深入的分析和理解。 使用understand5.1-windows64,程序员可以对源代码进行静态分析,了解代码的结构、功能和相互关系。它支持多种编程语言,包括C、C++、C#、Java等。程序员可以快速地浏览代码,并通过各种视图和图表来可视化分析结果。 此外,understand5.1-windows64还提供了全面的代码检查和度量功能,帮助程序员评估代码的质量和健壮性。它可以检测潜在的错误、重复的代码和性能问题,并生成报告供程序员参考和改进。 另外,understand5.1-windows64还支持代码重构和搜索功能。程序员可以通过重构工具对代码进行重构,提高代码的可读性和可维护性。搜索功能可以帮助程序员快速定位特定的代码片段,提高开发效率。 总而言之,understand5.1-windows64是一款功能强大且易于使用的代码理解工具。它提供了丰富的分析和度量功能,帮助程序员更好地理解和改进源代码。无论是初学者还是经验丰富的开发人员,都可以从中受益并提高代码开发的效率和质量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值