Adding public volume mounts for clone user.

Public SdCard Volumes are mounted only for user 0
(foreground user). This gives ENONT if the cloned
user tries to access the files in SdCard with
paths like "/storage/AB02-G212/DCIM/"

This change adds SdCard Volume mnt under
/mnt/usr/<cloned-user>/ which allows cloned apps
access to SdCard via direct file paths.

Bug: 203395175
Test: Manual by building and flashing device.
Change-Id: I091c40d3cb19915145cd5af40d1e79d5a9ecfa02
diff --git a/model/PublicVolume.cpp b/model/PublicVolume.cpp
index 034fb23..e86d002 100644
--- a/model/PublicVolume.cpp
+++ b/model/PublicVolume.cpp
@@ -257,9 +257,45 @@
     // See comment in model/EmulatedVolume.cpp
     ConfigureMaxDirtyRatioForFuse(GetFuseMountPathForUser(user_id, stableName), 40u);
 
+    auto vol_manager = VolumeManager::Instance();
+    // Create bind mounts for all running users
+    for (userid_t started_user : vol_manager->getStartedUsers()) {
+        userid_t mountUserId = getMountUserId();
+        if (started_user == mountUserId) {
+            // No need to bind mount for the user that owns the mount
+            continue;
+        }
+        if (mountUserId != VolumeManager::Instance()->getSharedStorageUser(started_user)) {
+            // No need to bind if the user does not share storage with the mount owner
+            continue;
+        }
+        auto bindMountStatus = bindMountForUser(started_user);
+        if (bindMountStatus != OK) {
+            LOG(ERROR) << "Bind Mounting Public Volume: " << stableName
+                       << " for user: " << started_user << "Failed. Error: " << bindMountStatus;
+        }
+    }
     return OK;
 }
 
+status_t PublicVolume::bindMountForUser(userid_t user_id) {
+    userid_t mountUserId = getMountUserId();
+    std::string stableName = getId();
+    if (!mFsUuid.empty()) {
+        stableName = mFsUuid;
+    }
+
+    LOG(INFO) << "Bind Mounting Public Volume for user: " << user_id
+              << ".Mount owner: " << mountUserId;
+    auto sourcePath = GetFuseMountPathForUser(mountUserId, stableName);
+    auto destPath = GetFuseMountPathForUser(user_id, stableName);
+    PrepareDir(destPath, 0770, AID_ROOT, AID_MEDIA_RW);
+    auto mountRes = BindMount(sourcePath, destPath);
+    LOG(INFO) << "Mount status: " << mountRes;
+
+    return mountRes;
+}
+
 status_t PublicVolume::doUnmount() {
     // Unmount the storage before we kill the FUSE process. If we kill
     // the FUSE process first, most file system operations will return
@@ -274,6 +310,20 @@
             stableName = mFsUuid;
         }
 
+        // Unmount bind mounts for running users
+        auto vol_manager = VolumeManager::Instance();
+        int user_id = getMountUserId();
+        for (int started_user : vol_manager->getStartedUsers()) {
+            if (started_user == user_id) {
+                // No need to remove bind mount for the user that owns the mount
+                continue;
+            }
+            LOG(INFO) << "Removing Public Volume Bind Mount for: " << started_user;
+            auto mountPath = GetFuseMountPathForUser(started_user, stableName);
+            ForceUnmount(mountPath);
+            rmdir(mountPath.c_str());
+        }
+
         if (UnmountUserFuse(getMountUserId(), getInternalPath(), stableName) != OK) {
             PLOG(INFO) << "UnmountUserFuse failed on public fuse volume";
             return -errno;