Make IGraphicBufferProducer a hybrid interface.
android::IGraphicBufferProducer will now become a hybrid
interface on
top of the HIDL interface
android::hardware::graphics::bufferqueue::V1_0::IGraphicBufferProducer.
This CL also removes the hybrid interface mechanism from libbinder and
splits BufferQueueDefs into two parts, ui and gui.
Test: Camera, Photos, YouTube and Play Movies apps.
Bug: 35442034
Bug: 33854657
Change-Id: Idbbfdc8d9be375281b533050cea03c56fded9075
diff --git a/include/binder/HalToken.h b/include/binder/HalToken.h
deleted file mode 100644
index ce97c78..0000000
--- a/include/binder/HalToken.h
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * 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 ANDROID_HALTOKEN_H
-#define ANDROID_HALTOKEN_H
-
-#include <binder/Parcel.h>
-#include <hidl/HidlSupport.h>
-
-/**
- * Hybrid Interfaces
- * =================
- *
- * A hybrid interface is a binder interface that
- * 1. is implemented both traditionally and as a wrapper around a hidl
- * interface, and allows querying whether the underlying instance comes from
- * a hidl interface or not; and
- * 2. allows efficient calls to a hidl interface (if the underlying instance
- * comes from a hidl interface) by automatically creating the wrapper in the
- * process that calls it.
- *
- * Terminology:
- * - `HalToken`: The type for a "token" of a hidl interface. This is defined to
- * be compatible with `ITokenManager.hal`.
- * - `HInterface`: The base type for a hidl interface. Currently, it is defined
- * as `::android::hidl::base::V1_0::IBase`.
- * - `HALINTERFACE`: The hidl interface that will be sent through binders.
- * - `INTERFACE`: The binder interface that will be the wrapper of
- * `HALINTERFACE`. `INTERFACE` is supposed to be somewhat similar to
- * `HALINTERFACE`.
- *
- * To demonstrate how this is done, here is an example. Suppose `INTERFACE` is
- * `IFoo` and `HALINTERFACE` is `HFoo`. The required steps are:
- * 1. Use DECLARE_HYBRID_META_INTERFACE instead of DECLARE_META_INTERFACE in the
- * definition of `IFoo`. The usage is
- * DECLARE_HYBRID_META_INTERFACE(IFoo, HFoo)
- * inside the body of `IFoo`.
- * 2. Create a converter class that derives from
- * `H2BConverter<HFoo, IFoo, BnFoo>`. Let us call this `H2BFoo`.
- * 3. Add the following constructor in `H2BFoo` that call the corresponding
- * constructors in `H2BConverter`:
- * H2BFoo(const sp<HalInterface>& base) : CBase(base) {}
- * Note: `CBase = H2BConverter<HFoo, IFoo, BnFoo>` and `HalInterface = HFoo`
- * are member typedefs of `H2BConverter<HFoo, IFoo, BnFoo>`, so the above
- * line can be copied into `H2BFoo`.
- * 4. Implement `IFoo` in `H2BFoo` on top of `HFoo`. `H2BConverter` provides a
- * protected `mBase` of type `sp<HFoo>` that can be used to access the `HFoo`
- * instance. (There is also a public function named `getHalInterface()` that
- * returns `mBase`.)
- * 5. Create a hardware proxy class that derives from
- * `HpInterface<BpFoo, H2BFoo>`. Name this class `HpFoo`. (This name cannot
- * deviate. See step 8 below.)
- * 6. Add the following constructor to `HpFoo`:
- * HpFoo(const sp<IBinder>& base): PBase(base) {}
- * Note: `PBase` a member typedef of `HpInterface<BpFoo, H2BFoo>` that is
- * equal to `HpInterface<BpFoo, H2BFoo>` itself, so the above line can be
- * copied verbatim into `HpFoo`.
- * 7. Delegate all functions in `HpFoo` that come from `IFoo` except
- * `getHalInterface` to the protected member `mBase`,
- * which is defined in `HpInterface<BpFoo, H2BFoo>` (hence in `HpFoo`) with
- * type `IFoo`. (There is also a public function named `getBaseInterface()`
- * that returns `mBase`.)
- * 8. Replace the existing `IMPLEMENT_META_INTERFACE` for INTERFACE by
- * `IMPLEMENT_HYBRID_META_INTERFACE`. Note that this macro relies on the
- * exact naming of `HpFoo`, where `Foo` comes from the interface name `IFoo`.
- * An example usage is
- * IMPLEMENT_HYBRID_META_INTERFACE(IFoo, HFoo, "example.interface.foo");
- *
- * `GETTOKEN` Template Argument
- * ============================
- *
- * Following the instructions above, `H2BConverter` and `HpInterface` would use
- * `transact()` to send over tokens, with `code` (the first argument of
- * `transact()`) equal to a 4-byte value of '_GTK'. If this value clashes with
- * other values already in use in the `Bp` class, it can be changed by supplying
- * the last optional template argument to `H2BConverter` and `HpInterface`.
- *
- */
-
-namespace android {
-
-typedef uint64_t HalToken;
-typedef ::android::hidl::base::V1_0::IBase HInterface;
-
-sp<HInterface> retrieveHalInterface(const HalToken& token);
-bool createHalToken(const sp<HInterface>& interface, HalToken* token);
-bool deleteHalToken(const HalToken& token);
-
-template <
- typename HINTERFACE,
- typename INTERFACE,
- typename BNINTERFACE,
- uint32_t GETTOKEN = '_GTK'>
-class H2BConverter : public BNINTERFACE {
-public:
- typedef H2BConverter<HINTERFACE, INTERFACE, BNINTERFACE, GETTOKEN> CBase; // Converter Base
- typedef INTERFACE BaseInterface;
- typedef HINTERFACE HalInterface;
- static constexpr uint32_t GET_HAL_TOKEN = GETTOKEN;
-
- H2BConverter(const sp<HalInterface>& base) : mBase(base) {}
- virtual status_t onTransact(uint32_t code,
- const Parcel& data, Parcel* reply, uint32_t flags = 0);
- sp<HalInterface> getHalInterface() override { return mBase; }
- HalInterface* getBaseInterface() { return mBase.get(); }
-
-protected:
- sp<HalInterface> mBase;
-};
-
-template <
- typename BPINTERFACE,
- typename CONVERTER,
- uint32_t GETTOKEN = '_GTK'>
-class HpInterface : public CONVERTER::BaseInterface {
-public:
- typedef HpInterface<BPINTERFACE, CONVERTER, GETTOKEN> PBase; // Proxy Base
- typedef typename CONVERTER::BaseInterface BaseInterface;
- typedef typename CONVERTER::HalInterface HalInterface;
- static constexpr uint32_t GET_HAL_TOKEN = GETTOKEN;
-
- explicit HpInterface(const sp<IBinder>& impl);
- sp<HalInterface> getHalInterface() override { return mHal; }
- BaseInterface* getBaseInterface() { return mBase.get(); }
-
-protected:
- sp<IBinder> mImpl;
- sp<BaseInterface> mBase;
- sp<HalInterface> mHal;
- IBinder* onAsBinder() override { return mImpl.get(); }
-};
-
-// ----------------------------------------------------------------------
-
-#define DECLARE_HYBRID_META_INTERFACE(INTERFACE, HAL) \
- static const ::android::String16 descriptor; \
- static ::android::sp<I##INTERFACE> asInterface( \
- const ::android::sp<::android::IBinder>& obj); \
- virtual const ::android::String16& getInterfaceDescriptor() const; \
- I##INTERFACE(); \
- virtual ~I##INTERFACE(); \
- virtual sp<HAL> getHalInterface(); \
-
-
-#define IMPLEMENT_HYBRID_META_INTERFACE(INTERFACE, HAL, NAME) \
- const ::android::String16 I##INTERFACE::descriptor(NAME); \
- const ::android::String16& \
- I##INTERFACE::getInterfaceDescriptor() const { \
- return I##INTERFACE::descriptor; \
- } \
- ::android::sp<I##INTERFACE> I##INTERFACE::asInterface( \
- const ::android::sp<::android::IBinder>& obj) \
- { \
- ::android::sp<I##INTERFACE> intr; \
- if (obj != NULL) { \
- intr = static_cast<I##INTERFACE*>( \
- obj->queryLocalInterface( \
- I##INTERFACE::descriptor).get()); \
- if (intr == NULL) { \
- intr = new Hp##INTERFACE(obj); \
- } \
- } \
- return intr; \
- } \
- I##INTERFACE::I##INTERFACE() { } \
- I##INTERFACE::~I##INTERFACE() { } \
- sp<HAL> I##INTERFACE::getHalInterface() { return nullptr; } \
-
-// ----------------------------------------------------------------------
-
-template <
- typename HINTERFACE,
- typename INTERFACE,
- typename BNINTERFACE,
- uint32_t GETTOKEN>
-status_t H2BConverter<HINTERFACE, INTERFACE, BNINTERFACE, GETTOKEN>::
- onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
- if (code == GET_HAL_TOKEN) {
- HalToken token;
- bool result;
- result = createHalToken(mBase, &token);
- if (!result) {
- ALOGE("H2BConverter: Failed to create HAL token.");
- }
- reply->writeBool(result);
- reply->writeUint64(token);
- return NO_ERROR;
- }
- return BNINTERFACE::onTransact(code, data, reply, flags);
-}
-
-template <typename BPINTERFACE, typename CONVERTER, uint32_t GETTOKEN>
-HpInterface<BPINTERFACE, CONVERTER, GETTOKEN>::HpInterface(
- const sp<IBinder>& impl) : mImpl(impl) {
- Parcel data, reply;
- data.writeInterfaceToken(BaseInterface::getInterfaceDescriptor());
- if (impl->transact(GET_HAL_TOKEN, data, &reply) == NO_ERROR) {
- bool tokenCreated = reply.readBool();
- HalToken token = reply.readUint64();
- if (!tokenCreated) {
- ALOGE("HpInterface: Sender failed to create HAL token.");
- mBase = new BPINTERFACE(impl);
- } else {
- sp<HInterface> hInterface = retrieveHalInterface(token);
- deleteHalToken(token);
- if (hInterface != nullptr) {
- mHal = static_cast<HalInterface*>(hInterface.get());
- mBase = new CONVERTER(mHal);
- } else {
- ALOGE("HpInterface: Cannot retrieve HAL interface from token.");
- mBase = new BPINTERFACE(impl);
- }
- }
- } else {
- mBase = new BPINTERFACE(impl);
- }
-}
-
-// ----------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_HALTOKEN_H
diff --git a/include/gui/BufferQueueDefs.h b/include/gui/BufferQueueDefs.h
index 83e9580..ffafb49 100644
--- a/include/gui/BufferQueueDefs.h
+++ b/include/gui/BufferQueueDefs.h
@@ -18,16 +18,12 @@
#define ANDROID_GUI_BUFFERQUEUECOREDEFS_H
#include <gui/BufferSlot.h>
+#include <ui/BufferQueueDefs.h>
namespace android {
class BufferQueueCore;
namespace BufferQueueDefs {
- // BufferQueue will keep track of at most this value of buffers.
- // Attempts at runtime to increase the number of buffers past this
- // will fail.
- enum { NUM_BUFFER_SLOTS = 64 };
-
typedef BufferSlot SlotsType[NUM_BUFFER_SLOTS];
} // namespace BufferQueueDefs
} // namespace android
diff --git a/include/gui/IGraphicBufferProducer.h b/include/gui/IGraphicBufferProducer.h
index 258cd2f..5810335 100644
--- a/include/gui/IGraphicBufferProducer.h
+++ b/include/gui/IGraphicBufferProducer.h
@@ -32,12 +32,17 @@
#include <gui/FrameTimestamps.h>
+#include <hidl/HybridInterface.h>
+#include <android/hardware/graphics/bufferqueue/1.0/IGraphicBufferProducer.h>
+
namespace android {
// ----------------------------------------------------------------------------
class IProducerListener;
class NativeHandle;
class Surface;
+typedef ::android::hardware::graphics::bufferqueue::V1_0::IGraphicBufferProducer
+ HGraphicBufferProducer;
/*
* This class defines the Binder IPC interface for the producer side of
@@ -56,7 +61,7 @@
class IGraphicBufferProducer : public IInterface
{
public:
- DECLARE_META_INTERFACE(GraphicBufferProducer)
+ DECLARE_HYBRID_META_INTERFACE(GraphicBufferProducer, HGraphicBufferProducer)
enum {
// A flag returned by dequeueBuffer when the client needs to call
diff --git a/include/gui/bufferqueue/1.0/B2HProducerListener.h b/include/gui/bufferqueue/1.0/B2HProducerListener.h
new file mode 100644
index 0000000..fa6c2d9
--- /dev/null
+++ b/include/gui/bufferqueue/1.0/B2HProducerListener.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2016, 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_HARDWARE_GRAPHICS_BUFFERQUEUE_V1_0_B2HPRODUCERLISTENER_H
+#define ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V1_0_B2HPRODUCERLISTENER_H
+
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+#include <binder/IBinder.h>
+#include <gui/IProducerListener.h>
+
+#include <android/hidl/base/1.0/IBase.h>
+#include <android/hardware/graphics/bufferqueue/1.0/IProducerListener.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace bufferqueue {
+namespace V1_0 {
+namespace utils {
+
+using ::android::hidl::base::V1_0::IBase;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+typedef ::android::hardware::graphics::bufferqueue::V1_0::IProducerListener
+ HProducerListener;
+
+typedef ::android::IProducerListener
+ BProducerListener;
+
+struct B2HProducerListener : public HProducerListener {
+ sp<BProducerListener> mBase;
+ B2HProducerListener(sp<BProducerListener> const& base);
+ Return<void> onBufferReleased() override;
+ Return<bool> needsReleaseNotify() override;
+};
+
+} // namespace utils
+} // namespace V1_0
+} // namespace omx
+} // namespace media
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V1_0_B2HPRODUCERLISTENER_H
+
diff --git a/include/gui/bufferqueue/1.0/H2BGraphicBufferProducer.h b/include/gui/bufferqueue/1.0/H2BGraphicBufferProducer.h
new file mode 100644
index 0000000..93c452a
--- /dev/null
+++ b/include/gui/bufferqueue/1.0/H2BGraphicBufferProducer.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2016, 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_HARDWARE_GRAPHICS_BUFFERQUEUE_V1_0_H2BGRAPHICBUFFERPRODUCER_H
+#define ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V1_0_H2BGRAPHICBUFFERPRODUCER_H
+
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+#include <binder/Binder.h>
+#include <gui/IGraphicBufferProducer.h>
+#include <gui/IProducerListener.h>
+
+#include <hidl/HybridInterface.h>
+#include <android/hardware/graphics/bufferqueue/1.0/IGraphicBufferProducer.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace bufferqueue {
+namespace V1_0 {
+namespace utils {
+
+using ::android::hidl::base::V1_0::IBase;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+using ::android::hardware::graphics::common::V1_0::PixelFormat;
+using ::android::hardware::media::V1_0::AnwBuffer;
+
+typedef ::android::hardware::graphics::bufferqueue::V1_0::IGraphicBufferProducer
+ HGraphicBufferProducer;
+typedef ::android::hardware::graphics::bufferqueue::V1_0::IProducerListener
+ HProducerListener;
+
+typedef ::android::IGraphicBufferProducer BGraphicBufferProducer;
+using ::android::BnGraphicBufferProducer;
+using ::android::IProducerListener;
+
+struct H2BGraphicBufferProducer : public ::android::H2BConverter<
+ HGraphicBufferProducer,
+ BGraphicBufferProducer,
+ BnGraphicBufferProducer> {
+ H2BGraphicBufferProducer(sp<HGraphicBufferProducer> const& base) : CBase(base) {}
+
+ status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) override;
+ status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers) override;
+ status_t setAsyncMode(bool async) override;
+ status_t dequeueBuffer(int* slot, sp<Fence>* fence, uint32_t w,
+ uint32_t h, ::android::PixelFormat format, uint32_t usage,
+ FrameEventHistoryDelta* outTimestamps) override;
+ status_t detachBuffer(int slot) override;
+ status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence)
+ override;
+ status_t attachBuffer(int* outSlot, const sp<GraphicBuffer>& buffer)
+ override;
+ status_t queueBuffer(int slot,
+ const QueueBufferInput& input,
+ QueueBufferOutput* output) override;
+ status_t cancelBuffer(int slot, const sp<Fence>& fence) override;
+ int query(int what, int* value) override;
+ status_t connect(const sp<IProducerListener>& listener, int api,
+ bool producerControlledByApp, QueueBufferOutput* output) override;
+ status_t disconnect(int api, DisconnectMode mode = DisconnectMode::Api)
+ override;
+ status_t setSidebandStream(const sp<NativeHandle>& stream) override;
+ void allocateBuffers(uint32_t width, uint32_t height,
+ ::android::PixelFormat format, uint32_t usage) override;
+ status_t allowAllocation(bool allow) override;
+ status_t setGenerationNumber(uint32_t generationNumber) override;
+ String8 getConsumerName() const override;
+ status_t setSharedBufferMode(bool sharedBufferMode) override;
+ status_t setAutoRefresh(bool autoRefresh) override;
+ status_t setDequeueTimeout(nsecs_t timeout) override;
+ status_t getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer,
+ sp<Fence>* outFence, float outTransformMatrix[16]) override;
+ void getFrameTimestamps(FrameEventHistoryDelta* outDelta) override;
+ status_t getUniqueId(uint64_t* outId) const override;
+};
+
+} // namespace utils
+} // namespace V1_0
+} // namespace bufferqueue
+} // namespace graphics
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V1_0_H2BGRAPHICBUFFERPRODUCER_H
diff --git a/include/ui/BufferQueueDefs.h b/include/ui/BufferQueueDefs.h
new file mode 100644
index 0000000..56de181
--- /dev/null
+++ b/include/ui/BufferQueueDefs.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 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 ANDROID_UI_BUFFERQUEUEDEFS_H
+#define ANDROID_UI_BUFFERQUEUEDEFS_H
+
+namespace android {
+ namespace BufferQueueDefs {
+ // BufferQueue will keep track of at most this value of buffers.
+ // Attempts at runtime to increase the number of buffers past this
+ // will fail.
+ static constexpr int NUM_BUFFER_SLOTS = 64;
+ } // namespace BufferQueueDefs
+} // namespace android
+
+#endif