Replacing Brillo Error

Creating our own error struct to remove libchrome dependancy. This also
allows us to propogate the error up and send more useful error messages

Test: m update_engine
Change-Id: I1bb651d9b7e759c9f902590685c1910b97c4ab5d
diff --git a/aosp/update_attempter_android.cc b/aosp/update_attempter_android.cc
index 6134885..2e0232b 100644
--- a/aosp/update_attempter_android.cc
+++ b/aosp/update_attempter_android.cc
@@ -81,18 +81,32 @@
 const double kBroadcastThresholdProgress = 0.01;  // 1%
 const int kBroadcastThresholdSeconds = 10;
 
-const char* const kErrorDomain = "update_engine";
-// TODO(deymo): Convert the different errors to a numeric value to report them
-// back on the service error.
-const char* const kGenericError = "generic_error";
+// Log and set the error on the passed ErrorPtr.
+bool LogAndSetGenericError(Error* error,
+                           int line_number,
+                           const char* file_name,
+                           const string& reason) {
+  LOG(ERROR) << "Replying with failure: " << file_name << " " << line_number
+             << ": " << reason;
+  error->line_number = line_number;
+  error->file_name = file_name;
+  error->message = reason;
+  error->error_code = ErrorCode::kError;
+  return false;
+}
 
 // Log and set the error on the passed ErrorPtr.
