diff --git a/Android.mk b/Android.mk
index 78d60df..5957df7 100644
--- a/Android.mk
+++ b/Android.mk
@@ -2,9 +2,6 @@
 
 common_src_files := \
 	VolumeManager.cpp \
-	CommandListener.cpp \
-	CryptCommandListener.cpp \
-	VoldCommand.cpp \
 	NetlinkManager.cpp \
 	NetlinkHandler.cpp \
 	Process.cpp \
@@ -13,7 +10,6 @@
 	fs/Vfat.cpp \
 	Loop.cpp \
 	Devmapper.cpp \
-	ResponseCode.cpp \
 	CheckBattery.cpp \
 	Ext4Crypt.cpp \
 	VoldUtil.c \
diff --git a/Asec.h b/Asec.h
deleted file mode 100644
index dd64fd0..0000000
--- a/Asec.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _ASEC_H
-#define _ASEC_H
-
-struct asec_superblock {
-#define ASEC_SB_MAGIC 0xc0def00d
-    unsigned int magic;
-
-#define ASEC_SB_VER 1
-    unsigned char ver;
-
-#define ASEC_SB_C_CIPHER_NONE    0
-#define ASEC_SB_C_CIPHER_TWOFISH 1
-#define ASEC_SB_C_CIPHER_AES     2
-    unsigned char c_cipher;
-
-#define ASEC_SB_C_CHAIN_NONE 0
-    unsigned char c_chain;
-
-#define ASEC_SB_C_OPTS_NONE 0
-#define ASEC_SB_C_OPTS_EXT4 1
-    unsigned char c_opts;
-
-#define ASEC_SB_C_MODE_NONE 0
-    unsigned char c_mode;
-} __attribute__((packed));
-
-#endif
diff --git a/BenchmarkTask.cpp b/BenchmarkTask.cpp
index 5ec249a..d10d792 100644
--- a/BenchmarkTask.cpp
+++ b/BenchmarkTask.cpp
@@ -17,7 +17,6 @@
 #include "BenchmarkTask.h"
 #include "BenchmarkGen.h"
 #include "VolumeManager.h"
-#include "ResponseCode.h"
 
 #include <android-base/file.h>
 #include <android-base/logging.h>
