Merge "DO NOT MERGE - Skip pi-platform-release (PPRL.190505.001) in stage-aosp-master" into stage-aosp-master
diff --git a/fastboot/fuzzy_fastboot/main.cpp b/fastboot/fuzzy_fastboot/main.cpp
index ff918a7..a1d69d2 100644
--- a/fastboot/fuzzy_fastboot/main.cpp
+++ b/fastboot/fuzzy_fastboot/main.cpp
@@ -244,16 +244,29 @@
 // Testing creation/resize/delete of logical partitions
 TEST_F(LogicalPartitionCompliance, CreateResizeDeleteLP) {
     ASSERT_TRUE(UserSpaceFastboot());
+    std::string test_partition_name = "test_partition";
+    std::string slot_count;
+    // Add suffix to test_partition_name if device is slotted.
+    EXPECT_EQ(fb->GetVar("slot-count", &slot_count), SUCCESS) << "getvar slot-count failed";
+    int32_t num_slots = strtol(slot_count.c_str(), nullptr, 10);
+    if (num_slots > 0) {
+        std::string current_slot;
+        EXPECT_EQ(fb->GetVar("current-slot", &current_slot), SUCCESS)
+                << "getvar current-slot failed";
+        std::string slot_suffix = "_" + current_slot;
+        test_partition_name += slot_suffix;
+    }
+
     GTEST_LOG_(INFO) << "Testing 'fastboot create-logical-partition' command";
-    EXPECT_EQ(fb->CreatePartition("test_partition_a", "0"), SUCCESS)
+    EXPECT_EQ(fb->CreatePartition(test_partition_name, "0"), SUCCESS)
             << "create-logical-partition failed";
     GTEST_LOG_(INFO) << "Testing 'fastboot resize-logical-partition' command";
-    EXPECT_EQ(fb->ResizePartition("test_partition_a", "4096"), SUCCESS)
+    EXPECT_EQ(fb->ResizePartition(test_partition_name, "4096"), SUCCESS)
             << "resize-logical-partition failed";
     std::vector<char> buf(4096);
 
     GTEST_LOG_(INFO) << "Flashing a logical partition..";
-    EXPECT_EQ(fb->FlashPartition("test_partition_a", buf), SUCCESS)
+    EXPECT_EQ(fb->FlashPartition(test_partition_name, buf), SUCCESS)
             << "flash logical -partition failed";
     GTEST_LOG_(INFO) << "Rebooting to bootloader mode";
     // Reboot to bootloader mode and attempt to flash the logical partitions
@@ -262,7 +275,7 @@
     ReconnectFastbootDevice();
     ASSERT_FALSE(UserSpaceFastboot());
     GTEST_LOG_(INFO) << "Attempt to flash a logical partition..";
-    EXPECT_EQ(fb->FlashPartition("test_partition", buf), DEVICE_FAIL)
+    EXPECT_EQ(fb->FlashPartition(test_partition_name, buf), DEVICE_FAIL)
             << "flash logical partition must fail in bootloader";
     GTEST_LOG_(INFO) << "Rebooting back to fastbootd mode";
     fb->RebootTo("fastboot");
@@ -270,7 +283,7 @@
     ReconnectFastbootDevice();
     ASSERT_TRUE(UserSpaceFastboot());
     GTEST_LOG_(INFO) << "Testing 'fastboot delete-logical-partition' command";
-    EXPECT_EQ(fb->DeletePartition("test_partition_a"), SUCCESS)
+    EXPECT_EQ(fb->DeletePartition(test_partition_name), SUCCESS)
             << "delete logical-partition failed";
 }
 
diff --git a/fs_mgr/README.overlayfs.md b/fs_mgr/README.overlayfs.md
index f89e598..d204bfd 100644
--- a/fs_mgr/README.overlayfs.md
+++ b/fs_mgr/README.overlayfs.md
@@ -117,3 +117,25 @@
   be used to clear scratch storage to permit the flash.
   Then reinstate the overrides and continue.
 - File bugs or submit fixes for review.
+- There are other subtle caveats requiring complex logic to solve.
+  Have evaluated them as too complex or not worth the trouble, please
+  File a bug if a use case needs to be covered.
+  - The backing storage is treated fragile, if anything else has
+    issue with the space taken, the backing storage will be cleared
+    out and we reserve the right to not inform, if the layering
+    does not prevent any messaging.
+  - Space remaining threshold is hard coded.  If 1% or more space
+    still remains, overlayfs will not be used, yet that amount of
+    space remaining is problematic.
+  - Flashing a partition via bootloader fastboot, as opposed to user
+    space fastbootd, is not detected, thus a partition may have
+    override content remaining.  adb enable-verity to wipe.
+  - Space is limited, there is near unlimited space on userdata,
+    we have made an architectural decision to not utilize
+    /data/overlay/ at this time.  Acquiring space to use for
+    backing remains an ongoing battle.
+  - First stage init, or ramdisk, can not be overriden.
+  - Backing storage will be discarded or ignored on errors, leading
+    to confusion.  When debugging using **adb remount** it is
+    currently advised to confirm update is present after a reboot
+    to develop confidence.
diff --git a/fs_mgr/fs_mgr_roots.cpp b/fs_mgr/fs_mgr_roots.cpp
index 58ef9b6..1e65587 100644
--- a/fs_mgr/fs_mgr_roots.cpp
+++ b/fs_mgr/fs_mgr_roots.cpp
@@ -101,7 +101,9 @@
         }
     }
 
