Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 79f407cc authored by James Dong's avatar James Dong
Browse files

Refactor to share code between MediaPlayer and MediaMetadataRetriever JNI

Change-Id: Ib847213f566dee79126d7c14d00750a9a8dedeb9
parent 8b1b0548
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@ LOCAL_SRC_FILES:= \
    android_media_ResampleInputStream.cpp \
    android_media_MediaProfiles.cpp \
    android_media_AmrInputStream.cpp \
    android_media_Utils.cpp \
    android_mtp_MtpDatabase.cpp \
    android_mtp_MtpDevice.cpp \
    android_mtp_MtpServer.cpp \
+6 −34
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
#include "jni.h"
#include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h"
#include "android_media_Utils.h"


using namespace android;
@@ -108,14 +109,6 @@ android_media_MediaMetadataRetriever_setDataSourceAndHeaders(
    env->ReleaseStringUTFChars(path, tmp);
    tmp = NULL;

    int nKeyValuePairs = env->GetArrayLength(keys);
    if (nKeyValuePairs != env->GetArrayLength(values)) {
        LOGE("keys and values have different length: %d <--> %d",
            nKeyValuePairs, env->GetArrayLength(values));
        jniThrowException(
                env, "java/lang/IllegalArgumentException", NULL);
        return;
    }
    // Don't let somebody trick us in to reading some random block of memory
    if (strncmp("mem://", pathStr.string(), 6) == 0) {
        jniThrowException(
@@ -125,41 +118,20 @@ android_media_MediaMetadataRetriever_setDataSourceAndHeaders(

    // We build a similar KeyedVector out of it.
    KeyedVector<String8, String8> headersVector;
    for (int i = 0; i < nKeyValuePairs; ++i) {
        // No need to check on the ArrayIndexOutOfBoundsException, since
        // it won't happen here.
        jstring key = (jstring) env->GetObjectArrayElement(keys, i);
        jstring value = (jstring) env->GetObjectArrayElement(values, i);

        const char* keyStr = env->GetStringUTFChars(key, NULL);
        if (!keyStr) {  // OutOfMemoryError
            return;
        }

        const char* valueStr = env->GetStringUTFChars(value, NULL);
        if (!valueStr) {  // OutOfMemoryError
            env->ReleaseStringUTFChars(key, keyStr);
    if (!ConvertKeyValueArraysToKeyedVector(
            env, keys, values, &headersVector)) {
        return;
    }

        headersVector.add(String8(keyStr), String8(valueStr));

        env->ReleaseStringUTFChars(key, keyStr);
        env->ReleaseStringUTFChars(value, valueStr);
        env->DeleteLocalRef(key);
        env->DeleteLocalRef(value);

    }

    process_media_retriever_call(
            env,
            retriever->setDataSource(
                pathStr.string(), nKeyValuePairs > 0 ? &headersVector : NULL),
                pathStr.string(), headersVector.size() > 0 ? &headersVector : NULL),

            "java/lang/RuntimeException",
            "setDataSource failed");
}


static void android_media_MediaMetadataRetriever_setDataSource(
        JNIEnv *env, jobject thiz, jstring path) {
    android_media_MediaMetadataRetriever_setDataSourceAndHeaders(
+6 −32
Original line number Diff line number Diff line
@@ -33,6 +33,8 @@
#include "utils/Errors.h"  // for status_t
#include "utils/KeyedVector.h"
#include "utils/String8.h"
#include "android_media_Utils.h"

#include "android_util_Binder.h"
#include <binder/Parcel.h>
#include <gui/SurfaceTexture.h>
@@ -209,46 +211,18 @@ android_media_MediaPlayer_setDataSourceAndHeaders(
    env->ReleaseStringUTFChars(path, tmp);
    tmp = NULL;

    int nKeyValuePairs = env->GetArrayLength(keys);
    if (nKeyValuePairs != env->GetArrayLength(values)) {
        LOGE("keys and values have different length: %d <-> %d",
            nKeyValuePairs, env->GetArrayLength(values));
        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
        return;
    }

    // We build a KeyedVector out of the key and val arrays
    KeyedVector<String8, String8> headersVector;
    for (int i = 0; i < nKeyValuePairs; ++i) {
        // No need to check ArrayIndexOutOfBoundsException, since we
        // know it won't happen here.
        jstring key = (jstring) env->GetObjectArrayElement(keys, i);
        jstring val = (jstring) env->GetObjectArrayElement(values, i);

        const char* keyStr = env->GetStringUTFChars(key, NULL);
        if (!keyStr) {  // OutOfMemoryError
    if (!ConvertKeyValueArraysToKeyedVector(
            env, keys, values, &headersVector)) {
        return;
    }

        const char* valueStr = env->GetStringUTFChars(val, NULL);
        if (!valueStr) {  // OutOfMemoryError
            env->ReleaseStringUTFChars(key, keyStr);
            return;
        }

        headersVector.add(String8(keyStr), String8(valueStr));

        env->ReleaseStringUTFChars(key, keyStr);
        env->ReleaseStringUTFChars(val, valueStr);
        env->DeleteLocalRef(key);
        env->DeleteLocalRef(val);
    }

    LOGV("setDataSource: path %s", pathStr);
    status_t opStatus =
        mp->setDataSource(
                pathStr,
                nKeyValuePairs > 0? &headersVector : NULL);
                headersVector.size() > 0? &headersVector : NULL);

    process_media_player_call(
            env, thiz, opStatus, "java/io/IOException",
+75 −0
Original line number Diff line number Diff line
/*
 * Copyright 2011, 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 "AndroidMediaUtils"

#include <utils/Log.h>
#include "android_media_Utils.h"

namespace android {

bool ConvertKeyValueArraysToKeyedVector(
        JNIEnv *env, jobjectArray keys, jobjectArray values,
        KeyedVector<String8, String8>* keyedVector) {

    int nKeyValuePairs = 0;
    bool failed = false;
    if (keys != NULL && values != NULL) {
        nKeyValuePairs = env->GetArrayLength(keys);
        failed = (nKeyValuePairs != env->GetArrayLength(values));
    }

    if (!failed) {
        failed = ((keys != NULL && values == NULL) ||
                  (keys == NULL && values != NULL));
    }

    if (failed) {
        LOGE("keys and values arrays have different length");
        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
        return false;
    }

    for (int i = 0; i < nKeyValuePairs; ++i) {
        // No need to check on the ArrayIndexOutOfBoundsException, since
        // it won't happen here.
        jstring key = (jstring) env->GetObjectArrayElement(keys, i);
        jstring value = (jstring) env->GetObjectArrayElement(values, i);

        const char* keyStr = env->GetStringUTFChars(key, NULL);
        if (!keyStr) {  // OutOfMemoryError
            return false;
        }

        const char* valueStr = env->GetStringUTFChars(value, NULL);
        if (!valueStr) {  // OutOfMemoryError
            env->ReleaseStringUTFChars(key, keyStr);
            return false;
        }

        keyedVector->add(String8(keyStr), String8(valueStr));

        env->ReleaseStringUTFChars(key, keyStr);
        env->ReleaseStringUTFChars(value, valueStr);
        env->DeleteLocalRef(key);
        env->DeleteLocalRef(value);
    }
    return true;
}

}  // namespace android
+38 −0
Original line number Diff line number Diff line
/*
 * Copyright 2011, 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_MEDIA_UTILS_H_
#define _ANDROID_MEDIA_UTILS_H_

#include "jni.h"
#include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h"

#include <utils/KeyedVector.h>
#include <utils/String8.h>

namespace android {

/**
 * Returns true if the conversion is successful; otherwise, false.
 */
bool ConvertKeyValueArraysToKeyedVector(
    JNIEnv *env, jobjectArray keys, jobjectArray values,
    KeyedVector<String8, String8>* vector);

};  // namespace android

#endif //  _ANDROID_MEDIA_UTILS_H_