diff --git a/CommandListener.cpp b/CommandListener.cpp
deleted file mode 100644
index a402ffa..0000000
--- a/CommandListener.cpp
+++ /dev/null
@@ -1,689 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-#include <sys/mount.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <fs_mgr.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdint.h>
-#include <inttypes.h>
-#include <ctype.h>
-
-#define LOG_TAG "VoldCmdListener"
-
-#include <android-base/logging.h>
-#include <android-base/stringprintf.h>
-#include <android-base/unique_fd.h>
-#include <cutils/fs.h>
-
-#include <sysutils/SocketClient.h>
-#include <private/android_filesystem_config.h>
-
-#include "CommandListener.h"
-#include "VolumeManager.h"
-#include "model/VolumeBase.h"
-#include "ResponseCode.h"
-#include "Process.h"
-#include "Loop.h"
-#include "Devmapper.h"
-#include "MoveTask.h"
-#include "TrimTask.h"
-
-#define DUMP_ARGS 0
-
-using android::base::unique_fd;
-
-CommandListener::CommandListener() :
-                 FrameworkListener("vold", true) {
-    registerCmd(new DumpCmd());
-    registerCmd(new VolumeCmd());
-    registerCmd(new AsecCmd());
-    registerCmd(new ObbCmd());
-    registerCmd(new StorageCmd());
-    registerCmd(new FstrimCmd());
-    registerCmd(new AppFuseCmd());
-}
-
-#if DUMP_ARGS
-void CommandListener::dumpArgs(int argc, char **argv, int argObscure) {
-    char buffer[4096];
-    char *p = buffer;
-
-    memset(buffer, 0, sizeof(buffer));
-    int i;
-    for (i = 0; i < argc; i++) {
-        unsigned int len = strlen(argv[i]) + 1; // Account for space
-        if (i == argObscure) {
-            len += 2; // Account for {}
-        }
-        if (((p - buffer) + len) < (sizeof(buffer)-1)) {
-            if (i == argObscure) {
-                *p++ = '{';
-                *p++ = '}';
-                *p++ = ' ';
-                continue;
-            }
-            strcpy(p, argv[i]);
-            p+= strlen(argv[i]);
-            if (i != (argc -1)) {
-                *p++ = ' ';
-            }
-        }
-    }
-    SLOGD("%s", buffer);
-}
-#else
-void CommandListener::dumpArgs(int /*argc*/, char ** /*argv*/, int /*argObscure*/) { }
-#endif
-
-int CommandListener::sendGenericOkFail(SocketClient *cli, int cond) {
-    if (!cond) {
-        return cli->sendMsg(ResponseCode::CommandOkay, "Command succeeded", false);
-    } else {
-        return cli->sendMsg(ResponseCode::OperationFailed, "Command failed", false);
-    }
-}
-
-CommandListener::DumpCmd::DumpCmd() :
-                 VoldCommand("dump") {
-}
-
-int CommandListener::DumpCmd::runCommand(SocketClient *cli,
-                                         int /*argc*/, char ** /*argv*/) {
-    cli->sendMsg(0, "Dumping loop status", false);
-    if (Loop::dumpState(cli)) {
-        cli->sendMsg(ResponseCode::CommandOkay, "Loop dump failed", true);
-    }
-    cli->sendMsg(0, "Dumping DM status", false);
-    if (Devmapper::dumpState(cli)) {
-        cli->sendMsg(ResponseCode::CommandOkay, "Devmapper dump failed", true);
-    }
-    cli->sendMsg(0, "Dumping mounted filesystems", false);
-    FILE *fp = fopen("/proc/mounts", "re");
-    if (fp) {
-        char line[1024];
-        while (fgets(line, sizeof(line), fp)) {
-            line[strlen(line)-1] = '\0';
-            cli->sendMsg(0, line, false);;
-        }
-        fclose(fp);
-    }
-
-    cli->sendMsg(ResponseCode::CommandOkay, "dump complete", false);
-    return 0;
-}
-
-CommandListener::VolumeCmd::VolumeCmd() :
-                 VoldCommand("volume") {
-}
-
-int CommandListener::VolumeCmd::runCommand(SocketClient *cli,
-                                           int argc, char **argv) {
-    dumpArgs(argc, argv, -1);
-
-    if (argc < 2) {
-        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false);
-        return 0;
-    }
-
-    VolumeManager *vm = VolumeManager::Instance();
-    std::lock_guard<std::mutex> lock(vm->getLock());
-
-    // TODO: tease out methods not directly related to volumes
-
-    std::string cmd(argv[1]);
-    if (cmd == "reset") {
-        return sendGenericOkFail(cli, vm->reset());
-
-    } else if (cmd == "shutdown") {
-        return sendGenericOkFail(cli, vm->shutdown());
-
-    } else if (cmd == "debug") {
-        return sendGenericOkFail(cli, vm->setDebug(true));
-
-    } else if (cmd == "partition" && argc > 3) {
-        // partition [diskId] [public|private|mixed] [ratio]
-        std::string id(argv[2]);
-        auto disk = vm->findDisk(id);
-        if (disk == nullptr) {
-            return cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown disk", false);
-        }
-
-        std::string type(argv[3]);
-        if (type == "public") {
-            return sendGenericOkFail(cli, disk->partitionPublic());
-        } else if (type == "private") {
-            return sendGenericOkFail(cli, disk->partitionPrivate());
-        } else if (type == "mixed") {
-            if (argc < 4) {
-                return cli->sendMsg(ResponseCode::CommandSyntaxError, nullptr, false);
-            }
-            int frac = atoi(argv[4]);
-            return sendGenericOkFail(cli, disk->partitionMixed(frac));
-        } else {
-            return cli->sendMsg(ResponseCode::CommandSyntaxError, nullptr, false);
-        }
-
-    } else if (cmd == "mkdirs" && argc > 2) {
-        // mkdirs [path]
-        return sendGenericOkFail(cli, vm->mkdirs(argv[2]));
-
-    } else if (cmd == "user_added" && argc > 3) {
-        // user_added [user] [serial]
-        return sendGenericOkFail(cli, vm->onUserAdded(atoi(argv[2]), atoi(argv[3])));
-
-    } else if (cmd == "user_removed" && argc > 2) {
-        // user_removed [user]
-        return sendGenericOkFail(cli, vm->onUserRemoved(atoi(argv[2])));
-
-    } else if (cmd == "user_started" && argc > 2) {
-        // user_started [user]
-        return sendGenericOkFail(cli, vm->onUserStarted(atoi(argv[2])));
-
-    } else if (cmd == "user_stopped" && argc > 2) {
-        // user_stopped [user]
-        return sendGenericOkFail(cli, vm->onUserStopped(atoi(argv[2])));
-
-    } else if (cmd == "mount" && argc > 2) {
-        // mount [volId] [flags] [user]
-        std::string id(argv[2]);
-        auto vol = vm->findVolume(id);
-        if (vol == nullptr) {
-            return cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown volume", false);
-        }
-
-        int mountFlags = (argc > 3) ? atoi(argv[3]) : 0;
-        userid_t mountUserId = (argc > 4) ? atoi(argv[4]) : -1;
-
-        vol->setMountFlags(mountFlags);
-        vol->setMountUserId(mountUserId);
-
-        int res = vol->mount();
-        if (mountFlags & android::vold::VolumeBase::MountFlags::kPrimary) {
-            vm->setPrimary(vol);
-        }
-        return sendGenericOkFail(cli, res);
-
-    } else if (cmd == "unmount" && argc > 2) {
-        // unmount [volId]
-        std::string id(argv[2]);
-        auto vol = vm->findVolume(id);
-        if (vol == nullptr) {
-            return cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown volume", false);
-        }
-
-        return sendGenericOkFail(cli, vol->unmount());
-
-    } else if (cmd == "format" && argc > 3) {
-        // format [volId] [fsType|auto]
-        std::string id(argv[2]);
-        std::string fsType(argv[3]);
-        auto vol = vm->findVolume(id);
-        if (vol == nullptr) {
-            return cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown volume", false);
-        }
-
-        return sendGenericOkFail(cli, vol->format(fsType));
-
-    } else if (cmd == "move_storage" && argc > 3) {
-        // move_storage [fromVolId] [toVolId]
-        auto fromVol = vm->findVolume(std::string(argv[2]));
-        auto toVol = vm->findVolume(std::string(argv[3]));
-        if (fromVol == nullptr || toVol == nullptr) {
-            return cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown volume", false);
-        }
-
-        (new android::vold::MoveTask(fromVol, toVol, nullptr))->start();
-        return sendGenericOkFail(cli, 0);
-
-    } else if (cmd == "benchmark" && argc > 2) {
-        // benchmark [volId]
-        std::string id(argv[2]);
-        LOG(WARNING) << "Benchmarking has moved to Binder interface";
-        nsecs_t res = 0;
-        return cli->sendMsg(ResponseCode::CommandOkay,
-                android::base::StringPrintf("%" PRId64, res).c_str(), false);
-
-    } else if (cmd == "forget_partition" && argc > 2) {
-        // forget_partition [partGuid]
-        std::string partGuid(argv[2]);
-        return sendGenericOkFail(cli, vm->forgetPartition(partGuid));
-
-    } else if (cmd == "remount_uid" && argc > 3) {
-        // remount_uid [uid] [none|default|read|write]
-        uid_t uid = atoi(argv[2]);
-        std::string mode(argv[3]);
-        return sendGenericOkFail(cli, vm->remountUid(uid, mode));
-    }
-
-    return cli->sendMsg(ResponseCode::CommandSyntaxError, nullptr, false);
-}
-
-CommandListener::StorageCmd::StorageCmd() :
-                 VoldCommand("storage") {
-}
-
-int CommandListener::StorageCmd::runCommand(SocketClient *cli,
-                                                      int argc, char **argv) {
-    /* Guarantied to be initialized by vold's main() before the CommandListener is active */
-    extern struct fstab *fstab;
-
-    dumpArgs(argc, argv, -1);
-
-    if (argc < 2) {
-        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false);
-        return 0;
-    }
-
-    if (!strcmp(argv[1], "mountall")) {
-        if (argc != 2) {
-            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: mountall", false);
-            return 0;
-        }
-        fs_mgr_mount_all(fstab, MOUNT_MODE_DEFAULT);
-        cli->sendMsg(ResponseCode::CommandOkay, "Mountall ran successfully", false);
-        return 0;
-    }
-    if (!strcmp(argv[1], "users")) {
-        DIR *dir;
-        struct dirent *de;
-
-        if (argc < 3) {
-            cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument: user <mountpoint>", false);
-            return 0;
-        }
-        if (!(dir = opendir("/proc"))) {
-            cli->sendMsg(ResponseCode::OperationFailed, "Failed to open /proc", true);
-            return 0;
-        }
-
-        while ((de = readdir(dir))) {
-            int pid = Process::getPid(de->d_name);
-
-            if (pid < 0) {
-                continue;
-            }
-
-            std::string processName;
-            Process::getProcessName(pid, processName);
-
-            if (Process::checkFileDescriptorSymLinks(pid, argv[2]) ||
-                Process::checkFileMaps(pid, argv[2]) ||
-                Process::checkSymLink(pid, argv[2], "cwd") ||
-                Process::checkSymLink(pid, argv[2], "root") ||
-                Process::checkSymLink(pid, argv[2], "exe")) {
-
-                char msg[1024];
-                snprintf(msg, sizeof(msg), "%d %s", pid, processName.c_str());
-                cli->sendMsg(ResponseCode::StorageUsersListResult, msg, false);
-            }
-        }
-        closedir(dir);
-        cli->sendMsg(ResponseCode::CommandOkay, "Storage user list complete", false);
-    } else {
-        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown storage cmd", false);
-    }
-    return 0;
-}
-
-CommandListener::AsecCmd::AsecCmd() :
-                 VoldCommand("asec") {
-}
-
-void CommandListener::AsecCmd::listAsecsInDirectory(SocketClient *cli, const char *directory) {
-    DIR *d = opendir(directory);
-
-    if (!d) {
-        cli->sendMsg(ResponseCode::OperationFailed, "Failed to open asec dir", true);
-        return;
-    }
-
-    dirent* dent;
-    while ((dent = readdir(d)) != NULL) {
-        if (dent->d_name[0] == '.')
-            continue;
-        if (dent->d_type != DT_REG)
-            continue;
-        size_t name_len = strlen(dent->d_name);
-        if (name_len > 5 && name_len < 260 &&
-                !strcmp(&dent->d_name[name_len - 5], ".asec")) {
-            char id[255];
-            memset(id, 0, sizeof(id));
-            strlcpy(id, dent->d_name, name_len - 4);
-            cli->sendMsg(ResponseCode::AsecListResult, id, false);
-        }
-    }
-    closedir(d);
-}
-
-int CommandListener::AsecCmd::runCommand(SocketClient *cli,
-                                                      int argc, char **argv) {
-    if (argc < 2) {
-        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false);
-        return 0;
-    }
-
-    VolumeManager *vm = VolumeManager::Instance();
-    int rc = 0;
-
-    if (!strcmp(argv[1], "list")) {
-        dumpArgs(argc, argv, -1);
-
-        listAsecsInDirectory(cli, VolumeManager::SEC_ASECDIR_EXT);
-        listAsecsInDirectory(cli, VolumeManager::SEC_ASECDIR_INT);
-    } else if (!strcmp(argv[1], "create")) {
-        dumpArgs(argc, argv, 5);
-        if (argc != 8) {
-            cli->sendMsg(ResponseCode::CommandSyntaxError,
-                    "Usage: asec create <container-id> <size_mb> <fstype> <key> <ownerUid> "
-                    "<isExternal>", false);
-            return 0;
-        }
-
-        unsigned long numSectors = (atoi(argv[3]) * (1024 * 1024)) / 512;
-        const bool isExternal = (atoi(argv[7]) == 1);
-        rc = vm->createAsec(argv[2], numSectors, argv[4], argv[5], atoi(argv[6]), isExternal);
-    } else if (!strcmp(argv[1], "resize")) {
-        dumpArgs(argc, argv, -1);
-        if (argc != 5) {
-            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec resize <container-id> <size_mb> <key>", false);
-            return 0;
-        }
-        unsigned long numSectors = (atoi(argv[3]) * (1024 * 1024)) / 512;
-        rc = vm->resizeAsec(argv[2], numSectors, argv[4]);
-    } else if (!strcmp(argv[1], "finalize")) {
-        dumpArgs(argc, argv, -1);
-        if (argc != 3) {
-            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec finalize <container-id>", false);
-            return 0;
-        }
-        rc = vm->finalizeAsec(argv[2]);
-    } else if (!strcmp(argv[1], "fixperms")) {
-        dumpArgs(argc, argv, -1);
-        if  (argc != 5) {
-            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec fixperms <container-id> <gid> <filename>", false);
-            return 0;
-        }
-
-        char *endptr;
-        gid_t gid = (gid_t) strtoul(argv[3], &endptr, 10);
-        if (*endptr != '\0') {
-            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec fixperms <container-id> <gid> <filename>", false);
-            return 0;
-        }
-
-        rc = vm->fixupAsecPermissions(argv[2], gid, argv[4]);
-    } else if (!strcmp(argv[1], "destroy")) {
-        dumpArgs(argc, argv, -1);
-        if (argc < 3) {
-            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec destroy <container-id> [force]", false);
-            return 0;
-        }
-        bool force = false;
-        if (argc > 3 && !strcmp(argv[3], "force")) {
-            force = true;
-        }
-        rc = vm->destroyAsec(argv[2], force);
-    } else if (!strcmp(argv[1], "mount")) {
-        dumpArgs(argc, argv, 3);
-        if (argc != 6) {
-            cli->sendMsg(ResponseCode::CommandSyntaxError,
-                    "Usage: asec mount <namespace-id> <key> <ownerUid> <ro|rw>", false);
-            return 0;
-        }
-        bool readOnly = true;
-        if (!strcmp(argv[5], "rw")) {
-            readOnly = false;
-        }
-        rc = vm->mountAsec(argv[2], argv[3], atoi(argv[4]), readOnly);
-    } else if (!strcmp(argv[1], "unmount")) {
-        dumpArgs(argc, argv, -1);
-        if (argc < 3) {
-            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec unmount <container-id> [force]", false);
-            return 0;
-        }
-        bool force = false;
-        if (argc > 3 && !strcmp(argv[3], "force")) {
-            force = true;
-        }
-        rc = vm->unmountAsec(argv[2], force);
-    } else if (!strcmp(argv[1], "rename")) {
-        dumpArgs(argc, argv, -1);
-        if (argc != 4) {
-            cli->sendMsg(ResponseCode::CommandSyntaxError,
-                    "Usage: asec rename <old_id> <new_id>", false);
-            return 0;
-        }
-        rc = vm->renameAsec(argv[2], argv[3]);
-    } else if (!strcmp(argv[1], "path")) {
-        dumpArgs(argc, argv, -1);
-        if (argc != 3) {
-            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec path <container-id>", false);
-            return 0;
-        }
-        char path[255];
-
-        if (!(rc = vm->getAsecMountPath(argv[2], path, sizeof(path)))) {
-            cli->sendMsg(ResponseCode::AsecPathResult, path, false);
-            return 0;
-        }
-    } else if (!strcmp(argv[1], "fspath")) {
-        dumpArgs(argc, argv, -1);
-        if (argc != 3) {
-            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec fspath <container-id>", false);
-            return 0;
-        }
-        char path[255];
-
-        if (!(rc = vm->getAsecFilesystemPath(argv[2], path, sizeof(path)))) {
-            cli->sendMsg(ResponseCode::AsecPathResult, path, false);
-            return 0;
-        }
-    } else {
-        dumpArgs(argc, argv, -1);
-        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown asec cmd", false);
-    }
-
-    if (!rc) {
-        cli->sendMsg(ResponseCode::CommandOkay, "asec operation succeeded", false);
-    } else {
-        rc = ResponseCode::convertFromErrno();
-        cli->sendMsg(rc, "asec operation failed", true);
-    }
-
-    return 0;
-}
-
-CommandListener::ObbCmd::ObbCmd() :
-                 VoldCommand("obb") {
-}
-
-int CommandListener::ObbCmd::runCommand(SocketClient *cli,
-                                                      int argc, char **argv) {
-    if (argc < 2) {
-        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false);
-        return 0;
-    }
-
-    VolumeManager *vm = VolumeManager::Instance();
-    int rc = 0;
-
-    if (!strcmp(argv[1], "list")) {
-        dumpArgs(argc, argv, -1);
-
-        rc = vm->listMountedObbs(cli);
-    } else if (!strcmp(argv[1], "mount")) {
-            dumpArgs(argc, argv, 3);
-            if (argc != 5) {
-                cli->sendMsg(ResponseCode::CommandSyntaxError,
-                        "Usage: obb mount <filename> <key> <ownerGid>", false);
-                return 0;
-            }
-            rc = vm->mountObb(argv[2], argv[3], atoi(argv[4]));
-    } else if (!strcmp(argv[1], "unmount")) {
-        dumpArgs(argc, argv, -1);
-        if (argc < 3) {
-            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: obb unmount <source file> [force]", false);
-            return 0;
-        }
-        bool force = false;
-        if (argc > 3 && !strcmp(argv[3], "force")) {
-            force = true;
-        }
-        rc = vm->unmountObb(argv[2], force);
-    } else if (!strcmp(argv[1], "path")) {
-        dumpArgs(argc, argv, -1);
-        if (argc != 3) {
-            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: obb path <source file>", false);
-            return 0;
-        }
-        char path[255];
-
-        if (!(rc = vm->getObbMountPath(argv[2], path, sizeof(path)))) {
-            cli->sendMsg(ResponseCode::AsecPathResult, path, false);
-            return 0;
-        }
-    } else {
-        dumpArgs(argc, argv, -1);
-        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown obb cmd", false);
-    }
-
-    if (!rc) {
-        cli->sendMsg(ResponseCode::CommandOkay, "obb operation succeeded", false);
-    } else {
-        rc = ResponseCode::convertFromErrno();
-        cli->sendMsg(rc, "obb operation failed", true);
-    }
-
-    return 0;
-}
-
-CommandListener::FstrimCmd::FstrimCmd() :
-                 VoldCommand("fstrim") {
-}
-int CommandListener::FstrimCmd::runCommand(SocketClient *cli,
-                                                      int argc, char **argv) {
-    if ((cli->getUid() != 0) && (cli->getUid() != AID_SYSTEM)) {
-        cli->sendMsg(ResponseCode::CommandNoPermission, "No permission to run fstrim commands", false);
-        return 0;
-    }
-
-    if (argc < 2) {
-        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false);
-        return 0;
-    }
-
-    VolumeManager *vm = VolumeManager::Instance();
-    std::lock_guard<std::mutex> lock(vm->getLock());
-
-    int flags = 0;
-
-    std::string cmd(argv[1]);
-    if (cmd == "dotrim") {
-        flags = 0;
-    } else if (cmd == "dodtrim") {
-        flags = android::vold::TrimTask::Flags::kDeepTrim;
-    } else if (cmd == "dodtrimbench") {
-        flags = android::vold::TrimTask::Flags::kDeepTrim;
-    }
-
-    (new android::vold::TrimTask(flags, nullptr))->start();
-    return sendGenericOkFail(cli, 0);
-}
-
-
-CommandListener::AppFuseCmd::AppFuseCmd() : VoldCommand("appfuse") {}
-
-int CommandListener::AppFuseCmd::runCommand(SocketClient *cli, int argc, char **argv) {
-    if (argc < 2) {
-        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
-        return 0;
-    }
-
-    VolumeManager *vm = VolumeManager::Instance();
-    std::lock_guard<std::mutex> lock(vm->getLock());
-
-    const std::string command(argv[1]);
-    if (command == "mount" && argc == 5) {
-        const uid_t uid = atoi(argv[2]);
-        const pid_t pid = atoi(argv[3]);
-        const int mountId = atoi(argv[4]);
-
-        unique_fd device_fd;
-        int result = vm->mountAppFuse(uid, pid, mountId, &device_fd);
-        if (result != 0) {
-            return sendGenericOkFail(cli, result);
-        } else {
-            return sendFd(cli, device_fd.get());
-        }
-    } else if (command == "unmount" && argc == 5) {
-        const uid_t uid = atoi(argv[2]);
-        const uid_t pid = atoi(argv[3]);
-        const int mountId = atoi(argv[4]);
-
-        int result = vm->unmountAppFuse(uid, pid, mountId);
-        return sendGenericOkFail(cli, result);
-    }
-
-    return cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown appfuse cmd", false);
-}
-
-android::status_t CommandListener::AppFuseCmd::sendFd(SocketClient *cli, int fd) {
-    struct iovec data;
-    char dataBuffer[128];
-    char controlBuffer[CMSG_SPACE(sizeof(int))];
-    struct msghdr message;
-
-    // Message.
-    memset(&message, 0, sizeof(struct msghdr));
-    message.msg_iov = &data;
-    message.msg_iovlen = 1;
-    message.msg_control = controlBuffer;
-    message.msg_controllen = CMSG_SPACE(sizeof(int));
-
-    // Data.
-    data.iov_base = dataBuffer;
-    data.iov_len = snprintf(dataBuffer,
-                            sizeof(dataBuffer),
-                            "200 %d AppFuse command succeeded",
-                            cli->getCmdNum()) + 1;
-
-    // Control.
-    struct cmsghdr* const controlMessage = CMSG_FIRSTHDR(&message);
-    memset(controlBuffer, 0, CMSG_SPACE(sizeof(int)));
-    controlMessage->cmsg_level = SOL_SOCKET;
-    controlMessage->cmsg_type = SCM_RIGHTS;
-    controlMessage->cmsg_len = CMSG_LEN(sizeof(int));
-    *((int *) CMSG_DATA(controlMessage)) = fd;
-
-    const int result = TEMP_FAILURE_RETRY(sendmsg(cli->getSocket(), &message, 0));
-    if (result == -1) {
-        PLOG(ERROR) << "Failed to send FD from vold";
-        return -errno;
-    }
-
-    return android::OK;
-}
diff --git a/CommandListener.h b/CommandListener.h
deleted file mode 100644
index f858ac0..0000000
--- a/CommandListener.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _COMMANDLISTENER_H__
-#define _COMMANDLISTENER_H__
-
-#include <sysutils/FrameworkListener.h>
-#include <utils/Errors.h>
-#include "VoldCommand.h"
-
-class CommandListener : public FrameworkListener {
-public:
-    CommandListener();
-    virtual ~CommandListener() {}
-
-private:
-    static void dumpArgs(int argc, char **argv, int argObscure);
-    static int sendGenericOkFail(SocketClient *cli, int cond);
-
-    class DumpCmd : public VoldCommand {
-    public:
-        DumpCmd();
-        virtual ~DumpCmd() {}
-        int runCommand(SocketClient *c, int argc, char ** argv);
-    };
-
-    class VolumeCmd : public VoldCommand {
-    public:
-        VolumeCmd();
-        virtual ~VolumeCmd() {}
-        int runCommand(SocketClient *c, int argc, char ** argv);
-    };
-
-    class AsecCmd : public VoldCommand {
-    public:
-        AsecCmd();
-        virtual ~AsecCmd() {}
-        int runCommand(SocketClient *c, int argc, char ** argv);
-    private:
-        void listAsecsInDirectory(SocketClient *c, const char *directory);
-    };
-
-    class ObbCmd : public VoldCommand {
-    public:
-        ObbCmd();
-        virtual ~ObbCmd() {}
-        int runCommand(SocketClient *c, int argc, char ** argv);
-    };
-
-    class StorageCmd : public VoldCommand {
-    public:
-        StorageCmd();
-        virtual ~StorageCmd() {}
-        int runCommand(SocketClient *c, int argc, char ** argv);
-    };
-
-    class FstrimCmd : public VoldCommand {
-    public:
-        FstrimCmd();
-        virtual ~FstrimCmd() {}
-        int runCommand(SocketClient *c, int argc, char ** argv);
-    };
-
-    class AppFuseCmd : public VoldCommand {
-    public:
-        AppFuseCmd();
-        virtual ~AppFuseCmd() {}
-        int runCommand(SocketClient *c, int argc, char ** argv);
-    private:
-        android::status_t sendFd(SocketClient *c, int fd);
-    };
-};
-
-#endif
diff --git a/CryptCommandListener.cpp b/CryptCommandListener.cpp
deleted file mode 100644
index 779338f..0000000
--- a/CryptCommandListener.cpp
+++ /dev/null
@@ -1,448 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <assert.h>
-#include <stdlib.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <fs_mgr.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdint.h>
-#include <inttypes.h>
-
-#include <algorithm>
-#include <thread>
-
-#define LOG_TAG "VoldCryptCmdListener"
-
-#include <android-base/logging.h>
-#include <android-base/stringprintf.h>
-
-#include <cutils/fs.h>
-#include <cutils/log.h>
-#include <cutils/sockets.h>
-
-#include <sysutils/SocketClient.h>
-#include <private/android_filesystem_config.h>
-
-#include "CryptCommandListener.h"
-#include "Process.h"
-#include "ResponseCode.h"
-#include "cryptfs.h"
-#include "Ext4Crypt.h"
-#include "MetadataCrypt.h"
-#include "Utils.h"
-
-#define DUMP_ARGS 0
-
-CryptCommandListener::CryptCommandListener() :
-FrameworkListener("cryptd", true) {
-    registerCmd(new CryptfsCmd());
-}
-
-#if DUMP_ARGS
-void CryptCommandListener::dumpArgs(int argc, char **argv, int argObscure) {
-    char buffer[4096];
-    char *p = buffer;
-
-    memset(buffer, 0, sizeof(buffer));
-    int i;
-    for (i = 0; i < argc; i++) {
-        unsigned int len = strlen(argv[i]) + 1; // Account for space
-        if (i == argObscure) {
-            len += 2; // Account for {}
-        }
-        if (((p - buffer) + len) < (sizeof(buffer)-1)) {
-            if (i == argObscure) {
-                *p++ = '{';
-                *p++ = '}';
-                *p++ = ' ';
-                continue;
-            }
-            strcpy(p, argv[i]);
-            p+= strlen(argv[i]);
-            if (i != (argc -1)) {
-                *p++ = ' ';
-            }
-        }
-    }
-    SLOGD("%s", buffer);
-}
-#else
-void CryptCommandListener::dumpArgs(int /*argc*/, char ** /*argv*/, int /*argObscure*/) { }
-#endif
-
-int CryptCommandListener::sendGenericOkFailOnBool(SocketClient *cli, bool success) {
-    if (success) {
-        return cli->sendMsg(ResponseCode::CommandOkay, "Command succeeded", false);
-    } else {
-        return cli->sendMsg(ResponseCode::OperationFailed, "Command failed", false);
-    }
-}
-
-CryptCommandListener::CryptfsCmd::CryptfsCmd() :
-                 VoldCommand("cryptfs") {
-}
-
-static int getType(const char* type)
-{
-    if (!strcmp(type, "default")) {
-        return CRYPT_TYPE_DEFAULT;
-    } else if (!strcmp(type, "password")) {
-        return CRYPT_TYPE_PASSWORD;
-    } else if (!strcmp(type, "pin")) {
-        return CRYPT_TYPE_PIN;
-    } else if (!strcmp(type, "pattern")) {
-        return CRYPT_TYPE_PATTERN;
-    } else {
-        return -1;
-    }
-}
-
-static char* parseNull(char* arg) {
-    if (strcmp(arg, "!") == 0) {
-        return nullptr;
-    } else {
-        return arg;
-    }
-}
-
-static bool check_argc(SocketClient *cli, const std::string &subcommand, int argc,
-        int expected, std::string usage) {
-    assert(expected >= 2);
-    if (expected == 2) {
-        assert(usage.empty());
-    } else {
-        assert(!usage.empty());
-        assert(std::count(usage.begin(), usage.end(), ' ') + 3 == expected);
-    }
-    if (argc == expected) {
-        return true;
-    }
-    auto message = std::string() + "Usage: cryptfs " + subcommand;
-    if (!usage.empty()) {
-        message += " " + usage;
-    }
-    cli->sendMsg(ResponseCode::CommandSyntaxError, message.c_str(), false);
-    return false;
-}
-
-static int do_enablecrypto(char* arg2, char* arg4, int type, bool no_ui) {
-    int rc;
-    int tries;
-    for (tries = 0; tries < 2; ++tries) {
-        if (type == CRYPT_TYPE_DEFAULT) {
-            rc = cryptfs_enable_default(arg2, no_ui);
-        } else {
-            rc = cryptfs_enable(arg2, type, arg4, no_ui);
-        }
-
-        if (rc == 0) {
-            free(arg2);
-            free(arg4);
-            return 0;
-        } else if (tries == 0) {
-            Process::killProcessesWithOpenFiles(DATA_MNT_POINT, SIGKILL);
-        }
-    }
-
-    free(arg2);
-    free(arg4);
-    return -1;
-}
-
-int CryptCommandListener::CryptfsCmd::runCommand(SocketClient *cli,
-                                                 int argc, char **argv) {
-    if ((cli->getUid() != 0) && (cli->getUid() != AID_SYSTEM)) {
-        cli->sendMsg(ResponseCode::CommandNoPermission, "No permission to run cryptfs commands", false);
-        return 0;
-    }
-
-    if (argc < 2) {
-        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing subcommand", false);
-        return 0;
-    }
-
-    int rc = 0;
-
-    std::string subcommand(argv[1]);
-    if (subcommand == "checkpw") {
-        if (!check_argc(cli, subcommand, argc, 3, "<passwd>")) return 0;
-        dumpArgs(argc, argv, 2);
-        rc = cryptfs_check_passwd(argv[2]);
-    } else if (subcommand == "restart") {
-        if (!check_argc(cli, subcommand, argc, 2, "")) return 0;
-        dumpArgs(argc, argv, -1);
-
-        // Spawn as thread so init can issue commands back to vold without
-        // causing deadlock, usually as a result of prep_data_fs.
-        std::thread(&cryptfs_restart).detach();
-    } else if (subcommand == "cryptocomplete") {
-        if (!check_argc(cli, subcommand, argc, 2, "")) return 0;
-        dumpArgs(argc, argv, -1);
-        rc = cryptfs_crypto_complete();
-    } else if (subcommand == "enablecrypto") {
-        if (e4crypt_is_native()) {
-            if (argc != 5 || strcmp(argv[2], "inplace") || strcmp(argv[3], "default")
-                    || strcmp(argv[4], "noui")) {
-                cli->sendMsg(ResponseCode::CommandSyntaxError,
-                        "Usage with ext4crypt: cryptfs enablecrypto inplace default noui", false);
-                return 0;
-            }
-            return sendGenericOkFailOnBool(cli, e4crypt_enable_crypto());
-        }
-        const char* syntax = "Usage: cryptfs enablecrypto <wipe|inplace> "
-                             "default|password|pin|pattern [passwd] [noui]";
-
-        // This should be replaced with a command line parser if more options
-        // are added
-        bool valid = true;
-        bool no_ui = false;
-        int type = CRYPT_TYPE_DEFAULT;
-        int options = 4; // Optional parameters are at this offset
-        if (argc < 4) {
-            // Minimum 4 parameters
-            valid = false;
-        } else if (strcmp(argv[2], "wipe") && strcmp(argv[2], "inplace") ) {
-            // Second parameter must be wipe or inplace
-            valid = false;
-        } else {
-            // Third parameter must be valid type
-            type = getType(argv[3]);
-            if (type == -1) {
-                valid = false;
-            } else if (type != CRYPT_TYPE_DEFAULT) {
-                options++;
-            }
-        }
-
-        if (valid) {
-            if(argc < options) {
-                // Too few parameters
-                valid = false;
-            } else if (argc == options) {
-                // No more, done
-            } else if (argc == options + 1) {
-                // One option, must be noui
-                if (!strcmp(argv[options], "noui")) {
-                    no_ui = true;
-                } else {
-                    valid = false;
-                }
-            } else {
-                // Too many options
-                valid = false;
-            }
-        }
-
-        if (!valid) {
-            cli->sendMsg(ResponseCode::CommandSyntaxError, syntax, false);
-            return 0;
-        }
-
-        dumpArgs(argc, argv, 4);
-
-        // Spawn as thread so init can issue commands back to vold without
-        // causing deadlock, usually as a result of prep_data_fs.
-        char* arg2 = argc > 2 ? strdup(argv[2]) : NULL;
-        char* arg4 = argc > 4 ? strdup(argv[4]) : NULL;
-        std::thread(&do_enablecrypto, arg2, arg4, type, no_ui).detach();
-    } else if (subcommand == "enablefilecrypto") {
-        if (!check_argc(cli, subcommand, argc, 2, "")) return 0;
-        dumpArgs(argc, argv, -1);
-        rc = e4crypt_initialize_global_de();
-    } else if (subcommand == "changepw") {
-        const char* syntax = "Usage: cryptfs changepw "
-                             "default|password|pin|pattern [newpasswd]";
-        const char* password;
-        if (argc == 3) {
-            password = "";
-        } else if (argc == 4) {
-            password = argv[3];
-        } else {
-            cli->sendMsg(ResponseCode::CommandSyntaxError, syntax, false);
-            return 0;
-        }
-        int type = getType(argv[2]);
-        if (type == -1) {
-            cli->sendMsg(ResponseCode::CommandSyntaxError, syntax, false);
-            return 0;
-        }
-        SLOGD("cryptfs changepw %s {}", argv[2]);
-        rc = cryptfs_changepw(type, password);
-    } else if (subcommand == "verifypw") {
-        if (!check_argc(cli, subcommand, argc, 3, "<passwd>")) return 0;
-        SLOGD("cryptfs verifypw {}");
-        rc = cryptfs_verify_passwd(argv[2]);
-    } else if (subcommand == "getfield") {
-        if (!check_argc(cli, subcommand, argc, 3, "<fieldname>")) return 0;
-        char *valbuf;
-        int valbuf_len = PROPERTY_VALUE_MAX;
-
-        dumpArgs(argc, argv, -1);
-
-        // Increase the buffer size until it is big enough for the field value stored.
-        while (1) {
-            valbuf = (char*)malloc(valbuf_len);
-            if (valbuf == NULL) {
-                cli->sendMsg(ResponseCode::OperationFailed, "Failed to allocate memory", false);
-                return 0;
-            }
-            rc = cryptfs_getfield(argv[2], valbuf, valbuf_len);
-            if (rc != CRYPTO_GETFIELD_ERROR_BUF_TOO_SMALL) {
-                break;
-            }
-            free(valbuf);
-            valbuf_len *= 2;
-        }
-        if (rc == CRYPTO_GETFIELD_OK) {
-            cli->sendMsg(ResponseCode::CryptfsGetfieldResult, valbuf, false);
-        }
-        free(valbuf);
-    } else if (subcommand == "setfield") {
-        if (!check_argc(cli, subcommand, argc, 4, "<fieldname> <value>")) return 0;
-        dumpArgs(argc, argv, -1);
-        rc = cryptfs_setfield(argv[2], argv[3]);
-    } else if (subcommand == "mountdefaultencrypted") {
-        if (!check_argc(cli, subcommand, argc, 2, "")) return 0;
-        SLOGD("cryptfs mountdefaultencrypted");
-        dumpArgs(argc, argv, -1);
-
-        if (e4crypt_is_native()) {
-            return sendGenericOkFailOnBool(cli, e4crypt_mount_metadata_encrypted());
-        }
-        // Spawn as thread so init can issue commands back to vold without
-        // causing deadlock, usually as a result of prep_data_fs.
-        std::thread(&cryptfs_mount_default_encrypted).detach();
-    } else if (subcommand == "getpwtype") {
-        if (!check_argc(cli, subcommand, argc, 2, "")) return 0;
-        SLOGD("cryptfs getpwtype");
-        dumpArgs(argc, argv, -1);
-        switch(cryptfs_get_password_type()) {
-        case CRYPT_TYPE_PASSWORD:
-            cli->sendMsg(ResponseCode::PasswordTypeResult, "password", false);
-            return 0;
-        case CRYPT_TYPE_PATTERN:
-            cli->sendMsg(ResponseCode::PasswordTypeResult, "pattern", false);
-            return 0;
-        case CRYPT_TYPE_PIN:
-            cli->sendMsg(ResponseCode::PasswordTypeResult, "pin", false);
-            return 0;
-        case CRYPT_TYPE_DEFAULT:
-            cli->sendMsg(ResponseCode::PasswordTypeResult, "default", false);
-            return 0;
-        default:
-          /** @TODO better error and make sure handled by callers */
-            cli->sendMsg(ResponseCode::OpFailedStorageNotFound, "Error", false);
-            return 0;
-        }
-    } else if (subcommand == "getpw") {
-        if (!check_argc(cli, subcommand, argc, 2, "")) return 0;
-        SLOGD("cryptfs getpw");
-        dumpArgs(argc, argv, -1);
-        const char* password = cryptfs_get_password();
-        if (password) {
-            char* message = 0;
-            int size = asprintf(&message, "{{sensitive}} %s", password);
-            if (size != -1) {
-                cli->sendMsg(ResponseCode::CommandOkay, message, false);
-                memset(message, 0, size);
-                free (message);
-                return 0;
-            }
-        }
-        rc = -1;
-    } else if (subcommand == "clearpw") {
-        if (!check_argc(cli, subcommand, argc, 2, "")) return 0;
-        SLOGD("cryptfs clearpw");
-        dumpArgs(argc, argv, -1);
-        cryptfs_clear_password();
-        rc = 0;
-
-    } else if (subcommand == "isConvertibleToFBE") {
-        if (!check_argc(cli, subcommand, argc, 2, "")) return 0;
-        // ext4enc:TODO: send a CommandSyntaxError if argv[2] not an integer
-        SLOGD("cryptfs isConvertibleToFBE");
-        dumpArgs(argc, argv, -1);
-        rc = cryptfs_isConvertibleToFBE();
-
-    } else if (subcommand == "init_user0") {
-        if (!check_argc(cli, subcommand, argc, 2, "")) return 0;
-        return sendGenericOkFailOnBool(cli, e4crypt_init_user0());
-
-    } else if (subcommand == "create_user_key") {
-        if (!check_argc(cli, subcommand, argc, 5, "<user> <serial> <ephemeral>")) return 0;
-        return sendGenericOkFailOnBool(cli, e4crypt_vold_create_user_key(
-            atoi(argv[2]), atoi(argv[3]), atoi(argv[4]) != 0));
-
-    } else if (subcommand == "destroy_user_key") {
-        if (!check_argc(cli, subcommand, argc, 3, "<user>")) return 0;
-        return sendGenericOkFailOnBool(cli, e4crypt_destroy_user_key(atoi(argv[2])));
-
-    } else if (subcommand == "add_user_key_auth") {
-        if (!check_argc(cli, subcommand, argc, 6, "<user> <serial> <token> <secret>")) return 0;
-        return sendGenericOkFailOnBool(cli, e4crypt_add_user_key_auth(
-            atoi(argv[2]), atoi(argv[3]), argv[4], argv[5]));
-
-    } else if (subcommand == "fixate_newest_user_key_auth") {
-        if (!check_argc(cli, subcommand, argc, 3, "<user>")) return 0;
-        return sendGenericOkFailOnBool(cli, e4crypt_fixate_newest_user_key_auth(atoi(argv[2])));
-
-    } else if (subcommand == "unlock_user_key") {
-        if (!check_argc(cli, subcommand, argc, 6, "<user> <serial> <token> <secret>")) return 0;
-        return sendGenericOkFailOnBool(cli, e4crypt_unlock_user_key(
-            atoi(argv[2]), atoi(argv[3]), argv[4], argv[5]));
-
-    } else if (subcommand == "lock_user_key") {
-        if (!check_argc(cli, subcommand, argc, 3, "<user>")) return 0;
-        return sendGenericOkFailOnBool(cli, e4crypt_lock_user_key(atoi(argv[2])));
-
-    } else if (subcommand == "prepare_user_storage") {
-        if (!check_argc(cli, subcommand, argc, 6, "<uuid> <user> <serial> <flags>")) return 0;
-        return sendGenericOkFailOnBool(cli, e4crypt_prepare_user_storage(
-            parseNull(argv[2]), atoi(argv[3]), atoi(argv[4]), atoi(argv[5])));
-
-    } else if (subcommand == "destroy_user_storage") {
-        if (!check_argc(cli, subcommand, argc, 5, "<uuid> <user> <flags>")) return 0;
-        return sendGenericOkFailOnBool(cli,
-                e4crypt_destroy_user_storage(parseNull(argv[2]), atoi(argv[3]), atoi(argv[4])));
-
-    } else if (subcommand == "secdiscard") {
-        if (!check_argc(cli, subcommand, argc, 3, "<path>")) return 0;
-        return sendGenericOkFailOnBool(cli,
-                e4crypt_secdiscard(parseNull(argv[2])));
-
-    } else {
-        dumpArgs(argc, argv, -1);
-        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown cryptfs subcommand", false);
-        return 0;
-    }
-
-    // Always report that the command succeeded and return the error code.
-    // The caller will check the return value to see what the error was.
-    char msg[255];
-    snprintf(msg, sizeof(msg), "%d", rc);
-    cli->sendMsg(ResponseCode::CommandOkay, msg, false);
-
-    return 0;
-}
diff --git a/CryptCommandListener.h b/CryptCommandListener.h
deleted file mode 100644
index 478ac02..0000000
--- a/CryptCommandListener.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _CRYPTCOMMANDLISTENER_H__
-#define _CRYPTCOMMANDLISTENER_H__
-
-#include <sysutils/FrameworkListener.h>
-#include <utils/Errors.h>
-#include "VoldCommand.h"
-
-class CryptCommandListener : public FrameworkListener {
-public:
-    CryptCommandListener();
-    virtual ~CryptCommandListener() {}
-
-private:
-    static void dumpArgs(int argc, char **argv, int argObscure);
-    static int sendGenericOkFailOnBool(SocketClient *cli, bool success);
-
-    class CryptfsCmd : public VoldCommand {
-    public:
-        CryptfsCmd();
-        virtual ~CryptfsCmd() {}
-        int runCommand(SocketClient *c, int argc, char ** argv);
-    };
-    int getSocket();
-};
-
-#endif
diff --git a/Devmapper.cpp b/Devmapper.cpp
index c945e9f..ed498a3 100644
--- a/Devmapper.cpp
+++ b/Devmapper.cpp
@@ -34,7 +34,6 @@
 
 #include <android-base/logging.h>
 #include <android-base/stringprintf.h>
