• 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         return JNI_FALSE;
145     }
146 
147     LOGV("android_media_JetPlayer_openFile(): trying to open %s", pathStr );
148     EAS_RESULT result = lpJet->loadFromFile(pathStr);
149     env->ReleaseStringUTFChars(path, pathStr);
150 
151     if(result==EAS_SUCCESS) {
152         //LOGV("android_media_JetPlayer_openFile(): file successfully opened");
153         return JNI_TRUE;
154     } else {
155         LOGE("android_media_JetPlayer_openFile(): failed to open file with EAS error %d",
156             (int)result);
157         return JNI_FALSE;
158     }
159 }
160 
161 
162 // ----------------------------------------------------------------------------
163 static jboolean
android_media_JetPlayer_loadFromFileD(JNIEnv * env,jobject thiz,jobject fileDescriptor,jlong offset,jlong length)164 android_media_JetPlayer_loadFromFileD(JNIEnv *env, jobject thiz,
165     jobject fileDescriptor, jlong offset, jlong length)
166 {
167     JetPlayer *lpJet = (JetPlayer *)env->GetIntField(
168         thiz, javaJetPlayerFields.nativePlayerInJavaObj);
169     if (lpJet == NULL ) {
170         jniThrowException(env, "java/lang/IllegalStateException",
171             "Unable to retrieve JetPlayer pointer for openFile()");
172     }
173 
174     // set up event callback function
175     lpJet->setEventCallback(jetPlayerEventCallback);
176 
177     LOGV("android_media_JetPlayer_openFileDescr(): trying to load JET file through its fd" );
178     EAS_RESULT result = lpJet->loadFromFD(jniGetFDFromFileDescriptor(env, fileDescriptor),
179         (long long)offset, (long long)length); // cast params to types used by EAS_FILE
180 
181     if(result==EAS_SUCCESS) {
182         LOGV("android_media_JetPlayer_openFileDescr(): file successfully opened");
183         return JNI_TRUE;
184     } else {
185         LOGE("android_media_JetPlayer_openFileDescr(): failed to open file with EAS error %d",
186             (int)result);
187         return JNI_FALSE;
188     }
189 }
190 
191 
192 // ----------------------------------------------------------------------------
193 static jboolean
android_media_JetPlayer_closeFile(JNIEnv * env,jobject thiz)194 android_media_JetPlayer_closeFile(JNIEnv *env, jobject thiz)
195 {
196     JetPlayer *lpJet = (JetPlayer *)env->GetIntField(
197         thiz, javaJetPlayerFields.nativePlayerInJavaObj);
198     if (lpJet == NULL ) {
199         jniThrowException(env, "java/lang/IllegalStateException",
200             "Unable to retrieve JetPlayer pointer for closeFile()");
201     }
202 
203     if( lpJet->closeFile()==EAS_SUCCESS) {
204         //LOGV("android_media_JetPlayer_closeFile(): file successfully closed");
205         return JNI_TRUE;
206     } else {
207         LOGE("android_media_JetPlayer_closeFile(): failed to close file");
208         return JNI_FALSE;
209     }
210 }
211 
212 
213 // ----------------------------------------------------------------------------
214 static jboolean
android_media_JetPlayer_play(JNIEnv * env,jobject thiz)215 android_media_JetPlayer_play(JNIEnv *env, jobject thiz)
216 {
217     JetPlayer *lpJet = (JetPlayer *)env->GetIntField(
218         thiz, javaJetPlayerFields.nativePlayerInJavaObj);
219     if (lpJet == NULL ) {
220         jniThrowException(env, "java/lang/IllegalStateException",
221             "Unable to retrieve JetPlayer pointer for play()");
222     }
223 
224     EAS_RESULT result = lpJet->play();
225     if( result==EAS_SUCCESS) {
226         //LOGV("android_media_JetPlayer_play(): play successful");
227         return JNI_TRUE;
228     } else {
229         LOGE("android_media_JetPlayer_play(): failed to play with EAS error code %ld",
230             result);
231         return JNI_FALSE;
232     }
233 }
234 
235 
236 // ----------------------------------------------------------------------------
237 static jboolean
android_media_JetPlayer_pause(JNIEnv * env,jobject thiz)238 android_media_JetPlayer_pause(JNIEnv *env, jobject thiz)
239 {
240     JetPlayer *lpJet = (JetPlayer *)env->GetIntField(
241         thiz, javaJetPlayerFields.nativePlayerInJavaObj);
242     if (lpJet == NULL ) {
243         jniThrowException(env, "java/lang/IllegalStateException",
244             "Unable to retrieve JetPlayer pointer for pause()");
245     }
246 
247     EAS_RESULT result = lpJet->pause();
248     if( result==EAS_SUCCESS) {
249         //LOGV("android_media_JetPlayer_pause(): pause successful");
250         return JNI_TRUE;
251     } else {
252         if(result==EAS_ERROR_QUEUE_IS_EMPTY) {
253             LOGV("android_media_JetPlayer_pause(): paused with an empty queue");
254             return JNI_TRUE;
255         } else
256             LOGE("android_media_JetPlayer_pause(): failed to pause with EAS error code %ld",
257                 result);
258         return JNI_FALSE;
259     }
260 }
261 
262 
263 // ----------------------------------------------------------------------------
264 static jboolean
android_media_JetPlayer_queueSegment(JNIEnv * env,jobject thiz,jint segmentNum,jint libNum,jint repeatCount,jint transpose,jint muteFlags,jbyte userID)265 android_media_JetPlayer_queueSegment(JNIEnv *env, jobject thiz,
266         jint segmentNum, jint libNum, jint repeatCount, jint transpose, jint muteFlags,
267         jbyte userID)
268 {
269     JetPlayer *lpJet = (JetPlayer *)env->GetIntField(
270         thiz, javaJetPlayerFields.nativePlayerInJavaObj);
271     if (lpJet == NULL ) {
272         jniThrowException(env, "java/lang/IllegalStateException",
273             "Unable to retrieve JetPlayer pointer for queueSegment()");
274     }
275 
276     EAS_RESULT result
277         = lpJet->queueSegment(segmentNum, libNum, repeatCount, transpose, muteFlags, userID);
278     if(result==EAS_SUCCESS) {
279         //LOGV("android_media_JetPlayer_queueSegment(): segment successfully queued");
280         return JNI_TRUE;
281     } else {
282         LOGE("android_media_JetPlayer_queueSegment(): failed with EAS error code %ld",
283             result);
284         return JNI_FALSE;
285     }
286 }
287 
288 
289 // ----------------------------------------------------------------------------
290 static jboolean
android_media_JetPlayer_queueSegmentMuteArray(JNIEnv * env,jobject thiz,jint segmentNum,jint libNum,jint repeatCount,jint transpose,jbooleanArray muteArray,jbyte userID)291 android_media_JetPlayer_queueSegmentMuteArray(JNIEnv *env, jobject thiz,
292         jint segmentNum, jint libNum, jint repeatCount, jint transpose, jbooleanArray muteArray,
293         jbyte userID)
294 {
295     JetPlayer *lpJet = (JetPlayer *)env->GetIntField(
296         thiz, javaJetPlayerFields.nativePlayerInJavaObj);
297     if (lpJet == NULL ) {
298         jniThrowException(env, "java/lang/IllegalStateException",
299             "Unable to retrieve JetPlayer pointer for queueSegmentMuteArray()");
300     }
301 
302     EAS_RESULT result=EAS_FAILURE;
303 
304     jboolean *muteTracks = NULL;
305     muteTracks = env->GetBooleanArrayElements(muteArray, NULL);
306     if (muteTracks == NULL) {
307         LOGE("android_media_JetPlayer_queueSegment(): failed to read track mute mask.");
308         return JNI_FALSE;
309     }
310 
311     EAS_U32 muteMask=0;
312     int maxTracks = lpJet->getMaxTracks();
313     for (jint trackIndex=0; trackIndex<maxTracks; trackIndex++) {
314         if(muteTracks[maxTracks-1-trackIndex]==JNI_TRUE)
315             muteMask = (muteMask << 1) | 0x00000001;
316         else
317             muteMask = muteMask << 1;
318     }
319     //LOGV("android_media_JetPlayer_queueSegmentMuteArray(): FINAL mute mask =0x%08lX", mask);
320 
321     result = lpJet->queueSegment(segmentNum, libNum, repeatCount, transpose, muteMask, userID);
322 
323     env->ReleaseBooleanArrayElements(muteArray, muteTracks, 0);
324     if(result==EAS_SUCCESS) {
325         //LOGV("android_media_JetPlayer_queueSegmentMuteArray(): segment successfully queued");
326         return JNI_TRUE;
327     } else {
328         LOGE("android_media_JetPlayer_queueSegmentMuteArray(): failed with EAS error code %ld",
329             result);
330         return JNI_FALSE;
331     }
332 }
333 
334 
335 // ----------------------------------------------------------------------------
336 static jboolean
android_media_JetPlayer_setMuteFlags(JNIEnv * env,jobject thiz,jint muteFlags,jboolean bSync)337 android_media_JetPlayer_setMuteFlags(JNIEnv *env, jobject thiz,
338          jint muteFlags /*unsigned?*/, jboolean bSync)
339 {
340     JetPlayer *lpJet = (JetPlayer *)env->GetIntField(
341         thiz, javaJetPlayerFields.nativePlayerInJavaObj);
342     if (lpJet == NULL ) {
343         jniThrowException(env, "java/lang/IllegalStateException",
344             "Unable to retrieve JetPlayer pointer for setMuteFlags()");
345     }
346 
347     EAS_RESULT result;
348     result = lpJet->setMuteFlags(muteFlags, bSync==JNI_TRUE ? true : false);
349     if(result==EAS_SUCCESS) {
350         //LOGV("android_media_JetPlayer_setMuteFlags(): mute flags successfully updated");
351         return JNI_TRUE;
352     } else {
353         LOGE("android_media_JetPlayer_setMuteFlags(): failed with EAS error code %ld", result);
354         return JNI_FALSE;
355     }
356 }
357 
358 
359 // ----------------------------------------------------------------------------
360 static jboolean
android_media_JetPlayer_setMuteArray(JNIEnv * env,jobject thiz,jbooleanArray muteArray,jboolean bSync)361 android_media_JetPlayer_setMuteArray(JNIEnv *env, jobject thiz,
362         jbooleanArray muteArray, jboolean bSync)
363 {
364     JetPlayer *lpJet = (JetPlayer *)env->GetIntField(
365         thiz, javaJetPlayerFields.nativePlayerInJavaObj);
366     if (lpJet == NULL ) {
367         jniThrowException(env, "java/lang/IllegalStateException",
368             "Unable to retrieve JetPlayer pointer for setMuteArray()");
369     }
370 
371     EAS_RESULT result=EAS_FAILURE;
372 
373     jboolean *muteTracks = NULL;
374     muteTracks = env->GetBooleanArrayElements(muteArray, NULL);
375     if (muteTracks == NULL) {
376         LOGE("android_media_JetPlayer_setMuteArray(): failed to read track mute mask.");
377         return JNI_FALSE;
378     }
379 
380     EAS_U32 muteMask=0;
381     int maxTracks = lpJet->getMaxTracks();
382     for (jint trackIndex=0; trackIndex<maxTracks; trackIndex++) {
383         if(muteTracks[maxTracks-1-trackIndex]==JNI_TRUE)
384             muteMask = (muteMask << 1) | 0x00000001;
385         else
386             muteMask = muteMask << 1;
387     }
388     //LOGV("android_media_JetPlayer_setMuteArray(): FINAL mute mask =0x%08lX", muteMask);
389 
390     result = lpJet->setMuteFlags(muteMask, bSync==JNI_TRUE ? true : false);
391 
392     env->ReleaseBooleanArrayElements(muteArray, muteTracks, 0);
393     if(result==EAS_SUCCESS) {
394         //LOGV("android_media_JetPlayer_setMuteArray(): mute flags successfully updated");
395         return JNI_TRUE;
396     } else {
397         LOGE("android_media_JetPlayer_setMuteArray(): \
398             failed to update mute flags with EAS error code %ld", result);
399         return JNI_FALSE;
400     }
401 }
402 
403 
404 // ----------------------------------------------------------------------------
405 static jboolean
android_media_JetPlayer_setMuteFlag(JNIEnv * env,jobject thiz,jint trackId,jboolean muteFlag,jboolean bSync)406 android_media_JetPlayer_setMuteFlag(JNIEnv *env, jobject thiz,
407          jint trackId, jboolean muteFlag, jboolean bSync)
408 {
409     JetPlayer *lpJet = (JetPlayer *)env->GetIntField(
410         thiz, javaJetPlayerFields.nativePlayerInJavaObj);
411     if (lpJet == NULL ) {
412         jniThrowException(env, "java/lang/IllegalStateException",
413             "Unable to retrieve JetPlayer pointer for setMuteFlag()");
414     }
415 
416     EAS_RESULT result;
417     result = lpJet->setMuteFlag(trackId,
418         muteFlag==JNI_TRUE ? true : false, bSync==JNI_TRUE ? true : false);
419     if(result==EAS_SUCCESS) {
420         //LOGV("android_media_JetPlayer_setMuteFlag(): mute flag successfully updated for track %d", trackId);
421         return JNI_TRUE;
422     } else {
423         LOGE("android_media_JetPlayer_setMuteFlag(): failed to update mute flag for track %d with EAS error code %ld",
424                 trackId, result);
425         return JNI_FALSE;
426     }
427 }
428 
429 
430 // ----------------------------------------------------------------------------
431 static jboolean
android_media_JetPlayer_triggerClip(JNIEnv * env,jobject thiz,jint clipId)432 android_media_JetPlayer_triggerClip(JNIEnv *env, jobject thiz, jint clipId)
433 {
434     JetPlayer *lpJet = (JetPlayer *)env->GetIntField(
435         thiz, javaJetPlayerFields.nativePlayerInJavaObj);
436     if (lpJet == NULL ) {
437         jniThrowException(env, "java/lang/IllegalStateException",
438             "Unable to retrieve JetPlayer pointer for triggerClip()");
439     }
440 
441     EAS_RESULT result;
442     result = lpJet->triggerClip(clipId);
443     if(result==EAS_SUCCESS) {
444         //LOGV("android_media_JetPlayer_triggerClip(): triggerClip successful for clip %d", clipId);
445         return JNI_TRUE;
446     } else {
447         LOGE("android_media_JetPlayer_triggerClip(): triggerClip for clip %d failed with EAS error code %ld",
448                 clipId, result);
449         return JNI_FALSE;
450     }
451 }
452 
453 
454 // ----------------------------------------------------------------------------
455 static jboolean
android_media_JetPlayer_clearQueue(JNIEnv * env,jobject thiz)456 android_media_JetPlayer_clearQueue(JNIEnv *env, jobject thiz)
457 {
458     JetPlayer *lpJet = (JetPlayer *)env->GetIntField(
459         thiz, javaJetPlayerFields.nativePlayerInJavaObj);
460     if (lpJet == NULL ) {
461         jniThrowException(env, "java/lang/IllegalStateException",
462             "Unable to retrieve JetPlayer pointer for clearQueue()");
463     }
464 
465     EAS_RESULT result = lpJet->clearQueue();
466     if(result==EAS_SUCCESS) {
467         //LOGV("android_media_JetPlayer_clearQueue(): clearQueue successful");
468         return JNI_TRUE;
469     } else {
470         LOGE("android_media_JetPlayer_clearQueue(): clearQueue failed with EAS error code %ld",
471                 result);
472         return JNI_FALSE;
473     }
474 }
475 
476 
477 // ----------------------------------------------------------------------------
478 // ----------------------------------------------------------------------------
479 static JNINativeMethod gMethods[] = {
480     // name,               signature,               funcPtr
481     {"native_setup",       "(Ljava/lang/Object;II)Z", (void *)android_media_JetPlayer_setup},
482     {"native_finalize",    "()V",                   (void *)android_media_JetPlayer_finalize},
483     {"native_release",     "()V",                   (void *)android_media_JetPlayer_release},
484     {"native_loadJetFromFile",
485                            "(Ljava/lang/String;)Z", (void *)android_media_JetPlayer_loadFromFile},
486     {"native_loadJetFromFileD", "(Ljava/io/FileDescriptor;JJ)Z",
487                                                     (void *)android_media_JetPlayer_loadFromFileD},
488     {"native_closeJetFile","()Z",                   (void *)android_media_JetPlayer_closeFile},
489     {"native_playJet",     "()Z",                   (void *)android_media_JetPlayer_play},
490     {"native_pauseJet",    "()Z",                   (void *)android_media_JetPlayer_pause},
491     {"native_queueJetSegment",
492                            "(IIIIIB)Z",             (void *)android_media_JetPlayer_queueSegment},
493     {"native_queueJetSegmentMuteArray",
494                            "(IIII[ZB)Z",     (void *)android_media_JetPlayer_queueSegmentMuteArray},
495     {"native_setMuteFlags","(IZ)Z",                 (void *)android_media_JetPlayer_setMuteFlags},
496     {"native_setMuteArray","([ZZ)Z",                (void *)android_media_JetPlayer_setMuteArray},
497     {"native_setMuteFlag", "(IZZ)Z",                (void *)android_media_JetPlayer_setMuteFlag},
498     {"native_triggerClip", "(I)Z",                  (void *)android_media_JetPlayer_triggerClip},
499     {"native_clearQueue",  "()Z",                   (void *)android_media_JetPlayer_clearQueue},
500 };
501 
502 #define JAVA_NATIVEJETPLAYERINJAVAOBJ_FIELD_NAME "mNativePlayerInJavaObj"
503 #define JAVA_NATIVEJETPOSTEVENT_CALLBACK_NAME "postEventFromNative"
504 
505 
register_android_media_JetPlayer(JNIEnv * env)506 int register_android_media_JetPlayer(JNIEnv *env)
507 {
508     jclass jetPlayerClass = NULL;
509     javaJetPlayerFields.jetClass = NULL;
510     javaJetPlayerFields.postNativeEventInJava = NULL;
511     javaJetPlayerFields.nativePlayerInJavaObj = NULL;
512 
513     // Get the JetPlayer java class
514     jetPlayerClass = env->FindClass(kClassPathName);
515     if (jetPlayerClass == NULL) {
516         LOGE("Can't find %s", kClassPathName);
517         return -1;
518     }
519     javaJetPlayerFields.jetClass = (jclass)env->NewGlobalRef(jetPlayerClass);
520 
521     // Get the mNativePlayerInJavaObj variable field
522     javaJetPlayerFields.nativePlayerInJavaObj = env->GetFieldID(
523             jetPlayerClass,
524             JAVA_NATIVEJETPLAYERINJAVAOBJ_FIELD_NAME, "I");
525     if (javaJetPlayerFields.nativePlayerInJavaObj == NULL) {
526         LOGE("Can't find AudioTrack.%s", JAVA_NATIVEJETPLAYERINJAVAOBJ_FIELD_NAME);
527         return -1;
528     }
529 
530     // Get the callback to post events from this native code to Java
531     javaJetPlayerFields.postNativeEventInJava = env->GetStaticMethodID(javaJetPlayerFields.jetClass,
532             JAVA_NATIVEJETPOSTEVENT_CALLBACK_NAME, "(Ljava/lang/Object;III)V");
533     if (javaJetPlayerFields.postNativeEventInJava == NULL) {
534         LOGE("Can't find Jet.%s", JAVA_NATIVEJETPOSTEVENT_CALLBACK_NAME);
535         return -1;
536     }
537 
538     return AndroidRuntime::registerNativeMethods(env,
539             kClassPathName, gMethods, NELEM(gMethods));
540 }
541