Change ErrorCode into an enum class.

This change is needed in order for us to be able to import ErrorCode
symbols from chromeos_update_engine into chromeos_update_manager.
Unfortunately, shifting from plain 'enum' into an 'enum class' means
that the compiler treats the new class as a distinct type from int,
which in turn means that plenty of seamless arithmetic/bitwise
operations we used for manipulating error code values throughout the
code needed to be retrofitted with static_cast operators.

In the future, we should consider imposing a proper abstraction on
update engine error codes that'll prevent mingling with value encoding
directly and prevent such nastiness. It'll also make things more
coherent (types, semantics) and safer.

BUG=chromium:358329
TEST=Unit tests.

Change-Id: Ie55fa566b764cdab6c4785d995fb6daee4cb32d3
Reviewed-on: https://chromium-review.googlesource.com/203209
Tested-by: Gilad Arnold <garnold@chromium.org>
Reviewed-by: Alex Deymo <deymo@chromium.org>
Commit-Queue: Gilad Arnold <garnold@chromium.org>
diff --git a/error_code.h b/error_code.h
index fc66ac9..5f3a2cb 100644
--- a/error_code.h
+++ b/error_code.h
@@ -5,56 +5,58 @@
 #ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_ERROR_CODE_H_
 #define CHROMEOS_PLATFORM_UPDATE_ENGINE_ERROR_CODE_H_
 
