Few improvements including disabling proximity sensor based on video & output audio device
This commit is contained in:
parent
a880682672
commit
f1f58d49e7
10 changed files with 55 additions and 32 deletions
|
@ -43,7 +43,7 @@ task getGitVersion() {
|
||||||
gitVersion = gitVersionStream.toString().trim() + "." + gitCommitsCount.toString().trim() + "+" + gitCommitHash.toString().trim()
|
gitVersion = gitVersionStream.toString().trim() + "." + gitCommitsCount.toString().trim() + "+" + gitCommitHash.toString().trim()
|
||||||
}
|
}
|
||||||
println("Git version: " + gitVersion)
|
println("Git version: " + gitVersion)
|
||||||
} catch (Exception e) {
|
} catch (ignored) {
|
||||||
println("Git not found")
|
println("Git not found")
|
||||||
}
|
}
|
||||||
project.version = gitVersion
|
project.version = gitVersion
|
||||||
|
@ -54,7 +54,7 @@ project.tasks['preBuild'].dependsOn 'linphoneSdkSource'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 29
|
compileSdkVersion 29
|
||||||
buildToolsVersion "29.0.2"
|
buildToolsVersion "29.0.3"
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 23
|
minSdkVersion 23
|
||||||
targetSdkVersion 29
|
targetSdkVersion 29
|
||||||
|
|
|
@ -85,17 +85,18 @@ class CallActivity : ProximitySensorActivity() {
|
||||||
MotionEvent.ACTION_MOVE -> {
|
MotionEvent.ACTION_MOVE -> {
|
||||||
v.animate().x(event.rawX + previewX).y(event.rawY + previewY).setDuration(0).start()
|
v.animate().x(event.rawX + previewX).y(event.rawY + previewY).setDuration(0).start()
|
||||||
}
|
}
|
||||||
else -> false
|
else -> {
|
||||||
|
v.performClick()
|
||||||
|
false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
videoZoomHelper = VideoZoomHelper(this, binding.remoteVideoSurface)
|
videoZoomHelper = VideoZoomHelper(this, binding.remoteVideoSurface)
|
||||||
|
|
||||||
viewModel.videoEnabledEvent.observe(this, Observer {
|
viewModel.proximitySensorEnabled.observe(this, Observer {
|
||||||
it.consume { videoEnabled ->
|
enableProximitySensor(it)
|
||||||
enableProximitySensor(!videoEnabled)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ class IncomingCallActivity : GenericActivity() {
|
||||||
binding = DataBindingUtil.setContentView(this, R.layout.call_incoming_activity)
|
binding = DataBindingUtil.setContentView(this, R.layout.call_incoming_activity)
|
||||||
binding.lifecycleOwner = this
|
binding.lifecycleOwner = this
|
||||||
|
|
||||||
var incomingCall: Call? = findIncomingCall()
|
val incomingCall: Call? = findIncomingCall()
|
||||||
if (incomingCall == null) {
|
if (incomingCall == null) {
|
||||||
Log.e("[Incoming Call Activity] Couldn't find call in state Incoming")
|
Log.e("[Incoming Call Activity] Couldn't find call in state Incoming")
|
||||||
finish()
|
finish()
|
||||||
|
@ -92,7 +92,7 @@ class IncomingCallActivity : GenericActivity() {
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
|
|
||||||
var incomingCall: Call? = findIncomingCall()
|
val incomingCall: Call? = findIncomingCall()
|
||||||
if (incomingCall == null) {
|
if (incomingCall == null) {
|
||||||
Log.e("[Incoming Call Activity] Couldn't find call in state Incoming")
|
Log.e("[Incoming Call Activity] Couldn't find call in state Incoming")
|
||||||
finish()
|
finish()
|
||||||
|
|
|
@ -27,6 +27,7 @@ import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import org.linphone.LinphoneApplication.Companion.coreContext
|
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||||
import org.linphone.R
|
import org.linphone.R
|
||||||
|
import org.linphone.activities.GenericActivity
|
||||||
import org.linphone.activities.call.viewmodels.CallViewModel
|
import org.linphone.activities.call.viewmodels.CallViewModel
|
||||||
import org.linphone.activities.call.viewmodels.CallViewModelFactory
|
import org.linphone.activities.call.viewmodels.CallViewModelFactory
|
||||||
import org.linphone.activities.call.viewmodels.ControlsViewModel
|
import org.linphone.activities.call.viewmodels.ControlsViewModel
|
||||||
|
@ -36,7 +37,7 @@ import org.linphone.databinding.CallOutgoingActivityBinding
|
||||||
import org.linphone.mediastream.Version
|
import org.linphone.mediastream.Version
|
||||||
import org.linphone.utils.PermissionHelper
|
import org.linphone.utils.PermissionHelper
|
||||||
|
|
||||||
class OutgoingCallActivity : ProximitySensorActivity() {
|
class OutgoingCallActivity : GenericActivity() {
|
||||||
private lateinit var binding: CallOutgoingActivityBinding
|
private lateinit var binding: CallOutgoingActivityBinding
|
||||||
private lateinit var viewModel: CallViewModel
|
private lateinit var viewModel: CallViewModel
|
||||||
private lateinit var controlsViewModel: ControlsViewModel
|
private lateinit var controlsViewModel: ControlsViewModel
|
||||||
|
@ -49,7 +50,7 @@ class OutgoingCallActivity : ProximitySensorActivity() {
|
||||||
binding = DataBindingUtil.setContentView(this, R.layout.call_outgoing_activity)
|
binding = DataBindingUtil.setContentView(this, R.layout.call_outgoing_activity)
|
||||||
binding.lifecycleOwner = this
|
binding.lifecycleOwner = this
|
||||||
|
|
||||||
var outgoingCall: Call? = findOutgoingCall()
|
val outgoingCall: Call? = findOutgoingCall()
|
||||||
if (outgoingCall == null) {
|
if (outgoingCall == null) {
|
||||||
Log.e("[Outgoing Call Activity] Couldn't find call in state Outgoing")
|
Log.e("[Outgoing Call Activity] Couldn't find call in state Outgoing")
|
||||||
finish()
|
finish()
|
||||||
|
@ -103,7 +104,7 @@ class OutgoingCallActivity : ProximitySensorActivity() {
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
|
|
||||||
var outgoingCall: Call? = findOutgoingCall()
|
val outgoingCall: Call? = findOutgoingCall()
|
||||||
if (outgoingCall == null) {
|
if (outgoingCall == null) {
|
||||||
Log.e("[Outgoing Call Activity] Couldn't find call in state Outgoing")
|
Log.e("[Outgoing Call Activity] Couldn't find call in state Outgoing")
|
||||||
finish()
|
finish()
|
||||||
|
|
|
@ -42,12 +42,12 @@ abstract class ProximitySensorActivity : GenericActivity() {
|
||||||
if (event.timestamp == 0L) return
|
if (event.timestamp == 0L) return
|
||||||
if (isProximitySensorNearby(event)) {
|
if (isProximitySensorNearby(event)) {
|
||||||
if (!proximityWakeLock.isHeld) {
|
if (!proximityWakeLock.isHeld) {
|
||||||
Log.i("[Call Activity] Acquiring proximity wake lock")
|
Log.i("[Proximity Sensor Activity] Acquiring proximity wake lock")
|
||||||
proximityWakeLock.acquire()
|
proximityWakeLock.acquire()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (proximityWakeLock.isHeld) {
|
if (proximityWakeLock.isHeld) {
|
||||||
Log.i("[Call Activity] Releasing proximity wake lock")
|
Log.i("[Proximity Sensor Activity] Releasing proximity wake lock")
|
||||||
proximityWakeLock.release()
|
proximityWakeLock.release()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ abstract class ProximitySensorActivity : GenericActivity() {
|
||||||
)
|
)
|
||||||
proximitySensorFound = true
|
proximitySensorFound = true
|
||||||
} catch (ise: IllegalStateException) {
|
} catch (ise: IllegalStateException) {
|
||||||
Log.e("[Call Activity] Failed to get proximity sensor: $ise")
|
Log.e("[Proximity Sensor Activity] Failed to get proximity sensor: $ise")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,19 +89,19 @@ abstract class ProximitySensorActivity : GenericActivity() {
|
||||||
|
|
||||||
protected fun enableProximitySensor(enable: Boolean) {
|
protected fun enableProximitySensor(enable: Boolean) {
|
||||||
if (!proximitySensorFound) {
|
if (!proximitySensorFound) {
|
||||||
Log.w("[Call Activity] Couldn't find proximity sensor in this device, skipping")
|
Log.w("[Proximity Sensor Activity] Couldn't find proximity sensor in this device, skipping")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enable) {
|
if (enable) {
|
||||||
if (!proximitySensorEnabled) {
|
if (!proximitySensorEnabled) {
|
||||||
Log.i("[Call Activity] Enabling proximity sensor listener")
|
Log.i("[Proximity Sensor Activity] Enabling proximity sensor listener")
|
||||||
sensorManager.registerListener(proximityListener, proximitySensor, SensorManager.SENSOR_DELAY_NORMAL)
|
sensorManager.registerListener(proximityListener, proximitySensor, SensorManager.SENSOR_DELAY_NORMAL)
|
||||||
proximitySensorEnabled = true
|
proximitySensorEnabled = true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (proximitySensorEnabled) {
|
if (proximitySensorEnabled) {
|
||||||
Log.i("[Call Activity] Disabling proximity sensor listener")
|
Log.i("[Proximity Sensor Activity] Disabling proximity sensor listener")
|
||||||
sensorManager.unregisterListener(proximityListener)
|
sensorManager.unregisterListener(proximityListener)
|
||||||
if (proximityWakeLock.isHeld) {
|
if (proximityWakeLock.isHeld) {
|
||||||
proximityWakeLock.release()
|
proximityWakeLock.release()
|
||||||
|
@ -116,7 +116,7 @@ abstract class ProximitySensorActivity : GenericActivity() {
|
||||||
|
|
||||||
val distanceInCm = event.values[0]
|
val distanceInCm = event.values[0]
|
||||||
val maxDistance = event.sensor.maximumRange
|
val maxDistance = event.sensor.maximumRange
|
||||||
Log.d("[Call Activity] Proximity sensor report [$distanceInCm] , for max range [$maxDistance]")
|
Log.d("[Proximity Sensor Activity] Proximity sensor report [$distanceInCm] , for max range [$maxDistance]")
|
||||||
|
|
||||||
if (maxDistance <= threshold) {
|
if (maxDistance <= threshold) {
|
||||||
// Case binary 0/1 and short sensors
|
// Case binary 0/1 and short sensors
|
||||||
|
|
|
@ -19,22 +19,25 @@
|
||||||
*/
|
*/
|
||||||
package org.linphone.activities.call.viewmodels
|
package org.linphone.activities.call.viewmodels
|
||||||
|
|
||||||
|
import androidx.lifecycle.MediatorLiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import org.linphone.LinphoneApplication.Companion.coreContext
|
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||||
|
import org.linphone.core.AudioDevice
|
||||||
import org.linphone.core.Call
|
import org.linphone.core.Call
|
||||||
import org.linphone.core.Core
|
import org.linphone.core.Core
|
||||||
import org.linphone.core.CoreListenerStub
|
import org.linphone.core.CoreListenerStub
|
||||||
import org.linphone.core.tools.Log
|
import org.linphone.core.tools.Log
|
||||||
import org.linphone.utils.Event
|
|
||||||
|
|
||||||
class ControlsFadingViewModel : ViewModel() {
|
class ControlsFadingViewModel : ViewModel() {
|
||||||
val areControlsHidden = MutableLiveData<Boolean>()
|
val areControlsHidden = MutableLiveData<Boolean>()
|
||||||
|
|
||||||
val isVideoPreviewHidden = MutableLiveData<Boolean>()
|
val isVideoPreviewHidden = MutableLiveData<Boolean>()
|
||||||
|
|
||||||
val videoEnabledEvent = MutableLiveData<Event<Boolean>>()
|
private val videoEnabled = MutableLiveData<Boolean>()
|
||||||
|
private val nonEarpieceOutputAudioDevice = MutableLiveData<Boolean>()
|
||||||
|
val proximitySensorEnabled: MediatorLiveData<Boolean> = MediatorLiveData()
|
||||||
|
|
||||||
private var timer: Timer? = null
|
private var timer: Timer? = null
|
||||||
|
|
||||||
|
@ -46,17 +49,24 @@ class ControlsFadingViewModel : ViewModel() {
|
||||||
message: String?
|
message: String?
|
||||||
) {
|
) {
|
||||||
if (state == Call.State.StreamsRunning || state == Call.State.Updating || state == Call.State.UpdatedByRemote) {
|
if (state == Call.State.StreamsRunning || state == Call.State.Updating || state == Call.State.UpdatedByRemote) {
|
||||||
val videoEnabled = coreContext.isVideoCallOrConferenceActive()
|
val isVideoCall = coreContext.isVideoCallOrConferenceActive()
|
||||||
Log.i("[Controls Fading] Call is in state $state, video is enabled? $videoEnabled")
|
Log.i("[Controls Fading] Call is in state $state, video is enabled? $videoEnabled")
|
||||||
if (videoEnabled) {
|
if (isVideoCall) {
|
||||||
videoEnabledEvent.value = Event(true)
|
videoEnabled.value = true
|
||||||
startTimer()
|
startTimer()
|
||||||
} else {
|
} else {
|
||||||
videoEnabledEvent.value = Event(false)
|
videoEnabled.value = false
|
||||||
stopTimer()
|
stopTimer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onAudioDeviceChanged(core: Core, audioDevice: AudioDevice) {
|
||||||
|
if (audioDevice.hasCapability(AudioDevice.Capabilities.CapabilityPlay)) {
|
||||||
|
Log.i("[Controls Fading] Output audio device changed to: ${audioDevice.id}")
|
||||||
|
nonEarpieceOutputAudioDevice.value = audioDevice.type != AudioDevice.Type.Earpiece
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
@ -64,12 +74,21 @@ class ControlsFadingViewModel : ViewModel() {
|
||||||
|
|
||||||
areControlsHidden.value = false
|
areControlsHidden.value = false
|
||||||
isVideoPreviewHidden.value = false
|
isVideoPreviewHidden.value = false
|
||||||
|
nonEarpieceOutputAudioDevice.value = coreContext.core.outputAudioDevice?.type != AudioDevice.Type.Earpiece
|
||||||
|
|
||||||
val videoEnabled = coreContext.isVideoCallOrConferenceActive()
|
val isVideoCall = coreContext.isVideoCallOrConferenceActive()
|
||||||
if (videoEnabled) {
|
videoEnabled.value = isVideoCall
|
||||||
videoEnabledEvent.value = Event(true)
|
if (isVideoCall) {
|
||||||
startTimer()
|
startTimer()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
proximitySensorEnabled.value = shouldEnableProximitySensor()
|
||||||
|
proximitySensorEnabled.addSource(videoEnabled) {
|
||||||
|
proximitySensorEnabled.value = shouldEnableProximitySensor()
|
||||||
|
}
|
||||||
|
proximitySensorEnabled.addSource(nonEarpieceOutputAudioDevice) {
|
||||||
|
proximitySensorEnabled.value = shouldEnableProximitySensor()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCleared() {
|
override fun onCleared() {
|
||||||
|
@ -84,6 +103,10 @@ class ControlsFadingViewModel : ViewModel() {
|
||||||
startTimer()
|
startTimer()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun shouldEnableProximitySensor(): Boolean {
|
||||||
|
return !(videoEnabled.value ?: false) && !(nonEarpieceOutputAudioDevice.value ?: false)
|
||||||
|
}
|
||||||
|
|
||||||
private fun stopTimer() {
|
private fun stopTimer() {
|
||||||
timer?.cancel()
|
timer?.cancel()
|
||||||
|
|
||||||
|
|
|
@ -518,7 +518,7 @@ class DetailChatRoomFragment : MasterFragment() {
|
||||||
|
|
||||||
private fun openFile(contentFilePath: String) {
|
private fun openFile(contentFilePath: String) {
|
||||||
val intent = Intent(Intent.ACTION_VIEW)
|
val intent = Intent(Intent.ACTION_VIEW)
|
||||||
var path = contentFilePath
|
val path = contentFilePath
|
||||||
val contentUri: Uri = FileUtils.getPublicFilePath(requireContext(), path)
|
val contentUri: Uri = FileUtils.getPublicFilePath(requireContext(), path)
|
||||||
val filePath: String = contentUri.toString()
|
val filePath: String = contentUri.toString()
|
||||||
Log.i("[Chat Message] Trying to open file: $filePath")
|
Log.i("[Chat Message] Trying to open file: $filePath")
|
||||||
|
|
|
@ -234,7 +234,7 @@ class FileUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getPublicFilePath(context: Context, path: String): Uri {
|
fun getPublicFilePath(context: Context, path: String): Uri {
|
||||||
var contentUri: Uri
|
val contentUri: Uri
|
||||||
when {
|
when {
|
||||||
path.startsWith("file://") -> {
|
path.startsWith("file://") -> {
|
||||||
val file = File(path.substring("file://".length))
|
val file = File(path.substring("file://".length))
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools">
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
<data>
|
<data>
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools">
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
<data>
|
<data>
|
||||||
|
|
Loading…
Reference in a new issue