Migrate ITransactionCompletedListener to AIDL

This migrates the c++ interface to aidl.

Bug: 225250470
Test: atest libsurfaceflinger_unittest libgui_test SurfaceFlinger_test
Change-Id: I997e302ac8c6a23bedefaa5b8272677f3dce54df
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index a77ca04..a0e75ff 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -42,6 +42,7 @@
 
 namespace android {
 
+using gui::CallbackId;
 using gui::DisplayCaptureArgs;
 using gui::IDisplayEventConnection;
 using gui::IRegionSamplingListener;
diff --git a/libs/gui/ITransactionCompletedListener.cpp b/libs/gui/ITransactionCompletedListener.cpp
index 2b25b61..23d7d50 100644
--- a/libs/gui/ITransactionCompletedListener.cpp
+++ b/libs/gui/ITransactionCompletedListener.cpp
@@ -21,22 +21,11 @@
 #include <optional>
 
 #include <gui/ISurfaceComposer.h>
-#include <gui/ITransactionCompletedListener.h>
 #include <gui/LayerState.h>
+#include <gui/ListenerStats.h>
 #include <private/gui/ParcelUtils.h>
 
-namespace android {
-
-namespace { // Anonymous
-
-enum class Tag : uint32_t {
-    ON_TRANSACTION_COMPLETED = IBinder::FIRST_CALL_TRANSACTION,
-    ON_RELEASE_BUFFER,
-    ON_TRANSACTION_QUEUE_STALLED,
-    LAST = ON_TRANSACTION_QUEUE_STALLED,
-};
-
-} // Anonymous namespace
+namespace android::gui {
 
 status_t FrameEventHistoryStats::writeToParcel(Parcel* output) const {
     status_t err = output->writeUint64(frameNumber);
@@ -274,60 +263,6 @@
     return listenerStats;
 }
 
-class BpTransactionCompletedListener : public SafeBpInterface<ITransactionCompletedListener> {
-public:
-    explicit BpTransactionCompletedListener(const sp<IBinder>& impl)
-          : SafeBpInterface<ITransactionCompletedListener>(impl, "BpTransactionCompletedListener") {
-    }
-
-    ~BpTransactionCompletedListener() override;
-
-    void onTransactionCompleted(ListenerStats stats) override {
-        callRemoteAsync<decltype(&ITransactionCompletedListener::
-                                         onTransactionCompleted)>(Tag::ON_TRANSACTION_COMPLETED,
-                                                                  stats);
-    }
-
-    void onReleaseBuffer(ReleaseCallbackId callbackId, sp<Fence> releaseFence,
-                         uint32_t currentMaxAcquiredBufferCount) override {
-        callRemoteAsync<decltype(&ITransactionCompletedListener::
-                                         onReleaseBuffer)>(Tag::ON_RELEASE_BUFFER, callbackId,
-                                                           releaseFence,
-                                                           currentMaxAcquiredBufferCount);
-    }
-
-    void onTransactionQueueStalled(const String8& reason) override {
-        callRemoteAsync<
-                decltype(&ITransactionCompletedListener::
-                                 onTransactionQueueStalled)>(Tag::ON_TRANSACTION_QUEUE_STALLED,
-                                                             reason);
-    }
-};
-
-// Out-of-line virtual method definitions to trigger vtable emission in this translation unit (see
-// clang warning -Wweak-vtables)
-BpTransactionCompletedListener::~BpTransactionCompletedListener() = default;
-
-IMPLEMENT_META_INTERFACE(TransactionCompletedListener, "android.gui.ITransactionComposerListener");
-
-status_t BnTransactionCompletedListener::onTransact(uint32_t code, const Parcel& data,
-                                                    Parcel* reply, uint32_t flags) {
-    if (code < IBinder::FIRST_CALL_TRANSACTION || code > static_cast<uint32_t>(Tag::LAST)) {
-        return BBinder::onTransact(code, data, reply, flags);
-    }
-    auto tag = static_cast<Tag>(code);
-    switch (tag) {
-        case Tag::ON_TRANSACTION_COMPLETED:
-            return callLocalAsync(data, reply,
-                                  &ITransactionCompletedListener::onTransactionCompleted);
-        case Tag::ON_RELEASE_BUFFER:
-            return callLocalAsync(data, reply, &ITransactionCompletedListener::onReleaseBuffer);
-        case Tag::ON_TRANSACTION_QUEUE_STALLED:
-            return callLocalAsync(data, reply,
-                                  &ITransactionCompletedListener::onTransactionQueueStalled);
-    }
-}
-
 ListenerCallbacks ListenerCallbacks::filter(CallbackId::Type type) const {
     std::vector<CallbackId> filteredCallbackIds;
     for (const auto& callbackId : callbackIds) {
@@ -366,4 +301,4 @@
 
 const ReleaseCallbackId ReleaseCallbackId::INVALID_ID = ReleaseCallbackId(0, 0);
 
-}; // namespace android
+}; // namespace android::gui
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index 59b62fe..0d1a69b 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -51,6 +51,7 @@
 
 namespace android {
 
+using gui::CallbackId;
 using gui::FocusRequest;
 using gui::WindowInfoHandle;
 
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 7085e8a..d741c99 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -314,7 +314,8 @@
     }
 }
 
-void TransactionCompletedListener::onTransactionCompleted(ListenerStats listenerStats) {
+binder::Status TransactionCompletedListener::onTransactionCompleted(
+        const ListenerStats& listenerStats) {
     std::unordered_map<CallbackId, CallbackTranslation, CallbackIdHash> callbacksMap;
     std::multimap<int32_t, sp<JankDataListener>> jankListenersMap;
     {
@@ -454,9 +455,10 @@
             }
         }
     }
+    return binder::Status::ok();
 }
 
-void TransactionCompletedListener::onTransactionQueueStalled(const String8& reason) {
+binder::Status TransactionCompletedListener::onTransactionQueueStalled(const std::string& reason) {
     std::unordered_map<void*, std::function<void(const std::string&)>> callbackCopy;
     {
         std::scoped_lock<std::mutex> lock(mMutex);
@@ -465,6 +467,7 @@
     for (auto const& it : callbackCopy) {
         it.second(reason.c_str());
     }
+    return binder::Status::ok();
 }
 
 void TransactionCompletedListener::addQueueStallListener(
@@ -478,9 +481,12 @@
     mQueueStallListeners.erase(id);
 }
 
-void TransactionCompletedListener::onReleaseBuffer(ReleaseCallbackId callbackId,
-                                                   sp<Fence> releaseFence,
-                                                   uint32_t currentMaxAcquiredBufferCount) {
+binder::Status TransactionCompletedListener::onReleaseBuffer(
+        const ReleaseCallbackId& callbackId,
+        const std::optional<os::ParcelFileDescriptor>& releaseFenceFd,
+        int32_t currentMaxAcquiredBufferCount) {
+    sp<Fence> releaseFence(releaseFenceFd ? new Fence(::dup(releaseFenceFd->get()))
+                                          : Fence::NO_FENCE);
     ReleaseBufferCallback callback;
     {
         std::scoped_lock<std::mutex> lock(mMutex);
@@ -489,13 +495,14 @@
     if (!callback) {
         ALOGE("Could not call release buffer callback, buffer not found %s",
               callbackId.to_string().c_str());
-        return;
+        return binder::Status::fromExceptionCode(binder::Status::EX_ILLEGAL_ARGUMENT);
     }
     std::optional<uint32_t> optionalMaxAcquiredBufferCount =
-            currentMaxAcquiredBufferCount == UINT_MAX
+            static_cast<uint32_t>(currentMaxAcquiredBufferCount) == UINT_MAX
             ? std::nullopt
             : std::make_optional<uint32_t>(currentMaxAcquiredBufferCount);
     callback(callbackId, releaseFence, optionalMaxAcquiredBufferCount);
+    return binder::Status::ok();
 }
 
 ReleaseBufferCallback TransactionCompletedListener::popReleaseBufferCallbackLocked(
@@ -825,7 +832,11 @@
                 ->mReleaseCallbackThread
                 .addReleaseCallback(state.bufferData->generateReleaseCallbackId(), fence);
     } else {
-        listener->onReleaseBuffer(state.bufferData->generateReleaseCallbackId(), fence, UINT_MAX);
+        std::optional<os::ParcelFileDescriptor> fenceFd;
+        if (fence != Fence::NO_FENCE) {
+            fenceFd = os::ParcelFileDescriptor(base::unique_fd(::dup(fence->get())));
+        }
+        listener->onReleaseBuffer(state.bufferData->generateReleaseCallbackId(), fenceFd, UINT_MAX);
     }
 }
 
@@ -2846,7 +2857,11 @@
 
         while (!callbackInfos.empty()) {
             auto [callbackId, releaseFence] = callbackInfos.front();
-            listener->onReleaseBuffer(callbackId, std::move(releaseFence), UINT_MAX);
+            std::optional<os::ParcelFileDescriptor> fenceFd;
+            if (releaseFence != Fence::NO_FENCE) {
+                fenceFd = os::ParcelFileDescriptor(base::unique_fd(::dup(releaseFence->get())));
+            }
+            listener->onReleaseBuffer(callbackId, fenceFd, UINT_MAX);
             callbackInfos.pop();
         }
 
diff --git a/libs/gui/aidl/android/gui/ITransactionCompletedListener.aidl b/libs/gui/aidl/android/gui/ITransactionCompletedListener.aidl
new file mode 100644
index 0000000..dde4d38
--- /dev/null
+++ b/libs/gui/aidl/android/gui/ITransactionCompletedListener.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2022 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.
+ */
+
+package android.gui;
+
+import android.gui.ListenerStats;
+import android.gui.ReleaseCallbackId;
+
+/** @hide */
+oneway interface ITransactionCompletedListener {
+   void onTransactionCompleted(in ListenerStats stats);
+
+   void onReleaseBuffer(in ReleaseCallbackId callbackId,
+                        in @nullable ParcelFileDescriptor releaseFenceFd,
+                        int currentMaxAcquiredBufferCount);
+
+   void onTransactionQueueStalled(@utf8InCpp String name);
+}
diff --git a/libs/gui/aidl/android/gui/ListenerStats.aidl b/libs/gui/aidl/android/gui/ListenerStats.aidl
new file mode 100644
index 0000000..63248b2
--- /dev/null
+++ b/libs/gui/aidl/android/gui/ListenerStats.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2022 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.
+ */
+
+package android.gui;
+
+parcelable ListenerStats cpp_header "gui/ListenerStats.h";
diff --git a/libs/gui/aidl/android/gui/ReleaseCallbackId.aidl b/libs/gui/aidl/android/gui/ReleaseCallbackId.aidl
new file mode 100644
index 0000000..c86de34
--- /dev/null
+++ b/libs/gui/aidl/android/gui/ReleaseCallbackId.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2022 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.
+ */
+
+package android.gui;
+
+parcelable ReleaseCallbackId cpp_header "gui/ReleaseCallbackId.h";
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index d517e99..d70a7f0 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -23,11 +23,11 @@
 #include <android/gui/IHdrLayerInfoListener.h>
 #include <android/gui/IRegionSamplingListener.h>
 #include <android/gui/IScreenCaptureListener.h>
+#include <android/gui/ITransactionCompletedListener.h>
 #include <android/gui/ITunnelModeEnabledListener.h>
 #include <android/gui/IWindowInfosListener.h>
 #include <binder/IBinder.h>
 #include <binder/IInterface.h>
-#include <gui/ITransactionCompletedListener.h>
 #include <gui/SpHash.h>
 #include <math/vec4.h>
 #include <stdint.h>
@@ -66,6 +66,7 @@
 using gui::IDisplayEventConnection;
 using gui::IRegionSamplingListener;
 using gui::IScreenCaptureListener;
+using gui::ListenerCallbacks;
 using gui::SpHash;
 
 namespace gui {
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index 45a84f6..c5fdf82 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -21,10 +21,10 @@
 #include <stdint.h>
 #include <sys/types.h>
 
+#include <android/gui/ITransactionCompletedListener.h>
 #include <android/gui/IWindowInfosReportedListener.h>
 #include <android/native_window.h>
 #include <gui/IGraphicBufferProducer.h>
-#include <gui/ITransactionCompletedListener.h>
 #include <math/mat4.h>
 
 #include <android/gui/DropInputMode.h>
@@ -35,6 +35,7 @@
 #include <gui/ISurfaceComposer.h>
 #include <gui/LayerCaptureArgs.h>
 #include <gui/LayerMetadata.h>
+#include <gui/ReleaseCallbackId.h>
 #include <gui/SpHash.h>
 #include <gui/SurfaceControl.h>
 #include <gui/WindowInfo.h>
@@ -56,6 +57,9 @@
 using gui::ISurfaceComposerClient;
 using gui::LayerMetadata;
 
+using gui::ITransactionCompletedListener;
+using gui::ReleaseCallbackId;
+
 struct client_cache_t {
     wp<IBinder> token = nullptr;
     uint64_t id;
diff --git a/libs/gui/include/gui/ITransactionCompletedListener.h b/libs/gui/include/gui/ListenerStats.h
similarity index 81%
rename from libs/gui/include/gui/ITransactionCompletedListener.h
rename to libs/gui/include/gui/ListenerStats.h
index 453e8f3..3a12802 100644
--- a/libs/gui/include/gui/ITransactionCompletedListener.h
+++ b/libs/gui/include/gui/ListenerStats.h
@@ -24,6 +24,8 @@
 #include <binder/SafeInterface.h>
 
 #include <gui/FrameTimestamps.h>
+#include <gui/ReleaseCallbackId.h>
+
 #include <ui/Fence.h>
 #include <utils/Timers.h>
 
@@ -32,10 +34,7 @@
 #include <unordered_set>
 #include <variant>
 
-namespace android {
-
-class ITransactionCompletedListener;
-class ListenerCallbacks;
+namespace android::gui {
 
 class CallbackId : public Parcelable {
 public:
@@ -54,30 +53,6 @@
     std::size_t operator()(const CallbackId& key) const { return std::hash<int64_t>()(key.id); }
 };
 
-class ReleaseCallbackId : public Parcelable {
-public:
-    static const ReleaseCallbackId INVALID_ID;
-
-    uint64_t bufferId;
-    uint64_t framenumber;
-    ReleaseCallbackId() {}
-    ReleaseCallbackId(uint64_t bufferId, uint64_t framenumber)
-          : bufferId(bufferId), framenumber(framenumber) {}
-    status_t writeToParcel(Parcel* output) const override;
-    status_t readFromParcel(const Parcel* input) override;
-
-    bool operator==(const ReleaseCallbackId& rhs) const {
-        return bufferId == rhs.bufferId && framenumber == rhs.framenumber;
-    }
-    bool operator!=(const ReleaseCallbackId& rhs) const { return !operator==(rhs); }
-    std::string to_string() const {
-        if (*this == INVALID_ID) return "INVALID_ID";
-
-        return "bufferId:" + std::to_string(bufferId) +
-                " framenumber:" + std::to_string(framenumber);
-    }
-};
-
 struct ReleaseBufferCallbackIdHash {
     std::size_t operator()(const ReleaseCallbackId& key) const {
         return std::hash<uint64_t>()(key.bufferId);
@@ -186,27 +161,6 @@
     std::vector<TransactionStats> transactionStats;
 };
 
-class ITransactionCompletedListener : public IInterface {
-public:
-    DECLARE_META_INTERFACE(TransactionCompletedListener)
-
-    virtual void onTransactionCompleted(ListenerStats stats) = 0;
-
-    virtual void onReleaseBuffer(ReleaseCallbackId callbackId, sp<Fence> releaseFence,
-                                 uint32_t currentMaxAcquiredBufferCount) = 0;
-
-    virtual void onTransactionQueueStalled(const String8& name) = 0;
-};
-
-class BnTransactionCompletedListener : public SafeBnInterface<ITransactionCompletedListener> {
-public:
-    BnTransactionCompletedListener()
-          : SafeBnInterface<ITransactionCompletedListener>("BnTransactionCompletedListener") {}
-
-    status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
-                        uint32_t flags = 0) override;
-};
-
 class ListenerCallbacks {
 public:
     ListenerCallbacks(const sp<IBinder>& listener,
@@ -268,4 +222,4 @@
     }
 };
 
-} // namespace android
+} // namespace android::gui
diff --git a/libs/gui/include/gui/ReleaseCallbackId.h b/libs/gui/include/gui/ReleaseCallbackId.h
new file mode 100644
index 0000000..142ee5a
--- /dev/null
+++ b/libs/gui/include/gui/ReleaseCallbackId.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2022 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.
+ */
+
+#pragma once
+
+#include <binder/Parcel.h>
+#include <binder/Parcelable.h>
+
+#include <cstdint>
+
+namespace android::gui {
+
+class ReleaseCallbackId : public Parcelable {
+public:
+    static const ReleaseCallbackId INVALID_ID;
+
+    uint64_t bufferId;
+    uint64_t framenumber;
+    ReleaseCallbackId() {}
+    ReleaseCallbackId(uint64_t bufferId, uint64_t framenumber)
+          : bufferId(bufferId), framenumber(framenumber) {}
+    status_t writeToParcel(Parcel* output) const override;
+    status_t readFromParcel(const Parcel* input) override;
+
+    bool operator==(const ReleaseCallbackId& rhs) const {
+        return bufferId == rhs.bufferId && framenumber == rhs.framenumber;
+    }
+    bool operator!=(const ReleaseCallbackId& rhs) const { return !operator==(rhs); }
+    std::string to_string() const {
+        if (*this == INVALID_ID) return "INVALID_ID";
+
+        return "bufferId:" + std::to_string(bufferId) +
+                " framenumber:" + std::to_string(framenumber);
+    }
+};
+
+} // namespace android::gui
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index df47002..96d3a23 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -42,10 +42,13 @@
 
 #include <android/gui/ISurfaceComposerClient.h>
 
+#include <android/gui/BnTransactionCompletedListener.h>
+
 #include <gui/CpuConsumer.h>
 #include <gui/ISurfaceComposer.h>
-#include <gui/ITransactionCompletedListener.h>
 #include <gui/LayerState.h>
+#include <gui/ListenerStats.h>
+#include <gui/ReleaseCallbackId.h>
 #include <gui/SurfaceControl.h>
 #include <gui/WindowInfosListenerReporter.h>
 #include <math/vec3.h>
@@ -59,11 +62,21 @@
 class ITunnelModeEnabledListener;
 class Region;
 
+using gui::BnTransactionCompletedListener;
+using gui::CallbackId;
+using gui::CallbackIdHash;
 using gui::DisplayCaptureArgs;
+using gui::FrameEventHistoryStats;
 using gui::IRegionSamplingListener;
 using gui::ISurfaceComposerClient;
+using gui::ITransactionCompletedListener;
+using gui::JankData;
 using gui::LayerCaptureArgs;
 using gui::LayerMetadata;
+using gui::ListenerStats;
+using gui::ReleaseBufferCallbackIdHash;
+using gui::ReleaseCallbackId;
+using gui::SurfaceStats;
 
 struct SurfaceControlStats {
     SurfaceControlStats(const sp<SurfaceControl>& sc, nsecs_t latchTime,
@@ -825,17 +838,17 @@
     void setReleaseBufferCallback(const ReleaseCallbackId&, ReleaseBufferCallback);
 
     // BnTransactionCompletedListener overrides
-    void onTransactionCompleted(ListenerStats stats) override;
-    void onReleaseBuffer(ReleaseCallbackId, sp<Fence> releaseFence,
-                         uint32_t currentMaxAcquiredBufferCount) override;
+    binder::Status onTransactionCompleted(const ListenerStats& stats) override;
+    binder::Status onReleaseBuffer(const ReleaseCallbackId& callbackId,
+                                   const std::optional<os::ParcelFileDescriptor>& releaseFenceFd,
+                                   int32_t currentMaxAcquiredBufferCount) override;
+    binder::Status onTransactionQueueStalled(const std::string& reason) override;
 
     void removeReleaseBufferCallback(const ReleaseCallbackId& callbackId);
 
     // For Testing Only
     static void setInstance(const sp<TransactionCompletedListener>&);
 
-    void onTransactionQueueStalled(const String8& reason) override;
-
 private:
     ReleaseBufferCallback popReleaseBufferCallbackLocked(const ReleaseCallbackId&);
     static sp<TransactionCompletedListener> sInstance;