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.