From 08052d64fde1910f41f6db42c4c8a3f0e3e8a05b Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 24 Jun 2024 11:10:19 +0200 Subject: [PATCH] Added top bar alert if post notifications permission isn't granted + improved connexion error toast + improved network unreachable alert --- .../java/org/linphone/ui/main/MainActivity.kt | 19 ++++ .../ui/main/viewmodel/MainViewModel.kt | 89 +++++++++++++++++-- app/src/main/res/values-fr/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + 4 files changed, 103 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/org/linphone/ui/main/MainActivity.kt b/app/src/main/java/org/linphone/ui/main/MainActivity.kt index f98e86609..7b9cf9219 100644 --- a/app/src/main/java/org/linphone/ui/main/MainActivity.kt +++ b/app/src/main/java/org/linphone/ui/main/MainActivity.kt @@ -34,6 +34,7 @@ import android.view.ViewGroup import android.view.ViewTreeObserver import androidx.activity.SystemBarStyle import androidx.activity.enableEdgeToEdge +import androidx.activity.result.contract.ActivityResultContracts import androidx.annotation.UiThread import androidx.car.app.connection.CarConnection import androidx.core.os.bundleOf @@ -107,6 +108,17 @@ class MainActivity : GenericActivity() { } } + private val postNotificationsPermissionLauncher = registerForActivityResult( + ActivityResultContracts.RequestPermission() + ) { isGranted -> + if (isGranted) { + Log.i("$TAG POST_NOTIFICATIONS permission has been granted") + viewModel.updatePostNotificationsPermission() + } else { + Log.w("$TAG POST_NOTIFICATIONS permission has been denied!") + } + } + override fun onCreate(savedInstanceState: Bundle?) { // Must be done before the setContentView installSplashScreen() @@ -172,6 +184,12 @@ class MainActivity : GenericActivity() { } } + viewModel.askPostNotificationsPermissionEvent.observe(this) { + it.consume { + postNotificationsPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS) + } + } + viewModel.defaultAccountRegistrationErrorEvent.observe(this) { it.consume { error -> val tag = "DEFAULT_ACCOUNT_REGISTRATION_ERROR" @@ -325,6 +343,7 @@ class MainActivity : GenericActivity() { super.onResume() viewModel.checkForNewAccount() + viewModel.updateNetworkReachability() } override fun onNewIntent(intent: Intent) { diff --git a/app/src/main/java/org/linphone/ui/main/viewmodel/MainViewModel.kt b/app/src/main/java/org/linphone/ui/main/viewmodel/MainViewModel.kt index 086b03206..07bf8fdef 100644 --- a/app/src/main/java/org/linphone/ui/main/viewmodel/MainViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/viewmodel/MainViewModel.kt @@ -19,8 +19,13 @@ */ package org.linphone.ui.main.viewmodel +import android.Manifest +import android.content.pm.PackageManager +import android.os.Build +import androidx.annotation.RequiresApi import androidx.annotation.UiThread import androidx.annotation.WorkerThread +import androidx.core.content.ContextCompat import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope @@ -55,6 +60,7 @@ class MainViewModel @UiThread constructor() : ViewModel() { const val NONE = 0 const val NON_DEFAULT_ACCOUNT_NOTIFICATIONS = 5 const val NON_DEFAULT_ACCOUNT_NOT_CONNECTED = 10 + const val SEND_NOTIFICATIONS_PERMISSION_NOT_GRANTED = 17 const val NETWORK_NOT_REACHABLE = 19 const val SINGLE_CALL = 20 const val MULTIPLE_CALLS = 21 @@ -84,6 +90,10 @@ class MainViewModel @UiThread constructor() : ViewModel() { MutableLiveData>() } + val askPostNotificationsPermissionEvent: MutableLiveData> by lazy { + MutableLiveData>() + } + val showNewAccountToastEvent: MutableLiveData> by lazy { MutableLiveData>() } @@ -165,13 +175,7 @@ class MainViewModel @UiThread constructor() : ViewModel() { @WorkerThread override fun onNetworkReachable(core: Core, reachable: Boolean) { - Log.i("$TAG Network is ${if (reachable) "reachable" else "not reachable"}") - if (!reachable) { - val label = AppUtils.getString(R.string.network_not_reachable) - addAlert(NETWORK_NOT_REACHABLE, label) - } else { - removeAlert(NETWORK_NOT_REACHABLE) - } + checkNetworkReachability() } @WorkerThread @@ -216,6 +220,15 @@ class MainViewModel @UiThread constructor() : ViewModel() { } } } + RegistrationState.Progress, RegistrationState.Refreshing -> { + if (defaultAccountRegistrationFailed) { + Log.i( + "$TAG Default account is registering, removing registration failed toast for now" + ) + defaultAccountRegistrationFailed = false + defaultAccountRegistrationErrorEvent.postValue(Event(false)) + } + } else -> {} } } @@ -267,6 +280,10 @@ class MainViewModel @UiThread constructor() : ViewModel() { addAlert(NETWORK_NOT_REACHABLE, label) } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + checkPostNotificationsPermission() + } + if (core.callsNb > 0) { updateCallAlert() } @@ -300,6 +317,22 @@ class MainViewModel @UiThread constructor() : ViewModel() { } } + @UiThread + fun updateNetworkReachability() { + coreContext.postOnCoreThread { + checkNetworkReachability() + } + } + + @UiThread + fun updatePostNotificationsPermission() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + coreContext.postOnCoreThread { + checkPostNotificationsPermission() + } + } + } + @UiThread fun checkForNewAccount() { coreContext.postOnCoreThread { core -> @@ -327,6 +360,8 @@ class MainViewModel @UiThread constructor() : ViewModel() { fun onTopBarClicked() { if (atLeastOneCall.value == true) { goBackToCallEvent.value = Event(true) + } else if (!isPostNotificationsPermissionGranted()) { + askPostNotificationsPermissionEvent.value = Event(true) } else { openDrawerEvent.value = Event(true) } @@ -458,6 +493,9 @@ class MainViewModel @UiThread constructor() : ViewModel() { NETWORK_NOT_REACHABLE -> { alertIcon.postValue(R.drawable.wifi_slash) } + SEND_NOTIFICATIONS_PERMISSION_NOT_GRANTED -> { + alertIcon.postValue(R.drawable.bell_simple_slash) + } SINGLE_CALL, MULTIPLE_CALLS -> { alertIcon.postValue(R.drawable.phone) } @@ -489,4 +527,41 @@ class MainViewModel @UiThread constructor() : ViewModel() { Log.i("$TAG Trying to fetch & import native contacts") startLoadingContactsEvent.postValue(Event(true)) } + + @WorkerThread + private fun checkNetworkReachability() { + val reachable = coreContext.core.isNetworkReachable + Log.i("$TAG Network is ${if (reachable) "reachable" else "not reachable"}") + if (!reachable) { + val label = AppUtils.getString(R.string.network_not_reachable) + addAlert(NETWORK_NOT_REACHABLE, label) + } else { + removeAlert(NETWORK_NOT_REACHABLE) + } + } + + private fun isPostNotificationsPermissionGranted(): Boolean { + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + ContextCompat.checkSelfPermission( + coreContext.context, + Manifest.permission.POST_NOTIFICATIONS + ) == PackageManager.PERMISSION_GRANTED + } else { + true + } + } + + @RequiresApi(Build.VERSION_CODES.TIRAMISU) + @WorkerThread + private fun checkPostNotificationsPermission() { + if (!isPostNotificationsPermissionGranted()) { + Log.w("$TAG POST_NOTIFICATIONS seems to be not granted!") + val label = AppUtils.getString(R.string.post_notifications_permission_not_granted) + coreContext.postOnCoreThread { + addAlert(SEND_NOTIFICATIONS_PERMISSION_NOT_GRANTED, label) + } + } else { + removeAlert(SEND_NOTIFICATIONS_PERMISSION_NOT_GRANTED) + } + } } diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 0b56ef70a..7dbcbf699 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -698,6 +698,7 @@ Conversations Contacts Suggestions + La permission de poster des notifications n\'est pas donnée ! Passer diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c68d4faf6..6cad33680 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -735,6 +735,7 @@ Conversations Contacts Suggestions + Post notifications permission not granted! Skip