mirror of
https://github.com/element-hq/element-android
synced 2024-11-23 09:55:40 +03:00
Merge pull request #7675 from vector-im/fix/mna/unified-push-selection
ANR when asking to select the notification method
This commit is contained in:
commit
a2f8fed63c
36 changed files with 1226 additions and 335 deletions
1
changelog.d/7653.bugfix
Normal file
1
changelog.d/7653.bugfix
Normal file
|
@ -0,0 +1 @@
|
||||||
|
ANR when asking to select the notification method
|
|
@ -17,7 +17,6 @@
|
||||||
|
|
||||||
package im.vector.app.push.fcm
|
package im.vector.app.push.fcm
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import im.vector.app.core.di.ActiveSessionHolder
|
import im.vector.app.core.di.ActiveSessionHolder
|
||||||
import im.vector.app.core.pushers.FcmHelper
|
import im.vector.app.core.pushers.FcmHelper
|
||||||
|
@ -44,7 +43,7 @@ class FdroidFcmHelper @Inject constructor(
|
||||||
// No op
|
// No op
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun ensureFcmTokenIsRetrieved(activity: Activity, pushersManager: PushersManager, registerPusher: Boolean) {
|
override fun ensureFcmTokenIsRetrieved(pushersManager: PushersManager, registerPusher: Boolean) {
|
||||||
// No op
|
// No op
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
*/
|
*/
|
||||||
package im.vector.app.push.fcm
|
package im.vector.app.push.fcm
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
@ -23,6 +22,7 @@ import androidx.core.content.edit
|
||||||
import com.google.android.gms.common.ConnectionResult
|
import com.google.android.gms.common.ConnectionResult
|
||||||
import com.google.android.gms.common.GoogleApiAvailability
|
import com.google.android.gms.common.GoogleApiAvailability
|
||||||
import com.google.firebase.messaging.FirebaseMessaging
|
import com.google.firebase.messaging.FirebaseMessaging
|
||||||
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.di.ActiveSessionHolder
|
import im.vector.app.core.di.ActiveSessionHolder
|
||||||
import im.vector.app.core.di.DefaultPreferences
|
import im.vector.app.core.di.DefaultPreferences
|
||||||
|
@ -36,8 +36,8 @@ import javax.inject.Inject
|
||||||
* It has an alter ego in the fdroid variant.
|
* It has an alter ego in the fdroid variant.
|
||||||
*/
|
*/
|
||||||
class GoogleFcmHelper @Inject constructor(
|
class GoogleFcmHelper @Inject constructor(
|
||||||
@DefaultPreferences
|
@ApplicationContext private val context: Context,
|
||||||
private val sharedPrefs: SharedPreferences,
|
@DefaultPreferences private val sharedPrefs: SharedPreferences,
|
||||||
) : FcmHelper {
|
) : FcmHelper {
|
||||||
companion object {
|
companion object {
|
||||||
private const val PREFS_KEY_FCM_TOKEN = "FCM_TOKEN"
|
private const val PREFS_KEY_FCM_TOKEN = "FCM_TOKEN"
|
||||||
|
@ -56,10 +56,9 @@ class GoogleFcmHelper @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun ensureFcmTokenIsRetrieved(activity: Activity, pushersManager: PushersManager, registerPusher: Boolean) {
|
override fun ensureFcmTokenIsRetrieved(pushersManager: PushersManager, registerPusher: Boolean) {
|
||||||
// if (TextUtils.isEmpty(getFcmToken(activity))) {
|
|
||||||
// 'app should always check the device for a compatible Google Play services APK before accessing Google Play services features'
|
// 'app should always check the device for a compatible Google Play services APK before accessing Google Play services features'
|
||||||
if (checkPlayServices(activity)) {
|
if (checkPlayServices(context)) {
|
||||||
try {
|
try {
|
||||||
FirebaseMessaging.getInstance().token
|
FirebaseMessaging.getInstance().token
|
||||||
.addOnSuccessListener { token ->
|
.addOnSuccessListener { token ->
|
||||||
|
@ -75,7 +74,7 @@ class GoogleFcmHelper @Inject constructor(
|
||||||
Timber.e(e, "## ensureFcmTokenIsRetrieved() : failed")
|
Timber.e(e, "## ensureFcmTokenIsRetrieved() : failed")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(activity, R.string.no_valid_google_play_services_apk, Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, R.string.no_valid_google_play_services_apk, Toast.LENGTH_SHORT).show()
|
||||||
Timber.e("No valid Google Play Services found. Cannot use FCM.")
|
Timber.e("No valid Google Play Services found. Cannot use FCM.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ package im.vector.app.core.di
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import im.vector.app.ActiveSessionDataSource
|
import im.vector.app.ActiveSessionDataSource
|
||||||
import im.vector.app.core.extensions.startSyncing
|
import im.vector.app.core.extensions.startSyncing
|
||||||
import im.vector.app.core.pushers.UnifiedPushHelper
|
import im.vector.app.core.pushers.UnregisterUnifiedPushUseCase
|
||||||
import im.vector.app.core.services.GuardServiceStarter
|
import im.vector.app.core.services.GuardServiceStarter
|
||||||
import im.vector.app.core.session.ConfigureAndStartSessionUseCase
|
import im.vector.app.core.session.ConfigureAndStartSessionUseCase
|
||||||
import im.vector.app.features.call.webrtc.WebRtcCallManager
|
import im.vector.app.features.call.webrtc.WebRtcCallManager
|
||||||
|
@ -46,12 +46,12 @@ class ActiveSessionHolder @Inject constructor(
|
||||||
private val pushRuleTriggerListener: PushRuleTriggerListener,
|
private val pushRuleTriggerListener: PushRuleTriggerListener,
|
||||||
private val sessionListener: SessionListener,
|
private val sessionListener: SessionListener,
|
||||||
private val imageManager: ImageManager,
|
private val imageManager: ImageManager,
|
||||||
private val unifiedPushHelper: UnifiedPushHelper,
|
|
||||||
private val guardServiceStarter: GuardServiceStarter,
|
private val guardServiceStarter: GuardServiceStarter,
|
||||||
private val sessionInitializer: SessionInitializer,
|
private val sessionInitializer: SessionInitializer,
|
||||||
private val applicationContext: Context,
|
private val applicationContext: Context,
|
||||||
private val authenticationService: AuthenticationService,
|
private val authenticationService: AuthenticationService,
|
||||||
private val configureAndStartSessionUseCase: ConfigureAndStartSessionUseCase,
|
private val configureAndStartSessionUseCase: ConfigureAndStartSessionUseCase,
|
||||||
|
private val unregisterUnifiedPushUseCase: UnregisterUnifiedPushUseCase,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
private var activeSessionReference: AtomicReference<Session?> = AtomicReference()
|
private var activeSessionReference: AtomicReference<Session?> = AtomicReference()
|
||||||
|
@ -85,7 +85,7 @@ class ActiveSessionHolder @Inject constructor(
|
||||||
incomingVerificationRequestHandler.stop()
|
incomingVerificationRequestHandler.stop()
|
||||||
pushRuleTriggerListener.stop()
|
pushRuleTriggerListener.stop()
|
||||||
// No need to unregister the pusher, the sign out will (should?) do it server side.
|
// No need to unregister the pusher, the sign out will (should?) do it server side.
|
||||||
unifiedPushHelper.unregister(pushersManager = null)
|
unregisterUnifiedPushUseCase.execute(pushersManager = null)
|
||||||
guardServiceStarter.stop()
|
guardServiceStarter.stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,6 +105,7 @@ import im.vector.app.features.settings.ignored.IgnoredUsersViewModel
|
||||||
import im.vector.app.features.settings.labs.VectorSettingsLabsViewModel
|
import im.vector.app.features.settings.labs.VectorSettingsLabsViewModel
|
||||||
import im.vector.app.features.settings.legals.LegalsViewModel
|
import im.vector.app.features.settings.legals.LegalsViewModel
|
||||||
import im.vector.app.features.settings.locale.LocalePickerViewModel
|
import im.vector.app.features.settings.locale.LocalePickerViewModel
|
||||||
|
import im.vector.app.features.settings.notifications.VectorSettingsNotificationPreferenceViewModel
|
||||||
import im.vector.app.features.settings.push.PushGatewaysViewModel
|
import im.vector.app.features.settings.push.PushGatewaysViewModel
|
||||||
import im.vector.app.features.settings.threepids.ThreePidsSettingsViewModel
|
import im.vector.app.features.settings.threepids.ThreePidsSettingsViewModel
|
||||||
import im.vector.app.features.share.IncomingShareViewModel
|
import im.vector.app.features.share.IncomingShareViewModel
|
||||||
|
@ -683,4 +684,11 @@ interface MavericksViewModelModule {
|
||||||
@IntoMap
|
@IntoMap
|
||||||
@MavericksViewModelKey(AttachmentTypeSelectorViewModel::class)
|
@MavericksViewModelKey(AttachmentTypeSelectorViewModel::class)
|
||||||
fun attachmentTypeSelectorViewModelFactory(factory: AttachmentTypeSelectorViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
|
fun attachmentTypeSelectorViewModelFactory(factory: AttachmentTypeSelectorViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoMap
|
||||||
|
@MavericksViewModelKey(VectorSettingsNotificationPreferenceViewModel::class)
|
||||||
|
fun vectorSettingsNotificationPreferenceViewModelFactory(
|
||||||
|
factory: VectorSettingsNotificationPreferenceViewModel.Factory
|
||||||
|
): MavericksAssistedViewModelFactory<*, *>
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.app.core.pushers
|
||||||
|
|
||||||
|
import im.vector.app.core.di.ActiveSessionHolder
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class EnsureFcmTokenIsRetrievedUseCase @Inject constructor(
|
||||||
|
private val unifiedPushHelper: UnifiedPushHelper,
|
||||||
|
private val fcmHelper: FcmHelper,
|
||||||
|
private val activeSessionHolder: ActiveSessionHolder,
|
||||||
|
) {
|
||||||
|
|
||||||
|
fun execute(pushersManager: PushersManager, registerPusher: Boolean) {
|
||||||
|
if (unifiedPushHelper.isEmbeddedDistributor()) {
|
||||||
|
fcmHelper.ensureFcmTokenIsRetrieved(pushersManager, shouldAddHttpPusher(registerPusher))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun shouldAddHttpPusher(registerPusher: Boolean) = if (registerPusher) {
|
||||||
|
val currentSession = activeSessionHolder.getActiveSession()
|
||||||
|
val currentPushers = currentSession.pushersService().getPushers()
|
||||||
|
currentPushers.none { it.deviceId == currentSession.sessionParams.deviceId }
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
package im.vector.app.core.pushers
|
package im.vector.app.core.pushers
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import im.vector.app.core.di.ActiveSessionHolder
|
import im.vector.app.core.di.ActiveSessionHolder
|
||||||
|
|
||||||
interface FcmHelper {
|
interface FcmHelper {
|
||||||
|
@ -39,11 +38,10 @@ interface FcmHelper {
|
||||||
/**
|
/**
|
||||||
* onNewToken may not be called on application upgrade, so ensure my shared pref is set.
|
* onNewToken may not be called on application upgrade, so ensure my shared pref is set.
|
||||||
*
|
*
|
||||||
* @param activity the first launch Activity.
|
|
||||||
* @param pushersManager the instance to register the pusher on.
|
* @param pushersManager the instance to register the pusher on.
|
||||||
* @param registerPusher whether the pusher should be registered.
|
* @param registerPusher whether the pusher should be registered.
|
||||||
*/
|
*/
|
||||||
fun ensureFcmTokenIsRetrieved(activity: Activity, pushersManager: PushersManager, registerPusher: Boolean)
|
fun ensureFcmTokenIsRetrieved(pushersManager: PushersManager, registerPusher: Boolean)
|
||||||
|
|
||||||
fun onEnterForeground(activeSessionHolder: ActiveSessionHolder)
|
fun onEnterForeground(activeSessionHolder: ActiveSessionHolder)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.app.core.pushers
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
|
import im.vector.app.features.VectorFeatures
|
||||||
|
import org.unifiedpush.android.connector.UnifiedPush
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class RegisterUnifiedPushUseCase @Inject constructor(
|
||||||
|
@ApplicationContext private val context: Context,
|
||||||
|
private val vectorFeatures: VectorFeatures,
|
||||||
|
) {
|
||||||
|
|
||||||
|
sealed interface RegisterUnifiedPushResult {
|
||||||
|
object Success : RegisterUnifiedPushResult
|
||||||
|
object NeedToAskUserForDistributor : RegisterUnifiedPushResult
|
||||||
|
}
|
||||||
|
|
||||||
|
fun execute(distributor: String = ""): RegisterUnifiedPushResult {
|
||||||
|
if (distributor.isNotEmpty()) {
|
||||||
|
saveAndRegisterApp(distributor)
|
||||||
|
return RegisterUnifiedPushResult.Success
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!vectorFeatures.allowExternalUnifiedPushDistributors()) {
|
||||||
|
saveAndRegisterApp(context.packageName)
|
||||||
|
return RegisterUnifiedPushResult.Success
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UnifiedPush.getDistributor(context).isNotEmpty()) {
|
||||||
|
registerApp()
|
||||||
|
return RegisterUnifiedPushResult.Success
|
||||||
|
}
|
||||||
|
|
||||||
|
val distributors = UnifiedPush.getDistributors(context)
|
||||||
|
|
||||||
|
return if (distributors.size == 1) {
|
||||||
|
saveAndRegisterApp(distributors.first())
|
||||||
|
RegisterUnifiedPushResult.Success
|
||||||
|
} else {
|
||||||
|
RegisterUnifiedPushResult.NeedToAskUserForDistributor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun saveAndRegisterApp(distributor: String) {
|
||||||
|
UnifiedPush.saveDistributor(context, distributor)
|
||||||
|
registerApp()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun registerApp() {
|
||||||
|
UnifiedPush.registerApp(context)
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,18 +17,13 @@
|
||||||
package im.vector.app.core.pushers
|
package im.vector.app.core.pushers
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.fragment.app.FragmentActivity
|
import androidx.annotation.MainThread
|
||||||
import androidx.lifecycle.lifecycleScope
|
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import com.squareup.moshi.Json
|
import com.squareup.moshi.Json
|
||||||
import com.squareup.moshi.JsonClass
|
import com.squareup.moshi.JsonClass
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.resources.StringProvider
|
import im.vector.app.core.resources.StringProvider
|
||||||
import im.vector.app.core.utils.getApplicationLabel
|
import im.vector.app.core.utils.getApplicationLabel
|
||||||
import im.vector.app.features.VectorFeatures
|
|
||||||
import im.vector.app.features.settings.BackgroundSyncMode
|
|
||||||
import im.vector.app.features.settings.VectorPreferences
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import org.matrix.android.sdk.api.Matrix
|
import org.matrix.android.sdk.api.Matrix
|
||||||
import org.matrix.android.sdk.api.cache.CacheStrategy
|
import org.matrix.android.sdk.api.cache.CacheStrategy
|
||||||
import org.matrix.android.sdk.api.util.MatrixJsonParser
|
import org.matrix.android.sdk.api.util.MatrixJsonParser
|
||||||
|
@ -41,90 +36,14 @@ class UnifiedPushHelper @Inject constructor(
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
private val unifiedPushStore: UnifiedPushStore,
|
private val unifiedPushStore: UnifiedPushStore,
|
||||||
private val stringProvider: StringProvider,
|
private val stringProvider: StringProvider,
|
||||||
private val vectorPreferences: VectorPreferences,
|
|
||||||
private val matrix: Matrix,
|
private val matrix: Matrix,
|
||||||
private val vectorFeatures: VectorFeatures,
|
|
||||||
private val fcmHelper: FcmHelper,
|
private val fcmHelper: FcmHelper,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
// Called when the home activity starts
|
@MainThread
|
||||||
// or when notifications are enabled
|
fun showSelectDistributorDialog(
|
||||||
fun register(
|
context: Context,
|
||||||
activity: FragmentActivity,
|
onDistributorSelected: (String) -> Unit,
|
||||||
onDoneRunnable: Runnable? = null,
|
|
||||||
) {
|
|
||||||
registerInternal(
|
|
||||||
activity,
|
|
||||||
onDoneRunnable = onDoneRunnable
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// If registration is forced:
|
|
||||||
// * the current distributor (if any) is removed
|
|
||||||
// * The dialog is opened
|
|
||||||
//
|
|
||||||
// The registration is forced in 2 cases :
|
|
||||||
// * in the settings
|
|
||||||
// * in the troubleshoot list (doFix)
|
|
||||||
fun forceRegister(
|
|
||||||
activity: FragmentActivity,
|
|
||||||
pushersManager: PushersManager,
|
|
||||||
onDoneRunnable: Runnable? = null
|
|
||||||
) {
|
|
||||||
registerInternal(
|
|
||||||
activity,
|
|
||||||
force = true,
|
|
||||||
pushersManager = pushersManager,
|
|
||||||
onDoneRunnable = onDoneRunnable
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun registerInternal(
|
|
||||||
activity: FragmentActivity,
|
|
||||||
force: Boolean = false,
|
|
||||||
pushersManager: PushersManager? = null,
|
|
||||||
onDoneRunnable: Runnable? = null
|
|
||||||
) {
|
|
||||||
activity.lifecycleScope.launch {
|
|
||||||
if (!vectorFeatures.allowExternalUnifiedPushDistributors()) {
|
|
||||||
UnifiedPush.saveDistributor(context, context.packageName)
|
|
||||||
UnifiedPush.registerApp(context)
|
|
||||||
onDoneRunnable?.run()
|
|
||||||
return@launch
|
|
||||||
}
|
|
||||||
if (force) {
|
|
||||||
// Un-register first
|
|
||||||
unregister(pushersManager)
|
|
||||||
}
|
|
||||||
// the !force should not be needed
|
|
||||||
if (!force && UnifiedPush.getDistributor(context).isNotEmpty()) {
|
|
||||||
UnifiedPush.registerApp(context)
|
|
||||||
onDoneRunnable?.run()
|
|
||||||
return@launch
|
|
||||||
}
|
|
||||||
|
|
||||||
val distributors = UnifiedPush.getDistributors(context)
|
|
||||||
|
|
||||||
if (!force && distributors.size == 1) {
|
|
||||||
UnifiedPush.saveDistributor(context, distributors.first())
|
|
||||||
UnifiedPush.registerApp(context)
|
|
||||||
onDoneRunnable?.run()
|
|
||||||
} else {
|
|
||||||
openDistributorDialogInternal(
|
|
||||||
activity = activity,
|
|
||||||
onDoneRunnable = onDoneRunnable,
|
|
||||||
distributors = distributors
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// There is no case where this function is called
|
|
||||||
// with a saved distributor and/or a pusher
|
|
||||||
private fun openDistributorDialogInternal(
|
|
||||||
activity: FragmentActivity,
|
|
||||||
onDoneRunnable: Runnable?,
|
|
||||||
distributors: List<String>
|
|
||||||
) {
|
) {
|
||||||
val internalDistributorName = stringProvider.getString(
|
val internalDistributorName = stringProvider.getString(
|
||||||
if (fcmHelper.isFirebaseAvailable()) {
|
if (fcmHelper.isFirebaseAvailable()) {
|
||||||
|
@ -134,6 +53,7 @@ class UnifiedPushHelper @Inject constructor(
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val distributors = UnifiedPush.getDistributors(context)
|
||||||
val distributorsName = distributors.map {
|
val distributorsName = distributors.map {
|
||||||
if (it == context.packageName) {
|
if (it == context.packageName) {
|
||||||
internalDistributorName
|
internalDistributorName
|
||||||
|
@ -142,44 +62,23 @@ class UnifiedPushHelper @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MaterialAlertDialogBuilder(activity)
|
MaterialAlertDialogBuilder(context)
|
||||||
.setTitle(stringProvider.getString(R.string.unifiedpush_getdistributors_dialog_title))
|
.setTitle(stringProvider.getString(R.string.unifiedpush_getdistributors_dialog_title))
|
||||||
.setItems(distributorsName.toTypedArray()) { _, which ->
|
.setItems(distributorsName.toTypedArray()) { _, which ->
|
||||||
val distributor = distributors[which]
|
val distributor = distributors[which]
|
||||||
|
onDistributorSelected(distributor)
|
||||||
activity.lifecycleScope.launch {
|
|
||||||
UnifiedPush.saveDistributor(context, distributor)
|
|
||||||
Timber.i("Saving distributor: $distributor")
|
|
||||||
UnifiedPush.registerApp(context)
|
|
||||||
onDoneRunnable?.run()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.setOnCancelListener {
|
.setOnCancelListener {
|
||||||
// By default, use internal solution (fcm/background sync)
|
// we do not want to change the distributor on behalf of the user
|
||||||
UnifiedPush.saveDistributor(context, context.packageName)
|
if (UnifiedPush.getDistributor(context).isEmpty()) {
|
||||||
UnifiedPush.registerApp(context)
|
// By default, use internal solution (fcm/background sync)
|
||||||
onDoneRunnable?.run()
|
onDistributorSelected(context.packageName)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.setCancelable(true)
|
.setCancelable(true)
|
||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun unregister(pushersManager: PushersManager? = null) {
|
|
||||||
val mode = BackgroundSyncMode.FDROID_BACKGROUND_SYNC_MODE_FOR_REALTIME
|
|
||||||
vectorPreferences.setFdroidSyncBackgroundMode(mode)
|
|
||||||
try {
|
|
||||||
getEndpointOrToken()?.let {
|
|
||||||
Timber.d("Removing $it")
|
|
||||||
pushersManager?.unregisterPusher(it)
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Timber.d(e, "Probably unregistering a non existing pusher")
|
|
||||||
}
|
|
||||||
unifiedPushStore.storeUpEndpoint(null)
|
|
||||||
unifiedPushStore.storePushGateway(null)
|
|
||||||
UnifiedPush.unregisterApp(context)
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsonClass(generateAdapter = true)
|
@JsonClass(generateAdapter = true)
|
||||||
internal data class DiscoveryResponse(
|
internal data class DiscoveryResponse(
|
||||||
@Json(name = "unifiedpush") val unifiedpush: DiscoveryUnifiedPush = DiscoveryUnifiedPush()
|
@Json(name = "unifiedpush") val unifiedpush: DiscoveryUnifiedPush = DiscoveryUnifiedPush()
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.app.core.pushers
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
|
import im.vector.app.features.settings.BackgroundSyncMode
|
||||||
|
import im.vector.app.features.settings.VectorPreferences
|
||||||
|
import org.unifiedpush.android.connector.UnifiedPush
|
||||||
|
import timber.log.Timber
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class UnregisterUnifiedPushUseCase @Inject constructor(
|
||||||
|
@ApplicationContext private val context: Context,
|
||||||
|
private val vectorPreferences: VectorPreferences,
|
||||||
|
private val unifiedPushStore: UnifiedPushStore,
|
||||||
|
private val unifiedPushHelper: UnifiedPushHelper,
|
||||||
|
) {
|
||||||
|
|
||||||
|
suspend fun execute(pushersManager: PushersManager?) {
|
||||||
|
val mode = BackgroundSyncMode.FDROID_BACKGROUND_SYNC_MODE_FOR_REALTIME
|
||||||
|
vectorPreferences.setFdroidSyncBackgroundMode(mode)
|
||||||
|
try {
|
||||||
|
unifiedPushHelper.getEndpointOrToken()?.let {
|
||||||
|
Timber.d("Removing $it")
|
||||||
|
pushersManager?.unregisterPusher(it)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Timber.d(e, "Probably unregistering a non existing pusher")
|
||||||
|
}
|
||||||
|
unifiedPushStore.storeUpEndpoint(null)
|
||||||
|
unifiedPushStore.storePushGateway(null)
|
||||||
|
UnifiedPush.unregisterApp(context)
|
||||||
|
}
|
||||||
|
}
|
|
@ -44,8 +44,6 @@ import im.vector.app.core.extensions.restart
|
||||||
import im.vector.app.core.extensions.validateBackPressed
|
import im.vector.app.core.extensions.validateBackPressed
|
||||||
import im.vector.app.core.platform.VectorBaseActivity
|
import im.vector.app.core.platform.VectorBaseActivity
|
||||||
import im.vector.app.core.platform.VectorMenuProvider
|
import im.vector.app.core.platform.VectorMenuProvider
|
||||||
import im.vector.app.core.pushers.FcmHelper
|
|
||||||
import im.vector.app.core.pushers.PushersManager
|
|
||||||
import im.vector.app.core.pushers.UnifiedPushHelper
|
import im.vector.app.core.pushers.UnifiedPushHelper
|
||||||
import im.vector.app.core.utils.registerForPermissionsResult
|
import im.vector.app.core.utils.registerForPermissionsResult
|
||||||
import im.vector.app.core.utils.startSharePlainTextIntent
|
import im.vector.app.core.utils.startSharePlainTextIntent
|
||||||
|
@ -128,7 +126,6 @@ class HomeActivity :
|
||||||
private val serverBackupStatusViewModel: ServerBackupStatusViewModel by viewModel()
|
private val serverBackupStatusViewModel: ServerBackupStatusViewModel by viewModel()
|
||||||
|
|
||||||
@Inject lateinit var vectorUncaughtExceptionHandler: VectorUncaughtExceptionHandler
|
@Inject lateinit var vectorUncaughtExceptionHandler: VectorUncaughtExceptionHandler
|
||||||
@Inject lateinit var pushersManager: PushersManager
|
|
||||||
@Inject lateinit var notificationDrawerManager: NotificationDrawerManager
|
@Inject lateinit var notificationDrawerManager: NotificationDrawerManager
|
||||||
@Inject lateinit var popupAlertManager: PopupAlertManager
|
@Inject lateinit var popupAlertManager: PopupAlertManager
|
||||||
@Inject lateinit var shortcutsHandler: ShortcutsHandler
|
@Inject lateinit var shortcutsHandler: ShortcutsHandler
|
||||||
|
@ -137,7 +134,6 @@ class HomeActivity :
|
||||||
@Inject lateinit var initSyncStepFormatter: InitSyncStepFormatter
|
@Inject lateinit var initSyncStepFormatter: InitSyncStepFormatter
|
||||||
@Inject lateinit var spaceStateHandler: SpaceStateHandler
|
@Inject lateinit var spaceStateHandler: SpaceStateHandler
|
||||||
@Inject lateinit var unifiedPushHelper: UnifiedPushHelper
|
@Inject lateinit var unifiedPushHelper: UnifiedPushHelper
|
||||||
@Inject lateinit var fcmHelper: FcmHelper
|
|
||||||
@Inject lateinit var nightlyProxy: NightlyProxy
|
@Inject lateinit var nightlyProxy: NightlyProxy
|
||||||
@Inject lateinit var disclaimerDialog: DisclaimerDialog
|
@Inject lateinit var disclaimerDialog: DisclaimerDialog
|
||||||
@Inject lateinit var notificationPermissionManager: NotificationPermissionManager
|
@Inject lateinit var notificationPermissionManager: NotificationPermissionManager
|
||||||
|
@ -209,16 +205,6 @@ class HomeActivity :
|
||||||
isNewAppLayoutEnabled = vectorPreferences.isNewAppLayoutEnabled()
|
isNewAppLayoutEnabled = vectorPreferences.isNewAppLayoutEnabled()
|
||||||
analyticsScreenName = MobileScreen.ScreenName.Home
|
analyticsScreenName = MobileScreen.ScreenName.Home
|
||||||
supportFragmentManager.registerFragmentLifecycleCallbacks(fragmentLifecycleCallbacks, false)
|
supportFragmentManager.registerFragmentLifecycleCallbacks(fragmentLifecycleCallbacks, false)
|
||||||
unifiedPushHelper.register(this) {
|
|
||||||
if (unifiedPushHelper.isEmbeddedDistributor()) {
|
|
||||||
fcmHelper.ensureFcmTokenIsRetrieved(
|
|
||||||
this,
|
|
||||||
pushersManager,
|
|
||||||
homeActivityViewModel.shouldAddHttpPusher()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sharedActionViewModel = viewModelProvider[HomeSharedActionViewModel::class.java]
|
sharedActionViewModel = viewModelProvider[HomeSharedActionViewModel::class.java]
|
||||||
roomListSharedActionViewModel = viewModelProvider[RoomListSharedActionViewModel::class.java]
|
roomListSharedActionViewModel = viewModelProvider[RoomListSharedActionViewModel::class.java]
|
||||||
views.drawerLayout.addDrawerListener(drawerListener)
|
views.drawerLayout.addDrawerListener(drawerListener)
|
||||||
|
@ -280,6 +266,7 @@ class HomeActivity :
|
||||||
HomeActivityViewEvents.ShowReleaseNotes -> handleShowReleaseNotes()
|
HomeActivityViewEvents.ShowReleaseNotes -> handleShowReleaseNotes()
|
||||||
HomeActivityViewEvents.NotifyUserForThreadsMigration -> handleNotifyUserForThreadsMigration()
|
HomeActivityViewEvents.NotifyUserForThreadsMigration -> handleNotifyUserForThreadsMigration()
|
||||||
is HomeActivityViewEvents.MigrateThreads -> migrateThreadsIfNeeded(it.checkSession)
|
is HomeActivityViewEvents.MigrateThreads -> migrateThreadsIfNeeded(it.checkSession)
|
||||||
|
is HomeActivityViewEvents.AskUserForPushDistributor -> askUserToSelectPushDistributor()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
homeActivityViewModel.onEach { renderState(it) }
|
homeActivityViewModel.onEach { renderState(it) }
|
||||||
|
@ -292,6 +279,12 @@ class HomeActivity :
|
||||||
homeActivityViewModel.handle(HomeActivityViewActions.ViewStarted)
|
homeActivityViewModel.handle(HomeActivityViewActions.ViewStarted)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun askUserToSelectPushDistributor() {
|
||||||
|
unifiedPushHelper.showSelectDistributorDialog(this) { selection ->
|
||||||
|
homeActivityViewModel.handle(HomeActivityViewActions.RegisterPushDistributor(selection))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun handleShowNotificationDialog() {
|
private fun handleShowNotificationDialog() {
|
||||||
notificationPermissionManager.eventuallyRequestPermission(this, postPermissionLauncher)
|
notificationPermissionManager.eventuallyRequestPermission(this, postPermissionLauncher)
|
||||||
}
|
}
|
||||||
|
@ -415,14 +408,6 @@ class HomeActivity :
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun renderState(state: HomeActivityViewState) {
|
private fun renderState(state: HomeActivityViewState) {
|
||||||
lifecycleScope.launch {
|
|
||||||
if (state.areNotificationsSilenced) {
|
|
||||||
unifiedPushHelper.unregister(pushersManager)
|
|
||||||
} else {
|
|
||||||
unifiedPushHelper.register(this@HomeActivity)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
when (val status = state.syncRequestState) {
|
when (val status = state.syncRequestState) {
|
||||||
is SyncRequestState.InitialSyncProgressing -> {
|
is SyncRequestState.InitialSyncProgressing -> {
|
||||||
val initSyncStepStr = initSyncStepFormatter.format(status.initialSyncStep)
|
val initSyncStepStr = initSyncStepFormatter.format(status.initialSyncStep)
|
||||||
|
|
|
@ -21,4 +21,5 @@ import im.vector.app.core.platform.VectorViewModelAction
|
||||||
sealed interface HomeActivityViewActions : VectorViewModelAction {
|
sealed interface HomeActivityViewActions : VectorViewModelAction {
|
||||||
object ViewStarted : HomeActivityViewActions
|
object ViewStarted : HomeActivityViewActions
|
||||||
object PushPromptHasBeenReviewed : HomeActivityViewActions
|
object PushPromptHasBeenReviewed : HomeActivityViewActions
|
||||||
|
data class RegisterPushDistributor(val distributor: String) : HomeActivityViewActions
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,9 +25,11 @@ sealed interface HomeActivityViewEvents : VectorViewEvents {
|
||||||
val userItem: MatrixItem.UserItem,
|
val userItem: MatrixItem.UserItem,
|
||||||
val waitForIncomingRequest: Boolean = true,
|
val waitForIncomingRequest: Boolean = true,
|
||||||
) : HomeActivityViewEvents
|
) : HomeActivityViewEvents
|
||||||
|
|
||||||
data class CurrentSessionCannotBeVerified(
|
data class CurrentSessionCannotBeVerified(
|
||||||
val userItem: MatrixItem.UserItem,
|
val userItem: MatrixItem.UserItem,
|
||||||
) : HomeActivityViewEvents
|
) : HomeActivityViewEvents
|
||||||
|
|
||||||
data class OnCrossSignedInvalidated(val userItem: MatrixItem.UserItem) : HomeActivityViewEvents
|
data class OnCrossSignedInvalidated(val userItem: MatrixItem.UserItem) : HomeActivityViewEvents
|
||||||
object PromptToEnableSessionPush : HomeActivityViewEvents
|
object PromptToEnableSessionPush : HomeActivityViewEvents
|
||||||
object ShowAnalyticsOptIn : HomeActivityViewEvents
|
object ShowAnalyticsOptIn : HomeActivityViewEvents
|
||||||
|
@ -37,4 +39,5 @@ sealed interface HomeActivityViewEvents : VectorViewEvents {
|
||||||
data class MigrateThreads(val checkSession: Boolean) : HomeActivityViewEvents
|
data class MigrateThreads(val checkSession: Boolean) : HomeActivityViewEvents
|
||||||
object StartRecoverySetupFlow : HomeActivityViewEvents
|
object StartRecoverySetupFlow : HomeActivityViewEvents
|
||||||
data class ForceVerification(val sendRequest: Boolean) : HomeActivityViewEvents
|
data class ForceVerification(val sendRequest: Boolean) : HomeActivityViewEvents
|
||||||
|
object AskUserForPushDistributor : HomeActivityViewEvents
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
package im.vector.app.features.home
|
package im.vector.app.features.home
|
||||||
|
|
||||||
import androidx.lifecycle.asFlow
|
|
||||||
import com.airbnb.mvrx.Mavericks
|
import com.airbnb.mvrx.Mavericks
|
||||||
import com.airbnb.mvrx.MavericksViewModelFactory
|
import com.airbnb.mvrx.MavericksViewModelFactory
|
||||||
import com.airbnb.mvrx.ViewModelContext
|
import com.airbnb.mvrx.ViewModelContext
|
||||||
|
@ -27,7 +26,9 @@ import im.vector.app.core.di.ActiveSessionHolder
|
||||||
import im.vector.app.core.di.MavericksAssistedViewModelFactory
|
import im.vector.app.core.di.MavericksAssistedViewModelFactory
|
||||||
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
||||||
import im.vector.app.core.platform.VectorViewModel
|
import im.vector.app.core.platform.VectorViewModel
|
||||||
import im.vector.app.features.VectorFeatures
|
import im.vector.app.core.pushers.EnsureFcmTokenIsRetrievedUseCase
|
||||||
|
import im.vector.app.core.pushers.PushersManager
|
||||||
|
import im.vector.app.core.pushers.RegisterUnifiedPushUseCase
|
||||||
import im.vector.app.features.analytics.AnalyticsConfig
|
import im.vector.app.features.analytics.AnalyticsConfig
|
||||||
import im.vector.app.features.analytics.AnalyticsTracker
|
import im.vector.app.features.analytics.AnalyticsTracker
|
||||||
import im.vector.app.features.analytics.extensions.toAnalyticsType
|
import im.vector.app.features.analytics.extensions.toAnalyticsType
|
||||||
|
@ -48,12 +49,10 @@ import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.flow.collect
|
import kotlinx.coroutines.flow.collect
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.map
|
|
||||||
import kotlinx.coroutines.flow.onCompletion
|
import kotlinx.coroutines.flow.onCompletion
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import kotlinx.coroutines.flow.takeWhile
|
import kotlinx.coroutines.flow.takeWhile
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.matrix.android.sdk.api.account.LocalNotificationSettingsContent
|
|
||||||
import org.matrix.android.sdk.api.auth.UIABaseAuth
|
import org.matrix.android.sdk.api.auth.UIABaseAuth
|
||||||
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
|
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
|
||||||
import org.matrix.android.sdk.api.auth.UserPasswordAuth
|
import org.matrix.android.sdk.api.auth.UserPasswordAuth
|
||||||
|
@ -62,11 +61,9 @@ import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse
|
||||||
import org.matrix.android.sdk.api.auth.registration.nextUncompletedStage
|
import org.matrix.android.sdk.api.auth.registration.nextUncompletedStage
|
||||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||||
import org.matrix.android.sdk.api.raw.RawService
|
import org.matrix.android.sdk.api.raw.RawService
|
||||||
import org.matrix.android.sdk.api.session.accountdata.UserAccountDataTypes
|
|
||||||
import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningService
|
import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningService
|
||||||
import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo
|
import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo
|
||||||
import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap
|
import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap
|
||||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
|
||||||
import org.matrix.android.sdk.api.session.getUserOrDefault
|
import org.matrix.android.sdk.api.session.getUserOrDefault
|
||||||
import org.matrix.android.sdk.api.session.pushrules.RuleIds
|
import org.matrix.android.sdk.api.session.pushrules.RuleIds
|
||||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||||
|
@ -92,8 +89,10 @@ class HomeActivityViewModel @AssistedInject constructor(
|
||||||
private val analyticsTracker: AnalyticsTracker,
|
private val analyticsTracker: AnalyticsTracker,
|
||||||
private val analyticsConfig: AnalyticsConfig,
|
private val analyticsConfig: AnalyticsConfig,
|
||||||
private val releaseNotesPreferencesStore: ReleaseNotesPreferencesStore,
|
private val releaseNotesPreferencesStore: ReleaseNotesPreferencesStore,
|
||||||
private val vectorFeatures: VectorFeatures,
|
|
||||||
private val stopOngoingVoiceBroadcastUseCase: StopOngoingVoiceBroadcastUseCase,
|
private val stopOngoingVoiceBroadcastUseCase: StopOngoingVoiceBroadcastUseCase,
|
||||||
|
private val pushersManager: PushersManager,
|
||||||
|
private val registerUnifiedPushUseCase: RegisterUnifiedPushUseCase,
|
||||||
|
private val ensureFcmTokenIsRetrievedUseCase: EnsureFcmTokenIsRetrievedUseCase,
|
||||||
) : VectorViewModel<HomeActivityViewState, HomeActivityViewActions, HomeActivityViewEvents>(initialState) {
|
) : VectorViewModel<HomeActivityViewState, HomeActivityViewActions, HomeActivityViewEvents>(initialState) {
|
||||||
|
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
|
@ -117,17 +116,36 @@ class HomeActivityViewModel @AssistedInject constructor(
|
||||||
private fun initialize() {
|
private fun initialize() {
|
||||||
if (isInitialized) return
|
if (isInitialized) return
|
||||||
isInitialized = true
|
isInitialized = true
|
||||||
|
registerUnifiedPushIfNeeded()
|
||||||
cleanupFiles()
|
cleanupFiles()
|
||||||
observeInitialSync()
|
observeInitialSync()
|
||||||
checkSessionPushIsOn()
|
checkSessionPushIsOn()
|
||||||
observeCrossSigningReset()
|
observeCrossSigningReset()
|
||||||
observeAnalytics()
|
observeAnalytics()
|
||||||
observeReleaseNotes()
|
observeReleaseNotes()
|
||||||
observeLocalNotificationsSilenced()
|
|
||||||
initThreadsMigration()
|
initThreadsMigration()
|
||||||
viewModelScope.launch { stopOngoingVoiceBroadcastUseCase.execute() }
|
viewModelScope.launch { stopOngoingVoiceBroadcastUseCase.execute() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun registerUnifiedPushIfNeeded() {
|
||||||
|
if (vectorPreferences.areNotificationEnabledForDevice()) {
|
||||||
|
registerUnifiedPush(distributor = "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun registerUnifiedPush(distributor: String) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
when (registerUnifiedPushUseCase.execute(distributor = distributor)) {
|
||||||
|
is RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.NeedToAskUserForDistributor -> {
|
||||||
|
_viewEvents.post(HomeActivityViewEvents.AskUserForPushDistributor)
|
||||||
|
}
|
||||||
|
RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.Success -> {
|
||||||
|
ensureFcmTokenIsRetrievedUseCase.execute(pushersManager, registerPusher = vectorPreferences.areNotificationEnabledForDevice())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun observeReleaseNotes() = withState { state ->
|
private fun observeReleaseNotes() = withState { state ->
|
||||||
if (vectorPreferences.isNewAppLayoutEnabled()) {
|
if (vectorPreferences.isNewAppLayoutEnabled()) {
|
||||||
// we don't want to show release notes for new users or after relogin
|
// we don't want to show release notes for new users or after relogin
|
||||||
|
@ -146,26 +164,6 @@ class HomeActivityViewModel @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun shouldAddHttpPusher() = if (vectorPreferences.areNotificationEnabledForDevice()) {
|
|
||||||
val currentSession = activeSessionHolder.getActiveSession()
|
|
||||||
val currentPushers = currentSession.pushersService().getPushers()
|
|
||||||
currentPushers.none { it.deviceId == currentSession.sessionParams.deviceId }
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fun observeLocalNotificationsSilenced() {
|
|
||||||
val currentSession = activeSessionHolder.getActiveSession()
|
|
||||||
val deviceId = currentSession.cryptoService().getMyDevice().deviceId
|
|
||||||
viewModelScope.launch {
|
|
||||||
currentSession.accountDataService()
|
|
||||||
.getLiveUserAccountDataEvent(UserAccountDataTypes.TYPE_LOCAL_NOTIFICATION_SETTINGS + deviceId)
|
|
||||||
.asFlow()
|
|
||||||
.map { it.getOrNull()?.content?.toModel<LocalNotificationSettingsContent>()?.isSilenced ?: false }
|
|
||||||
.onEach { setState { copy(areNotificationsSilenced = it) } }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun observeAnalytics() {
|
private fun observeAnalytics() {
|
||||||
if (analyticsConfig.isEnabled) {
|
if (analyticsConfig.isEnabled) {
|
||||||
analyticsStore.didAskUserConsentFlow
|
analyticsStore.didAskUserConsentFlow
|
||||||
|
@ -501,6 +499,9 @@ class HomeActivityViewModel @AssistedInject constructor(
|
||||||
HomeActivityViewActions.ViewStarted -> {
|
HomeActivityViewActions.ViewStarted -> {
|
||||||
initialize()
|
initialize()
|
||||||
}
|
}
|
||||||
|
is HomeActivityViewActions.RegisterPushDistributor -> {
|
||||||
|
registerUnifiedPush(distributor = action.distributor)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,5 +23,4 @@ import org.matrix.android.sdk.api.session.sync.SyncRequestState
|
||||||
data class HomeActivityViewState(
|
data class HomeActivityViewState(
|
||||||
val syncRequestState: SyncRequestState = SyncRequestState.Idle,
|
val syncRequestState: SyncRequestState = SyncRequestState.Idle,
|
||||||
val authenticationDescription: AuthenticationDescription? = null,
|
val authenticationDescription: AuthenticationDescription? = null,
|
||||||
val areNotificationsSilenced: Boolean = false,
|
|
||||||
) : MavericksState
|
) : MavericksState
|
||||||
|
|
|
@ -28,6 +28,8 @@ import im.vector.app.R
|
||||||
import im.vector.app.core.error.ErrorFormatter
|
import im.vector.app.core.error.ErrorFormatter
|
||||||
import im.vector.app.core.extensions.singletonEntryPoint
|
import im.vector.app.core.extensions.singletonEntryPoint
|
||||||
import im.vector.app.core.platform.VectorBaseActivity
|
import im.vector.app.core.platform.VectorBaseActivity
|
||||||
|
import im.vector.app.core.platform.VectorViewEvents
|
||||||
|
import im.vector.app.core.platform.VectorViewModel
|
||||||
import im.vector.app.core.utils.toast
|
import im.vector.app.core.utils.toast
|
||||||
import im.vector.app.features.analytics.AnalyticsTracker
|
import im.vector.app.features.analytics.AnalyticsTracker
|
||||||
import im.vector.app.features.analytics.plan.MobileScreen
|
import im.vector.app.features.analytics.plan.MobileScreen
|
||||||
|
@ -60,6 +62,19 @@ abstract class VectorSettingsBaseFragment : PreferenceFragmentCompat(), Maverick
|
||||||
protected lateinit var session: Session
|
protected lateinit var session: Session
|
||||||
protected lateinit var errorFormatter: ErrorFormatter
|
protected lateinit var errorFormatter: ErrorFormatter
|
||||||
|
|
||||||
|
/* ==========================================================================================
|
||||||
|
* ViewEvents
|
||||||
|
* ========================================================================================== */
|
||||||
|
|
||||||
|
protected fun <T : VectorViewEvents> VectorViewModel<*, *, T>.observeViewEvents(observer: (T) -> Unit) {
|
||||||
|
viewEvents
|
||||||
|
.stream()
|
||||||
|
.onEach {
|
||||||
|
observer(it)
|
||||||
|
}
|
||||||
|
.launchIn(viewLifecycleOwner.lifecycleScope)
|
||||||
|
}
|
||||||
|
|
||||||
/* ==========================================================================================
|
/* ==========================================================================================
|
||||||
* Views
|
* Views
|
||||||
* ========================================================================================== */
|
* ========================================================================================== */
|
||||||
|
@ -148,7 +163,7 @@ abstract class VectorSettingsBaseFragment : PreferenceFragmentCompat(), Maverick
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun displayErrorDialog(throwable: Throwable) {
|
protected fun displayErrorDialog(throwable: Throwable?) {
|
||||||
displayErrorDialog(errorFormatter.toHumanReadable(throwable))
|
displayErrorDialog(errorFormatter.toHumanReadable(throwable))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,17 +18,17 @@ package im.vector.app.features.settings.notifications
|
||||||
|
|
||||||
import im.vector.app.core.di.ActiveSessionHolder
|
import im.vector.app.core.di.ActiveSessionHolder
|
||||||
import im.vector.app.core.pushers.PushersManager
|
import im.vector.app.core.pushers.PushersManager
|
||||||
import im.vector.app.core.pushers.UnifiedPushHelper
|
import im.vector.app.core.pushers.UnregisterUnifiedPushUseCase
|
||||||
import im.vector.app.features.settings.devices.v2.notification.CheckIfCanTogglePushNotificationsViaPusherUseCase
|
import im.vector.app.features.settings.devices.v2.notification.CheckIfCanTogglePushNotificationsViaPusherUseCase
|
||||||
import im.vector.app.features.settings.devices.v2.notification.TogglePushNotificationUseCase
|
import im.vector.app.features.settings.devices.v2.notification.TogglePushNotificationUseCase
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class DisableNotificationsForCurrentSessionUseCase @Inject constructor(
|
class DisableNotificationsForCurrentSessionUseCase @Inject constructor(
|
||||||
private val activeSessionHolder: ActiveSessionHolder,
|
private val activeSessionHolder: ActiveSessionHolder,
|
||||||
private val unifiedPushHelper: UnifiedPushHelper,
|
|
||||||
private val pushersManager: PushersManager,
|
private val pushersManager: PushersManager,
|
||||||
private val checkIfCanTogglePushNotificationsViaPusherUseCase: CheckIfCanTogglePushNotificationsViaPusherUseCase,
|
private val checkIfCanTogglePushNotificationsViaPusherUseCase: CheckIfCanTogglePushNotificationsViaPusherUseCase,
|
||||||
private val togglePushNotificationUseCase: TogglePushNotificationUseCase,
|
private val togglePushNotificationUseCase: TogglePushNotificationUseCase,
|
||||||
|
private val unregisterUnifiedPushUseCase: UnregisterUnifiedPushUseCase,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
suspend fun execute() {
|
suspend fun execute() {
|
||||||
|
@ -37,7 +37,7 @@ class DisableNotificationsForCurrentSessionUseCase @Inject constructor(
|
||||||
if (checkIfCanTogglePushNotificationsViaPusherUseCase.execute(session)) {
|
if (checkIfCanTogglePushNotificationsViaPusherUseCase.execute(session)) {
|
||||||
togglePushNotificationUseCase.execute(deviceId, enabled = false)
|
togglePushNotificationUseCase.execute(deviceId, enabled = false)
|
||||||
} else {
|
} else {
|
||||||
unifiedPushHelper.unregister(pushersManager)
|
unregisterUnifiedPushUseCase.execute(pushersManager)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,56 +16,44 @@
|
||||||
|
|
||||||
package im.vector.app.features.settings.notifications
|
package im.vector.app.features.settings.notifications
|
||||||
|
|
||||||
import androidx.fragment.app.FragmentActivity
|
|
||||||
import im.vector.app.core.di.ActiveSessionHolder
|
import im.vector.app.core.di.ActiveSessionHolder
|
||||||
import im.vector.app.core.pushers.FcmHelper
|
import im.vector.app.core.pushers.EnsureFcmTokenIsRetrievedUseCase
|
||||||
import im.vector.app.core.pushers.PushersManager
|
import im.vector.app.core.pushers.PushersManager
|
||||||
import im.vector.app.core.pushers.UnifiedPushHelper
|
import im.vector.app.core.pushers.RegisterUnifiedPushUseCase
|
||||||
import im.vector.app.features.settings.devices.v2.notification.CheckIfCanTogglePushNotificationsViaPusherUseCase
|
|
||||||
import im.vector.app.features.settings.devices.v2.notification.TogglePushNotificationUseCase
|
import im.vector.app.features.settings.devices.v2.notification.TogglePushNotificationUseCase
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlin.coroutines.resume
|
|
||||||
import kotlin.coroutines.resumeWithException
|
|
||||||
import kotlin.coroutines.suspendCoroutine
|
|
||||||
|
|
||||||
class EnableNotificationsForCurrentSessionUseCase @Inject constructor(
|
class EnableNotificationsForCurrentSessionUseCase @Inject constructor(
|
||||||
private val activeSessionHolder: ActiveSessionHolder,
|
private val activeSessionHolder: ActiveSessionHolder,
|
||||||
private val unifiedPushHelper: UnifiedPushHelper,
|
|
||||||
private val pushersManager: PushersManager,
|
private val pushersManager: PushersManager,
|
||||||
private val fcmHelper: FcmHelper,
|
|
||||||
private val checkIfCanTogglePushNotificationsViaPusherUseCase: CheckIfCanTogglePushNotificationsViaPusherUseCase,
|
|
||||||
private val togglePushNotificationUseCase: TogglePushNotificationUseCase,
|
private val togglePushNotificationUseCase: TogglePushNotificationUseCase,
|
||||||
|
private val registerUnifiedPushUseCase: RegisterUnifiedPushUseCase,
|
||||||
|
private val ensureFcmTokenIsRetrievedUseCase: EnsureFcmTokenIsRetrievedUseCase,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
suspend fun execute(fragmentActivity: FragmentActivity) {
|
sealed interface EnableNotificationsResult {
|
||||||
|
object Success : EnableNotificationsResult
|
||||||
|
object Failure : EnableNotificationsResult
|
||||||
|
object NeedToAskUserForDistributor : EnableNotificationsResult
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun execute(distributor: String = ""): EnableNotificationsResult {
|
||||||
val pusherForCurrentSession = pushersManager.getPusherForCurrentSession()
|
val pusherForCurrentSession = pushersManager.getPusherForCurrentSession()
|
||||||
if (pusherForCurrentSession == null) {
|
if (pusherForCurrentSession == null) {
|
||||||
registerPusher(fragmentActivity)
|
when (registerUnifiedPushUseCase.execute(distributor)) {
|
||||||
}
|
is RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.NeedToAskUserForDistributor -> {
|
||||||
|
return EnableNotificationsResult.NeedToAskUserForDistributor
|
||||||
val session = activeSessionHolder.getSafeActiveSession() ?: return
|
}
|
||||||
if (checkIfCanTogglePushNotificationsViaPusherUseCase.execute(session)) {
|
RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.Success -> {
|
||||||
val deviceId = session.sessionParams.deviceId ?: return
|
ensureFcmTokenIsRetrievedUseCase.execute(pushersManager, registerPusher = true)
|
||||||
togglePushNotificationUseCase.execute(deviceId, enabled = true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private suspend fun registerPusher(fragmentActivity: FragmentActivity) {
|
|
||||||
suspendCoroutine { continuation ->
|
|
||||||
try {
|
|
||||||
unifiedPushHelper.register(fragmentActivity) {
|
|
||||||
if (unifiedPushHelper.isEmbeddedDistributor()) {
|
|
||||||
fcmHelper.ensureFcmTokenIsRetrieved(
|
|
||||||
fragmentActivity,
|
|
||||||
pushersManager,
|
|
||||||
registerPusher = true
|
|
||||||
)
|
|
||||||
}
|
|
||||||
continuation.resume(Unit)
|
|
||||||
}
|
}
|
||||||
} catch (error: Exception) {
|
|
||||||
continuation.resumeWithException(error)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val session = activeSessionHolder.getSafeActiveSession() ?: return EnableNotificationsResult.Failure
|
||||||
|
val deviceId = session.sessionParams.deviceId ?: return EnableNotificationsResult.Failure
|
||||||
|
togglePushNotificationUseCase.execute(deviceId, enabled = true)
|
||||||
|
|
||||||
|
return EnableNotificationsResult.Success
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ import android.content.Intent
|
||||||
import android.media.RingtoneManager
|
import android.media.RingtoneManager
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.distinctUntilChanged
|
import androidx.lifecycle.distinctUntilChanged
|
||||||
|
@ -29,6 +30,7 @@ import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.lifecycle.map
|
import androidx.lifecycle.map
|
||||||
import androidx.preference.Preference
|
import androidx.preference.Preference
|
||||||
import androidx.preference.SwitchPreference
|
import androidx.preference.SwitchPreference
|
||||||
|
import com.airbnb.mvrx.fragmentViewModel
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.di.ActiveSessionHolder
|
import im.vector.app.core.di.ActiveSessionHolder
|
||||||
|
@ -37,6 +39,7 @@ import im.vector.app.core.preference.VectorEditTextPreference
|
||||||
import im.vector.app.core.preference.VectorPreference
|
import im.vector.app.core.preference.VectorPreference
|
||||||
import im.vector.app.core.preference.VectorPreferenceCategory
|
import im.vector.app.core.preference.VectorPreferenceCategory
|
||||||
import im.vector.app.core.preference.VectorSwitchPreference
|
import im.vector.app.core.preference.VectorSwitchPreference
|
||||||
|
import im.vector.app.core.pushers.EnsureFcmTokenIsRetrievedUseCase
|
||||||
import im.vector.app.core.pushers.FcmHelper
|
import im.vector.app.core.pushers.FcmHelper
|
||||||
import im.vector.app.core.pushers.PushersManager
|
import im.vector.app.core.pushers.PushersManager
|
||||||
import im.vector.app.core.pushers.UnifiedPushHelper
|
import im.vector.app.core.pushers.UnifiedPushHelper
|
||||||
|
@ -80,14 +83,15 @@ class VectorSettingsNotificationPreferenceFragment :
|
||||||
@Inject lateinit var guardServiceStarter: GuardServiceStarter
|
@Inject lateinit var guardServiceStarter: GuardServiceStarter
|
||||||
@Inject lateinit var vectorFeatures: VectorFeatures
|
@Inject lateinit var vectorFeatures: VectorFeatures
|
||||||
@Inject lateinit var notificationPermissionManager: NotificationPermissionManager
|
@Inject lateinit var notificationPermissionManager: NotificationPermissionManager
|
||||||
@Inject lateinit var disableNotificationsForCurrentSessionUseCase: DisableNotificationsForCurrentSessionUseCase
|
@Inject lateinit var ensureFcmTokenIsRetrievedUseCase: EnsureFcmTokenIsRetrievedUseCase
|
||||||
@Inject lateinit var enableNotificationsForCurrentSessionUseCase: EnableNotificationsForCurrentSessionUseCase
|
|
||||||
|
|
||||||
override var titleRes: Int = R.string.settings_notifications
|
override var titleRes: Int = R.string.settings_notifications
|
||||||
override val preferenceXmlRes = R.xml.vector_settings_notifications
|
override val preferenceXmlRes = R.xml.vector_settings_notifications
|
||||||
|
|
||||||
private var interactionListener: VectorSettingsFragmentInteractionListener? = null
|
private var interactionListener: VectorSettingsFragmentInteractionListener? = null
|
||||||
|
|
||||||
|
private val viewModel: VectorSettingsNotificationPreferenceViewModel by fragmentViewModel()
|
||||||
|
|
||||||
private val notificationStartForActivityResult = registerStartForActivityResult { _ ->
|
private val notificationStartForActivityResult = registerStartForActivityResult { _ ->
|
||||||
// No op
|
// No op
|
||||||
}
|
}
|
||||||
|
@ -104,6 +108,23 @@ class VectorSettingsNotificationPreferenceFragment :
|
||||||
analyticsScreenName = MobileScreen.ScreenName.SettingsNotifications
|
analyticsScreenName = MobileScreen.ScreenName.SettingsNotifications
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
observeViewEvents()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun observeViewEvents() {
|
||||||
|
viewModel.observeViewEvents {
|
||||||
|
when (it) {
|
||||||
|
VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceEnabled -> onNotificationsForDeviceEnabled()
|
||||||
|
VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceDisabled -> onNotificationsForDeviceDisabled()
|
||||||
|
is VectorSettingsNotificationPreferenceViewEvent.AskUserForPushDistributor -> askUserToSelectPushDistributor()
|
||||||
|
VectorSettingsNotificationPreferenceViewEvent.EnableNotificationForDeviceFailure -> displayErrorDialog(throwable = null)
|
||||||
|
VectorSettingsNotificationPreferenceViewEvent.NotificationMethodChanged -> onNotificationMethodChanged()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun bindPref() {
|
override fun bindPref() {
|
||||||
findPreference<VectorSwitchPreference>(VectorPreferences.SETTINGS_ENABLE_ALL_NOTIF_PREFERENCE_KEY)!!.let { pref ->
|
findPreference<VectorSwitchPreference>(VectorPreferences.SETTINGS_ENABLE_ALL_NOTIF_PREFERENCE_KEY)!!.let { pref ->
|
||||||
val pushRuleService = session.pushRuleService()
|
val pushRuleService = session.pushRuleService()
|
||||||
|
@ -121,23 +142,15 @@ class VectorSettingsNotificationPreferenceFragment :
|
||||||
}
|
}
|
||||||
|
|
||||||
findPreference<SwitchPreference>(VectorPreferences.SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY)
|
findPreference<SwitchPreference>(VectorPreferences.SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY)
|
||||||
?.setTransactionalSwitchChangeListener(lifecycleScope) { isChecked ->
|
?.setOnPreferenceChangeListener { _, isChecked ->
|
||||||
if (isChecked) {
|
val action = if (isChecked as Boolean) {
|
||||||
enableNotificationsForCurrentSessionUseCase.execute(requireActivity())
|
VectorSettingsNotificationPreferenceViewAction.EnableNotificationsForDevice(pushDistributor = "")
|
||||||
|
|
||||||
findPreference<VectorPreference>(VectorPreferences.SETTINGS_NOTIFICATION_METHOD_KEY)
|
|
||||||
?.summary = unifiedPushHelper.getCurrentDistributorName()
|
|
||||||
|
|
||||||
notificationPermissionManager.eventuallyRequestPermission(
|
|
||||||
requireActivity(),
|
|
||||||
postPermissionLauncher,
|
|
||||||
showRationale = false,
|
|
||||||
ignorePreference = true
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
disableNotificationsForCurrentSessionUseCase.execute()
|
VectorSettingsNotificationPreferenceViewAction.DisableNotificationsForDevice
|
||||||
notificationPermissionManager.eventuallyRevokePermission(requireActivity())
|
|
||||||
}
|
}
|
||||||
|
viewModel.handle(action)
|
||||||
|
// preference will be updated on ViewEvent reception
|
||||||
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
findPreference<VectorPreference>(VectorPreferences.SETTINGS_FDROID_BACKGROUND_SYNC_MODE)?.let {
|
findPreference<VectorPreference>(VectorPreferences.SETTINGS_FDROID_BACKGROUND_SYNC_MODE)?.let {
|
||||||
|
@ -182,18 +195,7 @@ class VectorSettingsNotificationPreferenceFragment :
|
||||||
if (vectorFeatures.allowExternalUnifiedPushDistributors()) {
|
if (vectorFeatures.allowExternalUnifiedPushDistributors()) {
|
||||||
it.summary = unifiedPushHelper.getCurrentDistributorName()
|
it.summary = unifiedPushHelper.getCurrentDistributorName()
|
||||||
it.onPreferenceClickListener = Preference.OnPreferenceClickListener {
|
it.onPreferenceClickListener = Preference.OnPreferenceClickListener {
|
||||||
unifiedPushHelper.forceRegister(requireActivity(), pushersManager) {
|
askUserToSelectPushDistributor(withUnregister = true)
|
||||||
if (unifiedPushHelper.isEmbeddedDistributor()) {
|
|
||||||
fcmHelper.ensureFcmTokenIsRetrieved(
|
|
||||||
requireActivity(),
|
|
||||||
pushersManager,
|
|
||||||
vectorPreferences.areNotificationEnabledForDevice()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
it.summary = unifiedPushHelper.getCurrentDistributorName()
|
|
||||||
session.pushersService().refreshPushers()
|
|
||||||
refreshBackgroundSyncPrefs()
|
|
||||||
}
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -207,6 +209,42 @@ class VectorSettingsNotificationPreferenceFragment :
|
||||||
handleSystemPreference()
|
handleSystemPreference()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun onNotificationsForDeviceEnabled() {
|
||||||
|
findPreference<SwitchPreference>(VectorPreferences.SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY)
|
||||||
|
?.isChecked = true
|
||||||
|
findPreference<VectorPreference>(VectorPreferences.SETTINGS_NOTIFICATION_METHOD_KEY)
|
||||||
|
?.summary = unifiedPushHelper.getCurrentDistributorName()
|
||||||
|
|
||||||
|
notificationPermissionManager.eventuallyRequestPermission(
|
||||||
|
requireActivity(),
|
||||||
|
postPermissionLauncher,
|
||||||
|
showRationale = false,
|
||||||
|
ignorePreference = true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onNotificationsForDeviceDisabled() {
|
||||||
|
findPreference<SwitchPreference>(VectorPreferences.SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY)
|
||||||
|
?.isChecked = false
|
||||||
|
notificationPermissionManager.eventuallyRevokePermission(requireActivity())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun askUserToSelectPushDistributor(withUnregister: Boolean = false) {
|
||||||
|
unifiedPushHelper.showSelectDistributorDialog(requireContext()) { selection ->
|
||||||
|
if (withUnregister) {
|
||||||
|
viewModel.handle(VectorSettingsNotificationPreferenceViewAction.RegisterPushDistributor(selection))
|
||||||
|
} else {
|
||||||
|
viewModel.handle(VectorSettingsNotificationPreferenceViewAction.EnableNotificationsForDevice(selection))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onNotificationMethodChanged() {
|
||||||
|
findPreference<VectorPreference>(VectorPreferences.SETTINGS_NOTIFICATION_METHOD_KEY)?.summary = unifiedPushHelper.getCurrentDistributorName()
|
||||||
|
session.pushersService().refreshPushers()
|
||||||
|
refreshBackgroundSyncPrefs()
|
||||||
|
}
|
||||||
|
|
||||||
private fun bindEmailNotifications() {
|
private fun bindEmailNotifications() {
|
||||||
val initialEmails = session.getEmailsWithPushInformation()
|
val initialEmails = session.getEmailsWithPushInformation()
|
||||||
bindEmailNotificationCategory(initialEmails)
|
bindEmailNotificationCategory(initialEmails)
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.app.features.settings.notifications
|
||||||
|
|
||||||
|
import im.vector.app.core.platform.VectorViewModelAction
|
||||||
|
|
||||||
|
sealed interface VectorSettingsNotificationPreferenceViewAction : VectorViewModelAction {
|
||||||
|
data class EnableNotificationsForDevice(val pushDistributor: String) : VectorSettingsNotificationPreferenceViewAction
|
||||||
|
object DisableNotificationsForDevice : VectorSettingsNotificationPreferenceViewAction
|
||||||
|
data class RegisterPushDistributor(val pushDistributor: String) : VectorSettingsNotificationPreferenceViewAction
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.app.features.settings.notifications
|
||||||
|
|
||||||
|
import im.vector.app.core.platform.VectorViewEvents
|
||||||
|
|
||||||
|
sealed interface VectorSettingsNotificationPreferenceViewEvent : VectorViewEvents {
|
||||||
|
object NotificationsForDeviceEnabled : VectorSettingsNotificationPreferenceViewEvent
|
||||||
|
object EnableNotificationForDeviceFailure : VectorSettingsNotificationPreferenceViewEvent
|
||||||
|
object NotificationsForDeviceDisabled : VectorSettingsNotificationPreferenceViewEvent
|
||||||
|
object AskUserForPushDistributor : VectorSettingsNotificationPreferenceViewEvent
|
||||||
|
object NotificationMethodChanged : VectorSettingsNotificationPreferenceViewEvent
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.app.features.settings.notifications
|
||||||
|
|
||||||
|
import com.airbnb.mvrx.MavericksViewModelFactory
|
||||||
|
import dagger.assisted.Assisted
|
||||||
|
import dagger.assisted.AssistedFactory
|
||||||
|
import dagger.assisted.AssistedInject
|
||||||
|
import im.vector.app.core.di.MavericksAssistedViewModelFactory
|
||||||
|
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
||||||
|
import im.vector.app.core.platform.VectorDummyViewState
|
||||||
|
import im.vector.app.core.platform.VectorViewModel
|
||||||
|
import im.vector.app.core.pushers.EnsureFcmTokenIsRetrievedUseCase
|
||||||
|
import im.vector.app.core.pushers.PushersManager
|
||||||
|
import im.vector.app.core.pushers.RegisterUnifiedPushUseCase
|
||||||
|
import im.vector.app.core.pushers.UnregisterUnifiedPushUseCase
|
||||||
|
import im.vector.app.features.settings.VectorPreferences
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
class VectorSettingsNotificationPreferenceViewModel @AssistedInject constructor(
|
||||||
|
@Assisted initialState: VectorDummyViewState,
|
||||||
|
private val pushersManager: PushersManager,
|
||||||
|
private val vectorPreferences: VectorPreferences,
|
||||||
|
private val enableNotificationsForCurrentSessionUseCase: EnableNotificationsForCurrentSessionUseCase,
|
||||||
|
private val disableNotificationsForCurrentSessionUseCase: DisableNotificationsForCurrentSessionUseCase,
|
||||||
|
private val unregisterUnifiedPushUseCase: UnregisterUnifiedPushUseCase,
|
||||||
|
private val registerUnifiedPushUseCase: RegisterUnifiedPushUseCase,
|
||||||
|
private val ensureFcmTokenIsRetrievedUseCase: EnsureFcmTokenIsRetrievedUseCase,
|
||||||
|
) : VectorViewModel<VectorDummyViewState, VectorSettingsNotificationPreferenceViewAction, VectorSettingsNotificationPreferenceViewEvent>(initialState) {
|
||||||
|
|
||||||
|
@AssistedFactory
|
||||||
|
interface Factory : MavericksAssistedViewModelFactory<VectorSettingsNotificationPreferenceViewModel, VectorDummyViewState> {
|
||||||
|
override fun create(initialState: VectorDummyViewState): VectorSettingsNotificationPreferenceViewModel
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object : MavericksViewModelFactory<VectorSettingsNotificationPreferenceViewModel, VectorDummyViewState> by hiltMavericksViewModelFactory()
|
||||||
|
|
||||||
|
override fun handle(action: VectorSettingsNotificationPreferenceViewAction) {
|
||||||
|
when (action) {
|
||||||
|
VectorSettingsNotificationPreferenceViewAction.DisableNotificationsForDevice -> handleDisableNotificationsForDevice()
|
||||||
|
is VectorSettingsNotificationPreferenceViewAction.EnableNotificationsForDevice -> handleEnableNotificationsForDevice(action.pushDistributor)
|
||||||
|
is VectorSettingsNotificationPreferenceViewAction.RegisterPushDistributor -> handleRegisterPushDistributor(action.pushDistributor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleDisableNotificationsForDevice() {
|
||||||
|
viewModelScope.launch {
|
||||||
|
disableNotificationsForCurrentSessionUseCase.execute()
|
||||||
|
_viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceDisabled)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleEnableNotificationsForDevice(distributor: String) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
when (enableNotificationsForCurrentSessionUseCase.execute(distributor)) {
|
||||||
|
EnableNotificationsForCurrentSessionUseCase.EnableNotificationsResult.Failure -> {
|
||||||
|
_viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.EnableNotificationForDeviceFailure)
|
||||||
|
}
|
||||||
|
is EnableNotificationsForCurrentSessionUseCase.EnableNotificationsResult.NeedToAskUserForDistributor -> {
|
||||||
|
_viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.AskUserForPushDistributor)
|
||||||
|
}
|
||||||
|
EnableNotificationsForCurrentSessionUseCase.EnableNotificationsResult.Success -> {
|
||||||
|
_viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceEnabled)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleRegisterPushDistributor(distributor: String) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
unregisterUnifiedPushUseCase.execute(pushersManager)
|
||||||
|
when (registerUnifiedPushUseCase.execute(distributor)) {
|
||||||
|
RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.NeedToAskUserForDistributor -> {
|
||||||
|
_viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.AskUserForPushDistributor)
|
||||||
|
}
|
||||||
|
RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.Success -> {
|
||||||
|
ensureFcmTokenIsRetrievedUseCase.execute(pushersManager, registerPusher = vectorPreferences.areNotificationEnabledForDevice())
|
||||||
|
_viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.NotificationMethodChanged)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,14 +17,17 @@
|
||||||
package im.vector.app.features.settings.troubleshoot
|
package im.vector.app.features.settings.troubleshoot
|
||||||
|
|
||||||
import androidx.fragment.app.FragmentActivity
|
import androidx.fragment.app.FragmentActivity
|
||||||
import androidx.lifecycle.Observer
|
|
||||||
import androidx.work.WorkInfo
|
import androidx.work.WorkInfo
|
||||||
import androidx.work.WorkManager
|
import androidx.work.WorkManager
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.di.ActiveSessionHolder
|
import im.vector.app.core.di.ActiveSessionHolder
|
||||||
import im.vector.app.core.pushers.PushersManager
|
import im.vector.app.core.pushers.PushersManager
|
||||||
|
import im.vector.app.core.pushers.RegisterUnifiedPushUseCase
|
||||||
import im.vector.app.core.pushers.UnifiedPushHelper
|
import im.vector.app.core.pushers.UnifiedPushHelper
|
||||||
|
import im.vector.app.core.pushers.UnregisterUnifiedPushUseCase
|
||||||
import im.vector.app.core.resources.StringProvider
|
import im.vector.app.core.resources.StringProvider
|
||||||
|
import im.vector.app.features.session.coroutineScope
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import org.matrix.android.sdk.api.session.pushers.PusherState
|
import org.matrix.android.sdk.api.session.pushers.PusherState
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@ -34,6 +37,8 @@ class TestEndpointAsTokenRegistration @Inject constructor(
|
||||||
private val pushersManager: PushersManager,
|
private val pushersManager: PushersManager,
|
||||||
private val activeSessionHolder: ActiveSessionHolder,
|
private val activeSessionHolder: ActiveSessionHolder,
|
||||||
private val unifiedPushHelper: UnifiedPushHelper,
|
private val unifiedPushHelper: UnifiedPushHelper,
|
||||||
|
private val registerUnifiedPushUseCase: RegisterUnifiedPushUseCase,
|
||||||
|
private val unregisterUnifiedPushUseCase: UnregisterUnifiedPushUseCase,
|
||||||
) : TroubleshootTest(R.string.settings_troubleshoot_test_endpoint_registration_title) {
|
) : TroubleshootTest(R.string.settings_troubleshoot_test_endpoint_registration_title) {
|
||||||
|
|
||||||
override fun perform(testParameters: TestParameters) {
|
override fun perform(testParameters: TestParameters) {
|
||||||
|
@ -56,27 +61,52 @@ class TestEndpointAsTokenRegistration @Inject constructor(
|
||||||
)
|
)
|
||||||
quickFix = object : TroubleshootQuickFix(R.string.settings_troubleshoot_test_endpoint_registration_quick_fix) {
|
quickFix = object : TroubleshootQuickFix(R.string.settings_troubleshoot_test_endpoint_registration_quick_fix) {
|
||||||
override fun doFix() {
|
override fun doFix() {
|
||||||
unifiedPushHelper.forceRegister(
|
unregisterThenRegister(testParameters, endpoint)
|
||||||
context,
|
|
||||||
pushersManager
|
|
||||||
)
|
|
||||||
val workId = pushersManager.enqueueRegisterPusherWithFcmKey(endpoint)
|
|
||||||
WorkManager.getInstance(context).getWorkInfoByIdLiveData(workId).observe(context, Observer { workInfo ->
|
|
||||||
if (workInfo != null) {
|
|
||||||
if (workInfo.state == WorkInfo.State.SUCCEEDED) {
|
|
||||||
manager?.retry(testParameters)
|
|
||||||
} else if (workInfo.state == WorkInfo.State.FAILED) {
|
|
||||||
manager?.retry(testParameters)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
status = TestStatus.FAILED
|
status = TestStatus.FAILED
|
||||||
} else {
|
} else {
|
||||||
description = stringProvider.getString(R.string.settings_troubleshoot_test_endpoint_registration_success)
|
description = stringProvider.getString(R.string.settings_troubleshoot_test_endpoint_registration_success)
|
||||||
status = TestStatus.SUCCESS
|
status = TestStatus.SUCCESS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun unregisterThenRegister(testParameters: TestParameters, pushKey: String) {
|
||||||
|
activeSessionHolder.getSafeActiveSession()?.coroutineScope?.launch {
|
||||||
|
unregisterUnifiedPushUseCase.execute(pushersManager)
|
||||||
|
registerUnifiedPush(distributor = "", testParameters, pushKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun registerUnifiedPush(
|
||||||
|
distributor: String,
|
||||||
|
testParameters: TestParameters,
|
||||||
|
pushKey: String,
|
||||||
|
) {
|
||||||
|
when (registerUnifiedPushUseCase.execute(distributor)) {
|
||||||
|
is RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.NeedToAskUserForDistributor ->
|
||||||
|
askUserForDistributor(testParameters, pushKey)
|
||||||
|
RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.Success -> {
|
||||||
|
val workId = pushersManager.enqueueRegisterPusherWithFcmKey(pushKey)
|
||||||
|
WorkManager.getInstance(context).getWorkInfoByIdLiveData(workId).observe(context) { workInfo ->
|
||||||
|
if (workInfo != null) {
|
||||||
|
if (workInfo.state == WorkInfo.State.SUCCEEDED) {
|
||||||
|
manager?.retry(testParameters)
|
||||||
|
} else if (workInfo.state == WorkInfo.State.FAILED) {
|
||||||
|
manager?.retry(testParameters)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun askUserForDistributor(
|
||||||
|
testParameters: TestParameters,
|
||||||
|
pushKey: String,
|
||||||
|
) {
|
||||||
|
unifiedPushHelper.showSelectDistributorDialog(context) { selection ->
|
||||||
|
registerUnifiedPush(distributor = selection, testParameters, pushKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,105 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.app.core.pushers
|
||||||
|
|
||||||
|
import im.vector.app.test.fakes.FakeActiveSessionHolder
|
||||||
|
import im.vector.app.test.fakes.FakeFcmHelper
|
||||||
|
import im.vector.app.test.fakes.FakePushersManager
|
||||||
|
import im.vector.app.test.fakes.FakeUnifiedPushHelper
|
||||||
|
import im.vector.app.test.fixtures.PusherFixture
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class EnsureFcmTokenIsRetrievedUseCaseTest {
|
||||||
|
|
||||||
|
private val fakeUnifiedPushHelper = FakeUnifiedPushHelper()
|
||||||
|
private val fakeFcmHelper = FakeFcmHelper()
|
||||||
|
private val fakeActiveSessionHolder = FakeActiveSessionHolder()
|
||||||
|
|
||||||
|
private val ensureFcmTokenIsRetrievedUseCase = EnsureFcmTokenIsRetrievedUseCase(
|
||||||
|
unifiedPushHelper = fakeUnifiedPushHelper.instance,
|
||||||
|
fcmHelper = fakeFcmHelper.instance,
|
||||||
|
activeSessionHolder = fakeActiveSessionHolder.instance,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `given no registered pusher and distributor as embedded when execute then ensure the FCM token is retrieved with register pusher option`() {
|
||||||
|
// Given
|
||||||
|
val aPushersManager = FakePushersManager()
|
||||||
|
fakeUnifiedPushHelper.givenIsEmbeddedDistributorReturns(true)
|
||||||
|
fakeFcmHelper.givenEnsureFcmTokenIsRetrieved(aPushersManager.instance)
|
||||||
|
val aSessionId = "aSessionId"
|
||||||
|
fakeActiveSessionHolder.fakeSession.givenSessionId(aSessionId)
|
||||||
|
val expectedPusher = PusherFixture.aPusher(deviceId = "")
|
||||||
|
fakeActiveSessionHolder.fakeSession.fakePushersService.givenGetPushers(listOf(expectedPusher))
|
||||||
|
|
||||||
|
// When
|
||||||
|
ensureFcmTokenIsRetrievedUseCase.execute(aPushersManager.instance, registerPusher = true)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
fakeFcmHelper.verifyEnsureFcmTokenIsRetrieved(aPushersManager.instance, registerPusher = true)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `given a registered pusher and distributor as embedded when execute then ensure the FCM token is retrieved without register pusher option`() {
|
||||||
|
// Given
|
||||||
|
val aPushersManager = FakePushersManager()
|
||||||
|
fakeUnifiedPushHelper.givenIsEmbeddedDistributorReturns(true)
|
||||||
|
fakeFcmHelper.givenEnsureFcmTokenIsRetrieved(aPushersManager.instance)
|
||||||
|
val aSessionId = "aSessionId"
|
||||||
|
fakeActiveSessionHolder.fakeSession.givenSessionId(aSessionId)
|
||||||
|
val expectedPusher = PusherFixture.aPusher(deviceId = aSessionId)
|
||||||
|
fakeActiveSessionHolder.fakeSession.fakePushersService.givenGetPushers(listOf(expectedPusher))
|
||||||
|
|
||||||
|
// When
|
||||||
|
ensureFcmTokenIsRetrievedUseCase.execute(aPushersManager.instance, registerPusher = true)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
fakeFcmHelper.verifyEnsureFcmTokenIsRetrieved(aPushersManager.instance, registerPusher = false)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `given no registering asked and distributor as embedded when execute then ensure the FCM token is retrieved without register pusher option`() {
|
||||||
|
// Given
|
||||||
|
val aPushersManager = FakePushersManager()
|
||||||
|
fakeUnifiedPushHelper.givenIsEmbeddedDistributorReturns(true)
|
||||||
|
fakeFcmHelper.givenEnsureFcmTokenIsRetrieved(aPushersManager.instance)
|
||||||
|
val aSessionId = "aSessionId"
|
||||||
|
fakeActiveSessionHolder.fakeSession.givenSessionId(aSessionId)
|
||||||
|
val expectedPusher = PusherFixture.aPusher(deviceId = aSessionId)
|
||||||
|
fakeActiveSessionHolder.fakeSession.fakePushersService.givenGetPushers(listOf(expectedPusher))
|
||||||
|
|
||||||
|
// When
|
||||||
|
ensureFcmTokenIsRetrievedUseCase.execute(aPushersManager.instance, registerPusher = false)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
fakeFcmHelper.verifyEnsureFcmTokenIsRetrieved(aPushersManager.instance, registerPusher = false)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `given distributor as not embedded when execute then nothing is done`() {
|
||||||
|
// Given
|
||||||
|
val aPushersManager = FakePushersManager()
|
||||||
|
fakeUnifiedPushHelper.givenIsEmbeddedDistributorReturns(false)
|
||||||
|
|
||||||
|
// When
|
||||||
|
ensureFcmTokenIsRetrievedUseCase.execute(aPushersManager.instance, registerPusher = true)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
fakeFcmHelper.verifyEnsureFcmTokenIsRetrieved(aPushersManager.instance, registerPusher = true, inverse = true)
|
||||||
|
fakeFcmHelper.verifyEnsureFcmTokenIsRetrieved(aPushersManager.instance, registerPusher = false, inverse = true)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,158 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.app.core.pushers
|
||||||
|
|
||||||
|
import im.vector.app.test.fakes.FakeContext
|
||||||
|
import im.vector.app.test.fakes.FakeVectorFeatures
|
||||||
|
import io.mockk.every
|
||||||
|
import io.mockk.justRun
|
||||||
|
import io.mockk.mockkStatic
|
||||||
|
import io.mockk.unmockkAll
|
||||||
|
import io.mockk.verify
|
||||||
|
import io.mockk.verifyAll
|
||||||
|
import io.mockk.verifyOrder
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.amshove.kluent.shouldBe
|
||||||
|
import org.junit.After
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
import org.unifiedpush.android.connector.UnifiedPush
|
||||||
|
|
||||||
|
class RegisterUnifiedPushUseCaseTest {
|
||||||
|
|
||||||
|
private val fakeContext = FakeContext()
|
||||||
|
private val fakeVectorFeatures = FakeVectorFeatures()
|
||||||
|
|
||||||
|
private val registerUnifiedPushUseCase = RegisterUnifiedPushUseCase(
|
||||||
|
context = fakeContext.instance,
|
||||||
|
vectorFeatures = fakeVectorFeatures,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setup() {
|
||||||
|
mockkStatic(UnifiedPush::class)
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
fun tearDown() {
|
||||||
|
unmockkAll()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `given non empty distributor when execute then distributor is saved and app is registered`() = runTest {
|
||||||
|
// Given
|
||||||
|
val aDistributor = "distributor"
|
||||||
|
justRun { UnifiedPush.registerApp(any()) }
|
||||||
|
justRun { UnifiedPush.saveDistributor(any(), any()) }
|
||||||
|
|
||||||
|
// When
|
||||||
|
val result = registerUnifiedPushUseCase.execute(aDistributor)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
result shouldBe RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.Success
|
||||||
|
verifyOrder {
|
||||||
|
UnifiedPush.saveDistributor(fakeContext.instance, aDistributor)
|
||||||
|
UnifiedPush.registerApp(fakeContext.instance)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `given external distributors are not allowed when execute then internal distributor is saved and app is registered`() = runTest {
|
||||||
|
// Given
|
||||||
|
val aPackageName = "packageName"
|
||||||
|
fakeContext.givenPackageName(aPackageName)
|
||||||
|
justRun { UnifiedPush.registerApp(any()) }
|
||||||
|
justRun { UnifiedPush.saveDistributor(any(), any()) }
|
||||||
|
fakeVectorFeatures.givenExternalDistributorsAreAllowed(false)
|
||||||
|
|
||||||
|
// When
|
||||||
|
val result = registerUnifiedPushUseCase.execute()
|
||||||
|
|
||||||
|
// Then
|
||||||
|
result shouldBe RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.Success
|
||||||
|
verifyOrder {
|
||||||
|
UnifiedPush.saveDistributor(fakeContext.instance, aPackageName)
|
||||||
|
UnifiedPush.registerApp(fakeContext.instance)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `given a saved distributor and external distributors are allowed when execute then app is registered`() = runTest {
|
||||||
|
// Given
|
||||||
|
justRun { UnifiedPush.registerApp(any()) }
|
||||||
|
val aDistributor = "distributor"
|
||||||
|
every { UnifiedPush.getDistributor(any()) } returns aDistributor
|
||||||
|
fakeVectorFeatures.givenExternalDistributorsAreAllowed(true)
|
||||||
|
|
||||||
|
// When
|
||||||
|
val result = registerUnifiedPushUseCase.execute()
|
||||||
|
|
||||||
|
// Then
|
||||||
|
result shouldBe RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.Success
|
||||||
|
verifyAll {
|
||||||
|
UnifiedPush.getDistributor(fakeContext.instance)
|
||||||
|
UnifiedPush.registerApp(fakeContext.instance)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `given no saved distributor and a unique distributor available when execute then the distributor is saved and app is registered`() = runTest {
|
||||||
|
// Given
|
||||||
|
justRun { UnifiedPush.registerApp(any()) }
|
||||||
|
justRun { UnifiedPush.saveDistributor(any(), any()) }
|
||||||
|
every { UnifiedPush.getDistributor(any()) } returns ""
|
||||||
|
fakeVectorFeatures.givenExternalDistributorsAreAllowed(true)
|
||||||
|
val aDistributor = "distributor"
|
||||||
|
every { UnifiedPush.getDistributors(any()) } returns listOf(aDistributor)
|
||||||
|
|
||||||
|
// When
|
||||||
|
val result = registerUnifiedPushUseCase.execute()
|
||||||
|
|
||||||
|
// Then
|
||||||
|
result shouldBe RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.Success
|
||||||
|
verifyOrder {
|
||||||
|
UnifiedPush.getDistributor(fakeContext.instance)
|
||||||
|
UnifiedPush.getDistributors(fakeContext.instance)
|
||||||
|
UnifiedPush.saveDistributor(fakeContext.instance, aDistributor)
|
||||||
|
UnifiedPush.registerApp(fakeContext.instance)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `given no saved distributor and multiple distributors available when execute then result is to ask user`() = runTest {
|
||||||
|
// Given
|
||||||
|
every { UnifiedPush.getDistributor(any()) } returns ""
|
||||||
|
fakeVectorFeatures.givenExternalDistributorsAreAllowed(true)
|
||||||
|
val aDistributor1 = "distributor1"
|
||||||
|
val aDistributor2 = "distributor2"
|
||||||
|
every { UnifiedPush.getDistributors(any()) } returns listOf(aDistributor1, aDistributor2)
|
||||||
|
|
||||||
|
// When
|
||||||
|
val result = registerUnifiedPushUseCase.execute()
|
||||||
|
|
||||||
|
// Then
|
||||||
|
result shouldBe RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.NeedToAskUserForDistributor
|
||||||
|
verifyOrder {
|
||||||
|
UnifiedPush.getDistributor(fakeContext.instance)
|
||||||
|
UnifiedPush.getDistributors(fakeContext.instance)
|
||||||
|
}
|
||||||
|
verify(inverse = true) {
|
||||||
|
UnifiedPush.saveDistributor(any(), any())
|
||||||
|
UnifiedPush.registerApp(any())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,83 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.app.core.pushers
|
||||||
|
|
||||||
|
import im.vector.app.features.settings.BackgroundSyncMode
|
||||||
|
import im.vector.app.test.fakes.FakeContext
|
||||||
|
import im.vector.app.test.fakes.FakePushersManager
|
||||||
|
import im.vector.app.test.fakes.FakeUnifiedPushHelper
|
||||||
|
import im.vector.app.test.fakes.FakeUnifiedPushStore
|
||||||
|
import im.vector.app.test.fakes.FakeVectorPreferences
|
||||||
|
import io.mockk.justRun
|
||||||
|
import io.mockk.mockkStatic
|
||||||
|
import io.mockk.unmockkAll
|
||||||
|
import io.mockk.verifyAll
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.junit.After
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
import org.unifiedpush.android.connector.UnifiedPush
|
||||||
|
|
||||||
|
class UnregisterUnifiedPushUseCaseTest {
|
||||||
|
|
||||||
|
private val fakeContext = FakeContext()
|
||||||
|
private val fakeVectorPreferences = FakeVectorPreferences()
|
||||||
|
private val fakeUnifiedPushStore = FakeUnifiedPushStore()
|
||||||
|
private val fakeUnifiedPushHelper = FakeUnifiedPushHelper()
|
||||||
|
|
||||||
|
private val unregisterUnifiedPushUseCase = UnregisterUnifiedPushUseCase(
|
||||||
|
context = fakeContext.instance,
|
||||||
|
vectorPreferences = fakeVectorPreferences.instance,
|
||||||
|
unifiedPushStore = fakeUnifiedPushStore.instance,
|
||||||
|
unifiedPushHelper = fakeUnifiedPushHelper.instance,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setup() {
|
||||||
|
mockkStatic(UnifiedPush::class)
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
fun tearDown() {
|
||||||
|
unmockkAll()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `given pushersManager when execute then unregister and clean everything which is needed`() = runTest {
|
||||||
|
// Given
|
||||||
|
val aEndpoint = "endpoint"
|
||||||
|
fakeUnifiedPushHelper.givenGetEndpointOrTokenReturns(aEndpoint)
|
||||||
|
val aPushersManager = FakePushersManager()
|
||||||
|
aPushersManager.givenUnregisterPusher(aEndpoint)
|
||||||
|
justRun { UnifiedPush.unregisterApp(any()) }
|
||||||
|
fakeVectorPreferences.givenSetFdroidSyncBackgroundMode(BackgroundSyncMode.FDROID_BACKGROUND_SYNC_MODE_FOR_REALTIME)
|
||||||
|
fakeUnifiedPushStore.givenStorePushGateway(null)
|
||||||
|
fakeUnifiedPushStore.givenStoreUpEndpoint(null)
|
||||||
|
|
||||||
|
// When
|
||||||
|
unregisterUnifiedPushUseCase.execute(aPushersManager.instance)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
fakeVectorPreferences.verifySetFdroidSyncBackgroundMode(BackgroundSyncMode.FDROID_BACKGROUND_SYNC_MODE_FOR_REALTIME)
|
||||||
|
aPushersManager.verifyUnregisterPusher(aEndpoint)
|
||||||
|
verifyAll {
|
||||||
|
UnifiedPush.unregisterApp(fakeContext.instance)
|
||||||
|
}
|
||||||
|
fakeUnifiedPushStore.verifyStorePushGateway(null)
|
||||||
|
fakeUnifiedPushStore.verifyStoreUpEndpoint(null)
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,11 +16,11 @@
|
||||||
|
|
||||||
package im.vector.app.features.settings.notifications
|
package im.vector.app.features.settings.notifications
|
||||||
|
|
||||||
|
import im.vector.app.core.pushers.UnregisterUnifiedPushUseCase
|
||||||
import im.vector.app.features.settings.devices.v2.notification.CheckIfCanTogglePushNotificationsViaPusherUseCase
|
import im.vector.app.features.settings.devices.v2.notification.CheckIfCanTogglePushNotificationsViaPusherUseCase
|
||||||
import im.vector.app.features.settings.devices.v2.notification.TogglePushNotificationUseCase
|
import im.vector.app.features.settings.devices.v2.notification.TogglePushNotificationUseCase
|
||||||
import im.vector.app.test.fakes.FakeActiveSessionHolder
|
import im.vector.app.test.fakes.FakeActiveSessionHolder
|
||||||
import im.vector.app.test.fakes.FakePushersManager
|
import im.vector.app.test.fakes.FakePushersManager
|
||||||
import im.vector.app.test.fakes.FakeUnifiedPushHelper
|
|
||||||
import io.mockk.coJustRun
|
import io.mockk.coJustRun
|
||||||
import io.mockk.coVerify
|
import io.mockk.coVerify
|
||||||
import io.mockk.every
|
import io.mockk.every
|
||||||
|
@ -33,17 +33,17 @@ private const val A_SESSION_ID = "session-id"
|
||||||
class DisableNotificationsForCurrentSessionUseCaseTest {
|
class DisableNotificationsForCurrentSessionUseCaseTest {
|
||||||
|
|
||||||
private val fakeActiveSessionHolder = FakeActiveSessionHolder()
|
private val fakeActiveSessionHolder = FakeActiveSessionHolder()
|
||||||
private val fakeUnifiedPushHelper = FakeUnifiedPushHelper()
|
|
||||||
private val fakePushersManager = FakePushersManager()
|
private val fakePushersManager = FakePushersManager()
|
||||||
private val fakeCheckIfCanTogglePushNotificationsViaPusherUseCase = mockk<CheckIfCanTogglePushNotificationsViaPusherUseCase>()
|
private val fakeCheckIfCanTogglePushNotificationsViaPusherUseCase = mockk<CheckIfCanTogglePushNotificationsViaPusherUseCase>()
|
||||||
private val fakeTogglePushNotificationUseCase = mockk<TogglePushNotificationUseCase>()
|
private val fakeTogglePushNotificationUseCase = mockk<TogglePushNotificationUseCase>()
|
||||||
|
private val fakeUnregisterUnifiedPushUseCase = mockk<UnregisterUnifiedPushUseCase>()
|
||||||
|
|
||||||
private val disableNotificationsForCurrentSessionUseCase = DisableNotificationsForCurrentSessionUseCase(
|
private val disableNotificationsForCurrentSessionUseCase = DisableNotificationsForCurrentSessionUseCase(
|
||||||
activeSessionHolder = fakeActiveSessionHolder.instance,
|
activeSessionHolder = fakeActiveSessionHolder.instance,
|
||||||
unifiedPushHelper = fakeUnifiedPushHelper.instance,
|
|
||||||
pushersManager = fakePushersManager.instance,
|
pushersManager = fakePushersManager.instance,
|
||||||
checkIfCanTogglePushNotificationsViaPusherUseCase = fakeCheckIfCanTogglePushNotificationsViaPusherUseCase,
|
checkIfCanTogglePushNotificationsViaPusherUseCase = fakeCheckIfCanTogglePushNotificationsViaPusherUseCase,
|
||||||
togglePushNotificationUseCase = fakeTogglePushNotificationUseCase,
|
togglePushNotificationUseCase = fakeTogglePushNotificationUseCase,
|
||||||
|
unregisterUnifiedPushUseCase = fakeUnregisterUnifiedPushUseCase,
|
||||||
)
|
)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -67,12 +67,14 @@ class DisableNotificationsForCurrentSessionUseCaseTest {
|
||||||
val fakeSession = fakeActiveSessionHolder.fakeSession
|
val fakeSession = fakeActiveSessionHolder.fakeSession
|
||||||
fakeSession.givenSessionId(A_SESSION_ID)
|
fakeSession.givenSessionId(A_SESSION_ID)
|
||||||
every { fakeCheckIfCanTogglePushNotificationsViaPusherUseCase.execute(fakeSession) } returns false
|
every { fakeCheckIfCanTogglePushNotificationsViaPusherUseCase.execute(fakeSession) } returns false
|
||||||
fakeUnifiedPushHelper.givenUnregister(fakePushersManager.instance)
|
coJustRun { fakeUnregisterUnifiedPushUseCase.execute(any()) }
|
||||||
|
|
||||||
// When
|
// When
|
||||||
disableNotificationsForCurrentSessionUseCase.execute()
|
disableNotificationsForCurrentSessionUseCase.execute()
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
fakeUnifiedPushHelper.verifyUnregister(fakePushersManager.instance)
|
coVerify {
|
||||||
|
fakeUnregisterUnifiedPushUseCase.execute(fakePushersManager.instance)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,18 +16,18 @@
|
||||||
|
|
||||||
package im.vector.app.features.settings.notifications
|
package im.vector.app.features.settings.notifications
|
||||||
|
|
||||||
import androidx.fragment.app.FragmentActivity
|
import im.vector.app.core.pushers.EnsureFcmTokenIsRetrievedUseCase
|
||||||
import im.vector.app.features.settings.devices.v2.notification.CheckIfCanTogglePushNotificationsViaPusherUseCase
|
import im.vector.app.core.pushers.RegisterUnifiedPushUseCase
|
||||||
import im.vector.app.features.settings.devices.v2.notification.TogglePushNotificationUseCase
|
import im.vector.app.features.settings.devices.v2.notification.TogglePushNotificationUseCase
|
||||||
import im.vector.app.test.fakes.FakeActiveSessionHolder
|
import im.vector.app.test.fakes.FakeActiveSessionHolder
|
||||||
import im.vector.app.test.fakes.FakeFcmHelper
|
|
||||||
import im.vector.app.test.fakes.FakePushersManager
|
import im.vector.app.test.fakes.FakePushersManager
|
||||||
import im.vector.app.test.fakes.FakeUnifiedPushHelper
|
|
||||||
import io.mockk.coJustRun
|
import io.mockk.coJustRun
|
||||||
import io.mockk.coVerify
|
|
||||||
import io.mockk.every
|
import io.mockk.every
|
||||||
|
import io.mockk.justRun
|
||||||
import io.mockk.mockk
|
import io.mockk.mockk
|
||||||
|
import io.mockk.verify
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.amshove.kluent.shouldBe
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
private const val A_SESSION_ID = "session-id"
|
private const val A_SESSION_ID = "session-id"
|
||||||
|
@ -35,53 +35,71 @@ private const val A_SESSION_ID = "session-id"
|
||||||
class EnableNotificationsForCurrentSessionUseCaseTest {
|
class EnableNotificationsForCurrentSessionUseCaseTest {
|
||||||
|
|
||||||
private val fakeActiveSessionHolder = FakeActiveSessionHolder()
|
private val fakeActiveSessionHolder = FakeActiveSessionHolder()
|
||||||
private val fakeUnifiedPushHelper = FakeUnifiedPushHelper()
|
|
||||||
private val fakePushersManager = FakePushersManager()
|
private val fakePushersManager = FakePushersManager()
|
||||||
private val fakeFcmHelper = FakeFcmHelper()
|
|
||||||
private val fakeCheckIfCanTogglePushNotificationsViaPusherUseCase = mockk<CheckIfCanTogglePushNotificationsViaPusherUseCase>()
|
|
||||||
private val fakeTogglePushNotificationUseCase = mockk<TogglePushNotificationUseCase>()
|
private val fakeTogglePushNotificationUseCase = mockk<TogglePushNotificationUseCase>()
|
||||||
|
private val fakeRegisterUnifiedPushUseCase = mockk<RegisterUnifiedPushUseCase>()
|
||||||
|
private val fakeEnsureFcmTokenIsRetrievedUseCase = mockk<EnsureFcmTokenIsRetrievedUseCase>()
|
||||||
|
|
||||||
private val enableNotificationsForCurrentSessionUseCase = EnableNotificationsForCurrentSessionUseCase(
|
private val enableNotificationsForCurrentSessionUseCase = EnableNotificationsForCurrentSessionUseCase(
|
||||||
activeSessionHolder = fakeActiveSessionHolder.instance,
|
activeSessionHolder = fakeActiveSessionHolder.instance,
|
||||||
unifiedPushHelper = fakeUnifiedPushHelper.instance,
|
|
||||||
pushersManager = fakePushersManager.instance,
|
pushersManager = fakePushersManager.instance,
|
||||||
fcmHelper = fakeFcmHelper.instance,
|
|
||||||
checkIfCanTogglePushNotificationsViaPusherUseCase = fakeCheckIfCanTogglePushNotificationsViaPusherUseCase,
|
|
||||||
togglePushNotificationUseCase = fakeTogglePushNotificationUseCase,
|
togglePushNotificationUseCase = fakeTogglePushNotificationUseCase,
|
||||||
|
registerUnifiedPushUseCase = fakeRegisterUnifiedPushUseCase,
|
||||||
|
ensureFcmTokenIsRetrievedUseCase = fakeEnsureFcmTokenIsRetrievedUseCase,
|
||||||
)
|
)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `given no existing pusher for current session when execute then a new pusher is registered`() = runTest {
|
fun `given no existing pusher and a registered distributor when execute then a new pusher is registered and result is success`() = runTest {
|
||||||
// Given
|
// Given
|
||||||
val fragmentActivity = mockk<FragmentActivity>()
|
val aDistributor = "distributor"
|
||||||
fakePushersManager.givenGetPusherForCurrentSessionReturns(null)
|
|
||||||
fakeUnifiedPushHelper.givenRegister(fragmentActivity)
|
|
||||||
fakeUnifiedPushHelper.givenIsEmbeddedDistributorReturns(true)
|
|
||||||
fakeFcmHelper.givenEnsureFcmTokenIsRetrieved(fragmentActivity, fakePushersManager.instance)
|
|
||||||
every { fakeCheckIfCanTogglePushNotificationsViaPusherUseCase.execute(fakeActiveSessionHolder.fakeSession) } returns false
|
|
||||||
|
|
||||||
// When
|
|
||||||
enableNotificationsForCurrentSessionUseCase.execute(fragmentActivity)
|
|
||||||
|
|
||||||
// Then
|
|
||||||
fakeUnifiedPushHelper.verifyRegister(fragmentActivity)
|
|
||||||
fakeFcmHelper.verifyEnsureFcmTokenIsRetrieved(fragmentActivity, fakePushersManager.instance, registerPusher = true)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `given toggle via Pusher is possible when execute then current pusher is toggled to true`() = runTest {
|
|
||||||
// Given
|
|
||||||
val fragmentActivity = mockk<FragmentActivity>()
|
|
||||||
fakePushersManager.givenGetPusherForCurrentSessionReturns(mockk())
|
|
||||||
val fakeSession = fakeActiveSessionHolder.fakeSession
|
val fakeSession = fakeActiveSessionHolder.fakeSession
|
||||||
fakeSession.givenSessionId(A_SESSION_ID)
|
fakeSession.givenSessionId(A_SESSION_ID)
|
||||||
every { fakeCheckIfCanTogglePushNotificationsViaPusherUseCase.execute(fakeActiveSessionHolder.fakeSession) } returns true
|
fakePushersManager.givenGetPusherForCurrentSessionReturns(null)
|
||||||
|
every { fakeRegisterUnifiedPushUseCase.execute(any()) } returns RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.Success
|
||||||
|
justRun { fakeEnsureFcmTokenIsRetrievedUseCase.execute(any(), any()) }
|
||||||
coJustRun { fakeTogglePushNotificationUseCase.execute(A_SESSION_ID, any()) }
|
coJustRun { fakeTogglePushNotificationUseCase.execute(A_SESSION_ID, any()) }
|
||||||
|
|
||||||
// When
|
// When
|
||||||
enableNotificationsForCurrentSessionUseCase.execute(fragmentActivity)
|
val result = enableNotificationsForCurrentSessionUseCase.execute(aDistributor)
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
coVerify { fakeTogglePushNotificationUseCase.execute(A_SESSION_ID, true) }
|
result shouldBe EnableNotificationsForCurrentSessionUseCase.EnableNotificationsResult.Success
|
||||||
|
verify {
|
||||||
|
fakeRegisterUnifiedPushUseCase.execute(aDistributor)
|
||||||
|
fakeEnsureFcmTokenIsRetrievedUseCase.execute(fakePushersManager.instance, registerPusher = true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `given no existing pusher and a no registered distributor when execute then result is need to ask user for distributor`() = runTest {
|
||||||
|
// Given
|
||||||
|
val aDistributor = "distributor"
|
||||||
|
fakePushersManager.givenGetPusherForCurrentSessionReturns(null)
|
||||||
|
every { fakeRegisterUnifiedPushUseCase.execute(any()) } returns RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.NeedToAskUserForDistributor
|
||||||
|
|
||||||
|
// When
|
||||||
|
val result = enableNotificationsForCurrentSessionUseCase.execute(aDistributor)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
result shouldBe EnableNotificationsForCurrentSessionUseCase.EnableNotificationsResult.NeedToAskUserForDistributor
|
||||||
|
verify {
|
||||||
|
fakeRegisterUnifiedPushUseCase.execute(aDistributor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `given no deviceId for current session when execute then result is failure`() = runTest {
|
||||||
|
// Given
|
||||||
|
val aDistributor = "distributor"
|
||||||
|
val fakeSession = fakeActiveSessionHolder.fakeSession
|
||||||
|
fakeSession.givenSessionId(null)
|
||||||
|
fakePushersManager.givenGetPusherForCurrentSessionReturns(mockk())
|
||||||
|
every { fakeRegisterUnifiedPushUseCase.execute(any()) } returns RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.NeedToAskUserForDistributor
|
||||||
|
|
||||||
|
// When
|
||||||
|
val result = enableNotificationsForCurrentSessionUseCase.execute(aDistributor)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
result shouldBe EnableNotificationsForCurrentSessionUseCase.EnableNotificationsResult.Failure
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,202 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.app.features.settings.notifications
|
||||||
|
|
||||||
|
import com.airbnb.mvrx.test.MavericksTestRule
|
||||||
|
import im.vector.app.core.platform.VectorDummyViewState
|
||||||
|
import im.vector.app.core.pushers.EnsureFcmTokenIsRetrievedUseCase
|
||||||
|
import im.vector.app.core.pushers.RegisterUnifiedPushUseCase
|
||||||
|
import im.vector.app.core.pushers.UnregisterUnifiedPushUseCase
|
||||||
|
import im.vector.app.test.fakes.FakePushersManager
|
||||||
|
import im.vector.app.test.fakes.FakeVectorPreferences
|
||||||
|
import im.vector.app.test.test
|
||||||
|
import im.vector.app.test.testDispatcher
|
||||||
|
import io.mockk.coEvery
|
||||||
|
import io.mockk.coJustRun
|
||||||
|
import io.mockk.coVerify
|
||||||
|
import io.mockk.coVerifyOrder
|
||||||
|
import io.mockk.justRun
|
||||||
|
import io.mockk.mockk
|
||||||
|
import org.junit.Rule
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class VectorSettingsNotificationPreferenceViewModelTest {
|
||||||
|
|
||||||
|
@get:Rule
|
||||||
|
val mavericksTestRule = MavericksTestRule(testDispatcher = testDispatcher)
|
||||||
|
|
||||||
|
private val fakePushersManager = FakePushersManager()
|
||||||
|
private val fakeVectorPreferences = FakeVectorPreferences()
|
||||||
|
private val fakeEnableNotificationsForCurrentSessionUseCase = mockk<EnableNotificationsForCurrentSessionUseCase>()
|
||||||
|
private val fakeDisableNotificationsForCurrentSessionUseCase = mockk<DisableNotificationsForCurrentSessionUseCase>()
|
||||||
|
private val fakeUnregisterUnifiedPushUseCase = mockk<UnregisterUnifiedPushUseCase>()
|
||||||
|
private val fakeRegisterUnifiedPushUseCase = mockk<RegisterUnifiedPushUseCase>()
|
||||||
|
private val fakeEnsureFcmTokenIsRetrievedUseCase = mockk<EnsureFcmTokenIsRetrievedUseCase>()
|
||||||
|
|
||||||
|
private fun createViewModel() = VectorSettingsNotificationPreferenceViewModel(
|
||||||
|
initialState = VectorDummyViewState(),
|
||||||
|
pushersManager = fakePushersManager.instance,
|
||||||
|
vectorPreferences = fakeVectorPreferences.instance,
|
||||||
|
enableNotificationsForCurrentSessionUseCase = fakeEnableNotificationsForCurrentSessionUseCase,
|
||||||
|
disableNotificationsForCurrentSessionUseCase = fakeDisableNotificationsForCurrentSessionUseCase,
|
||||||
|
unregisterUnifiedPushUseCase = fakeUnregisterUnifiedPushUseCase,
|
||||||
|
registerUnifiedPushUseCase = fakeRegisterUnifiedPushUseCase,
|
||||||
|
ensureFcmTokenIsRetrievedUseCase = fakeEnsureFcmTokenIsRetrievedUseCase,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `given DisableNotificationsForDevice action when handling action then disable use case is called`() {
|
||||||
|
// Given
|
||||||
|
val viewModel = createViewModel()
|
||||||
|
val action = VectorSettingsNotificationPreferenceViewAction.DisableNotificationsForDevice
|
||||||
|
coJustRun { fakeDisableNotificationsForCurrentSessionUseCase.execute() }
|
||||||
|
val expectedEvent = VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceDisabled
|
||||||
|
|
||||||
|
// When
|
||||||
|
val viewModelTest = viewModel.test()
|
||||||
|
viewModel.handle(action)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
viewModelTest
|
||||||
|
.assertEvent { event -> event == expectedEvent }
|
||||||
|
.finish()
|
||||||
|
coVerify {
|
||||||
|
fakeDisableNotificationsForCurrentSessionUseCase.execute()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `given EnableNotificationsForDevice action and enable success when handling action then enable use case is called`() {
|
||||||
|
// Given
|
||||||
|
val viewModel = createViewModel()
|
||||||
|
val aDistributor = "aDistributor"
|
||||||
|
val action = VectorSettingsNotificationPreferenceViewAction.EnableNotificationsForDevice(aDistributor)
|
||||||
|
coEvery { fakeEnableNotificationsForCurrentSessionUseCase.execute(any()) } returns
|
||||||
|
EnableNotificationsForCurrentSessionUseCase.EnableNotificationsResult.Success
|
||||||
|
val expectedEvent = VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceEnabled
|
||||||
|
|
||||||
|
// When
|
||||||
|
val viewModelTest = viewModel.test()
|
||||||
|
viewModel.handle(action)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
viewModelTest
|
||||||
|
.assertEvent { event -> event == expectedEvent }
|
||||||
|
.finish()
|
||||||
|
coVerify {
|
||||||
|
fakeEnableNotificationsForCurrentSessionUseCase.execute(aDistributor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `given EnableNotificationsForDevice action and enable needs user choice when handling action then enable use case is called`() {
|
||||||
|
// Given
|
||||||
|
val viewModel = createViewModel()
|
||||||
|
val aDistributor = "aDistributor"
|
||||||
|
val action = VectorSettingsNotificationPreferenceViewAction.EnableNotificationsForDevice(aDistributor)
|
||||||
|
coEvery { fakeEnableNotificationsForCurrentSessionUseCase.execute(any()) } returns
|
||||||
|
EnableNotificationsForCurrentSessionUseCase.EnableNotificationsResult.NeedToAskUserForDistributor
|
||||||
|
val expectedEvent = VectorSettingsNotificationPreferenceViewEvent.AskUserForPushDistributor
|
||||||
|
|
||||||
|
// When
|
||||||
|
val viewModelTest = viewModel.test()
|
||||||
|
viewModel.handle(action)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
viewModelTest
|
||||||
|
.assertEvent { event -> event == expectedEvent }
|
||||||
|
.finish()
|
||||||
|
coVerify {
|
||||||
|
fakeEnableNotificationsForCurrentSessionUseCase.execute(aDistributor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `given EnableNotificationsForDevice action and enable failure when handling action then enable use case is called`() {
|
||||||
|
// Given
|
||||||
|
val viewModel = createViewModel()
|
||||||
|
val aDistributor = "aDistributor"
|
||||||
|
val action = VectorSettingsNotificationPreferenceViewAction.EnableNotificationsForDevice(aDistributor)
|
||||||
|
coEvery { fakeEnableNotificationsForCurrentSessionUseCase.execute(any()) } returns
|
||||||
|
EnableNotificationsForCurrentSessionUseCase.EnableNotificationsResult.Failure
|
||||||
|
val expectedEvent = VectorSettingsNotificationPreferenceViewEvent.EnableNotificationForDeviceFailure
|
||||||
|
|
||||||
|
// When
|
||||||
|
val viewModelTest = viewModel.test()
|
||||||
|
viewModel.handle(action)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
viewModelTest
|
||||||
|
.assertEvent { event -> event == expectedEvent }
|
||||||
|
.finish()
|
||||||
|
coVerify {
|
||||||
|
fakeEnableNotificationsForCurrentSessionUseCase.execute(aDistributor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `given RegisterPushDistributor action and register success when handling action then register use case is called`() {
|
||||||
|
// Given
|
||||||
|
val viewModel = createViewModel()
|
||||||
|
val aDistributor = "aDistributor"
|
||||||
|
val action = VectorSettingsNotificationPreferenceViewAction.RegisterPushDistributor(aDistributor)
|
||||||
|
coEvery { fakeRegisterUnifiedPushUseCase.execute(any()) } returns RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.Success
|
||||||
|
coJustRun { fakeUnregisterUnifiedPushUseCase.execute(any()) }
|
||||||
|
val areNotificationsEnabled = true
|
||||||
|
fakeVectorPreferences.givenAreNotificationsEnabledForDevice(areNotificationsEnabled)
|
||||||
|
justRun { fakeEnsureFcmTokenIsRetrievedUseCase.execute(any(), any()) }
|
||||||
|
val expectedEvent = VectorSettingsNotificationPreferenceViewEvent.NotificationMethodChanged
|
||||||
|
|
||||||
|
// When
|
||||||
|
val viewModelTest = viewModel.test()
|
||||||
|
viewModel.handle(action)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
viewModelTest
|
||||||
|
.assertEvent { event -> event == expectedEvent }
|
||||||
|
.finish()
|
||||||
|
coVerifyOrder {
|
||||||
|
fakeUnregisterUnifiedPushUseCase.execute(fakePushersManager.instance)
|
||||||
|
fakeRegisterUnifiedPushUseCase.execute(aDistributor)
|
||||||
|
fakeEnsureFcmTokenIsRetrievedUseCase.execute(fakePushersManager.instance, registerPusher = areNotificationsEnabled)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `given RegisterPushDistributor action and register needs user choice when handling action then register use case is called`() {
|
||||||
|
// Given
|
||||||
|
val viewModel = createViewModel()
|
||||||
|
val aDistributor = "aDistributor"
|
||||||
|
val action = VectorSettingsNotificationPreferenceViewAction.RegisterPushDistributor(aDistributor)
|
||||||
|
coEvery { fakeRegisterUnifiedPushUseCase.execute(any()) } returns RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.NeedToAskUserForDistributor
|
||||||
|
coJustRun { fakeUnregisterUnifiedPushUseCase.execute(any()) }
|
||||||
|
val expectedEvent = VectorSettingsNotificationPreferenceViewEvent.AskUserForPushDistributor
|
||||||
|
|
||||||
|
// When
|
||||||
|
val viewModelTest = viewModel.test()
|
||||||
|
viewModel.handle(action)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
viewModelTest
|
||||||
|
.assertEvent { event -> event == expectedEvent }
|
||||||
|
.finish()
|
||||||
|
coVerifyOrder {
|
||||||
|
fakeUnregisterUnifiedPushUseCase.execute(fakePushersManager.instance)
|
||||||
|
fakeRegisterUnifiedPushUseCase.execute(aDistributor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -81,4 +81,8 @@ class FakeContext(
|
||||||
givenService(Context.CLIPBOARD_SERVICE, ClipboardManager::class.java, fakeClipboardManager.instance)
|
givenService(Context.CLIPBOARD_SERVICE, ClipboardManager::class.java, fakeClipboardManager.instance)
|
||||||
return fakeClipboardManager
|
return fakeClipboardManager
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun givenPackageName(name: String) {
|
||||||
|
every { instance.packageName } returns name
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
package im.vector.app.test.fakes
|
package im.vector.app.test.fakes
|
||||||
|
|
||||||
import androidx.fragment.app.FragmentActivity
|
|
||||||
import im.vector.app.core.pushers.FcmHelper
|
import im.vector.app.core.pushers.FcmHelper
|
||||||
import im.vector.app.core.pushers.PushersManager
|
import im.vector.app.core.pushers.PushersManager
|
||||||
import io.mockk.justRun
|
import io.mockk.justRun
|
||||||
|
@ -27,18 +26,15 @@ class FakeFcmHelper {
|
||||||
|
|
||||||
val instance = mockk<FcmHelper>()
|
val instance = mockk<FcmHelper>()
|
||||||
|
|
||||||
fun givenEnsureFcmTokenIsRetrieved(
|
fun givenEnsureFcmTokenIsRetrieved(pushersManager: PushersManager) {
|
||||||
fragmentActivity: FragmentActivity,
|
justRun { instance.ensureFcmTokenIsRetrieved(pushersManager, any()) }
|
||||||
pushersManager: PushersManager,
|
|
||||||
) {
|
|
||||||
justRun { instance.ensureFcmTokenIsRetrieved(fragmentActivity, pushersManager, any()) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun verifyEnsureFcmTokenIsRetrieved(
|
fun verifyEnsureFcmTokenIsRetrieved(
|
||||||
fragmentActivity: FragmentActivity,
|
|
||||||
pushersManager: PushersManager,
|
pushersManager: PushersManager,
|
||||||
registerPusher: Boolean,
|
registerPusher: Boolean,
|
||||||
|
inverse: Boolean = false,
|
||||||
) {
|
) {
|
||||||
verify { instance.ensureFcmTokenIsRetrieved(fragmentActivity, pushersManager, registerPusher) }
|
verify(inverse = inverse) { instance.ensureFcmTokenIsRetrieved(pushersManager, registerPusher) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
package im.vector.app.test.fakes
|
package im.vector.app.test.fakes
|
||||||
|
|
||||||
import im.vector.app.core.pushers.PushersManager
|
import im.vector.app.core.pushers.PushersManager
|
||||||
|
import io.mockk.coJustRun
|
||||||
|
import io.mockk.coVerify
|
||||||
import io.mockk.every
|
import io.mockk.every
|
||||||
import io.mockk.mockk
|
import io.mockk.mockk
|
||||||
import org.matrix.android.sdk.api.session.pushers.Pusher
|
import org.matrix.android.sdk.api.session.pushers.Pusher
|
||||||
|
@ -28,4 +30,12 @@ class FakePushersManager {
|
||||||
fun givenGetPusherForCurrentSessionReturns(pusher: Pusher?) {
|
fun givenGetPusherForCurrentSessionReturns(pusher: Pusher?) {
|
||||||
every { instance.getPusherForCurrentSession() } returns pusher
|
every { instance.getPusherForCurrentSession() } returns pusher
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun givenUnregisterPusher(pushKey: String) {
|
||||||
|
coJustRun { instance.unregisterPusher(pushKey) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun verifyUnregisterPusher(pushKey: String) {
|
||||||
|
coVerify { instance.unregisterPusher(pushKey) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,38 +16,19 @@
|
||||||
|
|
||||||
package im.vector.app.test.fakes
|
package im.vector.app.test.fakes
|
||||||
|
|
||||||
import androidx.fragment.app.FragmentActivity
|
|
||||||
import im.vector.app.core.pushers.PushersManager
|
|
||||||
import im.vector.app.core.pushers.UnifiedPushHelper
|
import im.vector.app.core.pushers.UnifiedPushHelper
|
||||||
import io.mockk.coJustRun
|
|
||||||
import io.mockk.coVerify
|
|
||||||
import io.mockk.every
|
import io.mockk.every
|
||||||
import io.mockk.mockk
|
import io.mockk.mockk
|
||||||
import io.mockk.verify
|
|
||||||
|
|
||||||
class FakeUnifiedPushHelper {
|
class FakeUnifiedPushHelper {
|
||||||
|
|
||||||
val instance = mockk<UnifiedPushHelper>()
|
val instance = mockk<UnifiedPushHelper>()
|
||||||
|
|
||||||
fun givenRegister(fragmentActivity: FragmentActivity) {
|
|
||||||
every { instance.register(fragmentActivity, any()) } answers {
|
|
||||||
secondArg<Runnable>().run()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun verifyRegister(fragmentActivity: FragmentActivity) {
|
|
||||||
verify { instance.register(fragmentActivity, any()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenUnregister(pushersManager: PushersManager) {
|
|
||||||
coJustRun { instance.unregister(pushersManager) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun verifyUnregister(pushersManager: PushersManager) {
|
|
||||||
coVerify { instance.unregister(pushersManager) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun givenIsEmbeddedDistributorReturns(isEmbedded: Boolean) {
|
fun givenIsEmbeddedDistributorReturns(isEmbedded: Boolean) {
|
||||||
every { instance.isEmbeddedDistributor() } returns isEmbedded
|
every { instance.isEmbeddedDistributor() } returns isEmbedded
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun givenGetEndpointOrTokenReturns(endpoint: String?) {
|
||||||
|
every { instance.getEndpointOrToken() } returns endpoint
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.app.test.fakes
|
||||||
|
|
||||||
|
import im.vector.app.core.pushers.UnifiedPushStore
|
||||||
|
import io.mockk.justRun
|
||||||
|
import io.mockk.mockk
|
||||||
|
import io.mockk.verify
|
||||||
|
|
||||||
|
class FakeUnifiedPushStore {
|
||||||
|
|
||||||
|
val instance = mockk<UnifiedPushStore>()
|
||||||
|
|
||||||
|
fun givenStoreUpEndpoint(endpoint: String?) {
|
||||||
|
justRun { instance.storeUpEndpoint(endpoint) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun verifyStoreUpEndpoint(endpoint: String?) {
|
||||||
|
verify { instance.storeUpEndpoint(endpoint) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun givenStorePushGateway(gateway: String?) {
|
||||||
|
justRun { instance.storePushGateway(gateway) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun verifyStorePushGateway(gateway: String?) {
|
||||||
|
verify { instance.storePushGateway(gateway) }
|
||||||
|
}
|
||||||
|
}
|
|
@ -54,4 +54,8 @@ class FakeVectorFeatures : VectorFeatures by spyk<DefaultVectorFeatures>() {
|
||||||
fun givenUnverifiedSessionsAlertEnabled(isEnabled: Boolean) {
|
fun givenUnverifiedSessionsAlertEnabled(isEnabled: Boolean) {
|
||||||
every { isUnverifiedSessionsAlertEnabled() } returns isEnabled
|
every { isUnverifiedSessionsAlertEnabled() } returns isEnabled
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun givenExternalDistributorsAreAllowed(allowed: Boolean) {
|
||||||
|
every { allowExternalUnifiedPushDistributors() } returns allowed
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
package im.vector.app.test.fakes
|
package im.vector.app.test.fakes
|
||||||
|
|
||||||
|
import im.vector.app.features.settings.BackgroundSyncMode
|
||||||
import im.vector.app.features.settings.VectorPreferences
|
import im.vector.app.features.settings.VectorPreferences
|
||||||
import io.mockk.every
|
import io.mockk.every
|
||||||
import io.mockk.justRun
|
import io.mockk.justRun
|
||||||
|
@ -60,4 +61,16 @@ class FakeVectorPreferences {
|
||||||
fun givenUnverifiedSessionsAlertLastShownMillis(lastShownMillis: Long) {
|
fun givenUnverifiedSessionsAlertLastShownMillis(lastShownMillis: Long) {
|
||||||
every { instance.getUnverifiedSessionsAlertLastShownMillis(any()) } returns lastShownMillis
|
every { instance.getUnverifiedSessionsAlertLastShownMillis(any()) } returns lastShownMillis
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun givenSetFdroidSyncBackgroundMode(mode: BackgroundSyncMode) {
|
||||||
|
justRun { instance.setFdroidSyncBackgroundMode(mode) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun verifySetFdroidSyncBackgroundMode(mode: BackgroundSyncMode) {
|
||||||
|
verify { instance.setFdroidSyncBackgroundMode(mode) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun givenAreNotificationsEnabledForDevice(notificationsEnabled: Boolean) {
|
||||||
|
every { instance.areNotificationEnabledForDevice() } returns notificationsEnabled
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue