Call.java revision b1a95a77522b2a1c98b378a2e538d819918b7f2c
10407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad/* 20407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad * Copyright (C) 2014 The Android Open Source Project 30407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad * 40407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad * Licensed under the Apache License, Version 2.0 (the "License"); 50407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad * you may not use this file except in compliance with the License. 60407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad * You may obtain a copy of the License at 70407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad * 80407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad * http://www.apache.org/licenses/LICENSE-2.0 90407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad * 100407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad * Unless required by applicable law or agreed to in writing, software 110407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad * distributed under the License is distributed on an "AS IS" BASIS, 120407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad * See the License for the specific language governing permissions and 140407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad * limitations under the License. 150407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad */ 160407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad 179f2bed31374a56487f370be01224baf6ce97e8adBen Giladpackage com.android.telecomm; 189f2bed31374a56487f370be01224baf6ce97e8adBen Gilad 199d58de5df05d0358fc8ae57ab7e9a0c45337c602Sailesh Nepalimport android.app.PendingIntent; 2099c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordonimport android.graphics.Bitmap; 2199c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordonimport android.graphics.drawable.Drawable; 22ce704b9a5d9cf7db30a8c865975c70e5cbc0dc5cSailesh Nepalimport android.net.Uri; 2384fa5f8c59a1cd3c5716c239fb19c58244fc81feSailesh Nepalimport android.os.Bundle; 24fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordonimport android.os.Handler; 25e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepalimport android.telecomm.CallPropertyPresentation; 260b03b4b143234302f098ea18de3c32658b455ecaSantos Cordonimport android.telecomm.CallState; 2772890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordonimport android.telecomm.Connection; 28c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepalimport android.telecomm.ConnectionRequest; 2933501635c2cd21f40793041eff3b8ce3a5710d49Yorke Leeimport android.telecomm.GatewayInfo; 3072890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordonimport android.telecomm.ParcelableConnection; 3189176375c8d97db25588f720952a4fadbce2f9a3Evan Charltonimport android.telecomm.PhoneAccountHandle; 32ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awadimport android.telecomm.Response; 3335faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepalimport android.telecomm.StatusHints; 3479ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordonimport android.telephony.DisconnectCause; 356aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepalimport android.telephony.PhoneNumberUtils; 36fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordonimport android.text.TextUtils; 370b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon 38a65d41fb134e323ab43c3f9454313b262959b1d0Nancy Chenimport com.android.internal.telecomm.ICallVideoProvider; 39fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordonimport com.android.internal.telephony.CallerInfo; 40fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordonimport com.android.internal.telephony.CallerInfoAsyncQuery; 41fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordonimport com.android.internal.telephony.CallerInfoAsyncQuery.OnQueryCompleteListener; 42ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awadimport com.android.internal.telephony.SmsApplication; 4399c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordonimport com.android.telecomm.ContactsAsyncHelper.OnImageLoadCompleteListener; 4461d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordonimport com.google.common.base.Preconditions; 4561d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon 46ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awadimport java.util.Collections; 47a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordonimport java.util.LinkedList; 48a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordonimport java.util.List; 499199078322aea6df26f0d304a28a9a6d040f0717Sailesh Nepalimport java.util.Locale; 50e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepalimport java.util.Objects; 516192561b1f56d7c4e6c650e178e07ba61ad02667Ben Giladimport java.util.Set; 52dfc6601da7bfdf63cd5c7ed815c2cb5da7975f1dSantos Cordonimport java.util.concurrent.CopyOnWriteArraySet; 530407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad 542495d57b5b91f3a39529d8844a49d1be5f18b137Ben Gilad/** 552495d57b5b91f3a39529d8844a49d1be5f18b137Ben Gilad * Encapsulates all aspects of a given phone call throughout its lifecycle, starting 562495d57b5b91f3a39529d8844a49d1be5f18b137Ben Gilad * from the time the call intent was received by Telecomm (vs. the time the call was 572495d57b5b91f3a39529d8844a49d1be5f18b137Ben Gilad * connected etc). 582495d57b5b91f3a39529d8844a49d1be5f18b137Ben Gilad */ 59664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepalfinal class Call implements CreateConnectionResponse { 60766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon /** 61766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon * Listener for events on the call. 62766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon */ 63766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon interface Listener { 64766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon void onSuccessfulOutgoingCall(Call call); 655a73b03be0a2a929cf9974578445b90f773937b4Sailesh Nepal void onFailedOutgoingCall(Call call, int errorCode, String errorMsg); 665a73b03be0a2a929cf9974578445b90f773937b4Sailesh Nepal void onCancelledOutgoingCall(Call call); 67c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal void onSuccessfulIncomingCall(Call call); 68766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon void onFailedIncomingCall(Call call); 69cb387ac1bb278de62e352b363cb38339629a61f5Ihab Awad void onRequestingRingback(Call call, boolean requestingRingback); 70352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton void onPostDialWait(Call call, String remaining); 71e20bc974ffc24d852d09e153a280b51e0329299cSailesh Nepal void onCallCapabilitiesChanged(Call call); 72a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon void onExpiredConferenceCall(Call call); 73a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon void onConfirmedConferenceCall(Call call); 74a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon void onParentChanged(Call call); 75a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon void onChildrenChanged(Call call); 76ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad void onCannedSmsResponsesLoaded(Call call); 77a65d41fb134e323ab43c3f9454313b262959b1d0Nancy Chen void onCallVideoProviderChanged(Call call); 7864c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon void onCallerInfoChanged(Call call); 797e66957928c5c23a1028c8e2a2d7cf359cbfa44eSailesh Nepal void onAudioModeIsVoipChanged(Call call); 8035faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal void onStatusHintsChanged(Call call); 81e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal void onHandleChanged(Call call); 82e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal void onCallerDisplayNameChanged(Call call); 834a79660c984d54679ad4d2bdc89e224d9c8c375bAndrew Lee void onVideoStateChanged(Call call); 849d58de5df05d0358fc8ae57ab7e9a0c45337c602Sailesh Nepal void onStartActivityFromInCall(Call call, PendingIntent intent); 8569eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad void onPhoneAccountChanged(Call call); 8664c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon } 8764c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon 8864c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon abstract static class ListenerBase implements Listener { 8964c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon @Override 9064c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon public void onSuccessfulOutgoingCall(Call call) {} 9164c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon @Override 9264c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon public void onFailedOutgoingCall(Call call, int errorCode, String errorMsg) {} 9364c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon @Override 9464c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon public void onCancelledOutgoingCall(Call call) {} 9564c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon @Override 96c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal public void onSuccessfulIncomingCall(Call call) {} 9764c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon @Override 9864c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon public void onFailedIncomingCall(Call call) {} 9964c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon @Override 10064c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon public void onRequestingRingback(Call call, boolean requestingRingback) {} 10164c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon @Override 10264c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon public void onPostDialWait(Call call, String remaining) {} 10364c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon @Override 104e20bc974ffc24d852d09e153a280b51e0329299cSailesh Nepal public void onCallCapabilitiesChanged(Call call) {} 10564c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon @Override 10664c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon public void onExpiredConferenceCall(Call call) {} 10764c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon @Override 10864c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon public void onConfirmedConferenceCall(Call call) {} 10964c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon @Override 11064c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon public void onParentChanged(Call call) {} 11164c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon @Override 11264c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon public void onChildrenChanged(Call call) {} 11364c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon @Override 11464c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon public void onCannedSmsResponsesLoaded(Call call) {} 11564c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon @Override 11664c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon public void onCallVideoProviderChanged(Call call) {} 11764c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon @Override 11864c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon public void onCallerInfoChanged(Call call) {} 1197e66957928c5c23a1028c8e2a2d7cf359cbfa44eSailesh Nepal @Override 1207e66957928c5c23a1028c8e2a2d7cf359cbfa44eSailesh Nepal public void onAudioModeIsVoipChanged(Call call) {} 12135faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal @Override 12235faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal public void onStatusHintsChanged(Call call) {} 123e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal @Override 124e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal public void onHandleChanged(Call call) {} 125e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal @Override 126e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal public void onCallerDisplayNameChanged(Call call) {} 1274a79660c984d54679ad4d2bdc89e224d9c8c375bAndrew Lee @Override 1284a79660c984d54679ad4d2bdc89e224d9c8c375bAndrew Lee public void onVideoStateChanged(Call call) {} 1299d58de5df05d0358fc8ae57ab7e9a0c45337c602Sailesh Nepal @Override 1309d58de5df05d0358fc8ae57ab7e9a0c45337c602Sailesh Nepal public void onStartActivityFromInCall(Call call, PendingIntent intent) {} 13169eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad @Override 13269eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad public void onPhoneAccountChanged(Call call) {} 133766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon } 134766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon 135fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon private static final OnQueryCompleteListener sCallerInfoQueryListener = 13699c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon new OnQueryCompleteListener() { 13799c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon /** ${inheritDoc} */ 13899c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon @Override 13999c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon public void onQueryComplete(int token, Object cookie, CallerInfo callerInfo) { 14099c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon if (cookie != null) { 14199c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon ((Call) cookie).setCallerInfo(callerInfo, token); 14299c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon } 143fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon } 14499c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon }; 14599c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon 14699c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon private static final OnImageLoadCompleteListener sPhotoLoadListener = 14799c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon new OnImageLoadCompleteListener() { 14899c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon /** ${inheritDoc} */ 14999c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon @Override 15099c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon public void onImageLoadComplete( 15199c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon int token, Drawable photo, Bitmap photoIcon, Object cookie) { 15299c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon if (cookie != null) { 15399c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon ((Call) cookie).setPhoto(photo, photoIcon, token); 15499c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon } 15599c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon } 15699c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon }; 1570407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad 158664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal private final Runnable mDirectToVoicemailRunnable = new Runnable() { 159664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal @Override 160664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal public void run() { 161664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal processDirectToVoicemail(); 162664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal } 163664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal }; 164664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal 165810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal /** True if this is an incoming call. */ 166810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal private final boolean mIsIncoming; 167810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal 1680407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad /** 169664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal * The time this call was created. Beyond logging and such, may also be used for bookkeeping 170664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal * and specifically for marking certain call attempts as failed attempts. 1710407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad */ 1728c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal private final long mCreationTimeMillis = System.currentTimeMillis(); 1738c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal 174fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon /** The gateway information associated with this call. This stores the original call handle 175fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon * that the user is attempting to connect to via the gateway, the actual handle to dial in 176fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon * order to connect the call via the gateway, as well as the package name of the gateway 177fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon * service. */ 178fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon private final GatewayInfo mGatewayInfo; 179fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon 18089176375c8d97db25588f720952a4fadbce2f9a3Evan Charlton private PhoneAccountHandle mPhoneAccountHandle; 18177d2d0e90bc2a67d526743b8e32f920a0d755fbaNancy Chen 1822174fb56907fddf5680355e097f4425f837983e2Santos Cordon private final Handler mHandler = new Handler(); 1832174fb56907fddf5680355e097f4425f837983e2Santos Cordon 1848c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal private long mConnectTimeMillis; 1850407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad 18661d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon /** The state of the call. */ 18761d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon private CallState mState; 18861d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon 18961d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon /** The handle with which to establish this call. */ 190ce704b9a5d9cf7db30a8c865975c70e5cbc0dc5cSailesh Nepal private Uri mHandle; 19161d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon 192e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal /** The {@link CallPropertyPresentation} that controls how the handle is shown. */ 193e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal private int mHandlePresentation; 194e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal 195e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal /** The caller display name (CNAP) set by the connection service. */ 196e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal private String mCallerDisplayName; 197e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal 198e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal /** The {@link CallPropertyPresentation} that controls how the caller display name is shown. */ 199e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal private int mCallerDisplayNamePresentation; 200e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal 2010407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad /** 202c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal * The connection service which is attempted or already connecting this call. 203681663d17b6d92b604526a54b196fa88f25b6957Santos Cordon */ 204c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal private ConnectionServiceWrapper mConnectionService; 2056192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad 2066aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal private boolean mIsEmergencyCall; 2076aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal 208b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati private boolean mSpeakerphoneOn; 209b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati 2100a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn /** 2110a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn * Tracks the video states which were applicable over the duration of a call. 2120a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn * See {@link android.telecomm.VideoCallProfile} for a list of valid video states. 2130a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn */ 2140a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn private int mVideoStateHistory; 2150a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn 216c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn private int mVideoState; 217c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn 2186192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad /** 21979ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon * Disconnect cause for the call. Only valid if the state of the call is DISCONNECTED. 22079ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon * See {@link android.telephony.DisconnectCause}. 22179ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon */ 2228c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal private int mDisconnectCause = DisconnectCause.NOT_VALID; 22379ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon 22479ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon /** 225c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal * Additional disconnect information provided by the connection service. 22679ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon */ 22779ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon private String mDisconnectMessage; 22879ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon 229c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal /** Info used by the connection services. */ 2308c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal private Bundle mExtras = Bundle.EMPTY; 23184fa5f8c59a1cd3c5716c239fb19c58244fc81feSailesh Nepal 232766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon /** Set of listeners on this call. */ 233dfc6601da7bfdf63cd5c7ed815c2cb5da7975f1dSantos Cordon private Set<Listener> mListeners = new CopyOnWriteArraySet<>(); 234766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon 235664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal private CreateConnectionProcessor mCreateConnectionProcessor; 236682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon 237fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon /** Caller information retrieved from the latest contact query. */ 238fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon private CallerInfo mCallerInfo; 239fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon 240fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon /** The latest token used with a contact info query. */ 241fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon private int mQueryToken = 0; 242fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon 243cb387ac1bb278de62e352b363cb38339629a61f5Ihab Awad /** Whether this call is requesting that Telecomm play the ringback tone on its behalf. */ 244cb387ac1bb278de62e352b363cb38339629a61f5Ihab Awad private boolean mRequestingRingback = false; 245cb387ac1bb278de62e352b363cb38339629a61f5Ihab Awad 246c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal /** Whether direct-to-voicemail query is pending. */ 247c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal private boolean mDirectToVoicemailQueryPending; 2482174fb56907fddf5680355e097f4425f837983e2Santos Cordon 249e20bc974ffc24d852d09e153a280b51e0329299cSailesh Nepal private int mCallCapabilities; 250a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon 251a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon private boolean mIsConference = false; 252a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon 253a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon private Call mParentCall = null; 254a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon 255a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon private List<Call> mChildCalls = new LinkedList<>(); 256a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon 257ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad /** Set of text message responses allowed for this call, if applicable. */ 258ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad private List<String> mCannedSmsResponses = Collections.EMPTY_LIST; 259ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad 260ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad /** Whether an attempt has been made to load the text message responses. */ 261ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad private boolean mCannedSmsResponsesLoadingStarted = false; 262ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad 263a65d41fb134e323ab43c3f9454313b262959b1d0Nancy Chen private ICallVideoProvider mCallVideoProvider; 264a65d41fb134e323ab43c3f9454313b262959b1d0Nancy Chen 2657e66957928c5c23a1028c8e2a2d7cf359cbfa44eSailesh Nepal private boolean mAudioModeIsVoip; 26635faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal private StatusHints mStatusHints; 267664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal private final ConnectionServiceRepository mRepository; 2687e66957928c5c23a1028c8e2a2d7cf359cbfa44eSailesh Nepal 2698c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal /** 2700407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad * Persists the specified parameters and initializes the new instance. 2710407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad * 2720407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad * @param handle The handle to dial. 27333501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee * @param gatewayInfo Gateway information to use for the call. 27494d01629010a61f6112713f22330d5fd4baae851Evan Charlton * @param accountHandle Account information to use for the call. 275810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal * @param isIncoming True if this is an incoming call. 2760407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad */ 277664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal Call( 278664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal ConnectionServiceRepository repository, 279664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal Uri handle, 280664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal GatewayInfo gatewayInfo, 28194d01629010a61f6112713f22330d5fd4baae851Evan Charlton PhoneAccountHandle accountHandle, 282664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal boolean isIncoming, 283664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal boolean isConference) { 284a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon mState = isConference ? CallState.ACTIVE : CallState.NEW; 285664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal mRepository = repository; 286e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal setHandle(handle, CallPropertyPresentation.ALLOWED); 28733501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee mGatewayInfo = gatewayInfo; 28894d01629010a61f6112713f22330d5fd4baae851Evan Charlton mPhoneAccountHandle = accountHandle; 289810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal mIsIncoming = isIncoming; 290a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon mIsConference = isConference; 291ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad maybeLoadCannedSmsResponses(); 2920407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad } 2930407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad 294766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon void addListener(Listener listener) { 295766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon mListeners.add(listener); 296766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon } 297766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon 298766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon void removeListener(Listener listener) { 299766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon mListeners.remove(listener); 300766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon } 301766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon 30261d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon /** {@inheritDoc} */ 30361d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon @Override public String toString() { 3044538f01647fa207b41fb7e481cc180e67fd391deSailesh Nepal String component = null; 305c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal if (mConnectionService != null && mConnectionService.getComponentName() != null) { 306c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal component = mConnectionService.getComponentName().flattenToShortString(); 3074538f01647fa207b41fb7e481cc180e67fd391deSailesh Nepal } 3080a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn 3090a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn return String.format(Locale.US, "[%s, %s, %s, %d]", mState, component, 3100a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn Log.piiHandle(mHandle), getVideoState()); 31161d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon } 31261d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon 3130b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon CallState getState() { 314a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon if (mIsConference) { 315a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon if (!mChildCalls.isEmpty()) { 316a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon // If we have child calls, just return the child call. 317a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon return mChildCalls.get(0).getState(); 318a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 319a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon return CallState.ACTIVE; 320a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } else { 321a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon return mState; 322a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 3230b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon } 3240b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon 3250b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon /** 3260b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon * Sets the call state. Although there exists the notion of appropriate state transitions 3270b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon * (see {@link CallState}), in practice those expectations break down when cellular systems 3280b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon * misbehave and they do this very often. The result is that we do not enforce state transitions 3290b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon * and instead keep the code resilient to unexpected state changes. 3300b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon */ 331810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal void setState(CallState newState) { 33279ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon Preconditions.checkState(newState != CallState.DISCONNECTED || 33379ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon mDisconnectCause != DisconnectCause.NOT_VALID); 334810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal if (mState != newState) { 335810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal Log.v(this, "setState %s -> %s", mState, newState); 336810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal mState = newState; 337ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad maybeLoadCannedSmsResponses(); 338810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal } 3390b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon } 3400b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon 341cb387ac1bb278de62e352b363cb38339629a61f5Ihab Awad void setRequestingRingback(boolean requestingRingback) { 342cb387ac1bb278de62e352b363cb38339629a61f5Ihab Awad mRequestingRingback = requestingRingback; 343cb387ac1bb278de62e352b363cb38339629a61f5Ihab Awad for (Listener l : mListeners) { 344cb387ac1bb278de62e352b363cb38339629a61f5Ihab Awad l.onRequestingRingback(this, mRequestingRingback); 345cb387ac1bb278de62e352b363cb38339629a61f5Ihab Awad } 346cb387ac1bb278de62e352b363cb38339629a61f5Ihab Awad } 347cb387ac1bb278de62e352b363cb38339629a61f5Ihab Awad 348cb387ac1bb278de62e352b363cb38339629a61f5Ihab Awad boolean isRequestingRingback() { 349cb387ac1bb278de62e352b363cb38339629a61f5Ihab Awad return mRequestingRingback; 350cb387ac1bb278de62e352b363cb38339629a61f5Ihab Awad } 351cb387ac1bb278de62e352b363cb38339629a61f5Ihab Awad 352ce704b9a5d9cf7db30a8c865975c70e5cbc0dc5cSailesh Nepal Uri getHandle() { 3530bf5b912285e328a8f5eeec158d6caf17845b9f8Ben Gilad return mHandle; 3540bf5b912285e328a8f5eeec158d6caf17845b9f8Ben Gilad } 3550bf5b912285e328a8f5eeec158d6caf17845b9f8Ben Gilad 356e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal int getHandlePresentation() { 357e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal return mHandlePresentation; 358e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal } 359e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal 360e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal void setHandle(Uri handle, int presentation) { 361e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal if (!Objects.equals(handle, mHandle) || presentation != mHandlePresentation) { 362fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon mHandle = handle; 363e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal mHandlePresentation = presentation; 364fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon mIsEmergencyCall = mHandle != null && PhoneNumberUtils.isLocalEmergencyNumber( 3656625545769bd9c5aa15b7e1ee9402f75ad799e81Yorke Lee TelecommApp.getInstance(), mHandle.getSchemeSpecificPart()); 366fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon startCallerInfoLookup(); 367e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal for (Listener l : mListeners) { 368e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal l.onHandleChanged(this); 369e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal } 370e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal } 371e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal } 372e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal 373e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal String getCallerDisplayName() { 374e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal return mCallerDisplayName; 375e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal } 376e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal 377e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal int getCallerDisplayNamePresentation() { 378e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal return mCallerDisplayNamePresentation; 379e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal } 380e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal 381e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal void setCallerDisplayName(String callerDisplayName, int presentation) { 382e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal if (!TextUtils.equals(callerDisplayName, mCallerDisplayName) || 383e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal presentation != mCallerDisplayNamePresentation) { 384e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal mCallerDisplayName = callerDisplayName; 385e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal mCallerDisplayNamePresentation = presentation; 386e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal for (Listener l : mListeners) { 387e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal l.onCallerDisplayNameChanged(this); 388e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal } 389fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon } 3906aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal } 3916aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal 39299c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon String getName() { 39399c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon return mCallerInfo == null ? null : mCallerInfo.name; 39499c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon } 39599c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon 39699c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon Bitmap getPhotoIcon() { 39799c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon return mCallerInfo == null ? null : mCallerInfo.cachedPhotoIcon; 39899c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon } 39999c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon 40099c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon Drawable getPhoto() { 40199c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon return mCallerInfo == null ? null : mCallerInfo.cachedPhoto; 40299c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon } 40399c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon 40479ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon /** 40579ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon * @param disconnectCause The reason for the disconnection, any of 40679ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon * {@link android.telephony.DisconnectCause}. 407905dfba7883666f45a0c6958d8bc6c19d68972d9Sailesh Nepal * @param disconnectMessage Optional message about the disconnect. 40879ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon */ 40979ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon void setDisconnectCause(int disconnectCause, String disconnectMessage) { 41079ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon // TODO: Consider combining this method with a setDisconnected() method that is totally 41179ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon // separate from setState. 41279ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon mDisconnectCause = disconnectCause; 41379ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon mDisconnectMessage = disconnectMessage; 41479ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon } 41579ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon 41679ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon int getDisconnectCause() { 41779ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon return mDisconnectCause; 41879ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon } 41979ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon 42079ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon String getDisconnectMessage() { 42179ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon return mDisconnectMessage; 42279ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon } 42379ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon 4246aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal boolean isEmergencyCall() { 4256aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal return mIsEmergencyCall; 42661d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon } 42761d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon 42833501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee /** 42933501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee * @return The original handle this call is associated with. In-call services should use this 43033501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee * handle when indicating in their UI the handle that is being called. 43133501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee */ 43233501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee public Uri getOriginalHandle() { 43333501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee if (mGatewayInfo != null && !mGatewayInfo.isEmpty()) { 43433501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee return mGatewayInfo.getOriginalHandle(); 43533501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee } 43633501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee return getHandle(); 43733501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee } 43833501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee 43933501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee GatewayInfo getGatewayInfo() { 44033501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee return mGatewayInfo; 44133501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee } 44233501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee 44389176375c8d97db25588f720952a4fadbce2f9a3Evan Charlton PhoneAccountHandle getPhoneAccount() { 44489176375c8d97db25588f720952a4fadbce2f9a3Evan Charlton return mPhoneAccountHandle; 44577d2d0e90bc2a67d526743b8e32f920a0d755fbaNancy Chen } 44677d2d0e90bc2a67d526743b8e32f920a0d755fbaNancy Chen 44789176375c8d97db25588f720952a4fadbce2f9a3Evan Charlton void setPhoneAccount(PhoneAccountHandle accountHandle) { 44889176375c8d97db25588f720952a4fadbce2f9a3Evan Charlton if (!Objects.equals(mPhoneAccountHandle, accountHandle)) { 44989176375c8d97db25588f720952a4fadbce2f9a3Evan Charlton mPhoneAccountHandle = accountHandle; 45069eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad for (Listener l : mListeners) { 45169eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad l.onPhoneAccountChanged(this); 45269eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad } 45369eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad } 45453ceedc1f5ae5a075c7a3186db8bb4db32cbe583Nancy Chen } 45553ceedc1f5ae5a075c7a3186db8bb4db32cbe583Nancy Chen 456810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal boolean isIncoming() { 457810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal return mIsIncoming; 458810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal } 459810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal 4600407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad /** 4610407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad * @return The "age" of this call object in milliseconds, which typically also represents the 4628c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal * period since this call was added to the set pending outgoing calls, see 4638c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal * mCreationTimeMillis. 4640407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad */ 4658c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal long getAgeMillis() { 4668c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal return System.currentTimeMillis() - mCreationTimeMillis; 4670407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad } 4680b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon 469f98fb5790ed62a3d4893362554f8d251c74d0ecdYorke Lee /** 470f98fb5790ed62a3d4893362554f8d251c74d0ecdYorke Lee * @return The time when this call object was created and added to the set of pending outgoing 471f98fb5790ed62a3d4893362554f8d251c74d0ecdYorke Lee * calls. 472f98fb5790ed62a3d4893362554f8d251c74d0ecdYorke Lee */ 4738c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal long getCreationTimeMillis() { 4748c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal return mCreationTimeMillis; 4758c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal } 4768c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal 4778c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal long getConnectTimeMillis() { 4788c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal return mConnectTimeMillis; 4798c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal } 4808c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal 4818c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal void setConnectTimeMillis(long connectTimeMillis) { 4828c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal mConnectTimeMillis = connectTimeMillis; 483f98fb5790ed62a3d4893362554f8d251c74d0ecdYorke Lee } 484f98fb5790ed62a3d4893362554f8d251c74d0ecdYorke Lee 485e20bc974ffc24d852d09e153a280b51e0329299cSailesh Nepal int getCallCapabilities() { 486e20bc974ffc24d852d09e153a280b51e0329299cSailesh Nepal return mCallCapabilities; 487a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 488a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon 489e20bc974ffc24d852d09e153a280b51e0329299cSailesh Nepal void setCallCapabilities(int callCapabilities) { 490e20bc974ffc24d852d09e153a280b51e0329299cSailesh Nepal if (mCallCapabilities != callCapabilities) { 491e20bc974ffc24d852d09e153a280b51e0329299cSailesh Nepal mCallCapabilities = callCapabilities; 492a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon for (Listener l : mListeners) { 493e20bc974ffc24d852d09e153a280b51e0329299cSailesh Nepal l.onCallCapabilitiesChanged(this); 494a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 495a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 496a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 497a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon 498a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon Call getParentCall() { 499a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon return mParentCall; 500a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 501a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon 502a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon List<Call> getChildCalls() { 503a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon return mChildCalls; 504a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 505a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon 506c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal ConnectionServiceWrapper getConnectionService() { 507c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal return mConnectionService; 508681663d17b6d92b604526a54b196fa88f25b6957Santos Cordon } 509681663d17b6d92b604526a54b196fa88f25b6957Santos Cordon 510c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal void setConnectionService(ConnectionServiceWrapper service) { 511c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal Preconditions.checkNotNull(service); 5128e55d1d7ea86f768acb90f88dc9e5b5368d3398aBen Gilad 513c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal clearConnectionService(); 5148e55d1d7ea86f768acb90f88dc9e5b5368d3398aBen Gilad 515c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal service.incrementAssociatedCallCount(); 516c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal mConnectionService = service; 517c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal mConnectionService.addCall(this); 518681663d17b6d92b604526a54b196fa88f25b6957Santos Cordon } 519681663d17b6d92b604526a54b196fa88f25b6957Santos Cordon 520681663d17b6d92b604526a54b196fa88f25b6957Santos Cordon /** 521c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal * Clears the associated connection service. 522681663d17b6d92b604526a54b196fa88f25b6957Santos Cordon */ 523c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal void clearConnectionService() { 524c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal if (mConnectionService != null) { 525c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal ConnectionServiceWrapper serviceTemp = mConnectionService; 526c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal mConnectionService = null; 527c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal serviceTemp.removeCall(this); 528c499c1c0758dcb4b02048df96e7405994660ab3fSantos Cordon 529c499c1c0758dcb4b02048df96e7405994660ab3fSantos Cordon // Decrementing the count can cause the service to unbind, which itself can trigger the 530c499c1c0758dcb4b02048df96e7405994660ab3fSantos Cordon // service-death code. Since the service death code tries to clean up any associated 531c499c1c0758dcb4b02048df96e7405994660ab3fSantos Cordon // calls, we need to make sure to remove that information (e.g., removeCall()) before 532c499c1c0758dcb4b02048df96e7405994660ab3fSantos Cordon // we decrement. Technically, invoking removeCall() prior to decrementing is all that is 533c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal // necessary, but cleaning up mConnectionService prior to triggering an unbind is good 534c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal // to do. 535c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal decrementAssociatedCallCount(serviceTemp); 536adee12dd6b3e85ce3ae419329226c9aa72c184fcYorke Lee } 5378e55d1d7ea86f768acb90f88dc9e5b5368d3398aBen Gilad } 5388e55d1d7ea86f768acb90f88dc9e5b5368d3398aBen Gilad 539664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal private void processDirectToVoicemail() { 540c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal if (mDirectToVoicemailQueryPending) { 5412174fb56907fddf5680355e097f4425f837983e2Santos Cordon if (mCallerInfo != null && mCallerInfo.shouldSendToVoicemail) { 5422174fb56907fddf5680355e097f4425f837983e2Santos Cordon Log.i(this, "Directing call to voicemail: %s.", this); 5432174fb56907fddf5680355e097f4425f837983e2Santos Cordon // TODO(santoscordon): Once we move State handling from CallsManager to Call, we 5442174fb56907fddf5680355e097f4425f837983e2Santos Cordon // will not need to set RINGING state prior to calling reject. 5452174fb56907fddf5680355e097f4425f837983e2Santos Cordon setState(CallState.RINGING); 546ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad reject(false, null); 5472174fb56907fddf5680355e097f4425f837983e2Santos Cordon } else { 5482174fb56907fddf5680355e097f4425f837983e2Santos Cordon // TODO(santoscordon): Make this class (not CallsManager) responsible for changing 5492174fb56907fddf5680355e097f4425f837983e2Santos Cordon // the call state to RINGING. 5502174fb56907fddf5680355e097f4425f837983e2Santos Cordon 5512174fb56907fddf5680355e097f4425f837983e2Santos Cordon // TODO(santoscordon): Replace this with state transition to RINGING. 5522174fb56907fddf5680355e097f4425f837983e2Santos Cordon for (Listener l : mListeners) { 553c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal l.onSuccessfulIncomingCall(this); 5542174fb56907fddf5680355e097f4425f837983e2Santos Cordon } 5552174fb56907fddf5680355e097f4425f837983e2Santos Cordon } 556766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon 557c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal mDirectToVoicemailQueryPending = false; 558766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon } 559766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon } 560766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon 561766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon /** 562664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal * Starts the create connection sequence. Upon completion, there should exist an active 563664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal * connection through a connection service (or the call will have failed). 564766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon */ 565664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal void startCreateConnection() { 566664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal Preconditions.checkState(mCreateConnectionProcessor == null); 567664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal mCreateConnectionProcessor = new CreateConnectionProcessor(this, mRepository, this); 568664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal mCreateConnectionProcessor.process(); 569766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon } 570766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon 5715a73b03be0a2a929cf9974578445b90f773937b4Sailesh Nepal @Override 57272890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon public void handleCreateConnectionSuccessful( 57372890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon ConnectionRequest request, ParcelableConnection connection) { 574664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal mCreateConnectionProcessor = null; 57572890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon setState(getStateFromConnectionState(connection.getState())); 57672890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon setPhoneAccount(connection.getPhoneAccount()); 57772890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon setHandle(connection.getHandle(), connection.getHandlePresentation()); 57872890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon setCallerDisplayName( 57972890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon connection.getCallerDisplayName(), connection.getCallerDisplayNamePresentation()); 58072890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon setCallVideoProvider(connection.getCallVideoProvider()); 581b1a95a77522b2a1c98b378a2e538d819918b7f2cTyler Gunn setVideoState(connection.getVideoState()); 582664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal 583664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal if (mIsIncoming) { 584664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal // We do not handle incoming calls immediately when they are verified by the connection 585664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal // service. We allow the caller-info-query code to execute first so that we can read the 586664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal // direct-to-voicemail property before deciding if we want to show the incoming call to 587664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal // the user or if we want to reject the call. 588664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal mDirectToVoicemailQueryPending = true; 589664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal 590664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal // Timeout the direct-to-voicemail lookup execution so that we dont wait too long before 591664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal // showing the user the incoming call screen. 592664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal mHandler.postDelayed(mDirectToVoicemailRunnable, Timeouts.getDirectToVoicemailMillis()); 593664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal } else { 594664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal for (Listener l : mListeners) { 595664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal l.onSuccessfulOutgoingCall(this); 596664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal } 597766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon } 5985a73b03be0a2a929cf9974578445b90f773937b4Sailesh Nepal } 5995a73b03be0a2a929cf9974578445b90f773937b4Sailesh Nepal 6005a73b03be0a2a929cf9974578445b90f773937b4Sailesh Nepal @Override 601664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal public void handleCreateConnectionFailed(int code, String msg) { 602664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal mCreateConnectionProcessor = null; 603664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal if (mIsIncoming) { 604664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal clearConnectionService(); 605664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal setDisconnectCause(code, null); 606664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal setState(CallState.DISCONNECTED); 607664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal 608664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal Listener[] listeners = mListeners.toArray(new Listener[mListeners.size()]); 609664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal for (int i = 0; i < listeners.length; i++) { 610664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal listeners[i].onFailedIncomingCall(this); 611664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal } 612664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal } else { 613664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal Listener[] listeners = mListeners.toArray(new Listener[mListeners.size()]); 614664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal for (int i = 0; i < listeners.length; i++) { 615664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal listeners[i].onFailedOutgoingCall(this, code, msg); 616664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal } 617664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal clearConnectionService(); 6185a73b03be0a2a929cf9974578445b90f773937b4Sailesh Nepal } 619766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon } 620766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon 6215a73b03be0a2a929cf9974578445b90f773937b4Sailesh Nepal @Override 622664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal public void handleCreateConnectionCancelled() { 623664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal mCreateConnectionProcessor = null; 624664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal if (mIsIncoming) { 625664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal clearConnectionService(); 626664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal setDisconnectCause(DisconnectCause.ERROR_UNSPECIFIED, null); 627664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal setState(CallState.DISCONNECTED); 628664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal 629664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal Listener[] listeners = mListeners.toArray(new Listener[mListeners.size()]); 630664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal for (int i = 0; i < listeners.length; i++) { 631664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal listeners[i].onFailedIncomingCall(this); 632664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal } 633664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal } else { 634664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal Listener[] listeners = mListeners.toArray(new Listener[mListeners.size()]); 635664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal for (int i = 0; i < listeners.length; i++) { 636664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal listeners[i].onCancelledOutgoingCall(this); 637664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal } 638664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal clearConnectionService(); 639766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon } 640766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon } 641766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon 642766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon /** 64374549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad * Plays the specified DTMF tone. 64474549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad */ 64574549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad void playDtmfTone(char digit) { 646c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal if (mConnectionService == null) { 647c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal Log.w(this, "playDtmfTone() request on a call without a connection service."); 64874549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad } else { 649c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal Log.i(this, "Send playDtmfTone to connection service for call %s", this); 650c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal mConnectionService.playDtmfTone(this, digit); 65174549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad } 65274549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad } 65374549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad 65474549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad /** 65574549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad * Stops playing any currently playing DTMF tone. 65674549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad */ 65774549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad void stopDtmfTone() { 658c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal if (mConnectionService == null) { 659c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal Log.w(this, "stopDtmfTone() request on a call without a connectino service."); 66074549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad } else { 661c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal Log.i(this, "Send stopDtmfTone to connection service for call %s", this); 662c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal mConnectionService.stopDtmfTone(this); 66374549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad } 66474549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad } 66574549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad 66674549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad /** 667c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal * Attempts to disconnect the call through the connection service. 668049b7b6a8d0cf44d687d827cb57a18fa23358206Santos Cordon */ 669049b7b6a8d0cf44d687d827cb57a18fa23358206Santos Cordon void disconnect() { 67053ceedc1f5ae5a075c7a3186db8bb4db32cbe583Nancy Chen if (mState == CallState.NEW || mState == CallState.PRE_DIAL_WAIT) { 671682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon Log.v(this, "Aborting call %s", this); 672682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon abort(); 67374d420be72fa30735fe9b7a25715f6db046c0398Santos Cordon } else if (mState != CallState.ABORTED && mState != CallState.DISCONNECTED) { 674c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal Preconditions.checkNotNull(mConnectionService); 675766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon 676c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal Log.i(this, "Send disconnect to connection service for call: %s", this); 677c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal // The call isn't officially disconnected until the connection service confirms that the 678c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal // call was actually disconnected. Only then is the association between call and 679c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal // connection service severed, see {@link CallsManager#markCallAsDisconnected}. 680c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal mConnectionService.disconnect(this); 681049b7b6a8d0cf44d687d827cb57a18fa23358206Santos Cordon } 682049b7b6a8d0cf44d687d827cb57a18fa23358206Santos Cordon } 683049b7b6a8d0cf44d687d827cb57a18fa23358206Santos Cordon 684682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon void abort() { 685664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal if (mCreateConnectionProcessor != null) { 686664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal mCreateConnectionProcessor.abort(); 68753ceedc1f5ae5a075c7a3186db8bb4db32cbe583Nancy Chen } else if (mState == CallState.PRE_DIAL_WAIT) { 68853ceedc1f5ae5a075c7a3186db8bb4db32cbe583Nancy Chen handleCreateConnectionFailed(DisconnectCause.LOCAL, null); 689682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon } 690682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon } 691682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon 6920b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon /** 69361d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon * Answers the call if it is ringing. 69438931d0ad60f00a9f50c90cef446166731f0b871Andrew Lee * 69538931d0ad60f00a9f50c90cef446166731f0b871Andrew Lee * @param videoState The video state in which to answer the call. 69661d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon */ 69738931d0ad60f00a9f50c90cef446166731f0b871Andrew Lee void answer(int videoState) { 698c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal Preconditions.checkNotNull(mConnectionService); 69961d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon 70061d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon // Check to verify that the call is still in the ringing state. A call can change states 70161d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon // between the time the user hits 'answer' and Telecomm receives the command. 70261d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon if (isRinging("answer")) { 703c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal // At this point, we are asking the connection service to answer but we don't assume 704c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal // that it will work. Instead, we wait until confirmation from the connectino service 705c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal // that the call is in a non-RINGING state before changing the UI. See 706c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal // {@link ConnectionServiceAdapter#setActive} and other set* methods. 70738931d0ad60f00a9f50c90cef446166731f0b871Andrew Lee mConnectionService.answer(this, videoState); 70861d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon } 70961d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon } 71061d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon 71161d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon /** 71261d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon * Rejects the call if it is ringing. 713ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * 714ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * @param rejectWithMessage Whether to send a text message as part of the call rejection. 715ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * @param textMessage An optional text message to send as part of the rejection. 71661d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon */ 717ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad void reject(boolean rejectWithMessage, String textMessage) { 718c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal Preconditions.checkNotNull(mConnectionService); 71961d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon 72061d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon // Check to verify that the call is still in the ringing state. A call can change states 72161d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon // between the time the user hits 'reject' and Telecomm receives the command. 72261d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon if (isRinging("reject")) { 723c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal mConnectionService.reject(this); 72461d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon } 72561d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon } 72661d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon 72761d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon /** 728cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee * Puts the call on hold if it is currently active. 729cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee */ 730cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee void hold() { 731c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal Preconditions.checkNotNull(mConnectionService); 732cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee 733cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee if (mState == CallState.ACTIVE) { 734c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal mConnectionService.hold(this); 735cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee } 736cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee } 737cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee 738cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee /** 739cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee * Releases the call from hold if it is currently active. 740cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee */ 741cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee void unhold() { 742c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal Preconditions.checkNotNull(mConnectionService); 743cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee 744cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee if (mState == CallState.ON_HOLD) { 745c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal mConnectionService.unhold(this); 746571f0737002251f09b9ef696dc8b4c9ce02abbaeSantos Cordon } 7470b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon } 7480b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon 7496aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal /** Checks if this is a live call or not. */ 7506aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal boolean isAlive() { 7516aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal switch (mState) { 7526aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal case NEW: 7536aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal case RINGING: 7546aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal case DISCONNECTED: 7556aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal case ABORTED: 7566aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal return false; 7576aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal default: 7586aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal return true; 7596aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal } 7606aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal } 7616aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal 76240f78c210512570f14cdfde9613dd85c510a1c0cSantos Cordon boolean isActive() { 76384bfe47a2447c4983bcc58468000f04683eec55bIhab Awad return mState == CallState.ACTIVE; 76440f78c210512570f14cdfde9613dd85c510a1c0cSantos Cordon } 76540f78c210512570f14cdfde9613dd85c510a1c0cSantos Cordon 76684fa5f8c59a1cd3c5716c239fb19c58244fc81feSailesh Nepal Bundle getExtras() { 76784fa5f8c59a1cd3c5716c239fb19c58244fc81feSailesh Nepal return mExtras; 76884fa5f8c59a1cd3c5716c239fb19c58244fc81feSailesh Nepal } 76984fa5f8c59a1cd3c5716c239fb19c58244fc81feSailesh Nepal 77084fa5f8c59a1cd3c5716c239fb19c58244fc81feSailesh Nepal void setExtras(Bundle extras) { 77184fa5f8c59a1cd3c5716c239fb19c58244fc81feSailesh Nepal mExtras = extras; 77284fa5f8c59a1cd3c5716c239fb19c58244fc81feSailesh Nepal } 77384fa5f8c59a1cd3c5716c239fb19c58244fc81feSailesh Nepal 7745ba7f27491e287f39a999ddd3d1ed6a7bad78272Santos Cordon Uri getRingtone() { 7755ba7f27491e287f39a999ddd3d1ed6a7bad78272Santos Cordon return mCallerInfo == null ? null : mCallerInfo.contactRingtoneUri; 7765ba7f27491e287f39a999ddd3d1ed6a7bad78272Santos Cordon } 7775ba7f27491e287f39a999ddd3d1ed6a7bad78272Santos Cordon 778352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton void onPostDialWait(String remaining) { 779352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton for (Listener l : mListeners) { 780352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton l.onPostDialWait(this, remaining); 781352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton } 782352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton } 783352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton 784352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton void postDialContinue(boolean proceed) { 785c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal mConnectionService.onPostDialContinue(this, proceed); 786352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton } 787352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton 78877da19ea28b8753d439660b4352c1bf914f63a92Sailesh Nepal void phoneAccountClicked() { 789c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal mConnectionService.onPhoneAccountClicked(this); 79077da19ea28b8753d439660b4352c1bf914f63a92Sailesh Nepal } 79177da19ea28b8753d439660b4352c1bf914f63a92Sailesh Nepal 792a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon void conferenceInto(Call conferenceCall) { 793c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal if (mConnectionService == null) { 794c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal Log.w(this, "conference requested on a call without a connection service."); 795a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } else { 796c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal mConnectionService.conference(conferenceCall, this); 797a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 798a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 799a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon 800a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon void expireConference() { 801a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon // The conference call expired before we got a confirmation of the conference from the 802c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal // connection service...so start shutting down. 803c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal clearConnectionService(); 804a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon for (Listener l : mListeners) { 805a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon l.onExpiredConferenceCall(this); 806a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 807a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 808a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon 809a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon void confirmConference() { 810a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon Log.v(this, "confirming Conf call %s", mListeners); 811a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon for (Listener l : mListeners) { 812a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon l.onConfirmedConferenceCall(this); 813a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 814a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 815a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon 816a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon void splitFromConference() { 817a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon // TODO(santoscordon): todo 818a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 819a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon 820e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal void swapWithBackgroundCall() { 821e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal mConnectionService.swapWithBackgroundCall(this); 822e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal } 823e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal 824a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon void setParentCall(Call parentCall) { 825a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon if (parentCall == this) { 826a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon Log.e(this, new Exception(), "setting the parent to self"); 827a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon return; 828a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 829a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon Preconditions.checkState(parentCall == null || mParentCall == null); 830a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon 831a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon Call oldParent = mParentCall; 832a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon if (mParentCall != null) { 833a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon mParentCall.removeChildCall(this); 834a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 835a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon mParentCall = parentCall; 836a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon if (mParentCall != null) { 837a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon mParentCall.addChildCall(this); 838a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 839a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon 840a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon for (Listener l : mListeners) { 841a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon l.onParentChanged(this); 842a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 843a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 844a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon 845a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon private void addChildCall(Call call) { 846a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon if (!mChildCalls.contains(call)) { 847a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon mChildCalls.add(call); 848a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon 849a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon for (Listener l : mListeners) { 850a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon l.onChildrenChanged(this); 851a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 852a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 853a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 854a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon 855a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon private void removeChildCall(Call call) { 856a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon if (mChildCalls.remove(call)) { 857a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon for (Listener l : mListeners) { 858a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon l.onChildrenChanged(this); 859a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 860a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 861a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 862a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon 8630b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon /** 864ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * Return whether the user can respond to this {@code Call} via an SMS message. 865ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * 866ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * @return true if the "Respond via SMS" feature should be enabled 867ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * for this incoming call. 868ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * 869ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * The general rule is that we *do* allow "Respond via SMS" except for 870ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * the few (relatively rare) cases where we know for sure it won't 871ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * work, namely: 872ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * - a bogus or blank incoming number 873ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * - a call from a SIP address 874ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * - a "call presentation" that doesn't allow the number to be revealed 875ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * 876ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * In all other cases, we allow the user to respond via SMS. 877ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * 878ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * Note that this behavior isn't perfect; for example we have no way 879ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * to detect whether the incoming call is from a landline (with most 880ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * networks at least), so we still enable this feature even though 881ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * SMSes to that number will silently fail. 882ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad */ 883ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad boolean isRespondViaSmsCapable() { 884ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad if (mState != CallState.RINGING) { 885ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad return false; 886ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad } 887ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad 888ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad if (getHandle() == null) { 889ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad // No incoming number known or call presentation is "PRESENTATION_RESTRICTED", in 890ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad // other words, the user should not be able to see the incoming phone number. 891ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad return false; 892ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad } 893ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad 894ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad if (PhoneNumberUtils.isUriNumber(getHandle().toString())) { 895ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad // The incoming number is actually a URI (i.e. a SIP address), 896ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad // not a regular PSTN phone number, and we can't send SMSes to 897ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad // SIP addresses. 898ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad // (TODO: That might still be possible eventually, though. Is 899ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad // there some SIP-specific equivalent to sending a text message?) 900ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad return false; 901ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad } 902ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad 903ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad // Is there a valid SMS application on the phone? 904ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad if (SmsApplication.getDefaultRespondViaMessageApplication(TelecommApp.getInstance(), 905ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad true /*updateIfNeeded*/) == null) { 906ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad return false; 907ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad } 908ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad 909ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad // TODO: with some carriers (in certain countries) you *can* actually 910ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad // tell whether a given number is a mobile phone or not. So in that 911ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad // case we could potentially return false here if the incoming call is 912ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad // from a land line. 913ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad 914ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad // If none of the above special cases apply, it's OK to enable the 915ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad // "Respond via SMS" feature. 916ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad return true; 917ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad } 918ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad 919ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad List<String> getCannedSmsResponses() { 920ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad return mCannedSmsResponses; 921ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad } 922ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad 923ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad /** 92461d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon * @return True if the call is ringing, else logs the action name. 92561d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon */ 92661d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon private boolean isRinging(String actionName) { 92761d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon if (mState == CallState.RINGING) { 92861d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon return true; 92961d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon } 93061d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon 931f1c191d3974fed3f57680c63571ae0212c4622e7Sailesh Nepal Log.i(this, "Request to %s a non-ringing call %s", actionName, this); 93261d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon return false; 93361d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon } 93461d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon 9358e55d1d7ea86f768acb90f88dc9e5b5368d3398aBen Gilad @SuppressWarnings("rawtypes") 9368e55d1d7ea86f768acb90f88dc9e5b5368d3398aBen Gilad private void decrementAssociatedCallCount(ServiceBinder binder) { 9378e55d1d7ea86f768acb90f88dc9e5b5368d3398aBen Gilad if (binder != null) { 9388e55d1d7ea86f768acb90f88dc9e5b5368d3398aBen Gilad binder.decrementAssociatedCallCount(); 9398e55d1d7ea86f768acb90f88dc9e5b5368d3398aBen Gilad } 9408e55d1d7ea86f768acb90f88dc9e5b5368d3398aBen Gilad } 941fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon 942fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon /** 943fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon * Looks up contact information based on the current handle. 944fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon */ 945fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon private void startCallerInfoLookup() { 946fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon String number = mHandle == null ? null : mHandle.getSchemeSpecificPart(); 947fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon 948fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon mQueryToken++; // Updated so that previous queries can no longer set the information. 949fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon mCallerInfo = null; 950fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon if (!TextUtils.isEmpty(number)) { 9515ba7f27491e287f39a999ddd3d1ed6a7bad78272Santos Cordon Log.v(this, "Looking up information for: %s.", Log.piiHandle(number)); 952fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon CallerInfoAsyncQuery.startQuery( 953fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon mQueryToken, 954fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon TelecommApp.getInstance(), 955fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon number, 956fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon sCallerInfoQueryListener, 957fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon this); 958fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon } 959fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon } 960fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon 961fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon /** 96299c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon * Saves the specified caller info if the specified token matches that of the last query 963fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon * that was made. 964fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon * 965fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon * @param callerInfo The new caller information to set. 966fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon * @param token The token used with this query. 967fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon */ 968fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon private void setCallerInfo(CallerInfo callerInfo, int token) { 96999c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon Preconditions.checkNotNull(callerInfo); 97099c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon 971fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon if (mQueryToken == token) { 972fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon mCallerInfo = callerInfo; 9735ba7f27491e287f39a999ddd3d1ed6a7bad78272Santos Cordon Log.i(this, "CallerInfo received for %s: %s", Log.piiHandle(mHandle), callerInfo); 97499c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon 975a1662d0ae89d9fb514a5ac68cbc76660e34dae00Makoto Onuki if (mCallerInfo.contactDisplayPhotoUri != null) { 976a1662d0ae89d9fb514a5ac68cbc76660e34dae00Makoto Onuki Log.d(this, "Searching person uri %s for call %s", 977a1662d0ae89d9fb514a5ac68cbc76660e34dae00Makoto Onuki mCallerInfo.contactDisplayPhotoUri, this); 97899c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon ContactsAsyncHelper.startObtainPhotoAsync( 97999c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon token, 98099c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon TelecommApp.getInstance(), 981a1662d0ae89d9fb514a5ac68cbc76660e34dae00Makoto Onuki mCallerInfo.contactDisplayPhotoUri, 98299c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon sPhotoLoadListener, 98399c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon this); 984a1662d0ae89d9fb514a5ac68cbc76660e34dae00Makoto Onuki // Do not call onCallerInfoChanged yet in this case. We call it in setPhoto(). 98564c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon } else { 98664c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon for (Listener l : mListeners) { 98764c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon l.onCallerInfoChanged(this); 98864c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon } 98999c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon } 9902174fb56907fddf5680355e097f4425f837983e2Santos Cordon 9912174fb56907fddf5680355e097f4425f837983e2Santos Cordon processDirectToVoicemail(); 99299c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon } 99399c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon } 99499c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon 9956f3f7affb13e93cb70868d3114f02f1ed593194eYorke Lee CallerInfo getCallerInfo() { 9966f3f7affb13e93cb70868d3114f02f1ed593194eYorke Lee return mCallerInfo; 9976f3f7affb13e93cb70868d3114f02f1ed593194eYorke Lee } 9986f3f7affb13e93cb70868d3114f02f1ed593194eYorke Lee 99999c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon /** 100099c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon * Saves the specified photo information if the specified token matches that of the last query. 100199c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon * 100299c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon * @param photo The photo as a drawable. 100399c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon * @param photoIcon The photo as a small icon. 100499c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon * @param token The token used with this query. 100599c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon */ 100699c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon private void setPhoto(Drawable photo, Bitmap photoIcon, int token) { 100799c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon if (mQueryToken == token) { 100899c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon mCallerInfo.cachedPhoto = photo; 100999c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon mCallerInfo.cachedPhotoIcon = photoIcon; 101064c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon 101164c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon for (Listener l : mListeners) { 101264c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon l.onCallerInfoChanged(this); 101364c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon } 1014fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon } 1015fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon } 1016ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad 1017ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad private void maybeLoadCannedSmsResponses() { 1018ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad if (mIsIncoming && isRespondViaSmsCapable() && !mCannedSmsResponsesLoadingStarted) { 1019ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad Log.d(this, "maybeLoadCannedSmsResponses: starting task to load messages"); 1020ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad mCannedSmsResponsesLoadingStarted = true; 1021ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad RespondViaSmsManager.getInstance().loadCannedTextMessages( 1022ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad new Response<Void, List<String>>() { 1023ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad @Override 1024ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad public void onResult(Void request, List<String>... result) { 1025ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad if (result.length > 0) { 1026ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad Log.d(this, "maybeLoadCannedSmsResponses: got %s", result[0]); 1027ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad mCannedSmsResponses = result[0]; 1028ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad for (Listener l : mListeners) { 1029ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad l.onCannedSmsResponsesLoaded(Call.this); 1030ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad } 1031ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad } 1032ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad } 1033ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad 1034ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad @Override 1035ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad public void onError(Void request, int code, String msg) { 1036ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad Log.w(Call.this, "Error obtaining canned SMS responses: %d %s", code, 1037ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad msg); 1038ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad } 1039ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad } 1040ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad ); 1041ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad } else { 1042ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad Log.d(this, "maybeLoadCannedSmsResponses: doing nothing"); 1043ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad } 1044ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad } 1045b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati 1046b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati /** 1047b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati * Sets speakerphone option on when call begins. 1048b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati */ 1049b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati public void setStartWithSpeakerphoneOn(boolean startWithSpeakerphone) { 1050b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati mSpeakerphoneOn = startWithSpeakerphone; 1051b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati } 1052b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati 1053b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati /** 1054b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati * Returns speakerphone option. 1055b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati * 1056b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati * @return Whether or not speakerphone should be set automatically when call begins. 1057b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati */ 1058b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati public boolean getStartWithSpeakerphoneOn() { 1059b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati return mSpeakerphoneOn; 1060b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati } 1061e9a776560dfe6f000cfc0dc1ea36c0f37d937f53Andrew Lee 1062e9a776560dfe6f000cfc0dc1ea36c0f37d937f53Andrew Lee /** 1063e9a776560dfe6f000cfc0dc1ea36c0f37d937f53Andrew Lee * Sets a call video provider for the call. 1064e9a776560dfe6f000cfc0dc1ea36c0f37d937f53Andrew Lee */ 1065a65d41fb134e323ab43c3f9454313b262959b1d0Nancy Chen public void setCallVideoProvider(ICallVideoProvider callVideoProvider) { 1066a65d41fb134e323ab43c3f9454313b262959b1d0Nancy Chen mCallVideoProvider = callVideoProvider; 1067a65d41fb134e323ab43c3f9454313b262959b1d0Nancy Chen for (Listener l : mListeners) { 1068a65d41fb134e323ab43c3f9454313b262959b1d0Nancy Chen l.onCallVideoProviderChanged(Call.this); 1069a65d41fb134e323ab43c3f9454313b262959b1d0Nancy Chen } 1070a65d41fb134e323ab43c3f9454313b262959b1d0Nancy Chen } 1071a65d41fb134e323ab43c3f9454313b262959b1d0Nancy Chen 1072a65d41fb134e323ab43c3f9454313b262959b1d0Nancy Chen /** 1073a65d41fb134e323ab43c3f9454313b262959b1d0Nancy Chen * @return Return the call video Provider binder. 1074a65d41fb134e323ab43c3f9454313b262959b1d0Nancy Chen */ 1075a65d41fb134e323ab43c3f9454313b262959b1d0Nancy Chen public ICallVideoProvider getCallVideoProvider() { 1076a65d41fb134e323ab43c3f9454313b262959b1d0Nancy Chen return mCallVideoProvider; 1077e9a776560dfe6f000cfc0dc1ea36c0f37d937f53Andrew Lee } 1078e19cc005ddbff5313d6f7288587630b2410d005cTyler Gunn 1079e19cc005ddbff5313d6f7288587630b2410d005cTyler Gunn /** 1080c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn * The current video state for the call. 1081c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn * Valid values: {@link android.telecomm.VideoCallProfile#VIDEO_STATE_AUDIO_ONLY}, 1082c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn * {@link android.telecomm.VideoCallProfile#VIDEO_STATE_BIDIRECTIONAL}, 1083c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn * {@link android.telecomm.VideoCallProfile#VIDEO_STATE_TX_ENABLED}, 1084c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn * {@link android.telecomm.VideoCallProfile#VIDEO_STATE_RX_ENABLED}. 1085c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn * 1086c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn * @return True if video is enabled. 1087c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn */ 1088c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn public int getVideoState() { 1089c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn return mVideoState; 1090c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn } 1091c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn 1092c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn /** 10930a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn * Returns the video states which were applicable over the duration of a call. 10940a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn * See {@link android.telecomm.VideoCallProfile} for a list of valid video states. 10950a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn * 10960a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn * @return The video states applicable over the duration of the call. 10970a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn */ 10980a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn public int getVideoStateHistory() { 10990a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn return mVideoStateHistory; 11000a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn } 11010a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn 11020a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn /** 11030a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn * Determines the current video state for the call. 11040a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn * For an outgoing call determines the desired video state for the call. 1105c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn * Valid values: {@link android.telecomm.VideoCallProfile#VIDEO_STATE_AUDIO_ONLY}, 1106c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn * {@link android.telecomm.VideoCallProfile#VIDEO_STATE_BIDIRECTIONAL}, 1107c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn * {@link android.telecomm.VideoCallProfile#VIDEO_STATE_TX_ENABLED}, 1108c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn * {@link android.telecomm.VideoCallProfile#VIDEO_STATE_RX_ENABLED}. 1109c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn * 11100a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn * @param videoState The video state for the call. 1111c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn */ 1112c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn public void setVideoState(int videoState) { 11130a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn // Track which video states were applicable over the duration of the call. 11140a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn mVideoStateHistory = mVideoStateHistory | videoState; 11150a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn 1116c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn mVideoState = videoState; 11174a79660c984d54679ad4d2bdc89e224d9c8c375bAndrew Lee for (Listener l : mListeners) { 11184a79660c984d54679ad4d2bdc89e224d9c8c375bAndrew Lee l.onVideoStateChanged(this); 11194a79660c984d54679ad4d2bdc89e224d9c8c375bAndrew Lee } 1120c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn } 11217e66957928c5c23a1028c8e2a2d7cf359cbfa44eSailesh Nepal 11227e66957928c5c23a1028c8e2a2d7cf359cbfa44eSailesh Nepal public boolean getAudioModeIsVoip() { 11237e66957928c5c23a1028c8e2a2d7cf359cbfa44eSailesh Nepal return mAudioModeIsVoip; 11247e66957928c5c23a1028c8e2a2d7cf359cbfa44eSailesh Nepal } 11257e66957928c5c23a1028c8e2a2d7cf359cbfa44eSailesh Nepal 11267e66957928c5c23a1028c8e2a2d7cf359cbfa44eSailesh Nepal public void setAudioModeIsVoip(boolean audioModeIsVoip) { 11277e66957928c5c23a1028c8e2a2d7cf359cbfa44eSailesh Nepal mAudioModeIsVoip = audioModeIsVoip; 11287e66957928c5c23a1028c8e2a2d7cf359cbfa44eSailesh Nepal for (Listener l : mListeners) { 112935faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal l.onAudioModeIsVoipChanged(this); 113035faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal } 113135faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal } 113235faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal 113335faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal public StatusHints getStatusHints() { 113435faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal return mStatusHints; 113535faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal } 113635faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal 113735faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal public void setStatusHints(StatusHints statusHints) { 113835faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal mStatusHints = statusHints; 113935faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal for (Listener l : mListeners) { 114035faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal l.onStatusHintsChanged(this); 11417e66957928c5c23a1028c8e2a2d7cf359cbfa44eSailesh Nepal } 11427e66957928c5c23a1028c8e2a2d7cf359cbfa44eSailesh Nepal } 11439d58de5df05d0358fc8ae57ab7e9a0c45337c602Sailesh Nepal 11449d58de5df05d0358fc8ae57ab7e9a0c45337c602Sailesh Nepal public void startActivityFromInCall(PendingIntent intent) { 11459d58de5df05d0358fc8ae57ab7e9a0c45337c602Sailesh Nepal if (intent.isActivity()) { 11469d58de5df05d0358fc8ae57ab7e9a0c45337c602Sailesh Nepal for (Listener l : mListeners) { 11479d58de5df05d0358fc8ae57ab7e9a0c45337c602Sailesh Nepal l.onStartActivityFromInCall(this, intent); 11489d58de5df05d0358fc8ae57ab7e9a0c45337c602Sailesh Nepal } 11499d58de5df05d0358fc8ae57ab7e9a0c45337c602Sailesh Nepal } else { 11509d58de5df05d0358fc8ae57ab7e9a0c45337c602Sailesh Nepal Log.w(this, "startActivityFromInCall, activity intent required"); 11519d58de5df05d0358fc8ae57ab7e9a0c45337c602Sailesh Nepal } 11529d58de5df05d0358fc8ae57ab7e9a0c45337c602Sailesh Nepal } 115372890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon 115472890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon private CallState getStateFromConnectionState(int state) { 115572890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon switch (state) { 115672890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon case Connection.State.ACTIVE: 115772890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon return CallState.ACTIVE; 115872890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon case Connection.State.DIALING: 115972890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon return CallState.DIALING; 116072890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon case Connection.State.DISCONNECTED: 116172890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon return CallState.DISCONNECTED; 116272890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon case Connection.State.HOLDING: 116372890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon return CallState.ON_HOLD; 116472890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon case Connection.State.NEW: 116572890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon return CallState.NEW; 116672890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon case Connection.State.RINGING: 116772890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon return CallState.RINGING; 116872890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon } 116972890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon return CallState.DISCONNECTED; 117072890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon } 11719f2bed31374a56487f370be01224baf6ce97e8adBen Gilad} 1172