• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 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 "JET_JNI"
19 
20 
21 #include <stdio.h>
22 #include <unistd.h>
23 #include <fcntl.h>
24 
25 #include "jni.h"
26 #include "JNIHelp.h"
27 #include "android_runtime/AndroidRuntime.h"
28 
29 #include "utils/Log.h"
30 #include "media/JetPlayer.h"
31 
32 
33 using namespace android;
34 
35 // ----------------------------------------------------------------------------
36 static const char* const kClassPathName = "android/media/JetPlayer";
37 
38 // ----------------------------------------------------------------------------
39 struct fields_t {
40     // these fields provide access from C++ to the...
41     jclass    jetClass;              // JetPlayer java class global ref
42     jmethodID postNativeEventInJava; // java method to post events to the Java thread from native
43     jfieldID  nativePlayerInJavaObj; // stores in Java the native JetPlayer object
44 };
45 
46 static fields_t javaJetPlayerFields;
47 
48 
49 // ----------------------------------------------------------------------------
50 // ----------------------------------------------------------------------------
51 
52 /*
53  * This function is called from JetPlayer instance's render thread
54  */
55 static void
jetPlayerEventCallback(int what,int arg1=0,int arg2=0,void * javaTarget=NULL)56 jetPlayerEventCallback(int what, int arg1=0, int arg2=0, void* javaTarget = NULL)
57 {
58     JNIEnv *env = AndroidRuntime::getJNIEnv();
59     if(env) {
60         env->CallStaticVoidMethod(
61             javaJetPlayerFields.jetClass, javaJetPlayerFields.postNativeEventInJava,
62             javaTarget,
63             what, arg1, arg2);
64         if (env->ExceptionCheck()) {
65             env->ExceptionDescribe();
66             env->ExceptionClear();
67         }
68     } else {
69         LOGE("JET jetPlayerEventCallback(): No JNI env for JET event callback, can't post event.");
70         return;
71     }
72 }
73 
74 
75 // ----------------------------------------------------------------------------
76 // ----------------------------------------------------------------------------
77 
78 static jboolean
android_media_JetPlayer_setup(JNIEnv * env,jobject thiz,jobject weak_this,jint maxTracks,jint trackBufferSize)79 android_media_JetPlayer_setup(JNIEnv *env, jobject thiz, jobject weak_this,
80     jint maxTracks, jint trackBufferSize)
81 {
82     //LOGV("android_media_JetPlayer_setup(): entering.");
83     JetPlayer* lpJet = new JetPlayer(env->NewGlobalRef(weak_this), maxTracks, trackBufferSize);
84 
85     EAS_RESULT result = lpJet->init();
86 
87     if(result==EAS_SUCCESS) {
88         // save our newly created C++ JetPlayer in the "nativePlayerInJavaObj" field
89         // of the Java object (in mNativePlayerInJavaObj)
90         env->SetIntField(thiz, javaJetPlayerFields.nativePlayerInJavaObj, (int)lpJet);
91         return JNI_TRUE;
92     } else {
93         LOGE("android_media_JetPlayer_setup(): initialization failed with EAS error code %d", (int)result);
94         delete lpJet;
95         env->SetIntField(weak_this, javaJetPlayerFields.nativePlayerInJavaObj, 0);
96         return JNI_FALSE;
97     }
98 }
99 
100 
101 // ----------------------------------------------------------------------------
102 static void
android_media_JetPlayer_finalize(JNIEnv * env,jobject thiz)103 android_media_JetPlayer_finalize(JNIEnv *env, jobject thiz)
104 {
105     LOGV("android_media_JetPlayer_finalize(): entering.");
106     JetPlayer *lpJet = (JetPlayer *)env->GetIntField(
107         thiz, javaJetPlayerFields.nativePlayerInJavaObj);
108     if(lpJet != NULL) {
109         lpJet->release();
110         delete lpJet;
111     }
112 
113     LOGV("android_media_JetPlayer_finalize(): exiting.");
114 }
115 
116 
117 // ----------------------------------------------------------------------------
118 static void
android_media_JetPlayer_release(JNIEnv * env,jobject thiz)119 android_media_JetPlayer_release(JNIEnv *env, jobject thiz)
120 {
121     android_media_JetPlayer_finalize(env, thiz);
122     env->SetIntField(thiz, javaJetPlayerFields.nativePlayerInJavaObj, 0);
123     LOGV("android_media_JetPlayer_release() done");
124 }
125 
126 
127 // ----------------------------------------------------------------------------
128 static jboolean
android_media_JetPlayer_loadFromFile(JNIEnv * env,jobject thiz,jstring path)129 android_media_JetPlayer_loadFromFile(JNIEnv *env, jobject thiz, jstring path)
130 {
131     JetPlayer *lpJet = (JetPlayer *)env->GetIntField(
132         thiz, javaJetPlayerFields.nativePlayerInJavaObj);
133     if (lpJet == NULL ) {
134         jniThrowException(env, "java/lang/IllegalStateException",
135             "Unable to retrieve JetPlayer pointer for openFile()");
136     }
137 
138     // set up event callback function
139     lpJet->setEventCallback(jetPlayerEventCallback);
140 
141     const char *pathStr = env->GetStringUTFChars(path, NULL);
142     if (pathStr == NULL) {  // Out of memory
143         LOGE("android_media_JetPlayer_openFile(): aborting, out of memory");
144         jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
145         return JNI_FALSE;
146     }
147 
148     LOGV("android_media_JetPlayer_openFile(): trying to open %s", pathStr );
149     EAS_RESULT result = lpJet->loadFromFile(pathStr);
150     env->ReleaseStringUTFChars(path, pathStr);
151 
152     if(result==EAS_SUCCESS) {
153         //LOGV("android_media_JetPlayer_openFile(): file successfully opened");
154         return JNI_TRUE;
155     } else {
156         LOGE("android_media_JetPlayer_openFile(): failed to open file with EAS error %d",
157             (int)result);
158         return JNI_FALSE;
159     }
160 }
161 
162 
163 // ----------------------------------------------------------------------------
164 static jboolean
android_media_JetPlayer_loadFromFileD(JNIEnv * env,jobject thiz,jobject fileDescriptor,jlong offset,jlong length)165 android_media_JetPlayer_loadFromFileD(JNIEnv *env, jobject thiz,
166     jobject fileDescriptor, jlong offset, jlong length)
167 {
168     JetPlayer *lpJet = (JetPlayer *)env->GetIntField(
169         thiz, javaJetPlayerFields.nativePlayerInJavaObj);
170     if (lpJet == NULL ) {
171         jniThrowException(env, "java/lang/IllegalStateException",
172             "Unable to retrieve JetPlayer pointer for openFile()");
173     }
174 
175     // set up event callback function
176     lpJet->setEventCallback(jetPlayerEventCallback);
177 
178     LOGV("android_media_JetPlayer_openFileDescr(): trying to load JET file through its fd" );
179     EAS_RESULT result = lpJet->loadFromFD(getParcelFileDescriptorFD(env, fileDescriptor),
180         (long long)offset, (long long)length); // cast params to types used by EAS_FILE
181 
182     if(result==EAS_SUCCESS) {
183         LOGV("android_media_JetPlayer_openFileDescr(): file successfully opened");
184         return JNI_TRUE;
185     } else {
186         LOGE("android_media_JetPlayer_openFileDescr(): failed to open file with EAS error %d",
187             (int)result);
188         return JNI_FALSE;
189     }
190 }
191 
192 
193 // ----------------------------------------------------------------------------
194 static jboolean
android_media_JetPlayer_closeFile(JNIEnv * env,jobject thiz)195 android_media_JetPlayer_closeFile(JNIEnv *env, jobject thiz)
196 {
197     JetPlayer *lpJet = (JetPlayer *)env->GetIntField(
198         thiz, javaJetPlayerFields.nativePlayerInJavaObj);
199     if (lpJet == NULL ) {
200         jniThrowException(env, "java/lang/IllegalStateException",
201             "Unable to retrieve JetPlayer pointer for closeFile()");
202     }
203 
204     if( lpJet->closeFile()==EAS_SUCCESS) {
205         //LOGV("android_media_JetPlayer_closeFile(): file successfully closed");
206         return JNI_TRUE;
207     } else {
208         LOGE("android_media_JetPlayer_closeFile(): failed to close file");
209         return JNI_FALSE;
210     }
211 }
212 
213 
214 // ----------------------------------------------------------------------------
215 static jboolean
android_media_JetPlayer_play(JNIEnv * env,jobject thiz)216 android_media_JetPlayer_play(JNIEnv *env, jobject thiz)
217 {
218     JetPlayer *lpJet = (JetPlayer *)env->GetIntField(
219         thiz, javaJetPlayerFields.nativePlayerInJavaObj);
220     if (lpJet == NULL ) {
221         jniThrowException(env, "java/lang/IllegalStateException",
222             "Unable to retrieve JetPlayer pointer for play()");
223     }
224 
225     EAS_RESULT result = lpJet->play();
226     if( result==EAS_SUCCESS) {
227         //LOGV("android_media_JetPlayer_play(): play successful");
228         return JNI_TRUE;
229     } else {
230         LOGE("android_media_JetPlayer_play(): failed to play with EAS error code %ld",
231             result);
232         return JNI_FALSE;
233     }
234 }
235 
236 
237 // ----------------------------------------------------------------------------
238 static jboolean
android_media_JetPlayer_pause(JNIEnv * env,jobject thiz)239 android_media_JetPlayer_pause(JNIEnv *env, jobject thiz)
240 {
241     JetPlayer *lpJet = (JetPlayer *)env->GetIntField(
242         thiz, javaJetPlayerFields.nativePlayerInJavaObj);
243     if (lpJet == NULL ) {
244         jniThrowException(env, "java/lang/IllegalStateException",
245             "Unable to retrieve JetPlayer pointer for pause()");
246     }
247 
248     EAS_RESULT result = lpJet->pause();
249     if( result==EAS_SUCCESS) {
250         //LOGV("android_media_JetPlayer_pause(): pause successful");
251         return JNI_TRUE;
252     } else {
253         if(result==EAS_ERROR_QUEUE_IS_EMPTY) {
254             LOGV("android_media_JetPlayer_pause(): paused with an empty queue");
255             return JNI_TRUE;
256         } else
257             LOGE("android_media_JetPlayer_pause(): failed to pause with EAS error code %ld",
258                 result);
259         return JNI_FALSE;
260     }
261 }
262 
263 
264 // ----------------------------------------------------------------------------
265 static jboolean
android_media_JetPlayer_queueSegment(JNIEnv * env,jobject thiz,jint segmentNum,jint libNum,jint repeatCount,jint transpose,jint muteFlags,jbyte userID)266 android_media_JetPlayer_queueSegment(JNIEnv *env, jobject thiz,
267         jint segmentNum, jint libNum, jint repeatCount, jint transpose, jint muteFlags,
268         jbyte userID)
269 {
270     JetPlayer *lpJet = (JetPlayer *)env->GetIntField(
271         thiz, javaJetPlayerFields.nativePlayerInJavaObj);
272     if (lpJet == NULL ) {
273         jniThrowException(env, "java/lang/IllegalStateException",
274             "Unable to retrieve JetPlayer pointer for queueSegment()");
275     }
276 
277     EAS_RESULT result
278         = lpJet->queueSegment(segmentNum, libNum, repeatCount, transpose, muteFlags, userID);
279     if(result==EAS_SUCCESS) {
280         //LOGV("android_media_JetPlayer_queueSegment(): segment successfully queued");
281         return JNI_TRUE;
282     } else {
283         LOGE("android_media_JetPlayer_queueSegment(): failed with EAS error code %ld",
284             result);
285         return JNI_FALSE;
286     }
287 }
288 
289 
290 // ----------------------------------------------------------------------------
291 static jboolean
android_media_JetPlayer_queueSegmentMuteArray(JNIEnv * env,jobject thiz,jint segmentNum,jint libNum,jint repeatCount,jint transpose,jbooleanArray muteArray,jbyte userID)292 android_media_JetPlayer_queueSegmentMuteArray(JNIEnv *env, jobject thiz,
293         jint segmentNum, jint libNum, jint repeatCount, jint transpose, jbooleanArray muteArray,
294         jbyte userID)
295 {
296     JetPlayer *lpJet = (JetPlayer *)env->GetIntField(
297         thiz, javaJetPlayerFields.nativePlayerInJavaObj);
298     if (lpJet == NULL ) {
299         jniThrowException(env, "java/lang/IllegalStateException",
300             "Unable to retrieve JetPlayer pointer for queueSegmentMuteArray()");
301     }
302 
303     EAS_RESULT result=EAS_FAILURE;
304 
305     jboolean *muteTracks = NULL;
306     muteTracks = env->GetBooleanArrayElements(muteArray, NULL);
307     if (muteTracks == NULL) {
308         LOGE("android_media_JetPlayer_queueSegment(): failed to read track mute mask.");
309         return JNI_FALSE;
310     }
311 
312     EAS_U32 muteMask=0;
313     int maxTracks = lpJet->getMaxTracks();
314     for (jint trackIndex=0; trackIndex<maxTracks; trackIndex++) {
315         if(muteTracks[maxTracks-1-trackIndex]==JNI_TRUE)
316             muteMask = (muteMask << 1) | 0x00000001;
317         else
318             muteMask = muteMask << 1;
319     }
320     //LOGV("android_media_JetPlayer_queueSegmentMuteArray(): FINAL mute mask =0x%08lX", mask);
321 
322     result = lpJet->queueSegment(segmentNum, libNum, repeatCount, transpose, muteMask, userID);
323 
324     env->ReleaseBooleanArrayElements(muteArray, muteTracks, 0);
325     if(result==EAS_SUCCESS) {
326         //LOGV("android_media_JetPlayer_queueSegmentMuteArray(): segment successfully queued");
327         return JNI_TRUE;
328     } else {
329         LOGE("android_media_JetPlayer_queueSegmentMuteArray(): failed with EAS error code %ld",
330             result);
331         return JNI_FALSE;
332     }
333 }
334 
335 
336 // ----------------------------------------------------------------------------
337 static jboolean
android_media_JetPlayer_setMuteFlags(JNIEnv * env,jobject thiz,jint muteFlags,jboolean bSync)338 android_media_JetPlayer_setMuteFlags(JNIEnv *env, jobject thiz,
339          jint muteFlags /*unsigned?*/, jboolean bSync)
340 {
341     JetPlayer *lpJet = (JetPlayer *)env->GetIntField(
342         thiz, javaJetPlayerFields.nativePlayerInJavaObj);
343     if (lpJet == NULL ) {
344         jniThrowException(env, "java/lang/IllegalStateException",
345             "Unable to retrieve JetPlayer pointer for setMuteFlags()");
346     }
347 
348     EAS_RESULT result;
349     result = lpJet->setMuteFlags(muteFlags, bSync==JNI_TRUE ? true : false);
350     if(result==EAS_SUCCESS) {
351         //LOGV("android_media_JetPlayer_setMuteFlags(): mute flags successfully updated");
352         return JNI_TRUE;
353     } else {
354         LOGE("android_media_JetPlayer_setMuteFlags(): failed with EAS error code %ld", result);
355         return JNI_FALSE;
356     }
357 }
358 
359 
360 // ----------------------------------------------------------------------------
361 static jboolean
android_media_JetPlayer_setMuteArray(JNIEnv * env,jobject thiz,jbooleanArray muteArray,jboolean bSync)362 android_media_JetPlayer_setMuteArray(JNIEnv *env, jobject thiz,
363         jbooleanArray muteArray, jboolean bSync)
364 {
365     JetPlayer *lpJet = (JetPlayer *)env->GetIntField(
366         thiz, javaJetPlayerFields.nativePlayerInJavaObj);
367     if (lpJet == NULL ) {
368         jniThrowException(env, "java/lang/IllegalStateException",
369             "Unable to retrieve JetPlayer pointer for setMuteArray()");
370     }
371 
372     EAS_RESULT result=EAS_FAILURE;
373 
374     jboolean *muteTracks = NULL;
375     muteTracks = env->GetBooleanArrayElements(muteArray, NULL);
376     if (muteTracks == NULL) {
377         LOGE("android_media_JetPlayer_setMuteArray(): failed to read track mute mask.");
378         return JNI_FALSE;
379     }
380 
381     EAS_U32 muteMask=0;
382     int maxTracks = lpJet->getMaxTracks();
383     for (jint trackIndex=0; trackIndex<maxTracks; trackIndex++) {
384         if(muteTracks[maxTracks-1-trackIndex]==JNI_TRUE)
385             muteMask = (muteMask << 1) | 0x00000001;
386         else
387             muteMask = muteMask << 1;
388     }
389     //LOGV("android_media_JetPlayer_setMuteArray(): FINAL mute mask =0x%08lX", muteMask);
390 
391     result = lpJet->setMuteFlags(muteMask, bSync==JNI_TRUE ? true : false);
392 
393     env->ReleaseBooleanArrayElements(muteArray, muteTracks, 0);
394     if(result==EAS_SUCCESS) {
395         //LOGV("android_media_JetPlayer_setMuteArray(): mute flags successfully updated");
396         return JNI_TRUE;
397     } else {
398         LOGE("android_media_JetPlayer_setMuteArray(): \
399             failed to update mute flags with EAS error code %ld", result);
400         return JNI_FALSE;
401     }
402 }
403 
404 
405 // ----------------------------------------------------------------------------
406 static jboolean
android_media_JetPlayer_setMuteFlag(JNIEnv * env,jobject thiz,jint trackId,jboolean muteFlag,jboolean bSync)407 android_media_JetPlayer_setMuteFlag(JNIEnv *env, jobject thiz,
408          jint trackId, jboolean muteFlag, jboolean bSync)
409 {
410     JetPlayer *lpJet = (JetPlayer *)env->GetIntField(
411         thiz, javaJetPlayerFields.nativePlayerInJavaObj);
412     if (lpJet == NULL ) {
413         jniThrowException(env, "java/lang/IllegalStateException",
414             "Unable to retrieve JetPlayer pointer for setMuteFlag()");
415     }
416 
417     EAS_RESULT result;
418     result = lpJet->setMuteFlag(trackId,
419         muteFlag==JNI_TRUE ? true : false, bSync==JNI_TRUE ? true : false);
420     if(result==EAS_SUCCESS) {
421         //LOGV("android_media_JetPlayer_setMuteFlag(): mute flag successfully updated for track %d", trackId);
422         return JNI_TRUE;
423     } else {
424         LOGE("android_media_JetPlayer_setMuteFlag(): failed to update mute flag for track %d with EAS error code %ld",
425                 trackId, result);
426         return JNI_FALSE;
427     }
428 }
429 
430 
431 // ----------------------------------------------------------------------------
432 static jboolean
android_media_JetPlayer_triggerClip(JNIEnv * env,jobject thiz,jint clipId)433 android_media_JetPlayer_triggerClip(JNIEnv *env, jobject thiz, jint clipId)
434 {
435     JetPlayer *lpJet = (JetPlayer *)env->GetIntField(
436         thiz, javaJetPlayerFields.nativePlayerInJavaObj);
437     if (lpJet == NULL ) {
438         jniThrowException(env, "java/lang/IllegalStateException",
439             "Unable to retrieve JetPlayer pointer for triggerClip()");
440     }
441 
442     EAS_RESULT result;
443     result = lpJet->triggerClip(clipId);
444     if(result==EAS_SUCCESS) {
445         //LOGV("android_media_JetPlayer_triggerClip(): triggerClip successful for clip %d", clipId);
446         return JNI_TRUE;
447     } else {
448         LOGE("android_media_JetPlayer_triggerClip(): triggerClip for clip %d failed with EAS error code %ld",
449                 clipId, result);
450         return JNI_FALSE;
451     }
452 }
453 
454 
455 // ----------------------------------------------------------------------------
456 static jboolean
android_media_JetPlayer_clearQueue(JNIEnv * env,jobject thiz)457 android_media_JetPlayer_clearQueue(JNIEnv *env, jobject thiz)
458 {
459     JetPlayer *lpJet = (JetPlayer *)env->GetIntField(
460         thiz, javaJetPlayerFields.nativePlayerInJavaObj);
461     if (lpJet == NULL ) {
462         jniThrowException(env, "java/lang/IllegalStateException",
463             "Unable to retrieve JetPlayer pointer for clearQueue()");
464     }
465 
466     EAS_RESULT result = lpJet->clearQueue();
467     if(result==EAS_SUCCESS) {
468         //LOGV("android_media_JetPlayer_clearQueue(): clearQueue successful");
469         return JNI_TRUE;
470     } else {
471         LOGE("android_media_JetPlayer_clearQueue(): clearQueue failed with EAS error code %ld",
472                 result);
473         return JNI_FALSE;
474     }
475 }
476 
477 
478 // ----------------------------------------------------------------------------
479 // ----------------------------------------------------------------------------
480 static JNINativeMethod gMethods[] = {
481     // name,               signature,               funcPtr
482     {"native_setup",       "(Ljava/lang/Object;II)Z", (void *)android_media_JetPlayer_setup},
483     {"native_finalize",    "()V",                   (void *)android_media_JetPlayer_finalize},
484     {"native_release",     "()V",                   (void *)android_media_JetPlayer_release},
485     {"native_loadJetFromFile",
486                            "(Ljava/lang/String;)Z", (void *)android_media_JetPlayer_loadFromFile},
487     {"native_loadJetFromFileD", "(Ljava/io/FileDescriptor;JJ)Z",
488                                                     (void *)android_media_JetPlayer_loadFromFileD},
489     {"native_closeJetFile","()Z",                   (void *)android_media_JetPlayer_closeFile},
490     {"native_playJet",     "()Z",                   (void *)android_media_JetPlayer_play},
491     {"native_pauseJet",    "()Z",                   (void *)android_media_JetPlayer_pause},
492     {"native_queueJetSegment",
493                            "(IIIIIB)Z",             (void *)android_media_JetPlayer_queueSegment},
494     {"native_queueJetSegmentMuteArray",
495                            "(IIII[ZB)Z",     (void *)android_media_JetPlayer_queueSegmentMuteArray},
496     {"native_setMuteFlags","(IZ)Z",                 (void *)android_media_JetPlayer_setMuteFlags},
497     {"native_setMuteArray","([ZZ)Z",                (void *)android_media_JetPlayer_setMuteArray},
498     {"native_setMuteFlag", "(IZZ)Z",                (void *)android_media_JetPlayer_setMuteFlag},
499     {"native_triggerClip", "(I)Z",                  (void *)android_media_JetPlayer_triggerClip},
500     {"native_clearQueue",  "()Z",                   (void *)android_media_JetPlayer_clearQueue},
501 };
502 
503 #define JAVA_NATIVEJETPLAYERINJAVAOBJ_FIELD_NAME "mNativePlayerInJavaObj"
504 #define JAVA_NATIVEJETPOSTEVENT_CALLBACK_NAME "postEventFromNative"
505 
506 
register_android_media_JetPlayer(JNIEnv * env)507 int register_android_media_JetPlayer(JNIEnv *env)
508 {
509     jclass jetPlayerClass = NULL;
510     javaJetPlayerFields.jetClass = NULL;
511     javaJetPlayerFields.postNativeEventInJava = NULL;
512     javaJetPlayerFields.nativePlayerInJavaObj = NULL;
513 
514     // Get the JetPlayer java class
515     jetPlayerClass = env->FindClass(kClassPathName);
516     if (jetPlayerClass == NULL) {
517         LOGE("Can't find %s", kClassPathName);
518         return -1;
519     }
520     javaJetPlayerFields.jetClass = (jclass)env->NewGlobalRef(jetPlayerClass);
521 
522     // Get the mNativePlayerInJavaObj variable field
523     javaJetPlayerFields.nativePlayerInJavaObj = env->GetFieldID(
524             jetPlayerClass,
525             JAVA_NATIVEJETPLAYERINJAVAOBJ_FIELD_NAME, "I");
526     if (javaJetPlayerFields.nativePlayerInJavaObj == NULL) {
527         LOGE("Can't find AudioTrack.%s", JAVA_NATIVEJETPLAYERINJAVAOBJ_FIELD_NAME);
528         return -1;
529     }
530 
531     // Get the callback to post events from this native code to Java
532     javaJetPlayerFields.postNativeEventInJava = env->GetStaticMethodID(javaJetPlayerFields.jetClass,
533             JAVA_NATIVEJETPOSTEVENT_CALLBACK_NAME, "(Ljava/lang/Object;III)V");
534     if (javaJetPlayerFields.postNativeEventInJava == NULL) {
535         LOGE("Can't find Jet.%s", JAVA_NATIVEJETPOSTEVENT_CALLBACK_NAME);
536         return -1;
537     }
538 
539     return AndroidRuntime::registerNativeMethods(env,
540             kClassPathName, gMethods, NELEM(gMethods));
541 }
542