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