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 177cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnpackage com.android.server.telecom; 189f2bed31374a56487f370be01224baf6ce97e8adBen Gilad 1991d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunnimport android.content.Context; 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; 25e4a9c412f5c6f76f006659f0b4e171ef4547dc45Yorke Leeimport android.os.Trace; 268a736a887b50d4d042c008b2073e24e1b4681dfbYorke Leeimport android.provider.ContactsContract.Contacts; 277cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.CallState; 28701dc006ac11625b55d872f1639107b028933895Andrew Leeimport android.telecom.DisconnectCause; 297cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.Connection; 307cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.GatewayInfo; 317cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.ParcelableConnection; 327cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.PhoneAccount; 337cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.PhoneAccountHandle; 347cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.Response; 357cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.StatusHints; 367cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.TelecomManager; 377cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.VideoProfile; 386aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepalimport android.telephony.PhoneNumberUtils; 39fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordonimport android.text.TextUtils; 400b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon 417cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport com.android.internal.telecom.IVideoProvider; 42fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordonimport com.android.internal.telephony.CallerInfo; 43fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordonimport com.android.internal.telephony.CallerInfoAsyncQuery; 44fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordonimport com.android.internal.telephony.CallerInfoAsyncQuery.OnQueryCompleteListener; 45ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awadimport com.android.internal.telephony.SmsApplication; 467cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport com.android.server.telecom.ContactsAsyncHelper.OnImageLoadCompleteListener; 4791d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunnimport com.android.internal.util.Preconditions; 4861d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon 4912d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordonimport java.util.ArrayList; 50ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awadimport java.util.Collections; 51a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordonimport java.util.LinkedList; 52a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordonimport java.util.List; 539199078322aea6df26f0d304a28a9a6d040f0717Sailesh Nepalimport java.util.Locale; 54e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepalimport java.util.Objects; 556192561b1f56d7c4e6c650e178e07ba61ad02667Ben Giladimport java.util.Set; 56a82c8f794a0a1a9eaa1329a6361abe28043d139aJay Shraunerimport java.util.concurrent.ConcurrentHashMap; 570407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad 582495d57b5b91f3a39529d8844a49d1be5f18b137Ben Gilad/** 592495d57b5b91f3a39529d8844a49d1be5f18b137Ben Gilad * Encapsulates all aspects of a given phone call throughout its lifecycle, starting 607cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunn * from the time the call intent was received by Telecom (vs. the time the call was 612495d57b5b91f3a39529d8844a49d1be5f18b137Ben Gilad * connected etc). 622495d57b5b91f3a39529d8844a49d1be5f18b137Ben Gilad */ 63664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepalfinal class Call implements CreateConnectionResponse { 64766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon /** 65766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon * Listener for events on the call. 66766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon */ 67766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon interface Listener { 686fb37c87836b5245046bd3b14320823ab839a10cIhab Awad void onSuccessfulOutgoingCall(Call call, int callState); 69701dc006ac11625b55d872f1639107b028933895Andrew Lee void onFailedOutgoingCall(Call call, DisconnectCause disconnectCause); 70c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal void onSuccessfulIncomingCall(Call call); 71766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon void onFailedIncomingCall(Call call); 729250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee void onSuccessfulUnknownCall(Call call, int callState); 739250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee void onFailedUnknownCall(Call call); 745be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee void onRingbackRequested(Call call, boolean ringbackRequested); 75352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton void onPostDialWait(Call call, String remaining); 76a469f76c1710a945933910840f11f9fda0445d82Nancy Chen void onPostDialChar(Call call, char nextChar); 7707bc5ee853bc9a0b4cd46e0c702888b2c7989392Ihab Awad void onConnectionCapabilitiesChanged(Call call); 78a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon void onParentChanged(Call call); 79a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon void onChildrenChanged(Call call); 80ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad void onCannedSmsResponsesLoaded(Call call); 813bcf935b25470e94c8c6855862434d15b785c54aAndrew Lee void onVideoCallProviderChanged(Call call); 8264c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon void onCallerInfoChanged(Call call); 835be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee void onIsVoipAudioModeChanged(Call call); 8435faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal void onStatusHintsChanged(Call call); 85e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal void onHandleChanged(Call call); 86e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal void onCallerDisplayNameChanged(Call call); 874a79660c984d54679ad4d2bdc89e224d9c8c375bAndrew Lee void onVideoStateChanged(Call call); 88b78b27693afbe9736f0a54ec473328955251f885Ihab Awad void onTargetPhoneAccountChanged(Call call); 89b78b27693afbe9736f0a54ec473328955251f885Ihab Awad void onConnectionManagerPhoneAccountChanged(Call call); 9012d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon void onPhoneAccountChanged(Call call); 9112d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon void onConferenceableCallsChanged(Call call); 92cf5b2918ca58b155911a66222ae5b4d21cb5b8ecSantos Cordon boolean onCanceledViaNewOutgoingCallBroadcast(Call call); 9364c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon } 9464c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon 9564c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon abstract static class ListenerBase implements Listener { 9664c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon @Override 976fb37c87836b5245046bd3b14320823ab839a10cIhab Awad public void onSuccessfulOutgoingCall(Call call, int callState) {} 9864c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon @Override 99701dc006ac11625b55d872f1639107b028933895Andrew Lee public void onFailedOutgoingCall(Call call, DisconnectCause disconnectCause) {} 10064c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon @Override 101c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal public void onSuccessfulIncomingCall(Call call) {} 10264c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon @Override 10364c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon public void onFailedIncomingCall(Call call) {} 10464c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon @Override 1059250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee public void onSuccessfulUnknownCall(Call call, int callState) {} 1069250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee @Override 1079250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee public void onFailedUnknownCall(Call call) {} 1089250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee @Override 1095be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee public void onRingbackRequested(Call call, boolean ringbackRequested) {} 11064c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon @Override 11164c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon public void onPostDialWait(Call call, String remaining) {} 11264c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon @Override 113a469f76c1710a945933910840f11f9fda0445d82Nancy Chen public void onPostDialChar(Call call, char nextChar) {} 114a469f76c1710a945933910840f11f9fda0445d82Nancy Chen @Override 11507bc5ee853bc9a0b4cd46e0c702888b2c7989392Ihab Awad public void onConnectionCapabilitiesChanged(Call call) {} 11664c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon @Override 11764c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon public void onParentChanged(Call call) {} 11864c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon @Override 11964c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon public void onChildrenChanged(Call call) {} 12064c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon @Override 12164c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon public void onCannedSmsResponsesLoaded(Call call) {} 12264c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon @Override 1233bcf935b25470e94c8c6855862434d15b785c54aAndrew Lee public void onVideoCallProviderChanged(Call call) {} 12464c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon @Override 12564c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon public void onCallerInfoChanged(Call call) {} 1267e66957928c5c23a1028c8e2a2d7cf359cbfa44eSailesh Nepal @Override 1275be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee public void onIsVoipAudioModeChanged(Call call) {} 12835faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal @Override 12935faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal public void onStatusHintsChanged(Call call) {} 130e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal @Override 131e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal public void onHandleChanged(Call call) {} 132e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal @Override 133e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal public void onCallerDisplayNameChanged(Call call) {} 1344a79660c984d54679ad4d2bdc89e224d9c8c375bAndrew Lee @Override 1354a79660c984d54679ad4d2bdc89e224d9c8c375bAndrew Lee public void onVideoStateChanged(Call call) {} 1369d58de5df05d0358fc8ae57ab7e9a0c45337c602Sailesh Nepal @Override 137b78b27693afbe9736f0a54ec473328955251f885Ihab Awad public void onTargetPhoneAccountChanged(Call call) {} 138b78b27693afbe9736f0a54ec473328955251f885Ihab Awad @Override 139b78b27693afbe9736f0a54ec473328955251f885Ihab Awad public void onConnectionManagerPhoneAccountChanged(Call call) {} 14012d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon @Override 14112d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon public void onPhoneAccountChanged(Call call) {} 14212d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon @Override 14312d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon public void onConferenceableCallsChanged(Call call) {} 144cf5b2918ca58b155911a66222ae5b4d21cb5b8ecSantos Cordon @Override 145cf5b2918ca58b155911a66222ae5b4d21cb5b8ecSantos Cordon public boolean onCanceledViaNewOutgoingCallBroadcast(Call call) { 146cf5b2918ca58b155911a66222ae5b4d21cb5b8ecSantos Cordon return false; 147cf5b2918ca58b155911a66222ae5b4d21cb5b8ecSantos Cordon } 148766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon } 149766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon 150fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon private static final OnQueryCompleteListener sCallerInfoQueryListener = 15199c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon new OnQueryCompleteListener() { 15299c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon /** ${inheritDoc} */ 15399c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon @Override 15499c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon public void onQueryComplete(int token, Object cookie, CallerInfo callerInfo) { 15599c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon if (cookie != null) { 15699c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon ((Call) cookie).setCallerInfo(callerInfo, token); 15799c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon } 158fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon } 15999c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon }; 16099c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon 16199c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon private static final OnImageLoadCompleteListener sPhotoLoadListener = 16299c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon new OnImageLoadCompleteListener() { 16399c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon /** ${inheritDoc} */ 16499c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon @Override 16599c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon public void onImageLoadComplete( 16699c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon int token, Drawable photo, Bitmap photoIcon, Object cookie) { 16799c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon if (cookie != null) { 16899c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon ((Call) cookie).setPhoto(photo, photoIcon, token); 16999c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon } 17099c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon } 17199c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon }; 1720407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad 173664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal private final Runnable mDirectToVoicemailRunnable = new Runnable() { 174664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal @Override 175664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal public void run() { 176664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal processDirectToVoicemail(); 177664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal } 178664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal }; 179664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal 180810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal /** True if this is an incoming call. */ 181810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal private final boolean mIsIncoming; 182810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal 1839250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee /** True if this is a currently unknown call that was not previously tracked by CallsManager, 1849250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee * and did not originate via the regular incoming/outgoing call code paths. 1859250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee */ 1869250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee private boolean mIsUnknown; 1879250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee 1880407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad /** 189664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal * The time this call was created. Beyond logging and such, may also be used for bookkeeping 190664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal * and specifically for marking certain call attempts as failed attempts. 1910407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad */ 1920c1e4f6713d04f193e211e0b3d25968c0ece8535Yorke Lee private long mCreationTimeMillis = System.currentTimeMillis(); 1938c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal 19440f9b179e6aaa0d906d38a48040425f82727aab4Santos Cordon /** The time this call was made active. */ 19540f9b179e6aaa0d906d38a48040425f82727aab4Santos Cordon private long mConnectTimeMillis = 0; 19640f9b179e6aaa0d906d38a48040425f82727aab4Santos Cordon 19740f9b179e6aaa0d906d38a48040425f82727aab4Santos Cordon /** The time this call was disconnected. */ 19840f9b179e6aaa0d906d38a48040425f82727aab4Santos Cordon private long mDisconnectTimeMillis = 0; 19940f9b179e6aaa0d906d38a48040425f82727aab4Santos Cordon 200fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon /** The gateway information associated with this call. This stores the original call handle 201fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon * that the user is attempting to connect to via the gateway, the actual handle to dial in 202fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon * order to connect the call via the gateway, as well as the package name of the gateway 203fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon * service. */ 2040d3076c3dfa54f1102a843735ca774759e52d8b8Nancy Chen private GatewayInfo mGatewayInfo; 205fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon 206b78b27693afbe9736f0a54ec473328955251f885Ihab Awad private PhoneAccountHandle mConnectionManagerPhoneAccountHandle; 207b78b27693afbe9736f0a54ec473328955251f885Ihab Awad 208b78b27693afbe9736f0a54ec473328955251f885Ihab Awad private PhoneAccountHandle mTargetPhoneAccountHandle; 20977d2d0e90bc2a67d526743b8e32f920a0d755fbaNancy Chen 2102174fb56907fddf5680355e097f4425f837983e2Santos Cordon private final Handler mHandler = new Handler(); 2112174fb56907fddf5680355e097f4425f837983e2Santos Cordon 21212d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon private final List<Call> mConferenceableCalls = new ArrayList<>(); 21312d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon 21461d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon /** The state of the call. */ 2156fb37c87836b5245046bd3b14320823ab839a10cIhab Awad private int mState; 21661d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon 21761d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon /** The handle with which to establish this call. */ 218ce704b9a5d9cf7db30a8c865975c70e5cbc0dc5cSailesh Nepal private Uri mHandle; 21961d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon 220201b437535ebd07a3d8bf771920a4cb72d145ff3Nancy Chen /** 2217cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunn * The presentation requirements for the handle. See {@link TelecomManager} for valid values. 222201b437535ebd07a3d8bf771920a4cb72d145ff3Nancy Chen */ 223e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal private int mHandlePresentation; 224e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal 225e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal /** The caller display name (CNAP) set by the connection service. */ 226e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal private String mCallerDisplayName; 227e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal 228201b437535ebd07a3d8bf771920a4cb72d145ff3Nancy Chen /** 2297cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunn * The presentation requirements for the handle. See {@link TelecomManager} for valid values. 230201b437535ebd07a3d8bf771920a4cb72d145ff3Nancy Chen */ 231e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal private int mCallerDisplayNamePresentation; 232e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal 2330407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad /** 234c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal * The connection service which is attempted or already connecting this call. 235681663d17b6d92b604526a54b196fa88f25b6957Santos Cordon */ 236c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal private ConnectionServiceWrapper mConnectionService; 2376192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad 2386aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal private boolean mIsEmergencyCall; 2396aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal 240b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati private boolean mSpeakerphoneOn; 241b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati 2420a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn /** 2430a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn * Tracks the video states which were applicable over the duration of a call. 2446fb37c87836b5245046bd3b14320823ab839a10cIhab Awad * See {@link VideoProfile} for a list of valid video states. 2450a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn */ 2460a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn private int mVideoStateHistory; 2470a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn 248c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn private int mVideoState; 249c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn 2506192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad /** 2516fb37c87836b5245046bd3b14320823ab839a10cIhab Awad * Disconnect cause for the call. Only valid if the state of the call is STATE_DISCONNECTED. 252701dc006ac11625b55d872f1639107b028933895Andrew Lee * See {@link android.telecom.DisconnectCause}. 25379ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon */ 254701dc006ac11625b55d872f1639107b028933895Andrew Lee private DisconnectCause mDisconnectCause = new DisconnectCause(DisconnectCause.UNKNOWN); 25579ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon 256c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal /** Info used by the connection services. */ 2578c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal private Bundle mExtras = Bundle.EMPTY; 25884fa5f8c59a1cd3c5716c239fb19c58244fc81feSailesh Nepal 259a82c8f794a0a1a9eaa1329a6361abe28043d139aJay Shrauner /** Set of listeners on this call. 260a82c8f794a0a1a9eaa1329a6361abe28043d139aJay Shrauner * 261a82c8f794a0a1a9eaa1329a6361abe28043d139aJay Shrauner * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is 262a82c8f794a0a1a9eaa1329a6361abe28043d139aJay Shrauner * load factor before resizing, 1 means we only expect a single thread to 263a82c8f794a0a1a9eaa1329a6361abe28043d139aJay Shrauner * access the map so make only a single shard 264a82c8f794a0a1a9eaa1329a6361abe28043d139aJay Shrauner */ 265a82c8f794a0a1a9eaa1329a6361abe28043d139aJay Shrauner private final Set<Listener> mListeners = Collections.newSetFromMap( 266a82c8f794a0a1a9eaa1329a6361abe28043d139aJay Shrauner new ConcurrentHashMap<Listener, Boolean>(8, 0.9f, 1)); 267766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon 268664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal private CreateConnectionProcessor mCreateConnectionProcessor; 269682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon 270fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon /** Caller information retrieved from the latest contact query. */ 271fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon private CallerInfo mCallerInfo; 272fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon 273fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon /** The latest token used with a contact info query. */ 274fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon private int mQueryToken = 0; 275fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon 2767cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunn /** Whether this call is requesting that Telecom play the ringback tone on its behalf. */ 2775be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee private boolean mRingbackRequested = false; 278cb387ac1bb278de62e352b363cb38339629a61f5Ihab Awad 279c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal /** Whether direct-to-voicemail query is pending. */ 280c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal private boolean mDirectToVoicemailQueryPending; 2812174fb56907fddf5680355e097f4425f837983e2Santos Cordon 28207bc5ee853bc9a0b4cd46e0c702888b2c7989392Ihab Awad private int mConnectionCapabilities; 283a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon 284a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon private boolean mIsConference = false; 285a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon 286a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon private Call mParentCall = null; 287a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon 288a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon private List<Call> mChildCalls = new LinkedList<>(); 289a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon 290ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad /** Set of text message responses allowed for this call, if applicable. */ 291ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad private List<String> mCannedSmsResponses = Collections.EMPTY_LIST; 292ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad 293ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad /** Whether an attempt has been made to load the text message responses. */ 294ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad private boolean mCannedSmsResponsesLoadingStarted = false; 295ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad 2966fb37c87836b5245046bd3b14320823ab839a10cIhab Awad private IVideoProvider mVideoProvider; 297a65d41fb134e323ab43c3f9454313b262959b1d0Nancy Chen 2985be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee private boolean mIsVoipAudioMode; 29935faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal private StatusHints mStatusHints; 300664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal private final ConnectionServiceRepository mRepository; 30191d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn private final Context mContext; 3027e66957928c5c23a1028c8e2a2d7cf359cbfa44eSailesh Nepal 30388a4a60284de8e1222488667b810b098c16d22acSantos Cordon private boolean mWasConferencePreviouslyMerged = false; 30488a4a60284de8e1222488667b810b098c16d22acSantos Cordon 30588a4a60284de8e1222488667b810b098c16d22acSantos Cordon // For conferences which support merge/swap at their level, we retain a notion of an active call. 30688a4a60284de8e1222488667b810b098c16d22acSantos Cordon // This is used for BluetoothPhoneService. In order to support hold/merge, it must have the notion 30788a4a60284de8e1222488667b810b098c16d22acSantos Cordon // of the current "active" call within the conference call. This maintains the "active" call and 30888a4a60284de8e1222488667b810b098c16d22acSantos Cordon // switches every time the user hits "swap". 30988a4a60284de8e1222488667b810b098c16d22acSantos Cordon private Call mConferenceLevelActiveCall = null; 31088a4a60284de8e1222488667b810b098c16d22acSantos Cordon 311aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn private boolean mIsLocallyDisconnecting = false; 312aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn 3138c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal /** 3140407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad * Persists the specified parameters and initializes the new instance. 3150407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad * 31691d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn * @param context The context. 31791d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn * @param repository The connection service repository. 3180407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad * @param handle The handle to dial. 31933501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee * @param gatewayInfo Gateway information to use for the call. 320b78b27693afbe9736f0a54ec473328955251f885Ihab Awad * @param connectionManagerPhoneAccountHandle Account to use for the service managing the call. 321b78b27693afbe9736f0a54ec473328955251f885Ihab Awad * This account must be one that was registered with the 322b78b27693afbe9736f0a54ec473328955251f885Ihab Awad * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER} flag. 323b78b27693afbe9736f0a54ec473328955251f885Ihab Awad * @param targetPhoneAccountHandle Account information to use for the call. This account must be 324b78b27693afbe9736f0a54ec473328955251f885Ihab Awad * one that was registered with the {@link PhoneAccount#CAPABILITY_CALL_PROVIDER} flag. 325810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal * @param isIncoming True if this is an incoming call. 3260407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad */ 327664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal Call( 32891d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn Context context, 329664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal ConnectionServiceRepository repository, 330664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal Uri handle, 331664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal GatewayInfo gatewayInfo, 332b78b27693afbe9736f0a54ec473328955251f885Ihab Awad PhoneAccountHandle connectionManagerPhoneAccountHandle, 333b78b27693afbe9736f0a54ec473328955251f885Ihab Awad PhoneAccountHandle targetPhoneAccountHandle, 334664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal boolean isIncoming, 335664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal boolean isConference) { 336a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon mState = isConference ? CallState.ACTIVE : CallState.NEW; 33791d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn mContext = context; 338664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal mRepository = repository; 3390d3076c3dfa54f1102a843735ca774759e52d8b8Nancy Chen setHandle(handle); 3407cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunn setHandle(handle, TelecomManager.PRESENTATION_ALLOWED); 34133501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee mGatewayInfo = gatewayInfo; 342f193ba45fae5bc87e6a57779e4f5b56be59d08b0Santos Cordon setConnectionManagerPhoneAccount(connectionManagerPhoneAccountHandle); 343f193ba45fae5bc87e6a57779e4f5b56be59d08b0Santos Cordon setTargetPhoneAccount(targetPhoneAccountHandle); 344810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal mIsIncoming = isIncoming; 345a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon mIsConference = isConference; 346ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad maybeLoadCannedSmsResponses(); 3470407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad } 3480407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad 349d92e73772327537fe65edda43ca0ceb6fc781e51Tyler Gunn /** 350d92e73772327537fe65edda43ca0ceb6fc781e51Tyler Gunn * Persists the specified parameters and initializes the new instance. 351d92e73772327537fe65edda43ca0ceb6fc781e51Tyler Gunn * 352d92e73772327537fe65edda43ca0ceb6fc781e51Tyler Gunn * @param context The context. 353d92e73772327537fe65edda43ca0ceb6fc781e51Tyler Gunn * @param repository The connection service repository. 354d92e73772327537fe65edda43ca0ceb6fc781e51Tyler Gunn * @param handle The handle to dial. 355d92e73772327537fe65edda43ca0ceb6fc781e51Tyler Gunn * @param gatewayInfo Gateway information to use for the call. 356d92e73772327537fe65edda43ca0ceb6fc781e51Tyler Gunn * @param connectionManagerPhoneAccountHandle Account to use for the service managing the call. 357d92e73772327537fe65edda43ca0ceb6fc781e51Tyler Gunn * This account must be one that was registered with the 358d92e73772327537fe65edda43ca0ceb6fc781e51Tyler Gunn * {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER} flag. 359d92e73772327537fe65edda43ca0ceb6fc781e51Tyler Gunn * @param targetPhoneAccountHandle Account information to use for the call. This account must be 360d92e73772327537fe65edda43ca0ceb6fc781e51Tyler Gunn * one that was registered with the {@link PhoneAccount#CAPABILITY_CALL_PROVIDER} flag. 361d92e73772327537fe65edda43ca0ceb6fc781e51Tyler Gunn * @param isIncoming True if this is an incoming call. 362d92e73772327537fe65edda43ca0ceb6fc781e51Tyler Gunn * @param connectTimeMillis The connection time of the call. 363d92e73772327537fe65edda43ca0ceb6fc781e51Tyler Gunn */ 364d92e73772327537fe65edda43ca0ceb6fc781e51Tyler Gunn Call( 365d92e73772327537fe65edda43ca0ceb6fc781e51Tyler Gunn Context context, 366d92e73772327537fe65edda43ca0ceb6fc781e51Tyler Gunn ConnectionServiceRepository repository, 367d92e73772327537fe65edda43ca0ceb6fc781e51Tyler Gunn Uri handle, 368d92e73772327537fe65edda43ca0ceb6fc781e51Tyler Gunn GatewayInfo gatewayInfo, 369d92e73772327537fe65edda43ca0ceb6fc781e51Tyler Gunn PhoneAccountHandle connectionManagerPhoneAccountHandle, 370d92e73772327537fe65edda43ca0ceb6fc781e51Tyler Gunn PhoneAccountHandle targetPhoneAccountHandle, 371d92e73772327537fe65edda43ca0ceb6fc781e51Tyler Gunn boolean isIncoming, 372d92e73772327537fe65edda43ca0ceb6fc781e51Tyler Gunn boolean isConference, 373d92e73772327537fe65edda43ca0ceb6fc781e51Tyler Gunn long connectTimeMillis) { 374d92e73772327537fe65edda43ca0ceb6fc781e51Tyler Gunn this(context, repository, handle, gatewayInfo, connectionManagerPhoneAccountHandle, 375d92e73772327537fe65edda43ca0ceb6fc781e51Tyler Gunn targetPhoneAccountHandle, isIncoming, isConference); 376d92e73772327537fe65edda43ca0ceb6fc781e51Tyler Gunn 377d92e73772327537fe65edda43ca0ceb6fc781e51Tyler Gunn mConnectTimeMillis = connectTimeMillis; 378d92e73772327537fe65edda43ca0ceb6fc781e51Tyler Gunn } 379d92e73772327537fe65edda43ca0ceb6fc781e51Tyler Gunn 380766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon void addListener(Listener listener) { 381766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon mListeners.add(listener); 382766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon } 383766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon 384766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon void removeListener(Listener listener) { 385a82c8f794a0a1a9eaa1329a6361abe28043d139aJay Shrauner if (listener != null) { 386a82c8f794a0a1a9eaa1329a6361abe28043d139aJay Shrauner mListeners.remove(listener); 387a82c8f794a0a1a9eaa1329a6361abe28043d139aJay Shrauner } 388766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon } 389766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon 39061d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon /** {@inheritDoc} */ 39112d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon @Override 39212d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon public String toString() { 3934538f01647fa207b41fb7e481cc180e67fd391deSailesh Nepal String component = null; 394c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal if (mConnectionService != null && mConnectionService.getComponentName() != null) { 395c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal component = mConnectionService.getComponentName().flattenToShortString(); 3964538f01647fa207b41fb7e481cc180e67fd391deSailesh Nepal } 3970a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn 39866fe882a6437de1010af0dc8cd7350f81f2e028aSantos Cordon return String.format(Locale.US, "[%s, %s, %s, %s, %d, childs(%d), has_parent(%b), [%s]", 39966fe882a6437de1010af0dc8cd7350f81f2e028aSantos Cordon System.identityHashCode(this), 40066fe882a6437de1010af0dc8cd7350f81f2e028aSantos Cordon CallState.toString(mState), 40166fe882a6437de1010af0dc8cd7350f81f2e028aSantos Cordon component, 40266fe882a6437de1010af0dc8cd7350f81f2e028aSantos Cordon Log.piiHandle(mHandle), 40366fe882a6437de1010af0dc8cd7350f81f2e028aSantos Cordon getVideoState(), 40466fe882a6437de1010af0dc8cd7350f81f2e028aSantos Cordon getChildCalls().size(), 40566fe882a6437de1010af0dc8cd7350f81f2e028aSantos Cordon getParentCall() != null, 40607bc5ee853bc9a0b4cd46e0c702888b2c7989392Ihab Awad Connection.capabilitiesToString(getConnectionCapabilities())); 40761d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon } 40861d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon 4096fb37c87836b5245046bd3b14320823ab839a10cIhab Awad int getState() { 4100fbe6321e341ddce186634266dba2db3fa426b88Santos Cordon return mState; 4110b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon } 4120b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon 413646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal private boolean shouldContinueProcessingAfterDisconnect() { 414646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal // Stop processing once the call is active. 415646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal if (!CreateConnectionTimeout.isCallBeingPlaced(this)) { 416646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal return false; 417646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal } 418646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal 419646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal // Make sure that there are additional connection services to process. 420646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal if (mCreateConnectionProcessor == null 421646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal || !mCreateConnectionProcessor.isProcessingComplete() 422646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal || !mCreateConnectionProcessor.hasMorePhoneAccounts()) { 423646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal return false; 424646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal } 425646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal 426646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal if (mDisconnectCause == null) { 427646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal return false; 428646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal } 429646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal 430646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal // Continue processing if the current attempt failed or timed out. 431646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal return mDisconnectCause.getCode() == DisconnectCause.ERROR || 432646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal mCreateConnectionProcessor.isCallTimedOut(); 433646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal } 434646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal 4350b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon /** 4360b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon * Sets the call state. Although there exists the notion of appropriate state transitions 4370b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon * (see {@link CallState}), in practice those expectations break down when cellular systems 4380b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon * misbehave and they do this very often. The result is that we do not enforce state transitions 4390b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon * and instead keep the code resilient to unexpected state changes. 4400b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon */ 4416fb37c87836b5245046bd3b14320823ab839a10cIhab Awad void setState(int newState) { 442810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal if (mState != newState) { 443810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal Log.v(this, "setState %s -> %s", mState, newState); 4442767926bb2d241d651e823a25d5a24295c120ec5Sailesh Nepal 445646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal if (newState == CallState.DISCONNECTED && shouldContinueProcessingAfterDisconnect()) { 446646fa3d6eaea71fb4c3270fde1a30eeb7c5e4288Sailesh Nepal Log.w(this, "continuing processing disconnected call with another service"); 4472767926bb2d241d651e823a25d5a24295c120ec5Sailesh Nepal mCreateConnectionProcessor.continueProcessingIfPossible(this, mDisconnectCause); 4482767926bb2d241d651e823a25d5a24295c120ec5Sailesh Nepal return; 4492767926bb2d241d651e823a25d5a24295c120ec5Sailesh Nepal } 4502767926bb2d241d651e823a25d5a24295c120ec5Sailesh Nepal 451810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal mState = newState; 452ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad maybeLoadCannedSmsResponses(); 453672321e603555849831dd88d5c9f93d88143ee48Santos Cordon 45440f9b179e6aaa0d906d38a48040425f82727aab4Santos Cordon if (mState == CallState.ACTIVE || mState == CallState.ON_HOLD) { 45540f9b179e6aaa0d906d38a48040425f82727aab4Santos Cordon if (mConnectTimeMillis == 0) { 45640f9b179e6aaa0d906d38a48040425f82727aab4Santos Cordon // We check to see if mConnectTime is already set to prevent the 45740f9b179e6aaa0d906d38a48040425f82727aab4Santos Cordon // call from resetting active time when it goes in and out of 45840f9b179e6aaa0d906d38a48040425f82727aab4Santos Cordon // ACTIVE/ON_HOLD 45940f9b179e6aaa0d906d38a48040425f82727aab4Santos Cordon mConnectTimeMillis = System.currentTimeMillis(); 46040f9b179e6aaa0d906d38a48040425f82727aab4Santos Cordon } 46140f9b179e6aaa0d906d38a48040425f82727aab4Santos Cordon 46240f9b179e6aaa0d906d38a48040425f82727aab4Santos Cordon // We're clearly not disconnected, so reset the disconnected time. 46340f9b179e6aaa0d906d38a48040425f82727aab4Santos Cordon mDisconnectTimeMillis = 0; 46440f9b179e6aaa0d906d38a48040425f82727aab4Santos Cordon } else if (mState == CallState.DISCONNECTED) { 46540f9b179e6aaa0d906d38a48040425f82727aab4Santos Cordon mDisconnectTimeMillis = System.currentTimeMillis(); 4665dfd3800f15e9b0f1420813d8d7638e1cf9d621dSantos Cordon setLocallyDisconnecting(false); 467672321e603555849831dd88d5c9f93d88143ee48Santos Cordon fixParentAfterDisconnect(); 468672321e603555849831dd88d5c9f93d88143ee48Santos Cordon } 469810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal } 4700b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon } 4710b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon 4725be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee void setRingbackRequested(boolean ringbackRequested) { 4735be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee mRingbackRequested = ringbackRequested; 474cb387ac1bb278de62e352b363cb38339629a61f5Ihab Awad for (Listener l : mListeners) { 4755be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee l.onRingbackRequested(this, mRingbackRequested); 476cb387ac1bb278de62e352b363cb38339629a61f5Ihab Awad } 477cb387ac1bb278de62e352b363cb38339629a61f5Ihab Awad } 478cb387ac1bb278de62e352b363cb38339629a61f5Ihab Awad 4795be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee boolean isRingbackRequested() { 4805be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee return mRingbackRequested; 481cb387ac1bb278de62e352b363cb38339629a61f5Ihab Awad } 482cb387ac1bb278de62e352b363cb38339629a61f5Ihab Awad 483672321e603555849831dd88d5c9f93d88143ee48Santos Cordon boolean isConference() { 484672321e603555849831dd88d5c9f93d88143ee48Santos Cordon return mIsConference; 485672321e603555849831dd88d5c9f93d88143ee48Santos Cordon } 486672321e603555849831dd88d5c9f93d88143ee48Santos Cordon 487ce704b9a5d9cf7db30a8c865975c70e5cbc0dc5cSailesh Nepal Uri getHandle() { 4880bf5b912285e328a8f5eeec158d6caf17845b9f8Ben Gilad return mHandle; 4890bf5b912285e328a8f5eeec158d6caf17845b9f8Ben Gilad } 4900bf5b912285e328a8f5eeec158d6caf17845b9f8Ben Gilad 491e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal int getHandlePresentation() { 492e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal return mHandlePresentation; 493e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal } 494e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal 4950d3076c3dfa54f1102a843735ca774759e52d8b8Nancy Chen 4960d3076c3dfa54f1102a843735ca774759e52d8b8Nancy Chen void setHandle(Uri handle) { 4977cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunn setHandle(handle, TelecomManager.PRESENTATION_ALLOWED); 4980d3076c3dfa54f1102a843735ca774759e52d8b8Nancy Chen } 4990d3076c3dfa54f1102a843735ca774759e52d8b8Nancy Chen 500e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal void setHandle(Uri handle, int presentation) { 501e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal if (!Objects.equals(handle, mHandle) || presentation != mHandlePresentation) { 502e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal mHandlePresentation = presentation; 503ecaaeac225ada350b9b3acfb485583cc388050deSantos Cordon if (mHandlePresentation == TelecomManager.PRESENTATION_RESTRICTED || 504ecaaeac225ada350b9b3acfb485583cc388050deSantos Cordon mHandlePresentation == TelecomManager.PRESENTATION_UNKNOWN) { 505ecaaeac225ada350b9b3acfb485583cc388050deSantos Cordon mHandle = null; 506ecaaeac225ada350b9b3acfb485583cc388050deSantos Cordon } else { 507ecaaeac225ada350b9b3acfb485583cc388050deSantos Cordon mHandle = handle; 50896e662d3811673f284da0f9d2deabe939918a3b1Yorke Lee if (mHandle != null && !PhoneAccount.SCHEME_VOICEMAIL.equals(mHandle.getScheme()) 50996e662d3811673f284da0f9d2deabe939918a3b1Yorke Lee && TextUtils.isEmpty(mHandle.getSchemeSpecificPart())) { 51096e662d3811673f284da0f9d2deabe939918a3b1Yorke Lee // If the number is actually empty, set it to null, unless this is a 51196e662d3811673f284da0f9d2deabe939918a3b1Yorke Lee // SCHEME_VOICEMAIL uri which always has an empty number. 512ecaaeac225ada350b9b3acfb485583cc388050deSantos Cordon mHandle = null; 513ecaaeac225ada350b9b3acfb485583cc388050deSantos Cordon } 514ecaaeac225ada350b9b3acfb485583cc388050deSantos Cordon } 515ecaaeac225ada350b9b3acfb485583cc388050deSantos Cordon 51691d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn mIsEmergencyCall = mHandle != null && PhoneNumberUtils.isLocalEmergencyNumber(mContext, 51791d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn mHandle.getSchemeSpecificPart()); 518fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon startCallerInfoLookup(); 519e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal for (Listener l : mListeners) { 520e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal l.onHandleChanged(this); 521e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal } 522e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal } 523e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal } 524e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal 525e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal String getCallerDisplayName() { 526e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal return mCallerDisplayName; 527e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal } 528e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal 529e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal int getCallerDisplayNamePresentation() { 530e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal return mCallerDisplayNamePresentation; 531e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal } 532e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal 533e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal void setCallerDisplayName(String callerDisplayName, int presentation) { 534e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal if (!TextUtils.equals(callerDisplayName, mCallerDisplayName) || 535e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal presentation != mCallerDisplayNamePresentation) { 536e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal mCallerDisplayName = callerDisplayName; 537e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal mCallerDisplayNamePresentation = presentation; 538e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal for (Listener l : mListeners) { 539e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal l.onCallerDisplayNameChanged(this); 540e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal } 541fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon } 5426aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal } 5436aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal 54499c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon String getName() { 54599c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon return mCallerInfo == null ? null : mCallerInfo.name; 54699c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon } 54799c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon 54899c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon Bitmap getPhotoIcon() { 54999c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon return mCallerInfo == null ? null : mCallerInfo.cachedPhotoIcon; 55099c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon } 55199c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon 55299c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon Drawable getPhoto() { 55399c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon return mCallerInfo == null ? null : mCallerInfo.cachedPhoto; 55499c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon } 55599c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon 55679ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon /** 557701dc006ac11625b55d872f1639107b028933895Andrew Lee * @param disconnectCause The reason for the disconnection, represented by 558701dc006ac11625b55d872f1639107b028933895Andrew Lee * {@link android.telecom.DisconnectCause}. 55979ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon */ 560701dc006ac11625b55d872f1639107b028933895Andrew Lee void setDisconnectCause(DisconnectCause disconnectCause) { 56179ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon // TODO: Consider combining this method with a setDisconnected() method that is totally 56279ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon // separate from setState. 56379ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon mDisconnectCause = disconnectCause; 56479ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon } 56579ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon 566701dc006ac11625b55d872f1639107b028933895Andrew Lee DisconnectCause getDisconnectCause() { 56779ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon return mDisconnectCause; 56879ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon } 56979ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon 5706aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal boolean isEmergencyCall() { 5716aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal return mIsEmergencyCall; 57261d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon } 57361d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon 57433501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee /** 57533501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee * @return The original handle this call is associated with. In-call services should use this 57633501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee * handle when indicating in their UI the handle that is being called. 57733501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee */ 57833501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee public Uri getOriginalHandle() { 57933501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee if (mGatewayInfo != null && !mGatewayInfo.isEmpty()) { 580201b437535ebd07a3d8bf771920a4cb72d145ff3Nancy Chen return mGatewayInfo.getOriginalAddress(); 58133501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee } 58233501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee return getHandle(); 58333501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee } 58433501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee 58533501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee GatewayInfo getGatewayInfo() { 58633501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee return mGatewayInfo; 58733501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee } 58833501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee 5890d3076c3dfa54f1102a843735ca774759e52d8b8Nancy Chen void setGatewayInfo(GatewayInfo gatewayInfo) { 5900d3076c3dfa54f1102a843735ca774759e52d8b8Nancy Chen mGatewayInfo = gatewayInfo; 5910d3076c3dfa54f1102a843735ca774759e52d8b8Nancy Chen } 5920d3076c3dfa54f1102a843735ca774759e52d8b8Nancy Chen 593b78b27693afbe9736f0a54ec473328955251f885Ihab Awad PhoneAccountHandle getConnectionManagerPhoneAccount() { 594b78b27693afbe9736f0a54ec473328955251f885Ihab Awad return mConnectionManagerPhoneAccountHandle; 595b78b27693afbe9736f0a54ec473328955251f885Ihab Awad } 596b78b27693afbe9736f0a54ec473328955251f885Ihab Awad 597b78b27693afbe9736f0a54ec473328955251f885Ihab Awad void setConnectionManagerPhoneAccount(PhoneAccountHandle accountHandle) { 598b78b27693afbe9736f0a54ec473328955251f885Ihab Awad if (!Objects.equals(mConnectionManagerPhoneAccountHandle, accountHandle)) { 599b78b27693afbe9736f0a54ec473328955251f885Ihab Awad mConnectionManagerPhoneAccountHandle = accountHandle; 600b78b27693afbe9736f0a54ec473328955251f885Ihab Awad for (Listener l : mListeners) { 601b78b27693afbe9736f0a54ec473328955251f885Ihab Awad l.onConnectionManagerPhoneAccountChanged(this); 602b78b27693afbe9736f0a54ec473328955251f885Ihab Awad } 603b78b27693afbe9736f0a54ec473328955251f885Ihab Awad } 604b78b27693afbe9736f0a54ec473328955251f885Ihab Awad 605b78b27693afbe9736f0a54ec473328955251f885Ihab Awad } 606b78b27693afbe9736f0a54ec473328955251f885Ihab Awad 607b78b27693afbe9736f0a54ec473328955251f885Ihab Awad PhoneAccountHandle getTargetPhoneAccount() { 608b78b27693afbe9736f0a54ec473328955251f885Ihab Awad return mTargetPhoneAccountHandle; 60977d2d0e90bc2a67d526743b8e32f920a0d755fbaNancy Chen } 61077d2d0e90bc2a67d526743b8e32f920a0d755fbaNancy Chen 611b78b27693afbe9736f0a54ec473328955251f885Ihab Awad void setTargetPhoneAccount(PhoneAccountHandle accountHandle) { 612b78b27693afbe9736f0a54ec473328955251f885Ihab Awad if (!Objects.equals(mTargetPhoneAccountHandle, accountHandle)) { 613b78b27693afbe9736f0a54ec473328955251f885Ihab Awad mTargetPhoneAccountHandle = accountHandle; 61469eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad for (Listener l : mListeners) { 615b78b27693afbe9736f0a54ec473328955251f885Ihab Awad l.onTargetPhoneAccountChanged(this); 61669eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad } 61769eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad } 61853ceedc1f5ae5a075c7a3186db8bb4db32cbe583Nancy Chen } 61953ceedc1f5ae5a075c7a3186db8bb4db32cbe583Nancy Chen 620810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal boolean isIncoming() { 621810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal return mIsIncoming; 622810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal } 623810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal 6240407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad /** 6250407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad * @return The "age" of this call object in milliseconds, which typically also represents the 6268c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal * period since this call was added to the set pending outgoing calls, see 6278c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal * mCreationTimeMillis. 6280407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad */ 6298c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal long getAgeMillis() { 63040f9b179e6aaa0d906d38a48040425f82727aab4Santos Cordon if (mState == CallState.DISCONNECTED && 63140f9b179e6aaa0d906d38a48040425f82727aab4Santos Cordon (mDisconnectCause.getCode() == DisconnectCause.REJECTED || 63240f9b179e6aaa0d906d38a48040425f82727aab4Santos Cordon mDisconnectCause.getCode() == DisconnectCause.MISSED)) { 63340f9b179e6aaa0d906d38a48040425f82727aab4Santos Cordon // Rejected and missed calls have no age. They're immortal!! 63440f9b179e6aaa0d906d38a48040425f82727aab4Santos Cordon return 0; 63540f9b179e6aaa0d906d38a48040425f82727aab4Santos Cordon } else if (mConnectTimeMillis == 0) { 63640f9b179e6aaa0d906d38a48040425f82727aab4Santos Cordon // Age is measured in the amount of time the call was active. A zero connect time 63740f9b179e6aaa0d906d38a48040425f82727aab4Santos Cordon // indicates that we never went active, so return 0 for the age. 63840f9b179e6aaa0d906d38a48040425f82727aab4Santos Cordon return 0; 63940f9b179e6aaa0d906d38a48040425f82727aab4Santos Cordon } else if (mDisconnectTimeMillis == 0) { 64040f9b179e6aaa0d906d38a48040425f82727aab4Santos Cordon // We connected, but have not yet disconnected 64140f9b179e6aaa0d906d38a48040425f82727aab4Santos Cordon return System.currentTimeMillis() - mConnectTimeMillis; 64240f9b179e6aaa0d906d38a48040425f82727aab4Santos Cordon } 64340f9b179e6aaa0d906d38a48040425f82727aab4Santos Cordon 64440f9b179e6aaa0d906d38a48040425f82727aab4Santos Cordon return mDisconnectTimeMillis - mConnectTimeMillis; 6450407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad } 6460b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon 647f98fb5790ed62a3d4893362554f8d251c74d0ecdYorke Lee /** 648f98fb5790ed62a3d4893362554f8d251c74d0ecdYorke Lee * @return The time when this call object was created and added to the set of pending outgoing 649f98fb5790ed62a3d4893362554f8d251c74d0ecdYorke Lee * calls. 650f98fb5790ed62a3d4893362554f8d251c74d0ecdYorke Lee */ 6518c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal long getCreationTimeMillis() { 6528c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal return mCreationTimeMillis; 6538c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal } 6548c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal 6550c1e4f6713d04f193e211e0b3d25968c0ece8535Yorke Lee void setCreationTimeMillis(long time) { 6560c1e4f6713d04f193e211e0b3d25968c0ece8535Yorke Lee mCreationTimeMillis = time; 6570c1e4f6713d04f193e211e0b3d25968c0ece8535Yorke Lee } 6580c1e4f6713d04f193e211e0b3d25968c0ece8535Yorke Lee 6598c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal long getConnectTimeMillis() { 6608c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal return mConnectTimeMillis; 6618c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal } 6628c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal 66307bc5ee853bc9a0b4cd46e0c702888b2c7989392Ihab Awad int getConnectionCapabilities() { 66407bc5ee853bc9a0b4cd46e0c702888b2c7989392Ihab Awad return mConnectionCapabilities; 665a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 666a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon 66707bc5ee853bc9a0b4cd46e0c702888b2c7989392Ihab Awad void setConnectionCapabilities(int connectionCapabilities) { 66807bc5ee853bc9a0b4cd46e0c702888b2c7989392Ihab Awad setConnectionCapabilities(connectionCapabilities, false /* forceUpdate */); 669604a90f596deb41998e021151b3ddc8019e28eacYorke Lee } 670604a90f596deb41998e021151b3ddc8019e28eacYorke Lee 67107bc5ee853bc9a0b4cd46e0c702888b2c7989392Ihab Awad void setConnectionCapabilities(int connectionCapabilities, boolean forceUpdate) { 67207bc5ee853bc9a0b4cd46e0c702888b2c7989392Ihab Awad Log.v(this, "setConnectionCapabilities: %s", Connection.capabilitiesToString( 67307bc5ee853bc9a0b4cd46e0c702888b2c7989392Ihab Awad connectionCapabilities)); 67407bc5ee853bc9a0b4cd46e0c702888b2c7989392Ihab Awad if (forceUpdate || mConnectionCapabilities != connectionCapabilities) { 67507bc5ee853bc9a0b4cd46e0c702888b2c7989392Ihab Awad mConnectionCapabilities = connectionCapabilities; 676a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon for (Listener l : mListeners) { 67707bc5ee853bc9a0b4cd46e0c702888b2c7989392Ihab Awad l.onConnectionCapabilitiesChanged(this); 678a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 679a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 680a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 681a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon 682a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon Call getParentCall() { 683a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon return mParentCall; 684a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 685a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon 686a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon List<Call> getChildCalls() { 687a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon return mChildCalls; 688a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 689a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon 69088a4a60284de8e1222488667b810b098c16d22acSantos Cordon boolean wasConferencePreviouslyMerged() { 69188a4a60284de8e1222488667b810b098c16d22acSantos Cordon return mWasConferencePreviouslyMerged; 69288a4a60284de8e1222488667b810b098c16d22acSantos Cordon } 69388a4a60284de8e1222488667b810b098c16d22acSantos Cordon 69488a4a60284de8e1222488667b810b098c16d22acSantos Cordon Call getConferenceLevelActiveCall() { 69588a4a60284de8e1222488667b810b098c16d22acSantos Cordon return mConferenceLevelActiveCall; 69688a4a60284de8e1222488667b810b098c16d22acSantos Cordon } 69788a4a60284de8e1222488667b810b098c16d22acSantos Cordon 698c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal ConnectionServiceWrapper getConnectionService() { 699c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal return mConnectionService; 700681663d17b6d92b604526a54b196fa88f25b6957Santos Cordon } 701681663d17b6d92b604526a54b196fa88f25b6957Santos Cordon 70291d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn /** 70391d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn * Retrieves the {@link Context} for the call. 70491d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn * 70591d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn * @return The {@link Context}. 70691d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn */ 70791d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn Context getContext() { 70891d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn return mContext; 70991d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn } 71091d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn 711c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal void setConnectionService(ConnectionServiceWrapper service) { 712c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal Preconditions.checkNotNull(service); 7138e55d1d7ea86f768acb90f88dc9e5b5368d3398aBen Gilad 714c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal clearConnectionService(); 7158e55d1d7ea86f768acb90f88dc9e5b5368d3398aBen Gilad 716c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal service.incrementAssociatedCallCount(); 717c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal mConnectionService = service; 718c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal mConnectionService.addCall(this); 719681663d17b6d92b604526a54b196fa88f25b6957Santos Cordon } 720681663d17b6d92b604526a54b196fa88f25b6957Santos Cordon 721681663d17b6d92b604526a54b196fa88f25b6957Santos Cordon /** 722c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal * Clears the associated connection service. 723681663d17b6d92b604526a54b196fa88f25b6957Santos Cordon */ 724c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal void clearConnectionService() { 725c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal if (mConnectionService != null) { 726c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal ConnectionServiceWrapper serviceTemp = mConnectionService; 727c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal mConnectionService = null; 728c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal serviceTemp.removeCall(this); 729c499c1c0758dcb4b02048df96e7405994660ab3fSantos Cordon 730c499c1c0758dcb4b02048df96e7405994660ab3fSantos Cordon // Decrementing the count can cause the service to unbind, which itself can trigger the 731c499c1c0758dcb4b02048df96e7405994660ab3fSantos Cordon // service-death code. Since the service death code tries to clean up any associated 732c499c1c0758dcb4b02048df96e7405994660ab3fSantos Cordon // calls, we need to make sure to remove that information (e.g., removeCall()) before 733c499c1c0758dcb4b02048df96e7405994660ab3fSantos Cordon // we decrement. Technically, invoking removeCall() prior to decrementing is all that is 734c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal // necessary, but cleaning up mConnectionService prior to triggering an unbind is good 735c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal // to do. 736c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal decrementAssociatedCallCount(serviceTemp); 737adee12dd6b3e85ce3ae419329226c9aa72c184fcYorke Lee } 7388e55d1d7ea86f768acb90f88dc9e5b5368d3398aBen Gilad } 7398e55d1d7ea86f768acb90f88dc9e5b5368d3398aBen Gilad 740664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal private void processDirectToVoicemail() { 741c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal if (mDirectToVoicemailQueryPending) { 7422174fb56907fddf5680355e097f4425f837983e2Santos Cordon if (mCallerInfo != null && mCallerInfo.shouldSendToVoicemail) { 7432174fb56907fddf5680355e097f4425f837983e2Santos Cordon Log.i(this, "Directing call to voicemail: %s.", this); 744df39986de36d40aaa45e61d19a21eca536765ca5Santos Cordon // TODO: Once we move State handling from CallsManager to Call, we 7456fb37c87836b5245046bd3b14320823ab839a10cIhab Awad // will not need to set STATE_RINGING state prior to calling reject. 7462174fb56907fddf5680355e097f4425f837983e2Santos Cordon setState(CallState.RINGING); 747ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad reject(false, null); 7482174fb56907fddf5680355e097f4425f837983e2Santos Cordon } else { 749df39986de36d40aaa45e61d19a21eca536765ca5Santos Cordon // TODO: Make this class (not CallsManager) responsible for changing 7506fb37c87836b5245046bd3b14320823ab839a10cIhab Awad // the call state to STATE_RINGING. 7512174fb56907fddf5680355e097f4425f837983e2Santos Cordon 7526fb37c87836b5245046bd3b14320823ab839a10cIhab Awad // TODO: Replace this with state transition to STATE_RINGING. 7532174fb56907fddf5680355e097f4425f837983e2Santos Cordon for (Listener l : mListeners) { 754c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal l.onSuccessfulIncomingCall(this); 7552174fb56907fddf5680355e097f4425f837983e2Santos Cordon } 7562174fb56907fddf5680355e097f4425f837983e2Santos Cordon } 757766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon 758c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal mDirectToVoicemailQueryPending = false; 759766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon } 760766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon } 761766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon 762766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon /** 763664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal * Starts the create connection sequence. Upon completion, there should exist an active 764664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal * connection through a connection service (or the call will have failed). 76591d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn * 76691d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn * @param phoneAccountRegistrar The phone account registrar. 767766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon */ 76891d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn void startCreateConnection(PhoneAccountRegistrar phoneAccountRegistrar) { 769664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal Preconditions.checkState(mCreateConnectionProcessor == null); 77091d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn mCreateConnectionProcessor = new CreateConnectionProcessor(this, mRepository, this, 77191d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn phoneAccountRegistrar, mContext); 772664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal mCreateConnectionProcessor.process(); 773766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon } 774766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon 7755a73b03be0a2a929cf9974578445b90f773937b4Sailesh Nepal @Override 7768000845a81fd6a88ff69cb11e1b6dff5f47c2332Ihab Awad public void handleCreateConnectionSuccess( 7778000845a81fd6a88ff69cb11e1b6dff5f47c2332Ihab Awad CallIdMapper idMapper, 7788000845a81fd6a88ff69cb11e1b6dff5f47c2332Ihab Awad ParcelableConnection connection) { 77912d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon Log.v(this, "handleCreateConnectionSuccessful %s", connection); 780b78b27693afbe9736f0a54ec473328955251f885Ihab Awad setTargetPhoneAccount(connection.getPhoneAccount()); 78172890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon setHandle(connection.getHandle(), connection.getHandlePresentation()); 78272890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon setCallerDisplayName( 78372890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon connection.getCallerDisplayName(), connection.getCallerDisplayNamePresentation()); 78407bc5ee853bc9a0b4cd46e0c702888b2c7989392Ihab Awad setConnectionCapabilities(connection.getConnectionCapabilities()); 7856fb37c87836b5245046bd3b14320823ab839a10cIhab Awad setVideoProvider(connection.getVideoProvider()); 786b1a95a77522b2a1c98b378a2e538d819918b7f2cTyler Gunn setVideoState(connection.getVideoState()); 7875be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee setRingbackRequested(connection.isRingbackRequested()); 7885be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee setIsVoipAudioMode(connection.getIsVoipAudioMode()); 789604a4fe52c7de1347f40aadfba1964e9dcfb223cSailesh Nepal setStatusHints(connection.getStatusHints()); 790664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal 7918000845a81fd6a88ff69cb11e1b6dff5f47c2332Ihab Awad mConferenceableCalls.clear(); 7928000845a81fd6a88ff69cb11e1b6dff5f47c2332Ihab Awad for (String id : connection.getConferenceableConnectionIds()) { 7938000845a81fd6a88ff69cb11e1b6dff5f47c2332Ihab Awad mConferenceableCalls.add(idMapper.getCall(id)); 7948000845a81fd6a88ff69cb11e1b6dff5f47c2332Ihab Awad } 7958000845a81fd6a88ff69cb11e1b6dff5f47c2332Ihab Awad 7969250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee if (mIsUnknown) { 7979250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee for (Listener l : mListeners) { 7989250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee l.onSuccessfulUnknownCall(this, getStateFromConnectionState(connection.getState())); 7999250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee } 8009250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee } else if (mIsIncoming) { 801664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal // We do not handle incoming calls immediately when they are verified by the connection 802664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal // service. We allow the caller-info-query code to execute first so that we can read the 803664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal // direct-to-voicemail property before deciding if we want to show the incoming call to 804664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal // the user or if we want to reject the call. 805664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal mDirectToVoicemailQueryPending = true; 806664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal 807664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal // Timeout the direct-to-voicemail lookup execution so that we dont wait too long before 808664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal // showing the user the incoming call screen. 80991d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn mHandler.postDelayed(mDirectToVoicemailRunnable, Timeouts.getDirectToVoicemailMillis( 81091d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn mContext.getContentResolver())); 811664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal } else { 812664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal for (Listener l : mListeners) { 813cde2e5062b1b1689cd8962e28763fa0a35e2476aTyler Gunn l.onSuccessfulOutgoingCall(this, 814cde2e5062b1b1689cd8962e28763fa0a35e2476aTyler Gunn getStateFromConnectionState(connection.getState())); 815664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal } 816766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon } 8175a73b03be0a2a929cf9974578445b90f773937b4Sailesh Nepal } 8185a73b03be0a2a929cf9974578445b90f773937b4Sailesh Nepal 8195a73b03be0a2a929cf9974578445b90f773937b4Sailesh Nepal @Override 820701dc006ac11625b55d872f1639107b028933895Andrew Lee public void handleCreateConnectionFailure(DisconnectCause disconnectCause) { 821fb5560d634aef745466e8869f8acf496447da17bIhab Awad clearConnectionService(); 822701dc006ac11625b55d872f1639107b028933895Andrew Lee setDisconnectCause(disconnectCause); 823701dc006ac11625b55d872f1639107b028933895Andrew Lee CallsManager.getInstance().markCallAsDisconnected(this, disconnectCause); 824664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal 8259250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee if (mIsUnknown) { 8269250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee for (Listener listener : mListeners) { 8279250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee listener.onFailedUnknownCall(this); 8289250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee } 8299250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee } else if (mIsIncoming) { 830a82c8f794a0a1a9eaa1329a6361abe28043d139aJay Shrauner for (Listener listener : mListeners) { 831a82c8f794a0a1a9eaa1329a6361abe28043d139aJay Shrauner listener.onFailedIncomingCall(this); 832664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal } 833664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal } else { 834a82c8f794a0a1a9eaa1329a6361abe28043d139aJay Shrauner for (Listener listener : mListeners) { 835701dc006ac11625b55d872f1639107b028933895Andrew Lee listener.onFailedOutgoingCall(this, disconnectCause); 836664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal } 837766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon } 838766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon } 839766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon 840766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon /** 84174549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad * Plays the specified DTMF tone. 84274549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad */ 84374549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad void playDtmfTone(char digit) { 844c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal if (mConnectionService == null) { 845c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal Log.w(this, "playDtmfTone() request on a call without a connection service."); 84674549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad } else { 847c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal Log.i(this, "Send playDtmfTone to connection service for call %s", this); 848c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal mConnectionService.playDtmfTone(this, digit); 84974549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad } 85074549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad } 85174549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad 85274549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad /** 85374549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad * Stops playing any currently playing DTMF tone. 85474549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad */ 85574549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad void stopDtmfTone() { 856c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal if (mConnectionService == null) { 857fd4d7b5c86bb3ae9fc78b6dd820654ab977b7092Jay Shrauner Log.w(this, "stopDtmfTone() request on a call without a connection service."); 85874549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad } else { 859c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal Log.i(this, "Send stopDtmfTone to connection service for call %s", this); 860c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal mConnectionService.stopDtmfTone(this); 86174549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad } 86274549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad } 86374549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad 864cf5b2918ca58b155911a66222ae5b4d21cb5b8ecSantos Cordon void disconnect() { 865cf5b2918ca58b155911a66222ae5b4d21cb5b8ecSantos Cordon disconnect(false); 866cf5b2918ca58b155911a66222ae5b4d21cb5b8ecSantos Cordon } 867cf5b2918ca58b155911a66222ae5b4d21cb5b8ecSantos Cordon 86874549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad /** 869c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal * Attempts to disconnect the call through the connection service. 870049b7b6a8d0cf44d687d827cb57a18fa23358206Santos Cordon */ 871cf5b2918ca58b155911a66222ae5b4d21cb5b8ecSantos Cordon void disconnect(boolean wasViaNewOutgoingCallBroadcaster) { 872aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn // Track that the call is now locally disconnecting. 873aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn setLocallyDisconnecting(true); 874aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn 875fd4d7b5c86bb3ae9fc78b6dd820654ab977b7092Jay Shrauner if (mState == CallState.NEW || mState == CallState.PRE_DIAL_WAIT || 876fd4d7b5c86bb3ae9fc78b6dd820654ab977b7092Jay Shrauner mState == CallState.CONNECTING) { 877682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon Log.v(this, "Aborting call %s", this); 878cf5b2918ca58b155911a66222ae5b4d21cb5b8ecSantos Cordon abort(wasViaNewOutgoingCallBroadcaster); 87974d420be72fa30735fe9b7a25715f6db046c0398Santos Cordon } else if (mState != CallState.ABORTED && mState != CallState.DISCONNECTED) { 880fd4d7b5c86bb3ae9fc78b6dd820654ab977b7092Jay Shrauner if (mConnectionService == null) { 881fd4d7b5c86bb3ae9fc78b6dd820654ab977b7092Jay Shrauner Log.e(this, new Exception(), "disconnect() request on a call without a" 882fd4d7b5c86bb3ae9fc78b6dd820654ab977b7092Jay Shrauner + " connection service."); 883fd4d7b5c86bb3ae9fc78b6dd820654ab977b7092Jay Shrauner } else { 884fd4d7b5c86bb3ae9fc78b6dd820654ab977b7092Jay Shrauner Log.i(this, "Send disconnect to connection service for call: %s", this); 885fd4d7b5c86bb3ae9fc78b6dd820654ab977b7092Jay Shrauner // The call isn't officially disconnected until the connection service 886fd4d7b5c86bb3ae9fc78b6dd820654ab977b7092Jay Shrauner // confirms that the call was actually disconnected. Only then is the 887fd4d7b5c86bb3ae9fc78b6dd820654ab977b7092Jay Shrauner // association between call and connection service severed, see 888fd4d7b5c86bb3ae9fc78b6dd820654ab977b7092Jay Shrauner // {@link CallsManager#markCallAsDisconnected}. 889fd4d7b5c86bb3ae9fc78b6dd820654ab977b7092Jay Shrauner mConnectionService.disconnect(this); 890fd4d7b5c86bb3ae9fc78b6dd820654ab977b7092Jay Shrauner } 891049b7b6a8d0cf44d687d827cb57a18fa23358206Santos Cordon } 892049b7b6a8d0cf44d687d827cb57a18fa23358206Santos Cordon } 893049b7b6a8d0cf44d687d827cb57a18fa23358206Santos Cordon 894cf5b2918ca58b155911a66222ae5b4d21cb5b8ecSantos Cordon void abort(boolean wasViaNewOutgoingCallBroadcaster) { 895752cacbc0b88b9b4cb4ab7bd547e17b5d2690693Sailesh Nepal if (mCreateConnectionProcessor != null && 896752cacbc0b88b9b4cb4ab7bd547e17b5d2690693Sailesh Nepal !mCreateConnectionProcessor.isProcessingComplete()) { 897664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal mCreateConnectionProcessor.abort(); 89843df90f875f867e1e5cfd32b0cbc45440606c946Yorke Lee } else if (mState == CallState.NEW || mState == CallState.PRE_DIAL_WAIT 89943df90f875f867e1e5cfd32b0cbc45440606c946Yorke Lee || mState == CallState.CONNECTING) { 900cf5b2918ca58b155911a66222ae5b4d21cb5b8ecSantos Cordon if (wasViaNewOutgoingCallBroadcaster) { 901cf5b2918ca58b155911a66222ae5b4d21cb5b8ecSantos Cordon // If the cancelation was from NEW_OUTGOING_CALL, then we do not automatically 902cf5b2918ca58b155911a66222ae5b4d21cb5b8ecSantos Cordon // destroy the call. Instead, we announce the cancelation and CallsManager handles 903cf5b2918ca58b155911a66222ae5b4d21cb5b8ecSantos Cordon // it through a timer. Since apps often cancel calls through NEW_OUTGOING_CALL and 904cf5b2918ca58b155911a66222ae5b4d21cb5b8ecSantos Cordon // then re-dial them quickly using a gateway, allowing the first call to end 905cf5b2918ca58b155911a66222ae5b4d21cb5b8ecSantos Cordon // causes jank. This timeout allows CallsManager to transition the first call into 906cf5b2918ca58b155911a66222ae5b4d21cb5b8ecSantos Cordon // the second call so that in-call only ever sees a single call...eliminating the 907cf5b2918ca58b155911a66222ae5b4d21cb5b8ecSantos Cordon // jank altogether. 908cf5b2918ca58b155911a66222ae5b4d21cb5b8ecSantos Cordon for (Listener listener : mListeners) { 909cf5b2918ca58b155911a66222ae5b4d21cb5b8ecSantos Cordon if (listener.onCanceledViaNewOutgoingCallBroadcast(this)) { 910cf5b2918ca58b155911a66222ae5b4d21cb5b8ecSantos Cordon // The first listener to handle this wins. A return value of true means that 911cf5b2918ca58b155911a66222ae5b4d21cb5b8ecSantos Cordon // the listener will handle the disconnection process later and so we 912cf5b2918ca58b155911a66222ae5b4d21cb5b8ecSantos Cordon // should not continue it here. 913cf5b2918ca58b155911a66222ae5b4d21cb5b8ecSantos Cordon setLocallyDisconnecting(false); 914cf5b2918ca58b155911a66222ae5b4d21cb5b8ecSantos Cordon return; 915cf5b2918ca58b155911a66222ae5b4d21cb5b8ecSantos Cordon } 916cf5b2918ca58b155911a66222ae5b4d21cb5b8ecSantos Cordon } 917cf5b2918ca58b155911a66222ae5b4d21cb5b8ecSantos Cordon } 918cf5b2918ca58b155911a66222ae5b4d21cb5b8ecSantos Cordon 919504eb83ea06f4c737a4f4fdbd65aa2450505420cTyler Gunn handleCreateConnectionFailure(new DisconnectCause(DisconnectCause.CANCELED)); 9202d0b331f659e4e95621e738bbddaa38a80a70d4cSantos Cordon } else { 9212d0b331f659e4e95621e738bbddaa38a80a70d4cSantos Cordon Log.v(this, "Cannot abort a call which isn't either PRE_DIAL_WAIT or CONNECTING"); 922682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon } 923682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon } 924682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon 9250b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon /** 92661d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon * Answers the call if it is ringing. 92738931d0ad60f00a9f50c90cef446166731f0b871Andrew Lee * 92838931d0ad60f00a9f50c90cef446166731f0b871Andrew Lee * @param videoState The video state in which to answer the call. 92961d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon */ 93038931d0ad60f00a9f50c90cef446166731f0b871Andrew Lee void answer(int videoState) { 931c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal Preconditions.checkNotNull(mConnectionService); 93261d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon 93361d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon // Check to verify that the call is still in the ringing state. A call can change states 9347cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunn // between the time the user hits 'answer' and Telecom receives the command. 93561d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon if (isRinging("answer")) { 936c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal // At this point, we are asking the connection service to answer but we don't assume 937c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal // that it will work. Instead, we wait until confirmation from the connectino service 9386fb37c87836b5245046bd3b14320823ab839a10cIhab Awad // that the call is in a non-STATE_RINGING state before changing the UI. See 939c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal // {@link ConnectionServiceAdapter#setActive} and other set* methods. 94038931d0ad60f00a9f50c90cef446166731f0b871Andrew Lee mConnectionService.answer(this, videoState); 94161d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon } 94261d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon } 94361d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon 94461d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon /** 94561d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon * Rejects the call if it is ringing. 946ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * 947ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * @param rejectWithMessage Whether to send a text message as part of the call rejection. 948ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * @param textMessage An optional text message to send as part of the rejection. 94961d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon */ 950ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad void reject(boolean rejectWithMessage, String textMessage) { 951c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal Preconditions.checkNotNull(mConnectionService); 95261d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon 95361d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon // Check to verify that the call is still in the ringing state. A call can change states 95461d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon // between the time the user hits 'reject' and Telecomm receives the command. 95561d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon if (isRinging("reject")) { 956c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal mConnectionService.reject(this); 95761d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon } 95861d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon } 95961d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon 96061d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon /** 961cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee * Puts the call on hold if it is currently active. 962cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee */ 963cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee void hold() { 964c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal Preconditions.checkNotNull(mConnectionService); 965cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee 966cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee if (mState == CallState.ACTIVE) { 967c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal mConnectionService.hold(this); 968cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee } 969cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee } 970cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee 971cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee /** 972cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee * Releases the call from hold if it is currently active. 973cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee */ 974cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee void unhold() { 975c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal Preconditions.checkNotNull(mConnectionService); 976cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee 977cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee if (mState == CallState.ON_HOLD) { 978c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal mConnectionService.unhold(this); 979571f0737002251f09b9ef696dc8b4c9ce02abbaeSantos Cordon } 9800b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon } 9810b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon 9826aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal /** Checks if this is a live call or not. */ 9836aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal boolean isAlive() { 9846aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal switch (mState) { 9856fb37c87836b5245046bd3b14320823ab839a10cIhab Awad case CallState.NEW: 9866fb37c87836b5245046bd3b14320823ab839a10cIhab Awad case CallState.RINGING: 9876fb37c87836b5245046bd3b14320823ab839a10cIhab Awad case CallState.DISCONNECTED: 9886fb37c87836b5245046bd3b14320823ab839a10cIhab Awad case CallState.ABORTED: 9896aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal return false; 9906aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal default: 9916aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal return true; 9926aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal } 9936aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal } 9946aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal 99540f78c210512570f14cdfde9613dd85c510a1c0cSantos Cordon boolean isActive() { 99684bfe47a2447c4983bcc58468000f04683eec55bIhab Awad return mState == CallState.ACTIVE; 99740f78c210512570f14cdfde9613dd85c510a1c0cSantos Cordon } 99840f78c210512570f14cdfde9613dd85c510a1c0cSantos Cordon 99984fa5f8c59a1cd3c5716c239fb19c58244fc81feSailesh Nepal Bundle getExtras() { 100084fa5f8c59a1cd3c5716c239fb19c58244fc81feSailesh Nepal return mExtras; 100184fa5f8c59a1cd3c5716c239fb19c58244fc81feSailesh Nepal } 100284fa5f8c59a1cd3c5716c239fb19c58244fc81feSailesh Nepal 100384fa5f8c59a1cd3c5716c239fb19c58244fc81feSailesh Nepal void setExtras(Bundle extras) { 100484fa5f8c59a1cd3c5716c239fb19c58244fc81feSailesh Nepal mExtras = extras; 100584fa5f8c59a1cd3c5716c239fb19c58244fc81feSailesh Nepal } 100684fa5f8c59a1cd3c5716c239fb19c58244fc81feSailesh Nepal 10078a736a887b50d4d042c008b2073e24e1b4681dfbYorke Lee /** 10088a736a887b50d4d042c008b2073e24e1b4681dfbYorke Lee * @return the uri of the contact associated with this call. 10098a736a887b50d4d042c008b2073e24e1b4681dfbYorke Lee */ 10108a736a887b50d4d042c008b2073e24e1b4681dfbYorke Lee Uri getContactUri() { 10118a736a887b50d4d042c008b2073e24e1b4681dfbYorke Lee if (mCallerInfo == null || !mCallerInfo.contactExists) { 1012a7fa743f76242e9f039eea2fea0911f59255522eYorke Lee return getHandle(); 10138a736a887b50d4d042c008b2073e24e1b4681dfbYorke Lee } 10148a736a887b50d4d042c008b2073e24e1b4681dfbYorke Lee return Contacts.getLookupUri(mCallerInfo.contactIdOrZero, mCallerInfo.lookupKey); 10158a736a887b50d4d042c008b2073e24e1b4681dfbYorke Lee } 10168a736a887b50d4d042c008b2073e24e1b4681dfbYorke Lee 10175ba7f27491e287f39a999ddd3d1ed6a7bad78272Santos Cordon Uri getRingtone() { 10185ba7f27491e287f39a999ddd3d1ed6a7bad78272Santos Cordon return mCallerInfo == null ? null : mCallerInfo.contactRingtoneUri; 10195ba7f27491e287f39a999ddd3d1ed6a7bad78272Santos Cordon } 10205ba7f27491e287f39a999ddd3d1ed6a7bad78272Santos Cordon 1021352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton void onPostDialWait(String remaining) { 1022352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton for (Listener l : mListeners) { 1023352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton l.onPostDialWait(this, remaining); 1024352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton } 1025352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton } 1026352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton 1027a469f76c1710a945933910840f11f9fda0445d82Nancy Chen void onPostDialChar(char nextChar) { 1028a469f76c1710a945933910840f11f9fda0445d82Nancy Chen for (Listener l : mListeners) { 1029a469f76c1710a945933910840f11f9fda0445d82Nancy Chen l.onPostDialChar(this, nextChar); 1030a469f76c1710a945933910840f11f9fda0445d82Nancy Chen } 1031a469f76c1710a945933910840f11f9fda0445d82Nancy Chen } 1032a469f76c1710a945933910840f11f9fda0445d82Nancy Chen 1033352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton void postDialContinue(boolean proceed) { 1034c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal mConnectionService.onPostDialContinue(this, proceed); 1035352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton } 1036352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton 10370fbe6321e341ddce186634266dba2db3fa426b88Santos Cordon void conferenceWith(Call otherCall) { 1038c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal if (mConnectionService == null) { 1039c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal Log.w(this, "conference requested on a call without a connection service."); 1040a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } else { 10410fbe6321e341ddce186634266dba2db3fa426b88Santos Cordon mConnectionService.conference(this, otherCall); 1042a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 1043a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 1044a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon 1045a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon void splitFromConference() { 1046672321e603555849831dd88d5c9f93d88143ee48Santos Cordon if (mConnectionService == null) { 1047672321e603555849831dd88d5c9f93d88143ee48Santos Cordon Log.w(this, "splitting from conference call without a connection service"); 1048672321e603555849831dd88d5c9f93d88143ee48Santos Cordon } else { 1049672321e603555849831dd88d5c9f93d88143ee48Santos Cordon mConnectionService.splitFromConference(this); 1050672321e603555849831dd88d5c9f93d88143ee48Santos Cordon } 1051a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 1052a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon 10536805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon void mergeConference() { 10546805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon if (mConnectionService == null) { 10556805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon Log.w(this, "merging conference calls without a connection service."); 105607bc5ee853bc9a0b4cd46e0c702888b2c7989392Ihab Awad } else if (can(Connection.CAPABILITY_MERGE_CONFERENCE)) { 10576805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon mConnectionService.mergeConference(this); 105888a4a60284de8e1222488667b810b098c16d22acSantos Cordon mWasConferencePreviouslyMerged = true; 10596805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon } 10606805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon } 10616805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon 10626805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon void swapConference() { 10636805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon if (mConnectionService == null) { 10646805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon Log.w(this, "swapping conference calls without a connection service."); 106507bc5ee853bc9a0b4cd46e0c702888b2c7989392Ihab Awad } else if (can(Connection.CAPABILITY_SWAP_CONFERENCE)) { 10666805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon mConnectionService.swapConference(this); 106788a4a60284de8e1222488667b810b098c16d22acSantos Cordon switch (mChildCalls.size()) { 106888a4a60284de8e1222488667b810b098c16d22acSantos Cordon case 1: 106988a4a60284de8e1222488667b810b098c16d22acSantos Cordon mConferenceLevelActiveCall = mChildCalls.get(0); 107088a4a60284de8e1222488667b810b098c16d22acSantos Cordon break; 107188a4a60284de8e1222488667b810b098c16d22acSantos Cordon case 2: 107288a4a60284de8e1222488667b810b098c16d22acSantos Cordon // swap 107388a4a60284de8e1222488667b810b098c16d22acSantos Cordon mConferenceLevelActiveCall = mChildCalls.get(0) == mConferenceLevelActiveCall ? 107488a4a60284de8e1222488667b810b098c16d22acSantos Cordon mChildCalls.get(1) : mChildCalls.get(0); 107588a4a60284de8e1222488667b810b098c16d22acSantos Cordon break; 107688a4a60284de8e1222488667b810b098c16d22acSantos Cordon default: 107788a4a60284de8e1222488667b810b098c16d22acSantos Cordon // For anything else 0, or 3+, set it to null since it is impossible to tell. 107888a4a60284de8e1222488667b810b098c16d22acSantos Cordon mConferenceLevelActiveCall = null; 107988a4a60284de8e1222488667b810b098c16d22acSantos Cordon break; 108088a4a60284de8e1222488667b810b098c16d22acSantos Cordon } 10816805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon } 10826805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon } 10836805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon 1084a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon void setParentCall(Call parentCall) { 1085a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon if (parentCall == this) { 1086a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon Log.e(this, new Exception(), "setting the parent to self"); 1087a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon return; 1088a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 10890fbe6321e341ddce186634266dba2db3fa426b88Santos Cordon if (parentCall == mParentCall) { 10900fbe6321e341ddce186634266dba2db3fa426b88Santos Cordon // nothing to do 10910fbe6321e341ddce186634266dba2db3fa426b88Santos Cordon return; 10920fbe6321e341ddce186634266dba2db3fa426b88Santos Cordon } 1093a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon Preconditions.checkState(parentCall == null || mParentCall == null); 1094a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon 1095a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon Call oldParent = mParentCall; 1096a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon if (mParentCall != null) { 1097a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon mParentCall.removeChildCall(this); 1098a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 1099a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon mParentCall = parentCall; 1100a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon if (mParentCall != null) { 1101a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon mParentCall.addChildCall(this); 1102a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 1103a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon 1104a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon for (Listener l : mListeners) { 1105a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon l.onParentChanged(this); 1106a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 1107a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 1108a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon 110912d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon void setConferenceableCalls(List<Call> conferenceableCalls) { 111012d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon mConferenceableCalls.clear(); 111112d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon mConferenceableCalls.addAll(conferenceableCalls); 1112703d7cfdab59f84221fd803dd5810bea0e26cc56Tyler Gunn 1113703d7cfdab59f84221fd803dd5810bea0e26cc56Tyler Gunn for (Listener l : mListeners) { 1114703d7cfdab59f84221fd803dd5810bea0e26cc56Tyler Gunn l.onConferenceableCallsChanged(this); 1115703d7cfdab59f84221fd803dd5810bea0e26cc56Tyler Gunn } 111612d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon } 111712d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon 111812d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon List<Call> getConferenceableCalls() { 111912d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon return mConferenceableCalls; 112012d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon } 112112d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon 1122f193ba45fae5bc87e6a57779e4f5b56be59d08b0Santos Cordon boolean can(int capability) { 112307bc5ee853bc9a0b4cd46e0c702888b2c7989392Ihab Awad return (mConnectionCapabilities & capability) == capability; 11246805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon } 11256805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon 1126a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon private void addChildCall(Call call) { 1127a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon if (!mChildCalls.contains(call)) { 112888a4a60284de8e1222488667b810b098c16d22acSantos Cordon // Set the pseudo-active call to the latest child added to the conference. 112988a4a60284de8e1222488667b810b098c16d22acSantos Cordon // See definition of mConferenceLevelActiveCall for more detail. 113088a4a60284de8e1222488667b810b098c16d22acSantos Cordon mConferenceLevelActiveCall = call; 1131a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon mChildCalls.add(call); 1132a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon 1133a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon for (Listener l : mListeners) { 1134a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon l.onChildrenChanged(this); 1135a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 1136a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 1137a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 1138a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon 1139a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon private void removeChildCall(Call call) { 1140a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon if (mChildCalls.remove(call)) { 1141a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon for (Listener l : mListeners) { 1142a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon l.onChildrenChanged(this); 1143a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 1144a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 1145a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon } 1146a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon 11470b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon /** 1148ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * Return whether the user can respond to this {@code Call} via an SMS message. 1149ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * 1150ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * @return true if the "Respond via SMS" feature should be enabled 1151ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * for this incoming call. 1152ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * 1153ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * The general rule is that we *do* allow "Respond via SMS" except for 1154ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * the few (relatively rare) cases where we know for sure it won't 1155ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * work, namely: 1156ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * - a bogus or blank incoming number 1157ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * - a call from a SIP address 1158ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * - a "call presentation" that doesn't allow the number to be revealed 1159ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * 1160ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * In all other cases, we allow the user to respond via SMS. 1161ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * 1162ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * Note that this behavior isn't perfect; for example we have no way 1163ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * to detect whether the incoming call is from a landline (with most 1164ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * networks at least), so we still enable this feature even though 1165ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad * SMSes to that number will silently fail. 1166ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad */ 1167ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad boolean isRespondViaSmsCapable() { 1168ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad if (mState != CallState.RINGING) { 1169ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad return false; 1170ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad } 1171ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad 1172ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad if (getHandle() == null) { 1173ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad // No incoming number known or call presentation is "PRESENTATION_RESTRICTED", in 1174ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad // other words, the user should not be able to see the incoming phone number. 1175ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad return false; 1176ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad } 1177ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad 1178ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad if (PhoneNumberUtils.isUriNumber(getHandle().toString())) { 1179ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad // The incoming number is actually a URI (i.e. a SIP address), 1180ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad // not a regular PSTN phone number, and we can't send SMSes to 1181ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad // SIP addresses. 1182ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad // (TODO: That might still be possible eventually, though. Is 1183ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad // there some SIP-specific equivalent to sending a text message?) 1184ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad return false; 1185ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad } 1186ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad 1187ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad // Is there a valid SMS application on the phone? 118891d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn if (SmsApplication.getDefaultRespondViaMessageApplication(mContext, 1189ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad true /*updateIfNeeded*/) == null) { 1190ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad return false; 1191ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad } 1192ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad 1193ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad // TODO: with some carriers (in certain countries) you *can* actually 1194ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad // tell whether a given number is a mobile phone or not. So in that 1195ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad // case we could potentially return false here if the incoming call is 1196ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad // from a land line. 1197ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad 1198ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad // If none of the above special cases apply, it's OK to enable the 1199ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad // "Respond via SMS" feature. 1200ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad return true; 1201ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad } 1202ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad 1203ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad List<String> getCannedSmsResponses() { 1204ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad return mCannedSmsResponses; 1205ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad } 1206ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad 1207ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad /** 1208672321e603555849831dd88d5c9f93d88143ee48Santos Cordon * We need to make sure that before we move a call to the disconnected state, it no 1209672321e603555849831dd88d5c9f93d88143ee48Santos Cordon * longer has any parent/child relationships. We want to do this to ensure that the InCall 12107cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunn * Service always has the right data in the right order. We also want to do it in telecom so 1211672321e603555849831dd88d5c9f93d88143ee48Santos Cordon * that the insurance policy lives in the framework side of things. 1212672321e603555849831dd88d5c9f93d88143ee48Santos Cordon */ 1213672321e603555849831dd88d5c9f93d88143ee48Santos Cordon private void fixParentAfterDisconnect() { 1214672321e603555849831dd88d5c9f93d88143ee48Santos Cordon setParentCall(null); 1215672321e603555849831dd88d5c9f93d88143ee48Santos Cordon } 1216672321e603555849831dd88d5c9f93d88143ee48Santos Cordon 1217672321e603555849831dd88d5c9f93d88143ee48Santos Cordon /** 121861d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon * @return True if the call is ringing, else logs the action name. 121961d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon */ 122061d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon private boolean isRinging(String actionName) { 122161d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon if (mState == CallState.RINGING) { 122261d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon return true; 122361d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon } 122461d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon 1225f1c191d3974fed3f57680c63571ae0212c4622e7Sailesh Nepal Log.i(this, "Request to %s a non-ringing call %s", actionName, this); 122661d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon return false; 122761d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon } 122861d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon 12298e55d1d7ea86f768acb90f88dc9e5b5368d3398aBen Gilad @SuppressWarnings("rawtypes") 12308e55d1d7ea86f768acb90f88dc9e5b5368d3398aBen Gilad private void decrementAssociatedCallCount(ServiceBinder binder) { 12318e55d1d7ea86f768acb90f88dc9e5b5368d3398aBen Gilad if (binder != null) { 12328e55d1d7ea86f768acb90f88dc9e5b5368d3398aBen Gilad binder.decrementAssociatedCallCount(); 12338e55d1d7ea86f768acb90f88dc9e5b5368d3398aBen Gilad } 12348e55d1d7ea86f768acb90f88dc9e5b5368d3398aBen Gilad } 1235fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon 1236fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon /** 1237fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon * Looks up contact information based on the current handle. 1238fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon */ 1239fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon private void startCallerInfoLookup() { 1240fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon String number = mHandle == null ? null : mHandle.getSchemeSpecificPart(); 1241fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon 1242fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon mQueryToken++; // Updated so that previous queries can no longer set the information. 1243fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon mCallerInfo = null; 1244fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon if (!TextUtils.isEmpty(number)) { 12455ba7f27491e287f39a999ddd3d1ed6a7bad78272Santos Cordon Log.v(this, "Looking up information for: %s.", Log.piiHandle(number)); 1246fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon CallerInfoAsyncQuery.startQuery( 1247fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon mQueryToken, 124891d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn mContext, 1249fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon number, 1250fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon sCallerInfoQueryListener, 1251fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon this); 1252fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon } 1253fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon } 1254fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon 1255fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon /** 125699c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon * Saves the specified caller info if the specified token matches that of the last query 1257fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon * that was made. 1258fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon * 1259fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon * @param callerInfo The new caller information to set. 1260fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon * @param token The token used with this query. 1261fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon */ 1262fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon private void setCallerInfo(CallerInfo callerInfo, int token) { 1263e4a9c412f5c6f76f006659f0b4e171ef4547dc45Yorke Lee Trace.beginSection("setCallerInfo"); 126499c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon Preconditions.checkNotNull(callerInfo); 126599c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon 1266fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon if (mQueryToken == token) { 1267fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon mCallerInfo = callerInfo; 12685ba7f27491e287f39a999ddd3d1ed6a7bad78272Santos Cordon Log.i(this, "CallerInfo received for %s: %s", Log.piiHandle(mHandle), callerInfo); 126999c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon 1270a1662d0ae89d9fb514a5ac68cbc76660e34dae00Makoto Onuki if (mCallerInfo.contactDisplayPhotoUri != null) { 1271a1662d0ae89d9fb514a5ac68cbc76660e34dae00Makoto Onuki Log.d(this, "Searching person uri %s for call %s", 1272a1662d0ae89d9fb514a5ac68cbc76660e34dae00Makoto Onuki mCallerInfo.contactDisplayPhotoUri, this); 127399c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon ContactsAsyncHelper.startObtainPhotoAsync( 127499c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon token, 127591d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn mContext, 1276a1662d0ae89d9fb514a5ac68cbc76660e34dae00Makoto Onuki mCallerInfo.contactDisplayPhotoUri, 127799c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon sPhotoLoadListener, 127899c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon this); 1279a1662d0ae89d9fb514a5ac68cbc76660e34dae00Makoto Onuki // Do not call onCallerInfoChanged yet in this case. We call it in setPhoto(). 128064c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon } else { 128164c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon for (Listener l : mListeners) { 128264c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon l.onCallerInfoChanged(this); 128364c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon } 128499c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon } 12852174fb56907fddf5680355e097f4425f837983e2Santos Cordon 12862174fb56907fddf5680355e097f4425f837983e2Santos Cordon processDirectToVoicemail(); 128799c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon } 1288e4a9c412f5c6f76f006659f0b4e171ef4547dc45Yorke Lee Trace.endSection(); 128999c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon } 129099c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon 12916f3f7affb13e93cb70868d3114f02f1ed593194eYorke Lee CallerInfo getCallerInfo() { 12926f3f7affb13e93cb70868d3114f02f1ed593194eYorke Lee return mCallerInfo; 12936f3f7affb13e93cb70868d3114f02f1ed593194eYorke Lee } 12946f3f7affb13e93cb70868d3114f02f1ed593194eYorke Lee 129599c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon /** 129699c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon * Saves the specified photo information if the specified token matches that of the last query. 129799c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon * 129899c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon * @param photo The photo as a drawable. 129999c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon * @param photoIcon The photo as a small icon. 130099c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon * @param token The token used with this query. 130199c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon */ 130299c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon private void setPhoto(Drawable photo, Bitmap photoIcon, int token) { 130399c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon if (mQueryToken == token) { 130499c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon mCallerInfo.cachedPhoto = photo; 130599c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon mCallerInfo.cachedPhotoIcon = photoIcon; 130664c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon 130764c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon for (Listener l : mListeners) { 130864c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon l.onCallerInfoChanged(this); 130964c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon } 1310fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon } 1311fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon } 1312ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad 1313ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad private void maybeLoadCannedSmsResponses() { 1314ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad if (mIsIncoming && isRespondViaSmsCapable() && !mCannedSmsResponsesLoadingStarted) { 1315ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad Log.d(this, "maybeLoadCannedSmsResponses: starting task to load messages"); 1316ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad mCannedSmsResponsesLoadingStarted = true; 1317ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad RespondViaSmsManager.getInstance().loadCannedTextMessages( 1318ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad new Response<Void, List<String>>() { 1319ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad @Override 1320ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad public void onResult(Void request, List<String>... result) { 1321ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad if (result.length > 0) { 1322ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad Log.d(this, "maybeLoadCannedSmsResponses: got %s", result[0]); 1323ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad mCannedSmsResponses = result[0]; 1324ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad for (Listener l : mListeners) { 1325ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad l.onCannedSmsResponsesLoaded(Call.this); 1326ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad } 1327ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad } 1328ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad } 1329ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad 1330ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad @Override 1331ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad public void onError(Void request, int code, String msg) { 1332ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad Log.w(Call.this, "Error obtaining canned SMS responses: %d %s", code, 1333ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad msg); 1334ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad } 133591d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn }, 133691d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn mContext 1337ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad ); 1338ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad } else { 1339ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad Log.d(this, "maybeLoadCannedSmsResponses: doing nothing"); 1340ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad } 1341ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad } 1342b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati 1343b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati /** 1344b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati * Sets speakerphone option on when call begins. 1345b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati */ 1346b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati public void setStartWithSpeakerphoneOn(boolean startWithSpeakerphone) { 1347b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati mSpeakerphoneOn = startWithSpeakerphone; 1348b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati } 1349b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati 1350b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati /** 1351b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati * Returns speakerphone option. 1352b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati * 1353b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati * @return Whether or not speakerphone should be set automatically when call begins. 1354b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati */ 1355b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati public boolean getStartWithSpeakerphoneOn() { 1356b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati return mSpeakerphoneOn; 1357b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati } 1358e9a776560dfe6f000cfc0dc1ea36c0f37d937f53Andrew Lee 1359e9a776560dfe6f000cfc0dc1ea36c0f37d937f53Andrew Lee /** 13603bcf935b25470e94c8c6855862434d15b785c54aAndrew Lee * Sets a video call provider for the call. 1361e9a776560dfe6f000cfc0dc1ea36c0f37d937f53Andrew Lee */ 13626fb37c87836b5245046bd3b14320823ab839a10cIhab Awad public void setVideoProvider(IVideoProvider videoProvider) { 13636fb37c87836b5245046bd3b14320823ab839a10cIhab Awad mVideoProvider = videoProvider; 1364a65d41fb134e323ab43c3f9454313b262959b1d0Nancy Chen for (Listener l : mListeners) { 13653bcf935b25470e94c8c6855862434d15b785c54aAndrew Lee l.onVideoCallProviderChanged(Call.this); 1366a65d41fb134e323ab43c3f9454313b262959b1d0Nancy Chen } 1367a65d41fb134e323ab43c3f9454313b262959b1d0Nancy Chen } 1368a65d41fb134e323ab43c3f9454313b262959b1d0Nancy Chen 1369a65d41fb134e323ab43c3f9454313b262959b1d0Nancy Chen /** 13706fb37c87836b5245046bd3b14320823ab839a10cIhab Awad * @return Return the {@link Connection.VideoProvider} binder. 1371a65d41fb134e323ab43c3f9454313b262959b1d0Nancy Chen */ 13726fb37c87836b5245046bd3b14320823ab839a10cIhab Awad public IVideoProvider getVideoProvider() { 13736fb37c87836b5245046bd3b14320823ab839a10cIhab Awad return mVideoProvider; 1374e9a776560dfe6f000cfc0dc1ea36c0f37d937f53Andrew Lee } 1375e19cc005ddbff5313d6f7288587630b2410d005cTyler Gunn 1376e19cc005ddbff5313d6f7288587630b2410d005cTyler Gunn /** 1377c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn * The current video state for the call. 13786fb37c87836b5245046bd3b14320823ab839a10cIhab Awad * Valid values: see {@link VideoProfile.VideoState}. 1379c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn */ 1380c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn public int getVideoState() { 1381c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn return mVideoState; 1382c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn } 1383c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn 1384c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn /** 13850a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn * Returns the video states which were applicable over the duration of a call. 13866fb37c87836b5245046bd3b14320823ab839a10cIhab Awad * See {@link VideoProfile} for a list of valid video states. 13870a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn * 13880a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn * @return The video states applicable over the duration of the call. 13890a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn */ 13900a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn public int getVideoStateHistory() { 13910a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn return mVideoStateHistory; 13920a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn } 13930a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn 13940a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn /** 13950a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn * Determines the current video state for the call. 13960a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn * For an outgoing call determines the desired video state for the call. 13976fb37c87836b5245046bd3b14320823ab839a10cIhab Awad * Valid values: see {@link VideoProfile.VideoState} 1398c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn * 13990a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn * @param videoState The video state for the call. 1400c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn */ 1401c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn public void setVideoState(int videoState) { 14020a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn // Track which video states were applicable over the duration of the call. 14030a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn mVideoStateHistory = mVideoStateHistory | videoState; 14040a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn 1405c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn mVideoState = videoState; 14064a79660c984d54679ad4d2bdc89e224d9c8c375bAndrew Lee for (Listener l : mListeners) { 14074a79660c984d54679ad4d2bdc89e224d9c8c375bAndrew Lee l.onVideoStateChanged(this); 14084a79660c984d54679ad4d2bdc89e224d9c8c375bAndrew Lee } 1409c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn } 14107e66957928c5c23a1028c8e2a2d7cf359cbfa44eSailesh Nepal 14115be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee public boolean getIsVoipAudioMode() { 14125be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee return mIsVoipAudioMode; 14137e66957928c5c23a1028c8e2a2d7cf359cbfa44eSailesh Nepal } 14147e66957928c5c23a1028c8e2a2d7cf359cbfa44eSailesh Nepal 14155be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee public void setIsVoipAudioMode(boolean audioModeIsVoip) { 14165be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee mIsVoipAudioMode = audioModeIsVoip; 14177e66957928c5c23a1028c8e2a2d7cf359cbfa44eSailesh Nepal for (Listener l : mListeners) { 14185be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee l.onIsVoipAudioModeChanged(this); 141935faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal } 142035faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal } 142135faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal 142235faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal public StatusHints getStatusHints() { 142335faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal return mStatusHints; 142435faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal } 142535faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal 142635faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal public void setStatusHints(StatusHints statusHints) { 142735faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal mStatusHints = statusHints; 142835faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal for (Listener l : mListeners) { 142935faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal l.onStatusHintsChanged(this); 14307e66957928c5c23a1028c8e2a2d7cf359cbfa44eSailesh Nepal } 14317e66957928c5c23a1028c8e2a2d7cf359cbfa44eSailesh Nepal } 14329d58de5df05d0358fc8ae57ab7e9a0c45337c602Sailesh Nepal 14339250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee public boolean isUnknown() { 14349250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee return mIsUnknown; 14359250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee } 14369250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee 14379250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee public void setIsUnknown(boolean isUnknown) { 14389250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee mIsUnknown = isUnknown; 14399250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee } 14409250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee 1441aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn /** 1442aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn * Determines if this call is in a disconnecting state. 1443aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn * 1444aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn * @return {@code true} if this call is locally disconnecting. 1445aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn */ 1446aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn public boolean isLocallyDisconnecting() { 1447aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn return mIsLocallyDisconnecting; 1448aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn } 1449aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn 1450aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn /** 1451aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn * Sets whether this call is in a disconnecting state. 1452aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn * 1453aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn * @param isLocallyDisconnecting {@code true} if this call is locally disconnecting. 1454aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn */ 1455aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn private void setLocallyDisconnecting(boolean isLocallyDisconnecting) { 1456aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn mIsLocallyDisconnecting = isLocallyDisconnecting; 1457aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn } 1458aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn 14590fbe6321e341ddce186634266dba2db3fa426b88Santos Cordon static int getStateFromConnectionState(int state) { 146072890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon switch (state) { 1461a02bef5d67f261d7457d0dab9e51595f1960128bIhab Awad case Connection.STATE_INITIALIZING: 1462a02bef5d67f261d7457d0dab9e51595f1960128bIhab Awad return CallState.CONNECTING; 14636fb37c87836b5245046bd3b14320823ab839a10cIhab Awad case Connection.STATE_ACTIVE: 146472890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon return CallState.ACTIVE; 14656fb37c87836b5245046bd3b14320823ab839a10cIhab Awad case Connection.STATE_DIALING: 146672890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon return CallState.DIALING; 14676fb37c87836b5245046bd3b14320823ab839a10cIhab Awad case Connection.STATE_DISCONNECTED: 146872890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon return CallState.DISCONNECTED; 14696fb37c87836b5245046bd3b14320823ab839a10cIhab Awad case Connection.STATE_HOLDING: 147072890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon return CallState.ON_HOLD; 14716fb37c87836b5245046bd3b14320823ab839a10cIhab Awad case Connection.STATE_NEW: 147272890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon return CallState.NEW; 14736fb37c87836b5245046bd3b14320823ab839a10cIhab Awad case Connection.STATE_RINGING: 147472890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon return CallState.RINGING; 147572890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon } 147672890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon return CallState.DISCONNECTED; 147772890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon } 14789f2bed31374a56487f370be01224baf6ce97e8adBen Gilad} 1479