Merge "FastThread: Remove unused NBLog variable"
diff --git a/media/audioserver/Android.mk b/media/audioserver/Android.mk
index ddf98f6..a53a629 100644
--- a/media/audioserver/Android.mk
+++ b/media/audioserver/Android.mk
@@ -22,9 +22,6 @@
 	libsoundtriggerservice \
 	libutils
 
-LOCAL_STATIC_LIBRARIES := \
-	libjsoncpp
-
 # TODO oboeservice is the old folder name for aaudioservice. It will be changed.
 LOCAL_C_INCLUDES := \
 	frameworks/av/services/audioflinger \
diff --git a/media/libmediaplayer2/Android.bp b/media/libmediaplayer2/Android.bp
index 0672ca9..e30da85 100644
--- a/media/libmediaplayer2/Android.bp
+++ b/media/libmediaplayer2/Android.bp
@@ -8,8 +8,6 @@
     name: "libmediaplayer2",
 
     srcs: [
-        "JAudioTrack.cpp",
-        "JavaVMHelper.cpp",
         "MediaPlayer2AudioOutput.cpp",
         "mediaplayer2.cpp",
     ],
@@ -84,3 +82,55 @@
         },
     },
 }
+
+cc_library {
+    name: "libmedia2_jni_core",
+
+    srcs: [
+        "JavaVMHelper.cpp",
+        "JAudioTrack.cpp",
+        "JMedia2HTTPService.cpp",
+        "JMedia2HTTPConnection.cpp",
+    ],
+
+    shared_libs: [
+        "android.hidl.token@1.0-utils",
+        "liblog",
+        "libcutils",
+        "libutils",
+        "libbinder",
+        "libstagefright_foundation",
+        "libmediaextractor",
+        "libdl",
+        "libaudioutils",
+        "libaudioclient",
+        "libnativehelper",
+    ],
+
+    include_dirs: [
+        "frameworks/av/media/libmedia/include",
+        "frameworks/base/core/jni",
+    ],
+
+    export_include_dirs: [
+        "include",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wno-error=deprecated-declarations",
+        "-Wall",
+    ],
+
+    sanitize: {
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+        cfi: true,
+        diag: {
+            cfi: true,
+        },
+    },
+
+}
diff --git a/media/libmediaplayer2/JMedia2HTTPConnection.cpp b/media/libmediaplayer2/JMedia2HTTPConnection.cpp
new file mode 100644
index 0000000..d264a7f
--- /dev/null
+++ b/media/libmediaplayer2/JMedia2HTTPConnection.cpp
@@ -0,0 +1,180 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "JMedia2HTTPConnection"
+#include <utils/Log.h>
+
+#include <mediaplayer2/JavaVMHelper.h>
+#include <mediaplayer2/JMedia2HTTPConnection.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <nativehelper/ScopedLocalRef.h>
+
+#include "log/log.h"
+#include "jni.h"
+#include <nativehelper/JNIHelp.h>
+
+namespace android {
+
+static const size_t kBufferSize = 32768;
+
+JMedia2HTTPConnection::JMedia2HTTPConnection(JNIEnv *env, jobject thiz) {
+    mMedia2HTTPConnectionObj = env->NewGlobalRef(thiz);
+    CHECK(mMedia2HTTPConnectionObj != NULL);
+
+    ScopedLocalRef<jclass> media2HTTPConnectionClass(
+            env, env->GetObjectClass(mMedia2HTTPConnectionObj));
+    CHECK(media2HTTPConnectionClass.get() != NULL);
+
+    mConnectMethod = env->GetMethodID(
+            media2HTTPConnectionClass.get(),
+            "connect",
+            "(Ljava/lang/String;Ljava/lang/String;)Z");
+    CHECK(mConnectMethod != NULL);
+
+    mDisconnectMethod = env->GetMethodID(
+            media2HTTPConnectionClass.get(),
+            "disconnect",
+            "()V");
+    CHECK(mDisconnectMethod != NULL);
+
+    mReadAtMethod = env->GetMethodID(
+            media2HTTPConnectionClass.get(),
+            "readAt",
+            "(J[BI)I");
+    CHECK(mReadAtMethod != NULL);
+
+    mGetSizeMethod = env->GetMethodID(
+            media2HTTPConnectionClass.get(),
+            "getSize",
+            "()J");
+    CHECK(mGetSizeMethod != NULL);
+
+    mGetMIMETypeMethod = env->GetMethodID(
+            media2HTTPConnectionClass.get(),
+            "getMIMEType",
+            "()Ljava/lang/String;");
+    CHECK(mGetMIMETypeMethod != NULL);
+
+    mGetUriMethod = env->GetMethodID(
+            media2HTTPConnectionClass.get(),
+            "getUri",
+            "()Ljava/lang/String;");
+    CHECK(mGetUriMethod != NULL);
+
+    ScopedLocalRef<jbyteArray> tmp(
+        env, env->NewByteArray(kBufferSize));
+    mByteArrayObj = (jbyteArray)env->NewGlobalRef(tmp.get());
+    CHECK(mByteArrayObj != NULL);
+}
+
+JMedia2HTTPConnection::~JMedia2HTTPConnection() {
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
+    env->DeleteGlobalRef(mMedia2HTTPConnectionObj);
+    env->DeleteGlobalRef(mByteArrayObj);
+}
+
+bool JMedia2HTTPConnection::connect(
+        const char *uri, const KeyedVector<String8, String8> *headers) {
+    String8 tmp("");
+    if (headers != NULL) {
+        for (size_t i = 0; i < headers->size(); ++i) {
+            tmp.append(headers->keyAt(i));
+            tmp.append(String8(": "));
+            tmp.append(headers->valueAt(i));
+            tmp.append(String8("\r\n"));
+        }
+    }
+
+    JNIEnv* env = JavaVMHelper::getJNIEnv();
+    jstring juri = env->NewStringUTF(uri);
+    jstring jheaders = env->NewStringUTF(tmp.string());
+
+    jboolean ret =
+        env->CallBooleanMethod(mMedia2HTTPConnectionObj, mConnectMethod, juri, jheaders);
+
+    env->DeleteLocalRef(juri);
+    env->DeleteLocalRef(jheaders);
+
+    return (bool)ret;
+}
+
+void JMedia2HTTPConnection::disconnect() {
+    JNIEnv* env = JavaVMHelper::getJNIEnv();
+    env->CallVoidMethod(mMedia2HTTPConnectionObj, mDisconnectMethod);
+}
+
+ssize_t JMedia2HTTPConnection::readAt(off64_t offset, void *data, size_t size) {
+    JNIEnv* env = JavaVMHelper::getJNIEnv();
+
+    if (size > kBufferSize) {
+        size = kBufferSize;
+    }
+
+    jint n = env->CallIntMethod(
+            mMedia2HTTPConnectionObj, mReadAtMethod, (jlong)offset, mByteArrayObj, (jint)size);
+
+    if (n > 0) {
+        env->GetByteArrayRegion(
+                mByteArrayObj,
+                0,
+                n,
+                (jbyte *)data);
+    }
+
+    return n;
+}
+
+off64_t JMedia2HTTPConnection::getSize() {
+    JNIEnv* env = JavaVMHelper::getJNIEnv();
+    return (off64_t)(env->CallLongMethod(mMedia2HTTPConnectionObj, mGetSizeMethod));
+}
+
+status_t JMedia2HTTPConnection::getMIMEType(String8 *mimeType) {
+    JNIEnv* env = JavaVMHelper::getJNIEnv();
+    jstring jmime = (jstring)env->CallObjectMethod(mMedia2HTTPConnectionObj, mGetMIMETypeMethod);
+    jboolean flag = env->ExceptionCheck();
+    if (flag) {
+        env->ExceptionClear();
+        return UNKNOWN_ERROR;
+    }
+
+    const char *str = env->GetStringUTFChars(jmime, 0);
+    if (str != NULL) {
+        *mimeType = String8(str);
+    } else {
+        *mimeType = "application/octet-stream";
+    }
+    env->ReleaseStringUTFChars(jmime, str);
+    return OK;
+}
+
+status_t JMedia2HTTPConnection::getUri(String8 *uri) {
+    JNIEnv* env = JavaVMHelper::getJNIEnv();
+    jstring juri = (jstring)env->CallObjectMethod(mMedia2HTTPConnectionObj, mGetUriMethod);
+    jboolean flag = env->ExceptionCheck();
+    if (flag) {
+        env->ExceptionClear();
+        return UNKNOWN_ERROR;
+    }
+
+    const char *str = env->GetStringUTFChars(juri, 0);
+    *uri = String8(str);
+    env->ReleaseStringUTFChars(juri, str);
+    return OK;
+}
+
+}  // namespace android
diff --git a/media/libmediaplayer2/JMedia2HTTPService.cpp b/media/libmediaplayer2/JMedia2HTTPService.cpp
new file mode 100644
index 0000000..264c15d
--- /dev/null
+++ b/media/libmediaplayer2/JMedia2HTTPService.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2017, 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "JMedia2HTTPService"
+#include <utils/Log.h>
+
+#include <jni.h>
+
+#include <mediaplayer2/JavaVMHelper.h>
+#include <mediaplayer2/JMedia2HTTPService.h>
+#include <mediaplayer2/JMedia2HTTPConnection.h>
+#include <media/stagefright/foundation/ADebug.h>
+
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/ScopedLocalRef.h>
+
+namespace android {
+
+JMedia2HTTPService::JMedia2HTTPService(JNIEnv *env, jobject thiz) {
+    mMedia2HTTPServiceObj = env->NewGlobalRef(thiz);
+    CHECK(mMedia2HTTPServiceObj != NULL);
+
+    ScopedLocalRef<jclass> media2HTTPServiceClass(env, env->GetObjectClass(mMedia2HTTPServiceObj));
+    CHECK(media2HTTPServiceClass.get() != NULL);
+
+    mMakeHTTPConnectionMethod = env->GetMethodID(
+            media2HTTPServiceClass.get(),
+            "makeHTTPConnection",
+            "()Landroid/media/Media2HTTPConnection;");
+    CHECK(mMakeHTTPConnectionMethod != NULL);
+}
+
+JMedia2HTTPService::~JMedia2HTTPService() {
+    JNIEnv *env = JavaVMHelper::getJNIEnv();
+    env->DeleteGlobalRef(mMedia2HTTPServiceObj);
+}
+
+sp<MediaHTTPConnection> JMedia2HTTPService::makeHTTPConnection() {
+    JNIEnv* env = JavaVMHelper::getJNIEnv();
+    jobject media2HTTPConnectionObj =
+        env->CallObjectMethod(mMedia2HTTPServiceObj, mMakeHTTPConnectionMethod);
+
+    return new JMedia2HTTPConnection(env, media2HTTPConnectionObj);
+}
+
+}  // namespace android
diff --git a/media/libmediaplayer2/include/mediaplayer2/JMedia2HTTPConnection.h b/media/libmediaplayer2/include/mediaplayer2/JMedia2HTTPConnection.h
new file mode 100644
index 0000000..15f7f83
--- /dev/null
+++ b/media/libmediaplayer2/include/mediaplayer2/JMedia2HTTPConnection.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2017, 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 _J_MEDIA2_HTTP_CONNECTION_H_
+#define _J_MEDIA2_HTTP_CONNECTION_H_
+
+#include "jni.h"
+
+#include <media/MediaHTTPConnection.h>
+#include <media/stagefright/foundation/ABase.h>
+
+namespace android {
+
+struct JMedia2HTTPConnection : public MediaHTTPConnection {
+    JMedia2HTTPConnection(JNIEnv *env, jobject thiz);
+
+    virtual bool connect(
+            const char *uri, const KeyedVector<String8, String8> *headers) override;
+
+    virtual void disconnect() override;
+    virtual ssize_t readAt(off64_t offset, void *data, size_t size) override;
+    virtual off64_t getSize() override;
+    virtual status_t getMIMEType(String8 *mimeType) override;
+    virtual status_t getUri(String8 *uri) override;
+
+protected:
+    virtual ~JMedia2HTTPConnection();
+
+private:
+    jobject mMedia2HTTPConnectionObj;
+    jmethodID mConnectMethod;
+    jmethodID mDisconnectMethod;
+    jmethodID mReadAtMethod;
+    jmethodID mGetSizeMethod;
+    jmethodID mGetMIMETypeMethod;
+    jmethodID mGetUriMethod;
+
+    jbyteArray mByteArrayObj;
+
+    DISALLOW_EVIL_CONSTRUCTORS(JMedia2HTTPConnection);
+};
+
+}  // namespace android
+
+#endif  // _J_MEDIA2_HTTP_CONNECTION_H_
diff --git a/media/libmediaplayer2/include/mediaplayer2/JMedia2HTTPService.h b/media/libmediaplayer2/include/mediaplayer2/JMedia2HTTPService.h
new file mode 100644
index 0000000..bf61a7f
--- /dev/null
+++ b/media/libmediaplayer2/include/mediaplayer2/JMedia2HTTPService.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2017, 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 _J_MEDIA2_HTTP_SERVICE_H_
+#define _J_MEDIA2_HTTP_SERVICE_H_
+
+#include <jni.h>
+#include <utils/RefBase.h>
+
+#include <media/MediaHTTPService.h>
+#include <media/MediaHTTPConnection.h>
+#include <media/stagefright/foundation/ABase.h>
+
+namespace android {
+
+struct JMedia2HTTPService : public MediaHTTPService {
+    JMedia2HTTPService(JNIEnv *env, jobject thiz);
+
+    virtual sp<MediaHTTPConnection> makeHTTPConnection() override;
+
+protected:
+    virtual ~JMedia2HTTPService();
+
+private:
+    jobject mMedia2HTTPServiceObj;
+
+    jmethodID mMakeHTTPConnectionMethod;
+
+    DISALLOW_EVIL_CONSTRUCTORS(JMedia2HTTPService);
+};
+
+}  // namespace android
+
+#endif  // _J_MEDIA2_HTTP_SERVICE_H_
diff --git a/media/ndk/Android.bp b/media/ndk/Android.bp
index 4a36681..2f298cf 100644
--- a/media/ndk/Android.bp
+++ b/media/ndk/Android.bp
@@ -82,6 +82,7 @@
         "libbinder",
         "libgui",
         "libui",