-#include <sysutils/SocketClient.h>
 
 #include "Devmapper.h"
 
@@ -44,82 +43,6 @@
 
 static const char* kVoldPrefix = "vold:";
 
-int Devmapper::dumpState(SocketClient *c) {
-
-    char *buffer = (char *) malloc(1024 * 64);
-    if (!buffer) {
-        SLOGE("Error allocating memory (%s)", strerror(errno));
-        return -1;
-    }
-    memset(buffer, 0, (1024 * 64));
-
-    char *buffer2 = (char *) malloc(DEVMAPPER_BUFFER_SIZE);
-    if (!buffer2) {
-        SLOGE("Error allocating memory (%s)", strerror(errno));
-        free(buffer);
-        return -1;
-    }
-
-    int fd;
-    if ((fd = open("/dev/device-mapper", O_RDWR | O_CLOEXEC)) < 0) {
-        SLOGE("Error opening devmapper (%s)", strerror(errno));
-        free(buffer);
-        free(buffer2);
-        return -1;
-    }
-
-    struct dm_ioctl *io = (struct dm_ioctl *) buffer;
-    ioctlInit(io, (1024 * 64), NULL, 0);
-
-    if (ioctl(fd, DM_LIST_DEVICES, io)) {
-        SLOGE("DM_LIST_DEVICES ioctl failed (%s)", strerror(errno));
-        free(buffer);
-        free(buffer2);
-        close(fd);
-        return -1;
-    }
-
-    struct dm_name_list *n = (struct dm_name_list *) (((char *) buffer) + io->data_start);
-    if (!n->dev) {
-        free(buffer);
-        free(buffer2);
-        close(fd);
-        return 0;
-    }
-
-    unsigned nxt = 0;
-    do {
-        n = (struct dm_name_list *) (((char *) n) + nxt);
-
-        memset(buffer2, 0, DEVMAPPER_BUFFER_SIZE);
-        struct dm_ioctl *io2 = (struct dm_ioctl *) buffer2;
-        ioctlInit(io2, DEVMAPPER_BUFFER_SIZE, n->name, 0);
-        if (ioctl(fd, DM_DEV_STATUS, io2)) {
-            if (errno != ENXIO) {
-                SLOGE("DM_DEV_STATUS ioctl failed (%s)", strerror(errno));
-            }
-            io2 = NULL;
-        }
-
-        char *tmp;
-        if (!io2) {
-            asprintf(&tmp, "%s %llu:%llu (no status available)", n->name, MAJOR(n->dev), MINOR(n->dev));
-        } else {
-            asprintf(&tmp, "%s %llu:%llu %d %d 0x%.8x %llu:%llu", n->name, MAJOR(n->dev),
-                    MINOR(n->dev), io2->target_count, io2->open_count, io2->flags, MAJOR(io2->dev),
-                            MINOR(io2->dev));
-        }
-        c->sendMsg(0, tmp, false);
-        free(tmp);
-        nxt = n->next;
-    } while (nxt);
-
-    free(buffer);
-    free(buffer2);
-    close(fd);
-    return 0;
-}
-
 void Devmapper::ioctlInit(struct dm_ioctl *io, size_t dataSize,
                           const char *name, unsigned flags) {
     memset(io, 0, dataSize);
diff --git a/Devmapper.h b/Devmapper.h
index dcc39d8..086ad78 100644
--- a/Devmapper.h
+++ b/Devmapper.h
@@ -20,8 +20,6 @@
 #include <unistd.h>
 #include <linux/dm-ioctl.h>
 
-class SocketClient;
-
 class Devmapper {
 public:
     static int create(const char *name, const char *loopFile, const char *key,
@@ -29,7 +27,6 @@
     static int destroy(const char *name);
     static int destroyAll();
     static int lookupActive(const char *name, char *buffer, size_t len);
-    static int dumpState(SocketClient *c);
 
 private:
     static void *_align(void *ptr, unsigned int a);
diff --git a/Loop.cpp b/Loop.cpp
index 325b0d3..fc3909b 100644
--- a/Loop.cpp
+++ b/Loop.cpp
@@ -36,9 +36,7 @@
 #include <android-base/stringprintf.h>
 #include <android-base/unique_fd.h>
 
-#include <sysutils/SocketClient.h>
 #include "Loop.h"
-#include "Asec.h"
 #include "VoldUtil.h"
 #include "sehandle.h"
 
@@ -47,48 +45,6 @@
 
 static const char* kVoldPrefix = "vold:";
 
-int Loop::dumpState(SocketClient *c) {
-    int i;
-    int fd;
-    char filename[256];
-
-    for (i = 0; i < LOOP_MAX; i++) {
-        struct loop_info64 li;
-        int rc;
-
-        snprintf(filename, sizeof(filename), "/dev/block/loop%d", i);
-
-        if ((fd = open(filename, O_RDWR | O_CLOEXEC)) < 0) {
-            if (errno != ENOENT) {
-                SLOGE("Unable to open %s (%s)", filename, strerror(errno));
-            } else {
-                continue;
-            }
-            return -1;
-        }
-
-        rc = ioctl(fd, LOOP_GET_STATUS64, &li);
-        close(fd);
-        if (rc < 0 && errno == ENXIO) {
-            continue;
-        }
-
-        if (rc < 0) {
-            SLOGE("Unable to get loop status for %s (%s)", filename,
-                 strerror(errno));
-            return -1;
-        }
-        char *tmp = NULL;
-        asprintf(&tmp, "%s %d %lld:%lld %llu %lld:%lld %lld 0x%x {%s} {%s}", filename, li.lo_number,
-                MAJOR(li.lo_device), MINOR(li.lo_device), li.lo_inode, MAJOR(li.lo_rdevice),
-                        MINOR(li.lo_rdevice), li.lo_offset, li.lo_flags, li.lo_crypt_name,
-                        li.lo_file_name);
-        c->sendMsg(0, tmp, false);
-        free(tmp);
-    }
-    return 0;
-}
-
 int Loop::lookupActive(const char *id_raw, char *buffer, size_t len) {
     auto id_string = StringPrintf("%s%s", kVoldPrefix, id_raw);
     const char* id = id_string.c_str();
@@ -380,46 +336,3 @@
     close(fd);
     return 0;
 }
-
-int Loop::lookupInfo(const char *loopDevice, struct asec_superblock *sb, unsigned long *nr_sec) {
-    int fd;
-    struct asec_superblock buffer;
-
-    if ((fd = open(loopDevice, O_RDONLY | O_CLOEXEC)) < 0) {
-        SLOGE("Failed to open loopdevice (%s)", strerror(errno));
-        destroyByDevice(loopDevice);
-        return -1;
-    }
-
-    get_blkdev_size(fd, nr_sec);
-    if (*nr_sec == 0) {
-        SLOGE("Failed to get loop size (%s)", strerror(errno));
-        destroyByDevice(loopDevice);
-        close(fd);
-        return -1;
-    }
-
-    /*
-     * Try to read superblock.
-     */
-    memset(&buffer, 0, sizeof(struct asec_superblock));
-    if (lseek(fd, ((*nr_sec - 1) * 512), SEEK_SET) < 0) {
-        SLOGE("lseek failed (%s)", strerror(errno));
-        close(fd);
-        destroyByDevice(loopDevice);
-        return -1;
-    }
-    if (read(fd, &buffer, sizeof(struct asec_superblock)) != sizeof(struct asec_superblock)) {
-        SLOGE("superblock read failed (%s)", strerror(errno));
-        close(fd);
-        destroyByDevice(loopDevice);
-        return -1;
-    }
-    close(fd);
-
-    /*
-     * Superblock successfully read. Copy to caller's struct.
-     */
-    memcpy(sb, &buffer, sizeof(struct asec_superblock));
-    return 0;
-}
diff --git a/Loop.h b/Loop.h
index e3ad239..654b8ad 100644
--- a/Loop.h
+++ b/Loop.h
@@ -21,22 +21,17 @@
 #include <unistd.h>
 #include <linux/loop.h>
 
-class SocketClient;
-
 class Loop {
 public:
     static const int LOOP_MAX = 4096;
 public:
     static int lookupActive(const char *id, char *buffer, size_t len);
-    static int lookupInfo(const char *loopDevice, struct asec_superblock *sb, unsigned long *nr_sec);
     static int create(const char *id, const char *loopFile, char *loopDeviceBuffer, size_t len);
     static int create(const std::string& file, std::string& out_device);
     static int destroyByDevice(const char *loopDevice);
     static int destroyAll();
     static int createImageFile(const char *file, unsigned long numSectors);
     static int resizeImageFile(const char *file, unsigned long numSectors);
-
-    static int dumpState(SocketClient *c);
 };
 
 #endif
diff --git a/MoveTask.cpp b/MoveTask.cpp
index 8c0efac..4268ed4 100644
--- a/MoveTask.cpp
+++ b/MoveTask.cpp
@@ -17,7 +17,6 @@
 #include "MoveTask.h"
 #include "Utils.h"
 #include "VolumeManager.h"
-#include "ResponseCode.h"
 
 #include <android-base/stringprintf.h>
 #include <android-base/logging.h>
diff --git a/ResponseCode.cpp b/ResponseCode.cpp
deleted file mode 100644
index d7e778d..0000000
--- a/ResponseCode.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-
-#define LOG_TAG "Vold"
-
-#include <cutils/log.h>
-
-#include "ResponseCode.h"
-
-int ResponseCode::convertFromErrno() {
-   if (errno == ENODEV) {
-        return(ResponseCode::OpFailedNoMedia);
-    } else if (errno == ENODATA) {
-        return(ResponseCode::OpFailedMediaBlank);
-    } else if (errno == EIO) {
-        return(ResponseCode::OpFailedMediaCorrupt);
-    } else if (errno == EBUSY) {
-        return(ResponseCode::OpFailedStorageBusy);
-    } else if (errno == ENOENT) {
-        return(ResponseCode::OpFailedStorageNotFound);
-    }
-
-    SLOGW("Returning OperationFailed - no handler for errno %d", errno);
-    return(ResponseCode::OperationFailed);
-}
diff --git a/ResponseCode.h b/ResponseCode.h
deleted file mode 100644
index f2c533e..0000000
--- a/ResponseCode.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _RESPONSECODE_H
-#define _RESPONSECODE_H
-
-class ResponseCode {
-public:
-    // 100 series - Requestion action was initiated; expect another reply
-    // before proceeding with a new command.
-    static const int ActionInitiated  = 100;
-
-    static const int VolumeListResult         = 110;
-    static const int AsecListResult           = 111;
-    static const int StorageUsersListResult   = 112;
-    static const int CryptfsGetfieldResult    = 113;
-
-    // 200 series - Requested action has been successfully completed
-    static const int CommandOkay              = 200;
-    static const int ShareStatusResult        = 210;
-    static const int AsecPathResult           = 211;
-    static const int ShareEnabledResult       = 212;
-    static const int PasswordTypeResult       = 213;
-
-    // 400 series - The command was accepted but the requested action
-    // did not take place.
-    static const int OperationFailed          = 400;
-    static const int OpFailedNoMedia          = 401;
-    static const int OpFailedMediaBlank       = 402;
-    static const int OpFailedMediaCorrupt     = 403;
-    static const int OpFailedVolNotMounted    = 404;
-    static const int OpFailedStorageBusy      = 405;
-    static const int OpFailedStorageNotFound  = 406;
-
-    // 500 series - The command was not accepted and the requested
-    // action did not take place.
-    static const int CommandSyntaxError = 500;
-    static const int CommandParameterError = 501;
-    static const int CommandNoPermission = 502;
-
-    // 600 series - Unsolicited broadcasts
-    static const int UnsolicitedInformational       = 600;
-    static const int VolumeStateChange              = 605;
-    static const int VolumeMountFailedBlank         = 610;
-    static const int VolumeMountFailedDamaged       = 611;
-    static const int VolumeMountFailedNoMedia       = 612;
-    static const int VolumeUuidChange               = 613;
-    static const int VolumeUserLabelChange          = 614;
-
-    static const int ShareAvailabilityChange        = 620;
-
-    static const int VolumeDiskInserted            = 630;
-    static const int VolumeDiskRemoved             = 631;
-    static const int VolumeBadRemoval              = 632;
-
-    static const int DiskCreated = 640;
-    static const int DiskSizeChanged = 641;
-    static const int DiskLabelChanged = 642;
-    static const int DiskScanned = 643;
-    static const int DiskSysPathChanged = 644;
-    static const int DiskDestroyed = 649;
-
-    static const int VolumeCreated = 650;
-    static const int VolumeStateChanged = 651;
-    static const int VolumeFsTypeChanged = 652;
-    static const int VolumeFsUuidChanged = 653;
-    static const int VolumeFsLabelChanged = 654;
-    static const int VolumePathChanged = 655;
-    static const int VolumeInternalPathChanged = 656;
-    static const int VolumeDestroyed = 659;
-
-    static const int MoveStatus = 660;
-    static const int BenchmarkResult = 661;
-    static const int TrimResult = 662;
-
-    static int convertFromErrno();
-};
-#endif
diff --git a/TrimTask.cpp b/TrimTask.cpp
index d37ec20..fafb345 100644
--- a/TrimTask.cpp
+++ b/TrimTask.cpp
@@ -17,7 +17,6 @@
 #include "TrimTask.h"
 #include "Utils.h"
 #include "VolumeManager.h"
-#include "ResponseCode.h"
 
 #include <android-base/stringprintf.h>
 #include <android-base/logging.h>
diff --git a/Utils.h b/Utils.h
index 153c320..4e2be96 100644
--- a/Utils.h
+++ b/Utils.h
@@ -29,8 +29,6 @@
 
 struct DIR;
 
-#define ENABLE_BINDER 1
-
 namespace android {
 namespace vold {
 
diff --git a/VoldCommand.cpp b/VoldCommand.cpp
deleted file mode 100644
index 3c0d58d..0000000
--- a/VoldCommand.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "VoldCommand.h"
-
-VoldCommand::VoldCommand(const char *cmd) :
-              FrameworkCommand(cmd)  {
-}
diff --git a/VoldCommand.h b/VoldCommand.h
deleted file mode 100644
index e435159..0000000
--- a/VoldCommand.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _VOLD_COMMAND_H
-#define _VOLD_COMMAND_H
-
-#include <sysutils/FrameworkCommand.h>
-
-class VoldCommand : public FrameworkCommand {
-public:
-    explicit VoldCommand(const char *cmd);
-    virtual ~VoldCommand() {}
-};
-
-#endif
diff --git a/VoldNativeService.cpp b/VoldNativeService.cpp
index 6c25674..310610c 100644
--- a/VoldNativeService.cpp
+++ b/VoldNativeService.cpp
@@ -211,6 +211,20 @@
     return ok();
 }
 
+binder::Status VoldNativeService::monitor() {
+    ENFORCE_UID(AID_SYSTEM);
+
+    // Simply acquire/release each lock for watchdog
+    {
+        ACQUIRE_LOCK;
+    }
+    {
+        ACQUIRE_CRYPT_LOCK;
+    }
+
+    return ok();
+}
+
 binder::Status VoldNativeService::reset() {
     ENFORCE_UID(AID_SYSTEM);
     ACQUIRE_LOCK;
diff --git a/VoldNativeService.h b/VoldNativeService.h
index a00010b..dd2b854 100644
--- a/VoldNativeService.h
+++ b/VoldNativeService.h
@@ -33,6 +33,7 @@
 
     binder::Status setListener(const android::sp<android::os::IVoldListener>& listener);
 
+    binder::Status monitor();
     binder::Status reset();
     binder::Status shutdown();
     binder::Status mountAll();
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index 3150997..70f71f9 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -51,45 +51,18 @@
 #include "model/ObbVolume.h"
 #include "VolumeManager.h"
 #include "NetlinkManager.h"
-#include "ResponseCode.h"
 #include "Loop.h"
 #include "fs/Ext4.h"
 #include "fs/Vfat.h"
 #include "Utils.h"
 #include "Devmapper.h"
 #include "Process.h"
-#include "Asec.h"
 #include "VoldUtil.h"
 #include "cryptfs.h"
 
-#define MASS_STORAGE_FILE_PATH  "/sys/class/android_usb/android0/f_mass_storage/lun/file"
-
-#define ROUND_UP_POWER_OF_2(number, po2) (((!!((number) & ((1U << (po2)) - 1))) << (po2))\
-                                         + ((number) & (~((1U << (po2)) - 1))))
-
 using android::base::StringPrintf;
 using android::base::unique_fd;
 
-/*
- * Path to external storage where *only* root can access ASEC image files
- */
-const char *VolumeManager::SEC_ASECDIR_EXT   = "/mnt/secure/asec";
-
-/*
- * Path to internal storage where *only* root can access ASEC image files
- */
-const char *VolumeManager::SEC_ASECDIR_INT   = "/data/app-asec";
-
-/*
- * Path to where secure containers are mounted
- */
-const char *VolumeManager::ASECDIR           = "/mnt/asec";
-
-/*
- * Path to where OBBs are mounted
- */
-const char *VolumeManager::LOOPDIR           = "/mnt/obb";
-
 bool VolumeManager::shutting_down = false;
 
 static const char* kPathUserMount = "/mnt/user";
@@ -104,107 +77,6 @@
 static const unsigned int kMajorBlockExperimentalMin = 240;
 static const unsigned int kMajorBlockExperimentalMax = 254;
 
-/* writes superblock at end of file or device given by name */
-static int writeSuperBlock(const char* name, struct asec_superblock *sb, unsigned int numImgSectors) {
-    int sbfd = open(name, O_RDWR | O_CLOEXEC);
-    if (sbfd < 0) {
-        SLOGE("Failed to open %s for superblock write (%s)", name, strerror(errno));
-        return -1;
-    }
-
-    if (lseek(sbfd, (numImgSectors * 512), SEEK_SET) < 0) {
-        SLOGE("Failed to lseek for superblock (%s)", strerror(errno));
-        close(sbfd);
-        return -1;
-    }
-
-    if (write(sbfd, sb, sizeof(struct asec_superblock)) != sizeof(struct asec_superblock)) {
-        SLOGE("Failed to write superblock (%s)", strerror(errno));
-        close(sbfd);
-        return -1;
-    }
-    close(sbfd);
-    return 0;
-}
-
-static unsigned long adjustSectorNumExt4(unsigned long numSectors) {
-    // Ext4 started to reserve 2% or 4096 clusters, whichever is smaller for
-    // preventing costly operations or unexpected ENOSPC error.
-    // Ext4::format() uses default block size without clustering.
-    unsigned long clusterSectors = 4096 / 512;
-    unsigned long reservedSectors = (numSectors * 2)/100 + (numSectors % 50 > 0);
-    numSectors += reservedSectors > (4096 * clusterSectors) ? (4096 * clusterSectors) : reservedSectors;
-    return ROUND_UP_POWER_OF_2(numSectors, 3);
-}
-
-static unsigned long adjustSectorNumFAT(unsigned long numSectors) {
-    /*
-    * Add some headroom
-    */
-    unsigned long fatSize = (((numSectors * 4) / 512) + 1) * 2;
-    numSectors += fatSize + 2;
-    /*
-    * FAT is aligned to 32 kb with 512b sectors.
-    */
-    return ROUND_UP_POWER_OF_2(numSectors, 6);
-}
-
-static int setupLoopDevice(char* buffer, size_t len, const char* asecFileName, const char* idHash, bool debug) {
-    if (Loop::lookupActive(idHash, buffer, len)) {
-        if (Loop::create(idHash, asecFileName, buffer, len)) {
-            SLOGE("ASEC loop device creation failed for %s (%s)", asecFileName, strerror(errno));
-            return -1;
-        }
-        if (debug) {
-            SLOGD("New loop device created at %s", buffer);
-        }
-    } else {
-        if (debug) {
-            SLOGD("Found active loopback for %s at %s", asecFileName, buffer);
-        }
-    }
-    return 0;
-}
-
-static int setupDevMapperDevice(char* buffer, size_t len, const char* loopDevice, const char* asecFileName, const char* key, const char* idHash , unsigned long numImgSectors, bool* createdDMDevice, bool debug) {
-    if (strcmp(key, "none")) {
-        if (Devmapper::lookupActive(idHash, buffer, len)) {
-            if (Devmapper::create(idHash, loopDevice, key, numImgSectors,
-                                  buffer, len)) {
-                SLOGE("ASEC device mapping failed for %s (%s)", asecFileName, strerror(errno));
-                return -1;
-            }
-            if (debug) {
-                SLOGD("New devmapper instance created at %s", buffer);
-            }
-        } else {
-            if (debug) {
-                SLOGD("Found active devmapper for %s at %s", asecFileName, buffer);
-            }
-        }
-        *createdDMDevice = true;
-    } else {
-        strlcpy(buffer, loopDevice, len);
-        *createdDMDevice = false;
-    }
-    return 0;
-}
-
-static void waitForDevMapper(const char *dmDevice) {
-    /*
-     * Wait for the device mapper node to be created. Sometimes it takes a
-     * while. Wait for up to 1 second. We could also inspect incoming uevents,
-     * but that would take more effort.
-     */
-    int tries = 25;
-    while (tries--) {
-        if (!access(dmDevice, F_OK) || errno != ENOENT) {
-            break;
-        }
-        usleep(40 * 1000);
-    }
-}
-
 VolumeManager *VolumeManager::sInstance = NULL;
 
 VolumeManager *VolumeManager::Instance() {
@@ -215,49 +87,10 @@
 
 VolumeManager::VolumeManager() {
     mDebug = false;
-    mActiveContainers = new AsecIdCollection();
-    mBroadcaster = NULL;
-    mUmsSharingCount = 0;
-    mSavedDirtyRatio = -1;
-    // set dirty ratio to 0 when UMS is active
-    mUmsDirtyRatio = 0;
     mNextObbId = 0;
 }
 
 VolumeManager::~VolumeManager() {
-    delete mActiveContainers;
-}
-
-char *VolumeManager::asecHash(const char *id, char *buffer, size_t len) {
-    static const char* digits = "0123456789abcdef";
-
-    unsigned char sig[MD5_DIGEST_LENGTH];
-
-    if (buffer == NULL) {
-        SLOGE("Destination buffer is NULL");
-        errno = ESPIPE;
-        return NULL;
-    } else if (id == NULL) {
-        SLOGE("Source buffer is NULL");
-        errno = ESPIPE;
-        return NULL;
-    } else if (len < MD5_ASCII_LENGTH_PLUS_NULL) {
-        SLOGE("Target hash buffer size < %d bytes (%zu)",
-                MD5_ASCII_LENGTH_PLUS_NULL, len);
-        errno = ESPIPE;
-        return NULL;
-    }
-
-    MD5(reinterpret_cast<const unsigned char*>(id), strlen(id), sig);
-
-    char *p = buffer;
-    for (int i = 0; i < MD5_DIGEST_LENGTH; i++) {
-        *p++ = digits[sig[i] >> 4];
-        *p++ = digits[sig[i] & 0x0F];
-    }
-    *p = '\0';
-
-    return buffer;
 }
 
 int VolumeManager::updateVirtualDisk() {
@@ -752,1197 +585,11 @@
     return 0;
 }
 
-int VolumeManager::getObbMountPath(const char *sourceFile, char *mountPath, int mountPathLen) {
-    char idHash[33];
-    if (!asecHash(sourceFile, idHash, sizeof(idHash))) {
-        SLOGE("Hash of '%s' failed (%s)", sourceFile, strerror(errno));
-        return -1;
-    }
-
-    memset(mountPath, 0, mountPathLen);
-    int written = snprintf(mountPath, mountPathLen, "%s/%s", VolumeManager::LOOPDIR, idHash);
-    if ((written < 0) || (written >= mountPathLen)) {
-        errno = EINVAL;
-        return -1;
-    }
-
-    if (access(mountPath, F_OK)) {
-        errno = ENOENT;
-        return -1;
-    }
-
-    return 0;
-}
-
-int VolumeManager::getAsecMountPath(const char *id, char *buffer, int maxlen) {
-    char asecFileName[255];
-
-    if (!isLegalAsecId(id)) {
-        SLOGE("getAsecMountPath: Invalid asec id \"%s\"", id);
-        errno = EINVAL;
-        return -1;
-    }
-
-    if (findAsec(id, asecFileName, sizeof(asecFileName))) {
-        SLOGE("Couldn't find ASEC %s", id);
-        return -1;
-    }
-
-    memset(buffer, 0, maxlen);
-    if (access(asecFileName, F_OK)) {
-        errno = ENOENT;
-        return -1;
-    }
-
-    int written = snprintf(buffer, maxlen, "%s/%s", VolumeManager::ASECDIR, id);
-    if ((written < 0) || (written >= maxlen)) {
-        SLOGE("getAsecMountPath failed for %s: couldn't construct path in buffer", id);
-        errno = EINVAL;
-        return -1;
-    }
-
-    return 0;
-}
-
-int VolumeManager::getAsecFilesystemPath(const char *id, char *buffer, int maxlen) {
-    char asecFileName[255];
-
-    if (!isLegalAsecId(id)) {
-        SLOGE("getAsecFilesystemPath: Invalid asec id \"%s\"", id);
-        errno = EINVAL;
-        return -1;
-    }
-
-    if (findAsec(id, asecFileName, sizeof(asecFileName))) {
-        SLOGE("Couldn't find ASEC %s", id);
-        return -1;
-    }
-
-    memset(buffer, 0, maxlen);
-    if (access(asecFileName, F_OK)) {
-        errno = ENOENT;
-        return -1;
-    }
-
-    int written = snprintf(buffer, maxlen, "%s", asecFileName);
-    if ((written < 0) || (written >= maxlen)) {
-        errno = EINVAL;
-        return -1;
-    }
-
-    return 0;
-}
-
-int VolumeManager::createAsec(const char *id, unsigned long numSectors, const char *fstype,
-        const char *key, const int ownerUid, bool isExternal) {
-    struct asec_superblock sb;
-    memset(&sb, 0, sizeof(sb));
-
-    if (!isLegalAsecId(id)) {
-        SLOGE("createAsec: Invalid asec id \"%s\"", id);
-        errno = EINVAL;
-        return -1;
-    }
-
-    const bool wantFilesystem = strcmp(fstype, "none");
-    bool usingExt4 = false;
-    if (wantFilesystem) {
-        usingExt4 = !strcmp(fstype, "ext4");
-        if (usingExt4) {
-            sb.c_opts |= ASEC_SB_C_OPTS_EXT4;
-        } else if (strcmp(fstype, "fat")) {
-            SLOGE("Invalid filesystem type %s", fstype);
-            errno = EINVAL;
-            return -1;
-        }
-    }
-
-    sb.magic = ASEC_SB_MAGIC;
-    sb.ver = ASEC_SB_VER;
-
-    if (numSectors < ((1024*1024)/512)) {
-        SLOGE("Invalid container size specified (%lu sectors)", numSectors);
-        errno = EINVAL;
-        return -1;
-    }
-
-    char asecFileName[255];
-
-    if (!findAsec(id, asecFileName, sizeof(asecFileName))) {
-        SLOGE("ASEC file '%s' currently exists - destroy it first! (%s)",
-                asecFileName, strerror(errno));
-        errno = EADDRINUSE;
-        return -1;
-    }
-
-    const char *asecDir = isExternal ? VolumeManager::SEC_ASECDIR_EXT : VolumeManager::SEC_ASECDIR_INT;
-
-    int written = snprintf(asecFileName, sizeof(asecFileName), "%s/%s.asec", asecDir, id);
-    if ((written < 0) || (size_t(written) >= sizeof(asecFileName))) {
-        errno = EINVAL;
-        return -1;
-    }
-
-    if (!access(asecFileName, F_OK)) {
-        SLOGE("ASEC file '%s' currently exists - destroy it first! (%s)",
-                asecFileName, strerror(errno));
-        errno = EADDRINUSE;
-        return -1;
-    }
-
-    unsigned long numImgSectors;
-    if (usingExt4)
-        numImgSectors = adjustSectorNumExt4(numSectors);
-    else
-        numImgSectors = adjustSectorNumFAT(numSectors);
-
-    // Add +1 for our superblock which is at the end
-    if (Loop::createImageFile(asecFileName, numImgSectors + 1)) {
-        SLOGE("ASEC image file creation failed (%s)", strerror(errno));
-        return -1;
-    }
-
-    char idHash[33];
-    if (!asecHash(id, idHash, sizeof(idHash))) {
-        SLOGE("Hash of '%s' failed (%s)", id, strerror(errno));
-        unlink(asecFileName);
-        return -1;
-    }
-
-    char loopDevice[255];
-    if (Loop::create(idHash, asecFileName, loopDevice, sizeof(loopDevice))) {
-        SLOGE("ASEC loop device creation failed (%s)", strerror(errno));
-        unlink(asecFileName);
-        return -1;
-    }
-
-    char dmDevice[255];
-    bool cleanupDm = false;
-
-    if (strcmp(key, "none")) {
-        // XXX: This is all we support for now
-        sb.c_cipher = ASEC_SB_C_CIPHER_TWOFISH;
-        if (Devmapper::create(idHash, loopDevice, key, numImgSectors, dmDevice,
-                             sizeof(dmDevice))) {
-            SLOGE("ASEC device mapping failed (%s)", strerror(errno));
-            Loop::destroyByDevice(loopDevice);
-            unlink(asecFileName);
-            return -1;
-        }
-        cleanupDm = true;
-    } else {
-        sb.c_cipher = ASEC_SB_C_CIPHER_NONE;
-        strlcpy(dmDevice, loopDevice, sizeof(dmDevice));
-    }
-
-    /*
-     * Drop down the superblock at the end of the file
-     */
-    if (writeSuperBlock(loopDevice, &sb, numImgSectors)) {
-        if (cleanupDm) {
-            Devmapper::destroy(idHash);
-        }
-        Loop::destroyByDevice(loopDevice);
-        unlink(asecFileName);
-        return -1;
-    }
-
-    if (wantFilesystem) {
-        int formatStatus;
-        char mountPoint[255];
-
-        int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::ASECDIR, id);
-        if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
-            SLOGE("ASEC fs format failed: couldn't construct mountPoint");
-            if (cleanupDm) {
-                Devmapper::destroy(idHash);
-            }
-            Loop::destroyByDevice(loopDevice);
-            unlink(asecFileName);
-            return -1;
-        }
-
-        if (usingExt4) {
-            formatStatus = android::vold::ext4::Format(dmDevice, numImgSectors, mountPoint);
-        } else {
-            formatStatus = android::vold::vfat::Format(dmDevice, numImgSectors);
-        }
-
-        if (formatStatus < 0) {
-            SLOGE("ASEC fs format failed (%s)", strerror(errno));
-            if (cleanupDm) {
-                Devmapper::destroy(idHash);
-            }
-            Loop::destroyByDevice(loopDevice);
-            unlink(asecFileName);
-            return -1;
-        }
-
-        if (mkdir(mountPoint, 0000)) {
-            if (errno != EEXIST) {
-                SLOGE("Mountpoint creation failed (%s)", strerror(errno));
-                if (cleanupDm) {
-                    Devmapper::destroy(idHash);
-                }
-                Loop::destroyByDevice(loopDevice);
-                unlink(asecFileName);
-                return -1;
-            }
-        }
-
-        int mountStatus;
-        if (usingExt4) {
-            mountStatus = android::vold::ext4::Mount(dmDevice, mountPoint,
-                    false, false, false);
-        } else {
-            mountStatus = android::vold::vfat::Mount(dmDevice, mountPoint,
-                    false, false, false, ownerUid, 0, 0000, false);
-        }
-
-        if (mountStatus) {
-            SLOGE("ASEC FAT mount failed (%s)", strerror(errno));
-            if (cleanupDm) {
-                Devmapper::destroy(idHash);
-            }
-            Loop::destroyByDevice(loopDevice);
-            unlink(asecFileName);
-            return -1;
-        }
-
-        if (usingExt4) {
-            int dirfd = open(mountPoint, O_DIRECTORY | O_CLOEXEC);
-            if (dirfd >= 0) {
-                if (fchown(dirfd, ownerUid, AID_SYSTEM)
-                        || fchmod(dirfd, S_IRUSR | S_IWUSR | S_IXUSR | S_ISGID | S_IRGRP | S_IXGRP)) {
-                    SLOGI("Cannot chown/chmod new ASEC mount point %s", mountPoint);
-                }
-                close(dirfd);
-            }
-        }
-    } else {
-        SLOGI("Created raw secure container %s (no filesystem)", id);
-    }
-
-    mActiveContainers->push_back(new ContainerData(strdup(id), ASEC));
-    return 0;
-}
-
-int VolumeManager::resizeAsec(const char *id, unsigned long numSectors, const char *key) {
-    char asecFileName[255];
-    char mountPoint[255];
-    bool cleanupDm = false;
-
-    if (!isLegalAsecId(id)) {
-        SLOGE("resizeAsec: Invalid asec id \"%s\"", id);
-        errno = EINVAL;
-        return -1;
-    }
-
-    if (findAsec(id, asecFileName, sizeof(asecFileName))) {
-        SLOGE("Couldn't find ASEC %s", id);
-        return -1;
-    }
-
-    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::ASECDIR, id);
-    if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
-       SLOGE("ASEC resize failed for %s: couldn't construct mountpoint", id);
-       return -1;
-    }
-
-    if (isMountpointMounted(mountPoint)) {
-       SLOGE("ASEC %s mounted. Unmount before resizing", id);
-       errno = EBUSY;
-       return -1;
-    }
-
-    struct asec_superblock sb;
-    int fd;
-    unsigned long oldNumSec = 0;
-
-    if ((fd = open(asecFileName, O_RDONLY | O_CLOEXEC)) < 0) {
-        SLOGE("Failed to open ASEC file (%s)", strerror(errno));
-        return -1;
-    }
-
-    struct stat info;
-    if (fstat(fd, &info) < 0) {
-        SLOGE("Failed to get file size (%s)", strerror(errno));
-        close(fd);
-        return -1;
-    }
-
-    oldNumSec = info.st_size / 512;
-
-    /*
-     * Try to read superblock.
-     */
-    memset(&sb, 0, sizeof(struct asec_superblock));
-    if (lseek(fd, ((oldNumSec - 1) * 512), SEEK_SET) < 0) {
-        SLOGE("lseek failed (%s)", strerror(errno));
-        close(fd);
-        return -1;
-    }
-    if (read(fd, &sb, sizeof(struct asec_superblock)) != sizeof(struct asec_superblock)) {
-        SLOGE("superblock read failed (%s)", strerror(errno));
-        close(fd);
-        return -1;
-    }
-    close(fd);
-
-    if (mDebug) {
-        SLOGD("Container sb magic/ver (%.8x/%.2x)", sb.magic, sb.ver);
-    }
-    if (sb.magic != ASEC_SB_MAGIC || sb.ver != ASEC_SB_VER) {
-        SLOGE("Bad container magic/version (%.8x/%.2x)", sb.magic, sb.ver);
-        errno = EMEDIUMTYPE;
-        return -1;
-    }
-
-    unsigned long numImgSectors;
-    if (!(sb.c_opts & ASEC_SB_C_OPTS_EXT4)) {
-        SLOGE("Only ext4 partitions are supported for resize");
-        errno = EINVAL;
-        return -1;
-    } else {
-        numImgSectors = adjustSectorNumExt4(numSectors);
-    }
-
-    /*
-     *  add one block for the superblock
-     */
-    SLOGD("Resizing from %lu sectors to %lu sectors", oldNumSec, numImgSectors + 1);
-    if (oldNumSec == numImgSectors + 1) {
-        SLOGW("Size unchanged; ignoring resize request");
-        return 0;
-    } else if (oldNumSec > numImgSectors + 1) {
-        SLOGE("Only growing is currently supported.");
-        close(fd);
-        return -1;
-    }
-
-    if (Loop::resizeImageFile(asecFileName, numImgSectors + 1)) {
-        SLOGE("Resize of ASEC image file failed. Could not resize %s", id);
-        return -1;
-    }
-
-    /*
-     * Drop down a copy of the superblock at the end of the file
-     */
-    if (writeSuperBlock(asecFileName, &sb, numImgSectors))
-        goto fail;
-
-    char idHash[33];
-    if (!asecHash(id, idHash, sizeof(idHash))) {
-        SLOGE("Hash of '%s' failed (%s)", id, strerror(errno));
-        goto fail;
-    }
-
-    char loopDevice[255];
-    if (setupLoopDevice(loopDevice, sizeof(loopDevice), asecFileName, idHash, mDebug))
-        goto fail;
-
-    char dmDevice[255];
-
-    if (setupDevMapperDevice(dmDevice, sizeof(dmDevice), loopDevice, asecFileName, key, idHash, numImgSectors, &cleanupDm, mDebug)) {
-        Loop::destroyByDevice(loopDevice);
-        goto fail;
-    }
-
-    /*
-     * Wait for the device mapper node to be created.
-     */
-    waitForDevMapper(dmDevice);
-
-    if (android::vold::ext4::Resize(dmDevice, numImgSectors)) {
-        SLOGE("Unable to resize %s (%s)", id, strerror(errno));
-        if (cleanupDm) {
-            Devmapper::destroy(idHash);
-        }
-        Loop::destroyByDevice(loopDevice);
-        goto fail;
-    }
-
-    return 0;
-fail:
-    Loop::resizeImageFile(asecFileName, oldNumSec);
-    return -1;
-}
-
-int VolumeManager::finalizeAsec(const char *id) {
-    char asecFileName[255];
-    char loopDevice[255];
-    char mountPoint[255];
-
-    if (!isLegalAsecId(id)) {
-        SLOGE("finalizeAsec: Invalid asec id \"%s\"", id);
-        errno = EINVAL;
-        return -1;
-    }
-
-    if (findAsec(id, asecFileName, sizeof(asecFileName))) {
-        SLOGE("Couldn't find ASEC %s", id);
-        return -1;
-    }
-
-    char idHash[33];
-    if (!asecHash(id, idHash, sizeof(idHash))) {
-        SLOGE("Hash of '%s' failed (%s)", id, strerror(errno));
-        return -1;
-    }
-
-    if (Loop::lookupActive(idHash, loopDevice, sizeof(loopDevice))) {
-        SLOGE("Unable to finalize %s (%s)", id, strerror(errno));
-        return -1;
-    }
-
-    unsigned long nr_sec = 0;
-    struct asec_superblock sb;
-
-    if (Loop::lookupInfo(loopDevice, &sb, &nr_sec)) {
-        return -1;
-    }
-
-    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::ASECDIR, id);
-    if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
-        SLOGE("ASEC finalize failed: couldn't construct mountPoint");
-        return -1;
-    }
-
-    int result = 0;
-    if (sb.c_opts & ASEC_SB_C_OPTS_EXT4) {
-        result = android::vold::ext4::Mount(loopDevice, mountPoint,
-                true, true, true);
-    } else {
-        result = android::vold::vfat::Mount(loopDevice, mountPoint,
-                true, true, true, 0, 0, 0227, false);
-    }
-
-    if (result) {
-        SLOGE("ASEC finalize mount failed (%s)", strerror(errno));
-        return -1;
-    }
-
-    if (mDebug) {
-        SLOGD("ASEC %s finalized", id);
-    }
-    return 0;
-}
-
-int VolumeManager::fixupAsecPermissions(const char *id, gid_t gid, const char* filename) {
-    char asecFileName[255];
-    char loopDevice[255];
-    char mountPoint[255];
-
-    if (gid < AID_APP) {
-        SLOGE("Group ID is not in application range");
-        return -1;
-    }
-
-    if (!isLegalAsecId(id)) {
-        SLOGE("fixupAsecPermissions: Invalid asec id \"%s\"", id);
-        errno = EINVAL;
-        return -1;
-    }
-
-    if (findAsec(id, asecFileName, sizeof(asecFileName))) {
-        SLOGE("Couldn't find ASEC %s", id);
-        return -1;
-    }
-
-    char idHash[33];
-    if (!asecHash(id, idHash, sizeof(idHash))) {
-        SLOGE("Hash of '%s' failed (%s)", id, strerror(errno));
-        return -1;
-    }
-
-    if (Loop::lookupActive(idHash, loopDevice, sizeof(loopDevice))) {
-        SLOGE("Unable fix permissions during lookup on %s (%s)", id, strerror(errno));
-        return -1;
-    }
-
-    unsigned long nr_sec = 0;
-    struct asec_superblock sb;
-
-    if (Loop::lookupInfo(loopDevice, &sb, &nr_sec)) {
-        return -1;
-    }
-
-    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::ASECDIR, id);
-    if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
-        SLOGE("Unable remount to fix permissions for %s: couldn't construct mountpoint", id);
-        return -1;
-    }
-
-    int result = 0;
-    if ((sb.c_opts & ASEC_SB_C_OPTS_EXT4) == 0) {
-        return 0;
-    }
-
-    int ret = android::vold::ext4::Mount(loopDevice, mountPoint,
-            false /* read-only */,
-            true  /* remount */,
-            false /* executable */);
-    if (ret) {
-        SLOGE("Unable remount to fix permissions for %s (%s)", id, strerror(errno));
-        return -1;
-    }
-
-    char *paths[] = { mountPoint, NULL };
-
-    FTS *fts = fts_open(paths, FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV, NULL);
-    if (fts) {
-        // Traverse the entire hierarchy and chown to system UID.
-        for (FTSENT *ftsent = fts_read(fts); ftsent != NULL; ftsent = fts_read(fts)) {
-            // We don't care about the lost+found directory.
-            if (!strcmp(ftsent->fts_name, "lost+found")) {
-                continue;
-            }
-
-            /*
-             * There can only be one file marked as private right now.
-             * This should be more robust, but it satisfies the requirements
-             * we have for right now.
-             */
-            const bool privateFile = !strcmp(ftsent->fts_name, filename);
-
-            int fd = open(ftsent->fts_accpath, O_NOFOLLOW | O_CLOEXEC);
-            if (fd < 0) {
-                SLOGE("Couldn't open file %s: %s", ftsent->fts_accpath, strerror(errno));
-                result = -1;
-                continue;
-            }
-
-            result |= fchown(fd, AID_SYSTEM, privateFile? gid : AID_SYSTEM);
-
-            if (ftsent->fts_info & FTS_D) {
-                result |= fchmod(fd, 0755);
-            } else if (ftsent->fts_info & FTS_F) {
-                result |= fchmod(fd, privateFile ? 0640 : 0644);
-            }
-
-            if (selinux_android_restorecon(ftsent->fts_path, 0) < 0) {
-                SLOGE("restorecon failed for %s: %s\n", ftsent->fts_path, strerror(errno));
-                result |= -1;
-            }
-
-            close(fd);
-        }
-        fts_close(fts);
-
-        // Finally make the directory readable by everyone.
-        int dirfd = open(mountPoint, O_DIRECTORY | O_CLOEXEC);
-        if (dirfd < 0 || fchmod(dirfd, 0755)) {
-            SLOGE("Couldn't change owner of existing directory %s: %s", mountPoint, strerror(errno));
-            result |= -1;
-        }
-        close(dirfd);
-    } else {
-        result |= -1;
-    }
-
-    result |= android::vold::ext4::Mount(loopDevice, mountPoint,
-            true /* read-only */,
-            true /* remount */,
-            true /* execute */);
-
-    if (result) {
-        SLOGE("ASEC fix permissions failed (%s)", strerror(errno));
-        return -1;
-    }
-
-    if (mDebug) {
-        SLOGD("ASEC %s permissions fixed", id);
-    }
-    return 0;
-}
-
-int VolumeManager::renameAsec(const char *id1, const char *id2) {
-    char asecFilename1[255];
-    char *asecFilename2;
-    char mountPoint[255];
-
-    const char *dir;
-
-    if (!isLegalAsecId(id1)) {
-        SLOGE("renameAsec: Invalid asec id1 \"%s\"", id1);
-        errno = EINVAL;
-        return -1;
-    }
-
-    if (!isLegalAsecId(id2)) {
-        SLOGE("renameAsec: Invalid asec id2 \"%s\"", id2);
-        errno = EINVAL;
-        return -1;
-    }
-
-    if (findAsec(id1, asecFilename1, sizeof(asecFilename1), &dir)) {
-        SLOGE("Couldn't find ASEC %s", id1);
-        return -1;
-    }
-
-    asprintf(&asecFilename2, "%s/%s.asec", dir, id2);
-
-    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::ASECDIR, id1);
-    if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
-        SLOGE("Rename failed: couldn't construct mountpoint");
-        goto out_err;
-    }
-
-    if (isMountpointMounted(mountPoint)) {
-        SLOGW("Rename attempt when src mounted");
-        errno = EBUSY;
-        goto out_err;
-    }
-
-    written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::ASECDIR, id2);
-    if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
-        SLOGE("Rename failed: couldn't construct mountpoint2");
-        goto out_err;
-    }
-
-    if (isMountpointMounted(mountPoint)) {
-        SLOGW("Rename attempt when dst mounted");
-        errno = EBUSY;
-        goto out_err;
-    }
-
-    if (!access(asecFilename2, F_OK)) {
-        SLOGE("Rename attempt when dst exists");
-        errno = EADDRINUSE;
-        goto out_err;
-    }
-
-    if (rename(asecFilename1, asecFilename2)) {
-        SLOGE("Rename of '%s' to '%s' failed (%s)", asecFilename1, asecFilename2, strerror(errno));
-        goto out_err;
-    }
-
-    free(asecFilename2);
-    return 0;
-
-out_err:
-    free(asecFilename2);
-    return -1;
-}
-
-#define UNMOUNT_RETRIES 5
-#define UNMOUNT_SLEEP_BETWEEN_RETRY_MS (1000 * 1000)
-int VolumeManager::unmountAsec(const char *id, bool force) {
-    char asecFileName[255];
-    char mountPoint[255];
-
-    if (!isLegalAsecId(id)) {
-        SLOGE("unmountAsec: Invalid asec id \"%s\"", id);
-        errno = EINVAL;
-        return -1;
-    }
-
-    if (findAsec(id, asecFileName, sizeof(asecFileName))) {
-        SLOGE("Couldn't find ASEC %s", id);
-        return -1;
-    }
-
-    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::ASECDIR, id);
-    if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
-        SLOGE("ASEC unmount failed for %s: couldn't construct mountpoint", id);
-        return -1;
-    }
-
-    char idHash[33];
-    if (!asecHash(id, idHash, sizeof(idHash))) {
-        SLOGE("Hash of '%s' failed (%s)", id, strerror(errno));
-        return -1;
-    }
-
-    return unmountLoopImage(id, idHash, asecFileName, mountPoint, force);
-}
-
-int VolumeManager::unmountObb(const char *fileName, bool force) {
-    char mountPoint[255];
-
-    char idHash[33];
-    if (!asecHash(fileName, idHash, sizeof(idHash))) {
-        SLOGE("Hash of '%s' failed (%s)", fileName, strerror(errno));
-        return -1;
-    }
-
-    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::LOOPDIR, idHash);
-    if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
-        SLOGE("OBB unmount failed for %s: couldn't construct mountpoint", fileName);
-        return -1;
-    }
-
-    return unmountLoopImage(fileName, idHash, fileName, mountPoint, force);
-}
-
-int VolumeManager::unmountLoopImage(const char *id, const char *idHash,
-        const char *fileName, const char *mountPoint, bool force) {
-    if (!isMountpointMounted(mountPoint)) {
-        SLOGE("Unmount request for %s when not mounted", id);
-        errno = ENOENT;
-        return -1;
-    }
-
-    int i, rc;
-    for (i = 1; i <= UNMOUNT_RETRIES; i++) {
-        rc = umount(mountPoint);
-        if (!rc) {
-            break;
-        }
-        if (rc && (errno == EINVAL || errno == ENOENT)) {
-            SLOGI("Container %s unmounted OK", id);
-            rc = 0;
-            break;
-        }
-        SLOGW("%s unmount attempt %d failed (%s)",
-              id, i, strerror(errno));
-
-        int signal = 0; // default is to just complain
-
-        if (force) {
-            if (i > (UNMOUNT_RETRIES - 2))
-                signal = SIGKILL;
-            else if (i > (UNMOUNT_RETRIES - 3))
-                signal = SIGTERM;
-        }
-
-        Process::killProcessesWithOpenFiles(mountPoint, signal);
-        usleep(UNMOUNT_SLEEP_BETWEEN_RETRY_MS);
-    }
-
-    if (rc) {
-        errno = EBUSY;
-        SLOGE("Failed to unmount container %s (%s)", id, strerror(errno));
-        return -1;
-    }
-
-    int retries = 10;
-
-    while(retries--) {
-        if (!rmdir(mountPoint)) {
-            break;
-        }
-
-        SLOGW("Failed to rmdir %s (%s)", mountPoint, strerror(errno));
-        usleep(UNMOUNT_SLEEP_BETWEEN_RETRY_MS);
-    }
-
-    if (!retries) {
-        SLOGE("Timed out trying to rmdir %s (%s)", mountPoint, strerror(errno));
-    }
-
-    for (i=1; i <= UNMOUNT_RETRIES; i++) {
-        if (Devmapper::destroy(idHash) && errno != ENXIO) {
-            SLOGE("Failed to destroy devmapper instance (%s)", strerror(errno));
-            usleep(UNMOUNT_SLEEP_BETWEEN_RETRY_MS);
-            continue;
-        } else {
-          break;
-        }
-    }
-
-    char loopDevice[255];
-    if (!Loop::lookupActive(idHash, loopDevice, sizeof(loopDevice))) {
-        Loop::destroyByDevice(loopDevice);
-    } else {
-        SLOGW("Failed to find loop device for {%s} (%s)", fileName, strerror(errno));
-    }
-
-    AsecIdCollection::iterator it;
-    for (it = mActiveContainers->begin(); it != mActiveContainers->end(); ++it) {
-        ContainerData* cd = *it;
-        if (!strcmp(cd->id, id)) {
-            free(*it);
-            mActiveContainers->erase(it);
-            break;
-        }
-    }
-    if (it == mActiveContainers->end()) {
-        SLOGW("mActiveContainers is inconsistent!");
-    }
-    return 0;
-}
-
-int VolumeManager::destroyAsec(const char *id, bool force) {
-    char asecFileName[255];
-    char mountPoint[255];
-
-    if (!isLegalAsecId(id)) {
-        SLOGE("destroyAsec: Invalid asec id \"%s\"", id);
-        errno = EINVAL;
-        return -1;
-    }
-
-    if (findAsec(id, asecFileName, sizeof(asecFileName))) {
-        SLOGE("Couldn't find ASEC %s", id);
-        return -1;
-    }
-
-    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::ASECDIR, id);
-    if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
-        SLOGE("ASEC destroy failed for %s: couldn't construct mountpoint", id);
-        return -1;
-    }
-
-    if (isMountpointMounted(mountPoint)) {
-        if (mDebug) {
-            SLOGD("Unmounting container before destroy");
-        }
-        if (unmountAsec(id, force)) {
-            SLOGE("Failed to unmount asec %s for destroy (%s)", id, strerror(errno));
-            return -1;
-        }
-    }
-
-    if (unlink(asecFileName)) {
-        SLOGE("Failed to unlink asec '%s' (%s)", asecFileName, strerror(errno));
-        return -1;
-    }
-
-    if (mDebug) {
-        SLOGD("ASEC %s destroyed", id);
-    }
-    return 0;
-}
-
-/*
- * Legal ASEC ids consist of alphanumeric characters, '-',
- * '_', or '.'. ".." is not allowed. The first or last character
- * of the ASEC id cannot be '.' (dot).
- */
-bool VolumeManager::isLegalAsecId(const char *id) const {
-    size_t i;
-    size_t len = strlen(id);
-
-    if (len == 0) {
-        return false;
-    }
-    if ((id[0] == '.') || (id[len - 1] == '.')) {
-        return false;
-    }
-
-    for (i = 0; i < len; i++) {
-        if (id[i] == '.') {
-            // i=0 is guaranteed never to have a dot. See above.
-            if (id[i-1] == '.') return false;
-            continue;
-        }
-        if (id[i] == '_' || id[i] == '-') continue;
-        if (id[i] >= 'a' && id[i] <= 'z') continue;
-        if (id[i] >= 'A' && id[i] <= 'Z') continue;
-        if (id[i] >= '0' && id[i] <= '9') continue;
-        return false;
-    }
-
-    return true;
-}
-
-bool VolumeManager::isAsecInDirectory(const char *dir, const char *asecName) const {
-    int dirfd = open(dir, O_DIRECTORY | O_CLOEXEC);
-    if (dirfd < 0) {
-        SLOGE("Couldn't open internal ASEC dir (%s)", strerror(errno));
-        return false;
-    }
-
-    struct stat sb;
-    bool ret = (fstatat(dirfd, asecName, &sb, AT_SYMLINK_NOFOLLOW) == 0)
-        && S_ISREG(sb.st_mode);
-
-    close(dirfd);
-
-    return ret;
-}
-
-int VolumeManager::findAsec(const char *id, char *asecPath, size_t asecPathLen,
-        const char **directory) const {
-    char *asecName;
-
-    if (!isLegalAsecId(id)) {
-        SLOGE("findAsec: Invalid asec id \"%s\"", id);
-        errno = EINVAL;
-        return -1;
-    }
-
-    if (asprintf(&asecName, "%s.asec", id) < 0) {
-        SLOGE("Couldn't allocate string to write ASEC name");
-        return -1;
-    }
-
-    const char *dir;
-    if (isAsecInDirectory(VolumeManager::SEC_ASECDIR_INT, asecName)) {
-        dir = VolumeManager::SEC_ASECDIR_INT;
-    } else if (isAsecInDirectory(VolumeManager::SEC_ASECDIR_EXT, asecName)) {
-        dir = VolumeManager::SEC_ASECDIR_EXT;
-    } else {
-        free(asecName);
-        return -1;
-    }
-
-    if (directory != NULL) {
-        *directory = dir;
-    }
-
-    if (asecPath != NULL) {
-        int written = snprintf(asecPath, asecPathLen, "%s/%s", dir, asecName);
-        if ((written < 0) || (size_t(written) >= asecPathLen)) {
-            SLOGE("findAsec failed for %s: couldn't construct ASEC path", id);
-            free(asecName);
-            return -1;
-        }
-    }
-
-    free(asecName);
-    return 0;
-}
-
-int VolumeManager::mountAsec(const char *id, const char *key, int ownerUid, bool readOnly) {
-    char asecFileName[255];
-    char mountPoint[255];
-
-    if (!isLegalAsecId(id)) {
-        SLOGE("mountAsec: Invalid asec id \"%s\"", id);
-        errno = EINVAL;
-        return -1;
-    }
-
-    if (findAsec(id, asecFileName, sizeof(asecFileName))) {
-        SLOGE("Couldn't find ASEC %s", id);
-        return -1;
-    }
-
-    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::ASECDIR, id);
-    if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
-        SLOGE("ASEC mount failed for %s: couldn't construct mountpoint", id);
-        return -1;
-    }
-
-    if (isMountpointMounted(mountPoint)) {
-        SLOGE("ASEC %s already mounted", id);
-        errno = EBUSY;
-        return -1;
-    }
-
-    char idHash[33];
-    if (!asecHash(id, idHash, sizeof(idHash))) {
-        SLOGE("Hash of '%s' failed (%s)", id, strerror(errno));
-        return -1;
-    }
-
-    char loopDevice[255];
-    if (setupLoopDevice(loopDevice, sizeof(loopDevice), asecFileName, idHash, mDebug))
-        return -1;
-
-    char dmDevice[255];
-    bool cleanupDm = false;
-
-    unsigned long nr_sec = 0;
-    struct asec_superblock sb;
-
-    if (Loop::lookupInfo(loopDevice, &sb, &nr_sec)) {
-        return -1;
-    }
-
-    if (mDebug) {
-        SLOGD("Container sb magic/ver (%.8x/%.2x)", sb.magic, sb.ver);
-    }
-    if (sb.magic != ASEC_SB_MAGIC || sb.ver != ASEC_SB_VER) {
-        SLOGE("Bad container magic/version (%.8x/%.2x)", sb.magic, sb.ver);
-        Loop::destroyByDevice(loopDevice);
-        errno = EMEDIUMTYPE;
-        return -1;
-    }
-    nr_sec--; // We don't want the devmapping to extend onto our superblock
-
-    if (setupDevMapperDevice(dmDevice, sizeof(dmDevice), loopDevice, asecFileName, key, idHash , nr_sec, &cleanupDm, mDebug)) {
-        Loop::destroyByDevice(loopDevice);
-        return -1;
-    }
-
-    if (mkdir(mountPoint, 0000)) {
-        if (errno != EEXIST) {
-            SLOGE("Mountpoint creation failed (%s)", strerror(errno));
-            if (cleanupDm) {
-                Devmapper::destroy(idHash);
-            }
-            Loop::destroyByDevice(loopDevice);
-            return -1;
-        }
-    }
-
-    /*
-     * Wait for the device mapper node to be created.
-     */
-    waitForDevMapper(dmDevice);
-
-    int result;
-    if (sb.c_opts & ASEC_SB_C_OPTS_EXT4) {
-        result = android::vold::ext4::Mount(dmDevice, mountPoint,
-                readOnly, false, readOnly);
-    } else {
-        result = android::vold::vfat::Mount(dmDevice, mountPoint,
-                readOnly, false, readOnly, ownerUid, 0, 0222, false);
-    }
-
-    if (result) {
-        SLOGE("ASEC mount failed (%s)", strerror(errno));
-        if (cleanupDm) {
-            Devmapper::destroy(idHash);
-        }
-        Loop::destroyByDevice(loopDevice);
-        return -1;
-    }
-
-    mActiveContainers->push_back(new ContainerData(strdup(id), ASEC));
-    if (mDebug) {
-        SLOGD("ASEC %s mounted", id);
-    }
-    return 0;
-}
-
-/**
- * Mounts an image file <code>img</code>.
- */
-int VolumeManager::mountObb(const char *img, const char *key, int ownerGid) {
-    char mountPoint[255];
-
-    char idHash[33];
-    if (!asecHash(img, idHash, sizeof(idHash))) {
-        SLOGE("Hash of '%s' failed (%s)", img, strerror(errno));
-        return -1;
-    }
-
-    int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", VolumeManager::LOOPDIR, idHash);
-    if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) {
-        SLOGE("OBB mount failed for %s: couldn't construct mountpoint", img);
-        return -1;
-    }
-
-    if (isMountpointMounted(mountPoint)) {
-        SLOGE("Image %s already mounted", img);
-        errno = EBUSY;
-        return -1;
-    }
-
-    char loopDevice[255];
-    if (setupLoopDevice(loopDevice, sizeof(loopDevice), img, idHash, mDebug))
-        return -1;
-
-    char dmDevice[255];
-    bool cleanupDm = false;
-    int fd;
-    unsigned long nr_sec = 0;
-
-    if ((fd = open(loopDevice, O_RDWR | O_CLOEXEC)) < 0) {
-        SLOGE("Failed to open loopdevice (%s)", strerror(errno));
-        Loop::destroyByDevice(loopDevice);
-        return -1;
-    }
-
-    get_blkdev_size(fd, &nr_sec);
-    if (nr_sec == 0) {
-        SLOGE("Failed to get loop size (%s)", strerror(errno));
-        Loop::destroyByDevice(loopDevice);
-        close(fd);
-        return -1;
-    }
-
-    close(fd);
-
-    if (setupDevMapperDevice(dmDevice, sizeof(loopDevice), loopDevice, img,key, idHash, nr_sec, &cleanupDm, mDebug)) {
-        Loop::destroyByDevice(loopDevice);
-        return -1;
-    }
-
-    if (mkdir(mountPoint, 0755)) {
-        if (errno != EEXIST) {
-            SLOGE("Mountpoint creation failed (%s)", strerror(errno));
-            if (cleanupDm) {
-                Devmapper::destroy(idHash);
-            }
-            Loop::destroyByDevice(loopDevice);
-            return -1;
-        }
-    }
-
-    /*
-     * Wait for the device mapper node to be created.
-     */
-    waitForDevMapper(dmDevice);
-
-    if (android::vold::vfat::Mount(dmDevice, mountPoint,
-            true, false, true, 0, ownerGid, 0227, false)) {
-        SLOGE("Image mount failed (%s)", strerror(errno));
-        if (cleanupDm) {
-            Devmapper::destroy(idHash);
-        }
-        Loop::destroyByDevice(loopDevice);
-        return -1;
-    }
-
-    mActiveContainers->push_back(new ContainerData(strdup(img), OBB));
-    if (mDebug) {
-        SLOGD("Image %s mounted", img);
-    }
-    return 0;
-}
-
-int VolumeManager::listMountedObbs(SocketClient* cli) {
-    FILE *fp = setmntent("/proc/mounts", "r");
-    if (fp == NULL) {
-        SLOGE("Error opening /proc/mounts (%s)", strerror(errno));
-        return -1;
-    }
-
-    // Create a string to compare against that has a trailing slash
-    int loopDirLen = strlen(VolumeManager::LOOPDIR);
-    char loopDir[loopDirLen + 2];
-    strlcpy(loopDir, VolumeManager::LOOPDIR, sizeof(loopDir));
-    loopDir[loopDirLen++] = '/';
-    loopDir[loopDirLen] = '\0';
-
-    mntent* mentry;
-    while ((mentry = getmntent(fp)) != NULL) {
-        if (!strncmp(mentry->mnt_dir, loopDir, loopDirLen)) {
-            int fd = open(mentry->mnt_fsname, O_RDONLY | O_CLOEXEC);
-            if (fd >= 0) {
-                struct loop_info64 li;
-                if (ioctl(fd, LOOP_GET_STATUS64, &li) >= 0) {
-                    cli->sendMsg(ResponseCode::AsecListResult,
-                            (const char*) li.lo_file_name, false);
-                }
-                close(fd);
-            }
-        }
-    }
-    endmntent(fp);
-    return 0;
-}
-
 extern "C" int vold_unmountAll(void) {
     VolumeManager *vm = VolumeManager::Instance();
     return vm->unmountAll();
 }
 
