Snap for 6001391 from 80415b0f402f3b87f477c2048cdc4aca04bfcf74 to qt-aml-resolv-release

Change-Id: I7e7f5924fbf97375fa406ade8da7c1e94dbf22e5
diff --git a/boot_control/include/libboot_control/libboot_control.h b/boot_control/include/libboot_control/libboot_control.h
index 34a9aff..5468658 100644
--- a/boot_control/include/libboot_control/libboot_control.h
+++ b/boot_control/include/libboot_control/libboot_control.h
@@ -62,5 +62,28 @@
   unsigned int current_slot_ = 0;
 };
 
+// Helper functions to write the Virtual A/B merge status message. These are
+// separate because BootControl uses bootloader_control_ab in vendor space,
+// whereas the Virtual A/B merge status is in system space. A HAL might not
+// use bootloader_control_ab, but may want to use the AOSP method of maintaining
+// the merge status.
+
+// If the Virtual A/B message has not yet been initialized, then initialize it.
+// This should be called when the BootControl HAL first loads.
+//
+// If the Virtual A/B message in misc was already initialized, true is returned.
+// If initialization was attempted, but failed, false is returned, and the HAL
+// should fail to load.
+bool InitMiscVirtualAbMessageIfNeeded();
+
+// Save the current merge status as well as the current slot.
+bool SetMiscVirtualAbMergeStatus(unsigned int current_slot,
+                                 android::hardware::boot::V1_1::MergeStatus status);
+
+// Return the current merge status. If the saved status is SNAPSHOTTED but the
+// slot hasn't changed, the status returned will be NONE.
+bool GetMiscVirtualAbMergeStatus(unsigned int current_slot,
+                                 android::hardware::boot::V1_1::MergeStatus* status);
+
 }  // namespace bootable
 }  // namespace android
diff --git a/boot_control/libboot_control.cpp b/boot_control/libboot_control.cpp
index ff4eaab..7021839 100644
--- a/boot_control/libboot_control.cpp
+++ b/boot_control/libboot_control.cpp
@@ -232,6 +232,10 @@
     UpdateAndSaveBootloaderControl(device.c_str(), &boot_ctrl);
   }
 
+  if (!InitMiscVirtualAbMessageIfNeeded()) {
+    return false;
+  }
+
   num_slots_ = boot_ctrl.nb_slot;
   return true;
 }
@@ -335,18 +339,15 @@
 }
 
 bool BootControl::SetSnapshotMergeStatus(MergeStatus status) {
-  bootloader_control bootctrl;
-  if (!LoadBootloaderControl(misc_device_, &bootctrl)) return false;
-
-  bootctrl.merge_status = (unsigned int)status;
-  return UpdateAndSaveBootloaderControl(misc_device_, &bootctrl);
+  return SetMiscVirtualAbMergeStatus(current_slot_, status);
 }
 
 MergeStatus BootControl::GetSnapshotMergeStatus() {
-  bootloader_control bootctrl;
-  if (!LoadBootloaderControl(misc_device_, &bootctrl)) return MergeStatus::UNKNOWN;
-
-  return (MergeStatus)bootctrl.merge_status;
+  MergeStatus status;
+  if (!GetMiscVirtualAbMergeStatus(current_slot_, &status)) {
+    return MergeStatus::UNKNOWN;
+  }
+  return status;
 }
 
 const char* BootControl::GetSuffix(unsigned int slot) {
@@ -356,5 +357,66 @@
   return kSlotSuffixes[slot];
 }
 
