Skip to content

Commit 14be993

Browse files
1 parent 2393a19 commit 14be993

File tree

6 files changed

+235
-0
lines changed

6 files changed

+235
-0
lines changed

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

+76
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,49 @@ data class MessagingStyle (
213213
)
214214
}
215215
}
216+
217+
/**
218+
* Corresponds to `androidx.core.app.NotificationChannelCompat`
219+
*
220+
* See: https://developer.androicd.com/reference/androidx/core/app/NotificationChannelCompat
221+
*
222+
* Generated class from Pigeon that represents data sent in messages.
223+
*/
224+
data class NotificationChannel (
225+
val id: String,
226+
/**
227+
* Specifies the importance level of notifications
228+
* to be posted on this channel.
229+
*
230+
* Must be a valid constant from [NotificationImportance].
231+
*/
232+
val importance: Long,
233+
val name: String? = null,
234+
val lightsEnabled: Boolean? = null,
235+
val vibrationPattern: LongArray? = null
236+
237+
) {
238+
companion object {
239+
@Suppress("LocalVariableName")
240+
fun fromList(__pigeon_list: List<Any?>): NotificationChannel {
241+
val id = __pigeon_list[0] as String
242+
val importance = __pigeon_list[1].let { num -> if (num is Int) num.toLong() else num as Long }
243+
val name = __pigeon_list[2] as String?
244+
val lightsEnabled = __pigeon_list[3] as Boolean?
245+
val vibrationPattern = __pigeon_list[4] as LongArray?
246+
return NotificationChannel(id, importance, name, lightsEnabled, vibrationPattern)
247+
}
248+
}
249+
fun toList(): List<Any?> {
250+
return listOf(
251+
id,
252+
importance,
253+
name,
254+
lightsEnabled,
255+
vibrationPattern,
256+
)
257+
}
258+
}
216259
private object NotificationsPigeonCodec : StandardMessageCodec() {
217260
override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? {
218261
return when (type) {
@@ -241,6 +284,11 @@ private object NotificationsPigeonCodec : StandardMessageCodec() {
241284
MessagingStyle.fromList(it)
242285
}
243286
}
287+
134.toByte() -> {
288+
return (readValue(buffer) as? List<Any?>)?.let {
289+
NotificationChannel.fromList(it)
290+
}
291+
}
244292
else -> super.readValueOfType(type, buffer)
245293
}
246294
}
@@ -266,13 +314,23 @@ private object NotificationsPigeonCodec : StandardMessageCodec() {
266314
stream.write(133)
267315
writeValue(stream, value.toList())
268316
}
317+
is NotificationChannel -> {
318+
stream.write(134)
319+
writeValue(stream, value.toList())
320+
}
269321
else -> super.writeValue(stream, value)
270322
}
271323
}
272324
}
273325

