Merge "Improve code coverage for httplive_fuzzer"
diff --git a/media/libstagefright/RemoteMediaExtractor.cpp b/media/libstagefright/RemoteMediaExtractor.cpp
index baa2ca1..574fc1a 100644
--- a/media/libstagefright/RemoteMediaExtractor.cpp
+++ b/media/libstagefright/RemoteMediaExtractor.cpp
@@ -16,9 +16,16 @@
 
 //#define LOG_NDEBUG 0
 #define LOG_TAG "RemoteMediaExtractor"
+
+#include <list>
+#include <pthread.h>
+#include <condition_variable>
+#include <mutex>
+
 #include <utils/Log.h>
 
 #include <binder/IPCThreadState.h>
+#include <cutils/properties.h>
 #include <media/stagefright/InterfaceUtils.h>
 #include <media/MediaMetricsItem.h>
 #include <media/stagefright/MediaSource.h>
@@ -90,10 +97,65 @@
     }
 }
 
+static pthread_t myThread;
+static std::list<sp<DataSource>> pending;
+static std::mutex pending_mutex;
+static std::condition_variable pending_added;
+
+static void* closing_thread_func(void *arg) {
+    while (true) {
+        sp<DataSource> ds = nullptr;
+        std::unique_lock _lk(pending_mutex);
+        pending_added.wait(_lk, []{return !pending.empty();});
+        ALOGV("worker thread wake up with %zu entries", pending.size());
+        if (!pending.empty()) {
+            ds = pending.front();
+            (void) pending.pop_front();
+        }
+        _lk.unlock();       // unique_lock is not scoped
+        if (ds != nullptr) {
+            ds->close();
+        }
+    }
+
+    ALOGE("[unexpected] worker thread quit");
+    return arg;
+}
+
+// this can be '&ds' as long as the pending.push_back() bumps the
+// reference counts to ensure the object lives long enough
+static void start_close_thread(sp<DataSource> &ds) {
+
+    // make sure we have our (single) worker thread
+    static std::once_flag sCheckOnce;
+    std::call_once(sCheckOnce, [&](){
+        pthread_attr_t attr;
+        pthread_attr_init(&attr);
+        pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+        pthread_create(&myThread, &attr, closing_thread_func, nullptr);
+        pthread_attr_destroy(&attr);
+    });
+
+    {
+        std::lock_guard _lm(pending_mutex);     // scoped, no explicit unlock
+        pending.push_back(ds);
+    }
+    pending_added.notify_one();     // get the worker thread going
+}
+
 RemoteMediaExtractor::~RemoteMediaExtractor() {
     delete mExtractor;
-    mSource->close();
-    mSource.clear();
+    // TODO(287851984) hook for changing behavior this dynamically, drop after testing
+    int8_t new_scheme = property_get_bool("debug.mediaextractor.delayedclose", 1);
+    if (new_scheme != 0) {
+        ALOGV("deferred close()");
+        start_close_thread(mSource);
+        mSource.clear();
+    } else {
+        ALOGV("immediate close()");
+        mSource->close();
+        mSource.clear();
+    }
     mExtractorPlugin = nullptr;
     // log the current record, provided it has some information worth recording
     if (MEDIA_LOG) {
diff --git a/services/audioflinger/Android.bp b/services/audioflinger/Android.bp
index 73c2ff4..85746f3 100644
--- a/services/audioflinger/Android.bp
+++ b/services/audioflinger/Android.bp
@@ -151,7 +151,6 @@
         "DeviceEffectManager.cpp",
         "Effects.cpp",
         "PatchPanel.cpp",
-        "PropertyUtils.cpp",
         "Threads.cpp",
         "Tracks.cpp",
     ],
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 926110882..dd84bd5 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -58,7 +58,7 @@
 #include <audiomanager/AudioManager.h>
 
 #include "AudioFlinger.h"
-#include "PropertyUtils.h"
+#include <afutils/PropertyUtils.h>
 
 #include <media/AudioResamplerPublic.h>
 
diff --git a/services/audioflinger/afutils/Android.bp b/services/audioflinger/afutils/Android.bp
index 4c03e07..1580b8f 100644
--- a/services/audioflinger/afutils/Android.bp
+++ b/services/audioflinger/afutils/Android.bp
@@ -32,18 +32,21 @@
 
     defaults: [
         "audioflinger_utils_flags_defaults",
+        "latest_android_media_audio_common_types_cpp_shared", // PropertyUtils.cpp
     ],
 
     srcs: [
         "AudioWatchdog.cpp",
         "BufLog.cpp",
         "NBAIO_Tee.cpp",
+        "PropertyUtils.cpp",
         "TypedLogger.cpp",
     ],
 
     shared_libs: [
         "libaudioutils",
         "libbase",
+        "libcutils", // property_get_int32
         "liblog",
         "libnbaio",
         "libnblog",
@@ -54,6 +57,10 @@
         "libsndfile",
     ],
 
+    header_libs: [
+        "libaaudio_headers",  // PropertyUtils.cpp
+    ],
+
     include_dirs: [
         "frameworks/av/services/audioflinger",  // for configuration
     ],
diff --git a/services/audioflinger/PropertyUtils.cpp b/services/audioflinger/afutils/PropertyUtils.cpp
similarity index 100%
rename from services/audioflinger/PropertyUtils.cpp
rename to services/audioflinger/afutils/PropertyUtils.cpp
diff --git a/services/audioflinger/PropertyUtils.h b/services/audioflinger/afutils/PropertyUtils.h
similarity index 100%
rename from services/audioflinger/PropertyUtils.h
rename to services/audioflinger/afutils/PropertyUtils.h