e-ntfy-android/app/src/main/java/io/heckel/ntfy/up/BroadcastReceiver.kt

117 lines
5 KiB
Kotlin
Raw Normal View History

2021-12-29 20:33:17 +01:00
package io.heckel.ntfy.up
import android.content.Context
import android.content.Intent
import android.util.Log
import io.heckel.ntfy.R
import io.heckel.ntfy.app.Application
2021-12-30 14:23:47 +01:00
import io.heckel.ntfy.data.Repository
2021-12-29 20:33:17 +01:00
import io.heckel.ntfy.data.Subscription
2021-12-29 23:48:06 +01:00
import io.heckel.ntfy.ui.SubscriberManager
import io.heckel.ntfy.util.randomString
import io.heckel.ntfy.util.topicUrlUp
2021-12-29 20:33:17 +01:00
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import java.util.*
import kotlin.random.Random
class BroadcastReceiver : android.content.BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
2021-12-30 14:23:47 +01:00
if (context == null || intent == null) {
return
}
when (intent.action) {
ACTION_REGISTER -> register(context, intent)
ACTION_UNREGISTER -> unregister(context, intent)
}
}
private fun register(context: Context, intent: Intent) {
val appId = intent.getStringExtra(EXTRA_APPLICATION) ?: return
val connectorToken = intent.getStringExtra(EXTRA_TOKEN) ?: return
val app = context.applicationContext as Application
val repository = app.repository
val distributor = Distributor(app)
Log.d(TAG, "REGISTER received for app $appId (connectorToken=$connectorToken)")
if (appId.isBlank()) {
Log.w(TAG, "Refusing registration: empty application")
distributor.sendRegistrationRefused(appId, connectorToken)
return
}
GlobalScope.launch(Dispatchers.IO) {
val existingSubscription = repository.getSubscriptionByConnectorToken(connectorToken)
if (existingSubscription != null) {
if (existingSubscription.upAppId == appId) {
val endpoint = topicUrlUp(existingSubscription.baseUrl, existingSubscription.topic)
Log.d(TAG, "Subscription with connectorToken $connectorToken exists. Sending endpoint $endpoint.")
distributor.sendEndpoint(appId, connectorToken, endpoint)
2021-12-30 14:23:47 +01:00
} else {
Log.d(TAG, "Subscription with connectorToken $connectorToken exists for a different app. Refusing registration.")
distributor.sendRegistrationRefused(appId, connectorToken)
2021-12-29 20:33:17 +01:00
}
2021-12-30 14:23:47 +01:00
return@launch
2021-12-29 20:33:17 +01:00
}
2021-12-30 14:23:47 +01:00
val baseUrl = context.getString(R.string.app_base_url) // FIXME
val topic = UP_PREFIX + randomString(TOPIC_LENGTH)
val endpoint = topicUrlUp(baseUrl, topic)
val subscription = Subscription(
id = Random.nextLong(),
baseUrl = baseUrl,
topic = topic,
instant = true, // No Firebase, always instant!
mutedUntil = 0,
upAppId = appId,
upConnectorToken = connectorToken,
totalCount = 0,
newCount = 0,
lastActive = Date().time/1000
)
// Add subscription
Log.d(TAG, "Adding subscription with for app $appId (connectorToken $connectorToken): $subscription")
repository.addSubscription(subscription)
distributor.sendEndpoint(appId, connectorToken, endpoint)
// Refresh (and maybe start) foreground service
refreshSubscriberService(app, repository)
}
}
private fun unregister(context: Context, intent: Intent) {
val connectorToken = intent.getStringExtra(EXTRA_TOKEN) ?: return
val app = context.applicationContext as Application
val repository = app.repository
val distributor = Distributor(app)
Log.d(TAG, "UNREGISTER received (connectorToken=$connectorToken)")
GlobalScope.launch(Dispatchers.IO) {
val existingSubscription = repository.getSubscriptionByConnectorToken(connectorToken)
if (existingSubscription == null) {
Log.d(TAG, "Subscription with connectorToken $connectorToken does not exist. Ignoring.")
return@launch
2021-12-29 20:33:17 +01:00
}
2021-12-30 14:23:47 +01:00
// Remove subscription
Log.d(TAG, "Removing subscription ${existingSubscription.id} with connectorToken $connectorToken")
repository.removeSubscription(existingSubscription.id)
existingSubscription.upAppId?.let { appId -> distributor.sendUnregistered(appId, connectorToken) }
// Refresh (and maybe stop) foreground service
refreshSubscriberService(app, repository)
2021-12-29 20:33:17 +01:00
}
}
2021-12-30 14:23:47 +01:00
private fun refreshSubscriberService(context: Context, repository: Repository) {
Log.d(TAG, "Refreshing subscriber service")
val subscriptionIdsWithInstantStatus = repository.getSubscriptionIdsWithInstantStatus()
val subscriberManager = SubscriberManager(context)
subscriberManager.refreshService(subscriptionIdsWithInstantStatus)
}
2021-12-29 20:33:17 +01:00
companion object {
private const val TAG = "NtfyUpBroadcastRecv"
2021-12-30 14:23:47 +01:00
private const val UP_PREFIX = "up"
private const val TOPIC_LENGTH = 16
2021-12-29 20:33:17 +01:00
}
}