Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3037513
  • 博文数量: 674
  • 博客积分: 17881
  • 博客等级: 上将
  • 技术积分: 4849
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-17 10:15
文章分类

全部博文(674)

文章存档

2013年(34)

2012年(146)

2011年(197)

2010年(297)

分类: LINUX

2012-06-21 10:19:44

亮度设置 
应用设计 
1.1 设置进度条范围 
背光设置是在:设置->声音和显示->亮度,通过进度条来设置的。 

文件: 
packages/apps/Settings/src/com/Android/settings/BrightnessPreference.java 
Java代码  收藏代码
  1. private static final int MINIMUM_BACKLIGHT = Android.os.Power.BRIGHTNESS_DIM + 10;  
  2. private static final int MAXIMUM_BACKLIGHT = Android.os.Power.BRIGHTNESS_ON;  
  3.   
  4. mSeekBar.setMax(MAXIMUM_BACKLIGHT - MINIMUM_BACKLIGHT);  

设置进度条的范围,BRIGHTNESS_DIM = 20  BRIGHTNESS_ON=255,它们的定义在: 

frameworks/base/core/java/Android/os/Power.java 

1.2 设置亮度 
文件:packages/apps/Settings/src/com/Android/settings/BrightnessPreference.java 
Java代码  收藏代码
  1. public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {  
  2.   
  3.        setMode(isChecked ? Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC  
  4.   
  5.                 : Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);  
  6.   
  7.         if (!isChecked) {  
  8.   
  9.             setBrightness(mSeekBar.getProgress() + MINIMUM_BACKLIGHT);  
  10.   
  11.         }  
  12.   
  13.     }  
  14.   
  15. private void setBrightness(int brightness) {  
  16.   
  17.         try {  
  18.   
  19.             IPowerManager power = IPowerManager.Stub.asInterface(  
  20.   
  21.                     ServiceManager.getService("power"));  
  22.   
  23.             if (power != null) {  
  24.   
  25.                 power.setBacklightBrightness(brightness);  
  26.   
  27.             }  
  28.   
  29.         } catch (RemoteException doe) {  
  30.   
  31.              
  32.   
  33.         }         
  34.   
  35. }  

由以上代码可知,brightness的范围是:20~255;代码通过服务管理器(ServiceManager)获得power服务,然后通过power服务设置亮度。 

power.setBacklightBrightness的定义在: 

rameworks/base/core/java/Android/os/IPowerManager.aidl.java 

frameworks/base/core/java/Android/os/PowerManager.java 

2, Power服务 
文件:frameworks/base/core/java/Android/os/Power.java 

/** 

     * Brightness value for dim backlight 

     */ 

    public static final int BRIGHTNESS_DIM = 20; 

    /** 

     * Brightness value for fully on 

     */ 

public static final int BRIGHTNESS_ON = 255; 

文件:frameworks/base/core/java/Android/os/PowerManager.java 
Java代码  收藏代码
  1. /** 
  2.  
  3.      * sets the brightness of the backlights (screen, keyboard, button). 
  4.  
  5.      * 
  6.  
  7.      * @param brightness value from 0 to 255 
  8.  
  9.      * 
  10.  
  11.      * {@hide} 
  12.  
  13.      */  
  14.   
  15.     public void setBacklightBrightness(int brightness)  
  16.   
  17.     {  
  18.   
  19.         try {  
  20.   
  21.             mService.setBacklightBrightness(brightness);  
  22.   
  23.         } catch (RemoteException e) {  
  24.   
  25.         }  
  26.   
  27. }  

电源管理器(powermager)将brightness转给电源服务,该服务位置如下: 

文件:frameworks/base/services/java/com/android/server/PowerManagerService.java +2934 
Java代码  收藏代码
  1. public void setBacklightBrightness(int brightness) {  
  2.         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);  
  3.         // Don't let applications turn the screen all the way off  
  4.         synchronized (mLocks) {  
  5.             brightness = Math.max(brightness, mScreenBrightnessDim);  
  6.             mLcdLight.setBrightness(brightness);  
  7.             mKeyboardLight.setBrightness(mKeyboardVisible ? brightness : 0);  
  8.             mButtonLight.setBrightness(brightness);  
  9.             long identity = Binder.clearCallingIdentity();  
  10.             try {  
  11.                 mBatteryStats.noteScreenBrightness(brightness);  
  12.             } catch (RemoteException e) {  
  13.                 Slog.w(TAG, "RemoteException calling noteScreenBrightness on BatteryStatsService", e);  
  14.             } finally {  
  15.                 Binder.restoreCallingIdentity(identity);  
  16.             }  
  17.   
  18.             // update our animation state  
  19.             synchronized (mLocks) {  
  20.                 mScreenBrightness.targetValue = brightness;  
  21.                 mScreenBrightness.jumpToTargetLocked();  
  22.             }  
  23.         }  
  24.     }  

