android button light 流程分析(三) — framework

buttonandroidkeyboard代码分析jniresources

一、初始化信息

首先看看Android中的几种电源状态定义,这几个值定义了不同的led开闭状态以及lcd背光的不同亮度模式:

  1. // flags for setPowerState  
  2. private static final int SCREEN_ON_BIT          = 0x00000001;  
  3. private static final int SCREEN_BRIGHT_BIT      = 0x00000002;  
  4. private static final int BUTTON_BRIGHT_BIT      = 0x00000004;  
  5. private static final int KEYBOARD_BRIGHT_BIT    = 0x00000008;  
  6. private static final int BATTERY_LOW_BIT        = 0x00000010;  
  7.   
  8. // values for setPowerState  
  9.   
  10. // SCREEN_OFF == everything off  
  11. private static final int SCREEN_OFF         = 0x00000000;  
  12.   
  13. // SCREEN_DIM == screen on, screen backlight dim  
  14. private static final int SCREEN_DIM         = SCREEN_ON_BIT;  
  15.   
  16. // SCREEN_BRIGHT == screen on, screen backlight bright  
  17. private static final int SCREEN_BRIGHT      = SCREEN_ON_BIT | SCREEN_BRIGHT_BIT;  
  18.   
  19. // SCREEN_BUTTON_BRIGHT == screen on, screen and button backlights bright  
  20. private static final int SCREEN_BUTTON_BRIGHT  = SCREEN_BRIGHT | BUTTON_BRIGHT_BIT;  
  21.   
  22. // SCREEN_BUTTON_BRIGHT == screen on, screen, button and keyboard backlights bright  
  23. private static final int ALL_BRIGHT         = SCREEN_BUTTON_BRIGHT | KEYBOARD_BRIGHT_BIT;  
  24.   
  25. // used for noChangeLights in setPowerState()  
  26. private static final int LIGHTS_MASK        = SCREEN_BRIGHT_BIT | BUTTON_BRIGHT_BIT | KEYBOARD_BRIGHT_BIT;  

在frameworks/base/core/res/res/values/config.xml中配置自动背光的总开关mUseSoftwareAutoBrightness以及自动背光模式下的背光数值,如果没有lightsensor用于自动背光调整,则需要将mUseSoftwareAutoBrightness配置为false,配置项如下:

  1. <bool name="config_automatic_brightness_available">true</bool>  
  2.   
  3. <!-- Array of light sensor LUX values to define our levels for auto backlight brightness support.  
  4.      The N entries of this array define N + 1 zones as follows:  
  5.   
  6.      Zone 0:        0 <= LUX < array[0]  
  7.      Zone 1:        array[0] <= LUX < array[1]  
  8.      ...  
  9.      Zone N:        array[N - 1] <= LUX < array[N]  
  10.      Zone N + 1:    array[N] <= LUX < infinity  
  11.   
  12.      Must be overridden in platform specific overlays -->  
  13. <integer-array name="config_autoBrightnessLevels">  
  14.     <item>3</item>  
  15.     <item>10</item>  
  16.     <item>40</item>  
  17.     <item>65</item>  
  18.     <item>145</item>  
  19.     <item>300</item>  
  20.     <item>550</item>  
  21.     <item>930</item>  
  22.     <item>1250</item>  
  23. </integer-array>  
  24.   
  25. <!-- Array of output values for LCD backlight corresponding to the LUX values  
  26.      in the config_autoBrightnessLevels array.  This array should have size one greater  
  27.      than the size of the config_autoBrightnessLevels array.  
  28.      This must be overridden in platform specific overlays -->  
  29. <integer-array name="config_autoBrightnessLcdBacklightValues">  
  30.     <item>101</item>  
  31.     <item>117</item>  
  32.     <item>142</item>  
  33.     <item>183</item>  
  34.     <item>195</item>  
  35.     <item>216</item>  
  36.     <item>234</item>  
  37.     <item>245</item>  
  38.     <item>250</item>  
  39.     <item>250</item>  
  40. </integer-array>  
  41.   
  42. <!-- Array of output values for button backlight corresponding to the LUX values  
  43.      in the config_autoBrightnessLevels array.  This array should have size one greater  
  44.      than the size of the config_autoBrightnessLevels array.  
  45.      This must be overridden in platform specific overlays -->  
  46. <integer-array name="config_autoBrightnessButtonBacklightValues">  
  47.     <item>255</item>  
  48.     <item>255</item>  
  49.     <item>255</item>  
  50.     <item>0</item>  
  51.     <item>0</item>  
  52.     <item>0</item>  
  53.     <item>0</item>  
  54.     <item>0</item>  
  55.     <item>0</item>  
  56.     <item>0</item>  
  57. </integer-array>  
  58.   
  59. <!-- Array of output values for keyboard backlight corresponding to the LUX values  
  60.      in the config_autoBrightnessLevels array.  This array should have size one greater  
  61.      than the size of the config_autoBrightnessLevels array.  
  62.      This must be overridden in platform specific overlays -->  
  63. <integer-array name="config_autoBrightnessKeyboardBacklightValues">  
  64. </integer-array>  

