Implement IOmxStore

Separate out MediaCodecsXmlParser and implement IOmxStore and IOMXStore.

Test: make cts -j123 && cts-tradefed run cts-dev -m \
CtsMediaTestCases --compatibility:module-arg \
CtsMediaTestCases:include-annotation:\
android.platform.test.annotations.RequiresDevice

Test: make cts -j123 && cts-tradefed run cts -m \
CtsMediaTestCases -t android.media.cts.MediaCodecListTest

Bug: 37657124

Change-Id: I8c5a3a8fe6defab4f17c8a49bce57452879193dc
diff --git a/media/libmedia/MediaCodecInfo.cpp b/media/libmedia/MediaCodecInfo.cpp
index 2a74512..a570ffe 100644
--- a/media/libmedia/MediaCodecInfo.cpp
+++ b/media/libmedia/MediaCodecInfo.cpp
@@ -101,42 +101,46 @@
     return OK;
 }
 
-void MediaCodecInfo::CapabilitiesBuilder::addProfileLevel(uint32_t profile, uint32_t level) {
+void MediaCodecInfo::CapabilitiesWriter::addDetail(
+        const char* key, const char* value) {
+    mCap->mDetails->setString(key, value);
+}
+
+void MediaCodecInfo::CapabilitiesWriter::addDetail(
+        const char* key, int32_t value) {
+    mCap->mDetails->setInt32(key, value);
+}
+
+void MediaCodecInfo::CapabilitiesWriter::addProfileLevel(
+        uint32_t profile, uint32_t level) {
     ProfileLevel profileLevel;
     profileLevel.mProfile = profile;
     profileLevel.mLevel = level;
-    if (mProfileLevelsSorted.indexOf(profileLevel) < 0) {
-        mProfileLevels.push_back(profileLevel);
-        mProfileLevelsSorted.add(profileLevel);
+    if (mCap->mProfileLevelsSorted.indexOf(profileLevel) < 0) {
+        mCap->mProfileLevels.push_back(profileLevel);
+        mCap->mProfileLevelsSorted.add(profileLevel);
     }
 }
 
-void MediaCodecInfo::CapabilitiesBuilder::addColorFormat(uint32_t format) {
-    if (mColorFormatsSorted.indexOf(format) < 0) {
-        mColorFormats.push(format);
-        mColorFormatsSorted.add(format);
+void MediaCodecInfo::CapabilitiesWriter::addColorFormat(uint32_t format) {
+    if (mCap->mColorFormatsSorted.indexOf(format) < 0) {
+        mCap->mColorFormats.push(format);
+        mCap->mColorFormatsSorted.add(format);
     }
 }
 
-void MediaCodecInfo::CapabilitiesBuilder::addFlags(uint32_t flags) {
-    mFlags |= flags;
+void MediaCodecInfo::CapabilitiesWriter::addFlags(uint32_t flags) {
+    mCap->mFlags |= flags;
+}
+
+MediaCodecInfo::CapabilitiesWriter::CapabilitiesWriter(
+        MediaCodecInfo::Capabilities* cap) : mCap(cap) {
 }
 
 bool MediaCodecInfo::isEncoder() const {
     return mIsEncoder;
 }
 
-bool MediaCodecInfo::hasQuirk(const char *name) const {
-    if (name) {
-        for (size_t ix = 0; ix < mQuirks.size(); ix++) {
-            if (mQuirks.itemAt(ix).equalsIgnoreCase(name)) {
-                return true;
-            }
-        }
-    }
-    return false;
-}
-
 void MediaCodecInfo::getSupportedMimes(Vector<AString> *mimes) const {
     mimes->clear();
     for (size_t ix = 0; ix < mCaps.size(); ix++) {
@@ -157,20 +161,21 @@
     return mName.c_str();
 }
 
+const char *MediaCodecInfo::getOwnerName() const {
+    return mOwner.c_str();
+}
+
 // static
 sp<MediaCodecInfo> MediaCodecInfo::FromParcel(const Parcel &parcel) {
     AString name = AString::FromParcel(parcel);
+    AString owner = AString::FromParcel(parcel);
     bool isEncoder = static_cast<bool>(parcel.readInt32());
-    sp<MediaCodecInfo> info = new MediaCodecInfo(name, isEncoder, NULL);
+    sp<MediaCodecInfo> info = new MediaCodecInfo;
+    info->mName = name;
+    info->mOwner = owner;
+    info->mIsEncoder = isEncoder;
     size_t size = static_cast<size_t>(parcel.readInt32());
     for (size_t i = 0; i < size; i++) {
-        AString quirk = AString::FromParcel(parcel);
-        if (info != NULL) {
-            info->mQuirks.push_back(quirk);
-        }
-    }
-    size = static_cast<size_t>(parcel.readInt32());
-    for (size_t i = 0; i < size; i++) {
         AString mime = AString::FromParcel(parcel);
         sp<Capabilities> caps = Capabilities::FromParcel(parcel);
         if (caps == NULL)
@@ -184,11 +189,8 @@
 
 status_t MediaCodecInfo::writeToParcel(Parcel *parcel) const {
     mName.writeToParcel(parcel);
+    mOwner.writeToParcel(parcel);
     parcel->writeInt32(mIsEncoder);
-    parcel->writeInt32(mQuirks.size());
-    for (size_t i = 0; i < mQuirks.size(); i++) {
-        mQuirks.itemAt(i).writeToParcel(parcel);
-    }
     parcel->writeInt32(mCaps.size());
     for (size_t i = 0; i < mCaps.size(); i++) {
         mCaps.keyAt(i).writeToParcel(parcel);
@@ -208,86 +210,46 @@
     return -1;
 }
 
-MediaCodecInfo::MediaCodecInfo(AString name, bool encoder, const char *mime)
-    : mName(name),
-      mIsEncoder(encoder),
-      mHasSoleMime(false) {
-    if (mime != NULL) {
-        addMime(mime);
-        mHasSoleMime = true;
-    }
+MediaCodecInfo::MediaCodecInfo() {
 }
 
-status_t MediaCodecInfo::addMime(const char *mime) {
-    if (mHasSoleMime) {
-        ALOGE("Codec '%s' already had its type specified", mName.c_str());
-        return -EINVAL;
-    }
-    ssize_t ix = getCapabilityIndex(mime);
+void MediaCodecInfoWriter::setName(const char* name) {
+    mInfo->mName = name;
+}
+
+void MediaCodecInfoWriter::setOwner(const char* owner) {
+    mInfo->mOwner = owner;
+}
+
+void MediaCodecInfoWriter::setEncoder(bool isEncoder) {
+    mInfo->mIsEncoder = isEncoder;
+}
+
+std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>
+        MediaCodecInfoWriter::addMime(const char *mime) {
+    ssize_t ix = mInfo->getCapabilityIndex(mime);
     if (ix >= 0) {
-        mCurrentCaps = mCaps.valueAt(ix);
-    } else {
-        mCurrentCaps = new Capabilities();
-        mCaps.add(AString(mime), mCurrentCaps);
+        return std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>(
+                new MediaCodecInfo::CapabilitiesWriter(
+                mInfo->mCaps.valueAt(ix).get()));
     }
-    return OK;
+    sp<MediaCodecInfo::Capabilities> caps = new MediaCodecInfo::Capabilities();
+    mInfo->mCaps.add(AString(mime), caps);
+    return std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>(
+            new MediaCodecInfo::CapabilitiesWriter(caps.get()));
 }
 
-status_t MediaCodecInfo::updateMime(const char *mime) {
-    ssize_t ix = getCapabilityIndex(mime);
-    if (ix < 0) {
-        ALOGE("updateMime mime not found %s", mime);
-        return -EINVAL;
-    }
-
-    mCurrentCaps = mCaps.valueAt(ix);
-    return OK;
-}
-
-void MediaCodecInfo::removeMime(const char *mime) {
-    ssize_t ix = getCapabilityIndex(mime);
+bool MediaCodecInfoWriter::removeMime(const char *mime) {
+    ssize_t ix = mInfo->getCapabilityIndex(mime);
     if (ix >= 0) {
-        mCaps.removeItemsAt(ix);
-        // mCurrentCaps will be removed when completed
+        mInfo->mCaps.removeItemsAt(ix);
+        return true;
     }
+    return false;
 }
 
-status_t MediaCodecInfo::initializeCapabilities(const sp<Capabilities> &caps) {
-    // TRICKY: copy data to mCurrentCaps as it is a reference to
-    // an element of the capabilites map.
-    mCurrentCaps->mColorFormats.clear();
-    mCurrentCaps->mColorFormats.appendVector(caps->mColorFormats);
-    mCurrentCaps->mProfileLevels.clear();
-    mCurrentCaps->mProfileLevels.appendVector(caps->mProfileLevels);
-    mCurrentCaps->mFlags = caps->mFlags;
-    mCurrentCaps->mDetails = caps->mDetails;
-    return OK;
-}
-
-void MediaCodecInfo::addQuirk(const char *name) {
-    if (!hasQuirk(name)) {
-        mQuirks.push(name);
-    }
-}
-
-void MediaCodecInfo::complete() {
-    mCurrentCaps = NULL;
-}
-
-void MediaCodecInfo::addDetail(const AString &key, const AString &value) {
-    mCurrentCaps->mDetails->setString(key.c_str(), value.c_str());
-}
-
-void MediaCodecInfo::addFeature(const AString &key, int32_t value) {
-    AString tag = "feature-";
-    tag.append(key);
-    mCurrentCaps->mDetails->setInt32(tag.c_str(), value);
-}
-
-void MediaCodecInfo::addFeature(const AString &key, const char *value) {
-    AString tag = "feature-";
-    tag.append(key);
-    mCurrentCaps->mDetails->setString(tag.c_str(), value);
+MediaCodecInfoWriter::MediaCodecInfoWriter(MediaCodecInfo* info) :
+    mInfo(info) {
 }
 
 }  // namespace android