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;
- }
- }
-}