Skip to content

Commit

Permalink
Use a waiter with a lifecycle listener to change the polling period
Browse files Browse the repository at this point in the history
  • Loading branch information
emawby committed Jun 10, 2024
1 parent 3fda347 commit 3822030
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -199,12 +199,21 @@ class ConfigModel : Model() {
}

/**
* The number of milliseconds between fetching the current notification permission value
* The number of milliseconds between fetching the current notification permission value when the app is in focus
*/
var fetchNotificationPermissionInterval: Long
get() = getLongProperty(::fetchNotificationPermissionInterval.name) { 1_000 }
var foregroundFetchNotificationPermissionInterval: Long
get() = getLongProperty(::foregroundFetchNotificationPermissionInterval.name) { 1_000 }
set(value) {
setLongProperty(::fetchNotificationPermissionInterval.name, value)
setLongProperty(::foregroundFetchNotificationPermissionInterval.name, value)
}

/**
* The number of milliseconds between fetching the current notification permission value when the app is out of focus
*/
var backgroundFetchNotificationPermissionInterval: Long
get() = getLongProperty(::backgroundFetchNotificationPermissionInterval.name) { 1_800_000 }
set(value) {
setLongProperty(::backgroundFetchNotificationPermissionInterval.name, value)
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ import com.onesignal.notifications.internal.common.NotificationHelper
import com.onesignal.notifications.internal.permissions.INotificationPermissionChangedHandler
import com.onesignal.notifications.internal.permissions.INotificationPermissionController
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.newSingleThreadContext
import kotlinx.coroutines.withTimeoutOrNull
import kotlinx.coroutines.yield

internal class NotificationPermissionController(
Expand All @@ -59,6 +59,8 @@ internal class NotificationPermissionController(
) : IRequestPermissionService.PermissionCallback,
INotificationPermissionController {
private val waiter = WaiterWithValue<Boolean>()
private val pollingWaiter = WaiterWithValue<Boolean>()
private var pollingWaitInterval: Long
private val events = EventProducer<INotificationPermissionChangedHandler>()
private var enabled: Boolean
private val coroutineScope = CoroutineScope(newSingleThreadContext(name = "NotificationPermissionController"))
Expand All @@ -74,20 +76,40 @@ internal class NotificationPermissionController(
init {
this.enabled = notificationsEnabled()
_requestPermission.registerAsCallback(PERMISSION_TYPE, this)
pollingWaitInterval = _configModelStore.model.foregroundFetchNotificationPermissionInterval
registerPollingLifecycleListener()
coroutineScope.launch {
pollForPermission()
}
}

private fun registerPollingLifecycleListener() {
_applicationService.addApplicationLifecycleHandler(
object : ApplicationLifecycleHandlerBase() {
override fun onFocus() {
super.onFocus()
pollingWaitInterval = _configModelStore.model.foregroundFetchNotificationPermissionInterval
pollingWaiter.wake(true)
}

override fun onUnfocused() {
super.onUnfocused()
pollingWaitInterval = _configModelStore.model.backgroundFetchNotificationPermissionInterval
}
},
)
}

private suspend fun pollForPermission() {
while (true) {
val enabled = this.notificationsEnabled()
if (this.enabled != enabled) { // If the permission has changed without prompting through OneSignal
this.enabled = enabled
events.fire { it.onNotificationPermissionChanged(enabled) }
}
// change to use waiter and account for background/foreground
delay(_configModelStore.model.fetchNotificationPermissionInterval)
withTimeoutOrNull(pollingWaitInterval) {
pollingWaiter.waitForWake()
}
}
}

Expand Down

0 comments on commit 3822030

Please sign in to comment.