Snap for 6680390 from 6cbcea87a648bc236c8ec97914e342f4a0c4e8a5 to rvc-release

Change-Id: I3cece9a2e4de9f09e946f76b00fb277fca02633b
diff --git a/bootctl/bootctl.cpp b/bootctl/bootctl.cpp
index b9aae9c..c8f8b0b 100644
--- a/bootctl/bootctl.cpp
+++ b/bootctl/bootctl.cpp
@@ -31,7 +31,12 @@
 using android::hardware::boot::V1_1::IBootControl;
 using android::hardware::boot::V1_1::MergeStatus;
 
-static void usage(FILE* where, int /* argc */, char* argv[])
+namespace V1_0 = android::hardware::boot::V1_0;
+namespace V1_1 = android::hardware::boot::V1_1;
+
+enum BootCtlVersion { BOOTCTL_V1_0, BOOTCTL_V1_1 };
+
+static void usage(FILE* where, BootCtlVersion bootVersion, int /* argc */, char* argv[])
 {
     fprintf(where,
             "%s - command-line wrapper for the boot HAL.\n"
@@ -48,18 +53,22 @@
             "  set-slot-as-unbootable SLOT    - Mark SLOT as invalid.\n"
             "  is-slot-bootable SLOT          - Returns 0 only if SLOT is bootable.\n"
             "  is-slot-marked-successful SLOT - Returns 0 only if SLOT is marked GOOD.\n"
-            "  get-suffix SLOT                - Prints suffix for SLOT.\n"
-            "  set-snapshot-merge-status STAT - Sets whether a snapshot-merge of any dynamic\n"
-            "                                   partition is in progress. Valid STAT values\n"
-            "                                   are: none, unknown, snapshotted, merging,\n"
-            "                                   or cancelled.\n"
-            "  get-snapshot-merge-status      - Prints the current snapshot-merge status.\n"
-            "\n"
-            "SLOT parameter is the zero-based slot-number.\n",
+            "  get-suffix SLOT                - Prints suffix for SLOT.\n",
             argv[0], argv[0]);
+    if (bootVersion >= BOOTCTL_V1_1) {
+        fprintf(where,
+                "  set-snapshot-merge-status STAT - Sets whether a snapshot-merge of any dynamic\n"
+                "                                   partition is in progress. Valid STAT values\n"
+                "                                   are: none, unknown, snapshotted, merging,\n"
+                "                                   or cancelled.\n"
+                "  get-snapshot-merge-status      - Prints the current snapshot-merge status.\n");
+    }
+    fprintf(where,
+            "\n"
+            "SLOT parameter is the zero-based slot-number.\n");
 }
 
