android6.0 Power表示(明るさなど)詳細分析(一)PowerManagerService&DisplayPowerController
30227 ワード
前にandroid 5.1パワーを分析したことがありますが、そのブログは全体的な分析から少し雑然としていて、これらのブログはパワーの機能から分析されていて、個人的にはもっと理解しやすいと思います.
以前のブログで分析したことがあるので、PowerManagerServiceの表示に関連する主体に直接入ります.
updateDisplayPowerStateLocked関数:
まずgetDesiredScreenPolicyLocked関数を見てみましょう.これは、現在のPowerManagerのmWakefulnessの状態に基づいて各値を返します.
まず、DisplayManagerServiceの次のLocalServiceを見てみましょう.PowerManagerServiceではinitPowerManagementが先に呼び出され、上の関数ではrequestPowerState関数が呼び出され、最後にDisplayPowerControllerのrequestPowerStateインタフェースが呼び出されます.
ここでは、PowerManagerServicesがLocalServicesのinitPowerManagementインタフェースを呼び出すと、いくつかのパラメータが入力され、後で分析されることにも注意してください.
まずDisplayPowerControllerのコンストラクション関数を見てみましょう.まず、転送されたパラメータを保存します.転送されたhandlerはPowerManagerServiceから転送されたもので、DisplayPowerControllerのメッセージ処理スレッドがPowerManagerServiceにあることを示しています.このコンストラクション関数の後ろには様々なパラメータの構成があります.私たちは見ません.
次にrequestPowerState関数を見てみましょう.
sendUpdatePowerStateLockedはMSGを送信しましたUPDATE_POWER_STATEメッセージ
このメッセージ処理はupdatePowerState関数を呼び出します.
updatePowerState関数:
Initialize関数を見てmPowerStateを初期化しました
updatePowerState関数の解析を続行します.
上では受信したpolicyに基づいてstateの状態を決定し,後に呼び出された.
...
animateScreenStateChange関数は、最終的にDisplayPowerStateのsetScreenState関数を呼び出します.
一方、animateScreenBrightnessは汎用技術を通じて、ここでは言わないで、最終的に呼び出しました.
次に、scheduleScreenUpdate関数が最終的に非同期でメッセージを送信することを見てみましょう.
mScreenUpdateRunnableを見てみましょう
まずmPhotonicModulatorを呼び出しました.setState関数、この関数を見てみましょう.
このPhotonicModulatorはスレッドであり、DisplayPowerStateコンストラクション関数でこのスレッドが開きます.
最後にmBlankerを呼び出しました.requestDisplayState関数ですが、このblankerはDisplayPowerControllerから渡されます.最終的には
DisplayManagerServiceのinitPowerManagement関数で初期化されましたが、ノードの輝度を本当に設定するのはDisplayManagerServiceで、以前とは異なります.
もう一度見てみましょうonDisplayStateChange関数は、PowerManagerServiceのonDisplayStateChangeでもいくつかの設定です.
最後に、DisplayPowerControllerのupdatePowerState関数の最後のコードに戻ります.
readyこの変数は非常に重要で、DisplayPowerControllerが準備ができているかどうかを直接説明します.このready変数はDisplayPowerStateのwaitUntilCleanに関連しています.
trueは、mScreenReadyに対してのみ返されます.この変数は、前のsetScreenStateおよびsetScreenBrightness関数で非同期でメッセージを送信してから呼び出されます.
最後にDisplayPowerControllerのupdatePowerState関数を見てみましょう
完了していません.PowerManagerServiceのコールバックを呼び出します.次はロックとロックを解除し、Displaysのロックを呼び出します.
最後にリリースロックが完了し、mDisplayReadyLocked=true、sendOnStateChangedWithWakelock関数が呼び出されました
onStateChangedを見てみましょう.PowerManagerServiceを呼び出すupdatePowerStateLocked関数です.最終的にはDisplayPowerControllerのrequestPowerState関数が再び呼び出されます.
updatePowerStateLockedでupdateDisplayPowerStateLockedを2回目に呼び出します.そこでまたDisplayPowerControllerのrequestPowerState関数に来て、今では2回目の呼び出しです.
さらに、updateDisplayPowerStateLocked呼び出しrequestPowerStateの戻り値を見てみましょう.今回mDisplayReadyというメンバー変数を返すのがtrueです
android 5を分析したことがあります.1のこの内容、最大の違いは以前バックライトを設置した部分がDisplayPowerStateに置かれていたことであり、現在はDisplayManagerServiceに置かれていることである.
一、PowerManagerServiceの表示関連関数
以前のブログで分析したことがあるので、PowerManagerServiceの表示に関連する主体に直接入ります.
updateDisplayPowerStateLocked関数:
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) {
mDisplayPowerRequest.policy = getDesiredScreenPolicyLocked();// PowerManager mWakefulness
// Determine appropriate screen brightness and auto-brightness adjustments.
boolean brightnessSetByUser = true;
int screenBrightness = mScreenBrightnessSettingDefault;
float screenAutoBrightnessAdjustment = 0.0f;
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 = mScreenBrightnessSettingDefault;
if (isValidAutoBrightnessAdjustment(
mTemporaryScreenAutoBrightnessAdjustmentSettingOverride)) {
screenAutoBrightnessAdjustment =
mTemporaryScreenAutoBrightnessAdjustmentSettingOverride;
} else if (isValidAutoBrightnessAdjustment(
mScreenAutoBrightnessAdjustmentSetting)) {
screenAutoBrightnessAdjustment = mScreenAutoBrightnessAdjustmentSetting;
}
}
screenBrightness = Math.max(Math.min(screenBrightness,
mScreenBrightnessSettingMaximum), mScreenBrightnessSettingMinimum);
screenAutoBrightnessAdjustment = Math.max(Math.min(
screenAutoBrightnessAdjustment, 1.0f), -1.0f);
// Update display power request.
mDisplayPowerRequest.screenBrightness = screenBrightness;
mDisplayPowerRequest.screenAutoBrightnessAdjustment =
screenAutoBrightnessAdjustment;
mDisplayPowerRequest.brightnessSetByUser = brightnessSetByUser;
mDisplayPowerRequest.useAutoBrightness = autoBrightness;
mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked();//
mDisplayPowerRequest.lowPowerMode = mLowPowerModeEnabled;//
mDisplayPowerRequest.boostScreenBrightness = mScreenBrightnessBoostInProgress;//
if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE) {
mDisplayPowerRequest.dozeScreenState = mDozeScreenStateOverrideFromDreamManager;
if (mDisplayPowerRequest.dozeScreenState == Display.STATE_DOZE_SUSPEND
&& (mWakeLockSummary & WAKE_LOCK_DRAW) != 0) {
mDisplayPowerRequest.dozeScreenState = Display.STATE_DOZE;
}
mDisplayPowerRequest.dozeScreenBrightness =
mDozeScreenBrightnessOverrideFromDreamManager;
} else {
mDisplayPowerRequest.dozeScreenState = Display.STATE_UNKNOWN;
mDisplayPowerRequest.dozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT;
}
mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest,// DisplayPowerController
mRequestWaitForNegativeProximity);
mRequestWaitForNegativeProximity = false;
return mDisplayReady && !oldDisplayReady;
}
まずgetDesiredScreenPolicyLocked関数を見てみましょう.これは、現在のPowerManagerのmWakefulnessの状態に基づいて各値を返します.
private int getDesiredScreenPolicyLocked() {
if (mWakefulness == WAKEFULNESS_ASLEEP) {
return DisplayPowerRequest.POLICY_OFF;
}
if (mWakefulness == WAKEFULNESS_DOZING) {
if ((mWakeLockSummary & WAKE_LOCK_DOZE) != 0) {
return DisplayPowerRequest.POLICY_DOZE;
}
if (mDozeAfterScreenOffConfig) {
return DisplayPowerRequest.POLICY_OFF;
}
// Fall through and preserve the current screen policy if not configured to
// doze after screen off. This causes the screen off transition to be skipped.
}
if ((mWakeLockSummary & WAKE_LOCK_SCREEN_BRIGHT) != 0
|| (mUserActivitySummary & USER_ACTIVITY_SCREEN_BRIGHT) != 0
|| !mBootCompleted
|| mScreenBrightnessBoostInProgress) {
return DisplayPowerRequest.POLICY_BRIGHT;
}
return DisplayPowerRequest.POLICY_DIM;
}
まず、DisplayManagerServiceの次のLocalServiceを見てみましょう.PowerManagerServiceではinitPowerManagementが先に呼び出され、上の関数ではrequestPowerState関数が呼び出され、最後にDisplayPowerControllerのrequestPowerStateインタフェースが呼び出されます.
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) {
// The order of operations is important for legacy reasons.
if (state == Display.STATE_OFF) {
requestGlobalDisplayStateInternal(state, brightness);
}
callbacks.onDisplayStateChange(state);
if (state != Display.STATE_OFF) {
requestGlobalDisplayStateInternal(state, brightness);
}
}
};
mDisplayPowerController = new DisplayPowerController(
mContext, callbacks, handler, sensorManager, blanker);
}
}
@Override
public boolean requestPowerState(DisplayPowerRequest request,
boolean waitForNegativeProximity) {
return mDisplayPowerController.requestPowerState(request,
waitForNegativeProximity);
}
ここでは、PowerManagerServicesがLocalServicesのinitPowerManagementインタフェースを呼び出すと、いくつかのパラメータが入力され、後で分析されることにも注意してください.
二、DisplayPowerController
まずDisplayPowerControllerのコンストラクション関数を見てみましょう.まず、転送されたパラメータを保存します.転送されたhandlerはPowerManagerServiceから転送されたもので、DisplayPowerControllerのメッセージ処理スレッドがPowerManagerServiceにあることを示しています.このコンストラクション関数の後ろには様々なパラメータの構成があります.私たちは見ません.
public DisplayPowerController(Context context,
DisplayPowerCallbacks callbacks, Handler handler,
SensorManager sensorManager, DisplayBlanker blanker) {
mHandler = new DisplayControllerHandler(handler.getLooper());
mCallbacks = callbacks;
mBatteryStats = BatteryStatsService.getService();
mSensorManager = sensorManager;
mWindowManagerPolicy = LocalServices.getService(WindowManagerPolicy.class);
mBlanker = blanker;
mContext = context;
mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
次にrequestPowerState関数を見てみましょう.
public boolean requestPowerState(DisplayPowerRequest request,
boolean waitForNegativeProximity) {
synchronized (mLock) {
boolean changed = false;
if (waitForNegativeProximity
&& !mPendingWaitForNegativeProximityLocked) {
mPendingWaitForNegativeProximityLocked = true;
changed = true;
}
if (mPendingRequestLocked == null) {//
mPendingRequestLocked = new DisplayPowerRequest(request);// DisplayPowerRequest
changed = true;
} else if (!mPendingRequestLocked.equals(request)) {
mPendingRequestLocked.copyFrom(request);
changed = true;
}
if (changed) {
mDisplayReadyLocked = false;//
}
if (changed && !mPendingRequestChangedLocked) {// mPendingRequestChangedLocked false
mPendingRequestChangedLocked = true;// true
sendUpdatePowerStateLocked();
}
return mDisplayReadyLocked;
}
}
sendUpdatePowerStateLockedはMSGを送信しましたUPDATE_POWER_STATEメッセージ
private void sendUpdatePowerStateLocked() {
if (!mPendingUpdatePowerStateLocked) {
mPendingUpdatePowerStateLocked = true;
Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE);
msg.setAsynchronous(true);
mHandler.sendMessage(msg);
}
}
このメッセージ処理はupdatePowerState関数を呼び出します.
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_UPDATE_POWER_STATE:
updatePowerState();
break;
case MSG_PROXIMITY_SENSOR_DEBOUNCED:
debounceProximitySensor();
break;
case MSG_SCREEN_ON_UNBLOCKED:
if (mPendingScreenOnUnblocker == msg.obj) {
unblockScreenOn();
updatePowerState();
}
break;
}
}
updatePowerState関数:
private void updatePowerState() {
// Update the power state request.
final boolean mustNotify;
boolean mustInitialize = false;
boolean autoBrightnessAdjustmentChanged = false;
synchronized (mLock) {
mPendingUpdatePowerStateLocked = false;
if (mPendingRequestLocked == null) {// null
return; // wait until first actual power request
}
if (mPowerRequest == null) {//
mPowerRequest = new DisplayPowerRequest(mPendingRequestLocked);
mWaitingForNegativeProximity = mPendingWaitForNegativeProximityLocked;
mPendingWaitForNegativeProximityLocked = false;
mPendingRequestChangedLocked = false;
mustInitialize = true;
} else if (mPendingRequestChangedLocked) {
autoBrightnessAdjustmentChanged = (mPowerRequest.screenAutoBrightnessAdjustment
!= mPendingRequestLocked.screenAutoBrightnessAdjustment);
mPowerRequest.copyFrom(mPendingRequestLocked);
mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked;
mPendingWaitForNegativeProximityLocked = false;
mPendingRequestChangedLocked = false;
mDisplayReadyLocked = false;
}
mustNotify = !mDisplayReadyLocked;
}
// Initialize things the first time the power state is changed.
if (mustInitialize) {//
initialize();
}
Initialize関数を見てmPowerStateを初期化しました
private void initialize() {
// Initialize the power state object for the default display.
// In the future, we might manage multiple displays independently.
mPowerState = new DisplayPowerState(mBlanker,
new ColorFade(Display.DEFAULT_DISPLAY));
mColorFadeOnAnimator = ObjectAnimator.ofFloat(
mPowerState, DisplayPowerState.COLOR_FADE_LEVEL, 0.0f, 1.0f);
mColorFadeOnAnimator.setDuration(COLOR_FADE_ON_ANIMATION_DURATION_MILLIS);
mColorFadeOnAnimator.addListener(mAnimatorListener);
mColorFadeOffAnimator = ObjectAnimator.ofFloat(
mPowerState, DisplayPowerState.COLOR_FADE_LEVEL, 1.0f, 0.0f);
mColorFadeOffAnimator.setDuration(COLOR_FADE_OFF_ANIMATION_DURATION_MILLIS);
mColorFadeOffAnimator.addListener(mAnimatorListener);
mScreenBrightnessRampAnimator = new RampAnimator(
mPowerState, DisplayPowerState.SCREEN_BRIGHTNESS);
mScreenBrightnessRampAnimator.setListener(mRampAnimatorListener);
// Initialize screen state for battery stats.
try {
mBatteryStats.noteScreenState(mPowerState.getScreenState());
mBatteryStats.noteScreenBrightness(mPowerState.getScreenBrightness());
} catch (RemoteException ex) {
// same process
}
}
updatePowerState関数の解析を続行します.
int state;
int brightness = PowerManager.BRIGHTNESS_DEFAULT;
boolean performScreenOffTransition = false;
switch (mPowerRequest.policy) {
case DisplayPowerRequest.POLICY_OFF:
state = Display.STATE_OFF;
performScreenOffTransition = true;
break;
case DisplayPowerRequest.POLICY_DOZE:
if (mPowerRequest.dozeScreenState != Display.STATE_UNKNOWN) {
state = mPowerRequest.dozeScreenState;
} else {
state = Display.STATE_DOZE;
}
if (!mAllowAutoBrightnessWhileDozingConfig) {
brightness = mPowerRequest.dozeScreenBrightness;
}
break;
case DisplayPowerRequest.POLICY_DIM:
case DisplayPowerRequest.POLICY_BRIGHT:
default:
state = Display.STATE_ON;
break;
}
assert(state != Display.STATE_UNKNOWN);
上では受信したpolicyに基づいてstateの状態を決定し,後に呼び出された.
animateScreenStateChange(state, performScreenOffTransition);
state = mPowerState.getScreenState();
...
if (!mPendingScreenOff) {
if (state == Display.STATE_ON || state == Display.STATE_DOZE) {
animateScreenBrightness(brightness,
slowChange ? BRIGHTNESS_RAMP_RATE_SLOW : BRIGHTNESS_RAMP_RATE_FAST);
} else {
animateScreenBrightness(brightness, 0);
}
}
三、DisplayPowerState
animateScreenStateChange関数は、最終的にDisplayPowerStateのsetScreenState関数を呼び出します.
public void setScreenState(int state) {
if (mScreenState != state) {
if (DEBUG) {
Slog.d(TAG, "setScreenState: state=" + state);
}
mScreenState = state;
mScreenReady = false;
scheduleScreenUpdate();
}
}
一方、animateScreenBrightnessは汎用技術を通じて、ここでは言わないで、最終的に呼び出しました.
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();
}
}
}
次に、scheduleScreenUpdate関数が最終的に非同期でメッセージを送信することを見てみましょう.
private void scheduleScreenUpdate() {
if (!mScreenUpdatePending) {
mScreenUpdatePending = true;
postScreenUpdateThreadSafe();
}
}
private void postScreenUpdateThreadSafe() {
mHandler.removeCallbacks(mScreenUpdateRunnable);
mHandler.post(mScreenUpdateRunnable);
}
mScreenUpdateRunnableを見てみましょう
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)) {
if (DEBUG) {
Slog.d(TAG, "Screen ready");
}
mScreenReady = true;
invokeCleanListenerIfNeeded();
} else {
if (DEBUG) {
Slog.d(TAG, "Screen not ready");
}
}
}
};
まずmPhotonicModulatorを呼び出しました.setState関数、この関数を見てみましょう.
public boolean setState(int state, int backlight) {
synchronized (mLock) {
boolean stateChanged = state != mPendingState;
boolean backlightChanged = backlight != mPendingBacklight;
if (stateChanged || backlightChanged) {
if (DEBUG) {
Slog.d(TAG, "Requesting new screen state: state="
+ Display.stateToString(state) + ", backlight=" + backlight);
}
mPendingState = state;//
mPendingBacklight = backlight;//
boolean changeInProgress = mStateChangeInProgress || mBacklightChangeInProgress;
mStateChangeInProgress = stateChanged;
mBacklightChangeInProgress = backlightChanged;
if (!changeInProgress) {
Slog.d(TAG,"notify set backlight thread run");
mLock.notifyAll();
}
}
return !mStateChangeInProgress;
}
}
このPhotonicModulatorはスレッドであり、DisplayPowerStateコンストラクション関数でこのスレッドが開きます.
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) {
// State changed applied, notify outer class.
postScreenUpdateThreadSafe();
mStateChangeInProgress = false;
}
if (!backlightChanged) {
mBacklightChangeInProgress = false;
}
if (!stateChanged && !backlightChanged) {
try {
mLock.wait();
} catch (InterruptedException ex) { }
continue;
}
mActualState = state;
mActualBacklight = backlight;
}
// Apply pending change.
if (true) {
Slog.d(TAG, "Updating screen state: state="
+ Display.stateToString(state) + ", backlight=" + backlight);
}
mBlanker.requestDisplayState(state, backlight);
}
}
}
四、コールバック
最後にmBlankerを呼び出しました.requestDisplayState関数ですが、このblankerはDisplayPowerControllerから渡されます.最終的には
public void initPowerManagement(final DisplayPowerCallbacks callbacks, Handler handler,
SensorManager sensorManager) {
synchronized (mSyncRoot) {
DisplayBlanker blanker = new DisplayBlanker() {
@Override
public void requestDisplayState(int state, int brightness) {
// The order of operations is important for legacy reasons.
if (state == Display.STATE_OFF) {
requestGlobalDisplayStateInternal(state, brightness);
}
callbacks.onDisplayStateChange(state);
if (state != Display.STATE_OFF) {
requestGlobalDisplayStateInternal(state, brightness);
}
}
};
mDisplayPowerController = new DisplayPowerController(
mContext, callbacks, handler, sensorManager, blanker);
}
}
DisplayManagerServiceのinitPowerManagement関数で初期化されましたが、ノードの輝度を本当に設定するのはDisplayManagerServiceで、以前とは異なります.
もう一度見てみましょうonDisplayStateChange関数は、PowerManagerServiceのonDisplayStateChangeでもいくつかの設定です.
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);
}
}
}
}
}
最後に、DisplayPowerControllerのupdatePowerState関数の最後のコードに戻ります.
final boolean ready = mPendingScreenOnUnblocker == null
&& !mColorFadeOnAnimator.isStarted()
&& !mColorFadeOffAnimator.isStarted()
&& mPowerState.waitUntilClean(mCleanListener);
final boolean finished = ready
&& !mScreenBrightnessRampAnimator.isAnimating();
// Notify policy about screen turned on.
if (ready && state != Display.STATE_OFF
&& mReportedScreenStateToPolicy == REPORTED_TO_POLICY_SCREEN_TURNING_ON) {
mReportedScreenStateToPolicy = REPORTED_TO_POLICY_SCREEN_ON;
mWindowManagerPolicy.screenTurnedOn();
}
// Grab a wake lock if we have unfinished business.
if (!finished && !mUnfinishedBusiness) {//
if (DEBUG) {
Slog.d(TAG, "Unfinished business...");
}
mCallbacks.acquireSuspendBlocker();// ,PowerManagerService
mUnfinishedBusiness = true;
}
// Notify the power manager when ready.
if (ready && mustNotify) {
// Send state change.
synchronized (mLock) {
if (!mPendingRequestChangedLocked) {
mDisplayReadyLocked = true;
if (DEBUG) {
Slog.d(TAG, "Display ready!");
}
}
}
sendOnStateChangedWithWakelock();
}
// Release the wake lock when we have no unfinished business.
if (finished && mUnfinishedBusiness) {
if (DEBUG) {
Slog.d(TAG, "Finished business...");
}
mUnfinishedBusiness = false;
mCallbacks.releaseSuspendBlocker();//
}
}
readyこの変数は非常に重要で、DisplayPowerControllerが準備ができているかどうかを直接説明します.このready変数はDisplayPowerStateのwaitUntilCleanに関連しています.
public boolean waitUntilClean(Runnable listener) {
if (!mScreenReady || !mColorFadeReady) {
mCleanListener = listener;
return false;
} else {
mCleanListener = null;
return true;
}
}
trueは、mScreenReadyに対してのみ返されます.この変数は、前のsetScreenStateおよびsetScreenBrightness関数で非同期でメッセージを送信してから呼び出されます.
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)) {
if (DEBUG) {
Slog.d(TAG, "Screen ready");
}
mScreenReady = true;
invokeCleanListenerIfNeeded();
} else {
if (DEBUG) {
Slog.d(TAG, "Screen not ready");
}
}
}
};
最後にDisplayPowerControllerのupdatePowerState関数を見てみましょう
// Grab a wake lock if we have unfinished business.
if (!finished && !mUnfinishedBusiness) {//
if (DEBUG) {
Slog.d(TAG, "Unfinished business...");
}
mCallbacks.acquireSuspendBlocker();// ,PowerManagerService
mUnfinishedBusiness = true;
}
// Notify the power manager when ready.
if (ready && mustNotify) {
// Send state change.
synchronized (mLock) {
if (!mPendingRequestChangedLocked) {
mDisplayReadyLocked = true;
if (DEBUG) {
Slog.d(TAG, "Display ready!");
}
}
}
sendOnStateChangedWithWakelock();
}
// Release the wake lock when we have no unfinished business.
if (finished && mUnfinishedBusiness) {
if (DEBUG) {
Slog.d(TAG, "Finished business...");
}
mUnfinishedBusiness = false;
mCallbacks.releaseSuspendBlocker();//
}
}
完了していません.PowerManagerServiceのコールバックを呼び出します.次はロックとロックを解除し、Displaysのロックを呼び出します.
@Override
public void acquireSuspendBlocker() {
mDisplaySuspendBlocker.acquire();
}
@Override
public void releaseSuspendBlocker() {
mDisplaySuspendBlocker.release();
}
最後にリリースロックが完了し、mDisplayReadyLocked=true、sendOnStateChangedWithWakelock関数が呼び出されました
private void sendOnStateChangedWithWakelock() {
mCallbacks.acquireSuspendBlocker();
mHandler.post(mOnStateChangedRunnable);
}
private final Runnable mOnStateChangedRunnable = new Runnable() {
@Override
public void run() {
mCallbacks.onStateChanged();
mCallbacks.releaseSuspendBlocker();
}
};
五、PowerManagerService第二回コールrequestPowerState
onStateChangedを見てみましょう.PowerManagerServiceを呼び出すupdatePowerStateLocked関数です.最終的にはDisplayPowerControllerのrequestPowerState関数が再び呼び出されます.
public void onStateChanged() {
synchronized (mLock) {
mDirty |= DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED;
updatePowerStateLocked();
}
}
updatePowerStateLockedでupdateDisplayPowerStateLockedを2回目に呼び出します.そこでまたDisplayPowerControllerのrequestPowerState関数に来て、今では2回目の呼び出しです.
public boolean requestPowerState(DisplayPowerRequest request,
boolean waitForNegativeProximity) {
synchronized (mLock) {
boolean changed = false;
if (waitForNegativeProximity
&& !mPendingWaitForNegativeProximityLocked) {
mPendingWaitForNegativeProximityLocked = true;
changed = true;
}
if (mPendingRequestLocked == null) {
mPendingRequestLocked = new DisplayPowerRequest(request);
changed = true;
} else if (!mPendingRequestLocked.equals(request)) {
mPendingRequestLocked.copyFrom(request);
changed = true;
}
if (changed) {
mDisplayReadyLocked = false;
}
if (changed && !mPendingRequestChangedLocked) {
mPendingRequestChangedLocked = true;
sendUpdatePowerStateLocked();
}
return mDisplayReadyLocked;// true , updatePowerState true
}
}
さらに、updateDisplayPowerStateLocked呼び出しrequestPowerStateの戻り値を見てみましょう.今回mDisplayReadyというメンバー変数を返すのがtrueです
mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest,
mRequestWaitForNegativeProximity);
六、まとめ
android 5を分析したことがあります.1のこの内容、最大の違いは以前バックライトを設置した部分がDisplayPowerStateに置かれていたことであり、現在はDisplayManagerServiceに置かれていることである.