Bind mount pkg specific dirs in the zygote child namespaces.

- Also update vold to create sandboxes for secondary storage devices.
- Since bind mounts are created in the process specific namespaces, we
  don't need /mnt/storage anymore which we were using it to prevent
  some bind mounts from propagating onto /mnt/runtime/write.
- Create bind mounts for {media,obb} dirs similar to data dir in
  per process namespace.
- Also fix a bug where we are not passing correct packages to vold when
  a new user starts.

Bug: 111890351
Test: manual
Change-Id: I7849efc4fbf3c654606fa30de7ab2de0236d766f
diff --git a/model/EmulatedVolume.cpp b/model/EmulatedVolume.cpp
index a0cc069..8f46191 100644
--- a/model/EmulatedVolume.cpp
+++ b/model/EmulatedVolume.cpp
@@ -16,6 +16,7 @@
 
 #include "EmulatedVolume.h"
 #include "Utils.h"
+#include "VolumeManager.h"
 
 #include <android-base/logging.h>
 #include <android-base/stringprintf.h>
diff --git a/model/PublicVolume.cpp b/model/PublicVolume.cpp
index 3646290..77a156c 100644
--- a/model/PublicVolume.cpp
+++ b/model/PublicVolume.cpp
@@ -21,6 +21,7 @@
 #include "fs/Vfat.h"
 
 #include <android-base/logging.h>
+#include <android-base/properties.h>
 #include <android-base/stringprintf.h>
 #include <cutils/fs.h>
 #include <private/android_filesystem_config.h>
@@ -34,6 +35,7 @@
 #include <sys/types.h>
 #include <sys/wait.h>
 
+using android::base::GetBoolProperty;
 using android::base::StringPrintf;
 
 namespace android {
@@ -43,6 +45,8 @@
 
 static const char* kAsecPath = "/mnt/secure/asec";
 
+static const char* kIsolatedStorage = "persist.sys.isolated_storage";
+
 PublicVolume::PublicVolume(dev_t device) : VolumeBase(Type::kPublic), mDevice(device), mFusePid(0) {
     setId(StringPrintf("public:%u,%u", major(device), minor(device)));
     mDevPath = StringPrintf("/dev/block/vold/%s", getId().c_str());
@@ -179,16 +183,36 @@
                 PLOG(ERROR) << "Failed to exec";
             }
         } else {
+            // In Pre-Q, apps have full read access to secondary storage devices but only
+            // write access for their package specific directories. In Q, they only have access
+            // to their own sandboxes and they can write anywhere inside the sandbox. Instead of
+            // updating sdcardfs to allow packages writing into their own sandboxes, we could
+            // just allow them to write anywhere by passing "-w".
             // clang-format off
-            if (execl(kFusePath, kFusePath,
-                    "-u", "1023", // AID_MEDIA_RW
-                    "-g", "1023", // AID_MEDIA_RW
-                    "-U", std::to_string(getMountUserId()).c_str(),
-                    mRawPath.c_str(),
-                    stableName.c_str(),
-                    NULL)) {
-                // clang-format on
-                PLOG(ERROR) << "Failed to exec";
+            if (GetBoolProperty(kIsolatedStorage, false)) {
+                if (execl(kFusePath, kFusePath,
+                        "-u", "1023", // AID_MEDIA_RW
+                        "-g", "1023", // AID_MEDIA_RW
+                        "-U", std::to_string(getMountUserId()).c_str(),
+                        "-w",
+                        mRawPath.c_str(),
+                        stableName.c_str(),
+                        NULL)) {
+                    // clang-format on
+                    PLOG(ERROR) << "Failed to exec";
+                }
+            } else {
+                // clang-format off
+                if (execl(kFusePath, kFusePath,
+                        "-u", "1023", // AID_MEDIA_RW
+                        "-g", "1023", // AID_MEDIA_RW
+                        "-U", std::to_string(getMountUserId()).c_str(),
+                        mRawPath.c_str(),
+                        stableName.c_str(),
+                        NULL)) {
+                    // clang-format on
+                    PLOG(ERROR) << "Failed to exec";
+                }
             }
         }
 
diff --git a/model/VolumeBase.cpp b/model/VolumeBase.cpp
index 74bd874..29bc32c 100644
--- a/model/VolumeBase.cpp
+++ b/model/VolumeBase.cpp
@@ -35,7 +35,7 @@
 VolumeBase::VolumeBase(Type type)
     : mType(type),
       mMountFlags(0),
-      mMountUserId(-1),
+      mMountUserId(USER_UNKNOWN),
       mCreated(false),
       mState(State::kUnmounted),
       mSilent(false) {}
@@ -230,10 +230,9 @@
     setState(State::kChecking);
     status_t res = doMount();
     if (res == OK) {
-        setState(State::kMounted);
-    } else {
-        setState(State::kUnmountable);
+        res = VolumeManager::Instance()->onVolumeMounted(this);
     }
+    setState(res == OK ? State::kMounted : State::kUnmountable);
 
     return res;
 }
@@ -252,8 +251,11 @@
     }
     mVolumes.clear();
 
-    status_t res = doUnmount();
-    setState(State::kUnmounted);
+    status_t res = VolumeManager::Instance()->onVolumeUnmounted(this);
+    if (res == OK) {
+        res = doUnmount();
+        setState(State::kUnmounted);
+    }
     return res;
 }
 
@@ -277,5 +279,10 @@
     return -ENOTSUP;
 }
 
+std::ostream& VolumeBase::operator<<(std::ostream& stream) const {
+    return stream << " VolumeBase{id=" << mId << ",label=" << mLabel
+                  << ",mountFlags=" << mMountFlags << ",mountUserId=" << mMountUserId << "}";
+}
+
 }  // namespace vold
 }  // namespace android
diff --git a/model/VolumeBase.h b/model/VolumeBase.h
index a75669e..a9fd42d 100644
--- a/model/VolumeBase.h
+++ b/model/VolumeBase.h
@@ -27,6 +27,8 @@
 #include <list>
 #include <string>
 
+static constexpr userid_t USER_UNKNOWN = ((userid_t)-1);
+
 namespace android {
 namespace vold {
 
@@ -97,12 +99,16 @@
 
     std::shared_ptr<VolumeBase> findVolume(const std::string& id);
 
+    bool isEmulated() { return mType == Type::kEmulated; }
+
     status_t create();
     status_t destroy();
     status_t mount();
     status_t unmount();
     status_t format(const std::string& fsType);
 
+    std::ostream& operator<<(std::ostream& stream) const;
+
   protected:
     explicit VolumeBase(Type type);