在初始化的时候会调用如下代码获取配置信息:

  1. // 获取系统默认配置  
  2. Resources resources = mContext.getResources();  
  3. // 屏幕动画是否开启  
  4. mAnimateScreenLights = resources.getBoolean(  
  5.         com.android.internal.R.bool.config_animateScreenLights);  
  6.   
  7. mUnplugTurnsOnScreen = resources.getBoolean(  
  8.         com.android.internal.R.bool.config_unplugTurnsOnScreen);  
  9. // 软件自动背光调整是否打开  
  10. mUseSoftwareAutoBrightness = resources.getBoolean(  
  11.         com.android.internal.R.bool.config_automatic_brightness_available);  
  12. // 读取自动背光参考值  
  13. if (mUseSoftwareAutoBrightness) {  
  14.     mAutoBrightnessLevels = resources.getIntArray(  
  15.             com.android.internal.R.array.config_autoBrightnessLevels);  
  16.     mLcdBacklightValues = resources.getIntArray(  // lcd背光值  
  17.             com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);  
  18.     mButtonBacklightValues = resources.getIntArray(  // button背光值  
  19.             com.android.internal.R.array.config_autoBrightnessButtonBacklightValues);  
  20.     mKeyboardBacklightValues = resources.getIntArray(  // keyboard背光值  
  21.             com.android.internal.R.array.config_autoBrightnessKeyboardBacklightValues);  
  22.     mLightSensorWarmupTime = resources.getInteger(  
  23.             com.android.internal.R.integer.config_lightSensorWarmupTime);  
  24. }  

二、代码流程分析

在Android中,如果framework层接收到输入事件就会调用PowerManagerService里面的userActivity()去设置系统的下一个电源状态,流程图如下:


