blob: bc0a146673073d143f4ba821599137a6baa8ee67 [file] [log] [blame]
Ihab Awade63fadb2014-07-09 21:52:04 -07001/*
2 * Copyright (C) 2013 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
Tyler Gunnef9f6f92014-09-12 22:16:17 -070017package android.telecom;
Ihab Awade63fadb2014-07-09 21:52:04 -070018
Santos Cordon29886d82015-04-16 15:34:07 -070019import android.annotation.SystemApi;
Hall Liua98f58b52017-11-07 17:59:28 -080020import android.bluetooth.BluetoothDevice;
Artur Satayev2ebb31c2020-01-08 12:24:36 +000021import android.compat.annotation.UnsupportedAppUsage;
Tyler Gunn17933eb2019-03-05 13:58:45 -080022import android.os.Build;
Tyler Gunn876dbfb2016-03-14 15:18:07 -070023import android.os.Bundle;
Ihab Awade63fadb2014-07-09 21:52:04 -070024import android.util.ArrayMap;
25
Grace Jiac7173232021-07-15 11:36:49 -070026import com.android.internal.annotations.GuardedBy;
27
Ihab Awade63fadb2014-07-09 21:52:04 -070028import java.util.Collections;
29import java.util.List;
30import java.util.Map;
31import java.util.Objects;
Jay Shrauner229e3822014-08-15 09:23:07 -070032import java.util.concurrent.CopyOnWriteArrayList;
Ihab Awade63fadb2014-07-09 21:52:04 -070033
34/**
35 * A unified virtual device providing a means of voice (and other) communication on a device.
Santos Cordon29886d82015-04-16 15:34:07 -070036 *
37 * @hide
38 * @deprecated Use {@link InCallService} directly instead of using this class.
Ihab Awade63fadb2014-07-09 21:52:04 -070039 */
Santos Cordon29886d82015-04-16 15:34:07 -070040@SystemApi
41@Deprecated
Ihab Awade63fadb2014-07-09 21:52:04 -070042public final class Phone {
43
44 public abstract static class Listener {
45 /**
46 * Called when the audio state changes.
47 *
48 * @param phone The {@code Phone} calling this method.
Ihab Awadb19a0bc2014-08-07 19:46:01 -070049 * @param audioState The new {@link AudioState}.
Yorke Lee4af59352015-05-13 14:14:54 -070050 *
51 * @deprecated Use {@link #onCallAudioStateChanged(Phone, CallAudioState)} instead.
Ihab Awade63fadb2014-07-09 21:52:04 -070052 */
Yorke Lee4af59352015-05-13 14:14:54 -070053 @Deprecated
Ihab Awadb19a0bc2014-08-07 19:46:01 -070054 public void onAudioStateChanged(Phone phone, AudioState audioState) { }
Ihab Awade63fadb2014-07-09 21:52:04 -070055
56 /**
Yorke Lee4af59352015-05-13 14:14:54 -070057 * Called when the audio state changes.
58 *
59 * @param phone The {@code Phone} calling this method.
60 * @param callAudioState The new {@link CallAudioState}.
61 */
62 public void onCallAudioStateChanged(Phone phone, CallAudioState callAudioState) { }
63
64 /**
Ihab Awade63fadb2014-07-09 21:52:04 -070065 * Called to bring the in-call screen to the foreground. The in-call experience should
66 * respond immediately by coming to the foreground to inform the user of the state of
67 * ongoing {@code Call}s.
68 *
69 * @param phone The {@code Phone} calling this method.
70 * @param showDialpad If true, put up the dialpad when the screen is shown.
71 */
72 public void onBringToForeground(Phone phone, boolean showDialpad) { }
73
74 /**
75 * Called when a {@code Call} has been added to this in-call session. The in-call user
76 * experience should add necessary state listeners to the specified {@code Call} and
77 * immediately start to show the user information about the existence
78 * and nature of this {@code Call}. Subsequent invocations of {@link #getCalls()} will
79 * include this {@code Call}.
80 *
81 * @param phone The {@code Phone} calling this method.
82 * @param call A newly added {@code Call}.
83 */
84 public void onCallAdded(Phone phone, Call call) { }
85
86 /**
87 * Called when a {@code Call} has been removed from this in-call session. The in-call user
88 * experience should remove any state listeners from the specified {@code Call} and
89 * immediately stop displaying any information about this {@code Call}.
90 * Subsequent invocations of {@link #getCalls()} will no longer include this {@code Call}.
91 *
92 * @param phone The {@code Phone} calling this method.
93 * @param call A newly removed {@code Call}.
94 */
95 public void onCallRemoved(Phone phone, Call call) { }
Santos Cordon6c912b72014-11-07 16:05:09 -080096
97 /**
98 * Called when the {@code Phone} ability to add more calls changes. If the phone cannot
99 * support more calls then {@code canAddCall} is set to {@code false}. If it can, then it
100 * is set to {@code true}.
101 *
102 * @param phone The {@code Phone} calling this method.
103 * @param canAddCall Indicates whether an additional call can be added.
104 */
105 public void onCanAddCallChanged(Phone phone, boolean canAddCall) { }
Sailesh Nepal9c2618b2016-01-23 16:28:22 -0800106
107 /**
108 * Called to silence the ringer if a ringing call exists.
109 *
110 * @param phone The {@code Phone} calling this method.
111 */
112 public void onSilenceRinger(Phone phone) { }
Ihab Awade63fadb2014-07-09 21:52:04 -0700113 }
114
Hall Liu31de23d2019-10-11 15:38:29 -0700115 // TODO: replace all usages of this with the actual R constant from Build.VERSION_CODES
116 /** @hide */
117 public static final int SDK_VERSION_R = 30;
118
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700119 // A Map allows us to track each Call by its Telecom-specified call ID
Grace Jiac7173232021-07-15 11:36:49 -0700120 @GuardedBy("mLock")
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700121 private final Map<String, Call> mCallByTelecomCallId = new ArrayMap<>();
Ihab Awade63fadb2014-07-09 21:52:04 -0700122
123 // A List allows us to keep the Calls in a stable iteration order so that casually developed
124 // user interface components do not incur any spurious jank
Santos Cordonf30d7e92014-08-26 09:54:33 -0700125 private final List<Call> mCalls = new CopyOnWriteArrayList<>();
Ihab Awade63fadb2014-07-09 21:52:04 -0700126
127 // An unmodifiable view of the above List can be safely shared with subclass implementations
128 private final List<Call> mUnmodifiableCalls = Collections.unmodifiableList(mCalls);
129
130 private final InCallAdapter mInCallAdapter;
131
Yorke Lee4af59352015-05-13 14:14:54 -0700132 private CallAudioState mCallAudioState;
Ihab Awade63fadb2014-07-09 21:52:04 -0700133
Jay Shrauner229e3822014-08-15 09:23:07 -0700134 private final List<Listener> mListeners = new CopyOnWriteArrayList<>();
Ihab Awade63fadb2014-07-09 21:52:04 -0700135
Santos Cordon6c912b72014-11-07 16:05:09 -0800136 private boolean mCanAddCall = true;
137
Tyler Gunnbf9c6fd2016-11-09 10:19:23 -0800138 private final String mCallingPackage;
139
Tyler Gunn159f35c2017-03-02 09:28:37 -0800140 /**
141 * The Target SDK version of the InCallService implementation.
142 */
143 private final int mTargetSdkVersion;
144
Grace Jiac7173232021-07-15 11:36:49 -0700145 private final Object mLock = new Object();
146
Tyler Gunn159f35c2017-03-02 09:28:37 -0800147 Phone(InCallAdapter adapter, String callingPackage, int targetSdkVersion) {
Ihab Awade63fadb2014-07-09 21:52:04 -0700148 mInCallAdapter = adapter;
Tyler Gunnbf9c6fd2016-11-09 10:19:23 -0800149 mCallingPackage = callingPackage;
Tyler Gunn159f35c2017-03-02 09:28:37 -0800150 mTargetSdkVersion = targetSdkVersion;
Ihab Awade63fadb2014-07-09 21:52:04 -0700151 }
152
Santos Cordon88b771d2014-07-19 13:10:40 -0700153 final void internalAddCall(ParcelableCall parcelableCall) {
Hall Liu31de23d2019-10-11 15:38:29 -0700154 if (mTargetSdkVersion < SDK_VERSION_R
155 && parcelableCall.getState() == Call.STATE_AUDIO_PROCESSING) {
156 Log.i(this, "Skipping adding audio processing call for sdk compatibility");
157 return;
158 }
159
Grace Jiac7173232021-07-15 11:36:49 -0700160 Call call = getCallById(parcelableCall.getId());
Hall Liufc2be9c2019-11-08 18:26:47 -0800161 if (call == null) {
162 call = new Call(this, parcelableCall.getId(), mInCallAdapter,
163 parcelableCall.getState(), mCallingPackage, mTargetSdkVersion);
Grace Jiac7173232021-07-15 11:36:49 -0700164
165 synchronized (mLock) {
166 mCallByTelecomCallId.put(parcelableCall.getId(), call);
167 mCalls.add(call);
168 }
169
Hall Liufc2be9c2019-11-08 18:26:47 -0800170 checkCallTree(parcelableCall);
171 call.internalUpdate(parcelableCall, mCallByTelecomCallId);
172 fireCallAdded(call);
173 } else {
174 Log.w(this, "Call %s added, but it was already present", call.internalGetCallId());
175 checkCallTree(parcelableCall);
176 call.internalUpdate(parcelableCall, mCallByTelecomCallId);
177 }
Hall Liu31de23d2019-10-11 15:38:29 -0700178 }
Ihab Awade63fadb2014-07-09 21:52:04 -0700179
Ihab Awade63fadb2014-07-09 21:52:04 -0700180 final void internalRemoveCall(Call call) {
Grace Jiac7173232021-07-15 11:36:49 -0700181 synchronized (mLock) {
182 mCallByTelecomCallId.remove(call.internalGetCallId());
183 mCalls.remove(call);
184 }
Tyler Gunn75958422015-04-15 14:23:42 -0700185
186 InCallService.VideoCall videoCall = call.getVideoCall();
187 if (videoCall != null) {
Andrew Lee011728f2015-04-23 15:47:06 -0700188 videoCall.destroy();
Tyler Gunn75958422015-04-15 14:23:42 -0700189 }
Ihab Awade63fadb2014-07-09 21:52:04 -0700190 fireCallRemoved(call);
191 }
192
Santos Cordon88b771d2014-07-19 13:10:40 -0700193 final void internalUpdateCall(ParcelableCall parcelableCall) {
Hall Liu31de23d2019-10-11 15:38:29 -0700194 if (mTargetSdkVersion < SDK_VERSION_R
195 && parcelableCall.getState() == Call.STATE_AUDIO_PROCESSING) {
196 Log.i(this, "removing audio processing call during update for sdk compatibility");
Grace Jiac7173232021-07-15 11:36:49 -0700197 Call call = getCallById(parcelableCall.getId());
Hall Liu31de23d2019-10-11 15:38:29 -0700198 if (call != null) {
199 internalRemoveCall(call);
200 }
201 return;
202 }
203
Grace Jiac7173232021-07-15 11:36:49 -0700204 Call call = getCallById(parcelableCall.getId());
Hall Liu31de23d2019-10-11 15:38:29 -0700205 if (call != null) {
206 checkCallTree(parcelableCall);
207 call.internalUpdate(parcelableCall, mCallByTelecomCallId);
208 } else {
209 // This call may have come out of audio processing. Try adding it if our target sdk
210 // version is low enough.
Hall Liufc2be9c2019-11-08 18:26:47 -0800211 // The only two allowable states coming out of audio processing are ACTIVE and
212 // SIMULATED_RINGING.
213 if (mTargetSdkVersion < SDK_VERSION_R && (parcelableCall.getState() == Call.STATE_ACTIVE
214 || parcelableCall.getState() == Call.STATE_SIMULATED_RINGING)) {
215 Log.i(this, "adding call during update for sdk compatibility");
Hall Liu31de23d2019-10-11 15:38:29 -0700216 internalAddCall(parcelableCall);
217 }
218 }
219 }
Ihab Awade63fadb2014-07-09 21:52:04 -0700220
Grace Jiac7173232021-07-15 11:36:49 -0700221 Call getCallById(String callId) {
222 synchronized (mLock) {
223 return mCallByTelecomCallId.get(callId);
224 }
225 }
226
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700227 final void internalSetPostDialWait(String telecomId, String remaining) {
Grace Jiac7173232021-07-15 11:36:49 -0700228 Call call = getCallById(telecomId);
Ihab Awade63fadb2014-07-09 21:52:04 -0700229 if (call != null) {
230 call.internalSetPostDialWait(remaining);
231 }
232 }
233
Yorke Lee4af59352015-05-13 14:14:54 -0700234 final void internalCallAudioStateChanged(CallAudioState callAudioState) {
235 if (!Objects.equals(mCallAudioState, callAudioState)) {
236 mCallAudioState = callAudioState;
237 fireCallAudioStateChanged(callAudioState);
Ihab Awade63fadb2014-07-09 21:52:04 -0700238 }
239 }
240
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700241 final Call internalGetCallByTelecomId(String telecomId) {
Grace Jiac7173232021-07-15 11:36:49 -0700242 return getCallById(telecomId);
Ihab Awade63fadb2014-07-09 21:52:04 -0700243 }
244
Ihab Awade63fadb2014-07-09 21:52:04 -0700245 final void internalBringToForeground(boolean showDialpad) {
246 fireBringToForeground(showDialpad);
247 }
248
Santos Cordon6c912b72014-11-07 16:05:09 -0800249 final void internalSetCanAddCall(boolean canAddCall) {
250 if (mCanAddCall != canAddCall) {
251 mCanAddCall = canAddCall;
252 fireCanAddCallChanged(canAddCall);
253 }
254 }
255
Sailesh Nepal9c2618b2016-01-23 16:28:22 -0800256 final void internalSilenceRinger() {
257 fireSilenceRinger();
258 }
259
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700260 final void internalOnConnectionEvent(String telecomId, String event, Bundle extras) {
Grace Jiac7173232021-07-15 11:36:49 -0700261 Call call = getCallById(telecomId);
Tyler Gunn876dbfb2016-03-14 15:18:07 -0700262 if (call != null) {
263 call.internalOnConnectionEvent(event, extras);
264 }
265 }
266
Hall Liu95d55872017-01-25 17:12:49 -0800267 final void internalOnRttUpgradeRequest(String callId, int requestId) {
Grace Jiac7173232021-07-15 11:36:49 -0700268 Call call = getCallById(callId);
Hall Liu95d55872017-01-25 17:12:49 -0800269 if (call != null) {
270 call.internalOnRttUpgradeRequest(requestId);
271 }
272 }
273
Hall Liu57006aa2017-02-06 10:49:48 -0800274 final void internalOnRttInitiationFailure(String callId, int reason) {
Grace Jiac7173232021-07-15 11:36:49 -0700275 Call call = getCallById(callId);
Hall Liu57006aa2017-02-06 10:49:48 -0800276 if (call != null) {
277 call.internalOnRttInitiationFailure(reason);
278 }
279 }
280
Sanket Padawe85291f62017-12-01 13:59:27 -0800281 final void internalOnHandoverFailed(String callId, int error) {
Grace Jiac7173232021-07-15 11:36:49 -0700282 Call call = getCallById(callId);
Sanket Padawe85291f62017-12-01 13:59:27 -0800283 if (call != null) {
284 call.internalOnHandoverFailed(error);
285 }
286 }
287
Tyler Gunn858bfaf2018-01-22 15:17:54 -0800288 final void internalOnHandoverComplete(String callId) {
Grace Jiac7173232021-07-15 11:36:49 -0700289 Call call = getCallById(callId);
Tyler Gunn858bfaf2018-01-22 15:17:54 -0800290 if (call != null) {
291 call.internalOnHandoverComplete();
292 }
293 }
294
Ihab Awade63fadb2014-07-09 21:52:04 -0700295 /**
Santos Cordonf30d7e92014-08-26 09:54:33 -0700296 * Called to destroy the phone and cleanup any lingering calls.
Santos Cordonf30d7e92014-08-26 09:54:33 -0700297 */
298 final void destroy() {
299 for (Call call : mCalls) {
Tyler Gunn75958422015-04-15 14:23:42 -0700300 InCallService.VideoCall videoCall = call.getVideoCall();
301 if (videoCall != null) {
Andrew Lee011728f2015-04-23 15:47:06 -0700302 videoCall.destroy();
Tyler Gunn75958422015-04-15 14:23:42 -0700303 }
Santos Cordonf30d7e92014-08-26 09:54:33 -0700304 if (call.getState() != Call.STATE_DISCONNECTED) {
305 call.internalSetDisconnected();
306 }
307 }
308 }
309
310 /**
Ihab Awade63fadb2014-07-09 21:52:04 -0700311 * Adds a listener to this {@code Phone}.
312 *
313 * @param listener A {@code Listener} object.
314 */
315 public final void addListener(Listener listener) {
316 mListeners.add(listener);
317 }
318
319 /**
320 * Removes a listener from this {@code Phone}.
321 *
322 * @param listener A {@code Listener} object.
323 */
324 public final void removeListener(Listener listener) {
Jay Shrauner229e3822014-08-15 09:23:07 -0700325 if (listener != null) {
326 mListeners.remove(listener);
327 }
Ihab Awade63fadb2014-07-09 21:52:04 -0700328 }
329
330 /**
331 * Obtains the current list of {@code Call}s to be displayed by this in-call experience.
332 *
333 * @return A list of the relevant {@code Call}s.
334 */
335 public final List<Call> getCalls() {
336 return mUnmodifiableCalls;
337 }
338
339 /**
Santos Cordon6c912b72014-11-07 16:05:09 -0800340 * Returns if the {@code Phone} can support additional calls.
341 *
342 * @return Whether the phone supports adding more calls.
343 */
344 public final boolean canAddCall() {
345 return mCanAddCall;
346 }
347
348 /**
Ihab Awade63fadb2014-07-09 21:52:04 -0700349 * Sets the microphone mute state. When this request is honored, there will be change to
350 * the {@link #getAudioState()}.
351 *
352 * @param state {@code true} if the microphone should be muted; {@code false} otherwise.
353 */
354 public final void setMuted(boolean state) {
355 mInCallAdapter.mute(state);
356 }
357
358 /**
359 * Sets the audio route (speaker, bluetooth, etc...). When this request is honored, there will
360 * be change to the {@link #getAudioState()}.
361 *
362 * @param route The audio route to use.
363 */
364 public final void setAudioRoute(int route) {
365 mInCallAdapter.setAudioRoute(route);
366 }
367
368 /**
Hall Liua98f58b52017-11-07 17:59:28 -0800369 * Request audio routing to a specific bluetooth device. Calling this method may result in
370 * the device routing audio to a different bluetooth device than the one specified. A list of
371 * available devices can be obtained via {@link CallAudioState#getSupportedBluetoothDevices()}
372 *
373 * @param bluetoothAddress The address of the bluetooth device to connect to, as returned by
374 * {@link BluetoothDevice#getAddress()}, or {@code null} if no device is preferred.
375 */
376 public void requestBluetoothAudio(String bluetoothAddress) {
377 mInCallAdapter.requestBluetoothAudio(bluetoothAddress);
378 }
379
380 /**
Yorke Lee0d6ea712014-07-28 14:39:23 -0700381 * Turns the proximity sensor on. When this request is made, the proximity sensor will
382 * become active, and the touch screen and display will be turned off when the user's face
383 * is detected to be in close proximity to the screen. This operation is a no-op on devices
384 * that do not have a proximity sensor.
Tyler Gunn17933eb2019-03-05 13:58:45 -0800385 * <p>
386 * This API does not actually turn on the proximity sensor; apps should do this on their own if
387 * required.
Yorke Lee22244d02015-04-14 12:34:28 -0700388 * @hide
Yorke Lee0d6ea712014-07-28 14:39:23 -0700389 */
Tyler Gunn17933eb2019-03-05 13:58:45 -0800390 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 127403196)
Yorke Lee0d6ea712014-07-28 14:39:23 -0700391 public final void setProximitySensorOn() {
392 mInCallAdapter.turnProximitySensorOn();
393 }
394
395 /**
396 * Turns the proximity sensor off. When this request is made, the proximity sensor will
397 * become inactive, and no longer affect the touch screen and display. This operation is a
398 * no-op on devices that do not have a proximity sensor.
399 *
400 * @param screenOnImmediately If true, the screen will be turned on immediately if it was
401 * previously off. Otherwise, the screen will only be turned on after the proximity sensor
402 * is no longer triggered.
Tyler Gunn17933eb2019-03-05 13:58:45 -0800403 * <p>
404 * This API does not actually turn of the proximity sensor; apps should do this on their own if
405 * required.
Yorke Lee22244d02015-04-14 12:34:28 -0700406 * @hide
Yorke Lee0d6ea712014-07-28 14:39:23 -0700407 */
Tyler Gunn17933eb2019-03-05 13:58:45 -0800408 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 127403196)
Yorke Lee0d6ea712014-07-28 14:39:23 -0700409 public final void setProximitySensorOff(boolean screenOnImmediately) {
410 mInCallAdapter.turnProximitySensorOff(screenOnImmediately);
411 }
412
413 /**
Ihab Awade63fadb2014-07-09 21:52:04 -0700414 * Obtains the current phone call audio state of the {@code Phone}.
415 *
416 * @return An object encapsulating the audio state.
Yorke Lee4af59352015-05-13 14:14:54 -0700417 * @deprecated Use {@link #getCallAudioState()} instead.
Ihab Awade63fadb2014-07-09 21:52:04 -0700418 */
Yorke Lee4af59352015-05-13 14:14:54 -0700419 @Deprecated
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700420 public final AudioState getAudioState() {
Yorke Lee4af59352015-05-13 14:14:54 -0700421 return new AudioState(mCallAudioState);
422 }
423
424 /**
425 * Obtains the current phone call audio state of the {@code Phone}.
426 *
427 * @return An object encapsulating the audio state.
428 */
429 public final CallAudioState getCallAudioState() {
430 return mCallAudioState;
Ihab Awade63fadb2014-07-09 21:52:04 -0700431 }
432
433 private void fireCallAdded(Call call) {
Jay Shrauner229e3822014-08-15 09:23:07 -0700434 for (Listener listener : mListeners) {
435 listener.onCallAdded(this, call);
Ihab Awade63fadb2014-07-09 21:52:04 -0700436 }
437 }
438
439 private void fireCallRemoved(Call call) {
Jay Shrauner229e3822014-08-15 09:23:07 -0700440 for (Listener listener : mListeners) {
441 listener.onCallRemoved(this, call);
Ihab Awade63fadb2014-07-09 21:52:04 -0700442 }
443 }
444
Yorke Lee4af59352015-05-13 14:14:54 -0700445 private void fireCallAudioStateChanged(CallAudioState audioState) {
Jay Shrauner229e3822014-08-15 09:23:07 -0700446 for (Listener listener : mListeners) {
Yorke Lee4af59352015-05-13 14:14:54 -0700447 listener.onCallAudioStateChanged(this, audioState);
448 listener.onAudioStateChanged(this, new AudioState(audioState));
Ihab Awade63fadb2014-07-09 21:52:04 -0700449 }
450 }
451
452 private void fireBringToForeground(boolean showDialpad) {
Jay Shrauner229e3822014-08-15 09:23:07 -0700453 for (Listener listener : mListeners) {
454 listener.onBringToForeground(this, showDialpad);
Ihab Awade63fadb2014-07-09 21:52:04 -0700455 }
456 }
457
Santos Cordon6c912b72014-11-07 16:05:09 -0800458 private void fireCanAddCallChanged(boolean canAddCall) {
459 for (Listener listener : mListeners) {
460 listener.onCanAddCallChanged(this, canAddCall);
461 }
462 }
463
Sailesh Nepal9c2618b2016-01-23 16:28:22 -0800464 private void fireSilenceRinger() {
465 for (Listener listener : mListeners) {
466 listener.onSilenceRinger(this);
467 }
468 }
469
Santos Cordon88b771d2014-07-19 13:10:40 -0700470 private void checkCallTree(ParcelableCall parcelableCall) {
Santos Cordon88b771d2014-07-19 13:10:40 -0700471 if (parcelableCall.getChildCallIds() != null) {
472 for (int i = 0; i < parcelableCall.getChildCallIds().size(); i++) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700473 if (!mCallByTelecomCallId.containsKey(parcelableCall.getChildCallIds().get(i))) {
Santos Cordon88b771d2014-07-19 13:10:40 -0700474 Log.wtf(this, "ParcelableCall %s has nonexistent child %s",
475 parcelableCall.getId(), parcelableCall.getChildCallIds().get(i));
Ihab Awade63fadb2014-07-09 21:52:04 -0700476 }
477 }
478 }
479 }
480}