Merge changes from topic "b129710438_2" into qt-dev

* changes:
  codec2: use media_codecs from apex and support variants/domains
  media: add media_codecs.xml to apex module
  media: expand media_codecs.xml to support variants and domains
  media/omx: Make OMX software plugin an actual plugin
  omx: only list existing OMX codecs in OmxStore
diff --git a/apex/Android.bp b/apex/Android.bp
index 5b3fcde..42a620b 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -12,22 +12,30 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-com_android_media_extractors = [
-    "libaacextractor",
-    "libamrextractor",
-    "libflacextractor",
-    "libmidiextractor",
-    "libmkvextractor",
-    "libmp3extractor",
-    "libmp4extractor",
-    "libmpeg2extractor",
-    "liboggextractor",
-    "libwavextractor",
-]
-
 apex_defaults {
     name: "com.android.media-defaults",
     java_libs: ["updatable-media"],
+    multilib: {
+        first: {
+            // Extractor process runs only with the primary ABI.
+            native_shared_libs: [
+                // Extractor plugins
+                "libaacextractor",
+                "libamrextractor",
+                "libflacextractor",
+                "libmidiextractor",
+                "libmkvextractor",
+                "libmp3extractor",
+                "libmp4extractor",
+                "libmpeg2extractor",
+                "liboggextractor",
+                "libwavextractor",
+            ],
+        },
+    },
+    prebuilts: [
+        "mediaextractor.policy",
+    ],
     key: "com.android.media.key",
     certificate: ":com.android.media.certificate",
 
@@ -39,12 +47,6 @@
     name: "com.android.media",
     manifest: "manifest.json",
     defaults: ["com.android.media-defaults"],
-    multilib: {
-        first: {
-            // Extractor process runs only with the primary ABI.
-            native_shared_libs: com_android_media_extractors,
-        },
-    },
 }
 
 filegroup {
diff --git a/apex/manifest.json b/apex/manifest.json
index cee94e2..03b9dd0 100644
--- a/apex/manifest.json
+++ b/apex/manifest.json
@@ -1,4 +1,4 @@
 {
   "name": "com.android.media",
-  "version": 210000000
+  "version": 220000000
 }
diff --git a/apex/manifest_codec.json b/apex/manifest_codec.json
index b83e65a..58ce868 100644
--- a/apex/manifest_codec.json
+++ b/apex/manifest_codec.json
@@ -1,4 +1,4 @@
 {
   "name": "com.android.media.swcodec",
-  "version": 210000000
+  "version": 220000000
 }
diff --git a/apex/testing/Android.bp b/apex/testing/Android.bp
index 297d864..701ced7 100644
--- a/apex/testing/Android.bp
+++ b/apex/testing/Android.bp
@@ -17,13 +17,6 @@
     manifest: "test_manifest.json",
     file_contexts: "com.android.media",
     defaults: ["com.android.media-defaults"],
-    multilib: {
-        both: {
-            // for test apex, built for both ABIs
-            native_shared_libs: com_android_media_extractors,
-        },
-    },
-    compile_multilib: "both",
     installable: false,
 }
 
diff --git a/drm/libmediadrm/CryptoHal.cpp b/drm/libmediadrm/CryptoHal.cpp
index 4dda5d7..d62ccd6 100644
--- a/drm/libmediadrm/CryptoHal.cpp
+++ b/drm/libmediadrm/CryptoHal.cpp
@@ -301,7 +301,7 @@
     ssize_t offset;
     size_t size;
 
-    if (memory == NULL && buffer == NULL) {
+    if (memory == NULL || buffer == NULL) {
         return UNEXPECTED_NULL;
     }
 
diff --git a/media/bufferpool/1.0/Connection.cpp b/media/bufferpool/1.0/Connection.cpp
index e58f595..be89701 100644
--- a/media/bufferpool/1.0/Connection.cpp
+++ b/media/bufferpool/1.0/Connection.cpp
@@ -32,14 +32,22 @@
             status = mAccessor->fetch(
                     mConnectionId, transactionId, bufferId, &handle);
             if (status == ResultStatus::OK) {
-                _hidl_cb(status, Buffer{bufferId, handle});
+                Buffer buffer = {};
+                buffer.id = bufferId;
+                buffer.buffer = handle;
+                _hidl_cb(status, buffer);
                 return Void();
             }
         } else {
             mAccessor->cleanUp(false);
         }
     }
-    _hidl_cb(status, Buffer{0, nullptr});
+
+    Buffer buffer = {};
+    buffer.id = 0;
+    buffer.buffer = nullptr;
+
+    _hidl_cb(status, buffer);
     return Void();
 }
 
diff --git a/media/bufferpool/2.0/Connection.cpp b/media/bufferpool/2.0/Connection.cpp
index 6bd0e79..57d0c7e 100644
--- a/media/bufferpool/2.0/Connection.cpp
+++ b/media/bufferpool/2.0/Connection.cpp
@@ -32,14 +32,22 @@
             status = mAccessor->fetch(
                     mConnectionId, transactionId, bufferId, &handle);
             if (status == ResultStatus::OK) {
-                _hidl_cb(status, Buffer{bufferId, handle});
+                Buffer buffer = {};
+                buffer.id = bufferId;
+                buffer.buffer = handle;
+                _hidl_cb(status, buffer);
                 return Void();
             }
         } else {
             mAccessor->cleanUp(false);
         }
     }
-    _hidl_cb(status, Buffer{0, nullptr});
+
+    Buffer buffer = {};
+    buffer.id = 0;
+    buffer.buffer = nullptr;
+
+    _hidl_cb(status, buffer);
     return Void();
 }
 
diff --git a/media/codec2/components/avc/C2SoftAvcDec.cpp b/media/codec2/components/avc/C2SoftAvcDec.cpp
index 9290d74..063c537 100644
--- a/media/codec2/components/avc/C2SoftAvcDec.cpp
+++ b/media/codec2/components/avc/C2SoftAvcDec.cpp
@@ -812,19 +812,19 @@
             ALOGV("decodeTime=%6d delay=%6d numBytes=%6d", decodeTime, delay,
                   s_decode_op.u4_num_bytes_consumed);
         }
