Merge "Choose options format using property" into rvc-dev
diff --git a/Keymaster.cpp b/Keymaster.cpp
index c3f2912..786cdb5 100644
--- a/Keymaster.cpp
+++ b/Keymaster.cpp
@@ -229,13 +229,19 @@
 }
 
 void Keymaster::earlyBootEnded() {
-    auto error = mDevice->earlyBootEnded();
-    if (!error.isOk()) {
-        LOG(ERROR) << "earlyBootEnded failed: " << error.description();
-    }
-    km::V4_1_ErrorCode km_error = error;
-    if (km_error != km::V4_1_ErrorCode::OK && km_error != km::V4_1_ErrorCode::UNIMPLEMENTED) {
-        LOG(ERROR) << "Error reporting early boot ending to keymaster: " << int32_t(km_error);
+    auto devices = KmDevice::enumerateAvailableDevices();
+    for (auto& dev : devices) {
+        auto error = dev->earlyBootEnded();
+        if (!error.isOk()) {
+            LOG(ERROR) << "earlyBootEnded call failed: " << error.description() << " for "
+                       << dev->halVersion().keymasterName;
+        }
+        km::V4_1_ErrorCode km_error = error;
+        if (km_error != km::V4_1_ErrorCode::OK && km_error != km::V4_1_ErrorCode::UNIMPLEMENTED) {
+            LOG(ERROR) << "Error reporting early boot ending to keymaster: "
+                       << static_cast<int32_t>(km_error) << " for "
+                       << dev->halVersion().keymasterName;
+        }
     }
 }
 
diff --git a/Keymaster.h b/Keymaster.h
index 4a9ed02..d9ced91 100644
--- a/Keymaster.h
+++ b/Keymaster.h
@@ -128,9 +128,9 @@
                              km::AuthorizationSet* outParams);
     bool isSecure();
 
-    // Tell Keymaster that early boot has ended and early boot-only keys can no longer be created or
-    // used.
-    void earlyBootEnded();
+    // Tell all Keymaster instances that early boot has ended and early boot-only keys can no longer
+    // be created or used.
+    static void earlyBootEnded();
 
   private:
     sp<KmDevice> mDevice;
