Android中背光系统架构
2011-09-24 16:00
323 查看
Mg Android中背光系统架构
Email:wei7758@126.com
Blog:http://blog.csdn.net/yinwei520
Author:Yww
Time:2011-9-24
Update:
(转载请注明出处,谢谢)
不知不觉喜欢上了写Blog,这还是一种不错的休闲方式,所噶~~,会不会也害怕过周末呢?因为寂寞~~啥样儿的生活才让觉得舒适哦~单身好~哈哈。搞了两天,还是姚哥一语惊醒梦中人啊~忽略了Linux下的权限问题,让我纠结了好几个小时啊。首先说明一下,这次学习中让我学到的东西:
最主要的莫过于是了解了Android中jni编程,游荡整个Android源码,可以看到很多直接操作底层驱动接口,封装成so库,供Java调用的例子哦。
这次学习,也正是出于这样的想法,没想到这个设想高手们早就实现了哦,菜鸟现在也只能算是验证了。诶,菜鸟就是菜鸟,有虫子吃,就兴奋的不得了。
驱动架构略,这里只讨论jni接口的实现。
一、我的设想
其实设想很简单,找到背光驱动提供给上层的API接口,人家Android还不是一样需要一层一层的抽象(HAL、Framework),高手们考虑的东东很多,所以才一层层抽象封装,既然这样,咱菜鸟不就一根筋,有虫吃就是王道啊,我为什么不能直接将这个驱动接口封装成jni提供给Java呢?其实这想法很早就有了,只是到现在才验证,确实可以啊。其实Android中还是有N多这样的例子的。
背光驱动提供的接口是:/sys/class/leds/lcd-backlight/brightness。至于这个接口是怎么来的??那就要去看驱动结构了。驱动注册此接口的源码位于:
Kernel/driver/leds/led-class.c中。
这个文件只是实现了提供上层的接口,至于真正操作硬件的驱动程序,可以给出其源码路径为:(硬件操作其实就是脉宽调制(PWM)),mediatek\source\kernel\drivers\leds
二、设想验证
这里关键就是要清楚jni的接口实现规则咯,不过环境搭建也比较麻烦(ndk编译环境)。
环境搭建另外给出日志。
Jni接口的源码如下:
上层Java调用的源码如下:(只是实现了一个Button,点击,有一个消息响应,将背光调到20)
看上去,没几行代码,so easy!!看看高手们的实现吧!!
三、Android中背光系统实现
以往,我经常都是从底层往上看,这次从上层往下找找吧,同样的眼睛,不一样的视角,会别有一番风景哦~~其实,美女也要应该这样欣赏。
玩玩Android机子,其实知道背光调节就是在“设置”中的那个seekBar,那我们就去setting中去找源码吧.其源码路径为:
packages\apps\Settings\src\com\android\settings\ BrightnessPreference.java
打开看看吧~宽衣解带是最让人兴奋的啊。你会看到这样几行注释:
// Backlight range is from 0 - 255. Need to make sure that user
// doesn't set the backlight to 0 and get stuck
private static final intMINIMUM_BACKLIGHT = android.os.Power.BRIGHTNESS_DIM + 10;
private static final int
MAXIMUM_BACKLIGHT = android.os.Power.BRIGHTNESS_ON;
背光的调节范围是0-255啊~~
继续解带吧~会看到一个很亲切的函数:
public void UpdateBrightness()
{
if(mIsActive)
{
setBrightness(mSeekBar.getProgress() +MINIMUM_BACKLIGHT);
}
}
更新背光亮度,太亲切了,这不慢慢接近目标了吗?其调用了setBrightness()函数,跳进去看看其实现哦~~
private void setBrightness(int brightness) {
try {
IPowerManager power = IPowerManager.Stub.asInterface(
ServiceManager.getService("power"));
if (power !=null) {
power.setBacklightBrightness(brightness);
}
} catch (RemoteException doe) {
}
}
这不就是韩哥给出的那几行代码嘛~~呵呵~终于找到要点了吧,所谓打蛇要打七寸,不就是这样吗?这个IPowerManager类中有个setBacklightBrightness函数啊,那它又是怎么实现的啊?找来找去只找到了一个申明啊:
public void setBacklightBrightness(int brightness)throws android.os.RemoteException;
找不到其实现怎么办呢??这是个棘手的问题啊~还好Eclipse很恶心啊~~搜搜就又出来了,这个函数的实现在:
frameworks\base\services\java\com\android\server\PowerManagerService.java中。
看着看着又模糊啦,这里怎么又调用了setBrightness()哦,此setBrightness非BrightnessPreference.java中的setBrightness。其类属于:
private LightsService.Light mLcdLight;
革命尚未成功,你说咋办,那好吧,为了革命的胜利,再进去看看这个类中setBrightness()的实现吧。源码路径为:
frameworks\base\services\java\com\android\server\LightsService.java
这里又调用了setLightLocked()
革命的曙光来啦,看到没,这里调用了setLight_native这个本地接口,
private static native void setLight_native(int ptr,int light,int color,int mode,
int onMS,int offMS,int brightnessMode);
皇天不负有心人啊,胜利的曙光照耀着我们啊,终于就快脱光光啦~~!难以按捺住这颗激动的心啊。
可是这个setLight_native又是在哪里呢??经过一番苦苦搜索,它并不在灯火阑珊处,而是在:
frameworks\base\services\jni\ com_android_server_LightsService.cpp
宽衣,看看:
四、JNI层
哇,高手就是高手啊。看看,一个函数人家处理的不只是backlight,还有flash,color哦。惭愧啊~
到此,一个美女就这样被你看完啦~~当然,还有三点哦~~还想要激情的吗??激情就在底层了哦。想单刀直入吗?那还得看你本事了哦~~
devices->lights[light]->set_light(devices->lights[light], &state);
这句将带你穿梭进赤裸裸的XX。
五、HAL层
太神奇啦,这里直接给出HAL层的源码路劲,如下:
\mediatek\source\hardware\liblights\ lights.c
\hardware\libhardware\include\hardware\ lights.h
你会看到引你越过道德边缘的set_light的申明就在lights.h中啊。真是罪孽啊~~
看看吧,其实我们需要找的就是set_light_backlight。
当你认真看完lights.c会发现其基本思想跟之前的设想一样,只是人家是高手,我是菜鸟,人家看到赤裸裸的美女不是表面,而是艺术~~~~!!
通过这个分析,可以延伸了解到led灯的结构。
Email:wei7758@126.com
Blog:http://blog.csdn.net/yinwei520
Author:Yww
Time:2011-9-24
Update:
(转载请注明出处,谢谢)
不知不觉喜欢上了写Blog,这还是一种不错的休闲方式,所噶~~,会不会也害怕过周末呢?因为寂寞~~啥样儿的生活才让觉得舒适哦~单身好~哈哈。搞了两天,还是姚哥一语惊醒梦中人啊~忽略了Linux下的权限问题,让我纠结了好几个小时啊。首先说明一下,这次学习中让我学到的东西:
最主要的莫过于是了解了Android中jni编程,游荡整个Android源码,可以看到很多直接操作底层驱动接口,封装成so库,供Java调用的例子哦。
这次学习,也正是出于这样的想法,没想到这个设想高手们早就实现了哦,菜鸟现在也只能算是验证了。诶,菜鸟就是菜鸟,有虫子吃,就兴奋的不得了。
驱动架构略,这里只讨论jni接口的实现。
一、我的设想
其实设想很简单,找到背光驱动提供给上层的API接口,人家Android还不是一样需要一层一层的抽象(HAL、Framework),高手们考虑的东东很多,所以才一层层抽象封装,既然这样,咱菜鸟不就一根筋,有虫吃就是王道啊,我为什么不能直接将这个驱动接口封装成jni提供给Java呢?其实这想法很早就有了,只是到现在才验证,确实可以啊。其实Android中还是有N多这样的例子的。
背光驱动提供的接口是:/sys/class/leds/lcd-backlight/brightness。至于这个接口是怎么来的??那就要去看驱动结构了。驱动注册此接口的源码位于:
Kernel/driver/leds/led-class.c中。
这个文件只是实现了提供上层的接口,至于真正操作硬件的驱动程序,可以给出其源码路径为:(硬件操作其实就是脉宽调制(PWM)),mediatek\source\kernel\drivers\leds
二、设想验证
这里关键就是要清楚jni的接口实现规则咯,不过环境搭建也比较麻烦(ndk编译环境)。
环境搭建另外给出日志。
Jni接口的源码如下:
#include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> //#include <dirent.h> //#include <jni.h> #include <string.h> #include <android/log.h> #include "com_yecon_CtlBL_CtlBLActivity.h" #define LOG_TAG "ctlbl.c" #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) //#define DEV_PATH "/sys/class/leds/lcd-backlight/brightness" //#define DEV_PATH "/sys/devices/platform/leds-mt65xx/leds/lcd-backlight/brightness" /** * native method */ //JNIEXPORT jobjectArray JNICALL Java_com_yecon_CtlBL_CtlBLActivity_ctlbl(JNIEnv * env, jobject obj) JNIEXPORT jint JNICALL Java_com_yecon_CtlBL_CtlBLActivity_ctlbl(JNIEnv * env, jobject obj) { int fd; int err; char *p; char ctl[10]={"20"}; LOGI("HELLO!\n"); //__android_log_print(""); //printf("call ctlbl function succ!\n"); fd = open("/sys/class/leds/lcd-backlight/brightness",O_RDWR); if(fd < 0) { //fprintf(stderr,"error: open %s\n",DEV_PATH); LOGI("error: open!\n"); exit(1); } #if 0 err = read(fd,ctl,1); if(err != 1) { //fprintf(stderr,"error: write %d!\n",err); exit(1); }else{ //printf("the data is %s\n",ctl[0]); } #endif err=write(fd,ctl,2); //printf("%s\n",ctl); if(err != 2) { //fprintf(stderr,"error: write %d!\n",err); LOGI("error: write !\n"); exit(1); } close(fd); return 0; //return (*env)->NewStringUTF(env, "Hello ww JNI !"); }
上层Java调用的源码如下:(只是实现了一个Button,点击,有一个消息响应,将背光调到20)
package com.yecon.CtlBL; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; //import com.yecon.CtlBL.ctlbljni; public class CtlBLActivity extends Activity { Button b = null; // ctl = new ctlbljni(); private OnClickListener clickListener = new OnClickListener(){ @Override public void onClick(View v) { // TODO Auto-generated method stub // ctl.ctlbl(); ctlbl(); } }; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); b = (Button) this.findViewById(R.id.BtnCancel); b.setOnClickListener(clickListener); // TextView tv = new TextView(this); // tv.setText( ctlbl() ); // setContentView(tv); } public native int ctlbl();//本地方法 static { System.loadLibrary("ctlbl");//载入so库 } }
看上去,没几行代码,so easy!!看看高手们的实现吧!!
三、Android中背光系统实现
以往,我经常都是从底层往上看,这次从上层往下找找吧,同样的眼睛,不一样的视角,会别有一番风景哦~~其实,美女也要应该这样欣赏。
玩玩Android机子,其实知道背光调节就是在“设置”中的那个seekBar,那我们就去setting中去找源码吧.其源码路径为:
packages\apps\Settings\src\com\android\settings\ BrightnessPreference.java
打开看看吧~宽衣解带是最让人兴奋的啊。你会看到这样几行注释:
// Backlight range is from 0 - 255. Need to make sure that user
// doesn't set the backlight to 0 and get stuck
private static final intMINIMUM_BACKLIGHT = android.os.Power.BRIGHTNESS_DIM + 10;
private static final int
MAXIMUM_BACKLIGHT = android.os.Power.BRIGHTNESS_ON;
背光的调节范围是0-255啊~~
继续解带吧~会看到一个很亲切的函数:
public void UpdateBrightness()
{
if(mIsActive)
{
setBrightness(mSeekBar.getProgress() +MINIMUM_BACKLIGHT);
}
}
更新背光亮度,太亲切了,这不慢慢接近目标了吗?其调用了setBrightness()函数,跳进去看看其实现哦~~
private void setBrightness(int brightness) {
try {
IPowerManager power = IPowerManager.Stub.asInterface(
ServiceManager.getService("power"));
if (power !=null) {
power.setBacklightBrightness(brightness);
}
} catch (RemoteException doe) {
}
}
这不就是韩哥给出的那几行代码嘛~~呵呵~终于找到要点了吧,所谓打蛇要打七寸,不就是这样吗?这个IPowerManager类中有个setBacklightBrightness函数啊,那它又是怎么实现的啊?找来找去只找到了一个申明啊:
public void setBacklightBrightness(int brightness)throws android.os.RemoteException;
找不到其实现怎么办呢??这是个棘手的问题啊~还好Eclipse很恶心啊~~搜搜就又出来了,这个函数的实现在:
frameworks\base\services\java\com\android\server\PowerManagerService.java中。
public void setBacklightBrightness (int brightness) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); // Don't let applications turn the screen all the way off synchronized (mLocks) { brightness = Math.max(brightness, Power.BRIGHTNESS_DIM); mLcdLight.setBrightness(brightness); //We won't adjust Button/Keyboard BKL here for the time being, see CR[ALPS00132847] //mKeyboardLight.setBrightness(mKeyboardVisible ? brightness : 0); //mButtonLight.setBrightness(brightness); long identity = Binder.clearCallingIdentity(); try { mBatteryStats.noteScreenBrightness(brightness); } catch (RemoteException e) { Slog.w(TAG, "RemoteException calling noteScreenBrightness on BatteryStatsService", e); } finally { Binder.restoreCallingIdentity(identity); } // update our animation state synchronized (mLocks) { mScreenBrightness.targetValue = brightness; mScreenBrightness.jumpToTargetLocked(); } } }
看着看着又模糊啦,这里怎么又调用了setBrightness()哦,此setBrightness非BrightnessPreference.java中的setBrightness。其类属于:
private LightsService.Light mLcdLight;
革命尚未成功,你说咋办,那好吧,为了革命的胜利,再进去看看这个类中setBrightness()的实现吧。源码路径为:
frameworks\base\services\java\com\android\server\LightsService.java
public void setBrightness(int brightness) { setBrightness(brightness, BRIGHTNESS_MODE_USER); } 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()
private void setLightLocked(int color, int mode, int onMS, int offMS, int brightnessMode) { if (color != mColor || mode != mMode || onMS != mOnMS || offMS != mOffMS) { mColor = color; mMode = mode; mOnMS = onMS; mOffMS = offMS; setLight_native(mNativePointer, mId, color, mode, onMS, offMS, brightnessMode); } }
革命的曙光来啦,看到没,这里调用了setLight_native这个本地接口,
private static native void setLight_native(int ptr,int light,int color,int mode,
int onMS,int offMS,int brightnessMode);
皇天不负有心人啊,胜利的曙光照耀着我们啊,终于就快脱光光啦~~!难以按捺住这颗激动的心啊。
可是这个setLight_native又是在哪里呢??经过一番苦苦搜索,它并不在灯火阑珊处,而是在:
frameworks\base\services\jni\ com_android_server_LightsService.cpp
宽衣,看看:
四、JNI层
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; if (light < 0 || light >= LIGHT_COUNT || devices->lights[light] == NULL) { return ; } memset(&state, 0, sizeof(light_state_t)); state.color = colorARGB; state.flashMode = flashMode; state.flashOnMS = onMS; state.flashOffMS = offMS; state.brightnessMode = brightnessMode; devices->lights[light]->set_light(devices->lights[light], &state); } static JNINativeMethod method_table[] = { { "init_native", "()I", (void*)init_native }, { "finalize_native", "(I)V", (void*)finalize_native }, { "setLight_native", "(IIIIIII)V", (void*)setLight_native }, };
哇,高手就是高手啊。看看,一个函数人家处理的不只是backlight,还有flash,color哦。惭愧啊~
到此,一个美女就这样被你看完啦~~当然,还有三点哦~~还想要激情的吗??激情就在底层了哦。想单刀直入吗?那还得看你本事了哦~~
devices->lights[light]->set_light(devices->lights[light], &state);
这句将带你穿梭进赤裸裸的XX。
五、HAL层
太神奇啦,这里直接给出HAL层的源码路劲,如下:
\mediatek\source\hardware\liblights\ lights.c
\hardware\libhardware\include\hardware\ lights.h
你会看到引你越过道德边缘的set_light的申明就在lights.h中啊。真是罪孽啊~~
/** * module methods */ /** Open a new instance of a lights device using name */ 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)) { set_light = set_light_backlight; } else if (0 == strcmp(LIGHT_ID_KEYBOARD, name)) { set_light = set_light_keyboard; } else if (0 == strcmp(LIGHT_ID_BUTTONS, name)) { set_light = set_light_buttons; } 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_ATTENTION, name)) { set_light = set_light_attention; } else { return -EINVAL; } pthread_once(&g_init, init_globals); struct light_device_t *dev = malloc(sizeof(struct light_device_t)); 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; }
看看吧,其实我们需要找的就是set_light_backlight。
static int set_light_backlight(struct light_device_t* dev, struct light_state_t const* state) { int err = 0; int brightness = rgb_to_brightness(state); pthread_mutex_lock(&g_lock); LOGD("%s: brightness=%d start+++\n", __func__, brightness); g_backlight = brightness; err = write_int(LCD_FILE, brightness); if (g_haveTrackballLight) { handle_trackball_light_locked(dev); } pthread_mutex_unlock(&g_lock); return err; }
当你认真看完lights.c会发现其基本思想跟之前的设想一样,只是人家是高手,我是菜鸟,人家看到赤裸裸的美女不是表面,而是艺术~~~~!!
通过这个分析,可以延伸了解到led灯的结构。
相关文章推荐
- android背光系统架构
- Android中背光系统架构
- Android中背光系统架构
- Android中背光系统架构
- Android系统架构
- Android系统架构概述
- Android源码笔记——Camera系统架构
- Google工程师多图详解Android系统架构
- Android系统架构的详细解析——很全面
- Android系统架构详解
- Android系统架构图
- Android 系统中 Location Service 的实现与架构
- Android 系统架构
- Android系统架构学习
- Android系统架构
- Android系统架构初探
- Android与iOS系统架构对比
- android系统架构解析
- Android 系统中 Location Service 的实现与架构