summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Sarp Misoglu <sarpm@google.com> 2024-12-19 22:06:38 +0000
committer Sarp Misoglu <sarpm@google.com> 2024-12-23 16:54:10 +0000
commitbb80de0b84e607a07be352f0820fdd179432b808 (patch)
treeeb50389ed193e4b9db897a509a5bc5aec45cea55
parent75929fcf5b46c310035a080709a612fb80273516 (diff)
Acquire the backup wakelock with a timeout
There have been a few reports of the backup service failing to call release() on the wakelock and draining battery for hours. These are rare failures and hard to debug individually but with the timeout we will limit the worst case significantly. I am setting the default timeout to 30 minutes. This should be more than enough time for a backup or restore operation. If in the future these operation get longer, the timeout is configurable by a setting. Test: atest CtsBackupTestCases Fixes: 364931501 Fixes: 357769443 Fixes: 289789401 Flag: EXEMPT bugfix Change-Id: Iaac0218d5258031b6f67c3c56c776ce098e8a8c4
-rw-r--r--services/backup/java/com/android/server/backup/BackupManagerConstants.java14
-rw-r--r--services/backup/java/com/android/server/backup/UserBackupManagerService.java17
-rw-r--r--services/robotests/backup/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java7
3 files changed, 28 insertions, 10 deletions
diff --git a/services/backup/java/com/android/server/backup/BackupManagerConstants.java b/services/backup/java/com/android/server/backup/BackupManagerConstants.java
index 4bd987a17447..b753d01562ca 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerConstants.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerConstants.java
@@ -72,6 +72,9 @@ public class BackupManagerConstants extends KeyValueSettingObserver {
public static final String BACKUP_FINISHED_NOTIFICATION_RECEIVERS =
"backup_finished_notification_receivers";
+ @VisibleForTesting
+ public static final String WAKELOCK_TIMEOUT_MILLIS = "wakelock_timeout_millis";
+
// Hard coded default values.
@VisibleForTesting
public static final long DEFAULT_KEY_VALUE_BACKUP_INTERVAL_MILLISECONDS =
@@ -97,6 +100,9 @@ public class BackupManagerConstants extends KeyValueSettingObserver {
@VisibleForTesting
public static final String DEFAULT_BACKUP_FINISHED_NOTIFICATION_RECEIVERS = "";
+ @VisibleForTesting
+ public static final long DEFAULT_WAKELOCK_TIMEOUT_MILLIS = 30 * 60 * 1000; // 30 minutes
+
// Backup manager constants.
private long mKeyValueBackupIntervalMilliseconds;
private long mKeyValueBackupFuzzMilliseconds;
@@ -106,6 +112,7 @@ public class BackupManagerConstants extends KeyValueSettingObserver {
private boolean mFullBackupRequireCharging;
private int mFullBackupRequiredNetworkType;
private String[] mBackupFinishedNotificationReceivers;
+ private long mWakelockTimeoutMillis;
public BackupManagerConstants(Handler handler, ContentResolver resolver) {
super(handler, resolver, Settings.Secure.getUriFor(SETTING));
@@ -152,6 +159,8 @@ public class BackupManagerConstants extends KeyValueSettingObserver {
} else {
mBackupFinishedNotificationReceivers = backupFinishedNotificationReceivers.split(":");
}
+ mWakelockTimeoutMillis = parser.getLong(WAKELOCK_TIMEOUT_MILLIS,
+ DEFAULT_WAKELOCK_TIMEOUT_MILLIS);
}
// The following are access methods for the individual parameters.
@@ -235,4 +244,9 @@ public class BackupManagerConstants extends KeyValueSettingObserver {
}
return mBackupFinishedNotificationReceivers;
}
+
+ public synchronized long getWakelockTimeoutMillis() {
+ Slog.v(TAG, "wakelock timeout: " + mWakelockTimeoutMillis);
+ return mWakelockTimeoutMillis;
+ }
}
diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerService.java b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
index 549f8fa77b53..ac1f50f85d64 100644
--- a/services/backup/java/com/android/server/backup/UserBackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
@@ -181,11 +181,14 @@ public class UserBackupManagerService {
public static class BackupWakeLock {
private final PowerManager.WakeLock mPowerManagerWakeLock;
private boolean mHasQuit = false;
- private int mUserId;
+ private final int mUserId;
+ private final BackupManagerConstants mBackupManagerConstants;
- public BackupWakeLock(PowerManager.WakeLock powerManagerWakeLock, int userId) {
+ public BackupWakeLock(PowerManager.WakeLock powerManagerWakeLock, int userId,
+ BackupManagerConstants backupManagerConstants) {
mPowerManagerWakeLock = powerManagerWakeLock;
mUserId = userId;
+ mBackupManagerConstants = backupManagerConstants;
}
/** Acquires the {@link PowerManager.WakeLock} if hasn't been quit. */
@@ -199,7 +202,9 @@ public class UserBackupManagerService {
+ mPowerManagerWakeLock.getTag()));
return;
}
- mPowerManagerWakeLock.acquire();
+ // Set a timeout for the wakelock. Otherwise if we fail internally and never call
+ // release(), the device might stay awake and drain battery indefinitely.
+ mPowerManagerWakeLock.acquire(mBackupManagerConstants.getWakelockTimeoutMillis());
Slog.v(
TAG,
addUserIdToLogMessage(
@@ -674,10 +679,8 @@ public class UserBackupManagerService {
mBackupPreferences = new UserBackupPreferences(mContext, mBaseStateDir);
// Power management
- mWakelock = new BackupWakeLock(
- mPowerManager.newWakeLock(
- PowerManager.PARTIAL_WAKE_LOCK,
- "*backup*-" + userId + "-" + userBackupThread.getThreadId()), userId);
+ mWakelock = new BackupWakeLock(mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
+ "*backup*-" + userId + "-" + userBackupThread.getThreadId()), userId, mConstants);
// Set up the various sorts of package tracking we do
mFullBackupScheduleFile = new File(mBaseStateDir, "fb-schedule");
diff --git a/services/robotests/backup/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java b/services/robotests/backup/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java
index fc3ec7b44f4f..4d04c8b76fc7 100644
--- a/services/robotests/backup/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java
+++ b/services/robotests/backup/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java
@@ -37,6 +37,7 @@ import android.os.Process;
import android.util.Log;
import com.android.server.backup.BackupAgentTimeoutParameters;
+import com.android.server.backup.BackupManagerConstants;
import com.android.server.backup.BackupManagerService;
import com.android.server.backup.TransportManager;
import com.android.server.backup.UserBackupManagerService;
@@ -162,10 +163,10 @@ public class BackupManagerServiceTestUtils {
public static UserBackupManagerService.BackupWakeLock createBackupWakeLock(
Application application) {
- PowerManager powerManager =
- (PowerManager) application.getSystemService(Context.POWER_SERVICE);
+ PowerManager powerManager = application.getSystemService(PowerManager.class);
return new UserBackupManagerService.BackupWakeLock(
- powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*backup*"), 0);
+ powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*backup*"), 0,
+ new BackupManagerConstants(Handler.getMain(), application.getContentResolver()));
}
/**