-    auto mounted = GetMountState(rec->mount_point);
+    const std::string mount_point = mount_pt.empty() ? rec->mount_point : mount_pt;
+
+    auto mounted = GetMountState(mount_point);
     if (mounted == MountState::ERROR) {
         return false;
     }
@@ -109,8 +111,6 @@
         return true;
     }
 
-    const std::string mount_point = mount_pt.empty() ? rec->mount_point : mount_pt;
-
     static const std::vector<std::string> supported_fs{"ext4", "squashfs", "vfat", "f2fs", "none"};
     if (std::find(supported_fs.begin(), supported_fs.end(), rec->fs_type) == supported_fs.end()) {
         LERROR << "unknown fs_type \"" << rec->fs_type << "\" for " << mount_point;
diff --git a/fs_mgr/libdm/dm_target.cpp b/fs_mgr/libdm/dm_target.cpp
index f440e6d..da1013e 100644
--- a/fs_mgr/libdm/dm_target.cpp
+++ b/fs_mgr/libdm/dm_target.cpp
@@ -16,6 +16,9 @@
 
 #include "libdm/dm_target.h"
 
+#include <stdio.h>
+#include <sys/types.h>
+
 #include <android-base/logging.h>
 #include <android-base/macros.h>
 #include <android-base/parseint.h>
@@ -193,5 +196,30 @@
     return true;
 }
 
+std::string DmTargetCrypt::GetParameterString() const {
+    std::vector<std::string> argv = {
+            cipher_,
+            key_,
+            std::to_string(iv_sector_offset_),
+            device_,
+            std::to_string(device_sector_),
+    };
+
+    std::vector<std::string> extra_argv;
+    if (allow_discards_) extra_argv.emplace_back("allow_discards");
+    if (allow_encrypt_override_) extra_argv.emplace_back("allow_encrypt_override");
+    if (iv_large_sectors_) extra_argv.emplace_back("iv_large_sectors");
+    if (sector_size_) extra_argv.emplace_back("sector_size:" + std::to_string(sector_size_));
+
+    if (!extra_argv.empty()) argv.emplace_back(std::to_string(extra_argv.size()));
+
+    argv.insert(argv.end(), extra_argv.begin(), extra_argv.end());
+    return android::base::Join(argv, " ");
+}
+
+std::string DmTargetDefaultKey::GetParameterString() const {
+    return cipher_ + " " + key_ + " " + blockdev_ + " " + std::to_string(start_sector_);
+}
+
 }  // namespace dm
 }  // namespace android
diff --git a/fs_mgr/libdm/dm_test.cpp b/fs_mgr/libdm/dm_test.cpp
index 72a0e11..dc47c33 100644
--- a/fs_mgr/libdm/dm_test.cpp
+++ b/fs_mgr/libdm/dm_test.cpp
@@ -438,3 +438,26 @@
         ASSERT_EQ(status.error, "Invalid");
     }
 }
+
+TEST(libdm, CryptArgs) {
+    DmTargetCrypt target1(0, 512, "sha1", "abcdefgh", 50, "/dev/loop0", 100);
+    ASSERT_EQ(target1.name(), "crypt");
+    ASSERT_TRUE(target1.Valid());
+    ASSERT_EQ(target1.GetParameterString(), "sha1 abcdefgh 50 /dev/loop0 100");
+
+    DmTargetCrypt target2(0, 512, "sha1", "abcdefgh", 50, "/dev/loop0", 100);
+    target2.SetSectorSize(64);
+    target2.AllowDiscards();
+    target2.SetIvLargeSectors();
+    target2.AllowEncryptOverride();
+    ASSERT_EQ(target2.GetParameterString(),
+              "sha1 abcdefgh 50 /dev/loop0 100 4 allow_discards allow_encrypt_override "
+              "iv_large_sectors sector_size:64");
+}
+
+TEST(libdm, DefaultKeyArgs) {
+    DmTargetDefaultKey target(0, 4096, "AES-256-XTS", "abcdef0123456789", "/dev/loop0", 0);
+    ASSERT_EQ(target.name(), "default-key");
+    ASSERT_TRUE(target.Valid());
+    ASSERT_EQ(target.GetParameterString(), "AES-256-XTS abcdef0123456789 /dev/loop0 0");
+}
diff --git a/fs_mgr/libdm/include/libdm/dm_table.h b/fs_mgr/libdm/include/libdm/dm_table.h
index 5c639be..ee66653 100644
--- a/fs_mgr/libdm/include/libdm/dm_table.h
+++ b/fs_mgr/libdm/include/libdm/dm_table.h
@@ -43,12 +43,20 @@
     // successfully removed.
     bool RemoveTarget(std::unique_ptr<DmTarget>&& target);
 
