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

Commit e2ffb426 authored by Marissa Wall's avatar Marissa Wall
Browse files

blast: Send transaction callback

Send transaction callback to client via the
TransactionCompletedListener.

Test: Transaction_test
Bug: 80477568

Change-Id: Iac98780b1357b9cc54b93cc3c848013b28fab441
parent c837b5ec
Loading
Loading
Loading
Loading
+72 −3
Original line number Original line Diff line number Diff line
@@ -30,6 +30,74 @@ enum class Tag : uint32_t {


} // Anonymous namespace
} // Anonymous namespace


status_t SurfaceStats::writeToParcel(Parcel* output) const {
    return output->writeStrongBinder(surfaceControl);
}

status_t SurfaceStats::readFromParcel(const Parcel* input) {
    return input->readStrongBinder(&surfaceControl);
}

status_t TransactionStats::writeToParcel(Parcel* output) const {
    return output->writeParcelableVector(surfaceStats);
}

status_t TransactionStats::readFromParcel(const Parcel* input) {
    return input->readParcelableVector(&surfaceStats);
}

status_t ListenerStats::writeToParcel(Parcel* output) const {
    status_t err = output->writeInt32(static_cast<int32_t>(transactionStats.size()));
    if (err != NO_ERROR) {
        return err;
    }

    for (const auto& [callbackIds, stats] : transactionStats) {
        err = output->writeParcelable(stats);
        if (err != NO_ERROR) {
            return err;
        }
        err = output->writeInt64Vector(callbackIds);
        if (err != NO_ERROR) {
            return err;
        }
    }
    return NO_ERROR;
}

status_t ListenerStats::readFromParcel(const Parcel* input) {
    int32_t transactionStats_size = input->readInt32();

    for (int i = 0; i < transactionStats_size; i++) {
        TransactionStats stats;
        std::vector<CallbackId> callbackIds;

        status_t err = input->readParcelable(&stats);
        if (err != NO_ERROR) {
            return err;
        }
        err = input->readInt64Vector(&callbackIds);
        if (err != NO_ERROR) {
            return err;
        }

        transactionStats.emplace(callbackIds, stats);
    }
    return NO_ERROR;
}

ListenerStats ListenerStats::createEmpty(const sp<ITransactionCompletedListener>& listener,
                                         const std::unordered_set<CallbackId>& callbackIds) {
    ListenerStats listenerStats;
    listenerStats.listener = listener;
    TransactionStats transactionStats;
    listenerStats.transactionStats.emplace(std::piecewise_construct,
                                           std::forward_as_tuple(callbackIds.begin(),
                                                                 callbackIds.end()),
                                           std::forward_as_tuple(transactionStats));
    return listenerStats;
}

class BpTransactionCompletedListener : public SafeBpInterface<ITransactionCompletedListener> {
class BpTransactionCompletedListener : public SafeBpInterface<ITransactionCompletedListener> {
public:
public:
    explicit BpTransactionCompletedListener(const sp<IBinder>& impl)
    explicit BpTransactionCompletedListener(const sp<IBinder>& impl)
@@ -38,9 +106,10 @@ public:


    ~BpTransactionCompletedListener() override;
    ~BpTransactionCompletedListener() override;


    void onTransactionCompleted() override {
    void onTransactionCompleted(ListenerStats stats) override {
        callRemoteAsync<decltype(&ITransactionCompletedListener::onTransactionCompleted)>(
        callRemoteAsync<decltype(&ITransactionCompletedListener::
                Tag::ON_TRANSACTION_COMPLETED);
                                         onTransactionCompleted)>(Tag::ON_TRANSACTION_COMPLETED,
                                                                  stats);
    }
    }
};
};


+23 −6
Original line number Original line Diff line number Diff line
@@ -128,8 +128,7 @@ void TransactionCompletedListener::startListeningLocked() {
    mListening = true;
    mListening = true;
}
}