由以上代码可知,同时设置了背光、键盘、按钮的亮度。mHardware 是硬件服务,通过该服务调用底层与设备打交道的C\C++代码,setLightBrightness_UNCHECKED原型如下: 

文件:frameworks/base/services/java/com/android/server/LightsService.java 

Java代码  收藏代码
  1. public void setBrightness(int brightness, int brightnessMode) {  
  2.     synchronized (this) {  
  3.         Resources resources = mContext.getResources();  
  4.         int mScreenBrightnessDim = resources.getInteger(  
  5.                 com.android.internal.R.integer.config_screenBrightnessDim);  
  6.         brightness = Math.max(brightness, mScreenBrightnessDim);  
  7.   
  8.         int color = brightness & 0x000000ff;  
  9.         color = 0xff000000 | (color << 16) | (color << 8) | color;  
  10.         setLightLocked(color, LIGHT_FLASH_NONE, 00, brightnessMode);  
  11.     }  
  12. }  

参数说明:int light 表示类型,选项如下: 

static final int LIGHT_ID_BACKLIGHT = 0; 

    static final int LIGHT_ID_KEYBOARD = 1; 

    static final int LIGHT_ID_BUTTONS = 2; 
    static final int LIGHT_ID_BATTERY = 3; 

    static final int LIGHT_ID_NOTIFICATIONS = 4; 

static final int LIGHT_ID_ATTENTION = 5; 

int brightness 表示亮度值 

int brightnessMode 表示亮度的控制模式,选项如下: 

/** 

     * Light brightness is managed by a user setting. 

     */ 

    static final int BRIGHTNESS_MODE_USER = 0; 

    /** 

     * Light brightness is managed by a light sensor. 

     */ 

static final int BRIGHTNESS_MODE_SENSOR = 1; 

由代码: 