+    // Adds a target, constructing it in-place for convenience. For example,
+    //
+    //   table.Emplace<DmTargetZero>(0, num_sectors);
+    template <typename T, typename... Args>
+    bool Emplace(Args&&... args) {
+        return AddTarget(std::make_unique<T>(std::forward<Args>(args)...));
+    }
+
     // Checks the table to make sure it is valid. i.e. Checks for range overlaps, range gaps
     // and returns 'true' if the table is ready to be loaded into kernel. Returns 'false' if the
     // table is malformed.
     bool valid() const;
 
-    // Returns the toatl number of targets.
+    // Returns the total number of targets.
     size_t num_targets() const { return targets_.size(); }
 
     // Returns the total size represented by the table in terms of number of 512-byte sectors.
diff --git a/fs_mgr/libdm/include/libdm/dm_target.h b/fs_mgr/libdm/include/libdm/dm_target.h
index fce1175..722922d 100644
--- a/fs_mgr/libdm/include/libdm/dm_target.h
+++ b/fs_mgr/libdm/include/libdm/dm_target.h
@@ -241,6 +241,60 @@
     std::string device_;
 };
 
+class DmTargetCrypt final : public DmTarget {
+  public:
+    DmTargetCrypt(uint64_t start, uint64_t length, const std::string& cipher,
+                  const std::string& key, uint64_t iv_sector_offset, const std::string& device,
+                  uint64_t device_sector)
+        : DmTarget(start, length),
+          cipher_(cipher),
+          key_(key),
+          iv_sector_offset_(iv_sector_offset),
+          device_(device),
+          device_sector_(device_sector) {}
+
+    void AllowDiscards() { allow_discards_ = true; }
+    void AllowEncryptOverride() { allow_encrypt_override_ = true; }
+    void SetIvLargeSectors() { iv_large_sectors_ = true; }
+    void SetSectorSize(uint32_t sector_size) { sector_size_ = sector_size; }
+
+    std::string name() const override { return "crypt"; }
+    bool Valid() const override { return true; }
+    std::string GetParameterString() const override;
+
+  private:
+    std::string cipher_;
+    std::string key_;
+    uint64_t iv_sector_offset_;
+    std::string device_;
+    uint64_t device_sector_;
+    bool allow_discards_ = false;
+    bool allow_encrypt_override_ = false;
+    bool iv_large_sectors_ = false;
+    uint32_t sector_size_ = 0;
+};
+
+class DmTargetDefaultKey final : public DmTarget {
+  public:
+    DmTargetDefaultKey(uint64_t start, uint64_t length, const std::string& cipher,
+                       const std::string& key, const std::string& blockdev, uint64_t start_sector)
+        : DmTarget(start, length),
+          cipher_(cipher),
+          key_(key),
+          blockdev_(blockdev),
+          start_sector_(start_sector) {}
+
+    std::string name() const override { return "default-key"; }
+    bool Valid() const override { return true; }
+    std::string GetParameterString() const override;
+
+  private:
+    std::string cipher_;
+    std::string key_;
+    std::string blockdev_;
+    uint64_t start_sector_;
+};
+
 }  // namespace dm
 }  // namespace android
 
diff --git a/libsync/Android.bp b/libsync/Android.bp
index e56f8ba..c996e1b 100644
--- a/libsync/Android.bp
+++ b/libsync/Android.bp
@@ -23,6 +23,7 @@
 cc_library {
     name: "libsync",
     recovery_available: true,
+    native_bridge_supported: true,
     defaults: ["libsync_defaults"],
 }
 
diff --git a/logd/tests/Android.bp b/logd/tests/Android.bp
index 83a194f..d39da8a 100644
--- a/logd/tests/Android.bp
+++ b/logd/tests/Android.bp
@@ -35,12 +35,12 @@
 
     srcs: ["logd_test.cpp"],
 
-    shared_libs: [
+    static_libs: [
         "libbase",
         "libcutils",
         "libselinux",
+        "liblog",
     ],
-    static_libs: ["liblog"],
 }
 
 // Build tests for the logger. Run with: