Merge "TTY: Telecomm" into lmp-dev
diff --git a/res/values/config.xml b/res/values/config.xml
index d3e253c..365e758 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -35,4 +35,7 @@
<!-- Class name for the default main dialer activity [DO NOT TRANSLATE] -->
<string name="dialer_default_class" translatable="false">com.android.dialer.DialtactsActivity</string>
+
+ <!-- Flag indicating if the tty is enabled -->
+ <bool name="tty_enabled">false</bool>
</resources>
diff --git a/src/com/android/telecomm/CallAudioManager.java b/src/com/android/telecomm/CallAudioManager.java
index 8156db0..e9008f8 100644
--- a/src/com/android/telecomm/CallAudioManager.java
+++ b/src/com/android/telecomm/CallAudioManager.java
@@ -26,13 +26,14 @@
/**
* This class manages audio modes, streams and other properties.
*/
-final class CallAudioManager extends CallsManagerListenerBase {
+final class CallAudioManager extends CallsManagerListenerBase
+ implements WiredHeadsetManager.Listener {
private static final int STREAM_NONE = -1;
private final StatusBarNotifier mStatusBarNotifier;
private final AudioManager mAudioManager;
- private final WiredHeadsetManager mWiredHeadsetManager;
private final BluetoothManager mBluetoothManager;
+ private final WiredHeadsetManager mWiredHeadsetManager;
private CallAudioState mAudioState;
private int mAudioFocusStreamType;
@@ -40,11 +41,13 @@
private boolean mIsTonePlaying;
private boolean mWasSpeakerOn;
- CallAudioManager(Context context, StatusBarNotifier statusBarNotifier) {
+ CallAudioManager(Context context, StatusBarNotifier statusBarNotifier,
+ WiredHeadsetManager wiredHeadsetManager) {
mStatusBarNotifier = statusBarNotifier;
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
- mWiredHeadsetManager = new WiredHeadsetManager(this);
mBluetoothManager = new BluetoothManager(context, this);
+ mWiredHeadsetManager = wiredHeadsetManager;
+
saveAudioState(getInitialAudioState(null));
mAudioFocusStreamType = STREAM_NONE;
}
@@ -107,6 +110,25 @@
updateAudioStreamAndMode();
}
+ /**
+ * Updates the audio route when the headset plugged in state changes. For example, if audio is
+ * being routed over speakerphone and a headset is plugged in then switch to wired headset.
+ */
+ @Override
+ public void onWiredHeadsetPluggedInChanged(boolean oldIsPluggedIn, boolean newIsPluggedIn) {
+ int newRoute = CallAudioState.ROUTE_EARPIECE;
+ if (newIsPluggedIn) {
+ newRoute = CallAudioState.ROUTE_WIRED_HEADSET;
+ } else if (mWasSpeakerOn) {
+ Call call = getForegroundCall();
+ if (call != null && call.isAlive()) {
+ // Restore the speaker state.
+ newRoute = CallAudioState.ROUTE_SPEAKER;
+ }
+ }
+ setSystemAudioState(mAudioState.isMuted, newRoute, calculateSupportedRoutes());
+ }
+
void toggleMute() {
mute(!mAudioState.isMuted);
}
@@ -176,24 +198,6 @@
}
/**
- * Updates the audio route when the headset plugged in state changes. For example, if audio is
- * being routed over speakerphone and a headset is plugged in then switch to wired headset.
- */
- void onHeadsetPluggedInChanged(boolean oldIsPluggedIn, boolean newIsPluggedIn) {
- int newRoute = CallAudioState.ROUTE_EARPIECE;
- if (newIsPluggedIn) {
- newRoute = CallAudioState.ROUTE_WIRED_HEADSET;
- } else if (mWasSpeakerOn) {
- Call call = getForegroundCall();
- if (call != null && call.isAlive()) {
- // Restore the speaker state.
- newRoute = CallAudioState.ROUTE_SPEAKER;
- }
- }
- setSystemAudioState(mAudioState.isMuted, newRoute, calculateSupportedRoutes());
- }
-
- /**
* Updates the audio routing according to the bluetooth state.
*/
void onBluetoothStateChange(BluetoothManager bluetoothManager) {
diff --git a/src/com/android/telecomm/CallsManager.java b/src/com/android/telecomm/CallsManager.java
index fee41ad..36f8cea 100644
--- a/src/com/android/telecomm/CallsManager.java
+++ b/src/com/android/telecomm/CallsManager.java
@@ -76,6 +76,8 @@
private final Ringer mRinger;
private final Set<CallsManagerListener> mListeners = new HashSet<>();
private final HeadsetMediaButton mHeadsetMediaButton;
+ private final WiredHeadsetManager mWiredHeadsetManager;
+ private final TtyManager mTtyManager;
/**
* The call the user is currently interacting with. This is the call that should have audio
@@ -95,10 +97,12 @@
TelecommApp app = TelecommApp.getInstance();
StatusBarNotifier statusBarNotifier = new StatusBarNotifier(app, this);
- mCallAudioManager = new CallAudioManager(app, statusBarNotifier);
+ mWiredHeadsetManager = new WiredHeadsetManager(app);
+ mCallAudioManager = new CallAudioManager(app, statusBarNotifier, mWiredHeadsetManager);
InCallTonePlayer.Factory playerFactory = new InCallTonePlayer.Factory(mCallAudioManager);
mRinger = new Ringer(mCallAudioManager, this, playerFactory, app);
mHeadsetMediaButton = new HeadsetMediaButton(app, this);
+ mTtyManager = new TtyManager(app, mWiredHeadsetManager);
mListeners.add(statusBarNotifier);
mListeners.add(new CallLogManager(app));
@@ -239,6 +243,14 @@
return mCallAudioManager.getAudioState();
}
+ boolean isTtySupported() {
+ return mTtyManager.isTtySupported();
+ }
+
+ int getCurrentTtyMode() {
+ return mTtyManager.getCurrentTtyMode();
+ }
+
/**
* Starts the process to attach the call to a connection service.
*
diff --git a/src/com/android/telecomm/HeadsetMediaButton.java b/src/com/android/telecomm/HeadsetMediaButton.java
index 65c45df..70af0fd 100644
--- a/src/com/android/telecomm/HeadsetMediaButton.java
+++ b/src/com/android/telecomm/HeadsetMediaButton.java
@@ -16,7 +16,6 @@
package com.android.telecomm;
-import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
diff --git a/src/com/android/telecomm/TelecommServiceImpl.java b/src/com/android/telecomm/TelecommServiceImpl.java
index 9bf4987..509307b 100644
--- a/src/com/android/telecomm/TelecommServiceImpl.java
+++ b/src/com/android/telecomm/TelecommServiceImpl.java
@@ -80,6 +80,12 @@
case MSG_CANCEL_MISSED_CALLS_NOTIFICATION:
mMissedCallNotifier.clearMissedCalls();
break;
+ case MSG_IS_TTY_SUPPORTED:
+ result = mCallsManager.isTtySupported();
+ break;
+ case MSG_GET_CURRENT_TTY_MODE:
+ result = mCallsManager.getCurrentTtyMode();
+ break;
}
if (result != null) {
@@ -102,6 +108,8 @@
private static final int MSG_END_CALL = 3;
private static final int MSG_ACCEPT_RINGING_CALL = 4;
private static final int MSG_CANCEL_MISSED_CALLS_NOTIFICATION = 5;
+ private static final int MSG_IS_TTY_SUPPORTED = 6;
+ private static final int MSG_GET_CURRENT_TTY_MODE = 7;
/** The singleton instance. */
private static TelecommServiceImpl sInstance;
@@ -320,6 +328,24 @@
return retval;
}
+ /**
+ * @see TelecommManager#isTtySupported
+ */
+ @Override
+ public boolean isTtySupported() {
+ enforceReadPermission();
+ return (boolean) sendRequest(MSG_IS_TTY_SUPPORTED);
+ }
+
+ /**
+ * @see TelecommManager#getCurrentTtyMode
+ */
+ @Override
+ public int getCurrentTtyMode() {
+ enforceReadPermission();
+ return (int) sendRequest(MSG_GET_CURRENT_TTY_MODE);
+ }
+
//
// Supporting methods for the ITelecommService interface implementation.
//
diff --git a/src/com/android/telecomm/TtyManager.java b/src/com/android/telecomm/TtyManager.java
new file mode 100644
index 0000000..c94cd30
--- /dev/null
+++ b/src/com/android/telecomm/TtyManager.java
@@ -0,0 +1,123 @@
+/*
+ * 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.telecomm;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.media.AudioManager;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.telecomm.TelecommConstants;
+
+final class TtyManager implements WiredHeadsetManager.Listener {
+ private final TtyBroadcastReceiver mReceiver = new TtyBroadcastReceiver();
+ private final Context mContext;
+ private final WiredHeadsetManager mWiredHeadsetManager;
+ private int mPreferredTtyMode = TelecommConstants.TTY_MODE_OFF;
+ private int mCurrentTtyMode = TelecommConstants.TTY_MODE_OFF;
+
+ TtyManager(Context context, WiredHeadsetManager wiredHeadsetManager) {
+ mContext = context;
+ mWiredHeadsetManager = wiredHeadsetManager;
+ mWiredHeadsetManager.addListener(this);
+
+ mPreferredTtyMode = Settings.Secure.getInt(
+ mContext.getContentResolver(),
+ Settings.Secure.PREFERRED_TTY_MODE,
+ TelecommConstants.TTY_MODE_OFF);
+
+ IntentFilter intentFilter = new IntentFilter(
+ TelecommConstants.ACTION_TTY_PREFERRED_MODE_CHANGED);
+ mContext.registerReceiver(mReceiver, intentFilter);
+
+ updateCurrentTtyMode();
+ }
+
+ boolean isTtySupported() {
+ boolean isEnabled = mContext.getResources().getBoolean(R.bool.tty_enabled);
+ Log.v(this, "isTtySupported: " + isEnabled);
+ return isEnabled;
+ }
+
+ int getCurrentTtyMode() {
+ return mCurrentTtyMode;
+ }
+
+ @Override
+ public void onWiredHeadsetPluggedInChanged(boolean oldIsPluggedIn, boolean newIsPluggedIn) {
+ Log.v(this, "onWiredHeadsetPluggedInChanged");
+ updateCurrentTtyMode();
+ }
+
+ private void updateCurrentTtyMode() {
+ int newTtyMode = TelecommConstants.TTY_MODE_OFF;
+ if (isTtySupported() && mWiredHeadsetManager.isPluggedIn()) {
+ newTtyMode = mPreferredTtyMode;
+ }
+ Log.v(this, "updateCurrentTtyMode, %d -> %d", mCurrentTtyMode, newTtyMode);
+
+ if (mCurrentTtyMode != newTtyMode) {
+ mCurrentTtyMode = newTtyMode;
+ Intent ttyModeChanged = new Intent(TelecommConstants.ACTION_CURRENT_TTY_MODE_CHANGED);
+ ttyModeChanged.putExtra(TelecommConstants.EXTRA_CURRENT_TTY_MODE, mCurrentTtyMode);
+ mContext.sendBroadcastAsUser(ttyModeChanged, UserHandle.ALL);
+
+ updateAudioTtyMode();
+ }
+ }
+
+ private void updateAudioTtyMode() {
+ String audioTtyMode;
+ switch (mCurrentTtyMode) {
+ case TelecommConstants.TTY_MODE_FULL:
+ audioTtyMode = "tty_full";
+ break;
+ case TelecommConstants.TTY_MODE_VCO:
+ audioTtyMode = "tty_vco";
+ break;
+ case TelecommConstants.TTY_MODE_HCO:
+ audioTtyMode = "tty_hco";
+ break;
+ case TelecommConstants.TTY_MODE_OFF:
+ default:
+ audioTtyMode = "tty_off";
+ break;
+ }
+ Log.v(this, "updateAudioTtyMode, %s", audioTtyMode);
+
+ AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+ audioManager.setParameters("tty_mode=" + audioTtyMode);
+ }
+
+ 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(TelecommConstants.ACTION_TTY_PREFERRED_MODE_CHANGED)) {
+ int newPreferredTtyMode = intent.getIntExtra(
+ TelecommConstants.EXTRA_TTY_PREFERRED_MODE, TelecommConstants.TTY_MODE_OFF);
+ if (mPreferredTtyMode != newPreferredTtyMode) {
+ mPreferredTtyMode = newPreferredTtyMode;
+ updateCurrentTtyMode();
+ }
+ }
+ }
+ }
+}
diff --git a/src/com/android/telecomm/WiredHeadsetManager.java b/src/com/android/telecomm/WiredHeadsetManager.java
index 329df71..e59f1a5 100644
--- a/src/com/android/telecomm/WiredHeadsetManager.java
+++ b/src/com/android/telecomm/WiredHeadsetManager.java
@@ -22,12 +22,14 @@
import android.content.IntentFilter;
import android.media.AudioManager;
-/**
- * Listens for and caches headset state. Used By the CallAudioManger for maintaining
- * overall audio state for use in the UI layer. Also provides method for connecting the bluetooth
- * headset to the phone call.
- */
+import java.util.HashSet;
+
+/** Listens for and caches headset state. */
class WiredHeadsetManager {
+ interface Listener {
+ void onWiredHeadsetPluggedInChanged(boolean oldIsPluggedIn, boolean newIsPluggedIn);
+ }
+
/** Receiver for wired headset plugged and unplugged events. */
private class WiredHeadsetBroadcastReceiver extends BroadcastReceiver {
@Override
@@ -41,15 +43,13 @@
}
}
- private final CallAudioManager mCallAudioManager;
private final WiredHeadsetBroadcastReceiver mReceiver;
private boolean mIsPluggedIn;
+ private final HashSet<Listener> mListeners = new HashSet<>();
- WiredHeadsetManager(CallAudioManager callAudioManager) {
- mCallAudioManager = callAudioManager;
+ WiredHeadsetManager(Context context) {
mReceiver = new WiredHeadsetBroadcastReceiver();
- Context context = TelecommApp.getInstance();
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
mIsPluggedIn = audioManager.isWiredHeadsetOn();
@@ -58,6 +58,14 @@
context.registerReceiver(mReceiver, intentFilter);
}
+ void addListener(Listener listener) {
+ mListeners.add(listener);
+ }
+
+ void removeListener(Listener listener) {
+ mListeners.remove(listener);
+ }
+
boolean isPluggedIn() {
return mIsPluggedIn;
}
@@ -68,7 +76,9 @@
isPluggedIn);
boolean oldIsPluggedIn = mIsPluggedIn;
mIsPluggedIn = isPluggedIn;
- mCallAudioManager.onHeadsetPluggedInChanged(oldIsPluggedIn, mIsPluggedIn);
+ for (Listener listener : mListeners) {
+ listener.onWiredHeadsetPluggedInChanged(oldIsPluggedIn, mIsPluggedIn);
+ }
}
}
}