recovery: Hide unmountable volumes from selection

* In volume manager, check if new volumes are mountable.

* Check volumes for mountable for inclusion into update list.

* Erase unmountable volumes from volumes vector for consistency with
  the item array.

Change-Id: I89ff6cc05a93afffe5e46b24d70fc368bccaf020
diff --git a/recovery.cpp b/recovery.cpp
index 2f9e32d..f6178d1 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -217,8 +217,13 @@
     items.clear();
     items.push_back("Apply from ADB");
     VolumeManager::Instance()->getVolumeInfo(volumes);
-    for (auto& vitr : volumes) {
-      items.push_back("Choose from " + vitr.mLabel);
+    for (auto vol = volumes.begin(); vol != volumes.end(); /* empty */) {
+      if (!vol->mMountable) {
+        vol = volumes.erase(vol);
+        continue;
+      }
+      items.push_back("Choose from " + vol->mLabel);
+      ++vol;
     }
 
     int chosen = ui->ShowMenu(
diff --git a/volume_manager/EmulatedVolume.cpp b/volume_manager/EmulatedVolume.cpp
index 23e6434..d0e0dcf 100644
--- a/volume_manager/EmulatedVolume.cpp
+++ b/volume_manager/EmulatedVolume.cpp
@@ -32,6 +32,7 @@
 #include <sys/sysmacros.h>
 #include <sys/types.h>
 #include <sys/wait.h>
+#include <unistd.h>
 
 using android::base::StringPrintf;
 
@@ -39,6 +40,7 @@
 namespace volmgr {
 
 static const std::string kStagingPath = "/mnt/staging/emulated";
+static const std::string kFbeKeyVersion = kStagingPath + "/unencrypted/key/version";
 
 EmulatedVolume::EmulatedVolume(FstabEntry* rec, const std::string& subdir)
     : VolumeBase(Type::kEmulated),
@@ -90,5 +92,15 @@
     return OK;
 }
 
+bool EmulatedVolume::detectMountable() {
+    bool mountable = false;
+    if (doMount() == OK) {
+        // Check if FBE encrypted
+        mountable = access(kFbeKeyVersion.c_str(), F_OK) != 0;
+        doUnmount();
+    }
+    return mountable;
+}
+
 }  // namespace volmgr
 }  // namespace android
diff --git a/volume_manager/EmulatedVolume.h b/volume_manager/EmulatedVolume.h
index ac40b6f..66421cc 100644
--- a/volume_manager/EmulatedVolume.h
+++ b/volume_manager/EmulatedVolume.h
@@ -55,6 +55,8 @@
     unsigned long mFlags;
     std::string mFsOptions;
 
+    bool detectMountable() override;
+
     DISALLOW_COPY_AND_ASSIGN(EmulatedVolume);
 };
 
diff --git a/volume_manager/VolumeBase.cpp b/volume_manager/VolumeBase.cpp
index a0fd33b..bd7c29c 100644
--- a/volume_manager/VolumeBase.cpp
+++ b/volume_manager/VolumeBase.cpp
@@ -35,7 +35,7 @@
 namespace volmgr {
 
 VolumeBase::VolumeBase(Type type)
-    : mType(type), mMountFlags(0), mCreated(false), mState(State::kUnmounted), mSilent(false) {}
+    : mType(type), mMountFlags(0), mCreated(false), mState(State::kUnmounted), mSilent(false), mMountable(false) {}
 
 VolumeBase::~VolumeBase() {
     CHECK(!mCreated);
@@ -131,9 +131,21 @@
         }
     }
     setState(State::kUnmounted);
+
+    mMountable = detectMountable();
+
     return res;
 }
 
+bool VolumeBase::detectMountable() {
+    bool mountable = false;
+    if (doMount() == OK) {
+        mountable = true;
+        doUnmount();
+    }
+    return mountable;
+}
+
 status_t VolumeBase::doCreate() {
     return OK;
 }
diff --git a/volume_manager/VolumeBase.h b/volume_manager/VolumeBase.h
index 6ec6e27..acfff45 100644
--- a/volume_manager/VolumeBase.h
+++ b/volume_manager/VolumeBase.h
@@ -82,6 +82,7 @@
     int getMountFlags() const { return mMountFlags; }
     State getState() const { return mState; }
     const std::string& getPath() const { return mPath; }
+    bool isMountable() const { return mMountable; }
 
     status_t setDiskId(const std::string& diskId);
     status_t setPartGuid(const std::string& partGuid);
@@ -127,6 +128,9 @@
     /* Flag indicating that volume should emit no events */
     bool mSilent;
 
+    bool mMountable;
+    virtual bool detectMountable();
+
     void setState(State state);
 
     DISALLOW_COPY_AND_ASSIGN(VolumeBase);
diff --git a/volume_manager/VolumeManager.cpp b/volume_manager/VolumeManager.cpp
index 7609b1b..ded6565 100644
--- a/volume_manager/VolumeManager.cpp
+++ b/volume_manager/VolumeManager.cpp
@@ -136,7 +136,7 @@
 }
 
 VolumeInfo::VolumeInfo(const VolumeBase* vol)
-    : mId(vol->getId()), mLabel(vol->getPartLabel()), mPath(vol->getPath()) {
+    : mId(vol->getId()), mLabel(vol->getPartLabel()), mPath(vol->getPath()), mMountable(vol->isMountable()) {
     // Empty
 }
 
diff --git a/volume_manager/include/volume_manager/VolumeManager.h b/volume_manager/include/volume_manager/VolumeManager.h
index e5a65d4..c2cb8dd 100644
--- a/volume_manager/include/volume_manager/VolumeManager.h
+++ b/volume_manager/include/volume_manager/VolumeManager.h
@@ -49,6 +49,7 @@
     std::string mId;
     std::string mLabel;
     std::string mPath;
+    bool        mMountable;
 };
 
 class VolumeManager {