Android 8.1 Dozeモード分析(四)——Dozeモードの脱退
20026 ワード
概要
Dozeの脱退は、より厳密に言えば、Dozeモードの状態が他の状態からACTIVE状態に変化する場合である.簡単に言えば、Dozeモードを終了するには、画面が明るくなったり、充電器が挿入されたり、デバイスが移動したりする3つのケースがあります.以下、この3つのケースについて分析する.
前述の解析では
1.スクリーンの点滅
明るいスクリーンまたは消えるスクリーンの時、PMSは明るいスクリーンの放送を送信して、DICの中で明るいスクリーンの放送を傍受して、この放送を受け入れてそしてスクリーンの状態が変化した後の操作を行うことを担当します:放送を登録します:
ブロードキャストを受信して処理:
2.充電状態の変化
バッテリステータスの場合、BatteryServiceでブロードキャストが送信され、DICでもブロードキャストが傍受されます.
ブロードキャストを受信して処理:
ブロードキャストを受信すると、
最終的には、
3.他のサービスはBinderによって呼び出される
DeviceIdleController内部Binderには、Dozeを終了するためのインタフェースも用意されています.
内部でもbecomeActiveLocked()メソッドを呼び出してDozeを終了します.
4.MotionSensor検出状態発生
この場合は上記とは若干異なり、この場合Dozeの脱退は瞬時であり、両方の状態値をSTATE_に変換するACTIVE後、
Dozeの脱退は、より厳密に言えば、Dozeモードの状態が他の状態からACTIVE状態に変化する場合である.簡単に言えば、Dozeモードを終了するには、画面が明るくなったり、充電器が挿入されたり、デバイスが移動したりする3つのケースがあります.以下、この3つのケースについて分析する.
前述の解析では
becomeActiveLocked()
法を見たことがあるが,この方法は当時解析されていなかったが,この方法はDozeを脱退するためのものであり,厳密にはDoze状態をACTIVE状態にしてIDLE状態またはMAINTENANCE状態を脱退するためのものである.したがって,どのようにDozeを終了しても,このメソッドが呼び出される.この方法は次のとおりです.void becomeActiveLocked(String activeReason, int activeUid) {
if (mState != STATE_ACTIVE || mLightState != STATE_ACTIVE) {
// Handler, Handler PMS、 idle changed
scheduleReportActiveLocked(activeReason, activeUid);
// DeepDoze STATE_ACTIVE
mState = STATE_ACTIVE;
// LightDoze LIGHT_STATE_ACTIVE
mLightState = LIGHT_STATE_ACTIVE;
// INACTIVE
mInactiveTimeout = mConstants.INACTIVE_TIMEOUT;
mCurIdleBudget = 0;
mMaintenanceStartTime = 0;
// DeepDoze 、alarm、listener
resetIdleManagementLocked();
// LightDoze 、alarm、listener
resetLightIdleManagementLocked();
}
}
1.スクリーンの点滅
明るいスクリーンまたは消えるスクリーンの時、PMSは明るいスクリーンの放送を送信して、DICの中で明るいスクリーンの放送を傍受して、この放送を受け入れてそしてスクリーンの状態が変化した後の操作を行うことを担当します:放送を登録します:
filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_SCREEN_ON);
getContext().registerReceiver(mInteractivityReceiver, filter);
ブロードキャストを受信して処理:
private final BroadcastReceiver mInteractivityReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
synchronized (DeviceIdleController.this) {
updateInteractivityLocked();
}
}
};
updateInteractivityLocked()
の方法でLightDozeとDeepDozeの状態を更新し,この方法を最初の論文で解析した.2.充電状態の変化
バッテリステータスの場合、BatteryServiceでブロードキャストが送信され、DICでもブロードキャストが傍受されます.
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_BATTERY_CHANGED);
getContext().registerReceiver(mReceiver, filter);
ブロードキャストを受信して処理:
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) {
............
case Intent.ACTION_BATTERY_CHANGED: {
synchronized (DeviceIdleController.this) {
int plugged = intent.getIntExtra("plugged", 0);
updateChargingLocked(plugged != 0);
}
} break;
....................
}
}
};
ブロードキャストを受信すると、
updateChargingLocked(plugged != 0)
を呼び出してステータスを更新し、パラメータは充電線が挿入されているかどうかを示し、この方法は以下の通りである.void updateChargingLocked(boolean charging) {
//
if (!charging && mCharging) {
mCharging = false;
if (!mForceIdle) {
// INACTIVE , Doze
becomeInactiveIfAppropriateLocked();
}
} else if (charging) {//
mCharging = charging;
if (!mForceIdle) {
//Doze ACTIVE , Doze
becomeActiveLocked("charging", Process.myUid());
}
}
}
最終的には、
becomeActiveLocked()
も呼び出してDozeモードを終了する.3.他のサービスはBinderによって呼び出される
DeviceIdleController内部Binderには、Dozeを終了するためのインタフェースも用意されています.
@Override public void exitIdle(String reason) {
getContext().enforceCallingOrSelfPermission(Manifest.permission.DEVICE_POWER,
null);
long ident = Binder.clearCallingIdentity();
try {
exitIdleInternal(reason);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
内部でもbecomeActiveLocked()メソッドを呼び出してDozeを終了します.
public void exitIdleInternal(String reason) {
synchronized (this) {
becomeActiveLocked(reason, Binder.getCallingUid());
}
}
4.MotionSensor検出状態発生
この場合は上記とは若干異なり、この場合Dozeの脱退は瞬時であり、両方の状態値をSTATE_に変換するACTIVE後、
becomeInactiveIfAppropriateLocked()
メソッドを呼び出してINACTIVE状態に入り、いわば「瞬時」の脱退となる.MotionSensorが移動を検出するとDozeは終了し、処理ロジックはhandleMotionDetectedLocked()
にある.void handleMotionDetectedLocked(long timeout, String type) {
boolean becomeInactive = false;
if (mState != STATE_ACTIVE) {
// Handler PMS、NetworkPolicy、 IDLE_CHANGED
scheduleReportActiveLocked(type, Process.myUid());
mState = STATE_ACTIVE;// DeepDoze ACTIVE
mInactiveTimeout = timeout;
mCurIdleBudget = 0;
mMaintenanceStartTime = 0;
becomeInactive = true;
}
if (mLightState == LIGHT_STATE_OVERRIDE) {
mLightState = STATE_ACTIVE;// LightDoze ACTIVE
becomeInactive = true;
}
if (becomeInactive) {
// INACTIVE
becomeInactiveIfAppropriateLocked();
}
}