Setup Android/, Android/data and Android/obb dirs correctly.

Normally sdcardfs takes care of setting up these directories on-demand,
for example when an app requests its private data directory to be
created. On devices without sdcardfs however, we ourselves need to make
sure to setup the UID/GID of these directories correctly.

Introduce a new PrepareAndroidDirs() function which sets the dirs up
correctly. On devices without sdcardfs, that means:

Path              UID         GID         mode
/Android          media_rw    media_rw     771
/Android/data     media_rw    ext_data_rw  771
/Android/obb      media_rw    ext_obb_rw   771

Bug: 146419093
Test: wipe Android/, reboot, with and without sdcardfs, verify
      contents

Change-Id: I3a879089422c7fc449b6a3e6f1c4b386b86687a4
diff --git a/model/EmulatedVolume.cpp b/model/EmulatedVolume.cpp
index 082dea5..8f8c87a 100644
--- a/model/EmulatedVolume.cpp
+++ b/model/EmulatedVolume.cpp
@@ -73,17 +73,8 @@
     }
 }
 
-// Creates a bind mount from source to target, creating the source (!) directory
-// if not yet present.
+// Creates a bind mount from source to target
 static status_t doFuseBindMount(const std::string& source, const std::string& target) {
-    if (access(source.c_str(), F_OK) != 0) {
-        // Android path may not exist yet if users has just been created; create it on
-        // the lower fs.
-        if (fs_prepare_dir(source.c_str(), 0771, AID_MEDIA_RW, AID_MEDIA_RW) != 0) {
-            PLOG(ERROR) << "Failed to create " << source;
-            return -errno;
-        }
-    }
     LOG(INFO) << "Bind mounting " << source << " on " << target;
     auto status = BindMount(source, target);
     if (status != OK) {
@@ -232,11 +223,19 @@
         LOG(INFO) << "Mounting emulated fuse volume";
         android::base::unique_fd fd;
         int user_id = getMountUserId();
-        int result = MountUserFuse(user_id, getInternalPath(), label, &fd);
+        auto volumeRoot = getRootPath();
 
-        if (result != 0) {
+        // Make sure Android/ dirs exist for bind mounting
+        status_t res = PrepareAndroidDirs(volumeRoot);
+        if (res != OK) {
+            LOG(ERROR) << "Failed to prepare Android/ directories";
+            return res;
+        }
+
+        res = MountUserFuse(user_id, getInternalPath(), label, &fd);
+        if (res != 0) {
             PLOG(ERROR) << "Failed to mount emulated fuse volume";
-            return -result;
+            return res;
         }
 
         mFuseMounted = true;
@@ -252,7 +251,7 @@
         }
 
         // Only do the bind-mounts when we know for sure the FUSE daemon can resolve the path.
-        status_t res = mountFuseBindMounts();
+        res = mountFuseBindMounts();
         if (res != OK) {
             fd.reset();
             doUnmount();
@@ -317,5 +316,12 @@
     return OK;
 }
 
+std::string EmulatedVolume::getRootPath() const {
+    int user_id = getMountUserId();
+    std::string volumeRoot = StringPrintf("%s/%d", getInternalPath().c_str(), user_id);
+
+    return volumeRoot;
+}
+
 }  // namespace vold
 }  // namespace android