diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index a6ead9d..637dc47 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -87,8 +87,6 @@
 static const char* kPathUserMount = "/mnt/user";
 static const char* kPathVirtualDisk = "/data/misc/vold/virtual_disk";
 
-static const char* kIsolatedStorage = "persist.sys.isolated_storage";
-static const char* kIsolatedStorageSnapshot = "sys.isolated_storage_snapshot";
 static const char* kPropVirtualDisk = "persist.sys.virtual_disk";
 
 static const std::string kEmptyString("");
@@ -118,11 +116,6 @@
 
 VolumeManager::~VolumeManager() {}
 
-static bool hasIsolatedStorage() {
-    return false &&
-           GetBoolProperty(kIsolatedStorageSnapshot, GetBoolProperty(kIsolatedStorage, true));
-}
-
 int VolumeManager::updateVirtualDisk() {
     ATRACE_NAME("VolumeManager::updateVirtualDisk");
     if (GetBoolProperty(kPropVirtualDisk, false)) {
@@ -384,399 +377,6 @@
     return 0;
 }
 
-int VolumeManager::mountPkgSpecificDir(const std::string& mntSourceRoot,
-                                       const std::string& mntTargetRoot,
-                                       const std::string& packageName, const char* dirName) {
-    std::string mntSourceDir =
-        StringPrintf("%s/Android/%s/%s", mntSourceRoot.c_str(), dirName, packageName.c_str());
-    if (CreateDir(mntSourceDir, 0755) < 0) {
-        return -errno;
-    }
-    std::string mntTargetDir =
-        StringPrintf("%s/Android/%s/%s", mntTargetRoot.c_str(), dirName, packageName.c_str());
-    if (CreateDir(mntTargetDir, 0755) < 0) {
-        return -errno;
-    }
-    return BindMount(mntSourceDir, mntTargetDir);
-}
-
-int VolumeManager::mountPkgSpecificDirsForRunningProcs(
-    userid_t userId, const std::vector<std::string>& packageNames,
-    const std::vector<std::string>& visibleVolLabels, int remountMode) {
-    std::unique_ptr<DIR, decltype(&closedir)> dirp(opendir("/proc"), closedir);
-    if (!dirp) {
-        PLOG(ERROR) << "Failed to opendir /proc";
-        return -1;
-    }
-
-    std::string rootName;
-    // Figure out root namespace to compare against below
-    if (!android::vold::Readlinkat(dirfd(dirp.get()), "1/ns/mnt", &rootName)) {
-        PLOG(ERROR) << "Failed to read root namespace";
-        return -1;
-    }
-
-    struct stat mntFullSb;
-    struct stat mntWriteSb;
-    if (TEMP_FAILURE_RETRY(stat("/mnt/runtime/full", &mntFullSb)) == -1) {
-        PLOG(ERROR) << "Failed to stat /mnt/runtime/full";
-        return -1;
-    }
-    if (TEMP_FAILURE_RETRY(stat("/mnt/runtime/write", &mntWriteSb)) == -1) {
-        PLOG(ERROR) << "Failed to stat /mnt/runtime/write";
-        return -1;
-    }
-
-    std::string obbMountDir = StringPrintf("/mnt/user/%d/obb_mount", userId);
-    if (fs_prepare_dir(obbMountDir.c_str(), 0700, AID_ROOT, AID_ROOT) != 0) {
-        PLOG(ERROR) << "Failed to fs_prepare_dir " << obbMountDir;
-        return -1;
-    }
-    const unique_fd obbMountDirFd(
-        TEMP_FAILURE_RETRY(open(obbMountDir.c_str(), O_RDONLY | O_DIRECTORY | O_CLOEXEC)));
-    if (obbMountDirFd.get() < 0) {
-        PLOG(ERROR) << "Failed to open " << obbMountDir;
-        return -1;
-    }
-
-    std::unordered_set<appid_t> validAppIds;
-    for (auto& package : packageNames) {
-        validAppIds.insert(mAppIds[package]);
-    }
-    std::vector<std::string>& userPackages = mUserPackages[userId];
-
-    std::vector<pid_t> childPids;
-
-    struct dirent* de;
-    // Poke through all running PIDs look for apps running in userId
-    while ((de = readdir(dirp.get()))) {
-        pid_t pid;
-        if (de->d_type != DT_DIR) continue;
-        if (!android::base::ParseInt(de->d_name, &pid)) continue;
-
-        const unique_fd pidFd(
-            openat(dirfd(dirp.get()), de->d_name, O_RDONLY | O_DIRECTORY | O_CLOEXEC));
-        if (pidFd.get() < 0) {
-            PLOG(WARNING) << "Failed to open /proc/" << pid;
-            continue;
-        }
-        struct stat sb;
-        if (fstat(pidFd.get(), &sb) != 0) {
-            PLOG(WARNING) << "Failed to stat " << de->d_name;
-            continue;
-        }
-        if (multiuser_get_user_id(sb.st_uid) != userId) {
-            continue;
-        }
-
-        // Matches so far, but refuse to touch if in root namespace
-        LOG(VERBOSE) << "Found matching PID " << de->d_name;
-        std::string pidName;
-        if (!android::vold::Readlinkat(pidFd.get(), "ns/mnt", &pidName)) {
-            PLOG(WARNING) << "Failed to read namespace for " << de->d_name;
-            continue;
-        }
-        if (rootName == pidName) {
-            LOG(WARNING) << "Skipping due to root namespace";
-            continue;
-        }
-
-        // Only update the mount points of processes running with one of validAppIds.
-        // This should skip any isolated uids.
-        appid_t appId = multiuser_get_app_id(sb.st_uid);
-        if (validAppIds.find(appId) == validAppIds.end()) {
-            continue;
-        }
-
-        std::vector<std::string> packagesForUid;
-        for (auto& package : userPackages) {
-            if (mAppIds[package] == appId) {
-                packagesForUid.push_back(package);
-            }
-        }
-        if (packagesForUid.empty()) {
-            continue;
-        }
-        const std::string& sandboxId = mSandboxIds[appId];
-
-        // We purposefully leave the namespace open across the fork
-        // NOLINTNEXTLINE(android-cloexec-open): Deliberately not O_CLOEXEC
-        unique_fd nsFd(openat(pidFd.get(), "ns/mnt", O_RDONLY));
-        if (nsFd.get() < 0) {
-            PLOG(WARNING) << "Failed to open namespace for " << de->d_name;
-            continue;
-        }
-
-        pid_t child;
-        if (!(child = fork())) {
-            if (setns(nsFd.get(), CLONE_NEWNS) != 0) {
-                PLOG(ERROR) << "Failed to setns for " << de->d_name;
-                _exit(1);
-            }
-
-            int mountMode;
-            if (remountMode == -1) {
-                mountMode =
-                    getMountModeForRunningProc(packagesForUid, userId, mntWriteSb, mntFullSb);
-                if (mountMode == -1) {
-                    _exit(1);
-                }
-            } else {
-                mountMode = remountMode;
-                if (handleMountModeInstaller(mountMode, obbMountDirFd.get(), obbMountDir,
-                                             sandboxId) < 0) {
-                    _exit(1);
-                }
-            }
-            if (mountMode == VoldNativeService::REMOUNT_MODE_FULL ||
-                mountMode == VoldNativeService::REMOUNT_MODE_LEGACY ||
-                mountMode == VoldNativeService::REMOUNT_MODE_NONE) {
-                // These mount modes are not going to change dynamically, so don't bother
-                // unmounting/remounting dirs.
-                _exit(0);
-            }
-
-            for (auto& volumeLabel : visibleVolLabels) {
-                std::string mntSource = StringPrintf("/mnt/runtime/write/%s", volumeLabel.c_str());
-                std::string mntTarget = StringPrintf("/storage/%s", volumeLabel.c_str());
-                if (volumeLabel == "emulated") {
-                    StringAppendF(&mntSource, "/%d", userId);
-                    StringAppendF(&mntTarget, "/%d", userId);
-                }
-
-                std::string sandboxSource =
-                    StringPrintf("%s/Android/sandbox/%s", mntSource.c_str(), sandboxId.c_str());
-                if (CreateDir(sandboxSource, 0755) < 0) {
-                    continue;
-                }
-                if (BindMount(sandboxSource, mntTarget) < 0) {
-                    continue;
-                }
-
-                std::string obbSourceDir = StringPrintf("%s/Android/obb", mntSource.c_str());
-                std::string obbTargetDir = StringPrintf("%s/Android/obb", mntTarget.c_str());
-                if (UnmountTree(obbTargetDir) < 0) {
-                    continue;
-                }
-                if (!createPkgSpecificDirRoots(mntSource) || !createPkgSpecificDirRoots(mntTarget)) {
-                    continue;
-                }
-                for (auto& package : packagesForUid) {
-                    mountPkgSpecificDir(mntSource, mntTarget, package, "data");
-                    mountPkgSpecificDir(mntSource, mntTarget, package, "media");
-                    if (mountMode != VoldNativeService::REMOUNT_MODE_INSTALLER) {
-                        mountPkgSpecificDir(mntSource, mntTarget, package, "obb");
-                    }
-                }
-                if (mountMode == VoldNativeService::REMOUNT_MODE_INSTALLER) {
-                    if (BindMount(obbSourceDir, obbTargetDir) < 0) {
-                        continue;
-                    }
-                }
-            }
-            _exit(0);
-        }
-
-        if (child == -1) {
-            PLOG(ERROR) << "Failed to fork";
-        } else {
-            childPids.push_back(child);
-        }
-    }
-    for (auto& child : childPids) {
-        TEMP_FAILURE_RETRY(waitpid(child, nullptr, 0));
-    }
-    return 0;
-}
-
-int VolumeManager::getMountModeForRunningProc(const std::vector<std::string>& packagesForUid,
-                                              userid_t userId, struct stat& mntWriteStat,
-                                              struct stat& mntFullStat) {
-    struct stat storageSb;
-    if (TEMP_FAILURE_RETRY(stat("/storage", &storageSb)) == -1) {
-        PLOG(ERROR) << "Failed to stat /storage";
-        return -1;
-    }
-
-    // Some packages have access to full external storage, identify processes belonging
-    // to those packages by comparing inode no.s of /mnt/runtime/full and /storage
-    if (storageSb.st_dev == mntFullStat.st_dev && storageSb.st_ino == mntFullStat.st_ino) {
-        return VoldNativeService::REMOUNT_MODE_FULL;
-    } else if (storageSb.st_dev == mntWriteStat.st_dev && storageSb.st_ino == mntWriteStat.st_ino) {
-        return VoldNativeService::REMOUNT_MODE_LEGACY;
-    }
-
-    std::string obbMountFile =
-        StringPrintf("/mnt/user/%d/obb_mount/%s", userId, packagesForUid[0].c_str());
-    if (TEMP_FAILURE_RETRY(access(obbMountFile.c_str(), F_OK)) != -1) {
-        return VoldNativeService::REMOUNT_MODE_INSTALLER;
-    } else if (errno != ENOENT) {
-        PLOG(ERROR) << "Failed to access " << obbMountFile;
-        return -1;
-    }
-
-    // Some packages don't have access to external storage and processes belonging to
-    // those packages don't have anything mounted at /storage. So, identify those
-    // processes by comparing inode no.s of /mnt/user/%d/package
-    // and /storage
-    std::string sandbox = StringPrintf("/mnt/user/%d/package", userId);
-    struct stat sandboxStat;
-    if (TEMP_FAILURE_RETRY(stat(sandbox.c_str(), &sandboxStat)) == -1) {
-        PLOG(ERROR) << "Failed to stat " << sandbox;
-        return -1;
-    }
-    if (storageSb.st_dev == sandboxStat.st_dev && storageSb.st_ino == sandboxStat.st_ino) {
-        return VoldNativeService::REMOUNT_MODE_WRITE;
-    }
-
-    return VoldNativeService::REMOUNT_MODE_NONE;
-}
-
-int VolumeManager::handleMountModeInstaller(int mountMode, int obbMountDirFd,
-                                            const std::string& obbMountDir,
-                                            const std::string& sandboxId) {
-    if (mountMode == VoldNativeService::REMOUNT_MODE_INSTALLER) {
-        if (TEMP_FAILURE_RETRY(faccessat(obbMountDirFd, sandboxId.c_str(), F_OK, 0)) != -1) {
-            return 0;
-        } else if (errno != ENOENT) {
-            PLOG(ERROR) << "Failed to access " << obbMountDir << "/" << sandboxId;
-            return -errno;
-        }
-        const unique_fd fd(TEMP_FAILURE_RETRY(
-            openat(obbMountDirFd, sandboxId.c_str(), O_RDWR | O_CREAT | O_CLOEXEC, 0600)));
-        if (fd.get() < 0) {
-            PLOG(ERROR) << "Failed to create " << obbMountDir << "/" << sandboxId;
-            return -errno;
-        }
-    } else {
-        if (TEMP_FAILURE_RETRY(faccessat(obbMountDirFd, sandboxId.c_str(), F_OK, 0)) != -1) {
-            if (TEMP_FAILURE_RETRY(unlinkat(obbMountDirFd, sandboxId.c_str(), 0)) == -1) {
-                PLOG(ERROR) << "Failed to unlink " << obbMountDir << "/" << sandboxId;
-                return -errno;
-            }
-        } else if (errno != ENOENT) {
-            PLOG(ERROR) << "Failed to access " << obbMountDir << "/" << sandboxId;
-            return -errno;
-        }
-    }
-    return 0;
-}
-
-int VolumeManager::prepareSandboxes(userid_t userId, const std::vector<std::string>& packageNames,
-                                    const std::vector<std::string>& visibleVolLabels) {
-    if (visibleVolLabels.empty()) {
-        return 0;
-    }
-    for (auto& volumeLabel : visibleVolLabels) {
-        std::string volumeRoot(StringPrintf("/mnt/runtime/write/%s", volumeLabel.c_str()));
-        bool isVolPrimaryEmulated = (volumeLabel == mPrimary->getLabel() && mPrimary->isEmulated());
-        if (isVolPrimaryEmulated) {
-            StringAppendF(&volumeRoot, "/%d", userId);
-            if (CreateDir(volumeRoot, 0755) < 0) {
-                return -errno;
-            }
-        }
-
-        std::string sandboxRoot =
-            prepareSubDirs(volumeRoot, "Android/sandbox/", 0700, AID_ROOT, AID_ROOT);
-        if (sandboxRoot.empty()) {
-            return -errno;
-        }
-    }
-
-    if (prepareSandboxTargets(userId, visibleVolLabels) < 0) {
-        return -errno;
-    }
-
-    if (mountPkgSpecificDirsForRunningProcs(userId, packageNames, visibleVolLabels, -1) < 0) {
-        PLOG(ERROR) << "Failed to setup sandboxes for already running processes";
-        return -errno;
-    }
-    return 0;
-}
-
-int VolumeManager::prepareSandboxTargets(userid_t userId,
-                                         const std::vector<std::string>& visibleVolLabels) {
-    std::string mntTargetRoot = StringPrintf("/mnt/user/%d", userId);
-    if (fs_prepare_dir(mntTargetRoot.c_str(), 0751, AID_ROOT, AID_ROOT) != 0) {
-        PLOG(ERROR) << "Failed to fs_prepare_dir " << mntTargetRoot;
-        return -errno;
-    }
-
-    StringAppendF(&mntTargetRoot, "/package");
-    if (fs_prepare_dir(mntTargetRoot.c_str(), 0755, AID_ROOT, AID_ROOT) != 0) {
-        PLOG(ERROR) << "Failed to fs_prepare_dir " << mntTargetRoot;
-        return -errno;
-    }
-
-    for (auto& volumeLabel : visibleVolLabels) {
-        std::string sandboxTarget =
-            StringPrintf("%s/%s", mntTargetRoot.c_str(), volumeLabel.c_str());
-        if (fs_prepare_dir(sandboxTarget.c_str(), 0755, AID_ROOT, AID_ROOT) != 0) {
-            PLOG(ERROR) << "Failed to fs_prepare_dir " << sandboxTarget;
-            return -errno;
-        }
-
-        if (mPrimary && volumeLabel == mPrimary->getLabel() && mPrimary->isEmulated()) {
-            StringAppendF(&sandboxTarget, "/%d", userId);
-            if (fs_prepare_dir(sandboxTarget.c_str(), 0755, AID_ROOT, AID_ROOT) != 0) {
-                PLOG(ERROR) << "Failed to fs_prepare_dir " << sandboxTarget;
-                return -errno;
-            }
-        }
-    }
-
-    StringAppendF(&mntTargetRoot, "/self");
-    if (fs_prepare_dir(mntTargetRoot.c_str(), 0755, AID_ROOT, AID_ROOT) != 0) {
-        PLOG(ERROR) << "Failed to fs_prepare_dir " << mntTargetRoot;
-        return -errno;
-    }
-
-    if (mPrimary) {
-        std::string pkgPrimarySource(mPrimary->getPath());
-        if (mPrimary->isEmulated()) {
-            StringAppendF(&pkgPrimarySource, "/%d", userId);
-        }
-        StringAppendF(&mntTargetRoot, "/primary");
-        if (Symlink(pkgPrimarySource, mntTargetRoot) < 0) {
-            return -errno;
-        }
-    }
-    return 0;
-}
-
-std::string VolumeManager::prepareSubDirs(const std::string& pathPrefix, const std::string& subDirs,
-                                          mode_t mode, uid_t uid, gid_t gid) {
-    std::string path(pathPrefix);
-    std::vector<std::string> subDirList = android::base::Split(subDirs, "/");
-    for (size_t i = 0; i < subDirList.size(); ++i) {
-        std::string subDir = subDirList[i];
-        if (subDir.empty()) {
-            continue;
-        }
-        StringAppendF(&path, "/%s", subDir.c_str());
-        if (CreateDir(path, mode) < 0) {
-            return kEmptyString;
-        }
-    }
-    return path;
-}
-
-bool VolumeManager::createPkgSpecificDirRoots(const std::string& volumeRoot) {
-    std::string volumeAndroidRoot = StringPrintf("%s/Android", volumeRoot.c_str());
-    if (CreateDir(volumeAndroidRoot, 0700) < 0) {
-        return false;
-    }
-    std::array<std::string, 3> dirs = {"data", "media", "obb"};
-    for (auto& dir : dirs) {
-        std::string path = StringPrintf("%s/%s", volumeAndroidRoot.c_str(), dir.c_str());
-        if (CreateDir(path, 0700) < 0) {
-            return false;
-        }
-    }
-    return true;
-}
-
 int VolumeManager::onUserAdded(userid_t userId, int userSerialNumber) {
     mAddedUsers[userId] = userSerialNumber;
     return 0;
@@ -787,9 +387,7 @@
     return 0;
 }
 
-int VolumeManager::onUserStarted(userid_t userId, const std::vector<std::string>& packageNames,
-                                 const std::vector<int>& appIds,
-                                 const std::vector<std::string>& sandboxIds) {
+int VolumeManager::onUserStarted(userid_t userId) {
     LOG(VERBOSE) << "onUserStarted: " << userId;
     // Note that sometimes the system will spin up processes from Zygote
     // before actually starting the user, so we're okay if Zygote
@@ -798,159 +396,15 @@
     fs_prepare_dir(path.c_str(), 0755, AID_ROOT, AID_ROOT);
 
     mStartedUsers.insert(userId);
-    mUserPackages[userId] = packageNames;
-    for (size_t i = 0; i < packageNames.size(); ++i) {
-        mAppIds[packageNames[i]] = appIds[i];
-        mSandboxIds[appIds[i]] = sandboxIds[i];
-    }
     if (mPrimary) {
         linkPrimary(userId);
     }
-    if (hasIsolatedStorage()) {
-        std::vector<std::string> visibleVolLabels;
-        for (auto& volId : mVisibleVolumeIds) {
-            auto vol = findVolume(volId);
-            userid_t mountUserId = vol->getMountUserId();
-            if (mountUserId == userId || vol->isEmulated()) {
-                visibleVolLabels.push_back(vol->getLabel());
-            }
-        }
-        if (prepareSandboxes(userId, packageNames, visibleVolLabels) != 0) {
-            return -errno;
-        }
-    }
     return 0;
 }
 
 int VolumeManager::onUserStopped(userid_t userId) {
     LOG(VERBOSE) << "onUserStopped: " << userId;
     mStartedUsers.erase(userId);
-
-    if (hasIsolatedStorage()) {
-        auto& userPackages = mUserPackages[userId];
-        std::string userMntTargetRoot = StringPrintf("/mnt/user/%d", userId);
-        std::string pkgPrimaryDir =
-            StringPrintf("%s/package/self/primary", userMntTargetRoot.c_str());
-        if (Unlink(pkgPrimaryDir) < 0) {
-            return -errno;
-        }
-        mUserPackages.erase(userId);
-        if (DeleteDirContentsAndDir(userMntTargetRoot) < 0) {
-            PLOG(ERROR) << "DeleteDirContentsAndDir failed on " << userMntTargetRoot;
-            return -errno;
-        }
-        LOG(VERBOSE) << "Success: DeleteDirContentsAndDir on " << userMntTargetRoot;
-    }
-    return 0;
-}
-
-int VolumeManager::addAppIds(const std::vector<std::string>& packageNames,
-                             const std::vector<int32_t>& appIds) {
-    for (size_t i = 0; i < packageNames.size(); ++i) {
-        mAppIds[packageNames[i]] = appIds[i];
-    }
-    return 0;
-}
-
-int VolumeManager::addSandboxIds(const std::vector<int32_t>& appIds,
-                                 const std::vector<std::string>& sandboxIds) {
-    for (size_t i = 0; i < appIds.size(); ++i) {
-        mSandboxIds[appIds[i]] = sandboxIds[i];
-    }
-    return 0;
-}
-
-int VolumeManager::prepareSandboxForApp(const std::string& packageName, appid_t appId,
-                                        const std::string& sandboxId, userid_t userId) {
-    if (!hasIsolatedStorage()) {
-        return 0;
-    } else if (mStartedUsers.find(userId) == mStartedUsers.end()) {
-        // User not started, no need to do anything now. Required bind mounts for the package will
-        // be created when the user starts.
-        return 0;
-    }
-
-    auto& userPackages = mUserPackages[userId];
-    if (std::find(userPackages.begin(), userPackages.end(), packageName) != userPackages.end()) {
-        return 0;
-    }
-
-    LOG(VERBOSE) << "prepareSandboxForApp: " << packageName << ", appId=" << appId
-                 << ", sandboxId=" << sandboxId << ", userId=" << userId;
-    mUserPackages[userId].push_back(packageName);
-    mAppIds[packageName] = appId;
-    mSandboxIds[appId] = sandboxId;
-
-    std::vector<std::string> visibleVolLabels;
-    for (auto& volId : mVisibleVolumeIds) {
-        auto vol = findVolume(volId);
-        userid_t mountUserId = vol->getMountUserId();
-        if (mountUserId == userId || vol->isEmulated()) {
-            visibleVolLabels.push_back(vol->getLabel());
-        }
-    }
-    return prepareSandboxes(userId, {packageName}, visibleVolLabels);
-}
-
-int VolumeManager::destroySandboxForApp(const std::string& packageName,
-                                        const std::string& sandboxId, userid_t userId) {
-    if (!hasIsolatedStorage()) {
-        return 0;
-    }
-    LOG(VERBOSE) << "destroySandboxForApp: " << packageName << ", sandboxId=" << sandboxId
-                 << ", userId=" << userId;
-    auto& userPackages = mUserPackages[userId];
-    userPackages.erase(std::remove(userPackages.begin(), userPackages.end(), packageName),
-                       userPackages.end());
-    // If the package is not uninstalled in any other users, remove appId and sandboxId
-    // corresponding to it from the internal state.
-    bool installedInAnyUser = false;
-    for (auto& it : mUserPackages) {
-        auto& packages = it.second;
-        if (std::find(packages.begin(), packages.end(), packageName) != packages.end()) {
-            installedInAnyUser = true;
-            break;
-        }
-    }
-    if (!installedInAnyUser) {
-        const auto& entry = mAppIds.find(packageName);
-        if (entry != mAppIds.end()) {
-            mSandboxIds.erase(entry->second);
-            mAppIds.erase(entry);
-        }
-    }
-
-    std::vector<std::string> visibleVolLabels;
-    for (auto& volId : mVisibleVolumeIds) {
-        auto vol = findVolume(volId);
-        userid_t mountUserId = vol->getMountUserId();
-        if (mountUserId == userId || vol->isEmulated()) {
-            if (destroySandboxForAppOnVol(packageName, sandboxId, userId, vol->getLabel()) < 0) {
-                return -errno;
-            }
-        }
-    }
-
-    return 0;
-}
-
-int VolumeManager::destroySandboxForAppOnVol(const std::string& packageName,
-                                             const std::string& sandboxId, userid_t userId,
-                                             const std::string& volLabel) {
-    LOG(VERBOSE) << "destroySandboxOnVol: " << packageName << ", userId=" << userId
-                 << ", volLabel=" << volLabel;
-
-    std::string sandboxDir = StringPrintf("/mnt/runtime/write/%s", volLabel.c_str());
-    if (volLabel == mPrimary->getLabel() && mPrimary->isEmulated()) {
-        StringAppendF(&sandboxDir, "/%d", userId);
-    }
-    StringAppendF(&sandboxDir, "/Android/sandbox/%s", sandboxId.c_str());
-
-    if (DeleteDirContentsAndDir(sandboxDir) < 0) {
-        PLOG(ERROR) << "DeleteDirContentsAndDir failed on " << sandboxDir;
-        return -errno;
-    }
-
     return 0;
 }
 
@@ -968,86 +422,7 @@
     return 0;
 }
 
-int VolumeManager::onVolumeMounted(android::vold::VolumeBase* vol) {
-    if (!hasIsolatedStorage()) {
-        return 0;
-    }
-
-    if ((vol->getMountFlags() & android::vold::VoldNativeService::MOUNT_FLAG_VISIBLE) == 0) {
-        return 0;
-    }
-
-    mVisibleVolumeIds.insert(vol->getId());
-    userid_t mountUserId = vol->getMountUserId();
-    if ((vol->getMountFlags() & android::vold::VoldNativeService::MOUNT_FLAG_PRIMARY) != 0) {
-        // We don't want to create another shared_ptr here because then we will end up with
-        // two shared_ptrs owning the underlying pointer without sharing it.
-        mPrimary = findVolume(vol->getId());
-        for (userid_t userId : mStartedUsers) {
-            if (linkPrimary(userId) != 0) {
-                return -errno;
-            }
-        }
-    }
-    if (vol->isEmulated()) {
-        for (userid_t userId : mStartedUsers) {
-            if (prepareSandboxes(userId, mUserPackages[userId], {vol->getLabel()}) != 0) {
-                return -errno;
-            }
-        }
-    } else if (mStartedUsers.find(mountUserId) != mStartedUsers.end()) {
-        if (prepareSandboxes(mountUserId, mUserPackages[mountUserId], {vol->getLabel()}) != 0) {
-            return -errno;
-        }
-    }
-    return 0;
-}
-
-int VolumeManager::onVolumeUnmounted(android::vold::VolumeBase* vol) {
-    if (!hasIsolatedStorage()) {
-        return 0;
-    }
-
-    if (mVisibleVolumeIds.erase(vol->getId()) == 0) {
-        return 0;
-    }
-
-    if ((vol->getMountFlags() & android::vold::VoldNativeService::MOUNT_FLAG_PRIMARY) != 0) {
-        mPrimary = nullptr;
-    }
-
-    LOG(VERBOSE) << "visibleVolumeUnmounted: " << vol;
-    userid_t mountUserId = vol->getMountUserId();
-    if (vol->isEmulated()) {
-        for (userid_t userId : mStartedUsers) {
-            if (destroySandboxesForVol(vol, userId) != 0) {
-                return -errno;
-            }
-        }
-    } else if (mStartedUsers.find(mountUserId) != mStartedUsers.end()) {
-        if (destroySandboxesForVol(vol, mountUserId) != 0) {
-            return -errno;
-        }
-    }
-    return 0;
-}
-
-int VolumeManager::destroySandboxesForVol(android::vold::VolumeBase* vol, userid_t userId) {
-    LOG(VERBOSE) << "destroysandboxesForVol: " << vol << " for user=" << userId;
-    std::string volSandboxRoot =
-        StringPrintf("/mnt/user/%d/package/%s", userId, vol->getLabel().c_str());
-    if (android::vold::DeleteDirContentsAndDir(volSandboxRoot) < 0) {
-        PLOG(ERROR) << "DeleteDirContentsAndDir failed on " << volSandboxRoot;
-        return -errno;
-    }
-    LOG(VERBOSE) << "Success: DeleteDirContentsAndDir on " << volSandboxRoot;
-    return 0;
-}
-
 int VolumeManager::setPrimary(const std::shared_ptr<android::vold::VolumeBase>& vol) {
-    if (hasIsolatedStorage()) {
-        return 0;
-    }
     mPrimary = vol;
     for (userid_t userId : mStartedUsers) {
         linkPrimary(userId);
@@ -1056,37 +431,6 @@
 }
 
 int VolumeManager::remountUid(uid_t uid, int32_t mountMode) {
-    if (!hasIsolatedStorage()) {
-        return remountUidLegacy(uid, mountMode);
-    }
-
-    appid_t appId = multiuser_get_app_id(uid);
-    userid_t userId = multiuser_get_user_id(uid);
-    std::vector<std::string> visibleVolLabels;
-    for (auto& volId : mVisibleVolumeIds) {
-        auto vol = findVolume(volId);
-        userid_t mountUserId = vol->getMountUserId();
-        if (mountUserId == userId || vol->isEmulated()) {
-            visibleVolLabels.push_back(vol->getLabel());
-        }
-    }
-
-    // Finding one package with appId is enough
-    std::vector<std::string> packageNames;
-    for (auto it = mAppIds.begin(); it != mAppIds.end(); ++it) {
-        if (it->second == appId) {
-            packageNames.push_back(it->first);
-            break;
-        }
-    }
-    if (packageNames.empty()) {
-        PLOG(ERROR) << "Failed to find packageName for " << uid;
-        return -1;
-    }
-    return mountPkgSpecificDirsForRunningProcs(userId, packageNames, visibleVolLabels, mountMode);
-}
-
-int VolumeManager::remountUidLegacy(uid_t uid, int32_t mountMode) {
     std::string mode;
     switch (mountMode) {
         case VoldNativeService::REMOUNT_MODE_NONE:
@@ -1264,15 +608,6 @@
     }
     updateVirtualDisk();
     mAddedUsers.clear();
-
-    mUserPackages.clear();
-    mAppIds.clear();
-    mSandboxIds.clear();
-    mVisibleVolumeIds.clear();
-
-    for (userid_t userId : mStartedUsers) {
-        DeleteDirContents(StringPrintf("/mnt/user/%d/package", userId));
-    }
     mStartedUsers.clear();
     return 0;
 }