-bool VolumeManager::isMountpointMounted(const char *mp)
-{
-    FILE *fp = setmntent("/proc/mounts", "r");
-    if (fp == NULL) {
-        SLOGE("Error opening /proc/mounts (%s)", strerror(errno));
-        return false;
-    }
-
-    bool found_mp = false;
-    mntent* mentry;
-    while ((mentry = getmntent(fp)) != NULL) {
-        if (strcmp(mentry->mnt_dir, mp) == 0) {
-            found_mp = true;
-            break;
-        }
-    }
-    endmntent(fp);
-    return found_mp;
-}
-
 int VolumeManager::mkdirs(const char* path) {
     // Only offer to create directories for paths managed by vold
     if (strncmp(path, "/storage/", 9) == 0) {
diff --git a/VolumeManager.h b/VolumeManager.h
index a00520e..dcfbdad 100644
--- a/VolumeManager.h
+++ b/VolumeManager.h
@@ -33,7 +33,6 @@
 #include <cutils/multiuser.h>
 #include <utils/List.h>
 #include <utils/Timers.h>
-#include <sysutils/SocketListener.h>
 #include <sysutils/NetlinkEvent.h>
 
 #include "android/os/IVoldListener.h"
@@ -41,56 +40,18 @@
 #include "model/Disk.h"
 #include "model/VolumeBase.h"
 
-/* The length of an MD5 hash when encoded into ASCII hex characters */
-#define MD5_ASCII_LENGTH_PLUS_NULL ((MD5_DIGEST_LENGTH*2)+1)
-
 #define DEBUG_APPFUSE 0
 
-typedef enum { ASEC, OBB } container_type_t;
-
-class ContainerData {
-public:
-    ContainerData(char* _id, container_type_t _type)
-            : id(_id)
-            , type(_type)
-    {}
-
-    ~ContainerData() {
-        if (id != NULL) {
-            free(id);
-            id = NULL;
-        }
-    }
-
-    char *id;
-    container_type_t type;
-};
-
-typedef android::List<ContainerData*> AsecIdCollection;
-
 class VolumeManager {
 public:
-    static const char *SEC_ASECDIR_EXT;
-    static const char *SEC_ASECDIR_INT;
-    static const char *ASECDIR;
-    static const char *LOOPDIR;
-
     //TODO remove this with better solution, b/64143519
     static bool shutting_down;
 
 private:
     static VolumeManager *sInstance;
 
-    SocketListener        *mBroadcaster;
-
-    AsecIdCollection      *mActiveContainers;
     bool                   mDebug;
 
-    // for adjusting /proc/sys/vm/dirty_ratio when UMS is active
-    int                    mUmsSharingCount;
-    int                    mSavedDirtyRatio;
-    int                    mUmsDirtyRatio;
-
 public:
     virtual ~VolumeManager();
 
@@ -150,52 +111,11 @@
     /* Unmount all volumes, usually for encryption */
     int unmountAll();
 
-    /* ASEC */
-    int findAsec(const char *id, char *asecPath = NULL, size_t asecPathLen = 0,
-            const char **directory = NULL) const;
-    int createAsec(const char *id, unsigned long numSectors, const char *fstype,
-                   const char *key, const int ownerUid, bool isExternal);
-    int resizeAsec(const char *id, unsigned long numSectors, const char *key);
-    int finalizeAsec(const char *id);
-
-    /**
-     * Fixes ASEC permissions on a filesystem that has owners and permissions.
-     * This currently means EXT4-based ASEC containers.
-     *
-     * There is a single file that can be marked as "private" and will not have
-     * world-readable permission. The group for that file will be set to the gid
-     * supplied.
-     *
-     * Returns 0 on success.
-     */
-    int fixupAsecPermissions(const char *id, gid_t gid, const char* privateFilename);
-    int destroyAsec(const char *id, bool force);
-    int mountAsec(const char *id, const char *key, int ownerUid, bool readOnly);
-    int unmountAsec(const char *id, bool force);
-    int renameAsec(const char *id1, const char *id2);
-    int getAsecMountPath(const char *id, char *buffer, int maxlen);
-    int getAsecFilesystemPath(const char *id, char *buffer, int maxlen);
-
-    /* Loopback images */
-    int listMountedObbs(SocketClient* cli);
-    int mountObb(const char *fileName, const char *key, int ownerUid);
-    int unmountObb(const char *fileName, bool force);
-    int getObbMountPath(const char *id, char *buffer, int maxlen);
-
-    /* Shared between ASEC and Loopback images */
-    int unmountLoopImage(const char *containerId, const char *loopId,
-            const char *fileName, const char *mountPoint, bool force);
-
     int updateVirtualDisk();
     int setDebug(bool enable);
 
-    void setBroadcaster(SocketListener *sl) { mBroadcaster = sl; }
-    SocketListener *getBroadcaster() { return mBroadcaster; }
-
     static VolumeManager *Instance();
 
-    static char *asecHash(const char *id, char *buffer, size_t len);
-
     /*
      * Ensure that all directories along given path exist, creating parent
      * directories as needed.  Validates that given path is absolute and that
@@ -215,9 +135,6 @@
 private:
     VolumeManager();
     void readInitialState();
-    bool isMountpointMounted(const char *mp);
-    bool isAsecInDirectory(const char *dir, const char *asec) const;
-    bool isLegalAsecId(const char *id) const;
 
     int linkPrimary(userid_t userId);
 
diff --git a/binder/android/os/IVold.aidl b/binder/android/os/IVold.aidl
index 1736829..d47f113 100644
--- a/binder/android/os/IVold.aidl
+++ b/binder/android/os/IVold.aidl
@@ -23,6 +23,7 @@
 interface IVold {
     void setListener(IVoldListener listener);
 
+    void monitor();
     void reset();
     void shutdown();
     void mountAll();
diff --git a/main.cpp b/main.cpp
index 8175dc5..37d02e7 100644
--- a/main.cpp
+++ b/main.cpp
@@ -16,8 +16,6 @@
 
 #include "model/Disk.h"
 #include "VolumeManager.h"
-#include "CommandListener.h"
-#include "CryptCommandListener.h"
 #include "NetlinkManager.h"
 #include "VoldNativeService.h"
 #include "cryptfs.h"
@@ -27,7 +25,6 @@
 #include <android-base/stringprintf.h>
 #include <cutils/klog.h>
 #include <cutils/properties.h>
-#include <cutils/sockets.h>
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -62,8 +59,6 @@
             << (android::vold::IsFilesystemSupported("vfat") ? " vfat" : "");
 
     VolumeManager *vm;
-    CommandListener *cl;
-    CryptCommandListener *ccl;
     NetlinkManager *nm;
 
     parse_args(argc, argv);
@@ -73,10 +68,6 @@
         selinux_android_set_sehandle(sehandle);
     }
 
-    // Quickly throw a CLOEXEC on the socket we just inherited from init
-    fcntl(android_get_control_socket("vold"), F_SETFD, FD_CLOEXEC);
-    fcntl(android_get_control_socket("cryptd"), F_SETFD, FD_CLOEXEC);
-
     mkdir("/dev/block/vold", 0755);
 
     /* For when cryptfs checks and mounts an encrypted filesystem */
@@ -97,11 +88,6 @@
         vm->setDebug(true);
     }
 
-    cl = new CommandListener();
-    ccl = new CryptCommandListener();
-    vm->setBroadcaster((SocketListener *) cl);
-    nm->setBroadcaster((SocketListener *) cl);
-
     if (vm->start()) {
         PLOG(ERROR) << "Unable to start VolumeManager";
         exit(1);
@@ -124,19 +110,6 @@
         exit(1);
     }
 
-    /*
-     * Now that we're up, we can respond to commands
-     */
-    if (cl->startListener()) {
-        PLOG(ERROR) << "Unable to start CommandListener";
-        exit(1);
-    }
-
-    if (ccl->startListener()) {
-        PLOG(ERROR) << "Unable to start CryptCommandListener";
-        exit(1);
-    }
-
     // This call should go after listeners are started to avoid
     // a deadlock between vold and init (see b/34278978 for details)
     property_set("vold.has_adoptable", has_adoptable ? "1" : "0");
diff --git a/model/Disk.cpp b/model/Disk.cpp
index 151937f..f9799ad 100644
--- a/model/Disk.cpp
+++ b/model/Disk.cpp
@@ -20,7 +20,6 @@
 #include "Utils.h"
 #include "VolumeBase.h"
 #include "VolumeManager.h"
-#include "ResponseCode.h"
 #include "Ext4Crypt.h"
 
 #include <android-base/file.h>
@@ -151,12 +150,10 @@
 status_t Disk::create() {
     CHECK(!mCreated);
     mCreated = true;
-#if ENABLE_BINDER
+
     auto listener = VolumeManager::Instance()->getListener();
     if (listener) listener->onDiskCreated(getId(), mFlags);
-#else
-    notifyEvent(ResponseCode::DiskCreated, StringPrintf("%d", mFlags));
-#endif
+
     readMetadata();
     readPartitions();
     return OK;
@@ -166,12 +163,10 @@
     CHECK(mCreated);
     destroyAllVolumes();
     mCreated = false;
-#if ENABLE_BINDER
+
     auto listener = VolumeManager::Instance()->getListener();
     if (listener) listener->onDiskDestroyed(getId());
-#else
-    notifyEvent(ResponseCode::DiskDestroyed);
-#endif
+
     return OK;
 }
 
@@ -291,15 +286,10 @@
     }
     }
 