当调用userActivity()之后,将进行一些事件类型和状态的判断并先后调用setPowerState()设置新的状态、setTimeoutLocked()设置新状态超时后的状态,代码分析如下:

  1. private void userActivity(long time, long timeoutOverride, boolean noChangeLights,  
  2.         int eventType, boolean force) {  
  3.     // 检测是否忽略CHEEK_EVENT事件  
  4.     if (((mPokey & POKE_LOCK_IGNORE_CHEEK_EVENTS) != 0)  
  5.             && (eventType == CHEEK_EVENT)) {  
  6.         if (false) {  
  7.             Slog.d(TAG, "dropping cheek event mPokey=0x" + Integer.toHexString(mPokey));  
  8.         }  
  9.         return;  
  10.     }  
  11.     // 检测是否忽略CHEEK_EVENT与TOUCH事件  
  12.     if (((mPokey & POKE_LOCK_IGNORE_TOUCH_AND_CHEEK_EVENTS) != 0)  
  13.             && (eventType == TOUCH_EVENT || eventType == TOUCH_UP_EVENT  
  14.                 || eventType == LONG_TOUCH_EVENT || eventType == CHEEK_EVENT)) {  
  15.         if (false) {  
  16.             Slog.d(TAG, "dropping touch mPokey=0x" + Integer.toHexString(mPokey));  
  17.         }  
  18.         return;  
  19.     }  
  20.   
  21.     if (false) {  
  22.         if (((mPokey & POKE_LOCK_IGNORE_CHEEK_EVENTS) != 0)) {  
  23.             Slog.d(TAG, "userActivity !!!");//, new RuntimeException());  
  24.         } else {  
  25.             Slog.d(TAG, "mPokey=0x" + Integer.toHexString(mPokey));  
  26.         }  
  27.     }  
  28.   
  29.     synchronized (mLocks) {  
  30.         if (mSpew) {  
  31.             Slog.d(TAG, "userActivity mLastEventTime=" + mLastEventTime + " time=" + time  
  32.                     + " mUserActivityAllowed=" + mUserActivityAllowed  
  33.                     + " mUserState=0x" + Integer.toHexString(mUserState)  
  34.                     + " mWakeLockState=0x" + Integer.toHexString(mWakeLockState)  
  35.                     + " mProximitySensorActive=" + mProximitySensorActive  
  36.                     + " timeoutOverride=" + timeoutOverride  
  37.                     + " force=" + force  
  38.                     + " eventType=" + eventType);  
  39.         }  
  40.         // 如果当前屏幕为关闭状态则不处理  
  41.         if (isScreenTurningOffLocked()) {  
  42.             Slog.d(TAG, "ignoring user activity while turning off screen");  
  43.             return;  
  44.         }  
  45.         // 如果正在等待距离传感器为负值时用户按下power键则关闭距离传感器功能  
  46.         if (mProximitySensorActive && mProximityWakeLockCount == 0) {  
  47.             mProximitySensorActive = false;  
  48.         }  
  49.         if (mLastEventTime <= time || force) {  // 判断事件是否为最新的  
  50.             mLastEventTime = time;  
  51.             if ((mUserActivityAllowed && !mProximitySensorActive) || force) {  
  52.                 // 在用户点击触摸屏或者虚拟按键并且不是自动背光状态时设置下一个状态为全亮  
  53.                 if ((eventType == BUTTON_EVENT || eventType == TOUCH_EVENT  
  54.                     || eventType == TOUCH_UP_EVENT || eventType == LONG_TOUCH_EVENT)  
  55.                         && (!mUseSoftwareAutoBrightness || !mAutoBrightessEnabled)) {  
  56.                     mUserState = (mKeyboardVisible ? ALL_BRIGHT : SCREEN_BUTTON_BRIGHT);  
  57.                 } else {  
  58.                     // 设置系统下一个状态为SCREEN_BRIGHT,并保留上次状态  
  59.                     mUserState |= SCREEN_BRIGHT;  
  60.                 }  
  61.   
  62.                 int uid = Binder.getCallingUid();  
  63.                 long ident = Binder.clearCallingIdentity();  
  64.                 try {  
  65.                     mBatteryStats.noteUserActivity(uid, eventType);  
  66.                 } catch (RemoteException e) {  
  67.                     // Ignore  
  68.                 } finally {  
  69.                     Binder.restoreCallingIdentity(ident);  
  70.                 }  
  71.                 // 获取当前WakeLock状态  
  72.                 mWakeLockState = mLocks.reactivateScreenLocksLocked();  
  73.                 // 设置下一个状态  
  74.                 setPowerState(mUserState | mWakeLockState, noChangeLights,  
  75.                         WindowManagerPolicy.OFF_BECAUSE_OF_USER);  
  76.                 // 设置超时后的状态  
  77.                 setTimeoutLocked(time, timeoutOverride, SCREEN_BRIGHT);  
  78.             }  
  79.         }  
  80.     }  
  81.   
  82.     if (mPolicy != null) {  
  83.         mPolicy.userActivity();  
  84.     }  
  85. }  
  1. private void setTimeoutLocked(long now, final long originalTimeoutOverride, int nextState) {  
  2.     long timeoutOverride = originalTimeoutOverride;  // 超时时间  
  3.     if (mBootCompleted) {  // 判断系统是否启动完成  
  4.         synchronized (mLocks) {  
  5.             long when = 0;  
  6.             if (timeoutOverride <= 0) {  
  7.                 switch (nextState)  
  8.                 {  
  9.                     case SCREEN_BRIGHT:  
  10.                         when = now + mKeylightDelay;  // 关闭按键灯的时间  
  11.                         break;  
  12.                     case SCREEN_DIM:  
  13.                         if (mDimDelay >= 0) {  
  14.                             when = now + mDimDelay;  // 屏幕亮度降低的时间  
  15.                             break;  
  16.                         } else {  
  17.                             Slog.w(TAG, "mDimDelay=" + mDimDelay + " while trying to dim");  
  18.                         }  
  19.                    case SCREEN_OFF:  
  20.                         synchronized (mLocks) {  
  21.                             when = now + mScreenOffDelay;  // 关闭屏幕时间  
  22.                         }  
  23.                         break;  
  24.                     default:  
  25.                         when = now;  
  26.                         break;  
  27.                 }  
  28.             } else {  // 如果指定了originalTimeoutOverride  
  29.                 override: {  
  30.                     if (timeoutOverride <= mScreenOffDelay) {  
  31.                         when = now + timeoutOverride;  
  32.                         nextState = SCREEN_OFF;  
  33.                         break override;  
  34.                     }  
  35.                     timeoutOverride -= mScreenOffDelay;  
  36.   
  37.                     if (mDimDelay >= 0) {  
  38.                          if (timeoutOverride <= mDimDelay) {  
  39.                             when = now + timeoutOverride;  
  40.                             nextState = SCREEN_DIM;  
  41.                             break override;  
  42.                         }  
  43.                         timeoutOverride -= mDimDelay;  
  44.                     }  
  45.   
  46.                     when = now + timeoutOverride;  
  47.                     nextState = SCREEN_BRIGHT;  
  48.                 }  
  49.             }  
  50.             if (mSpew) {  
  51.                 Slog.d(TAG, "setTimeoutLocked now=" + now  
  52.                         + " timeoutOverride=" + timeoutOverride  
  53.                         + " nextState=" + nextState + " when=" + when);  
  54.             }  
  55.   
  56.             mHandler.removeCallbacks(mTimeoutTask);  // 清除超时任务  
  57.             mTimeoutTask.nextState = nextState;  // 设置超时后的状态  
  58.             mTimeoutTask.remainingTimeoutOverride = timeoutOverride > 0  
  59.                     ? (originalTimeoutOverride - timeoutOverride)  
  60.                     : -1;  
  61.             mHandler.postAtTime(mTimeoutTask, when);  // 启动超时任务  
  62.             mNextTimeout = when; // for debugging  
  63.         }  
  64.     }  
  65. }  
  1. private class TimeoutTask implements Runnable  
  2. {  
  3.     int nextState; // access should be synchronized on mLocks  
  4.     long remainingTimeoutOverride;  
  5.     public void run()  
  6.     {  
  7.         synchronized (mLocks) {  
  8.             if (mSpew) {  
  9.                 Slog.d(TAG, "user activity timeout timed out nextState=" + this.nextState);  
  10.             }  
  11.   
  12.             if (nextState == -1) {  
  13.                 return;  
  14.             }  
  15.   
  16.             mUserState = this.nextState;  // 设置全局变量  
  17.             setPowerState(this.nextState | mWakeLockState);  // 设置电源状态  
  18.   
  19.             long now = SystemClock.uptimeMillis();  
  20.   
  21.             switch (this.nextState)  // 设置超时后的下一个状态  
  22.             {  
  23.                 case SCREEN_BRIGHT:  // 如果当前屏幕全亮则下一状态为暗屏  
  24.                     if (mDimDelay >= 0) {  
  25.                         setTimeoutLocked(now, remainingTimeoutOverride, SCREEN_DIM);  
  26.                         break;  
  27.                     }  
  28.                 case SCREEN_DIM:  // 如果当前屏幕为暗屏则下一状态为熄屏  
  29.                     setTimeoutLocked(now, remainingTimeoutOverride, SCREEN_OFF);  
  30.                     break;  
  31.             }  
  32.         }  
  33.     }  
  34. }  

