栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Android 通知灯设置

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android 通知灯设置

  系统通知灯相关文件

 frameworks/base/services/core/java/com/android/server/lights/LightsManager.java 

 frameworks/base/services/core/java/com/android/server/lights/LogicalLight.java

 frameworks/base/services/core/java/com/android/server/lights/LightsService.java

 frameworks/base/services/core/jni/com_android_server_lights_LightsService.cpp

 hardware/interfaces/light/2.0/default/Light.cpp

 hardware/qcom/display/liblight/lights.c 

一、LightsManager.java 

主要定义各种灯类型和一个 getLight 抽象函数

public abstract class LightsManager {
    public static final int LIGHT_ID_BACKLIGHT = Type.BACKLIGHT; //背光灯
    public static final int LIGHT_ID_KEYBOARD = Type.KEYBOARD; //键盘灯
    public static final int LIGHT_ID_BUTTONS = Type.BUTTONS; //按键灯
    public static final int LIGHT_ID_BATTERY = Type.BATTERY; //电池指示灯
    public static final int LIGHT_ID_NOTIFICATIONS = Type.NOTIFICATIONS; //通知灯
    public static final int LIGHT_ID_ATTENTION = Type.ATTENTION; //重要灯
    public static final int LIGHT_ID_BLUETOOTH = Type.BLUETOOTH; //蓝牙
    public static final int LIGHT_ID_WIFI = Type.WIFI; //WIFI灯
    public static final int LIGHT_ID_COUNT = Type.COUNT; //这个表示灯类型数量

    public abstract LogicalLight getLight(int id);
}

二、LogicalLight.java

定义调用接口,供系统使用,其实现在 LightsService$LightImpl 中

三、LightsService.java

系统服务,实际实现led控制功能,往下调用 jni native函数

    @Override
    public void onStart() {
        publishLocalService(LightsManager.class, mService);
        publishBinderService(Context.LIGHTS_SERVICE, mManagerService);
    }

    ... ...

    private final LightsManager mService = new LightsManager() {
        @Override
        public LogicalLight getLight(int lightType) {
            if (mLightsByType != null && 0 <= lightType && lightType < mLightsByType.length) {
                return mLightsByType[lightType];
            } else {
                return null;
            }
        }
    };

 内部主要是使用一个 LightsService$LightImpl(LogicalLight 实现类)数组 mLightsByType ,保存所有类型灯的对象,通过 getSystemService 获取 LightsManager 需要根据不同灯的类型去获取对应的对象。

LightImpl 中是所有led相关操作上层接口的实现,例如设置灯打开、关闭、颜色、亮度、闪烁等。

        @Override
        public void setColor(int color) {
            synchronized (this) {
                // 设置颜色灯是常亮的,使用 LIGHT_FLASH_NONE
                setLightLocked(color, LIGHT_FLASH_NONE, 0, 0, 0);
            }
        }

        @Override
        public void setFlashing(int color, int mode, int onMS, int offMS) {
            synchronized (this) {
                setLightLocked(color, mode, onMS, offMS, BRIGHTNESS_MODE_USER);
            }
        }

mode 有三种:

public static final int LIGHT_FLASH_NONE = Flash.NONE;


public static final int LIGHT_FLASH_TIMED = Flash.TIMED;


public static final int LIGHT_FLASH_HARDWARE = Flash.HARDWARE;

四、com_android_server_lights_LightsService.cpp

系统 jni 层,调用 HIDL 服务端接口

Return ret = hal->setLight(type, state);

五、hardware/interfaces/light/2.0/default/Light.cpp 

HIDL 服务端接口,继续调用系统的 HAL 库函数

Return Light::setLight(Type type, const LightState& state)  {
    auto it = mLights.find(type);
    if (it == mLights.end()) {
        return Status::LIGHT_NOT_SUPPORTED;
    }
    light_device_t* hwLight = it->second;
    light_state_t legacyState {
        .color = state.color,
        .flashMode = static_cast(state.flashMode),
        .flashonMS = state.flashOnMs,
        .flashOffMS = state.flashOffMs,
        .brightnessMode = static_cast(state.brightnessMode),
    };
    int ret = hwLight->set_light(hwLight, &legacyState);
    switch (ret) {
        case -ENOSYS:
            return Status::BRIGHTNESS_NOT_SUPPORTED;
        case 0:
            return Status::SUCCESS;
        default:
            return Status::UNKNOWN;
    }
}

mLights 也是根据不同的灯 id 类型保存了一个数组 

六、hardware/qcom/display/liblight/lights.c

系统的 HAL 库代码文件,直接操作系统节点,实现 led 控制

static int
set_light_battery(struct light_device_t* dev,
        struct light_state_t const* state)
{
    pthread_mutex_lock(&g_lock);
    g_battery = *state;
    handle_speaker_battery_locked(dev);
    pthread_mutex_unlock(&g_lock);
    return 0;
}
static int
set_light_notifications(struct light_device_t* dev,
        struct light_state_t const* state)
{
    pthread_mutex_lock(&g_lock);
    g_notification = *state;
    handle_speaker_battery_locked(dev);
    pthread_mutex_unlock(&g_lock);
    return 0;
}


static int open_lights(const struct hw_module_t* module, char const* name,
        struct hw_device_t** device)
{
    int (*set_light)(struct light_device_t* dev,
            struct light_state_t const* state);
    if (0 == strcmp(LIGHT_ID_BACKLIGHT, name)) {
        g_has_persistence_node = !access(PERSISTENCE_FILE, F_OK);
        set_light = set_light_backlight;
    } else if (0 == strcmp(LIGHT_ID_BATTERY, name))
        set_light = set_light_battery;
    else if (0 == strcmp(LIGHT_ID_NOTIFICATIONS, name))
        set_light = set_light_notifications;
    else if (0 == strcmp(LIGHT_ID_BUTTONS, name)) {
        if (!access(BUTTON_FILE, F_OK)) {
          // enable light button when the file is present
          set_light = set_light_buttons;
        } else {
          return -EINVAL;
        }
    }

... ...
}

根据不同灯的类型执行不同函数,以通知灯电量灯为例,最后执 handle_speaker_battery_locked

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);
    }
}

系统在这里对电量灯和通知灯做了区分,有电量指示灯时通知灯的设置是无效的。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/713534.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号