-#if ENABLE_BINDER
     auto listener = VolumeManager::Instance()->getListener();
     if (listener) listener->onDiskMetadataChanged(getId(),
             mSize, mLabel, mSysPath);
-#else
-    notifyEvent(ResponseCode::DiskSizeChanged, StringPrintf("%" PRIu64, mSize));
-    notifyEvent(ResponseCode::DiskLabelChanged, mLabel);
-    notifyEvent(ResponseCode::DiskSysPathChanged, mSysPath);
-#endif
+
     return OK;
 }
 
@@ -322,12 +312,10 @@
     status_t res = ForkExecvp(cmd, output);
     if (res != OK) {
         LOG(WARNING) << "sgdisk failed to scan " << mDevPath;
-#if ENABLE_BINDER
+
         auto listener = VolumeManager::Instance()->getListener();
         if (listener) listener->onDiskScanned(getId());
-#else
-        notifyEvent(ResponseCode::DiskScanned);
-#endif
+
         mJustPartitioned = false;
         return res;
     }
@@ -393,12 +381,9 @@
         }
     }
 
-#if ENABLE_BINDER
     auto listener = VolumeManager::Instance()->getListener();
     if (listener) listener->onDiskScanned(getId());
-#else
-    notifyEvent(ResponseCode::DiskScanned);
-#endif
+
     mJustPartitioned = false;
     return OK;
 }
