Add call waiting to Ringer.java.
When an incoming call is in the background, play call waiting instead of
ringer.
Bug: 13674415
Change-Id: I9d450202774c6890794fa318fdab01290b4a7eb2
diff --git a/src/com/android/telecomm/Ringer.java b/src/com/android/telecomm/Ringer.java
index fdc9349..f298081 100644
--- a/src/com/android/telecomm/Ringer.java
+++ b/src/com/android/telecomm/Ringer.java
@@ -49,17 +49,29 @@
private final List<Call> mUnansweredCalls = Lists.newLinkedList();
private final CallAudioManager mCallAudioManager;
-
+ private final CallsManager mCallsManager;
+ private final InCallTonePlayer.Factory mPlayerFactory;
+ private final Context mContext;
private final Vibrator mVibrator;
+ private InCallTonePlayer mCallWaitingPlayer;
+
/**
* Used to track the status of {@link #mVibrator} in the case of simultaneous incoming calls.
*/
private boolean mIsVibrating = false;
- Ringer(CallAudioManager callAudioManager) {
- mCallAudioManager = callAudioManager;
+ /** Initializes the Ringer. */
+ Ringer(
+ CallAudioManager callAudioManager,
+ CallsManager callsManager,
+ InCallTonePlayer.Factory playerFactory,
+ Context context) {
+ mCallAudioManager = callAudioManager;
+ mCallsManager = callsManager;
+ mPlayerFactory = playerFactory;
+ mContext = context;
// We don't rely on getSystemService(Context.VIBRATOR_SERVICE) to make sure this
// vibrator object will be isolated from others.
mVibrator = new SystemVibrator(TelecommApp.getInstance());
@@ -72,14 +84,11 @@
Log.wtf(this, "New ringing call is already in list of unanswered calls");
}
mUnansweredCalls.add(call);
- if (mUnansweredCalls.size() == 1) {
- // Start the ringer if we are the top-most incoming call (the only one in this
- // case).
- startRinging();
- }
+ updateRinging();
}
}
+
@Override
public void onCallRemoved(Call call) {
removeFromUnansweredCall(call);
@@ -102,11 +111,27 @@
onRespondedToIncomingCall(call);
}
+ @Override
+ public void onForegroundCallChanged(Call oldForegroundCall, Call newForegroundCall) {
+ if (mUnansweredCalls.contains(oldForegroundCall) ||
+ mUnansweredCalls.contains(newForegroundCall)) {
+ updateRinging();
+ }
+ }
+
private void onRespondedToIncomingCall(Call call) {
// Only stop the ringer if this call is the top-most incoming call.
- if (!mUnansweredCalls.isEmpty() && mUnansweredCalls.get(0) == call) {
+ if (getTopMostUnansweredCall() == call) {
stopRinging();
+ stopCallWaiting();
}
+
+ // We do not remove the call from mUnansweredCalls until the call state changes from RINGING
+ // or the call is removed. see onCallStateChanged or onCallRemoved.
+ }
+
+ private Call getTopMostUnansweredCall() {
+ return mUnansweredCalls.isEmpty() ? null : mUnansweredCalls.get(0);
}
/**
@@ -115,44 +140,78 @@
* present in the list of incoming calls.
*/
private void removeFromUnansweredCall(Call call) {
- if (mUnansweredCalls.remove(call)) {
- if (mUnansweredCalls.isEmpty()) {
- stopRinging();
- } else {
- startRinging();
- }
+ mUnansweredCalls.remove(call);
+ updateRinging();
+ }
+
+ private void updateRinging() {
+ if (mUnansweredCalls.isEmpty()) {
+ stopRinging();
+ stopCallWaiting();
+ } else {
+ startRingingOrCallWaiting();
}
}
- private void startRinging() {
- AudioManager audioManager = (AudioManager) TelecommApp.getInstance().getSystemService(
- Context.AUDIO_SERVICE);
- if (audioManager.getStreamVolume(AudioManager.STREAM_RING) > 0) {
- Log.v(this, "startRinging");
- mCallAudioManager.setIsRinging(true);
- mRingtonePlayer.play();
- } else {
- Log.v(this, "startRinging, skipping because volume is 0");
- }
+ private void startRingingOrCallWaiting() {
+ Call foregroundCall = mCallsManager.getForegroundCall();
+ Log.v(this, "startRingingOrCallWaiting, foregroundCall: %s.", foregroundCall);
- if (shouldVibrate(TelecommApp.getInstance()) && !mIsVibrating) {
- mVibrator.vibrate(VIBRATION_PATTERN, VIBRATION_PATTERN_REPEAT,
- AudioManager.STREAM_RING);
- mIsVibrating = true;
+ if (mUnansweredCalls.contains(foregroundCall)) {
+ // The foreground call is one of incoming calls so play the ringer out loud.
+ stopCallWaiting();
+
+ AudioManager audioManager =
+ (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+ if (audioManager.getStreamVolume(AudioManager.STREAM_RING) > 0) {
+ Log.v(this, "startRingingOrCallWaiting");
+ mCallAudioManager.setIsRinging(true);
+
+ mRingtonePlayer.play();
+
+ if (shouldVibrate(TelecommApp.getInstance()) && !mIsVibrating) {
+ mVibrator.vibrate(VIBRATION_PATTERN, VIBRATION_PATTERN_REPEAT,
+ AudioManager.STREAM_RING);
+ mIsVibrating = true;
+ }
+ } else {
+ Log.v(this, "startRingingOrCallWaiting, skipping because volume is 0");
+ }
+ } else {
+ Log.v(this, "Playing call-waiting tone.");
+
+ // All incoming calls are in background so play call waiting.
+ stopRinging();
+
+ if (mCallWaitingPlayer == null) {
+ mCallWaitingPlayer =
+ mPlayerFactory.createPlayer(InCallTonePlayer.TONE_CALL_WAITING);
+ mCallWaitingPlayer.startTone();
+ }
}
}
private void stopRinging() {
Log.v(this, "stopRinging");
+
mRingtonePlayer.stop();
- // Even though stop is asynchronous it's ok to update the audio manager. Things like audio
- // focus are voluntary so releasing focus too early is not detrimental.
- mCallAudioManager.setIsRinging(false);
if (mIsVibrating) {
mVibrator.cancel();
mIsVibrating = false;
}
+
+ // Even though stop is asynchronous it's ok to update the audio manager. Things like audio
+ // focus are voluntary so releasing focus too early is not detrimental.
+ mCallAudioManager.setIsRinging(false);
+ }
+
+ private void stopCallWaiting() {
+ Log.v(this, "stop call waiting.");
+ if (mCallWaitingPlayer != null) {
+ mCallWaitingPlayer.stopTone();
+ mCallWaitingPlayer = null;
+ }
}
private boolean shouldVibrate(Context context) {