Skip to content

Commit d9c8110

Browse files
authored
Merge pull request #2094 from OneSignal/feature/preventDefault_discard_parameter
Add discard parameter to preventDefault()
2 parents 4727d9b + 64b309c commit d9c8110

File tree

6 files changed

+128
-2
lines changed

6 files changed

+128
-2
lines changed

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/notifications/INotificationReceivedEvent.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,11 @@ interface INotificationReceivedEvent {
5050
* can still be manually displayed using `notification.display()`.
5151
*/
5252
fun preventDefault()
53+
54+
/**
55+
* Call this to prevent OneSignal from displaying the notification automatically.
56+
* @param discard an [preventDefault] set to true to dismiss the notification with no
57+
* possibility of displaying it in the future.
58+
*/
59+
fun preventDefault(discard: Boolean)
5360
}

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/notifications/INotificationWillDisplayEvent.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,11 @@ interface INotificationWillDisplayEvent {
3838
* caller still has the option to display the notification by calling `notification.display()`.
3939
*/
4040
fun preventDefault()
41+
42+
/**
43+
* Call this to prevent OneSignal from displaying the notification automatically.
44+
* @param discard an [preventDefault] set to true to dismiss the notification with no
45+
* possibility of displaying it in the future.
46+
*/
47+
fun preventDefault(discard: Boolean)
4148
}

OneSignalSDK/onesignal/notifications/src/main/java/com/onesignal/notifications/internal/NotificationReceivedEvent.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,15 @@ internal class NotificationReceivedEvent(
99
override val notification: Notification,
1010
) : INotificationReceivedEvent {
1111
var isPreventDefault: Boolean = false
12+
var discard: Boolean = false
1213

1314
override fun preventDefault() {
15+
preventDefault(false)
16+
}
17+
18+
override fun preventDefault(discard: Boolean) {
1419
Logging.debug("NotificationReceivedEvent.preventDefault()")
1520
isPreventDefault = true
21+
this.discard = discard
1622
}
1723
}

OneSignalSDK/onesignal/notifications/src/main/java/com/onesignal/notifications/internal/NotificationWillDisplayEvent.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,15 @@ internal class NotificationWillDisplayEvent(
77
override val notification: Notification,
88
) : INotificationWillDisplayEvent {
99
var isPreventDefault: Boolean = false
10+
var discard: Boolean = false
1011

1112
override fun preventDefault() {
13+
preventDefault(false)
14+
}
15+
16+
override fun preventDefault(discard: Boolean) {
1217
Logging.debug("NotificationWillDisplayEvent.preventDefault()")
1318
isPreventDefault = true
19+
this.discard = discard
1420
}
1521
}

