recovery: Implement a volume manager

This is a copy of the pre-binderized vold which has been converted to
use direct calls instead of sockets and stripped down to only what is
needed to support recovery.

Includes:
  * recovery: volmgr: remove unused IsSupported

    Change-Id: If8206658fdfb6108221806c09c99bf0a30f4a586
    Signed-off-by: Jesse Chan <jc@lineageos.org>

  * recovery: volmgr: remove filesystem checks

    Those checks are not strictly necessary and we are
    not building fsck tools for recovery for now.

    Remove those checks so volmgr can be useful.

    Change-Id: I87756c61b933b6cdccd281c6276b686fbd36019f
    Signed-off-by: Jesse Chan <jc@lineageos.org>

  * recovery: fixup `EmulatedVolume creating`

    Avoid dangling pointer. Instead of pointing to FstabEntry create copy.

    Change-Id: I57f76006db09a6add2c173f43175f0f6b848d87b

  * recovery: fix volmgr cleaning up

    Don't reset pointer to netlink manager
    Delete disks in stop() rather then in ~VolumeManager
    Call destroy() before deleting disks cause delete expects the
      disk to be destroyed
    Clear the lists or we would read garbage data on the next scan

    Change-Id: Idadfa1f33b7cb5f2f3c780848a99344a6608420e

  * recovery: handle interrupts in apply update menu

    Change-Id: I1f78f9196634353b77986545332d7d52a5f0c161

Change-Id: Ic82d929e052b5ba70ecf7b475e0a223d77d9687e
diff --git a/volume_manager/VolumeBase.h b/volume_manager/VolumeBase.h
new file mode 100644
index 0000000..6ec6e27
--- /dev/null
+++ b/volume_manager/VolumeBase.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2019 The LineageOS 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 ANDROID_VOLMGR_VOLUMEBASE_H
+#define ANDROID_VOLMGR_VOLUMEBASE_H
+
+#include "Utils.h"
+
+#include <cutils/multiuser.h>
+#include <utils/Errors.h>
+
+#include <sys/types.h>
+#include <list>
+#include <string>
+
+namespace android {
+namespace volmgr {
+
+/*
+ * Representation of a mounted volume ready for presentation.
+ *
+ * Various subclasses handle the different mounting prerequisites, such as
+ * encryption details, etc.  Volumes can also be "stacked" above other
+ * volumes to help communicate dependencies.  For example, an ASEC volume
+ * can be stacked on a vfat volume.
+ *
+ * Mounted volumes can be asked to manage bind mounts to present themselves
+ * to specific users on the device.
+ *
+ * When an unmount is requested, the volume recursively unmounts any stacked
+ * volumes and removes any bind mounts before finally unmounting itself.
+ */
+class VolumeBase {
+  public:
+    virtual ~VolumeBase();
+
+    enum class Type {
+        kPublic = 0,
+        kPrivate,
+        kEmulated,
+        kAsec,
+        kObb,
+    };
+
+    enum MountFlags {
+        /* Flag that volume is primary external storage */
+        kPrimary = 1 << 0,
+        /* Flag that volume is visible to normal apps */
+        kVisible = 1 << 1,
+    };
+
+    enum class State {
+        kUnmounted = 0,
+        kChecking,
+        kMounted,
+        kMountedReadOnly,
+        kEjecting,
+        kUnmountable,
+        kRemoved,
+        kBadRemoval,
+    };
+
+    const std::string& getId() const { return mId; }
+    const std::string& getDiskId() const { return mDiskId; }
+    const std::string& getPartGuid() const { return mPartGuid; }
+    const std::string& getPartLabel() const { return mPartLabel; }
+    Type getType() const { return mType; }
+    int getMountFlags() const { return mMountFlags; }
+    State getState() const { return mState; }
+    const std::string& getPath() const { return mPath; }
+
+    status_t setDiskId(const std::string& diskId);
+    status_t setPartGuid(const std::string& partGuid);
+    status_t setPartLabel(const std::string& partLabel);
+    status_t setMountFlags(int mountFlags);
+    status_t setSilent(bool silent);
+
+    status_t create();
+    status_t destroy();
+    status_t mount();
+    status_t unmount(bool detach = false);
+
+  protected:
+    explicit VolumeBase(Type type);
+
+    virtual status_t doCreate();
+    virtual status_t doDestroy();
+    virtual status_t doMount() = 0;
+    virtual status_t doUnmount(bool detach = false) = 0;
+
+    status_t setId(const std::string& id);
+    status_t setPath(const std::string& path);
+
+  private:
+    /* ID that uniquely references volume while alive */
+    std::string mId;
+    /* ID that uniquely references parent disk while alive */
+    std::string mDiskId;
+    /* Partition GUID of this volume */
+    std::string mPartGuid;
+    /* Partition label of this volume */
+    std::string mPartLabel;
+    /* Volume type */
+    Type mType;
+    /* Flags used when mounting this volume */
+    int mMountFlags;
+    /* Flag indicating object is created */
+    bool mCreated;
+    /* Current state of volume */
+    State mState;
+    /* Path to mounted volume */
+    std::string mPath;
+    /* Flag indicating that volume should emit no events */
+    bool mSilent;
+
+    void setState(State state);
+
+    DISALLOW_COPY_AND_ASSIGN(VolumeBase);
+};
+
+}  // namespace volmgr
+}  // namespace android
+
+#endif