fastboot: Add oem command to wipe Titan M userdata

Because fastbootd just wipe Android userdata partition when
user input "fastboot erase userdata" command.

We add a new oem command for fastbootd to notify Titan M to
wipe userdata after Android userdata has been erased.

Bug: 150929955
Change-Id: Ife9d49580c35c184ac2feecb70844785b42a0591
diff --git a/fastboot/Android.bp b/fastboot/Android.bp
index 646c0a9..4ba5231 100644
--- a/fastboot/Android.bp
+++ b/fastboot/Android.bp
@@ -22,10 +22,16 @@
     relative_install_path: "hw",
     export_include_dirs: ["include"],
     shared_libs: [
+        "liblog",
         "libbase",
         "libhidlbase",
         "libutils",
         "libcutils",
         "android.hardware.fastboot@1.0",
     ],
+    static_libs: [
+        "libnos_for_fastboot",
+        "libnos_citadel_for_fastboot",
+        "libfstab",
+    ],
 }
diff --git a/fastboot/Fastboot.cpp b/fastboot/Fastboot.cpp
index f68c7c3..a29148d 100644
--- a/fastboot/Fastboot.cpp
+++ b/fastboot/Fastboot.cpp
@@ -24,6 +24,9 @@
 #include <android-base/logging.h>
 #include <android-base/strings.h>
 #include <android-base/unique_fd.h>
+#include <app_nugget.h>
+#include <nos/NuggetClient.h>
+#include <nos/debug.h>
 
 namespace android {
 namespace hardware {
@@ -96,10 +99,43 @@
     return { Status::FAILURE_UNKNOWN, "Unable to set display brightness" };
 }
 
+Result PostWipeData(const std::vector<std::string>& args) {
+    if (!args.size()||((args[0] != "userdata")&&(args[0] != "support"))) {
+        return { Status::INVALID_ARGUMENT, "Invalid oem command" };
+    }
+
+    if (args[0] == "support") {
+        return { Status::SUCCESS, "" };
+    }
+
+    // Connect to Titan M
+    ::nos::NuggetClient client;
+    client.Open();
+    if (!client.IsOpen()) {
+        return { Status::FAILURE_UNKNOWN, "open Titan M fail" };
+    }
+
+    // Tell Titan M to wipe user data
+    const uint32_t magicValue = htole32(ERASE_CONFIRMATION);
+    std::vector<uint8_t> magic(sizeof(magicValue));
+    memcpy(magic.data(), &magicValue, sizeof(magicValue));
+    const uint8_t retry_count = 5;
+    for(uint8_t i = 0; i < retry_count; i++) {
+        const uint32_t status
+            = client.CallApp(APP_ID_NUGGET, NUGGET_PARAM_NUKE_FROM_ORBIT, magic, nullptr);
+        if (status == APP_SUCCESS) {
+            return { Status::SUCCESS, "" };
+        }
+    }
+
+    return { Status::FAILURE_UNKNOWN, "Titan M user data wipe failed" };
+}
+
 Return<void> Fastboot::doOemCommand(const ::android::hardware::hidl_string& oemCmdArgs,
                           doOemCommand_cb _hidl_cb) {
     const std::unordered_map<std::string, OEMCommandHandler> kOEMCmdMap = {
         {FB_OEM_SET_BRIGHTNESS, SetBrightnessLevel},
+        {FB_OEM_POST_WIPEDATA, PostWipeData},
     };
 
     auto args = android::base::Split(oemCmdArgs, " ");
diff --git a/fastboot/include/fastboot/Fastboot.h b/fastboot/include/fastboot/Fastboot.h
index e5c0a11..5280f7c 100644
--- a/fastboot/include/fastboot/Fastboot.h
+++ b/fastboot/include/fastboot/Fastboot.h
@@ -27,6 +27,7 @@
 namespace implementation {
 
 #define FB_OEM_SET_BRIGHTNESS "setbrightness"
+#define FB_OEM_POST_WIPEDATA "postwipedata"
 
 using ::android::hardware::hidl_vec;
 using ::android::hardware::Return;