diff --git a/MetadataCrypt.cpp b/MetadataCrypt.cpp
index 7b2219b..b97be9d 100644
--- a/MetadataCrypt.cpp
+++ b/MetadataCrypt.cpp
@@ -87,13 +87,9 @@
 }
 
 static bool mount_via_fs_mgr(const char* mount_point, const char* blk_device) {
-    // We're about to mount data not verified by verified boot.  Tell Keymaster that early boot has
-    // ended.
-    //
-    // TODO(paulcrowley): Make a Keymaster singleton or something, so we don't have to repeatedly
-    // open and initialize the service.
-    ::android::vold::Keymaster keymaster;
-    keymaster.earlyBootEnded();
+    // We're about to mount data not verified by verified boot.  Tell Keymaster instances that early
+    // boot has ended.
+    ::android::vold::Keymaster::earlyBootEnded();
 
     // fs_mgr_do_mount runs fsck. Use setexeccon to run trusted
     // partitions in the fsck domain.
diff --git a/VoldNativeService.cpp b/VoldNativeService.cpp
index 5a77a83..0cce561 100644
--- a/VoldNativeService.cpp
+++ b/VoldNativeService.cpp
@@ -18,6 +18,17 @@
 
 #include "VoldNativeService.h"
 
+#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
+#include <fs_mgr.h>
+#include <fscrypt/fscrypt.h>
+#include <private/android_filesystem_config.h>
+#include <utils/Trace.h>
+
+#include <fstream>
+#include <thread>
+
 #include "Benchmark.h"
 #include "CheckEncryption.h"
 #include "Checkpoint.h"
@@ -30,20 +41,8 @@
 #include "VoldUtil.h"
 #include "VolumeManager.h"
 #include "cryptfs.h"
-
 #include "incfs_ndk.h"
 
-#include <fstream>
-#include <thread>
-
-#include <android-base/logging.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-#include <fs_mgr.h>
-#include <fscrypt/fscrypt.h>
-#include <private/android_filesystem_config.h>
-#include <utils/Trace.h>
-
 using android::base::StringPrintf;
 using std::endl;
 using namespace std::literals;
@@ -144,7 +143,7 @@
 }
 
 binder::Status VoldNativeService::setListener(
-    const android::sp<android::os::IVoldListener>& listener) {
+        const android::sp<android::os::IVoldListener>& listener) {
     ENFORCE_SYSTEM_OR_ROOT;
     ACQUIRE_LOCK;
 
@@ -332,7 +331,7 @@
 }
 
 binder::Status VoldNativeService::benchmark(
-    const std::string& volId, const android::sp<android::os::IVoldTaskListener>& listener) {
+        const std::string& volId, const android::sp<android::os::IVoldTaskListener>& listener) {
     ENFORCE_SYSTEM_OR_ROOT;
     CHECK_ARGUMENT_ID(volId);
     ACQUIRE_LOCK;
@@ -357,8 +356,8 @@
 }
 
 binder::Status VoldNativeService::moveStorage(
-    const std::string& fromVolId, const std::string& toVolId,
-    const android::sp<android::os::IVoldTaskListener>& listener) {
+        const std::string& fromVolId, const std::string& toVolId,
+        const android::sp<android::os::IVoldTaskListener>& listener) {
     ENFORCE_SYSTEM_OR_ROOT;
     CHECK_ARGUMENT_ID(fromVolId);
     CHECK_ARGUMENT_ID(toVolId);
@@ -416,7 +415,7 @@
     ACQUIRE_LOCK;
 
     return translate(
-        VolumeManager::Instance()->createObb(sourcePath, sourceKey, ownerGid, _aidl_return));
+            VolumeManager::Instance()->createObb(sourcePath, sourceKey, ownerGid, _aidl_return));
 }
 
 binder::Status VoldNativeService::destroyObb(const std::string& volId) {
@@ -454,7 +453,7 @@
 }
 
 binder::Status VoldNativeService::fstrim(
-    int32_t fstrimFlags, const android::sp<android::os::IVoldTaskListener>& listener) {
+        int32_t fstrimFlags, const android::sp<android::os::IVoldTaskListener>& listener) {
     ENFORCE_SYSTEM_OR_ROOT;
     ACQUIRE_LOCK;
 
@@ -463,7 +462,7 @@
 }
 
 binder::Status VoldNativeService::runIdleMaint(
-    const android::sp<android::os::IVoldTaskListener>& listener) {
+        const android::sp<android::os::IVoldTaskListener>& listener) {
     ENFORCE_SYSTEM_OR_ROOT;
     ACQUIRE_LOCK;
 
@@ -472,7 +471,7 @@
 }
 
 binder::Status VoldNativeService::abortIdleMaint(
-    const android::sp<android::os::IVoldTaskListener>& listener) {
+        const android::sp<android::os::IVoldTaskListener>& listener) {
     ENFORCE_SYSTEM_OR_ROOT;
     ACQUIRE_LOCK;
 
@@ -689,7 +688,8 @@
     return translateBool(fscrypt_mount_metadata_encrypted(blkDevice, mountPoint, true));
 }
 
