mirror of
https://github.com/element-hq/element-android
synced 2024-11-27 03:48:12 +03:00
Adding new use cases to handle the Unified push registration
This commit is contained in:
parent
9456789047
commit
4dbca7858c
14 changed files with 271 additions and 82 deletions
|
@ -17,7 +17,6 @@
|
|||
|
||||
package im.vector.app.push.fcm
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import im.vector.app.core.di.ActiveSessionHolder
|
||||
import im.vector.app.core.pushers.FcmHelper
|
||||
|
@ -44,7 +43,7 @@ class FdroidFcmHelper @Inject constructor(
|
|||
// No op
|
||||
}
|
||||
|
||||
override fun ensureFcmTokenIsRetrieved(activity: Activity, pushersManager: PushersManager, registerPusher: Boolean) {
|
||||
override fun ensureFcmTokenIsRetrieved(pushersManager: PushersManager, registerPusher: Boolean) {
|
||||
// No op
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
*/
|
||||
package im.vector.app.push.fcm
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
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.GoogleApiAvailability
|
||||
import com.google.firebase.messaging.FirebaseMessaging
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.di.ActiveSessionHolder
|
||||
import im.vector.app.core.di.DefaultPreferences
|
||||
|
@ -36,8 +36,8 @@ import javax.inject.Inject
|
|||
* It has an alter ego in the fdroid variant.
|
||||
*/
|
||||
class GoogleFcmHelper @Inject constructor(
|
||||
@DefaultPreferences
|
||||
private val sharedPrefs: SharedPreferences,
|
||||
@ApplicationContext private val context: Context,
|
||||
@DefaultPreferences private val sharedPrefs: SharedPreferences,
|
||||
) : FcmHelper {
|
||||
companion object {
|
||||
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) {
|
||||
// if (TextUtils.isEmpty(getFcmToken(activity))) {
|
||||
override fun ensureFcmTokenIsRetrieved(pushersManager: PushersManager, registerPusher: Boolean) {
|
||||
// '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 {
|
||||
FirebaseMessaging.getInstance().token
|
||||
.addOnSuccessListener { token ->
|
||||
|
@ -75,7 +74,7 @@ class GoogleFcmHelper @Inject constructor(
|
|||
Timber.e(e, "## ensureFcmTokenIsRetrieved() : failed")
|
||||
}
|
||||
} 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.")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* 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 timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
class EnsureFcmTokenIsRetrievedUseCase @Inject constructor(
|
||||
private val unifiedPushHelper: UnifiedPushHelper,
|
||||
private val fcmHelper: FcmHelper,
|
||||
private val activeSessionHolder: ActiveSessionHolder,
|
||||
) {
|
||||
|
||||
// TODO add unit tests
|
||||
fun execute(pushersManager: PushersManager, registerPusher: Boolean) {
|
||||
if (unifiedPushHelper.isEmbeddedDistributor()) {
|
||||
Timber.d("ensureFcmTokenIsRetrieved")
|
||||
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
|
||||
}
|
||||
}
|
|
@ -39,11 +39,10 @@ interface FcmHelper {
|
|||
/**
|
||||
* 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 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)
|
||||
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* 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
|
||||
data class NeedToAskUserForDistributor(val distributors: List<String>) : RegisterUnifiedPushResult
|
||||
}
|
||||
|
||||
// TODO add unit tests
|
||||
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(distributors)
|
||||
}
|
||||
}
|
||||
|
||||
private fun saveAndRegisterApp(distributor: String) {
|
||||
UnifiedPush.saveDistributor(context, distributor)
|
||||
registerApp()
|
||||
}
|
||||
|
||||
private fun registerApp() {
|
||||
UnifiedPush.registerApp(context)
|
||||
}
|
||||
}
|
|
@ -17,6 +17,7 @@
|
|||
package im.vector.app.core.pushers
|
||||
|
||||
import android.content.Context
|
||||
import androidx.annotation.MainThread
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
|
@ -28,7 +29,9 @@ 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.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.matrix.android.sdk.api.Matrix
|
||||
import org.matrix.android.sdk.api.cache.CacheStrategy
|
||||
import org.matrix.android.sdk.api.util.MatrixJsonParser
|
||||
|
@ -49,6 +52,7 @@ class UnifiedPushHelper @Inject constructor(
|
|||
|
||||
// Called when the home activity starts
|
||||
// or when notifications are enabled
|
||||
// TODO remove and replace by use case
|
||||
fun register(
|
||||
activity: FragmentActivity,
|
||||
onDoneRunnable: Runnable? = null,
|
||||
|
@ -66,10 +70,11 @@ class UnifiedPushHelper @Inject constructor(
|
|||
// The registration is forced in 2 cases :
|
||||
// * in the settings
|
||||
// * in the troubleshoot list (doFix)
|
||||
// TODO remove and replace by use case
|
||||
fun forceRegister(
|
||||
activity: FragmentActivity,
|
||||
pushersManager: PushersManager,
|
||||
onDoneRunnable: Runnable? = null
|
||||
@MainThread onDoneRunnable: Runnable? = null
|
||||
) {
|
||||
registerInternal(
|
||||
activity,
|
||||
|
@ -79,17 +84,21 @@ class UnifiedPushHelper @Inject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
// TODO remove
|
||||
private fun registerInternal(
|
||||
activity: FragmentActivity,
|
||||
force: Boolean = false,
|
||||
pushersManager: PushersManager? = null,
|
||||
onDoneRunnable: Runnable? = null
|
||||
) {
|
||||
activity.lifecycleScope.launch {
|
||||
activity.lifecycleScope.launch(Dispatchers.IO) {
|
||||
Timber.d("registerInternal force=$force, $activity on thread ${Thread.currentThread()}")
|
||||
if (!vectorFeatures.allowExternalUnifiedPushDistributors()) {
|
||||
UnifiedPush.saveDistributor(context, context.packageName)
|
||||
UnifiedPush.registerApp(context)
|
||||
onDoneRunnable?.run()
|
||||
withContext(Dispatchers.Main) {
|
||||
onDoneRunnable?.run()
|
||||
}
|
||||
return@launch
|
||||
}
|
||||
if (force) {
|
||||
|
@ -99,7 +108,9 @@ class UnifiedPushHelper @Inject constructor(
|
|||
// the !force should not be needed
|
||||
if (!force && UnifiedPush.getDistributor(context).isNotEmpty()) {
|
||||
UnifiedPush.registerApp(context)
|
||||
onDoneRunnable?.run()
|
||||
withContext(Dispatchers.Main) {
|
||||
onDoneRunnable?.run()
|
||||
}
|
||||
return@launch
|
||||
}
|
||||
|
||||
|
@ -108,7 +119,9 @@ class UnifiedPushHelper @Inject constructor(
|
|||
if (!force && distributors.size == 1) {
|
||||
UnifiedPush.saveDistributor(context, distributors.first())
|
||||
UnifiedPush.registerApp(context)
|
||||
onDoneRunnable?.run()
|
||||
withContext(Dispatchers.Main) {
|
||||
onDoneRunnable?.run()
|
||||
}
|
||||
} else {
|
||||
openDistributorDialogInternal(
|
||||
activity = activity,
|
||||
|
@ -164,6 +177,43 @@ class UnifiedPushHelper @Inject constructor(
|
|||
.show()
|
||||
}
|
||||
|
||||
@MainThread
|
||||
fun showSelectDistributorDialog(
|
||||
context: Context,
|
||||
distributors: List<String>,
|
||||
onDistributorSelected: (String) -> Unit,
|
||||
) {
|
||||
val internalDistributorName = stringProvider.getString(
|
||||
if (fcmHelper.isFirebaseAvailable()) {
|
||||
R.string.unifiedpush_distributor_fcm_fallback
|
||||
} else {
|
||||
R.string.unifiedpush_distributor_background_sync
|
||||
}
|
||||
)
|
||||
|
||||
val distributorsName = distributors.map {
|
||||
if (it == context.packageName) {
|
||||
internalDistributorName
|
||||
} else {
|
||||
context.getApplicationLabel(it)
|
||||
}
|
||||
}
|
||||
|
||||
MaterialAlertDialogBuilder(context)
|
||||
.setTitle(stringProvider.getString(R.string.unifiedpush_getdistributors_dialog_title))
|
||||
.setItems(distributorsName.toTypedArray()) { _, which ->
|
||||
val distributor = distributors[which]
|
||||
onDistributorSelected(distributor)
|
||||
}
|
||||
.setOnCancelListener {
|
||||
// By default, use internal solution (fcm/background sync)
|
||||
onDistributorSelected(context.packageName)
|
||||
}
|
||||
.setCancelable(true)
|
||||
.show()
|
||||
}
|
||||
|
||||
// TODO remove and replace by use case
|
||||
suspend fun unregister(pushersManager: PushersManager? = null) {
|
||||
val mode = BackgroundSyncMode.FDROID_BACKGROUND_SYNC_MODE_FOR_REALTIME
|
||||
vectorPreferences.setFdroidSyncBackgroundMode(mode)
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* 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 pushersManager: PushersManager,
|
||||
private val vectorPreferences: VectorPreferences,
|
||||
private val unifiedPushStore: UnifiedPushStore,
|
||||
private val unifiedPushHelper: UnifiedPushHelper,
|
||||
) {
|
||||
|
||||
// TODO add unit tests
|
||||
suspend fun execute() {
|
||||
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.platform.VectorBaseActivity
|
||||
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.utils.registerForPermissionsResult
|
||||
import im.vector.app.core.utils.startSharePlainTextIntent
|
||||
|
@ -128,7 +126,6 @@ class HomeActivity :
|
|||
private val serverBackupStatusViewModel: ServerBackupStatusViewModel by viewModel()
|
||||
|
||||
@Inject lateinit var vectorUncaughtExceptionHandler: VectorUncaughtExceptionHandler
|
||||
@Inject lateinit var pushersManager: PushersManager
|
||||
@Inject lateinit var notificationDrawerManager: NotificationDrawerManager
|
||||
@Inject lateinit var popupAlertManager: PopupAlertManager
|
||||
@Inject lateinit var shortcutsHandler: ShortcutsHandler
|
||||
|
@ -137,7 +134,6 @@ class HomeActivity :
|
|||
@Inject lateinit var initSyncStepFormatter: InitSyncStepFormatter
|
||||
@Inject lateinit var spaceStateHandler: SpaceStateHandler
|
||||
@Inject lateinit var unifiedPushHelper: UnifiedPushHelper
|
||||
@Inject lateinit var fcmHelper: FcmHelper
|
||||
@Inject lateinit var nightlyProxy: NightlyProxy
|
||||
@Inject lateinit var disclaimerDialog: DisclaimerDialog
|
||||
@Inject lateinit var notificationPermissionManager: NotificationPermissionManager
|
||||
|
@ -209,16 +205,6 @@ class HomeActivity :
|
|||
isNewAppLayoutEnabled = vectorPreferences.isNewAppLayoutEnabled()
|
||||
analyticsScreenName = MobileScreen.ScreenName.Home
|
||||
supportFragmentManager.registerFragmentLifecycleCallbacks(fragmentLifecycleCallbacks, false)
|
||||
unifiedPushHelper.register(this) {
|
||||
if (unifiedPushHelper.isEmbeddedDistributor()) {
|
||||
fcmHelper.ensureFcmTokenIsRetrieved(
|
||||
this,
|
||||
pushersManager,
|
||||
homeActivityViewModel.shouldAddHttpPusher()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
sharedActionViewModel = viewModelProvider[HomeSharedActionViewModel::class.java]
|
||||
roomListSharedActionViewModel = viewModelProvider[RoomListSharedActionViewModel::class.java]
|
||||
views.drawerLayout.addDrawerListener(drawerListener)
|
||||
|
@ -280,6 +266,7 @@ class HomeActivity :
|
|||
HomeActivityViewEvents.ShowReleaseNotes -> handleShowReleaseNotes()
|
||||
HomeActivityViewEvents.NotifyUserForThreadsMigration -> handleNotifyUserForThreadsMigration()
|
||||
is HomeActivityViewEvents.MigrateThreads -> migrateThreadsIfNeeded(it.checkSession)
|
||||
is HomeActivityViewEvents.AskUserForPushDistributor -> askUserToSelectPushDistributor(it.distributors)
|
||||
}
|
||||
}
|
||||
homeActivityViewModel.onEach { renderState(it) }
|
||||
|
@ -292,6 +279,12 @@ class HomeActivity :
|
|||
homeActivityViewModel.handle(HomeActivityViewActions.ViewStarted)
|
||||
}
|
||||
|
||||
private fun askUserToSelectPushDistributor(distributors: List<String>) {
|
||||
unifiedPushHelper.showSelectDistributorDialog(this, distributors) { selection ->
|
||||
homeActivityViewModel.handle(HomeActivityViewActions.RegisterPushDistributor(selection))
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleShowNotificationDialog() {
|
||||
notificationPermissionManager.eventuallyRequestPermission(this, postPermissionLauncher)
|
||||
}
|
||||
|
@ -415,14 +408,6 @@ class HomeActivity :
|
|||
}
|
||||
|
||||
private fun renderState(state: HomeActivityViewState) {
|
||||
lifecycleScope.launch {
|
||||
if (state.areNotificationsSilenced) {
|
||||
unifiedPushHelper.unregister(pushersManager)
|
||||
} else {
|
||||
unifiedPushHelper.register(this@HomeActivity)
|
||||
}
|
||||
}
|
||||
|
||||
when (val status = state.syncRequestState) {
|
||||
is SyncRequestState.InitialSyncProgressing -> {
|
||||
val initSyncStepStr = initSyncStepFormatter.format(status.initialSyncStep)
|
||||
|
|
|
@ -21,4 +21,5 @@ import im.vector.app.core.platform.VectorViewModelAction
|
|||
sealed interface HomeActivityViewActions : VectorViewModelAction {
|
||||
object ViewStarted : HomeActivityViewActions
|
||||
object PushPromptHasBeenReviewed : HomeActivityViewActions
|
||||
data class RegisterPushDistributor(val distributor: String) : HomeActivityViewActions
|
||||
}
|
||||
|
|
|
@ -25,9 +25,11 @@ sealed interface HomeActivityViewEvents : VectorViewEvents {
|
|||
val userItem: MatrixItem.UserItem,
|
||||
val waitForIncomingRequest: Boolean = true,
|
||||
) : HomeActivityViewEvents
|
||||
|
||||
data class CurrentSessionCannotBeVerified(
|
||||
val userItem: MatrixItem.UserItem,
|
||||
) : HomeActivityViewEvents
|
||||
|
||||
data class OnCrossSignedInvalidated(val userItem: MatrixItem.UserItem) : HomeActivityViewEvents
|
||||
object PromptToEnableSessionPush : HomeActivityViewEvents
|
||||
object ShowAnalyticsOptIn : HomeActivityViewEvents
|
||||
|
@ -37,4 +39,5 @@ sealed interface HomeActivityViewEvents : VectorViewEvents {
|
|||
data class MigrateThreads(val checkSession: Boolean) : HomeActivityViewEvents
|
||||
object StartRecoverySetupFlow : HomeActivityViewEvents
|
||||
data class ForceVerification(val sendRequest: Boolean) : HomeActivityViewEvents
|
||||
data class AskUserForPushDistributor(val distributors: List<String>) : HomeActivityViewEvents
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
package im.vector.app.features.home
|
||||
|
||||
import androidx.lifecycle.asFlow
|
||||
import com.airbnb.mvrx.Mavericks
|
||||
import com.airbnb.mvrx.MavericksViewModelFactory
|
||||
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.hiltMavericksViewModelFactory
|
||||
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.AnalyticsTracker
|
||||
import im.vector.app.features.analytics.extensions.toAnalyticsType
|
||||
|
@ -48,12 +49,10 @@ import kotlinx.coroutines.Dispatchers
|
|||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onCompletion
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.takeWhile
|
||||
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.UserInteractiveAuthInterceptor
|
||||
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.extensions.tryOrNull
|
||||
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.model.CryptoDeviceInfo
|
||||
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.pushrules.RuleIds
|
||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||
|
@ -92,8 +89,10 @@ class HomeActivityViewModel @AssistedInject constructor(
|
|||
private val analyticsTracker: AnalyticsTracker,
|
||||
private val analyticsConfig: AnalyticsConfig,
|
||||
private val releaseNotesPreferencesStore: ReleaseNotesPreferencesStore,
|
||||
private val vectorFeatures: VectorFeatures,
|
||||
private val stopOngoingVoiceBroadcastUseCase: StopOngoingVoiceBroadcastUseCase,
|
||||
private val pushersManager: PushersManager,
|
||||
private val registerUnifiedPushUseCase: RegisterUnifiedPushUseCase,
|
||||
private val ensureFcmTokenIsRetrievedUseCase: EnsureFcmTokenIsRetrievedUseCase,
|
||||
) : VectorViewModel<HomeActivityViewState, HomeActivityViewActions, HomeActivityViewEvents>(initialState) {
|
||||
|
||||
@AssistedFactory
|
||||
|
@ -117,17 +116,32 @@ class HomeActivityViewModel @AssistedInject constructor(
|
|||
private fun initialize() {
|
||||
if (isInitialized) return
|
||||
isInitialized = true
|
||||
registerUnifiedPush(distributor = "")
|
||||
cleanupFiles()
|
||||
observeInitialSync()
|
||||
checkSessionPushIsOn()
|
||||
observeCrossSigningReset()
|
||||
observeAnalytics()
|
||||
observeReleaseNotes()
|
||||
observeLocalNotificationsSilenced()
|
||||
initThreadsMigration()
|
||||
viewModelScope.launch { stopOngoingVoiceBroadcastUseCase.execute() }
|
||||
}
|
||||
|
||||
private fun registerUnifiedPush(distributor: String) {
|
||||
viewModelScope.launch {
|
||||
when (val result = registerUnifiedPushUseCase.execute(distributor = distributor)) {
|
||||
is RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.NeedToAskUserForDistributor -> {
|
||||
Timber.d("registerUnifiedPush $distributor need to ask user")
|
||||
_viewEvents.post(HomeActivityViewEvents.AskUserForPushDistributor(result.distributors))
|
||||
}
|
||||
RegisterUnifiedPushUseCase.RegisterUnifiedPushResult.Success -> {
|
||||
Timber.d("registerUnifiedPush $distributor success")
|
||||
ensureFcmTokenIsRetrievedUseCase.execute(pushersManager, registerPusher = vectorPreferences.areNotificationEnabledForDevice())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun observeReleaseNotes() = withState { state ->
|
||||
if (vectorPreferences.isNewAppLayoutEnabled()) {
|
||||
// we don't want to show release notes for new users or after relogin
|
||||
|
@ -146,26 +160,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() {
|
||||
if (analyticsConfig.isEnabled) {
|
||||
analyticsStore.didAskUserConsentFlow
|
||||
|
@ -501,6 +495,9 @@ class HomeActivityViewModel @AssistedInject constructor(
|
|||
HomeActivityViewActions.ViewStarted -> {
|
||||
initialize()
|
||||
}
|
||||
is HomeActivityViewActions.RegisterPushDistributor -> {
|
||||
registerUnifiedPush(distributor = action.distributor)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,5 +23,4 @@ import org.matrix.android.sdk.api.session.sync.SyncRequestState
|
|||
data class HomeActivityViewState(
|
||||
val syncRequestState: SyncRequestState = SyncRequestState.Idle,
|
||||
val authenticationDescription: AuthenticationDescription? = null,
|
||||
val areNotificationsSilenced: Boolean = false,
|
||||
) : MavericksState
|
||||
|
|
|
@ -18,6 +18,7 @@ package im.vector.app.features.settings.notifications
|
|||
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import im.vector.app.core.di.ActiveSessionHolder
|
||||
import im.vector.app.core.pushers.EnsureFcmTokenIsRetrievedUseCase
|
||||
import im.vector.app.core.pushers.FcmHelper
|
||||
import im.vector.app.core.pushers.PushersManager
|
||||
import im.vector.app.core.pushers.UnifiedPushHelper
|
||||
|
@ -32,11 +33,12 @@ class EnableNotificationsForCurrentSessionUseCase @Inject constructor(
|
|||
private val activeSessionHolder: ActiveSessionHolder,
|
||||
private val unifiedPushHelper: UnifiedPushHelper,
|
||||
private val pushersManager: PushersManager,
|
||||
private val fcmHelper: FcmHelper,
|
||||
private val checkIfCanTogglePushNotificationsViaPusherUseCase: CheckIfCanTogglePushNotificationsViaPusherUseCase,
|
||||
private val togglePushNotificationUseCase: TogglePushNotificationUseCase,
|
||||
private val ensureFcmTokenIsRetrievedUseCase: EnsureFcmTokenIsRetrievedUseCase,
|
||||
) {
|
||||
|
||||
// TODO update unit tests
|
||||
suspend fun execute(fragmentActivity: FragmentActivity) {
|
||||
val pusherForCurrentSession = pushersManager.getPusherForCurrentSession()
|
||||
if (pusherForCurrentSession == null) {
|
||||
|
@ -54,13 +56,7 @@ class EnableNotificationsForCurrentSessionUseCase @Inject constructor(
|
|||
suspendCoroutine { continuation ->
|
||||
try {
|
||||
unifiedPushHelper.register(fragmentActivity) {
|
||||
if (unifiedPushHelper.isEmbeddedDistributor()) {
|
||||
fcmHelper.ensureFcmTokenIsRetrieved(
|
||||
fragmentActivity,
|
||||
pushersManager,
|
||||
registerPusher = true
|
||||
)
|
||||
}
|
||||
ensureFcmTokenIsRetrievedUseCase.execute(pushersManager, registerPusher = true)
|
||||
continuation.resume(Unit)
|
||||
}
|
||||
} catch (error: Exception) {
|
||||
|
|
|
@ -37,6 +37,7 @@ import im.vector.app.core.preference.VectorEditTextPreference
|
|||
import im.vector.app.core.preference.VectorPreference
|
||||
import im.vector.app.core.preference.VectorPreferenceCategory
|
||||
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.PushersManager
|
||||
import im.vector.app.core.pushers.UnifiedPushHelper
|
||||
|
@ -82,6 +83,7 @@ class VectorSettingsNotificationPreferenceFragment :
|
|||
@Inject lateinit var notificationPermissionManager: NotificationPermissionManager
|
||||
@Inject lateinit var disableNotificationsForCurrentSessionUseCase: DisableNotificationsForCurrentSessionUseCase
|
||||
@Inject lateinit var enableNotificationsForCurrentSessionUseCase: EnableNotificationsForCurrentSessionUseCase
|
||||
@Inject lateinit var ensureFcmTokenIsRetrievedUseCase: EnsureFcmTokenIsRetrievedUseCase
|
||||
|
||||
override var titleRes: Int = R.string.settings_notifications
|
||||
override val preferenceXmlRes = R.xml.vector_settings_notifications
|
||||
|
@ -183,13 +185,7 @@ class VectorSettingsNotificationPreferenceFragment :
|
|||
it.summary = unifiedPushHelper.getCurrentDistributorName()
|
||||
it.onPreferenceClickListener = Preference.OnPreferenceClickListener {
|
||||
unifiedPushHelper.forceRegister(requireActivity(), pushersManager) {
|
||||
if (unifiedPushHelper.isEmbeddedDistributor()) {
|
||||
fcmHelper.ensureFcmTokenIsRetrieved(
|
||||
requireActivity(),
|
||||
pushersManager,
|
||||
vectorPreferences.areNotificationEnabledForDevice()
|
||||
)
|
||||
}
|
||||
ensureFcmTokenIsRetrievedUseCase.execute(pushersManager, registerPusher = vectorPreferences.areNotificationEnabledForDevice())
|
||||
it.summary = unifiedPushHelper.getCurrentDistributorName()
|
||||
session.pushersService().refreshPushers()
|
||||
refreshBackgroundSyncPrefs()
|
||||
|
|
Loading…
Reference in a new issue