Android4.4 LightsService使用笔记(一)

简介: 笔记

框架图


8.png

一、先看framework层提供的API


LightsService中的一些注释

路径frameworks/base/services/java/com/android/server/LightsService.java

//灯的定义
public static final int LIGHT_ID_BACKLIGHT = 0;//LCD背光灯
public static final int LIGHT_ID_KEYBOARD = 1;//键盘灯
public static final int LIGHT_ID_BUTTONS = 2;//按键灯
public static final int LIGHT_ID_BATTERY = 3;//电池灯
public static final int LIGHT_ID_NOTIFICATIONS = 4;//消息通知等灯
public static final int LIGHT_ID_ATTENTION = 5;//警示灯
public static final int LIGHT_ID_BLUETOOTH = 6;//蓝牙灯
public static final int LIGHT_ID_WIFI = 7;//Wifi灯
//闪烁方式
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;
//存放Light对象的数组
private final Light mLights[] = new Light[LIGHT_ID_COUNT];
//构造方法
LightsService(Context context) {
    mNativePointer = init_native();
    mContext = context;
    ServiceManager.addService("hardware",mLegacyFlashlightHack);
    for (int i = 0; i < LIGHT_ID_COUNT; i++) {
        mLights[i] = new Light(i);
    }
}
/*
*根据id获取对应的Light对象
*/
public Light getLight(int id) {
    return mLights[id];
}
//本地方法
private static native int init_native();  //初始化
private static native void finalize_native(int ptr); //释放资源 
//设置灯参数
private static native void setLight_native(int ptr, int light, int color, int mode,
        int onMS, int offMS, int brightnessMode);

LightsService中的内部类Light的一些注释

Light的方法定义有如下几个:

public void setBrightness(int brightness);
public void setBrightness(int brightness, int brightnessMode);
public void setColor(int color);
public void setFlashing(int color, int mode, int onMS, int offMS);
public void pulse();
public void pulse(int color, int onMS);
public void turnOff();

Light类的方法详解

setBrightness

/*
*这个方法是设置灯的亮度值,它最终会将这个亮度brightness(取值范围0~255)转换成色彩值
*color(ARGB)。我们知道颜色都是三基色RGB组成的,我们要控制的灯基本上都是单色的,
*要么是红色,要么是绿色。所以在转换过程中,是将亮度值对应的数值分别设置到RGB三色
*中,也就是每一个单色上都设置为跟亮度相同的数值,这样无论控制的是什么颜色的灯,都会将
*亮度值设置为brightness。其中0xff000000表示的是ARGB模式,A表示的是透明度。在实际操作过程中,只要亮度值大于0,设置任意数值都会起到相同的作用,都能够达到点亮灯的效果。
*/
public void setBrightness(int brightness, int brightnessMode) {
    synchronized (this) {
        int color = brightness & 0x000000ff;
        color = 0xff000000 | (color << 16) | (color << 8) | color;
        setLightLocked(color, LIGHT_FLASH_NONE, 0, 0, brightnessMode);
    }
}

setLightLocked

这个方法名中之所以要加上Locked,是因为在调用这个方法的时候都要放在关键字synchronized的作用域中

private void setLightLocked(int color, int mode, int onMS, int offMS, int brightnessMode) {
     if (color != mColor || mode != mMode || onMS != mOnMS || offMS != mOffMS) {
         if (DEBUG) Slog.v(TAG, "setLight #" + mId + ": color=#"
                 + Integer.toHexString(color));
         mColor = color;
         mMode = mode;
         mOnMS = onMS;
         mOffMS = offMS;
         setLight_native(mNativePointer, mId, color, mode, onMS, offMS, brightnessMode);
     }
 }

例如其它方法都同步调用setLightLocked方法:

public void turnOff() {
    synchronized (this) {
        setLightLocked(0, LIGHT_FLASH_NONE, 0, 0, 0);
    }
}
private void stopFlashing() {
    synchronized (this) {
        setLightLocked(mColor, LIGHT_FLASH_NONE, 0, 0, BRIGHTNESS_MODE_USER);
    }
}

二、JNI层


com_android_server_LightsService.cpp

路径:frameworks/base/services/jni/com_android_server_LightsService.cpp

LightsService调用了LightsService.cpp的本地方法,下面看一下该类。

com_android_server_LightsService.cpp的一些注释

