Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import at.bitfire.davdroid.push.PushRegistrationManager.Companion.mutex
import at.bitfire.davdroid.repository.AccountRepository
import at.bitfire.davdroid.repository.DavCollectionRepository
import at.bitfire.davdroid.repository.DavServiceRepository
import at.bitfire.davdroid.settings.Settings.EXPLICIT_PUSH_DISABLE
import at.bitfire.davdroid.settings.SettingsManager
import at.bitfire.davdroid.sync.account.InvalidAccountException
import dagger.Lazy
import dagger.hilt.android.qualifiers.ApplicationContext
Expand Down Expand Up @@ -64,7 +66,9 @@ class PushRegistrationManager @Inject constructor(
private val httpClientBuilder: Provider<HttpClientBuilder>,
@IoDispatcher private val ioDispatcher: CoroutineDispatcher,
private val logger: Logger,
private val serviceRepository: DavServiceRepository
private val serviceRepository: DavServiceRepository,
private val settings: SettingsManager,
private val distributorPreferences: DistributorPreferences,
) {

/**
Expand All @@ -87,8 +91,16 @@ class PushRegistrationManager @Inject constructor(
}
}

/**
* Get the distributor registered by the user.
* @return The distributor package name if any, else `null`.
*/
fun getCurrentDistributor() = UnifiedPush.getSavedDistributor(context)

/**
* Get a list of available distributors installed on the system.
* @return The list of distributor's package name.
*/
fun getDistributors() = UnifiedPush.getDistributors(context)


Expand All @@ -102,6 +114,27 @@ class PushRegistrationManager @Inject constructor(
* with [update(serviceId)].
*/
suspend fun update() = mutex.withLock {
val currentDistributor = getCurrentDistributor()
val isPushDisabled = settings.getBooleanOrNull(EXPLICIT_PUSH_DISABLE)
if (currentDistributor == null) {
if (isPushDisabled == true) {
logger.info("Push is explicitly disabled, no distributor will be selected.")
} else {
val availableDistributors = getDistributors()
if (availableDistributors.isNotEmpty()) {
logger.fine("No Push distributor selected, but ${availableDistributors.size} distributors are available.")
// select preferred distributor if available, otherwise first available
val distributor = distributorPreferences.packageNames.firstNotNullOfOrNull { preferredPackageName ->
availableDistributors.find { it == preferredPackageName }
} ?: availableDistributors.first()
logger.fine("Automatically selecting Push distributor: $distributor")
UnifiedPush.saveDistributor(context, distributor)
} else {
logger.fine("No Push distributor selected and no distributors are available.")
}
}
}

for (service in serviceRepository.getAll())
updateService(service.id)

Expand Down Expand Up @@ -352,6 +385,19 @@ class PushRegistrationManager @Inject constructor(
}


/**
* Allows preferring certain distributors over others.
*/
interface DistributorPreferences {
/**
* A list of package names ordered by preference.
* If any of those is available, it will be automatically selected.
* Otherwise, another available distributor will be chosen automatically.
*/
val packageNames: List<String>
}


companion object {

private const val WORKER_UNIQUE_NAME = "push-registration"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,5 +65,12 @@ object Settings {

/** max. number of accounts */
const val MAX_ACCOUNTS = "max_accounts"


/**
* By default, a push distributor is automatically selected when needed. However, the user can choose to disable push completely.
* This setting reflects that choice.
*/
const val EXPLICIT_PUSH_DISABLE = "push_disable"

}
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,13 @@ class AppSettingsModel @Inject constructor(
viewModelScope.launch(ioDispatcher) {
pushRegistrationManager.setPushDistributor(pushDistributor)

if (pushDistributor == null) {
// Disable push explicitly, this will disable the automatic distributor selector
settings.putBoolean(Settings.EXPLICIT_PUSH_DISABLE, true)
} else {
settings.remove(Settings.EXPLICIT_PUSH_DISABLE)
}

_pushDistributor.value = pushDistributor
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

package at.bitfire.davdroid.di

import at.bitfire.davdroid.push.DistributorPreferencesProvider
import at.bitfire.davdroid.push.PushRegistrationManager
import at.bitfire.davdroid.ui.intro.OseIntroPageFactory

import at.bitfire.davdroid.ui.AboutActivity
Expand Down Expand Up @@ -47,6 +49,9 @@ interface OseModules {
interface Global {
@Binds
fun introPageFactory(impl: OseIntroPageFactory): IntroPageFactory

@Binds
fun pushDistributorPreferences(impl: DistributorPreferencesProvider): PushRegistrationManager.DistributorPreferences
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/

package at.bitfire.davdroid.push

import javax.inject.Inject

class DistributorPreferencesProvider @Inject constructor() : PushRegistrationManager.DistributorPreferences {
// No special preferences for OSE flavor, select the first distributor available
override val packageNames: List<String> = emptyList()
}
Loading