平時通過一個slider調節改變螢幕亮度,其實這個slider是systemui的東西,叫做BrightnessDialog
public class BrightnessDialog extends Activity {
....
private BrightnessController mBrightnessController;
@Override
protected void onStart() {
super.onStart();
// mBrightnessController是BrightnessController類型的
mBrightnessController.registerCallbacks();
}
....
}
進一步會通過BrightnessController
public class BrightnessController implements ToggleSlider.Listener {
....
public void registerCallbacks() {
....
//
mControl.setOnChangedListener(this);
}
....
@Override
public void onChanged(ToggleSlider view, boolean tracking, boolean automatic, int value,
boolean stopTracking) {
mTracking = tracking;
updateIcon(mAutomatic);
if (mExternalChange) return;
// 如果不是自動亮度,即使用者手動設定的亮度
if (!mAutomatic) {
final int val = value + mMinimumBacklight;
if (stopTracking) {
MetricsLogger.action(mContext, MetricsLogger.ACTION_BRIGHTNESS, val);
}
// 設定目前手機螢幕亮度
setBrightness(val);
// 存儲目前手機螢幕亮度的值到資料庫中
if (!tracking) {
AsyncTask.execute(new Runnable() {
public void run() {
Settings.System.putIntForUser(mContext.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS, val,
UserHandle.USER_CURRENT);
}
});
}
} else {
// 自動亮度,計算出自動亮度值,然後通過setBrightnessAdj進行設定
final float adj = value / ((mMaximumBacklight - mMinimumBacklight) / 2f) - 1;
if (stopTracking) {
MetricsLogger.action(mContext, MetricsLogger.ACTION_BRIGHTNESS_AUTO, value);
}
setBrightnessAdj(adj);
if (!tracking) {
AsyncTask.execute(new Runnable() {
public void run() {
Settings.System.putFloatForUser(mContext.getContentResolver(),
Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, adj,
UserHandle.USER_CURRENT);
}
});
}
}
// 回調所有實作BrightnessStateChangeCallback接口的監聽
for (BrightnessStateChangeCallback cb : mChangeCallbacks) {
cb.onBrightnessLevelChanged();
}
}
private void setBrightness(int brightness) {
try {
// mPower是一個IPowerManager接口,最終實作是在PowerManagerService
mPower.setTemporaryScreenBrightnessSettingOverride(brightness);
} catch (RemoteException ex) {
}
}
}
可以看到,在BrightnessController#onChanged 回調中,調用了自己的setBrightness方法,并且最終通過PowerManagerService#setTemporaryScreenBrightnessSettingOverride實作
PowerManagerService#setTemporaryScreenBrightnessSettingOverride
@Override // Binder call
public void setTemporaryScreenBrightnessSettingOverride(int brightness) {
// 檢查目前調用是否有android.Manifest.permission.DEVICE_POWER權限,如果沒有,則抛出SecurityException
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.DEVICE_POWER, null);
final long ident = Binder.clearCallingIdentity();
try {
// 通過setTemporaryScreenBrightnessSettingOverrideInternal方法設定螢幕亮度
setTemporaryScreenBrightnessSettingOverrideInternal(brightness);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
private void setTemporaryScreenBrightnessSettingOverrideInternal(int brightness) {
synchronized (mLock) {
// 螢幕亮度發生改變的時候調用
if (mTemporaryScreenBrightnessSettingOverride != brightness) {
// 設定新的螢幕亮度,後面在更新螢幕亮度中會用到
mTemporaryScreenBrightnessSettingOverride = brightness;
mDirty |= DIRTY_SETTINGS;
// 改變目前螢幕亮度
updatePowerStateLocked();
}
}
}
private void updatePowerStateLocked() {
....
try {
// 設定螢幕顯示
boolean displayBecameReady = updateDisplayPowerStateLocked(dirtyPhase2);
} finally {
}
....
}
private boolean updateDisplayPowerStateLocked(int dirty) {
final boolean oldDisplayReady = mDisplayReady;
if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS
| DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED | DIRTY_BOOT_COMPLETED
| DIRTY_SETTINGS | DIRTY_SCREEN_BRIGHTNESS_BOOST)) != 0) {
....
boolean autoBrightness = (mScreenBrightnessModeSetting ==
Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
if (isValidBrightness(mScreenBrightnessOverrideFromWindowManager)) {
screenBrightness = mScreenBrightnessOverrideFromWindowManager;
autoBrightness = false;
brightnessSetByUser = false;
} else if (isValidBrightness(mTemporaryScreenBrightnessSettingOverride)) {
// 使用者自己設定的螢幕亮度值
screenBrightness = mTemporaryScreenBrightnessSettingOverride;
} else if (isValidBrightness(mScreenBrightnessSetting)) {
screenBrightness = mScreenBrightnessSetting;
}
if (autoBrightness) { //如果是自動亮度
....
}
screenBrightness = Math.max(Math.min(screenBrightness,
mScreenBrightnessSettingMaximum), mScreenBrightnessSettingMinimum);
// 将新的螢幕亮度值指派給mDisplayPowerRequest.screenBrightness
mDisplayPowerRequest.screenBrightness = screenBrightness;
// 進一步通過mDisplayManagerInternal請求改變目前的power狀态
mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest,
mRequestWaitForNegativeProximity);
}
return mDisplayReady && !oldDisplayReady;
}
這裡的mDisplayManagerInternal是什麼呢,可以看到它是DisplayManagerInternal類,是一個抽象類
public abstract class DisplayManagerInternal {
}
那麼它的實作在哪裡?還記得我們手機開機的時候所有的系統服務都是由SystemServer來啟動的,其中在startBootstrapServices中啟動了DisplayManagerService
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
接着DisplayManagerService#onStart會被執行
@Override
public void onStart() {
mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER);
publishBinderService(Context.DISPLAY_SERVICE, new BinderService(),
true /*allowIsolated*/);
// DisplayManagerInternal對應的是LocalService服務
publishLocalService(DisplayManagerInternal.class, new LocalService());
}
從上面代碼可以看出DisplayManagerInternal對應的是LocalService服務,LocalService是DisplayManagerService的一個内部類,繼承自DisplayManagerInternal
private final class LocalService extends DisplayManagerInternal {
@Override
public void initPowerManagement(final DisplayPowerCallbacks callbacks, Handler handler,
SensorManager sensorManager) {
synchronized (mSyncRoot) {
DisplayBlanker blanker = new DisplayBlanker() {
@Override
public void requestDisplayState(int state, int brightness, int brightnessMode) {
// The order of operations is important for legacy reasons.
if (state == Display.STATE_OFF) {
requestGlobalDisplayStateInternal(state, brightness, brightnessMode);
}
callbacks.onDisplayStateChange(state);
if (state != Display.STATE_OFF) {
requestGlobalDisplayStateInternal(state, brightness, brightnessMode);
}
}
};
mDisplayPowerController = new DisplayPowerController(
mContext, callbacks, handler, sensorManager, blanker);
}
}
....
@Override
public boolean requestPowerState(DisplayPowerRequest request,
boolean waitForNegativeProximity) {
// mDisplayPowerController是DisplayPowerController類型
return mDisplayPowerController.requestPowerState(request,
waitForNegativeProximity);
}
....
}
接着看下DisplayPowerController#requestPowerState方法:
public boolean requestPowerState(DisplayPowerRequest request,
boolean waitForNegativeProximity) {
synchronized (mLock) {
boolean changed = 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);
}
}
發送"MSG_UPDATE_POWER_STATE"消息,DisplayControllerHandler是DisplayPowerController的一個内部handler
private final class DisplayControllerHandler extends Handler {
public DisplayControllerHandler(Looper looper) {
super(looper, null, true /*async*/);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_UPDATE_POWER_STATE:
updatePowerState();
break;
....
}
}
}
private void updatePowerState() {
....
// If need to set the screen brightness immediately,
// set the brightness and the brightness mode here.
if (mSetBrightnessImmediatelyAtNextRequest) {
if (DEBUG) {
Slog.d(TAG, "Setting the screen brightness immediately:"
+ brightness);
}
mPowerState.setScreenBrightnessAndBrightnessMode(
brightness,
hardwareAutoBrightnessEnabled ?
Light.BRIGHTNESS_MODE_SENSOR : Light.BRIGHTNESS_MODE_USER);
}
....
if (!mPendingScreenOff) {
if (!mSetBrightnessImmediatelyAtNextRequest
&& (state == Display.STATE_ON || state == Display.STATE_DOZE)) {
// 動态調整螢幕亮度
animateScreenBrightness(brightness,
slowChange ? BRIGHTNESS_RAMP_RATE_SLOW : BRIGHTNESS_RAMP_RATE_FAST);
} else {
animateScreenBrightness(brightness, 0);
mSetBrightnessImmediatelyAtNextRequest = false;
}
}
}
public void setScreenBrightnessAndBrightnessMode(int brightness, int brightnessMode) {
if (mScreenBrightness != brightness || mBrightnessMode != brightnessMode) {
mScreenBrightness = brightness;
mBrightnessMode = brightnessMode;
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);
}
private final Runnable mScreenUpdateRunnable = new Runnable() {
@Override
public void run() {
mScreenUpdatePending = false;
int brightness = mScreenState != Display.STATE_OFF
&& mColorFadeLevel > 0f ? mScreenBrightness : 0;
// 調用了setState方法,mPhotonicModulator是PhotonicModulator類型,是一個線程
if (mPhotonicModulator.setState(mScreenState, brightness, mBrightnessMode)) {
mScreenReady = true;
invokeCleanListenerIfNeeded();
} else {
}
}
};
看下PhotonicModulator線程
private final class PhotonicModulator extends Thread {
private static final int INITIAL_SCREEN_STATE = Display.STATE_OFF; // unknown, assume off
private final Object mLock = new Object();
private boolean mChangeInProgress;
public PhotonicModulator() {
super("PhotonicModulator");
}
public boolean setState(int state, int backlight, int brightnessMode) {
synchronized (mLock) {
if (state != mPendingState || backlight != mPendingBacklight ||
brightnessMode != mPendingBrightnessMode) {
mPendingState = state;
mPendingBacklight = backlight;
mPendingBrightnessMode = brightnessMode;
if (!mChangeInProgress) {
mChangeInProgress = true;
// 當亮度發生改變完成以後,通過notifyAll喚醒處于等待的所有線程,包括自己,
// 此時就會繼續走之前"mLock.wait();"下面的代碼,通過mBlanker.requestDisplayState實作螢幕亮度變化
mLock.notifyAll();
}
}
return !mChangeInProgress;
}
}
@Override
public void run() {
for (;;) {
// Get pending change.
final int state;
final boolean stateChanged;
final int backlight;
final boolean backlightChanged;
final int brightnessMode;
final boolean brightnessModeChanged;
synchronized (mLock) {
state = mPendingState;
stateChanged = (state != mActualState);
backlight = mPendingBacklight;
backlightChanged = (backlight != mActualBacklight);
brightnessMode = mPendingBrightnessMode;
brightnessModeChanged = (brightnessMode != mActualBrightnessMode);
if (!stateChanged && !backlightChanged && !brightnessModeChanged) {
// All changed applied, notify outer class and wait for more.
mChangeInProgress = false;
postScreenUpdateThreadSafe();
// 如果沒有發生改變,則目前線程處于等待狀态,下面的代碼也是不會執行的
try {
mLock.wait();
} catch (InterruptedException ex) { }
continue;
}
mActualState = state;
mActualBacklight = backlight;
mActualBrightnessMode = brightnessMode;
}
// 通過mBlanker.requestDisplayState來實作頁面亮度改變
mBlanker.requestDisplayState(state, backlight, brightnessMode);
}
}
}
這裡,可以看到,在mScreenUpdateRunnable線程中調用了PhotonicModulator#setState來喚醒所有處于等待狀态的線程,包括它自己,PhotonicModulator是在DisplayPowerState的構造方法中就已經啟動了,
好了現在看下mBlanker.requestDisplayState,可是發現mBlanker對應的DisplayBlanker是一個接口,那麼肯定有它的實作類:
public interface DisplayBlanker {
void requestDisplayState(int state, int brightness, int brightnessMode);
}
DisplayBlanker是在DisplayManagerService#onStart中綁定LocalService時候構造的
private final class LocalService extends DisplayManagerInternal {
@Override
public void initPowerManagement(final DisplayPowerCallbacks callbacks, Handler handler,
SensorManager sensorManager) {
synchronized (mSyncRoot) {
DisplayBlanker blanker = new DisplayBlanker() {
@Override
public void requestDisplayState(int state, int brightness, int brightnessMode) {
// The order of operations is important for legacy reasons.
if (state == Display.STATE_OFF) {
requestGlobalDisplayStateInternal(state, brightness, brightnessMode);
}
// 調用了PowerManagerService中的onDisplayStateChange
callbacks.onDisplayStateChange(state);
if (state != Display.STATE_OFF) {
requestGlobalDisplayStateInternal(state, brightness, brightnessMode);
}
}
};
mDisplayPowerController = new DisplayPowerController(
mContext, callbacks, handler, sensorManager, blanker);
}
}
}
@Override
public void onDisplayStateChange(int state) {
// This method is only needed to support legacy display blanking behavior
// where the display's power state is coupled to suspend or to the power HAL.
// The order of operations matters here.
synchronized (mLock) {
if (mDisplayState != state) {
mDisplayState = state;
if (state == Display.STATE_OFF) {
if (!mDecoupleHalInteractiveModeFromDisplayConfig) {
setHalInteractiveModeLocked(false);
}
if (!mDecoupleHalAutoSuspendModeFromDisplayConfig) {
setHalAutoSuspendModeLocked(true);
}
} else {
if (!mDecoupleHalAutoSuspendModeFromDisplayConfig) {
setHalAutoSuspendModeLocked(false);
}
if (!mDecoupleHalInteractiveModeFromDisplayConfig) {
setHalInteractiveModeLocked(true);
}
}
}
}
}
其中setHalInteractiveModeLocked是一個native函數,設定螢幕是否亮。
接着繼續看下updatePowerState中animateScreenBrightness動态調整螢幕亮度的過程
private void animateScreenBrightness(int target, float rate) {
if (mScreenBrightnessRampAnimator.animateTo(target, rate)) {//泛型技術,最後調用了DisplayPowerState的setScreenBrightness函數
try {
mBatteryStats.noteScreenBrightness(target);
} catch (RemoteException ex) {
// same process
}
}
}
最終程式會走到LightsService$LightImpl類中
public class LightsService extends SystemService {
private final class LightImpl extends Light {
@Override
public void setBrightnessForce(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, true);
}
}
....
private void setLightLocked(int color, int mode, int onMS, int offMS, int brightnessMode, boolean force) {
if (color != mColor || mode != mMode || onMS != mOnMS || offMS != mOffMS
|| brightnessMode != mBrightnessMode || force) {
mColor = color;
mMode = mode;
mOnMS = onMS;
mOffMS = offMS;
Trace.traceBegin(Trace.TRACE_TAG_POWER, "setLight(" + mId + ", 0x"
+ Integer.toHexString(color) + ")");
mBrightnessMode = brightnessMode;
try {
if (mAllowSetLight) {
// 設定目前螢幕亮度
setLight_native(mNativePointer, mId, color, mode, onMS, offMS, brightnessMode);
}
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
}
}
....
}
}
歡 迎 關 注 我 的 公 衆 号 “編 程 大 全”
專注技術分享,包括Java,python,AI人工智能,Android分享,不定期更新學習視訊