Home | History | Annotate | Download | only in jni
      1 /*
      2  * Copyright 2017, The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 //#define LOG_NDEBUG 0
     18 #define LOG_TAG "Media2HTTPConnection-JNI"
     19 #include <utils/Log.h>
     20 
     21 #include <media/stagefright/foundation/ADebug.h>
     22 #include <nativehelper/ScopedLocalRef.h>
     23 
     24 #include "android_media_Media2HTTPConnection.h"
     25 #include "android_util_Binder.h"
     26 
     27 #include "android_runtime/AndroidRuntime.h"
     28 #include "android_runtime/Log.h"
     29 #include "jni.h"
     30 #include <nativehelper/JNIHelp.h>
     31 
     32 namespace android {
     33 
     34 static const size_t kBufferSize = 32768;
     35 
     36 JMedia2HTTPConnection::JMedia2HTTPConnection(JNIEnv *env, jobject thiz) {
     37     mMedia2HTTPConnectionObj = env->NewGlobalRef(thiz);
     38     CHECK(mMedia2HTTPConnectionObj != NULL);
     39 
     40     ScopedLocalRef<jclass> media2HTTPConnectionClass(
     41             env, env->GetObjectClass(mMedia2HTTPConnectionObj));
     42     CHECK(media2HTTPConnectionClass.get() != NULL);
     43 
     44     mConnectMethod = env->GetMethodID(
     45             media2HTTPConnectionClass.get(),
     46             "connect",
     47             "(Ljava/lang/String;Ljava/lang/String;)Z");
     48     CHECK(mConnectMethod != NULL);
     49 
     50     mDisconnectMethod = env->GetMethodID(
     51             media2HTTPConnectionClass.get(),
     52             "disconnect",
     53             "()V");
     54     CHECK(mDisconnectMethod != NULL);
     55 
     56     mReadAtMethod = env->GetMethodID(
     57             media2HTTPConnectionClass.get(),
     58             "readAt",
     59             "(J[BI)I");
     60     CHECK(mReadAtMethod != NULL);
     61 
     62     mGetSizeMethod = env->GetMethodID(
     63             media2HTTPConnectionClass.get(),
     64             "getSize",
     65             "()J");
     66     CHECK(mGetSizeMethod != NULL);
     67 
     68     mGetMIMETypeMethod = env->GetMethodID(
     69             media2HTTPConnectionClass.get(),
     70             "getMIMEType",
     71             "()Ljava/lang/String;");
     72     CHECK(mGetMIMETypeMethod != NULL);
     73 
     74     mGetUriMethod = env->GetMethodID(
     75             media2HTTPConnectionClass.get(),
     76             "getUri",
     77             "()Ljava/lang/String;");
     78     CHECK(mGetUriMethod != NULL);
     79 
     80     ScopedLocalRef<jbyteArray> tmp(
     81         env, env->NewByteArray(kBufferSize));
     82     mByteArrayObj = (jbyteArray)env->NewGlobalRef(tmp.get());
     83     CHECK(mByteArrayObj != NULL);
     84 }
     85 
     86 JMedia2HTTPConnection::~JMedia2HTTPConnection() {
     87     JNIEnv *env = AndroidRuntime::getJNIEnv();
     88     env->DeleteGlobalRef(mMedia2HTTPConnectionObj);
     89     env->DeleteGlobalRef(mByteArrayObj);
     90 }
     91 
     92 bool JMedia2HTTPConnection::connect(
     93         const char *uri, const KeyedVector<String8, String8> *headers) {
     94     String8 tmp("");
     95     if (headers != NULL) {
     96         for (size_t i = 0; i < headers->size(); ++i) {
     97             tmp.append(headers->keyAt(i));
     98             tmp.append(String8(": "));
     99             tmp.append(headers->valueAt(i));
    100             tmp.append(String8("\r\n"));
    101         }
    102     }
    103 
    104     JNIEnv* env = AndroidRuntime::getJNIEnv();
    105     jstring juri = env->NewStringUTF(uri);
    106     jstring jheaders = env->NewStringUTF(tmp.string());
    107 
    108     jboolean ret =
    109         env->CallBooleanMethod(mMedia2HTTPConnectionObj, mConnectMethod, juri, jheaders);
    110 
    111     env->DeleteLocalRef(juri);
    112     env->DeleteLocalRef(jheaders);
    113 
    114     return (bool)ret;
    115 }
    116 
    117 void JMedia2HTTPConnection::disconnect() {
    118     JNIEnv* env = AndroidRuntime::getJNIEnv();
    119     env->CallVoidMethod(mMedia2HTTPConnectionObj, mDisconnectMethod);
    120 }
    121 
    122 ssize_t JMedia2HTTPConnection::readAt(off64_t offset, void *data, size_t size) {
    123     JNIEnv* env = AndroidRuntime::getJNIEnv();
    124 
    125     if (size > kBufferSize) {
    126         size = kBufferSize;
    127     }
    128 
    129     jint n = env->CallIntMethod(
    130             mMedia2HTTPConnectionObj, mReadAtMethod, (jlong)offset, mByteArrayObj, (jint)size);
    131 
    132     if (n > 0) {
    133         env->GetByteArrayRegion(
    134                 mByteArrayObj,
    135                 0,
    136                 n,
    137                 (jbyte *)data);
    138     }
    139 
    140     return n;
    141 }
    142 
    143 off64_t JMedia2HTTPConnection::getSize() {
    144     JNIEnv* env = AndroidRuntime::getJNIEnv();
    145     return (off64_t)(env->CallLongMethod(mMedia2HTTPConnectionObj, mGetSizeMethod));
    146 }
    147 
    148 status_t JMedia2HTTPConnection::getMIMEType(String8 *mimeType) {
    149     JNIEnv* env = AndroidRuntime::getJNIEnv();
    150     jstring jmime = (jstring)env->CallObjectMethod(mMedia2HTTPConnectionObj, mGetMIMETypeMethod);
    151     jboolean flag = env->ExceptionCheck();
    152     if (flag) {
    153         env->ExceptionClear();
    154         return UNKNOWN_ERROR;
    155     }
    156 
    157     const char *str = env->GetStringUTFChars(jmime, 0);
    158     if (str != NULL) {
    159         *mimeType = String8(str);
    160     } else {
    161         *mimeType = "application/octet-stream";
    162     }
    163     env->ReleaseStringUTFChars(jmime, str);
    164     return OK;
    165 }
    166 
    167 status_t JMedia2HTTPConnection::getUri(String8 *uri) {
    168     JNIEnv* env = AndroidRuntime::getJNIEnv();
    169     jstring juri = (jstring)env->CallObjectMethod(mMedia2HTTPConnectionObj, mGetUriMethod);
    170     jboolean flag = env->ExceptionCheck();
    171     if (flag) {
    172         env->ExceptionClear();
    173         return UNKNOWN_ERROR;
    174     }
    175 
    176     const char *str = env->GetStringUTFChars(juri, 0);
    177     *uri = String8(str);
    178     env->ReleaseStringUTFChars(juri, str);
    179     return OK;
    180 }
    181 
    182 }  // namespace android
    183