Reworked permissions fragment

This commit is contained in:
Sylvain Berfini 2023-10-12 15:50:47 +02:00
parent faf3e887b9
commit c9db3df251
7 changed files with 114 additions and 277 deletions

View file

@ -87,8 +87,6 @@ class LinphoneApplication : Application(), ImageLoaderFactory {
override fun newImageLoader(): ImageLoader {
return ImageLoader.Builder(this)
.crossfade(true)
.crossfade(400)
.components {
add(VideoFrameDecoder.Factory())
add(SvgDecoder.Factory())

View file

@ -30,11 +30,8 @@ import androidx.annotation.UiThread
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import androidx.navigation.navGraphViewModels
import org.linphone.R
import org.linphone.core.tools.Log
import org.linphone.databinding.AssistantPermissionsFragmentBinding
import org.linphone.ui.assistant.viewmodel.PermissionsViewModel
@UiThread
class PermissionsFragment : Fragment() {
@ -44,41 +41,19 @@ class PermissionsFragment : Fragment() {
private lateinit var binding: AssistantPermissionsFragmentBinding
private val viewModel: PermissionsViewModel by navGraphViewModels(
R.id.assistant_nav_graph
)
private val requestPermissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestMultiplePermissions()
) { permissions ->
permissions.entries.forEach() {
val permissionName = it.key
val isGranted = it.value
when (permissionName) {
"READ_CONTACTS" -> {
viewModel.readContacts.value = isGranted
}
"POST_NOTIFICATIONS" -> {
viewModel.postNotifications.value = isGranted
}
"RECORD_AUDIO" -> {
viewModel.recordAudio.value = isGranted
}
"CAMERA" -> {
viewModel.accessCamera.value = isGranted
}
else -> {}
}
if (isGranted) {
Log.i("Permission [$permissionName] is now granted")
} else {
Log.i("Permission [$permissionName] has been denied")
}
}
checkIfAllPermissionsHaveBeenGranted()
goToLoginFragment()
}
override fun onCreateView(
@ -94,33 +69,11 @@ class PermissionsFragment : Fragment() {
super.onViewCreated(view, savedInstanceState)
binding.lifecycleOwner = viewLifecycleOwner
binding.viewModel = viewModel
binding.setBackClickListener {
findNavController().popBackStack()
}
binding.setGrantReadContactsClickListener {
Log.i("$TAG Requesting READ_CONTACTS permission")
requestPermissionLauncher.launch(arrayOf(Manifest.permission.READ_CONTACTS))
}
// TODO FIXME: use compat for older Androids
binding.setGrantPostNotificationsClickListener {
Log.i("$TAG Requesting POST_NOTIFICATIONS permission")
requestPermissionLauncher.launch(arrayOf(Manifest.permission.POST_NOTIFICATIONS))
}
binding.setGrantRecordAudioClickListener {
Log.i("$TAG Requesting RECORD_AUDIO permission")
requestPermissionLauncher.launch(arrayOf(Manifest.permission.RECORD_AUDIO))
}
binding.setGrantAccessCameraClickListener {
Log.i("$TAG Requesting CAMERA permission")
requestPermissionLauncher.launch(arrayOf(Manifest.permission.CAMERA))
}
binding.setSkipClickListener {
Log.i("$TAG User clicked skip...")
goToLoginFragment()
@ -130,8 +83,8 @@ class PermissionsFragment : Fragment() {
Log.i("$TAG Requesting all permissions")
requestPermissionLauncher.launch(
arrayOf(
Manifest.permission.READ_CONTACTS,
Manifest.permission.POST_NOTIFICATIONS,
Manifest.permission.READ_CONTACTS,
Manifest.permission.RECORD_AUDIO,
Manifest.permission.CAMERA
)
@ -147,42 +100,8 @@ class PermissionsFragment : Fragment() {
}
}
override fun onResume() {
super.onResume()
viewModel.readContacts.value = ContextCompat.checkSelfPermission(
requireContext(),
Manifest.permission.READ_CONTACTS
) == PackageManager.PERMISSION_GRANTED
// TODO FIXME: use compat for older Androids
viewModel.postNotifications.value = ContextCompat.checkSelfPermission(
requireContext(),
Manifest.permission.POST_NOTIFICATIONS
) == PackageManager.PERMISSION_GRANTED
viewModel.recordAudio.value = ContextCompat.checkSelfPermission(
requireContext(),
Manifest.permission.RECORD_AUDIO
) == PackageManager.PERMISSION_GRANTED
viewModel.accessCamera.value = ContextCompat.checkSelfPermission(
requireContext(),
Manifest.permission.CAMERA
) == PackageManager.PERMISSION_GRANTED
checkIfAllPermissionsHaveBeenGranted()
}
private fun goToLoginFragment() {
val action = PermissionsFragmentDirections.actionPermissionsFragmentToLoginFragment()
findNavController().navigate(action)
}
private fun checkIfAllPermissionsHaveBeenGranted() {
if (viewModel.readContacts.value == true && viewModel.postNotifications.value == true && viewModel.recordAudio.value == true && viewModel.accessCamera.value == true) {
Log.i("$TAG All permissions are granted, continuing to login fragment")
goToLoginFragment()
}
}
}

View file

@ -1,34 +0,0 @@
/*
* Copyright (c) 2010-2023 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 <http://www.gnu.org/licenses/>.
*/
package org.linphone.ui.assistant.viewmodel
import androidx.annotation.UiThread
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class PermissionsViewModel @UiThread constructor() : ViewModel() {
val readContacts = MutableLiveData<Boolean>()
val postNotifications = MutableLiveData<Boolean>()
val recordAudio = MutableLiveData<Boolean>()
val accessCamera = MutableLiveData<Boolean>()
}

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="256"
android:viewportHeight="256">
<path
android:pathData="M224,71.1a8,8 0,0 1,-10.78 -3.42,94.13 94.13,0 0,0 -33.46,-36.91 8,8 0,1 1,8.54 -13.54,111.46 111.46,0 0,1 39.12,43.09A8,8 0,0 1,224 71.1ZM35.71,72a8,8 0,0 0,7.1 -4.32A94.13,94.13 0,0 1,76.27 30.77a8,8 0,1 0,-8.54 -13.54A111.46,111.46 0,0 0,28.61 60.32,8 8,0 0,0 35.71,72ZM221.81,175.94A16,16 0,0 1,208 200L167.2,200a40,40 0,0 1,-78.4 0L48,200a16,16 0,0 1,-13.79 -24.06C43.22,160.39 48,138.28 48,112a80,80 0,0 1,160 0C208,138.27 212.78,160.38 221.81,175.94ZM150.62,200L105.38,200a24,24 0,0 0,45.24 0ZM208,184c-10.64,-18.27 -16,-42.49 -16,-72a64,64 0,0 0,-128 0c0,29.52 -5.38,53.74 -16,72Z"
android:fillColor="#4e6074"/>
</vector>

View file

@ -26,9 +26,6 @@
<variable
name="grantAllClickListener"
type="View.OnClickListener" />
<variable
name="viewModel"
type="org.linphone.ui.assistant.viewmodel.PermissionsViewModel" />
</data>
<ScrollView
@ -91,194 +88,140 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/title" />
<com.google.android.material.materialswitch.MaterialSwitch
style="@style/material_switch_style"
android:id="@+id/read_contacts_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:layout_marginEnd="16dp"
android:checked="@{viewModel.readContacts}"
android:enabled="@{!viewModel.readContacts}"
android:onClick="@{grantReadContactsClickListener}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/subtitle" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/settings_title_style"
android:id="@+id/read_contacts_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
<ImageView
android:id="@+id/post_notifications_icon"
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_marginTop="44dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="10dp"
android:text="@string/assistant_permissions_read_contacts_title"
android:maxLines="1"
android:ellipsize="end"
app:layout_constraintTop_toTopOf="@id/read_contacts_switch"
app:layout_constraintBottom_toTopOf="@id/read_contacts_subtitle"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/read_contacts_switch"/>
android:background="@drawable/circle_light_blue_button_background"
android:padding="12dp"
android:src="@drawable/bell_ringing"
app:tint="@color/gray_main2_500"
app:layout_constraintTop_toBottomOf="@id/subtitle"
app:layout_constraintStart_toStartOf="parent"/>
<androidx.appcompat.widget.AppCompatTextView
style="@style/settings_subtitle_style"
android:id="@+id/read_contacts_subtitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="10dp"
android:text="@string/assistant_permissions_read_contacts_message"
app:layout_constraintTop_toBottomOf="@id/read_contacts_title"
app:layout_constraintBottom_toBottomOf="@id/read_contacts_switch"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/read_contacts_switch"/>
<com.google.android.material.materialswitch.MaterialSwitch
style="@style/material_switch_style"
android:id="@+id/post_notifications_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginEnd="16dp"
android:checked="@{viewModel.postNotifications}"
android:enabled="@{!viewModel.postNotifications}"
android:onClick="@{grantPostNotificationsClickListener}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/read_contacts_switch" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/settings_title_style"
style="@style/default_text_style"
android:id="@+id/post_notifications_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="10dp"
android:layout_marginEnd="16dp"
android:text="@string/assistant_permissions_post_notifications_title"
android:maxLines="1"
android:maxLines="2"
android:ellipsize="end"
app:layout_constraintTop_toTopOf="@id/post_notifications_switch"
app:layout_constraintBottom_toTopOf="@id/post_notifications_subtitle"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/post_notifications_switch"/>
app:layout_constraintTop_toTopOf="@id/post_notifications_icon"
app:layout_constraintStart_toEndOf="@id/post_notifications_icon"
app:layout_constraintBottom_toBottomOf="@id/post_notifications_icon"
app:layout_constraintEnd_toEndOf="parent"/>
<ImageView
android:id="@+id/read_contacts_icon"
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_marginTop="25dp"
android:layout_marginStart="16dp"
android:background="@drawable/circle_light_blue_button_background"
android:padding="12dp"
android:src="@drawable/address_book"
app:tint="@color/gray_main2_500"
app:layout_constraintTop_toBottomOf="@id/post_notifications_icon"
app:layout_constraintStart_toStartOf="parent"/>
<androidx.appcompat.widget.AppCompatTextView
style="@style/settings_subtitle_style"
android:id="@+id/post_notifications_subtitle"
style="@style/default_text_style"
android:id="@+id/read_contacts_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="10dp"
android:text="@string/assistant_permissions_post_notifications_message"
app:layout_constraintTop_toBottomOf="@id/post_notifications_title"
app:layout_constraintBottom_toBottomOf="@id/post_notifications_switch"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/post_notifications_switch"/>
<com.google.android.material.materialswitch.MaterialSwitch
style="@style/material_switch_style"
android:id="@+id/record_audio_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginEnd="16dp"
android:checked="@{viewModel.recordAudio}"
android:enabled="@{!viewModel.recordAudio}"
android:onClick="@{grantRecordAudioClickListener}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/post_notifications_switch" />
android:text="@string/assistant_permissions_read_contacts_title"
android:maxLines="2"
android:ellipsize="end"
app:layout_constraintTop_toTopOf="@id/read_contacts_icon"
app:layout_constraintStart_toEndOf="@id/read_contacts_icon"
app:layout_constraintBottom_toBottomOf="@id/read_contacts_icon"
app:layout_constraintEnd_toEndOf="parent"/>
<ImageView
android:id="@+id/record_audio_icon"
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_marginTop="25dp"
android:layout_marginStart="16dp"
android:background="@drawable/circle_light_blue_button_background"
android:padding="12dp"
android:src="@drawable/microphone"
app:tint="@color/gray_main2_500"
app:layout_constraintTop_toBottomOf="@id/read_contacts_icon"
app:layout_constraintStart_toStartOf="parent"/>
<androidx.appcompat.widget.AppCompatTextView
style="@style/settings_title_style"
style="@style/default_text_style"
android:id="@+id/record_audio_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="10dp"
android:text="@string/assistant_permissions_record_audio_title"
android:maxLines="1"
android:ellipsize="end"
app:layout_constraintTop_toTopOf="@id/record_audio_switch"
app:layout_constraintBottom_toTopOf="@id/record_audio_subtitle"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/record_audio_switch"/>
<androidx.appcompat.widget.AppCompatTextView
style="@style/settings_subtitle_style"
android:id="@+id/record_audio_subtitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="10dp"
android:text="@string/assistant_permissions_record_audio_message"
app:layout_constraintTop_toBottomOf="@id/record_audio_title"
app:layout_constraintBottom_toBottomOf="@id/record_audio_switch"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/record_audio_switch"/>
<com.google.android.material.materialswitch.MaterialSwitch
style="@style/material_switch_style"
android:id="@+id/access_camera_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginEnd="16dp"
android:checked="@{viewModel.accessCamera}"
android:enabled="@{!viewModel.accessCamera}"
android:onClick="@{grantAccessCameraClickListener}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/record_audio_switch" />
android:text="@string/assistant_permissions_record_audio_title"
android:maxLines="2"
android:ellipsize="end"
app:layout_constraintTop_toTopOf="@id/record_audio_icon"
app:layout_constraintStart_toEndOf="@id/record_audio_icon"
app:layout_constraintBottom_toBottomOf="@id/record_audio_icon"
app:layout_constraintEnd_toEndOf="parent"/>
<ImageView
android:id="@+id/access_camera_icon"
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_marginTop="25dp"
android:layout_marginStart="16dp"
android:background="@drawable/circle_light_blue_button_background"
android:padding="12dp"
android:src="@drawable/video_camera"
app:tint="@color/gray_main2_500"
app:layout_constraintTop_toBottomOf="@id/record_audio_icon"
app:layout_constraintStart_toStartOf="parent"/>
<androidx.appcompat.widget.AppCompatTextView
style="@style/settings_title_style"
style="@style/default_text_style"
android:id="@+id/access_camera_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="10dp"
android:layout_marginEnd="16dp"
android:text="@string/assistant_permissions_access_camera_title"
android:maxLines="1"
android:maxLines="2"
android:ellipsize="end"
app:layout_constraintTop_toTopOf="@id/access_camera_switch"
app:layout_constraintBottom_toTopOf="@id/access_camera_subtitle"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/access_camera_switch"/>
<androidx.appcompat.widget.AppCompatTextView
style="@style/settings_subtitle_style"
android:id="@+id/access_camera_subtitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="10dp"
android:text="@string/assistant_permissions_access_camera_message"
app:layout_constraintTop_toBottomOf="@id/access_camera_title"
app:layout_constraintBottom_toBottomOf="@id/access_camera_switch"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/access_camera_switch"/>
app:layout_constraintTop_toTopOf="@id/access_camera_icon"
app:layout_constraintStart_toEndOf="@id/access_camera_icon"
app:layout_constraintBottom_toBottomOf="@id/access_camera_icon"
app:layout_constraintEnd_toEndOf="parent"/>
<androidx.appcompat.widget.AppCompatTextView
android:onClick="@{skipClickListener}"
style="@style/default_text_style_600"
style="@style/secondary_button_label_style"
android:id="@+id/skip"
android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:paddingTop="13dp"
android:paddingBottom="13dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="@dimen/screen_bottom_margin"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:text="@string/welcome_carousel_skip"
android:textSize="13sp"
android:textColor="@color/gray_main2_500"
app:layout_constraintVertical_bias="0"
android:text="@string/assistant_permissions_skip_permissions"
app:layout_constraintWidth_max="@dimen/button_max_width"
app:layout_constraintBottom_toTopOf="@id/grant_all_permissions"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/access_camera_switch"
app:layout_constraintBottom_toBottomOf="parent"/>
app:layout_constraintEnd_toEndOf="parent" />
<androidx.appcompat.widget.AppCompatTextView
android:onClick="@{grantAllClickListener}"
style="@style/primary_button_label_style"
android:id="@+id/continue_third_party_account_login"
android:id="@+id/grant_all_permissions"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
@ -292,7 +235,6 @@
app:layout_constraintVertical_bias="1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/skip"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -160,16 +160,13 @@
<string name="assistant_account_login_error">Failed to login: error code is %i</string>
<string name="assistant_permissions_title">Grant permissions</string>
<string name="assistant_permissions_grant_all_of_them">Grant all</string>
<string name="assistant_permissions_skip_permissions">Do it later</string>
<string name="assistant_permissions_subtitle">To be able to work properly, we need you to grand the application the following permissions.\n\nIf you don\'t, some features won\'t be available, but you can grant them later.</string>
<string name="assistant_permissions_read_contacts_title">Read contacts</string>
<string name="assistant_permissions_read_contacts_message">This allows us to import your address-book in &appName;</string>
<string name="assistant_permissions_post_notifications_title">Post notifications</string>
<string name="assistant_permissions_post_notifications_message">To notify incoming calls &amp; chat messages</string>
<string name="assistant_permissions_record_audio_title">Record audio</string>
<string name="assistant_permissions_record_audio_message">For audio calls, duh!</string>
<string name="assistant_permissions_access_camera_title">Access camera</string>
<string name="assistant_permissions_access_camera_message">For video calls &amp; scan QR codes</string>
<string name="assistant_permissions_subtitle">To fully enjoy &appName; we need you to grant us the following permissions :</string>
<string name="assistant_permissions_read_contacts_title"><b>Read contacts:</b> To display your contacts and find whom is using &appName;.</string>
<string name="assistant_permissions_post_notifications_title"><b>Post notifications:</b> To be informed when you receive a message or a call.</string>
<string name="assistant_permissions_record_audio_title"><b>Record audio:</b> So your correspondent can hear you and to record voice messages.</string>
<string name="assistant_permissions_access_camera_title"><b>Access camera:</b> To capture video during video calls and conferences.</string>
<string name="drawer_menu_manage_account">Manage the profile</string>
<string name="drawer_menu_account_connection_status_connected">Connected</string>

View file

@ -3,26 +3,32 @@
<style name="default_text_style_300">
<item name="android:fontFamily">@font/noto_sans_300</item>
<item name="android:textColor">@color/gray_main2_600</item>
<item name="android:textSize">14sp</item>
</style>
<style name="default_text_style">
<item name="android:fontFamily">@font/noto_sans</item>
<item name="android:textColor">@color/gray_main2_600</item>
<item name="android:textSize">14sp</item>
</style>
<style name="default_text_style_500">
<item name="android:fontFamily">@font/noto_sans_500</item>
<item name="android:textColor">@color/gray_main2_600</item>
<item name="android:textSize">14sp</item>
</style>
<style name="default_text_style_600">
<item name="android:fontFamily">@font/noto_sans_600</item>
<item name="android:textColor">@color/gray_main2_600</item>
<item name="android:textSize">14sp</item>
</style>
<style name="default_text_style_700">
<item name="android:fontFamily">@font/noto_sans_700</item>
<item name="android:textColor">@color/gray_main2_600</item>
<item name="android:textSize">14sp</item>
</style>
<style name="default_text_style_800">
<item name="android:fontFamily">@font/noto_sans_800</item>
<item name="android:textColor">@color/gray_main2_600</item>
<item name="android:textSize">14sp</item>
</style>
<style name="main_page_title_style">
<item name="android:fontFamily">@font/noto_sans_800</item>