Skip to content

Commit 4043060

Browse files
1 parent c17dd0e commit 4043060

File tree

6 files changed

+260
-18
lines changed

6 files changed

+260
-18
lines changed

android/app/src/main/kotlin/com/zulip/flutter/Notifications.g.kt

+87-9
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,51 @@ class FlutterError (
4444
val details: Any? = null
4545
) : Throwable()
4646

47+
/**
48+
* Corresponds to `androidx.core.app.NotificationChannelCompat`
49+
*
50+
* See:
51+
* https://developer.android.com/reference/androidx/core/app/NotificationChannelCompat
52+
* https://developer.android.com/reference/androidx/core/app/NotificationChannelCompat.Builder#Builder(java.lang.String,int)
53+
*
54+
* Generated class from Pigeon that represents data sent in messages.
55+
*/
56+
data class NotificationChannel (
57+
val id: String,
58+
/**
59+
* Specifies the importance level of notifications
60+
* to be posted on this channel.
61+
*
62+
* Must be a valid constant from [NotificationImportance].
63+
*/
64+
val importance: Long,
65+
val name: String? = null,
66+
val lightsEnabled: Boolean? = null,
67+
val vibrationPattern: LongArray? = null
68+
69+
) {
70+
companion object {
71+
@Suppress("LocalVariableName")
72+
fun fromList(__pigeon_list: List<Any?>): NotificationChannel {
73+
val id = __pigeon_list[0] as String
74+
val importance = __pigeon_list[1].let { num -> if (num is Int) num.toLong() else num as Long }
75+
val name = __pigeon_list[2] as String?
76+
val lightsEnabled = __pigeon_list[3] as Boolean?
77+
val vibrationPattern = __pigeon_list[4] as LongArray?
78+
return NotificationChannel(id, importance, name, lightsEnabled, vibrationPattern)
79+
}
80+
}
81+
fun toList(): List<Any?> {
82+
return listOf(
83+
id,
84+
importance,
85+
name,
86+
lightsEnabled,
87+
vibrationPattern,
88+
)
89+
}
90+
}
91+
4792
/**
4893
* Corresponds to `android.app.PendingIntent`.
4994
*
@@ -218,25 +263,30 @@ private object NotificationsPigeonCodec : StandardMessageCodec() {
218263
return when (type) {
219264
129.toByte() -> {
220265
return (readValue(buffer) as? List<Any?>)?.let {
221-
PendingIntent.fromList(it)
266+
NotificationChannel.fromList(it)
222267
}
223268
}
224269
130.toByte() -> {
225270
return (readValue(buffer) as? List<Any?>)?.let {
226-
InboxStyle.fromList(it)
271+
PendingIntent.fromList(it)
227272
}
228273
}
229274
131.toByte() -> {
230275
return (readValue(buffer) as? List<Any?>)?.let {
231-
Person.fromList(it)
276+
InboxStyle.fromList(it)
232277
}
233278
}
234279
132.toByte() -> {
235280
return (readValue(buffer) as? List<Any?>)?.let {
236-
MessagingStyleMessage.fromList(it)
281+
Person.fromList(it)
237282
}
238283
}
239284
133.toByte() -> {
285+
return (readValue(buffer) as? List<Any?>)?.let {
286+
MessagingStyleMessage.fromList(it)
287+
}
288+
}
289+
134.toByte() -> {
240290
return (readValue(buffer) as? List<Any?>)?.let {
241291
MessagingStyle.fromList(it)
242292
}
@@ -246,33 +296,43 @@ private object NotificationsPigeonCodec : StandardMessageCodec() {
246296
}
247297
override fun writeValue(stream: ByteArrayOutputStream, value: Any?) {
248298
when (value) {
249-
is PendingIntent -> {
299+
is NotificationChannel -> {
250300
stream.write(129)
251301
writeValue(stream, value.toList())
252302
}
253-
is InboxStyle -> {
303+
is PendingIntent -> {
254304
stream.write(130)
255305
writeValue(stream, value.toList())
256306
}
257-
is Person -> {
307+
is InboxStyle -> {
258308
stream.write(131)
259309
writeValue(stream, value.toList())
260310
}
261-
is MessagingStyleMessage -> {
311+
is Person -> {
262312
stream.write(132)
263313
writeValue(stream, value.toList())
264314
}
265-
is MessagingStyle -> {
315+
is MessagingStyleMessage -> {
266316
stream.write(133)
267317
writeValue(stream, value.toList())
268318
}
319+
is MessagingStyle -> {
320+
stream.write(134)
321+
writeValue(stream, value.toList())
322+
}
269323
else -> super.writeValue(stream, value)
270324
}
271325
}
272326
}
273327

274328
/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
275329
interface AndroidNotificationHostApi {
330+
/**
331+
* Corresponds to `androidx.core.app.NotificationManagerCompat.createNotificationChannel`.
332+
*
333+
* See: https://developer.android.com/reference/androidx/core/app/NotificationManagerCompat#createNotificationChannel(androidx.core.app.NotificationChannelCompat)
334+
*/
335+
fun createNotificationChannel(channel: NotificationChannel)
276336
/**
277337
* Corresponds to `android.app.NotificationManager.notify`,
278338
* combined with `androidx.core.app.NotificationCompat.Builder`.
@@ -317,6 +377,24 @@ interface AndroidNotificationHostApi {
317377
@JvmOverloads
318378
fun setUp(binaryMessenger: BinaryMessenger, api: AndroidNotificationHostApi?, messageChannelSuffix: String = "") {
319379
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
380+
run {
381+
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.zulip.AndroidNotificationHostApi.createNotificationChannel$separatedMessageChannelSuffix", codec)
382+
if (api != null) {
383+
channel.setMessageHandler { message, reply ->
384+
val args = message as List<Any?>
385+
val channelArg = args[0] as NotificationChannel
386+
val wrapped: List<Any?> = try {
387+
api.createNotificationChannel(channelArg)
388+
listOf(null)
389+
} catch (exception: Throwable) {
390+
wrapError(exception)
391+
}
392+
reply.reply(wrapped)
393+
}
394+
} else {
395+
channel.setMessageHandler(null)
396+
}
397+
}
320398
run {
321399
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.zulip.AndroidNotificationHostApi.notify$separatedMessageChannelSuffix", codec)
322400
if (api != null) {

android/app/src/main/kotlin/com/zulip/flutter/ZulipPlugin.kt

+11
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import android.content.Intent
66
import android.os.Bundle
77
import android.util.Log
88
import androidx.annotation.Keep
9+
import androidx.core.app.NotificationChannelCompat
910
import androidx.core.app.NotificationCompat
1011
import androidx.core.app.NotificationManagerCompat
1112
import androidx.core.graphics.drawable.IconCompat
@@ -42,6 +43,16 @@ fun toPigeonPerson(person: androidx.core.app.Person): Person {
4243

4344
private class AndroidNotificationHost(val context: Context)
4445
: AndroidNotificationHostApi {
46+
override fun createNotificationChannel(channel: NotificationChannel) {
47+
val notificationChannel = NotificationChannelCompat
48+
.Builder(channel.id, channel.importance.toInt()).apply {
49+
channel.name?.let { setName(it) }
50+
channel.lightsEnabled?.let { setLightsEnabled(it) }
51+
channel.vibrationPattern?.let { setVibrationPattern(it) }
52+
}.build()
53+
NotificationManagerCompat.from(context).createNotificationChannel(notificationChannel)
54+
}
55+
4556
@SuppressLint(
4657
// If permission is missing, `notify` will throw an exception.
4758
// Which hopefully will propagate to Dart, and then it's up to Dart code to handle it.

lib/host/android_notifications.dart

+35
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,40 @@
11
export './android_notifications.g.dart';
22

3+
/// For use in [NotificationChannel.importance].
4+
///
5+
/// See:
6+
/// https://developer.android.com/reference/android/app/NotificationChannel#setImportance(int)
7+
/// https://developer.android.com/reference/android/app/NotificationChannel#getImportance()
8+
abstract class NotificationImportance {
9+
/// Corresponds to `IMPORTANCE_UNSPECIFIED`:
10+
/// https://developer.android.com/reference/androidx/core/app/NotificationManagerCompat#IMPORTANCE_UNSPECIFIED()
11+
static const unspecified = -1000;
12+
13+
/// Corresponds to `IMPORTANCE_NONE`:
14+
/// https://developer.android.com/reference/androidx/core/app/NotificationManagerCompat#IMPORTANCE_NONE()
15+
static const none = 0;
16+
17+
/// Corresponds to `IMPORTANCE_MIN`:
18+
/// https://developer.android.com/reference/androidx/core/app/NotificationManagerCompat#IMPORTANCE_MIN()
19+
static const min = 1;
20+
21+
/// Corresponds to `IMPORTANCE_LOW`:
22+
/// https://developer.android.com/reference/androidx/core/app/NotificationManagerCompat#IMPORTANCE_LOW()
23+
static const low = 2;
24+
25+
/// Corresponds to `IMPORTANCE_DEFAULT`:
26+
/// https://developer.android.com/reference/androidx/core/app/NotificationManagerCompat#IMPORTANCE_DEFAULT()
27+
static const default_ = 3;
28+
29+
/// Corresponds to `IMPORTANCE_HIGH`:
30+
/// https://developer.android.com/reference/androidx/core/app/NotificationManagerCompat#IMPORTANCE_HIGH()
31+
static const high = 4;
32+
33+
/// Corresponds to `IMPORTANCE_MAX`:
34+
/// https://developer.android.com/reference/androidx/core/app/NotificationManagerCompat#IMPORTANCE_MAX()
35+
static const max = 5;
36+
}
37+
338
/// For use in [PendingIntent.flags].
439
///
540
/// See: https://developer.android.com/reference/android/app/PendingIntent#constants_1

lib/host/android_notifications.g.dart

+89-9
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,56 @@ PlatformException _createConnectionError(String channelName) {
1515
);
1616
}
1717

18+
/// Corresponds to `androidx.core.app.NotificationChannelCompat`
19+
///
20+
/// See:
21+
/// https://developer.android.com/reference/androidx/core/app/NotificationChannelCompat
22+
/// https://developer.android.com/reference/androidx/core/app/NotificationChannelCompat.Builder#Builder(java.lang.String,int)
23+
class NotificationChannel {
24+
NotificationChannel({
25+
required this.id,
26+
required this.importance,
27+
this.name,
28+
this.lightsEnabled,
29+
this.vibrationPattern,
30+
});
31+
32+
String id;
33+
34+
/// Specifies the importance level of notifications
35+
/// to be posted on this channel.
36+
///
37+
/// Must be a valid constant from [NotificationImportance].
38+
int importance;
39+
40+
String? name;
41+
42+
bool? lightsEnabled;
43+
44+
Int64List? vibrationPattern;
45+
46+
Object encode() {
47+
return <Object?>[
48+
id,
49+
importance,
50+
name,
51+
lightsEnabled,
52+
vibrationPattern,
53+
];
54+
}
55+
56+
static NotificationChannel decode(Object result) {
57+
result as List<Object?>;
58+
return NotificationChannel(
59+
id: result[0]! as String,
60+
importance: result[1]! as int,
61+
name: result[2] as String?,
62+
lightsEnabled: result[3] as bool?,
63+
vibrationPattern: result[4] as Int64List?,
64+
);
65+
}
66+
}
67+
1868
/// Corresponds to `android.app.PendingIntent`.
1969
///
2070
/// See: https://developer.android.com/reference/android/app/PendingIntent
@@ -197,21 +247,24 @@ class _PigeonCodec extends StandardMessageCodec {
197247
const _PigeonCodec();
198248
@override
199249
void writeValue(WriteBuffer buffer, Object? value) {
200-
if (value is PendingIntent) {
250+
if (value is NotificationChannel) {
201251
buffer.putUint8(129);
202252
writeValue(buffer, value.encode());
203-
} else if (value is InboxStyle) {
253+
} else if (value is PendingIntent) {
204254
buffer.putUint8(130);
205255
writeValue(buffer, value.encode());
206-
} else if (value is Person) {
256+
} else if (value is InboxStyle) {
207257
buffer.putUint8(131);
208258
writeValue(buffer, value.encode());
209-
} else if (value is MessagingStyleMessage) {
259+
} else if (value is Person) {
210260
buffer.putUint8(132);
211261
writeValue(buffer, value.encode());
212-
} else if (value is MessagingStyle) {
262+
} else if (value is MessagingStyleMessage) {
213263
buffer.putUint8(133);
214264
writeValue(buffer, value.encode());
265+
} else if (value is MessagingStyle) {
266+
buffer.putUint8(134);
267+
writeValue(buffer, value.encode());
215268
} else {
216269
super.writeValue(buffer, value);
217270
}
@@ -221,14 +274,16 @@ class _PigeonCodec extends StandardMessageCodec {
221274
Object? readValueOfType(int type, ReadBuffer buffer) {
222275
switch (type) {
223276
case 129:
224-
return PendingIntent.decode(readValue(buffer)!);
277+
return NotificationChannel.decode(readValue(buffer)!);
225278
case 130:
226-
return InboxStyle.decode(readValue(buffer)!);
279+
return PendingIntent.decode(readValue(buffer)!);
227280
case 131:
228-
return Person.decode(readValue(buffer)!);
281+
return InboxStyle.decode(readValue(buffer)!);
229282
case 132:
230-
return MessagingStyleMessage.decode(readValue(buffer)!);
283+
return Person.decode(readValue(buffer)!);
231284
case 133:
285+
return MessagingStyleMessage.decode(readValue(buffer)!);
286+
case 134:
232287
return MessagingStyle.decode(readValue(buffer)!);
233288
default:
234289
return super.readValueOfType(type, buffer);
@@ -249,6 +304,31 @@ class AndroidNotificationHostApi {
249304

250305
final String __pigeon_messageChannelSuffix;
251306

307+
/// Corresponds to `androidx.core.app.NotificationManagerCompat.createNotificationChannel`.
308+
///
309+
/// See: https://developer.android.com/reference/androidx/core/app/NotificationManagerCompat#createNotificationChannel(androidx.core.app.NotificationChannelCompat)
310+
Future<void> createNotificationChannel(NotificationChannel channel) async {
311+
final String __pigeon_channelName = 'dev.flutter.pigeon.zulip.AndroidNotificationHostApi.createNotificationChannel$__pigeon_messageChannelSuffix';
312+
final BasicMessageChannel<Object?> __pigeon_channel = BasicMessageChannel<Object?>(
313+
__pigeon_channelName,
314+
pigeonChannelCodec,
315+
binaryMessenger: __pigeon_binaryMessenger,
316+
);
317+
final List<Object?>? __pigeon_replyList =
318+
await __pigeon_channel.send(<Object?>[channel]) as List<Object?>?;
319+
if (__pigeon_replyList == null) {
320+
throw _createConnectionError(__pigeon_channelName);
321+
} else if (__pigeon_replyList.length > 1) {
322+
throw PlatformException(
323+
code: __pigeon_replyList[0]! as String,
324+
message: __pigeon_replyList[1] as String?,
325+
details: __pigeon_replyList[2],
326+
);
327+
} else {
328+
return;
329+
}
330+
}
331+
252332
/// Corresponds to `android.app.NotificationManager.notify`,
253333
/// combined with `androidx.core.app.NotificationCompat.Builder`.
254334
///

0 commit comments

Comments
 (0)