Disable buffer dropping from BufferQueueProducer

Disable legacy buffer dropping behavior from app targetted Android Q or
above.

Bug: 130039639
Change-Id: I492a41495f011309910f6e79ff566228d43ff35b
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 2ca5eee..e56750b 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -1110,6 +1110,9 @@
             reset();
         }
         if (!isResourceError(err)) {
+            if (err == OK) {
+                disableLegacyBufferDropPostQ(surface);
+            }
             break;
         }
     }
@@ -1175,7 +1178,11 @@
     msg->setObject("surface", surface);
 
     sp<AMessage> response;
-    return PostAndAwaitResponse(msg, &response);
+    status_t result = PostAndAwaitResponse(msg, &response);
+    if (result == OK) {
+        disableLegacyBufferDropPostQ(surface);
+    }
+    return result;
 }
 
 status_t MediaCodec::createInputSurface(
diff --git a/media/libstagefright/SurfaceUtils.cpp b/media/libstagefright/SurfaceUtils.cpp
index 9e11a94..4c94baa 100644
--- a/media/libstagefright/SurfaceUtils.cpp
+++ b/media/libstagefright/SurfaceUtils.cpp
@@ -18,10 +18,13 @@
 #define LOG_TAG "SurfaceUtils"
 #include <utils/Log.h>
 
+#include <android/api-level.h>
 #include <media/hardware/VideoAPI.h>
 #include <media/stagefright/SurfaceUtils.h>
 #include <gui/Surface.h>
 
+extern "C" int android_get_application_target_sdk_version();
+
 namespace android {
 
 status_t setNativeWindowSizeFormatAndUsage(
@@ -291,5 +294,28 @@
 
     return err;
 }
+
+status_t disableLegacyBufferDropPostQ(const sp<Surface> &surface) {
+    sp<IGraphicBufferProducer> igbp =
+            surface ? surface->getIGraphicBufferProducer() : nullptr;
+    if (igbp) {
+        int targetSdk = android_get_application_target_sdk_version();
+        // When the caller is not an app (e.g. MediaPlayer in mediaserver)
+        // targetSdk is __ANDROID_API_FUTURE__.
+        bool drop =
+                targetSdk < __ANDROID_API_Q__ ||
+                targetSdk == __ANDROID_API_FUTURE__;
+        if (!drop) {
+            status_t err = igbp->setLegacyBufferDrop(false);
+            if (err == NO_ERROR) {
+                ALOGD("legacy buffer drop disabled: target sdk (%d)",
+                      targetSdk);
+            } else {
+                ALOGD("disabling legacy buffer drop failed: %d", err);
+            }
+        }
+    }
+    return NO_ERROR;
+}
 }  // namespace android
 
diff --git a/media/libstagefright/include/media/stagefright/SurfaceUtils.h b/media/libstagefright/include/media/stagefright/SurfaceUtils.h
index 689e458..ae55c65 100644
--- a/media/libstagefright/include/media/stagefright/SurfaceUtils.h
+++ b/media/libstagefright/include/media/stagefright/SurfaceUtils.h
@@ -19,8 +19,10 @@
 #define SURFACE_UTILS_H_
 
 #include <utils/Errors.h>
+#include <utils/StrongPointer.h>
 
 struct ANativeWindow;
+class Surface;
 
 namespace android {
 
@@ -40,6 +42,15 @@
 status_t nativeWindowConnect(ANativeWindow *surface, const char *reason);
 status_t nativeWindowDisconnect(ANativeWindow *surface, const char *reason);
 
+/**
+ * Disable buffer dropping behavior of BufferQueue if target sdk of application
+ * is Q or later. If the caller is not an app (e.g. MediaPlayer in mediaserver)
+ * retain buffer dropping behavior.
+ *
+ * @return NO_ERROR
+ */
+status_t disableLegacyBufferDropPostQ(const sp<Surface> &surface);
+
 } // namespace android
 
 #endif  // SURFACE_UTILS_H_