int b = brightness & 0x000000ff; 

        b = 0xff000000 | (b << 16) | (b << | b; 

可知,亮度值在此进行了修改,即亮度值的格式变成:FFRRGGBB,FF是没有的,RR、GG、BB分别是256色的红绿蓝,并且红绿蓝的值都是一样的亮度值。 

3 硬件调用 
3.1获取硬件 
文件:frameworks/base/services/jni/com_android_server_LightsService.cpp +129 
Cpp代码  收藏代码
  1. static jint init_native(JNIEnv *env, jobject clazz)  
  2. {  
  3.     int err;  
  4.     hw_module_t* module;  
  5.     Devices* devices;  
  6.   
  7.     devices = (Devices*)malloc(sizeof(Devices));  
  8.   
  9.     err = hw_get_module(LIGHTS_HARDWARE_MODULE_ID, (hw_module_t const**)&module);  
  10.     if (err == 0) {  
  11.         devices->lights[LIGHT_INDEX_BACKLIGHT]  
  12.                 = get_device(module, LIGHT_ID_BACKLIGHT);  
  13.         devices->lights[LIGHT_INDEX_KEYBOARD]  
  14.                 = get_device(module, LIGHT_ID_KEYBOARD);  
  15.         devices->lights[LIGHT_INDEX_BUTTONS]  
  16.                 = get_device(module, LIGHT_ID_BUTTONS);  
  17.         devices->lights[LIGHT_INDEX_BATTERY]  
  18.                 = get_device(module, LIGHT_ID_BATTERY);  
  19.         devices->lights[LIGHT_INDEX_NOTIFICATIONS]  
  20.                 = get_device(module, LIGHT_ID_NOTIFICATIONS);  
  21.         devices->lights[LIGHT_INDEX_ATTENTION]  
  22.                 = get_device(module, LIGHT_ID_ATTENTION);  
  23.         devices->lights[LIGHT_INDEX_BLUETOOTH]  
  24.                 = get_device(module, LIGHT_ID_BLUETOOTH);  
  25.         devices->lights[LIGHT_INDEX_WIFI]  
  26.                 = get_device(module, LIGHT_ID_WIFI);  
  27.     } else {  
  28.         memset(devices, 0, sizeof(Devices));  
  29.     }  
  30.   
  31.     return (jint)devices;  
  32. }  

用hw_get_module获取ID为LIGHTS_HARDWARE_MODULE_ID的硬件模块,该模块含有6个不同类型的亮度控制。 

hw_get_module 的实现原理,如下: 

文件:hardware/libhardware/Hardware.c 
C代码  收藏代码
  1. #define HAL_LIBRARY_PATH "/system/lib/hw"  
  2.   
  3. static const char *variant_keys[] = {  
  4.   
  5.     "ro.hardware",  /* This goes first so that it can pick up a different 
  6.  
  7.                        file on the emulator. */  
  8.   
  9.     "ro.product.board",  
  10.   
  11.     "ro.board.platform",  
  12.   
  13.     "ro.arch"  
  14.   
  15. };  
  16.   
  17. static const int HAL_VARIANT_KEYS_COUNT =  
  18.   
  19.     (sizeof(variant_keys)/sizeof(variant_keys[0]));  
  20.   
  21. int hw_get_module_by_class(const char *class_id, const char *inst,  
  22.                            const struct hw_module_t **module)  
  23. {  
  24.     int status;  
  25.     int i;  
  26.     const struct hw_module_t *hmi = NULL;  
  27.     char prop[PATH_MAX];  
  28.     char path[PATH_MAX];  
  29.     char name[PATH_MAX];  
  30.   
  31.     if (inst)  
  32.         snprintf(name, PATH_MAX, "%s.%s", class_id, inst);  
  33.     else  
  34.         strlcpy(name, class_id, PATH_MAX);  
  35.   
  36.     /* 
  37.      * Here we rely on the fact that calling dlopen multiple times on 
  38.      * the same .so will simply increment a refcount (and not load 
  39.      * a new copy of the library). 
  40.      * We also assume that dlopen() is thread-safe. 
  41.      */  
  42.   
  43.     /* Loop through the configuration variants looking for a module */  
  44.     for (i=0 ; i
  45.         if (i < HAL_VARIANT_KEYS_COUNT) {  
  46.             if (property_get(variant_keys[i], prop, NULL) == 0) {  
  47.                 continue;  
  48.             }  
  49.             snprintf(path, sizeof(path), "%s/%s.%s.so",  
  50.                      HAL_LIBRARY_PATH2, name, prop);  
  51.             if (access(path, R_OK) == 0) break;  
  52.   
  53.             snprintf(path, sizeof(path), "%s/%s.%s.so",  
  54.                      HAL_LIBRARY_PATH1, name, prop);  
  55.             if (access(path, R_OK) == 0) break;  
  56.         } else {  
  57.             snprintf(path, sizeof(path), "%s/%s.default.so",  
  58.                      HAL_LIBRARY_PATH1, name);  
  59.             if (access(path, R_OK) == 0) break;  
  60.         }  
  61.     }  
  62.   
  63.     status = -ENOENT;  
  64.     if (i < HAL_VARIANT_KEYS_COUNT+1) {  
  65.         /* load the module, if this fails, we're doomed, and we should not try 
  66.          * to load a different variant. */  
  67.         status = load(class_id, path, module);  
  68.     }  
  69.   
  70.     return status;  
  71. }  
  72.   
  73. int hw_get_module(const char *id, const struct hw_module_t **module)  
  74. {  
  75.     return hw_get_module_by_class(id, NULL, module);  
  76. }  
  77.   
  78. }  

property_get(variant_keys[i], prop, NULL) 会按如下顺序去获取如下变量所对应的值,然后返回给prop: 

"ro.hardware",  /* This goes first so that it can pick up a different 

                       file on the emulator. */ 

    "ro.product.board", 

    "ro.board.platform", 

"ro.arch" 

它们对应的变量为: 

"ro.product.board=$TARGET_BOOTLOADER_BOARD_NAME" 