@@ -560,16 +545,6 @@
     return OK;
 }
 
-void Disk::notifyEvent(int event) {
-    VolumeManager::Instance()->getBroadcaster()->sendBroadcast(event,
-            getId().c_str(), false);
-}
-
-void Disk::notifyEvent(int event, const std::string& value) {
-    VolumeManager::Instance()->getBroadcaster()->sendBroadcast(event,
-            StringPrintf("%s %s", getId().c_str(), value.c_str()).c_str(), false);
-}
-
 int Disk::getMaxMinors() {
     // Figure out maximum partition devices supported
     unsigned int majorId = major(mDevice);
diff --git a/model/Disk.h b/model/Disk.h
index 77ec7df..63acf6a 100644
--- a/model/Disk.h
+++ b/model/Disk.h
@@ -79,9 +79,6 @@
     status_t partitionPrivate();
     status_t partitionMixed(int8_t ratio);
 
-    void notifyEvent(int msg);
-    void notifyEvent(int msg, const std::string& value);
-
 private:
     /* ID that uniquely references this disk */
     std::string mId;
diff --git a/model/PrivateVolume.cpp b/model/PrivateVolume.cpp
index 9a96082..3152313 100644
--- a/model/PrivateVolume.cpp
+++ b/model/PrivateVolume.cpp
@@ -20,7 +20,6 @@
 #include "EmulatedVolume.h"
 #include "Utils.h"
 #include "VolumeManager.h"
-#include "ResponseCode.h"
 #include "cryptfs.h"
 
 #include <android-base/stringprintf.h>
@@ -55,14 +54,10 @@
 
 status_t PrivateVolume::readMetadata() {
     status_t res = ReadMetadata(mDmDevPath, mFsType, mFsUuid, mFsLabel);
-#if ENABLE_BINDER
+
     auto listener = getListener();
     if (listener) listener->onVolumeMetadataChanged(getId(), mFsType, mFsUuid, mFsLabel);
-#else
-    notifyEvent(ResponseCode::VolumeFsTypeChanged, mFsType);
-    notifyEvent(ResponseCode::VolumeFsUuidChanged, mFsUuid);
-    notifyEvent(ResponseCode::VolumeFsLabelChanged, mFsLabel);
-#endif
+
     return res;
 }
 
diff --git a/model/PublicVolume.cpp b/model/PublicVolume.cpp
index 04bafed..569203c 100644
--- a/model/PublicVolume.cpp
+++ b/model/PublicVolume.cpp
@@ -18,7 +18,6 @@
 #include "PublicVolume.h"
 #include "Utils.h"
 #include "VolumeManager.h"
-#include "ResponseCode.h"
 
 #include <android-base/stringprintf.h>
 #include <android-base/logging.h>
@@ -53,14 +52,10 @@
 
 status_t PublicVolume::readMetadata() {
     status_t res = ReadMetadataUntrusted(mDevPath, mFsType, mFsUuid, mFsLabel);
-#if ENABLE_BINDER
+
     auto listener = getListener();
     if (listener) listener->onVolumeMetadataChanged(getId(), mFsType, mFsUuid, mFsLabel);
-#else
-    notifyEvent(ResponseCode::VolumeFsTypeChanged, mFsType);
-    notifyEvent(ResponseCode::VolumeFsUuidChanged, mFsUuid);
-    notifyEvent(ResponseCode::VolumeFsLabelChanged, mFsLabel);
-#endif
+
     return res;
 }
 
diff --git a/model/VolumeBase.cpp b/model/VolumeBase.cpp
index b2eff3b..429f134 100644
--- a/model/VolumeBase.cpp
+++ b/model/VolumeBase.cpp
@@ -17,7 +17,6 @@
 #include "Utils.h"
 #include "VolumeBase.h"
 #include "VolumeManager.h"
-#include "ResponseCode.h"
 
 #include <android-base/stringprintf.h>
 #include <android-base/logging.h>
@@ -44,12 +43,9 @@
 
 void VolumeBase::setState(State state) {
     mState = state;
-#if ENABLE_BINDER
+
     auto listener = getListener();
     if (listener) listener->onVolumeStateChanged(getId(), static_cast<int32_t>(mState));
-#else
-    notifyEvent(ResponseCode::VolumeStateChanged, StringPrintf("%d", mState));
-#endif
 }
 
 status_t VolumeBase::setDiskId(const std::string& diskId) {
@@ -119,12 +115,10 @@
     }
 
     mPath = path;
-#if ENABLE_BINDER
+
     auto listener = getListener();
     if (listener) listener->onVolumePathChanged(getId(), mPath);
-#else
-    notifyEvent(ResponseCode::VolumePathChanged, mPath);
-#endif
+
     return OK;
 }
 