-binder::Status VoldNativeService::createUserKey(int32_t userId, int32_t userSerial, bool ephemeral) {
+binder::Status VoldNativeService::createUserKey(int32_t userId, int32_t userSerial,
+                                                bool ephemeral) {
     ENFORCE_SYSTEM_OR_ROOT;
     ACQUIRE_CRYPT_LOCK;
 
@@ -890,19 +890,22 @@
     CHECK_ARGUMENT_PATH(backingPath);
     CHECK_ARGUMENT_PATH(targetDir);
 
-    auto result = IncFs_Mount(backingPath.c_str(), targetDir.c_str(),
-                              {.flags = IncFsMountFlags(flags),
-                               .defaultReadTimeoutMs = INCFS_DEFAULT_READ_TIMEOUT_MS,
-                               .readLogBufferPages = 4});
-    if (result.cmd < 0) {
-        return translate(result.cmd);
+    auto control = IncFs_Mount(backingPath.c_str(), targetDir.c_str(),
+                               {.flags = IncFsMountFlags(flags),
+                                .defaultReadTimeoutMs = INCFS_DEFAULT_READ_TIMEOUT_MS,
+                                // Mount with read logs disabled.
+                                .readLogBufferPages = 0});
+    if (control == nullptr) {
+        return translate(-1);
     }
     using unique_fd = ::android::base::unique_fd;
-    _aidl_return->cmd.reset(unique_fd(result.cmd));
-    _aidl_return->pendingReads.reset(unique_fd(result.pendingReads));
-    if (result.logs >= 0) {
-        _aidl_return->log.reset(unique_fd(result.logs));
+    _aidl_return->cmd.reset(unique_fd(dup(IncFs_GetControlFd(control, CMD))));
+    _aidl_return->pendingReads.reset(unique_fd(dup(IncFs_GetControlFd(control, PENDING_READS))));
+    auto logsFd = IncFs_GetControlFd(control, LOGS);
+    if (logsFd >= 0) {
+        _aidl_return->log.reset(unique_fd(dup(logsFd)));
     }
+    IncFs_DeleteControl(control);
     return Ok();
 }
 
@@ -913,6 +916,26 @@
     return translate(IncFs_Unmount(dir.c_str()));
 }
 
+binder::Status VoldNativeService::setIncFsMountOptions(
+        const ::android::os::incremental::IncrementalFileSystemControlParcel& control,
+        bool enableReadLogs) {
+    ENFORCE_SYSTEM_OR_ROOT;
+
+    auto status = Ok();
+    auto incfsControl = IncFs_CreateControl(dup(control.cmd.get()), dup(control.pendingReads.get()),
+                                            dup(control.log.get()));
+    if (auto error = IncFs_SetOptions(
+                incfsControl,
+                {.defaultReadTimeoutMs = INCFS_DEFAULT_READ_TIMEOUT_MS,
+                 .readLogBufferPages = enableReadLogs ? INCFS_DEFAULT_PAGE_READ_BUFFER_PAGES : 0});
+        error < 0) {
+        status = binder::Status::fromServiceSpecificError(error);
+    }
+    IncFs_DeleteControl(incfsControl);
+
+    return status;
+}
+
 binder::Status VoldNativeService::bindMount(const std::string& sourceDir,
                                             const std::string& targetDir) {
     ENFORCE_SYSTEM_OR_ROOT;
diff --git a/VoldNativeService.h b/VoldNativeService.h
index 2f4b6eb..060d704 100644
--- a/VoldNativeService.h
+++ b/VoldNativeService.h
@@ -154,6 +154,9 @@
             const std::string& backingPath, const std::string& targetDir, int32_t flags,
             ::android::os::incremental::IncrementalFileSystemControlParcel* _aidl_return) override;
     binder::Status unmountIncFs(const std::string& dir) override;
+    binder::Status setIncFsMountOptions(
+            const ::android::os::incremental::IncrementalFileSystemControlParcel& control,
+            bool enableReadLogs) override;
     binder::Status bindMount(const std::string& sourceDir, const std::string& targetDir) override;
 };
 
diff --git a/VoldNativeServiceValidation.cpp b/VoldNativeServiceValidation.cpp
index 2e21ace..ee1e65a 100644
--- a/VoldNativeServiceValidation.cpp
+++ b/VoldNativeServiceValidation.cpp
@@ -39,11 +39,10 @@
 }
 
 binder::Status CheckPermission(const char* permission) {
-    pid_t pid;
-    uid_t uid;
+    int32_t pid;
+    int32_t uid;
 
-    if (checkCallingPermission(String16(permission), reinterpret_cast<int32_t*>(&pid),
-                               reinterpret_cast<int32_t*>(&uid))) {
+    if (checkCallingPermission(String16(permission), &pid, &uid)) {
         return Ok();
     } else {
         return Exception(binder::Status::EX_SECURITY,
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index 6a40a52..e4e5781 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -776,7 +776,8 @@
 }
 
 // Fork the process and remount storage
-static bool forkAndRemountStorage(int uid, int pid, const std::vector<std::string>& packageNames) {
+bool VolumeManager::forkAndRemountStorage(int uid, int pid,
+                                          const std::vector<std::string>& packageNames) {
     userid_t userId = multiuser_get_user_id(uid);
     std::string mnt_path = StringPrintf("/proc/%d/ns/mnt", pid);
     android::base::unique_fd nsFd(
@@ -814,7 +815,8 @@
             PLOG(ERROR) << "Failed to create dir: " << sources_cstr[i];
             return false;
         }
-        status = EnsureDirExists(targets_cstr[i], 0771, AID_MEDIA_RW, AID_MEDIA_RW);
+        // Make sure /storage/emulated/... paths are setup correctly
+        status = setupAppDir(targets_cstr[i], uid, false /* fixupExistingOnly */);
         if (status != OK) {
             PLOG(ERROR) << "Failed to create dir: " << targets_cstr[i];
             return false;
diff --git a/VolumeManager.h b/VolumeManager.h
index b83871e..a9087fd 100644
--- a/VolumeManager.h
+++ b/VolumeManager.h
@@ -130,6 +130,8 @@
     int updateVirtualDisk();
     int setDebug(bool enable);
 
+    bool forkAndRemountStorage(int uid, int pid, const std::vector<std::string>& packageNames);
+
     static VolumeManager* Instance();
 
     /*
diff --git a/binder/android/os/IVold.aidl b/binder/android/os/IVold.aidl
index 1d5657f..68e2ba9 100644
--- a/binder/android/os/IVold.aidl
+++ b/binder/android/os/IVold.aidl
@@ -135,6 +135,7 @@
     boolean incFsEnabled();
     IncrementalFileSystemControlParcel mountIncFs(@utf8InCpp String backingPath, @utf8InCpp String targetDir, int flags);
     void unmountIncFs(@utf8InCpp String dir);
+    void setIncFsMountOptions(in IncrementalFileSystemControlParcel control, boolean enableReadLogs);
     void bindMount(@utf8InCpp String sourceDir, @utf8InCpp String targetDir);
 
     const int ENCRYPTION_FLAG_NO_UI = 4;
diff --git a/model/PrivateVolume.cpp b/model/PrivateVolume.cpp
index a54b05e..75757f7 100644
--- a/model/PrivateVolume.cpp
+++ b/model/PrivateVolume.cpp
@@ -43,6 +43,7 @@
 namespace android {
 namespace vold {
 
+static const unsigned int kMajorBlockLoop = 7;
 static const unsigned int kMajorBlockMmc = 179;
 
 PrivateVolume::PrivateVolume(dev_t device, const KeyBuffer& keyRaw)
@@ -207,7 +208,9 @@
     if (fsType == "auto") {
         // For now, assume that all MMC devices are flash-based SD cards, and
         // give everyone else ext4 because sysfs rotational isn't reliable.
-        if ((major(mRawDevice) == kMajorBlockMmc) && f2fs::IsSupported()) {
+        // Additionally, prefer f2fs for loop-bases devices
+        if ((major(mRawDevice) == kMajorBlockMmc || major(mRawDevice) == kMajorBlockLoop) &&
+            f2fs::IsSupported()) {
             resolvedFsType = "f2fs";
         } else {
             resolvedFsType = "ext4";