-        if (IVD_MEM_ALLOC_FAILED == (s_decode_op.u4_error_code & 0xFF)) {
+        if (IVD_MEM_ALLOC_FAILED == (s_decode_op.u4_error_code & IVD_ERROR_MASK)) {
             ALOGE("allocation failure in decoder");
             mSignalledError = true;
             work->workletsProcessed = 1u;
             work->result = C2_CORRUPTED;
             return;
-        } else if (IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED == (s_decode_op.u4_error_code & 0xFF)) {
+        } else if (IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED == (s_decode_op.u4_error_code & IVD_ERROR_MASK)) {
             ALOGE("unsupported resolution : %dx%d", mWidth, mHeight);
             mSignalledError = true;
             work->workletsProcessed = 1u;
             work->result = C2_CORRUPTED;
             return;
-        } else if (IVD_RES_CHANGED == (s_decode_op.u4_error_code & 0xFF)) {
+        } else if (IVD_RES_CHANGED == (s_decode_op.u4_error_code & IVD_ERROR_MASK)) {
             ALOGV("resolution changed");
             drainInternal(DRAIN_COMPONENT_NO_EOS, pool, work);
             resetDecoder();
@@ -834,6 +834,12 @@
             /* Decode header and get new dimensions */
             setParams(mStride, IVD_DECODE_HEADER);
             (void) ivdec_api_function(mDecHandle, &s_decode_ip, &s_decode_op);
+        } else if (IS_IVD_FATAL_ERROR(s_decode_op.u4_error_code)) {
+            ALOGE("Fatal error in decoder 0x%x", s_decode_op.u4_error_code);
+            mSignalledError = true;
+            work->workletsProcessed = 1u;
+            work->result = C2_CORRUPTED;
+            return;
         }
         if (0 < s_decode_op.u4_pic_wd && 0 < s_decode_op.u4_pic_ht) {
             if (mHeaderDecoded == false) {
diff --git a/media/codec2/components/avc/C2SoftAvcEnc.h b/media/codec2/components/avc/C2SoftAvcEnc.h
index aa3ca61..58a86d8 100644
--- a/media/codec2/components/avc/C2SoftAvcEnc.h
+++ b/media/codec2/components/avc/C2SoftAvcEnc.h
@@ -38,7 +38,7 @@
 #define DEFAULT_MAX_REORDER_FRM     0
 #define DEFAULT_QP_MIN              10
 #define DEFAULT_QP_MAX              40
-#define DEFAULT_MAX_BITRATE         20000000
+#define DEFAULT_MAX_BITRATE         240000000
 #define DEFAULT_MAX_SRCH_RANGE_X    256
 #define DEFAULT_MAX_SRCH_RANGE_Y    256
 #define DEFAULT_MAX_FRAMERATE       120000
diff --git a/media/codec2/components/hevc/C2SoftHevcDec.cpp b/media/codec2/components/hevc/C2SoftHevcDec.cpp
index bb8dda0..5da59bd 100644
--- a/media/codec2/components/hevc/C2SoftHevcDec.cpp
+++ b/media/codec2/components/hevc/C2SoftHevcDec.cpp
@@ -806,19 +806,20 @@
         TIME_DIFF(mTimeStart, mTimeEnd, decodeTime);
         ALOGV("decodeTime=%6d delay=%6d numBytes=%6d", decodeTime, delay,
               s_decode_op.u4_num_bytes_consumed);
-        if (IVD_MEM_ALLOC_FAILED == (s_decode_op.u4_error_code & 0xFF)) {
+        if (IVD_MEM_ALLOC_FAILED == (s_decode_op.u4_error_code & IVD_ERROR_MASK)) {
             ALOGE("allocation failure in decoder");
             mSignalledError = true;
             work->workletsProcessed = 1u;
             work->result = C2_CORRUPTED;
             return;
-        } else if (IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED == (s_decode_op.u4_error_code & 0xFF)) {
+        } else if (IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED ==
+                   (s_decode_op.u4_error_code & IVD_ERROR_MASK)) {
             ALOGE("unsupported resolution : %dx%d", mWidth, mHeight);
             mSignalledError = true;
             work->workletsProcessed = 1u;
             work->result = C2_CORRUPTED;
             return;
-        } else if (IVD_RES_CHANGED == (s_decode_op.u4_error_code & 0xFF)) {
+        } else if (IVD_RES_CHANGED == (s_decode_op.u4_error_code & IVD_ERROR_MASK)) {
             ALOGV("resolution changed");
             drainInternal(DRAIN_COMPONENT_NO_EOS, pool, work);
             resetDecoder();
@@ -828,6 +829,12 @@
             /* Decode header and get new dimensions */
             setParams(mStride, IVD_DECODE_HEADER);
             (void) ivdec_api_function(mDecHandle, &s_decode_ip, &s_decode_op);
+        } else if (IS_IVD_FATAL_ERROR(s_decode_op.u4_error_code)) {
+            ALOGE("Fatal error in decoder 0x%x", s_decode_op.u4_error_code);
+            mSignalledError = true;
+            work->workletsProcessed = 1u;
+            work->result = C2_CORRUPTED;
+            return;
         }
         if (0 < s_decode_op.u4_pic_wd && 0 < s_decode_op.u4_pic_ht) {
             if (mHeaderDecoded == false) {
diff --git a/media/codec2/core/include/media/stagefright/codec2/1.0/InputSurface.h b/media/codec2/core/include/media/stagefright/codec2/1.0/InputSurface.h
index b011a06..0a82a68 100644
--- a/media/codec2/core/include/media/stagefright/codec2/1.0/InputSurface.h
+++ b/media/codec2/core/include/media/stagefright/codec2/1.0/InputSurface.h
@@ -20,7 +20,6 @@
 #include <memory>
 
 #include <C2Component.h>
-#include <media/stagefright/bqhelper/WGraphicBufferProducer.h>
 #include <media/stagefright/codec2/1.0/InputSurfaceConnection.h>
 
 namespace android {
diff --git a/media/codec2/core/include/media/stagefright/codec2/1.0/InputSurfaceConnection.h b/media/codec2/core/include/media/stagefright/codec2/1.0/InputSurfaceConnection.h
index b24a416..5eae3af 100644
--- a/media/codec2/core/include/media/stagefright/codec2/1.0/InputSurfaceConnection.h
+++ b/media/codec2/core/include/media/stagefright/codec2/1.0/InputSurfaceConnection.h
@@ -21,7 +21,6 @@
 
 #include <C2Component.h>
 #include <media/stagefright/bqhelper/GraphicBufferSource.h>
-#include <media/stagefright/bqhelper/WGraphicBufferProducer.h>
 #include <media/stagefright/codec2/1.0/InputSurfaceConnection.h>
 
 namespace android {
diff --git a/media/codec2/hidl/1.0/utils/ComponentStore.cpp b/media/codec2/hidl/1.0/utils/ComponentStore.cpp
index d6f84b4..1e0a190 100644
--- a/media/codec2/hidl/1.0/utils/ComponentStore.cpp
+++ b/media/codec2/hidl/1.0/utils/ComponentStore.cpp
@@ -23,7 +23,6 @@
 #include <codec2/hidl/1.0/types.h>
 
 #include <android-base/file.h>
-#include <gui/bufferqueue/2.0/B2HGraphicBufferProducer.h>
 #include <media/stagefright/bqhelper/GraphicBufferSource.h>
 #include <utils/Errors.h>
 
diff --git a/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/InputSurface.h b/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/InputSurface.h
index 34ea959..29ed7ff 100644
--- a/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/InputSurface.h
+++ b/media/codec2/hidl/1.0/utils/include/codec2/hidl/1.0/InputSurface.h
@@ -22,7 +22,6 @@
 #include <android/hardware/graphics/bufferqueue/2.0/IGraphicBufferProducer.h>
 #include <android/hardware/media/c2/1.0/IInputSink.h>
 #include <android/hardware/media/c2/1.0/IInputSurface.h>
-#include <gui/IGraphicBufferProducer.h>
 #include <hidl/Status.h>
 #include <media/stagefright/bqhelper/GraphicBufferSource.h>
 
diff --git a/media/codec2/vndk/C2Store.cpp b/media/codec2/vndk/C2Store.cpp
index 10c4dcc..f5dc838 100644
--- a/media/codec2/vndk/C2Store.cpp
+++ b/media/codec2/vndk/C2Store.cpp
@@ -26,6 +26,7 @@
 #include <C2Config.h>
 #include <C2PlatformStorePluginLoader.h>
 #include <C2PlatformSupport.h>
+#include <media/stagefright/foundation/ADebug.h>
 #include <util/C2InterfaceHelper.h>
 
 #include <dlfcn.h>
@@ -661,31 +662,37 @@
     ALOGV("in %s", __func__);
     ALOGV("loading dll");
     mLibHandle = dlopen(libPath.c_str(), RTLD_NOW|RTLD_NODELETE);
-    LOG_ALWAYS_FATAL_IF(mLibHandle == nullptr,
-            "could not dlopen %s: %s", libPath.c_str(), dlerror());
+    if (mLibHandle == nullptr) {
+        LOG_ALWAYS_FATAL_IN_CHILD_PROC("could not dlopen %s: %s", libPath.c_str(), dlerror());
+        mInit = C2_CORRUPTED;
+        return mInit;
+    }
 
     createFactory =
         (C2ComponentFactory::CreateCodec2FactoryFunc)dlsym(mLibHandle, "CreateCodec2Factory");
-    LOG_ALWAYS_FATAL_IF(createFactory == nullptr,
-            "createFactory is null in %s", libPath.c_str());
+    if (createFactory == nullptr) {
+        LOG_ALWAYS_FATAL_IN_CHILD_PROC("createFactory is null in %s", libPath.c_str());
+        mInit = C2_CORRUPTED;
+        return mInit;
+    }
 
     destroyFactory =
         (C2ComponentFactory::DestroyCodec2FactoryFunc)dlsym(mLibHandle, "DestroyCodec2Factory");
-    LOG_ALWAYS_FATAL_IF(destroyFactory == nullptr,
-            "destroyFactory is null in %s", libPath.c_str());
+    if (destroyFactory == nullptr) {
+        LOG_ALWAYS_FATAL_IN_CHILD_PROC("destroyFactory is null in %s", libPath.c_str());
+        mInit = C2_CORRUPTED;
+        return mInit;
+    }
 
     mComponentFactory = createFactory();
     if (mComponentFactory == nullptr) {
         ALOGD("could not create factory in %s", libPath.c_str());
         mInit = C2_NO_MEMORY;
-    } else {
-        mInit = C2_OK;
-    }
-
-    if (mInit != C2_OK) {
         return mInit;
     }
 
+    mInit = C2_OK;
+
     std::shared_ptr<C2ComponentInterface> intf;
     c2_status_t res = createInterface(0, &intf);
     if (res != C2_OK) {
diff --git a/media/extractors/aac/Android.bp b/media/extractors/aac/Android.bp
index 6fe5970..a58167a 100644
--- a/media/extractors/aac/Android.bp
+++ b/media/extractors/aac/Android.bp
@@ -20,7 +20,7 @@
     name: "libaacextractor",
     relative_install_path: "extractors",
 
-    compile_multilib: "both",
+    compile_multilib: "first",
 
     cflags: [
         "-Werror",
diff --git a/media/extractors/amr/Android.bp b/media/extractors/amr/Android.bp
index b26b2d8..4bd933d 100644
--- a/media/extractors/amr/Android.bp
+++ b/media/extractors/amr/Android.bp
@@ -18,7 +18,7 @@
     name: "libamrextractor",
     relative_install_path: "extractors",
 
-    compile_multilib: "both",
+    compile_multilib: "first",
 
     cflags: [
         "-Werror",
diff --git a/media/extractors/flac/Android.bp b/media/extractors/flac/Android.bp
index 3e83090..3a3d051 100644
--- a/media/extractors/flac/Android.bp
+++ b/media/extractors/flac/Android.bp
@@ -24,7 +24,7 @@
     name: "libflacextractor",
     relative_install_path: "extractors",
 
-    compile_multilib: "both",
+    compile_multilib: "first",
 
     cflags: [
         "-Werror",
diff --git a/media/extractors/midi/Android.bp b/media/extractors/midi/Android.bp
index 6790dd6..7d42e70 100644
--- a/media/extractors/midi/Android.bp
+++ b/media/extractors/midi/Android.bp
@@ -19,7 +19,7 @@
     name: "libmidiextractor",
     relative_install_path: "extractors",
 
-    compile_multilib: "both",
+    compile_multilib: "first",
 
     cflags: [
         "-Werror",
diff --git a/media/extractors/mkv/Android.bp b/media/extractors/mkv/Android.bp
index 7c94149..1744d3d 100644
--- a/media/extractors/mkv/Android.bp
+++ b/media/extractors/mkv/Android.bp
@@ -25,7 +25,7 @@
     name: "libmkvextractor",
     relative_install_path: "extractors",
 
-    compile_multilib: "both",
+    compile_multilib: "first",
 
     cflags: [
         "-Werror",
diff --git a/media/extractors/mp3/Android.bp b/media/extractors/mp3/Android.bp
index 168ef68..4e2f248 100644
--- a/media/extractors/mp3/Android.bp
+++ b/media/extractors/mp3/Android.bp
@@ -24,7 +24,7 @@
     name: "libmp3extractor",
     relative_install_path: "extractors",
 
-    compile_multilib: "both",
+    compile_multilib: "first",
 
     cflags: [
         "-Werror",
diff --git a/media/extractors/mp4/Android.bp b/media/extractors/mp4/Android.bp
index 9b9c931..1b308aa 100644
--- a/media/extractors/mp4/Android.bp
+++ b/media/extractors/mp4/Android.bp
@@ -32,7 +32,7 @@
     ],
     version_script: "exports.lds",
     relative_install_path: "extractors",
-    compile_multilib: "both",
+    compile_multilib: "first",
 }
 
 cc_library_shared {
diff --git a/media/extractors/mpeg2/Android.bp b/media/extractors/mpeg2/Android.bp
index 14f49ae..0f0c72c 100644
--- a/media/extractors/mpeg2/Android.bp
+++ b/media/extractors/mpeg2/Android.bp
@@ -40,7 +40,7 @@
     name: "libmpeg2extractor",
     relative_install_path: "extractors",
 
-    compile_multilib: "both",
+    compile_multilib: "first",
 
     cflags: [
         "-Werror",
diff --git a/media/extractors/ogg/Android.bp b/media/extractors/ogg/Android.bp
index fd03f64..604ec59 100644
--- a/media/extractors/ogg/Android.bp
+++ b/media/extractors/ogg/Android.bp
@@ -26,7 +26,7 @@
     name: "liboggextractor",
     relative_install_path: "extractors",
 
-    compile_multilib: "both",
+    compile_multilib: "first",
 
     cflags: [
         "-Werror",
diff --git a/media/extractors/wav/Android.bp b/media/extractors/wav/Android.bp
index 15fd796..7e89271 100644
--- a/media/extractors/wav/Android.bp
+++ b/media/extractors/wav/Android.bp
@@ -21,7 +21,7 @@
     name: "libwavextractor",
     relative_install_path: "extractors",
 
-    compile_multilib: "both",
+    compile_multilib: "first",
 
     cflags: [
         "-Werror",
diff --git a/media/libaaudio/src/binding/IAAudioService.cpp b/media/libaaudio/src/binding/IAAudioService.cpp
index 9b32543..97ad2b0 100644
--- a/media/libaaudio/src/binding/IAAudioService.cpp
+++ b/media/libaaudio/src/binding/IAAudioService.cpp
@@ -251,8 +251,15 @@
             CHECK_INTERFACE(IAAudioService, data, reply);
             sp<IAAudioClient> client = interface_cast<IAAudioClient>(
                     data.readStrongBinder());
-            registerClient(client);
-            return NO_ERROR;
+            // readStrongBinder() can return null
+            if (client.get() == nullptr) {
+                ALOGE("BnAAudioService::%s(REGISTER_CLIENT) client is NULL!", __func__);
+                android_errorWriteLog(0x534e4554, "116230453");
+                return DEAD_OBJECT;
+            } else {
+                registerClient(client);
+                return NO_ERROR;
+            }
         } break;
 
         case OPEN_STREAM: {
diff --git a/media/libaaudio/src/legacy/AudioStreamRecord.cpp b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
index 4a65fc9..71efc30 100644
--- a/media/libaaudio/src/legacy/AudioStreamRecord.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
@@ -63,7 +63,9 @@
     // TODO Support UNSPECIFIED in AudioRecord. For now, use stereo if unspecified.
     int32_t samplesPerFrame = (getSamplesPerFrame() == AAUDIO_UNSPECIFIED)
                               ? 2 : getSamplesPerFrame();
-    audio_channel_mask_t channelMask = audio_channel_in_mask_from_count(samplesPerFrame);
+    audio_channel_mask_t channelMask = samplesPerFrame <= 2 ?
+                               audio_channel_in_mask_from_count(samplesPerFrame) :
+                               audio_channel_mask_for_index_assignment_from_count(samplesPerFrame);
 
     size_t frameCount = (builder.getBufferCapacity() == AAUDIO_UNSPECIFIED) ? 0
                         : builder.getBufferCapacity();
diff --git a/media/libaaudio/src/legacy/AudioStreamTrack.cpp b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
index d628bf7..094cdd1 100644
--- a/media/libaaudio/src/legacy/AudioStreamTrack.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
@@ -66,7 +66,9 @@
     // Use stereo if unspecified.
     int32_t samplesPerFrame = (getSamplesPerFrame() == AAUDIO_UNSPECIFIED)
                               ? 2 : getSamplesPerFrame();
-    audio_channel_mask_t channelMask = audio_channel_out_mask_from_count(samplesPerFrame);
+    audio_channel_mask_t channelMask = samplesPerFrame <= 2 ?
+                            audio_channel_out_mask_from_count(samplesPerFrame) :
+                            audio_channel_mask_for_index_assignment_from_count(samplesPerFrame);
 
     audio_output_flags_t flags;
     aaudio_performance_mode_t perfMode = getPerformanceMode();
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index 9387d4d..4a80cd3 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -2144,9 +2144,27 @@
                     const nsecs_t timeNow = systemTime();
                     ns = max((nsecs_t)0, ns - (timeNow - timeAfterCallbacks));
                 }
-                nsecs_t myns = framesToNanoseconds(mRemainingFrames - avail, sampleRate, speed);
-                if (ns < 0 /* NS_WHENEVER */ || myns < ns) {
-                    ns = myns;
+
+                // delayNs is first computed by the additional frames required in the buffer.
+                nsecs_t delayNs = framesToNanoseconds(
+                        mRemainingFrames - avail, sampleRate, speed);
+
+                // afNs is the AudioFlinger mixer period in ns.
+                const nsecs_t afNs = framesToNanoseconds(mAfFrameCount, mAfSampleRate, speed);
+
+                // If the AudioTrack is double buffered based on the AudioFlinger mixer period,
+                // we may have a race if we wait based on the number of frames desired.
+                // This is a possible issue with resampling and AAudio.
+                //
+                // The granularity of audioflinger processing is one mixer period; if
+                // our wait time is less than one mixer period, wait at most half the period.
+                if (delayNs < afNs) {
+                    delayNs = std::min(delayNs, afNs / 2);
+                }
+
+                // adjust our ns wait by delayNs.
+                if (ns < 0 /* NS_WHENEVER */ || delayNs < ns) {
+                    ns = delayNs;
                 }
                 return ns;
             }
diff --git a/media/libmedia/include/media/omx/1.0/Conversion.h b/media/libmedia/include/media/omx/1.0/Conversion.h
index babda22..80e8f3a 100644
--- a/media/libmedia/include/media/omx/1.0/Conversion.h
+++ b/media/libmedia/include/media/omx/1.0/Conversion.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_HARDWARE_MEDIA_OMX_V1_0__CONVERSION_H
-#define ANDROID_HARDWARE_MEDIA_OMX_V1_0__CONVERSION_H
+#ifndef ANDROID_HARDWARE_MEDIA_OMX_V1_0_UTILS_CONVERSION_H
+#define ANDROID_HARDWARE_MEDIA_OMX_V1_0_UTILS_CONVERSION_H
 
 #include <vector>
 #include <list>
@@ -258,7 +258,12 @@
  */
 // convert: Status -> status_t
 inline status_t toStatusT(Return<Status> const& t) {
-    return t.isOk() ? toStatusT(static_cast<Status>(t)) : UNKNOWN_ERROR;
+    if (t.isOk()) {
+        return toStatusT(static_cast<Status>(t));
+    } else if (t.isDeadObject()) {
+        return DEAD_OBJECT;
+    }
+    return UNKNOWN_ERROR;
 }
 
 /**
@@ -938,4 +943,4 @@
 }  // namespace hardware
 }  // namespace android
 
-#endif  // ANDROID_HARDWARE_MEDIA_OMX_V1_0__CONVERSION_H
+#endif  // ANDROID_HARDWARE_MEDIA_OMX_V1_0_UTILS_CONVERSION_H
diff --git a/media/libstagefright/MediaExtractorFactory.cpp b/media/libstagefright/MediaExtractorFactory.cpp
index d97591f..81d2abb 100644
--- a/media/libstagefright/MediaExtractorFactory.cpp
+++ b/media/libstagefright/MediaExtractorFactory.cpp
@@ -19,11 +19,11 @@
 #include <utils/Log.h>
 
 #include <android/dlext.h>
-#include <android-base/logging.h>
 #include <binder/IPCThreadState.h>
 #include <binder/PermissionCache.h>
 #include <binder/IServiceManager.h>
 #include <media/DataSource.h>
+#include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/InterfaceUtils.h>
 #include <media/stagefright/MediaExtractor.h>
 #include <media/stagefright/MediaExtractorFactory.h>
@@ -245,17 +245,21 @@
             void *libHandle = android_dlopen_ext(
                     libPath.string(),
                     RTLD_NOW | RTLD_LOCAL, dlextinfo);
-            CHECK(libHandle != nullptr)
-                    << "couldn't dlopen(" << libPath.string() << ") " << strerror(errno);
-
-            GetExtractorDef getDef =
-                (GetExtractorDef) dlsym(libHandle, "GETEXTRACTORDEF");
-            CHECK(getDef != nullptr)
-                    << libPath.string() << " does not contain sniffer";
-
-            ALOGV("registering sniffer for %s", libPath.string());
-            RegisterExtractor(
-                    new ExtractorPlugin(getDef(), libHandle, libPath), pluginList);
+            if (libHandle) {
+                GetExtractorDef getDef =
+                    (GetExtractorDef) dlsym(libHandle, "GETEXTRACTORDEF");
+                if (getDef) {
+                    ALOGV("registering sniffer for %s", libPath.string());
+                    RegisterExtractor(
+                            new ExtractorPlugin(getDef(), libHandle, libPath), pluginList);
+                } else {
+                    LOG_ALWAYS_FATAL_IN_CHILD_PROC("%s does not contain sniffer", libPath.string());
+                    dlclose(libHandle);
+                }
+            } else {
+                LOG_ALWAYS_FATAL_IN_CHILD_PROC(
+                        "couldn't dlopen(%s) %s", libPath.string(), strerror(errno));
+            }
         }
         closedir(libDir);
     } else {
diff --git a/media/libstagefright/bqhelper/Android.bp b/media/libstagefright/bqhelper/Android.bp
index 218fe15..db67034 100644
--- a/media/libstagefright/bqhelper/Android.bp
+++ b/media/libstagefright/bqhelper/Android.bp
@@ -6,10 +6,8 @@
     },
     double_loadable: true,
     srcs: [
-        "Conversion.cpp",
         "FrameDropper.cpp",
         "GraphicBufferSource.cpp",
-        "WProducerListener.cpp",
     ],
 
     export_include_dirs: [
@@ -27,7 +25,6 @@
     shared_libs: [
         "libbinder",
         "libcutils",
-        "libgui",
         "libhidlbase",
         "libhidlmemory",
         "libhidltransport",
@@ -37,12 +34,25 @@
         "libutils",
 
         "android.hardware.graphics.bufferqueue@1.0",
+        // Following libs are from libgui_bufferqueue_static
+        "android.hardware.graphics.bufferqueue@2.0",
+        "android.hidl.token@1.0-utils",
+        "libbase",
+        "libEGL",
+        "libhwbinder",
+        "libnativewindow",
+        "libvndksupport",
+    ],
+    
+    static_libs: [
+        "libgui_bufferqueue_static"
     ],
 
     export_shared_lib_headers: [
-        "libgui",
         "libhidlmemory",
         "libstagefright_foundation",
+        "android.hardware.graphics.bufferqueue@1.0",
+        "android.hardware.graphics.bufferqueue@2.0",
     ],
 
     cflags: [
diff --git a/media/libstagefright/bqhelper/Conversion.cpp b/media/libstagefright/bqhelper/Conversion.cpp
deleted file mode 100644
index 91d7c74..0000000
--- a/media/libstagefright/bqhelper/Conversion.cpp
+++ /dev/null
@@ -1,1542 +0,0 @@
-/*
- * Copyright 2018, 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.
- */
-
-#include <media/stagefright/bqhelper/Conversion.h>
-
-namespace android {
-namespace conversion {
-
-// native_handle_t helper functions.
-
-/**
- * \brief Take an fd and create a native handle containing only the given fd.
- * The created handle will need to be deleted manually with
- * `native_handle_delete()`.
- *
- * \param[in] fd The source file descriptor (of type `int`).
- * \return The create `native_handle_t*` that contains the given \p fd. If the
- * supplied \p fd is negative, the created native handle will contain no file
- * descriptors.
- *
- * If the native handle cannot be created, the return value will be
- * `nullptr`.
- *
- * This function does not duplicate the file descriptor.
- */
-native_handle_t* native_handle_create_from_fd(int fd) {
-    if (fd < 2) {
-        return native_handle_create(0, 0);
-    }
-    native_handle_t* nh = native_handle_create(1, 0);
-    if (nh == nullptr) {
-        return nullptr;
-    }
-    nh->data[0] = fd;
-    return nh;
-}
-
-/**
- * \brief Extract a file descriptor from a native handle.
- *
- * \param[in] nh The source `native_handle_t*`.
- * \param[in] index The index of the file descriptor in \p nh to read from. This
- * input has the default value of `0`.
- * \return The `index`-th file descriptor in \p nh. If \p nh does not have
- * enough file descriptors, the returned value will be `-1`.
- *
- * This function does not duplicate the file descriptor.
- */
-int native_handle_read_fd(native_handle_t const* nh, int index) {
-    return ((nh == nullptr) || (nh->numFds == 0) ||
-            (nh->numFds <= index) || (index < 0)) ?
-            -1 : nh->data[index];
-}
-
-/**
- * Conversion functions
- * ====================
- *
- * There are two main directions of conversion:
- * - `inTargetType(...)`: Create a wrapper whose lifetime depends on the
- *   input. The wrapper has type `TargetType`.
- * - `toTargetType(...)`: Create a standalone object of type `TargetType` that
- *   corresponds to the input. The lifetime of the output does not depend on the
- *   lifetime of the input.
- * - `wrapIn(TargetType*, ...)`: Same as `inTargetType()`, but for `TargetType`
- *   that cannot be copied and/or moved efficiently, or when there are multiple
- *   output arguments.
- * - `convertTo(TargetType*, ...)`: Same as `toTargetType()`, but for
- *   `TargetType` that cannot be copied and/or moved efficiently, or when there
- *   are multiple output arguments.
- *
- * `wrapIn()` and `convertTo()` functions will take output arguments before
- * input arguments. Some of these functions might return a value to indicate
- * success or error.
- *
- * In converting or wrapping something as a Treble type that contains a
- * `hidl_handle`, `native_handle_t*` will need to be created and returned as
- * an additional output argument, hence only `wrapIn()` or `convertTo()` would
- * be available. The caller must call `native_handle_delete()` to deallocate the
- * returned native handle when it is no longer needed.
- *
- * For types that contain file descriptors, `inTargetType()` and `wrapAs()` do
- * not perform duplication of file descriptors, while `toTargetType()` and
- * `convertTo()` do.
- */
-
-/**
- * \brief Convert `Return<void>` to `status_t`. This is for legacy binder calls.
- *
- * \param[in] t The source `Return<void>`.
- * \return The corresponding `status_t`.
- */
-// convert: Return<void> -> status_t
-status_t toStatusT(Return<void> const& t) {
-    return t.isOk() ? OK : (t.isDeadObject() ? DEAD_OBJECT : UNKNOWN_ERROR);
-}
-
-/**
- * \brief Convert `Return<void>` to `binder::Status`.
- *
- * \param[in] t The source `Return<void>`.
- * \return The corresponding `binder::Status`.
- */
-// convert: Return<void> -> ::android::binder::Status
-::android::binder::Status toBinderStatus(
-        Return<void> const& t) {
-    return ::android::binder::Status::fromExceptionCode(
-            toStatusT(t),
-            t.description().c_str());
-}
-
-/**
- * \brief Wrap `native_handle_t*` in `hidl_handle`.
- *
- * \param[in] nh The source `native_handle_t*`.
- * \return The `hidl_handle` that points to \p nh.
- */
-// wrap: native_handle_t* -> hidl_handle
-hidl_handle inHidlHandle(native_handle_t const* nh) {
-    return hidl_handle(nh);
-}
-
-/**
- * \brief Convert `int32_t` to `Dataspace`.
- *
- * \param[in] l The source `int32_t`.
- * \result The corresponding `Dataspace`.
- */
-// convert: int32_t -> Dataspace
-Dataspace toHardwareDataspace(int32_t l) {
-    return static_cast<Dataspace>(l);
-}
-
-/**
- * \brief Convert `Dataspace` to `int32_t`.
- *
- * \param[in] t The source `Dataspace`.
- * \result The corresponding `int32_t`.
- */
-// convert: Dataspace -> int32_t
-int32_t toRawDataspace(Dataspace const& t) {
-    return static_cast<int32_t>(t);
-}
-
-/**
- * \brief Wrap an opaque buffer inside a `hidl_vec<uint8_t>`.
- *
- * \param[in] l The pointer to the beginning of the opaque buffer.
- * \param[in] size The size of the buffer.
- * \return A `hidl_vec<uint8_t>` that points to the buffer.
- */
-// wrap: void*, size_t -> hidl_vec<uint8_t>
-hidl_vec<uint8_t> inHidlBytes(void const* l, size_t size) {
-    hidl_vec<uint8_t> t;
-    t.setToExternal(static_cast<uint8_t*>(const_cast<void*>(l)), size, false);
-    return t;
-}
-
-/**
- * \brief Create a `hidl_vec<uint8_t>` that is a copy of an opaque buffer.
- *
- * \param[in] l The pointer to the beginning of the opaque buffer.
- * \param[in] size The size of the buffer.
- * \return A `hidl_vec<uint8_t>` that is a copy of the input buffer.
- */
-// convert: void*, size_t -> hidl_vec<uint8_t>
-hidl_vec<uint8_t> toHidlBytes(void const* l, size_t size) {
-    hidl_vec<uint8_t> t;
-    t.resize(size);
-    uint8_t const* src = static_cast<uint8_t const*>(l);
-    std::copy(src, src + size, t.data());
-    return t;
-}
-
-/**
- * \brief Wrap `GraphicBuffer` in `AnwBuffer`.
- *
- * \param[out] t The wrapper of type `AnwBuffer`.
- * \param[in] l The source `GraphicBuffer`.
- */
-// wrap: GraphicBuffer -> AnwBuffer
-void wrapAs(AnwBuffer* t, GraphicBuffer const& l) {
-    t->attr.width = l.getWidth();
-    t->attr.height = l.getHeight();
-    t->attr.stride = l.getStride();
-    t->attr.format = static_cast<PixelFormat>(l.getPixelFormat());
-    t->attr.layerCount = l.getLayerCount();
-    t->attr.usage = l.getUsage();
-    t->attr.id = l.getId();
-    t->attr.generationNumber = l.getGenerationNumber();
-    t->nativeHandle = hidl_handle(l.handle);
-}
-
-/**
- * \brief Convert `AnwBuffer` to `GraphicBuffer`.
- *
- * \param[out] l The destination `GraphicBuffer`.
- * \param[in] t The source `AnwBuffer`.
- *
- * This function will duplicate all file descriptors in \p t.
- */
-// convert: AnwBuffer -> GraphicBuffer
-// Ref: frameworks/native/libs/ui/GraphicBuffer.cpp: GraphicBuffer::flatten
-bool convertTo(GraphicBuffer* l, AnwBuffer const& t) {
-    native_handle_t* handle = t.nativeHandle == nullptr ?
-            nullptr : native_handle_clone(t.nativeHandle);
-
-    size_t const numInts = 12 + (handle ? handle->numInts : 0);
-    int32_t* ints = new int32_t[numInts];
-
-    size_t numFds = static_cast<size_t>(handle ? handle->numFds : 0);
-    int* fds = new int[numFds];
-
-    ints[0] = 'GBFR';
-    ints[1] = static_cast<int32_t>(t.attr.width);
-    ints[2] = static_cast<int32_t>(t.attr.height);
-    ints[3] = static_cast<int32_t>(t.attr.stride);
-    ints[4] = static_cast<int32_t>(t.attr.format);
-    ints[5] = static_cast<int32_t>(t.attr.layerCount);
-    ints[6] = static_cast<int32_t>(t.attr.usage);
-    ints[7] = static_cast<int32_t>(t.attr.id >> 32);
-    ints[8] = static_cast<int32_t>(t.attr.id & 0xFFFFFFFF);
-    ints[9] = static_cast<int32_t>(t.attr.generationNumber);
-    ints[10] = 0;
-    ints[11] = 0;
-    if (handle) {
-        ints[10] = static_cast<int32_t>(handle->numFds);
-        ints[11] = static_cast<int32_t>(handle->numInts);
-        int* intsStart = handle->data + handle->numFds;
-        std::copy(handle->data, intsStart, fds);
-        std::copy(intsStart, intsStart + handle->numInts, &ints[12]);
-    }
-
-    void const* constBuffer = static_cast<void const*>(ints);
-    size_t size = numInts * sizeof(int32_t);
-    int const* constFds = static_cast<int const*>(fds);
-    status_t status = l->unflatten(constBuffer, size, constFds, numFds);
-
-    delete [] fds;
-    delete [] ints;
-    native_handle_delete(handle);
-    return status == NO_ERROR;
-}
-
-/**
- * Conversion functions for types outside media
- * ============================================
- *
- * Some objects in libui and libgui that were made to go through binder calls do
- * not expose ways to read or write their fields to the public. To pass an
- * object of this kind through the HIDL boundary, translation functions need to
- * work around the access restriction by using the publicly available
- * `flatten()` and `unflatten()` functions.
- *
- * All `flatten()` and `unflatten()` overloads follow the same convention as
- * follows:
- *
- *     status_t flatten(ObjectType const& object,
- *                      [OtherType const& other, ...]
- *                      void*& buffer, size_t& size,
- *                      int*& fds, size_t& numFds)
- *
- *     status_t unflatten(ObjectType* object,
- *                        [OtherType* other, ...,]
- *                        void*& buffer, size_t& size,
- *                        int*& fds, size_t& numFds)
- *
- * The number of `other` parameters varies depending on the `ObjectType`. For
- * example, in the process of unflattening an object that contains
- * `hidl_handle`, `other` is needed to hold `native_handle_t` objects that will
- * be created.
- *
- * The last four parameters always work the same way in all overloads of
- * `flatten()` and `unflatten()`:
- * - For `flatten()`, `buffer` is the pointer to the non-fd buffer to be filled,
- *   `size` is the size (in bytes) of the non-fd buffer pointed to by `buffer`,
- *   `fds` is the pointer to the fd buffer to be filled, and `numFds` is the
- *   size (in ints) of the fd buffer pointed to by `fds`.
- * - For `unflatten()`, `buffer` is the pointer to the non-fd buffer to be read
- *   from, `size` is the size (in bytes) of the non-fd buffer pointed to by
- *   `buffer`, `fds` is the pointer to the fd buffer to be read from, and
- *   `numFds` is the size (in ints) of the fd buffer pointed to by `fds`.
- * - After a successful call to `flatten()` or `unflatten()`, `buffer` and `fds`
- *   will be advanced, while `size` and `numFds` will be decreased to reflect
- *   how much storage/data of the two buffers (fd and non-fd) have been used.
- * - After an unsuccessful call, the values of `buffer`, `size`, `fds` and
- *   `numFds` are invalid.
- *
- * The return value of a successful `flatten()` or `unflatten()` call will be
- * `OK` (also aliased as `NO_ERROR`). Any other values indicate a failure.
- *
- * For each object type that supports flattening, there will be two accompanying
- * functions: `getFlattenedSize()` and `getFdCount()`. `getFlattenedSize()` will
- * return the size of the non-fd buffer that the object will need for
- * flattening. `getFdCount()` will return the size of the fd buffer that the
- * object will need for flattening.
- *
- * The set of these four functions, `getFlattenedSize()`, `getFdCount()`,
- * `flatten()` and `unflatten()`, are similar to functions of the same name in
- * the abstract class `Flattenable`. The only difference is that functions in
- * this file are not member functions of the object type. For example, we write
- *
- *     flatten(x, buffer, size, fds, numFds)
- *
- * instead of
- *
- *     x.flatten(buffer, size, fds, numFds)
- *
- * because we cannot modify the type of `x`.
- *
- * There is one exception to the naming convention: `hidl_handle` that
- * represents a fence. The four functions for this "Fence" type have the word
- * "Fence" attched to their names because the object type, which is
- * `hidl_handle`, does not carry the special meaning that the object itself can
- * only contain zero or one file descriptor.
- */
-
-// Ref: frameworks/native/libs/ui/Fence.cpp
-
-/**
- * \brief Return the size of the non-fd buffer required to flatten a fence.
- *
- * \param[in] fence The input fence of type `hidl_handle`.
- * \return The required size of the flat buffer.
- *
- * The current version of this function always returns 4, which is the number of
- * bytes required to store the number of file descriptors contained in the fd
- * part of the flat buffer.
- */
-size_t getFenceFlattenedSize(hidl_handle const& /* fence */) {
-    return 4;
-};
-
-/**
- * \brief Return the number of file descriptors contained in a fence.
- *
- * \param[in] fence The input fence of type `hidl_handle`.
- * \return `0` if \p fence does not contain a valid file descriptor, or `1`
- * otherwise.
- */
-size_t getFenceFdCount(hidl_handle const& fence) {
-    return native_handle_read_fd(fence) == -1 ? 0 : 1;
-}
-
-/**
- * \brief Unflatten `Fence` to `hidl_handle`.
- *
- * \param[out] fence The destination `hidl_handle`.
- * \param[out] nh The underlying native handle.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- *
- * If the return value is `NO_ERROR`, \p nh will point to a newly created
- * native handle, which needs to be deleted with `native_handle_delete()`
- * afterwards.
- */
-status_t unflattenFence(hidl_handle* fence, native_handle_t** nh,
-        void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
-    if (size < 4) {
-        return NO_MEMORY;
-    }
-
-    uint32_t numFdsInHandle;
-    FlattenableUtils::read(buffer, size, numFdsInHandle);
-
-    if (numFdsInHandle > 1) {
-        return BAD_VALUE;
-    }
-
-    if (numFds < numFdsInHandle) {
-        return NO_MEMORY;
-    }
-
-    if (numFdsInHandle) {
-        *nh = native_handle_create_from_fd(*fds);
-        if (*nh == nullptr) {
-            return NO_MEMORY;
-        }
-        *fence = *nh;
-        ++fds;
-        --numFds;
-    } else {
-        *nh = nullptr;
-        *fence = hidl_handle();
-    }
-
-    return NO_ERROR;
-}
-
-/**
- * \brief Flatten `hidl_handle` as `Fence`.
- *
- * \param[in] t The source `hidl_handle`.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- */
-status_t flattenFence(hidl_handle const& fence,
-        void*& buffer, size_t& size, int*& fds, size_t& numFds) {
-    if (size < getFenceFlattenedSize(fence) ||
-            numFds < getFenceFdCount(fence)) {
-        return NO_MEMORY;
-    }
-    // Cast to uint32_t since the size of a size_t can vary between 32- and
-    // 64-bit processes
-    FlattenableUtils::write(buffer, size,
-            static_cast<uint32_t>(getFenceFdCount(fence)));
-    int fd = native_handle_read_fd(fence);
-    if (fd != -1) {
-        *fds = fd;
-        ++fds;
-        --numFds;
-    }
-    return NO_ERROR;
-}
-
-/**
- * \brief Wrap `Fence` in `hidl_handle`.
- *
- * \param[out] t The wrapper of type `hidl_handle`.
- * \param[out] nh The native handle pointed to by \p t.
- * \param[in] l The source `Fence`.
- *
- * On success, \p nh will hold a newly created native handle, which must be
- * deleted manually with `native_handle_delete()` afterwards.
- */
-// wrap: Fence -> hidl_handle
-bool wrapAs(hidl_handle* t, native_handle_t** nh, Fence const& l) {
-    size_t const baseSize = l.getFlattenedSize();
-    std::unique_ptr<uint8_t[]> baseBuffer(
-            new (std::nothrow) uint8_t[baseSize]);
-    if (!baseBuffer) {
-        return false;
-    }
-
-    size_t const baseNumFds = l.getFdCount();
-    std::unique_ptr<int[]> baseFds(
-            new (std::nothrow) int[baseNumFds]);
-    if (!baseFds) {
-        return false;
-    }
-
-    void* buffer = static_cast<void*>(baseBuffer.get());
-    size_t size = baseSize;
-    int* fds = static_cast<int*>(baseFds.get());
-    size_t numFds = baseNumFds;
-    if (l.flatten(buffer, size, fds, numFds) != NO_ERROR) {
-        return false;
-    }
-
-    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
-    size = baseSize;
-    int const* constFds = static_cast<int const*>(baseFds.get());
-    numFds = baseNumFds;
-    if (unflattenFence(t, nh, constBuffer, size, constFds, numFds)
-            != NO_ERROR) {
-        return false;
-    }
-
-    return true;
-}
-
-/**
- * \brief Convert `hidl_handle` to `Fence`.
- *
- * \param[out] l The destination `Fence`. `l` must not have been used
- * (`l->isValid()` must return `false`) before this function is called.
- * \param[in] t The source `hidl_handle`.
- *
- * If \p t contains a valid file descriptor, it will be duplicated.
- */
-// convert: hidl_handle -> Fence
-bool convertTo(Fence* l, hidl_handle const& t) {
-    int fd = native_handle_read_fd(t);
-    if (fd != -1) {
-        fd = dup(fd);
-        if (fd == -1) {
-            return false;
-        }
-    }
-    native_handle_t* nh = native_handle_create_from_fd(fd);
-    if (nh == nullptr) {
-        if (fd != -1) {
-            close(fd);
-        }
-        return false;
-    }
-
-    size_t const baseSize = getFenceFlattenedSize(t);
-    std::unique_ptr<uint8_t[]> baseBuffer(
-            new (std::nothrow) uint8_t[baseSize]);
-    if (!baseBuffer) {
-        native_handle_delete(nh);
-        return false;
-    }
-
-    size_t const baseNumFds = getFenceFdCount(t);
-    std::unique_ptr<int[]> baseFds(
-            new (std::nothrow) int[baseNumFds]);
-    if (!baseFds) {
-        native_handle_delete(nh);
-        return false;
-    }
-
-    void* buffer = static_cast<void*>(baseBuffer.get());
-    size_t size = baseSize;
-    int* fds = static_cast<int*>(baseFds.get());
-    size_t numFds = baseNumFds;
-    if (flattenFence(hidl_handle(nh), buffer, size, fds, numFds) != NO_ERROR) {
-        native_handle_delete(nh);
-        return false;
-    }
-    native_handle_delete(nh);
-
-    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
-    size = baseSize;
-    int const* constFds = static_cast<int const*>(baseFds.get());
-    numFds = baseNumFds;
-    if (l->unflatten(constBuffer, size, constFds, numFds) != NO_ERROR) {
-        return false;
-    }
-
-    return true;
-}
-
-// Ref: frameworks/native/libs/ui/FenceTime.cpp: FenceTime::Snapshot
-
-/**
- * \brief Return the size of the non-fd buffer required to flatten
- * `FenceTimeSnapshot`.
- *
- * \param[in] t The input `FenceTimeSnapshot`.
- * \return The required size of the flat buffer.
- */
-size_t getFlattenedSize(
-        HGraphicBufferProducer::FenceTimeSnapshot const& t) {
-    constexpr size_t min = sizeof(t.state);
-    switch (t.state) {
-        case HGraphicBufferProducer::FenceTimeSnapshot::State::EMPTY:
-            return min;
-        case HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE:
-            return min + getFenceFlattenedSize(t.fence);
-        case HGraphicBufferProducer::FenceTimeSnapshot::State::SIGNAL_TIME:
-            return min + sizeof(
-                    ::android::FenceTime::Snapshot::signalTime);
-    }
-    return 0;
-}
-
-/**
- * \brief Return the number of file descriptors contained in
- * `FenceTimeSnapshot`.
- *
- * \param[in] t The input `FenceTimeSnapshot`.
- * \return The number of file descriptors contained in \p snapshot.
- */
-size_t getFdCount(
-        HGraphicBufferProducer::FenceTimeSnapshot const& t) {
-    return t.state ==
-            HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE ?
-            getFenceFdCount(t.fence) : 0;
-}
-
-/**
- * \brief Flatten `FenceTimeSnapshot`.
- *
- * \param[in] t The source `FenceTimeSnapshot`.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- *
- * This function will duplicate the file descriptor in `t.fence` if `t.state ==
- * FENCE`.
- */
-status_t flatten(HGraphicBufferProducer::FenceTimeSnapshot const& t,
-        void*& buffer, size_t& size, int*& fds, size_t& numFds) {
-    if (size < getFlattenedSize(t)) {
-        return NO_MEMORY;
-    }
-
-    switch (t.state) {
-        case HGraphicBufferProducer::FenceTimeSnapshot::State::EMPTY:
-            FlattenableUtils::write(buffer, size,
-                    ::android::FenceTime::Snapshot::State::EMPTY);
-            return NO_ERROR;
-        case HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE:
-            FlattenableUtils::write(buffer, size,
-                    ::android::FenceTime::Snapshot::State::FENCE);
-            return flattenFence(t.fence, buffer, size, fds, numFds);
-        case HGraphicBufferProducer::FenceTimeSnapshot::State::SIGNAL_TIME:
-            FlattenableUtils::write(buffer, size,
-                    ::android::FenceTime::Snapshot::State::SIGNAL_TIME);
-            FlattenableUtils::write(buffer, size, t.signalTimeNs);
-            return NO_ERROR;
-    }
-    return NO_ERROR;
-}
-
-/**
- * \brief Unflatten `FenceTimeSnapshot`.
- *
- * \param[out] t The destination `FenceTimeSnapshot`.
- * \param[out] nh The underlying native handle.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- *
- * If the return value is `NO_ERROR` and the constructed snapshot contains a
- * file descriptor, \p nh will be created to hold that file descriptor. In this
- * case, \p nh needs to be deleted with `native_handle_delete()` afterwards.
- */
-status_t unflatten(
-        HGraphicBufferProducer::FenceTimeSnapshot* t, native_handle_t** nh,
-        void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
-    if (size < sizeof(t->state)) {
-        return NO_MEMORY;
-    }
-
-    *nh = nullptr;
-    ::android::FenceTime::Snapshot::State state;
-    FlattenableUtils::read(buffer, size, state);
-    switch (state) {
-        case ::android::FenceTime::Snapshot::State::EMPTY:
-            t->state = HGraphicBufferProducer::FenceTimeSnapshot::State::EMPTY;
-            return NO_ERROR;
-        case ::android::FenceTime::Snapshot::State::FENCE:
-            t->state = HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE;
-            return unflattenFence(&t->fence, nh, buffer, size, fds, numFds);
-        case ::android::FenceTime::Snapshot::State::SIGNAL_TIME:
-            t->state = HGraphicBufferProducer::FenceTimeSnapshot::State::SIGNAL_TIME;
-            if (size < sizeof(t->signalTimeNs)) {
-                return NO_MEMORY;
-            }
-            FlattenableUtils::read(buffer, size, t->signalTimeNs);
-            return NO_ERROR;
-    }
-    return NO_ERROR;
-}
-
-// Ref: frameworks/native/libs/gui/FrameTimestamps.cpp: FrameEventsDelta
-
-/**
- * \brief Return a lower bound on the size of the non-fd buffer required to
- * flatten `FrameEventsDelta`.
- *
- * \param[in] t The input `FrameEventsDelta`.
- * \return A lower bound on the size of the flat buffer.
- */
-constexpr size_t minFlattenedSize(
-        HGraphicBufferProducer::FrameEventsDelta const& /* t */) {
-    return sizeof(uint64_t) + // mFrameNumber
-            sizeof(uint8_t) + // mIndex
-            sizeof(uint8_t) + // mAddPostCompositeCalled
-            sizeof(uint8_t) + // mAddRetireCalled
-            sizeof(uint8_t) + // mAddReleaseCalled
-            sizeof(nsecs_t) + // mPostedTime
-            sizeof(nsecs_t) + // mRequestedPresentTime
-            sizeof(nsecs_t) + // mLatchTime
-            sizeof(nsecs_t) + // mFirstRefreshStartTime
-            sizeof(nsecs_t); // mLastRefreshStartTime
-}
-
-/**
- * \brief Return the size of the non-fd buffer required to flatten
- * `FrameEventsDelta`.
- *
- * \param[in] t The input `FrameEventsDelta`.
- * \return The required size of the flat buffer.
- */
-size_t getFlattenedSize(
-        HGraphicBufferProducer::FrameEventsDelta const& t) {
-    return minFlattenedSize(t) +
-            getFlattenedSize(t.gpuCompositionDoneFence) +
-            getFlattenedSize(t.displayPresentFence) +
-            getFlattenedSize(t.displayRetireFence) +
-            getFlattenedSize(t.releaseFence);
-};
-
-/**
- * \brief Return the number of file descriptors contained in
- * `FrameEventsDelta`.
- *
- * \param[in] t The input `FrameEventsDelta`.
- * \return The number of file descriptors contained in \p t.
- */
-size_t getFdCount(
-        HGraphicBufferProducer::FrameEventsDelta const& t) {
-    return getFdCount(t.gpuCompositionDoneFence) +
-            getFdCount(t.displayPresentFence) +
-            getFdCount(t.displayRetireFence) +
-            getFdCount(t.releaseFence);
-};
-
-/**
- * \brief Unflatten `FrameEventsDelta`.
- *
- * \param[out] t The destination `FrameEventsDelta`.
- * \param[out] nh The underlying array of native handles.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- *
- * If the return value is `NO_ERROR`, \p nh will have length 4, and it will be
- * populated with `nullptr` or newly created handles. Each non-null slot in \p
- * nh will need to be deleted manually with `native_handle_delete()`.
- */
-status_t unflatten(HGraphicBufferProducer::FrameEventsDelta* t,
-        std::vector<native_handle_t*>* nh,
-        void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
-    if (size < minFlattenedSize(*t)) {
-        return NO_MEMORY;
-    }
-    FlattenableUtils::read(buffer, size, t->frameNumber);
-
-    // These were written as uint8_t for alignment.
-    uint8_t temp = 0;
-    FlattenableUtils::read(buffer, size, temp);
-    size_t index = static_cast<size_t>(temp);
-    if (index >= ::android::FrameEventHistory::MAX_FRAME_HISTORY) {
-        return BAD_VALUE;
-    }
-    t->index = static_cast<uint32_t>(index);
-
-    FlattenableUtils::read(buffer, size, temp);
-    t->addPostCompositeCalled = static_cast<bool>(temp);
-    FlattenableUtils::read(buffer, size, temp);
-    t->addRetireCalled = static_cast<bool>(temp);
-    FlattenableUtils::read(buffer, size, temp);
-    t->addReleaseCalled = static_cast<bool>(temp);
-
-    FlattenableUtils::read(buffer, size, t->postedTimeNs);
-    FlattenableUtils::read(buffer, size, t->requestedPresentTimeNs);
-    FlattenableUtils::read(buffer, size, t->latchTimeNs);
-    FlattenableUtils::read(buffer, size, t->firstRefreshStartTimeNs);
-    FlattenableUtils::read(buffer, size, t->lastRefreshStartTimeNs);
-    FlattenableUtils::read(buffer, size, t->dequeueReadyTime);
-
-    // Fences
-    HGraphicBufferProducer::FenceTimeSnapshot* tSnapshot[4];
-    tSnapshot[0] = &t->gpuCompositionDoneFence;
-    tSnapshot[1] = &t->displayPresentFence;
-    tSnapshot[2] = &t->displayRetireFence;
-    tSnapshot[3] = &t->releaseFence;
-    nh->resize(4);
-    for (size_t snapshotIndex = 0; snapshotIndex < 4; ++snapshotIndex) {
-        status_t status = unflatten(
-                tSnapshot[snapshotIndex], &((*nh)[snapshotIndex]),
-                buffer, size, fds, numFds);
-        if (status != NO_ERROR) {
-            while (snapshotIndex > 0) {
-                --snapshotIndex;
-                if ((*nh)[snapshotIndex] != nullptr) {
-                    native_handle_delete((*nh)[snapshotIndex]);
-                }
-            }
-            return status;
-        }
-    }
-    return NO_ERROR;
-}
-
-/**
- * \brief Flatten `FrameEventsDelta`.
- *
- * \param[in] t The source `FrameEventsDelta`.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- *
- * This function will duplicate file descriptors contained in \p t.
- */
-// Ref: frameworks/native/libs/gui/FrameTimestamp.cpp:
-//      FrameEventsDelta::flatten
-status_t flatten(HGraphicBufferProducer::FrameEventsDelta const& t,
-        void*& buffer, size_t& size, int*& fds, size_t numFds) {
-    // Check that t.index is within a valid range.
-    if (t.index >= static_cast<uint32_t>(FrameEventHistory::MAX_FRAME_HISTORY)
-            || t.index > std::numeric_limits<uint8_t>::max()) {
-        return BAD_VALUE;
-    }
-
-    FlattenableUtils::write(buffer, size, t.frameNumber);
-
-    // These are static_cast to uint8_t for alignment.
-    FlattenableUtils::write(buffer, size, static_cast<uint8_t>(t.index));
-    FlattenableUtils::write(
-            buffer, size, static_cast<uint8_t>(t.addPostCompositeCalled));
-    FlattenableUtils::write(
-            buffer, size, static_cast<uint8_t>(t.addRetireCalled));
-    FlattenableUtils::write(
-            buffer, size, static_cast<uint8_t>(t.addReleaseCalled));
-
-    FlattenableUtils::write(buffer, size, t.postedTimeNs);
-    FlattenableUtils::write(buffer, size, t.requestedPresentTimeNs);
-    FlattenableUtils::write(buffer, size, t.latchTimeNs);
-    FlattenableUtils::write(buffer, size, t.firstRefreshStartTimeNs);
-    FlattenableUtils::write(buffer, size, t.lastRefreshStartTimeNs);
-    FlattenableUtils::write(buffer, size, t.dequeueReadyTime);
-
-    // Fences
-    HGraphicBufferProducer::FenceTimeSnapshot const* tSnapshot[4];
-    tSnapshot[0] = &t.gpuCompositionDoneFence;
-    tSnapshot[1] = &t.displayPresentFence;
-    tSnapshot[2] = &t.displayRetireFence;
-    tSnapshot[3] = &t.releaseFence;
-    for (size_t snapshotIndex = 0; snapshotIndex < 4; ++snapshotIndex) {
-        status_t status = flatten(
-                *(tSnapshot[snapshotIndex]), buffer, size, fds, numFds);
-        if (status != NO_ERROR) {
-            return status;
-        }
-    }
-    return NO_ERROR;
-}
-
-// Ref: frameworks/native/libs/gui/FrameTimestamps.cpp: FrameEventHistoryDelta
-
-/**
- * \brief Return the size of the non-fd buffer required to flatten
- * `HGraphicBufferProducer::FrameEventHistoryDelta`.
- *
- * \param[in] t The input `HGraphicBufferProducer::FrameEventHistoryDelta`.
- * \return The required size of the flat buffer.
- */
-size_t getFlattenedSize(
-        HGraphicBufferProducer::FrameEventHistoryDelta const& t) {
-    size_t size = 4 + // mDeltas.size()
-            sizeof(t.compositorTiming);
-    for (size_t i = 0; i < t.deltas.size(); ++i) {
-        size += getFlattenedSize(t.deltas[i]);
-    }
-    return size;
-}
-
-/**
- * \brief Return the number of file descriptors contained in
- * `HGraphicBufferProducer::FrameEventHistoryDelta`.
- *
- * \param[in] t The input `HGraphicBufferProducer::FrameEventHistoryDelta`.
- * \return The number of file descriptors contained in \p t.
- */
-size_t getFdCount(
-        HGraphicBufferProducer::FrameEventHistoryDelta const& t) {
-    size_t numFds = 0;
-    for (size_t i = 0; i < t.deltas.size(); ++i) {
-        numFds += getFdCount(t.deltas[i]);
-    }
-    return numFds;
-}
-
-/**
- * \brief Unflatten `FrameEventHistoryDelta`.
- *
- * \param[out] t The destination `FrameEventHistoryDelta`.
- * \param[out] nh The underlying array of arrays of native handles.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- *
- * If the return value is `NO_ERROR`, \p nh will be populated with `nullptr` or
- * newly created handles. The second dimension of \p nh will be 4. Each non-null
- * slot in \p nh will need to be deleted manually with `native_handle_delete()`.
- */
-status_t unflatten(
-        HGraphicBufferProducer::FrameEventHistoryDelta* t,
-        std::vector<std::vector<native_handle_t*> >* nh,
-        void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
-    if (size < 4) {
-        return NO_MEMORY;
-    }
-
-    FlattenableUtils::read(buffer, size, t->compositorTiming);
-
-    uint32_t deltaCount = 0;
-    FlattenableUtils::read(buffer, size, deltaCount);
-    if (static_cast<size_t>(deltaCount) >
-            ::android::FrameEventHistory::MAX_FRAME_HISTORY) {
-        return BAD_VALUE;
-    }
-    t->deltas.resize(deltaCount);
-    nh->resize(deltaCount);
-    for (size_t deltaIndex = 0; deltaIndex < deltaCount; ++deltaIndex) {
-        status_t status = unflatten(
-                &(t->deltas[deltaIndex]), &((*nh)[deltaIndex]),
-                buffer, size, fds, numFds);
-        if (status != NO_ERROR) {
-            return status;
-        }
-    }
-    return NO_ERROR;
-}
-
-/**
- * \brief Flatten `FrameEventHistoryDelta`.
- *
- * \param[in] t The source `FrameEventHistoryDelta`.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- *
- * This function will duplicate file descriptors contained in \p t.
- */
-status_t flatten(
-        HGraphicBufferProducer::FrameEventHistoryDelta const& t,
-        void*& buffer, size_t& size, int*& fds, size_t& numFds) {
-    if (t.deltas.size() > ::android::FrameEventHistory::MAX_FRAME_HISTORY) {
-        return BAD_VALUE;
-    }
-    if (size < getFlattenedSize(t)) {
-        return NO_MEMORY;
-    }
-
-    FlattenableUtils::write(buffer, size, t.compositorTiming);
-
-    FlattenableUtils::write(buffer, size, static_cast<uint32_t>(t.deltas.size()));
-    for (size_t deltaIndex = 0; deltaIndex < t.deltas.size(); ++deltaIndex) {
-        status_t status = flatten(t.deltas[deltaIndex], buffer, size, fds, numFds);
-        if (status != NO_ERROR) {
-            return status;
-        }
-    }
-    return NO_ERROR;
-}
-
-/**
- * \brief Wrap `::android::FrameEventHistoryData` in
- * `HGraphicBufferProducer::FrameEventHistoryDelta`.
- *
- * \param[out] t The wrapper of type
- * `HGraphicBufferProducer::FrameEventHistoryDelta`.
- * \param[out] nh The array of array of native handles that are referred to by
- * members of \p t.
- * \param[in] l The source `::android::FrameEventHistoryDelta`.
- *
- * On success, each member of \p nh will be either `nullptr` or a newly created
- * native handle. All the non-`nullptr` elements must be deleted individually
- * with `native_handle_delete()`.
- */
-bool wrapAs(HGraphicBufferProducer::FrameEventHistoryDelta* t,
-        std::vector<std::vector<native_handle_t*> >* nh,
-        ::android::FrameEventHistoryDelta const& l) {
-
-    size_t const baseSize = l.getFlattenedSize();
-    std::unique_ptr<uint8_t[]> baseBuffer(
-            new (std::nothrow) uint8_t[baseSize]);
-    if (!baseBuffer) {
-        return false;
-    }
-
-    size_t const baseNumFds = l.getFdCount();
-    std::unique_ptr<int[]> baseFds(
-            new (std::nothrow) int[baseNumFds]);
-    if (!baseFds) {
-        return false;
-    }
-
-    void* buffer = static_cast<void*>(baseBuffer.get());
-    size_t size = baseSize;
-    int* fds = baseFds.get();
-    size_t numFds = baseNumFds;
-    if (l.flatten(buffer, size, fds, numFds) != NO_ERROR) {
-        return false;
-    }
-
-    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
-    size = baseSize;
-    int const* constFds = static_cast<int const*>(baseFds.get());
-    numFds = baseNumFds;
-    if (unflatten(t, nh, constBuffer, size, constFds, numFds) != NO_ERROR) {
-        return false;
-    }
-
-    return true;
-}
-
-/**
- * \brief Convert `HGraphicBufferProducer::FrameEventHistoryDelta` to
- * `::android::FrameEventHistoryDelta`.
- *
- * \param[out] l The destination `::android::FrameEventHistoryDelta`.
- * \param[in] t The source `HGraphicBufferProducer::FrameEventHistoryDelta`.
- *
- * This function will duplicate all file descriptors contained in \p t.
- */
-bool convertTo(
-        ::android::FrameEventHistoryDelta* l,
-        HGraphicBufferProducer::FrameEventHistoryDelta const& t) {
-
-    size_t const baseSize = getFlattenedSize(t);
-    std::unique_ptr<uint8_t[]> baseBuffer(
-            new (std::nothrow) uint8_t[baseSize]);
-    if (!baseBuffer) {
-        return false;
-    }
-
-    size_t const baseNumFds = getFdCount(t);
-    std::unique_ptr<int[]> baseFds(
-            new (std::nothrow) int[baseNumFds]);
-    if (!baseFds) {
-        return false;
-    }
-
-    void* buffer = static_cast<void*>(baseBuffer.get());
-    size_t size = baseSize;
-    int* fds = static_cast<int*>(baseFds.get());
-    size_t numFds = baseNumFds;
-    if (flatten(t, buffer, size, fds, numFds) != NO_ERROR) {
-        return false;
-    }
-
-    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
-    size = baseSize;
-    int const* constFds = static_cast<int const*>(baseFds.get());
-    numFds = baseNumFds;
-    if (l->unflatten(constBuffer, size, constFds, numFds) != NO_ERROR) {
-        return false;
-    }
-
-    return true;
-}
-
-// Ref: frameworks/native/libs/ui/Region.cpp
-
-/**
- * \brief Return the size of the buffer required to flatten `Region`.
- *
- * \param[in] t The input `Region`.
- * \return The required size of the flat buffer.
- */
-size_t getFlattenedSize(Region const& t) {
-    return sizeof(uint32_t) + t.size() * sizeof(::android::Rect);
-}
-
-/**
- * \brief Unflatten `Region`.
- *
- * \param[out] t The destination `Region`.
- * \param[in,out] buffer The pointer to the flat buffer.
- * \param[in,out] size The size of the flat buffer.
- * \return `NO_ERROR` on success; other value on failure.
- */
-status_t unflatten(Region* t, void const*& buffer, size_t& size) {
-    if (size < sizeof(uint32_t)) {
-        return NO_MEMORY;
-    }
-
-    uint32_t numRects = 0;
-    FlattenableUtils::read(buffer, size, numRects);
-    if (size < numRects * sizeof(Rect)) {
-        return NO_MEMORY;
-    }
-    if (numRects > (UINT32_MAX / sizeof(Rect))) {
-        return NO_MEMORY;
-    }
-
-    t->resize(numRects);
-    for (size_t r = 0; r < numRects; ++r) {
-        ::android::Rect rect(::android::Rect::EMPTY_RECT);
-        status_t status = rect.unflatten(buffer, size);
-        if (status != NO_ERROR) {
-            return status;
-        }
-        FlattenableUtils::advance(buffer, size, sizeof(rect));
-        (*t)[r] = Rect{
-                static_cast<int32_t>(rect.left),
-                static_cast<int32_t>(rect.top),
-                static_cast<int32_t>(rect.right),
-                static_cast<int32_t>(rect.bottom)};
-    }
-    return NO_ERROR;
-}
-
-/**
- * \brief Flatten `Region`.
- *
- * \param[in] t The source `Region`.
- * \param[in,out] buffer The pointer to the flat buffer.
- * \param[in,out] size The size of the flat buffer.
- * \return `NO_ERROR` on success; other value on failure.
- */
-status_t flatten(Region const& t, void*& buffer, size_t& size) {
-    if (size < getFlattenedSize(t)) {
-        return NO_MEMORY;
-    }
-
-    FlattenableUtils::write(buffer, size, static_cast<uint32_t>(t.size()));
-    for (size_t r = 0; r < t.size(); ++r) {
-        ::android::Rect rect(
-                static_cast<int32_t>(t[r].left),
-                static_cast<int32_t>(t[r].top),
-                static_cast<int32_t>(t[r].right),
-                static_cast<int32_t>(t[r].bottom));
-        status_t status = rect.flatten(buffer, size);
-        if (status != NO_ERROR) {
-            return status;
-        }
-        FlattenableUtils::advance(buffer, size, sizeof(rect));
-    }
-    return NO_ERROR;
-}
-
-/**
- * \brief Convert `::android::Region` to `Region`.
- *
- * \param[out] t The destination `Region`.
- * \param[in] l The source `::android::Region`.
- */
-// convert: ::android::Region -> Region
-bool convertTo(Region* t, ::android::Region const& l) {
-    size_t const baseSize = l.getFlattenedSize();
-    std::unique_ptr<uint8_t[]> baseBuffer(
-            new (std::nothrow) uint8_t[baseSize]);
-    if (!baseBuffer) {
-        return false;
-    }
-
-    void* buffer = static_cast<void*>(baseBuffer.get());
-    size_t size = baseSize;
-    if (l.flatten(buffer, size) != NO_ERROR) {
-        return false;
-    }
-
-    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
-    size = baseSize;
-    if (unflatten(t, constBuffer, size) != NO_ERROR) {
-        return false;
-    }
-
-    return true;
-}
-
-/**
- * \brief Convert `Region` to `::android::Region`.
- *
- * \param[out] l The destination `::android::Region`.
- * \param[in] t The source `Region`.
- */
-// convert: Region -> ::android::Region
-bool convertTo(::android::Region* l, Region const& t) {
-    size_t const baseSize = getFlattenedSize(t);
-    std::unique_ptr<uint8_t[]> baseBuffer(
-            new (std::nothrow) uint8_t[baseSize]);
-    if (!baseBuffer) {
-        return false;
-    }
-
-    void* buffer = static_cast<void*>(baseBuffer.get());
-    size_t size = baseSize;
-    if (flatten(t, buffer, size) != NO_ERROR) {
-        return false;
-    }
-
-    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
-    size = baseSize;
-    if (l->unflatten(constBuffer, size) != NO_ERROR) {
-        return false;
-    }
-
-    return true;
-}
-
-// Ref: frameworks/native/libs/gui/BGraphicBufferProducer.cpp:
-//      BGraphicBufferProducer::QueueBufferInput
-
-/**
- * \brief Return a lower bound on the size of the buffer required to flatten
- * `HGraphicBufferProducer::QueueBufferInput`.
- *
- * \param[in] t The input `HGraphicBufferProducer::QueueBufferInput`.
- * \return A lower bound on the size of the flat buffer.
- */
-constexpr size_t minFlattenedSize(
-        HGraphicBufferProducer::QueueBufferInput const& /* t */) {
-    return sizeof(int64_t) + // timestamp
-            sizeof(int) + // isAutoTimestamp
-            sizeof(android_dataspace) + // dataSpace
-            sizeof(::android::Rect) + // crop
-            sizeof(int) + // scalingMode
-            sizeof(uint32_t) + // transform
-            sizeof(uint32_t) + // stickyTransform
-            sizeof(bool); // getFrameTimestamps
-}
-
-/**
- * \brief Return the size of the buffer required to flatten
- * `HGraphicBufferProducer::QueueBufferInput`.
- *
- * \param[in] t The input `HGraphicBufferProducer::QueueBufferInput`.
- * \return The required size of the flat buffer.
- */
-size_t getFlattenedSize(HGraphicBufferProducer::QueueBufferInput const& t) {
-    return minFlattenedSize(t) +
-            getFenceFlattenedSize(t.fence) +
-            getFlattenedSize(t.surfaceDamage) +
-            sizeof(HdrMetadata::validTypes);
-}
-
-/**
- * \brief Return the number of file descriptors contained in
- * `HGraphicBufferProducer::QueueBufferInput`.
- *
- * \param[in] t The input `HGraphicBufferProducer::QueueBufferInput`.
- * \return The number of file descriptors contained in \p t.
- */
-size_t getFdCount(
-        HGraphicBufferProducer::QueueBufferInput const& t) {
-    return getFenceFdCount(t.fence);
-}
-
-/**
- * \brief Flatten `HGraphicBufferProducer::QueueBufferInput`.
- *
- * \param[in] t The source `HGraphicBufferProducer::QueueBufferInput`.
- * \param[out] nh The native handle cloned from `t.fence`.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- *
- * This function will duplicate the file descriptor in `t.fence`. */
-status_t flatten(HGraphicBufferProducer::QueueBufferInput const& t,
-        native_handle_t** nh,
-        void*& buffer, size_t& size, int*& fds, size_t& numFds) {
-    if (size < getFlattenedSize(t)) {
-        return NO_MEMORY;
-    }
-
-    FlattenableUtils::write(buffer, size, t.timestamp);
-    FlattenableUtils::write(buffer, size, static_cast<int>(t.isAutoTimestamp));
-    FlattenableUtils::write(buffer, size,
-            static_cast<android_dataspace_t>(t.dataSpace));
-    FlattenableUtils::write(buffer, size, ::android::Rect(
-            static_cast<int32_t>(t.crop.left),
-            static_cast<int32_t>(t.crop.top),
-            static_cast<int32_t>(t.crop.right),
-            static_cast<int32_t>(t.crop.bottom)));
-    FlattenableUtils::write(buffer, size, static_cast<int>(t.scalingMode));
-    FlattenableUtils::write(buffer, size, t.transform);
-    FlattenableUtils::write(buffer, size, t.stickyTransform);
-    FlattenableUtils::write(buffer, size, t.getFrameTimestamps);
-
-    *nh = t.fence.getNativeHandle() == nullptr ?
-            nullptr : native_handle_clone(t.fence);
-    status_t status = flattenFence(hidl_handle(*nh), buffer, size, fds, numFds);
-    if (status != NO_ERROR) {
-        return status;
-    }
-    status = flatten(t.surfaceDamage, buffer, size);
-    if (status != NO_ERROR) {
-        return status;
-    }
-    FlattenableUtils::write(buffer, size, decltype(HdrMetadata::validTypes)(0));
-    return NO_ERROR;
-}
-
-/**
- * \brief Unflatten `HGraphicBufferProducer::QueueBufferInput`.
- *
- * \param[out] t The destination `HGraphicBufferProducer::QueueBufferInput`.
- * \param[out] nh The underlying native handle for `t->fence`.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- *
- * If the return value is `NO_ERROR` and `t->fence` contains a valid file
- * descriptor, \p nh will be a newly created native handle holding that file
- * descriptor. \p nh needs to be deleted with `native_handle_delete()`
- * afterwards.
- */
-status_t unflatten(
-        HGraphicBufferProducer::QueueBufferInput* t, native_handle_t** nh,
-        void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
-    if (size < minFlattenedSize(*t)) {
-        return NO_MEMORY;
-    }
-
-    FlattenableUtils::read(buffer, size, t->timestamp);
-    int lIsAutoTimestamp;
-    FlattenableUtils::read(buffer, size, lIsAutoTimestamp);
-    t->isAutoTimestamp = static_cast<int32_t>(lIsAutoTimestamp);
-    android_dataspace_t lDataSpace;
-    FlattenableUtils::read(buffer, size, lDataSpace);
-    t->dataSpace = static_cast<Dataspace>(lDataSpace);
-    Rect lCrop;
-    FlattenableUtils::read(buffer, size, lCrop);
-    t->crop = Rect{
-            static_cast<int32_t>(lCrop.left),
-            static_cast<int32_t>(lCrop.top),
-            static_cast<int32_t>(lCrop.right),
-            static_cast<int32_t>(lCrop.bottom)};
-    int lScalingMode;
-    FlattenableUtils::read(buffer, size, lScalingMode);
-    t->scalingMode = static_cast<int32_t>(lScalingMode);
-    FlattenableUtils::read(buffer, size, t->transform);
-    FlattenableUtils::read(buffer, size, t->stickyTransform);
-    FlattenableUtils::read(buffer, size, t->getFrameTimestamps);
-
-    status_t status = unflattenFence(&(t->fence), nh,
-            buffer, size, fds, numFds);
-    if (status != NO_ERROR) {
-        return status;
-    }
-    // HdrMetadata ignored
-    return unflatten(&(t->surfaceDamage), buffer, size);
-}
-
-/**
- * \brief Wrap `BGraphicBufferProducer::QueueBufferInput` in
- * `HGraphicBufferProducer::QueueBufferInput`.
- *
- * \param[out] t The wrapper of type
- * `HGraphicBufferProducer::QueueBufferInput`.
- * \param[out] nh The underlying native handle for `t->fence`.
- * \param[in] l The source `BGraphicBufferProducer::QueueBufferInput`.
- *
- * If the return value is `true` and `t->fence` contains a valid file
- * descriptor, \p nh will be a newly created native handle holding that file
- * descriptor. \p nh needs to be deleted with `native_handle_delete()`
- * afterwards.
- */
-bool wrapAs(
-        HGraphicBufferProducer::QueueBufferInput* t,
-        native_handle_t** nh,
-        BGraphicBufferProducer::QueueBufferInput const& l) {
-
-    size_t const baseSize = l.getFlattenedSize();
-    std::unique_ptr<uint8_t[]> baseBuffer(
-            new (std::nothrow) uint8_t[baseSize]);
-    if (!baseBuffer) {
-        return false;
-    }
-
-    size_t const baseNumFds = l.getFdCount();
-    std::unique_ptr<int[]> baseFds(
-            new (std::nothrow) int[baseNumFds]);
-    if (!baseFds) {
-        return false;
-    }
-
-    void* buffer = static_cast<void*>(baseBuffer.get());
-    size_t size = baseSize;
-    int* fds = baseFds.get();
-    size_t numFds = baseNumFds;
-    if (l.flatten(buffer, size, fds, numFds) != NO_ERROR) {
-        return false;
-    }
-
-    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
-    size = baseSize;
-    int const* constFds = static_cast<int const*>(baseFds.get());
-    numFds = baseNumFds;
-    if (unflatten(t, nh, constBuffer, size, constFds, numFds) != NO_ERROR) {
-        return false;
-    }
-
-    return true;
-}
-
-/**
- * \brief Convert `HGraphicBufferProducer::QueueBufferInput` to
- * `BGraphicBufferProducer::QueueBufferInput`.
- *
- * \param[out] l The destination `BGraphicBufferProducer::QueueBufferInput`.
- * \param[in] t The source `HGraphicBufferProducer::QueueBufferInput`.
- *
- * If `t.fence` has a valid file descriptor, it will be duplicated.
- */
-bool convertTo(
-        BGraphicBufferProducer::QueueBufferInput* l,
-        HGraphicBufferProducer::QueueBufferInput const& t) {
-
-    size_t const baseSize = getFlattenedSize(t);
-    std::unique_ptr<uint8_t[]> baseBuffer(
-            new (std::nothrow) uint8_t[baseSize]);
-    if (!baseBuffer) {
-        return false;
-    }
-
-    size_t const baseNumFds = getFdCount(t);
-    std::unique_ptr<int[]> baseFds(
-            new (std::nothrow) int[baseNumFds]);
-    if (!baseFds) {
-        return false;
-    }
-
-    void* buffer = static_cast<void*>(baseBuffer.get());
-    size_t size = baseSize;
-    int* fds = baseFds.get();
-    size_t numFds = baseNumFds;
-    native_handle_t* nh;
-    if (flatten(t, &nh, buffer, size, fds, numFds) != NO_ERROR) {
-        return false;
-    }
-
-    void const* constBuffer = static_cast<void const*>(baseBuffer.get());
-    size = baseSize;
-    int const* constFds = static_cast<int const*>(baseFds.get());
-    numFds = baseNumFds;
-    if (l->unflatten(constBuffer, size, constFds, numFds) != NO_ERROR) {
-        if (nh != nullptr) {
-            native_handle_close(nh);
-            native_handle_delete(nh);
-        }
-        return false;
-    }
-
-    native_handle_delete(nh);
-    return true;
-}
-
-// Ref: frameworks/native/libs/gui/BGraphicBufferProducer.cpp:
-//      BGraphicBufferProducer::QueueBufferOutput
-
-/**
- * \brief Wrap `BGraphicBufferProducer::QueueBufferOutput` in
- * `HGraphicBufferProducer::QueueBufferOutput`.
- *
- * \param[out] t The wrapper of type
- * `HGraphicBufferProducer::QueueBufferOutput`.
- * \param[out] nh The array of array of native handles that are referred to by
- * members of \p t.
- * \param[in] l The source `BGraphicBufferProducer::QueueBufferOutput`.
- *
- * On success, each member of \p nh will be either `nullptr` or a newly created
- * native handle. All the non-`nullptr` elements must be deleted individually
- * with `native_handle_delete()`.
- */
-// wrap: BGraphicBufferProducer::QueueBufferOutput ->
-// HGraphicBufferProducer::QueueBufferOutput
-bool wrapAs(HGraphicBufferProducer::QueueBufferOutput* t,
-        std::vector<std::vector<native_handle_t*> >* nh,
-        BGraphicBufferProducer::QueueBufferOutput const& l) {
-    if (!wrapAs(&(t->frameTimestamps), nh, l.frameTimestamps)) {
-        return false;
-    }
-    t->width = l.width;
-    t->height = l.height;
-    t->transformHint = l.transformHint;
-    t->numPendingBuffers = l.numPendingBuffers;
-    t->nextFrameNumber = l.nextFrameNumber;
-    t->bufferReplaced = l.bufferReplaced;
-    return true;
-}
-
-/**
- * \brief Convert `HGraphicBufferProducer::QueueBufferOutput` to
- * `BGraphicBufferProducer::QueueBufferOutput`.
- *
- * \param[out] l The destination `BGraphicBufferProducer::QueueBufferOutput`.
- * \param[in] t The source `HGraphicBufferProducer::QueueBufferOutput`.
- *
- * This function will duplicate all file descriptors contained in \p t.
- */
-// convert: HGraphicBufferProducer::QueueBufferOutput ->
-// BGraphicBufferProducer::QueueBufferOutput
-bool convertTo(
-        BGraphicBufferProducer::QueueBufferOutput* l,
-        HGraphicBufferProducer::QueueBufferOutput const& t) {
-    if (!convertTo(&(l->frameTimestamps), t.frameTimestamps)) {
-        return false;
-    }
-    l->width = t.width;
-    l->height = t.height;
-    l->transformHint = t.transformHint;
-    l->numPendingBuffers = t.numPendingBuffers;
-    l->nextFrameNumber = t.nextFrameNumber;
-    l->bufferReplaced = t.bufferReplaced;
-    return true;
-}
-
-/**
- * \brief Convert `BGraphicBufferProducer::DisconnectMode` to
- * `HGraphicBufferProducer::DisconnectMode`.
- *
- * \param[in] l The source `BGraphicBufferProducer::DisconnectMode`.
- * \return The corresponding `HGraphicBufferProducer::DisconnectMode`.
- */
-HGraphicBufferProducer::DisconnectMode toHidlDisconnectMode(
-        BGraphicBufferProducer::DisconnectMode l) {
-    switch (l) {
-        case BGraphicBufferProducer::DisconnectMode::Api:
-            return HGraphicBufferProducer::DisconnectMode::API;
-        case BGraphicBufferProducer::DisconnectMode::AllLocal:
-            return HGraphicBufferProducer::DisconnectMode::ALL_LOCAL;
-    }
-    return HGraphicBufferProducer::DisconnectMode::API;
-}
-
-/**
- * \brief Convert `HGraphicBufferProducer::DisconnectMode` to
- * `BGraphicBufferProducer::DisconnectMode`.
- *
- * \param[in] l The source `HGraphicBufferProducer::DisconnectMode`.
- * \return The corresponding `BGraphicBufferProducer::DisconnectMode`.
- */
-BGraphicBufferProducer::DisconnectMode toGuiDisconnectMode(
-        HGraphicBufferProducer::DisconnectMode t) {
-    switch (t) {
-        case HGraphicBufferProducer::DisconnectMode::API:
-            return BGraphicBufferProducer::DisconnectMode::Api;
-        case HGraphicBufferProducer::DisconnectMode::ALL_LOCAL:
-            return BGraphicBufferProducer::DisconnectMode::AllLocal;
-    }
-    return BGraphicBufferProducer::DisconnectMode::Api;
-}
-
-}  // namespace conversion
-}  // namespace android
-
diff --git a/media/libstagefright/bqhelper/GraphicBufferSource.cpp b/media/libstagefright/bqhelper/GraphicBufferSource.cpp
index 68abcb5..59317e7 100644
--- a/media/libstagefright/bqhelper/GraphicBufferSource.cpp
+++ b/media/libstagefright/bqhelper/GraphicBufferSource.cpp
@@ -32,7 +32,11 @@
 #include <media/hardware/MetadataBufferType.h>
 #include <ui/GraphicBuffer.h>
 #include <gui/BufferItem.h>
+#include <gui/BufferQueue.h>
+#include <gui/bufferqueue/1.0/WGraphicBufferProducer.h>
 #include <gui/bufferqueue/2.0/B2HGraphicBufferProducer.h>
+#include <gui/IGraphicBufferProducer.h>
+#include <gui/IGraphicBufferConsumer.h>
 #include <media/hardware/HardwareAPI.h>
 
 #include <inttypes.h>
@@ -389,6 +393,18 @@
     }
 }
 
+sp<IGraphicBufferProducer> GraphicBufferSource::getIGraphicBufferProducer() const {
+    return mProducer;
+}
+
+sp<::android::hardware::graphics::bufferqueue::V1_0::IGraphicBufferProducer>
+GraphicBufferSource::getHGraphicBufferProducer_V1_0() const {
+    using TWGraphicBufferProducer = ::android::TWGraphicBufferProducer<
+        ::android::hardware::graphics::bufferqueue::V1_0::IGraphicBufferProducer>;
+
+    return new TWGraphicBufferProducer(getIGraphicBufferProducer());
+}
+
 sp<::android::hardware::graphics::bufferqueue::V2_0::IGraphicBufferProducer>
 GraphicBufferSource::getHGraphicBufferProducer() const {
     return new ::android::hardware::graphics::bufferqueue::V2_0::utils::
diff --git a/media/libstagefright/bqhelper/WProducerListener.cpp b/media/libstagefright/bqhelper/WProducerListener.cpp
deleted file mode 100644
index 2ca13be..0000000
--- a/media/libstagefright/bqhelper/WProducerListener.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2016, 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.
- */
-
-#include <media/stagefright/bqhelper/WProducerListener.h>
-
-namespace android {
-
-// TWProducerListener
-TWProducerListener::TWProducerListener(
-        sp<BProducerListener> const& base):
-    mBase(base) {
-}
-
-Return<void> TWProducerListener::onBufferReleased() {
-    mBase->onBufferReleased();
-    return Void();
-}
-
-Return<bool> TWProducerListener::needsReleaseNotify() {
-    return mBase->needsReleaseNotify();
-}
-
-// LWProducerListener
-LWProducerListener::LWProducerListener(
-        sp<HProducerListener> const& base):
-    mBase(base) {
-}
-
-void LWProducerListener::onBufferReleased() {
-    mBase->onBufferReleased();
-}
-
-bool LWProducerListener::needsReleaseNotify() {
-    return static_cast<bool>(mBase->needsReleaseNotify());
-}
-
-}  // namespace android
diff --git a/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/Conversion.h b/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/Conversion.h
deleted file mode 100644
index 60d8c1e..0000000
--- a/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/Conversion.h
+++ /dev/null
@@ -1,769 +0,0 @@
-/*
- * Copyright 2016, 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.
- */
-
-#ifndef MEDIA_STAGEFRIGHT_BQHELPER_CONVERSION_H_
-#define MEDIA_STAGEFRIGHT_BQHELPER_CONVERSION_H_
-
-#include <vector>
-#include <list>
-
-#include <unistd.h>
-
-#include <hidl/MQDescriptor.h>
-#include <hidl/Status.h>
-#include <hidlmemory/mapping.h>
-
-#include <binder/Binder.h>
-#include <binder/Status.h>
-#include <ui/FenceTime.h>
-#include <cutils/native_handle.h>
-#include <gui/IGraphicBufferProducer.h>
-
-#include <media/hardware/VideoAPI.h>
-
-#include <android/hidl/memory/1.0/IMemory.h>
-#include <android/hardware/graphics/bufferqueue/1.0/IProducerListener.h>
-
-namespace android {
-namespace conversion {
-
-using ::android::hardware::hidl_array;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::hidl_handle;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::sp;
-using ::android::status_t;
-
-using ::android::String8;
-
-using ::android::hardware::media::V1_0::Rect;
-using ::android::hardware::media::V1_0::Region;
-
-using ::android::hardware::graphics::common::V1_0::Dataspace;
-
-using ::android::hardware::graphics::common::V1_0::PixelFormat;
-
-using ::android::hardware::media::V1_0::AnwBuffer;
-using ::android::GraphicBuffer;
-
-typedef ::android::hardware::graphics::bufferqueue::V1_0::IGraphicBufferProducer
-        HGraphicBufferProducer;
-typedef ::android::IGraphicBufferProducer
-        BGraphicBufferProducer;
-
-// native_handle_t helper functions.
-
-/**
- * \brief Take an fd and create a native handle containing only the given fd.
- * The created handle will need to be deleted manually with
- * `native_handle_delete()`.
- *
- * \param[in] fd The source file descriptor (of type `int`).
- * \return The create `native_handle_t*` that contains the given \p fd. If the
- * supplied \p fd is negative, the created native handle will contain no file
- * descriptors.
- *
- * If the native handle cannot be created, the return value will be
- * `nullptr`.
- *
- * This function does not duplicate the file descriptor.
- */
-native_handle_t* native_handle_create_from_fd(int fd);
-
-/**
- * \brief Extract a file descriptor from a native handle.
- *
- * \param[in] nh The source `native_handle_t*`.
- * \param[in] index The index of the file descriptor in \p nh to read from. This
- * input has the default value of `0`.
- * \return The `index`-th file descriptor in \p nh. If \p nh does not have
- * enough file descriptors, the returned value will be `-1`.
- *
- * This function does not duplicate the file descriptor.
- */
-int native_handle_read_fd(native_handle_t const* nh, int index = 0);
-
-/**
- * Conversion functions
- * ====================
- *
- * There are two main directions of conversion:
- * - `inTargetType(...)`: Create a wrapper whose lifetime depends on the
- *   input. The wrapper has type `TargetType`.
- * - `toTargetType(...)`: Create a standalone object of type `TargetType` that
- *   corresponds to the input. The lifetime of the output does not depend on the
- *   lifetime of the input.
- * - `wrapIn(TargetType*, ...)`: Same as `inTargetType()`, but for `TargetType`
- *   that cannot be copied and/or moved efficiently, or when there are multiple
- *   output arguments.
- * - `convertTo(TargetType*, ...)`: Same as `toTargetType()`, but for
- *   `TargetType` that cannot be copied and/or moved efficiently, or when there
- *   are multiple output arguments.
- *
- * `wrapIn()` and `convertTo()` functions will take output arguments before
- * input arguments. Some of these functions might return a value to indicate
- * success or error.
- *
- * In converting or wrapping something as a Treble type that contains a
- * `hidl_handle`, `native_handle_t*` will need to be created and returned as
- * an additional output argument, hence only `wrapIn()` or `convertTo()` would
- * be available. The caller must call `native_handle_delete()` to deallocate the
- * returned native handle when it is no longer needed.
- *
- * For types that contain file descriptors, `inTargetType()` and `wrapAs()` do
- * not perform duplication of file descriptors, while `toTargetType()` and
- * `convertTo()` do.
- */
-
-/**
- * \brief Convert `Return<void>` to `binder::Status`.
- *
- * \param[in] t The source `Return<void>`.
- * \return The corresponding `binder::Status`.
- */
-// convert: Return<void> -> ::android::binder::Status
-::android::binder::Status toBinderStatus(Return<void> const& t);
-
-/**
- * \brief Convert `Return<void>` to `status_t`. This is for legacy binder calls.
- *
- * \param[in] t The source `Return<void>`.
- * \return The corresponding `status_t`.
- */
-// convert: Return<void> -> status_t
-status_t toStatusT(Return<void> const& t);
-
-/**
- * \brief Wrap `native_handle_t*` in `hidl_handle`.
- *
- * \param[in] nh The source `native_handle_t*`.
- * \return The `hidl_handle` that points to \p nh.
- */
-// wrap: native_handle_t* -> hidl_handle
-hidl_handle inHidlHandle(native_handle_t const* nh);
-
-/**
- * \brief Convert `int32_t` to `Dataspace`.
- *
- * \param[in] l The source `int32_t`.
- * \result The corresponding `Dataspace`.
- */
-// convert: int32_t -> Dataspace
-Dataspace toHardwareDataspace(int32_t l);
-
-/**
- * \brief Convert `Dataspace` to `int32_t`.
- *
- * \param[in] t The source `Dataspace`.
- * \result The corresponding `int32_t`.
- */
-// convert: Dataspace -> int32_t
-int32_t toRawDataspace(Dataspace const& t);
-
-/**
- * \brief Wrap an opaque buffer inside a `hidl_vec<uint8_t>`.
- *
- * \param[in] l The pointer to the beginning of the opaque buffer.
- * \param[in] size The size of the buffer.
- * \return A `hidl_vec<uint8_t>` that points to the buffer.
- */
-// wrap: void*, size_t -> hidl_vec<uint8_t>
-hidl_vec<uint8_t> inHidlBytes(void const* l, size_t size);
-
-/**
- * \brief Create a `hidl_vec<uint8_t>` that is a copy of an opaque buffer.
- *
- * \param[in] l The pointer to the beginning of the opaque buffer.
- * \param[in] size The size of the buffer.
- * \return A `hidl_vec<uint8_t>` that is a copy of the input buffer.
- */
-// convert: void*, size_t -> hidl_vec<uint8_t>
-hidl_vec<uint8_t> toHidlBytes(void const* l, size_t size);
-
-/**
- * \brief Wrap `GraphicBuffer` in `AnwBuffer`.
- *
- * \param[out] t The wrapper of type `AnwBuffer`.
- * \param[in] l The source `GraphicBuffer`.
- */
-// wrap: GraphicBuffer -> AnwBuffer
-void wrapAs(AnwBuffer* t, GraphicBuffer const& l);
-
-/**
- * \brief Convert `AnwBuffer` to `GraphicBuffer`.
- *
- * \param[out] l The destination `GraphicBuffer`.
- * \param[in] t The source `AnwBuffer`.
- *
- * This function will duplicate all file descriptors in \p t.
- */
-// convert: AnwBuffer -> GraphicBuffer
-// Ref: frameworks/native/libs/ui/GraphicBuffer.cpp: GraphicBuffer::flatten
-bool convertTo(GraphicBuffer* l, AnwBuffer const& t);
-
-/**
- * Conversion functions for types outside media
- * ============================================
- *
- * Some objects in libui and libgui that were made to go through binder calls do
- * not expose ways to read or write their fields to the public. To pass an
- * object of this kind through the HIDL boundary, translation functions need to
- * work around the access restriction by using the publicly available
- * `flatten()` and `unflatten()` functions.
- *
- * All `flatten()` and `unflatten()` overloads follow the same convention as
- * follows:
- *
- *     status_t flatten(ObjectType const& object,
- *                      [OtherType const& other, ...]
- *                      void*& buffer, size_t& size,
- *                      int*& fds, size_t& numFds)
- *
- *     status_t unflatten(ObjectType* object,
- *                        [OtherType* other, ...,]
- *                        void*& buffer, size_t& size,
- *                        int*& fds, size_t& numFds)
- *
- * The number of `other` parameters varies depending on the `ObjectType`. For
- * example, in the process of unflattening an object that contains
- * `hidl_handle`, `other` is needed to hold `native_handle_t` objects that will
- * be created.
- *
- * The last four parameters always work the same way in all overloads of
- * `flatten()` and `unflatten()`:
- * - For `flatten()`, `buffer` is the pointer to the non-fd buffer to be filled,
- *   `size` is the size (in bytes) of the non-fd buffer pointed to by `buffer`,
- *   `fds` is the pointer to the fd buffer to be filled, and `numFds` is the
- *   size (in ints) of the fd buffer pointed to by `fds`.
- * - For `unflatten()`, `buffer` is the pointer to the non-fd buffer to be read
- *   from, `size` is the size (in bytes) of the non-fd buffer pointed to by
- *   `buffer`, `fds` is the pointer to the fd buffer to be read from, and
- *   `numFds` is the size (in ints) of the fd buffer pointed to by `fds`.
- * - After a successful call to `flatten()` or `unflatten()`, `buffer` and `fds`
- *   will be advanced, while `size` and `numFds` will be decreased to reflect
- *   how much storage/data of the two buffers (fd and non-fd) have been used.
- * - After an unsuccessful call, the values of `buffer`, `size`, `fds` and
- *   `numFds` are invalid.
- *
- * The return value of a successful `flatten()` or `unflatten()` call will be
- * `OK` (also aliased as `NO_ERROR`). Any other values indicate a failure.
- *
- * For each object type that supports flattening, there will be two accompanying
- * functions: `getFlattenedSize()` and `getFdCount()`. `getFlattenedSize()` will
- * return the size of the non-fd buffer that the object will need for
- * flattening. `getFdCount()` will return the size of the fd buffer that the
- * object will need for flattening.
- *
- * The set of these four functions, `getFlattenedSize()`, `getFdCount()`,
- * `flatten()` and `unflatten()`, are similar to functions of the same name in
- * the abstract class `Flattenable`. The only difference is that functions in
- * this file are not member functions of the object type. For example, we write
- *
- *     flatten(x, buffer, size, fds, numFds)
- *
- * instead of
- *
- *     x.flatten(buffer, size, fds, numFds)
- *
- * because we cannot modify the type of `x`.
- *
- * There is one exception to the naming convention: `hidl_handle` that
- * represents a fence. The four functions for this "Fence" type have the word
- * "Fence" attched to their names because the object type, which is
- * `hidl_handle`, does not carry the special meaning that the object itself can
- * only contain zero or one file descriptor.
- */
-
-// Ref: frameworks/native/libs/ui/Fence.cpp
-
-/**
- * \brief Return the size of the non-fd buffer required to flatten a fence.
- *
- * \param[in] fence The input fence of type `hidl_handle`.
- * \return The required size of the flat buffer.
- *
- * The current version of this function always returns 4, which is the number of
- * bytes required to store the number of file descriptors contained in the fd
- * part of the flat buffer.
- */
-size_t getFenceFlattenedSize(hidl_handle const& fence);
-
-/**
- * \brief Return the number of file descriptors contained in a fence.
- *
- * \param[in] fence The input fence of type `hidl_handle`.
- * \return `0` if \p fence does not contain a valid file descriptor, or `1`
- * otherwise.
- */
-size_t getFenceFdCount(hidl_handle const& fence);
-
-/**
- * \brief Unflatten `Fence` to `hidl_handle`.
- *
- * \param[out] fence The destination `hidl_handle`.
- * \param[out] nh The underlying native handle.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- *
- * If the return value is `NO_ERROR`, \p nh will point to a newly created
- * native handle, which needs to be deleted with `native_handle_delete()`
- * afterwards.
- */
-status_t unflattenFence(hidl_handle* fence, native_handle_t** nh,
-        void const*& buffer, size_t& size, int const*& fds, size_t& numFds);
-
-/**
- * \brief Flatten `hidl_handle` as `Fence`.
- *
- * \param[in] t The source `hidl_handle`.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- */
-status_t flattenFence(hidl_handle const& fence,
-        void*& buffer, size_t& size, int*& fds, size_t& numFds);
-
-/**
- * \brief Wrap `Fence` in `hidl_handle`.
- *
- * \param[out] t The wrapper of type `hidl_handle`.
- * \param[out] nh The native handle pointed to by \p t.
- * \param[in] l The source `Fence`.
- *
- * On success, \p nh will hold a newly created native handle, which must be
- * deleted manually with `native_handle_delete()` afterwards.
- */
-// wrap: Fence -> hidl_handle
-bool wrapAs(hidl_handle* t, native_handle_t** nh, Fence const& l);
-
-/**
- * \brief Convert `hidl_handle` to `Fence`.
- *
- * \param[out] l The destination `Fence`. `l` must not have been used
- * (`l->isValid()` must return `false`) before this function is called.
- * \param[in] t The source `hidl_handle`.
- *
- * If \p t contains a valid file descriptor, it will be duplicated.
- */
-// convert: hidl_handle -> Fence
-bool convertTo(Fence* l, hidl_handle const& t);
-
-// Ref: frameworks/native/libs/ui/FenceTime.cpp: FenceTime::Snapshot
-
-/**
- * \brief Return the size of the non-fd buffer required to flatten
- * `FenceTimeSnapshot`.
- *
- * \param[in] t The input `FenceTimeSnapshot`.
- * \return The required size of the flat buffer.
- */
-size_t getFlattenedSize(HGraphicBufferProducer::FenceTimeSnapshot const& t);
-
-/**
- * \brief Return the number of file descriptors contained in
- * `FenceTimeSnapshot`.
- *
- * \param[in] t The input `FenceTimeSnapshot`.
- * \return The number of file descriptors contained in \p snapshot.
- */
-size_t getFdCount(HGraphicBufferProducer::FenceTimeSnapshot const& t);
-
-/**
- * \brief Flatten `FenceTimeSnapshot`.
- *
- * \param[in] t The source `FenceTimeSnapshot`.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- *
- * This function will duplicate the file descriptor in `t.fence` if `t.state ==
- * FENCE`.
- */
-status_t flatten(HGraphicBufferProducer::FenceTimeSnapshot const& t,
-        void*& buffer, size_t& size, int*& fds, size_t& numFds);
-
-/**
- * \brief Unflatten `FenceTimeSnapshot`.
- *
- * \param[out] t The destination `FenceTimeSnapshot`.
- * \param[out] nh The underlying native handle.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- *
- * If the return value is `NO_ERROR` and the constructed snapshot contains a
- * file descriptor, \p nh will be created to hold that file descriptor. In this
- * case, \p nh needs to be deleted with `native_handle_delete()` afterwards.
- */
-status_t unflatten(
-        HGraphicBufferProducer::FenceTimeSnapshot* t, native_handle_t** nh,
-        void const*& buffer, size_t& size, int const*& fds, size_t& numFds);
-
-// Ref: frameworks/native/libs/gui/FrameTimestamps.cpp: FrameEventsDelta
-
-/**
- * \brief Return the size of the non-fd buffer required to flatten
- * `FrameEventsDelta`.
- *
- * \param[in] t The input `FrameEventsDelta`.
- * \return The required size of the flat buffer.
- */
-size_t getFlattenedSize(HGraphicBufferProducer::FrameEventsDelta const& t);
-
-/**
- * \brief Return the number of file descriptors contained in
- * `FrameEventsDelta`.
- *
- * \param[in] t The input `FrameEventsDelta`.
- * \return The number of file descriptors contained in \p t.
- */
-size_t getFdCount(HGraphicBufferProducer::FrameEventsDelta const& t);
-
-/**
- * \brief Unflatten `FrameEventsDelta`.
- *
- * \param[out] t The destination `FrameEventsDelta`.
- * \param[out] nh The underlying array of native handles.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- *
- * If the return value is `NO_ERROR`, \p nh will have length 4, and it will be
- * populated with `nullptr` or newly created handles. Each non-null slot in \p
- * nh will need to be deleted manually with `native_handle_delete()`.
- */
-status_t unflatten(HGraphicBufferProducer::FrameEventsDelta* t,
-        std::vector<native_handle_t*>* nh,
-        void const*& buffer, size_t& size, int const*& fds, size_t& numFds);
-
-/**
- * \brief Flatten `FrameEventsDelta`.
- *
- * \param[in] t The source `FrameEventsDelta`.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- *
- * This function will duplicate file descriptors contained in \p t.
- */
-// Ref: frameworks/native/libs/gui/FrameTimestamp.cpp:
-//      FrameEventsDelta::flatten
-status_t flatten(HGraphicBufferProducer::FrameEventsDelta const& t,
-        void*& buffer, size_t& size, int*& fds, size_t numFds);
-
-// Ref: frameworks/native/libs/gui/FrameTimestamps.cpp: FrameEventHistoryDelta
-
-/**
- * \brief Return the size of the non-fd buffer required to flatten
- * `HGraphicBufferProducer::FrameEventHistoryDelta`.
- *
- * \param[in] t The input `HGraphicBufferProducer::FrameEventHistoryDelta`.
- * \return The required size of the flat buffer.
- */
-size_t getFlattenedSize(
-        HGraphicBufferProducer::FrameEventHistoryDelta const& t);
-
-/**
- * \brief Return the number of file descriptors contained in
- * `HGraphicBufferProducer::FrameEventHistoryDelta`.
- *
- * \param[in] t The input `HGraphicBufferProducer::FrameEventHistoryDelta`.
- * \return The number of file descriptors contained in \p t.
- */
-size_t getFdCount(
-        HGraphicBufferProducer::FrameEventHistoryDelta const& t);
-
-/**
- * \brief Unflatten `FrameEventHistoryDelta`.
- *
- * \param[out] t The destination `FrameEventHistoryDelta`.
- * \param[out] nh The underlying array of arrays of native handles.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- *
- * If the return value is `NO_ERROR`, \p nh will be populated with `nullptr` or
- * newly created handles. The second dimension of \p nh will be 4. Each non-null
- * slot in \p nh will need to be deleted manually with `native_handle_delete()`.
- */
-status_t unflatten(
-        HGraphicBufferProducer::FrameEventHistoryDelta* t,
-        std::vector<std::vector<native_handle_t*> >* nh,
-        void const*& buffer, size_t& size, int const*& fds, size_t& numFds);
-
-/**
- * \brief Flatten `FrameEventHistoryDelta`.
- *
- * \param[in] t The source `FrameEventHistoryDelta`.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- *
- * This function will duplicate file descriptors contained in \p t.
- */
-status_t flatten(
-        HGraphicBufferProducer::FrameEventHistoryDelta const& t,
-        void*& buffer, size_t& size, int*& fds, size_t& numFds);
-
-/**
- * \brief Wrap `::android::FrameEventHistoryData` in
- * `HGraphicBufferProducer::FrameEventHistoryDelta`.
- *
- * \param[out] t The wrapper of type
- * `HGraphicBufferProducer::FrameEventHistoryDelta`.
- * \param[out] nh The array of array of native handles that are referred to by
- * members of \p t.
- * \param[in] l The source `::android::FrameEventHistoryDelta`.
- *
- * On success, each member of \p nh will be either `nullptr` or a newly created
- * native handle. All the non-`nullptr` elements must be deleted individually
- * with `native_handle_delete()`.
- */
-bool wrapAs(HGraphicBufferProducer::FrameEventHistoryDelta* t,
-        std::vector<std::vector<native_handle_t*> >* nh,
-        ::android::FrameEventHistoryDelta const& l);
-
-/**
- * \brief Convert `HGraphicBufferProducer::FrameEventHistoryDelta` to
- * `::android::FrameEventHistoryDelta`.
- *
- * \param[out] l The destination `::android::FrameEventHistoryDelta`.
- * \param[in] t The source `HGraphicBufferProducer::FrameEventHistoryDelta`.
- *
- * This function will duplicate all file descriptors contained in \p t.
- */
-bool convertTo(
-        ::android::FrameEventHistoryDelta* l,
-        HGraphicBufferProducer::FrameEventHistoryDelta const& t);
-
-// Ref: frameworks/native/libs/ui/Region.cpp
-
-/**
- * \brief Return the size of the buffer required to flatten `Region`.
- *
- * \param[in] t The input `Region`.
- * \return The required size of the flat buffer.
- */
-size_t getFlattenedSize(Region const& t);
-
-/**
- * \brief Unflatten `Region`.
- *
- * \param[out] t The destination `Region`.
- * \param[in,out] buffer The pointer to the flat buffer.
- * \param[in,out] size The size of the flat buffer.
- * \return `NO_ERROR` on success; other value on failure.
- */
-status_t unflatten(Region* t, void const*& buffer, size_t& size);
-
-/**
- * \brief Flatten `Region`.
- *
- * \param[in] t The source `Region`.
- * \param[in,out] buffer The pointer to the flat buffer.
- * \param[in,out] size The size of the flat buffer.
- * \return `NO_ERROR` on success; other value on failure.
- */
-status_t flatten(Region const& t, void*& buffer, size_t& size);
-
-/**
- * \brief Convert `::android::Region` to `Region`.
- *
- * \param[out] t The destination `Region`.
- * \param[in] l The source `::android::Region`.
- */
-// convert: ::android::Region -> Region
-bool convertTo(Region* t, ::android::Region const& l);
-
-/**
- * \brief Convert `Region` to `::android::Region`.
- *
- * \param[out] l The destination `::android::Region`.
- * \param[in] t The source `Region`.
- */
-// convert: Region -> ::android::Region
-bool convertTo(::android::Region* l, Region const& t);
-
-// Ref: frameworks/native/libs/gui/BGraphicBufferProducer.cpp:
-//      BGraphicBufferProducer::QueueBufferInput
-
-/**
- * \brief Return the size of the buffer required to flatten
- * `HGraphicBufferProducer::QueueBufferInput`.
- *
- * \param[in] t The input `HGraphicBufferProducer::QueueBufferInput`.
- * \return The required size of the flat buffer.
- */
-size_t getFlattenedSize(HGraphicBufferProducer::QueueBufferInput const& t);
-
-/**
- * \brief Return the number of file descriptors contained in
- * `HGraphicBufferProducer::QueueBufferInput`.
- *
- * \param[in] t The input `HGraphicBufferProducer::QueueBufferInput`.
- * \return The number of file descriptors contained in \p t.
- */
-size_t getFdCount(
-        HGraphicBufferProducer::QueueBufferInput const& t);
-/**
- * \brief Flatten `HGraphicBufferProducer::QueueBufferInput`.
- *
- * \param[in] t The source `HGraphicBufferProducer::QueueBufferInput`.
- * \param[out] nh The native handle cloned from `t.fence`.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- *
- * This function will duplicate the file descriptor in `t.fence`. */
-status_t flatten(HGraphicBufferProducer::QueueBufferInput const& t,
-        native_handle_t** nh,
-        void*& buffer, size_t& size, int*& fds, size_t& numFds);
-
-/**
- * \brief Unflatten `HGraphicBufferProducer::QueueBufferInput`.
- *
- * \param[out] t The destination `HGraphicBufferProducer::QueueBufferInput`.
- * \param[out] nh The underlying native handle for `t->fence`.
- * \param[in,out] buffer The pointer to the flat non-fd buffer.
- * \param[in,out] size The size of the flat non-fd buffer.
- * \param[in,out] fds The pointer to the flat fd buffer.
- * \param[in,out] numFds The size of the flat fd buffer.
- * \return `NO_ERROR` on success; other value on failure.
- *
- * If the return value is `NO_ERROR` and `t->fence` contains a valid file
- * descriptor, \p nh will be a newly created native handle holding that file
- * descriptor. \p nh needs to be deleted with `native_handle_delete()`
- * afterwards.
- */
-status_t unflatten(
-        HGraphicBufferProducer::QueueBufferInput* t, native_handle_t** nh,
-        void const*& buffer, size_t& size, int const*& fds, size_t& numFds);
-
-/**
- * \brief Wrap `BGraphicBufferProducer::QueueBufferInput` in
- * `HGraphicBufferProducer::QueueBufferInput`.
- *
- * \param[out] t The wrapper of type
- * `HGraphicBufferProducer::QueueBufferInput`.
- * \param[out] nh The underlying native handle for `t->fence`.
- * \param[in] l The source `BGraphicBufferProducer::QueueBufferInput`.
- *
- * If the return value is `true` and `t->fence` contains a valid file
- * descriptor, \p nh will be a newly created native handle holding that file
- * descriptor. \p nh needs to be deleted with `native_handle_delete()`
- * afterwards.
- */
-bool wrapAs(
-        HGraphicBufferProducer::QueueBufferInput* t,
-        native_handle_t** nh,
-        BGraphicBufferProducer::QueueBufferInput const& l);
-
-/**
- * \brief Convert `HGraphicBufferProducer::QueueBufferInput` to
- * `BGraphicBufferProducer::QueueBufferInput`.
- *
- * \param[out] l The destination `BGraphicBufferProducer::QueueBufferInput`.
- * \param[in] t The source `HGraphicBufferProducer::QueueBufferInput`.
- *
- * If `t.fence` has a valid file descriptor, it will be duplicated.
- */
-bool convertTo(
-        BGraphicBufferProducer::QueueBufferInput* l,
-        HGraphicBufferProducer::QueueBufferInput const& t);
-
-// Ref: frameworks/native/libs/gui/BGraphicBufferProducer.cpp:
-//      BGraphicBufferProducer::QueueBufferOutput
-
-/**
- * \brief Wrap `BGraphicBufferProducer::QueueBufferOutput` in
- * `HGraphicBufferProducer::QueueBufferOutput`.
- *
- * \param[out] t The wrapper of type
- * `HGraphicBufferProducer::QueueBufferOutput`.
- * \param[out] nh The array of array of native handles that are referred to by
- * members of \p t.
- * \param[in] l The source `BGraphicBufferProducer::QueueBufferOutput`.
- *
- * On success, each member of \p nh will be either `nullptr` or a newly created
- * native handle. All the non-`nullptr` elements must be deleted individually
- * with `native_handle_delete()`.
- */
-// wrap: BGraphicBufferProducer::QueueBufferOutput ->
-// HGraphicBufferProducer::QueueBufferOutput
-bool wrapAs(HGraphicBufferProducer::QueueBufferOutput* t,
-        std::vector<std::vector<native_handle_t*> >* nh,
-        BGraphicBufferProducer::QueueBufferOutput const& l);
-
-/**
- * \brief Convert `HGraphicBufferProducer::QueueBufferOutput` to
- * `BGraphicBufferProducer::QueueBufferOutput`.
- *
- * \param[out] l The destination `BGraphicBufferProducer::QueueBufferOutput`.
- * \param[in] t The source `HGraphicBufferProducer::QueueBufferOutput`.
- *
- * This function will duplicate all file descriptors contained in \p t.
- */
-// convert: HGraphicBufferProducer::QueueBufferOutput ->
-// BGraphicBufferProducer::QueueBufferOutput
-bool convertTo(
-        BGraphicBufferProducer::QueueBufferOutput* l,
-        HGraphicBufferProducer::QueueBufferOutput const& t);
-
-/**
- * \brief Convert `BGraphicBufferProducer::DisconnectMode` to
- * `HGraphicBufferProducer::DisconnectMode`.
- *
- * \param[in] l The source `BGraphicBufferProducer::DisconnectMode`.
- * \return The corresponding `HGraphicBufferProducer::DisconnectMode`.
- */
-HGraphicBufferProducer::DisconnectMode toHidlDisconnectMode(
-        BGraphicBufferProducer::DisconnectMode l);
-
-/**
- * \brief Convert `HGraphicBufferProducer::DisconnectMode` to
- * `BGraphicBufferProducer::DisconnectMode`.
- *
- * \param[in] l The source `HGraphicBufferProducer::DisconnectMode`.
- * \return The corresponding `BGraphicBufferProducer::DisconnectMode`.
- */
-BGraphicBufferProducer::DisconnectMode toGuiDisconnectMode(
-        HGraphicBufferProducer::DisconnectMode t);
-
-}  // namespace conversion
-}  // namespace android
-
-#endif  // MEDIA_STAGEFRIGHT_BQHELPER_CONVERSION_H_
diff --git a/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/GraphicBufferSource.h b/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/GraphicBufferSource.h
index bf329b9..b4c4d4a 100644
--- a/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/GraphicBufferSource.h
+++ b/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/GraphicBufferSource.h
@@ -19,8 +19,6 @@
 #define GRAPHIC_BUFFER_SOURCE_H_
 
 #include <binder/Status.h>
-#include <gui/BufferQueue.h>
-#include <gui/IGraphicBufferProducer.h>
 #include <utils/RefBase.h>
 
 #include <media/hardware/VideoAPI.h>
@@ -28,13 +26,17 @@
 #include <media/stagefright/foundation/AHandlerReflector.h>
 #include <media/stagefright/foundation/ALooper.h>
 #include <media/stagefright/bqhelper/ComponentWrapper.h>
+#include <android/hardware/graphics/bufferqueue/1.0/IGraphicBufferProducer.h>
+#include <android/hardware/graphics/bufferqueue/2.0/IGraphicBufferProducer.h>
 
 namespace android {
 
 using ::android::binder::Status;
 
 struct FrameDropper;
-
+class BufferItem;
+class IGraphicBufferProducer;
+class IGraphicBufferConsumer;
 /*
  * This class is used to feed codecs from a Surface via BufferQueue or
  * HW producer.
@@ -82,9 +84,12 @@
 
     // Returns the handle to the producer side of the BufferQueue.  Buffers
     // queued on this will be received by GraphicBufferSource.
-    sp<IGraphicBufferProducer> getIGraphicBufferProducer() const {
-        return mProducer;
-    }
+    sp<IGraphicBufferProducer> getIGraphicBufferProducer() const;
+
+    // Returns the handle to the bufferqueue HAL (V1_0) producer side of the BufferQueue.
+    // Buffers queued on this will be received by GraphicBufferSource.
+    sp<::android::hardware::graphics::bufferqueue::V1_0::IGraphicBufferProducer>
+        getHGraphicBufferProducer_V1_0() const;
 
     // Returns the handle to the bufferqueue HAL producer side of the BufferQueue.
     // Buffers queued on this will be received by GraphicBufferSource.
diff --git a/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/WGraphicBufferProducer.h b/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/WGraphicBufferProducer.h
deleted file mode 100644
index 8ddf20f..0000000
--- a/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/WGraphicBufferProducer.h
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * Copyright 2016, 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.
- */
-
-#ifndef MEDIA_STAGEFRIGHT_WGRAPHICBUFFERPRODUCER_H_
-#define MEDIA_STAGEFRIGHT_WGRAPHICBUFFERPRODUCER_H_
-
-#include <hidl/MQDescriptor.h>
-#include <hidl/Status.h>
-
-#include <binder/Binder.h>
-#include <gui/IGraphicBufferProducer.h>
-#include <gui/IProducerListener.h>
-#include <media/stagefright/bqhelper/Conversion.h>
-#include <media/stagefright/bqhelper/WProducerListener.h>
-#include <system/window.h>
-
-#include <android/hardware/graphics/bufferqueue/1.0/IGraphicBufferProducer.h>
-
-namespace android {
-
-using ::android::hardware::media::V1_0::AnwBuffer;
-using ::android::hidl::base::V1_0::IBase;
-using ::android::hardware::hidl_array;
-using ::android::hardware::hidl_handle;
-using ::android::hardware::hidl_memory;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::sp;
-
-typedef ::android::hardware::graphics::bufferqueue::V1_0::
-        IGraphicBufferProducer HGraphicBufferProducer;
-typedef ::android::hardware::graphics::bufferqueue::V1_0::
-        IProducerListener HProducerListener;
-
-typedef ::android::IGraphicBufferProducer BGraphicBufferProducer;
-typedef ::android::IProducerListener BProducerListener;
-using ::android::BnGraphicBufferProducer;
-
-#ifndef LOG
-struct LOG_dummy {
-    template <typename T>
-    LOG_dummy& operator<< (const T&) { return *this; }
-};
-
-#define LOG(x)  LOG_dummy()
-#endif
-
-// Instantiate only if HGraphicBufferProducer is base of BASE.
-template <typename BASE,
-          typename = typename std::enable_if<std::is_base_of<HGraphicBufferProducer, BASE>::value>::type>
-struct TWGraphicBufferProducer : public BASE {
-    TWGraphicBufferProducer(sp<BGraphicBufferProducer> const& base) : mBase(base) {}
-    Return<void> requestBuffer(int32_t slot, HGraphicBufferProducer::requestBuffer_cb _hidl_cb) override {
-        sp<GraphicBuffer> buf;
-        status_t status = mBase->requestBuffer(slot, &buf);
-        AnwBuffer anwBuffer;
-        if (buf != nullptr) {
-            ::android::conversion::wrapAs(&anwBuffer, *buf);
-        }
-        _hidl_cb(static_cast<int32_t>(status), anwBuffer);
-        return Void();
-    }
-
-    Return<int32_t> setMaxDequeuedBufferCount(int32_t maxDequeuedBuffers) override {
-        return static_cast<int32_t>(mBase->setMaxDequeuedBufferCount(
-                static_cast<int>(maxDequeuedBuffers)));
-    }
-
-    Return<int32_t> setAsyncMode(bool async) override {
-        return static_cast<int32_t>(mBase->setAsyncMode(async));
-    }
-
-    Return<void> dequeueBuffer(
-            uint32_t width, uint32_t height,
-            ::android::hardware::graphics::common::V1_0::PixelFormat format, uint32_t usage,
-            bool getFrameTimestamps, HGraphicBufferProducer::dequeueBuffer_cb _hidl_cb) override {
-        int slot;
-        sp<Fence> fence;
-        ::android::FrameEventHistoryDelta outTimestamps;
-        status_t status = mBase->dequeueBuffer(
-            &slot, &fence, width, height,
-            static_cast<::android::PixelFormat>(format), usage, nullptr,
-            getFrameTimestamps ? &outTimestamps : nullptr);
-        hidl_handle tFence;
-        HGraphicBufferProducer::FrameEventHistoryDelta tOutTimestamps;
-
-        native_handle_t* nh = nullptr;
-        if ((fence == nullptr) || !::android::conversion::wrapAs(&tFence, &nh, *fence)) {
-            LOG(ERROR) << "TWGraphicBufferProducer::dequeueBuffer - "
-                    "Invalid output fence";
-            _hidl_cb(static_cast<int32_t>(status),
-                     static_cast<int32_t>(slot),
-                     tFence,
-                     tOutTimestamps);
-            return Void();
-        }
-        std::vector<std::vector<native_handle_t*> > nhAA;
-        if (getFrameTimestamps && !::android::conversion::wrapAs(&tOutTimestamps, &nhAA, outTimestamps)) {
-            LOG(ERROR) << "TWGraphicBufferProducer::dequeueBuffer - "
-                    "Invalid output timestamps";
-            _hidl_cb(static_cast<int32_t>(status),
-                     static_cast<int32_t>(slot),
-                     tFence,
-                     tOutTimestamps);
-            native_handle_delete(nh);
-            return Void();
-        }
-
-        _hidl_cb(static_cast<int32_t>(status),
-                static_cast<int32_t>(slot),
-                tFence,
-                tOutTimestamps);
-        native_handle_delete(nh);
-        if (getFrameTimestamps) {
-            for (auto& nhA : nhAA) {
-                for (auto& handle : nhA) {
-                    native_handle_delete(handle);
-                }
-            }
-        }
-        return Void();
-    }
-
-    Return<int32_t> detachBuffer(int32_t slot) override {
-        return static_cast<int32_t>(mBase->detachBuffer(slot));
-    }
-
-    Return<void> detachNextBuffer(HGraphicBufferProducer::detachNextBuffer_cb _hidl_cb) override {
-        sp<GraphicBuffer> outBuffer;
-        sp<Fence> outFence;
-        status_t status = mBase->detachNextBuffer(&outBuffer, &outFence);
-        AnwBuffer tBuffer;
-        hidl_handle tFence;
-
-        if (outBuffer == nullptr) {
-            LOG(ERROR) << "TWGraphicBufferProducer::detachNextBuffer - "
-                    "Invalid output buffer";
-            _hidl_cb(static_cast<int32_t>(status), tBuffer, tFence);
-            return Void();
-        }
-        ::android::conversion::wrapAs(&tBuffer, *outBuffer);
-        native_handle_t* nh = nullptr;
-        if ((outFence != nullptr) && !::android::conversion::wrapAs(&tFence, &nh, *outFence)) {
-            LOG(ERROR) << "TWGraphicBufferProducer::detachNextBuffer - "
-                    "Invalid output fence";
-            _hidl_cb(static_cast<int32_t>(status), tBuffer, tFence);
-            return Void();
-        }
-
-        _hidl_cb(static_cast<int32_t>(status), tBuffer, tFence);
-        native_handle_delete(nh);
-        return Void();
-    }
-
-    Return<void> attachBuffer(const AnwBuffer& buffer, HGraphicBufferProducer::attachBuffer_cb _hidl_cb) override {
-        int outSlot;
-        sp<GraphicBuffer> lBuffer = new GraphicBuffer();
-        if (!::android::conversion::convertTo(lBuffer.get(), buffer)) {
-            LOG(ERROR) << "TWGraphicBufferProducer::attachBuffer - "
-                    "Invalid input native window buffer";
-            _hidl_cb(static_cast<int32_t>(BAD_VALUE), -1);
-            return Void();
-        }
-        status_t status = mBase->attachBuffer(&outSlot, lBuffer);
-
-        _hidl_cb(static_cast<int32_t>(status), static_cast<int32_t>(outSlot));
-        return Void();
-    }
-
-    Return<void> queueBuffer(
-            int32_t slot, const HGraphicBufferProducer::QueueBufferInput& input,
-            HGraphicBufferProducer::queueBuffer_cb _hidl_cb) override {
-        HGraphicBufferProducer::QueueBufferOutput tOutput;
-        BGraphicBufferProducer::QueueBufferInput lInput(
-                0, false, HAL_DATASPACE_UNKNOWN,
-                ::android::Rect(0, 0, 1, 1),
-                NATIVE_WINDOW_SCALING_MODE_FREEZE,
-                0, ::android::Fence::NO_FENCE);
-        if (!::android::conversion::convertTo(&lInput, input)) {
-            LOG(ERROR) << "TWGraphicBufferProducer::queueBuffer - "
-                    "Invalid input";
-            _hidl_cb(static_cast<int32_t>(BAD_VALUE), tOutput);
-            return Void();
-        }
-        BGraphicBufferProducer::QueueBufferOutput lOutput;
-        status_t status = mBase->queueBuffer(
-                static_cast<int>(slot), lInput, &lOutput);
-
-        std::vector<std::vector<native_handle_t*> > nhAA;
-        if (!::android::conversion::wrapAs(&tOutput, &nhAA, lOutput)) {
-            LOG(ERROR) << "TWGraphicBufferProducer::queueBuffer - "
-                    "Invalid output";
-            _hidl_cb(static_cast<int32_t>(BAD_VALUE), tOutput);
-            return Void();
-        }
-
-        _hidl_cb(static_cast<int32_t>(status), tOutput);
-        for (auto& nhA : nhAA) {
-            for (auto& nh : nhA) {
-                native_handle_delete(nh);
-            }
-        }
-        return Void();
-    }
-
-    Return<int32_t> cancelBuffer(int32_t slot, const hidl_handle& fence) override {
-        sp<Fence> lFence = new Fence();
-        if (!::android::conversion::convertTo(lFence.get(), fence)) {
-            LOG(ERROR) << "TWGraphicBufferProducer::cancelBuffer - "
-                    "Invalid input fence";
-            return static_cast<int32_t>(BAD_VALUE);
-        }
-        return static_cast<int32_t>(mBase->cancelBuffer(static_cast<int>(slot), lFence));
-    }
-
-    Return<void> query(int32_t what, HGraphicBufferProducer::query_cb _hidl_cb) override {
-        int lValue;
-        int lReturn = mBase->query(static_cast<int>(what), &lValue);
-        _hidl_cb(static_cast<int32_t>(lReturn), static_cast<int32_t>(lValue));
-        return Void();
-    }
-
-    Return<void> connect(const sp<HProducerListener>& listener,
-            int32_t api, bool producerControlledByApp,
-            HGraphicBufferProducer::connect_cb _hidl_cb) override {
-        sp<BProducerListener> lListener = listener == nullptr ?
-                nullptr : new LWProducerListener(listener);
-        BGraphicBufferProducer::QueueBufferOutput lOutput;
-        status_t status = mBase->connect(lListener,
-                static_cast<int>(api),
-                producerControlledByApp,
-                &lOutput);
-
-        HGraphicBufferProducer::QueueBufferOutput tOutput;
-        std::vector<std::vector<native_handle_t*> > nhAA;
-        if (!::android::conversion::wrapAs(&tOutput, &nhAA, lOutput)) {
-            LOG(ERROR) << "TWGraphicBufferProducer::connect - "
-                    "Invalid output";
-            _hidl_cb(static_cast<int32_t>(status), tOutput);
-            return Void();
-        }
-
-        _hidl_cb(static_cast<int32_t>(status), tOutput);
-        for (auto& nhA : nhAA) {
-            for (auto& nh : nhA) {
-                native_handle_delete(nh);
-            }
-        }
-        return Void();
-    }
-
-    Return<int32_t> disconnect(
-            int32_t api,
-            HGraphicBufferProducer::DisconnectMode mode) override {
-        return static_cast<int32_t>(mBase->disconnect(
-                static_cast<int>(api),
-                ::android::conversion::toGuiDisconnectMode(mode)));
-    }
-
-    Return<int32_t> setSidebandStream(const hidl_handle& stream) override {
-        return static_cast<int32_t>(mBase->setSidebandStream(NativeHandle::create(
-                stream ? native_handle_clone(stream) : NULL, true)));
-    }
-
-    Return<void> allocateBuffers(
-            uint32_t width, uint32_t height,
-            ::android::hardware::graphics::common::V1_0::PixelFormat format,
-            uint32_t usage) override {
-        mBase->allocateBuffers(
-                width, height,
-                static_cast<::android::PixelFormat>(format),
-                usage);
-        return Void();
-    }
-
-    Return<int32_t> allowAllocation(bool allow) override {
-        return static_cast<int32_t>(mBase->allowAllocation(allow));
-    }
-
-    Return<int32_t> setGenerationNumber(uint32_t generationNumber) override {
-        return static_cast<int32_t>(mBase->setGenerationNumber(generationNumber));
-    }
-
-    Return<void> getConsumerName(HGraphicBufferProducer::getConsumerName_cb _hidl_cb) override {
-        _hidl_cb(mBase->getConsumerName().string());
-        return Void();
-    }
-
-    Return<int32_t> setSharedBufferMode(bool sharedBufferMode) override {
-        return static_cast<int32_t>(mBase->setSharedBufferMode(sharedBufferMode));
-    }
-
-    Return<int32_t> setAutoRefresh(bool autoRefresh) override {
-        return static_cast<int32_t>(mBase->setAutoRefresh(autoRefresh));
-    }
-
-    Return<int32_t> setDequeueTimeout(int64_t timeoutNs) override {
-        return static_cast<int32_t>(mBase->setDequeueTimeout(timeoutNs));
-    }
-
-    Return<void> getLastQueuedBuffer(HGraphicBufferProducer::getLastQueuedBuffer_cb _hidl_cb) override {
-        sp<GraphicBuffer> lOutBuffer = new GraphicBuffer();
-        sp<Fence> lOutFence = new Fence();
-        float lOutTransformMatrix[16];
-        status_t status = mBase->getLastQueuedBuffer(
-                &lOutBuffer, &lOutFence, lOutTransformMatrix);
-
-        AnwBuffer tOutBuffer;
-        if (lOutBuffer != nullptr) {
-            ::android::conversion::wrapAs(&tOutBuffer, *lOutBuffer);
-        }
-        hidl_handle tOutFence;
-        native_handle_t* nh = nullptr;
-        if ((lOutFence == nullptr) || !::android::conversion::wrapAs(&tOutFence, &nh, *lOutFence)) {
-            LOG(ERROR) << "TWGraphicBufferProducer::getLastQueuedBuffer - "
-                    "Invalid output fence";
-            _hidl_cb(static_cast<int32_t>(status),
-                    tOutBuffer,
-                    tOutFence,
-                    hidl_array<float, 16>());
-            return Void();
-        }
-        hidl_array<float, 16> tOutTransformMatrix(lOutTransformMatrix);
-
-        _hidl_cb(static_cast<int32_t>(status), tOutBuffer, tOutFence, tOutTransformMatrix);
-        native_handle_delete(nh);
-        return Void();
-    }
-
-    Return<void> getFrameTimestamps(HGraphicBufferProducer::getFrameTimestamps_cb _hidl_cb) override {
-        ::android::FrameEventHistoryDelta lDelta;
-        mBase->getFrameTimestamps(&lDelta);
-
-        HGraphicBufferProducer::FrameEventHistoryDelta tDelta;
-        std::vector<std::vector<native_handle_t*> > nhAA;
-        if (!::android::conversion::wrapAs(&tDelta, &nhAA, lDelta)) {
-            LOG(ERROR) << "TWGraphicBufferProducer::getFrameTimestamps - "
-                    "Invalid output frame timestamps";
-            _hidl_cb(tDelta);
-            return Void();
-        }
-
-        _hidl_cb(tDelta);
-        for (auto& nhA : nhAA) {
-            for (auto& nh : nhA) {
-                native_handle_delete(nh);
-            }
-        }
-        return Void();
-    }
-
-    Return<void> getUniqueId(HGraphicBufferProducer::getUniqueId_cb _hidl_cb) override {
-        uint64_t outId;
-        status_t status = mBase->getUniqueId(&outId);
-        _hidl_cb(static_cast<int32_t>(status), outId);
-        return Void();
-    }
-
-private:
-    sp<BGraphicBufferProducer> mBase;
-};
-
-}  // namespace android
-
-#endif  // MEDIA_STAGEFRIGHT_WGRAPHICBUFFERPRODUCER_H_
diff --git a/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/WProducerListener.h b/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/WProducerListener.h
deleted file mode 100644
index febba87..0000000
--- a/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/WProducerListener.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2016, 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.
- */
-
-#ifndef MEDIA_STAGEFRIGHT_WPRODUCERLISTENER_H_
-#define MEDIA_STAGEFRIGHT_WPRODUCERLISTENER_H_
-
-#include <hidl/MQDescriptor.h>
-#include <hidl/Status.h>
-
-#include <binder/IBinder.h>
-#include <gui/IProducerListener.h>
-
-#include <android/hardware/graphics/bufferqueue/1.0/IProducerListener.h>
-
-namespace android {
-
-using ::android::hidl::base::V1_0::IBase;
-using ::android::hardware::hidl_array;
-using ::android::hardware::hidl_memory;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::sp;
-
-typedef ::android::hardware::graphics::bufferqueue::V1_0::IProducerListener
-        HProducerListener;
-typedef ::android::IProducerListener
-        BProducerListener;
-using ::android::BnProducerListener;
-
-struct TWProducerListener : public HProducerListener {
-    sp<BProducerListener> mBase;
-    TWProducerListener(sp<BProducerListener> const& base);
-    Return<void> onBufferReleased() override;
-    Return<bool> needsReleaseNotify() override;
-};
-
-class LWProducerListener : public BnProducerListener {
-public:
-    sp<HProducerListener> mBase;
-    LWProducerListener(sp<HProducerListener> const& base);
-    void onBufferReleased() override;
-    bool needsReleaseNotify() override;
-};
-
-}  // namespace android
-
-#endif  // MEDIA_STAGEFRIGHT_WPRODUCERLISTENER_H_
diff --git a/media/libstagefright/codecs/amrwb/src/deemphasis_32.cpp b/media/libstagefright/codecs/amrwb/src/deemphasis_32.cpp
index b80555b..c0e4c51 100644
--- a/media/libstagefright/codecs/amrwb/src/deemphasis_32.cpp
+++ b/media/libstagefright/codecs/amrwb/src/deemphasis_32.cpp
@@ -131,7 +131,7 @@
     int16 lo, hi;
 
     L_tmp  = ((int32)x_hi[0]) << 16;
-    L_tmp += ((int32)x_lo[0]) << 4;
+    L_tmp += (((int32)x_lo[0]) << 4) & 0xFFFF;
     L_tmp  = shl_int32(L_tmp, 3);
 
     L_tmp = fxp_mac_16by16(*mem, mu, L_tmp),
@@ -144,7 +144,7 @@
     for (i = 1; i < L - 1; i++)
     {
         L_tmp  = ((int32)hi) << 16;
-        L_tmp += ((int32)lo) << 4;
+        L_tmp += (((int32)lo) << 4) & 0xFFFF;
         L_tmp  = shl_int32(L_tmp, 3);
         L_tmp  = fxp_mac_16by16(y[i - 1], mu, L_tmp),
                  L_tmp  = shl_int32(L_tmp, 1);           /* saturation can occur here */
@@ -153,7 +153,7 @@
         hi     = x_hi[i+1];
     }
     L_tmp  = ((int32)hi) << 16;
-    L_tmp += ((int32)lo) << 4;
+    L_tmp += (((int32)lo) << 4) & 0xFFFF;
     L_tmp  = shl_int32(L_tmp, 3);
     L_tmp  = fxp_mac_16by16(y[i - 1], mu, L_tmp),
              L_tmp  = shl_int32(L_tmp, 1);           /* saturation can occur here */
diff --git a/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp b/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp
index bf5e243..5a4b2f8 100644
--- a/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp
+++ b/media/libstagefright/codecs/avcdec/SoftAVCDec.cpp
@@ -580,7 +580,7 @@
             status = ivdec_api_function(mCodecCtx, (void *)&s_dec_ip, (void *)&s_dec_op);
 
             bool unsupportedResolution =
-                (IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED == (s_dec_op.u4_error_code & 0xFF));
+                (IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED == (s_dec_op.u4_error_code & IVD_ERROR_MASK));
 
             /* Check for unsupported dimensions */
             if (unsupportedResolution) {
@@ -590,7 +590,7 @@
                 return;
             }
 
-            bool allocationFailed = (IVD_MEM_ALLOC_FAILED == (s_dec_op.u4_error_code & 0xFF));
+            bool allocationFailed = (IVD_MEM_ALLOC_FAILED == (s_dec_op.u4_error_code & IVD_ERROR_MASK));
             if (allocationFailed) {
                 ALOGE("Allocation failure in decoder");
                 notify(OMX_EventError, OMX_ErrorUnsupportedSetting, 0, NULL);
@@ -598,7 +598,14 @@
                 return;
             }
 
-            bool resChanged = (IVD_RES_CHANGED == (s_dec_op.u4_error_code & 0xFF));
+            if (IS_IVD_FATAL_ERROR(s_dec_op.u4_error_code)) {
+                ALOGE("Fatal Error : 0x%x", s_dec_op.u4_error_code);
+                notify(OMX_EventError, OMX_ErrorUnsupportedSetting, 0, NULL);
+                mSignalledError = true;
+                return;
+            }
+
+            bool resChanged = (IVD_RES_CHANGED == (s_dec_op.u4_error_code & IVD_ERROR_MASK));
 
             getVUIParams();
 
diff --git a/media/libstagefright/codecs/avcenc/SoftAVCEnc.h b/media/libstagefright/codecs/avcenc/SoftAVCEnc.h
index 8253b7d..6d2e084 100644
--- a/media/libstagefright/codecs/avcenc/SoftAVCEnc.h
+++ b/media/libstagefright/codecs/avcenc/SoftAVCEnc.h
@@ -36,7 +36,7 @@
 #define DEFAULT_MAX_REORDER_FRM     0
 #define DEFAULT_QP_MIN              10
 #define DEFAULT_QP_MAX              40
-#define DEFAULT_MAX_BITRATE         20000000
+#define DEFAULT_MAX_BITRATE         240000000
 #define DEFAULT_MAX_SRCH_RANGE_X    256
 #define DEFAULT_MAX_SRCH_RANGE_Y    256
 #define DEFAULT_MAX_FRAMERATE       120000
diff --git a/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp b/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp
index bb7d361..f6ae1f4 100644
--- a/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp
+++ b/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp
@@ -569,7 +569,7 @@
             status = ivdec_api_function(mCodecCtx, (void *)&s_dec_ip, (void *)&s_dec_op);
 
             bool unsupportedResolution =
-                (IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED == (s_dec_op.u4_error_code & 0xFF));
+                (IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED == (s_dec_op.u4_error_code & IVD_ERROR_MASK));
 
             /* Check for unsupported dimensions */
             if (unsupportedResolution) {
@@ -579,7 +579,8 @@
                 return;
             }
 
-            bool allocationFailed = (IVD_MEM_ALLOC_FAILED == (s_dec_op.u4_error_code & 0xFF));
+            bool allocationFailed = 
+                (IVD_MEM_ALLOC_FAILED == (s_dec_op.u4_error_code & IVD_ERROR_MASK));
             if (allocationFailed) {
                 ALOGE("Allocation failure in decoder");
                 notify(OMX_EventError, OMX_ErrorUnsupportedSetting, 0, NULL);
@@ -587,7 +588,14 @@
                 return;
             }
 
-            bool resChanged = (IVD_RES_CHANGED == (s_dec_op.u4_error_code & 0xFF));
+            if (IS_IVD_FATAL_ERROR(s_dec_op.u4_error_code)) {
+                ALOGE("Fatal Error : 0x%x", s_dec_op.u4_error_code);
+                notify(OMX_EventError, OMX_ErrorUnsupportedSetting, 0, NULL);
+                mSignalledError = true;
+                return;
+            }
+
+            bool resChanged = (IVD_RES_CHANGED == (s_dec_op.u4_error_code & IVD_ERROR_MASK));
 
             getVUIParams();
 
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/ADebug.h b/media/libstagefright/foundation/include/media/stagefright/foundation/ADebug.h
index ab17a02..37388a0 100644
--- a/media/libstagefright/foundation/include/media/stagefright/foundation/ADebug.h
+++ b/media/libstagefright/foundation/include/media/stagefright/foundation/ADebug.h
@@ -114,6 +114,15 @@
 #define TRESPASS_DBG(...)
 #endif
 
+#ifndef LOG_ALWAYS_FATAL_IN_CHILD_PROC
+#define LOG_ALWAYS_FATAL_IN_CHILD_PROC(...)   \
+    do {                                      \
+        if (fork() == 0) {                    \
+            LOG_ALWAYS_FATAL(__VA_ARGS__);    \
+        }                                     \
+    } while (false)
+#endif
+
 struct ADebug {
     enum Level {
         kDebugNone,             // no debug
diff --git a/media/libstagefright/omx/1.0/Omx.cpp b/media/libstagefright/omx/1.0/Omx.cpp
index 556a694..eef9ce3 100644
--- a/media/libstagefright/omx/1.0/Omx.cpp
+++ b/media/libstagefright/omx/1.0/Omx.cpp
@@ -18,7 +18,6 @@
 #include <list>
 
 #include <android-base/logging.h>
-#include <gui/IGraphicBufferProducer.h>
 #include <media/openmax/OMX_Core.h>
 #include <media/openmax/OMX_AsString.h>
 
@@ -28,7 +27,6 @@
 
 #include <media/stagefright/omx/1.0/WOmxNode.h>
 #include <media/stagefright/omx/1.0/WOmxObserver.h>
-#include <media/stagefright/omx/1.0/WGraphicBufferProducer.h>
 #include <media/stagefright/omx/1.0/WGraphicBufferSource.h>
 #include <media/stagefright/omx/1.0/Conversion.h>
 #include <media/stagefright/omx/1.0/Omx.h>
@@ -148,8 +146,6 @@
 }
 
 Return<void> Omx::createInputSurface(createInputSurface_cb _hidl_cb) {
-    sp<::android::IGraphicBufferProducer> bufferProducer;
-
     sp<OmxGraphicBufferSource> graphicBufferSource = new OmxGraphicBufferSource();
     status_t err = graphicBufferSource->initCheck();
     if (err != OK) {
@@ -159,10 +155,9 @@
         _hidl_cb(toStatus(err), nullptr, nullptr);
         return Void();
     }
-    bufferProducer = graphicBufferSource->getIGraphicBufferProducer();
 
     _hidl_cb(toStatus(OK),
-            new TWGraphicBufferProducer(bufferProducer),
+            graphicBufferSource->getHGraphicBufferProducer_V1_0(),
             new TWGraphicBufferSource(graphicBufferSource));
     return Void();
 }
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index d7aacff..ddb4ba0 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -33,12 +33,13 @@
 
 #include <binder/IMemory.h>
 #include <cutils/properties.h>
-#include <gui/BufferQueue.h>
 #include <media/hardware/HardwareAPI.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ColorUtils.h>
 #include <media/stagefright/MediaErrors.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/Fence.h>
 #include <utils/misc.h>
 #include <utils/NativeHandle.h>
 #include <media/OMXBuffer.h>
diff --git a/media/libstagefright/omx/include/media/stagefright/omx/1.0/Conversion.h b/media/libstagefright/omx/include/media/stagefright/omx/1.0/Conversion.h
index 0f229f7..9669677 100644
--- a/media/libstagefright/omx/include/media/stagefright/omx/1.0/Conversion.h
+++ b/media/libstagefright/omx/include/media/stagefright/omx/1.0/Conversion.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_HARDWARE_MEDIA_OMX_V1_0__CONVERSION_H
-#define ANDROID_HARDWARE_MEDIA_OMX_V1_0__CONVERSION_H
+#ifndef ANDROID_HARDWARE_MEDIA_OMX_V1_0_IMPL_CONVERSION_H
+#define ANDROID_HARDWARE_MEDIA_OMX_V1_0_IMPL_CONVERSION_H
 
 #include <vector>
 #include <list>
@@ -29,15 +29,15 @@
 
 #include <binder/Binder.h>
 #include <binder/Status.h>
+#include <ui/BufferQueueDefs.h>
 #include <ui/FenceTime.h>
 #include <cutils/native_handle.h>
-#include <gui/IGraphicBufferProducer.h>
 
 #include <media/OMXFenceParcelable.h>
 #include <media/OMXBuffer.h>
+#include <media/omx/1.0/Conversion.h>
 #include <media/hardware/VideoAPI.h>
 #include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/bqhelper/Conversion.h>
 
 #include <android/hidl/memory/1.0/IMemory.h>
 #include <android/hardware/graphics/bufferqueue/1.0/IProducerListener.h>
@@ -99,16 +99,9 @@
 
 typedef ::android::hardware::graphics::bufferqueue::V1_0::IGraphicBufferProducer
         HGraphicBufferProducer;
-typedef ::android::IGraphicBufferProducer
-        BGraphicBufferProducer;
 
-// We want to use all functions declared in ::android::conversion
-using namespace ::android::conversion;
-
-// Now specifically inject these two functions here, because we're going to
-// declare functions with the same name in this namespace.
-using ::android::conversion::convertTo;
-using ::android::conversion::toStatusT;
+// Use the conversion functions from libmedia_omx so that we don't need libgui
+using namespace ::android::hardware::media::omx::V1_0::utils;
 
 /**
  * Conversion functions
@@ -143,62 +136,6 @@
  */
 
 /**
- * \brief Convert `Status` to `status_t`. This is for legacy binder calls.
- *
- * \param[in] t The source `Status`.
- * \return the corresponding `status_t`.
- */
-// convert: Status -> status_t
-inline status_t toStatusT(Status const& t) {
-    switch (t) {
-    case Status::NO_ERROR:
-    case Status::NAME_NOT_FOUND:
-    case Status::WOULD_BLOCK:
-    case Status::NO_MEMORY:
-    case Status::ALREADY_EXISTS:
-    case Status::NO_INIT:
-    case Status::BAD_VALUE:
-    case Status::DEAD_OBJECT:
-    case Status::INVALID_OPERATION:
-    case Status::TIMED_OUT:
-    case Status::ERROR_UNSUPPORTED:
-    case Status::UNKNOWN_ERROR:
-    case Status::RELEASE_ALL_BUFFERS:
-        return static_cast<status_t>(t);
-    case Status::BUFFER_NEEDS_REALLOCATION:
-        return NOT_ENOUGH_DATA;
-    default:
-        ALOGW("Unrecognized status value: %" PRId32, static_cast<int32_t>(t));
-        return static_cast<status_t>(t);
-    }
-}
-
-/**
- * \brief Convert `Return<Status>` to `status_t`. This is for legacy binder
- * calls.
- *
- * \param[in] t The source `Return<Status>`.
- * \return The corresponding `status_t`.
- *
- * This function first check if \p t has a transport error. If it does, then the
- * return value is the transport error code. Otherwise, the return value is
- * converted from `Status` contained inside \p t.
- *
- * Note:
- * - This `Status` is omx-specific. It is defined in `types.hal`.
- * - The name of this function is not `convert`.
- */
-// convert: Status -> status_t
-inline status_t toStatusT(Return<Status> const& t) {
-    if (t.isOk()) {
-        return toStatusT(static_cast<Status>(t));
-    } else if (t.isDeadObject()) {
-        return DEAD_OBJECT;
-    }
-    return UNKNOWN_ERROR;
-}
-
-/**
  * \brief Convert `status_t` to `Status`.
  *
  * \param[in] l The source `status_t`.
@@ -219,8 +156,8 @@
     case TIMED_OUT:
     case ERROR_UNSUPPORTED:
     case UNKNOWN_ERROR:
-    case IGraphicBufferProducer::RELEASE_ALL_BUFFERS:
-    case IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION:
+    case BufferQueueDefs::RELEASE_ALL_BUFFERS:
+    case BufferQueueDefs::BUFFER_NEEDS_REALLOCATION:
         return static_cast<Status>(l);
     case NOT_ENOUGH_DATA:
         return Status::BUFFER_NEEDS_REALLOCATION;
@@ -572,7 +509,8 @@
             anwBuffer.nativeHandle = t.nativeHandle;
             anwBuffer.attr = t.attr.anwBuffer;
             sp<GraphicBuffer> graphicBuffer = new GraphicBuffer();
-            if (!convertTo(graphicBuffer.get(), anwBuffer)) {
+            if (!::android::hardware::media::omx::V1_0::utils::convertTo(
+                    graphicBuffer.get(), anwBuffer)) {
                 return false;
             }
             *l = OMXBuffer(graphicBuffer);
@@ -756,4 +694,4 @@
 }  // namespace hardware
 }  // namespace android
 
-#endif  // ANDROID_HARDWARE_MEDIA_OMX_V1_0__CONVERSION_H
+#endif  // ANDROID_HARDWARE_MEDIA_OMX_V1_0_IMPL_CONVERSION_H
diff --git a/media/libstagefright/omx/include/media/stagefright/omx/1.0/WGraphicBufferProducer.h b/media/libstagefright/omx/include/media/stagefright/omx/1.0/WGraphicBufferProducer.h
deleted file mode 100644
index 322a699..0000000
--- a/media/libstagefright/omx/include/media/stagefright/omx/1.0/WGraphicBufferProducer.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2018, 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.
- */
-
-#ifndef ANDROID_HARDWARE_MEDIA_OMX_V1_0_WGRAPHICBUFFERPRODUCER_H
-#define ANDROID_HARDWARE_MEDIA_OMX_V1_0_WGRAPHICBUFFERPRODUCER_H
-
-#include <media/stagefright/bqhelper/WGraphicBufferProducer.h>
-
-namespace android {
-namespace hardware {
-namespace media {
-namespace omx {
-namespace V1_0 {
-namespace implementation {
-
-using TWGraphicBufferProducer = ::android::TWGraphicBufferProducer<
-    ::android::hardware::graphics::bufferqueue::V1_0::IGraphicBufferProducer>;
-
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace omx
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
-
-#endif  // ANDROID_HARDWARE_MEDIA_OMX_V1_0_WOMXBUFFERPRODUCER_H
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 0c6cfa1..7daa929 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -3276,6 +3276,8 @@
         cpuStats.sample(myName);
 
         Vector< sp<EffectChain> > effectChains;
+        audio_session_t activeHapticSessionId = AUDIO_SESSION_NONE;
+        std::vector<sp<Track>> activeTracks;
 
         // If the device is AUDIO_DEVICE_OUT_BUS, check for downstream latency.
         //
@@ -3549,6 +3551,25 @@
             // during mixing and effect process as the audio buffers could be deleted
             // or modified if an effect is created or deleted
             lockEffectChains_l(effectChains);
+
+            // Determine which session to pick up haptic data.
+            // This must be done under the same lock as prepareTracks_l().
+            // TODO: Write haptic data directly to sink buffer when mixing.
+            if (mHapticChannelCount > 0 && effectChains.size() > 0) {
+                for (const auto& track : mActiveTracks) {
+                    if (track->getHapticPlaybackEnabled()) {
+                        activeHapticSessionId = track->sessionId();
+                        break;
+                    }
+                }
+            }
+
+            // Acquire a local copy of active tracks with lock (release w/o lock).
+            //
+            // Control methods on the track acquire the ThreadBase lock (e.g. start()
+            // stop(), pause(), etc.), but the threadLoop is entitled to call audio
+            // data / buffer methods on tracks from activeTracks without the ThreadBase lock.
+            activeTracks.insert(activeTracks.end(), mActiveTracks.begin(), mActiveTracks.end());
         } // mLock scope ends
 
         if (mBytesRemaining == 0) {
@@ -3563,6 +3584,13 @@
                 threadLoop_sleepTime();
                 if (mSleepTimeUs == 0) {
                     mCurrentWriteLength = mSinkBufferSize;
+
+                    // Tally underrun frames as we are inserting 0s here.
+                    for (const auto& track : activeTracks) {
+                        if (track->mFillingUpStatus == Track::FS_ACTIVE) {
+                            track->mAudioTrackServerProxy->tallyUnderrunFrames(mNormalFrameCount);
+                        }
+                    }
                 }
             }
             // Either threadLoop_mix() or threadLoop_sleepTime() should have set
@@ -3621,20 +3649,11 @@
 
             // only process effects if we're going to write
             if (mSleepTimeUs == 0 && mType != OFFLOAD) {
-                audio_session_t activeHapticId = AUDIO_SESSION_NONE;
-                if (mHapticChannelCount > 0 && effectChains.size() > 0) {
-                    for (auto track : mActiveTracks) {
-                        if (track->getHapticPlaybackEnabled()) {
-                            activeHapticId = track->sessionId();
-                            break;
-                        }
-                    }
-                }
                 for (size_t i = 0; i < effectChains.size(); i ++) {
                     effectChains[i]->process_l();
                     // TODO: Write haptic data directly to sink buffer when mixing.
-                    if (activeHapticId != AUDIO_SESSION_NONE
-                            && activeHapticId == effectChains[i]->sessionId()) {
+                    if (activeHapticSessionId != AUDIO_SESSION_NONE
+                            && activeHapticSessionId == effectChains[i]->sessionId()) {
                         // Haptic data is active in this case, copy it directly from
                         // in buffer to out buffer.
                         const size_t audioBufferSize = mNormalFrameCount
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPort.h b/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
index 2d182bd..d906f11 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
@@ -112,6 +112,9 @@
     static bool isBetterFormatMatch(audio_format_t newFormat,
                                         audio_format_t currentFormat,
                                         audio_format_t targetFormat);
+    static uint32_t formatDistance(audio_format_t format1,
+                                   audio_format_t format2);
+    static const uint32_t kFormatDistanceMax = 4;
 
     audio_module_handle_t getModuleHandle() const;
     uint32_t getModuleVersionMajor() const;
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
index a66c695..c11490a 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
@@ -282,30 +282,25 @@
     return index1 - index2;
 }
 
+uint32_t AudioPort::formatDistance(audio_format_t format1, audio_format_t format2)
+{
+    if (format1 == format2) {
+        return 0;
+    }
+    if (format1 == AUDIO_FORMAT_INVALID || format2 == AUDIO_FORMAT_INVALID) {
+        return kFormatDistanceMax;
+    }
+    int diffBytes = (int)audio_bytes_per_sample(format1) -
+            audio_bytes_per_sample(format2);
+
+    return abs(diffBytes);
+}
+
 bool AudioPort::isBetterFormatMatch(audio_format_t newFormat,
                                     audio_format_t currentFormat,
                                     audio_format_t targetFormat)
 {
-    if (newFormat == currentFormat) {
-        return false;
-    }
-    if (currentFormat == AUDIO_FORMAT_INVALID) {
-        return true;
-    }
-    if (newFormat == targetFormat) {
-        return true;
-    }
-    int currentDiffBytes = (int)audio_bytes_per_sample(targetFormat) -
-            audio_bytes_per_sample(currentFormat);
-    int newDiffBytes = (int)audio_bytes_per_sample(targetFormat) -
-            audio_bytes_per_sample(newFormat);
-
-    if (abs(newDiffBytes) < abs(currentDiffBytes)) {
-        return true;
-    } else if (abs(newDiffBytes) == abs(currentDiffBytes)) {
-        return (newDiffBytes >= 0);
-    }
-    return false;
+    return formatDistance(newFormat, targetFormat) < formatDistance(currentFormat, targetFormat);
 }
 
 void AudioPort::pickAudioProfile(uint32_t &samplingRate,
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index c0ca440..2dc7cad 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -36,12 +36,12 @@
 #define AUDIO_POLICY_BLUETOOTH_LEGACY_HAL_XML_CONFIG_FILE_NAME \
         "audio_policy_configuration_bluetooth_legacy_hal.xml"
 
+#include <algorithm>
 #include <inttypes.h>
 #include <math.h>
 #include <set>
 #include <unordered_set>
 #include <vector>
-
 #include <AudioPolicyManagerInterface.h>
 #include <AudioPolicyEngineInstance.h>
 #include <cutils/properties.h>
@@ -592,7 +592,7 @@
                     AUDIO_DEVICE_OUT_TELEPHONY_TX, String8(), AUDIO_FORMAT_DEFAULT);
     SortedVector<audio_io_handle_t> outputs =
             getOutputsForDevices(DeviceVector(outputDevice), mOutputs);
-    audio_io_handle_t output = selectOutput(outputs, AUDIO_OUTPUT_FLAG_NONE, AUDIO_FORMAT_INVALID);
+    const audio_io_handle_t output = selectOutput(outputs);
     // request to reuse existing output stream if one is already opened to reach the target device
     if (output != AUDIO_IO_HANDLE_NONE) {
         sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
@@ -883,7 +883,7 @@
     // and AudioSystem::getOutputSamplingRate().
 
     SortedVector<audio_io_handle_t> outputs = getOutputsForDevices(devices, mOutputs);
-    audio_io_handle_t output = selectOutput(outputs, AUDIO_OUTPUT_FLAG_NONE, AUDIO_FORMAT_INVALID);
+    const audio_io_handle_t output = selectOutput(outputs);
 
     ALOGV("getOutput() stream %d selected devices %s, output %d", stream,
           devices.toString().c_str(), output);
@@ -1430,108 +1430,125 @@
                                                        audio_channel_mask_t channelMask,
                                                        uint32_t samplingRate)
 {
+    LOG_ALWAYS_FATAL_IF(!(format == AUDIO_FORMAT_INVALID || audio_is_linear_pcm(format)),
+        "%s called with format %#x", __func__, format);
+
+    // Flags disqualifying an output: the match must happen before calling selectOutput()
+    static const audio_output_flags_t kExcludedFlags = (audio_output_flags_t)
+        (AUDIO_OUTPUT_FLAG_HW_AV_SYNC | AUDIO_OUTPUT_FLAG_MMAP_NOIRQ | AUDIO_OUTPUT_FLAG_DIRECT);
+
+    // Flags expressing a functional request: must be honored in priority over
+    // other criteria
+    static const audio_output_flags_t kFunctionalFlags = (audio_output_flags_t)
+        (AUDIO_OUTPUT_FLAG_VOIP_RX | AUDIO_OUTPUT_FLAG_INCALL_MUSIC |
+            AUDIO_OUTPUT_FLAG_TTS | AUDIO_OUTPUT_FLAG_DIRECT_PCM);
+    // Flags expressing a performance request: have lower priority than serving
+    // requested sampling rate or channel mask
+    static const audio_output_flags_t kPerformanceFlags = (audio_output_flags_t)
+        (AUDIO_OUTPUT_FLAG_FAST | AUDIO_OUTPUT_FLAG_DEEP_BUFFER |
+            AUDIO_OUTPUT_FLAG_RAW | AUDIO_OUTPUT_FLAG_SYNC);
+
+    const audio_output_flags_t functionalFlags =
+        (audio_output_flags_t)(flags & kFunctionalFlags);
+    const audio_output_flags_t performanceFlags =
+        (audio_output_flags_t)(flags & kPerformanceFlags);
+
+    audio_io_handle_t bestOutput = (outputs.size() == 0) ? AUDIO_IO_HANDLE_NONE : outputs[0];
+
     // select one output among several that provide a path to a particular device or set of
     // devices (the list was previously build by getOutputsForDevices()).
     // The priority is as follows:
     // 1: the output supporting haptic playback when requesting haptic playback
-    // 2: the output with the highest number of requested policy flags
-    // 3: the output with the bit depth the closest to the requested one
-    // 4: the primary output
-    // 5: the first output in the list
+    // 2: the output with the highest number of requested functional flags
+    // 3: the output supporting the exact channel mask
+    // 4: the output with a higher channel count than requested
+    // 5: the output with a higher sampling rate than requested
+    // 6: the output with the highest number of requested performance flags
+    // 7: the output with the bit depth the closest to the requested one
+    // 8: the primary output
+    // 9: the first output in the list
 
-    if (outputs.size() == 0) {
-        return AUDIO_IO_HANDLE_NONE;
-    }
-    if (outputs.size() == 1) {
-        return outputs[0];
-    }
+    // matching criteria values in priority order for best matching output so far
+    std::vector<uint32_t> bestMatchCriteria(8, 0);
 
-    int maxCommonFlags = 0;
-    const size_t hapticChannelCount = audio_channel_count_from_out_mask(
-            channelMask & AUDIO_CHANNEL_HAPTIC_ALL);
-    audio_io_handle_t outputForFlags = AUDIO_IO_HANDLE_NONE;
-    audio_io_handle_t outputForPrimary = AUDIO_IO_HANDLE_NONE;
-    audio_io_handle_t outputForFormat = AUDIO_IO_HANDLE_NONE;
-    audio_format_t bestFormat = AUDIO_FORMAT_INVALID;
-    audio_format_t bestFormatForFlags = AUDIO_FORMAT_INVALID;
-
-    // Flags which must be present on both the request and the selected output
-    static const audio_output_flags_t kMandatedFlags = (audio_output_flags_t)
-        (AUDIO_OUTPUT_FLAG_HW_AV_SYNC | AUDIO_OUTPUT_FLAG_MMAP_NOIRQ);
+    const uint32_t channelCount = audio_channel_count_from_out_mask(channelMask);
+    const uint32_t hapticChannelCount = audio_channel_count_from_out_mask(
+        channelMask & AUDIO_CHANNEL_HAPTIC_ALL);
 
     for (audio_io_handle_t output : outputs) {
         sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
-        if (!outputDesc->isDuplicated()) {
-            if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) {
-                continue;
-            }
-            // If haptic channel is specified, use the haptic output if present.
-            // When using haptic output, same audio format and sample rate are required.
-            if (hapticChannelCount > 0) {
-                // If haptic channel is specified, use the first output that
-                // support haptic playback.
-                if (audio_channel_count_from_out_mask(
-                        outputDesc->mChannelMask & AUDIO_CHANNEL_HAPTIC_ALL) >= hapticChannelCount
-                        && format == outputDesc->mFormat
-                        && samplingRate == outputDesc->mSamplingRate) {
-                    return output;
-                }
-            } else {
-                // When haptic channel is not specified, skip haptic output.
-                if (outputDesc->mChannelMask & AUDIO_CHANNEL_HAPTIC_ALL) {
-                    continue;
-                }
-            }
-            if ((kMandatedFlags & flags) !=
-                (kMandatedFlags & outputDesc->mProfile->getFlags())) {
-                continue;
-            }
+        // matching criteria values in priority order for current output
+        std::vector<uint32_t> currentMatchCriteria(8, 0);
 
-            // if a valid format is specified, skip output if not compatible
-            if (format != AUDIO_FORMAT_INVALID) {
-                if (!audio_is_linear_pcm(format)) {
-                    continue;
-                }
-                if (AudioPort::isBetterFormatMatch(
-                        outputDesc->mFormat, bestFormat, format)) {
-                    outputForFormat = output;
-                    bestFormat = outputDesc->mFormat;
-                }
-            }
+        if (outputDesc->isDuplicated()) {
+            continue;
+        }
+        if ((kExcludedFlags & outputDesc->mFlags) != 0) {
+            continue;
+        }
 
-            int commonFlags = popcount(outputDesc->mProfile->getFlags() & flags);
-            if (commonFlags >= maxCommonFlags) {
-                if (commonFlags == maxCommonFlags) {
-                    if (format != AUDIO_FORMAT_INVALID
-                            && AudioPort::isBetterFormatMatch(
-                                    outputDesc->mFormat, bestFormatForFlags, format)) {
-                        outputForFlags = output;
-                        bestFormatForFlags = outputDesc->mFormat;
-                    }
-                } else {
-                    outputForFlags = output;
-                    maxCommonFlags = commonFlags;
-                    bestFormatForFlags = outputDesc->mFormat;
-                }
-                ALOGV("selectOutput() commonFlags for output %d, %04x", output, commonFlags);
+        // If haptic channel is specified, use the haptic output if present.
+        // When using haptic output, same audio format and sample rate are required.
+        const uint32_t outputHapticChannelCount = audio_channel_count_from_out_mask(
+            outputDesc->mChannelMask & AUDIO_CHANNEL_HAPTIC_ALL);
+        if ((hapticChannelCount == 0) != (outputHapticChannelCount == 0)) {
+            continue;
+        }
+        if (outputHapticChannelCount >= hapticChannelCount
+            && format == outputDesc->mFormat
+            && samplingRate == outputDesc->mSamplingRate) {
+                currentMatchCriteria[0] = outputHapticChannelCount;
+        }
+
+        // functional flags match
+        currentMatchCriteria[1] = popcount(outputDesc->mFlags & functionalFlags);
+
+        // channel mask and channel count match
+        uint32_t outputChannelCount = audio_channel_count_from_out_mask(outputDesc->mChannelMask);
+        if (channelMask != AUDIO_CHANNEL_NONE && channelCount > 2 &&
+            channelCount <= outputChannelCount) {
+            if ((audio_channel_mask_get_representation(channelMask) ==
+                    audio_channel_mask_get_representation(outputDesc->mChannelMask)) &&
+                    ((channelMask & outputDesc->mChannelMask) == channelMask)) {
+                currentMatchCriteria[2] = outputChannelCount;
             }
-            if (outputDesc->mProfile->getFlags() & AUDIO_OUTPUT_FLAG_PRIMARY) {
-                outputForPrimary = output;
-            }
+            currentMatchCriteria[3] = outputChannelCount;
+        }
+
+        // sampling rate match
+        if (samplingRate > SAMPLE_RATE_HZ_DEFAULT &&
+                samplingRate <= outputDesc->mSamplingRate) {
+            currentMatchCriteria[4] = outputDesc->mSamplingRate;
+        }
+
+        // performance flags match
+        currentMatchCriteria[5] = popcount(outputDesc->mFlags & performanceFlags);
+
+        // format match
+        if (format != AUDIO_FORMAT_INVALID) {
+            currentMatchCriteria[6] =
+                AudioPort::kFormatDistanceMax -
+                AudioPort::formatDistance(format, outputDesc->mFormat);
+        }
+
+        // primary output match
+        currentMatchCriteria[7] = outputDesc->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY;
+
+        // compare match criteria by priority then value
+        if (std::lexicographical_compare(bestMatchCriteria.begin(), bestMatchCriteria.end(),
+                currentMatchCriteria.begin(), currentMatchCriteria.end())) {
+            bestMatchCriteria = currentMatchCriteria;
+            bestOutput = output;
+
+            std::stringstream result;
+            std::copy(bestMatchCriteria.begin(), bestMatchCriteria.end(),
+                std::ostream_iterator<int>(result, " "));
+            ALOGV("%s new bestOutput %d criteria %s",
+                __func__, bestOutput, result.str().c_str());
         }
     }
 
-    if (outputForFlags != AUDIO_IO_HANDLE_NONE) {
-        return outputForFlags;
-    }
-    if (outputForFormat != AUDIO_IO_HANDLE_NONE) {
-        return outputForFormat;
-    }
-    if (outputForPrimary != AUDIO_IO_HANDLE_NONE) {
-        return outputForPrimary;
-    }
-
-    return outputs[0];
+    return bestOutput;
 }
 
 status_t AudioPolicyManager::startOutput(audio_port_handle_t portId)
@@ -3003,22 +3020,11 @@
 
 status_t AudioPolicyManager::removeUidDeviceAffinities(uid_t uid) {
     ALOGV("%s() uid=%d", __FUNCTION__, uid);
-    Vector<AudioDeviceTypeAddr> devices;
-    status_t res =  mPolicyMixes.getDevicesForUid(uid, devices);
-    if (res == NO_ERROR) {
-        // reevaluate outputs for all found devices
-        for (size_t i = 0; i < devices.size(); i++) {
-            sp<DeviceDescriptor> devDesc = mHwModules.getDeviceDescriptor(
-                    devices[i].mType, devices[i].mAddress, String8(),
-                    AUDIO_FORMAT_DEFAULT);
-            SortedVector<audio_io_handle_t> outputs;
-            if (checkOutputsForDevice(devDesc, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
-                    outputs) != NO_ERROR) {
-                ALOGE("%s() error in checkOutputsForDevice for device=%08x addr=%s",
-                        __FUNCTION__, devices[i].mType, devices[i].mAddress.string());
-                return INVALID_OPERATION;
-            }
-        }
+    status_t res = mPolicyMixes.removeUidDeviceAffinities(uid);
+    if (res != NO_ERROR) {
+        ALOGE("%s() Could not remove all device affinities fo uid = %d",
+            __FUNCTION__, uid);
+        return INVALID_OPERATION;
     }
 
     return res;
@@ -3485,7 +3491,7 @@
                             getOutputsForDevices(DeviceVector(sinkDevice), mOutputs);
                     // if the sink device is reachable via an opened output stream, request to go via
                     // this output stream by adding a second source to the patch description
-                    audio_io_handle_t output = selectOutput(outputs);
+                    const audio_io_handle_t output = selectOutput(outputs);
                     if (output != AUDIO_IO_HANDLE_NONE) {
                         sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
                         if (outputDesc->isDuplicated()) {
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 415b2d8..f4abba4 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -2522,6 +2522,9 @@
         CLOGE("Stream %d is unknown", streamId);
         return BAD_VALUE;
     }
+
+    // isConsumerConfigurationDeferred will be off after setConsumers
+    bool isDeferred = stream->isConsumerConfigurationDeferred();
     status_t res = stream->setConsumers(consumers);
     if (res != OK) {
         CLOGE("Stream %d set consumer failed (error %d %s) ", streamId, res, strerror(-res));
@@ -2537,7 +2540,7 @@
         surfaceIds->push_back(id);
     }
 
-    if (stream->isConsumerConfigurationDeferred()) {
+    if (isDeferred) {
         if (!stream->isConfiguring()) {
             CLOGE("Stream %d was already fully configured.", streamId);
             return INVALID_OPERATION;
@@ -2612,7 +2615,6 @@
 sp<Camera3Device::CaptureRequest> Camera3Device::createCaptureRequest(
         const PhysicalCameraSettingsList &request, const SurfaceMap &surfaceMap) {
     ATRACE_CALL();
-    status_t res;
 
     sp<CaptureRequest> newRequest = new CaptureRequest;
     newRequest->mSettingsList = request;
@@ -2626,16 +2628,11 @@
                     inputStreams.data.u8[0]);
             return NULL;
         }
-        // Lazy completion of stream configuration (allocation/registration)
-        // on first use
+
         if (mInputStream->isConfiguring()) {
-            res = mInputStream->finishConfiguration();
-            if (res != OK) {
-                SET_ERR_L("Unable to finish configuring input stream %d:"
-                        " %s (%d)",
-                        mInputStream->getId(), strerror(-res), res);
-                return NULL;
-            }
+            SET_ERR_L("%s: input stream %d is not configured!",
+                    __FUNCTION__, mInputStream->getId());
+            return NULL;
         }
         // Check if stream prepare is blocking requests.
         if (mInputStream->isBlockedByPrepare()) {
@@ -2675,15 +2672,9 @@
             newRequest->mOutputSurfaces[streams.data.i32[i]] = surfaces;
         }
 
-        // Lazy completion of stream configuration (allocation/registration)
-        // on first use
         if (stream->isConfiguring()) {
-            res = stream->finishConfiguration();
-            if (res != OK) {
-                SET_ERR_L("Unable to finish configuring stream %d: %s (%d)",
-                        stream->getId(), strerror(-res), res);
-                return NULL;
-            }
+            SET_ERR_L("%s: stream %d is not configured!", __FUNCTION__, stream->getId());
+            return NULL;
         }
         // Check if stream prepare is blocking requests.
         if (stream->isBlockedByPrepare()) {
@@ -2908,7 +2899,8 @@
     // faster
 
     if (mInputStream != NULL && mInputStream->isConfiguring()) {
-        res = mInputStream->finishConfiguration();
+        bool streamReConfigured = false;
+        res = mInputStream->finishConfiguration(&streamReConfigured);
         if (res != OK) {
             CLOGE("Can't finish configuring input stream %d: %s (%d)",
                     mInputStream->getId(), strerror(-res), res);
@@ -2918,12 +2910,16 @@
             }
             return BAD_VALUE;
         }
+        if (streamReConfigured) {
+            mInterface->onStreamReConfigured(mInputStream->getId());
+        }
     }
 
     for (size_t i = 0; i < mOutputStreams.size(); i++) {
         sp<Camera3OutputStreamInterface> outputStream = mOutputStreams[i];
         if (outputStream->isConfiguring() && !outputStream->isConsumerConfigurationDeferred()) {
-            res = outputStream->finishConfiguration();
+            bool streamReConfigured = false;
+            res = outputStream->finishConfiguration(&streamReConfigured);
             if (res != OK) {
                 CLOGE("Can't finish configuring output stream %d: %s (%d)",
                         outputStream->getId(), strerror(-res), res);
@@ -2933,6 +2929,9 @@
                 }
                 return BAD_VALUE;
             }
+            if (streamReConfigured) {
+                mInterface->onStreamReConfigured(outputStream->getId());
+            }
         }
     }
 
@@ -4780,7 +4779,7 @@
                 __FUNCTION__, handle, streamId);
         return;
     } else {
-        bufferId =  it->second;
+        bufferId = it->second;
         bIdMap.erase(it);
         ALOGV("%s: stream %d now have %zu buffer caches after removing buf %p",
                 __FUNCTION__, streamId, bIdMap.size(), handle);
@@ -4788,6 +4787,22 @@
     mFreedBuffers.push_back(std::make_pair(streamId, bufferId));
 }
 
+void Camera3Device::HalInterface::onStreamReConfigured(int streamId) {
+    std::lock_guard<std::mutex> lock(mBufferIdMapLock);
+    auto mapIt = mBufferIdMaps.find(streamId);
+    if (mapIt == mBufferIdMaps.end()) {
+        ALOGE("%s: streamId %d not found!", __FUNCTION__, streamId);
+        return;
+    }
+
+    BufferIdMap& bIdMap = mapIt->second;
+    for (const auto& it : bIdMap) {
+        uint64_t bufferId = it.second;
+        mFreedBuffers.push_back(std::make_pair(streamId, bufferId));
+    }
+    bIdMap.clear();
+}
+
 /**
  * RequestThread inner class methods
  */
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index f8245df..23df3c7 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -336,6 +336,8 @@
         // Get a vector of bufferId of currently inflight buffers
         void getInflightRequestBufferKeys(std::vector<uint64_t>* out);
 
+        void onStreamReConfigured(int streamId);
+
         static const uint64_t BUFFER_ID_NO_BUFFER = 0;
       private:
         // Always valid
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp
index 12ff130..d73a2f9 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp
@@ -287,8 +287,11 @@
     return (mState == STATE_IN_CONFIG) || (mState == STATE_IN_RECONFIG);
 }
 
-status_t Camera3Stream::finishConfiguration() {
+status_t Camera3Stream::finishConfiguration(/*out*/bool* streamReconfigured) {
     ATRACE_CALL();
+    if (streamReconfigured != nullptr) {
+        *streamReconfigured = false;
+    }
     Mutex::Autolock l(mLock);
     switch (mState) {
         case STATE_ERROR:
@@ -313,7 +316,7 @@
 
     // Register for idle tracking
     sp<StatusTracker> statusTracker = mStatusTracker.promote();
-    if (statusTracker != 0) {
+    if (statusTracker != 0 && mStatusId == StatusTracker::NO_STATUS_ID) {
         mStatusId = statusTracker->addComponent();
     }
 
@@ -332,6 +335,7 @@
     mPrepareBlockRequest = true;
     mStreamUnpreparable = false;
 
+    bool reconfiguring = (mState == STATE_IN_RECONFIG);
     status_t res;
     res = configureQueueLocked();
     // configureQueueLocked could return error in case of abandoned surface.
@@ -348,6 +352,9 @@
         return res;
     }
 
+    if (reconfiguring && streamReconfigured != nullptr) {
+        *streamReconfigured = true;
+    }
     mState = STATE_CONFIGURED;
 
     return res;
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.h b/services/camera/libcameraservice/device3/Camera3Stream.h
index 3d21029..c916fe8 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.h
+++ b/services/camera/libcameraservice/device3/Camera3Stream.h
@@ -197,6 +197,8 @@
      * after this call, but can still be read until the destruction of the
      * stream.
      *
+     * streamReconfigured: set to true when a stream is being reconfigured.
+     *
      * Returns:
      *   OK on a successful configuration
      *   NO_INIT in case of a serious error from the HAL device
@@ -204,7 +206,7 @@
      *   INVALID_OPERATION in case connecting to the consumer failed or consumer
      *       doesn't exist yet.
      */
-    status_t         finishConfiguration();
+    status_t         finishConfiguration(/*out*/bool* streamReconfigured = nullptr);
 
     /**
      * Cancels the stream configuration process. This returns the stream to the
diff --git a/services/camera/libcameraservice/device3/Camera3StreamInterface.h b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
index 5cd11b7..73f501a 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamInterface.h
+++ b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
@@ -130,13 +130,15 @@
      * modified after this call, but can still be read until the destruction of
      * the stream.
      *
+     * streamReconfigured: set to true when a stream is being reconfigured.
+     *
      * Returns:
      *   OK on a successful configuration
      *   NO_INIT in case of a serious error from the HAL device
      *   NO_MEMORY in case of an error registering buffers
      *   INVALID_OPERATION in case connecting to the consumer failed
      */
-    virtual status_t finishConfiguration() = 0;
+    virtual status_t finishConfiguration(/*out*/bool* streamReconfigured = nullptr) = 0;
 
     /**
      * Cancels the stream configuration process. This returns the stream to the
diff --git a/services/mediacodec/seccomp_policy/mediaswcodec-arm.policy b/services/mediacodec/seccomp_policy/mediaswcodec-arm.policy
index 02cedba..f75515a 100644
--- a/services/mediacodec/seccomp_policy/mediaswcodec-arm.policy
+++ b/services/mediacodec/seccomp_policy/mediaswcodec-arm.policy
@@ -61,3 +61,24 @@
 restart_syscall: 1
 rt_sigreturn: 1
 getrandom: 1
+madvise: 1
+
+# crash dump policy additions
+sigreturn: 1
+clock_gettime: 1
+futex: 1
+getpid: 1
+gettid: 1
+pipe2: 1
+recvmsg: 1
+process_vm_readv: 1
+tgkill: 1
+rt_sigaction: 1
+rt_tgsigqueueinfo: 1
+#prctl: arg0 == PR_GET_NO_NEW_PRIVS || arg0 == 0x53564d41
+#mprotect: arg2 in 0x1|0x2
+#mmap2: arg2 in 0x1|0x2
+geteuid32: 1
+getgid32: 1
+getegid32: 1
+getgroups32: 1
diff --git a/services/mediaextractor/Android.bp b/services/mediaextractor/Android.bp
new file mode 100644
index 0000000..b812244
--- /dev/null
+++ b/services/mediaextractor/Android.bp
@@ -0,0 +1,71 @@
+// service library
+cc_library_shared {
+    name: "libmediaextractorservice",
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+    srcs: ["MediaExtractorService.cpp"],
+
+    shared_libs: [
+        "libmedia",
+        "libstagefright",
+        "libbinder",
+        "libutils",
+    ],
+}
+
+// service executable
+cc_binary {
+    name: "mediaextractor",
+
+    srcs: ["main_extractorservice.cpp"],
+    shared_libs: [
+        "libmedia",
+        "libmediaextractorservice",
+        "libbinder",
+        "libutils",
+        "liblog",
+        "libavservices_minijail",
+    ],
+    target: {
+        android: {
+            product_variables: {
+                malloc_not_svelte: {
+                    // Scudo increases memory footprint, so only enable on
+                    // non-svelte devices.
+                    shared_libs: ["libc_scudo"],
+                },
+            },
+        },
+    },
+    init_rc: ["mediaextractor.rc"],
+
+    include_dirs: ["frameworks/av/media/libmedia"],
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+}
+
+prebuilt_etc {
+    name: "mediaextractor.policy",
+    sub_dir: "seccomp_policy",
+    arch: {
+        arm: {
+            src: "seccomp_policy/mediaextractor-arm.policy",
+        },
+        arm64: {
+            src: "seccomp_policy/mediaextractor-arm64.policy",
+        },
+        x86: {
+            src: "seccomp_policy/mediaextractor-x86.policy",
+        },
+        x86_64: {
+            src: "seccomp_policy/mediaextractor-x86_64.policy",
+        },
+    },
+    required: ["crash_dump.policy"],
+}
+
diff --git a/services/mediaextractor/Android.mk b/services/mediaextractor/Android.mk
deleted file mode 100644
index 9db6ed1..0000000
--- a/services/mediaextractor/Android.mk
+++ /dev/null
@@ -1,43 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-# service library
-include $(CLEAR_VARS)
-LOCAL_CFLAGS := -Wall -Werror
-LOCAL_SRC_FILES := \
-    MediaExtractorService.cpp
-
-LOCAL_SHARED_LIBRARIES := libmedia libstagefright libbinder libutils
-LOCAL_MODULE:= libmediaextractorservice
-include $(BUILD_SHARED_LIBRARY)
-
-
-# service executable
-include $(CLEAR_VARS)
-# seccomp filters are defined for the following architectures:
-LOCAL_REQUIRED_MODULES_arm := crash_dump.policy mediaextractor.policy
-LOCAL_REQUIRED_MODULES_arm64 := crash_dump.policy mediaextractor.policy
-LOCAL_REQUIRED_MODULES_x86 := crash_dump.policy mediaextractor.policy
-LOCAL_REQUIRED_MODULES_x86_64 := crash_dump.policy mediaextractor.policy
-
-LOCAL_SRC_FILES := main_extractorservice.cpp
-ifneq (true, $(filter true, $(MALLOC_SVELTE)))
-# Scudo increases memory footprint, so only use on non-svelte configs.
-LOCAL_SHARED_LIBRARIES := libc_scudo
-endif
-LOCAL_SHARED_LIBRARIES += libmedia libmediaextractorservice libbinder libutils \
-    liblog libandroidicu libavservices_minijail
-LOCAL_MODULE:= mediaextractor
-LOCAL_INIT_RC := mediaextractor.rc
-LOCAL_C_INCLUDES := frameworks/av/media/libmedia
-LOCAL_CFLAGS := -Wall -Werror
-include $(BUILD_EXECUTABLE)
-
-# service seccomp filter
-ifeq ($(TARGET_ARCH), $(filter $(TARGET_ARCH), arm arm64 x86 x86_64))
-include $(CLEAR_VARS)
-LOCAL_MODULE := mediaextractor.policy
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/seccomp_policy
-LOCAL_SRC_FILES := seccomp_policy/mediaextractor-$(TARGET_ARCH).policy
-include $(BUILD_PREBUILT)
-endif
diff --git a/services/mediaextractor/main_extractorservice.cpp b/services/mediaextractor/main_extractorservice.cpp
index bb9a56b..3c4125b 100644
--- a/services/mediaextractor/main_extractorservice.cpp
+++ b/services/mediaextractor/main_extractorservice.cpp
@@ -15,7 +15,6 @@
 ** limitations under the License.
 */
 
-#include <aicu/AIcu.h>
 #include <fcntl.h>
 #include <sys/prctl.h>
 #include <sys/wait.h>
@@ -37,7 +36,7 @@
 using namespace android;
 
 static const char kSystemSeccompPolicyPath[] =
-        "/system/etc/seccomp_policy/mediaextractor.policy";
+        "/apex/com.android.media/etc/seccomp_policy/mediaextractor.policy";
 static const char kVendorSeccompPolicyPath[] =
         "/vendor/etc/seccomp_policy/mediaextractor.policy";
 
@@ -58,8 +57,6 @@
 
     SetUpMinijail(kSystemSeccompPolicyPath, kVendorSeccompPolicyPath);
 
-    AIcu_initializeIcuOrDie();
-
     strcpy(argv[0], "media.extractor");
     sp<ProcessState> proc(ProcessState::self());
     sp<IServiceManager> sm = defaultServiceManager();
diff --git a/services/oboeservice/AAudioClientTracker.cpp b/services/oboeservice/AAudioClientTracker.cpp
index 83704ba..8572561 100644
--- a/services/oboeservice/AAudioClientTracker.cpp
+++ b/services/oboeservice/AAudioClientTracker.cpp
@@ -67,6 +67,12 @@
                                          const sp<IAAudioClient>& client) {
     ALOGV("registerClient(), calling pid = %d, getpid() = %d\n", pid, getpid());
 
+    if (client.get() == nullptr) {
+        ALOGE("AAudioClientTracker::%s() client is NULL!", __func__);
+        android_errorWriteLog(0x534e4554, "116230453");
+        return AAUDIO_ERROR_NULL;
+    }
+
     std::lock_guard<std::mutex> lock(mLock);
     if (mNotificationClients.count(pid) == 0) {
         sp<NotificationClient> notificationClient = new NotificationClient(pid);