1 /* Communication module for Android terminals. -*- c-file-style: "GNU" -*-
2
3 Copyright (C) 2023 Free Software Foundation, Inc.
4
5 This file is part of GNU Emacs.
6
7 GNU Emacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or (at
10 your option) any later version.
11
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
19
20 package org.gnu.emacs;
21
22 import android.app.Notification;
23 import android.app.NotificationManager;
24 import android.app.NotificationChannel;
25 import android.app.PendingIntent;
26
27 import android.content.Context;
28 import android.content.Intent;
29
30 import android.os.Build;
31
32 import android.widget.RemoteViews;
33
34
35
36 /* Structure designating a single desktop notification.
37
38 New versions of Android also organize notifications into individual
39 ``channels'', which are used to implement groups. Unlike on other
40 systems, notification importance is set for each group, not for
41 each individual notification. */
42
43
44
45 public final class EmacsDesktopNotification
46 {
47 /* The content of this desktop notification. */
48 public final String content;
49
50 /* The title of this desktop notification. */
51 public final String title;
52
53 /* The notification group. */
54 public final String group;
55
56 /* String identifying this notification for future replacement.
57 Typically a string resembling ``XXXX.NNNN.YYYY'', where XXXX is
58 the system boot time, NNNN is the PID of this Emacs instance, and
59 YYYY is the counter value returned by the notifications display
60 function. */
61 public final String tag;
62
63 /* The identifier of this notification's icon. */
64 public final int icon;
65
66 /* The importance of this notification's group. */
67 public final int importance;
68
69 public
70 EmacsDesktopNotification (String title, String content,
71 String group, String tag, int icon,
72 int importance)
73 {
74 this.content = content;
75 this.title = title;
76 this.group = group;
77 this.tag = tag;
78 this.icon = icon;
79 this.importance = importance;
80 }
81
82
83
84 /* Functions for displaying desktop notifications. */
85
86 /* Internal helper for `display' executed on the main thread. */
87
88 @SuppressWarnings ("deprecation") /* Notification.Builder (Context). */
89 private void
90 display1 (Context context)
91 {
92 NotificationManager manager;
93 NotificationChannel channel;
94 Notification notification;
95 Object tem;
96 RemoteViews contentView;
97 Intent intent;
98 PendingIntent pending;
99
100 tem = context.getSystemService (Context.NOTIFICATION_SERVICE);
101 manager = (NotificationManager) tem;
102
103 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
104 {
105 /* Create the notification channel for this group. If a group
106 already exists with the same name, its linked attributes
107 (such as its importance) will be overridden. */
108 channel = new NotificationChannel (group, group, importance);
109 manager.createNotificationChannel (channel);
110
111 /* Create a notification object and display it. */
112 notification = (new Notification.Builder (context, group)
113 .setContentTitle (title)
114 .setContentText (content)
115 .setSmallIcon (icon)
116 .build ());
117 }
118 else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
119 notification = (new Notification.Builder (context)
120 .setContentTitle (title)
121 .setContentText (content)
122 .setSmallIcon (icon)
123 .build ());
124 else
125 {
126 notification = new Notification ();
127 notification.icon = icon;
128
129 /* This remote widget tree is defined in
130 java/res/layout/sdk8_notifications_view.xml. */
131 notification.contentView
132 = contentView
133 = new RemoteViews ("org.gnu.emacs",
134 R.layout.sdk8_notifications_view);
135 contentView.setTextViewText (R.id.sdk8_notifications_title,
136 title);
137 contentView.setTextViewText (R.id.sdk8_notifications_content,
138 content);
139 }
140
141 /* Provide a content intent which starts Emacs when the
142 notification is clicked. */
143
144 intent = new Intent (context, EmacsActivity.class);
145 intent.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK);
146
147 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
148 pending = PendingIntent.getActivity (context, 0, intent,
149 PendingIntent.FLAG_IMMUTABLE);
150 else
151 pending = PendingIntent.getActivity (context, 0, intent, 0);
152
153 notification.contentIntent = pending;
154
155 manager.notify (tag, 2, notification);
156 }
157
158 /* Display this desktop notification.
159
160 Create a notification channel named GROUP or update its
161 importance if such a channel is already defined. */
162
163 public void
164 display ()
165 {
166 EmacsService.SERVICE.runOnUiThread (new Runnable () {
167 @Override
168 public void
169 run ()
170 {
171 display1 (EmacsService.SERVICE);
172 }
173 });
174 }
175 };