Disable VT when TTY is enabled during a VOLTE call.

Add a listener to TelephonyCS to track when TTY turns on/off.
Ensure that connections remove their local VT capability when TTY turns
off.
Also, did a bit of opportunistic code cleanup to remove the TTyManager
class which is not used in Telephony.  This in turn enabled the removal
of the TelephonyGlobals class since I could move setup of the
TelecomAccountRegistry into PhoneGlobals instead.  Yay, less globals!

Test: Start VOLTE call with TTY disabled; turn on TTY and ensure VT
button goes away.
Test: Continue VOLTE call with TTY disabled; turn off TTY and ensure VT
button shows up again.
Bug: 77937629

Change-Id: Ia2c98e31c152d7a1136c06913f773b451a1952c7
diff --git a/src/com/android/phone/PhoneApp.java b/src/com/android/phone/PhoneApp.java
index f16d8ce..df151bf 100644
--- a/src/com/android/phone/PhoneApp.java
+++ b/src/com/android/phone/PhoneApp.java
@@ -19,14 +19,13 @@
 import android.app.Application;
 import android.os.UserHandle;
 
-import com.android.services.telephony.TelephonyGlobals;
+import com.android.services.telephony.TelecomAccountRegistry;
 
 /**
  * Top-level Application class for the Phone app.
  */
 public class PhoneApp extends Application {
     PhoneGlobals mPhoneGlobals;
-    TelephonyGlobals mTelephonyGlobals;
 
     public PhoneApp() {
     }
@@ -39,8 +38,7 @@
             mPhoneGlobals = new PhoneGlobals(this);
             mPhoneGlobals.onCreate();
 
-            mTelephonyGlobals = new TelephonyGlobals(this);
-            mTelephonyGlobals.onCreate();
+            TelecomAccountRegistry.getInstance(this).setupOnBoot();
         }
     }
 }
diff --git a/src/com/android/services/telephony/TelecomAccountRegistry.java b/src/com/android/services/telephony/TelecomAccountRegistry.java
index 642af85..6b7a002 100644
--- a/src/com/android/services/telephony/TelecomAccountRegistry.java
+++ b/src/com/android/services/telephony/TelecomAccountRegistry.java
@@ -64,7 +64,7 @@
  * Owns all data we have registered with Telecom including handling dynamic addition and
  * removal of SIMs and SIP accounts.
  */
