vold: allow to store key in a file on another partition

Add support for keeping the keys in a separate file on another partition,
for devices with no space reserved for a footer after the userdata filesystem.

Add support for encrypting the volumes managed by vold, if they meet certain
criteria, namely being marked as nonremovable and encryptable in vold.fstab.
A bit of trickiness is required to keep vold happy.

Change-Id: Idf0611f74b56c1026c45742ca82e0c26e58828fe
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index 906fb9e..071e027 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -41,6 +41,7 @@
 #include "Devmapper.h"
 #include "Process.h"
 #include "Asec.h"
+#include "cryptfs.h"
 
 VolumeManager *VolumeManager::sInstance = NULL;
 
@@ -1130,6 +1131,50 @@
     return 0;
 }
 
+extern "C" int vold_unmountVol(const char *label) {
+    VolumeManager *vm = VolumeManager::Instance();
+    return vm->unmountVolume(label, true);
+}
+
+extern "C" int vold_getNumDirectVolumes(void) {
+    VolumeManager *vm = VolumeManager::Instance();
+    return vm->getNumDirectVolumes();
+}
+
+int VolumeManager::getNumDirectVolumes(void) {
+    VolumeCollection::iterator i;
+    int n=0;
+
+    for (i = mVolumes->begin(); i != mVolumes->end(); ++i) {
+        if ((*i)->getShareDevice() != (dev_t)0) {
+            n++;
+        }
+    }
+    return n;
+}
+
+extern "C" int vold_getDirectVolumeList(struct volume_info *vol_list) {
+    VolumeManager *vm = VolumeManager::Instance();
+    return vm->getDirectVolumeList(vol_list);
+}
+
+int VolumeManager::getDirectVolumeList(struct volume_info *vol_list) {
+    VolumeCollection::iterator i;
+    int n=0;
+    dev_t d;
+
+    for (i = mVolumes->begin(); i != mVolumes->end(); ++i) {
+        if ((d=(*i)->getShareDevice()) != (dev_t)0) {
+            (*i)->getVolInfo(&vol_list[n]);
+            snprintf(vol_list[n].blk_dev, sizeof(vol_list[n].blk_dev),
+                     "/dev/block/vold/%d:%d",MAJOR(d), MINOR(d));
+            n++;
+        }
+    }
+
+    return 0;
+}
+
 int VolumeManager::unmountVolume(const char *label, bool force) {
     Volume *v = lookupVolume(label);