OSDN Git Service

libgui: Make IConsumerListener a SafeInterface
authorDan Stoza <stoza@google.com>
Wed, 29 Mar 2017 00:05:13 +0000 (17:05 -0700)
committerDan Stoza <stoza@google.com>
Tue, 4 Apr 2017 23:12:26 +0000 (16:12 -0700)
Converts IConsumerListener to be a SafeInterface such that all
parceling/unparceling is done automatically.

Test: libgui_tests + manual testing
Change-Id: I1ed97f9802e320662cd29e181539ce839ffe0f3f

include/gui/IConsumerListener.h
libs/gui/IConsumerListener.cpp

index c1b4880..c082882 100644 (file)
  * limitations under the License.
  */
 
-#ifndef ANDROID_GUI_ICONSUMERLISTENER_H
-#define ANDROID_GUI_ICONSUMERLISTENER_H
-
-#include <gui/FrameTimestamps.h>
+#pragma once
 
 #include <binder/IInterface.h>
+#include <binder/SafeInterface.h>
 
 #include <utils/Errors.h>
 #include <utils/RefBase.h>
 
-#include <stdint.h>
-#include <sys/types.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
@@ -76,6 +75,8 @@ public:
 
     // 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*/) {}
 };
@@ -85,12 +86,12 @@ 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") {}
+
+    status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
+                        uint32_t flags = 0) override;
 };
 
 } // namespace android
-
-#endif // ANDROID_GUI_ICONSUMERLISTENER_H
index ff15205..85ac304 100644 (file)
 
 #include <gui/BufferItem.h>
 
-#include <binder/IInterface.h>
-#include <binder/Parcel.h>
-
-#include <stdint.h>
-#include <sys/types.h>
-
 namespace android {
 
-enum {
+namespace { // Anonymous
+
+enum class Tag : uint32_t {
     ON_DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
     ON_FRAME_AVAILABLE,
-    ON_BUFFER_RELEASED,
+    ON_FRAME_REPLACED,
+    ON_BUFFERS_RELEASED,
     ON_SIDEBAND_STREAM_CHANGED,
-    GET_FRAME_TIMESTAMPS
+    LAST = ON_SIDEBAND_STREAM_CHANGED,
 };
 
-class BpConsumerListener : public BpInterface<IConsumerListener> {
+} // Anonymous namespace
+
+class BpConsumerListener : public SafeBpInterface<IConsumerListener> {
 public:
-    explicit BpConsumerListener(const sp<IBinder>& impl) : BpInterface<IConsumerListener>(impl) {}
+    explicit BpConsumerListener(const sp<IBinder>& impl)
+          : SafeBpInterface<IConsumerListener>(impl, "BpConsumerListener") {}
+
+    ~BpConsumerListener() override;
+
+    void onDisconnect() override {
+        callRemoteAsync<decltype(&IConsumerListener::onDisconnect)>(Tag::ON_DISCONNECT);
+    }
 
-    virtual ~BpConsumerListener();
+    void onFrameAvailable(const BufferItem& item) override {
+        callRemoteAsync<decltype(&IConsumerListener::onFrameAvailable)>(Tag::ON_FRAME_AVAILABLE,
+                                                                        item);
+    }
 
-    virtual void onDisconnect() {
-        Parcel data, reply;
-        data.writeInterfaceToken(IConsumerListener::getInterfaceDescriptor());
-        remote()->transact(ON_DISCONNECT, data, &reply, IBinder::FLAG_ONEWAY);
+    void onFrameReplaced(const BufferItem& item) override {
+        callRemoteAsync<decltype(&IConsumerListener::onFrameReplaced)>(Tag::ON_FRAME_REPLACED,
+                                                                       item);
     }
 
-    virtual void onFrameAvailable(const BufferItem& item) {
-        Parcel data, reply;
-        data.writeInterfaceToken(IConsumerListener::getInterfaceDescriptor());
-        data.write(item);
-        remote()->transact(ON_FRAME_AVAILABLE, data, &reply, IBinder::FLAG_ONEWAY);
+    void onBuffersReleased() override {
+        callRemoteAsync<decltype(&IConsumerListener::onBuffersReleased)>(Tag::ON_BUFFERS_RELEASED);
     }
 
-    virtual void onBuffersReleased() {
-        Parcel data, reply;
-        data.writeInterfaceToken(IConsumerListener::getInterfaceDescriptor());
-        remote()->transact(ON_BUFFER_RELEASED, data, &reply, IBinder::FLAG_ONEWAY);
+    void onSidebandStreamChanged() override {
+        callRemoteAsync<decltype(&IConsumerListener::onSidebandStreamChanged)>(
+                Tag::ON_SIDEBAND_STREAM_CHANGED);
     }
 
-    virtual void onSidebandStreamChanged() {
-        Parcel data, reply;
-        data.writeInterfaceToken(IConsumerListener::getInterfaceDescriptor());
-        remote()->transact(ON_SIDEBAND_STREAM_CHANGED, data, &reply, IBinder::FLAG_ONEWAY);
+    void addAndGetFrameTimestamps(const NewFrameEventsEntry* /*newTimestamps*/,
+                                  FrameEventHistoryDelta* /*outDelta*/) override {
+        LOG_ALWAYS_FATAL("IConsumerListener::addAndGetFrameTimestamps cannot be proxied");
     }
 };
 
-// Out-of-line virtual method definition to trigger vtable emission in this translation unit (see
+// Out-of-line virtual method definitions to trigger vtable emission in this translation unit (see
 // clang warning -Wweak-vtables)
-BpConsumerListener::~BpConsumerListener() {}
+BpConsumerListener::~BpConsumerListener() = default;
+ConsumerListener::~ConsumerListener() = default;
 
 IMPLEMENT_META_INTERFACE(ConsumerListener, "android.gui.IConsumerListener");
 
 status_t BnConsumerListener::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
                                         uint32_t flags) {
-    switch (code) {
-        case ON_DISCONNECT: {
-            CHECK_INTERFACE(IConsumerListener, data, reply);
-            onDisconnect();
-            return NO_ERROR;
-        }
-        case ON_FRAME_AVAILABLE: {
-            CHECK_INTERFACE(IConsumerListener, data, reply);
-            BufferItem item;
-            data.read(item);
-            onFrameAvailable(item);
-            return NO_ERROR;
-        }
-        case ON_BUFFER_RELEASED: {
-            CHECK_INTERFACE(IConsumerListener, data, reply);
-            onBuffersReleased();
-            return NO_ERROR;
-        }
-        case ON_SIDEBAND_STREAM_CHANGED: {
-            CHECK_INTERFACE(IConsumerListener, data, reply);
-            onSidebandStreamChanged();
-            return NO_ERROR;
-        }
+    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_DISCONNECT:
+            return callLocalAsync(data, reply, &IConsumerListener::onDisconnect);
+        case Tag::ON_FRAME_AVAILABLE:
+            return callLocalAsync(data, reply, &IConsumerListener::onFrameAvailable);
+        case Tag::ON_FRAME_REPLACED:
+            return callLocalAsync(data, reply, &IConsumerListener::onFrameReplaced);
+        case Tag::ON_BUFFERS_RELEASED:
+            return callLocalAsync(data, reply, &IConsumerListener::onBuffersReleased);
+        case Tag::ON_SIDEBAND_STREAM_CHANGED:
+            return callLocalAsync(data, reply, &IConsumerListener::onSidebandStreamChanged);
     }
-    return BBinder::onTransact(code, data, reply, flags);
 }
 
-ConsumerListener::~ConsumerListener() = default;
-
 } // namespace android