Merge changes Id47b288d,I969565eb,Iba2e654e

* changes:
  logd: drop can_read_security_logs
  logd: create FlushToState class
  logd: fix bug in FlushTo when requesting exact sequence number
diff --git a/fastboot/device/usb_client.cpp b/fastboot/device/usb_client.cpp
index 9c80765..c653167 100644
--- a/fastboot/device/usb_client.cpp
+++ b/fastboot/device/usb_client.cpp
@@ -146,7 +146,7 @@
                 },
 };
 
-#define STR_INTERFACE_ "fastboot"
+#define STR_INTERFACE_ "fastbootd"
 
 static const struct {
     struct usb_functionfs_strings_head header;
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 7f6e723..7abc936 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -258,6 +258,10 @@
 static int list_devices_callback(usb_ifc_info* info) {
     if (match_fastboot_with_serial(info, nullptr) == 0) {
         std::string serial = info->serial_number;
+        std::string interface = info->interface;
+        if (interface.empty()) {
+            interface = "fastboot";
+        }
         if (!info->writable) {
             serial = UsbNoPermissionsShortHelpText();
         }
@@ -266,9 +270,9 @@
         }
         // output compatible with "adb devices"
         if (!g_long_listing) {
-            printf("%s\tfastboot", serial.c_str());
+            printf("%s\t%s", serial.c_str(), interface.c_str());
         } else {
-            printf("%-22s fastboot", serial.c_str());
+            printf("%-22s %s", serial.c_str(), interface.c_str());
             if (strlen(info->device_path) > 0) printf(" %s", info->device_path);
         }
         putchar('\n');
diff --git a/fastboot/usb.h b/fastboot/usb.h
index 7ca44c4..e5f56e2 100644
--- a/fastboot/usb.h
+++ b/fastboot/usb.h
@@ -50,6 +50,8 @@
 
     char serial_number[256];
     char device_path[256];
+
+    char interface[256];
 };
 
 class UsbTransport : public Transport {
diff --git a/fastboot/usb_linux.cpp b/fastboot/usb_linux.cpp
index 6363aa5..964488c 100644
--- a/fastboot/usb_linux.cpp
+++ b/fastboot/usb_linux.cpp
@@ -43,6 +43,8 @@
 #include <linux/version.h>
 #include <linux/usb/ch9.h>
 
+#include <android-base/file.h>
+#include <android-base/stringprintf.h>
 #include <chrono>
 #include <memory>
 #include <thread>
@@ -263,6 +265,13 @@
         info.has_bulk_in = (in != -1);
         info.has_bulk_out = (out != -1);
 
+        std::string interface;
+        auto path = android::base::StringPrintf("/sys/bus/usb/devices/%s/%s:1.%d/interface",
+                                                sysfs_name, sysfs_name, ifc->bInterfaceNumber);
+        if (android::base::ReadFileToString(path, &interface)) {
+            snprintf(info.interface, sizeof(info.interface), "%s", interface.c_str());
+        }
+
         if(callback(&info) == 0) {
             *ept_in_id = in;
             *ept_out_id = out;
diff --git a/fastboot/usb_osx.cpp b/fastboot/usb_osx.cpp
index 8a3c213..610eebf 100644
--- a/fastboot/usb_osx.cpp
+++ b/fastboot/usb_osx.cpp
@@ -368,6 +368,7 @@
         // device has no serial number
         handle->info.serial_number[0] = 0;
     }
+    handle->info.interface[0] = 0;
     handle->info.writable = 1;
 
     if (try_interfaces(dev, handle)) {
diff --git a/fastboot/usb_windows.cpp b/fastboot/usb_windows.cpp
index bf840f8..67bf8a3 100644
--- a/fastboot/usb_windows.cpp
+++ b/fastboot/usb_windows.cpp
@@ -319,6 +319,7 @@
                     &serial_number_len, true)) {
         info.serial_number[0] = 0;
     }
+    info.interface[0] = 0;
 
     info.device_path[0] = 0;
 
diff --git a/fs_mgr/libdm/dm.cpp b/fs_mgr/libdm/dm.cpp
index 673e145..7912688 100644
--- a/fs_mgr/libdm/dm.cpp
+++ b/fs_mgr/libdm/dm.cpp
@@ -29,6 +29,7 @@
 #include <android-base/file.h>
 #include <android-base/logging.h>
 #include <android-base/macros.h>
+#include <android-base/properties.h>
 #include <android-base/strings.h>
 #include <uuid/uuid.h>
 
@@ -140,6 +141,10 @@
     return std::string{uuid_chars};
 }
 
