lights从上到下的流程

frameworks/base/core/res/res/values/config.xml里面的配置项config_automatic_brightness_available, 如果在没贴光感的情况下, 设置为 false,setting中就会自动去掉“自动调节亮度”   ,如果还是true,可能会出现 没有光感的情况下唤醒屏幕时按键灯不会亮的情况。               
        

先来看张框架图
lights从上到下的流程_第1张图片

下面分析各个流程

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

文件:packages/apps/Settings/src/com/android/settings/BrightnessPreference.java
private static final int MINIMUM_BACKLIGHT = android.os.Power.BRIGHTNESS_DIM + 10;
private static final int MAXIMUM_BACKLIGHT = android.os.Power.BRIGHTNESS_ON;
mSeekBar.setMax(MAXIMUM_BACKLIGHT - MINIMUM_BACKLIGHT);

 设置亮度

public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
setMode(isChecked ? Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC
: Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
if (!isChecked) {
         setBrightness(mSeekBar.getProgress() + MINIMUM_BACKLIGHT);
}
}

private void setBrightness(int brightness) {
    try {
                IPowerManager power = IPowerManager.Stub.asInterface(
                                                           ServiceManager.getService("power"));
               if (power != null) {
                     power.setBacklightBrightness(brightness);
               }
    } catch (RemoteException doe) {

    }       
}
由以上代码可知,brightness的范围是:20~255;

代码通过ServiceManager获得power服务,然后通过power服务设置亮度。


power.setBacklightBrightness的定义在:
frameworks/base/core/java/android/os/IPowerManager.aidl.java

    // sets the brightness of the backlights (screen, keyboard, button) 0-255
    void setBacklightBrightness(int brightness);
    void setAttentionLight(boolean on, int color);

设置进度条的范围,BRIGHTNESS_DIM = 20  BRIGHTNESS_ON=255,它们的定义在:
frameworks/base/core/java/android/os/Power.java

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


 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

    public void setBacklightBrightness(int brightness)
    {
        try {
            mService.setBacklightBrightness(brightness);
        } catch (RemoteException e) {
        }
    }

mService如何赋值的??


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


----------->/system/framework/services.jar

frameworks/base/services/java/com/android/server/PowerManagerService.java

    private LightsService.Light mLcdLight;
    private LightsService.Light mButtonLight;
    private LightsService.Light mKeyboardLight;


void init(Context context, LightsService lights, IActivityManager activity,
            BatteryService battery) {
        mLightsService = lights;
        mContext = context;
        mActivityService = activity;
        mBatteryStats = BatteryStatsService.getService();
        mBatteryService = battery;

        mLcdLight = lights.getLight(LightsService.LIGHT_ID_BACKLIGHT);
        mButtonLight = lights.getLight(LightsService.LIGHT_ID_BUTTONS);
        mKeyboardLight = lights.getLight(LightsService.LIGHT_ID_KEYBOARD);
        mAttentionLight = lights.getLight(LightsService.LIGHT_ID_ATTENTION);
    mFlashLedLight= lights.getLight(LightsService.LIGHT_ID_FLASHLED);


//设置亮度

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

方法接口:

        mButtonLight.setBrightness(brightness);

         mButtonLight.setBrightness(buttonValue);

         // make sure button and key backlights are off too
         mButtonLight.turnOff();


LightsService.Light是LightsService的内部类,其实现在下面的文件中
----------->/system/framework/services.jar

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

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

这个文件就是通过JNI调用native函数,把native函数进行封装,以对上层提供更多的API,真正native函数就3个:
    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);

真正的设置亮度是setLight_native,其他成员函数都是对此函数封装,如在PowerManagerService.java中调用的
        public void turnOff() {
            synchronized (this) {
                setLightLocked(0, LIGHT_FLASH_NONE, 0, 0, 0);
            }
        }

 public void setBrightness(int brightness, int brightnessMode)

//brightness是亮度值,brightnessMode是模式即 BRIGHTNESS_MODE_USER (* Light brightness is managed by a user setting
) 还是BRIGHTNESS_MODE_SENSOR( Light brightness is managed by a light sensor.),对应

设置->声音和显示->亮度,



上面3个native函数在此文件中被调用,其实现在com_android_server_LightsService.cpp

上面两个文件都在services.jar中



----------->/system/lib/libandroid_servers.so

/frameworks/base/services/jni/com_android_server_LightsService.cpp


此文件的入口是register_android_server_LightsService(),在onload.cpp中调用,

主要动作

注册方法表