+#include <ostream>
+
 namespace chromeos_update_engine {
 
 // Action exit codes.
-enum ErrorCode {
-  kErrorCodeSuccess = 0,
-  kErrorCodeError = 1,
-  kErrorCodeOmahaRequestError = 2,
-  kErrorCodeOmahaResponseHandlerError = 3,
-  kErrorCodeFilesystemCopierError = 4,
-  kErrorCodePostinstallRunnerError = 5,
-  kErrorCodePayloadMismatchedType = 6,
-  kErrorCodeInstallDeviceOpenError = 7,
-  kErrorCodeKernelDeviceOpenError = 8,
-  kErrorCodeDownloadTransferError = 9,
-  kErrorCodePayloadHashMismatchError = 10,
-  kErrorCodePayloadSizeMismatchError = 11,
-  kErrorCodeDownloadPayloadVerificationError = 12,
-  kErrorCodeDownloadNewPartitionInfoError = 13,
-  kErrorCodeDownloadWriteError = 14,
-  kErrorCodeNewRootfsVerificationError = 15,
-  kErrorCodeNewKernelVerificationError = 16,
-  kErrorCodeSignedDeltaPayloadExpectedError = 17,
-  kErrorCodeDownloadPayloadPubKeyVerificationError = 18,
-  kErrorCodePostinstallBootedFromFirmwareB = 19,
-  kErrorCodeDownloadStateInitializationError = 20,
-  kErrorCodeDownloadInvalidMetadataMagicString = 21,
-  kErrorCodeDownloadSignatureMissingInManifest = 22,
-  kErrorCodeDownloadManifestParseError = 23,
-  kErrorCodeDownloadMetadataSignatureError = 24,
-  kErrorCodeDownloadMetadataSignatureVerificationError = 25,
-  kErrorCodeDownloadMetadataSignatureMismatch = 26,
-  kErrorCodeDownloadOperationHashVerificationError = 27,
-  kErrorCodeDownloadOperationExecutionError = 28,
-  kErrorCodeDownloadOperationHashMismatch = 29,
-  kErrorCodeOmahaRequestEmptyResponseError = 30,
-  kErrorCodeOmahaRequestXMLParseError = 31,
-  kErrorCodeDownloadInvalidMetadataSize = 32,
-  kErrorCodeDownloadInvalidMetadataSignature = 33,
-  kErrorCodeOmahaResponseInvalid = 34,
-  kErrorCodeOmahaUpdateIgnoredPerPolicy = 35,
-  kErrorCodeOmahaUpdateDeferredPerPolicy = 36,
-  kErrorCodeOmahaErrorInHTTPResponse = 37,
-  kErrorCodeDownloadOperationHashMissingError = 38,
-  kErrorCodeDownloadMetadataSignatureMissingError = 39,
-  kErrorCodeOmahaUpdateDeferredForBackoff = 40,
-  kErrorCodePostinstallPowerwashError = 41,
-  kErrorCodeUpdateCanceledByChannelChange = 42,
-  kErrorCodePostinstallFirmwareRONotUpdatable = 43,
-  kErrorCodeUnsupportedMajorPayloadVersion = 44,
-  kErrorCodeUnsupportedMinorPayloadVersion = 45,
+enum class ErrorCode : int {
+  kSuccess = 0,
+  kError = 1,
+  kOmahaRequestError = 2,
+  kOmahaResponseHandlerError = 3,
+  kFilesystemCopierError = 4,
+  kPostinstallRunnerError = 5,
+  kPayloadMismatchedType = 6,
+  kInstallDeviceOpenError = 7,
+  kKernelDeviceOpenError = 8,
+  kDownloadTransferError = 9,
+  kPayloadHashMismatchError = 10,
+  kPayloadSizeMismatchError = 11,
+  kDownloadPayloadVerificationError = 12,
+  kDownloadNewPartitionInfoError = 13,
+  kDownloadWriteError = 14,
+  kNewRootfsVerificationError = 15,
+  kNewKernelVerificationError = 16,
+  kSignedDeltaPayloadExpectedError = 17,
+  kDownloadPayloadPubKeyVerificationError = 18,
+  kPostinstallBootedFromFirmwareB = 19,
+  kDownloadStateInitializationError = 20,
+  kDownloadInvalidMetadataMagicString = 21,
+  kDownloadSignatureMissingInManifest = 22,
+  kDownloadManifestParseError = 23,
+  kDownloadMetadataSignatureError = 24,
+  kDownloadMetadataSignatureVerificationError = 25,
+  kDownloadMetadataSignatureMismatch = 26,
+  kDownloadOperationHashVerificationError = 27,
+  kDownloadOperationExecutionError = 28,
+  kDownloadOperationHashMismatch = 29,
+  kOmahaRequestEmptyResponseError = 30,
+  kOmahaRequestXMLParseError = 31,
+  kDownloadInvalidMetadataSize = 32,
+  kDownloadInvalidMetadataSignature = 33,
+  kOmahaResponseInvalid = 34,
+  kOmahaUpdateIgnoredPerPolicy = 35,
+  kOmahaUpdateDeferredPerPolicy = 36,
+  kOmahaErrorInHTTPResponse = 37,
+  kDownloadOperationHashMissingError = 38,
+  kDownloadMetadataSignatureMissingError = 39,
+  kOmahaUpdateDeferredForBackoff = 40,
+  kPostinstallPowerwashError = 41,
+  kUpdateCanceledByChannelChange = 42,
+  kPostinstallFirmwareRONotUpdatable = 43,
+  kUnsupportedMajorPayloadVersion = 44,
+  kUnsupportedMinorPayloadVersion = 45,
 
   // VERY IMPORTANT! When adding new error codes:
   //
@@ -64,10 +66,10 @@
   //    build until this case is added.
 
   // Any code above this is sent to both Omaha and UMA as-is, except
-  // kErrorCodeOmahaErrorInHTTPResponse (see error code 2000 for more details).
+  // kOmahaErrorInHTTPResponse (see error code 2000 for more details).
   // Codes/flags below this line is sent only to Omaha and not to UMA.
 
-  // kErrorCodeUmaReportedMax is not an error code per se, it's just the count
+  // kUmaReportedMax is not an error code per se, it's just the count
   // of the number of enums above.  Add any new errors above this line if you
   // want them to show up on UMA. Stuff below this line will not be sent to UMA
   // but is used for other errors that are sent to Omaha. We don't assign any
@@ -75,38 +77,45 @@
   // one above and thus always represents the correct count of UMA metrics
   // buckets, even when new enums are added above this line in future. See
   // utils::SendErrorCodeToUma on how this enum is used.
-  kErrorCodeUmaReportedMax,
+  kUmaReportedMax,
 
   // use the 2xxx range to encode HTTP errors. These errors are available in
   // Dremel with the individual granularity. But for UMA purposes, all these
-  // errors are aggregated into one: kErrorCodeOmahaErrorInHTTPResponse.
-  kErrorCodeOmahaRequestHTTPResponseBase = 2000,  // + HTTP response code
+  // errors are aggregated into one: kOmahaErrorInHTTPResponse.
+  kOmahaRequestHTTPResponseBase = 2000,  // + HTTP response code
 
   // TODO(jaysri): Move out all the bit masks into separate constants
   // outside the enum as part of fixing bug 34369.
   // Bit flags. Remember to update the mask below for new bits.
 
   // Set if boot mode not normal.
-  kErrorCodeDevModeFlag        = 1 << 31,
+  // TODO(garnold) This is very debatable value to use, knowing that the
+  // underlying type is a signed int (often, 32-bit). However, at this point
+  // there are parts of the ecosystem that expect this to be a negative value,
+  // so we preserve this semantics. This should be reconsidered if/when we
+  // modify the implementation of ErrorCode into a properly encapsulated class.
+  kDevModeFlag = 1 << 31,
 
   // Set if resuming an interruped update.
-  kErrorCodeResumedFlag         = 1 << 30,
+  kResumedFlag = 1 << 30,
 
   // Set if using a dev/test image as opposed to an MP-signed image.
-  kErrorCodeTestImageFlag       = 1 << 29,
+  kTestImageFlag = 1 << 29,
 
   // Set if using devserver or Omaha sandbox (using crosh autest).
-  kErrorCodeTestOmahaUrlFlag    = 1 << 28,
+  kTestOmahaUrlFlag = 1 << 28,
 
   // Mask that indicates bit positions that are used to indicate special flags
   // that are embedded in the error code to provide additional context about
   // the system in which the error was encountered.
-  kErrorCodeSpecialFlags = (kErrorCodeDevModeFlag |
-                            kErrorCodeResumedFlag |
-                            kErrorCodeTestImageFlag |
-                            kErrorCodeTestOmahaUrlFlag)
+  kSpecialFlags = (kDevModeFlag | kResumedFlag | kTestImageFlag |
+                   kTestOmahaUrlFlag)
 };
 
+inline std::ostream& operator<<(std::ostream& os, ErrorCode val) {
+  return os << static_cast<int>(val);
+}
+
 }  // namespace chromeos_update_engine
 
 #endif  // CHROMEOS_PLATFORM_UPDATE_ENGINE_ERROR_CODE_H_