注意在led-classes.c中定义的led_class_attrs[]所建立的文件的属性应该改为0666,否则应用程序无权操作它

同时ledtrig-time.c里面对应新建的那几个delay_on/delay_off也要改为0666,这样才能写它

Java: frameworks/base/services/core/java/com/android/server/lights/LightsService.java
JNI: frameworks/base/services/core/jni/com_android_server_lights_LightsService.cpp
Hal: lights.c  //参考google上搜索到的lights.c,我们的开发上只有HAL的so库,在vendor/friendly-arm/tiny4412/proprietary/lights_tiny4412.so

默认配色:frameworks/base/core/res/res/values/config.xml
电池灯:frameworks/base/services/core/java/com/android/server/BatteryService.java
通知灯:frameworks/base/services/core/java/com/android/server/notification/NotificationManagerService.java

怎么写LIGHTS HAL
a. 实现一个名为HMI的hw_module_t结构体
b. 实现一个open函数, 它会根据name返回一个light_device_t结构体
c. 实现多个light_device_t结构体,每一个对应一个DEVICE
 light_device_t结构体里第1个成员是hw_device_t结构体, 紧接着一个set_light函数

设置LED状态:
struct light_state_t {
/**
* The color of the LED in ARGB.
*
* Do your best here.
* - If your light can only do red or green, if they ask for blue,
* you should do green.
* - If you can only do a brightness ramp, then use this formula:
* unsigned char brightness = ((77*((color>>16)&0x00ff))
* + (150*((color>>8)&0x00ff)) + (29*(color&0x00ff))) >> 8;
* - If you can only do on or off, 0 is off, anything else is on.
*
* The high byte should be ignored. Callers will set it to 0xff (which
* would correspond to 255 alpha).
*/
unsigned int color; // 把灯设为什么颜色, 或 把LCD的亮度设为什么

/**
* See the LIGHT_FLASH_* constants
*/
int flashMode; // 是否闪烁, LIGHT_FLASH_NONE表示不闪
int flashOnMS; // 亮的时间
int flashOffMS;// 灭的时间

/**
* Policy used by the framework to manage the light's brightness.
* Currently the values are BRIGHTNESS_MODE_USER and BRIGHTNESS_MODE_SENSOR.
*/
int brightnessMode; // 表示LCD的背光亮度模式
};

lights.c文件

注意在led-classes.c中定义的led_class_attrs[]所建立的文件的属性应该改为0666,否则应用程序无权操作它

#define LOG_TAG “lights”

#define LOG_NDEBUG 0  //加上这句就可以用ALOGV来打印了,否则打印信息被忽略

#include <hardware/led_hal.h>

#include <hardware/hardware.h>

......还有很多头文件.........

//HAL里面操作led等就是往这些文件里面写值来完成的

char const*const RED_LED_FILE                                = "sys/class/leds/led1/brightness";

char const*const GREEN_LED_FILE          = "sys/class/leds/led2/brightness";

char const*const BLUE_LED_FILE        = "sys/class/leds/led3/brightness";

char const*const RED_LED_FILE_TRIGGER    =  "sys/class/leds/led1/trigger";

char const*const GREEN_LED_FILE_TRIGGER  =  "sys/class/leds/led2/trigger";

char const*const BLUE_LED_FILE_TRIGGER    =  "sys/class/leds/led3/trigger";

char const*const RED_LED_FILE_DELAYON    =  "sys/class/leds/led1/delay_on";

char const*const GREEN_LED_FILE_DELAYON    =  "sys/class/leds/led2/delay_on";

char const*const BLUE_LED_FILE_DELAYON    =  "sys/class/leds/led3/delay_on";

char const*const RED_LED_FILE_DELAYOFF    =  "sys/class/leds/led1/delay_off";

char const*const GREEN_LED_FILE_DELAYOFF    =  "sys/class/leds/led2/delay_off";

char const*const BLUE_LED_FILE_DELAYOFF    =  "sys/class/leds/led3/delay_off";