+bool InitMiscVirtualAbMessageIfNeeded() {
+  std::string err;
+  misc_virtual_ab_message message;
+  if (!ReadMiscVirtualAbMessage(&message, &err)) {
+    LOG(ERROR) << "Could not read merge status: " << err;
+    return false;
+  }
+
+  if (message.version == MISC_VIRTUAL_AB_MESSAGE_VERSION) {
+    // Already initialized.
+    return true;
+  }
+
+  message = {};
+  message.version = MISC_VIRTUAL_AB_MESSAGE_VERSION;
+  if (!WriteMiscVirtualAbMessage(message, &err)) {
+    LOG(ERROR) << "Could not write merge status: " << err;
+    return false;
+  }
+  return true;
+}
+
+bool SetMiscVirtualAbMergeStatus(unsigned int current_slot,
+                                 android::hardware::boot::V1_1::MergeStatus status) {
+  std::string err;
+  misc_virtual_ab_message message;
+
+  if (!ReadMiscVirtualAbMessage(&message, &err)) {
+    LOG(ERROR) << "Could not read merge status: " << err;
+    return false;
+  }
+
+  message.merge_status = static_cast<uint8_t>(status);
+  message.source_slot = current_slot;
+  if (!WriteMiscVirtualAbMessage(message, &err)) {
+    LOG(ERROR) << "Could not write merge status: " << err;
+    return false;
+  }
+  return true;
+}
+
+bool GetMiscVirtualAbMergeStatus(unsigned int current_slot,
+                                 android::hardware::boot::V1_1::MergeStatus* status) {
+  std::string err;
+  misc_virtual_ab_message message;
+
+  if (!ReadMiscVirtualAbMessage(&message, &err)) {
+    LOG(ERROR) << "Could not read merge status: " << err;
+    return false;
+  }
+
+  // If the slot reverted after having created a snapshot, then the snapshot will
+  // be thrown away at boot. Thus we don't count this as being in a snapshotted
+  // state.
+  *status = static_cast<MergeStatus>(message.merge_status);
+  if (*status == MergeStatus::SNAPSHOTTED && current_slot == message.source_slot) {
+    *status = MergeStatus::NONE;
+  }
+  return true;
+}
+
 }  // namespace bootable
 }  // namespace android
diff --git a/bootloader_message/bootloader_message.cpp b/bootloader_message/bootloader_message.cpp
index b15a9b9..4f7085d 100644
--- a/bootloader_message/bootloader_message.cpp
+++ b/bootloader_message/bootloader_message.cpp
@@ -250,6 +250,13 @@
   if (misc_blk_device.empty()) {
     return false;
   }
+  static constexpr size_t kMaximumWipePackageSize =
+      SYSTEM_SPACE_OFFSET_IN_MISC - WIPE_PACKAGE_OFFSET_IN_MISC;
+  if (package_data.size() > kMaximumWipePackageSize) {
+    *err = "Wipe package size " + std::to_string(package_data.size()) + " exceeds " +
+           std::to_string(kMaximumWipePackageSize) + " bytes";
+    return false;
+  }
   return write_misc_partition(package_data.data(), package_data.size(), misc_blk_device,
                               WIPE_PACKAGE_OFFSET_IN_MISC, err);
 }
@@ -285,6 +292,49 @@
                               err);
 }
 
