weaved: Add Command::AbortWithCustomError() and SetError/SetCustomError
am: 13d115ca0f

* commit '13d115ca0f3961ea7084f68795f8fd887b369be4':
  weaved: Add Command::AbortWithCustomError() and SetError/SetCustomError
diff --git a/libweaved/command.cc b/libweaved/command.cc
index 9950673..fa10955 100644
--- a/libweaved/command.cc
+++ b/libweaved/command.cc
@@ -25,6 +25,34 @@
 
 namespace weaved {
 
+namespace {
+
+// Converts binder exception code into a weave error code string.
+std::string BinderExceptionString(int32_t exception_code) {
+  if (exception_code == android::binder::Status::EX_NONE)
+    return "_none";
+  else if (exception_code == android::binder::Status::EX_SECURITY)
+    return "_security";
+  else if (exception_code == android::binder::Status::EX_BAD_PARCELABLE)
+    return "_bad_parcelable";
+  else if (exception_code == android::binder::Status::EX_ILLEGAL_ARGUMENT)
+    return "_illegal_argument";
+  else if (exception_code == android::binder::Status::EX_NULL_POINTER)
+    return "_null_pointer";
+  else if (exception_code == android::binder::Status::EX_ILLEGAL_STATE)
+    return "_illegal_state";
+  else if (exception_code == android::binder::Status::EX_NETWORK_MAIN_THREAD)
+    return "_network_error";
+  else if (exception_code == android::binder::Status::EX_UNSUPPORTED_OPERATION)
+    return "_unsupported_operation";
+  else if (exception_code == android::binder::Status::EX_SERVICE_SPECIFIC)
+    return "_general_failure";
+
+  return "_unknown";
+}
+
+}  // anonymous namespace
+
 Command::Command(const android::sp<android::weave::IWeaveCommand>& proxy)
     : binder_proxy_{proxy} {}
 
@@ -125,8 +153,44 @@
                        error);
 }
 
+bool Command::AbortWithCustomError(const brillo::Error* command_error,
+                                   brillo::ErrorPtr* error) {
+  std::string error_code = "_" + command_error->GetCode();
+  return Abort(error_code, command_error->GetMessage(), error);
+}
+
+bool Command::AbortWithCustomError(android::binder::Status status,
+                                   brillo::ErrorPtr* error) {
+  std::string error_code = BinderExceptionString(status.exceptionCode());
+  return Abort(error_code, status.exceptionMessage().string(), error);
+}
+
 bool Command::Cancel(brillo::ErrorPtr* error) {
   return StatusToError(binder_proxy_->cancel(), error);
 }
 
+bool Command::Pause(brillo::ErrorPtr* error) {
+  return StatusToError(binder_proxy_->pause(), error);
+}
+
+bool Command::SetError(const std::string& error_code,
+                       const std::string& error_message,
+                       brillo::ErrorPtr* error) {
+  return StatusToError(binder_proxy_->setError(ToString16(error_code),
+                                               ToString16(error_message)),
+                       error);
+}
+
+bool Command::SetCustomError(const brillo::Error* command_error,
+                             brillo::ErrorPtr* error) {
+  std::string error_code = "_" + command_error->GetCode();
+  return SetError(error_code, command_error->GetMessage(), error);
+}
+
+bool Command::SetCustomError(android::binder::Status status,
+                             brillo::ErrorPtr* error) {
+  std::string error_code = BinderExceptionString(status.exceptionCode());
+  return SetError(error_code, status.exceptionMessage().string(), error);
+}
+
 }  // namespace weave
diff --git a/libweaved/command.h b/libweaved/command.h
index 2b69266..4f7bf7c 100644
--- a/libweaved/command.h
+++ b/libweaved/command.h
@@ -18,6 +18,7 @@
 #include <string>
 
 #include <base/macros.h>
+#include <binder/Status.h>
 #include <brillo/errors/error.h>
 #include <brillo/variant_dictionary.h>
 #include <libweaved/export.h>
@@ -123,10 +124,42 @@
              const std::string& error_message,
              brillo::ErrorPtr* error);
 
+  // Aborts command execution.
+  // Sets command into terminal "aborted" state and uses the error information
+  // from the |command_error| object. The error codes extracted from
+  // |command_error| are automatically prepended with an underscore ("_").
+  bool AbortWithCustomError(const brillo::Error* command_error,
+                            brillo::ErrorPtr* error);
+  // AbortWithCustomError overload for specifying the error information as
+  // binder::Status.
+  bool AbortWithCustomError(android::binder::Status status,
+                            brillo::ErrorPtr* error);
+
   // Cancels command execution.
   // Sets command into terminal "canceled" state.
   bool Cancel(brillo::ErrorPtr* error);
 
+  // Sets command into paused state.
+  // This is not terminal state. Command can be resumed with |SetProgress| call.
+  bool Pause(brillo::ErrorPtr* error);
+
+  // Sets command into error state and assign error.
+  // This is not terminal state. Command can be resumed with |SetProgress| call.
+  bool SetError(const std::string& error_code,
+                const std::string& error_message,
+                brillo::ErrorPtr* error);
+
+  // Sets command into error state and assign error.
+  // This is not terminal state. Command can be resumed with |SetProgress| call.
+  // Uses the error information from the |command_error| object.
+  // The error codes extracted from |command_error| are automatically prepended
+  // with an underscore ("_").
+  bool SetCustomError(const brillo::Error* command_error,
+                      brillo::ErrorPtr* error);
+  // SetError overload for specifying the error information as binder::Status.
+  bool SetCustomError(android::binder::Status status,
+                      brillo::ErrorPtr* error);
+
  protected:
   explicit Command(const android::sp<android::weave::IWeaveCommand>& proxy);