new class AudioRouter manages audio routing for the phone call
This CL only has support between bluetooth/earpiece
Of Note:
- New shared class AudioMode defines different modes for audio routing
- New class AudioRouter manages between EARPIECE and Bluetooth modes.
- Add function in CallCommandService and CallHandlerService for audio
mode
Change-Id: I52ff70e53868c45e5202b757cc80a13af3abe5f8
diff --git a/src/com/android/phone/AudioRouter.java b/src/com/android/phone/AudioRouter.java
new file mode 100644
index 0000000..2b8201c
--- /dev/null
+++ b/src/com/android/phone/AudioRouter.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2013 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.phone;
+
+import com.google.common.collect.Lists;
+
+import android.content.Context;
+import android.media.AudioManager;
+import android.os.SystemProperties;
+import android.util.Log;
+
+import com.android.phone.BluetoothManager.BluetoothIndicatorListener;
+import com.android.services.telephony.common.AudioMode;
+
+import java.util.List;
+
+/**
+ * Responsible for Routing in-call audio and maintaining routing state.
+ */
+/* package */ class AudioRouter implements BluetoothIndicatorListener {
+
+ private static String LOG_TAG = AudioRouter.class.getSimpleName();
+ private static final boolean DBG =
+ (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
+ private static final boolean VDBG = (PhoneGlobals.DBG_LEVEL >= 2);
+
+ private final Context mContext;
+ private final BluetoothManager mBluetoothManager;
+ private final List<AudioModeListener> mListeners = Lists.newArrayList();
+ private int mAudioMode = AudioMode.EARPIECE;
+ private int mPreviousMode = AudioMode.EARPIECE;
+
+ public AudioRouter(Context context, BluetoothManager bluetoothManager) {
+ mContext = context;
+ mBluetoothManager = bluetoothManager;
+
+ init();
+ }
+
+ /**
+ * Return the current audio mode.
+ */
+ public int getAudioMode() {
+ return mAudioMode;
+ }
+
+ /**
+ * Add a listener to audio mode changes.
+ */
+ public void addAudioModeListener(AudioModeListener listener) {
+ if (!mListeners.contains(listener)) {
+ mListeners.add(listener);
+ }
+ }
+
+ /**
+ * Remove listener.
+ */
+ public void removeAudioModeListener(AudioModeListener listener) {
+ if (mListeners.contains(listener)) {
+ mListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Sets the audio mode to the mode that is passed in.
+ */
+ public void setAudioMode(int mode) {
+ if (AudioMode.BLUETOOTH == mode) {
+
+ // dont set mAudioMode because we will get a notificaiton through
+ // onBluetoothIndicationChange if successful
+ toggleBluetooth(true);
+ } else if (AudioMode.EARPIECE == mode) {
+ toggleBluetooth(false);
+ }
+ }
+
+ /**
+ * Called when the bluetooth connection changes.
+ * We adjust the audio mode according to the state we receive.
+ */
+ @Override
+ public void onBluetoothIndicationChange(boolean isConnected, BluetoothManager btManager) {
+ int newMode = mAudioMode;
+
+ if (isConnected) {
+ newMode = AudioMode.BLUETOOTH;
+ } else {
+ newMode = AudioMode.EARPIECE;
+ }
+
+ changeAudioModeTo(newMode);
+ }
+
+ private void toggleBluetooth(boolean on) {
+ if (on) {
+ mBluetoothManager.connectBluetoothAudio();
+ } else {
+ mBluetoothManager.disconnectBluetoothAudio();
+ }
+ }
+
+ private void init() {
+ mBluetoothManager.addBluetoothIndicatorListener(this);
+ }
+
+ private void changeAudioModeTo(int mode) {
+ if (mAudioMode != mode) {
+ Log.i(LOG_TAG, "Audio mode changing to " + AudioMode.toString(mode));
+
+ mPreviousMode = mAudioMode;
+ mAudioMode = mode;
+
+ notifyListeners();
+ }
+ }
+
+ private void notifyListeners() {
+ for (int i = 0; i < mListeners.size(); i++) {
+ mListeners.get(i).onAudioModeChange(mPreviousMode, mAudioMode);
+ }
+ }
+
+ public interface AudioModeListener {
+ void onAudioModeChange(int previousMode, int newMode);
+ }
+}
diff --git a/src/com/android/phone/BluetoothManager.java b/src/com/android/phone/BluetoothManager.java
index a297472..8d20c25 100644
--- a/src/com/android/phone/BluetoothManager.java
+++ b/src/com/android/phone/BluetoothManager.java
@@ -221,12 +221,18 @@
notifyListeners(mShowBluetoothIndication);
}
- /* package */ void addBluetoothIndicatorListener(BluetoothIndicatorListener listener) {
+ public void addBluetoothIndicatorListener(BluetoothIndicatorListener listener) {
if (!mListeners.contains(listener)) {
mListeners.add(listener);
}
}
+ public void removeBluetoothIndicatorListener(BluetoothIndicatorListener listener) {
+ if (mListeners.contains(listener)) {
+ mListeners.remove(listener);
+ }
+ }
+
private void notifyListeners(boolean showBluetoothOn) {
for (int i = 0; i < mListeners.size(); i++) {
mListeners.get(i).onBluetoothIndicationChange(showBluetoothOn, this);
@@ -396,6 +402,6 @@
}
/* package */ interface BluetoothIndicatorListener {
- public void onBluetoothIndicationChange(boolean showAsConnected, BluetoothManager manager);
+ public void onBluetoothIndicationChange(boolean isConnected, BluetoothManager manager);
}
}
diff --git a/src/com/android/phone/CallCommandService.java b/src/com/android/phone/CallCommandService.java
index 560e78c..35c507a 100644
--- a/src/com/android/phone/CallCommandService.java
+++ b/src/com/android/phone/CallCommandService.java
@@ -21,6 +21,7 @@
import com.android.internal.telephony.CallManager;
import com.android.phone.CallModeler.CallResult;
+import com.android.services.telephony.common.AudioMode;
import com.android.services.telephony.common.Call;
import com.android.services.telephony.common.ICallCommandService;
@@ -36,13 +37,15 @@
private final CallManager mCallManager;
private final CallModeler mCallModeler;
private final DTMFTonePlayer mDtmfTonePlayer;
+ private final AudioRouter mAudioRouter;
public CallCommandService(Context context, CallManager callManager, CallModeler callModeler,
- DTMFTonePlayer dtmfTonePlayer) {
+ DTMFTonePlayer dtmfTonePlayer, AudioRouter audioRouter) {
mContext = context;
mCallManager = callManager;
mCallModeler = callModeler;
mDtmfTonePlayer = dtmfTonePlayer;
+ mAudioRouter = audioRouter;
}
/**
@@ -110,7 +113,8 @@
@Override
public void mute(boolean onOff) {
try {
- PhoneUtils.setMute(onOff);
+ //PhoneUtils.setMute(onOff);
+ mAudioRouter.setAudioMode(onOff ? AudioMode.BLUETOOTH : AudioMode.EARPIECE);
} catch (Exception e) {
Log.e(TAG, "Error during mute().", e);
}
@@ -143,4 +147,13 @@
Log.e(TAG, "Error stopping DTMF tone.", e);
}
}
+
+ @Override
+ public void setAudioMode(int mode) {
+ try {
+ mAudioRouter.setAudioMode(mode);
+ } catch (Exception e) {
+ Log.e(TAG, "Error setting the audio mode.", e);
+ }
+ }
}
diff --git a/src/com/android/phone/CallHandlerServiceProxy.java b/src/com/android/phone/CallHandlerServiceProxy.java
index b134310..2762c98 100644
--- a/src/com/android/phone/CallHandlerServiceProxy.java
+++ b/src/com/android/phone/CallHandlerServiceProxy.java
@@ -28,6 +28,8 @@
import android.os.SystemProperties;
import android.util.Log;
+import com.android.phone.AudioRouter.AudioModeListener;
+import com.android.services.telephony.common.AudioMode;
import com.android.services.telephony.common.Call;
import com.android.services.telephony.common.ICallHandlerService;
import com.android.services.telephony.common.ICallCommandService;
@@ -37,7 +39,8 @@
/**
* This class is responsible for passing through call state changes to the CallHandlerService.
*/
-public class CallHandlerServiceProxy extends Handler implements CallModeler.Listener {
+public class CallHandlerServiceProxy extends Handler implements CallModeler.Listener,
+ AudioModeListener {
private static final String TAG = CallHandlerServiceProxy.class.getSimpleName();
private static final boolean DBG =
@@ -85,6 +88,21 @@
}
}
+ @Override
+ public void onAudioModeChange(int previousMode, int newMode) {
+ // Just do a simple log for now.
+ Log.i(TAG, "Updating with new audio mode: " + AudioMode.toString(newMode) +
+ " from " + AudioMode.toString(previousMode));
+
+ if (mCallHandlerService != null) {
+ try {
+ mCallHandlerService.onAudioModeChange(newMode);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Remote exception handling onAudioModeChange", e);
+ }
+ }
+ }
+
/**
* Sets up the connection with ICallHandlerService
*/
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index 9db596b..914db15 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -169,6 +169,7 @@
Phone phone;
PhoneInterfaceManager phoneMgr;
+ private AudioRouter audioRouter;
private BluetoothManager bluetoothManager;
private CallCommandService callCommandService;
private CallHandlerServiceProxy callHandlerServiceProxy;
@@ -550,8 +551,12 @@
// Plays DTMF Tones
dtmfTonePlayer = new DTMFTonePlayer(mCM, callModeler);
+ // Audio router
+ audioRouter = new AudioRouter(this, bluetoothManager);
+
// Service used by in-call UI to control calls
- callCommandService = new CallCommandService(this, mCM, callModeler, dtmfTonePlayer);
+ callCommandService = new CallCommandService(this, mCM, callModeler, dtmfTonePlayer,
+ audioRouter);
// Sends call state to the UI
callHandlerServiceProxy = new CallHandlerServiceProxy(this, callModeler,