Codec2: move allocators to the platform allocator store

Also change allocator store to create allocators by ID vs type.

Bug: 64121714
Test: unittest
Change-Id: I5f8954d66ea575bea87a3bae5f5c536f17982ae8
diff --git a/media/libstagefright/codec2/include/C2Component.h b/media/libstagefright/codec2/include/C2Component.h
index f536132..34f78e2 100644
--- a/media/libstagefright/codec2/include/C2Component.h
+++ b/media/libstagefright/codec2/include/C2Component.h
@@ -518,15 +518,20 @@
 public:
     // TBD
 
-    enum Type {
-        LINEAR,     ///< basic linear allocator type
-        GRALLOC,    ///< basic gralloc allocator type
+    typedef uint32_t ID;
+
+    enum ID_ : uint32_t {
+        DEFAULT_LINEAR,     ///< basic linear allocator type
+        DEFAULT_GRAPHIC,    ///< basic graphic allocator type
+        PLATFORM_START = 0x10,
+        VENDOR_START   = 0x100,
     };
 
     /**
      * Creates an allocator.
      *
-     * \param type      the type of allocator to create
+     * \param id      the ID of the allocator to create. This is defined by the store, but
+     *                the ID of the default linear and graphic allocators is formalized.
      * \param allocator shared pointer where the created allocator is stored. Cleared on failure
      *                  and updated on success.
      *
@@ -537,7 +542,7 @@
      * \retval C2_NOT_FOUND no such allocator
      * \retval C2_NO_MEMORY not enough memory to create the allocator
      */
-    virtual status_t createAllocator(Type type, std::shared_ptr<C2Allocator>* const allocator) = 0;
+    virtual status_t createAllocator(ID id, std::shared_ptr<C2Allocator>* const allocator) = 0;
 
     virtual ~C2AllocatorStore() = default;
 };
diff --git a/media/libstagefright/codec2/vndk/Android.bp b/media/libstagefright/codec2/vndk/Android.bp
index 93bcb3a..64ce5e6 100644
--- a/media/libstagefright/codec2/vndk/Android.bp
+++ b/media/libstagefright/codec2/vndk/Android.bp
@@ -6,6 +6,7 @@
         "C2AllocatorGralloc.cpp",
         "C2Buffer.cpp",
         "C2Config.cpp",
