Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ba55e0e5 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes I1ed97f98,I32449355,I5c84d6f2,Ib9652278,I73deaa44 into oc-dev

* changes:
  libgui: Make IConsumerListener a SafeInterface
  libgui: Format IConsumerListener
  libbinder: Support Flattenable in SafeInterface
  libgui: Add missing FenceTime header to GLConsumer
  libgui: Fix naming/enums in ISurfaceComposerClient
parents 77e270d0 c8ca12ae
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <gui/BufferQueueDefs.h>
#include <gui/ConsumerBase.h>

#include <ui/FenceTime.h>
#include <ui/GraphicBuffer.h>

#include <utils/String8.h>
+42 −61
Original line number Diff line number Diff line
@@ -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 {
@@ -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
+0 −8
Original line number Diff line number Diff line
@@ -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,
+10 −0
Original line number Diff line number Diff line
@@ -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); });
+45 −0
Original line number Diff line number Diff line
@@ -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) {}
@@ -142,6 +161,7 @@ public:
        SetDeathToken = IBinder::FIRST_CALL_TRANSACTION,
        ReturnsNoMemory,
        LogicalNot,
        IncrementFlattenable,
        IncrementLightFlattenable,
        IncrementNoCopyNoMove,
        ToUpper,
@@ -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;
@@ -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&,
@@ -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__);
@@ -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,
@@ -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