blob: 60176e3d238ea873cf8252ab1b4fac20c08a794a [file] [log] [blame]
Wei Jia0a8a8f02017-12-05 17:05:29 -08001/*
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