在setPowerState()中如果leds有变化则调用updateLightsLocked()更新leds的状态,如果lcd新状态和当前状态不同,则可能需要调用setScreenStateLocked()处理系统的休眠和唤醒流程,代码分析如下:

  1. private void setPowerState(int newState, boolean noChangeLights, int reason)  
  2. {  
  3.     synchronized (mLocks) {  
  4.         int err;  
  5.   
  6.         if (mSpew) {  
  7.             Slog.d(TAG, "setPowerState: mPowerState=0x" + Integer.toHexString(mPowerState)  
  8.                     + " newState=0x" + Integer.toHexString(newState)  
  9.                     + " noChangeLights=" + noChangeLights  
  10.                     + " reason=" + reason);  
  11.         }  
  12.   
  13.         if (noChangeLights) {  // 如果不改变light状态,则保持上次light状态  
  14.             newState = (newState & ~LIGHTS_MASK) | (mPowerState & LIGHTS_MASK);  
  15.         }  
  16.         if (mProximitySensorActive) {  // 如果距离传感器锁定则关闭lcd背光  
  17.             // don't turn on the screen when the proximity sensor lock is held  
  18.             newState = (newState & ~SCREEN_BRIGHT);  
  19.         }  
  20.   
  21.         if (batteryIsLow()) {  // 如果当前低电则添加低电状态  
  22.             newState |= BATTERY_LOW_BIT;  
  23.         } else {  
  24.             newState &= ~BATTERY_LOW_BIT;  
  25.         }  
  26.         if (newState == mPowerState) {  // 如果本次状态和上次状态一致则直接返回  
  27.             return;  
  28.         }  
  29.         // 如果正在启动并且没有设置自动背光则为全亮  
  30.         if (!mBootCompleted && !mUseSoftwareAutoBrightness) {  
  31.             newState |= ALL_BRIGHT;  
  32.         }  
  33.   
  34.         boolean oldScreenOn = (mPowerState & SCREEN_ON_BIT) != 0;  // 当前屏幕状态  
  35.         boolean newScreenOn = (newState & SCREEN_ON_BIT) != 0;  // 下次屏幕状态  
  36.   
  37.         if (mSpew) {  
  38.             Slog.d(TAG, "setPowerState: mPowerState=" + mPowerState  
  39.                     + " newState=" + newState + " noChangeLights=" + noChangeLights);  
  40.             Slog.d(TAG, "  oldKeyboardBright=" + ((mPowerState & KEYBOARD_BRIGHT_BIT) != 0)  
  41.                      + " newKeyboardBright=" + ((newState & KEYBOARD_BRIGHT_BIT) != 0));  
  42.             Slog.d(TAG, "  oldScreenBright=" + ((mPowerState & SCREEN_BRIGHT_BIT) != 0)  
  43.                      + " newScreenBright=" + ((newState & SCREEN_BRIGHT_BIT) != 0));  
  44.             Slog.d(TAG, "  oldButtonBright=" + ((mPowerState & BUTTON_BRIGHT_BIT) != 0)  
  45.                      + " newButtonBright=" + ((newState & BUTTON_BRIGHT_BIT) != 0));  
  46.             Slog.d(TAG, "  oldScreenOn=" + oldScreenOn  
  47.                      + " newScreenOn=" + newScreenOn);  
  48.             Slog.d(TAG, "  oldBatteryLow=" + ((mPowerState & BATTERY_LOW_BIT) != 0)  
  49.                      + " newBatteryLow=" + ((newState & BATTERY_LOW_BIT) != 0));  
  50.         }  
  51.   
  52.         if (mPowerState != newState) {  // 判断状态是否改变  
  53.             updateLightsLocked(newState, 0);  // 更新按键灯状态  
  54.             mPowerState = (mPowerState & ~LIGHTS_MASK) | (newState & LIGHTS_MASK);  
  55.         }  
  56.   
  57.         if (oldScreenOn != newScreenOn) {  // 判断屏幕状态是否不同  
  58.             if (newScreenOn) {  // 如果要点亮屏幕  
  59.                 // When the user presses the power button, we need to always send out the  
  60.                 // notification that it's going to sleep so the keyguard goes on.  But  
  61.                 // we can't do that until the screen fades out, so we don't show the keyguard  
  62.                 // too early.  
  63.                 if (mStillNeedSleepNotification) {  
  64.                     sendNotificationLocked(false, WindowManagerPolicy.OFF_BECAUSE_OF_USER);  
  65.                 }  
  66.   
  67.                 // Turn on the screen UNLESS there was a prior  
  68.                 // preventScreenOn(true) request.  (Note that the lifetime  
  69.                 // of a single preventScreenOn() request is limited to 5  
  70.                 // seconds to prevent a buggy app from disabling the  
  71.                 // screen forever; see forceReenableScreen().)  
  72.                 boolean reallyTurnScreenOn = true;  
  73.                 if (mSpew) {  
  74.                     Slog.d(TAG, "- turning screen on...  mPreventScreenOn = "  
  75.                           + mPreventScreenOn);  
  76.                 }  
  77.   
  78.                 if (mPreventScreenOn) {  // 是否阻止屏幕点亮  
  79.                     if (mSpew) {  
  80.                         Slog.d(TAG, "- PREVENTING screen from really turning on!");  
  81.                     }  
  82.                     reallyTurnScreenOn = false;  
  83.                 }  
  84.                 if (reallyTurnScreenOn) {  
  85.                     err = setScreenStateLocked(true);  // 唤醒系统,点亮屏幕  
  86.                     long identity = Binder.clearCallingIdentity();  
  87.                     try {  
  88.                         mBatteryStats.noteScreenBrightness(getPreferredBrightness());  
  89.                         mBatteryStats.noteScreenOn();  
  90.                     } catch (RemoteException e) {  
  91.                         Slog.w(TAG, "RemoteException calling noteScreenOn on BatteryStatsService", e);  
  92.                     } finally {  
  93.                         Binder.restoreCallingIdentity(identity);  
  94.                     }  
  95.                 } else {  
  96.                     setScreenStateLocked(false);  // 休眠系统  
  97.                     // But continue as if we really did turn the screen on...  
  98.                     err = 0;  
  99.                 }  
  100.   
  101.                 mLastTouchDown = 0;  
  102.                 mTotalTouchDownTime = 0;  
  103.                 mTouchCycles = 0;  
  104.                 EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 1, reason,  
  105.                         mTotalTouchDownTime, mTouchCycles);  
  106.                 if (err == 0) {  
  107.                     mPowerState |= SCREEN_ON_BIT;  
  108.                     sendNotificationLocked(true, -1);  
  109.                 }  
  110.             } else {  // 如果要关闭屏幕  
  111.                 // cancel light sensor task  
  112.                 mHandler.removeCallbacks(mAutoBrightnessTask);  // 取消背光自动调整任务  
  113.                 mScreenOffTime = SystemClock.elapsedRealtime();  // 获取关闭时间  
  114.                 long identity = Binder.clearCallingIdentity();  
  115.                 try {  
  116.                     mBatteryStats.noteScreenOff();  
  117.                 } catch (RemoteException e) {  
  118.                     Slog.w(TAG, "RemoteException calling noteScreenOff on BatteryStatsService", e);  
  119.                 } finally {  
  120.                     Binder.restoreCallingIdentity(identity);  
  121.                 }  
  122.                 mPowerState &= ~SCREEN_ON_BIT;  // 设置状态位  
  123.                 mScreenOffReason = reason;  
  124.                 if (!mScreenBrightness.animating) {  // 判断是否打开关屏动画  
  125.                     err = screenOffFinishedAnimatingLocked(reason);  
  126.                 } else {  
  127.                     err = 0;  
  128.                     mLastTouchDown = 0;  
  129.                 }  
  130.             }  
  131.         }  
  132.           
  133.         updateNativePowerStateLocked();  // 更新HAL层状态  
  134.     }  
  135. }  