OneSignalSDK/onesignal/notifications/src/main/java/com/onesignal/notifications/internal/generation/impl/NotificationGenerationProcessor.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@ internal class NotificationGenerationProcessor(
7373
GlobalScope.launch(Dispatchers.IO) {
7474
_lifecycleService.externalRemoteNotificationReceived(notificationReceivedEvent)
7575

76-
if (notificationReceivedEvent.isPreventDefault) {
76+
if (notificationReceivedEvent.discard) {
77+
wantsToDisplay = false
78+
} else if (notificationReceivedEvent.isPreventDefault) {
7779
// wait on display waiter. If the caller calls `display` on the notification,
7880
// we will exit `waitForWake` and set `wantsToDisplay` to true. If the callback
7981
// never calls `display` we will timeout and never set `wantsToDisplay` to true.
@@ -105,7 +107,9 @@ internal class NotificationGenerationProcessor(
105107
GlobalScope.launch(Dispatchers.IO) {
106108
_lifecycleService.externalNotificationWillShowInForeground(notificationWillDisplayEvent)
107109

108-
if (notificationWillDisplayEvent.isPreventDefault) {
110+
if (notificationWillDisplayEvent.discard) {
111+
wantsToDisplay = false
112+
} else if (notificationWillDisplayEvent.isPreventDefault) {
109113
// wait on display waiter. If the caller calls `display` on the notification,
110114
// we will exit `waitForWake` and set `wantsToDisplay` to true. If the callback
111115
// never calls `display` we will timeout and never set `wantsToDisplay` to true.

OneSignalSDK/onesignal/notifications/src/test/java/com/onesignal/notifications/internal/generation/NotificationGenerationProcessorTests.kt

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import io.mockk.just
2323
import io.mockk.mockk
2424
import io.mockk.runs
2525
import kotlinx.coroutines.delay
26+
import kotlinx.coroutines.withTimeout
2627
import org.json.JSONObject
2728
import org.robolectric.annotation.Config
2829

@@ -373,4 +374,99 @@ class NotificationGenerationProcessorTests : FunSpec({
373374
)
374375
}
375376
}
377+
378+
test("processNotificationData should immediately drop the notification when will display callback indicates to") {
379+
// Given
380+
val context = ApplicationProvider.getApplicationContext<Context>()
381+
val mockTime = MockHelper.time(1111)
382+
val mockApplicationService = AndroidMockHelper.applicationService()
383+
every { mockApplicationService.isInForeground } returns true
384+
val mockNotificationDisplayer = mockk<INotificationDisplayer>()
385+
val mockNotificationRepository = mockk<INotificationRepository>()
386+
coEvery { mockNotificationRepository.doesNotificationExist(any()) } returns false
387+
coEvery { mockNotificationRepository.createNotification(any(), any(), any(), any(), any(), any(), any(), any(), any(), any()) } just runs
388+
val mockNotificationSummaryManager = mockk<INotificationSummaryManager>()
389+
val mockNotificationLifecycleService = mockk<INotificationLifecycleService>()
390+
coEvery { mockNotificationLifecycleService.canReceiveNotification(any()) } returns true
391+
coEvery { mockNotificationLifecycleService.notificationReceived(any()) } just runs
392+
coEvery { mockNotificationLifecycleService.externalRemoteNotificationReceived(any()) } just runs
393+
coEvery { mockNotificationLifecycleService.externalNotificationWillShowInForeground(any()) } answers {
394+
val willDisplayEvent = firstArg<INotificationWillDisplayEvent>()
395+
// Setting discard parameter to true indicating we should immediately discard
396+
willDisplayEvent.preventDefault(true)
397+
}
398+
399+
val notificationGenerationProcessor =
400+
NotificationGenerationProcessor(
401+
mockApplicationService,
402+
mockNotificationDisplayer,
403+
MockHelper.configModelStore(),
404+
mockNotificationRepository,
405+
mockNotificationSummaryManager,
406+
mockNotificationLifecycleService,
407+
mockTime,
408+
)
409+
410+
val payload =
411+
JSONObject()
412+
.put("alert", "test message")
413+
.put("title", "test title")
414+
.put(
415+
"custom",
416+
JSONObject()
417+
.put("i", "UUID1"),
418+
)
419+
420+
// If discard is set to false this should timeout waiting for display()
421+
withTimeout(1_000) {
422+
notificationGenerationProcessor.processNotificationData(context, 1, payload, false, 1111)
423+
}
424+
}
425+
426+
test("processNotificationData should immediately drop the notification when received event callback indicates to") {
427+
// Given
428+
val context = ApplicationProvider.getApplicationContext<Context>()
429+
val mockTime = MockHelper.time(1111)
430+
val mockApplicationService = AndroidMockHelper.applicationService()
431+
every { mockApplicationService.isInForeground } returns true
432+
val mockNotificationDisplayer = mockk<INotificationDisplayer>()
433+
val mockNotificationRepository = mockk<INotificationRepository>()
434+
coEvery { mockNotificationRepository.doesNotificationExist(any()) } returns false
435+
coEvery { mockNotificationRepository.createNotification(any(), any(), any(), any(), any(), any(), any(), any(), any(), any()) } just runs
436+
val mockNotificationSummaryManager = mockk<INotificationSummaryManager>()
437+
val mockNotificationLifecycleService = mockk<INotificationLifecycleService>()
438+
coEvery { mockNotificationLifecycleService.canReceiveNotification(any()) } returns true
439+
coEvery { mockNotificationLifecycleService.notificationReceived(any()) } just runs
440+
coEvery { mockNotificationLifecycleService.externalRemoteNotificationReceived(any()) } answers {
441+
val receivedEvent = firstArg<INotificationReceivedEvent>()
442+
receivedEvent.preventDefault(true)
443+
}
444+
coEvery { mockNotificationLifecycleService.externalNotificationWillShowInForeground(any()) } just runs
445+
446+
val notificationGenerationProcessor =
447+
NotificationGenerationProcessor(
448+
mockApplicationService,
449+
mockNotificationDisplayer,
450+
MockHelper.configModelStore(),
451+
mockNotificationRepository,
452+
mockNotificationSummaryManager,
453+
mockNotificationLifecycleService,
454+
mockTime,
455+
)
456+
457+
val payload =
458+
JSONObject()
459+
.put("alert", "test message")
460+
.put("title", "test title")
461+
.put(
462+
"custom",
463+
JSONObject()
464+
.put("i", "UUID1"),
465+
)
466+
467+
// If discard is set to false this should timeout waiting for display()
468+
withTimeout(1_000) {
469+
notificationGenerationProcessor.processNotificationData(context, 1, payload, false, 1111)
470+
}
471+
}
376472
})

0 commit comments

Comments
 (0)