Allow max 3 minutes before going into suspend-to-RAM
- The system keeps trying to go into up to the duration specified
by config_maxSuspendWaitDuration.
- The valid range of the duration is 0 to 180000(= 3min).
- Wait interval is adjusted so that it will be fixed to 1000ms after
several exponential back-off.
Bug: 173113571
Test: manual test
Change-Id: I45c0f3f85fddeb86d5f902d810fd57ce94aa731d
diff --git a/service/src/com/android/car/power/CarPowerManagementService.java b/service/src/com/android/car/power/CarPowerManagementService.java
index 3665090..9af8f72 100644
--- a/service/src/com/android/car/power/CarPowerManagementService.java
+++ b/service/src/com/android/car/power/CarPowerManagementService.java
@@ -95,9 +95,13 @@
private static final String WIFI_STATE_MODIFIED = "forcibly_disabled";
private static final String WIFI_STATE_ORIGINAL = "original";
// If Suspend to RAM fails, we retry with an exponential back-off:
- // 10 msec, 20 msec, ..., 1280 msec, for a maximum of about 2.5 seconds.
- private static final int MAX_SUSPEND_TRIES = 9; // Initial + 8 retries
+ // The wait interval will be 10 msec, 20 msec, 40 msec, ...
+ // Once the wait interval goes beyond 1000 msec, it is fixed at 1000 msec.
private static final long INITIAL_SUSPEND_RETRY_INTERVAL_MS = 10;
+ private static final long MAX_RETRY_INTERVAL_MS = 1000;
+ // Minimum and maximum wait duration before the system goes into Suspend to RAM.
+ private static final long MIN_SUSPEND_WAIT_DURATION_MS = 0;
+ private static final long MAX_SUSPEND_WAIT_DURATION_MS = 3 * 60 * 1000;
private static final long CAR_POWER_POLICY_DAEMON_FIND_MARGINAL_TIME_MS = 300;
private static final long CAR_POWER_POLICY_DAEMON_BIND_RETRY_INTERVAL_MS = 500;
@@ -145,6 +149,12 @@
// This is a temp work-around to reduce user switching delay after wake-up.
private final boolean mSwitchGuestUserBeforeSleep;
+ // CPMS tries to enter Suspend to RAM within the duration specified at
+ // mMaxSuspendWaitDurationMs. The default max duration is MAX_SUSPEND_WAIT_DRATION, and can be
+ // overridden by setting config_maxSuspendWaitDuration in an overrlay resource.
+ // The valid range is MIN_SUSPEND_WAIT_DRATION to MAX_SUSPEND_WAIT_DURATION.
+ private final long mMaxSuspendWaitDurationMs;
+
@GuardedBy("mSimulationWaitObject")
private boolean mWakeFromSimulatedSleep;
@GuardedBy("mSimulationWaitObject")
@@ -233,6 +243,8 @@
mWifiStateFile = new AtomicFile(
new File(mSystemInterface.getSystemCarDir(), WIFI_STATE_FILENAME));
mPowerComponentHandler = new PowerComponentHandler(context, systemInterface);
+ mMaxSuspendWaitDurationMs = Math.max(MIN_SUSPEND_WAIT_DURATION_MS,
+ Math.min(getMaxSuspendWaitDurationConfig(), MAX_SUSPEND_WAIT_DURATION_MS));
}
/**
@@ -306,6 +318,8 @@
writer.println("mSwitchGuestUserBeforeSleep:" + mSwitchGuestUserBeforeSleep);
writer.println("mCurrentPowerPolicy:" + mCurrentPowerPolicy);
writer.println("mCurrentPowerPolicyGroup:" + mCurrentPowerPolicyGroup);
+ writer.print("mMaxSuspendWaitDurationMs:" + mMaxSuspendWaitDurationMs);
+ writer.println(", config_maxSuspendWaitDuration:" + getMaxSuspendWaitDurationConfig());
}
mPolicyReader.dump(writer);
}
@@ -1238,7 +1252,7 @@
// Returns true if we successfully suspended.
private boolean suspendWithRetries() {
long retryIntervalMs = INITIAL_SUSPEND_RETRY_INTERVAL_MS;
- int tryCount = 0;
+ long totalWaitDurationMs = 0;
while (true) {
Slog.i(TAG, "Entering Suspend to RAM");
@@ -1246,20 +1260,20 @@
if (suspendSucceeded) {
return true;
}
- tryCount++;
- if (tryCount >= MAX_SUSPEND_TRIES) {
+ if (totalWaitDurationMs >= mMaxSuspendWaitDurationMs) {
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.");
+ Slog.w(TAG, "Failed to Suspend; will retry after " + retryIntervalMs + "ms.");
try {
mLock.wait(retryIntervalMs);
} catch (InterruptedException ignored) {
Thread.currentThread().interrupt();
}
- retryIntervalMs *= 2;
+ totalWaitDurationMs += retryIntervalMs;
+ retryIntervalMs = Math.min(retryIntervalMs * 2, MAX_RETRY_INTERVAL_MS);
}
// Check for a new power state now, before going around the loop again
if (!mPendingPowerStates.isEmpty()) {
@@ -1269,7 +1283,8 @@
}
}
// Too many failures trying to suspend. Shut down.
- Slog.w(TAG, "Could not Suspend to RAM. Shutting down.");
+ Slog.w(TAG, "Could not Suspend to RAM after " + totalWaitDurationMs
+ + "ms long trial. Shutting down.");
mSystemInterface.shutdown();
return false;
}
@@ -1540,4 +1555,8 @@
}
Slog.i(TAG, "Exit Deep Sleep simulation");
}
+
+ private int getMaxSuspendWaitDurationConfig() {
+ return mContext.getResources().getInteger(R.integer.config_maxSuspendWaitDuration);
+ }
}