"ro.board.platform=$TARGET_BOARD_PLATFORM" 

如vendor/htc/dream-open/BoardConfig.mk里定义的TARGET_BOARD_PLATFORM := msm7k,则prop返回” msm7k ”,所以path = /system/lib/hw/lights. msm7k.so,也就是说要获取的硬件模块为lights. msm7k.so。 

3.2调用硬件 

setLight_native对应的jni C/C++代码是: 

文件:frameworks/base/frameworks/base/services/jni/com_android_server_LightsService.cpp 

Cpp代码  收藏代码
  1. static void setLight_native(JNIEnv *env, jobject clazz, int ptr,  
  2.         int light, int colorARGB, int flashMode, int onMS, int offMS, int brightnessMode)  
  3. {  
  4.     Devices* devices = (Devices*)ptr;  
  5.     light_state_t state;  
  6.   
  7.     if (light < 0 || light >= LIGHT_COUNT || devices->lights[light] == NULL) {  
  8.         return ;  
  9.     }  
  10.   
  11.     memset(&state, 0, sizeof(light_state_t));  
  12.     state.color = colorARGB;  
  13.     state.flashMode = flashMode;  
  14.     state.flashOnMS = onMS;  
  15.     state.flashOffMS = offMS;  
  16.     state.brightnessMode = brightnessMode;  
  17.   
  18.     devices->lights[light]->set_light(devices->lights[light], &state);  
  19. }  

通过light标识找到对应的light设备,然后再设置亮度。 

3.3 硬件原型 
msm7k的lights对应的硬件原型是在:hardware/msm7k/liblights 

文件:hardware/msm7k/liblights/Android.mk 

LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw 

LOCAL_MODULE := lights.$(TARGET_BOARD_PLATFORM) 

也就是生成模块:/system/lib/hw/lights. msm7k.so 

文件:device/softwinner/crane-common/hardware/libhardware/lights/lights.c 
C代码  收藏代码
  1. /** Open a new instance of a lights device using name */  
  2. static int open_lights(const struct hw_module_t* module, char const* name,  
  3.         struct hw_device_t** device)  
  4. {  
  5.     int (*set_light)(struct light_device_t* dev,  
  6.             struct light_state_t const* state);  
  7.   
  8.     LOGD("open_lights!name = %s\n",name);  
  9.     if (0 == strcmp(LIGHT_ID_BACKLIGHT, name)) {  
  10.         set_light = set_light_backlight;  
  11.     }  
  12.     else if (0 == strcmp(LIGHT_ID_KEYBOARD, name)) {  
  13.         set_light = set_light_keyboard;  
  14.     }  
  15.     else if (0 == strcmp(LIGHT_ID_BUTTONS, name)) {  
  16.         set_light = set_light_buttons;  
  17.     }  
  18.     else if (0 == strcmp(LIGHT_ID_BATTERY, name)) {  
  19.         set_light = set_light_battery;  
  20.     }  
  21.     else if (0 == strcmp(LIGHT_ID_NOTIFICATIONS, name)) {  
  22.         set_light = set_light_notifications;  
  23.     }  
  24.     else if (0 == strcmp(LIGHT_ID_ATTENTION, name)) {  
  25.         set_light = set_light_attention;  
  26.     }  
  27.     else {  
  28.         return -EINVAL;  
  29.     }  
  30.   
  31.     pthread_once(&g_init, init_globals);  
  32.   
  33.     struct light_context_t *dev = (struct light_context_t *)malloc(sizeof(struct light_context_t));  
  34.     memset(dev, 0, sizeof(struct light_context_t));  
  35.   
  36.     LOGD("light set back linghts!name = %s\n",name);  
  37.   
  38.         if(0 == strcmp(LIGHT_ID_BACKLIGHT, name))  
  39.     {  
  40.         dev->fd = open("/dev/disp", O_RDONLY);  
  41.         if (dev->fd < 0)  
  42.         {  
  43.             LOGE("Failed to open display device dev->fd = %x\n",dev->fd);  
  44.         }  
  45.     }  
  46.   
  47.     dev->device.common.tag = HARDWARE_DEVICE_TAG;  
  48.     dev->device.common.version = 0;  
  49.     dev->device.common.module = (struct hw_module_t*)module;  
  50.     dev->device.common.close = (int (*)(struct hw_device_t*))close_lights;  
  51.     dev->device.set_light = set_light;  
  52.   
  53.     *device = (struct hw_device_t*)dev;  
  54.   
  55.     return 0;  
  56.   
  57. error:  
  58.     free(dev);  
  59.   
  60.     return -EINVAL;  
  61. }  
  62.   
  63.   
  64. static struct hw_module_methods_t lights_module_methods = {  
  65.   
  66.     .open =  open_lights,  
  67.   
  68. };  

