Reschedule works or alarms if needed when device boot
Test: atest DeviceLockControllerRoboTests
Bug: 288937639
Change-Id: I30a60501913ea2f043e93efcb03741a5cb6ca140
(cherry picked from commit adfa5aff29f084a07014228595a201f9729d7317)
diff --git a/DeviceLockController/src/com/android/devicelockcontroller/AbstractDeviceLockControllerScheduler.java b/DeviceLockController/src/com/android/devicelockcontroller/AbstractDeviceLockControllerScheduler.java
index 70c3509..8a0ce85 100644
--- a/DeviceLockController/src/com/android/devicelockcontroller/AbstractDeviceLockControllerScheduler.java
+++ b/DeviceLockController/src/com/android/devicelockcontroller/AbstractDeviceLockControllerScheduler.java
@@ -30,16 +30,16 @@
public abstract void correctExpectedToRunTime(Duration delta);
/**
+ * Reschedule any works / alarms that were scheduled previously but got pushed back or canceled.
+ */
+ public abstract void rescheduleIfNeeded();
+
+ /**
* Schedule an alarm to resume the provision flow.
*/
public abstract void scheduleResumeProvisionAlarm();
/**
- * Reschedule the alarm to resume provision based on the stored expected to run time.
- */
- public abstract void rescheduleResumeProvisionAlarm();
-
- /**
* Schedule the initial check-in work when device first boot.
*/
public abstract void scheduleInitialCheckInWork();
@@ -52,27 +52,12 @@
public abstract void scheduleRetryCheckInWork(Duration delay);
/**
- * Reschedule retry check-in work based on the stored expected to run time.
- */
- public abstract void rescheduleRetryCheckInWork();
-
- /**
* Schedule an alarm to perform next provision failed step with the default delay.
*/
public abstract void scheduleNextProvisionFailedStepAlarm();
/**
- * Reschedule the alarm to perform next provision failed step based on the stored time.
- */
- public abstract void rescheduleNextProvisionFailedStepAlarm();
-
- /**
* Schedule an alarm to factory reset the device in case of provision is failed.
*/
public abstract void scheduleResetDeviceAlarm();
-
- /**
- * Reschedule the alarm to factory reset device based on stored timestamp.
- */
- public abstract void rescheduleResetDeviceAlarm();
}
diff --git a/DeviceLockController/src/com/android/devicelockcontroller/DeviceLockControllerScheduler.java b/DeviceLockController/src/com/android/devicelockcontroller/DeviceLockControllerScheduler.java
index 6c98247..fc97a66 100644
--- a/DeviceLockController/src/com/android/devicelockcontroller/DeviceLockControllerScheduler.java
+++ b/DeviceLockController/src/com/android/devicelockcontroller/DeviceLockControllerScheduler.java
@@ -16,6 +16,7 @@
package com.android.devicelockcontroller;
+import static com.android.devicelockcontroller.policy.DeviceStateController.DeviceState.PROVISION_FAILED;
import static com.android.devicelockcontroller.policy.DeviceStateController.DeviceState.PROVISION_PAUSED;
import static com.android.devicelockcontroller.policy.DeviceStateController.DeviceState.UNPROVISIONED;
import static com.android.devicelockcontroller.storage.GlobalParametersClient.getInstance;
@@ -123,6 +124,30 @@
}
@Override
+ public void rescheduleIfNeeded() {
+ DeviceStateController stateController =
+ ((PolicyObjectsInterface) mContext.getApplicationContext()).getStateController();
+
+ switch (stateController.getState()) {
+ case UNPROVISIONED:
+ rescheduleRetryCheckInWork();
+ break;
+ case PROVISION_PAUSED:
+ rescheduleResumeProvisionAlarm();
+ break;
+ case PROVISION_FAILED:
+ rescheduleNextProvisionFailedStepAlarm();
+ // Reset device is the last step in provision failed flow. We call this API
+ // regardless, because the alarm will only be rescheduled if it has been
+ // scheduled previously.
+ rescheduleResetDeviceAlarm();
+ break;
+ default:
+ // no-op for other states.
+ }
+ }
+
+ @Override
public void scheduleResumeProvisionAlarm() {
Duration delay = Duration.ofMinutes(PROVISION_PAUSED_MINUTES_DEFAULT);
if (Build.isDebuggable()) {
@@ -148,13 +173,14 @@
}, MoreExecutors.directExecutor());
}
- @Override
- public void rescheduleResumeProvisionAlarm() {
+ @VisibleForTesting
+ void rescheduleResumeProvisionAlarm() {
Futures.addCallback(
getInstance().getResumeProvisionTimeMillis(),
new FutureCallback<>() {
@Override
public void onSuccess(Long resumeProvisionTimeMillis) {
+ if (resumeProvisionTimeMillis <= 0) return;
Duration delay = Duration.between(
Instant.now(mClock),
Instant.ofEpochMilli(resumeProvisionTimeMillis));
@@ -198,13 +224,14 @@
}, MoreExecutors.directExecutor());
}
- @Override
- public void rescheduleRetryCheckInWork() {
+ @VisibleForTesting
+ void rescheduleRetryCheckInWork() {
Futures.addCallback(
getInstance().getNextCheckInTimeMillis(),
new FutureCallback<>() {
@Override
public void onSuccess(Long nextCheckInTimeMillis) {
+ if (nextCheckInTimeMillis <= 0) return;
Duration delay = Duration.between(
Instant.now(mClock),
Instant.ofEpochMilli(nextCheckInTimeMillis));
@@ -247,12 +274,13 @@
}, MoreExecutors.directExecutor());
}
- @Override
- public void rescheduleNextProvisionFailedStepAlarm() {
+ @VisibleForTesting
+ void rescheduleNextProvisionFailedStepAlarm() {
Futures.addCallback(getInstance().getNextProvisionFailedStepTimeMills(),
new FutureCallback<>() {
@Override
public void onSuccess(Long timestamp) {
+ if (timestamp <= 0) return;
Duration delay = Duration.between(
Instant.now(mClock),
Instant.ofEpochMilli(timestamp));
@@ -297,12 +325,13 @@
}, MoreExecutors.directExecutor());
}
- @Override
- public void rescheduleResetDeviceAlarm() {
+ @VisibleForTesting
+ void rescheduleResetDeviceAlarm() {
Futures.addCallback(getInstance().getResetDeviceTimeMillis(),
new FutureCallback<>() {
@Override
public void onSuccess(Long timestamp) {
+ if (timestamp <= 0) return;
Duration delay = Duration.between(
Instant.now(mClock),
Instant.ofEpochMilli(timestamp));
diff --git a/DeviceLockController/src/com/android/devicelockcontroller/debug/DeviceLockCommandReceiver.java b/DeviceLockController/src/com/android/devicelockcontroller/debug/DeviceLockCommandReceiver.java
index 95d51a8..49dce60 100644
--- a/DeviceLockController/src/com/android/devicelockcontroller/debug/DeviceLockCommandReceiver.java
+++ b/DeviceLockController/src/com/android/devicelockcontroller/debug/DeviceLockCommandReceiver.java
@@ -204,7 +204,10 @@
AlarmManager alarmManager = Objects.requireNonNull(
context.getSystemService(AlarmManager.class));
alarmManager.cancel(
- ResetDeviceReceiver.getResetDevicePendingIntent(context));
+ PendingIntent.getBroadcast(
+ context, /* ignored */ 0,
+ new Intent(context, ResetDeviceReceiver.class),
+ PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE));
alarmManager.cancel(PendingIntent.getBroadcast(
context, /* ignored */ 0,
new Intent(context, NextProvisionFailedStepReceiver.class),
diff --git a/DeviceLockController/src/com/android/devicelockcontroller/provision/worker/PauseProvisioningWorker.java b/DeviceLockController/src/com/android/devicelockcontroller/provision/worker/PauseProvisioningWorker.java
index 011fc09..9e3f697 100644
--- a/DeviceLockController/src/com/android/devicelockcontroller/provision/worker/PauseProvisioningWorker.java
+++ b/DeviceLockController/src/com/android/devicelockcontroller/provision/worker/PauseProvisioningWorker.java
@@ -41,7 +41,8 @@
import com.google.common.util.concurrent.MoreExecutors;
/**
- * A worker class dedicated to request pause of provisioning for device lock program.
+ * Despite the naming, this worker class is only to report provision has been paused by user to
+ * backend server.
*/
public final class PauseProvisioningWorker extends AbstractCheckInWorker {
private static final String KEY_PAUSE_DEVICE_PROVISIONING_REASON =
diff --git a/DeviceLockController/src/com/android/devicelockcontroller/receivers/ResetDeviceReceiver.java b/DeviceLockController/src/com/android/devicelockcontroller/receivers/ResetDeviceReceiver.java
index d1b4394..de8c3e6 100644
--- a/DeviceLockController/src/com/android/devicelockcontroller/receivers/ResetDeviceReceiver.java
+++ b/DeviceLockController/src/com/android/devicelockcontroller/receivers/ResetDeviceReceiver.java
@@ -16,7 +16,6 @@
package com.android.devicelockcontroller.receivers;
-import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -28,16 +27,6 @@
*/
public final class ResetDeviceReceiver extends BroadcastReceiver {
- /**
- * Get a {@link PendingIntent} for resetting the device.
- */
- public static PendingIntent getResetDevicePendingIntent(Context context) {
- return PendingIntent.getBroadcast(
- context, /* ignored */ 0,
- new Intent(context, ResetDeviceReceiver.class),
- PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE);
- }
-
@Override
public void onReceive(Context context, Intent intent) {
if (!ResetDeviceReceiver.class.getName().equals(intent.getComponent().getClassName())) {
diff --git a/DeviceLockController/src/com/android/devicelockcontroller/receivers/SingleUserBootCompletedReceiver.java b/DeviceLockController/src/com/android/devicelockcontroller/receivers/SingleUserBootCompletedReceiver.java
index e529562..9fd8dda 100644
--- a/DeviceLockController/src/com/android/devicelockcontroller/receivers/SingleUserBootCompletedReceiver.java
+++ b/DeviceLockController/src/com/android/devicelockcontroller/receivers/SingleUserBootCompletedReceiver.java
@@ -78,8 +78,10 @@
return;
}
+ DeviceLockControllerScheduler scheduler = new DeviceLockControllerScheduler(context);
checkInIfNeeded(
((PolicyObjectsInterface) context.getApplicationContext()).getStateController(),
- new DeviceLockControllerScheduler(context));
+ scheduler);
+ scheduler.rescheduleIfNeeded();
}
}