-bool LogAndSetError(brillo::ErrorPtr* error,
-                    const base::Location& location,
-                    const string& reason) {
-  brillo::Error::AddTo(error, location, kErrorDomain, kGenericError, reason);
-  LOG(ERROR) << "Replying with failure: " << location.ToString() << ": "
-             << reason;
+bool LogAndSetError(Error* error,
+                    int line_number,
+                    const char* file_name,
+                    const string& reason,
+                    ErrorCode error_code) {
+  LOG(ERROR) << "Replying with failure: " << file_name << " " << line_number
+             << ": " << reason;
+  error->line_number = line_number;
+  error->file_name = file_name;
+  error->message = reason;
+  error->error_code = error_code;
   return false;
 }
 
@@ -105,17 +119,20 @@
 
 bool ParseKeyValuePairHeaders(const vector<string>& key_value_pair_headers,
                               std::map<string, string>* headers,
-                              brillo::ErrorPtr* error) {
+                              Error* error) {
   for (const string& key_value_pair : key_value_pair_headers) {
     string key;
     string value;
     if (!brillo::string_utils::SplitAtFirst(
             key_value_pair, "=", &key, &value, false)) {
-      return LogAndSetError(
-          error, FROM_HERE, "Passed invalid header: " + key_value_pair);
+      return LogAndSetGenericError(error,
+                                   __LINE__,
+                                   __FILE__,
+                                   "Passed invalid header: " + key_value_pair);
     }
     if (!headers->emplace(key, value).second)
-      return LogAndSetError(error, FROM_HERE, "Passed repeated key: " + key);
+      return LogAndSetGenericError(
+          error, __LINE__, __FILE__, "Passed repeated key: " + key);
   }
   return true;
 }
@@ -217,14 +234,20 @@
     int64_t payload_offset,
     int64_t payload_size,
     const vector<string>& key_value_pair_headers,
-    brillo::ErrorPtr* error) {
+    Error* error) {
   if (status_ == UpdateStatus::UPDATED_NEED_REBOOT) {
-    return LogAndSetError(
-        error, FROM_HERE, "An update already applied, waiting for reboot");
+    return LogAndSetGenericError(
+        error,
+        __LINE__,
+        __FILE__,
+        "An update already applied, waiting for reboot");
   }
   if (processor_->IsRunning()) {
-    return LogAndSetError(
-        error, FROM_HERE, "Already processing an update, cancel it first.");
+    return LogAndSetGenericError(
+        error,
+        __LINE__,
+        __FILE__,
+        "Already processing an update, cancel it first.");
   }
   DCHECK_EQ(status_, UpdateStatus::IDLE);
 
@@ -307,15 +330,17 @@
   if (!headers[kPayloadPropertyNetworkId].empty()) {
     if (!base::StringToUint64(headers[kPayloadPropertyNetworkId],
                               &network_id)) {
-      return LogAndSetError(
+      return LogAndSetGenericError(
           error,
-          FROM_HERE,
+          __LINE__,
+          __FILE__,
           "Invalid network_id: " + headers[kPayloadPropertyNetworkId]);
     }
     if (!network_selector_->SetProcessNetwork(network_id)) {
-      return LogAndSetError(
+      return LogAndSetGenericError(
           error,
-          FROM_HERE,
+          __LINE__,
+          __FILE__,
           "Unable to set network_id: " + headers[kPayloadPropertyNetworkId]);
     }
   }
@@ -379,17 +404,23 @@
     int64_t payload_offset,
     int64_t payload_size,
     const vector<string>& key_value_pair_headers,
-    brillo::ErrorPtr* error) {
+    Error* error) {
   // update_engine state must be checked before modifying payload_fd_ otherwise
   // already running update will be terminated (existing file descriptor will be
   // closed)
   if (status_ == UpdateStatus::UPDATED_NEED_REBOOT) {
-    return LogAndSetError(
-        error, FROM_HERE, "An update already applied, waiting for reboot");
+    return LogAndSetGenericError(
+        error,
+        __LINE__,
+        __FILE__,
+        "An update already applied, waiting for reboot");
   }
   if (processor_->IsRunning()) {
-    return LogAndSetError(
-        error, FROM_HERE, "Already processing an update, cancel it first.");
+    return LogAndSetGenericError(
+        error,
+        __LINE__,
+        __FILE__,
+        "Already processing an update, cancel it first.");
   }
   DCHECK_EQ(status_, UpdateStatus::IDLE);
 
@@ -400,40 +431,48 @@
       payload_url, payload_offset, payload_size, key_value_pair_headers, error);
 }
 
-bool UpdateAttempterAndroid::SuspendUpdate(brillo::ErrorPtr* error) {
+bool UpdateAttempterAndroid::SuspendUpdate(Error* error) {
   if (!processor_->IsRunning())
-    return LogAndSetError(error, FROM_HERE, "No ongoing update to suspend.");
+    return LogAndSetGenericError(
+        error, __LINE__, __FILE__, "No ongoing update to suspend.");
   processor_->SuspendProcessing();
   return true;
 }
 
-bool UpdateAttempterAndroid::ResumeUpdate(brillo::ErrorPtr* error) {
+bool UpdateAttempterAndroid::ResumeUpdate(Error* error) {
   if (!processor_->IsRunning())
-    return LogAndSetError(error, FROM_HERE, "No ongoing update to resume.");
+    return LogAndSetGenericError(
+        error, __LINE__, __FILE__, "No ongoing update to resume.");
   processor_->ResumeProcessing();
   return true;
 }
 
-bool UpdateAttempterAndroid::CancelUpdate(brillo::ErrorPtr* error) {
+bool UpdateAttempterAndroid::CancelUpdate(Error* error) {
   if (!processor_->IsRunning())
-    return LogAndSetError(error, FROM_HERE, "No ongoing update to cancel.");
+    return LogAndSetGenericError(
+        error, __LINE__, __FILE__, "No ongoing update to cancel.");
   processor_->StopProcessing();
   return true;
 }
 
-bool UpdateAttempterAndroid::ResetStatus(brillo::ErrorPtr* error) {
+bool UpdateAttempterAndroid::ResetStatus(Error* error) {
   LOG(INFO) << "Attempting to reset state from "
             << UpdateStatusToString(status_) << " to UpdateStatus::IDLE";
   if (processor_->IsRunning()) {
-    return LogAndSetError(
-        error, FROM_HERE, "Already processing an update, cancel it first.");
+    return LogAndSetGenericError(
+        error,
+        __LINE__,
+        __FILE__,
+        "Already processing an update, cancel it first.");
   }
   if (status_ != UpdateStatus::IDLE &&
       status_ != UpdateStatus::UPDATED_NEED_REBOOT) {
-    return LogAndSetError(error,
-                          FROM_HERE,
-                          "Status reset not allowed in this state, please "
-                          "cancel on going OTA first.");
+    return LogAndSetGenericError(
+        error,
+        __LINE__,
+        __FILE__,
+        "Status reset not allowed in this state, please "
+        "cancel on going OTA first.");
   }
 
   if (apex_handler_android_ != nullptr) {
@@ -445,10 +484,11 @@
   // after resetting to idle state, it doesn't go back to
   // UpdateStatus::UPDATED_NEED_REBOOT state.
   if (!ClearUpdateCompletedMarker()) {
-    return LogAndSetError(error,
-                          FROM_HERE,
-                          "Failed to reset the status because "
-                          "ClearUpdateCompletedMarker() failed");
+    return LogAndSetGenericError(error,
+                                 __LINE__,
+                                 __FILE__,
+                                 "Failed to reset the status because "
+                                 "ClearUpdateCompletedMarker() failed");
   }
   if (status_ == UpdateStatus::UPDATED_NEED_REBOOT) {
     if (!resetShouldSwitchSlotOnReboot(error)) {
@@ -478,27 +518,34 @@
     const std::string& metadata_filename,
     std::string_view expected_metadata_hash,
     DeltaArchiveManifest* manifest,
-    brillo::ErrorPtr* error) {
+    Error* error) {
   FileDescriptorPtr fd(new EintrSafeFileDescriptor);
   if (!fd->Open(metadata_filename.c_str(), O_RDONLY)) {
-    return LogAndSetError(
-        error, FROM_HERE, "Failed to open " + metadata_filename);
+    return LogAndSetError(error,
+                          __LINE__,
+                          __FILE__,
+                          "Failed to open " + metadata_filename,
+                          ErrorCode::kDownloadManifestParseError);
   }
   brillo::Blob metadata(kMaxPayloadHeaderSize);
   if (!fd->Read(metadata.data(), metadata.size())) {
     return LogAndSetError(
         error,
-        FROM_HERE,
-        "Failed to read payload header from " + metadata_filename);
+        __LINE__,
+        __FILE__,
+        "Failed to read payload header from " + metadata_filename,
+        ErrorCode::kDownloadManifestParseError);
   }
   ErrorCode errorcode{};
   PayloadMetadata payload_metadata;
   if (payload_metadata.ParsePayloadHeader(metadata, &errorcode) !=
       MetadataParseResult::kSuccess) {
     return LogAndSetError(error,
-                          FROM_HERE,
+                          __LINE__,
+                          __FILE__,
                           "Failed to parse payload header: " +
-                              utils::ErrorCodeToString(errorcode));
+                              utils::ErrorCodeToString(errorcode),
+                          errorcode);
   }
   uint64_t metadata_size = payload_metadata.GetMetadataSize() +
                            payload_metadata.GetMetadataSignatureSize();
@@ -507,16 +554,20 @@
           static_cast<uint64_t>(utils::FileSize(metadata_filename))) {
     return LogAndSetError(
         error,
-        FROM_HERE,
-        "Invalid metadata size: " + std::to_string(metadata_size));
+        __LINE__,
+        __FILE__,
+        "Invalid metadata size: " + std::to_string(metadata_size),
+        ErrorCode::kDownloadManifestParseError);
   }
   metadata.resize(metadata_size);
   if (!fd->Read(metadata.data() + kMaxPayloadHeaderSize,
                 metadata.size() - kMaxPayloadHeaderSize)) {
     return LogAndSetError(
         error,
-        FROM_HERE,
-        "Failed to read metadata and signature from " + metadata_filename);
+        __LINE__,
+        __FILE__,
+        "Failed to read metadata and signature from " + metadata_filename,
+        ErrorCode::kDownloadManifestParseError);
   }
   fd->Close();
   if (!expected_metadata_hash.empty()) {
@@ -525,10 +576,12 @@
         metadata.data(), payload_metadata.GetMetadataSize(), &metadata_hash));
     if (metadata_hash != expected_metadata_hash) {
       return LogAndSetError(error,
-                            FROM_HERE,
+                            __LINE__,
+                            __FILE__,
                             "Metadata hash mismatch. Expected hash: " +
                                 HexEncode(expected_metadata_hash) +
-                                " actual hash: " + HexEncode(metadata_hash));
+                                " actual hash: " + HexEncode(metadata_hash),
+                            ErrorCode::kDownloadManifestParseError);
     } else {
       LOG(INFO) << "Payload metadata hash check passed : "
                 << HexEncode(metadata_hash);
@@ -539,27 +592,35 @@
       constants::kUpdateCertificatesPath);
   if (!payload_verifier) {
     return LogAndSetError(error,
-                          FROM_HERE,
+                          __LINE__,
+                          __FILE__,
                           "Failed to create the payload verifier from " +
-                              std::string(constants::kUpdateCertificatesPath));
+                              std::string(constants::kUpdateCertificatesPath),
+                          ErrorCode::kDownloadManifestParseError);
   }
   errorcode = payload_metadata.ValidateMetadataSignature(
       metadata, "", *payload_verifier);
   if (errorcode != ErrorCode::kSuccess) {
     return LogAndSetError(error,
-                          FROM_HERE,
+                          __LINE__,
+                          __FILE__,
                           "Failed to validate metadata signature: " +
-                              utils::ErrorCodeToString(errorcode));
+                              utils::ErrorCodeToString(errorcode),
+                          errorcode);
   }
   if (!payload_metadata.GetManifest(metadata, manifest)) {
-    return LogAndSetError(error, FROM_HERE, "Failed to parse manifest.");
+    return LogAndSetError(error,
+                          __LINE__,
+                          __FILE__,
+                          "Failed to parse manifest.",
+                          ErrorCode::kDownloadManifestParseError);
   }
 
   return true;
 }
 
 bool UpdateAttempterAndroid::VerifyPayloadApplicable(
-    const std::string& metadata_filename, brillo::ErrorPtr* error) {
+    const std::string& metadata_filename, Error* error) {
   DeltaArchiveManifest manifest;
   TEST_AND_RETURN_FALSE(
       VerifyPayloadParseManifest(metadata_filename, &manifest, error));
@@ -574,14 +635,15 @@
     string partition_path;
     if (!boot_control_->GetPartitionDevice(
             partition.partition_name(), current_slot, &partition_path)) {
-      return LogAndSetError(
+      return LogAndSetGenericError(
           error,
-          FROM_HERE,
+          __LINE__,
+          __FILE__,
           "Failed to get partition device for " + partition.partition_name());
     }
     if (!fd->Open(partition_path.c_str(), O_RDONLY)) {
-      return LogAndSetError(
-          error, FROM_HERE, "Failed to open " + partition_path);
+      return LogAndSetGenericError(
+          error, __LINE__, __FILE__, "Failed to open " + partition_path);
     }
     for (const InstallOperation& operation : partition.operations()) {
       if (!operation.has_src_sha256_hash())
@@ -591,8 +653,8 @@
                                         operation.src_extents(),
                                         manifest.block_size(),
                                         &source_hash)) {
-        return LogAndSetError(
-            error, FROM_HERE, "Failed to hash " + partition_path);
+        return LogAndSetGenericError(
+            error, __LINE__, __FILE__, "Failed to hash " + partition_path);
       }
       if (!PartitionWriter::ValidateSourceHash(
               source_hash, operation, fd, &errorcode)) {
@@ -1122,7 +1184,7 @@
 uint64_t UpdateAttempterAndroid::AllocateSpaceForPayload(
     const std::string& metadata_filename,
     const vector<string>& key_value_pair_headers,
-    brillo::ErrorPtr* error) {
+    Error* error) {
   std::map<string, string> headers;
   if (!ParseKeyValuePairHeaders(key_value_pair_headers, &headers, error)) {
     return 0;
@@ -1144,9 +1206,11 @@
   if (apex_handler_android_ != nullptr) {
     auto result = apex_handler_android_->CalculateSize(apex_infos);
     if (!result.ok()) {
-      LogAndSetError(error,
-                     FROM_HERE,
-                     "Failed to calculate size required for compressed APEX");
+      LogAndSetGenericError(
+          error,
+          __LINE__,
+          __FILE__,
+          "Failed to calculate size required for compressed APEX");
       return 0;
     }
     apex_size_required = *result;
@@ -1161,7 +1225,8 @@
                                                   payload_id,
                                                   &required_size)) {
     if (required_size == 0) {
-      LogAndSetError(error, FROM_HERE, "Failed to allocate space for payload.");
+      LogAndSetGenericError(
+          error, __LINE__, __FILE__, "Failed to allocate space for payload.");
       return 0;
     } else {
       LOG(ERROR) << "Insufficient space for payload: " << required_size
@@ -1184,7 +1249,7 @@
 
 void UpdateAttempterAndroid::CleanupSuccessfulUpdate(
     std::unique_ptr<CleanupSuccessfulUpdateCallbackInterface> callback,
-    brillo::ErrorPtr* error) {
+    Error* error) {
   if (cleanup_previous_update_code_.has_value()) {
     LOG(INFO) << "CleanupSuccessfulUpdate has previously completed with "
               << utils::ErrorCodeToString(*cleanup_previous_update_code_);
@@ -1206,11 +1271,14 @@
 }
 
 bool UpdateAttempterAndroid::setShouldSwitchSlotOnReboot(
-    const std::string& metadata_filename, brillo::ErrorPtr* error) {
+    const std::string& metadata_filename, Error* error) {
   LOG(INFO) << "setShouldSwitchSlotOnReboot(" << metadata_filename << ")";
   if (processor_->IsRunning()) {
-    return LogAndSetError(
-        error, FROM_HERE, "Already processing an update, cancel it first.");
+    return LogAndSetGenericError(
+        error,
+        __LINE__,
+        __FILE__,
+        "Already processing an update, cancel it first.");
   }
   DeltaArchiveManifest manifest;
   TEST_AND_RETURN_FALSE(
@@ -1248,8 +1316,8 @@
                                           manifest,
                                           false /* should update */,
                                           nullptr)) {
-      return LogAndSetError(
-          error, FROM_HERE, "Failed to PreparePartitionsForUpdate");
+      return LogAndSetGenericError(
+          error, __LINE__, __FILE__, "Failed to PreparePartitionsForUpdate");
     }
     ErrorCode error_code{};
     if (!install_plan_.ParsePartitions(manifest.partitions(),
@@ -1257,9 +1325,11 @@
                                        manifest.block_size(),
                                        &error_code)) {
       return LogAndSetError(error,
-                            FROM_HERE,
+                            __LINE__,
+                            __FILE__,
                             "Failed to LoadPartitionsFromSlots " +
-                                utils::ErrorCodeToString(error_code));
+                                utils::ErrorCodeToString(error_code),
+                            error_code);
     }
 
     auto filesystem_verifier_action =
@@ -1278,24 +1348,27 @@
   return true;
 }
 
-bool UpdateAttempterAndroid::resetShouldSwitchSlotOnReboot(
-    brillo::ErrorPtr* error) {
+bool UpdateAttempterAndroid::resetShouldSwitchSlotOnReboot(Error* error) {
   if (processor_->IsRunning()) {
-    return LogAndSetError(
-        error, FROM_HERE, "Already processing an update, cancel it first.");
+    return LogAndSetGenericError(
+        error,
+        __LINE__,
+        __FILE__,
+        "Already processing an update, cancel it first.");
   }
   TEST_AND_RETURN_FALSE(ClearUpdateCompletedMarker());
   // Update the boot flags so the current slot has higher priority.
   if (!boot_control_->SetActiveBootSlot(GetCurrentSlot())) {
-    return LogAndSetError(error, FROM_HERE, "Failed to SetActiveBootSlot");
+    return LogAndSetGenericError(
+        error, __LINE__, __FILE__, "Failed to SetActiveBootSlot");
   }
 
   // Mark the current slot as successful again, since marking it as active
   // may reset the successful bit. We ignore the result of whether marking
   // the current slot as successful worked.
   if (!boot_control_->MarkBootSuccessfulAsync(Bind([](bool successful) {}))) {
-    return LogAndSetError(
-        error, FROM_HERE, "Failed to MarkBootSuccessfulAsync");
+    return LogAndSetGenericError(
+        error, __LINE__, __FILE__, "Failed to MarkBootSuccessfulAsync");
   }
 
   // Resets the warm reset property since we won't switch the slot.