char const*const LCD_BACKLIGHT_FILE = "/dev/backlight-1wire";//反汇编厂家提供的HAL层SO,lights_tiny4412.so,可以看到对背光灯的操作是该文件,在内核中搜索“backlight-1wire”,发现其是对应drivers/input/touchscreen/tiny4412_1wire_host.c中注册的设备,其是一个miscdevice,提供了file_operation结构体

static pthread_one_t g_init = PTHREAD_ONCE_INIT;

static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER;

//通知灯和电池灯公用一个硬件

static struct light_state_t g_notification;

static struct light_state_t g_battery;

static int write_int(const char *path,int value){

  int fd;

  static int already_warned = 0;

  fd = open(path,O_RDWR);

  if(fd<0)

  {

    if(already_warned == 0)

    {

      already_warned = 1;

    }

    return -errno;

  }

  char buffer[20];

  int bytes = snprintf(buffer,sizeof(buffer),"%s\n",value);

  int written = write(fd,buffer,bytes);

  close(fd);

  return written == -1?-errno:0;

}

static int write_string(const char *path,const char *value){

  int fd;

  static int already_warned = 0;

  fd = open(path,O_RDWR);

  if(fd<0)

  {

    if(already_warned == 0)

    {

      already_warned = 1;

    }

    return -errno;

  }

  char buffer[20];

  int bytes = snprintf(buffer,sizeof(buffer),"%s\n",value);

  int written = write(fd,buffer,bytes);

  close(fd);

  return written == -1?-errno:0;

}

static int is_lit(struct light_state_t const * state){

  return state->color & 0x00ffffff;

}

static int rgb_to_brightness(struct light_state_t const * state){

  int color = state->color & 0x00ffffff;

  return ((77*((color>>16)&0x00ff))+(150*((color>>8)&0x00ff))+(29*(color&0x00ff)))>>

}

static int set_light_backlight(struct light_device_t *dev,,struct light_state_t *state){

  int brightness = rgb_to_brightness(state);

  pthread_mutex_lock(&g_lock);

  //brightness在这里的范围是0-255,但是设备文件能接受的是0-127

  write_int(LCD_BACKLIGHT_FILR,brightness/2);

  pthread_mutex_unlock(&g_lock);

  return 0;

}

static void set_shared_light_locked(struct light_device_t *dev,struct light_state_t *state){

  int r,g,b;

  int delayOn,delayOff;

  r = (state->color>>16)&0xff;

  g = (state->color>>8)&0xff;

  b = (state->color)&0xff;

  delayOn = state->flashOnMS;

  delayOff = state->flashOffMS;

  if(state->flashMode != LIGHT_FLASH_NONE){

    write_string(RED_LED_FILE_TRIGGER,"trigger");

    write_string(GREEN_LED_FILE_TRIGGER,"trigger");

    write_string(BLUE_LED_FILE_TRIGGER,"trigger");

    write_int(RED_LED_FILR_DELAYON,delayOn);

    write_int(GREEN_LED_FILR_DELAYON,delayOn);

    write_int(BLUE_LED_FILR_DELAYON,delayOn);

    write_int(RED_LED_FILR_DELAYOFF,delayOff);

    write_int(GREEN_LED_FILR_DELAYOFF,delayOff);

    write_int(BLUE_LED_FILR_DELAYOFF,delayOff);

  }else{

    write_string(RED_LED_FILE_TRIGGER,"none");

    write_string(GREEN_LED_FILE_TRIGGER,"none");

    write_string(BLUE_LED_FILE_TRIGGER,"none");

    

  }

  write_int(RED_LED_FILE,r);

  write_int(GREEN_LED_FILE,g);

  write_int(BLUE_LED_FILE,b)

}

static void handle_shared_battery_locked(struct light_device_t *dev){

  if(is_lit(&g_notification)){//优先设置通知灯

    set_shared_light_locked(dev,&g_notification);

  }else{

    set_shared_light_locked(dev,&g_battery);

  }

}

