公司项目开发VR设备,VR系统是在AndroidN基础上定制的。最近需要对LED灯做一些逻辑控制,于是查看了下led灯相关的代码,下面简单分享下:
安卓系统的呼吸灯在BatteryService里面写了一段逻辑,在电池信息变化的时候更新呼吸灯状态。
BatteryService路径在 “frameworks/base/services/core/java/com/android/server/BatteryService.java”
private void update(BatteryProperties props) {
synchronized (mLock) {
if (!mUpdatesStopped) {
mBatteryProps = props;
// Process the new values.
processValuesLocked(false);
} else {
mLastBatteryProps.set(props);
}
}
}
private void processValuesLocked(boolean force) {
...
// Update the battery LED
mLed.updateLightsLocked();
...
}
public void updateLightsLocked() {
final int level = mBatteryProps.batteryLevel;
final int status = mBatteryProps.batteryStatus;
if (level < mLowBatteryWarningLevel) {
if (status == BatteryManager.BATTERY_STATUS_CHARGING) {
// Solid red when battery is charging
mBatteryLight.setColor(mBatteryLowARGB);
} else {
// Flash red when battery is low and not charging
mBatteryLight.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 full
mBatteryLight.setColor(mBatteryFullARGB);
} else {
if (isHvdcpPresent()) {
// Blinking orange if HVDCP charger
mBatteryLight.setFlashing(mBatteryMediumARGB, Light.LIGHT_FLASH_TIMED,
mBatteryLedOn, mBatteryLedOn);
} else {
// Solid orange when charging and halfway full
mBatteryLight.setColor(mBatteryMediumARGB);
}
}
} else {
// No lights if not charging and not low
mBatteryLight.turnOff();
}
}
updateLightsLocked里面根据电量大小和电池状态控制led灯
led控制的接口如下
public abstract class Light {
public static final int LIGHT_FLASH_NONE = 0;
public static final int LIGHT_FLASH_TIMED = 1;
public static final int LIGHT_FLASH_HARDWARE = 2;
/**
* Light brightness is managed by a user setting.
*/
public static final int BRIGHTNESS_MODE_USER = 0;
/**
* Light brightness is managed by a light sensor.
*/
public static final int BRIGHTNESS_MODE_SENSOR = 1;
public abstract void setBrightness(int brightness);
public abstract void setBrightness(int brightness, int brightnessMode);
public abstract void setColor(int color);
public abstract void setFlashing(int color, int mode, int onMS, int offMS);
public abstract void pulse();
public abstract void pulse(int color, int onMS);
public abstract void turnOff();
}
具体实现在“frameworks/base/services/java/com/android/server/LightsService.java”
比如 turnOff() 方法
public void turnOff() {
synchronized (this) {
setLightLocked(0, LIGHT_FLASH_NONE, 0, 0, 0);
}
}
private void setLightLocked(int color, int mode, int onMS, int offMS, int brightnessMode) {
if (!mLocked && (color != mColor || mode != mMode || onMS != mOnMS || offMS != mOffMS ||
mBrightnessMode != brightnessMode)) {
if (DEBUG) Slog.v(TAG, "setLight #" + mId + ": color=#"
+ Integer.toHexString(color) + ": brightnessMode=" + brightnessMode);
mLastColor = mColor;
mColor = color;
mMode = mode;
mOnMS = onMS;
mOffMS = offMS;
mLastBrightnessMode = mBrightnessMode;
mBrightnessMode = brightnessMode;
Trace.traceBegin(Trace.TRACE_TAG_POWER, "setLight(" + mId + ", 0x"
+ Integer.toHexString(color) + ")");
try {
setLight_native(mNativePointer, mId, color, mode, onMS, offMS, brightnessMode);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
}
}
最终通过JNI调用底层方法
static native void setLight_native(long ptr, int light, int color, int mode, int onMS, int offMS, int brightnessMode);
setLight_native里面调用set_light转入HAL层
呼吸灯的HAL层对应位置如下:
mediatek/hardware/liblights/lights.c
后面没有再往下跟踪,但我们可以知道,在HAL中最后,点亮,关闭和闪烁呼吸灯,点亮和关闭呼吸灯都是直接操作设备接口: RED_LED_FILE = “/sys/class/leds/red/brightness”;