274326
/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
275327
interface AndroidNotificationHostApi {
328+
/**
329+
* Corresponds to `androidx.core.app.NotificationManagerCompat.createNotificationChannel`.
330+
*
331+
* See: https://developer.android.com/reference/androidx/core/app/NotificationManagerCompat#createNotificationChannel(androidx.core.app.NotificationChannelCompat)
332+
*/
333+
fun createNotificationChannel(channel: NotificationChannel)
276334
/**
277335
* Corresponds to `android.app.NotificationManager.notify`,
278336
* combined with `androidx.core.app.NotificationCompat.Builder`.
@@ -317,6 +375,24 @@ interface AndroidNotificationHostApi {
317375
@JvmOverloads
318376
fun setUp(binaryMessenger: BinaryMessenger, api: AndroidNotificationHostApi?, messageChannelSuffix: String = "") {
319377
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
378+
run {
379+
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.zulip.AndroidNotificationHostApi.createNotificationChannel$separatedMessageChannelSuffix", codec)
380+
if (api != null) {
381+
channel.setMessageHandler { message, reply ->
382+
val args = message as List<Any?>
383+
val channelArg = args[0] as NotificationChannel
384+
val wrapped: List<Any?> = try {
385+
api.createNotificationChannel(channelArg)
386+
listOf(null)
387+
} catch (exception: Throwable) {
388+
wrapError(exception)
389+
}
390+
reply.reply(wrapped)
391+
}
392+
} else {
393+
channel.setMessageHandler(null)
394+
}
395+
}
320396
run {
321397
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.zulip.AndroidNotificationHostApi.notify$separatedMessageChannelSuffix", codec)
322398
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

+33
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,36 @@ abstract class PendingIntentFlag {
2525
/// Corresponds to `FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT`.
2626
static const allowUnsafeImplicitIntent = 1 << 24;
2727
}
28+
29+
/// For use in [NotificationChannel.importance].
30+
///
31+
/// See: https://developer.android.com/reference/android/app/NotificationChannel#setImportance(int)
32+
abstract class NotificationImportance {
33+
/// Corresponds to `IMPORTANCE_UNSPECIFIED`:
34+
/// https://developer.android.com/reference/androidx/core/app/NotificationManagerCompat#IMPORTANCE_UNSPECIFIED()
35+
static const unspecified = -1000;
36+
37+
/// Corresponds to `IMPORTANCE_NONE`:
38+
/// https://developer.android.com/reference/androidx/core/app/NotificationManagerCompat#IMPORTANCE_NONE()
39+
static const none = 0;
40+
41+
/// Corresponds to `IMPORTANCE_MIN`:
42+
/// https://developer.android.com/reference/androidx/core/app/NotificationManagerCompat#IMPORTANCE_MIN()
43+
static const min = 1;
44+
45+
/// Corresponds to `IMPORTANCE_LOW`:
46+
/// https://developer.android.com/reference/androidx/core/app/NotificationManagerCompat#IMPORTANCE_LOW()
47+
static const low = 2;
48+
49+
/// Corresponds to `IMPORTANCE_DEFAULT`:
50+
/// https://developer.android.com/reference/androidx/core/app/NotificationManagerCompat#IMPORTANCE_DEFAULT()
51+
static const default_ = 3;
52+
53+
/// Corresponds to `IMPORTANCE_HIGH`:
54+
/// https://developer.android.com/reference/androidx/core/app/NotificationManagerCompat#IMPORTANCE_HIGH()
55+
static const high = 4;
56+
57+
/// Corresponds to `IMPORTANCE_MAX`:
58+
/// https://developer.android.com/reference/androidx/core/app/NotificationManagerCompat#IMPORTANCE_MAX()
59+
static const max = 5;
60+
}

lib/host/android_notifications.g.dart

+78
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,54 @@ class MessagingStyle {
192192
}
193193
}
194194

195+
/// Corresponds to `androidx.core.app.NotificationChannelCompat`
196+
///
197+
/// See: https://developer.androicd.com/reference/androidx/core/app/NotificationChannelCompat
198+
class NotificationChannel {
199+
NotificationChannel({
200+
required this.id,
201+
required this.importance,
202+
this.name,
203+
this.lightsEnabled,
204+
this.vibrationPattern,
205+
});
206+
207+
String id;
208+
209+
/// Specifies the importance level of notifications
210+
/// to be posted on this channel.
211+
///
212+
/// Must be a valid constant from [NotificationImportance].
213+
int importance;
214+
215+
String? name;
216+
217+
bool? lightsEnabled;
218+
219+
Int64List? vibrationPattern;
220+
221+
Object encode() {
222+
return <Object?>[
223+
id,
224+
importance,
225+
name,
226+
lightsEnabled,
227+
vibrationPattern,
228+
];
229+
}
230+
231+
static NotificationChannel decode(Object result) {
232+
result as List<Object?>;
233+
return NotificationChannel(
234+
id: result[0]! as String,
235+
importance: result[1]! as int,
236+
name: result[2] as String?,
237+
lightsEnabled: result[3] as bool?,
238+
vibrationPattern: result[4] as Int64List?,
239+
);
240+
}
241+
}
242+
195243

196244
class _PigeonCodec extends StandardMessageCodec {
197245
const _PigeonCodec();
@@ -212,6 +260,9 @@ class _PigeonCodec extends StandardMessageCodec {
212260
} else if (value is MessagingStyle) {
213261
buffer.putUint8(133);
214262
writeValue(buffer, value.encode());
263+
} else if (value is NotificationChannel) {
264+
buffer.putUint8(134);
265+
writeValue(buffer, value.encode());
215266
} else {
216267
super.writeValue(buffer, value);
217268
}
@@ -230,6 +281,8 @@ class _PigeonCodec extends StandardMessageCodec {
230281
return MessagingStyleMessage.decode(readValue(buffer)!);
231282
case 133:
232283
return MessagingStyle.decode(readValue(buffer)!);
284+
case 134:
285+
return NotificationChannel.decode(readValue(buffer)!);
233286
default:
234287
return super.readValueOfType(type, buffer);
235288
}
@@ -249,6 +302,31 @@ class AndroidNotificationHostApi {
249302

250303
final String __pigeon_messageChannelSuffix;
251304

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

pigeon/notifications.dart

+31
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,39 @@ class MessagingStyle {
9494
final bool isGroupConversation;
9595
}
9696

97+
/// Corresponds to `androidx.core.app.NotificationChannelCompat`
98+
///
99+
/// See: https://developer.android.com/reference/androidx/core/app/NotificationChannelCompat
100+
class NotificationChannel {
101+
/// Corresponds to [`NotificationChannelCompat.Builder`](https://developer.android.com/reference/androidx/core/app/NotificationChannelCompat.Builder#Builder(java.lang.String,int))
102+
NotificationChannel({
103+
required this.id,
104+
required this.importance,
105+
this.name,
106+
this.lightsEnabled,
107+
this.vibrationPattern,
108+
});
109+
110+
final String id;
111+
112+
/// Specifies the importance level of notifications
113+
/// to be posted on this channel.
114+
///
115+
/// Must be a valid constant from [NotificationImportance].
116+
final int importance;
117+
118+
final String? name;
119+
final bool? lightsEnabled;
120+
final Int64List? vibrationPattern;
121+
}
122+
97123
@HostApi()
98124
abstract class AndroidNotificationHostApi {
125+
/// Corresponds to `androidx.core.app.NotificationManagerCompat.createNotificationChannel`.
126+
///
127+
/// See: https://developer.android.com/reference/androidx/core/app/NotificationManagerCompat#createNotificationChannel(androidx.core.app.NotificationChannelCompat)
128+
void createNotificationChannel(NotificationChannel channel);
129+
99130
/// Corresponds to `android.app.NotificationManager.notify`,
100131
/// combined with `androidx.core.app.NotificationCompat.Builder`.
101132
///

test/model/binding.dart

+6
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,12 @@ class FakeAndroidNotificationHostApi implements AndroidNotificationHostApi {
513513
_activeNotificationsMessagingStyle.clear();
514514
}
515515

516+
@override
517+
Future<void> createNotificationChannel(NotificationChannel channel) {
518+
// TODO: implement createNotificationChannel
519+
throw UnimplementedError();
520+
}
521+
516522
@override
517523
Future<void> notify({
518524
String? tag,

0 commit comments

Comments
 (0)