+static bool IsRecovery() {
+    return access("/system/bin/recovery", F_OK) == 0;
+}
+
 bool DeviceMapper::CreateDevice(const std::string& name, const DmTable& table, std::string* path,
                                 const std::chrono::milliseconds& timeout_ms) {
     std::string uuid = GenerateUuid();
@@ -160,6 +165,16 @@
     if (timeout_ms <= std::chrono::milliseconds::zero()) {
         return true;
     }
+
+    if (IsRecovery()) {
+        bool non_ab_device = android::base::GetProperty("ro.build.ab_update", "").empty();
+        int sdk = android::base::GetIntProperty("ro.build.version.sdk", 0);
+        if (non_ab_device && sdk && sdk <= 29) {
+            LOG(INFO) << "Detected ueventd incompatibility, reverting to legacy libdm behavior.";
+            unique_path = *path;
+        }
+    }
+
     if (!WaitForFile(unique_path, timeout_ms)) {
         LOG(ERROR) << "Failed waiting for device path: " << unique_path;
         DeleteDevice(name);
diff --git a/fs_mgr/libsnapshot/android/snapshot/snapshot.proto b/fs_mgr/libsnapshot/android/snapshot/snapshot.proto
index 2ac0c44..0328132 100644
--- a/fs_mgr/libsnapshot/android/snapshot/snapshot.proto
+++ b/fs_mgr/libsnapshot/android/snapshot/snapshot.proto
@@ -132,7 +132,7 @@
     uint64 metadata_sectors = 4;
 }
 
-// Next: 2
+// Next: 4
 message SnapshotMergeReport {
     // Status of the update after the merge attempts.
     UpdateState state = 1;
@@ -140,4 +140,7 @@
     // Number of reboots that occurred after issuing and before completeing the
     // merge of all the snapshot devices.
     int32 resume_count = 2;
+
+    // Total size of all the COW images before the update.
+    uint64 cow_file_size = 3;
 }
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/mock_snapshot.h b/fs_mgr/libsnapshot/include/libsnapshot/mock_snapshot.h
index cf0b085..4457de3 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/mock_snapshot.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/mock_snapshot.h
@@ -25,7 +25,7 @@
     MOCK_METHOD(bool, BeginUpdate, (), (override));
     MOCK_METHOD(bool, CancelUpdate, (), (override));
     MOCK_METHOD(bool, FinishedSnapshotWrites, (bool wipe), (override));
-    MOCK_METHOD(bool, InitiateMerge, (), (override));
+    MOCK_METHOD(bool, InitiateMerge, (uint64_t * cow_file_size), (override));
 
     MOCK_METHOD(UpdateState, ProcessUpdateState,
                 (const std::function<bool()>& callback, const std::function<bool()>& before_cancel),
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h b/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
index 2d6071f..3c2c776 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
@@ -124,7 +124,7 @@
 
     // Initiate a merge on all snapshot devices. This should only be used after an
     // update has been marked successful after booting.
-    virtual bool InitiateMerge() = 0;
+    virtual bool InitiateMerge(uint64_t* cow_file_size = nullptr) = 0;
 
     // Perform any necessary post-boot actions. This should be run soon after
     // /data is mounted.
@@ -281,7 +281,7 @@
     bool BeginUpdate() override;
     bool CancelUpdate() override;
     bool FinishedSnapshotWrites(bool wipe) override;
-    bool InitiateMerge() override;
+    bool InitiateMerge(uint64_t* cow_file_size = nullptr) override;
     UpdateState ProcessUpdateState(const std::function<bool()>& callback = {},
                                    const std::function<bool()>& before_cancel = {}) override;
     UpdateState GetUpdateState(double* progress = nullptr) override;
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/snapshot_stats.h b/fs_mgr/libsnapshot/include/libsnapshot/snapshot_stats.h
index 4caf632..d691d4f 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/snapshot_stats.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/snapshot_stats.h
@@ -29,6 +29,8 @@
     // Called when merge starts or resumes.
     virtual bool Start() = 0;
     virtual void set_state(android::snapshot::UpdateState state) = 0;
+    virtual void set_cow_file_size(uint64_t cow_file_size) = 0;
+    virtual uint64_t cow_file_size() = 0;
 
     // Called when merge ends. Properly clean up permanent storage.
     class Result {
@@ -50,6 +52,8 @@
     // ISnapshotMergeStats overrides
     bool Start() override;
     void set_state(android::snapshot::UpdateState state) override;
+    void set_cow_file_size(uint64_t cow_file_size) override;
+    uint64_t cow_file_size() override;
     std::unique_ptr<Result> Finish() override;
 
   private:
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/snapshot_stub.h b/fs_mgr/libsnapshot/include/libsnapshot/snapshot_stub.h
index 9c82906..7a27fad 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/snapshot_stub.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/snapshot_stub.h
@@ -27,7 +27,7 @@
     bool BeginUpdate() override;
     bool CancelUpdate() override;
     bool FinishedSnapshotWrites(bool wipe) override;
-    bool InitiateMerge() override;
+    bool InitiateMerge(uint64_t* cow_file_size = nullptr) override;
     UpdateState ProcessUpdateState(const std::function<bool()>& callback = {},
                                    const std::function<bool()>& before_cancel = {}) override;
     UpdateState GetUpdateState(double* progress = nullptr) override;
diff --git a/fs_mgr/libsnapshot/snapshot.cpp b/fs_mgr/libsnapshot/snapshot.cpp
index 488009a..5909cff 100644
--- a/fs_mgr/libsnapshot/snapshot.cpp
+++ b/fs_mgr/libsnapshot/snapshot.cpp
@@ -555,7 +555,7 @@
     return true;
 }
 
-bool SnapshotManager::InitiateMerge() {
+bool SnapshotManager::InitiateMerge(uint64_t* cow_file_size) {
     auto lock = LockExclusive();
     if (!lock) return false;
 
@@ -618,6 +618,7 @@
         }
     }
 
+    uint64_t total_cow_file_size = 0;
     DmTargetSnapshot::Status initial_target_values = {};
     for (const auto& snapshot : snapshots) {
         DmTargetSnapshot::Status current_status;
@@ -627,6 +628,16 @@
         initial_target_values.sectors_allocated += current_status.sectors_allocated;
         initial_target_values.total_sectors += current_status.total_sectors;
         initial_target_values.metadata_sectors += current_status.metadata_sectors;
+
+        SnapshotStatus snapshot_status;
+        if (!ReadSnapshotStatus(lock.get(), snapshot, &snapshot_status)) {
+            return false;
+        }
+        total_cow_file_size += snapshot_status.cow_file_size();
+    }
+
+    if (cow_file_size) {
+        *cow_file_size = total_cow_file_size;
     }
 
     SnapshotUpdateStatus initial_status;
diff --git a/fs_mgr/libsnapshot/snapshot_stats.cpp b/fs_mgr/libsnapshot/snapshot_stats.cpp
index 5da7b98..3723730 100644
--- a/fs_mgr/libsnapshot/snapshot_stats.cpp
+++ b/fs_mgr/libsnapshot/snapshot_stats.cpp
@@ -88,6 +88,15 @@
     report_.set_state(state);
 }
 
+void SnapshotMergeStats::set_cow_file_size(uint64_t cow_file_size) {
+    report_.set_cow_file_size(cow_file_size);
+    WriteState();
+}
+
+uint64_t SnapshotMergeStats::cow_file_size() {
+    return report_.cow_file_size();
+}
+
 class SnapshotMergeStatsResultImpl : public SnapshotMergeStats::Result {
   public:
     SnapshotMergeStatsResultImpl(const SnapshotMergeReport& report,
diff --git a/fs_mgr/libsnapshot/snapshot_stub.cpp b/fs_mgr/libsnapshot/snapshot_stub.cpp
index 2aaa78c..9b6f758 100644
--- a/fs_mgr/libsnapshot/snapshot_stub.cpp
+++ b/fs_mgr/libsnapshot/snapshot_stub.cpp
@@ -42,7 +42,7 @@
     return false;
 }
 
-bool SnapshotManagerStub::InitiateMerge() {
+bool SnapshotManagerStub::InitiateMerge(uint64_t*) {
     LOG(ERROR) << __FUNCTION__ << " should never be called.";
     return false;
 }
@@ -118,6 +118,8 @@
 class SnapshotMergeStatsStub : public ISnapshotMergeStats {
     bool Start() override { return false; }
     void set_state(android::snapshot::UpdateState) override {}
+    void set_cow_file_size(uint64_t) override {}
+    uint64_t cow_file_size() override { return 0; }
     std::unique_ptr<Result> Finish() override { return nullptr; }
 };