@@ -135,27 +129,13 @@
     }
 
     mInternalPath = internalPath;
-#if ENABLE_BINDER
+
     auto listener = getListener();
     if (listener) listener->onVolumeInternalPathChanged(getId(), mInternalPath);
-#else
-    notifyEvent(ResponseCode::VolumeInternalPathChanged, mInternalPath);
-#endif
+
     return OK;
 }
 
-void VolumeBase::notifyEvent(int event) {
-    if (mSilent) return;
-    VolumeManager::Instance()->getBroadcaster()->sendBroadcast(event,
-            getId().c_str(), false);
-}
-
-void VolumeBase::notifyEvent(int event, const std::string& value) {
-    if (mSilent) return;
-    VolumeManager::Instance()->getBroadcaster()->sendBroadcast(event,
-            StringPrintf("%s %s", getId().c_str(), value.c_str()).c_str(), false);
-}
-
 android::sp<android::os::IVoldListener> VolumeBase::getListener() {
     if (mSilent) {
         return nullptr;
@@ -186,14 +166,11 @@
 
     mCreated = true;
     status_t res = doCreate();
-#if ENABLE_BINDER
+
     auto listener = getListener();
     if (listener) listener->onVolumeCreated(getId(),
             static_cast<int32_t>(mType), mDiskId, mPartGuid);
-#else
-    notifyEvent(ResponseCode::VolumeCreated,
-            StringPrintf("%d \"%s\" \"%s\"", mType, mDiskId.c_str(), mPartGuid.c_str()));
-#endif
+
     setState(State::kUnmounted);
     return res;
 }
@@ -212,12 +189,10 @@
         setState(State::kRemoved);
     }
 