-static int do_hal_info(const sp<IBootControl> module) {
+static int do_hal_info(const sp<V1_0::IBootControl> module) {
     module->interfaceDescriptor([&](const auto& descriptor) {
         fprintf(stdout,
                 "HAL Version: %s\n",
@@ -68,14 +77,14 @@
     return EX_OK;
 }
 
-static int do_get_number_slots(sp<IBootControl> module)
+static int do_get_number_slots(sp<V1_0::IBootControl> module)
 {
     uint32_t numSlots = module->getNumberSlots();
     fprintf(stdout, "%u\n", numSlots);
     return EX_OK;
 }
 
-static int do_get_current_slot(sp<IBootControl> module)
+static int do_get_current_slot(sp<V1_0::IBootControl> module)
 {
     Slot curSlot = module->getCurrentSlot();
     fprintf(stdout, "%u\n", curSlot);
@@ -99,14 +108,14 @@
     return EX_OK;
 }
 
-static int do_mark_boot_successful(sp<IBootControl> module)
+static int do_mark_boot_successful(sp<V1_0::IBootControl> module)
 {
     CommandResult cr;
     Return<void> ret = module->markBootSuccessful(generate_callback(&cr));
     return handle_return(ret, cr, "Error marking as having booted successfully: %s\n");
 }
 
-static int do_set_active_boot_slot(sp<IBootControl> module,
+static int do_set_active_boot_slot(sp<V1_0::IBootControl> module,
                                    Slot slot_number)
 {
     CommandResult cr;
@@ -114,7 +123,7 @@
     return handle_return(ret, cr, "Error setting active boot slot: %s\n");
 }
 
-static int do_set_slot_as_unbootable(sp<IBootControl> module,
+static int do_set_slot_as_unbootable(sp<V1_0::IBootControl> module,
                                      Slot slot_number)
 {
     CommandResult cr;
@@ -135,13 +144,13 @@
     return EX_SOFTWARE;
 }
 
-static int do_is_slot_bootable(sp<IBootControl> module, Slot slot_number)
+static int do_is_slot_bootable(sp<V1_0::IBootControl> module, Slot slot_number)
 {
     Return<BoolResult> ret = module->isSlotBootable(slot_number);
     return handle_return(ret, "Error calling isSlotBootable(): %s\n");
 }
 
-static int do_is_slot_marked_successful(sp<IBootControl> module,
+static int do_is_slot_marked_successful(sp<V1_0::IBootControl> module,
                                         Slot slot_number)
 {
     Return<BoolResult> ret = module->isSlotMarkedSuccessful(slot_number);
@@ -157,16 +166,17 @@
     return {};
 }
 
-static int do_set_snapshot_merge_status(sp<IBootControl> module, int argc, char *argv[]) {
+static int do_set_snapshot_merge_status(sp<V1_1::IBootControl> module, BootCtlVersion bootVersion,
+                                        int argc, char *argv[]) {
     if (argc != 3) {
-        usage(stderr, argc, argv);
+        usage(stderr, bootVersion, argc, argv);
         exit(EX_USAGE);
         return -1;
     }
 
     auto status = stringToMergeStatus(argv[2]);
     if (!status.has_value()) {
-        usage(stderr, argc, argv);
+        usage(stderr, bootVersion, argc, argv);
         exit(EX_USAGE);
         return -1;
     }
@@ -194,7 +204,7 @@
     }
 }
 
-static int do_get_snapshot_merge_status(sp<IBootControl> module) {
+static int do_get_snapshot_merge_status(sp<V1_1::IBootControl> module) {
     MergeStatus ret = module->getSnapshotMergeStatus();
     std::stringstream ss;
     ss << ret;
@@ -202,7 +212,7 @@
     return EX_OK;
 }
 
-static int do_get_suffix(sp<IBootControl> module, Slot slot_number) {
+static int do_get_suffix(sp<V1_0::IBootControl> module, Slot slot_number) {
     std::function<void(hidl_string)> cb = [](hidl_string suffix){
         fprintf(stdout, "%s\n", suffix.c_str());
     };
@@ -215,17 +225,17 @@
     return EX_OK;
 }
 
-static uint32_t parse_slot(int pos, int argc, char *argv[])
+static uint32_t parse_slot(BootCtlVersion bootVersion, int pos, int argc, char *argv[])
 {
     if (pos > argc - 1) {
-        usage(stderr, argc, argv);
+        usage(stderr, bootVersion, argc, argv);
         exit(EX_USAGE);
         return -1;
     }
     errno = 0;
     uint64_t ret = strtoul(argv[pos], NULL, 10);
     if (errno != 0 || ret > UINT_MAX) {
-        usage(stderr, argc, argv);
+        usage(stderr, bootVersion, argc, argv);
         exit(EX_USAGE);
         return -1;
     }
@@ -234,45 +244,62 @@
 
 int main(int argc, char *argv[])
 {
-    sp<IBootControl> module;
+    sp<V1_0::IBootControl> v1_0_module;
+    sp<V1_1::IBootControl> v1_1_module;
+    BootCtlVersion bootVersion = BOOTCTL_V1_0;
 
-    if (argc < 2) {
-        usage(stderr, argc, argv);
-        return EX_USAGE;
-    }
-
-    module = IBootControl::getService();
-    if (module == NULL) {
-        fprintf(stderr, "Error getting bootctrl module.\n");
+    v1_0_module = V1_0::IBootControl::getService();
+    if (v1_0_module == nullptr) {
+        fprintf(stderr, "Error getting bootctrl v1.0 module.\n");
         return EX_SOFTWARE;
     }
+    v1_1_module = V1_1::IBootControl::castFrom(v1_0_module);
+    if (v1_1_module != nullptr) {
+        bootVersion = BOOTCTL_V1_1;
+    }
 
-    if (strcmp(argv[1], "hal-info") == 0) {
-        return do_hal_info(module);
-    } else if (strcmp(argv[1], "get-number-slots") == 0) {
-        return do_get_number_slots(module);
-    } else if (strcmp(argv[1], "get-current-slot") == 0) {
-        return do_get_current_slot(module);
-    } else if (strcmp(argv[1], "mark-boot-successful") == 0) {
-        return do_mark_boot_successful(module);
-    } else if (strcmp(argv[1], "set-active-boot-slot") == 0) {
-        return do_set_active_boot_slot(module, parse_slot(2, argc, argv));
-    } else if (strcmp(argv[1], "set-slot-as-unbootable") == 0) {
-        return do_set_slot_as_unbootable(module, parse_slot(2, argc, argv));
-    } else if (strcmp(argv[1], "is-slot-bootable") == 0) {
-        return do_is_slot_bootable(module, parse_slot(2, argc, argv));
-    } else if (strcmp(argv[1], "get-suffix") == 0) {
-        return do_get_suffix(module, parse_slot(2, argc, argv));
-    } else if (strcmp(argv[1], "is-slot-marked-successful") == 0) {
-        return do_is_slot_marked_successful(module, parse_slot(2, argc, argv));
-    } else if (strcmp(argv[1], "set-snapshot-merge-status") == 0) {
-        return do_set_snapshot_merge_status(module, argc, argv);
-    } else if (strcmp(argv[1], "get-snapshot-merge-status") == 0) {
-        return do_get_snapshot_merge_status(module);
-    } else {
-        usage(stderr, argc, argv);
+    if (argc < 2) {
+        usage(stderr, bootVersion, argc, argv);
         return EX_USAGE;
     }
 
-    return 0;
+    // Functions present from version 1.0
+    if (strcmp(argv[1], "hal-info") == 0) {
+        return do_hal_info(v1_0_module);
+    } else if (strcmp(argv[1], "get-number-slots") == 0) {
+        return do_get_number_slots(v1_0_module);
+    } else if (strcmp(argv[1], "get-current-slot") == 0) {
+        return do_get_current_slot(v1_0_module);
+    } else if (strcmp(argv[1], "mark-boot-successful") == 0) {
+        return do_mark_boot_successful(v1_0_module);
+    } else if (strcmp(argv[1], "set-active-boot-slot") == 0) {
+        return do_set_active_boot_slot(v1_0_module, parse_slot(bootVersion, 2, argc, argv));
+    } else if (strcmp(argv[1], "set-slot-as-unbootable") == 0) {
+        return do_set_slot_as_unbootable(v1_0_module, parse_slot(bootVersion, 2, argc, argv));
+    } else if (strcmp(argv[1], "is-slot-bootable") == 0) {
+        return do_is_slot_bootable(v1_0_module, parse_slot(bootVersion, 2, argc, argv));
+    } else if (strcmp(argv[1], "is-slot-marked-successful") == 0) {
+        return do_is_slot_marked_successful(v1_0_module, parse_slot(bootVersion, 2, argc, argv));
+    } else if (strcmp(argv[1], "get-suffix") == 0) {
+        return do_get_suffix(v1_0_module, parse_slot(bootVersion, 2, argc, argv));
+    }
+
+    // Functions present from version 1.1
+    if (strcmp(argv[1], "set-snapshot-merge-status") == 0 ||
+        strcmp(argv[1], "get-snapshot-merge-status") == 0 ) {
+
+        if (v1_1_module == nullptr) {
+            fprintf(stderr, "Error getting bootctrl v1.1 module.\n");
+            return EX_SOFTWARE;
+        }
+        if (strcmp(argv[1], "set-snapshot-merge-status") == 0) {
+            return do_set_snapshot_merge_status(v1_1_module, bootVersion, argc, argv);
+        } else if (strcmp(argv[1], "get-snapshot-merge-status") == 0) {
+            return do_get_snapshot_merge_status(v1_1_module);
+        }
+    }
+
+    // Parameter not matched, print usage
+    usage(stderr, bootVersion, argc, argv);
+    return EX_USAGE;
 }