Add non-treble IOMXStore interface
Test: Compiles
Bug: 37657124
Change-Id: If1c800ff0560357c6d0d380a83e7e77f621f93da
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index 043c84a..c07a6cc 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -34,6 +34,7 @@
"IMediaCodecList.cpp",
"IMediaCodecService.cpp",
"IOMX.cpp",
+ "IOMXStore.cpp",
"MediaCodecBuffer.cpp",
"MediaCodecInfo.cpp",
"MediaDefs.cpp",
diff --git a/media/libmedia/IOMXStore.cpp b/media/libmedia/IOMXStore.cpp
new file mode 100644
index 0000000..4948f1a
--- /dev/null
+++ b/media/libmedia/IOMXStore.cpp
@@ -0,0 +1,367 @@
+/*
+ * Copyright (c) 2009 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "IOMXStore"
+
+#include <utils/Log.h>
+
+#include <media/IOMX.h>
+#include <media/IOMXStore.h>
+#include <android/hardware/media/omx/1.0/IOmxStore.h>
+
+#include <binder/IInterface.h>
+#include <binder/IBinder.h>
+#include <binder/Parcel.h>
+
+#include <vector>
+#include <string>
+
+namespace android {
+
+namespace {
+
+enum {
+ CONNECT = IBinder::FIRST_CALL_TRANSACTION,
+ LIST_SERVICE_ATTRIBUTES,
+ GET_NODE_PREFIX,
+ LIST_ROLES,
+ GET_OMX,
+};
+
+// Forward declarations of std::vector<T> <-> Parcel conversion funcitons that
+// depend on writeToParcel() and readToParcel() for T <-> Parcel.
+
+template <typename T>
+status_t writeToParcel(const std::vector<T>& v, Parcel* p);
+
+template <typename T>
+status_t readFromParcel(std::vector<T>* v, const Parcel& p);
+
+// std::string <-> Parcel
+
+status_t writeToParcel(const std::string& s, Parcel* p) {
+ if (s.size() > INT32_MAX) {
+ return BAD_VALUE;
+ }
+ return p->writeByteArray(
+ s.size(), reinterpret_cast<const uint8_t*>(s.c_str()));
+}
+
+status_t readFromParcel(std::string* s, const Parcel& p) {
+ int32_t len;
+ status_t status = p.readInt32(&len);
+ if (status != NO_ERROR) {
+ return status;
+ } else if ((len < 0) || (static_cast<uint64_t>(len) > SIZE_MAX)) {
+ return BAD_VALUE;
+ }
+ s->resize(len);
+ if (len == 0) {
+ return NO_ERROR;
+ }
+ return p.read(static_cast<void*>(&s->front()), static_cast<size_t>(len));
+}
+
+// IOMXStore::Attribute <-> Parcel
+
+status_t writeToParcel(const IOMXStore::Attribute& a, Parcel* p) {
+ status_t status = writeToParcel(a.key, p);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ return writeToParcel(a.value, p);
+}
+
+status_t readFromParcel(IOMXStore::Attribute* a, const Parcel& p) {
+ status_t status = readFromParcel(&(a->key), p);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ return readFromParcel(&(a->value), p);
+}
+
+// IOMXStore::NodeInfo <-> Parcel
+
+status_t writeToParcel(const IOMXStore::NodeInfo& n, Parcel* p) {
+ status_t status = writeToParcel(n.name, p);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = writeToParcel(n.owner, p);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ return writeToParcel(n.attributes, p);
+}
+
+status_t readFromParcel(IOMXStore::NodeInfo* n, const Parcel& p) {
+ status_t status = readFromParcel(&(n->name), p);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = readFromParcel(&(n->owner), p);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ return readFromParcel(&(n->attributes), p);
+}
+
+// IOMXStore::RoleInfo <-> Parcel
+
+status_t writeToParcel(const IOMXStore::RoleInfo& r, Parcel* p) {
+ status_t status = writeToParcel(r.role, p);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = writeToParcel(r.type, p);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = p->writeBool(r.isEncoder);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = p->writeBool(r.preferPlatformNodes);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ return writeToParcel(r.nodes, p);
+}
+
+status_t readFromParcel(IOMXStore::RoleInfo* r, const Parcel& p) {
+ status_t status = readFromParcel(&(r->role), p);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = readFromParcel(&(r->type), p);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = p.readBool(&(r->isEncoder));
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = p.readBool(&(r->preferPlatformNodes));
+ if (status != NO_ERROR) {
+ return status;
+ }
+ return readFromParcel(&(r->nodes), p);
+}
+
+// std::vector<NodeInfo> <-> Parcel
+// std::vector<RoleInfo> <-> Parcel
+
+template <typename T>
+status_t writeToParcel(const std::vector<T>& v, Parcel* p) {
+ status_t status = p->writeVectorSize(v);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ for (const T& x : v) {
+ status = writeToParcel(x, p);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ }
+ return NO_ERROR;
+}
+
+template <typename T>
+status_t readFromParcel(std::vector<T>* v, const Parcel& p) {
+ status_t status = p.resizeOutVector(v);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ for (T& x : *v) {
+ status = readFromParcel(&x, p);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ }
+ return NO_ERROR;
+}
+
+} // unnamed namespace
+
+////////////////////////////////////////////////////////////////////////////////
+
+class BpOMXStore : public BpInterface<IOMXStore> {
+public:
+ explicit BpOMXStore(const sp<IBinder> &impl)
+ : BpInterface<IOMXStore>(impl) {
+ }
+
+ status_t listServiceAttributes(
+ std::vector<Attribute>* attributes) override {
+ Parcel data, reply;
+ status_t status;
+ status = data.writeInterfaceToken(IOMXStore::getInterfaceDescriptor());
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = remote()->transact(LIST_SERVICE_ATTRIBUTES, data, &reply);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ return readFromParcel(attributes, reply);
+ }
+
+ status_t getNodePrefix(std::string* prefix) override {
+ Parcel data, reply;
+ status_t status;
+ status = data.writeInterfaceToken(IOMXStore::getInterfaceDescriptor());
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = remote()->transact(GET_NODE_PREFIX, data, &reply);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ return readFromParcel(prefix, reply);
+ }
+
+ status_t listRoles(std::vector<RoleInfo>* roleList) override {
+ Parcel data, reply;
+ status_t status;
+ status = data.writeInterfaceToken(IOMXStore::getInterfaceDescriptor());
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = remote()->transact(LIST_ROLES, data, &reply);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ return readFromParcel(roleList, reply);
+ }
+
+ status_t getOmx(const std::string& name, sp<IOMX>* omx) override {
+ Parcel data, reply;
+ status_t status;
+ status = data.writeInterfaceToken(IOMXStore::getInterfaceDescriptor());
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = writeToParcel(name, &data);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = remote()->transact(GET_OMX, data, &reply);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ return reply.readStrongBinder(omx);
+ }
+
+};
+
+IMPLEMENT_META_INTERFACE(OMXStore, "android.hardware.IOMXStore");
+
+////////////////////////////////////////////////////////////////////////////////
+
+#define CHECK_OMX_INTERFACE(interface, data, reply) \
+ do { if (!(data).enforceInterface(interface::getInterfaceDescriptor())) { \
+ ALOGW("Call incorrectly routed to " #interface); \
+ return PERMISSION_DENIED; \
+ } } while (0)
+
+status_t BnOMXStore::onTransact(
+ uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
+ switch (code) {
+ case LIST_SERVICE_ATTRIBUTES: {
+ CHECK_OMX_INTERFACE(IOMXStore, data, reply);
+ status_t status;
+ std::vector<Attribute> attributes;
+
+ status = listServiceAttributes(&attributes);
+ if (status != NO_ERROR) {
+ ALOGE("listServiceAttributes() fails with status %d",
+ static_cast<int>(status));
+ return NO_ERROR;
+ }
+ status = writeToParcel(attributes, reply);
+ if (status != NO_ERROR) {
+ ALOGE("listServiceAttributes() fails to send reply");
+ return NO_ERROR;
+ }
+ return NO_ERROR;
+ }
+ case GET_NODE_PREFIX: {
+ CHECK_OMX_INTERFACE(IOMXStore, data, reply);
+ status_t status;
+ std::string prefix;
+
+ status = getNodePrefix(&prefix);
+ if (status != NO_ERROR) {
+ ALOGE("getNodePrefix() fails with status %d",
+ static_cast<int>(status));
+ return NO_ERROR;
+ }
+ status = writeToParcel(prefix, reply);
+ if (status != NO_ERROR) {
+ ALOGE("getNodePrefix() fails to send reply");
+ return NO_ERROR;
+ }
+ return NO_ERROR;
+ }
+ case LIST_ROLES: {
+ CHECK_OMX_INTERFACE(IOMXStore, data, reply);
+ status_t status;
+ std::vector<RoleInfo> roleList;
+
+ status = listRoles(&roleList);
+ if (status != NO_ERROR) {
+ ALOGE("listRoles() fails with status %d",
+ static_cast<int>(status));
+ return NO_ERROR;
+ }
+ status = writeToParcel(roleList, reply);
+ if (status != NO_ERROR) {
+ ALOGE("listRoles() fails to send reply");
+ return NO_ERROR;
+ }
+ return NO_ERROR;
+ }
+ case GET_OMX: {
+ CHECK_OMX_INTERFACE(IOMXStore, data, reply);
+ status_t status;
+ std::string name;
+ sp<IOMX> omx;
+
+ status = readFromParcel(&name, data);
+ if (status != NO_ERROR) {
+ ALOGE("getOmx() fails to retrieve name");
+ return NO_ERROR;
+ }
+ status = getOmx(name, &omx);
+ if (status != NO_ERROR) {
+ ALOGE("getOmx() fails with status %d",
+ static_cast<int>(status));
+ return NO_ERROR;
+ }
+ status = reply->writeStrongBinder(IInterface::asBinder(omx));
+ if (status != NO_ERROR) {
+ ALOGE("getOmx() fails to send reply");
+ return NO_ERROR;
+ }
+ return NO_ERROR;
+ }
+ default:
+ return BBinder::onTransact(code, data, reply, flags);
+ }
+}
+
+} // namespace android
diff --git a/media/libmedia/include/media/IOMXStore.h b/media/libmedia/include/media/IOMXStore.h
new file mode 100644
index 0000000..f739c3b
--- /dev/null
+++ b/media/libmedia/include/media/IOMXStore.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2009 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 ANDROID_IOMXSTORE_H_
+
+#define ANDROID_IOMXSTORE_H_
+
+#include <media/IOMX.h>
+#include <android/hardware/media/omx/1.0/IOmxStore.h>
+
+#include <binder/IInterface.h>
+#include <binder/IBinder.h>
+
+#include <vector>
+#include <string>
+
+/*
+#include <OMX_Core.h>
+#include <OMX_Video.h>
+*/
+
+namespace android {
+
+using hardware::media::omx::V1_0::IOmxStore;
+
+class IOMXStore : public IInterface {
+public:
+ DECLARE_META_INTERFACE(OMXStore);
+
+ struct Attribute {
+ std::string key;
+ std::string value;
+ };
+
+ struct NodeInfo {
+ std::string name;
+ std::string owner;
+ std::vector<Attribute> attributes;
+ };
+
+ struct RoleInfo {
+ std::string role;
+ std::string type;
+ bool isEncoder;
+ bool preferPlatformNodes;
+ std::vector<NodeInfo> nodes;
+ };
+
+ virtual status_t listServiceAttributes(
+ std::vector<Attribute>* attributes) = 0;
+
+ virtual status_t getNodePrefix(std::string* prefix) = 0;
+
+ virtual status_t listRoles(std::vector<RoleInfo>* roleList) = 0;
+
+ virtual status_t getOmx(const std::string& name, sp<IOMX>* omx) = 0;
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+class BnOMXStore : public BnInterface<IOMXStore> {
+public:
+ virtual status_t onTransact(
+ uint32_t code, const Parcel &data, Parcel *reply,
+ uint32_t flags = 0);
+};
+
+} // namespace android
+
+#endif // ANDROID_IOMX_H_