RTT bugfixes, part 5

* Stop destroying and re-creating the RTT pipes -- they have a complex
lifecycle on the other side of the pipe

Bug: 72648661
Bug: 72762206
Test: manual, with telecom testapp dialer over the network and Dialer
simulator

Change-Id: I4fd657e4c204386826fc6e7f9e529b673d16e001
Merged-In: I4fd657e4c204386826fc6e7f9e529b673d16e001
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index e485e88..4c29e45 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -60,7 +60,6 @@
 import java.lang.String;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
 import java.util.LinkedList;
@@ -487,11 +486,6 @@
     private ParcelFileDescriptor[] mConnectionServiceToInCallStreams;
 
     /**
-     * Abandoned RTT pipes, to be cleaned up when the call is removed
-     */
-    private Collection<ParcelFileDescriptor> mDiscardedRttFds = new LinkedList<>();
-
-    /**
      * True if we're supposed to start this call with RTT, either due to the master switch or due
      * to an extra.
      */
@@ -671,16 +665,33 @@
             mCallerInfo.cachedPhotoIcon = null;
             mCallerInfo.cachedPhoto = null;
         }
-        for (ParcelFileDescriptor fd : mDiscardedRttFds) {
-            if (fd != null) {
-                try {
-                    fd.close();
-                } catch (IOException e) {
-                    // ignore
+
+        Log.addEvent(this, LogUtils.Events.DESTROYED);
+    }
+
+    private void closeRttStreams() {
+        if (mConnectionServiceToInCallStreams != null) {
+            for (ParcelFileDescriptor fd : mConnectionServiceToInCallStreams) {
+                if (fd != null) {
+                    try {
+                        fd.close();
+                    } catch (IOException e) {
+                        // ignore
+                    }
                 }
             }
         }
-        Log.addEvent(this, LogUtils.Events.DESTROYED);
+        if (mInCallToConnectionServiceStreams != null) {
+            for (ParcelFileDescriptor fd : mInCallToConnectionServiceStreams) {
+                if (fd != null) {
+                    try {
+                        fd.close();
+                    } catch (IOException e) {
+                        // ignore
+                    }
+                }
+            }
+        }
     }
 
     /** {@inheritDoc} */
@@ -1308,12 +1319,8 @@
                 && mDidRequestToStartWithRtt && !areRttStreamsInitialized()) {
             // If the phone account got set to an RTT capable one and we haven't set the streams
             // yet, do so now.
-            setRttStreams(true);
+            createRttStreams();
             Log.i(this, "Setting RTT streams after target phone account selected");
-        } else if (!isRttSupported && !isConnectionManagerRttSupported) {
-            // If the phone account got set to RTT-incapable, unset the streams.
-            Log.i(this, "Unsetting RTT streams after target phone account selected");
-            setRttStreams(false);
         }
     }
 
@@ -1418,8 +1425,10 @@
         if (changedProperties != 0) {
             int previousProperties = mConnectionProperties;
             mConnectionProperties = connectionProperties;
-            setRttStreams((mConnectionProperties & Connection.PROPERTY_IS_RTT) ==
-                    Connection.PROPERTY_IS_RTT);
+            if ((mConnectionProperties & Connection.PROPERTY_IS_RTT) ==
+                    Connection.PROPERTY_IS_RTT) {
+                createRttStreams();
+            }
             mWasHighDefAudio = (connectionProperties & Connection.PROPERTY_HIGH_DEF_AUDIO) ==
                     Connection.PROPERTY_HIGH_DEF_AUDIO;
             boolean didRttChange =
@@ -2525,7 +2534,7 @@
     }
 
     public void sendRttRequest() {
-        setRttStreams(true);
+        createRttStreams();
         mConnectionService.startRtt(this, getInCallToCsRttPipeForCs(), getCsToInCallRttPipeForCs());
     }
 
@@ -2534,10 +2543,9 @@
                 && mConnectionServiceToInCallStreams != null;
     }
 