+        "libmedia2_jni_core",
     ],
 
     export_include_dirs: ["include"],
diff --git a/media/ndk/NdkMediaDataSource.cpp b/media/ndk/NdkMediaDataSource.cpp
index 9d00e5e..ec2aed6 100644
--- a/media/ndk/NdkMediaDataSource.cpp
+++ b/media/ndk/NdkMediaDataSource.cpp
@@ -23,13 +23,18 @@
 #include <jni.h>
 #include <unistd.h>
 
+#include <android_runtime/AndroidRuntime.h>
+#include <android_util_Binder.h>
 #include <binder/IServiceManager.h>
 #include <cutils/properties.h>
 #include <utils/Log.h>
 #include <utils/StrongPointer.h>
+#include <media/IMediaHTTPService.h>
 #include <media/NdkMediaError.h>
 #include <media/NdkMediaDataSource.h>
 #include <media/stagefright/InterfaceUtils.h>
+#include <mediaplayer2/JavaVMHelper.h>
+#include <mediaplayer2/JMedia2HTTPService.h>
 
 #include "../../libstagefright/include/HTTPBase.h"
 #include "../../libstagefright/include/NuCachedSource2.h"
@@ -92,6 +97,84 @@
     }
 }
 
+static sp<MediaHTTPService> createMediaHttpServiceFromJavaObj(JNIEnv *env, jobject obj, int version) {
+    if (obj == NULL) {
+        return NULL;
+    }
+    switch (version) {
+        case 1:
+            return interface_cast<IMediaHTTPService>(ibinderForJavaObject(env, obj));
+        case 2:
+            return new JMedia2HTTPService(env, obj);
+        default:
+            return NULL;
+    }
+}
+
+static sp<MediaHTTPService> createMediaHttpServiceTemplate(
+        JNIEnv *env,
+        const char *uri,
+        const char *clazz,
+        const char *method,
+        const char *signature,
+        int version) {
+    jobject service = NULL;
+    if (env == NULL) {
+        ALOGE("http service must be created from Java thread");
+        return NULL;
+    }
+
+    jclass mediahttpclass = env->FindClass(clazz);
+    if (mediahttpclass == NULL) {
+        ALOGE("can't find Media(2)HttpService");
+        env->ExceptionClear();
+        return NULL;
+    }
+
+    jmethodID mediaHttpCreateMethod = env->GetStaticMethodID(mediahttpclass, method, signature);
+    if (mediaHttpCreateMethod == NULL) {
+        ALOGE("can't find method");
+        env->ExceptionClear();
+        return NULL;
+    }
+
+    jstring juri = env->NewStringUTF(uri);
+
+    service = env->CallStaticObjectMethod(mediahttpclass, mediaHttpCreateMethod, juri);
+    env->DeleteLocalRef(juri);
+
+    env->ExceptionClear();
+    sp<MediaHTTPService> httpService = createMediaHttpServiceFromJavaObj(env, service, version);
+    return httpService;
+
+}
+
+sp<MediaHTTPService> createMediaHttpService(const char *uri, int version) {
+
+    JNIEnv *env;
+    const char *clazz, *method, *signature;
+
+    switch (version) {
+        case 1:
+            env = AndroidRuntime::getJNIEnv();
+            clazz = "android/media/MediaHTTPService";
+            method = "createHttpServiceBinderIfNecessary";
+            signature = "(Ljava/lang/String;)Landroid/os/IBinder;";
+            break;
+        case 2:
+            env = JavaVMHelper::getJNIEnv();
+            clazz = "android/media/Media2HTTPService";
+            method = "createHTTPService";
+            signature = "(Ljava/lang/String;)Landroid/media/Media2HTTPService;";
+            break;
+        default:
+            return NULL;
+    }
+
+    return createMediaHttpServiceTemplate(env, uri, clazz, method, signature, version);
+
+}
+
 extern "C" {
 
 EXPORT
diff --git a/media/ndk/NdkMediaDataSourcePriv.h b/media/ndk/NdkMediaDataSourcePriv.h
index ea9c865..3b0aa59 100644
--- a/media/ndk/NdkMediaDataSourcePriv.h
+++ b/media/ndk/NdkMediaDataSourcePriv.h
@@ -32,6 +32,7 @@
 #include <sys/types.h>
 
 #include <media/DataSource.h>
+#include <media/MediaHTTPService.h>
 #include <media/NdkMediaDataSource.h>
 #include <utils/Mutex.h>
 #include <utils/String8.h>
@@ -59,5 +60,7 @@
 
 };
 
+sp<MediaHTTPService> createMediaHttpService(const char *uri, int version);
+
 #endif // _NDK_MEDIA_DATASOURCE_PRIV_H
 
diff --git a/media/ndk/NdkMediaExtractor.cpp b/media/ndk/NdkMediaExtractor.cpp
index c66cd50..f00a19c 100644
--- a/media/ndk/NdkMediaExtractor.cpp
+++ b/media/ndk/NdkMediaExtractor.cpp
@@ -96,39 +96,12 @@
 
     ALOGV("setDataSource(%s)", uri);
 
-    JNIEnv *env = AndroidRuntime::getJNIEnv();
-    jobject service = NULL;
-    if (env == NULL) {
-        ALOGE("setDataSource(path) must be called from Java thread");
+    sp<MediaHTTPService> httpService = createMediaHttpService(uri, /* version = */ 1);
+    if (httpService == NULL) {
+        ALOGE("can't create http service");
         return AMEDIA_ERROR_UNSUPPORTED;
     }
 
-    jclass mediahttpclass = env->FindClass("android/media/MediaHTTPService");
-    if (mediahttpclass == NULL) {
-        ALOGE("can't find MediaHttpService");
-        env->ExceptionClear();
-        return AMEDIA_ERROR_UNSUPPORTED;
-    }
-
-    jmethodID mediaHttpCreateMethod = env->GetStaticMethodID(mediahttpclass,
-            "createHttpServiceBinderIfNecessary", "(Ljava/lang/String;)Landroid/os/IBinder;");
-    if (mediaHttpCreateMethod == NULL) {
-        ALOGE("can't find method");
-        env->ExceptionClear();
-        return AMEDIA_ERROR_UNSUPPORTED;
-    }
-
-    jstring jloc = env->NewStringUTF(uri);
-
-    service = env->CallStaticObjectMethod(mediahttpclass, mediaHttpCreateMethod, jloc);
-    env->DeleteLocalRef(jloc);
-
-    sp<IMediaHTTPService> httpService;
-    if (service != NULL) {
-        sp<IBinder> binder = ibinderForJavaObject(env, service);
-        httpService = interface_cast<IMediaHTTPService>(binder);
-    }
-
     KeyedVector<String8, String8> headers;
     for (int i = 0; i < numheaders; ++i) {
         String8 key8(keys[i]);
@@ -138,7 +111,6 @@
 
     status_t err;
     err = mData->mImpl->setDataSource(httpService, uri, numheaders > 0 ? &headers : NULL);
-    env->ExceptionClear();
     return translate_error(err);
 }
 
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index 2c26ba4..c0aa477 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -42,7 +42,6 @@
 
 LOCAL_STATIC_LIBRARIES := \
     libcpustats \
-    libjsoncpp \
     libsndfile \
 
 LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 47dbabf..6e65ac0 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -20,7 +20,6 @@
 //#define LOG_NDEBUG 0
 
 #include "Configuration.h"
-#include <algorithm>    // std::any_of
 #include <dirent.h>
 #include <math.h>
 #include <signal.h>
@@ -58,8 +57,6 @@
 
 #include <audio_utils/primitives.h>
 
-#include <json/json.h>
-
 #include <powermanager/PowerManager.h>
 
 #include <media/IMediaLogService.h>
@@ -437,18 +434,6 @@
     if (!dumpAllowed()) {
         dumpPermissionDenial(fd, args);
     } else {
-        // XXX This is sort of hacky for now.
-        const bool formatJson = std::any_of(args.begin(), args.end(),
-                [](const String16 &arg) { return arg == String16("--json"); });
-        if (formatJson) {
-            Json::Value root = getJsonDump();
-            Json::FastWriter writer;
-            std::string rootStr = writer.write(root);
-            // XXX consider buffering if the string happens to be too long.
-            dprintf(fd, "%s", rootStr.c_str());
-            return NO_ERROR;
-        }
-
         // get state of hardware lock
         bool hardwareLocked = dumpTryLock(mHardwareLock);
         if (!hardwareLocked) {
@@ -575,32 +560,6 @@
     return NO_ERROR;
 }
 
-Json::Value AudioFlinger::getJsonDump()
-{
-    Json::Value root(Json::objectValue);
-    const bool locked = dumpTryLock(mLock);
-
-    // failed to lock - AudioFlinger is probably deadlocked
-    if (!locked) {
-        root["deadlock_message"] = kDeadlockedString;
-    }
-    // FIXME risky to access data structures without a lock held?
-
-    Json::Value playbackThreads = Json::arrayValue;
-    // dump playback threads
-    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
-        playbackThreads.append(mPlaybackThreads.valueAt(i)->getJsonDump());
-    }
-
-    if (locked) {
-        mLock.unlock();
-    }
-
-    root["playback_threads"] = playbackThreads;
-
-    return root;
-}
-
 sp<AudioFlinger::Client> AudioFlinger::registerPid(pid_t pid)
 {
     Mutex::Autolock _cl(mClientLock);
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 37d26b2..b6b3815 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -23,7 +23,6 @@
 #include <mutex>
 #include <deque>
 #include <map>
-#include <memory>
 #include <set>
 #include <string>
 #include <vector>
@@ -81,7 +80,6 @@
 
 #include <powermanager/IPowerManager.h>
 
-#include <json/json.h>
 #include <media/nblog/NBLog.h>
 #include <private/media/AudioEffectShared.h>
 #include <private/media/AudioTrackShared.h>
@@ -117,7 +115,6 @@
     static const char* getServiceName() ANDROID_API { return "media.audio_flinger"; }
 
     virtual     status_t    dump(int fd, const Vector<String16>& args);
-                Json::Value getJsonDump();
 
     // IAudioFlinger interface, in binder opcode order
     virtual sp<IAudioTrack> createTrack(const CreateTrackInput& input,
diff --git a/services/audioflinger/Configuration.h b/services/audioflinger/Configuration.h
index 34cd821..ede8e3f 100644
--- a/services/audioflinger/Configuration.h
+++ b/services/audioflinger/Configuration.h
@@ -27,7 +27,7 @@
 //#define AUDIO_WATCHDOG
 
 // uncomment to display CPU load adjusted for CPU frequency
-//define CPU_FREQUENCY_STATISTICS
+//#define CPU_FREQUENCY_STATISTICS
 
 // uncomment to enable fast threads to take performance samples for later statistical analysis
 #define FAST_THREAD_STATISTICS
diff --git a/services/audioflinger/FastMixerDumpState.cpp b/services/audioflinger/FastMixerDumpState.cpp
index 2abfbfb..a42e09c 100644
--- a/services/audioflinger/FastMixerDumpState.cpp
+++ b/services/audioflinger/FastMixerDumpState.cpp
@@ -24,8 +24,6 @@
 #include <cpustats/ThreadCpuUsage.h>
 #endif
 #endif
-#include <json/json.h>
-#include <string>
 #include <utils/Debug.h>
 #include <utils/Log.h>
 #include "FastMixerDumpState.h"
@@ -206,49 +204,4 @@
     }
 }
 
-Json::Value FastMixerDumpState::getJsonDump() const
-{
-    Json::Value root(Json::objectValue);
-    if (mCommand == FastMixerState::INITIAL) {
-        root["status"] = "uninitialized";
-        return root;
-    }
-#ifdef FAST_THREAD_STATISTICS
-    // find the interval of valid samples
-    const uint32_t bounds = mBounds;
-    const uint32_t newestOpen = bounds & 0xFFFF;
-    uint32_t oldestClosed = bounds >> 16;
-
-    //uint32_t n = (newestOpen - oldestClosed) & 0xFFFF;
-    uint32_t n;
-    __builtin_sub_overflow(newestOpen, oldestClosed, &n);
-    n &= 0xFFFF;
-
-    if (n > mSamplingN) {
-        ALOGE("too many samples %u", n);
-        n = mSamplingN;
-    }
-    // statistics for monotonic (wall clock) time, thread raw CPU load in time, CPU clock frequency,
-    // and adjusted CPU load in MHz normalized for CPU clock frequency
-    Json::Value jsonWall(Json::arrayValue);
-    Json::Value jsonLoadNs(Json::arrayValue);
-    // loop over all the samples
-    for (uint32_t j = 0; j < n; ++j) {
-        size_t i = oldestClosed++ & (mSamplingN - 1);
-        uint32_t wallNs = mMonotonicNs[i];
-        jsonWall.append(wallNs);
-        uint32_t sampleLoadNs = mLoadNs[i];
-        jsonLoadNs.append(sampleLoadNs);
-    }
-    if (n) {
-        root["wall_clock_time_ns"] = jsonWall;
-        root["raw_cpu_load_ns"] = jsonLoadNs;
-        root["status"] = "ok";
-    } else {
-        root["status"] = "unavailable";
-    }
-#endif
-    return root;
-}
-
 }   // android
