aboutsummaryrefslogtreecommitdiffstats
path: root/src/androidselect.c
diff options
context:
space:
mode:
authorPo Lu2023-08-21 09:36:52 +0800
committerPo Lu2023-08-21 09:36:52 +0800
commitb1e498ac8c067b265c5f3de778e0a2722f7948a6 (patch)
treebee97091b8a44db86654aec71c2382336837276e /src/androidselect.c
parent652e45b70d82e6f615febe00553dbded80557845 (diff)
downloademacs-b1e498ac8c067b265c5f3de778e0a2722f7948a6.tar.gz
emacs-b1e498ac8c067b265c5f3de778e0a2722f7948a6.zip
Enable providing icons for Android desktop notifications
* doc/lispref/os.texi (Desktop Notifications) <android-notifications-notify>: Mention the :icon parameter. * java/org/gnu/emacs/EmacsDesktopNotification.java (EmacsDesktopNotification) <icon>: New field. (<init>): New argument ICON. Set this.icon to its value. (display1): Use provided icon and always supply a pending intent to open Emacs once the notification is clicked. * java/res/layout/sdk8_notifications_view.xml (sdk8_notifications_title, sdk8_notifications_content): Set foreground color to #000000. * src/androidselect.c (android_init_emacs_desktop_notification): Update signature of <init>. (android_locate_icon): New function. (android_notifications_notify_1): New arg ICON. (Fandroid_notifications_notify): New parameter icon. (syms_of_androidselect): <QCicon>: New symbol.
Diffstat (limited to 'src/androidselect.c')
-rw-r--r--src/androidselect.c73
1 files changed, 64 insertions, 9 deletions
diff --git a/src/androidselect.c b/src/androidselect.c
index 5551598032d..5735eda2dd5 100644
--- a/src/androidselect.c
+++ b/src/androidselect.c
@@ -515,24 +515,60 @@ android_init_emacs_desktop_notification (void)
515 515
516 FIND_METHOD (init, "<init>", "(Ljava/lang/String;" 516 FIND_METHOD (init, "<init>", "(Ljava/lang/String;"
517 "Ljava/lang/String;Ljava/lang/String;" 517 "Ljava/lang/String;Ljava/lang/String;"
518 "Ljava/lang/String;I)V"); 518 "Ljava/lang/String;II)V");
519 FIND_METHOD (display, "display", "()V"); 519 FIND_METHOD (display, "display", "()V");
520#undef FIND_METHOD 520#undef FIND_METHOD
521} 521}
522 522
523/* Return the numeric resource ID designating the icon within the
524 ``android.R.drawable'' package by the supplied NAME.
525
526 If no icon is found, return that of
527 ``android.R.drawable.ic_dialog_alert''. */
528
529static jint
530android_locate_icon (const char *name)
531{
532 jclass drawable;
533 jfieldID field;
534 jint rc;
535
536 if (android_verify_jni_string (name))
537 /* If NAME isn't valid, return the default value. */
538 return 17301543; /* android.R.drawable.ic_dialog_alert. */
539
540 drawable = (*android_java_env)->FindClass (android_java_env,
541 "android/R$drawable");
542 android_exception_check ();
543
544 field = (*android_java_env)->GetStaticFieldID (android_java_env,
545 drawable, name, "I");
546 (*android_java_env)->ExceptionClear (android_java_env);
547
548 if (!field)
549 rc = 17301543; /* android.R.drawable.ic_dialog_alert. */
550 else
551 rc = (*android_java_env)->GetStaticIntField (android_java_env,
552 drawable, field);
553
554 ANDROID_DELETE_LOCAL_REF (drawable);
555 return rc;
556}
557
523/* Display a desktop notification with the provided TITLE, BODY, 558/* Display a desktop notification with the provided TITLE, BODY,
524 REPLACES_ID, GROUP and URGENCY. Return an identifier for the 559 REPLACES_ID, GROUP, ICON, and URGENCY. Return an identifier for
525 resulting notification. */ 560 the resulting notification. */
526 561
527static intmax_t 562static intmax_t
528android_notifications_notify_1 (Lisp_Object title, Lisp_Object body, 563android_notifications_notify_1 (Lisp_Object title, Lisp_Object body,
529 Lisp_Object replaces_id, 564 Lisp_Object replaces_id,
530 Lisp_Object group, Lisp_Object urgency) 565 Lisp_Object group, Lisp_Object icon,
566 Lisp_Object urgency)
531{ 567{
532 static intmax_t counter; 568 static intmax_t counter;
533 intmax_t id; 569 intmax_t id;
534 jstring title1, body1, group1, identifier1; 570 jstring title1, body1, group1, identifier1;
535 jint type; 571 jint type, icon1;
536 jobject notification; 572 jobject notification;
537 char identifier[INT_STRLEN_BOUND (int) 573 char identifier[INT_STRLEN_BOUND (int)
538 + INT_STRLEN_BOUND (long int) 574 + INT_STRLEN_BOUND (long int)
@@ -562,6 +598,9 @@ android_notifications_notify_1 (Lisp_Object title, Lisp_Object body,
562 id = -1; /* Overflow. */ 598 id = -1; /* Overflow. */
563 } 599 }
564 600
601 /* Locate the integer ID linked to ICON. */
602 icon1 = android_locate_icon (SSDATA (icon));
603
565 /* Generate a unique identifier for this notification. Because 604 /* Generate a unique identifier for this notification. Because
566 Android persists notifications past system shutdown, also include 605 Android persists notifications past system shutdown, also include
567 the boot time within IDENTIFIER. Scale it down to avoid being 606 the boot time within IDENTIFIER. Scale it down to avoid being
@@ -585,7 +624,7 @@ android_notifications_notify_1 (Lisp_Object title, Lisp_Object body,
585 notification_class.class, 624 notification_class.class,
586 notification_class.init, 625 notification_class.init,
587 title1, body1, group1, 626 title1, body1, group1,
588 identifier1, type); 627 identifier1, icon1, type);
589 android_exception_check_4 (title1, body1, group1, identifier1); 628 android_exception_check_4 (title1, body1, group1, identifier1);
590 629
591 /* Delete unused local references. */ 630 /* Delete unused local references. */
@@ -618,6 +657,8 @@ keywords is understood:
618 :group The notification group, or nil. 657 :group The notification group, or nil.
619 :urgency One of the symbols `low', `normal' or `critical', 658 :urgency One of the symbols `low', `normal' or `critical',
620 defining the importance of the notification group. 659 defining the importance of the notification group.
660 :icon The name of a drawable resource to display as the
661 notification's icon.
621 662
622The notification group and urgency are ignored on Android 7.1 and 663The notification group and urgency are ignored on Android 7.1 and
623earlier versions of Android. Outside such older systems, it 664earlier versions of Android. Outside such older systems, it
@@ -626,6 +667,11 @@ menu. The urgency provided always extends to affect all notifications
626displayed within that category. If the group is not provided, it 667displayed within that category. If the group is not provided, it
627defaults to the string "Desktop Notifications". 668defaults to the string "Desktop Notifications".
628 669
670The provided icon should be the name of a "drawable resource" present
671within the "android.R.drawable" class designating an icon with a
672transparent background. If no icon is provided (or the icon is absent
673from this system), it defaults to "ic_dialog_alert".
674
629When the system is running Android 13 or later, notifications sent 675When the system is running Android 13 or later, notifications sent
630will be silently disregarded unless permission to display 676will be silently disregarded unless permission to display
631notifications is expressly granted from the "App Info" settings panel 677notifications is expressly granted from the "App Info" settings panel
@@ -640,6 +686,7 @@ usage: (android-notifications-notify &rest ARGS) */)
640 (ptrdiff_t nargs, Lisp_Object *args) 686 (ptrdiff_t nargs, Lisp_Object *args)
641{ 687{
642 Lisp_Object title, body, replaces_id, group, urgency; 688 Lisp_Object title, body, replaces_id, group, urgency;
689 Lisp_Object icon;
643 Lisp_Object key, value; 690 Lisp_Object key, value;
644 ptrdiff_t i; 691 ptrdiff_t i;
645 692
@@ -647,7 +694,7 @@ usage: (android-notifications-notify &rest ARGS) */)
647 error ("No Android display connection!"); 694 error ("No Android display connection!");
648 695
649 /* Clear each variable above. */ 696 /* Clear each variable above. */
650 title = body = replaces_id = group = urgency = Qnil; 697 title = body = replaces_id = group = icon = urgency = Qnil;
651 698
652 /* If NARGS is odd, error. */ 699 /* If NARGS is odd, error. */
653 700
@@ -671,6 +718,8 @@ usage: (android-notifications-notify &rest ARGS) */)
671 group = value; 718 group = value;
672 else if (EQ (key, QCurgency)) 719 else if (EQ (key, QCurgency))
673 urgency = value; 720 urgency = value;
721 else if (EQ (key, QCicon))
722 icon = value;
674 } 723 }
675 724
676 /* Demand at least TITLE and BODY be present. */ 725 /* Demand at least TITLE and BODY be present. */
@@ -687,10 +736,15 @@ usage: (android-notifications-notify &rest ARGS) */)
687 urgency = Qlow; 736 urgency = Qlow;
688 737
689 if (NILP (group)) 738 if (NILP (group))
690 group = build_string ("Desktop Notifications"); 739 group = build_string ("Desktop Notifications");
740
741 if (NILP (icon))
742 icon = build_string ("ic_dialog_alert");
743 else
744 CHECK_STRING (icon);
691 745
692 return make_int (android_notifications_notify_1 (title, body, replaces_id, 746 return make_int (android_notifications_notify_1 (title, body, replaces_id,
693 group, urgency)); 747 group, icon, urgency));
694} 748}
695 749
696 750
@@ -731,6 +785,7 @@ syms_of_androidselect (void)
731 DEFSYM (QCreplaces_id, ":replaces-id"); 785 DEFSYM (QCreplaces_id, ":replaces-id");
732 DEFSYM (QCgroup, ":group"); 786 DEFSYM (QCgroup, ":group");
733 DEFSYM (QCurgency, ":urgency"); 787 DEFSYM (QCurgency, ":urgency");
788 DEFSYM (QCicon, ":icon");
734 789
735 DEFSYM (Qlow, "low"); 790 DEFSYM (Qlow, "low");
736 DEFSYM (Qnormal, "normal"); 791 DEFSYM (Qnormal, "normal");