Loading include/gui/GLConsumer.h +1 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <gui/BufferQueueDefs.h> #include <gui/ConsumerBase.h> #include <ui/FenceTime.h> #include <ui/GraphicBuffer.h> #include <utils/String8.h> Loading include/gui/IConsumerListener.h +42 −61 Original line number Diff line number Diff line Loading @@ -14,28 +14,25 @@ * limitations under the License. */ #ifndef ANDROID_GUI_ICONSUMERLISTENER_H #define ANDROID_GUI_ICONSUMERLISTENER_H #pragma once #include <stdint.h> #include <sys/types.h> #include <binder/IInterface.h> #include <binder/SafeInterface.h> #include <utils/Errors.h> #include <utils/RefBase.h> #include <binder/IInterface.h> #include <gui/FrameTimestamps.h> #include <cstdint> namespace android { // ---------------------------------------------------------------------------- class BufferItem; class FrameEventHistoryDelta; struct NewFrameEventsEntry; // ConsumerListener is the interface through which the BufferQueue notifies // the consumer of events that the consumer may wish to react to. Because // the consumer will generally have a mutex that is locked during calls from // the consumer to the BufferQueue, these calls from the BufferQueue to the // ConsumerListener is the interface through which the BufferQueue notifies the consumer of events // that the consumer may wish to react to. Because the consumer will generally have a mutex that is // locked during calls from the consumer to the BufferQueue, these calls from the BufferQueue to the // consumer *MUST* be called only when the BufferQueue mutex is NOT locked. class ConsumerListener : public virtual RefBase { Loading @@ -46,71 +43,55 @@ public: // onDisconnect is called when a producer disconnects from the BufferQueue. virtual void onDisconnect() {} /* Asynchronous */ // onFrameAvailable is called from queueBuffer each time an additional // frame becomes available for consumption. This means that frames that // are queued while in asynchronous mode only trigger the callback if no // previous frames are pending. Frames queued while in synchronous mode // always trigger the callback. The item passed to the callback will contain // all of the information about the queued frame except for its // GraphicBuffer pointer, which will always be null (except if the consumer // is SurfaceFlinger). // onFrameAvailable is called from queueBuffer each time an additional frame becomes available // for consumption. This means that frames that are queued while in asynchronous mode only // trigger the callback if no previous frames are pending. Frames queued while in synchronous // mode always trigger the callback. The item passed to the callback will contain all of the // information about the queued frame except for its GraphicBuffer pointer, which will always be // null (except if the consumer is SurfaceFlinger). // // This is called without any lock held and can be called concurrently // by multiple threads. // This is called without any lock held and can be called concurrently by multiple threads. virtual void onFrameAvailable(const BufferItem& item) = 0; /* Asynchronous */ // onFrameReplaced is called from queueBuffer if the frame being queued is // replacing an existing slot in the queue. Any call to queueBuffer that // doesn't call onFrameAvailable will call this callback instead. The item // passed to the callback will contain all of the information about the // queued frame except for its GraphicBuffer pointer, which will always be // null. // onFrameReplaced is called from queueBuffer if the frame being queued is replacing an existing // slot in the queue. Any call to queueBuffer that doesn't call onFrameAvailable will call this // callback instead. The item passed to the callback will contain all of the information about // the queued frame except for its GraphicBuffer pointer, which will always be null. // // This is called without any lock held and can be called concurrently // by multiple threads. // This is called without any lock held and can be called concurrently by multiple threads. virtual void onFrameReplaced(const BufferItem& /* item */) {} /* Asynchronous */ // onBuffersReleased is called to notify the buffer consumer that the // BufferQueue has released its references to one or more GraphicBuffers // contained in its slots. The buffer consumer should then call // BufferQueue::getReleasedBuffers to retrieve the list of buffers // onBuffersReleased is called to notify the buffer consumer that the BufferQueue has released // its references to one or more GraphicBuffers contained in its slots. The buffer consumer // should then call BufferQueue::getReleasedBuffers to retrieve the list of buffers. // // This is called without any lock held and can be called concurrently // by multiple threads. // This is called without any lock held and can be called concurrently by multiple threads. virtual void onBuffersReleased() = 0; /* Asynchronous */ // onSidebandStreamChanged is called to notify the buffer consumer that the // BufferQueue's sideband buffer stream has changed. This is called when a // stream is first attached and when it is either detached or replaced by a // different stream. // onSidebandStreamChanged is called to notify the buffer consumer that the BufferQueue's // sideband buffer stream has changed. This is called when a stream is first attached and when // it is either detached or replaced by a different stream. virtual void onSidebandStreamChanged() = 0; /* Asynchronous */ // Notifies the consumer of any new producer-side timestamps and // returns the combined frame history that hasn't already been retrieved. virtual void addAndGetFrameTimestamps( const NewFrameEventsEntry* /*newTimestamps*/, // Notifies the consumer of any new producer-side timestamps and returns the combined frame // history that hasn't already been retrieved. // // WARNING: This method can only be called when the BufferQueue is in the consumer's process. virtual void addAndGetFrameTimestamps(const NewFrameEventsEntry* /*newTimestamps*/, FrameEventHistoryDelta* /*outDelta*/) {} }; class IConsumerListener : public ConsumerListener, public IInterface { class IConsumerListener : public ConsumerListener, public IInterface { public: DECLARE_META_INTERFACE(ConsumerListener) }; // ---------------------------------------------------------------------------- class BnConsumerListener : public BnInterface<IConsumerListener> { class BnConsumerListener : public SafeBnInterface<IConsumerListener> { public: virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0); }; BnConsumerListener() : SafeBnInterface<IConsumerListener>("BnConsumerListener") {} // ---------------------------------------------------------------------------- }; // namespace android status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0) override; }; #endif // ANDROID_GUI_ICONSUMERLISTENER_H } // namespace android include/gui/ISurfaceComposerClient.h +0 −8 Original line number Diff line number Diff line Loading @@ -29,14 +29,6 @@ class ISurfaceComposerClient : public IInterface { public: DECLARE_META_INTERFACE(SurfaceComposerClient) enum class Tag : uint32_t { CreateSurface = IBinder::FIRST_CALL_TRANSACTION, DestroySurface, ClearLayerFrameStats, GetLayerFrameStats, Last, }; // flags for createSurface() enum { // (keep in sync with Surface.java) eHidden = 0x00000004, Loading libs/binder/include/binder/SafeInterface.h +10 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,16 @@ public: return callParcel("writeBool", [&]() { return parcel->writeBool(b); }); } template <typename T> typename std::enable_if<std::is_base_of<Flattenable<T>, T>::value, status_t>::type read( const Parcel& parcel, T* t) const { return callParcel("read(Flattenable)", [&]() { return parcel.read(*t); }); } template <typename T> typename std::enable_if<std::is_base_of<Flattenable<T>, T>::value, status_t>::type write( Parcel* parcel, const T& t) const { return callParcel("write(Flattenable)", [&]() { return parcel->write(t); }); } template <typename T> typename std::enable_if<std::is_base_of<LightFlattenable<T>, T>::value, status_t>::type read( const Parcel& parcel, T* t) const { return callParcel("read(LightFlattenable)", [&]() { return parcel.read(*t); }); Loading libs/binder/tests/binderSafeInterfaceTest.cpp +45 −0 Original line number Diff line number Diff line Loading @@ -65,6 +65,25 @@ private: uint8_t mPadding[4] = {}; // Avoids a warning from -Wpadded }; struct TestFlattenable : Flattenable<TestFlattenable> { TestFlattenable() = default; explicit TestFlattenable(int32_t v) : value(v) {} // Flattenable protocol size_t getFlattenedSize() const { return sizeof(value); } size_t getFdCount() const { return 0; } status_t flatten(void*& buffer, size_t& size, int*& /*fds*/, size_t& /*count*/) const { FlattenableUtils::write(buffer, size, value); return NO_ERROR; } status_t unflatten(void const*& buffer, size_t& size, int const*& /*fds*/, size_t& /*count*/) { FlattenableUtils::read(buffer, size, value); return NO_ERROR; } int32_t value = 0; }; struct TestLightFlattenable : LightFlattenablePod<TestLightFlattenable> { TestLightFlattenable() = default; explicit TestLightFlattenable(int32_t v) : value(v) {} Loading Loading @@ -142,6 +161,7 @@ public: SetDeathToken = IBinder::FIRST_CALL_TRANSACTION, ReturnsNoMemory, LogicalNot, IncrementFlattenable, IncrementLightFlattenable, IncrementNoCopyNoMove, ToUpper, Loading @@ -161,6 +181,7 @@ public: // These are ordered according to their corresponding methods in SafeInterface::ParcelHandler virtual status_t logicalNot(bool a, bool* notA) const = 0; virtual status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const = 0; virtual status_t increment(const TestLightFlattenable& a, TestLightFlattenable* aPlusOne) const = 0; virtual status_t increment(const NoCopyNoMove& a, NoCopyNoMove* aPlusOne) const = 0; Loading Loading @@ -192,6 +213,12 @@ public: ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__); return callRemote<decltype(&ISafeInterfaceTest::logicalNot)>(Tag::LogicalNot, a, notA); } status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const override { using Signature = status_t (ISafeInterfaceTest::*)(const TestFlattenable&, TestFlattenable*) const; ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__); return callRemote<Signature>(Tag::IncrementFlattenable, a, aPlusOne); } status_t increment(const TestLightFlattenable& a, TestLightFlattenable* aPlusOne) const override { using Signature = status_t (ISafeInterfaceTest::*)(const TestLightFlattenable&, Loading Loading @@ -263,6 +290,11 @@ public: *notA = !a; return NO_ERROR; } status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const override { ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__); aPlusOne->value = a.value + 1; return NO_ERROR; } status_t increment(const TestLightFlattenable& a, TestLightFlattenable* aPlusOne) const override { ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__); Loading Loading @@ -317,6 +349,11 @@ public: case ISafeInterfaceTest::Tag::LogicalNot: { return callLocal(data, reply, &ISafeInterfaceTest::logicalNot); } case ISafeInterfaceTest::Tag::IncrementFlattenable: { using Signature = status_t (ISafeInterfaceTest::*)(const TestFlattenable& a, TestFlattenable* aPlusOne) const; return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment); } case ISafeInterfaceTest::Tag::IncrementLightFlattenable: { using Signature = status_t (ISafeInterfaceTest::*)(const TestLightFlattenable& a, Loading Loading @@ -428,6 +465,14 @@ TEST_F(SafeInterfaceTest, TestLogicalNot) { ASSERT_EQ(!b, notB); } TEST_F(SafeInterfaceTest, TestIncrementFlattenable) { const TestFlattenable a{1}; TestFlattenable aPlusOne{0}; status_t result = mSafeInterfaceTest->increment(a, &aPlusOne); ASSERT_EQ(NO_ERROR, result); ASSERT_EQ(a.value + 1, aPlusOne.value); } TEST_F(SafeInterfaceTest, TestIncrementLightFlattenable) { const TestLightFlattenable a{1}; TestLightFlattenable aPlusOne{0}; Loading Loading
include/gui/GLConsumer.h +1 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <gui/BufferQueueDefs.h> #include <gui/ConsumerBase.h> #include <ui/FenceTime.h> #include <ui/GraphicBuffer.h> #include <utils/String8.h> Loading
include/gui/IConsumerListener.h +42 −61 Original line number Diff line number Diff line Loading @@ -14,28 +14,25 @@ * limitations under the License. */ #ifndef ANDROID_GUI_ICONSUMERLISTENER_H #define ANDROID_GUI_ICONSUMERLISTENER_H #pragma once #include <stdint.h> #include <sys/types.h> #include <binder/IInterface.h> #include <binder/SafeInterface.h> #include <utils/Errors.h> #include <utils/RefBase.h> #include <binder/IInterface.h> #include <gui/FrameTimestamps.h> #include <cstdint> namespace android { // ---------------------------------------------------------------------------- class BufferItem; class FrameEventHistoryDelta; struct NewFrameEventsEntry; // ConsumerListener is the interface through which the BufferQueue notifies // the consumer of events that the consumer may wish to react to. Because // the consumer will generally have a mutex that is locked during calls from // the consumer to the BufferQueue, these calls from the BufferQueue to the // ConsumerListener is the interface through which the BufferQueue notifies the consumer of events // that the consumer may wish to react to. Because the consumer will generally have a mutex that is // locked during calls from the consumer to the BufferQueue, these calls from the BufferQueue to the // consumer *MUST* be called only when the BufferQueue mutex is NOT locked. class ConsumerListener : public virtual RefBase { Loading @@ -46,71 +43,55 @@ public: // onDisconnect is called when a producer disconnects from the BufferQueue. virtual void onDisconnect() {} /* Asynchronous */ // onFrameAvailable is called from queueBuffer each time an additional // frame becomes available for consumption. This means that frames that // are queued while in asynchronous mode only trigger the callback if no // previous frames are pending. Frames queued while in synchronous mode // always trigger the callback. The item passed to the callback will contain // all of the information about the queued frame except for its // GraphicBuffer pointer, which will always be null (except if the consumer // is SurfaceFlinger). // onFrameAvailable is called from queueBuffer each time an additional frame becomes available // for consumption. This means that frames that are queued while in asynchronous mode only // trigger the callback if no previous frames are pending. Frames queued while in synchronous // mode always trigger the callback. The item passed to the callback will contain all of the // information about the queued frame except for its GraphicBuffer pointer, which will always be // null (except if the consumer is SurfaceFlinger). // // This is called without any lock held and can be called concurrently // by multiple threads. // This is called without any lock held and can be called concurrently by multiple threads. virtual void onFrameAvailable(const BufferItem& item) = 0; /* Asynchronous */ // onFrameReplaced is called from queueBuffer if the frame being queued is // replacing an existing slot in the queue. Any call to queueBuffer that // doesn't call onFrameAvailable will call this callback instead. The item // passed to the callback will contain all of the information about the // queued frame except for its GraphicBuffer pointer, which will always be // null. // onFrameReplaced is called from queueBuffer if the frame being queued is replacing an existing // slot in the queue. Any call to queueBuffer that doesn't call onFrameAvailable will call this // callback instead. The item passed to the callback will contain all of the information about // the queued frame except for its GraphicBuffer pointer, which will always be null. // // This is called without any lock held and can be called concurrently // by multiple threads. // This is called without any lock held and can be called concurrently by multiple threads. virtual void onFrameReplaced(const BufferItem& /* item */) {} /* Asynchronous */ // onBuffersReleased is called to notify the buffer consumer that the // BufferQueue has released its references to one or more GraphicBuffers // contained in its slots. The buffer consumer should then call // BufferQueue::getReleasedBuffers to retrieve the list of buffers // onBuffersReleased is called to notify the buffer consumer that the BufferQueue has released // its references to one or more GraphicBuffers contained in its slots. The buffer consumer // should then call BufferQueue::getReleasedBuffers to retrieve the list of buffers. // // This is called without any lock held and can be called concurrently // by multiple threads. // This is called without any lock held and can be called concurrently by multiple threads. virtual void onBuffersReleased() = 0; /* Asynchronous */ // onSidebandStreamChanged is called to notify the buffer consumer that the // BufferQueue's sideband buffer stream has changed. This is called when a // stream is first attached and when it is either detached or replaced by a // different stream. // onSidebandStreamChanged is called to notify the buffer consumer that the BufferQueue's // sideband buffer stream has changed. This is called when a stream is first attached and when // it is either detached or replaced by a different stream. virtual void onSidebandStreamChanged() = 0; /* Asynchronous */ // Notifies the consumer of any new producer-side timestamps and // returns the combined frame history that hasn't already been retrieved. virtual void addAndGetFrameTimestamps( const NewFrameEventsEntry* /*newTimestamps*/, // Notifies the consumer of any new producer-side timestamps and returns the combined frame // history that hasn't already been retrieved. // // WARNING: This method can only be called when the BufferQueue is in the consumer's process. virtual void addAndGetFrameTimestamps(const NewFrameEventsEntry* /*newTimestamps*/, FrameEventHistoryDelta* /*outDelta*/) {} }; class IConsumerListener : public ConsumerListener, public IInterface { class IConsumerListener : public ConsumerListener, public IInterface { public: DECLARE_META_INTERFACE(ConsumerListener) }; // ---------------------------------------------------------------------------- class BnConsumerListener : public BnInterface<IConsumerListener> { class BnConsumerListener : public SafeBnInterface<IConsumerListener> { public: virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0); }; BnConsumerListener() : SafeBnInterface<IConsumerListener>("BnConsumerListener") {} // ---------------------------------------------------------------------------- }; // namespace android status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0) override; }; #endif // ANDROID_GUI_ICONSUMERLISTENER_H } // namespace android
include/gui/ISurfaceComposerClient.h +0 −8 Original line number Diff line number Diff line Loading @@ -29,14 +29,6 @@ class ISurfaceComposerClient : public IInterface { public: DECLARE_META_INTERFACE(SurfaceComposerClient) enum class Tag : uint32_t { CreateSurface = IBinder::FIRST_CALL_TRANSACTION, DestroySurface, ClearLayerFrameStats, GetLayerFrameStats, Last, }; // flags for createSurface() enum { // (keep in sync with Surface.java) eHidden = 0x00000004, Loading
libs/binder/include/binder/SafeInterface.h +10 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,16 @@ public: return callParcel("writeBool", [&]() { return parcel->writeBool(b); }); } template <typename T> typename std::enable_if<std::is_base_of<Flattenable<T>, T>::value, status_t>::type read( const Parcel& parcel, T* t) const { return callParcel("read(Flattenable)", [&]() { return parcel.read(*t); }); } template <typename T> typename std::enable_if<std::is_base_of<Flattenable<T>, T>::value, status_t>::type write( Parcel* parcel, const T& t) const { return callParcel("write(Flattenable)", [&]() { return parcel->write(t); }); } template <typename T> typename std::enable_if<std::is_base_of<LightFlattenable<T>, T>::value, status_t>::type read( const Parcel& parcel, T* t) const { return callParcel("read(LightFlattenable)", [&]() { return parcel.read(*t); }); Loading
libs/binder/tests/binderSafeInterfaceTest.cpp +45 −0 Original line number Diff line number Diff line Loading @@ -65,6 +65,25 @@ private: uint8_t mPadding[4] = {}; // Avoids a warning from -Wpadded }; struct TestFlattenable : Flattenable<TestFlattenable> { TestFlattenable() = default; explicit TestFlattenable(int32_t v) : value(v) {} // Flattenable protocol size_t getFlattenedSize() const { return sizeof(value); } size_t getFdCount() const { return 0; } status_t flatten(void*& buffer, size_t& size, int*& /*fds*/, size_t& /*count*/) const { FlattenableUtils::write(buffer, size, value); return NO_ERROR; } status_t unflatten(void const*& buffer, size_t& size, int const*& /*fds*/, size_t& /*count*/) { FlattenableUtils::read(buffer, size, value); return NO_ERROR; } int32_t value = 0; }; struct TestLightFlattenable : LightFlattenablePod<TestLightFlattenable> { TestLightFlattenable() = default; explicit TestLightFlattenable(int32_t v) : value(v) {} Loading Loading @@ -142,6 +161,7 @@ public: SetDeathToken = IBinder::FIRST_CALL_TRANSACTION, ReturnsNoMemory, LogicalNot, IncrementFlattenable, IncrementLightFlattenable, IncrementNoCopyNoMove, ToUpper, Loading @@ -161,6 +181,7 @@ public: // These are ordered according to their corresponding methods in SafeInterface::ParcelHandler virtual status_t logicalNot(bool a, bool* notA) const = 0; virtual status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const = 0; virtual status_t increment(const TestLightFlattenable& a, TestLightFlattenable* aPlusOne) const = 0; virtual status_t increment(const NoCopyNoMove& a, NoCopyNoMove* aPlusOne) const = 0; Loading Loading @@ -192,6 +213,12 @@ public: ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__); return callRemote<decltype(&ISafeInterfaceTest::logicalNot)>(Tag::LogicalNot, a, notA); } status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const override { using Signature = status_t (ISafeInterfaceTest::*)(const TestFlattenable&, TestFlattenable*) const; ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__); return callRemote<Signature>(Tag::IncrementFlattenable, a, aPlusOne); } status_t increment(const TestLightFlattenable& a, TestLightFlattenable* aPlusOne) const override { using Signature = status_t (ISafeInterfaceTest::*)(const TestLightFlattenable&, Loading Loading @@ -263,6 +290,11 @@ public: *notA = !a; return NO_ERROR; } status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const override { ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__); aPlusOne->value = a.value + 1; return NO_ERROR; } status_t increment(const TestLightFlattenable& a, TestLightFlattenable* aPlusOne) const override { ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__); Loading Loading @@ -317,6 +349,11 @@ public: case ISafeInterfaceTest::Tag::LogicalNot: { return callLocal(data, reply, &ISafeInterfaceTest::logicalNot); } case ISafeInterfaceTest::Tag::IncrementFlattenable: { using Signature = status_t (ISafeInterfaceTest::*)(const TestFlattenable& a, TestFlattenable* aPlusOne) const; return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment); } case ISafeInterfaceTest::Tag::IncrementLightFlattenable: { using Signature = status_t (ISafeInterfaceTest::*)(const TestLightFlattenable& a, Loading Loading @@ -428,6 +465,14 @@ TEST_F(SafeInterfaceTest, TestLogicalNot) { ASSERT_EQ(!b, notB); } TEST_F(SafeInterfaceTest, TestIncrementFlattenable) { const TestFlattenable a{1}; TestFlattenable aPlusOne{0}; status_t result = mSafeInterfaceTest->increment(a, &aPlusOne); ASSERT_EQ(NO_ERROR, result); ASSERT_EQ(a.value + 1, aPlusOne.value); } TEST_F(SafeInterfaceTest, TestIncrementLightFlattenable) { const TestLightFlattenable a{1}; TestLightFlattenable aPlusOne{0}; Loading