extend isBusyState to check phone state as well

Daniel Gultsch created

Change summary

src/main/AndroidManifest.xml                                                  |  5 
src/main/java/eu/siacs/conversations/services/XmppConnectionService.java      | 22 
src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java | 11 
3 files changed, 30 insertions(+), 8 deletions(-)

Detailed changes

src/main/AndroidManifest.xml 🔗

@@ -7,6 +7,7 @@
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.READ_CONTACTS" />
     <uses-permission android:name="android.permission.READ_PROFILE" />
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" android:maxSdkVersion="22" />
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.WAKE_LOCK" />
@@ -36,10 +37,6 @@
     <uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
     <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
 
-    <uses-permission
-        android:name="android.permission.READ_PHONE_STATE"
-        tools:node="remove" />
-
     <uses-sdk tools:overrideLibrary="net.ypresto.androidtranscoder" />
 
     <uses-feature

src/main/java/eu/siacs/conversations/services/XmppConnectionService.java 🔗

@@ -36,6 +36,8 @@ import android.support.annotation.BoolRes;
 import android.support.annotation.IntegerRes;
 import android.support.v4.app.RemoteInput;
 import android.support.v4.content.ContextCompat;
+import android.telephony.PhoneStateListener;
+import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.DisplayMetrics;
 import android.util.Log;
@@ -262,6 +264,13 @@ public class XmppConnectionService extends Service {
             return false;
         }
     };
+    private final AtomicBoolean isPhoneInCall = new AtomicBoolean(false);
+    private final PhoneStateListener phoneStateListener = new PhoneStateListener() {
+        @Override
+        public void onCallStateChanged(final int state, final String phoneNumber) {
+            isPhoneInCall.set(state != 0);
+        }
+    };
 
     private boolean destroyed = false;
 
@@ -1156,6 +1165,19 @@ public class XmppConnectionService extends Service {
         registerReceiver(this.mInternalEventReceiver, intentFilter);
         mForceDuringOnCreate.set(false);
         toggleForegroundService();
+        setupPhoneStateListener();
+    }
+
+
+    private void setupPhoneStateListener() {
+        final TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
+        if (telephonyManager != null) {
+            telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
+        }
+    }
+
+    public boolean isPhoneInCall() {
+        return isPhoneInCall.get();
     }
 
     private void checkForDeletedFiles() {

src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java 🔗

@@ -90,7 +90,7 @@ public class JingleConnectionManager extends AbstractConnectionManager {
             final AbstractJingleConnection connection;
             if (FileTransferDescription.NAMESPACES.contains(descriptionNamespace)) {
                 connection = new JingleFileTransferConnection(this, id, from);
-            } else if (Namespace.JINGLE_APPS_RTP.equals(descriptionNamespace) && !usesTor(account)) {
+            } else if (Namespace.JINGLE_APPS_RTP.equals(descriptionNamespace) && isUsingClearNet(account)) {
                 final boolean sessionEnded = this.terminatedSessions.asMap().containsKey(PersistableSessionId.of(id));
                 final boolean stranger = isWithStrangerAndStrangerNotificationsAreOff(account, id.with);
                 if (isBusy() || sessionEnded || stranger) {
@@ -116,11 +116,14 @@ public class JingleConnectionManager extends AbstractConnectionManager {
         }
     }
 
-    private boolean usesTor(final Account account) {
-        return account.isOnion() || mXmppConnectionService.useTorToConnect();
+    private boolean isUsingClearNet(final Account account) {
+        return !account.isOnion() && !mXmppConnectionService.useTorToConnect();
     }
 
     public boolean isBusy() {
+        if (mXmppConnectionService.isPhoneInCall()) {
+            return true;
+        }
         for (AbstractJingleConnection connection : this.connections.values()) {
             if (connection instanceof JingleRtpConnection) {
                 if (((JingleRtpConnection) connection).isTerminated()) {
@@ -257,7 +260,7 @@ public class JingleConnectionManager extends AbstractConnectionManager {
                     Collections2.filter(descriptions, d -> d instanceof RtpDescription),
                     input -> (RtpDescription) input
             );
-            if (rtpDescriptions.size() > 0 && rtpDescriptions.size() == descriptions.size() && !usesTor(account)) {
+            if (rtpDescriptions.size() > 0 && rtpDescriptions.size() == descriptions.size() && isUsingClearNet(account)) {
                 final Collection<Media> media = Collections2.transform(rtpDescriptions, RtpDescription::getMedia);
                 if (media.contains(Media.UNKNOWN)) {
                     Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": encountered unknown media in session proposal. " + propose);