libbinder_ndk: add AStatus_getDescription

API to get a description of the status.

Bug: 136027762
Test: using API
Change-Id: I04be1dcba27f03751c4db5627432fe94d3636d44
diff --git a/libs/binder/ndk/include_ndk/android/binder_auto_utils.h b/libs/binder/ndk/include_ndk/android/binder_auto_utils.h
index 946ccb7..2b61cf1 100644
--- a/libs/binder/ndk/include_ndk/android/binder_auto_utils.h
+++ b/libs/binder/ndk/include_ndk/android/binder_auto_utils.h
@@ -34,6 +34,7 @@
 
 #include <unistd.h>
 #include <cstddef>
+#include <string>
 
 namespace ndk {
 
@@ -228,6 +229,13 @@
      */
     const char* getMessage() const { return AStatus_getMessage(get()); }
 
+    std::string getDescription() const {
+        const char* cStr = AStatus_getDescription(get());
+        std::string ret = cStr;
+        AStatus_deleteDescription(cStr);
+        return ret;
+    }
+
     /**
      * Convenience methods for creating scoped statuses.
      */
diff --git a/libs/binder/ndk/include_ndk/android/binder_status.h b/libs/binder/ndk/include_ndk/android/binder_status.h
index 78d70f8..ab9a144 100644
--- a/libs/binder/ndk/include_ndk/android/binder_status.h
+++ b/libs/binder/ndk/include_ndk/android/binder_status.h
@@ -247,6 +247,25 @@
 const char* AStatus_getMessage(const AStatus* status) __INTRODUCED_IN(29);
 
 /**
+ * Get human-readable description for debugging.
+ *
+ * Available since API level 30.
+ *
+ * \param status the status being queried.
+ *
+ * \return a description, must be deleted with AStatus_deleteDescription.
+ */
+__attribute__((warn_unused_result)) const char* AStatus_getDescription(const AStatus* status)
+        __INTRODUCED_IN(30);
+
+/**
+ * Delete description.
+ *
+ * \param description value from AStatus_getDescription
+ */
+void AStatus_deleteDescription(const char* description) __INTRODUCED_IN(30);
+
+/**
  * Deletes memory associated with the status instance.
  *
  * Available since API level 29.
diff --git a/libs/binder/ndk/libbinder_ndk.map.txt b/libs/binder/ndk/libbinder_ndk.map.txt
index d59d6e4..71d8103 100644
--- a/libs/binder/ndk/libbinder_ndk.map.txt
+++ b/libs/binder/ndk/libbinder_ndk.map.txt
@@ -103,6 +103,8 @@
   global:
     AIBinder_getExtension;
     AIBinder_setExtension;
+    AStatus_getDescription;
+    AStatus_deleteDescription;
 
     AIBinder_markSystemStability; # apex
     AIBinder_markVendorStability; # llndk
diff --git a/libs/binder/ndk/status.cpp b/libs/binder/ndk/status.cpp
index 1f75b0b..87e1341 100644
--- a/libs/binder/ndk/status.cpp
+++ b/libs/binder/ndk/status.cpp
@@ -66,6 +66,17 @@
     return status->get()->exceptionMessage().c_str();
 }
 
+const char* AStatus_getDescription(const AStatus* status) {
+    android::String8 description = status->get()->toString8();
+    char* cStr = new char[description.size() + 1];
+    memcpy(cStr, description.c_str(), description.size() + 1);
+    return cStr;
+}
+
+void AStatus_deleteDescription(const char* description) {
+    delete[] const_cast<char*>(description);
+}
+
 void AStatus_delete(AStatus* status) {
     delete status;
 }
diff --git a/libs/binder/ndk/test/binderVendorDoubleLoadTest.cpp b/libs/binder/ndk/test/binderVendorDoubleLoadTest.cpp
index d3ccdc2..ad78e31 100644
--- a/libs/binder/ndk/test/binderVendorDoubleLoadTest.cpp
+++ b/libs/binder/ndk/test/binderVendorDoubleLoadTest.cpp
@@ -105,7 +105,8 @@
 
         std::string outString;
         ScopedAStatus status = server->RepeatString("foo", &outString);
-        EXPECT_EQ(STATUS_OK, AStatus_getExceptionCode(status.get())) << serviceName;
+        EXPECT_EQ(STATUS_OK, AStatus_getExceptionCode(status.get()))
+                << serviceName << " " << status.getDescription();
         EXPECT_EQ("foo", outString) << serviceName;
     }
 }