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/VolumeManager.cpp b/VolumeManager.cpp
index e29b920..d47d9f3 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -68,6 +68,7 @@
 #include "model/EmulatedVolume.h"
 #include "model/ObbVolume.h"
 #include "model/PrivateVolume.h"
+#include "model/PublicVolume.h"
 #include "model/StubVolume.h"
 
 using android::OK;
@@ -88,6 +89,7 @@
 using android::vold::PrepareAndroidDirs;
 using android::vold::PrepareAppDirFromRoot;
 using android::vold::PrivateVolume;
+using android::vold::PublicVolume;
 using android::vold::Symlink;
 using android::vold::Unlink;
 using android::vold::UnmountTree;
@@ -457,6 +459,31 @@
 
     if (mStartedUsers.find(userId) == mStartedUsers.end()) {
         createEmulatedVolumesForUser(userId);
+        std::list<std::string> public_vols;
+        listVolumes(VolumeBase::Type::kPublic, public_vols);
+        for (const std::string& id : public_vols) {
+            PublicVolume* pvol = static_cast<PublicVolume*>(findVolume(id).get());
+            if (pvol->getState() != VolumeBase::State::kMounted) {
+                continue;
+            }
+            if (pvol->isVisible() == 0) {
+                continue;
+            }
+            userid_t mountUserId = pvol->getMountUserId();
+            if (userId == mountUserId) {
+                // No need to bind mount for the user that owns the mount
+                continue;
+            }
+            if (mountUserId != VolumeManager::Instance()->getSharedStorageUser(userId)) {
+                // No need to bind if the user does not share storage with the mount owner
+                continue;
+            }
+            auto bindMountStatus = pvol->bindMountForUser(userId);
+            if (bindMountStatus != OK) {
+                LOG(ERROR) << "Bind Mounting Public Volume: " << pvol << " for user: " << userId
+                           << "Failed. Error: " << bindMountStatus;
+            }
+        }
     }
 
     mStartedUsers.insert(userId);