From 416cc6ea7f0cb009fec3c45b5a2871072a6dcdde Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 2 Oct 2025 15:17:05 +0200 Subject: [PATCH] Only display missing permissions in assistant PermissionsFragment --- .../assistant/fragment/PermissionsFragment.kt | 13 ++++- .../viewmodel/PermissionsViewModel.kt | 52 +++++++++++++++++++ .../layout/assistant_permissions_fragment.xml | 11 ++++ 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/org/linphone/ui/assistant/viewmodel/PermissionsViewModel.kt diff --git a/app/src/main/java/org/linphone/ui/assistant/fragment/PermissionsFragment.kt b/app/src/main/java/org/linphone/ui/assistant/fragment/PermissionsFragment.kt index 562ae8936..3af77bfd0 100644 --- a/app/src/main/java/org/linphone/ui/assistant/fragment/PermissionsFragment.kt +++ b/app/src/main/java/org/linphone/ui/assistant/fragment/PermissionsFragment.kt @@ -29,6 +29,7 @@ import androidx.activity.result.contract.ActivityResultContracts import androidx.annotation.UiThread import androidx.core.content.ContextCompat import androidx.navigation.fragment.findNavController +import androidx.navigation.navGraphViewModels import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.R import org.linphone.compatibility.Compatibility @@ -36,6 +37,8 @@ import org.linphone.core.tools.Log import org.linphone.databinding.AssistantPermissionsFragmentBinding import org.linphone.ui.GenericFragment import org.linphone.ui.assistant.AssistantActivity +import org.linphone.ui.assistant.viewmodel.PermissionsViewModel +import kotlin.getValue @UiThread class PermissionsFragment : GenericFragment() { @@ -45,6 +48,10 @@ class PermissionsFragment : GenericFragment() { private lateinit var binding: AssistantPermissionsFragmentBinding + private val viewModel: PermissionsViewModel by navGraphViewModels( + R.id.assistant_nav_graph + ) + private var leaving = false private val requestPermissionLauncher = registerForActivityResult( @@ -93,6 +100,7 @@ class PermissionsFragment : GenericFragment() { super.onViewCreated(view, savedInstanceState) binding.lifecycleOwner = viewLifecycleOwner + binding.viewModel = viewModel binding.setBackClickListener { findNavController().popBackStack() @@ -180,10 +188,13 @@ class PermissionsFragment : GenericFragment() { private fun areAllPermissionsGranted(): Boolean { for (permission in Compatibility.getAllRequiredPermissionsArray()) { - if (ContextCompat.checkSelfPermission(requireContext(), permission) != PackageManager.PERMISSION_GRANTED) { + val granted = ContextCompat.checkSelfPermission(requireContext(), permission) == PackageManager.PERMISSION_GRANTED + viewModel.setPermissionGranted(permission, granted) + if (!granted) { Log.w("$TAG Permission [$permission] hasn't been granted yet!") return false } + } return Compatibility.hasFullScreenIntentPermission(requireContext()) } diff --git a/app/src/main/java/org/linphone/ui/assistant/viewmodel/PermissionsViewModel.kt b/app/src/main/java/org/linphone/ui/assistant/viewmodel/PermissionsViewModel.kt new file mode 100644 index 000000000..9030a5689 --- /dev/null +++ b/app/src/main/java/org/linphone/ui/assistant/viewmodel/PermissionsViewModel.kt @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2010-2025 Belledonne Communications SARL. + * + * This file is part of linphone-android + * (see https://www.linphone.org). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.linphone.ui.assistant.viewmodel + +import android.Manifest +import androidx.annotation.UiThread +import androidx.lifecycle.MutableLiveData +import org.linphone.core.tools.Log +import org.linphone.ui.GenericViewModel + +class PermissionsViewModel +@UiThread +constructor() : GenericViewModel() { + companion object { + private const val TAG = "[Permissions ViewModel]" + } + + val cameraPermissionGranted = MutableLiveData() + + val recordAudioPermissionGranted = MutableLiveData() + + val readContactsPermissionGranted = MutableLiveData() + + val postNotificationsPermissionGranted = MutableLiveData() + + fun setPermissionGranted(permission: String, granted: Boolean) { + Log.i("$TAG Permission [$permission] is ${if (granted) "granted" else "not granted yet/denied"}") + when (permission) { + Manifest.permission.READ_CONTACTS -> readContactsPermissionGranted.postValue(granted) + Manifest.permission.RECORD_AUDIO -> recordAudioPermissionGranted.postValue(granted) + Manifest.permission.CAMERA -> cameraPermissionGranted.postValue(granted) + Manifest.permission.POST_NOTIFICATIONS -> postNotificationsPermissionGranted.postValue(granted) + } + } +} diff --git a/app/src/main/res/layout/assistant_permissions_fragment.xml b/app/src/main/res/layout/assistant_permissions_fragment.xml index f487daf3b..2b7e608a9 100644 --- a/app/src/main/res/layout/assistant_permissions_fragment.xml +++ b/app/src/main/res/layout/assistant_permissions_fragment.xml @@ -26,6 +26,9 @@ + @@ -100,6 +104,7 @@ android:text="@string/assistant_permissions_post_notifications_title" android:maxLines="2" android:ellipsize="end" + android:visibility="@{viewModel.postNotificationsPermissionGranted ? View.GONE : View.VISIBLE}" app:layout_constraintTop_toTopOf="@id/post_notifications_icon" app:layout_constraintStart_toEndOf="@id/post_notifications_icon" app:layout_constraintBottom_toBottomOf="@id/post_notifications_icon" @@ -115,6 +120,7 @@ android:padding="12dp" android:src="@drawable/address_book" android:contentDescription="@null" + android:visibility="@{viewModel.readContactsPermissionGranted ? View.GONE : View.VISIBLE}" app:tint="?attr/color_main2_500" app:layout_constraintTop_toBottomOf="@id/post_notifications_icon" app:layout_constraintStart_toStartOf="parent"/> @@ -129,6 +135,7 @@ android:text="@string/assistant_permissions_read_contacts_title" android:maxLines="2" android:ellipsize="end" + android:visibility="@{viewModel.readContactsPermissionGranted ? View.GONE : View.VISIBLE}" app:layout_constraintTop_toTopOf="@id/read_contacts_icon" app:layout_constraintStart_toEndOf="@id/read_contacts_icon" app:layout_constraintBottom_toBottomOf="@id/read_contacts_icon" @@ -144,6 +151,7 @@ android:padding="12dp" android:src="@drawable/microphone" android:contentDescription="@null" + android:visibility="@{viewModel.recordAudioPermissionGranted ? View.GONE : View.VISIBLE}" app:tint="?attr/color_main2_500" app:layout_constraintTop_toBottomOf="@id/read_contacts_icon" app:layout_constraintStart_toStartOf="parent"/> @@ -158,6 +166,7 @@ android:text="@string/assistant_permissions_record_audio_title" android:maxLines="2" android:ellipsize="end" + android:visibility="@{viewModel.recordAudioPermissionGranted ? View.GONE : View.VISIBLE}" app:layout_constraintTop_toTopOf="@id/record_audio_icon" app:layout_constraintStart_toEndOf="@id/record_audio_icon" app:layout_constraintBottom_toBottomOf="@id/record_audio_icon" @@ -173,6 +182,7 @@ android:padding="12dp" android:src="@drawable/video_camera" android:contentDescription="@null" + android:visibility="@{viewModel.cameraPermissionGranted ? View.GONE : View.VISIBLE}" app:tint="?attr/color_main2_500" app:layout_constraintTop_toBottomOf="@id/record_audio_icon" app:layout_constraintStart_toStartOf="parent"/> @@ -187,6 +197,7 @@ android:text="@string/assistant_permissions_access_camera_title" android:maxLines="2" android:ellipsize="end" + android:visibility="@{viewModel.cameraPermissionGranted ? View.GONE : View.VISIBLE}" app:layout_constraintTop_toTopOf="@id/access_camera_icon" app:layout_constraintStart_toEndOf="@id/access_camera_icon" app:layout_constraintBottom_toBottomOf="@id/access_camera_icon"