Expand identifier to handle Exception -> FailureDescription conversion

In some cases, our HarnessException will need to become
a FailureDescription, we need the FailureStatus in those
cases to carry the type.

Test: unit tests
Bug: 159457859
Change-Id: I0d175650251275702e1d9cc13d93b6ddcc4ae669
diff --git a/src/com/android/tradefed/targetprep/BuildError.java b/device_build_interfaces/com/android/tradefed/targetprep/BuildError.java
similarity index 63%
rename from src/com/android/tradefed/targetprep/BuildError.java
rename to device_build_interfaces/com/android/tradefed/targetprep/BuildError.java
index 309ae5c..0d2ea14 100644
--- a/src/com/android/tradefed/targetprep/BuildError.java
+++ b/device_build_interfaces/com/android/tradefed/targetprep/BuildError.java
@@ -16,11 +16,11 @@
 package com.android.tradefed.targetprep;
 
 import com.android.tradefed.command.remote.DeviceDescriptor;
+import com.android.tradefed.error.HarnessException;
+import com.android.tradefed.result.error.ErrorIdentifier;
 
-/**
- * Thrown if the provided build fails to run.
- */
-public class BuildError extends Exception {
+/** Thrown if the provided build fails to run. */
+public class BuildError extends HarnessException {
 
     private static final long serialVersionUID = 2202987086655357201L;
     private String mDeviceSerial = null;
@@ -30,9 +30,11 @@
      *
      * @param reason an error message giving more details on the build error
      * @param descriptor the descriptor of the device concerned
+     * @deprecated use {@link #BuildError(String, DeviceDescriptor, ErrorIdentifier)} instead.
      */
+    @Deprecated
     public BuildError(String reason, DeviceDescriptor descriptor) {
-        super(reason + " " + descriptor);
+        super(reason + " " + descriptor, null);
         if (descriptor != null) {
             mDeviceSerial = descriptor.getSerial();
         }
@@ -42,11 +44,25 @@
      * Constructs a new (@link BuildError} with a detailed error message.
      *
      * @param reason an error message giving more details on the build error
-     * @deprecated use {@link #BuildError(String, DeviceDescriptor)} instead.
+     * @param descriptor the descriptor of the device concerned
+     * @param errorId the error identifier for this error.
+     */
+    public BuildError(String reason, DeviceDescriptor descriptor, ErrorIdentifier errorId) {
+        super(reason + " " + descriptor, errorId);
+        if (descriptor != null) {
+            mDeviceSerial = descriptor.getSerial();
+        }
+    }
+
+    /**
+     * Constructs a new (@link BuildError} with a detailed error message.
+     *
+     * @param reason an error message giving more details on the build error
+     * @deprecated use {@link #BuildError(String, DeviceDescriptor, ErrorIdentifier)} instead.
      */
     @Deprecated
     public BuildError(String reason) {
-        super(reason);
+        super(reason, null);
     }
 
     /** Return the serial of the device impacted by the BuildError. */
diff --git a/src/com/android/tradefed/build/BuildRetrievalError.java b/src/com/android/tradefed/build/BuildRetrievalError.java
index 5343047..56e6921 100644
--- a/src/com/android/tradefed/build/BuildRetrievalError.java
+++ b/src/com/android/tradefed/build/BuildRetrievalError.java
@@ -30,7 +30,7 @@
      * @param reason a error message describing the cause of the error
      */
     public BuildRetrievalError(String reason) {
-        super(reason, null);
+        this(reason, null, null, null);
     }
 
     /**
@@ -40,7 +40,7 @@
      * @param errorId the error identifier for this error.
      */
     public BuildRetrievalError(String reason, ErrorIdentifier errorId) {
-        super(reason, errorId);
+        this(reason, null, errorId, null);
     }
 
     /**
@@ -51,7 +51,7 @@
      * @param cause a {@link Throwable} capturing the original cause of the ProvideBuildError
      */
     public BuildRetrievalError(String reason, Throwable cause) {
-        super(reason, cause, null);
+        this(reason, cause, null, null);
     }
 
     /**
@@ -62,7 +62,7 @@
      * @param errorId the error identifier for this error.
      */
     public BuildRetrievalError(String reason, Throwable cause, ErrorIdentifier errorId) {
-        super(reason, cause, errorId);
+        this(reason, cause, errorId, null);
     }
 
     /**
@@ -74,8 +74,24 @@
      * @param build details about the build that was attempted to be retrieved
      */
     public BuildRetrievalError(String reason, Throwable cause, IBuildInfo build) {
-        super(reason, cause, null);
-        mBuildInfo = build;
+        this(reason, cause, null, build);
+    }
+
+    /**
+     * Constructs a new {@link BuildRetrievalError} with a meaningful error message, a cause, and
+     * build details.
+     *
+     * @param reason a detailed error message.
+     * @param cause a {@link Throwable} capturing the original cause of the ProvideBuildError
+     * @param errorId the error identifier for this error.
+     * @param build details about the build that was attempted to be retrieved
+     */
+    public BuildRetrievalError(
+            String reason, Throwable cause, ErrorIdentifier errorId, IBuildInfo build) {
+        super(reason, cause, errorId);
+        if (build != null) {
+            mBuildInfo = build;
+        }
     }
 
     /**
diff --git a/src/com/android/tradefed/result/proto/ProtoResultParser.java b/src/com/android/tradefed/result/proto/ProtoResultParser.java
index 46d6cfc..a481cc9 100644
--- a/src/com/android/tradefed/result/proto/ProtoResultParser.java
+++ b/src/com/android/tradefed/result/proto/ProtoResultParser.java
@@ -670,6 +670,11 @@
                         public long code() {
                             return errorCode;
                         }
+
+                        @Override
+                        public FailureStatus status() {
+                            return failure.getFailureStatus();
+                        }
                     };
             failure.setErrorIdentifier(errorId);
         }
diff --git a/src/com/android/tradefed/targetprep/DeviceFailedToBootError.java b/src/com/android/tradefed/targetprep/DeviceFailedToBootError.java
index 9afa172..45cfbc6 100644
--- a/src/com/android/tradefed/targetprep/DeviceFailedToBootError.java
+++ b/src/com/android/tradefed/targetprep/DeviceFailedToBootError.java
@@ -16,6 +16,7 @@
 package com.android.tradefed.targetprep;
 
 import com.android.tradefed.command.remote.DeviceDescriptor;
+import com.android.tradefed.result.error.ErrorIdentifier;
 
 /**
  * Thrown if a device fails to boot after being flashed with a build.
@@ -32,4 +33,15 @@
     public DeviceFailedToBootError(String reason, DeviceDescriptor descriptor) {
         super(reason, descriptor);
     }
+
+    /**
+     * Constructs a new (@link DeviceFailedToBootError} with a detailed error message.
+     *
+     * @param reason an error message giving more details about the boot failure
+     * @param descriptor the descriptor of the device concerned by the exception
+     */
+    public DeviceFailedToBootError(
+            String reason, DeviceDescriptor descriptor, ErrorIdentifier errorId) {
+        super(reason, descriptor, errorId);
+    }
 }
diff --git a/test_result_interfaces/com/android/tradefed/result/error/ErrorIdentifier.java b/test_result_interfaces/com/android/tradefed/result/error/ErrorIdentifier.java
index 3dea54d..54a01aa 100644
--- a/test_result_interfaces/com/android/tradefed/result/error/ErrorIdentifier.java
+++ b/test_result_interfaces/com/android/tradefed/result/error/ErrorIdentifier.java
@@ -15,6 +15,9 @@
  */
 package com.android.tradefed.result.error;
 
+import com.android.tradefed.result.FailureDescription;
+import com.android.tradefed.result.proto.TestRecordProto.FailureStatus;
+
 /** This interface describes a specific error and its properties. */
 public interface ErrorIdentifier {
 
@@ -23,4 +26,10 @@
 
     /** The unique code identifying the error. */
     public long code();
+
+    /**
+     * The failure status associated with the identifier, this status is expected to align with the
+     * {@link FailureDescription} one.
+     */
+    public FailureStatus status();
 }
diff --git a/test_result_interfaces/com/android/tradefed/result/error/InfraErrorIdentifier.java b/test_result_interfaces/com/android/tradefed/result/error/InfraErrorIdentifier.java
index 6d6dc3e..1f13121 100644
--- a/test_result_interfaces/com/android/tradefed/result/error/InfraErrorIdentifier.java
+++ b/test_result_interfaces/com/android/tradefed/result/error/InfraErrorIdentifier.java
@@ -15,6 +15,8 @@
  */
 package com.android.tradefed.result.error;
 
+import com.android.tradefed.result.proto.TestRecordProto.FailureStatus;
+
 /** Error Identifiers from Trade Federation infra, and dependent infra (like Build infra). */
 public enum InfraErrorIdentifier implements ErrorIdentifier {
 
@@ -22,24 +24,31 @@
     // Infra: 10_001 ~ 20_000
     // ********************************************************************************************
     // 10_001 - 10_500: General errors
-    ARTIFACT_NOT_FOUND(10_001),
-    FAIL_TO_CREATE_FILE(10_002),
+    ARTIFACT_NOT_FOUND(10_001, FailureStatus.INFRA_FAILURE),
+    FAIL_TO_CREATE_FILE(10_002, FailureStatus.INFRA_FAILURE),
 
     // 10_501 - 11_000: Build, Artifacts download related errors
-    ARTIFACT_REMOTE_PATH_NULL(10_501),
-    ARTIFACT_UNSUPPORTED_PATH(10_502),
-    ARTIFACT_DOWNLOAD_ERROR(10_503),
+    ARTIFACT_REMOTE_PATH_NULL(10_501, FailureStatus.INFRA_FAILURE),
+    ARTIFACT_UNSUPPORTED_PATH(10_502, FailureStatus.INFRA_FAILURE),
+    ARTIFACT_DOWNLOAD_ERROR(10_503, FailureStatus.INFRA_FAILURE),
 
-    UNDETERMINED(20_000);
+    UNDETERMINED(20_000, FailureStatus.UNSET);
 
     private final long code;
+    private final FailureStatus status;
 
-    InfraErrorIdentifier(int code) {
+    InfraErrorIdentifier(int code, FailureStatus status) {
         this.code = code;
+        this.status = status;
     }
 
     @Override
     public long code() {
         return code;
     }
+
+    @Override
+    public FailureStatus status() {
+        return status;
+    }
 }