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 32namespace android { 33 34static const size_t kBufferSize = 32768; 35 36JMedia2HTTPConnection::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 86JMedia2HTTPConnection::~JMedia2HTTPConnection() { 87 JNIEnv *env = AndroidRuntime::getJNIEnv(); 88 env->DeleteGlobalRef(mMedia2HTTPConnectionObj); 89 env->DeleteGlobalRef(mByteArrayObj); 90} 91 92bool 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 117void JMedia2HTTPConnection::disconnect() { 118 JNIEnv* env = AndroidRuntime::getJNIEnv(); 119 env->CallVoidMethod(mMedia2HTTPConnectionObj, mDisconnectMethod); 120} 121 122ssize_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 143off64_t JMedia2HTTPConnection::getSize() { 144 JNIEnv* env = AndroidRuntime::getJNIEnv(); 145 return (off64_t)(env->CallLongMethod(mMedia2HTTPConnectionObj, mGetSizeMethod)); 146} 147 148status_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 167status_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