CallbackId TransactionCompletedListener::addCallback(
CallbackId TransactionCompletedListener::addCallback(const TransactionCompletedCallback& callback) {
        const TransactionCompletedCallbackWithContext& callback) {
    std::lock_guard<std::mutex> lock(mMutex);
    std::lock_guard<std::mutex> lock(mMutex);
    startListeningLocked();
    startListeningLocked();


@@ -138,8 +137,20 @@ CallbackId TransactionCompletedListener::addCallback(
    return callbackId;
    return callbackId;
}
}


void TransactionCompletedListener::onTransactionCompleted() {
void TransactionCompletedListener::onTransactionCompleted(ListenerStats listenerStats) {
    return;
    std::lock_guard lock(mMutex);

    for (const auto& [callbackIds, transactionStats] : listenerStats.transactionStats) {
        for (auto callbackId : callbackIds) {
            const auto& callback = mCallbacks[callbackId];
            if (!callback) {
                ALOGE("cannot call null callback function, skipping");
                continue;
            }
            callback(transactionStats);
            mCallbacks.erase(callbackId);
        }
    }
}
}


// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
@@ -201,6 +212,12 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous) {
            continue;
            continue;
        }
        }


        // If the listener does not have any SurfaceControls set on this Transaction, send the
        // callback now
        if (surfaceControls.empty()) {
            listener->onTransactionCompleted(ListenerStats::createEmpty(listener, callbackIds));
        }

        // If the listener has any SurfaceControls set on this Transaction update the surface state
        // If the listener has any SurfaceControls set on this Transaction update the surface state
        for (const auto& surfaceControl : surfaceControls) {
        for (const auto& surfaceControl : surfaceControls) {
            layer_state_t* s = getLayerState(surfaceControl);
            layer_state_t* s = getLayerState(surfaceControl);
@@ -676,10 +693,10 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setSideb


SurfaceComposerClient::Transaction&
SurfaceComposerClient::Transaction&
SurfaceComposerClient::Transaction::addTransactionCompletedCallback(
SurfaceComposerClient::Transaction::addTransactionCompletedCallback(
        TransactionCompletedCallback callback, void* callbackContext) {
        TransactionCompletedCallbackTakesContext callback, void* callbackContext) {
    auto listener = TransactionCompletedListener::getInstance();
    auto listener = TransactionCompletedListener::getInstance();


    auto callbackWithContext = std::bind(callback, callbackContext);
    auto callbackWithContext = std::bind(callback, callbackContext, std::placeholders::_1);


    CallbackId callbackId = listener->addCallback(callbackWithContext);
    CallbackId callbackId = listener->addCallback(callbackWithContext);


+53 −3
Original line number Original line Diff line number Diff line
@@ -17,18 +17,70 @@
#pragma once
#pragma once


#include <binder/IInterface.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>
#include <binder/Parcelable.h>
#include <binder/SafeInterface.h>
#include <binder/SafeInterface.h>


#include <utils/Timers.h>

#include <cstdint>
#include <cstdint>
#include <unordered_map>
#include <unordered_set>
#include <unordered_set>


namespace android {
namespace android {


class ITransactionCompletedListener;

using CallbackId = int64_t;

struct CallbackIdsHash {
    // CallbackId vectors have several properties that let us get away with this simple hash.
    // 1) CallbackIds are never 0 so if something has gone wrong and our CallbackId vector is
    // empty we can still hash 0.
    // 2) CallbackId vectors for the same listener either are identical or contain none of the
    // same members. It is sufficient to just check the first CallbackId in the vectors. If
    // they match, they are the same. If they do not match, they are not the same.
    std::size_t operator()(const std::vector<CallbackId> callbackIds) const {
        return std::hash<CallbackId>{}((callbackIds.size() == 0) ? 0 : callbackIds.front());
    }
};

class SurfaceStats : public Parcelable {
public:
    status_t writeToParcel(Parcel* output) const override;
    status_t readFromParcel(const Parcel* input) override;

    SurfaceStats() = default;
    explicit SurfaceStats(const sp<IBinder>& sc) : surfaceControl(sc) {}

    sp<IBinder> surfaceControl;
};

class TransactionStats : public Parcelable {
public:
    status_t writeToParcel(Parcel* output) const override;
    status_t readFromParcel(const Parcel* input) override;

    std::vector<SurfaceStats> surfaceStats;
};

class ListenerStats : public Parcelable {
public:
    status_t writeToParcel(Parcel* output) const override;
    status_t readFromParcel(const Parcel* input) override;

    static ListenerStats createEmpty(const sp<ITransactionCompletedListener>& listener,
                                     const std::unordered_set<CallbackId>& callbackIds);

    sp<ITransactionCompletedListener> listener;
    std::unordered_map<std::vector<CallbackId>, TransactionStats, CallbackIdsHash> transactionStats;
};

class ITransactionCompletedListener : public IInterface {
class ITransactionCompletedListener : public IInterface {
public:
public:
    DECLARE_META_INTERFACE(TransactionCompletedListener)
    DECLARE_META_INTERFACE(TransactionCompletedListener)


    virtual void onTransactionCompleted() = 0;
    virtual void onTransactionCompleted(ListenerStats stats) = 0;
};
};


class BnTransactionCompletedListener : public SafeBnInterface<ITransactionCompletedListener> {
class BnTransactionCompletedListener : public SafeBnInterface<ITransactionCompletedListener> {
@@ -40,8 +92,6 @@ public:
                        uint32_t flags = 0) override;
                        uint32_t flags = 0) override;
};
};


using CallbackId = int64_t;

class ListenerCallbacks {
class ListenerCallbacks {
public:
public:
    ListenerCallbacks(const sp<ITransactionCompletedListener>& listener,
    ListenerCallbacks(const sp<ITransactionCompletedListener>& listener,
+8 −7
Original line number Original line Diff line number Diff line
@@ -52,8 +52,9 @@ class Region;


// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------


using TransactionCompletedCallback = std::function<void(void* /*context*/)>;
using TransactionCompletedCallbackTakesContext =
using TransactionCompletedCallbackWithContext = std::function<void()>;
        std::function<void(void* /*context*/, const TransactionStats&)>;
using TransactionCompletedCallback = std::function<void(const TransactionStats&)>;


class TransactionCompletedListener : public BnTransactionCompletedListener {
class TransactionCompletedListener : public BnTransactionCompletedListener {
    TransactionCompletedListener();
    TransactionCompletedListener();
@@ -66,7 +67,7 @@ class TransactionCompletedListener : public BnTransactionCompletedListener {


    CallbackId mCallbackIdCounter GUARDED_BY(mMutex) = 1;
    CallbackId mCallbackIdCounter GUARDED_BY(mMutex) = 1;


    std::map<CallbackId, TransactionCompletedCallbackWithContext> mCallbacks GUARDED_BY(mMutex);
    std::map<CallbackId, TransactionCompletedCallback> mCallbacks GUARDED_BY(mMutex);


public:
public:
    static sp<TransactionCompletedListener> getInstance();
    static sp<TransactionCompletedListener> getInstance();
@@ -74,10 +75,10 @@ public:


    void startListeningLocked() REQUIRES(mMutex);
    void startListeningLocked() REQUIRES(mMutex);


    CallbackId addCallback(const TransactionCompletedCallbackWithContext& callback);
    CallbackId addCallback(const TransactionCompletedCallback& callback);


    // Overrides BnTransactionCompletedListener's onTransactionCompleted
    // Overrides BnTransactionCompletedListener's onTransactionCompleted
    void onTransactionCompleted() override;
    void onTransactionCompleted(ListenerStats stats) override;
};
};


// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
@@ -303,8 +304,8 @@ public:
        Transaction& setSidebandStream(const sp<SurfaceControl>& sc,
        Transaction& setSidebandStream(const sp<SurfaceControl>& sc,
                                       const sp<NativeHandle>& sidebandStream);
                                       const sp<NativeHandle>& sidebandStream);


        Transaction& addTransactionCompletedCallback(TransactionCompletedCallback callback,
        Transaction& addTransactionCompletedCallback(
                                                     void* callbackContext);
                TransactionCompletedCallbackTakesContext callback, void* callbackContext);


        // Detaches all child surfaces (and their children recursively)
        // Detaches all child surfaces (and their children recursively)
        // from their SurfaceControl.
        // from their SurfaceControl.
+1 −0
Original line number Original line Diff line number Diff line
@@ -153,6 +153,7 @@ filegroup {
        "SurfaceInterceptor.cpp",
        "SurfaceInterceptor.cpp",
        "SurfaceTracing.cpp",
        "SurfaceTracing.cpp",
        "TimeStats/TimeStats.cpp",
        "TimeStats/TimeStats.cpp",
        "TransactionCompletedThread.cpp",
    ],
    ],
}
}


Loading