以上代码对应的是: 

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

也就是说,对不同的亮度设置给予了不同的设置函数。 

举例,背光设置,背光对应的代码如下: 
C代码  收藏代码
  1. static int  
  2. rgb_to_brightness(struct light_state_t const* state)  
  3. {  
  4.     int color = state->color & 0x00ffffff;  
  5.     int bright;  
  6.   
  7.     bright = ((77*((color>>16)&0x00ff)) + (150*((color>>8)&0x00ff)) + (29*(color&0x00ff))) >> 8;  
  8.   
  9.     //support backlight 0-255  
  10. //    bright = bright >> 4;  
  11.   
  12.   
  13.         /* fix bright value >=5 , for HW reason*/  
  14.         if(bright < 5)  
  15.                 bright = 5;  
  16.   
  17.     return bright;  
  18. }  
  19.   
  20.   
  21.   
  22. static int  
  23. set_light_backlight(struct light_device_t* dev,  
  24.         struct light_state_t const* state)  
  25. {  
  26.     struct light_context_t      *ctx;  
  27.   
  28.     int err = 0;  
  29.   
  30.     int brightness = rgb_to_brightness(state);  
  31.   
  32.     pthread_mutex_lock(&g_lock);  
  33.     g_backlight = brightness;  
  34.     ctx = (struct light_context_t *)dev;  
  35.     unsigned long  args[3];  
  36.   
  37.         args[0]  = 0;  
  38.         args[1]  = brightness;  
  39.         args[2]  = 0;  
  40.         err = ioctl(ctx->fd,DISP_CMD_LCD_SET_BRIGHTNESS,args);  
  41.   
  42.         if(err == 0)  
  43.         {  
  44.                 g_backlight = brightness;  
  45.         }  
  46.   
  47.     pthread_mutex_unlock(&g_lock);  
  48.   
  49.     return err;  
  50. }  


然后驱动层 
vendor/softwinner/linux-3.0/drivers/video/sun4i/disp/dev_disp.c 

vendor/softwinner/linux-3.0/drivers/video/sun4i/disp/de_bsp/de/disp_lcd.c +1739 



写寄存器 

C代码  收藏代码
  1. __s32 pwm_set_duty_ns(__u32 channel, __u32 duty_ns)  
  2. {  
  3.     __u32 active_cycle = 0;  
  4.     __u32 tmp;  
  5.   
  6.     active_cycle = (duty_ns * gdisp.pwm[channel].entire_cycle + (gdisp.pwm[channel].period_ns/2)) / gdisp.pwm[channel].period_ns;  
  7.   
  8.     if(channel == 0)  
  9.     {  
  10.             tmp = pwm_read_reg(0x204);  
  11.         pwm_write_reg(0x204,(tmp & 0xffff0000) | active_cycle);  
  12.     }  
  13.     else  
  14.     {  
  15.             tmp = pwm_read_reg(0x208);  
  16.         pwm_write_reg(0x208,(tmp & 0xffff0000) | active_cycle);  
  17.     }  
  18.   
  19.     gdisp.pwm[channel].duty_ns = duty_ns;  
  20.   
  21.     DE_INF("%d,%d,%d,%d\n", duty_ns, gdisp.pwm[channel].period_ns, active_cycle, gdisp.pwm[channel].entire_cycle);  
  22.     return 0;  
  23. }  
  24.   
  25.   
  26. //.....  
  27.   
  28. static __s32 pwm_write_reg(__u32 offset, __u32 value)  
  29. {  
  30.     sys_put_wvalue(gdisp.init_para.base_pwm+offset, value);  
  31.   
  32.     LCD_delay_ms(20);  
  33.   
  34.     return 0;  
  35. }  
阅读(1421) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~