diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d787b4f97..4c3a0ae64 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,6 +1,9 @@ + + + diff --git a/app/src/main/java/org/linphone/contacts/ContactsManager.kt b/app/src/main/java/org/linphone/contacts/ContactsManager.kt index 213ce1334..1746d0a94 100644 --- a/app/src/main/java/org/linphone/contacts/ContactsManager.kt +++ b/app/src/main/java/org/linphone/contacts/ContactsManager.kt @@ -41,7 +41,7 @@ import org.linphone.utils.ImageUtils class ContactsManager @UiThread constructor(context: Context) { companion object { - const val TAG = "[Contacts Manager]" + private const val TAG = "[Contacts Manager]" } val contactAvatar: IconCompat diff --git a/app/src/main/java/org/linphone/core/CoreContext.kt b/app/src/main/java/org/linphone/core/CoreContext.kt index a4f4a7547..bf10cb0ee 100644 --- a/app/src/main/java/org/linphone/core/CoreContext.kt +++ b/app/src/main/java/org/linphone/core/CoreContext.kt @@ -42,7 +42,7 @@ import org.linphone.utils.LinphoneUtils class CoreContext @UiThread constructor(val context: Context) : HandlerThread("Core Thread") { companion object { - const val TAG = "[Core Context]" + private const val TAG = "[Core Context]" } lateinit var core: Core diff --git a/app/src/main/java/org/linphone/core/CoreForegroundService.kt b/app/src/main/java/org/linphone/core/CoreForegroundService.kt index 77b47438d..ffea9f3e4 100644 --- a/app/src/main/java/org/linphone/core/CoreForegroundService.kt +++ b/app/src/main/java/org/linphone/core/CoreForegroundService.kt @@ -26,7 +26,7 @@ import org.linphone.core.tools.service.CoreService class CoreForegroundService : CoreService() { companion object { - const val TAG = "[Core Foreground Service]" + private const val TAG = "[Core Foreground Service]" } override fun onCreate() { diff --git a/app/src/main/java/org/linphone/notifications/NotificationBroadcastReceiver.kt b/app/src/main/java/org/linphone/notifications/NotificationBroadcastReceiver.kt index baf6720d8..3d4f14aab 100644 --- a/app/src/main/java/org/linphone/notifications/NotificationBroadcastReceiver.kt +++ b/app/src/main/java/org/linphone/notifications/NotificationBroadcastReceiver.kt @@ -28,7 +28,7 @@ import org.linphone.core.tools.Log class NotificationBroadcastReceiver : BroadcastReceiver() { companion object { - const val TAG = "[NotificationBroadcastReceiver]" + private const val TAG = "[NotificationBroadcastReceiver]" } override fun onReceive(context: Context, intent: Intent) { diff --git a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt index 338a15eb4..7a59e510a 100644 --- a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt +++ b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt @@ -56,7 +56,7 @@ import org.linphone.utils.LinphoneUtils class NotificationsManager @MainThread constructor(private val context: Context) { companion object { - const val TAG = "[Notifications Manager]" + private const val TAG = "[Notifications Manager]" const val INTENT_HANGUP_CALL_NOTIF_ACTION = "org.linphone.HANGUP_CALL_ACTION" const val INTENT_ANSWER_CALL_NOTIF_ACTION = "org.linphone.ANSWER_CALL_ACTION" diff --git a/app/src/main/java/org/linphone/ui/assistant/viewmodel/AssistantViewModel.kt b/app/src/main/java/org/linphone/ui/assistant/viewmodel/AssistantViewModel.kt index e96daf5cb..53eedeb8c 100644 --- a/app/src/main/java/org/linphone/ui/assistant/viewmodel/AssistantViewModel.kt +++ b/app/src/main/java/org/linphone/ui/assistant/viewmodel/AssistantViewModel.kt @@ -37,7 +37,7 @@ import org.linphone.utils.Event class AssistantViewModel @UiThread constructor() : ViewModel() { companion object { - const val TAG = "[Assistant ViewModel]" + private const val TAG = "[Assistant ViewModel]" } val username = MutableLiveData() diff --git a/app/src/main/java/org/linphone/ui/main/calls/fragment/CallsListFragment.kt b/app/src/main/java/org/linphone/ui/main/calls/fragment/CallsListFragment.kt index c910f31ec..966eaf123 100644 --- a/app/src/main/java/org/linphone/ui/main/calls/fragment/CallsListFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/calls/fragment/CallsListFragment.kt @@ -52,7 +52,7 @@ import org.linphone.utils.Event @UiThread class CallsListFragment : GenericFragment() { companion object { - const val TAG = "[Calls List Fragment]" + private const val TAG = "[Calls List Fragment]" } private lateinit var binding: CallsListFragmentBinding diff --git a/app/src/main/java/org/linphone/ui/main/calls/viewmodel/SuggestionsListViewModel.kt b/app/src/main/java/org/linphone/ui/main/calls/viewmodel/SuggestionsListViewModel.kt index 9bed5ba9b..187aeaac8 100644 --- a/app/src/main/java/org/linphone/ui/main/calls/viewmodel/SuggestionsListViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/calls/viewmodel/SuggestionsListViewModel.kt @@ -37,7 +37,7 @@ import org.linphone.ui.main.model.isInSecureMode class SuggestionsListViewModel @UiThread constructor() : ViewModel() { companion object { - const val TAG = "[Suggestions List ViewModel]" + private const val TAG = "[Suggestions List ViewModel]" } val suggestionsList = MutableLiveData>() diff --git a/app/src/main/java/org/linphone/ui/main/contacts/fragment/ContactFragment.kt b/app/src/main/java/org/linphone/ui/main/contacts/fragment/ContactFragment.kt index 9a0e982ab..abdff70ef 100644 --- a/app/src/main/java/org/linphone/ui/main/contacts/fragment/ContactFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/contacts/fragment/ContactFragment.kt @@ -49,7 +49,7 @@ import org.linphone.utils.Event @UiThread class ContactFragment : GenericFragment() { companion object { - const val TAG = "[Contact Fragment]" + private const val TAG = "[Contact Fragment]" } private lateinit var binding: ContactFragmentBinding diff --git a/app/src/main/java/org/linphone/ui/main/contacts/fragment/ContactsListFragment.kt b/app/src/main/java/org/linphone/ui/main/contacts/fragment/ContactsListFragment.kt index 5db063867..4b3c558ae 100644 --- a/app/src/main/java/org/linphone/ui/main/contacts/fragment/ContactsListFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/contacts/fragment/ContactsListFragment.kt @@ -42,7 +42,7 @@ import org.linphone.utils.Event @UiThread class ContactsListFragment : GenericFragment() { companion object { - const val TAG = "[Contacts List Fragment]" + private const val TAG = "[Contacts List Fragment]" } private lateinit var binding: ContactsListFragmentBinding diff --git a/app/src/main/java/org/linphone/ui/main/contacts/fragment/EditContactFragment.kt b/app/src/main/java/org/linphone/ui/main/contacts/fragment/EditContactFragment.kt index 4446882f9..5056877f9 100644 --- a/app/src/main/java/org/linphone/ui/main/contacts/fragment/EditContactFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/contacts/fragment/EditContactFragment.kt @@ -50,7 +50,7 @@ import org.linphone.utils.FileUtils @UiThread class EditContactFragment : GenericFragment() { companion object { - const val TAG = "[Edit Contact Fragment]" + private const val TAG = "[Edit Contact Fragment]" } private lateinit var binding: ContactNewOrEditFragmentBinding diff --git a/app/src/main/java/org/linphone/ui/main/contacts/fragment/NewContactFragment.kt b/app/src/main/java/org/linphone/ui/main/contacts/fragment/NewContactFragment.kt index 828b05a7e..a07719f39 100644 --- a/app/src/main/java/org/linphone/ui/main/contacts/fragment/NewContactFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/contacts/fragment/NewContactFragment.kt @@ -50,7 +50,7 @@ import org.linphone.utils.FileUtils @UiThread class NewContactFragment : GenericFragment() { companion object { - const val TAG = "[New Contact Fragment]" + private const val TAG = "[New Contact Fragment]" } private lateinit var binding: ContactNewOrEditFragmentBinding diff --git a/app/src/main/java/org/linphone/ui/main/contacts/model/ContactAvatarModel.kt b/app/src/main/java/org/linphone/ui/main/contacts/model/ContactAvatarModel.kt index b4c867465..a44611730 100644 --- a/app/src/main/java/org/linphone/ui/main/contacts/model/ContactAvatarModel.kt +++ b/app/src/main/java/org/linphone/ui/main/contacts/model/ContactAvatarModel.kt @@ -32,7 +32,7 @@ import org.linphone.utils.LinphoneUtils class ContactAvatarModel @WorkerThread constructor(val friend: Friend) { companion object { - const val TAG = "[Contact Avatar Model]" + private const val TAG = "[Contact Avatar Model]" } val id = friend.refKey diff --git a/app/src/main/java/org/linphone/ui/main/contacts/viewmodel/ContactNewOrEditViewModel.kt b/app/src/main/java/org/linphone/ui/main/contacts/viewmodel/ContactNewOrEditViewModel.kt index c91bc36be..5a899f122 100644 --- a/app/src/main/java/org/linphone/ui/main/contacts/viewmodel/ContactNewOrEditViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/contacts/viewmodel/ContactNewOrEditViewModel.kt @@ -34,7 +34,7 @@ import org.linphone.utils.FileUtils class ContactNewOrEditViewModel @UiThread constructor() : ViewModel() { companion object { - const val TAG = "[Contact New/Edit View Model]" + private const val TAG = "[Contact New/Edit View Model]" } private lateinit var friend: Friend diff --git a/app/src/main/java/org/linphone/ui/main/contacts/viewmodel/ContactViewModel.kt b/app/src/main/java/org/linphone/ui/main/contacts/viewmodel/ContactViewModel.kt index 2c2232f4d..1d723cd0e 100644 --- a/app/src/main/java/org/linphone/ui/main/contacts/viewmodel/ContactViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/contacts/viewmodel/ContactViewModel.kt @@ -41,7 +41,7 @@ import org.linphone.utils.PhoneNumberUtils class ContactViewModel @UiThread constructor() : ViewModel() { companion object { - const val TAG = "[Contact ViewModel]" + private const val TAG = "[Contact ViewModel]" } val contact = MutableLiveData() diff --git a/app/src/main/java/org/linphone/ui/main/contacts/viewmodel/ContactsListViewModel.kt b/app/src/main/java/org/linphone/ui/main/contacts/viewmodel/ContactsListViewModel.kt index 6c8e391bf..ea46897b9 100644 --- a/app/src/main/java/org/linphone/ui/main/contacts/viewmodel/ContactsListViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/contacts/viewmodel/ContactsListViewModel.kt @@ -37,7 +37,7 @@ import org.linphone.ui.main.model.isInSecureMode class ContactsListViewModel @UiThread constructor() : ViewModel() { companion object { - const val TAG = "[Contacts List ViewModel]" + private const val TAG = "[Contacts List ViewModel]" } val contactsList = MutableLiveData>() diff --git a/app/src/main/java/org/linphone/ui/main/fragment/GenericFragment.kt b/app/src/main/java/org/linphone/ui/main/fragment/GenericFragment.kt index 910b5bcba..bed6b2a72 100644 --- a/app/src/main/java/org/linphone/ui/main/fragment/GenericFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/fragment/GenericFragment.kt @@ -33,18 +33,22 @@ import org.linphone.ui.main.viewmodel.SharedMainViewModel @UiThread abstract class GenericFragment : Fragment() { + companion object { + private const val TAG = "[Generic Fragment]" + } + protected lateinit var sharedViewModel: SharedMainViewModel private val onBackPressedCallback = object : OnBackPressedCallback(false) { override fun handleOnBackPressed() { try { val navController = findNavController() - Log.d("[Generic Fragment] ${getFragmentRealClassName()} handleOnBackPressed") + Log.d("$TAG ${getFragmentRealClassName()} handleOnBackPressed") if (!navController.popBackStack()) { - Log.d("[Generic Fragment] ${getFragmentRealClassName()} couldn't pop") + Log.d("$TAG ${getFragmentRealClassName()} couldn't pop") if (!navController.navigateUp()) { Log.d( - "[Generic Fragment] ${getFragmentRealClassName()} couldn't navigate up" + "$TAG ${getFragmentRealClassName()} couldn't navigate up" ) // Disable this callback & start a new back press event isEnabled = false @@ -53,7 +57,7 @@ abstract class GenericFragment : Fragment() { } } catch (ise: IllegalStateException) { Log.e( - "[Generic Fragment] ${getFragmentRealClassName()}.handleOnBackPressed() Can't go back: $ise" + "$TAG ${getFragmentRealClassName()}.handleOnBackPressed() Can't go back: $ise" ) } } @@ -68,7 +72,7 @@ abstract class GenericFragment : Fragment() { sharedViewModel.isSlidingPaneSlideable.observe(viewLifecycleOwner) { Log.d( - "[Generic Fragment] ${getFragmentRealClassName()} shared main VM sliding pane has changed" + "$TAG ${getFragmentRealClassName()} shared main VM sliding pane has changed" ) onBackPressedCallback.isEnabled = backPressedCallBackEnabled() } @@ -90,17 +94,17 @@ abstract class GenericFragment : Fragment() { try { requireActivity().onBackPressedDispatcher.onBackPressed() } catch (ise: IllegalStateException) { - Log.w("[Generic Fragment] ${getFragmentRealClassName()}.goBack() can't go back: $ise") + Log.w("$TAG ${getFragmentRealClassName()}.goBack() can't go back: $ise") onBackPressedCallback.handleOnBackPressed() } } private fun setupBackPressCallback() { - Log.d("[Generic Fragment] ${getFragmentRealClassName()} setupBackPressCallback") + Log.d("$TAG ${getFragmentRealClassName()} setupBackPressCallback") val backButton = view?.findViewById(R.id.back) if (backButton != null && backButton.visibility == View.VISIBLE) { - Log.d("[Generic Fragment] ${getFragmentRealClassName()} found back button") + Log.d("$TAG ${getFragmentRealClassName()} found back button") // If popping navigation back stack entry would bring us to an "empty" fragment // then don't do it if sliding pane layout isn't "flat" onBackPressedCallback.isEnabled = backPressedCallBackEnabled() @@ -123,14 +127,14 @@ abstract class GenericFragment : Fragment() { val isSlidingPaneFlat = sharedViewModel.isSlidingPaneSlideable.value == false Log.d( - "[Generic Fragment] ${getFragmentRealClassName()} isSlidingPaneFlat ? $isSlidingPaneFlat" + "$TAG ${getFragmentRealClassName()} isSlidingPaneFlat ? $isSlidingPaneFlat" ) val isPreviousFragmentEmpty = findNavController().previousBackStackEntry?.destination?.id == R.id.emptyFragment Log.d( - "[Generic Fragment] ${getFragmentRealClassName()} isPreviousFragmentEmpty ? $isPreviousFragmentEmpty" + "$TAG ${getFragmentRealClassName()} isPreviousFragmentEmpty ? $isPreviousFragmentEmpty" ) val popBackStack = isSlidingPaneFlat || !isPreviousFragmentEmpty - Log.d("[Generic Fragment] ${getFragmentRealClassName()} popBackStack ? $popBackStack") + Log.d("$TAG ${getFragmentRealClassName()} popBackStack ? $popBackStack") return popBackStack } } diff --git a/app/src/main/java/org/linphone/ui/main/settings/fragment/AccountProfileFragment.kt b/app/src/main/java/org/linphone/ui/main/settings/fragment/AccountProfileFragment.kt index 203979d10..22a5f1630 100644 --- a/app/src/main/java/org/linphone/ui/main/settings/fragment/AccountProfileFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/settings/fragment/AccountProfileFragment.kt @@ -18,7 +18,6 @@ import kotlinx.coroutines.withContext import org.linphone.R import org.linphone.core.tools.Log import org.linphone.databinding.AccountProfileFragmentBinding -import org.linphone.ui.main.contacts.fragment.EditContactFragment import org.linphone.ui.main.fragment.GenericFragment import org.linphone.ui.main.settings.viewmodel.AccountProfileViewModel import org.linphone.utils.FileUtils @@ -26,7 +25,7 @@ import org.linphone.utils.FileUtils @UiThread class AccountProfileFragment : GenericFragment() { companion object { - const val TAG = "[Account Profile Fragment]" + private const val TAG = "[Account Profile Fragment]" } private lateinit var binding: AccountProfileFragmentBinding @@ -54,12 +53,12 @@ class AccountProfileFragment : GenericFragment() { } } else { Log.e( - "${EditContactFragment.TAG} Failed to copy file from [$uri] to [${localFileName.absolutePath}]" + "$TAG Failed to copy file from [$uri] to [${localFileName.absolutePath}]" ) } } } else { - Log.w("${EditContactFragment.TAG} No picture picked") + Log.w("$TAG No picture picked") } } diff --git a/app/src/main/java/org/linphone/ui/main/settings/viewmodel/AccountProfileViewModel.kt b/app/src/main/java/org/linphone/ui/main/settings/viewmodel/AccountProfileViewModel.kt index 9366b2f06..7074b6305 100644 --- a/app/src/main/java/org/linphone/ui/main/settings/viewmodel/AccountProfileViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/settings/viewmodel/AccountProfileViewModel.kt @@ -13,7 +13,7 @@ import org.linphone.utils.FileUtils class AccountProfileViewModel @UiThread constructor() : ViewModel() { companion object { - const val TAG = "[Account Profile ViewModel]" + private const val TAG = "[Account Profile ViewModel]" } val picturePath = MutableLiveData() diff --git a/app/src/main/java/org/linphone/ui/main/viewmodel/BottomNavBarViewModel.kt b/app/src/main/java/org/linphone/ui/main/viewmodel/BottomNavBarViewModel.kt index 48b884345..cb87d37d4 100644 --- a/app/src/main/java/org/linphone/ui/main/viewmodel/BottomNavBarViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/viewmodel/BottomNavBarViewModel.kt @@ -32,7 +32,7 @@ import org.linphone.core.tools.Log class BottomNavBarViewModel @UiThread constructor() : ViewModel() { companion object { - const val TAG = "[Bottom Navigation Bar ViewModel]" + private const val TAG = "[Bottom Navigation Bar ViewModel]" } val contactsSelected = MutableLiveData() diff --git a/app/src/main/java/org/linphone/ui/main/viewmodel/DrawerMenuViewModel.kt b/app/src/main/java/org/linphone/ui/main/viewmodel/DrawerMenuViewModel.kt index 0b4e5aad2..58097b9fd 100644 --- a/app/src/main/java/org/linphone/ui/main/viewmodel/DrawerMenuViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/viewmodel/DrawerMenuViewModel.kt @@ -32,7 +32,7 @@ import org.linphone.utils.Event class DrawerMenuViewModel @UiThread constructor() : ViewModel() { companion object { - const val TAG = "[Drawer Menu ViewModel]" + private const val TAG = "[Drawer Menu ViewModel]" } val accounts = MutableLiveData>() diff --git a/app/src/main/java/org/linphone/ui/main/viewmodel/TopBarViewModel.kt b/app/src/main/java/org/linphone/ui/main/viewmodel/TopBarViewModel.kt index e5ee2fe47..50932d0a8 100644 --- a/app/src/main/java/org/linphone/ui/main/viewmodel/TopBarViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/viewmodel/TopBarViewModel.kt @@ -30,7 +30,7 @@ import org.linphone.utils.Event class TopBarViewModel @UiThread constructor() : ViewModel() { companion object { - const val TAG = "[Top Bar ViewModel]" + private const val TAG = "[Top Bar ViewModel]" } val title = MutableLiveData() diff --git a/app/src/main/java/org/linphone/ui/voip/VoipActivity.kt b/app/src/main/java/org/linphone/ui/voip/VoipActivity.kt index 73d0ce006..7db104fc8 100644 --- a/app/src/main/java/org/linphone/ui/voip/VoipActivity.kt +++ b/app/src/main/java/org/linphone/ui/voip/VoipActivity.kt @@ -26,6 +26,8 @@ import androidx.annotation.UiThread import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.WindowInsetsControllerCompat import androidx.databinding.DataBindingUtil import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope @@ -33,17 +35,24 @@ import androidx.navigation.findNavController import androidx.navigation.fragment.findNavController import org.linphone.LinphoneApplication import org.linphone.R +import org.linphone.core.tools.Log import org.linphone.databinding.VoipActivityBinding import org.linphone.ui.voip.fragment.ActiveCallFragmentDirections import org.linphone.ui.voip.fragment.IncomingCallFragmentDirections import org.linphone.ui.voip.fragment.OutgoingCallFragmentDirections import org.linphone.ui.voip.viewmodel.CallsViewModel +import org.linphone.ui.voip.viewmodel.SharedCallViewModel import org.linphone.utils.slideInToastFromTopForDuration @UiThread class VoipActivity : AppCompatActivity() { + companion object { + private const val TAG = "[VoIP Activity]" + } + private lateinit var binding: VoipActivityBinding + private lateinit var sharedViewModel: SharedCallViewModel private lateinit var callsViewModel: CallsViewModel override fun onCreate(savedInstanceState: Bundle?) { @@ -63,6 +72,10 @@ class VoipActivity : AppCompatActivity() { binding = DataBindingUtil.setContentView(this, R.layout.voip_activity) binding.lifecycleOwner = this + sharedViewModel = run { + ViewModelProvider(this)[SharedCallViewModel::class.java] + } + callsViewModel = run { ViewModelProvider(this)[CallsViewModel::class.java] } @@ -100,6 +113,12 @@ class VoipActivity : AppCompatActivity() { finish() } } + + sharedViewModel.toggleFullScreenEvent.observe(this) { + it.consume { hide -> + hideUI(hide) + } + } } fun showBlueToast(message: String, @DrawableRes icon: Int) { @@ -109,4 +128,20 @@ class VoipActivity : AppCompatActivity() { val target = binding.blueToast.root target.slideInToastFromTopForDuration(binding.root as ViewGroup, lifecycleScope) } + + private fun hideUI(hide: Boolean) { + Log.i("$TAG Switching full screen mode to ${if (hide) "ON" else "OFF"}") + val windowInsetsCompat = WindowInsetsControllerCompat(window, window.decorView) + if (hide) { + WindowCompat.setDecorFitsSystemWindows(window, false) + windowInsetsCompat.let { + it.hide(WindowInsetsCompat.Type.systemBars()) + it.systemBarsBehavior = + WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE + } + } else { + windowInsetsCompat.show(WindowInsetsCompat.Type.systemBars()) + WindowCompat.setDecorFitsSystemWindows(window, true) + } + } } diff --git a/app/src/main/java/org/linphone/ui/voip/fragment/ActiveCallFragment.kt b/app/src/main/java/org/linphone/ui/voip/fragment/ActiveCallFragment.kt index e72e5b64a..11dd0cdfe 100644 --- a/app/src/main/java/org/linphone/ui/voip/fragment/ActiveCallFragment.kt +++ b/app/src/main/java/org/linphone/ui/voip/fragment/ActiveCallFragment.kt @@ -30,15 +30,16 @@ import androidx.lifecycle.ViewModelProvider import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.R import org.linphone.databinding.VoipActiveCallFragmentBinding -import org.linphone.ui.main.fragment.GenericFragment import org.linphone.ui.voip.VoipActivity import org.linphone.ui.voip.model.ZrtpSasConfirmationDialogModel import org.linphone.ui.voip.viewmodel.CurrentCallViewModel +import org.linphone.ui.voip.viewmodel.SharedCallViewModel import org.linphone.utils.AppUtils import org.linphone.utils.DialogUtils +import org.linphone.utils.Event @UiThread -class ActiveCallFragment : GenericFragment() { +class ActiveCallFragment : GenericCallFragment() { private lateinit var binding: VoipActiveCallFragmentBinding private lateinit var callViewModel: CurrentCallViewModel @@ -89,11 +90,12 @@ class ActiveCallFragment : GenericFragment() { binding.lifecycleOwner = viewLifecycleOwner binding.viewModel = callViewModel - callViewModel.toggleExtraActionMenuVisibilityEvent.observe(viewLifecycleOwner) { - /*it.consume { opened -> - val visibility = if (opened) View.VISIBLE else View.GONE - binding.extraActions.slideInExtraActionsMenu(binding.root as ViewGroup, visibility) - }*/ + sharedViewModel = requireActivity().run { + ViewModelProvider(this)[SharedCallViewModel::class.java] + } + + callViewModel.fullScreenMode.observe(viewLifecycleOwner) { hide -> + sharedViewModel.toggleFullScreenEvent.value = Event(hide) } callViewModel.isRemoteDeviceTrusted.observe(viewLifecycleOwner) { trusted -> diff --git a/app/src/main/java/org/linphone/ui/voip/fragment/GenericCallFragment.kt b/app/src/main/java/org/linphone/ui/voip/fragment/GenericCallFragment.kt new file mode 100644 index 000000000..0dbd3f058 --- /dev/null +++ b/app/src/main/java/org/linphone/ui/voip/fragment/GenericCallFragment.kt @@ -0,0 +1,44 @@ +/* + * 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 . + */ +package org.linphone.ui.voip.fragment + +import android.os.Bundle +import android.view.View +import androidx.annotation.UiThread +import androidx.fragment.app.Fragment +import androidx.lifecycle.ViewModelProvider +import org.linphone.ui.voip.viewmodel.SharedCallViewModel + +@UiThread +abstract class GenericCallFragment : Fragment() { + companion object { + private const val TAG = "[Generic Call Fragment]" + } + + protected lateinit var sharedViewModel: SharedCallViewModel + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + sharedViewModel = requireActivity().run { + ViewModelProvider(this)[SharedCallViewModel::class.java] + } + } +} diff --git a/app/src/main/java/org/linphone/ui/voip/model/ZrtpSasConfirmationDialogModel.kt b/app/src/main/java/org/linphone/ui/voip/model/ZrtpSasConfirmationDialogModel.kt index 78217c7dd..748b2552d 100644 --- a/app/src/main/java/org/linphone/ui/voip/model/ZrtpSasConfirmationDialogModel.kt +++ b/app/src/main/java/org/linphone/ui/voip/model/ZrtpSasConfirmationDialogModel.kt @@ -31,8 +31,8 @@ class ZrtpSasConfirmationDialogModel @UiThread constructor( private val authTokenToListen: String ) : ViewModel() { companion object { - const val TAG = "[ZRTP SAS Confirmation Dialog]" - const val alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + private const val TAG = "[ZRTP SAS Confirmation Dialog]" + private const val alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" } val message = MutableLiveData() diff --git a/app/src/main/java/org/linphone/ui/voip/viewmodel/CurrentCallViewModel.kt b/app/src/main/java/org/linphone/ui/voip/viewmodel/CurrentCallViewModel.kt index 8cb6611d0..e80702c07 100644 --- a/app/src/main/java/org/linphone/ui/voip/viewmodel/CurrentCallViewModel.kt +++ b/app/src/main/java/org/linphone/ui/voip/viewmodel/CurrentCallViewModel.kt @@ -19,9 +19,12 @@ */ package org.linphone.ui.voip.viewmodel +import android.Manifest import android.animation.ValueAnimator +import android.content.pm.PackageManager import androidx.annotation.UiThread import androidx.annotation.WorkerThread +import androidx.core.app.ActivityCompat import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import java.util.Locale @@ -38,7 +41,7 @@ import org.linphone.utils.LinphoneUtils class CurrentCallViewModel @UiThread constructor() : ViewModel() { companion object { - const val TAG = "[Current Call ViewModel]" + private const val TAG = "[Current Call ViewModel]" } val contact = MutableLiveData() @@ -49,6 +52,8 @@ class CurrentCallViewModel @UiThread constructor() : ViewModel() { val isVideoEnabled = MutableLiveData() + val showSwitchCamera = MutableLiveData() + val isOutgoing = MutableLiveData() val isMicrophoneMuted = MutableLiveData() @@ -90,8 +95,6 @@ class CurrentCallViewModel @UiThread constructor() : ViewModel() { } } - val toggleExtraActionMenuVisibilityEvent = MutableLiveData>() - private lateinit var call: Call private val callListener = object : CallListenerStub() { @@ -105,7 +108,13 @@ class CurrentCallViewModel @UiThread constructor() : ViewModel() { if (LinphoneUtils.isCallOutgoing(call.state)) { isVideoEnabled.postValue(call.params.isVideoEnabled) } else { - isVideoEnabled.postValue(call.currentParams.isVideoEnabled) + val videoEnabled = call.currentParams.isVideoEnabled + isVideoEnabled.postValue(videoEnabled) + + // Toggle full screen OFF when remote disables video + if (!videoEnabled && fullScreenMode.value == true) { + fullScreenMode.postValue(false) + } } } } @@ -127,6 +136,8 @@ class CurrentCallViewModel @UiThread constructor() : ViewModel() { } else { Log.e("$TAG Failed to find outgoing call!") } + + showSwitchCamera.postValue(coreContext.showSwitchCameraButton()) } } @@ -168,7 +179,14 @@ class CurrentCallViewModel @UiThread constructor() : ViewModel() { @UiThread fun toggleMuteMicrophone() { - // TODO: check record audio permission + if (ActivityCompat.checkSelfPermission( + coreContext.context, + Manifest.permission.RECORD_AUDIO + ) != PackageManager.PERMISSION_GRANTED + ) { + // TODO: request record audio permission + return + } coreContext.postOnCoreThread { call.microphoneMuted = !call.microphoneMuted isMicrophoneMuted.postValue(call.microphoneMuted) @@ -182,7 +200,14 @@ class CurrentCallViewModel @UiThread constructor() : ViewModel() { @UiThread fun toggleVideo() { - // TODO: check video permission + if (ActivityCompat.checkSelfPermission( + coreContext.context, + Manifest.permission.CAMERA + ) != PackageManager.PERMISSION_GRANTED + ) { + // TODO: request video permission + return + } coreContext.postOnCoreThread { core -> if (::call.isInitialized) { diff --git a/app/src/main/java/org/linphone/ui/voip/viewmodel/SharedCallViewModel.kt b/app/src/main/java/org/linphone/ui/voip/viewmodel/SharedCallViewModel.kt new file mode 100644 index 000000000..580899f01 --- /dev/null +++ b/app/src/main/java/org/linphone/ui/voip/viewmodel/SharedCallViewModel.kt @@ -0,0 +1,29 @@ +/* + * 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 . + */ +package org.linphone.ui.voip.viewmodel + +import androidx.annotation.UiThread +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import org.linphone.utils.Event + +class SharedCallViewModel @UiThread constructor() : ViewModel() { + val toggleFullScreenEvent = MutableLiveData>() +} diff --git a/app/src/main/java/org/linphone/utils/FileUtils.kt b/app/src/main/java/org/linphone/utils/FileUtils.kt index 4d6c3a49d..e8958857a 100644 --- a/app/src/main/java/org/linphone/utils/FileUtils.kt +++ b/app/src/main/java/org/linphone/utils/FileUtils.kt @@ -33,7 +33,7 @@ import org.linphone.core.tools.Log class FileUtils { companion object { - const val TAG = "[File Utils]" + private const val TAG = "[File Utils]" @AnyThread fun getProperFilePath(path: String): String { diff --git a/app/src/main/java/org/linphone/utils/ImageUtils.kt b/app/src/main/java/org/linphone/utils/ImageUtils.kt index e9f817b07..3327194d9 100644 --- a/app/src/main/java/org/linphone/utils/ImageUtils.kt +++ b/app/src/main/java/org/linphone/utils/ImageUtils.kt @@ -34,7 +34,7 @@ import org.linphone.core.tools.Log class ImageUtils { companion object { - const val TAG = "[Image Utils]" + private const val TAG = "[Image Utils]" @AnyThread fun getRoundBitmapFromUri( diff --git a/app/src/main/res/drawable/in_call_button_background.xml b/app/src/main/res/drawable/in_call_button_background.xml index 9db05d647..22033920b 100644 --- a/app/src/main/res/drawable/in_call_button_background.xml +++ b/app/src/main/res/drawable/in_call_button_background.xml @@ -2,6 +2,8 @@ + \ No newline at end of file diff --git a/app/src/main/res/drawable/shape_round_in_call_button_background.xml b/app/src/main/res/drawable/shape_round_in_call_button_background.xml index 30b2406c1..912287c36 100644 --- a/app/src/main/res/drawable/shape_round_in_call_button_background.xml +++ b/app/src/main/res/drawable/shape_round_in_call_button_background.xml @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/app/src/main/res/drawable/shape_round_in_call_pressed_button_background.xml b/app/src/main/res/drawable/shape_round_in_call_pressed_button_background.xml new file mode 100644 index 000000000..f2c42f6c2 --- /dev/null +++ b/app/src/main/res/drawable/shape_round_in_call_pressed_button_background.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/call_start_fragment.xml b/app/src/main/res/layout/call_start_fragment.xml index 627ccb117..08be0c296 100644 --- a/app/src/main/res/layout/call_start_fragment.xml +++ b/app/src/main/res/layout/call_start_fragment.xml @@ -82,6 +82,7 @@ android:padding="10dp" android:src="@drawable/users_three" android:background="@drawable/shape_orange_round" + app:tint="@color/white" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/search_bar" /> diff --git a/app/src/main/res/layout/voip_active_call_fragment.xml b/app/src/main/res/layout/voip_active_call_fragment.xml index 43a960ada..b0bf66c01 100644 --- a/app/src/main/res/layout/voip_active_call_fragment.xml +++ b/app/src/main/res/layout/voip_active_call_fragment.xml @@ -21,6 +21,7 @@ android:layout_height="24dp" android:layout_marginStart="10dp" android:adjustViewBounds="true" + android:visibility="@{viewModel.fullScreenMode ? View.GONE : View.VISIBLE}" android:src="@{viewModel.isOutgoing ? @drawable/outgoing_call : @drawable/incoming_call, default=@drawable/outgoing_call}" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@id/call_direction_label" @@ -33,6 +34,7 @@ android:layout_height="wrap_content" android:layout_marginStart="10dp" android:layout_marginTop="7dp" + android:visibility="@{viewModel.fullScreenMode ? View.GONE : View.VISIBLE}" android:text="@{viewModel.isOutgoing ? `Outgoing call` : `Incoming call`, default=`Outgoing call`}" android:textColor="@color/white" android:textSize="16sp" @@ -48,6 +50,7 @@ android:textColor="@color/white" android:textSize="16sp" android:text="@string/vertical_separator" + android:visibility="@{viewModel.fullScreenMode ? View.GONE : View.VISIBLE}" app:layout_constraintStart_toEndOf="@id/call_direction_label" app:layout_constraintTop_toTopOf="@id/call_direction_label" app:layout_constraintBottom_toBottomOf="@id/call_direction_label"/> @@ -60,6 +63,7 @@ android:layout_marginStart="5dp" android:textColor="@color/white" android:textSize="16sp" + android:visibility="@{viewModel.fullScreenMode ? View.GONE : View.VISIBLE}" app:layout_constraintStart_toEndOf="@id/separator" app:layout_constraintTop_toTopOf="@id/call_direction_label" app:layout_constraintBottom_toBottomOf="@id/call_direction_label"/> @@ -67,12 +71,12 @@ diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index f8dbaba4d..3ced8fa5f 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -34,5 +34,4 @@ #070707 #2E3030 - #4E4E4E \ No newline at end of file