aboutsummaryrefslogtreecommitdiffstats
path: root/src/android.c
diff options
context:
space:
mode:
authorPo Lu2024-03-11 21:40:47 +0800
committerPo Lu2024-03-11 21:41:14 +0800
commita7a37341cad230448e487d0ffa343eeeb8a66a65 (patch)
treeab06b5826c5ae7bdd5b3dcc85b3ecba8dbee8c84 /src/android.c
parent75cfc6c73faa1561018b1212156964a7919c69fe (diff)
downloademacs-a7a37341cad230448e487d0ffa343eeeb8a66a65.tar.gz
emacs-a7a37341cad230448e487d0ffa343eeeb8a66a65.zip
Implement notification callbacks on Android
* doc/lispref/os.texi (Desktop Notifications): Document that :on-cancel, :on-action and :actions are now supported on Android. * java/org/gnu/emacs/EmacsActivity.java (onNewIntent): New function. * java/org/gnu/emacs/EmacsDesktopNotification.java (NOTIFICATION_ACTION, NOTIFICATION_TAG, NOTIFICATION_DISMISSED): New constants. <actions, titles>: New fields. (insertActions): New function. (display1, display): Insert actions on Jelly Bean and up, and arrange to be notified when the notification is dismissed. (CancellationReceiver): New class. * java/org/gnu/emacs/EmacsNative.java (sendNotificationDeleted) (sendNotificationAction): New functions. * src/android.c (sendDndDrag, sendDndUri, sendDndText): Correct return types. (sendNotificationDeleted, sendNotificationAction) (android_exception_check_5, android_exception_check_6): New functions. * src/android.h: * src/androidgui.h (struct android_notification_event): New structure. (union android_event): New member for notification events. * src/androidselect.c (android_init_emacs_desktop_notification): Update JNI signatures. (android_notifications_notify_1, Fandroid_notifications_notify): New arguments ACTIONS, ACTION_CB and CANCEL_CB. Convert and record them as appropriate. (android_notification_deleted, android_notification_action): New functions. (syms_of_androidselect): Prepare a hash table of outstanding notifications. <QCactions, QCon_action, QCon_cancel> New defsyms. * src/androidterm.c (handle_one_android_event) <ANDROID_NOTIFICATION_DELETED> <ANDROID_NOTIFICATION_ACTION>: Dispatch event contents to androidselect.c for processing. * src/androidterm.h: * src/androidvfs.c (java_string_class): Export. * src/keyboard.c (kbd_buffer_get_event) <NOTIFICATION_EVENT>: Call callback specified by the event. * src/termhooks.h (enum event_kind) [HAVE_ANDROID]: New enum NOTIFICATION_EVENT.
Diffstat (limited to 'src/android.c')
-rw-r--r--src/android.c161
1 files changed, 158 insertions, 3 deletions
diff --git a/src/android.c b/src/android.c
index d7bd06f1f34..125bb5209c3 100644
--- a/src/android.c
+++ b/src/android.c
@@ -2457,7 +2457,7 @@ NATIVE_NAME (sendExpose) (JNIEnv *env, jobject object,
2457 return event_serial; 2457 return event_serial;
2458} 2458}
2459 2459
2460JNIEXPORT jboolean JNICALL 2460JNIEXPORT jlong JNICALL
2461NATIVE_NAME (sendDndDrag) (JNIEnv *env, jobject object, 2461NATIVE_NAME (sendDndDrag) (JNIEnv *env, jobject object,
2462 jshort window, jint x, jint y) 2462 jshort window, jint x, jint y)
2463{ 2463{
@@ -2477,7 +2477,7 @@ NATIVE_NAME (sendDndDrag) (JNIEnv *env, jobject object,
2477 return event_serial; 2477 return event_serial;
2478} 2478}
2479 2479
2480JNIEXPORT jboolean JNICALL 2480JNIEXPORT jlong JNICALL
2481NATIVE_NAME (sendDndUri) (JNIEnv *env, jobject object, 2481NATIVE_NAME (sendDndUri) (JNIEnv *env, jobject object,
2482 jshort window, jint x, jint y, 2482 jshort window, jint x, jint y,
2483 jstring string) 2483 jstring string)
@@ -2514,7 +2514,7 @@ NATIVE_NAME (sendDndUri) (JNIEnv *env, jobject object,
2514 return event_serial; 2514 return event_serial;
2515} 2515}
2516 2516
2517JNIEXPORT jboolean JNICALL 2517JNIEXPORT jlong JNICALL
2518NATIVE_NAME (sendDndText) (JNIEnv *env, jobject object, 2518NATIVE_NAME (sendDndText) (JNIEnv *env, jobject object,
2519 jshort window, jint x, jint y, 2519 jshort window, jint x, jint y,
2520 jstring string) 2520 jstring string)
@@ -2551,6 +2551,85 @@ NATIVE_NAME (sendDndText) (JNIEnv *env, jobject object,
2551 return event_serial; 2551 return event_serial;
2552} 2552}
2553 2553
2554JNIEXPORT jlong JNICALL
2555NATIVE_NAME (sendNotificationDeleted) (JNIEnv *env, jobject object,
2556 jstring tag)
2557{
2558 JNI_STACK_ALIGNMENT_PROLOGUE;
2559
2560 union android_event event;
2561 const char *characters;
2562
2563 event.notification.type = ANDROID_NOTIFICATION_DELETED;
2564 event.notification.serial = ++event_serial;
2565 event.notification.window = ANDROID_NONE;
2566
2567 /* TAG is guaranteed to be an ASCII string, of which the JNI character
2568 encoding is a superset. */
2569 characters = (*env)->GetStringUTFChars (env, tag, NULL);
2570 if (!characters)
2571 return 0;
2572
2573 event.notification.tag = strdup (characters);
2574 (*env)->ReleaseStringUTFChars (env, tag, characters);
2575 if (!event.notification.tag)
2576 return 0;
2577
2578 event.notification.action = NULL;
2579 event.notification.length = 0;
2580
2581 android_write_event (&event);
2582 return event_serial;
2583}
2584
2585JNIEXPORT jlong JNICALL
2586NATIVE_NAME (sendNotificationAction) (JNIEnv *env, jobject object,
2587 jstring tag, jstring action)
2588{
2589 JNI_STACK_ALIGNMENT_PROLOGUE;
2590
2591 union android_event event;
2592 const void *characters;
2593 jsize length;
2594 uint16_t *buffer;
2595
2596 event.notification.type = ANDROID_NOTIFICATION_ACTION;
2597 event.notification.serial = ++event_serial;
2598 event.notification.window = ANDROID_NONE;
2599
2600 /* TAG is guaranteed to be an ASCII string, of which the JNI character
2601 encoding is a superset. */
2602 characters = (*env)->GetStringUTFChars (env, tag, NULL);
2603 if (!characters)
2604 return 0;
2605
2606 event.notification.tag = strdup (characters);
2607 (*env)->ReleaseStringUTFChars (env, tag, characters);
2608 if (!event.notification.tag)
2609 return 0;
2610
2611 length = (*env)->GetStringLength (env, action);
2612 buffer = malloc (length * sizeof *buffer);
2613 characters = (*env)->GetStringChars (env, action, NULL);
2614
2615 if (!characters)
2616 {
2617 /* The JVM has run out of memory; return and let the out of memory
2618 error take its course. */
2619 xfree (event.notification.tag);
2620 return 0;
2621 }
2622
2623 memcpy (buffer, characters, length * sizeof *buffer);
2624 (*env)->ReleaseStringChars (env, action, characters);
2625
2626 event.notification.action = buffer;
2627 event.notification.length = length;
2628
2629 android_write_event (&event);
2630 return event_serial;
2631}
2632
2554JNIEXPORT jboolean JNICALL 2633JNIEXPORT jboolean JNICALL
2555NATIVE_NAME (shouldForwardMultimediaButtons) (JNIEnv *env, 2634NATIVE_NAME (shouldForwardMultimediaButtons) (JNIEnv *env,
2556 jobject object) 2635 jobject object)
@@ -6310,6 +6389,82 @@ android_exception_check_4 (jobject object, jobject object1,
6310 memory_full (0); 6389 memory_full (0);
6311} 6390}
6312 6391
6392/* Like android_exception_check_4, except it takes more than four local
6393 reference arguments. */
6394
6395void
6396android_exception_check_5 (jobject object, jobject object1,
6397 jobject object2, jobject object3,
6398 jobject object4)
6399{
6400 if (likely (!(*android_java_env)->ExceptionCheck (android_java_env)))
6401 return;
6402
6403 __android_log_print (ANDROID_LOG_WARN, __func__,
6404 "Possible out of memory error. "
6405 " The Java exception follows: ");
6406 /* Describe exactly what went wrong. */
6407 (*android_java_env)->ExceptionDescribe (android_java_env);
6408 (*android_java_env)->ExceptionClear (android_java_env);
6409
6410 if (object)
6411 ANDROID_DELETE_LOCAL_REF (object);
6412
6413 if (object1)
6414 ANDROID_DELETE_LOCAL_REF (object1);
6415
6416 if (object2)
6417 ANDROID_DELETE_LOCAL_REF (object2);
6418
6419 if (object3)
6420 ANDROID_DELETE_LOCAL_REF (object3);
6421
6422 if (object4)
6423 ANDROID_DELETE_LOCAL_REF (object4);
6424
6425 memory_full (0);
6426}
6427
6428
6429/* Like android_exception_check_5, except it takes more than five local
6430 reference arguments. */
6431
6432void
6433android_exception_check_6 (jobject object, jobject object1,
6434 jobject object2, jobject object3,
6435 jobject object4, jobject object5)
6436{
6437 if (likely (!(*android_java_env)->ExceptionCheck (android_java_env)))
6438 return;
6439
6440 __android_log_print (ANDROID_LOG_WARN, __func__,
6441 "Possible out of memory error. "
6442 " The Java exception follows: ");
6443 /* Describe exactly what went wrong. */
6444 (*android_java_env)->ExceptionDescribe (android_java_env);
6445 (*android_java_env)->ExceptionClear (android_java_env);
6446
6447 if (object)
6448 ANDROID_DELETE_LOCAL_REF (object);
6449
6450 if (object1)
6451 ANDROID_DELETE_LOCAL_REF (object1);
6452
6453 if (object2)
6454 ANDROID_DELETE_LOCAL_REF (object2);
6455
6456 if (object3)
6457 ANDROID_DELETE_LOCAL_REF (object3);
6458
6459 if (object4)
6460 ANDROID_DELETE_LOCAL_REF (object4);
6461
6462 if (object5)
6463 ANDROID_DELETE_LOCAL_REF (object5);
6464
6465 memory_full (0);
6466}
6467
6313/* Check for JNI problems based on the value of OBJECT. 6468/* Check for JNI problems based on the value of OBJECT.
6314 6469
6315 Signal out of memory if OBJECT is NULL. OBJECT1 means the 6470 Signal out of memory if OBJECT is NULL. OBJECT1 means the