static int set_light_battery((struct light_device_t *dev,struct light_state_t *state){

  pthread_mutex_lock(&g_lock);

  g_battery = *state;

  handle_shared_battery_locked(dev);

  pthread_mutex_unlock(&g_lock);

  return 0;

}

static int set_light_notifications((struct light_device_t *dev,struct light_state_t *state){

  pthread_mutex_lock(&g_lock);

  g_notification = *state;

  handle_shared_battery_locked(dev);

  pthread_mutex_unlock(&g_lock);

  return 0;

}

void init_globals(){

  pthread_mutex_init(&g_lock,NULL);

}

static int close_lights(struct light_device_t* dev){

}

static int open_lights(const struct hw_module_t *module,const char *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))

    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{

    return -EINVAL;

  }

  pthread_once(&g_init,init_globals);

  struct light_device_t *dev = malloc(sizeof(struct light_device_t),GPKERNEL);

  memset(dev,0,sizeof(*dev));

  dev->common.tag = HARDWARE_DEVICE_TAG;

  dev->common.version = 0;

  dev->common.module = (struct hw_module_t *)module;

  dev->common.close = (int (*)(struct hw_device_t *))close_lights;

  dev->set_light = set_light;

  *device = (struct hw_device_t*)dev;

  return 0;

  *device = &led_dev //led_dev 的第一个成员就是hw_device_t ,他们地址一样

}

static struct hw_module_methods_t lights_module_methods {

  .open = open_lights,

};

struct hw_module_t HAL_MODULE_INFO_SYM = {

  .tag = HARDWARE_MODULE_TAG,

  .version_major = 1,

  .version_minor = 0,

  .id = LIGHTS_HARDWARE_MODULE_ID,

  .name ="Snoy_lights_module",

  .methods = lights_module_methods ;

}

在lights.c下添加Android.mk

Android.mk内容如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := lights.tiny4412;

LOCAL_MODULE_RELATIVE_PATH :=hw  //指定了so存在的目录在/system/lib/hw下

LOCAL_C_INCLUDES := hardware/libhardware  //头文件

LOCAL__SRC_FILES := lights.c  //源文件

LOCAL_SHARED_LIBRARIES := liblog

LOCAL_MODULE_TAGS := eng

include $(BUILD_SHARED_LIBRARY)

上传HAL:lights.c

 hardware/libhardware/modules/lights/lights.c

 hardware/libhardware/modules/lights/Android.mk

修改:

vi vendor friendly-arm/tiny4412/device-tiny4412.mk

注释掉device-tiny4412.mk里面的(应该是去掉厂家提供的HAL)

ifeq ($(BOARD_USES_PWMLIGHTS),false)

#PRODUCT_COPY_FILES +=\

#      $(VENDOR_PATH)/proprietary/lights.tiny4412.so:system/lib/hw/lights.tiny4412.so

endif

编译:

.setenv//先设置环境变量

lunch//执行后选择23 full_tiny4412_eng  这里的eng对应的Android.mk里面设置的eng

mmm hardware/libhardware/modules/lights -B  //强制编译C库

make snod

./gen-img.sh

对比下厂家提供HAL和我们自己生成的HAL,会发现不一样,同时该命令也能确保我们提供的lights.c已经编进system.img

diff vendor/friendly-arm/tiny4412/proprietary/lights.tiny4412.so  out/target/product/tiny4412/system/lib/hw/lights.tiny4412.so

更新system.img 和上一节中得到的zImage

