frameworks\base\services\core\java\com\android\server\power\PowerManagerService.java
public final class PowerManagerService extends SystemService implements Watchdog.Monitor {
...
public void systemReady(IAppOpsService appOps) {synchronized (mLock) {mSettingsObserver = new SettingsObserver(mHandler);....// Register for broadcasts from other components of the system.IntentFilter filter = new IntentFilter();filter.addAction(Intent.ACTION_BATTERY_CHANGED);filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);mContext.registerReceiver(new BatteryReceiver(), filter, null, mHandler);filter = new IntentFilter();filter.addAction(Intent.ACTION_DREAMING_STARTED);filter.addAction(Intent.ACTION_DREAMING_STOPPED);mContext.registerReceiver(new DreamReceiver(), filter, null, mHandler);filter = new IntentFilter();filter.addAction(Intent.ACTION_USER_SWITCHED);mContext.registerReceiver(new UserSwitchedReceiver(), filter, null, mHandler);filter = new IntentFilter();filter.addAction(Intent.ACTION_DOCK_EVENT);mContext.registerReceiver(new DockReceiver(), filter, null, mHandler);// Register for settings changes.final ContentResolver resolver = mContext.getContentResolver();...resolver.registerContentObserver(Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS),false, mSettingsObserver, UserHandle.USER_ALL);resolver.registerContentObserver(Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_MODE),false, mSettingsObserver, UserHandle.USER_ALL);...}}
以上无论是 receiver 还是 mSettingsObserver ,当收到“信号”,都会间接调用到 updatePowerStateLocked
private void updatePowerStateLocked() { if (!mSystemReady || mDirty == 0) { return; } if (!Thread.holdsLock(mLock)) { Slog.wtf(TAG, "Power manager lock was not held when calling updatePowerStateLocked"); } Trace.traceBegin(Trace.TRACE_TAG_POWER, "updatePowerState"); try { // Phase 0: Basic state updates. updateIsPoweredLocked(mDirty); updateStayOnLocked(mDirty); // Phase 1: Update wakefulness. // Loop because the wake lock and user activity computations are influenced // by changes in wakefulness. final long now = SystemClock.uptimeMillis(); int dirtyPhase2 = 0; for (;;) { int dirtyPhase1 = mDirty; dirtyPhase2 |= dirtyPhase1; mDirty = 0; updateWakeLockSummaryLocked(dirtyPhase1); updateUserActivitySummaryLocked(now, dirtyPhase1); if (!updateWakefulnessLocked(dirtyPhase1)) { break; } } // Phase 2: Update display power state. boolean displayBecameReady = updateDisplayPowerStateLocked(dirtyPhase2); // Phase 3: Update dream state (depends on display ready signal). updateDreamLocked(dirtyPhase2, displayBecameReady); // Phase 4: Send notifications, if needed. if (mDisplayReady) { finishInteractiveStateChangeLocked(); } // Phase 5: Update suspend blocker. // Because we might release the last suspend blocker here, we need to make sure // we finished everything else first! updateSuspendBlockerLocked(); } finally { Trace.traceEnd(Trace.TRACE_TAG_POWER); } }
对于背光,调用 updateDisplayPowerStateLocked(dirtyPhase2);
private boolean updateDisplayPowerStateLocked(int dirty) { final boolean oldDisplayReady = mDisplayReady; ... if (autoBrightness) { ... } screenBrightness = Math.max(Math.min(screenBrightness, mScreenBrightnessSettingMaximum), mScreenBrightnessSettingMinimum); screenAutoBrightnessAdjustment = Math.max(Math.min( screenAutoBrightnessAdjustment, 1.0f), -1.0f); mDisplayPowerRequest.screenBrightness = screenBrightness; mDisplayPowerRequest.screenAutoBrightnessAdjustment = screenAutoBrightnessAdjustment; mDisplayPowerRequest.useAutoBrightness = autoBrightness; mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked(); mDisplayPowerRequest.lowPowerMode = mLowPowerModeEnabled; if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE) { mDisplayPowerRequest.dozeScreenState = mDozeScreenStateOverrideFromDreamManager; mDisplayPowerRequest.dozeScreenBrightness = mDozeScreenBrightnessOverrideFromDreamManager; } else { mDisplayPowerRequest.dozeScreenState = Display.STATE_UNKNOWN; mDisplayPowerRequest.dozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT; } mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest, mRequestWaitForNegativeProximity); mRequestWaitForNegativeProximity = false; } return mDisplayReady && !oldDisplayReady; }
public abstract boolean requestPowerState(DisplayPowerRequest request,boolean waitForNegativeProximity);
虚函数,子类中实现在:
frameworks\base\services\core\java\com\android\server\display\DisplayManagerService.java
public boolean requestPowerState(DisplayPowerRequest request, boolean waitForNegativeProximity) { return mDisplayPowerController.requestPowerState(request, waitForNegativeProximity); }
public boolean requestPowerState(DisplayPowerRequest request, boolean waitForNegativeProximity) { ... synchronized (mLock) { boolean changed = false; ... if (changed) { mDisplayReadyLocked = false; } if (changed && !mPendingRequestChangedLocked) { mPendingRequestChangedLocked = true; sendUpdatePowerStateLocked(); } return mDisplayReadyLocked; } }
private void sendUpdatePowerStateLocked() { if (!mPendingUpdatePowerStateLocked) { mPendingUpdatePowerStateLocked = true; Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE); msg.setAsynchronous(true); mHandler.sendMessage(msg); } }
前面学习过线程间通信,将调用到 mHandler 里的 handleMessage 函数
public void handleMessage(Message msg) { switch (msg.what) { case MSG_UPDATE_POWER_STATE: updatePowerState(); break; ... } }
private void updatePowerState() {
// Skip the animation when the screen is off or suspended.// Animate the screen brightness when the screen is on or dozing.
if (state == Display.STATE_ON || state == Display.STATE_DOZE) {
animateScreenBrightness(brightness,
slowChange ? BRIGHTNESS_RAMP_RATE_SLOW : BRIGHTNESS_RAMP_RATE_FAST);
} else {
animateScreenBrightness(brightness, 0);
}
private void animateScreenBrightness(int target, int rate) { if (mScreenBrightnessRampAnimator.animateTo(target, rate)) { } }
public boolean animateTo(int target, int rate) { // Immediately jump to the target the first time. if (mFirstTime || rate <= 0) { if (mFirstTime || target != mCurrentValue) { ... mProperty.setValue(mObject, target); ... return true; } return false; }
public void setValue(DisplayPowerState object, int value) { object.setScreenBrightness(value); }
public void setScreenBrightness(int brightness) { if (mScreenBrightness != brightness) { if (DEBUG) { Slog.d(TAG, "setScreenBrightness: brightness=" + brightness); } mScreenBrightness = brightness; if (mScreenState != Display.STATE_OFF) { mScreenReady = false; scheduleScreenUpdate(); } } }
private void scheduleScreenUpdate() { if (!mScreenUpdatePending) { mScreenUpdatePending = true; postScreenUpdateThreadSafe(); } }
private void postScreenUpdateThreadSafe() { mHandler.removeCallbacks(mScreenUpdateRunnable); mHandler.post(mScreenUpdateRunnable); }
还是前面学习的线程间通信,调用 mScreenUpdateRunnable 中的 run 函数
private final Runnable mScreenUpdateRunnable = new Runnable() { @Override public void run() { mScreenUpdatePending = false; int brightness = mScreenState != Display.STATE_OFF && mColorFadeLevel > 0f ? mScreenBrightness : 0; if (mPhotonicModulator.setState(mScreenState, brightness)) { ... } };
public boolean setState(int state, int backlight) { synchronized (mLock) { if (state != mPendingState || backlight != mPendingBacklight) { mPendingState = state; mPendingBacklight = backlight; if (!mChangeInProgress) { mChangeInProgress = true; mLock.notifyAll(); } } return !mChangeInProgress; } }
唤醒 mLock 休眠的地方:
private final class PhotonicModulator extends Thread {
}public void run() {for (;;) {// Get pending change.final int state;final boolean stateChanged;final int backlight;final boolean backlightChanged;synchronized (mLock) {state = mPendingState;stateChanged = (state != mActualState);backlight = mPendingBacklight;backlightChanged = (backlight != mActualBacklight);if (!stateChanged && !backlightChanged) {// All changed applied, notify outer class and wait for more.mChangeInProgress = false;postScreenUpdateThreadSafe();try {mLock.wait();//休眠} catch (InterruptedException ex) { }continue;}mActualState = state;mActualBacklight = backlight;}// Apply pending change.if (DEBUG) {Slog.d(TAG, "Updating screen state: state="+ Display.stateToString(state) + ", backlight=" + backlight);}boolean suspending = Display.isSuspendedState(state);if (stateChanged && !suspending) {requestDisplayState(state);}if (backlightChanged) {setBrightness(backlight);//设置背光}if (stateChanged && suspending) {requestDisplayState(state);}}}
private void setBrightness(int backlight) { Trace.traceBegin(Trace.TRACE_TAG_POWER, "setBrightness(" + backlight + ")"); try { mBacklight.setBrightness(backlight); } finally { Trace.traceEnd(Trace.TRACE_TAG_POWER); } }
frameworks\base\services\core\java\com\android\server\lights\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); } }
private void setLightLocked(int color, int mode, int onMS, int offMS, int brightnessMode) { if (color != mColor || mode != mMode || onMS != mOnMS || offMS != mOffMS) { if (DEBUG) Slog.v(TAG, "setLight #" + mId + ": color=#" + Integer.toHexString(color)); mColor = color; mMode = mode; mOnMS = onMS; mOffMS = offMS; Trace.traceBegin(Trace.TRACE_TAG_POWER, "setLight(" + mId + ", " + color + ")"); try { setLight_native(mNativePointer, mId, color, mode, onMS, offMS, brightnessMode); } finally { Trace.traceEnd(Trace.TRACE_TAG_POWER); } } }
frameworks\base\services\core\jni\com_android_server_lights_LightsService.cpp
static JNINativeMethod method_table[] = { { "init_native", "()J", (void*)init_native }, { "finalize_native", "(J)V", (void*)finalize_native }, { "setLight_native", "(JIIIIII)V", (void*)setLight_native }, };
static void setLight_native(JNIEnv *env, jobject clazz, jlong ptr, jint light, jint colorARGB, jint flashMode, jint onMS, jint offMS, jint 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; { ALOGD_IF_SLOW(50, "Excessive delay setting light"); devices->lights[light]->set_light(devices->lights[light], &state); } }
...
这一部分的分析参考之前的文章
由以上代码分析可知,最初的地方注册了一个 ContentObserver
resolver.registerContentObserver(Settings.System.getUriFor( Settings.System.SCREEN_BRIGHTNESS),false, mSettingsObserver, UserHandle.USER_ALL);
我们只需要改变这个东西,它就会帮我们去一层层调用去改变背光
app:
设置背光:
android.provider.Settings.System.putInt(getContentResolver(), android.provider.Settings.System.SCREEN_BRIGHTNESS, brightness);
获取背光当前值:
android.provider.Settings.System.getInt(getContentResolver(), android.provider.Settings.System.SCREEN_BRIGHTNESS);
安卓中自带的背光设置代码在:
frameworks\base\packages\SystemUI\src\com\android\systemui\settings\BrightnessDialog.java