static JNINativeMethod method_table[] = {
    { "init_native", "()I", (void*)init_native },
    { "finalize_native", "(I)V", (void*)finalize_native },
    { "
setLight_native", "(IIIIIII)V", (void*)setLight_native},

//Java fn                                                Cpp Function

};

这就是对应LightsService.java中3个函数的实现

其中init_native中通过ID打开硬件模块,即/system/lib/hw/lights.sprdbp.so

hw_get_module(LIGHTS_HARDWARE_MODULE_ID, (hw_module_t const**)&module);

这就可以调到light的hal层了,于是进入


----------->/system/lib/hw/lights.sprdbp.so

/hardware/sprd/hsdroid/liblights/lights.c

最重要是定义硬件模块,也是文件入口如下

/*
 * The lights Module
 */
const struct hw_module_t HAL_MODULE_INFO_SYM = {
    .tag = HARDWARE_MODULE_TAG,
    .version_major = 1,
    .version_minor = 0,
    .id = LIGHTS_HARDWARE_MODULE_ID,
    .name = "SPRD sc8800 lights Module",
    .author = "Spreadtrum, Inc.",
    .methods = &lights_module_methods,
};

在hal中通过驱动提供的sysfs接口来设置对应led亮度

char const*const KEYBOARD_FILE
        = "/sys/class/leds/keyboard-backlight/brightness";

char const*const BUTTON_FILE
        = "/sys/class/leds/button-backlight/brightness";

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);
    /*
    LOGE("####: sprd/lights.c: set_light_backlight() brightness = %d. #####\n", 
          brightness);
    */
    pthread_mutex_lock(&g_lock);
    g_backlight = brightness;
    err = write_int(LCD_FILE, brightness);
    if (g_haveTrackballLight) {
        handle_trackball_light_locked(dev);
    }
    pthread_mutex_unlock(&g_lock);
    return err;
}


再向下就是driver文件

/kernel/drivers/leds/leds-sc8810-kb.c

sprd_kb_led_probe()中led->cdev.name = "keyboard-backlight";

/kernel/drivers/leds/leds-sc8810-lcd.c


参考  http://jinguo.iteye.com/blog/974208

lights从上到下的流程_第2张图片



案例:lightsensor调节背光不明显

自动调节背光亮度是通过如下代码来实现的

frameworks/base/core/res/res/values/config.xml 

      
        Must be overridden in platform specific overlays -->
    <integer-array name="config_autoBrightnessLevels">
    <item>20</item>
    <item>85</item>
    <item>347</item>
    <item>1500</item>
    </integer-array>

    <!-- Array of output values for LCD backlight corresponding to the LUX values
         in the config_autoBrightnessLevels array.  This array should have size one greater
         than the size of the config_autoBrightnessLevels array.
         This must be overridden in platform specific overlays -->
    <integer-array name="config_autoBrightnessLcdBacklightValues">
    <item>20</item>
    <item>100</item>
    <item>150</item>
    <item>200</item>
    <item>250</item>
    </integer-array>

/frameworks/base/services/java/com/android/server/PowerManagerService.java
/*
*@sensorValue:lightsensor传上来的值
*@ values:具体调节背光数组,如是autoBrightnessLcdBacklightValues,或者autoBrightnessButtonBacklightValues
*
*/

private int getAutoBrightnessValue(int sensorValue, int[] values) { 

                                                                                       
 
             try {                                                                                         
 
                     int i;                                                                                         
 
                     for (i = 0; i < mAutoBrightnessLevels.length; i++) {                                                                                         
 
                             if (sensorValue < mAutoBrightnessLevels[i]) {                                                                                         
 
                                     break;                                                                                         
 
                             }                                                                                         
 
                     }                                                                                         
 
                     return values[i];                                                                                         
 
             } catch (Exception e) {                                                                                         
 
                     // guard against null pointer or index out of bounds errors                                                                                         
 
                     Slog.e(TAG, "getAutoBrightnessValue", e);                                                                                         
 
                     return 255;                                                                                         
 
             }                                                                                         
 
     }                                                                                         
此段代码的意思是,如果传入的sensorValue比config_autoBrightnessLevels的第i个值要小,则获得值是
values 的第i个值          
如拿lcdbacklight为例,sensorvalue和backlight背光值对应关系是
在0~20--------->20
20~85--------->100
85~347--------->150
347~1500--------->200
其他keyboardbrightness ,buttonbrightness与light sensor value的对应关系类似,都是通过call getAutoBrightnessValue()来取得的。
如果sensor value的变化始终在某一区间内(如由5-->19),则背光值是不会改变的(始终是20),
即没有亮度变化。
 
                                                                            
目前传入的sensorValue总是比config_autoBrightnessLevels的第一个值要小,所以每次lcdValue得到的值都是config_autoBrightnessLcdBacklig
htValues的第一个值                                                                                         
所以亮度一直都没实际变动。 
                                                                                       
前面根据日志,onSensorChanged方法里面每次获取当前亮度在0到20几之间,似乎和config_autoBrightnessLevels 的配置不协调,显得太小了。 
                                                                                       




你可能感兴趣的:(lights从上到下的流程)