-final class TelecomAccountRegistry {
+public final class TelecomAccountRegistry {
     private static final boolean DBG = false; /* STOP SHIP if true */
 
     // This icon is the one that is used when the Slot ID that we have for a particular SIM
@@ -659,7 +659,10 @@
         mSubscriptionManager = SubscriptionManager.from(context);
     }
 
-    static synchronized final TelecomAccountRegistry getInstance(Context context) {
+    /**
+     * Get the singleton instance.
+     */
+    public static synchronized TelecomAccountRegistry getInstance(Context context) {
         if (sInstance == null && context != null) {
             sInstance = new TelecomAccountRegistry(context);
         }
@@ -828,7 +831,7 @@
     /**
      * Sets up all the phone accounts for SIMs on first boot.
      */
-    void setupOnBoot() {
+    public void setupOnBoot() {
         // TODO: When this object "finishes" we should unregister by invoking
         // SubscriptionManager.getInstance(mContext).unregister(mOnSubscriptionsChangedListener);
         // This is not strictly necessary because it will be unregistered if the
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index 6904874..4c1963f 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -661,6 +661,11 @@
     private boolean mIsHoldable;
 
     /**
+     * Indicates whether TTY is enabled; used to determine whether a call is VT capable.
+     */
+    private boolean mIsTtyEnabled;
+
+    /**
      * Indicates whether this call is using assisted dialing.
      */
     private boolean mIsUsingAssistedDialing;
@@ -1810,8 +1815,10 @@
         capabilities = changeBitmask(capabilities, CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL,
                 can(mOriginalConnectionCapabilities, Capability.SUPPORTS_VT_REMOTE_BIDIRECTIONAL));
 
+        boolean isLocalVideoSupported = can(mOriginalConnectionCapabilities,
+                Capability.SUPPORTS_VT_LOCAL_BIDIRECTIONAL) && !mIsTtyEnabled;
         capabilities = changeBitmask(capabilities, CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL,
-                can(mOriginalConnectionCapabilities, Capability.SUPPORTS_VT_LOCAL_BIDIRECTIONAL));
+                isLocalVideoSupported);
 
         return capabilities;
     }
@@ -1939,6 +1946,15 @@
     }
 
     /**
+     * Sets whether TTY is enabled or not.
+     * @param isTtyEnabled
+     */
+    public void setTtyEnabled(boolean isTtyEnabled) {
+        mIsTtyEnabled = isTtyEnabled;
+        updateConnectionCapabilities();
+    }
+
+    /**
      * Whether the original connection is an IMS connection.
      * @return {@code True} if the original connection is an IMS connection, {@code false}
      *     otherwise.
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index 195194c..3aac490 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -17,9 +17,11 @@
 package com.android.services.telephony;
 
 import android.content.ActivityNotFoundException;
+import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.net.Uri;
 import android.os.Bundle;
 import android.provider.Settings;
@@ -119,6 +121,23 @@
         }
     };
 
+    private final BroadcastReceiver mTtyBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            Log.v(this, "onReceive, action: %s", action);
+            if (action.equals(TelecomManager.ACTION_TTY_PREFERRED_MODE_CHANGED)) {
+                int newPreferredTtyMode = intent.getIntExtra(
+                        TelecomManager.EXTRA_TTY_PREFERRED_MODE, TelecomManager.TTY_MODE_OFF);
+
+                boolean isTtyNowEnabled = newPreferredTtyMode != TelecomManager.TTY_MODE_OFF;
+                if (isTtyNowEnabled != mIsTtyEnabled) {
+                    handleTtyModeChange(isTtyNowEnabled);
+                }
+            }
+        }
+    };
+
     private final TelephonyConferenceController mTelephonyConferenceController =
             new TelephonyConferenceController(mTelephonyConnectionServiceProxy);
     private final CdmaConferenceController mCdmaConferenceController =
@@ -131,6 +150,7 @@
     private RadioOnHelper mRadioOnHelper;
     private EmergencyTonePlayer mEmergencyTonePlayer;
     private HoldTracker mHoldTracker;
+    private boolean mIsTtyEnabled;
 
     // Contains one TelephonyConnection that has placed a call and a memory of which Phones it has
     // already tried to connect with. There should be only one TelephonyConnection trying to place a
@@ -263,6 +283,17 @@
         mEmergencyTonePlayer = new EmergencyTonePlayer(this);
         TelecomAccountRegistry.getInstance(this).setTelephonyConnectionService(this);
         mHoldTracker = new HoldTracker();
+        mIsTtyEnabled = isTtyModeEnabled(getApplicationContext());
+
+        IntentFilter intentFilter = new IntentFilter(
+                TelecomManager.ACTION_TTY_PREFERRED_MODE_CHANGED);
+        registerReceiver(mTtyBroadcastReceiver, intentFilter);
+    }
+
+    @Override
+    public boolean onUnbind(Intent intent) {
+        unregisterReceiver(mTtyBroadcastReceiver);
+        return super.onUnbind(intent);
     }
 
     @Override
@@ -633,8 +664,9 @@
         }
 
         final Context context = getApplicationContext();
-        if (VideoProfile.isVideo(request.getVideoState()) && isTtyModeEnabled(context) &&
-                !isEmergencyNumber) {
+        final boolean isTtyModeEnabled = isTtyModeEnabled(context);
+        if (VideoProfile.isVideo(request.getVideoState()) && isTtyModeEnabled
+                && !isEmergencyNumber) {
             return Connection.createFailedConnection(DisconnectCauseUtil.toTelecomDisconnectCause(
                     android.telephony.DisconnectCause.VIDEO_CALL_NOT_ALLOWED_WHILE_TTY_ENABLED,
                     null, phone.getPhoneId()));
@@ -670,7 +702,7 @@
         connection.setInitializing();
         connection.setVideoState(request.getVideoState());
         connection.setRttTextStream(request.getRttTextStream());
-
+        connection.setTtyEnabled(isTtyModeEnabled);
         return connection;
     }
 
@@ -1453,4 +1485,15 @@
             }
         }
     }
+
+    private void handleTtyModeChange(boolean isTtyEnabled) {
+        Log.i(this, "handleTtyModeChange; isTtyEnabled=%b", isTtyEnabled);
+        mIsTtyEnabled = isTtyEnabled;
+        for (Connection connection : getAllConnections()) {
+            if (connection instanceof TelephonyConnection) {
+                TelephonyConnection telephonyConnection = (TelephonyConnection) connection;
+                telephonyConnection.setTtyEnabled(isTtyEnabled);
+            }
+        }
+    }
 }
diff --git a/src/com/android/services/telephony/TelephonyGlobals.java b/src/com/android/services/telephony/TelephonyGlobals.java
deleted file mode 100644
index 02ef639..0000000
--- a/src/com/android/services/telephony/TelephonyGlobals.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.services.telephony;
-
-import android.content.Context;
-
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneFactory;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Singleton entry point for the telephony-services app. Initializes ongoing systems relating to
- * PSTN calls. This is started when the device starts and will be restarted automatically
- * if it goes away for any reason (e.g., crashes).
- * This is separate from the actual Application class because we only support one instance of this
- * app - running as the default user. {@link com.android.phone.PhoneApp} determines whether or not
- * we are running as the default user and if we are, then initializes and runs this class's
- * {@link #onCreate}.
- */
-public class TelephonyGlobals {
-    private static TelephonyGlobals sInstance;
-
-    /** The application context. */
-    private final Context mContext;
-
-    // For supporting MSIM phone, change Phone and TtyManager as 1 to 1
-    private List<TtyManager> mTtyManagers = new ArrayList<>();
-
-    /**
-     * Persists the specified parameters.
-     *
-     * @param context The application context.
-     */
-    public TelephonyGlobals(Context context) {
-        mContext = context.getApplicationContext();
-    }
-
-    public static synchronized TelephonyGlobals getInstance(Context context) {
-        if (sInstance == null) {
-            sInstance = new TelephonyGlobals(context);
-        }
-        return sInstance;
-    }
-
-    public void onCreate() {
-        // Make this work with Multi-SIM devices
-        Phone[] phones = PhoneFactory.getPhones();
-        for (Phone phone : phones) {
-            mTtyManagers.add(new TtyManager(mContext, phone));
-        }
-
-        TelecomAccountRegistry.getInstance(mContext).setupOnBoot();
-    }
-}
diff --git a/src/com/android/services/telephony/TtyManager.java b/src/com/android/services/telephony/TtyManager.java
deleted file mode 100644
index 3389ce8..0000000
--- a/src/com/android/services/telephony/TtyManager.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.services.telephony;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.provider.Settings;
-import android.telecom.TelecomManager;
-
-import com.android.internal.telephony.Phone;
-
-final class TtyManager {
-    private final static int MSG_SET_TTY_MODE_RESPONSE = 1;
-    private final static int MSG_GET_TTY_MODE_RESPONSE = 2;
-
-    private final TtyBroadcastReceiver mReceiver = new TtyBroadcastReceiver();
-    private final Phone mPhone;
-    private int mTtyMode;
-    private int mUiTtyMode = -1;
-
-    private final Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_SET_TTY_MODE_RESPONSE: {
-                    Log.v(TtyManager.this, "got setTtyMode response");
-                    AsyncResult ar = (AsyncResult) msg.obj;
-                    if (ar.exception != null) {
-                        Log.d(TtyManager.this, "setTTYMode exception: %s", ar.exception);
-                    }
-                    mPhone.queryTTYMode(obtainMessage(MSG_GET_TTY_MODE_RESPONSE));
-                    break;
-                }
-                case MSG_GET_TTY_MODE_RESPONSE: {
-                    Log.v(TtyManager.this, "got queryTTYMode response");
-                    AsyncResult ar = (AsyncResult) msg.obj;
-                    if (ar.exception != null) {
-                        Log.d(TtyManager.this, "queryTTYMode exception: %s", ar.exception);
-                    } else {
-                        int ttyMode = phoneModeToTelecomMode(((int[]) ar.result)[0]);
-                        if (ttyMode != mTtyMode) {
-                            Log.d(TtyManager.this, "setting TTY mode failed, attempted %d, got: %d",
-                                    mTtyMode, ttyMode);
-                        } else {
-                            Log.d(TtyManager.this, "setting TTY mode to %d succeeded", ttyMode);
-                        }
-                    }
-                    break;
-                }
-            }
-        }
-    };
-
-    TtyManager(Context context, Phone phone) {
-        mPhone = phone;
-
-        IntentFilter intentFilter = new IntentFilter(
-                TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED);
-        intentFilter.addAction(TelecomManager.ACTION_TTY_PREFERRED_MODE_CHANGED);
-        context.registerReceiver(mReceiver, intentFilter);
-
-        int ttyMode = TelecomManager.TTY_MODE_OFF;
-        TelecomManager telecomManager = TelecomManager.from(context);
-        if (telecomManager != null) {
-            ttyMode = telecomManager.getCurrentTtyMode();
-        }
-        updateTtyMode(ttyMode);
-        //Get preferred TTY mode from data base as UI Tty mode is always user preferred Tty mode.
-        ttyMode = Settings.Secure.getInt(context.getContentResolver(),
-                Settings.Secure.PREFERRED_TTY_MODE, TelecomManager.TTY_MODE_OFF);
-        updateUiTtyMode(ttyMode);
-    }
-
-    private void updateTtyMode(int ttyMode) {
-        Log.v(this, "updateTtyMode %d -> %d", mTtyMode, ttyMode);
-        mTtyMode = ttyMode;
-        mPhone.setTTYMode(telecomModeToPhoneMode(ttyMode),
-                mHandler.obtainMessage(MSG_SET_TTY_MODE_RESPONSE));
-    }
-
-    private void updateUiTtyMode(int ttyMode) {
-        Log.i(this, "updateUiTtyMode %d -> %d", mUiTtyMode, ttyMode);
-        if(mUiTtyMode != ttyMode) {
-            mUiTtyMode = ttyMode;
-            mPhone.setUiTTYMode(telecomModeToPhoneMode(ttyMode), null);
-        } else {
-           Log.i(this, "ui tty mode didnt change");
-        }
-    }
-
-    private final class TtyBroadcastReceiver extends BroadcastReceiver {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            Log.v(TtyManager.this, "onReceive, action: %s", action);
-            if (action.equals(TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED)) {
-                int ttyMode = intent.getIntExtra(
-                        TelecomManager.EXTRA_CURRENT_TTY_MODE, TelecomManager.TTY_MODE_OFF);
-                updateTtyMode(ttyMode);
-            } else if (action.equals(TelecomManager.ACTION_TTY_PREFERRED_MODE_CHANGED)) {
-                int newPreferredTtyMode = intent.getIntExtra(
-                        TelecomManager.EXTRA_TTY_PREFERRED_MODE, TelecomManager.TTY_MODE_OFF);
-                updateUiTtyMode(newPreferredTtyMode);
-            }
-        }
-    }
-
-    private static int telecomModeToPhoneMode(int telecomMode) {
-        switch (telecomMode) {
-            // AT command only has 0 and 1, so mapping VCO
-            // and HCO to FULL
-            case TelecomManager.TTY_MODE_FULL:
-            case TelecomManager.TTY_MODE_VCO:
-            case TelecomManager.TTY_MODE_HCO:
-                return Phone.TTY_MODE_FULL;
-            default:
-                return Phone.TTY_MODE_OFF;
-        }
-    }
-
-    private static int phoneModeToTelecomMode(int phoneMode) {
-        switch (phoneMode) {
-            case Phone.TTY_MODE_FULL:
-                return TelecomManager.TTY_MODE_FULL;
-            case Phone.TTY_MODE_VCO:
-                return TelecomManager.TTY_MODE_VCO;
-            case Phone.TTY_MODE_HCO:
-                return TelecomManager.TTY_MODE_HCO;
-            case Phone.TTY_MODE_OFF:
-            default:
-                return TelecomManager.TTY_MODE_OFF;
-        }
-    }
-}