diff --git a/services/audioflinger/FastMixerDumpState.h b/services/audioflinger/FastMixerDumpState.h
index 69c2e4e..9b91cbc 100644
--- a/services/audioflinger/FastMixerDumpState.h
+++ b/services/audioflinger/FastMixerDumpState.h
@@ -18,9 +18,7 @@
 #define ANDROID_AUDIO_FAST_MIXER_DUMP_STATE_H
 
 #include <stdint.h>
-#include <string>
 #include <audio_utils/TimestampVerifier.h>
-#include <json/json.h>
 #include "Configuration.h"
 #include "FastThreadDumpState.h"
 #include "FastMixerState.h"
@@ -67,8 +65,7 @@
     FastMixerDumpState();
     /*virtual*/ ~FastMixerDumpState();
 
-    void dump(int fd) const;             // should only be called on a stable copy, not the original
-    Json::Value getJsonDump() const;     // should only be called on a stable copy, not the original
+    void dump(int fd) const;    // should only be called on a stable copy, not the original
 
     double   mLatencyMs = 0.;   // measured latency, default of 0 if no valid timestamp read.
     uint32_t mWriteSequence;    // incremented before and after each write()
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index b5e7856..d7a4451 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -42,7 +42,6 @@
 #include <audio_utils/primitives.h>
 #include <audio_utils/format.h>
 #include <audio_utils/minifloat.h>
