Add UnifiedPush troubleshoot

This commit is contained in:
sim 2022-02-28 15:46:53 +01:00 committed by Benoit Marty
parent 848adc415f
commit f00257f461
16 changed files with 448 additions and 58 deletions

View File

@ -28,6 +28,19 @@
android:enabled="true" android:enabled="true"
android:exported="false" /> android:exported="false" />
<receiver android:name=".fdroid.receiver.KeepInternalDistributor"
android:enabled="true"
android:exported="false">
<intent-filter>
<!--
This action is checked to track installed and uninstalled distributors.
We declare it to keep the background sync as an internal
unifiedpush distributor.
-->
<action android:name="org.unifiedpush.android.distributor.REGISTER" />
</intent-filter>
</receiver>
<service <service
android:name=".fdroid.service.GuardService" android:name=".fdroid.service.GuardService"
android:exported="false" android:exported="false"

View File

@ -0,0 +1,32 @@
/*
* 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.fdroid.receiver
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
/**
* UnifiedPush lib tracks an action to check installed and uninstalled distributors.
* We declare it to keep the background sync as an internal unifiedpush distributor.
* This class is used to declare this action.
*/
class KeepInternalDistributor : BroadcastReceiver() {
override fun onReceive(p0: Context?, p1: Intent?) {
return
}
}

View File

