From b6934e02fd815a4b305c272c41f9b58ba0945e1d Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 26 May 2020 20:50:14 +0200 Subject: [PATCH] Trying to prevent or understand issues with incoming call activity --- app/src/main/AndroidManifest.xml | 5 +- .../linphone/activities/call/CallActivity.kt | 1 + .../activities/call/IncomingCallActivity.kt | 47 ++++++++++++++----- .../activities/call/OutgoingCallActivity.kt | 45 +++++++++++++----- .../call/viewmodels/CallViewModel.kt | 6 +++ .../compatibility/Api21Compatibility.kt | 4 ++ .../compatibility/Api27Compatibility.kt | 6 +++ .../linphone/compatibility/Compatibility.kt | 8 ++++ .../java/org/linphone/core/CoreContext.kt | 4 +- .../notifications/NotificationsManager.kt | 10 +++- 10 files changed, 106 insertions(+), 30 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3fdcb8eb2..4f4211a53 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -101,14 +101,11 @@ + android:noHistory="true" /> () if (!PermissionHelper.get().hasRecordAudioPermission()) { - Log.i("[Incoming Call] Asking for RECORD_AUDIO permission") + 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] Asking for CAMERA permission") + Log.i("[Incoming Call Activity] Asking for CAMERA permission") permissionsRequiredList.add(android.Manifest.permission.CAMERA) } if (permissionsRequiredList.isNotEmpty()) { @@ -106,4 +119,14 @@ class IncomingCallActivity : GenericActivity() { requestPermissions(permissionsRequired, 0) } } + + private fun findIncomingCall(): Call? { + for (call in coreContext.core.calls) { + if (call.state == Call.State.IncomingReceived || + call.state == Call.State.IncomingEarlyMedia) { + return call + } + } + return null + } } diff --git a/app/src/main/java/org/linphone/activities/call/OutgoingCallActivity.kt b/app/src/main/java/org/linphone/activities/call/OutgoingCallActivity.kt index b4e26f2a3..14b204359 100644 --- a/app/src/main/java/org/linphone/activities/call/OutgoingCallActivity.kt +++ b/app/src/main/java/org/linphone/activities/call/OutgoingCallActivity.kt @@ -49,17 +49,9 @@ class OutgoingCallActivity : ProximitySensorActivity() { binding = DataBindingUtil.setContentView(this, R.layout.call_outgoing_activity) binding.lifecycleOwner = this - var outgoingCall: Call? = null - for (call in coreContext.core.calls) { - if (call.state == Call.State.OutgoingInit || - call.state == Call.State.OutgoingProgress || - call.state == Call.State.OutgoingRinging) { - outgoingCall = call - } - } - + var outgoingCall: Call? = findOutgoingCall() if (outgoingCall == null) { - Log.e("[Outgoing Call] Couldn't find call in state Outgoing") + Log.e("[Outgoing Call Activity] Couldn't find call in state Outgoing") finish() return } @@ -91,6 +83,14 @@ class OutgoingCallActivity : ProximitySensorActivity() { viewModel.callEndedEvent.observe(this, Observer { it.consume { + Log.i("[Outgoing Call Activity] Call ended, finish activity") + finish() + } + }) + + viewModel.callConnectedEvent.observe(this, Observer { + it.consume { + Log.i("[Outgoing Call Activity] Call connected, finish activity") finish() } }) @@ -100,15 +100,25 @@ class OutgoingCallActivity : ProximitySensorActivity() { } } + override fun onResume() { + super.onResume() + + var outgoingCall: Call? = findOutgoingCall() + if (outgoingCall == null) { + Log.e("[Outgoing Call Activity] Couldn't find call in state Outgoing") + finish() + } + } + @TargetApi(Version.API23_MARSHMALLOW_60) private fun checkPermissions() { val permissionsRequiredList = arrayListOf() if (!PermissionHelper.get().hasRecordAudioPermission()) { - Log.i("[Outgoing Call] Asking for RECORD_AUDIO permission") + Log.i("[Outgoing Call Activity] Asking for RECORD_AUDIO permission") permissionsRequiredList.add(android.Manifest.permission.RECORD_AUDIO) } if (viewModel.call.currentParams.videoEnabled() && !PermissionHelper.get().hasCameraPermission()) { - Log.i("[Outgoing Call] Asking for CAMERA permission") + Log.i("[Outgoing Call Activity] Asking for CAMERA permission") permissionsRequiredList.add(android.Manifest.permission.CAMERA) } if (permissionsRequiredList.isNotEmpty()) { @@ -117,4 +127,15 @@ class OutgoingCallActivity : ProximitySensorActivity() { requestPermissions(permissionsRequired, 0) } } + + private fun findOutgoingCall(): Call? { + for (call in coreContext.core.calls) { + if (call.state == Call.State.OutgoingInit || + call.state == Call.State.OutgoingProgress || + call.state == Call.State.OutgoingRinging) { + return call + } + } + return null + } } diff --git a/app/src/main/java/org/linphone/activities/call/viewmodels/CallViewModel.kt b/app/src/main/java/org/linphone/activities/call/viewmodels/CallViewModel.kt index 3330a6144..9d1d3fbdc 100644 --- a/app/src/main/java/org/linphone/activities/call/viewmodels/CallViewModel.kt +++ b/app/src/main/java/org/linphone/activities/call/viewmodels/CallViewModel.kt @@ -50,6 +50,10 @@ open class CallViewModel(val call: Call) : GenericContactViewModel(call.remoteAd MutableLiveData>() } + val callConnectedEvent: MutableLiveData> by lazy { + MutableLiveData>() + } + private val listener = object : CallListenerStub() { override fun onStateChanged(call: Call, state: Call.State, message: String) { if (call != this@CallViewModel.call) return @@ -62,6 +66,8 @@ open class CallViewModel(val call: Call) : GenericContactViewModel(call.remoteAd if (state == Call.State.Error) { Log.e("[Call View Model] Error state reason is ${call.reason}") } + } else if (call.state == Call.State.Connected) { + callConnectedEvent.value = Event(true) } } } diff --git a/app/src/main/java/org/linphone/compatibility/Api21Compatibility.kt b/app/src/main/java/org/linphone/compatibility/Api21Compatibility.kt index 2c07e21bb..cfe5391c6 100644 --- a/app/src/main/java/org/linphone/compatibility/Api21Compatibility.kt +++ b/app/src/main/java/org/linphone/compatibility/Api21Compatibility.kt @@ -169,5 +169,9 @@ class Api21Compatibility { activity.window.clearFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) } } + + fun requestDismissKeyguard(activity: Activity) { + activity.window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD) + } } } diff --git a/app/src/main/java/org/linphone/compatibility/Api27Compatibility.kt b/app/src/main/java/org/linphone/compatibility/Api27Compatibility.kt index f148b9fd0..55724fa6c 100644 --- a/app/src/main/java/org/linphone/compatibility/Api27Compatibility.kt +++ b/app/src/main/java/org/linphone/compatibility/Api27Compatibility.kt @@ -21,6 +21,7 @@ package org.linphone.compatibility import android.annotation.TargetApi import android.app.* +import android.content.Context @TargetApi(27) class Api27Compatibility { @@ -32,5 +33,10 @@ class Api27Compatibility { fun setTurnScreenOn(activity: Activity, enable: Boolean) { activity.setTurnScreenOn(enable) } + + fun requestDismissKeyguard(activity: Activity) { + val keyguardManager = activity.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager + keyguardManager.requestDismissKeyguard(activity, null) + } } } diff --git a/app/src/main/java/org/linphone/compatibility/Compatibility.kt b/app/src/main/java/org/linphone/compatibility/Compatibility.kt index 5e7f78913..ed37472c0 100644 --- a/app/src/main/java/org/linphone/compatibility/Compatibility.kt +++ b/app/src/main/java/org/linphone/compatibility/Compatibility.kt @@ -64,6 +64,14 @@ class Compatibility { } } + fun requestDismissKeyguard(activity: Activity) { + if (Version.sdkStrictlyBelow(Version.API27_OREO_81)) { + Api21Compatibility.requestDismissKeyguard(activity) + } else { + Api27Compatibility.requestDismissKeyguard(activity) + } + } + /* Notifications */ fun createNotificationChannels( diff --git a/app/src/main/java/org/linphone/core/CoreContext.kt b/app/src/main/java/org/linphone/core/CoreContext.kt index 294ad57c6..0710769e4 100644 --- a/app/src/main/java/org/linphone/core/CoreContext.kt +++ b/app/src/main/java/org/linphone/core/CoreContext.kt @@ -30,7 +30,6 @@ import android.telephony.PhoneStateListener import android.telephony.TelephonyManager import android.view.* import java.io.File -import java.util.* import kotlin.math.abs import org.linphone.LinphoneApplication.Companion.corePreferences import org.linphone.activities.call.CallActivity @@ -435,6 +434,7 @@ class CoreContext(val context: Context, coreConfig: Config) { /* Start call related activities */ private fun onIncomingReceived() { + Log.i("[Context] Starting IncomingCallActivity") val intent = Intent(context, IncomingCallActivity::class.java) // This flag is required to start an Activity from a Service context intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) @@ -442,6 +442,7 @@ class CoreContext(val context: Context, coreConfig: Config) { } private fun onOutgoingStarted() { + Log.i("[Context] Starting OutgoingCallActivity") val intent = Intent(context, OutgoingCallActivity::class.java) // This flag is required to start an Activity from a Service context intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) @@ -449,6 +450,7 @@ class CoreContext(val context: Context, coreConfig: Config) { } private fun onCallStarted() { + Log.i("[Context] Starting CallActivity") val intent = Intent(context, CallActivity::class.java) // This flag is required to start an Activity from a Service context intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) diff --git a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt index fba181116..8e3ead83e 100644 --- a/app/src/main/java/org/linphone/notifications/NotificationsManager.kt +++ b/app/src/main/java/org/linphone/notifications/NotificationsManager.kt @@ -343,6 +343,11 @@ class NotificationsManager(private val context: Context) { val address = call.remoteAddress.asStringUriOnly() val notifiable = getNotifiableForCall(call) + if (notifiable.notificationId == currentForegroundServiceNotificationId) { + Log.w("[Notifications Manager] Incoming call notification already displayed by foreground service, skipping") + return + } + val contact: Contact? = coreContext.contactsManager.findContactByAddress(call.remoteAddress) val pictureUri = contact?.getContactThumbnailPictureUri() val roundPicture = ImageUtils.getRoundBitmapFromUri(context, pictureUri) @@ -380,10 +385,13 @@ class NotificationsManager(private val context: Context) { .addAction(getCallAnswerAction(notifiable.notificationId)) .setCustomHeadsUpContentView(notificationLayoutHeadsUp) .build() - notify(notifiable.notificationId, notification) if (useAsForeground) { + Log.i("[Notifications Manager] Notifying incoming call notification for foreground service") startForeground(notifiable.notificationId, notification) + } else { + Log.i("[Notifications Manager] Notifying incoming call notification") + notify(notifiable.notificationId, notification) } }