一、SystemUI、Settings中手动调节
/frameworks/base/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
@Override
public void onChanged(ToggleSlider toggleSlider, boolean tracking, boolean automatic,
int value, boolean stopTracking) {
final String setting;
if (mIsVrModeEnabled) {
setting = Settings.System.SCREEN_BRIGHTNESS_FOR_VR;
} else {
setting = Settings.System.SCREEN_BRIGHTNESS;
}
//获取亮度值
final int val = convertGammaToLinear(value, min, max);
//设置亮度值
setBrightness(val);
if (!tracking) {
//在异步任务中将新的亮度值保存在SettingsProvider中
AsyncTask.execute(new Runnable() {
public void run() {
Settings.System.putIntForUser(mContext.getContentResolver(),
setting, val, UserHandle.USER_CURRENT);
}
});
}
}
private void setBrightness(int brightness) {
mDisplayManager.setTemporaryBrightness(brightness);
}
//frameworks/base/core/java/android/hardware/display/DisplayManager.java
public void setTemporaryBrightness(int brightness) {
mGlobal.setTemporaryBrightness(brightness);
}
//frameworks/base/core/java/android/hardware/display/DisplayManagerGlobal.java
public void setTemporaryBrightness(int brightness) {
try {
mDm.setTemporaryBrightness(brightness);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
//frameworks/base/services/core/java/com/android/server/display/DisplayManagerService.java
@Override // Binder call
public void setTemporaryBrightness(int brightness) {
mContext.enforceCallingOrSelfPermission(
Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS,
"Permission required to set the display's brightness");
final long token = Binder.clearCallingIdentity();
try {
synchronized (mSyncRoot) {
mDisplayPowerController.setTemporaryBrightness(brightness);
}
} finally {
Binder.restoreCallingIdentity(token);
}
}
/frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.java
public void setTemporaryBrightness(int brightness) {
Message msg = mHandler.obtainMessage(MSG_SET_TEMPORARY_BRIGHTNESS,
brightness, 0 /*unused*/);
msg.sendToTarget();
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SET_TEMPORARY_BRIGHTNESS:
// TODO: Should we have a a timeout for the temporary brightness?
//将brightness赋值给了mTemporaryScreenBrightness
mTemporaryScreenBrightness = msg.arg1;
updatePowerState();
break;
}
}
}
private void updatePowerState() {
// ......
//手动设置亮度是否改变
final boolean userSetBrightnessChanged = updateUserSetScreenBrightness();
if (userSetBrightnessChanged) {
mTemporaryScreenBrightness = -1;
}
// ......
// Apply manual brightness.
if (brightness < 0) {
brightness = clampScreenBrightness(mCurrentScreenBrightnessSetting);
}
// ......
// Use the temporary screen brightness if there isn't an override, either from
// WindowManager or based on the display state.
if (mTemporaryScreenBrightness > 0) {
//使用手动设置的亮度
brightness = mTemporaryScreenBrightness;
mAppliedTemporaryBrightness = true;
} else {
mAppliedTemporaryBrightness = false;
}
//........
if (!mPendingScreenOff) {
final boolean isDisplayContentVisible = mColorFadeEnabled ?
(mColorFadeEnabled && mPowerState.getColorFadeLevel() == 1.0f) :
(state == Display.STATE_ON && mSkipRampState == RAMP_STATE_SKIP_NONE);
if (initialRampSkip || hasBrightnessBuckets
|| wasOrWillBeInVr || !isDisplayContentVisible || brightnessIsTemporary) {
//设置亮度值到底层驱动,调节背光值,不设置背光动画
animateScreenBrightness(brightness, 0);
} else {
//设置亮度值到底层驱动,调节背光值,根据slowChange设置快动画还是慢动画
animateScreenBrightness(brightness,
slowChange ? mBrightnessRampRateSlow : mBrightnessRampRateFast);
}
//......
}
private boolean updateUserSetScreenBrightness() {
if (mPendingScreenBrightnessSetting < 0) {
return false;
}
//add for bug BEG
if (mPendingScreenBrightnessSetting > 0 && (mCurrentScreenBrightnessSetting == mTemporaryScreenBrightness)){
return true;
}
//add for bug END
if (mCurrentScreenBrightnessSetting == mPendingScreenBrightnessSetting) {
mPendingScreenBrightnessSetting = -1;
return false;
}
mCurrentScreenBrightnessSetting = mPendingScreenBrightnessSetting;
mLastUserSetScreenBrightness = mPendingScreenBrightnessSetting;
mPendingScreenBrightnessSetting = -1;
return true;
}
//监听SettingsProvider中Settings.System.SCREEN_BRIGHTNESS的值变化(对应systemUI,Settings中seekbar的拖动)
private final class SettingsObserver extends ContentObserver {
public SettingsObserver(Handler handler) {
super(handler);
}
@Override
public void onChange(boolean selfChange, Uri uri) {
handleSettingsChange(false /* userSwitch */);
}
}
private void handleSettingsChange(boolean userSwitch) {
mPendingScreenBrightnessSetting = getScreenBrightnessSetting();
sendUpdatePowerState();
}
private int getScreenBrightnessSetting() {
final int brightness = Settings.System.getIntForUser(mContext.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS, mScreenBrightnessDefault,
UserHandle.USER_CURRENT);
return clampAbsoluteBrightness(brightness);
}
二、视频背光调节
播放视频时,可以通过上下滑动界面来设置亮度,当退出播放界面时,又会恢复到原亮度,其调用接口正是PMS中的setScreenBrightnessOverrideFromWindowManager()方法。
/frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
public void handleMessage(Message msg) {
switch (msg.what) {
case SET_SCREEN_BRIGHTNESS_OVERRIDE:
//调用PMS相关接口 mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(
msg.arg1);
break;
......
}
}
}
/frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
@Override
public void setScreenBrightnessOverrideFromWindowManager(int screenBrightness) {
if (screenBrightness < PowerManager.BRIGHTNESS_DEFAULT
|| screenBrightness > PowerManager.BRIGHTNESS_ON) {
screenBrightness = PowerManager.BRIGHTNESS_DEFAULT;
}
setScreenBrightnessOverrideFromWindowManagerInternal(screenBrightness);
}
private void setScreenBrightnessOverrideFromWindowManagerInternal(int brightness) {
synchronized (mLock) {
//将亮度值设置给了mScreenBrightnessOverrideFromWindowManager变量
if (mScreenBrightnessOverrideFromWindowManager != brightness) {
mScreenBrightnessOverrideFromWindowManager = brightness;
mDirty |= DIRTY_SETTINGS;
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);
updateScreenBrightnessBoostLocked(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: Lock profiles that became inactive/not kept awake.
updateProfilesLocked(now);
// Phase 3: Update display power state.
final boolean displayBecameReady = updateDisplayPowerStateLocked(dirtyPhase2);
// Phase 4: Update dream state (depends on display ready signal).
updateDreamLocked(dirtyPhase2, displayBecameReady);
// Phase 5: Send notifications, if needed.
finishWakefulnessChangeIfNeededLocked(