From e5f70bdbda10e34632aa4185ab37fa80080c08c4 Mon Sep 17 00:00:00 2001 From: Alan Evans Date: Thu, 23 May 2019 16:56:05 -0300 Subject: [PATCH] End RTC call on incoming PSTN call. * Hangs up when new device call is answered. * Ensure not on a device call when starting a Signal call. --- res/values/strings.xml | 1 + .../securesms/service/WebRtcCallService.java | 39 ++++++++++++++++--- .../securesms/util/CommunicationActions.java | 8 ++++ .../securesms/util/TelephonyUtil.java | 6 +++ 4 files changed, 48 insertions(+), 6 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 72d294034c..a363709fb8 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -94,6 +94,7 @@ No web browser found. + A cellular call is already in progress. Your safety number with %1$s has changed. This could either mean that someone is trying to intercept your communication, or that %2$s simply reinstalled Signal. diff --git a/src/org/thoughtcrime/securesms/service/WebRtcCallService.java b/src/org/thoughtcrime/securesms/service/WebRtcCallService.java index be20047e97..96800516ae 100644 --- a/src/org/thoughtcrime/securesms/service/WebRtcCallService.java +++ b/src/org/thoughtcrime/securesms/service/WebRtcCallService.java @@ -18,8 +18,8 @@ import android.os.ResultReceiver; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.WorkerThread; +import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; -import org.thoughtcrime.securesms.logging.Log; import android.util.Pair; import com.google.protobuf.InvalidProtocolBufferException; @@ -34,12 +34,14 @@ import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.RecipientDatabase.VibrateState; import org.thoughtcrime.securesms.dependencies.InjectableType; import org.thoughtcrime.securesms.events.WebRtcViewModel; +import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.notifications.MessageNotifier; import org.thoughtcrime.securesms.permissions.Permissions; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.util.FutureTaskListener; import org.thoughtcrime.securesms.util.ListenableFutureTask; import org.thoughtcrime.securesms.util.ServiceUtil; +import org.thoughtcrime.securesms.util.TelephonyUtil; import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.Util; import org.thoughtcrime.securesms.webrtc.CallNotificationBuilder; @@ -90,12 +92,10 @@ import org.whispersystems.signalservice.internal.util.concurrent.SettableFuture; import java.io.IOException; import java.nio.ByteBuffer; -import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.LinkedList; import java.util.List; import java.util.concurrent.Callable; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -192,15 +192,21 @@ public class WebRtcCallService extends Service implements InjectableType, private ExecutorService networkExecutor = Executors.newSingleThreadExecutor(); private ScheduledExecutorService timeoutExecutor = Executors.newScheduledThreadPool(1); + private final PhoneStateListener hangUpRtcOnDeviceCallAnswered = new HangUpRtcOnPstnCallAnsweredListener(); + @Override public void onCreate() { super.onCreate(); + Log.d(TAG, "onCreate"); initializeResources(); registerIncomingPstnCallReceiver(); registerUncaughtExceptionHandler(); registerWiredHeadsetStateReceiver(); + + TelephonyUtil.getManager(this) + .listen(hangUpRtcOnDeviceCallAnswered, PhoneStateListener.LISTEN_CALL_STATE); } @Override @@ -239,6 +245,7 @@ public class WebRtcCallService extends Service implements InjectableType, @Override public void onDestroy() { super.onDestroy(); + Log.d(TAG, "onDestroy"); if (callReceiver != null) { unregisterReceiver(callReceiver); @@ -261,6 +268,9 @@ public class WebRtcCallService extends Service implements InjectableType, unregisterReceiver(powerButtonReceiver); powerButtonReceiver = null; } + + TelephonyUtil.getManager(this) + .listen(hangUpRtcOnDeviceCallAnswered, PhoneStateListener.LISTEN_NONE); } @Override @@ -901,9 +911,7 @@ public class WebRtcCallService extends Service implements InjectableType, /// Helper Methods private boolean isBusy() { - TelephonyManager telephonyManager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE); - - return callState != CallState.STATE_IDLE || telephonyManager.getCallState() != TelephonyManager.CALL_STATE_IDLE; + return callState != CallState.STATE_IDLE || TelephonyUtil.isAnyPstnLineBusy(this); } private boolean isIdle() { @@ -1381,4 +1389,23 @@ public class WebRtcCallService extends Service implements InjectableType, context.startService(intent); } + + private class HangUpRtcOnPstnCallAnsweredListener extends PhoneStateListener { + + @Override + public void onCallStateChanged(int state, String phoneNumber) { + super.onCallStateChanged(state, phoneNumber); + if (state == TelephonyManager.CALL_STATE_OFFHOOK) { + hangup(); + Log.i(TAG, "Device phone call ended Signal call."); + } + } + + private void hangup() { + Intent intent = new Intent(WebRtcCallService.this, WebRtcCallService.class); + intent.setAction(ACTION_LOCAL_HANGUP); + + startService(intent); + } + } } diff --git a/src/org/thoughtcrime/securesms/util/CommunicationActions.java b/src/org/thoughtcrime/securesms/util/CommunicationActions.java index 20dad6ae61..1df299cefa 100644 --- a/src/org/thoughtcrime/securesms/util/CommunicationActions.java +++ b/src/org/thoughtcrime/securesms/util/CommunicationActions.java @@ -25,6 +25,14 @@ import org.thoughtcrime.securesms.service.WebRtcCallService; public class CommunicationActions { public static void startVoiceCall(@NonNull Activity activity, @NonNull Recipient recipient) { + if (TelephonyUtil.isAnyPstnLineBusy(activity)) { + Toast.makeText(activity, + R.string.CommunicationActions_a_cellular_call_is_already_in_progress, + Toast.LENGTH_SHORT + ).show(); + return; + } + Permissions.with(activity) .request(Manifest.permission.RECORD_AUDIO, Manifest.permission.CAMERA) .ifNecessary() diff --git a/src/org/thoughtcrime/securesms/util/TelephonyUtil.java b/src/org/thoughtcrime/securesms/util/TelephonyUtil.java index 949ef46ca5..3609cc7c7c 100644 --- a/src/org/thoughtcrime/securesms/util/TelephonyUtil.java +++ b/src/org/thoughtcrime/securesms/util/TelephonyUtil.java @@ -3,7 +3,9 @@ package org.thoughtcrime.securesms.util; import android.content.Context; import android.content.res.Configuration; import android.net.ConnectivityManager; +import android.support.annotation.NonNull; import android.telephony.TelephonyManager; + import org.thoughtcrime.securesms.logging.Log; import java.util.Locale; @@ -39,4 +41,8 @@ public class TelephonyUtil { final ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); return cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE_MMS).getExtraInfo(); } + + public static boolean isAnyPstnLineBusy(@NonNull Context context) { + return getManager(context).getCallState() != TelephonyManager.CALL_STATE_IDLE; + } }