blob: e53de84f483bc0c96e98a7aa114d2d1b1b667284 [file] [log] [blame]
Sailesh Nepal810735e2014-03-18 18:15:46 -07001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.telecomm;
18
19import android.content.Context;
20import android.media.AudioManager;
Sailesh Nepal6aca10a2014-03-24 16:11:02 -070021import android.telecomm.CallAudioState;
Sailesh Nepal810735e2014-03-18 18:15:46 -070022import android.telecomm.CallState;
23
Sailesh Nepal6aca10a2014-03-24 16:11:02 -070024import com.google.common.base.Preconditions;
Santos Cordon1ae2b852014-03-19 03:03:10 -070025
Sailesh Nepal810735e2014-03-18 18:15:46 -070026/**
27 * This class manages audio modes, streams and other properties.
28 */
Sailesh Nepalb88795a2014-07-15 14:53:27 -070029final class CallAudioManager extends CallsManagerListenerBase
30 implements WiredHeadsetManager.Listener {
Sailesh Nepal6aca10a2014-03-24 16:11:02 -070031 private static final int STREAM_NONE = -1;
Santos Cordon1ae2b852014-03-19 03:03:10 -070032
Santos Cordondeb8c892014-05-30 01:38:03 -070033 private final StatusBarNotifier mStatusBarNotifier;
Sailesh Nepal6aca10a2014-03-24 16:11:02 -070034 private final AudioManager mAudioManager;
Santos Cordonc7e85d42014-05-22 02:51:48 -070035 private final BluetoothManager mBluetoothManager;
Sailesh Nepalb88795a2014-07-15 14:53:27 -070036 private final WiredHeadsetManager mWiredHeadsetManager;
Santos Cordondeb8c892014-05-30 01:38:03 -070037
Sailesh Nepal6aca10a2014-03-24 16:11:02 -070038 private CallAudioState mAudioState;
39 private int mAudioFocusStreamType;
40 private boolean mIsRinging;
Santos Cordona56f2762014-03-24 15:55:53 -070041 private boolean mIsTonePlaying;
Sailesh Nepal6aca10a2014-03-24 16:11:02 -070042 private boolean mWasSpeakerOn;
Santos Cordon1ae2b852014-03-19 03:03:10 -070043
Sailesh Nepalb88795a2014-07-15 14:53:27 -070044 CallAudioManager(Context context, StatusBarNotifier statusBarNotifier,
45 WiredHeadsetManager wiredHeadsetManager) {
Santos Cordondeb8c892014-05-30 01:38:03 -070046 mStatusBarNotifier = statusBarNotifier;
Sailesh Nepal6aca10a2014-03-24 16:11:02 -070047 mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
Santos Cordonc7e85d42014-05-22 02:51:48 -070048 mBluetoothManager = new BluetoothManager(context, this);
Sailesh Nepalb88795a2014-07-15 14:53:27 -070049 mWiredHeadsetManager = wiredHeadsetManager;
Sailesh Nepald0a76aa2014-07-16 22:12:23 -070050 mWiredHeadsetManager.addListener(this);
Sailesh Nepalb88795a2014-07-15 14:53:27 -070051
Santos Cordondeb8c892014-05-30 01:38:03 -070052 saveAudioState(getInitialAudioState(null));
Sailesh Nepal6aca10a2014-03-24 16:11:02 -070053 mAudioFocusStreamType = STREAM_NONE;
54 }
Santos Cordon1ae2b852014-03-19 03:03:10 -070055
Sailesh Nepal6aca10a2014-03-24 16:11:02 -070056 CallAudioState getAudioState() {
57 return mAudioState;
58 }
Santos Cordon1ae2b852014-03-19 03:03:10 -070059
60 @Override
61 public void onCallAdded(Call call) {
Sailesh Nepal6aca10a2014-03-24 16:11:02 -070062 updateAudioStreamAndMode();
63 if (CallsManager.getInstance().getCalls().size() == 1) {
64 Log.v(this, "first call added, reseting system audio to default state");
Santos Cordonc7e85d42014-05-22 02:51:48 -070065 setInitialAudioState(call);
Sailesh Nepal6aca10a2014-03-24 16:11:02 -070066 } else if (!call.isIncoming()) {
67 // Unmute new outgoing call.
68 setSystemAudioState(false, mAudioState.route, mAudioState.supportedRouteMask);
Santos Cordon1ae2b852014-03-19 03:03:10 -070069 }
Santos Cordon1ae2b852014-03-19 03:03:10 -070070 }
71
72 @Override
73 public void onCallRemoved(Call call) {
Sailesh Nepal6aca10a2014-03-24 16:11:02 -070074 if (CallsManager.getInstance().getCalls().isEmpty()) {
75 Log.v(this, "all calls removed, reseting system audio to default state");
Santos Cordonc7e85d42014-05-22 02:51:48 -070076 setInitialAudioState(null);
Santos Cordona343b762014-08-06 05:01:53 -070077 mWasSpeakerOn = false;
Sailesh Nepal6aca10a2014-03-24 16:11:02 -070078 }
79 updateAudioStreamAndMode();
Santos Cordon1ae2b852014-03-19 03:03:10 -070080 }
81
Sailesh Nepal810735e2014-03-18 18:15:46 -070082 @Override
83 public void onCallStateChanged(Call call, CallState oldState, CallState newState) {
Sailesh Nepal6aca10a2014-03-24 16:11:02 -070084 updateAudioStreamAndMode();
Santos Cordon1ae2b852014-03-19 03:03:10 -070085 }
86
87 @Override
88 public void onIncomingCallAnswered(Call call) {
Santos Cordonc7e85d42014-05-22 02:51:48 -070089 int route = mAudioState.route;
90
91 // We do two things:
92 // (1) If this is the first call, then we can to turn on bluetooth if available.
93 // (2) Unmute the audio for the new incoming call.
94 boolean isOnlyCall = CallsManager.getInstance().getCalls().size() == 1;
95 if (isOnlyCall && mBluetoothManager.isBluetoothAvailable()) {
96 mBluetoothManager.connectBluetoothAudio();
97 route = CallAudioState.ROUTE_BLUETOOTH;
98 }
99
100 setSystemAudioState(false /* isMute */, route, mAudioState.supportedRouteMask);
Santos Cordon1ae2b852014-03-19 03:03:10 -0700101 }
102
103 @Override
Sailesh Nepal6aca10a2014-03-24 16:11:02 -0700104 public void onForegroundCallChanged(Call oldForegroundCall, Call newForegroundCall) {
105 updateAudioStreamAndMode();
106 // Ensure that the foreground call knows about the latest audio state.
107 updateAudioForForegroundCall();
Santos Cordon1ae2b852014-03-19 03:03:10 -0700108 }
109
Sailesh Nepal7e669572014-07-08 21:29:12 -0700110 @Override
111 public void onAudioModeIsVoipChanged(Call call) {
112 updateAudioStreamAndMode();
113 }
114
Sailesh Nepalb88795a2014-07-15 14:53:27 -0700115 /**
116 * Updates the audio route when the headset plugged in state changes. For example, if audio is
117 * being routed over speakerphone and a headset is plugged in then switch to wired headset.
118 */
119 @Override
120 public void onWiredHeadsetPluggedInChanged(boolean oldIsPluggedIn, boolean newIsPluggedIn) {
121 int newRoute = CallAudioState.ROUTE_EARPIECE;
122 if (newIsPluggedIn) {
123 newRoute = CallAudioState.ROUTE_WIRED_HEADSET;
124 } else if (mWasSpeakerOn) {
125 Call call = getForegroundCall();
126 if (call != null && call.isAlive()) {
127 // Restore the speaker state.
128 newRoute = CallAudioState.ROUTE_SPEAKER;
129 }
130 }
131 setSystemAudioState(mAudioState.isMuted, newRoute, calculateSupportedRoutes());
132 }
133
Santos Cordondeb8c892014-05-30 01:38:03 -0700134 void toggleMute() {
135 mute(!mAudioState.isMuted);
136 }
137
Sailesh Nepal6aca10a2014-03-24 16:11:02 -0700138 void mute(boolean shouldMute) {
139 Log.v(this, "mute, shouldMute: %b", shouldMute);
Santos Cordon1ae2b852014-03-19 03:03:10 -0700140
Sailesh Nepal6aca10a2014-03-24 16:11:02 -0700141 // Don't mute if there are any emergency calls.
142 if (CallsManager.getInstance().hasEmergencyCall()) {
143 shouldMute = false;
144 Log.v(this, "ignoring mute for emergency call");
Santos Cordon1ae2b852014-03-19 03:03:10 -0700145 }
146
Sailesh Nepal6aca10a2014-03-24 16:11:02 -0700147 if (mAudioState.isMuted != shouldMute) {
148 setSystemAudioState(shouldMute, mAudioState.route, mAudioState.supportedRouteMask);
Sailesh Nepal810735e2014-03-18 18:15:46 -0700149 }
150 }
151
Santos Cordon1ae2b852014-03-19 03:03:10 -0700152 /**
Sailesh Nepal6aca10a2014-03-24 16:11:02 -0700153 * Changed the audio route, for example from earpiece to speaker phone.
Santos Cordon1ae2b852014-03-19 03:03:10 -0700154 *
Sailesh Nepal6aca10a2014-03-24 16:11:02 -0700155 * @param route The new audio route to use. See {@link CallAudioState}.
Santos Cordon1ae2b852014-03-19 03:03:10 -0700156 */
Sailesh Nepal6aca10a2014-03-24 16:11:02 -0700157 void setAudioRoute(int route) {
158 Log.v(this, "setAudioRoute, route: %s", CallAudioState.audioRouteToString(route));
Santos Cordon1ae2b852014-03-19 03:03:10 -0700159
Sailesh Nepal6aca10a2014-03-24 16:11:02 -0700160 // Change ROUTE_WIRED_OR_EARPIECE to a single entry.
161 int newRoute = selectWiredOrEarpiece(route, mAudioState.supportedRouteMask);
162
163 // If route is unsupported, do nothing.
164 if ((mAudioState.supportedRouteMask | newRoute) == 0) {
165 Log.wtf(this, "Asking to set to a route that is unsupported: %d", newRoute);
166 return;
167 }
168
169 if (mAudioState.route != newRoute) {
170 // Remember the new speaker state so it can be restored when the user plugs and unplugs
171 // a headset.
172 mWasSpeakerOn = newRoute == CallAudioState.ROUTE_SPEAKER;
173 setSystemAudioState(mAudioState.isMuted, newRoute, mAudioState.supportedRouteMask);
174 }
175 }
176
177 void setIsRinging(boolean isRinging) {
178 if (mIsRinging != isRinging) {
179 Log.v(this, "setIsRinging %b -> %b", mIsRinging, isRinging);
180 mIsRinging = isRinging;
181 updateAudioStreamAndMode();
Santos Cordon1ae2b852014-03-19 03:03:10 -0700182 }
Sailesh Nepal810735e2014-03-18 18:15:46 -0700183 }
184
Santos Cordon1ae2b852014-03-19 03:03:10 -0700185 /**
Santos Cordona56f2762014-03-24 15:55:53 -0700186 * Sets the tone playing status. Some tones can play even when there are no live calls and this
187 * status indicates that we should keep audio focus even for tones that play beyond the life of
188 * calls.
189 *
190 * @param isPlayingNew The status to set.
191 */
192 void setIsTonePlaying(boolean isPlayingNew) {
193 ThreadUtil.checkOnMainThread();
194
195 if (mIsTonePlaying != isPlayingNew) {
196 Log.v(this, "mIsTonePlaying %b -> %b.", mIsTonePlaying, isPlayingNew);
197 mIsTonePlaying = isPlayingNew;
198 updateAudioStreamAndMode();
199 }
200 }
201
202 /**
Santos Cordonc7e85d42014-05-22 02:51:48 -0700203 * Updates the audio routing according to the bluetooth state.
204 */
205 void onBluetoothStateChange(BluetoothManager bluetoothManager) {
206 int newRoute = mAudioState.route;
207 if (bluetoothManager.isBluetoothAudioConnectedOrPending()) {
208 newRoute = CallAudioState.ROUTE_BLUETOOTH;
209 } else if (mAudioState.route == CallAudioState.ROUTE_BLUETOOTH) {
210 newRoute = CallAudioState.ROUTE_WIRED_OR_EARPIECE;
211 // Do not switch to speaker when bluetooth disconnects.
212 mWasSpeakerOn = false;
213 }
214
215 setSystemAudioState(mAudioState.isMuted, newRoute, calculateSupportedRoutes());
216 }
217
218 boolean isBluetoothAudioOn() {
219 return mBluetoothManager.isBluetoothAudioConnected();
220 }
221
222 boolean isBluetoothDeviceAvailable() {
223 return mBluetoothManager.isBluetoothAvailable();
224 }
225
Santos Cordondeb8c892014-05-30 01:38:03 -0700226 private void saveAudioState(CallAudioState audioState) {
227 mAudioState = audioState;
228 mStatusBarNotifier.notifyMute(mAudioState.isMuted);
229 mStatusBarNotifier.notifySpeakerphone(mAudioState.route == CallAudioState.ROUTE_SPEAKER);
230 }
231
Sailesh Nepal6aca10a2014-03-24 16:11:02 -0700232 private void setSystemAudioState(boolean isMuted, int route, int supportedRouteMask) {
233 CallAudioState oldAudioState = mAudioState;
Santos Cordondeb8c892014-05-30 01:38:03 -0700234 saveAudioState(new CallAudioState(isMuted, route, supportedRouteMask));
Sailesh Nepal6aca10a2014-03-24 16:11:02 -0700235 Log.i(this, "changing audio state from %s to %s", oldAudioState, mAudioState);
Santos Cordon1ae2b852014-03-19 03:03:10 -0700236
Sailesh Nepal6aca10a2014-03-24 16:11:02 -0700237 // Mute.
238 if (mAudioState.isMuted != mAudioManager.isMicrophoneMute()) {
239 Log.i(this, "changing microphone mute state to: %b", mAudioState.isMuted);
240 mAudioManager.setMicrophoneMute(mAudioState.isMuted);
Santos Cordon1ae2b852014-03-19 03:03:10 -0700241 }
242
Sailesh Nepal6aca10a2014-03-24 16:11:02 -0700243 // Audio route.
Santos Cordonc7e85d42014-05-22 02:51:48 -0700244 if (mAudioState.route == CallAudioState.ROUTE_BLUETOOTH) {
245 turnOnSpeaker(false);
246 turnOnBluetooth(true);
247 } else if (mAudioState.route == CallAudioState.ROUTE_SPEAKER) {
248 turnOnBluetooth(false);
249 turnOnSpeaker(true);
Sailesh Nepal6aca10a2014-03-24 16:11:02 -0700250 } else if (mAudioState.route == CallAudioState.ROUTE_EARPIECE ||
251 mAudioState.route == CallAudioState.ROUTE_WIRED_HEADSET) {
Santos Cordonc7e85d42014-05-22 02:51:48 -0700252 turnOnBluetooth(false);
253 turnOnSpeaker(false);
Sailesh Nepal6aca10a2014-03-24 16:11:02 -0700254 }
255
256 if (!oldAudioState.equals(mAudioState)) {
257 CallsManager.getInstance().onAudioStateChanged(oldAudioState, mAudioState);
258 updateAudioForForegroundCall();
259 }
260 }
261
Santos Cordonc7e85d42014-05-22 02:51:48 -0700262 private void turnOnSpeaker(boolean on) {
263 // Wired headset and earpiece work the same way
264 if (mAudioManager.isSpeakerphoneOn() != on) {
265 Log.i(this, "turning speaker phone off");
266 mAudioManager.setSpeakerphoneOn(on);
267 }
268 }
269
270 private void turnOnBluetooth(boolean on) {
271 if (mBluetoothManager.isBluetoothAvailable()) {
272 boolean isAlreadyOn = mBluetoothManager.isBluetoothAudioConnected();
273 if (on != isAlreadyOn) {
274 if (on) {
275 mBluetoothManager.connectBluetoothAudio();
276 } else {
277 mBluetoothManager.disconnectBluetoothAudio();
278 }
279 }
280 }
281 }
282
Sailesh Nepal6aca10a2014-03-24 16:11:02 -0700283 private void updateAudioStreamAndMode() {
Santos Cordona56f2762014-03-24 15:55:53 -0700284 Log.v(this, "updateAudioStreamAndMode, mIsRinging: %b, mIsTonePlaying: %b", mIsRinging,
285 mIsTonePlaying);
Sailesh Nepal6aca10a2014-03-24 16:11:02 -0700286 if (mIsRinging) {
287 requestAudioFocusAndSetMode(AudioManager.STREAM_RING, AudioManager.MODE_RINGTONE);
288 } else {
Santos Cordon5ba7f272014-05-28 13:59:49 -0700289 Call call = getForegroundCall();
Sailesh Nepal6aca10a2014-03-24 16:11:02 -0700290 if (call != null) {
Sailesh Nepal7e669572014-07-08 21:29:12 -0700291 int mode = call.getAudioModeIsVoip() ?
292 AudioManager.MODE_IN_COMMUNICATION : AudioManager.MODE_IN_CALL;
Sailesh Nepal6aca10a2014-03-24 16:11:02 -0700293 requestAudioFocusAndSetMode(AudioManager.STREAM_VOICE_CALL, mode);
Santos Cordona56f2762014-03-24 15:55:53 -0700294 } else if (mIsTonePlaying) {
295 // There is no call, however, we are still playing a tone, so keep focus.
296 requestAudioFocusAndSetMode(
297 AudioManager.STREAM_VOICE_CALL, AudioManager.MODE_IN_COMMUNICATION);
Sailesh Nepal6aca10a2014-03-24 16:11:02 -0700298 } else {
299 abandonAudioFocus();
300 }
301 }
302 }
303
304 private void requestAudioFocusAndSetMode(int stream, int mode) {
305 Log.v(this, "setSystemAudioStreamAndMode, stream: %d -> %d", mAudioFocusStreamType, stream);
306 Preconditions.checkState(stream != STREAM_NONE);
307
Santos Cordon5ba7f272014-05-28 13:59:49 -0700308 // Even if we already have focus, if the stream is different we update audio manager to give
309 // it a hint about the purpose of our focus.
310 if (mAudioFocusStreamType != stream) {
Sailesh Nepal6aca10a2014-03-24 16:11:02 -0700311 Log.v(this, "requesting audio focus for stream: %d", stream);
312 mAudioManager.requestAudioFocusForCall(stream,
313 AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
314 }
315 mAudioFocusStreamType = stream;
316 setMode(mode);
317 }
318
319 private void abandonAudioFocus() {
320 if (mAudioFocusStreamType != STREAM_NONE) {
321 setMode(AudioManager.MODE_NORMAL);
322 Log.v(this, "abandoning audio focus");
323 mAudioManager.abandonAudioFocusForCall();
324 mAudioFocusStreamType = STREAM_NONE;
325 }
Santos Cordon1ae2b852014-03-19 03:03:10 -0700326 }
327
328 /**
329 * Sets the audio mode.
330 *
Sailesh Nepal6aca10a2014-03-24 16:11:02 -0700331 * @param newMode Mode constant from AudioManager.MODE_*.
Santos Cordon1ae2b852014-03-19 03:03:10 -0700332 */
Sailesh Nepal6aca10a2014-03-24 16:11:02 -0700333 private void setMode(int newMode) {
334 Preconditions.checkState(mAudioFocusStreamType != STREAM_NONE);
335 int oldMode = mAudioManager.getMode();
336 Log.v(this, "Request to change audio mode from %d to %d", oldMode, newMode);
337 if (oldMode != newMode) {
338 mAudioManager.setMode(newMode);
339 }
340 }
341
342 private int selectWiredOrEarpiece(int route, int supportedRouteMask) {
343 // Since they are mutually exclusive and one is ALWAYS valid, we allow a special input of
344 // ROUTE_WIRED_OR_EARPIECE so that callers dont have to make a call to check which is
345 // supported before calling setAudioRoute.
346 if (route == CallAudioState.ROUTE_WIRED_OR_EARPIECE) {
347 route = CallAudioState.ROUTE_WIRED_OR_EARPIECE & supportedRouteMask;
348 if (route == 0) {
349 Log.wtf(this, "One of wired headset or earpiece should always be valid.");
350 // assume earpiece in this case.
351 route = CallAudioState.ROUTE_EARPIECE;
Santos Cordon1ae2b852014-03-19 03:03:10 -0700352 }
Sailesh Nepal6aca10a2014-03-24 16:11:02 -0700353 }
354 return route;
355 }
356
357 private int calculateSupportedRoutes() {
358 int routeMask = CallAudioState.ROUTE_SPEAKER;
359
360 if (mWiredHeadsetManager.isPluggedIn()) {
361 routeMask |= CallAudioState.ROUTE_WIRED_HEADSET;
Santos Cordon1ae2b852014-03-19 03:03:10 -0700362 } else {
Sailesh Nepal6aca10a2014-03-24 16:11:02 -0700363 routeMask |= CallAudioState.ROUTE_EARPIECE;
Santos Cordon1ae2b852014-03-19 03:03:10 -0700364 }
Sailesh Nepal6aca10a2014-03-24 16:11:02 -0700365
Santos Cordonc7e85d42014-05-22 02:51:48 -0700366 if (mBluetoothManager.isBluetoothAvailable()) {
367 routeMask |= CallAudioState.ROUTE_BLUETOOTH;
368 }
369
Sailesh Nepal6aca10a2014-03-24 16:11:02 -0700370 return routeMask;
Santos Cordon1ae2b852014-03-19 03:03:10 -0700371 }
372
Santos Cordonc7e85d42014-05-22 02:51:48 -0700373 private CallAudioState getInitialAudioState(Call call) {
Sailesh Nepal6aca10a2014-03-24 16:11:02 -0700374 int supportedRouteMask = calculateSupportedRoutes();
Santos Cordonc7e85d42014-05-22 02:51:48 -0700375 int route = selectWiredOrEarpiece(
376 CallAudioState.ROUTE_WIRED_OR_EARPIECE, supportedRouteMask);
377
378 // We want the UI to indicate that "bluetooth is in use" in two slightly different cases:
379 // (a) The obvious case: if a bluetooth headset is currently in use for an ongoing call.
380 // (b) The not-so-obvious case: if an incoming call is ringing, and we expect that audio
381 // *will* be routed to a bluetooth headset once the call is answered. In this case, just
382 // check if the headset is available. Note this only applies when we are dealing with
383 // the first call.
384 if (call != null && mBluetoothManager.isBluetoothAvailable()) {
385 switch(call.getState()) {
386 case ACTIVE:
387 case ON_HOLD:
388 if (mBluetoothManager.isBluetoothAudioConnectedOrPending()) {
389 route = CallAudioState.ROUTE_BLUETOOTH;
390 }
391 break;
392 case RINGING:
393 route = CallAudioState.ROUTE_BLUETOOTH;
394 break;
395 default:
396 break;
397 }
398 }
399
400 return new CallAudioState(false, route, supportedRouteMask);
Santos Cordon1ae2b852014-03-19 03:03:10 -0700401 }
402
Santos Cordonc7e85d42014-05-22 02:51:48 -0700403 private void setInitialAudioState(Call call) {
404 CallAudioState audioState = getInitialAudioState(call);
Sailesh Nepal6aca10a2014-03-24 16:11:02 -0700405 setSystemAudioState(audioState.isMuted, audioState.route, audioState.supportedRouteMask);
406 }
407
408 private void updateAudioForForegroundCall() {
409 Call call = CallsManager.getInstance().getForegroundCall();
Sailesh Nepalc92c4362014-07-04 18:33:21 -0700410 if (call != null && call.getConnectionService() != null) {
411 call.getConnectionService().onAudioStateChanged(call, mAudioState);
Sailesh Nepal6aca10a2014-03-24 16:11:02 -0700412 }
Sailesh Nepal810735e2014-03-18 18:15:46 -0700413 }
Santos Cordon5ba7f272014-05-28 13:59:49 -0700414
415 /**
416 * Returns the current foreground call in order to properly set the audio mode.
417 */
418 private Call getForegroundCall() {
419 Call call = CallsManager.getInstance().getForegroundCall();
420
421 // We ignore any foreground call that is in the ringing state because we deal with ringing
422 // calls exclusively through the mIsRinging variable set by {@link Ringer}.
423 if (call != null && call.getState() == CallState.RINGING) {
424 call = null;
425 }
426 return call;
427 }
Sailesh Nepal810735e2014-03-18 18:15:46 -0700428}