• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
JMedia2HTTPConnection(JNIEnv * env,jobject thiz)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 
~JMedia2HTTPConnection()86 JMedia2HTTPConnection::~JMedia2HTTPConnection() {
87     JNIEnv *env = AndroidRuntime::getJNIEnv();
88     env->DeleteGlobalRef(mMedia2HTTPConnectionObj);
89     env->DeleteGlobalRef(mByteArrayObj);
90 }
91 
connect(const char * uri,const KeyedVector<String8,String8> * headers)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 
disconnect()117 void JMedia2HTTPConnection::disconnect() {
118     JNIEnv* env = AndroidRuntime::getJNIEnv();
119     env->CallVoidMethod(mMedia2HTTPConnectionObj, mDisconnectMethod);
120 }
121 
readAt(off64_t offset,void * data,size_t size)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 
getSize()143 off64_t JMedia2HTTPConnection::getSize() {
144     JNIEnv* env = AndroidRuntime::getJNIEnv();
145     return (off64_t)(env->CallLongMethod(mMedia2HTTPConnectionObj, mGetSizeMethod));
146 }
147 
getMIMEType(String8 * mimeType)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 
getUri(String8 * uri)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