-#if ENABLE_BINDER
+
     auto listener = getListener();
     if (listener) listener->onVolumeDestroyed(getId());
-#else
-    notifyEvent(ResponseCode::VolumeDestroyed);
-#endif
+
     status_t res = doDestroy();
     mCreated = false;
     return res;
diff --git a/model/VolumeBase.h b/model/VolumeBase.h
index ac111c2..4aa8b02 100644
--- a/model/VolumeBase.h
+++ b/model/VolumeBase.h
@@ -115,9 +115,6 @@
     status_t setPath(const std::string& path);
     status_t setInternalPath(const std::string& internalPath);
 
-    void notifyEvent(int msg);
-    void notifyEvent(int msg, const std::string& value);
-
     android::sp<android::os::IVoldListener> getListener();
 
 private:
diff --git a/tests/VolumeManager_test.cpp b/tests/VolumeManager_test.cpp
index c0c1fa5..f661d49 100644
--- a/tests/VolumeManager_test.cpp
+++ b/tests/VolumeManager_test.cpp
@@ -34,31 +34,4 @@
     }
 };
 
-TEST_F(VolumeManagerTest, AsecHashTests) {
-    char buffer[MD5_ASCII_LENGTH_PLUS_NULL];
-    char* dst = reinterpret_cast<char*>(&buffer);
-
-    const char* src1 = "";
-    const char* exp1 = "d41d8cd98f00b204e9800998ecf8427e";
-
-    EXPECT_TRUE(VolumeManager::asecHash(exp1, (char*)NULL, sizeof(buffer)) == NULL && errno == ESPIPE)
-            << "Should return NULL and set errno to ESPIPE when destination buffer is NULL";
-    EXPECT_TRUE(VolumeManager::asecHash(exp1, dst, 0) == NULL && errno == ESPIPE)
-            << "Should return NULL and set errno to ESPIPE when destination buffer length is 0";
-    EXPECT_TRUE(VolumeManager::asecHash((const char*)NULL, dst, sizeof(buffer)) == NULL && errno == ESPIPE)
-            << "Should return NULL and set errno to ESPIPE when source buffer is NULL";
-
-    EXPECT_FALSE(VolumeManager::asecHash(src1, dst, sizeof(buffer)) == NULL)
-            << "Should not return NULL on valid source, destination, and destination size";
-    EXPECT_STREQ(exp1, dst)
-            << "MD5 summed output should match";
-
-    const char* src2 = "android";
-    const char* exp2 = "c31b32364ce19ca8fcd150a417ecce58";
-    EXPECT_FALSE(VolumeManager::asecHash(src2, dst, sizeof(buffer)) == NULL)
-            << "Should not return NULL on valid source, destination, and destination size";
-    EXPECT_STREQ(exp2, dst)
-            << "MD5 summed output should match";
-}
-
 }
diff --git a/vdc.cpp b/vdc.cpp
index 3a38641..b249987 100644
--- a/vdc.cpp
+++ b/vdc.cpp
@@ -24,7 +24,6 @@
 #include <stdlib.h>
 #include <poll.h>
 
-#include <sys/socket.h>
 #include <sys/select.h>
 #include <sys/time.h>
 #include <sys/types.h>
@@ -36,23 +35,13 @@
 #include <android-base/stringprintf.h>
 #include <binder/IServiceManager.h>
 
-#include <cutils/sockets.h>
 #include <private/android_filesystem_config.h>
 
-#define ENABLE_BINDER 1
-
 static void usage(char *progname);
 
-#if !ENABLE_BINDER
-static int do_monitor(int sock, int stop_after_cmd);
-static int do_cmd(int sock, int argc, char **argv);
-#endif
-
-static constexpr int kCommandTimeoutMs = 20 * 1000;
-
 int main(int argc, char **argv) {
     int sock;
-    int wait_for_socket;
+    int wait;
     char *progname;
 
     progname = argv[0];
@@ -64,8 +53,8 @@
         android::base::InitLogging(argv, &android::base::StderrLogger);
     }
 
-    wait_for_socket = argc > 1 && strcmp(argv[1], "--wait") == 0;
-    if (wait_for_socket) {
+    wait = argc > 1 && strcmp(argv[1], "--wait") == 0;
+    if (wait) {
         argv++;
         argc--;
     }
@@ -75,7 +64,6 @@
         exit(5);
     }
 
-#if ENABLE_BINDER
     std::string arg1 = argv[1];
     std::string arg2 = argv[2];
 
@@ -102,119 +90,8 @@
         LOG(ERROR) << "Raw commands are no longer supported";
         exit(EINVAL);
     }
-#else
-    const char* sockname = "vold";
-    if (!strcmp(argv[1], "cryptfs")) {
-        sockname = "cryptd";
-    }
-
-    while ((sock = socket_local_client(sockname,
-                                 ANDROID_SOCKET_NAMESPACE_RESERVED,
-                                 SOCK_STREAM)) < 0) {
-        if (!wait_for_socket) {
-            PLOG(ERROR) << "Error connecting to " << sockname;
-            exit(4);
-        } else {
-            usleep(10000);
-        }
-    }
-
-    if (!strcmp(argv[1], "monitor")) {
-        exit(do_monitor(sock, 0));
-    } else {
-        exit(do_cmd(sock, argc, argv));
-    }
-#endif
 }
 
-#if !ENABLE_BINDER
-static int do_cmd(int sock, int argc, char **argv) {
-    int seq = getpid();
-
-    std::string cmd(android::base::StringPrintf("%d ", seq));
-    for (int i = 1; i < argc; i++) {
-        if (!strchr(argv[i], ' ')) {
-            cmd.append(argv[i]);
-        } else {
-            cmd.push_back('\"');
-            cmd.append(argv[i]);
-            cmd.push_back('\"');
-        }
-
-        if (i < argc - 1) {
-            cmd.push_back(' ');
-        }
-    }
-
-    if (TEMP_FAILURE_RETRY(write(sock, cmd.c_str(), cmd.length() + 1)) < 0) {
-        PLOG(ERROR) << "Failed to write command";
-        return errno;
-    }
-
-    return do_monitor(sock, seq);
-}
-
-static int do_monitor(int sock, int stop_after_seq) {
-    char buffer[4096];
-    int timeout = kCommandTimeoutMs;
-
-    if (stop_after_seq == 0) {
-        LOG(INFO) << "Connected to vold";
-        timeout = -1;
-    }
-
-    while (1) {
-        struct pollfd poll_sock = { sock, POLLIN, 0 };
-        int rc = TEMP_FAILURE_RETRY(poll(&poll_sock, 1, timeout));
-        if (rc == 0) {
-            LOG(ERROR) << "Timeout waiting for " << stop_after_seq;
-            return ETIMEDOUT;
-        } else if (rc < 0) {
-            PLOG(ERROR) << "Failed during poll";
-            return errno;
-        }
-
-        if (!(poll_sock.revents & POLLIN)) {
-            LOG(INFO) << "No data; trying again";
-            continue;
-        }
-
-        memset(buffer, 0, sizeof(buffer));
-        rc = TEMP_FAILURE_RETRY(read(sock, buffer, sizeof(buffer)));
-        if (rc == 0) {
-            LOG(ERROR) << "Lost connection, did vold crash?";
-            return ECONNRESET;
-        } else if (rc < 0) {
-            PLOG(ERROR) << "Error reading data";
-            return errno;
-        }
-
-        int offset = 0;
-        for (int i = 0; i < rc; i++) {
-            if (buffer[i] == '\0') {
-                char* res = buffer + offset;
-                fprintf(stdout, "%s\n", res);
-
-                int code = atoi(strtok(res, " "));
-                if (code >= 200 && code < 600) {
-                    int seq = atoi(strtok(nullptr, " "));
-                    if (seq == stop_after_seq) {
-                        if (code == 200) {
-                            return 0;
-                        } else {
-                            return code;
-                        }
-                    }
-                }
-
-                offset = i + 1;
-            }
-        }
-    }
-    return EIO;
-}
-#endif
-
 static void usage(char *progname) {
     LOG(INFO) << "Usage: " << progname << " [--wait] <monitor>|<cmd> [arg1] [arg2...]";
 }
diff --git a/vold.rc b/vold.rc
index 87e2fd8..c27aeda 100644
--- a/vold.rc
+++ b/vold.rc
@@ -2,9 +2,6 @@
         --blkid_context=u:r:blkid:s0 --blkid_untrusted_context=u:r:blkid_untrusted:s0 \
         --fsck_context=u:r:fsck:s0 --fsck_untrusted_context=u:r:fsck_untrusted:s0
     class core
-    socket vold stream 0660 root mount
-    socket cryptd stream 0660 root mount
     ioprio be 2
     writepid /dev/cpuset/foreground/tasks
     shutdown critical
-