在updateLightsLocked()里面将会进行一系列的状态处理, 比如调用applyButtonState()获取button led的相关数据和状态,然后调用setLightBrightness()设置leds,代码分析如下:
  1. private void updateLightsLocked(int newState, int forceState) {  
  2.     final int oldState = mPowerState;  
  3.     if ((newState & SCREEN_ON_BIT) != 0) {  // 如果屏幕打开则设置按键灯  
  4.         newState = applyButtonState(newState);  // 请求button灯状态  
  5.         newState = applyKeyboardState(newState);  // 请求keyboard灯状态  
  6.     }  
  7.     final int realDifference = (newState ^ oldState);  // 判断状态是否相同,取得不同的位  
  8.     final int difference = realDifference | forceState;  // 是否强制更新状态  
  9.     if (difference == 0) {  
  10.         return;  
  11.     }  
  12.   
  13.     int offMask = 0;  
  14.     int dimMask = 0;  
  15.     int onMask = 0;  
  16.   
  17.     int preferredBrightness = getPreferredBrightness();  // 获取参考亮度  
  18.   
  19.     if ((difference & KEYBOARD_BRIGHT_BIT) != 0) {  // 如果keyboard有变化  
  20.         if ((newState & KEYBOARD_BRIGHT_BIT) == 0) {  
  21.             offMask |= KEYBOARD_BRIGHT_BIT;  
  22.         } else {  
  23.             onMask |= KEYBOARD_BRIGHT_BIT;  
  24.         }  
  25.     }  
  26.   
  27.     if ((difference & BUTTON_BRIGHT_BIT) != 0) {  // 如果button有变化  
  28.         if ((newState & BUTTON_BRIGHT_BIT) == 0) {  
  29.             offMask |= BUTTON_BRIGHT_BIT;  
  30.         } else {  
  31.             onMask |= BUTTON_BRIGHT_BIT;  
  32.         }  
  33.     }  
  34.     // 如果状态不同且forceState有效或者屏幕状态变化  
  35.     if ((difference & (SCREEN_ON_BIT | SCREEN_BRIGHT_BIT)) != 0) {  
  36.         int nominalCurrentValue = -1;  
  37.         // If there was an actual difference in the light state, then  
  38.         // figure out the "ideal" current value based on the previous  
  39.         // state.  Otherwise, this is a change due to the brightness  
  40.         // override, so we want to animate from whatever the current  
  41.         // value is.  
  42.         // 如果屏幕状态变化  
  43.         if ((realDifference & (SCREEN_ON_BIT | SCREEN_BRIGHT_BIT)) != 0) {  
  44.             switch (oldState & (SCREEN_BRIGHT_BIT|SCREEN_ON_BIT)) {  // 判断当前屏幕状态  
  45.                 case SCREEN_BRIGHT_BIT | SCREEN_ON_BIT:  // 屏幕全亮状态  
  46.                     nominalCurrentValue = preferredBrightness;  
  47.                     break;  
  48.                 case SCREEN_ON_BIT:  // 屏幕DIM状态  
  49.                     nominalCurrentValue = Power.BRIGHTNESS_DIM;  
  50.                     break;  
  51.                 case 0:  // 屏幕关闭状态  
  52.                     nominalCurrentValue = Power.BRIGHTNESS_OFF;  
  53.                     break;  
  54.                 case SCREEN_BRIGHT_BIT:  
  55.                 default:  
  56.                     // not possible  
  57.                     nominalCurrentValue = (int)mScreenBrightness.curValue;  
  58.                     break;  
  59.             }  
  60.         }  
  61.         int brightness = preferredBrightness;  
  62.         int steps = ANIM_STEPS;  // 动画步数  
  63.         if ((newState & SCREEN_BRIGHT_BIT) == 0) {  // 下一个状态为DIM或者OFF  
  64.             // dim or turn off backlight, depending on if the screen is on  
  65.             // the scale is because the brightness ramp isn't linear and this biases  
  66.             // it so the later parts take longer.  
  67.             final float scale = 1.5f;  
  68.             // 每次变化比例  
  69.             float ratio = (((float)Power.BRIGHTNESS_DIM)/preferredBrightness);  
  70.             if (ratio > 1.0f) ratio = 1.0f;  
  71.             if ((newState & SCREEN_ON_BIT) == 0) {  // 下一个状态为OFF  
  72.                 if ((oldState & SCREEN_BRIGHT_BIT) != 0) {  
  73.                     // was bright  
  74.                     steps = ANIM_STEPS;  
  75.                 } else {  
  76.                     // was dim  
  77.                     steps = (int)(ANIM_STEPS*ratio*scale);  
  78.                 }  
  79.                 brightness = Power.BRIGHTNESS_OFF;  // 设置brightness  
  80.             } else {  // 下一个状态为DIM  
  81.                 if ((oldState & SCREEN_ON_BIT) != 0) {  
  82.                     // was bright  
  83.                     steps = (int)(ANIM_STEPS*(1.0f-ratio)*scale);  
  84.                 } else {  
  85.                     // was dim  
  86.                     steps = (int)(ANIM_STEPS*ratio);  
  87.                 }  
  88.                 if (mStayOnConditions != 0 && mBatteryService.isPowered(mStayOnConditions)) {  
  89.                     // If the "stay on while plugged in" option is  
  90.                     // turned on, then the screen will often not  
  91.                     // automatically turn off while plugged in.  To  
  92.                     // still have a sense of when it is inactive, we  
  93.                     // will then count going dim as turning off.  
  94.                     mScreenOffTime = SystemClock.elapsedRealtime();  
  95.                 }  
  96.                 brightness = Power.BRIGHTNESS_DIM;  
  97.             }  
  98.         }  
  99.         long identity = Binder.clearCallingIdentity();  
  100.         try {  
  101.             mBatteryStats.noteScreenBrightness(brightness);  
  102.         } catch (RemoteException e) {  
  103.             // Nothing interesting to do.  
  104.         } finally {  
  105.             Binder.restoreCallingIdentity(identity);  
  106.         }  
  107.         mScreenBrightness.setTargetLocked(brightness, steps,  // 设置背光亮度  
  108.                 INITIAL_SCREEN_BRIGHTNESS, nominalCurrentValue);  
  109.     }  
  110.   
  111.     if (mSpew) {  
  112.         Slog.d(TAG, "offMask=0x" + Integer.toHexString(offMask)  
  113.                 + " dimMask=0x" + Integer.toHexString(dimMask)  
  114.                 + " onMask=0x" + Integer.toHexString(onMask)  
  115.                 + " difference=0x" + Integer.toHexString(difference)  
  116.                 + " realDifference=0x" + Integer.toHexString(realDifference)  
  117.                 + " forceState=0x" + Integer.toHexString(forceState)  
  118.                 );  
  119.     }  
  120.   
  121.     if (offMask != 0) {  // 如果有灯要关闭  
  122.         if (mSpew) Slog.i(TAG, "Setting brightess off: " + offMask);  
  123.         setLightBrightness(offMask, Power.BRIGHTNESS_OFF);  
  124.     }  
  125.     if (dimMask != 0) {  
  126.         int brightness = Power.BRIGHTNESS_DIM;  
  127.         if ((newState & BATTERY_LOW_BIT) != 0 &&  
  128.                 brightness > Power.BRIGHTNESS_LOW_BATTERY) {  
  129.             brightness = Power.BRIGHTNESS_LOW_BATTERY;  
  130.         }  
  131.         if (mSpew) Slog.i(TAG, "Setting brightess dim " + brightness + ": " + dimMask);  
  132.         setLightBrightness(dimMask, brightness);  // 设置leds  
  133.     }  
  134.     if (onMask != 0) {  // 如果有灯要打开  
  135.         int brightness = getPreferredBrightness();  // 获取亮度值,包括按键灯的亮度值,都是从用户设置中获取  
  136.         if ((newState & BATTERY_LOW_BIT) != 0 &&  
  137.                 brightness > Power.BRIGHTNESS_LOW_BATTERY) {  
  138.             brightness = Power.BRIGHTNESS_LOW_BATTERY;  
  139.         }  
  140.         if (mSpew) Slog.i(TAG, "Setting brightess on " + brightness + ": " + onMask);  
  141.         setLightBrightness(onMask, brightness);  // 设置leds  
  142.     }  
  143. }  
  1. private int applyButtonState(int state) {  
  2.     int brightness = -1;  
  3.     if ((state & BATTERY_LOW_BIT) != 0) {  
  4.         // 如果电池电量低则不覆盖亮度值  
  5.         return state;  
  6.     }  
  7.     if (mButtonBrightnessOverride >= 0) {  // 判断亮度值是否有效  
  8.         brightness = mButtonBrightnessOverride;  
  9.     } else if (mLightSensorButtonBrightness >= 0 && mUseSoftwareAutoBrightness) {  
  10.         // 根据lightsensor设置亮度值  
  11.         // 这里有android系统的一个bug,如果开启自动背光后再关闭自动背光  
  12.         // 会导致mLightSensorButtonBrightness为之前自动背光时的值,如果为0按键灯就不会再被点亮了  
  13.         brightness = mLightSensorButtonBrightness;  
  14.     }  
  15.     if (brightness > 0) {  
  16.         return state | BUTTON_BRIGHT_BIT;  // 如果亮度值大于0则返回状态  
  17.     } else if (brightness == 0) {  
  18.         return state & ~BUTTON_BRIGHT_BIT;  
  19.     } else {  
  20.         return state;  
  21.     }  
  22. }  

在setLightBrightness()中将根据标志依次调用JNI接口去设置leds,代码分析如下:

  1. private void setLightBrightness(int mask, int value) {  
  2.     int brightnessMode = (mAutoBrightessEnabled  
  3.                         ? LightsService.BRIGHTNESS_MODE_SENSOR  
  4.                         : LightsService.BRIGHTNESS_MODE_USER);  // 设置背光模式  
  5.     if ((mask & SCREEN_BRIGHT_BIT) != 0) {  
  6.         mLcdLight.setBrightness(value, brightnessMode);  // 调用JNI接口设置lcd亮度  
  7.     }  
  8.     if ((mask & BUTTON_BRIGHT_BIT) != 0) {  
  9.         mButtonLight.setBrightness(value);  // 调用JNI接口设置button灯  
  10.     }  
  11.     if ((mask & KEYBOARD_BRIGHT_BIT) != 0) {  
  12.         mKeyboardLight.setBrightness(value);  // 调用JNI接口设置keyboard灯  
  13.     }  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值