@ -16,15 +16,23 @@
package im.vector.app.push.fcm package im.vector.app.push.fcm
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import im.vector.app.BuildConfig
import im.vector.app.core.pushers.UnifiedPushHelper
import im.vector.app.fdroid.features.settings.troubleshoot.TestAutoStartBoot import im.vector.app.fdroid.features.settings.troubleshoot.TestAutoStartBoot
import im.vector.app.fdroid.features.settings.troubleshoot.TestBackgroundRestrictions import im.vector.app.fdroid.features.settings.troubleshoot.TestBackgroundRestrictions
import im.vector.app.fdroid.features.settings.troubleshoot.TestBatteryOptimization import im.vector.app.fdroid.features.settings.troubleshoot.TestBatteryOptimization
import im.vector.app.features.settings.troubleshoot.NotificationTroubleshootTestManager import im.vector.app.features.settings.troubleshoot.NotificationTroubleshootTestManager
import im.vector.app.features.settings.troubleshoot.TestAccountSettings import im.vector.app.features.settings.troubleshoot.TestAccountSettings
import im.vector.app.features.settings.troubleshoot.TestAvailableUnifiedPushDistributors
import im.vector.app.features.settings.troubleshoot.TestCurrentUnifiedPushDistributor
import im.vector.app.features.settings.troubleshoot.TestDeviceSettings import im.vector.app.features.settings.troubleshoot.TestDeviceSettings
import im.vector.app.features.settings.troubleshoot.TestEndpointAsTokenRegistration
import im.vector.app.features.settings.troubleshoot.TestNotification import im.vector.app.features.settings.troubleshoot.TestNotification
import im.vector.app.features.settings.troubleshoot.TestPushFromPushGateway
import im.vector.app.features.settings.troubleshoot.TestPushRulesSettings import im.vector.app.features.settings.troubleshoot.TestPushRulesSettings
import im.vector.app.features.settings.troubleshoot.TestSystemSettings import im.vector.app.features.settings.troubleshoot.TestSystemSettings
import im.vector.app.features.settings.troubleshoot.TestUnifiedPushEndpoint
import im.vector.app.features.settings.troubleshoot.TestUnifiedPushGateway
import javax.inject.Inject import javax.inject.Inject
class NotificationTroubleshootTestManagerFactory @Inject constructor( class NotificationTroubleshootTestManagerFactory @Inject constructor(
@ -32,6 +40,12 @@ class NotificationTroubleshootTestManagerFactory @Inject constructor(
private val testAccountSettings: TestAccountSettings, private val testAccountSettings: TestAccountSettings,
private val testDeviceSettings: TestDeviceSettings, private val testDeviceSettings: TestDeviceSettings,
private val testPushRulesSettings: TestPushRulesSettings, private val testPushRulesSettings: TestPushRulesSettings,
private val testCurrentUnifiedPushDistributor: TestCurrentUnifiedPushDistributor,
private val testUnifiedPushGateway: TestUnifiedPushGateway,
private val testUnifiedPushEndpoint: TestUnifiedPushEndpoint,
private val testAvailableUnifiedPushDistributors: TestAvailableUnifiedPushDistributors,
private val testEndpointAsTokenRegistration: TestEndpointAsTokenRegistration,
private val testPushFromPushGateway: TestPushFromPushGateway,
private val testAutoStartBoot: TestAutoStartBoot, private val testAutoStartBoot: TestAutoStartBoot,
private val testBackgroundRestrictions: TestBackgroundRestrictions, private val testBackgroundRestrictions: TestBackgroundRestrictions,
private val testBatteryOptimization: TestBatteryOptimization, private val testBatteryOptimization: TestBatteryOptimization,
@ -44,9 +58,20 @@ class NotificationTroubleshootTestManagerFactory @Inject constructor(
mgr.addTest(testAccountSettings) mgr.addTest(testAccountSettings)
mgr.addTest(testDeviceSettings) mgr.addTest(testDeviceSettings)
mgr.addTest(testPushRulesSettings) mgr.addTest(testPushRulesSettings)
mgr.addTest(testAutoStartBoot) if (BuildConfig.ALLOW_EXTERNAL_UNIFIEDPUSH_DISTRIB) {
mgr.addTest(testBackgroundRestrictions) mgr.addTest(testAvailableUnifiedPushDistributors)
mgr.addTest(testBatteryOptimization) mgr.addTest(testCurrentUnifiedPushDistributor)
}
if (UnifiedPushHelper.isBackgroundSync(fragment.requireContext())) {
mgr.addTest(testAutoStartBoot)
mgr.addTest(testBackgroundRestrictions)
mgr.addTest(testBatteryOptimization)
} else {
mgr.addTest(testUnifiedPushGateway)
mgr.addTest(testUnifiedPushEndpoint)
mgr.addTest(testEndpointAsTokenRegistration)
mgr.addTest(testPushFromPushGateway)
}
mgr.addTest(testNotification) mgr.addTest(testNotification)
return mgr return mgr
} }

View File

@ -16,15 +16,22 @@
package im.vector.app.push.fcm package im.vector.app.push.fcm
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import im.vector.app.BuildConfig
import im.vector.app.core.pushers.UnifiedPushHelper
import im.vector.app.features.settings.troubleshoot.NotificationTroubleshootTestManager import im.vector.app.features.settings.troubleshoot.NotificationTroubleshootTestManager
import im.vector.app.features.settings.troubleshoot.TestAccountSettings import im.vector.app.features.settings.troubleshoot.TestAccountSettings
import im.vector.app.features.settings.troubleshoot.TestAvailableUnifiedPushDistributors
import im.vector.app.features.settings.troubleshoot.TestCurrentUnifiedPushDistributor
import im.vector.app.features.settings.troubleshoot.TestDeviceSettings import im.vector.app.features.settings.troubleshoot.TestDeviceSettings
import im.vector.app.features.settings.troubleshoot.TestEndpointAsTokenRegistration
import im.vector.app.features.settings.troubleshoot.TestNotification import im.vector.app.features.settings.troubleshoot.TestNotification
import im.vector.app.features.settings.troubleshoot.TestPushRulesSettings import im.vector.app.features.settings.troubleshoot.TestPushRulesSettings
import im.vector.app.features.settings.troubleshoot.TestSystemSettings import im.vector.app.features.settings.troubleshoot.TestSystemSettings
import im.vector.app.features.settings.troubleshoot.TestUnifiedPushEndpoint
import im.vector.app.features.settings.troubleshoot.TestUnifiedPushGateway
import im.vector.app.features.settings.troubleshoot.TestPushFromPushGateway
import im.vector.app.gplay.features.settings.troubleshoot.TestFirebaseToken import im.vector.app.gplay.features.settings.troubleshoot.TestFirebaseToken
import im.vector.app.gplay.features.settings.troubleshoot.TestPlayServices import im.vector.app.gplay.features.settings.troubleshoot.TestPlayServices
import im.vector.app.gplay.features.settings.troubleshoot.TestPushFromPushGateway
import im.vector.app.gplay.features.settings.troubleshoot.TestTokenRegistration import im.vector.app.gplay.features.settings.troubleshoot.TestTokenRegistration
import javax.inject.Inject import javax.inject.Inject
@ -32,10 +39,15 @@ class NotificationTroubleshootTestManagerFactory @Inject constructor(
private val testSystemSettings: TestSystemSettings, private val testSystemSettings: TestSystemSettings,
private val testAccountSettings: TestAccountSettings, private val testAccountSettings: TestAccountSettings,
private val testDeviceSettings: TestDeviceSettings, private val testDeviceSettings: TestDeviceSettings,
private val testBingRulesSettings: TestPushRulesSettings, private val testPushRulesSettings: TestPushRulesSettings,
private val testPlayServices: TestPlayServices, private val testPlayServices: TestPlayServices,
private val testFirebaseToken: TestFirebaseToken, private val testFirebaseToken: TestFirebaseToken,
private val testTokenRegistration: TestTokenRegistration, private val testTokenRegistration: TestTokenRegistration,
private val testCurrentUnifiedPushDistributor: TestCurrentUnifiedPushDistributor,
private val testUnifiedPushGateway: TestUnifiedPushGateway,
private val testUnifiedPushEndpoint: TestUnifiedPushEndpoint,
private val testAvailableUnifiedPushDistributors: TestAvailableUnifiedPushDistributors,
private val testEndpointAsTokenRegistration: TestEndpointAsTokenRegistration,
private val testPushFromPushGateway: TestPushFromPushGateway, private val testPushFromPushGateway: TestPushFromPushGateway,
private val testNotification: TestNotification private val testNotification: TestNotification
) { ) {
@ -45,10 +57,21 @@ class NotificationTroubleshootTestManagerFactory @Inject constructor(
mgr.addTest(testSystemSettings) mgr.addTest(testSystemSettings)
mgr.addTest(testAccountSettings) mgr.addTest(testAccountSettings)
mgr.addTest(testDeviceSettings) mgr.addTest(testDeviceSettings)
mgr.addTest(testBingRulesSettings) mgr.addTest(testPushRulesSettings)
mgr.addTest(testPlayServices) if (BuildConfig.ALLOW_EXTERNAL_UNIFIEDPUSH_DISTRIB) {
mgr.addTest(testFirebaseToken) mgr.addTest(testAvailableUnifiedPushDistributors)
mgr.addTest(testTokenRegistration) mgr.addTest(testCurrentUnifiedPushDistributor)
}
if (UnifiedPushHelper.isEmbeddedDistributor(fragment.requireContext())) {
mgr.addTest(testPlayServices)
mgr.addTest(testFirebaseToken)
mgr.addTest(testTokenRegistration)
} else {
mgr.addTest(testUnifiedPushGateway)
mgr.addTest(testUnifiedPushEndpoint)
mgr.addTest(testEndpointAsTokenRegistration)
}
mgr.addTest(testPushFromPushGateway) mgr.addTest(testPushFromPushGateway)
mgr.addTest(testNotification) mgr.addTest(testNotification)
return mgr return mgr

View File

@ -39,7 +39,7 @@ class PushersManager @Inject constructor(
val currentSession = activeSessionHolder.getActiveSession() val currentSession = activeSessionHolder.getActiveSession()
currentSession.pushersService().testPush( currentSession.pushersService().testPush(
UnifiedPushHelper.getPushGateway(context), UnifiedPushHelper.getPushGateway(context)!!,
stringProvider.getString(R.string.pusher_app_id), stringProvider.getString(R.string.pusher_app_id),
UnifiedPushHelper.getEndpointOrToken(context) ?: "", UnifiedPushHelper.getEndpointOrToken(context) ?: "",
TEST_EVENT_ID TEST_EVENT_ID

View File

@ -66,8 +66,8 @@ object UnifiedPushHelper {
* *
* @return the Push Gateway or null if not defined * @return the Push Gateway or null if not defined
*/ */
fun getPushGateway(context: Context): String { fun getPushGateway(context: Context): String? {
return DefaultSharedPreferences.getInstance(context).getString(PREFS_PUSH_GATEWAY, null)!! return DefaultSharedPreferences.getInstance(context).getString(PREFS_PUSH_GATEWAY, null)
} }
/** /**
@ -84,9 +84,27 @@ object UnifiedPushHelper {
} }
} }
fun register(context: Context, fun register(context: Context, onDoneRunnable: Runnable? = null) {
gRegister(context,
onDoneRunnable = onDoneRunnable)
}
fun reRegister(context: Context,
pushersManager: PushersManager,
vectorPreferences: VectorPreferences,
onDoneRunnable: Runnable? = null) {
gRegister(context,
force = true,
pushersManager = pushersManager,
vectorPreferences = vectorPreferences,
onDoneRunnable = onDoneRunnable
)
}
private fun gRegister(context: Context,
force: Boolean = false, force: Boolean = false,
pushersManager: PushersManager? = null, pushersManager: PushersManager? = null,
vectorPreferences: VectorPreferences? = null,
onDoneRunnable: Runnable? = null) { onDoneRunnable: Runnable? = null) {
if (!BuildConfig.ALLOW_EXTERNAL_UNIFIEDPUSH_DISTRIB) { if (!BuildConfig.ALLOW_EXTERNAL_UNIFIEDPUSH_DISTRIB) {
up.saveDistributor(context, context.packageName) up.saveDistributor(context, context.packageName)
@ -96,12 +114,7 @@ object UnifiedPushHelper {
} }
if (force) { if (force) {
// Un-register first // Un-register first
runBlocking { unregister(context, pushersManager, vectorPreferences)
pushersManager?.unregisterPusher(getEndpointOrToken(context) ?: "")
}
up.unregisterApp(context)
storeUpEndpoint(context, null)
storePushGateway(context, null)
} }
if (up.getDistributor(context).isNotEmpty()) { if (up.getDistributor(context).isNotEmpty()) {
up.registerApp(context) up.registerApp(context)
@ -113,12 +126,10 @@ object UnifiedPushHelper {
up.saveDistributor(context, context.packageName) up.saveDistributor(context, context.packageName)
val distributors = up.getDistributors(context).toMutableList() val distributors = up.getDistributors(context).toMutableList()
val internalDistributorName = if (!FcmHelper.isPushSupported()) { val internalDistributorName = if (FcmHelper.isPushSupported()) {
// Adding packageName for background sync context.getString(R.string.unifiedpush_distributor_fcm_fallback)
distributors.add(context.packageName)
context.getString(R.string.unifiedpush_getdistributors_dialog_background_sync)
} else { } else {
context.getString(R.string.unifiedpush_getdistributors_dialog_fcm_fallback) context.getString(R.string.unifiedpush_distributor_background_sync)
} }
if (distributors.size == 1 if (distributors.size == 1
@ -175,6 +186,8 @@ object UnifiedPushHelper {
Timber.d("Probably unregistering a non existant pusher") Timber.d("Probably unregistering a non existant pusher")
} }
} }
storeUpEndpoint(context, null)
storePushGateway(context, null)
up.unregisterApp(context) up.unregisterApp(context)
} }
@ -183,7 +196,10 @@ object UnifiedPushHelper {
// register app_id type upfcm on sygnal // register app_id type upfcm on sygnal
// the pushkey if FCM key // the pushkey if FCM key
if (up.getDistributor(context) == context.packageName) { if (up.getDistributor(context) == context.packageName) {
return context.getString(R.string.pusher_http_url) context.getString(R.string.pusher_http_url).let {
storePushGateway(context, it)
return it
}
} }
// else, unifiedpush, and pushkey is an endpoint // else, unifiedpush, and pushkey is an endpoint
val default = context.getString(R.string.default_push_gateway_http_url) val default = context.getString(R.string.default_push_gateway_http_url)
@ -197,11 +213,30 @@ object UnifiedPushHelper {
* return custom * return custom
*/ */
} }
storePushGateway(context, default)
return default return default
} }
fun distributorExists(context: Context): Boolean { fun getExternalDistributors(context: Context): List<String> {
return up.getDistributor(context).isNotEmpty() val distributors = up.getDistributors(context).toMutableList()
distributors.remove(context.packageName)
return distributors
}
fun getCurrentDistributorName(context: Context): String {
if (isEmbeddedDistributor(context)) {
return context.getString(R.string.unifiedpush_distributor_fcm_fallback)
}
if (isBackgroundSync(context)) {
return context.getString(R.string.unifiedpush_distributor_background_sync)
}
val distributor = up.getDistributor(context)
return try {
val ai = context.packageManager.getApplicationInfo(distributor, 0)
context.packageManager.getApplicationLabel(ai)
} catch (e: PackageManager.NameNotFoundException) {
distributor
} as String
} }
fun isEmbeddedDistributor(context: Context) : Boolean { fun isEmbeddedDistributor(context: Context) : Boolean {
@ -222,7 +257,7 @@ object UnifiedPushHelper {
} }
return try { return try {
val parsed = URL(endpoint) val parsed = URL(endpoint)
"${parsed.protocol}://${parsed.host}" "${parsed.protocol}://${parsed.host}/***"
} catch (e: Exception) { } catch (e: Exception) {
Timber.e("Error parsing unifiedpush endpoint: $e") Timber.e("Error parsing unifiedpush endpoint: $e")
null null

View File

@ -32,6 +32,7 @@ import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.BuildConfig import im.vector.app.BuildConfig
import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.network.WifiDetector import im.vector.app.core.network.WifiDetector
import im.vector.app.core.services.GuardServiceStarter
import im.vector.app.features.badge.BadgeProxy import im.vector.app.features.badge.BadgeProxy
import im.vector.app.features.notifications.NotifiableEventResolver import im.vector.app.features.notifications.NotifiableEventResolver
import im.vector.app.features.notifications.NotificationDrawerManager import im.vector.app.features.notifications.NotificationDrawerManager
@ -78,11 +79,12 @@ private val loggerTag = LoggerTag("Push", LoggerTag.SYNC)
class VectorMessagingReceiver : MessagingReceiver() { class VectorMessagingReceiver : MessagingReceiver() {
@Inject lateinit var notificationDrawerManager: NotificationDrawerManager @Inject lateinit var notificationDrawerManager: NotificationDrawerManager
@Inject lateinit var notifiableEventResolver: NotifiableEventResolver @Inject lateinit var notifiableEventResolver: NotifiableEventResolver
@Inject lateinit var pusherManager: PushersManager @Inject lateinit var pushersManager: PushersManager
@Inject lateinit var activeSessionHolder: ActiveSessionHolder @Inject lateinit var activeSessionHolder: ActiveSessionHolder
@Inject lateinit var vectorPreferences: VectorPreferences @Inject lateinit var vectorPreferences: VectorPreferences
@Inject lateinit var vectorDataStore: VectorDataStore @Inject lateinit var vectorDataStore: VectorDataStore
@Inject lateinit var wifiDetector: WifiDetector @Inject lateinit var wifiDetector: WifiDetector
@Inject lateinit var guardServiceStarter: GuardServiceStarter
private val coroutineScope = CoroutineScope(SupervisorJob()) private val coroutineScope = CoroutineScope(SupervisorJob())
@ -161,26 +163,31 @@ class VectorMessagingReceiver : MessagingReceiver() {
|| UnifiedPushHelper.getPushGateway(context) != gateway) { || UnifiedPushHelper.getPushGateway(context) != gateway) {
UnifiedPushHelper.storePushGateway(context, gateway) UnifiedPushHelper.storePushGateway(context, gateway)
UnifiedPushHelper.storeUpEndpoint(context, endpoint) UnifiedPushHelper.storeUpEndpoint(context, endpoint)
pusherManager.enqueueRegisterPusher(endpoint, gateway) pushersManager.enqueueRegisterPusher(endpoint, gateway)
} else { } else {
Timber.tag(loggerTag.value).i("onNewEndpoint: skipped") Timber.tag(loggerTag.value).i("onNewEndpoint: skipped")
} }
} }
val mode = BackgroundSyncMode.FDROID_BACKGROUND_SYNC_MODE_DISABLED val mode = BackgroundSyncMode.FDROID_BACKGROUND_SYNC_MODE_DISABLED
vectorPreferences.setFdroidSyncBackgroundMode(mode) vectorPreferences.setFdroidSyncBackgroundMode(mode)
guardServiceStarter.stop()
} }
override fun onRegistrationFailed(context: Context, instance: String) { override fun onRegistrationFailed(context: Context, instance: String) {
Toast.makeText(context, "Push service registration failed", Toast.LENGTH_SHORT).show() Toast.makeText(context, "Push service registration failed", Toast.LENGTH_SHORT).show()
val mode = BackgroundSyncMode.FDROID_BACKGROUND_SYNC_MODE_FOR_REALTIME
vectorPreferences.setFdroidSyncBackgroundMode(mode)
guardServiceStarter.start()
} }
override fun onUnregistered(context: Context, instance: String) { override fun onUnregistered(context: Context, instance: String) {
Timber.tag(loggerTag.value).d("Unifiedpush: Unregistered") Timber.tag(loggerTag.value).d("Unifiedpush: Unregistered")
val mode = BackgroundSyncMode.FDROID_BACKGROUND_SYNC_MODE_FOR_REALTIME val mode = BackgroundSyncMode.FDROID_BACKGROUND_SYNC_MODE_FOR_REALTIME
vectorPreferences.setFdroidSyncBackgroundMode(mode) vectorPreferences.setFdroidSyncBackgroundMode(mode)
guardServiceStarter.start()
runBlocking { runBlocking {
try { try {
pusherManager.unregisterPusher(UnifiedPushHelper.getEndpointOrToken(context) ?: "") pushersManager.unregisterPusher(UnifiedPushHelper.getEndpointOrToken(context) ?: "")
} catch (e: Exception) { } catch (e: Exception) {
Timber.tag(loggerTag.value).d("Probably unregistering a non existant pusher") Timber.tag(loggerTag.value).d("Probably unregistering a non existant pusher")
} }

View File

@ -188,7 +188,7 @@ class HomeActivity :
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
analyticsScreenName = MobileScreen.ScreenName.Home analyticsScreenName = MobileScreen.ScreenName.Home
supportFragmentManager.registerFragmentLifecycleCallbacks(fragmentLifecycleCallbacks, false) supportFragmentManager.registerFragmentLifecycleCallbacks(fragmentLifecycleCallbacks, false)
UnifiedPushHelper.register(this, onDoneRunnable = { UnifiedPushHelper.register(this) {
if (UnifiedPushHelper.isEmbeddedDistributor(this)) { if (UnifiedPushHelper.isEmbeddedDistributor(this)) {
FcmHelper.ensureFcmTokenIsRetrieved( FcmHelper.ensureFcmTokenIsRetrieved(
this, this,
@ -196,7 +196,7 @@ class HomeActivity :
vectorPreferences.areNotificationEnabledForDevice() vectorPreferences.areNotificationEnabledForDevice()
) )
} }
}) }
sharedActionViewModel = viewModelProvider.get(HomeSharedActionViewModel::class.java) sharedActionViewModel = viewModelProvider.get(HomeSharedActionViewModel::class.java)
views.drawerLayout.addDrawerListener(drawerListener) views.drawerLayout.addDrawerListener(drawerListener)
if (isFirstCreation()) { if (isFirstCreation()) {

View File

@ -63,7 +63,7 @@ import javax.inject.Inject
// Referenced in vector_settings_preferences_root.xml // Referenced in vector_settings_preferences_root.xml
class VectorSettingsNotificationPreferenceFragment @Inject constructor( class VectorSettingsNotificationPreferenceFragment @Inject constructor(
private val pushManager: PushersManager, private val pushersManager: PushersManager,
private val activeSessionHolder: ActiveSessionHolder, private val activeSessionHolder: ActiveSessionHolder,
private val vectorPreferences: VectorPreferences, private val vectorPreferences: VectorPreferences,
private val guardServiceStarter: GuardServiceStarter private val guardServiceStarter: GuardServiceStarter
@ -103,7 +103,7 @@ class VectorSettingsNotificationPreferenceFragment @Inject constructor(
} else { } else {
UnifiedPushHelper.unregister( UnifiedPushHelper.unregister(
requireContext(), requireContext(),
pushManager, pushersManager,
vectorPreferences vectorPreferences
) )
session.pushersService().refreshPushers() session.pushersService().refreshPushers()
@ -152,14 +152,16 @@ class VectorSettingsNotificationPreferenceFragment @Inject constructor(
findPreference<VectorPreference>(VectorPreferences.SETTINGS_UNIFIED_PUSH_RE_REGISTER_KEY)?.let { findPreference<VectorPreference>(VectorPreferences.SETTINGS_UNIFIED_PUSH_RE_REGISTER_KEY)?.let {
if (BuildConfig.ALLOW_EXTERNAL_UNIFIEDPUSH_DISTRIB) { if (BuildConfig.ALLOW_EXTERNAL_UNIFIEDPUSH_DISTRIB) {
it.onPreferenceClickListener = Preference.OnPreferenceClickListener { it.onPreferenceClickListener = Preference.OnPreferenceClickListener {
UnifiedPushHelper.register( UnifiedPushHelper.reRegister(
requireContext(), requireContext(),
force = true, pushersManager,
pushManager vectorPreferences
) ) {
session.pushersService().refreshPushers()
refreshBackgroundSyncPrefs()
}
true true
} }
session.pushersService().refreshPushers()
} else { } else {
it.isVisible = false it.isVisible = false
} }
@ -199,9 +201,9 @@ class VectorSettingsNotificationPreferenceFragment @Inject constructor(
pref.isChecked = isEnabled pref.isChecked = isEnabled
pref.setTransactionalSwitchChangeListener(lifecycleScope) { isChecked -> pref.setTransactionalSwitchChangeListener(lifecycleScope) { isChecked ->
if (isChecked) { if (isChecked) {
pushManager.registerEmailForPush(emailPid.email) pushersManager.registerEmailForPush(emailPid.email)
} else { } else {
pushManager.unregisterEmailPusher(emailPid.email) pushersManager.unregisterEmailPusher(emailPid.email)
} }
} }
category.addPreference(pref) category.addPreference(pref)

View File

@ -0,0 +1,47 @@
/*
* 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.troubleshoot
import android.content.Intent
import androidx.activity.result.ActivityResultLauncher
import androidx.fragment.app.FragmentActivity
import im.vector.app.R
import im.vector.app.core.pushers.UnifiedPushHelper
import im.vector.app.core.resources.StringProvider
import im.vector.app.push.fcm.FcmHelper
import javax.inject.Inject
class TestAvailableUnifiedPushDistributors @Inject constructor(private val context: FragmentActivity,
private val stringProvider: StringProvider) :
TroubleshootTest(R.string.settings_troubleshoot_test_distributors_title) {
override fun perform(activityResultLauncher: ActivityResultLauncher<Intent>) {
val distributors = UnifiedPushHelper.getExternalDistributors(context)
if (distributors.isEmpty()) {
description = if (FcmHelper.isPushSupported()) {
stringProvider.getString(R.string.settings_troubleshoot_test_distributors_gplay)
} else {
stringProvider.getString(R.string.settings_troubleshoot_test_distributors_fdroid)
}
status = TestStatus.SUCCESS
} else {
description = stringProvider.getString(R.string.settings_troubleshoot_test_distributors_many,
distributors.size + 1)
status = TestStatus.SUCCESS
}
}
}

View File

@ -0,0 +1,36 @@
/*
* 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.troubleshoot
import android.content.Intent
import androidx.activity.result.ActivityResultLauncher
import androidx.fragment.app.FragmentActivity
import im.vector.app.R
import im.vector.app.core.pushers.UnifiedPushHelper
import im.vector.app.core.resources.StringProvider
import javax.inject.Inject
class TestCurrentUnifiedPushDistributor @Inject constructor(private val context: FragmentActivity,
private val stringProvider: StringProvider) :
TroubleshootTest(R.string.settings_troubleshoot_test_current_distributor_title) {
override fun perform(activityResultLauncher: ActivityResultLauncher<Intent>) {
description = stringProvider.getString(R.string.settings_troubleshoot_test_current_distributor,
UnifiedPushHelper.getCurrentDistributorName(context))
status = TestStatus.SUCCESS
}
}

View File

@ -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.features.settings.troubleshoot
import android.content.Intent
import androidx.activity.result.ActivityResultLauncher
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.Observer
import androidx.work.WorkInfo
import androidx.work.WorkManager
import im.vector.app.R
import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.pushers.PushersManager
import im.vector.app.core.pushers.UnifiedPushHelper
import im.vector.app.core.resources.StringProvider
import im.vector.app.features.settings.VectorPreferences
import org.matrix.android.sdk.api.session.pushers.PusherState
import javax.inject.Inject
class TestEndpointAsTokenRegistration @Inject constructor(private val context: FragmentActivity,
private val stringProvider: StringProvider,
private val pushersManager: PushersManager,
private val vectorPreferences: VectorPreferences,
private val activeSessionHolder: ActiveSessionHolder) :
TroubleshootTest(R.string.settings_troubleshoot_test_endpoint_registration_title) {
override fun perform(activityResultLauncher: ActivityResultLauncher<Intent>) {
// Check if we have a registered pusher for this token
val endpoint = UnifiedPushHelper.getEndpointOrToken(context) ?: run {
status = TestStatus.FAILED
return
}
val session = activeSessionHolder.getSafeActiveSession() ?: run {
status = TestStatus.FAILED
return
}
val pushers = session.pushersService().getPushers().filter {
it.pushKey == endpoint && it.state == PusherState.REGISTERED
}
if (pushers.isEmpty()) {
description = stringProvider.getString(R.string.settings_troubleshoot_test_endpoint_registration_failed,
stringProvider.getString(R.string.sas_error_unknown))
quickFix = object : TroubleshootQuickFix(R.string.settings_troubleshoot_test_endpoint_registration_quick_fix) {
override fun doFix() {
UnifiedPushHelper.reRegister(
context,
pushersManager,
vectorPreferences
)
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(activityResultLauncher)
} else if (workInfo.state == WorkInfo.State.FAILED) {
manager?.retry(activityResultLauncher)
}
}
})
}
}
status = TestStatus.FAILED
} else {
description = stringProvider.getString(R.string.settings_troubleshoot_test_endpoint_registration_success)
status = TestStatus.SUCCESS
}
}
}

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package im.vector.app.gplay.features.settings.troubleshoot package im.vector.app.features.settings.troubleshoot
import android.content.Intent import android.content.Intent
import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.ActivityResultLauncher
@ -24,8 +24,6 @@ import im.vector.app.core.error.ErrorFormatter
import im.vector.app.core.pushers.PushersManager import im.vector.app.core.pushers.PushersManager
import im.vector.app.core.resources.StringProvider import im.vector.app.core.resources.StringProvider
import im.vector.app.features.session.coroutineScope import im.vector.app.features.session.coroutineScope
import im.vector.app.features.settings.troubleshoot.TroubleshootTest
import im.vector.app.push.fcm.FcmHelper
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -36,13 +34,11 @@ import javax.inject.Inject
/** /**
* Test Push by asking the Push Gateway to send a Push back * Test Push by asking the Push Gateway to send a Push back
*/ */
class TestPushFromPushGateway @Inject constructor( class TestPushFromPushGateway @Inject constructor(private val context: FragmentActivity,
private val context: FragmentActivity, private val stringProvider: StringProvider,
private val stringProvider: StringProvider, private val errorFormatter: ErrorFormatter,
private val errorFormatter: ErrorFormatter, private val pushersManager: PushersManager,
private val pushersManager: PushersManager, private val activeSessionHolder: ActiveSessionHolder) :
private val activeSessionHolder: ActiveSessionHolder
) :
TroubleshootTest(R.string.settings_troubleshoot_test_push_loop_title) { TroubleshootTest(R.string.settings_troubleshoot_test_push_loop_title) {
private var action: Job? = null private var action: Job? = null
@ -50,10 +46,6 @@ class TestPushFromPushGateway @Inject constructor(
override fun perform(activityResultLauncher: ActivityResultLauncher<Intent>) { override fun perform(activityResultLauncher: ActivityResultLauncher<Intent>) {
pushReceived = false pushReceived = false
FcmHelper.getFcmToken(context) ?: run {
status = TestStatus.FAILED
return
}
action = activeSessionHolder.getActiveSession().coroutineScope.launch { action = activeSessionHolder.getActiveSession().coroutineScope.launch {
val result = runCatching { pushersManager.testPush(context) } val result = runCatching { pushersManager.testPush(context) }

View File

@ -0,0 +1,42 @@
/*
* 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.troubleshoot
import android.content.Intent
import androidx.activity.result.ActivityResultLauncher
import androidx.fragment.app.FragmentActivity
import im.vector.app.R
import im.vector.app.core.pushers.UnifiedPushHelper
import im.vector.app.core.resources.StringProvider
import javax.inject.Inject
class TestUnifiedPushEndpoint @Inject constructor(private val context: FragmentActivity,
private val stringProvider: StringProvider) :
TroubleshootTest(R.string.settings_troubleshoot_test_current_endpoint_title) {
override fun perform(activityResultLauncher: ActivityResultLauncher<Intent>) {
val endpoint = UnifiedPushHelper.getPrivacyFriendlyUpEndpoint(context)
endpoint?.let {
description = stringProvider.getString(R.string.settings_troubleshoot_test_current_endpoint_success,
UnifiedPushHelper.getPrivacyFriendlyUpEndpoint(context))
status = TestStatus.SUCCESS
} ?: run {
description = stringProvider.getString(R.string.settings_troubleshoot_test_current_endpoint_failed)
status = TestStatus.FAILED
}
}
}

View File

@ -0,0 +1,36 @@
/*
* 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.troubleshoot
import android.content.Intent
import androidx.activity.result.ActivityResultLauncher
import androidx.fragment.app.FragmentActivity
import im.vector.app.R
import im.vector.app.core.pushers.UnifiedPushHelper
import im.vector.app.core.resources.StringProvider
import javax.inject.Inject
class TestUnifiedPushGateway @Inject constructor(private val context: FragmentActivity,
private val stringProvider: StringProvider) :
TroubleshootTest(R.string.settings_troubleshoot_test_current_gateway_title) {
override fun perform(activityResultLauncher: ActivityResultLauncher<Intent>) {
description = stringProvider.getString(R.string.settings_troubleshoot_test_current_gateway,
UnifiedPushHelper.getPushGateway(context))
status = TestStatus.SUCCESS
}
}

View File

@ -855,6 +855,10 @@
<string name="settings_troubleshoot_test_token_registration_success">FCM token successfully registered to homeserver.</string> <string name="settings_troubleshoot_test_token_registration_success">FCM token successfully registered to homeserver.</string>
<string name="settings_troubleshoot_test_token_registration_failed">Failed to register FCM token to homeserver:\n%1$s</string> <string name="settings_troubleshoot_test_token_registration_failed">Failed to register FCM token to homeserver:\n%1$s</string>
<string name="settings_troubleshoot_test_endpoint_registration_title">Endpoint Registration</string>
<string name="settings_troubleshoot_test_endpoint_registration_success">Endpoint successfully registered to homeserver.</string>
<string name="settings_troubleshoot_test_endpoint_registration_failed">Failed to register endpoint token to homeserver:\n%1$s</string>
<string name="settings_troubleshoot_test_push_loop_title">Test Push</string> <string name="settings_troubleshoot_test_push_loop_title">Test Push</string>
<string name="settings_troubleshoot_test_push_loop_waiting_for_push">The application is waiting for the PUSH</string> <string name="settings_troubleshoot_test_push_loop_waiting_for_push">The application is waiting for the PUSH</string>
<string name="settings_troubleshoot_test_push_loop_success">The application is receiving PUSH</string> <string name="settings_troubleshoot_test_push_loop_success">The application is receiving PUSH</string>
@ -1665,6 +1669,8 @@
<string name="settings_troubleshoot_test_token_registration_quick_fix">Register token</string> <string name="settings_troubleshoot_test_token_registration_quick_fix">Register token</string>
<string name="settings_troubleshoot_test_endpoint_registration_quick_fix">Reset notification method</string>
<string name="send_suggestion">Make a suggestion</string> <string name="send_suggestion">Make a suggestion</string>
<string name="send_suggestion_content">Please write your suggestion below.</string> <string name="send_suggestion_content">Please write your suggestion below.</string>
<string name="send_suggestion_report_placeholder">Describe your suggestion here</string> <string name="send_suggestion_report_placeholder">Describe your suggestion here</string>
@ -3065,7 +3071,18 @@
<string name="screen_sharing_notification_description">Screen sharing is in progress</string> <string name="screen_sharing_notification_description">Screen sharing is in progress</string>
<string name="unifiedpush_getdistributors_dialog_title">Choose how to receive notifications</string> <string name="unifiedpush_getdistributors_dialog_title">Choose how to receive notifications</string>
<string name="unifiedpush_getdistributors_dialog_fcm_fallback">Google Services</string> <string name="unifiedpush_distributor_fcm_fallback">Google Services</string>
<string name="unifiedpush_getdistributors_dialog_background_sync">Background synchronization</string> <string name="unifiedpush_distributor_background_sync">Background synchronization</string>
<string name="settings_unifiedpush_reregister">Notification method</string> <string name="settings_unifiedpush_reregister">Notification method</string>
<string name="settings_troubleshoot_test_distributors_title">Available methods</string>
<string name="settings_troubleshoot_test_distributors_gplay">No other method than Google Play Service found.</string>
<string name="settings_troubleshoot_test_distributors_fdroid">No other method than background synchronization found.</string>
<string name="settings_troubleshoot_test_distributors_many">Found %d methods.</string>
<string name="settings_troubleshoot_test_current_distributor_title">Method</string>
<string name="settings_troubleshoot_test_current_distributor">Currently using %s.</string>
<string name="settings_troubleshoot_test_current_endpoint_title">Endpoint</string>
<string name="settings_troubleshoot_test_current_endpoint_success">Current endpoint: %s</string>
<string name="settings_troubleshoot_test_current_endpoint_failed">Cannot find the endpoint.</string>
<string name="settings_troubleshoot_test_current_gateway_title">Gateway</string>
<string name="settings_troubleshoot_test_current_gateway">Current gateway: %s</string>
</resources> </resources>