当前位置: 首页 > news >正文

Android的亮灯逻辑辨析

Android手机的亮灯逻辑由三层结构:

1. framework层控制行为逻辑

2. hardware提供HAL接口

3. 驱动层负责亮灯。

首先在/framework/base/core/res/res/values/config.xml中定义了灯的颜色和亮灯阈值

<!-- Display low battery warning when battery level dips to this value -->
1144     <integer name="config_lowBatteryWarningLevel">20</integer>
1145 
1146     <!-- The default suggested battery % at which we enable battery saver automatically.  -->
1147     <integer name="config_lowBatteryAutoTriggerDefaultLevel">15</integer>
1148 
1149     <!-- Close low battery warning when battery level reaches the lowBatteryWarningLevel
1150          plus this -->
1151     <integer name="config_lowBatteryCloseWarningBump">5</integer>
notification LED. -->
1154     <color name="config_defaultNotificationColor">#ffffffff</color>
1155 
1156     <!-- Default LED on time for notification LED in milliseconds. -->
1157     <integer name="config_defaultNotificationLedOn">500</integer>
1158 
1159     <!-- Default LED off time for notification LED in milliseconds. -->
1160     <integer name="config_defaultNotificationLedOff">2000</integer>
1161 
1162     <!-- Default value for led color when battery is low on charge -->
1163     <integer name="config_notificationsBatteryLowARGB">0xFFFF0000</integer>
1164 
1165     <!-- Default value for led color when battery is medium charged -->
1166     <integer name="config_notificationsBatteryMediumARGB">0xFF0000FF</integer>
1167 
1168     <!-- Default value for led color when battery is fully charged -->
1169     <integer name="config_notificationsBatteryFullARGB">0xFF00FF00</integer>
1170 

诸如电量15%显示一种灯,电量为FULL时显示一种;而颜色为0xFFFF0000; 其中最高两位的FF表示灯的通透性(景深),而接下来的6位,2位为一种颜色,分别为RGB,RED,GREEN,BLUE;因此0xFFFF0000红色,0xFFFFFF00(橙色,红绿), 0xFF00FF00(绿), 0xFF0000FF(蓝);

这些值在/framework/base/services/core/java/com/android/server/BatteryService.java中被解析,进而进行判断行为

public void updateLightsLocked() {final int level = mHealthInfo.batteryLevel;final int status = mHealthInfo.batteryStatus;if (level < mLowBatteryWarningLevel) {if (status == BatteryManager.BATTERY_STATUS_CHARGING) {// Solid red when battery is chargingmBatteryLight.setColor(mBatteryLowARGB);} else {// Flash red when battery is low and not chargingmBatteryLight.setFlashing(mBatteryLowARGB, Light.LIGHT_FLASH_TIMED,mBatteryLedOn, mBatteryLedOff);}} else if (status == BatteryManager.BATTERY_STATUS_CHARGING|| status == BatteryManager.BATTERY_STATUS_FULL) {if (status == BatteryManager.BATTERY_STATUS_FULL || level >= 90) {// Solid green when full or charging and nearly fullmBatteryLight.setColor(mBatteryFullARGB);} else {// Solid orange when charging and halfway fullmBatteryLight.setColor(mBatteryMediumARGB);}} else {// No lights if not charging and not lowmBatteryLight.turnOff();}}

这段逻辑就是控制底层亮灯行为;大家可以仔细看一下有没有问题,在status为CHARGING或者FULL的时候亮灯。这是一个或逻辑!也就是说或在充电,或满,就显示红灯(惯例),那么有没有可能是FULL而不是CHARGING呢?又或者既不是CHARGING也不是FULL的时候按照这里的逻辑是灭灯,但是手机还连着USB线呢? 这里就涉及到了充电相关的知识。

       电量低的时候,不在充电则闪烁,充电则常亮; 而充电时亮两种灯,充满与不充满; 那么你一定会问,可以有不在充电但是满的情况吗? 有的;但是,FULL的时候一定是连接着充电器的,所以一定会亮灯。而不连接充电器的时候也是满的怎么办?不连接充电器的时候一定不是FULL,而是DIS_CHARGING,放电状态,所以关灯。还有一种情况,连接着充电器,又不满 FULL,又不在充电CHARGING,也就是所谓的NOT_CHARGING状态。这种状态亮不亮灯呢? 按照这个逻辑一定是关灯的。NOT_CHARGING在高通平台上通过/sys/class/power_supply/battery/battery_charging_enabled这个节点来实现。也就是插着USB线只做调试不做充电,实测与逻辑一致,是灭灯的。该节点后来移动其他地方去了,又后来隐藏了。

接下来我们看hardware中的接口hardware/qcom/display/liblight/lights.c中定义了各种接口,比如很重要的呼吸灯接口handle_speaker_battery_locked()

如果在充电,又有消息来,那么我们通常的逻辑就是消息优先显示,而充电作为第二优先级;则这里就需要改动,调换g_battery与g_notification的顺序。

static void
handle_speaker_battery_locked(struct light_device_t* dev)
{if (is_lit(&g_battery)) {set_speaker_light_locked(dev, &g_battery);} else {set_speaker_light_locked(dev, &g_notification);}
}

这个文件下,通过写sysfs节点的方式与驱动层进行数据交流:

/sys/class/leds/%s/delay_off

通过设置常亮,或者亮灭的时间间隔达到呼吸灯的效果。

再往下就是驱动层的事情了。

由此,我们就清楚了android亮灯的逻辑。

相关文章:

  • Linux学习笔记3-GPIO(1)
  • 63基于matlab的生物地理的优化器(BBO)被用作多层感知器(MLP)的训练器。
  • Python---集合中的交集 、并集 | 与差集 - 特性
  • 基于单片机的塑料厂房气体检测系统设计
  • Java读取文件内容写入新文件
  • 深入理解 Django 单元测试
  • 企业大数据治理管理平台解决方案:PPT全文33页,附下载
  • 四、Vue3中使用Pinia解构Store
  • UML建模语言
  • Linux 安装与配置
  • SpringBoot 是什么
  • Python数据容器之[列表]
  • postman上传照片,视频,音频等上传文件操作测试方法
  • 【C#学习】backgroundWorker控件
  • Qt之qobject_cast使用
  • Angular4 模板式表单用法以及验证
  • CSS盒模型深入
  • express如何解决request entity too large问题
  • MySQL的数据类型
  • MySQL用户中的%到底包不包括localhost?
  • node入门
  • Objective-C 中关联引用的概念
  • Protobuf3语言指南
  • vue2.0开发聊天程序(四) 完整体验一次Vue开发(下)
  • 百度小程序遇到的问题
  • 码农张的Bug人生 - 见面之礼
  • 容器服务kubernetes弹性伸缩高级用法
  • 首页查询功能的一次实现过程
  • 学习使用ExpressJS 4.0中的新Router
  • 一份游戏开发学习路线
  • #pragma once
  • #QT(一种朴素的计算器实现方法)
  • #我与Java虚拟机的故事#连载08:书读百遍其义自见
  • (附源码)springboot金融新闻信息服务系统 毕业设计651450
  • (免费领源码)python#django#mysql校园校园宿舍管理系统84831-计算机毕业设计项目选题推荐
  • (三)Hyperledger Fabric 1.1安装部署-chaincode测试
  • (十)DDRC架构组成、效率Efficiency及功能实现
  • (四)汇编语言——简单程序
  • (转)jdk与jre的区别
  • (转)shell调试方法
  • .NET : 在VS2008中计算代码度量值
  • .Net Core webapi RestFul 统一接口数据返回格式
  • .Net IE10 _doPostBack 未定义
  • .NET程序员迈向卓越的必由之路
  • .NET开源的一个小而快并且功能强大的 Windows 动态桌面软件 - DreamScene2
  • @angular/cli项目构建--Dynamic.Form
  • @GlobalLock注解作用与原理解析
  • @TableId注解详细介绍 mybaits 实体类主键注解
  • @取消转义
  • []Telit UC864E 拨号上网
  • [2018][note]用于超快偏振开关和动态光束分裂的all-optical有源THz超表——
  • [8-23]知识梳理:文件系统、Bash基础特性、目录管理、文件管理、文本查看编辑处理...
  • [Angular 基础] - 数据绑定(databinding)
  • [Angularjs]asp.net mvc+angularjs+web api单页应用
  • [ASP.NET MVC]如何定制Numeric属性/字段验证消息