diff --git a/app/src/main/java/org/linphone/ui/call/CallActivity.kt b/app/src/main/java/org/linphone/ui/call/CallActivity.kt index fc0020f10..5e2272130 100644 --- a/app/src/main/java/org/linphone/ui/call/CallActivity.kt +++ b/app/src/main/java/org/linphone/ui/call/CallActivity.kt @@ -20,10 +20,12 @@ package org.linphone.ui.call import android.Manifest +import android.content.Context import android.content.Intent import android.content.pm.PackageManager import android.content.res.Resources import android.os.Bundle +import android.os.PowerManager import androidx.activity.result.contract.ActivityResultContracts import androidx.annotation.UiThread import androidx.core.view.WindowCompat @@ -70,6 +72,8 @@ class CallActivity : GenericActivity() { private lateinit var callsViewModel: CallsViewModel private lateinit var callViewModel: CurrentCallViewModel + private lateinit var proximityWakeLock: PowerManager.WakeLock + private var bottomSheetDialog: BottomSheetDialogFragment? = null private var isPipSupported = false @@ -114,6 +118,16 @@ class CallActivity : GenericActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager + if (!powerManager.isWakeLockLevelSupported(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)) { + Log.w("$TAG PROXIMITY_SCREEN_OFF_WAKE_LOCK isn't supported on this device!") + } + + proximityWakeLock = powerManager.newWakeLock( + PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, + "$packageName;proximity_sensor" + ) + binding = DataBindingUtil.setContentView(this, R.layout.call_activity) binding.lifecycleOwner = this @@ -209,6 +223,11 @@ class CallActivity : GenericActivity() { } } + callViewModel.proximitySensorEnabled.observe(this) { enabled -> + Log.i("$TAG ${if (enabled) "Enabling" else "Disabling"} proximity sensor") + enableProximitySensor(enabled) + } + callsViewModel.showIncomingCallEvent.observe(this) { it.consume { val action = IncomingCallFragmentDirections.actionGlobalIncomingCallFragment() @@ -291,6 +310,8 @@ class CallActivity : GenericActivity() { } override fun onPause() { + enableProximitySensor(false) + super.onPause() bottomSheetDialog?.dismiss() @@ -298,6 +319,8 @@ class CallActivity : GenericActivity() { } override fun onDestroy() { + enableProximitySensor(false) + super.onDestroy() coreContext.postOnCoreThread { core -> @@ -442,4 +465,16 @@ class CallActivity : GenericActivity() { modalBottomSheet.show(supportFragmentManager, ConferenceLayoutMenuDialogFragment.TAG) bottomSheetDialog = modalBottomSheet } + + private fun enableProximitySensor(enable: Boolean) { + if (enable && !proximityWakeLock.isHeld) { + Log.i("$TAG Acquiring PROXIMITY_SCREEN_OFF_WAKE_LOCK for 2 hours") + proximityWakeLock.acquire(7200 * 1000L) // 2 heures + } else if (!enable && proximityWakeLock.isHeld) { + Log.i( + "$TAG Asking to release PROXIMITY_SCREEN_OFF_WAKE_LOCK (next time sensor detects no proximity)" + ) + proximityWakeLock.release(PowerManager.RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY) + } + } } diff --git a/app/src/main/java/org/linphone/ui/call/viewmodel/CurrentCallViewModel.kt b/app/src/main/java/org/linphone/ui/call/viewmodel/CurrentCallViewModel.kt index 637806bd8..4de403c23 100644 --- a/app/src/main/java/org/linphone/ui/call/viewmodel/CurrentCallViewModel.kt +++ b/app/src/main/java/org/linphone/ui/call/viewmodel/CurrentCallViewModel.kt @@ -152,6 +152,8 @@ class CurrentCallViewModel @UiThread constructor() : GenericViewModel() { MutableLiveData>() } + val proximitySensorEnabled = MutableLiveData() + // To synchronize chronometers in UI val callDuration = MutableLiveData() @@ -385,6 +387,8 @@ class CurrentCallViewModel @UiThread constructor() : GenericViewModel() { ) configureCall(call) } + + updateProximitySensor() } @WorkerThread @@ -401,9 +405,33 @@ class CurrentCallViewModel @UiThread constructor() : GenericViewModel() { } } + @WorkerThread + private fun updateProximitySensor() { + if (::currentCall.isInitialized) { + val callState = currentCall.state + if (LinphoneUtils.isCallIncoming(callState) || LinphoneUtils.isCallOutgoing(callState)) { + proximitySensorEnabled.postValue(false) + } else { + if (isSendingVideo.value == true || isReceivingVideo.value == true) { + proximitySensorEnabled.postValue(false) + } else { + val outputAudioDevice = currentCall.outputAudioDevice ?: coreContext.core.outputAudioDevice + if (outputAudioDevice != null && outputAudioDevice.type == AudioDevice.Type.Earpiece) { + proximitySensorEnabled.postValue(true) + } else { + proximitySensorEnabled.postValue(false) + } + } + } + } else { + proximitySensorEnabled.postValue(false) + } + } + init { fullScreenMode.value = false operationInProgress.value = false + proximitySensorEnabled.value = false coreContext.postOnCoreThread { core -> core.addListener(coreListener) @@ -1086,6 +1114,8 @@ class CurrentCallViewModel @UiThread constructor() : GenericViewModel() { audioDevice?.type == AudioDevice.Type.Headphones || audioDevice?.type == AudioDevice.Type.Headset ) isBluetoothEnabled.postValue(audioDevice?.type == AudioDevice.Type.Bluetooth) + + updateProximitySensor() } @WorkerThread @@ -1117,7 +1147,9 @@ class CurrentCallViewModel @UiThread constructor() : GenericViewModel() { isReceivingVideo.postValue( isReceived ) - Log.i("$TAG Is video being sent? [$isSending] Is video being received? [$isReceived]") + Log.d("$TAG Is video being sent? [$isSending] Is video being received? [$isReceived]") + + updateProximitySensor() } @AnyThread