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