前言:
在前两篇中初步介绍了STR和开机流程
进入STR流程
触发进入STR流程一般是锁车休眠,在锁车的时候MCU上报进入休眠流程,这里不详细讲,就讲Android原生的部分。
进入STR时,vhal会上报一个状态(信号:VehicleProperty.AP_POWER_STATE_REPORT,信号值SHUTDOWN_PREPARE)。
然后执行handleShutdownPrepare方法
private void handleShutdownPrepare(CpmsState newState) {
//静音
setVoiceInteractionDisabled(true);
//释放ON时申请的锁,为休眠做准备
mSystemInterface.setDisplayState(false);
// Shutdown on finish if the system doesn't support deep sleep or doesn't allow it.
synchronized (mLock) {
mShutdownOnFinish = mShutdownOnNextSuspend
|| !mHal.isDeepSleepAllowed()
|| !mSystemInterface.isSystemSupportingDeepSleep()
|| !newState.mCanSleep;
mGarageModeShouldExitImmediately = !newState.mCanPostpone;
}
Slog.i(TAG,
(newState.mCanPostpone
? "starting shutdown prepare with Garage Mode"
: "starting shutdown prepare without Garage Mode"));
//给Vhal发送状态
sendPowerManagerEvent(CarPowerStateListener.SHUTDOWN_PREPARE);
mHal.sendShutdownPrepare();
doHandlePreprocessing();
}
这里的主要目的就是释放ON时申请的锁,如果不释放是不会进入休眠的
GarageMode也会执行自己的finish。
收到Vhal发送的finish状态(信号:VehicleProperty.AP_POWER_STATE_REPORT,信号值FINISHED)
然后执行handleFinish方法,真正让系统休眠的方法
private void handleFinish() {
boolean simulatedMode;
synchronized (mSimulationWaitObject) {
simulatedMode = mInSimulatedDeepSleepMode;
}
boolean mustShutDown;
boolean forceReboot;
synchronized (mLock) {
mustShutDown = mShutdownOnFinish && !simulatedMode;
forceReboot = mRebootAfterGarageMode;
mRebootAfterGarageMode = false;
}
if (forceReboot) {
PowerManager powerManager = mContext.getSystemService(PowerManager.class);
if (powerManager == null) {
Slog.wtf(TAG, "No PowerManager. Cannot reboot.");
} else {
Slog.i(TAG, "GarageMode has completed. Forcing reboot.");
powerManager.reboot("GarageModeReboot");
throw new AssertionError("Should not return from PowerManager.reboot()");
}
}
setVoiceInteractionDisabled(true);
// To make Kernel implementation simpler when going into sleep.
disableWifi();
// mustShutDown 是false
if (mustShutDown) {
// shutdown HU
mSystemInterface.shutdown();
} else {
//核心休眠方法
doHandleDeepSleep(simulatedMode);
}
mShutdownOnNextSuspend = false;
}
doHandleDeepSleep是真正进入休眠的方法
private void doHandleDeepSleep(boolean simulatedMode) {
// keep holding partial wakelock to prevent entering sleep before enterDeepSleep call
// enterDeepSleep should force sleep entry even if wake lock is kept.
//设置display false已经执行过了,此处多余
mSystemInterface.switchToPartialWakeLock();
//清空任务
mHandler.cancelProcessingComplete();
synchronized (mLock) {
mLastSleepEntryTime = SystemClock.elapsedRealtime();
}
int nextListenerState;
//simulatedMode 是false
if (simulatedMode) {
simulateSleepByWaiting();
nextListenerState = CarPowerStateListener.SHUTDOWN_CANCELLED;
} else {
//suspendWithRetries调用就是强制休眠,且执行完此处,系统休眠,log中断不会往下进行了
boolean sleepSucceeded = suspendWithRetries();
//进入休眠失败或者唤醒往下执行,切记切记
if (!sleepSucceeded) {
// Suspend failed and we shut down instead.
// We either won't get here at all or we will power off very soon.
return;
}
// We suspended and have now resumed
nextListenerState = CarPowerStateListener.SUSPEND_EXIT;
}
synchronized (mLock) {
mIsResuming = true;
// Any wakeup time from before is no longer valid.
mNextWakeupSec = 0;
}
Slog.i(TAG, "Resuming after suspending");
mSystemInterface.refreshDisplayBrightness();
onApPowerStateChange(CpmsState.WAIT_FOR_VHAL, nextListenerState);
}
重点
boolean sleepSucceeded = suspendWithRetries();、
执行suspendWithRetries这个方法就强制进入休眠且log中断,代码也不会往下走,除非是进入休眠失败或者是唤醒。
此时,可以拉低电流值,并且进入STR。
// Send the command to enter Suspend to RAM.
// If the command is not successful, try again with an exponential back-off.
// If it fails repeatedly, send the command to shut down.
// If we decide to go to a different power state, abort this retry mechanism.
// Returns true if we successfully suspended.
private boolean suspendWithRetries() {
long retryIntervalMs = INITIAL_SUSPEND_RETRY_INTERVAL_MS;
int tryCount = 0;
while (true) {
Slog.i(TAG, "Entering Suspend to RAM");
boolean suspendSucceeded = mSystemInterface.enterDeepSleep();
//进入休眠正常这里就是true,return掉了,失败会往下走
if (suspendSucceeded) {
return true;
}
tryCount++;
if (tryCount >= MAX_SUSPEND_TRIES) {
break;
}
// We failed to suspend. Block the thread briefly and try again.
synchronized (mLock) {
if (mPendingPowerStates.isEmpty()) {
Slog.w(TAG, "Failed to Suspend; will retry later.");
try {
mLock.wait(retryIntervalMs);
} catch (InterruptedException ignored) {
Thread.currentThread().interrupt();
}
retryIntervalMs *= 2;
}
// Check for a new power state now, before going around the loop again
if (!mPendingPowerStates.isEmpty()) {
Slog.i(TAG, "Terminating the attempt to Suspend to RAM");
return false;
}
}
}
// Too many failures trying to suspend. Shut down.
Slog.w(TAG, "Could not Suspend to RAM. Shutting down.");
mSystemInterface.shutdown();
return false;
}