//关键引入hardware模块和lights模块接口
#include <hardware/hardware.h>
#include <hardware/lights.h>
//入口函数,注册方法
int register_android_server_LightsService(JNIEnv *env)
{
    return jniRegisterNativeMethods(env, "com/android/server/LightsService",
            method_table, NELEM(method_table));
}
//注册方法表
static JNINativeMethod method_table[] = {
    { "init_native", "()I", (void*)init_native },
    { "finalize_native", "(I)V", (void*)finalize_native },
    { "setLight_native", "(IIIIIII)V", (void*)setLight_native },
};
//LIGHT_ID定义,与LightsService.java中定义的必须一致
// These values must correspond with the LIGHT_ID constants in LightsService.java
enum {
    LIGHT_INDEX_BACKLIGHT = 0,
    LIGHT_INDEX_KEYBOARD = 1,
    LIGHT_INDEX_BUTTONS = 2,
    LIGHT_INDEX_BATTERY = 3,
    LIGHT_INDEX_NOTIFICATIONS = 4,
    LIGHT_INDEX_ATTENTION = 5,
    LIGHT_INDEX_BLUETOOTH = 6,
    LIGHT_INDEX_WIFI = 7,
    LIGHT_COUNT
};
//定义结构体
struct Devices {
    light_device_t* lights[LIGHT_COUNT];
};
//初始化方法
static jint init_native(JNIEnv *env, jobject clazz)
{
    int err;
    hw_module_t* module;
    Devices* devices;
    //为Light设备分配内存
    devices = (Devices*)malloc(sizeof(Devices));
    //根据模块ID获取Lights模块,LIGHTS_HARDWARE_MODULE_ID定义在lights.h中
    //#define LIGHTS_HARDWARE_MODULE_ID "lights"
    err = hw_get_module(LIGHTS_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
    if (err == 0) {  //err=0表示获取Lights模块成功
        //Light设备内存的初始化,根据不同的LIGHT_ID获取对应的设备,LIGHT_ID_XX 定义在lights.h中
        devices->lights[LIGHT_INDEX_BACKLIGHT]
                = get_device(module, LIGHT_ID_BACKLIGHT);
        devices->lights[LIGHT_INDEX_KEYBOARD]
                = get_device(module, LIGHT_ID_KEYBOARD);
        devices->lights[LIGHT_INDEX_BUTTONS]
                = get_device(module, LIGHT_ID_BUTTONS);
        devices->lights[LIGHT_INDEX_BATTERY]
                = get_device(module, LIGHT_ID_BATTERY);
        devices->lights[LIGHT_INDEX_NOTIFICATIONS]
                = get_device(module, LIGHT_ID_NOTIFICATIONS);
        devices->lights[LIGHT_INDEX_ATTENTION]
                = get_device(module, LIGHT_ID_ATTENTION);
        devices->lights[LIGHT_INDEX_BLUETOOTH]
                = get_device(module, LIGHT_ID_BLUETOOTH);
        devices->lights[LIGHT_INDEX_WIFI]
                = get_device(module, LIGHT_ID_WIFI);
    } else {
        memset(devices, 0, sizeof(Devices));
      }
     return (jint)devices;
 }
//根据ID获取设备
static light_device_t* get_device(hw_module_t* module, char const* name)
{
    int err;
    hw_device_t* device;
    //打开设备,err=0表示打开成功
    err = module->methods->open(module, name, &device);
    if (err == 0) {
        return (light_device_t*)device;
    } else {
        return NULL;
    }
}
/*设置Light设备的参数
* env: jni环境变量
* clazz:调用该本地方法的java对象
*  ptr: light设备的地址指针
*  light: light的id值
* colorARGB:颜色值
* flashMode:闪烁模式(不闪烁/根据设置时间闪烁/硬件控制闪烁)
* onMS: 闪烁时light打开时长
* offMS: 闪烁时light关闭时长
* brightnessMode:背光亮度模式(传感器/用户设置)
*/
static void setLight_native(JNIEnv *env, jobject clazz, int ptr,
        int light, int colorARGB, int flashMode, int onMS, int offMS, int brightnessMode)
{
    Devices* devices = (Devices*)ptr;  //根据指针获取到实例对象
    light_state_t state;
    //判断light id值是否合法必须>=0并且小于LIGHT_COUNT,设备的light对象不能为空
    if (light < 0 || light >= LIGHT_COUNT || devices->lights[light] == NULL) {
        return ;
    }
    //生成参数写入到state对象
    memset(&state, 0, sizeof(light_state_t));
    state.color = colorARGB;
    state.flashMode = flashMode;
    state.flashOnMS = onMS;
    state.flashOffMS = offMS;
    state.brightnessMode = brightnessMode;
    {
        ALOGD_IF_SLOW(50, "Excessive delay setting light");
        //将state对象设置到light对象中
        devices->lights[light]->set_light(devices->lights[light], &state);
    }
}
//销毁LightService
static void finalize_native(JNIEnv *env, jobject clazz, int ptr)
{   
    Devices* devices = (Devices*)ptr;
    if (devices == NULL) {  //对象指向空地址
        return;
    }
    free(devices);//释放内存空间
}


目录
相关文章
|
6天前
|
Linux 编译器 Android开发
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
在Linux环境下,本文指导如何交叉编译x265的so库以适应Android。首先,需安装cmake和下载android-ndk-r21e。接着,下载x265源码,修改crosscompile.cmake的编译器设置。配置x265源码,使用指定的NDK路径,并在配置界面修改相关选项。随后,修改编译规则,编译并安装x265,调整pc描述文件并更新PKG_CONFIG_PATH。最后,修改FFmpeg配置脚本启用x265支持,编译安装FFmpeg,将生成的so文件导入Android工程,调整gradle配置以确保顺利运行。
24 1
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
|
5天前
|
存储 Java API
Android系统 文件访问权限笔记
Android系统 文件访问权限笔记
35 1
|
6月前
|
Java Android开发
[笔记]Android 学习一之转场动画+ViewPager+ListView简单Demo
[笔记]Android 学习一之转场动画+ViewPager+ListView简单Demo
|
6月前
|
Android开发
[笔记]Android开发之相机开发 Camera1、2、X
[笔记]Android开发之相机开发 Camera1、2、X
|
10月前
|
Java Android开发 容器
Android实战开发--小慕笔记UI设计(Fragment布局的使用)
Android实战开发--小慕笔记UI设计(Fragment布局的使用)
Android实战开发--小慕笔记UI设计(Fragment布局的使用)
|
存储 前端开发 Shell
Android Jetpack Compose——一个简单的笔记APP
此项目功能较为简单,基本就是使用Room数据库实现CRUD,但是此项目实现了一个干净的架构,项目使用MVVM架构进行设计,每一个模块的职责划分清晰,功能明确,没有冗余的代码。其中涉及了Hilt依赖注入,对于数据库的的操作,使用接口实现类进行获取,然后将实现类的CRUD操作封装在一个数据类中,最后通过Hilt自动注入依赖,供外部调用。
582 1
Android Jetpack Compose——一个简单的笔记APP
|
编解码 Java Linux
|
Java Android开发 安全