Eliminate unnecessary calls to onBufferReleased

This change adds a callback to ProducerListener to indicate whether the
listener needs the 'onBufferReleased' notification. This allows us to
avoid making that binder call unnecessarily, saving ~170us per frame on
Android Wear.

By default the new callback returns true, so behavior for existing
clients should be unchanged. Only the DummyProducerListener returns
false.

Also note that it would be simpler to just pass NULL for the
ProducerListener if not for that fact that we still need it for death
notification.

Bug: b/31122630

Change-Id: I730834218a055d89e89f876dd77da8127eb78000
diff --git a/libs/gui/IProducerListener.cpp b/libs/gui/IProducerListener.cpp
index 81adc95..da54ce1 100644
--- a/libs/gui/IProducerListener.cpp
+++ b/libs/gui/IProducerListener.cpp
@@ -22,6 +22,7 @@
 
 enum {
     ON_BUFFER_RELEASED = IBinder::FIRST_CALL_TRANSACTION,
+    NEEDS_RELEASE_NOTIFY,
 };
 
 class BpProducerListener : public BpInterface<IProducerListener>
@@ -37,6 +38,23 @@
         data.writeInterfaceToken(IProducerListener::getInterfaceDescriptor());
         remote()->transact(ON_BUFFER_RELEASED, data, &reply, IBinder::FLAG_ONEWAY);
     }
+
+    virtual bool needsReleaseNotify() {
+        bool result;
+        Parcel data, reply;
+        data.writeInterfaceToken(IProducerListener::getInterfaceDescriptor());
+        status_t err = remote()->transact(NEEDS_RELEASE_NOTIFY, data, &reply);
+        if (err != NO_ERROR) {
+            ALOGE("IProducerListener: binder call \'needsReleaseNotify\' failed");
+            return true;
+        }
+        err = reply.readBool(&result);
+        if (err != NO_ERROR) {
+            ALOGE("IProducerListener: malformed binder reply");
+            return true;
+        }
+        return result;
+    }
 };
 
 // Out-of-line virtual method definition to trigger vtable emission in this
@@ -52,8 +70,16 @@
             CHECK_INTERFACE(IProducerListener, data, reply);
             onBufferReleased();
             return NO_ERROR;
+        case NEEDS_RELEASE_NOTIFY:
+            CHECK_INTERFACE(IProducerListener, data, reply);
+            reply->writeBool(needsReleaseNotify());
+            return NO_ERROR;
     }
     return BBinder::onTransact(code, data, reply, flags);
 }
 
+bool BnProducerListener::needsReleaseNotify() {
+    return true;
+}
+
 } // namespace android