+        "C2Store.cpp",
     ],
 
     include_dirs: [
diff --git a/media/libstagefright/codec2/vndk/C2AllocatorGralloc.cpp b/media/libstagefright/codec2/vndk/C2AllocatorGralloc.cpp
index 16b818b..baa6637 100644
--- a/media/libstagefright/codec2/vndk/C2AllocatorGralloc.cpp
+++ b/media/libstagefright/codec2/vndk/C2AllocatorGralloc.cpp
@@ -15,7 +15,7 @@
  */
 
 //#define LOG_NDEBUG 0
-#define LOG_TAG "C2AllocatorIon"
+#define LOG_TAG "C2AllocatorGralloc"
 #include <utils/Log.h>
 
 #include <android/hardware/graphics/allocator/2.0/IAllocator.h>
diff --git a/media/libstagefright/codec2/vndk/C2Store.cpp b/media/libstagefright/codec2/vndk/C2Store.cpp
new file mode 100644
index 0000000..f21a3f0
--- /dev/null
+++ b/media/libstagefright/codec2/vndk/C2Store.cpp
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2017 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 <C2AllocatorGralloc.h>
+#include <C2AllocatorIon.h>
+#include <C2Component.h>
+#include <C2PlatformSupport.h>
+
+#include <map>
+#include <memory>
+#include <mutex>
+
+namespace android {
+
+class C2PlatformAllocatorStore : public C2AllocatorStore {
+public:
+    enum ID_ : uint32_t {
+        ION = PLATFORM_START,
+        GRALLOC,
+    };
+
+    C2PlatformAllocatorStore(
+        /* ionmapper */
+    );
+    virtual status_t createAllocator(ID id, std::shared_ptr<C2Allocator> *const allocator);
+
+private:
+    // returns a shared-singleton ion allocator
+    std::shared_ptr<C2Allocator> getIonAllocator();
+
+    // returns a shared-singleton gralloc allocator
+    std::shared_ptr<C2Allocator> getGrallocAllocator();
+};
+
+C2PlatformAllocatorStore::C2PlatformAllocatorStore() {
+}
+
+status_t C2PlatformAllocatorStore::createAllocator(
+        ID id, std::shared_ptr<C2Allocator> *const allocator) {
+    allocator->reset();
+    switch (id) {
+    // TODO: should we implement a generic registry for all, and use that?
+    case C2PlatformAllocatorStore::ION:
+    case C2AllocatorStore::DEFAULT_LINEAR:
+        *allocator = getIonAllocator();
+        break;
+
+    case C2PlatformAllocatorStore::GRALLOC:
+    case C2AllocatorStore::DEFAULT_GRAPHIC:
+        *allocator = getGrallocAllocator();
+        break;
+
+    default:
+        return C2_NOT_FOUND;
+    }
+    if (*allocator == nullptr) {
+        return C2_NO_MEMORY;
+    }
+    return C2_OK;
+}
+
+std::shared_ptr<C2Allocator> C2PlatformAllocatorStore::getIonAllocator() {
+    static std::mutex mutex;
+    static std::weak_ptr<C2Allocator> ionAllocator;
+    std::lock_guard<std::mutex> lock(mutex);
+    std::shared_ptr<C2Allocator> allocator = ionAllocator.lock();
+    if (allocator == nullptr) {
+        allocator = std::make_shared<C2AllocatorIon>();
+        ionAllocator = allocator;
+    }
+    return allocator;
+}
+
+std::shared_ptr<C2Allocator> C2PlatformAllocatorStore::getGrallocAllocator() {
+    static std::mutex mutex;
+    static std::weak_ptr<C2Allocator> grallocAllocator;
+    std::lock_guard<std::mutex> lock(mutex);
+    std::shared_ptr<C2Allocator> allocator = grallocAllocator.lock();
+    if (allocator == nullptr) {
+        allocator = std::make_shared<C2AllocatorGralloc>();
+        grallocAllocator = allocator;
+    }
+    return allocator;
+}
+
+std::shared_ptr<C2AllocatorStore> GetCodec2PlatformAllocatorStore() {
+    return std::make_shared<C2PlatformAllocatorStore>();
+}
+
+} // namespace android
\ No newline at end of file
diff --git a/media/libstagefright/codec2/vndk/include/C2PlatformSupport.h b/media/libstagefright/codec2/vndk/include/C2PlatformSupport.h
new file mode 100644
index 0000000..9402050
--- /dev/null
+++ b/media/libstagefright/codec2/vndk/include/C2PlatformSupport.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2017 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 STAGEFRIGHT_CODEC2_PLATFORM_SUPPORT_H_
+#define STAGEFRIGHT_CODEC2_PLATFORM_SUPPORT_H_
+
+#include <C2Component.h>
+
+#include <memory>
+
+namespace android {
+
+/**
+ * Returns the platform allocator store.
+ */
+std::shared_ptr<C2AllocatorStore> GetCodec2PlatformAllocatorStore();
+
+} // namespace android
+
+#endif // STAGEFRIGHT_CODEC2_PLATFORM_SUPPORT_H_
diff --git a/media/libstagefright/codecs/cmds/codec2.cpp b/media/libstagefright/codecs/cmds/codec2.cpp
index c4cc6a6..29669aa 100644
--- a/media/libstagefright/codecs/cmds/codec2.cpp
+++ b/media/libstagefright/codecs/cmds/codec2.cpp
@@ -52,11 +52,10 @@
 #include <gui/SurfaceComposerClient.h>
 
 #include <util/C2ParamUtils.h>
-#include <C2AllocatorGralloc.h>
-#include <C2AllocatorIon.h>
 #include <C2Buffer.h>
 #include <C2BufferPriv.h>
 #include <C2Component.h>
+#include <C2PlatformSupport.h>
 #include <C2Work.h>
 
 #include "../avcdec/C2SoftAvcDec.h"
@@ -141,13 +140,16 @@
 SimplePlayer::SimplePlayer()
     : mListener(new Listener(this)),
       mProducerListener(new DummyProducerListener),
-      mAllocIon(new C2AllocatorIon),
-      mAllocGralloc(new C2AllocatorGralloc),
-      mLinearAlloc(new C2DefaultBlockAllocator(mAllocIon)),
-      mGraphicAlloc(new C2DefaultGraphicBlockAllocator(mAllocGralloc)),
       mComposerClient(new SurfaceComposerClient) {
     CHECK_EQ(mComposerClient->initCheck(), (status_t)OK);
 
+    std::shared_ptr<C2AllocatorStore> store = GetCodec2PlatformAllocatorStore();
+    CHECK_EQ(store->createAllocator(C2AllocatorStore::DEFAULT_LINEAR, &mAllocIon), C2_OK);
+    CHECK_EQ(store->createAllocator(C2AllocatorStore::DEFAULT_GRAPHIC, &mAllocGralloc), C2_OK);
+
+    mLinearAlloc = std::make_shared<C2DefaultBlockAllocator>(mAllocIon);
+    mGraphicAlloc = std::make_shared<C2DefaultGraphicBlockAllocator>(mAllocGralloc);
+
     mControl = mComposerClient->createSurface(
             String8("A Surface"),
             1280,