diff options
| author | Po Lu | 2023-08-21 09:36:52 +0800 |
|---|---|---|
| committer | Po Lu | 2023-08-21 09:36:52 +0800 |
| commit | b1e498ac8c067b265c5f3de778e0a2722f7948a6 (patch) | |
| tree | bee97091b8a44db86654aec71c2382336837276e /src/androidselect.c | |
| parent | 652e45b70d82e6f615febe00553dbded80557845 (diff) | |
| download | emacs-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.c | 73 |
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 | |||
| 529 | static jint | ||
| 530 | android_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 | ||
| 527 | static intmax_t | 562 | static intmax_t |
| 528 | android_notifications_notify_1 (Lisp_Object title, Lisp_Object body, | 563 | android_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 | ||
| 622 | The notification group and urgency are ignored on Android 7.1 and | 663 | The notification group and urgency are ignored on Android 7.1 and |
| 623 | earlier versions of Android. Outside such older systems, it | 664 | earlier versions of Android. Outside such older systems, it |
| @@ -626,6 +667,11 @@ menu. The urgency provided always extends to affect all notifications | |||
| 626 | displayed within that category. If the group is not provided, it | 667 | displayed within that category. If the group is not provided, it |
| 627 | defaults to the string "Desktop Notifications". | 668 | defaults to the string "Desktop Notifications". |
| 628 | 669 | ||
| 670 | The provided icon should be the name of a "drawable resource" present | ||
| 671 | within the "android.R.drawable" class designating an icon with a | ||
| 672 | transparent background. If no icon is provided (or the icon is absent | ||
| 673 | from this system), it defaults to "ic_dialog_alert". | ||
| 674 | |||
| 629 | When the system is running Android 13 or later, notifications sent | 675 | When the system is running Android 13 or later, notifications sent |
| 630 | will be silently disregarded unless permission to display | 676 | will be silently disregarded unless permission to display |
| 631 | notifications is expressly granted from the "App Info" settings panel | 677 | notifications 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"); |