In-call audio/camera permissions improvements
This commit is contained in:
parent
1ad5d31426
commit
19fe8dd57b
5 changed files with 108 additions and 33 deletions
|
@ -19,9 +19,11 @@
|
|||
*/
|
||||
package org.linphone.activities.call
|
||||
|
||||
import android.Manifest
|
||||
import android.annotation.TargetApi
|
||||
import android.app.KeyguardManager
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Bundle
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
|
@ -113,10 +115,12 @@ class IncomingCallActivity : GenericActivity() {
|
|||
Log.i("[Incoming Call Activity] Asking for RECORD_AUDIO permission")
|
||||
permissionsRequiredList.add(android.Manifest.permission.RECORD_AUDIO)
|
||||
}
|
||||
|
||||
if (viewModel.call.currentParams.videoEnabled() && !PermissionHelper.get().hasCameraPermission()) {
|
||||
Log.i("[Incoming Call Activity] Asking for CAMERA permission")
|
||||
permissionsRequiredList.add(android.Manifest.permission.CAMERA)
|
||||
}
|
||||
|
||||
if (permissionsRequiredList.isNotEmpty()) {
|
||||
val permissionsRequired = arrayOfNulls<String>(permissionsRequiredList.size)
|
||||
permissionsRequiredList.toArray(permissionsRequired)
|
||||
|
@ -124,6 +128,26 @@ class IncomingCallActivity : GenericActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
override fun onRequestPermissionsResult(
|
||||
requestCode: Int,
|
||||
permissions: Array<out String>,
|
||||
grantResults: IntArray
|
||||
) {
|
||||
if (requestCode == 0) {
|
||||
for (i in permissions.indices) {
|
||||
when (permissions[i]) {
|
||||
Manifest.permission.RECORD_AUDIO -> if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
|
||||
Log.i("[Incoming Call Activity] RECORD_AUDIO permission has been granted")
|
||||
}
|
||||
Manifest.permission.CAMERA -> if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
|
||||
Log.i("[Incoming Call Activity] CAMERA permission has been granted")
|
||||
coreContext.core.reloadVideoDevices()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun findIncomingCall(): Call? {
|
||||
for (call in coreContext.core.calls) {
|
||||
if (call.state == Call.State.IncomingReceived ||
|
||||
|
|
|
@ -19,7 +19,9 @@
|
|||
*/
|
||||
package org.linphone.activities.call
|
||||
|
||||
import android.Manifest
|
||||
import android.annotation.TargetApi
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Bundle
|
||||
import android.view.WindowManager
|
||||
import androidx.databinding.DataBindingUtil
|
||||
|
@ -64,22 +66,6 @@ class OutgoingCallActivity : ProximitySensorActivity() {
|
|||
controlsViewModel = ViewModelProvider(this).get(ControlsViewModel::class.java)
|
||||
binding.controlsViewModel = controlsViewModel
|
||||
|
||||
binding.setTerminateCallClickListener {
|
||||
viewModel.terminateCall()
|
||||
}
|
||||
|
||||
binding.setToggleMicrophoneClickListener {
|
||||
if (PermissionHelper.get().hasRecordAudioPermission()) {
|
||||
controlsViewModel.toggleMuteMicrophone()
|
||||
} else {
|
||||
checkPermissions()
|
||||
}
|
||||
}
|
||||
|
||||
binding.setToggleSpeakerClickListener {
|
||||
controlsViewModel.toggleSpeaker()
|
||||
}
|
||||
|
||||
viewModel.callEndedEvent.observe(this, {
|
||||
it.consume {
|
||||
Log.i("[Outgoing Call Activity] Call ended, finish activity")
|
||||
|
@ -98,6 +84,12 @@ class OutgoingCallActivity : ProximitySensorActivity() {
|
|||
enableProximitySensor(!it)
|
||||
})
|
||||
|
||||
controlsViewModel.askPermissionEvent.observe(this, {
|
||||
it.consume { permission ->
|
||||
requestPermissions(arrayOf(permission), 0)
|
||||
}
|
||||
})
|
||||
|
||||
if (Version.sdkAboveOrEqual(Version.API23_MARSHMALLOW_60)) {
|
||||
checkPermissions()
|
||||
}
|
||||
|
@ -131,6 +123,27 @@ class OutgoingCallActivity : ProximitySensorActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
override fun onRequestPermissionsResult(
|
||||
requestCode: Int,
|
||||
permissions: Array<out String>,
|
||||
grantResults: IntArray
|
||||
) {
|
||||
if (requestCode == 0) {
|
||||
for (i in permissions.indices) {
|
||||
when (permissions[i]) {
|
||||
Manifest.permission.RECORD_AUDIO -> if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
|
||||
Log.i("[Outgoing Call Activity] RECORD_AUDIO permission has been granted")
|
||||
controlsViewModel.updateMuteMicState()
|
||||
}
|
||||
Manifest.permission.CAMERA -> if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
|
||||
Log.i("[Outgoing Call Activity] CAMERA permission has been granted")
|
||||
coreContext.core.reloadVideoDevices()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun findOutgoingCall(): Call? {
|
||||
for (call in coreContext.core.calls) {
|
||||
if (call.state == Call.State.OutgoingInit ||
|
||||
|
|
|
@ -19,13 +19,15 @@
|
|||
*/
|
||||
package org.linphone.activities.call.fragments
|
||||
|
||||
import android.Manifest
|
||||
import android.annotation.TargetApi
|
||||
import android.app.Dialog
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.pm.PackageManager.PERMISSION_GRANTED
|
||||
import android.os.Bundle
|
||||
import android.os.SystemClock
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||
import org.linphone.R
|
||||
import org.linphone.activities.GenericFragment
|
||||
import org.linphone.activities.call.viewmodels.CallsViewModel
|
||||
|
@ -122,6 +124,13 @@ class ControlsFragment : GenericFragment<CallControlsFragmentBinding>() {
|
|||
}
|
||||
})
|
||||
|
||||
controlsViewModel.askPermissionEvent.observe(viewLifecycleOwner, {
|
||||
it.consume { permission ->
|
||||
Log.i("[Controls Fragment] Asking for $permission permission")
|
||||
requestPermissions(arrayOf(permission), 0)
|
||||
}
|
||||
})
|
||||
|
||||
controlsViewModel.somethingClickedEvent.observe(viewLifecycleOwner, {
|
||||
it.consume {
|
||||
sharedViewModel.resetHiddenInterfaceTimerInVideoCallEvent.value = Event(true)
|
||||
|
@ -138,9 +147,19 @@ class ControlsFragment : GenericFragment<CallControlsFragmentBinding>() {
|
|||
permissions: Array<out String>,
|
||||
grantResults: IntArray
|
||||
) {
|
||||
if (requestCode == 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
Log.i("[Controls Fragment] RECORD_AUDIO permission has been granted")
|
||||
controlsViewModel.updateMuteMicState()
|
||||
if (requestCode == 0) {
|
||||
for (i in permissions.indices) {
|
||||
when (permissions[i]) {
|
||||
Manifest.permission.RECORD_AUDIO -> if (grantResults[i] == PERMISSION_GRANTED) {
|
||||
Log.i("[Controls Fragment] RECORD_AUDIO permission has been granted")
|
||||
controlsViewModel.updateMuteMicState()
|
||||
}
|
||||
Manifest.permission.CAMERA -> if (grantResults[i] == PERMISSION_GRANTED) {
|
||||
Log.i("[Controls Fragment] CAMERA permission has been granted")
|
||||
coreContext.core.reloadVideoDevices()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||
}
|
||||
|
@ -148,10 +167,17 @@ class ControlsFragment : GenericFragment<CallControlsFragmentBinding>() {
|
|||
@TargetApi(Version.API23_MARSHMALLOW_60)
|
||||
private fun checkPermissions() {
|
||||
val permissionsRequiredList = arrayListOf<String>()
|
||||
|
||||
if (!PermissionHelper.get().hasRecordAudioPermission()) {
|
||||
Log.i("[Controls Fragment] Asking for RECORD_AUDIO permission")
|
||||
permissionsRequiredList.add(android.Manifest.permission.RECORD_AUDIO)
|
||||
}
|
||||
|
||||
if (coreContext.isVideoCallOrConferenceActive() && !PermissionHelper.get().hasCameraPermission()) {
|
||||
Log.i("[Controls Fragment] Asking for CAMERA permission")
|
||||
permissionsRequiredList.add(android.Manifest.permission.CAMERA)
|
||||
}
|
||||
|
||||
if (permissionsRequiredList.isNotEmpty()) {
|
||||
val permissionsRequired = arrayOfNulls<String>(permissionsRequiredList.size)
|
||||
permissionsRequiredList.toArray(permissionsRequired)
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
*/
|
||||
package org.linphone.activities.call.viewmodels
|
||||
|
||||
import android.Manifest
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import kotlin.math.max
|
||||
|
@ -74,6 +75,10 @@ class ControlsViewModel : ViewModel() {
|
|||
MutableLiveData<Event<Boolean>>()
|
||||
}
|
||||
|
||||
val askPermissionEvent: MutableLiveData<Event<String>> by lazy {
|
||||
MutableLiveData<Event<String>>()
|
||||
}
|
||||
|
||||
val somethingClickedEvent = MutableLiveData<Event<Boolean>>()
|
||||
|
||||
val onKeyClick: NumpadDigitListener = object : NumpadDigitListener {
|
||||
|
@ -105,6 +110,10 @@ class ControlsViewModel : ViewModel() {
|
|||
) {
|
||||
if (state == Call.State.StreamsRunning) isVideoUpdateInProgress.value = false
|
||||
|
||||
if (coreContext.isVideoCallOrConferenceActive() && !PermissionHelper.get().hasCameraPermission()) {
|
||||
askPermissionEvent.value = Event(Manifest.permission.CAMERA)
|
||||
}
|
||||
|
||||
updateUI()
|
||||
}
|
||||
|
||||
|
@ -147,6 +156,11 @@ class ControlsViewModel : ViewModel() {
|
|||
}
|
||||
|
||||
fun toggleMuteMicrophone() {
|
||||
if (!PermissionHelper.get().hasRecordAudioPermission()) {
|
||||
askPermissionEvent.value = Event(Manifest.permission.RECORD_AUDIO)
|
||||
return
|
||||
}
|
||||
|
||||
somethingClickedEvent.value = Event(true)
|
||||
val micEnabled = coreContext.core.micEnabled()
|
||||
coreContext.core.enableMic(!micEnabled)
|
||||
|
@ -178,6 +192,11 @@ class ControlsViewModel : ViewModel() {
|
|||
}
|
||||
|
||||
fun toggleVideo() {
|
||||
if (!PermissionHelper.get().hasCameraPermission()) {
|
||||
askPermissionEvent.value = Event(Manifest.permission.CAMERA)
|
||||
return
|
||||
}
|
||||
|
||||
val core = coreContext.core
|
||||
val currentCall = core.currentCall
|
||||
val conference = core.conference
|
||||
|
@ -314,6 +333,7 @@ class ControlsViewModel : ViewModel() {
|
|||
|
||||
fun updateMuteMicState() {
|
||||
isMicrophoneMuted.value = !PermissionHelper.get().hasRecordAudioPermission() || !coreContext.core.micEnabled()
|
||||
isMuteMicrophoneEnabled.value = coreContext.core.currentCall != null || coreContext.core.isInConference
|
||||
}
|
||||
|
||||
private fun updateSpeakerState() {
|
||||
|
@ -349,7 +369,8 @@ class ControlsViewModel : ViewModel() {
|
|||
}
|
||||
|
||||
private fun updateVideoEnabled() {
|
||||
isVideoEnabled.value = coreContext.isVideoCallOrConferenceActive()
|
||||
val enabled = coreContext.isVideoCallOrConferenceActive()
|
||||
isVideoEnabled.value = enabled
|
||||
}
|
||||
|
||||
private fun updateConferenceState() {
|
||||
|
|
|
@ -5,15 +5,6 @@
|
|||
|
||||
<data>
|
||||
<import type="android.view.View" />
|
||||
<variable
|
||||
name="toggleMicrophoneClickListener"
|
||||
type="android.view.View.OnClickListener" />
|
||||
<variable
|
||||
name="toggleSpeakerClickListener"
|
||||
type="android.view.View.OnClickListener" />
|
||||
<variable
|
||||
name="terminateCallClickListener"
|
||||
type="android.view.View.OnClickListener" />
|
||||
<variable
|
||||
name="viewModel"
|
||||
type="org.linphone.activities.call.viewmodels.CallViewModel" />
|
||||
|
@ -99,7 +90,7 @@
|
|||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:onClick="@{toggleMicrophoneClickListener}"
|
||||
android:onClick="@{() -> controlsViewModel.toggleMuteMicrophone()}"
|
||||
android:selected="@{controlsViewModel.isMicrophoneMuted}"
|
||||
android:contentDescription="@{controlsViewModel.isMicrophoneMuted ? @string/content_description_disable_mic_mute : @string/content_description_enable_mic_mute}"
|
||||
android:layout_width="match_parent"
|
||||
|
@ -110,7 +101,7 @@
|
|||
android:src="@drawable/micro" />
|
||||
|
||||
<ImageView
|
||||
android:onClick="@{toggleSpeakerClickListener}"
|
||||
android:onClick="@{() -> controlsViewModel.toggleSpeaker()}"
|
||||
android:selected="@{controlsViewModel.isSpeakerSelected}"
|
||||
android:contentDescription="@{controlsViewModel.isSpeakerSelected ? @string/content_description_disable_speaker : @string/content_description_enable_speaker}"
|
||||
android:layout_width="match_parent"
|
||||
|
@ -121,7 +112,7 @@
|
|||
android:src="@drawable/speaker" />
|
||||
|
||||
<ImageView
|
||||
android:onClick="@{terminateCallClickListener}"
|
||||
android:onClick="@{() -> viewModel.terminateCall()}"
|
||||
android:contentDescription="@string/content_description_terminate_call"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
Loading…
Reference in a new issue