android_media_MediaHTTPConnection.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /*
  2. * Copyright 2013, 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. //#define LOG_NDEBUG 0
  17. #define LOG_TAG "MediaHTTPConnection-JNI"
  18. #include <utils/Log.h>
  19. #include <binder/MemoryDealer.h>
  20. #include <media/stagefright/foundation/ADebug.h>
  21. #include <nativehelper/ScopedLocalRef.h>
  22. #include "android_media_MediaHTTPConnection.h"
  23. #include "android_util_Binder.h"
  24. #include "android_runtime/AndroidRuntime.h"
  25. #include "jni.h"
  26. #include <nativehelper/JNIHelp.h>
  27. namespace android {
  28. JMediaHTTPConnection::JMediaHTTPConnection(JNIEnv *env, jobject thiz)
  29. : mClass(NULL),
  30. mObject(NULL),
  31. mByteArrayObj(NULL) {
  32. jclass clazz = env->GetObjectClass(thiz);
  33. CHECK(clazz != NULL);
  34. mClass = (jclass)env->NewGlobalRef(clazz);
  35. mObject = env->NewWeakGlobalRef(thiz);
  36. mDealer = new MemoryDealer(kBufferSize, "MediaHTTPConnection");
  37. mMemory = mDealer->allocate(kBufferSize);
  38. ScopedLocalRef<jbyteArray> tmp(
  39. env, env->NewByteArray(JMediaHTTPConnection::kBufferSize));
  40. mByteArrayObj = (jbyteArray)env->NewGlobalRef(tmp.get());
  41. }
  42. JMediaHTTPConnection::~JMediaHTTPConnection() {
  43. JNIEnv *env = AndroidRuntime::getJNIEnv();
  44. env->DeleteGlobalRef(mByteArrayObj);
  45. mByteArrayObj = NULL;
  46. env->DeleteWeakGlobalRef(mObject);
  47. mObject = NULL;
  48. env->DeleteGlobalRef(mClass);
  49. mClass = NULL;
  50. }
  51. sp<IMemory> JMediaHTTPConnection::getIMemory() {
  52. return mMemory;
  53. }
  54. jbyteArray JMediaHTTPConnection::getByteArrayObj() {
  55. return mByteArrayObj;
  56. }
  57. } // namespace android
  58. using namespace android;
  59. struct fields_t {
  60. jfieldID context;
  61. jmethodID readAtMethodID;
  62. };
  63. static fields_t gFields;
  64. static sp<JMediaHTTPConnection> setObject(
  65. JNIEnv *env, jobject thiz, const sp<JMediaHTTPConnection> &conn) {
  66. sp<JMediaHTTPConnection> old =
  67. (JMediaHTTPConnection *)env->GetLongField(thiz, gFields.context);
  68. if (conn != NULL) {
  69. conn->incStrong(thiz);
  70. }
  71. if (old != NULL) {
  72. old->decStrong(thiz);
  73. }
  74. env->SetLongField(thiz, gFields.context, (jlong)conn.get());
  75. return old;
  76. }
  77. static sp<JMediaHTTPConnection> getObject(JNIEnv *env, jobject thiz) {
  78. return (JMediaHTTPConnection *)env->GetLongField(thiz, gFields.context);
  79. }
  80. static void android_media_MediaHTTPConnection_native_init(JNIEnv *env) {
  81. ScopedLocalRef<jclass> clazz(
  82. env, env->FindClass("android/media/MediaHTTPConnection"));
  83. CHECK(clazz.get() != NULL);
  84. gFields.context = env->GetFieldID(clazz.get(), "mNativeContext", "J");
  85. CHECK(gFields.context != NULL);
  86. gFields.readAtMethodID = env->GetMethodID(clazz.get(), "readAt", "(J[BI)I");
  87. }
  88. static void android_media_MediaHTTPConnection_native_setup(
  89. JNIEnv *env, jobject thiz) {
  90. sp<JMediaHTTPConnection> conn = new JMediaHTTPConnection(env, thiz);
  91. setObject(env, thiz, conn);
  92. }
  93. static void android_media_MediaHTTPConnection_native_finalize(
  94. JNIEnv *env, jobject thiz) {
  95. setObject(env, thiz, NULL);
  96. }
  97. static jobject android_media_MediaHTTPConnection_native_getIMemory(
  98. JNIEnv *env, jobject thiz) {
  99. sp<JMediaHTTPConnection> conn = getObject(env, thiz);
  100. return javaObjectForIBinder(env, IInterface::asBinder(conn->getIMemory()));
  101. }
  102. static jint android_media_MediaHTTPConnection_native_readAt(
  103. JNIEnv *env, jobject thiz, jlong offset, jint size) {
  104. sp<JMediaHTTPConnection> conn = getObject(env, thiz);
  105. if (size > JMediaHTTPConnection::kBufferSize) {
  106. size = JMediaHTTPConnection::kBufferSize;
  107. }
  108. jbyteArray byteArrayObj = conn->getByteArrayObj();
  109. jint n = env->CallIntMethod(
  110. thiz, gFields.readAtMethodID, offset, byteArrayObj, size);
  111. if (n > 0) {
  112. env->GetByteArrayRegion(
  113. byteArrayObj,
  114. 0,
  115. n,
  116. (jbyte *)conn->getIMemory()->pointer());
  117. }
  118. return n;
  119. }
  120. static const JNINativeMethod gMethods[] = {
  121. { "native_getIMemory", "()Landroid/os/IBinder;",
  122. (void *)android_media_MediaHTTPConnection_native_getIMemory },
  123. { "native_readAt", "(JI)I",
  124. (void *)android_media_MediaHTTPConnection_native_readAt },
  125. { "native_init", "()V",
  126. (void *)android_media_MediaHTTPConnection_native_init },
  127. { "native_setup", "()V",
  128. (void *)android_media_MediaHTTPConnection_native_setup },
  129. { "native_finalize", "()V",
  130. (void *)android_media_MediaHTTPConnection_native_finalize },
  131. };
  132. int register_android_media_MediaHTTPConnection(JNIEnv *env) {
  133. return AndroidRuntime::registerNativeMethods(env,
  134. "android/media/MediaHTTPConnection", gMethods, NELEM(gMethods));
  135. }