8.3 Android灯光系统_编写HAL_lights.c的更多相关文章

  1. Android灯光系统_编写HAL_lights.c【转】

    本文转载自:https://blog.csdn.net/qq_33443989/article/details/77074411 1>. 编写灯光系统的HAL层 之 HAL_light.c1&l ...

  2. 8.1 Android灯光系统_总体框架

    1.框架 APP(java语言实现) ------------------------------- JNI(c++语言实现)     向上提供Java执行c函数的接口  向下访问HAL ------ ...

  3. 8.6 Android灯光系统_源码分析_背光灯

    Change system screen brightness, using android.provider.Settings.System.SCREEN_BRIGHTNESSandroid-er. ...

  4. 8.5 Android灯光系统_源码分析_通知灯

    参考文章(应用程序举例)how to use the LED with Android phonehttp://androidblogger.blogspot.jp/2009/09/tutorial- ...

  5. 8.4 Android灯光系统_源码分析_电池灯

    电池灯的Java代码在batteryservice.java中 电池的状态电量等信息由驱动获得,但驱动不会主动做这些事情,因此肯定有个App调用驱动程序读取电池信息,称这个App为A应用. 还有个Ap ...

  6. Android系统--灯光系统驱动编写

    Android系统开发--Android灯光系统tiny4412_led_class驱动编写 框架分析 led_classdev_4412结构体 创建led_classdev_4412结构体 分配结构 ...

  7. Android灯光系统--通知灯深入分析【转】

    本文转自:https://www.cnblogs.com/lkq1220/p/6406261.html Android灯光系统--通知灯深入分析 通知的类别 声音 振动 闪灯 APP如何发出通知灯请求 ...

  8. Android灯光系统--通知灯深入分析

    Android灯光系统--通知灯深入分析 通知的类别 声音 振动 闪灯 APP如何发出通知灯请求 getSystemService(获得通知服务) 构造notification 类别 其他参数(颜色, ...

  9. Android灯光系统--深入理解背光灯

    Android灯光系统--深入理解背光灯 一.怎么控制背光灯(简述) APP将亮度值写入数据库 线程检测数据库的值是否发生变化 这种机制成为"内容观察者"--contentObse ...

随机推荐

  1. 怎样通过MSG_WAITALL设置阻塞时间,IO模式精细讲解: MSG_DONTWAIT 、 MSG_WAITALL

    首先给出MSDN上一段设置阻塞超时的代码:(网址为http://social.msdn.microsoft.com/Forums/zh-SG/visualcpluszhchs/thread/3d9da ...

  2. 13.Axis创建webservice客户端和服务端

    转自:https://blog.csdn.net/chenghui0317/article/details/9318317 一.Axis的介绍 Web Service是现在最适合实现SOA的技术,而A ...

  3. 38.C语言字符串总结

    1.自己实现三个常用函数 strlen,strcpy,strstr 自己实现strstr函数,如果找到返回首地址,找不到则返回NULL //查找元素,返回首地址 char *mystrstr(cons ...

  4. C++的继承和Java继承的比较

    在C++中继承可分为公有继承(public)保护继承(protected)和私有继承(private),而在Java中默认只有一种继承(相当于C++中的公有继承)下面我们来看一段代码 #include ...

  5. IOS应用在ios7(iPhone5/iPhone5s)上不能全屏显示

    前言 [IOS应用在iOS7系统或者iPhone5/iPhone5s上不能全屏显示,应用画面上下各有1条黑色,但是在其他系统或者型号的手机上却是正常显示 Paste_Image.png Paste_I ...

  6. C#List<string>和string[]之间的相互转换

     一.LIST概述 所属命名空间:System.Collections.Generic      public class List<T> : IList<T>, IColle ...

  7. exit---退出目前的shell

    exit命令   exit命令同于退出shell,并返回给定值.在shell脚本中可以终止当前脚本执行.执行exit可使shell以指定的状态值退出.若不设置状态值参数,则shell以预设值退出.状态 ...

  8. PLSQL乱码&TNS-12557: protocol adapter not loadable解决

    PLSQL乱码&TNS-12557: protocol adapter not loadable解决 PLSQL乱码&TNS-12557: protocol adapter not l ...

  9. 8 Great Java 8 Features No One's Talking about--转载

    原文地址:http://www.infoq.com/articles/Java-8-Quiet-Features If you haven’t seen some of the videos or t ...

  10. BZOJ1396: 识别子串(后缀自动机,线段树)

    Description Input 一行,一个由小写字母组成的字符串S,长度不超过10^5 Output L行,每行一个整数,第i行的数据表示关于S的第i个元素的最短识别子串有多长. Sample I ...