diff --git a/src/java/com/google/devtools/deviceinfra/ext/devicemanagement/device/platform/android/realdevice/AndroidRealDeviceDelegate.java b/src/java/com/google/devtools/deviceinfra/ext/devicemanagement/device/platform/android/realdevice/AndroidRealDeviceDelegate.java index f0a423f39..48248866f 100644 --- a/src/java/com/google/devtools/deviceinfra/ext/devicemanagement/device/platform/android/realdevice/AndroidRealDeviceDelegate.java +++ b/src/java/com/google/devtools/deviceinfra/ext/devicemanagement/device/platform/android/realdevice/AndroidRealDeviceDelegate.java @@ -113,6 +113,10 @@ public abstract class AndroidRealDeviceDelegate { private static final FluentLogger logger = FluentLogger.forEnclosingClass(); + // The property written to the device before resetting. The value of this property will be checked + // to confirm whether the device was reset successfully. + private static final String RESET_PROPERTY_LABEL = "debug.mobileharness.before_reset"; + /** Last time record for checkPingGoogle method in order to call it every 30 minutes. */ private Instant lastCheckPingGoogleTime = null; @@ -454,6 +458,10 @@ private void resetDevice() throws MobileHarnessException, InterruptedException { boolean isOverTcpDevice = DeviceUtil.isOverTcpDevice(deviceId); cacheDevice(deviceId, AndroidRealDeviceConstants.WAIT_FOR_REBOOT_TIMEOUT); + + // Set the property to the device. Will check the value of this property after resetting to + // ensure the reset is successful. + androidAdbUtil.setProperty(deviceId, RESET_PROPERTY_LABEL, "true", /* ignoreError= */ false); try { logger.atInfo().log("Start to factory reset device %s via test harness", deviceId); systemStateUtil.factoryResetViaTestHarness(deviceId, /* waitTime= */ null); @@ -476,6 +484,20 @@ private void resetDevice() throws MobileHarnessException, InterruptedException { } finally { invalidateCacheDevice(deviceId); } + + try { + if (!Strings.isNullOrEmpty( + androidAdbUtil.getProperty(deviceId, ImmutableList.of(RESET_PROPERTY_LABEL)))) { + throw new MobileHarnessException( + AndroidErrorId.ANDROID_REAL_DEVICE_DELEGATE_RESET_DEVICE_FAILED, + String.format( + "The property %s is not deleted after resetting on device %s, which means the" + + " device is not reset successfully.", + RESET_PROPERTY_LABEL, deviceId)); + } + } finally { + androidAdbUtil.setProperty(deviceId, RESET_PROPERTY_LABEL, "", /* ignoreError= */ true); + } logger.atInfo().log("Device %s reset is done", deviceId); } diff --git a/src/java/com/google/devtools/mobileharness/api/model/error/AndroidErrorId.java b/src/java/com/google/devtools/mobileharness/api/model/error/AndroidErrorId.java index 353e26dce..1dd9b29e3 100644 --- a/src/java/com/google/devtools/mobileharness/api/model/error/AndroidErrorId.java +++ b/src/java/com/google/devtools/mobileharness/api/model/error/AndroidErrorId.java @@ -402,6 +402,7 @@ public enum AndroidErrorId implements ErrorId { ANDROID_REAL_DEVICE_DELEGATE_RECOVERY_DEVICE_TO_REBOOT(111_201, ErrorType.INFRA_ISSUE), ANDROID_REAL_DEVICE_DELEGATE_FASTBOOT_DEVICE_TO_REBOOT(111_202, ErrorType.INFRA_ISSUE), ANDROID_REAL_DEVICE_DELEGATE_UNDETECTED_DURING_INIT(111_203, ErrorType.INFRA_ISSUE), + ANDROID_REAL_DEVICE_DELEGATE_RESET_DEVICE_FAILED(111_204, ErrorType.INFRA_ISSUE), /** Android Drivers: 115_001 ~ 125_000 */ // Android Instrumentation: 115_001 ~ 115_500