+static bool ValidateSystemSpaceRegion(size_t offset, size_t size, std::string* err) {
+  if (size <= SYSTEM_SPACE_SIZE_IN_MISC && offset <= (SYSTEM_SPACE_SIZE_IN_MISC - size)) {
+    return true;
+  }
+  *err = android::base::StringPrintf("Out of bound access (offset %zu size %zu)", offset, size);
+  return false;
+}
+
+static bool ReadMiscPartitionSystemSpace(void* data, size_t size, size_t offset, std::string* err) {
+  if (!ValidateSystemSpaceRegion(offset, size, err)) {
+    return false;
+  }
+  auto misc_blk_device = get_misc_blk_device(err);
+  if (misc_blk_device.empty()) {
+    return false;
+  }
+  return read_misc_partition(data, size, misc_blk_device, SYSTEM_SPACE_OFFSET_IN_MISC + offset,
+                             err);
+}
+
+static bool WriteMiscPartitionSystemSpace(const void* data, size_t size, size_t offset,
+                                          std::string* err) {
+  if (!ValidateSystemSpaceRegion(offset, size, err)) {
+    return false;
+  }
+  auto misc_blk_device = get_misc_blk_device(err);
+  if (misc_blk_device.empty()) {
+    return false;
+  }
+  return write_misc_partition(data, size, misc_blk_device, SYSTEM_SPACE_OFFSET_IN_MISC + offset,
+                              err);
+}
+
+bool ReadMiscVirtualAbMessage(misc_virtual_ab_message* message, std::string* err) {
+  return ReadMiscPartitionSystemSpace(message, sizeof(*message),
+                                      offsetof(misc_system_space_layout, virtual_ab_message), err);
+}
+
+bool WriteMiscVirtualAbMessage(const misc_virtual_ab_message& message, std::string* err) {
+  return WriteMiscPartitionSystemSpace(&message, sizeof(message),
+                                       offsetof(misc_system_space_layout, virtual_ab_message), err);
+}
+
 extern "C" bool write_reboot_bootloader(void) {
   std::string err;
   return write_reboot_bootloader(&err);
diff --git a/bootloader_message/include/bootloader_message/bootloader_message.h b/bootloader_message/include/bootloader_message/bootloader_message.h
index b787830..3a3b862 100644
--- a/bootloader_message/include/bootloader_message/bootloader_message.h
+++ b/bootloader_message/include/bootloader_message/bootloader_message.h
@@ -25,12 +25,15 @@
 // 0   - 2K     For bootloader_message
 // 2K  - 16K    Used by Vendor's bootloader (the 2K - 4K range may be optionally used
 //              as bootloader_message_ab struct)
-// 16K - 64K    Used by uncrypt and recovery to store wipe_package for A/B devices
+// 16K - 32K    Used by uncrypt and recovery to store wipe_package for A/B devices
+// 32K - 64K    System space, used for miscellanious AOSP features. See below.
 // Note that these offsets are admitted by bootloader,recovery and uncrypt, so they
 // are not configurable without changing all of them.
 constexpr size_t BOOTLOADER_MESSAGE_OFFSET_IN_MISC = 0;
 constexpr size_t VENDOR_SPACE_OFFSET_IN_MISC = 2 * 1024;
 constexpr size_t WIPE_PACKAGE_OFFSET_IN_MISC = 16 * 1024;
+constexpr size_t SYSTEM_SPACE_OFFSET_IN_MISC = 32 * 1024;
+constexpr size_t SYSTEM_SPACE_SIZE_IN_MISC = 32 * 1024;
 
 /* Bootloader Message (2-KiB)
  *
@@ -182,6 +185,28 @@
               "struct bootloader_control has wrong size");
 #endif
 
+// Holds Virtual A/B merge status information. Current version is 1. New fields
+// must be added to the end.
+struct misc_virtual_ab_message {
+  uint8_t version;
+  uint8_t merge_status;  // IBootControl 1.1, MergeStatus enum.
+  uint8_t source_slot;   // Slot number when merge_status was written.
+  uint8_t reserved[61];
+} __attribute__((packed));
+
+#define MISC_VIRTUAL_AB_MESSAGE_VERSION 1
+
+#if (__STDC_VERSION__ >= 201112L) || defined(__cplusplus)
+static_assert(sizeof(struct misc_virtual_ab_message) == 64,
+              "struct misc_virtual_ab_message has wrong size");
+#endif
+
+// This struct is not meant to be used directly, rather, it is to make
+// computation of offsets easier. New fields must be added to the end.
+struct misc_system_space_layout {
+  misc_virtual_ab_message virtual_ab_message;
+} __attribute__((packed));
+
 #ifdef __cplusplus
 
 #include <string>
@@ -244,6 +269,10 @@
 // offset is in relative to the start of the vendor space.
 bool WriteMiscPartitionVendorSpace(const void* data, size_t size, size_t offset, std::string* err);
 
+// Read or write the Virtual A/B message from system space in /misc.
+bool ReadMiscVirtualAbMessage(misc_virtual_ab_message* message, std::string* err);
+bool WriteMiscVirtualAbMessage(const misc_virtual_ab_message& message, std::string* err);
+
 #else
 
 #include <stdbool.h>
diff --git a/etc/init.rc b/etc/init.rc
index 0822aba..d5b056a 100644
--- a/etc/init.rc
+++ b/etc/init.rc
@@ -95,10 +95,6 @@
 on property:service.adb.root=1
     restart adbd
 
-# Always start adbd on userdebug and eng builds
-on fs && property:ro.debuggable=1
-    setprop sys.usb.config adb
-
 on fs && property:sys.usb.configfs=1
     mount configfs none /config
     mkdir /config/usb_gadget/g1 0770 shell shell
diff --git a/recovery_main.cpp b/recovery_main.cpp
index 89253dc..30a1fc0 100644
--- a/recovery_main.cpp
+++ b/recovery_main.cpp
@@ -69,6 +69,10 @@
   return android::base::GetBoolProperty("ro.debuggable", false);
 }
 
+static bool IsDeviceUnlocked() {
+  return "orange" == android::base::GetProperty("ro.boot.verifiedbootstate", "");
+}
+
 static void UiLogger(android::base::LogId /* id */, android::base::LogSeverity severity,
                      const char* /* tag */, const char* /* file */, unsigned int /* line */,
                      const char* message) {
@@ -463,7 +467,9 @@
   listener_thread.detach();
 
   while (true) {
-    std::string usb_config = fastboot ? "fastboot" : IsRoDebuggable() ? "adb" : "none";
+    // We start adbd in recovery for the device with userdebug build or a unlocked bootloader.
+    std::string usb_config =
+        fastboot ? "fastboot" : IsRoDebuggable() || IsDeviceUnlocked() ? "adb" : "none";
     std::string usb_state = android::base::GetProperty("sys.usb.state", "none");
     if (usb_config != usb_state) {
       if (!SetUsbConfig("none")) {