-    public void setRttStreams(boolean shouldBeRtt) {
-        boolean areStreamsInitialized = areRttStreamsInitialized();
-        Log.i(this, "Setting RTT streams to %b, currently %b", shouldBeRtt, areStreamsInitialized);
-        if (shouldBeRtt && !areStreamsInitialized) {
+    public void createRttStreams() {
+        if (!areRttStreamsInitialized()) {
+            Log.i(this, "Initializing RTT streams");
             try {
                 mWasEverRtt = true;
                 mInCallToConnectionServiceStreams = ParcelFileDescriptor.createReliablePipe();
@@ -2545,16 +2553,11 @@
             } catch (IOException e) {
                 Log.e(this, e, "Failed to create pipes for RTT call.");
             }
-        } else if (!shouldBeRtt && areStreamsInitialized) {
-            closeRttPipes();
-            mInCallToConnectionServiceStreams = null;
-            mConnectionServiceToInCallStreams = null;
         }
     }
 
     public void onRttConnectionFailure(int reason) {
         Log.i(this, "Got RTT initiation failure with reason %d", reason);
-        setRttStreams(false);
         for (Listener l : mListeners) {
             l.onRttInitiationFailure(this, reason);
         }
@@ -2581,8 +2584,8 @@
             Log.w(this, "Response ID %d does not match expected %d", id, mPendingRttRequestId);
             return;
         }
-        setRttStreams(accept);
         if (accept) {
+            createRttStreams();
             Log.i(this, "RTT request %d accepted.", id);
             mConnectionService.respondToRttRequest(
                     this, getInCallToCsRttPipeForCs(), getCsToInCallRttPipeForCs());
@@ -2592,18 +2595,6 @@
         }
     }
 
-    public void closeRttPipes() {
-        // Defer closing until the call is destroyed
-        if (mInCallToConnectionServiceStreams != null) {
-            mDiscardedRttFds.add(mInCallToConnectionServiceStreams[0]);
-            mDiscardedRttFds.add(mInCallToConnectionServiceStreams[1]);
-        }
-        if (mConnectionServiceToInCallStreams != null) {
-            mDiscardedRttFds.add(mConnectionServiceToInCallStreams[0]);
-            mDiscardedRttFds.add(mConnectionServiceToInCallStreams[1]);
-        }
-    }
-
     public boolean isRttCall() {
         return (mConnectionProperties & Connection.PROPERTY_IS_RTT) == Connection.PROPERTY_IS_RTT;
     }
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index e83f28b..1f60d27 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -915,12 +915,12 @@
                 call.setIsVoipAudioMode(true);
             }
         }
-        if (isRttSettingOn() ||
+        if (isRttSettingOn() &&
                 extras.getBoolean(TelecomManager.EXTRA_START_CALL_WITH_RTT, false)) {
             Log.d(this, "Incoming call requesting RTT, rtt setting is %b", isRttSettingOn());
             if (phoneAccount != null &&
                     phoneAccount.hasCapabilities(PhoneAccount.CAPABILITY_RTT)) {
-                call.setRttStreams(true);
+                call.createRttStreams();
             }
             // Even if the phone account doesn't support RTT yet, the connection manager might
             // change that. Set this to check it later.
@@ -1211,7 +1211,7 @@
                 Log.d(this, "Outgoing call requesting RTT, rtt setting is %b", isRttSettingOn());
                 if (accountToUse != null
                         && accountToUse.hasCapabilities(PhoneAccount.CAPABILITY_RTT)) {
-                    call.setRttStreams(true);
+                    call.createRttStreams();
                 }
                 // Even if the phone account doesn't support RTT yet, the connection manager might
                 // change that. Set this to check it later.
@@ -1778,8 +1778,7 @@
 
     private boolean isRttSettingOn() {
         return Settings.System.getInt(mContext.getContentResolver(),
-                Settings.System.RTT_CALLING_MODE, TelecomManager.TTY_MODE_OFF)
-                != TelecomManager.TTY_MODE_OFF;
+                Settings.System.RTT_CALLING_MODE, 0) != 0;
     }
 
     void phoneAccountSelected(Call call, PhoneAccountHandle account, boolean setDefault) {
@@ -1801,7 +1800,7 @@
                         " rtt setting is %b", isRttSettingOn());
                 if (realPhoneAccount != null
                         && realPhoneAccount.hasCapabilities(PhoneAccount.CAPABILITY_RTT)) {
-                    call.setRttStreams(true);
+                    call.createRttStreams();
                 }
                 // Even if the phone account doesn't support RTT yet, the connection manager might
                 // change that. Set this to check it later.
diff --git a/src/com/android/server/telecom/ParcelableCallUtils.java b/src/com/android/server/telecom/ParcelableCallUtils.java
index 3c0e756..77598c8 100644
--- a/src/com/android/server/telecom/ParcelableCallUtils.java
+++ b/src/com/android/server/telecom/ParcelableCallUtils.java
@@ -342,7 +342,10 @@
         android.telecom.Call.Details.PROPERTY_SELF_MANAGED,
 
         Connection.PROPERTY_ASSISTED_DIALING_USED,
-        android.telecom.Call.Details.PROPERTY_ASSISTED_DIALING_USED
+        android.telecom.Call.Details.PROPERTY_ASSISTED_DIALING_USED,
+
+        Connection.PROPERTY_IS_RTT,
+        android.telecom.Call.Details.PROPERTY_RTT
     };
 
     private static int convertConnectionToCallProperties(int connectionProperties) {