This commit is contained in:
Philipp Heckel 2021-12-31 15:30:49 +01:00
parent bec263d1c8
commit 496bdcd285
7 changed files with 42 additions and 4 deletions

View file

@ -23,8 +23,8 @@ class NotificationDispatcher(val context: Context, val repository: Repository) {
fun dispatch(subscription: Subscription, notification: Notification) {
val muted = checkMuted(subscription)
val notify = checkNotify(subscription, notification, muted)
val broadcast = subscription.upAppId == null
val distribute = subscription.upAppId != null
val broadcast = subscription.upAppId == null // Never broadcast for UnifiedPush
val distribute = subscription.upAppId != null // Only distribute for UnifiedPush subscriptions
if (notify) {
notifier.send(subscription, notification)
}

View file

@ -11,6 +11,11 @@ import io.heckel.ntfy.up.BroadcastReceiver
/**
* This class only manages the SubscriberService, i.e. it starts or stops it.
* It's used in multiple activities.
*
* We are starting the service via a worker and not directly because since Android 7
* (but officially since Lollipop!), any process called by a BroadcastReceiver
* (only manifest-declared receiver) is run at low priority and hence eventually
* killed by Android.
*/
class SubscriberServiceManager(private val context: Context) {
fun refresh() {
@ -20,6 +25,10 @@ class SubscriberServiceManager(private val context: Context) {
workManager.enqueue(startServiceRequest)
}
/**
* Starts or stops the foreground service by figuring out how many instant delivery subscriptions
* exist. If there's > 0, then we need a foreground service.
*/
class RefreshWorker(private val context: Context, params: WorkerParameters) : Worker(context, params) {
override fun doWork(): Result {
if (context.applicationContext !is Application) {

View file

@ -1,10 +1,15 @@
package io.heckel.ntfy.ui
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.os.Bundle
import android.text.TextUtils
import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.preference.*
import androidx.preference.Preference.OnPreferenceClickListener
import io.heckel.ntfy.BuildConfig
import io.heckel.ntfy.R
import io.heckel.ntfy.app.Application
@ -37,6 +42,10 @@ class SettingsActivity : AppCompatActivity() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.main_preferences, rootKey)
// Important note: We do not use the default shared prefs to store settings. Every
// preferenceDataStore is overridden to use the repository. This is convenient, because
// everybody has access to the repository.
// UnifiedPush Enabled
val upEnabledPrefId = context?.getString(R.string.pref_unified_push_enabled) ?: return
val upEnabled: SwitchPreference? = findPreference(upEnabledPrefId)
@ -82,7 +91,18 @@ class SettingsActivity : AppCompatActivity() {
// Version
val versionPrefId = context?.getString(R.string.pref_version) ?: return
val versionPref: Preference? = findPreference(versionPrefId)
versionPref?.summary = getString(R.string.settings_about_version_format, BuildConfig.VERSION_NAME, BuildConfig.FLAVOR)
val version = getString(R.string.settings_about_version_format, BuildConfig.VERSION_NAME, BuildConfig.FLAVOR)
versionPref?.summary = version
versionPref?.onPreferenceClickListener = OnPreferenceClickListener {
val context = context ?: return@OnPreferenceClickListener false
val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clip = ClipData.newPlainText("app version", version)
clipboard.setPrimaryClip(clip)
Toast
.makeText(context, getString(R.string.settings_about_version_copied_to_clipboard_message), Toast.LENGTH_LONG)
.show()
true
}
}
}
}

View file

@ -16,6 +16,10 @@ import kotlinx.coroutines.launch
import java.util.*
import kotlin.random.Random
/**
* This is the UnifiedPush broadcast receiver to handle the distributor actions REGISTER and UNREGISTER.
* See https://unifiedpush.org/spec/android/ for details.
*/
class BroadcastReceiver : android.content.BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
if (context == null || intent == null) {
@ -69,7 +73,6 @@ class BroadcastReceiver : android.content.BroadcastReceiver() {
newCount = 0,
lastActive = Date().time/1000
)
Log.d(TAG, "Adding subscription with for app $appId (connectorToken $connectorToken): $subscription")
repository.addSubscription(subscription)
distributor.sendEndpoint(appId, connectorToken, endpoint)

View file

@ -4,6 +4,10 @@ import android.content.Context
import android.content.Intent
import android.util.Log
/**
* This is the UnifiedPush distributor, an amalgamation of messages to be sent as part of the spec.
* See https://unifiedpush.org/spec/android/ for details.
*/
class Distributor(val context: Context) {
fun sendMessage(app: String, connectorToken: String, message: String) {
Log.d(TAG, "Sending MESSAGE to $app (token=$connectorToken): $message")

View file

@ -104,6 +104,7 @@ fun fadeStatusBarColor(window: Window, fromColor: Int, toColor: Int) {
statusBarColorAnimation.start()
}
// Generates a (cryptographically secure) random string of a certain length
fun randomString(len: Int): String {
val random = SecureRandom()
val chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".toCharArray()

View file

@ -157,6 +157,7 @@
<string name="settings_about_header">About</string>
<string name="settings_about_version">Version</string>
<string name="settings_about_version_format">ntfy %1$s (%2$s)</string>
<string name="settings_about_version_copied_to_clipboard_message">Copied to clipboard</string>
<!-- Preferences IDs -->
<string name="pref_unified_push_enabled">UnifiedPushEnabled</string>