-#include <json/json.h>
 #include <system/audio_effects/effect_ns.h>
 #include <system/audio_effects/effect_aec.h>
 #include <system/audio.h>
@@ -1776,11 +1775,6 @@
     mLocalLog.dump(fd, "   " /* prefix */, 40 /* lines */);
 }
 
-Json::Value AudioFlinger::PlaybackThread::getJsonDump() const
-{
-    return Json::Value(Json::objectValue);
-}
-
 void AudioFlinger::PlaybackThread::dumpTracks(int fd, const Vector<String16>& args __unused)
 {
     String8 result;
@@ -5182,7 +5176,8 @@
         // while we are dumping it.  It may be inconsistent, but it won't mutate!
         // This is a large object so we place it on the heap.
         // FIXME 25972958: Need an intelligent copy constructor that does not touch unused pages.
-        const std::unique_ptr<FastMixerDumpState> copy(new FastMixerDumpState(mFastMixerDumpState));
+        const std::unique_ptr<FastMixerDumpState> copy =
+                std::make_unique<FastMixerDumpState>(mFastMixerDumpState);
         copy->dump(fd);
 
 #ifdef STATE_QUEUE_DUMP
@@ -5206,22 +5201,6 @@
     }
 }
 
-Json::Value AudioFlinger::MixerThread::getJsonDump() const
-{
-    Json::Value root;
-    if (hasFastMixer()) {
-        // Make a non-atomic copy of fast mixer dump state so it won't change underneath us
-        // while we are dumping it.  It may be inconsistent, but it won't mutate!
-        // This is a large object so we place it on the heap.
-        // FIXME 25972958: Need an intelligent copy constructor that does not touch unused pages.
-        const std::unique_ptr<FastMixerDumpState> copy(new FastMixerDumpState(mFastMixerDumpState));
-        root["fastmixer_stats"] = copy->getJsonDump();
-    } else {
-        root["fastmixer_stats"] = "no_fastmixer";
-    }
-    return root;
-}
-
 uint32_t AudioFlinger::MixerThread::idleSleepTimeUs() const
 {
     return (uint32_t)(((mNormalFrameCount * 1000) / mSampleRate) * 1000) / 2;
@@ -7570,7 +7549,8 @@
     // while we are dumping it.  It may be inconsistent, but it won't mutate!
     // This is a large object so we place it on the heap.
     // FIXME 25972958: Need an intelligent copy constructor that does not touch unused pages.
-    std::unique_ptr<FastCaptureDumpState> copy(new FastCaptureDumpState(mFastCaptureDumpState));
+    const std::unique_ptr<FastCaptureDumpState> copy =
+            std::make_unique<FastCaptureDumpState>(mFastCaptureDumpState);
     copy->dump(fd);
 }
 
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index bb37a0a..88c6ff3 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -668,8 +668,6 @@
     virtual             ~PlaybackThread();
 
                 void        dump(int fd, const Vector<String16>& args) override;
-                // returns a string of audio performance related data in JSON format.
-    virtual     Json::Value getJsonDump() const;
 
     // Thread virtuals
     virtual     bool        threadLoop();
@@ -1116,7 +1114,6 @@
     virtual     bool        checkForNewParameter_l(const String8& keyValuePair,
                                                    status_t& status);
     virtual     void        dumpInternals(int fd, const Vector<String16>& args);
-                Json::Value getJsonDump() const override;
 
     virtual     bool        isTrackAllowed_l(
                                     audio_channel_mask_t channelMask, audio_format_t format,