Android系统呼吸灯源码简单跟踪分析

公司项目开发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";


在上一篇文章我们提到如何直接通过操作底层文件,实现led灯的控制。



猜你喜欢

转载自blog.csdn.net/killfunst/article/details/78666077