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;
258a736a887b50d4d042c008b2073e24e1b4681dfbYorke Leeimport android.provider.ContactsContract.Contacts;
267cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.CallState;
27701dc006ac11625b55d872f1639107b028933895Andrew Leeimport android.telecom.DisconnectCause;
287cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.Connection;
297cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.GatewayInfo;
307cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.ParcelableConnection;
317cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.PhoneAccount;
327cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.PhoneAccountHandle;
337cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnimport android.telecom.PhoneCapabilities;
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;
478a736a887b50d4d042c008b2073e24e1b4681dfbYorke Lee
4891d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunnimport com.android.internal.util.Preconditions;
4961d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon
5012d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordonimport java.util.ArrayList;
51ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awadimport java.util.Collections;
52a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordonimport java.util.LinkedList;
53a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordonimport java.util.List;
549199078322aea6df26f0d304a28a9a6d040f0717Sailesh Nepalimport java.util.Locale;
55e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepalimport java.util.Objects;
566192561b1f56d7c4e6c650e178e07ba61ad02667Ben Giladimport java.util.Set;
57a82c8f794a0a1a9eaa1329a6361abe28043d139aJay Shraunerimport java.util.concurrent.ConcurrentHashMap;
580407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad
592495d57b5b91f3a39529d8844a49d1be5f18b137Ben Gilad/**
602495d57b5b91f3a39529d8844a49d1be5f18b137Ben Gilad *  Encapsulates all aspects of a given phone call throughout its lifecycle, starting
617cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunn *  from the time the call intent was received by Telecom (vs. the time the call was
622495d57b5b91f3a39529d8844a49d1be5f18b137Ben Gilad *  connected etc).
632495d57b5b91f3a39529d8844a49d1be5f18b137Ben Gilad */
64664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepalfinal class Call implements CreateConnectionResponse {
65766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon    /**
66766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon     * Listener for events on the call.
67766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon     */
68766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon    interface Listener {
696fb37c87836b5245046bd3b14320823ab839a10cIhab Awad        void onSuccessfulOutgoingCall(Call call, int callState);
70701dc006ac11625b55d872f1639107b028933895Andrew Lee        void onFailedOutgoingCall(Call call, DisconnectCause disconnectCause);
71c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal        void onSuccessfulIncomingCall(Call call);
72766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon        void onFailedIncomingCall(Call call);
739250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee        void onSuccessfulUnknownCall(Call call, int callState);
749250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee        void onFailedUnknownCall(Call call);
755be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee        void onRingbackRequested(Call call, boolean ringbackRequested);
76352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton        void onPostDialWait(Call call, String remaining);
77e20bc974ffc24d852d09e153a280b51e0329299cSailesh Nepal        void onCallCapabilitiesChanged(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);
9264c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon    }
9364c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon
9464c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon    abstract static class ListenerBase implements Listener {
9564c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon        @Override
966fb37c87836b5245046bd3b14320823ab839a10cIhab Awad        public void onSuccessfulOutgoingCall(Call call, int callState) {}
9764c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon        @Override
98701dc006ac11625b55d872f1639107b028933895Andrew Lee        public void onFailedOutgoingCall(Call call, DisconnectCause disconnectCause) {}
9964c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon        @Override
100c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal        public void onSuccessfulIncomingCall(Call call) {}
10164c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon        @Override
10264c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon        public void onFailedIncomingCall(Call call) {}
10364c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon        @Override
1049250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee        public void onSuccessfulUnknownCall(Call call, int callState) {}
1059250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee        @Override
1069250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee        public void onFailedUnknownCall(Call call) {}
1079250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee        @Override
1085be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee        public void onRingbackRequested(Call call, boolean ringbackRequested) {}
10964c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon        @Override
11064c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon        public void onPostDialWait(Call call, String remaining) {}
11164c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon        @Override
112e20bc974ffc24d852d09e153a280b51e0329299cSailesh Nepal        public void onCallCapabilitiesChanged(Call call) {}
11364c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon        @Override
11464c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon        public void onParentChanged(Call call) {}
11564c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon        @Override
11664c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon        public void onChildrenChanged(Call call) {}
11764c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon        @Override
11864c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon        public void onCannedSmsResponsesLoaded(Call call) {}
11964c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon        @Override
1203bcf935b25470e94c8c6855862434d15b785c54aAndrew Lee        public void onVideoCallProviderChanged(Call call) {}
12164c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon        @Override
12264c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon        public void onCallerInfoChanged(Call call) {}
1237e66957928c5c23a1028c8e2a2d7cf359cbfa44eSailesh Nepal        @Override
1245be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee        public void onIsVoipAudioModeChanged(Call call) {}
12535faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal        @Override
12635faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal        public void onStatusHintsChanged(Call call) {}
127e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal        @Override
128e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal        public void onHandleChanged(Call call) {}
129e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal        @Override
130e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal        public void onCallerDisplayNameChanged(Call call) {}
1314a79660c984d54679ad4d2bdc89e224d9c8c375bAndrew Lee        @Override
1324a79660c984d54679ad4d2bdc89e224d9c8c375bAndrew Lee        public void onVideoStateChanged(Call call) {}
1339d58de5df05d0358fc8ae57ab7e9a0c45337c602Sailesh Nepal        @Override
134b78b27693afbe9736f0a54ec473328955251f885Ihab Awad        public void onTargetPhoneAccountChanged(Call call) {}
135b78b27693afbe9736f0a54ec473328955251f885Ihab Awad        @Override
136b78b27693afbe9736f0a54ec473328955251f885Ihab Awad        public void onConnectionManagerPhoneAccountChanged(Call call) {}
13712d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon        @Override
13812d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon        public void onPhoneAccountChanged(Call call) {}
13912d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon        @Override
14012d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon        public void onConferenceableCallsChanged(Call call) {}
141766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon    }
142766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon
143fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon    private static final OnQueryCompleteListener sCallerInfoQueryListener =
14499c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon            new OnQueryCompleteListener() {
14599c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon                /** ${inheritDoc} */
14699c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon                @Override
14799c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon                public void onQueryComplete(int token, Object cookie, CallerInfo callerInfo) {
14899c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon                    if (cookie != null) {
14999c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon                        ((Call) cookie).setCallerInfo(callerInfo, token);
15099c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon                    }
151fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon                }
15299c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon            };
15399c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon
15499c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon    private static final OnImageLoadCompleteListener sPhotoLoadListener =
15599c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon            new OnImageLoadCompleteListener() {
15699c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon                /** ${inheritDoc} */
15799c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon                @Override
15899c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon                public void onImageLoadComplete(
15999c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon                        int token, Drawable photo, Bitmap photoIcon, Object cookie) {
16099c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon                    if (cookie != null) {
16199c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon                        ((Call) cookie).setPhoto(photo, photoIcon, token);
16299c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon                    }
16399c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon                }
16499c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon            };
1650407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad
166664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    private final Runnable mDirectToVoicemailRunnable = new Runnable() {
167664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        @Override
168664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        public void run() {
169664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            processDirectToVoicemail();
170664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        }
171664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    };
172664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
173810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal    /** True if this is an incoming call. */
174810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal    private final boolean mIsIncoming;
175810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal
1769250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee    /** True if this is a currently unknown call that was not previously tracked by CallsManager,
1779250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee     *  and did not originate via the regular incoming/outgoing call code paths.
1789250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee     */
1799250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee    private boolean mIsUnknown;
1809250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee
1810407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad    /**
182664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal     * The time this call was created. Beyond logging and such, may also be used for bookkeeping
183664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal     * and specifically for marking certain call attempts as failed attempts.
1840407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad     */
1858c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal    private final long mCreationTimeMillis = System.currentTimeMillis();
1868c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal
187fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon    /** The gateway information associated with this call. This stores the original call handle
188fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon     * that the user is attempting to connect to via the gateway, the actual handle to dial in
189fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon     * order to connect the call via the gateway, as well as the package name of the gateway
190fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon     * service. */
1910d3076c3dfa54f1102a843735ca774759e52d8b8Nancy Chen    private GatewayInfo mGatewayInfo;
192fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon
193b78b27693afbe9736f0a54ec473328955251f885Ihab Awad    private PhoneAccountHandle mConnectionManagerPhoneAccountHandle;
194b78b27693afbe9736f0a54ec473328955251f885Ihab Awad
195b78b27693afbe9736f0a54ec473328955251f885Ihab Awad    private PhoneAccountHandle mTargetPhoneAccountHandle;
19677d2d0e90bc2a67d526743b8e32f920a0d755fbaNancy Chen
1972174fb56907fddf5680355e097f4425f837983e2Santos Cordon    private final Handler mHandler = new Handler();
1982174fb56907fddf5680355e097f4425f837983e2Santos Cordon
19912d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon    private final List<Call> mConferenceableCalls = new ArrayList<>();
20012d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon
20103f51283f587aa08bd4a40f21c866cbb9f679e6aYorke Lee    private long mConnectTimeMillis = 0;
2020407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad
20361d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon    /** The state of the call. */
2046fb37c87836b5245046bd3b14320823ab839a10cIhab Awad    private int mState;
20561d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon
20661d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon    /** The handle with which to establish this call. */
207ce704b9a5d9cf7db30a8c865975c70e5cbc0dc5cSailesh Nepal    private Uri mHandle;
20861d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon
209201b437535ebd07a3d8bf771920a4cb72d145ff3Nancy Chen    /**
2107cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunn     * The presentation requirements for the handle. See {@link TelecomManager} for valid values.
211201b437535ebd07a3d8bf771920a4cb72d145ff3Nancy Chen     */
212e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal    private int mHandlePresentation;
213e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal
214e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal    /** The caller display name (CNAP) set by the connection service. */
215e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal    private String mCallerDisplayName;
216e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal
217201b437535ebd07a3d8bf771920a4cb72d145ff3Nancy Chen    /**
2187cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunn     * The presentation requirements for the handle. See {@link TelecomManager} for valid values.
219201b437535ebd07a3d8bf771920a4cb72d145ff3Nancy Chen     */
220e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal    private int mCallerDisplayNamePresentation;
221e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal
2220407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad    /**
223c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal     * The connection service which is attempted or already connecting this call.
224681663d17b6d92b604526a54b196fa88f25b6957Santos Cordon     */
225c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal    private ConnectionServiceWrapper mConnectionService;
2266192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad
2276aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal    private boolean mIsEmergencyCall;
2286aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal
229b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati    private boolean mSpeakerphoneOn;
230b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati
2310a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn    /**
2320a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn     * Tracks the video states which were applicable over the duration of a call.
2336fb37c87836b5245046bd3b14320823ab839a10cIhab Awad     * See {@link VideoProfile} for a list of valid video states.
2340a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn     */
2350a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn    private int mVideoStateHistory;
2360a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn
237c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn    private int mVideoState;
238c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn
2396192561b1f56d7c4e6c650e178e07ba61ad02667Ben Gilad    /**
2406fb37c87836b5245046bd3b14320823ab839a10cIhab Awad     * Disconnect cause for the call. Only valid if the state of the call is STATE_DISCONNECTED.
241701dc006ac11625b55d872f1639107b028933895Andrew Lee     * See {@link android.telecom.DisconnectCause}.
24279ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon     */
243701dc006ac11625b55d872f1639107b028933895Andrew Lee    private DisconnectCause mDisconnectCause = new DisconnectCause(DisconnectCause.UNKNOWN);
24479ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon
245c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal    /** Info used by the connection services. */
2468c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal    private Bundle mExtras = Bundle.EMPTY;
24784fa5f8c59a1cd3c5716c239fb19c58244fc81feSailesh Nepal
248a82c8f794a0a1a9eaa1329a6361abe28043d139aJay Shrauner    /** Set of listeners on this call.
249a82c8f794a0a1a9eaa1329a6361abe28043d139aJay Shrauner     *
250a82c8f794a0a1a9eaa1329a6361abe28043d139aJay Shrauner     * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
251a82c8f794a0a1a9eaa1329a6361abe28043d139aJay Shrauner     * load factor before resizing, 1 means we only expect a single thread to
252a82c8f794a0a1a9eaa1329a6361abe28043d139aJay Shrauner     * access the map so make only a single shard
253a82c8f794a0a1a9eaa1329a6361abe28043d139aJay Shrauner     */
254a82c8f794a0a1a9eaa1329a6361abe28043d139aJay Shrauner    private final Set<Listener> mListeners = Collections.newSetFromMap(
255a82c8f794a0a1a9eaa1329a6361abe28043d139aJay Shrauner            new ConcurrentHashMap<Listener, Boolean>(8, 0.9f, 1));
256766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon
257664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    private CreateConnectionProcessor mCreateConnectionProcessor;
258682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon
259fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon    /** Caller information retrieved from the latest contact query. */
260fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon    private CallerInfo mCallerInfo;
261fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon
262fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon    /** The latest token used with a contact info query. */
263fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon    private int mQueryToken = 0;
264fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon
2657cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunn    /** Whether this call is requesting that Telecom play the ringback tone on its behalf. */
2665be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee    private boolean mRingbackRequested = false;
267cb387ac1bb278de62e352b363cb38339629a61f5Ihab Awad
268c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal    /** Whether direct-to-voicemail query is pending. */
269c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal    private boolean mDirectToVoicemailQueryPending;
2702174fb56907fddf5680355e097f4425f837983e2Santos Cordon
271e20bc974ffc24d852d09e153a280b51e0329299cSailesh Nepal    private int mCallCapabilities;
272a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon
273a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon    private boolean mIsConference = false;
274a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon
275a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon    private Call mParentCall = null;
276a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon
277a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon    private List<Call> mChildCalls = new LinkedList<>();
278a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon
279ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad    /** Set of text message responses allowed for this call, if applicable. */
280ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad    private List<String> mCannedSmsResponses = Collections.EMPTY_LIST;
281ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad
282ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad    /** Whether an attempt has been made to load the text message responses. */
283ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad    private boolean mCannedSmsResponsesLoadingStarted = false;
284ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad
2856fb37c87836b5245046bd3b14320823ab839a10cIhab Awad    private IVideoProvider mVideoProvider;
286a65d41fb134e323ab43c3f9454313b262959b1d0Nancy Chen
2875be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee    private boolean mIsVoipAudioMode;
28835faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal    private StatusHints mStatusHints;
289664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    private final ConnectionServiceRepository mRepository;
29091d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn    private final Context mContext;
2917e66957928c5c23a1028c8e2a2d7cf359cbfa44eSailesh Nepal
29288a4a60284de8e1222488667b810b098c16d22acSantos Cordon    private boolean mWasConferencePreviouslyMerged = false;
29388a4a60284de8e1222488667b810b098c16d22acSantos Cordon
29488a4a60284de8e1222488667b810b098c16d22acSantos Cordon    // For conferences which support merge/swap at their level, we retain a notion of an active call.
29588a4a60284de8e1222488667b810b098c16d22acSantos Cordon    // This is used for BluetoothPhoneService.  In order to support hold/merge, it must have the notion
29688a4a60284de8e1222488667b810b098c16d22acSantos Cordon    // of the current "active" call within the conference call. This maintains the "active" call and
29788a4a60284de8e1222488667b810b098c16d22acSantos Cordon    // switches every time the user hits "swap".
29888a4a60284de8e1222488667b810b098c16d22acSantos Cordon    private Call mConferenceLevelActiveCall = null;
29988a4a60284de8e1222488667b810b098c16d22acSantos Cordon
300aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn    private boolean mIsLocallyDisconnecting = false;
301aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn
3028c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal    /**
3030407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad     * Persists the specified parameters and initializes the new instance.
3040407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad     *
30591d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn     * @param context The context.
30691d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn     * @param repository The connection service repository.
3070407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad     * @param handle The handle to dial.
30833501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee     * @param gatewayInfo Gateway information to use for the call.
309b78b27693afbe9736f0a54ec473328955251f885Ihab Awad     * @param connectionManagerPhoneAccountHandle Account to use for the service managing the call.
310b78b27693afbe9736f0a54ec473328955251f885Ihab Awad     *         This account must be one that was registered with the
311b78b27693afbe9736f0a54ec473328955251f885Ihab Awad     *         {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER} flag.
312b78b27693afbe9736f0a54ec473328955251f885Ihab Awad     * @param targetPhoneAccountHandle Account information to use for the call. This account must be
313b78b27693afbe9736f0a54ec473328955251f885Ihab Awad     *         one that was registered with the {@link PhoneAccount#CAPABILITY_CALL_PROVIDER} flag.
314810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal     * @param isIncoming True if this is an incoming call.
3150407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad     */
316664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    Call(
31791d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn            Context context,
318664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            ConnectionServiceRepository repository,
319664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            Uri handle,
320664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            GatewayInfo gatewayInfo,
321b78b27693afbe9736f0a54ec473328955251f885Ihab Awad            PhoneAccountHandle connectionManagerPhoneAccountHandle,
322b78b27693afbe9736f0a54ec473328955251f885Ihab Awad            PhoneAccountHandle targetPhoneAccountHandle,
323664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            boolean isIncoming,
324664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            boolean isConference) {
325a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon        mState = isConference ? CallState.ACTIVE : CallState.NEW;
32691d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn        mContext = context;
327664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        mRepository = repository;
3280d3076c3dfa54f1102a843735ca774759e52d8b8Nancy Chen        setHandle(handle);
3297cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunn        setHandle(handle, TelecomManager.PRESENTATION_ALLOWED);
33033501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee        mGatewayInfo = gatewayInfo;
331f193ba45fae5bc87e6a57779e4f5b56be59d08b0Santos Cordon        setConnectionManagerPhoneAccount(connectionManagerPhoneAccountHandle);
332f193ba45fae5bc87e6a57779e4f5b56be59d08b0Santos Cordon        setTargetPhoneAccount(targetPhoneAccountHandle);
333810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal        mIsIncoming = isIncoming;
334a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon        mIsConference = isConference;
335ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad        maybeLoadCannedSmsResponses();
3360407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad    }
3370407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad
338766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon    void addListener(Listener listener) {
339766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon        mListeners.add(listener);
340766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon    }
341766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon
342766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon    void removeListener(Listener listener) {
343a82c8f794a0a1a9eaa1329a6361abe28043d139aJay Shrauner        if (listener != null) {
344a82c8f794a0a1a9eaa1329a6361abe28043d139aJay Shrauner            mListeners.remove(listener);
345a82c8f794a0a1a9eaa1329a6361abe28043d139aJay Shrauner        }
346766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon    }
347766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon
34861d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon    /** {@inheritDoc} */
34912d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon    @Override
35012d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon    public String toString() {
3514538f01647fa207b41fb7e481cc180e67fd391deSailesh Nepal        String component = null;
352c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal        if (mConnectionService != null && mConnectionService.getComponentName() != null) {
353c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal            component = mConnectionService.getComponentName().flattenToShortString();
3544538f01647fa207b41fb7e481cc180e67fd391deSailesh Nepal        }
3550a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn
35666fe882a6437de1010af0dc8cd7350f81f2e028aSantos Cordon        return String.format(Locale.US, "[%s, %s, %s, %s, %d, childs(%d), has_parent(%b), [%s]",
35766fe882a6437de1010af0dc8cd7350f81f2e028aSantos Cordon                System.identityHashCode(this),
35866fe882a6437de1010af0dc8cd7350f81f2e028aSantos Cordon                CallState.toString(mState),
35966fe882a6437de1010af0dc8cd7350f81f2e028aSantos Cordon                component,
36066fe882a6437de1010af0dc8cd7350f81f2e028aSantos Cordon                Log.piiHandle(mHandle),
36166fe882a6437de1010af0dc8cd7350f81f2e028aSantos Cordon                getVideoState(),
36266fe882a6437de1010af0dc8cd7350f81f2e028aSantos Cordon                getChildCalls().size(),
36366fe882a6437de1010af0dc8cd7350f81f2e028aSantos Cordon                getParentCall() != null,
36466fe882a6437de1010af0dc8cd7350f81f2e028aSantos Cordon                PhoneCapabilities.toString(getCallCapabilities()));
36561d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon    }
36661d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon
3676fb37c87836b5245046bd3b14320823ab839a10cIhab Awad    int getState() {
3680fbe6321e341ddce186634266dba2db3fa426b88Santos Cordon        return mState;
3690b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon    }
3700b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon
3710b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon    /**
3720b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon     * Sets the call state. Although there exists the notion of appropriate state transitions
3730b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon     * (see {@link CallState}), in practice those expectations break down when cellular systems
3740b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon     * misbehave and they do this very often. The result is that we do not enforce state transitions
3750b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon     * and instead keep the code resilient to unexpected state changes.
3760b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon     */
3776fb37c87836b5245046bd3b14320823ab839a10cIhab Awad    void setState(int newState) {
378810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal        if (mState != newState) {
379810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal            Log.v(this, "setState %s -> %s", mState, newState);
380810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal            mState = newState;
381ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad            maybeLoadCannedSmsResponses();
382672321e603555849831dd88d5c9f93d88143ee48Santos Cordon
383672321e603555849831dd88d5c9f93d88143ee48Santos Cordon            if (mState == CallState.DISCONNECTED) {
3845dfd3800f15e9b0f1420813d8d7638e1cf9d621dSantos Cordon                setLocallyDisconnecting(false);
385672321e603555849831dd88d5c9f93d88143ee48Santos Cordon                fixParentAfterDisconnect();
386672321e603555849831dd88d5c9f93d88143ee48Santos Cordon            }
387810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal        }
3880b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon    }
3890b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon
3905be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee    void setRingbackRequested(boolean ringbackRequested) {
3915be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee        mRingbackRequested = ringbackRequested;
392cb387ac1bb278de62e352b363cb38339629a61f5Ihab Awad        for (Listener l : mListeners) {
3935be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee            l.onRingbackRequested(this, mRingbackRequested);
394cb387ac1bb278de62e352b363cb38339629a61f5Ihab Awad        }
395cb387ac1bb278de62e352b363cb38339629a61f5Ihab Awad    }
396cb387ac1bb278de62e352b363cb38339629a61f5Ihab Awad
3975be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee    boolean isRingbackRequested() {
3985be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee        return mRingbackRequested;
399cb387ac1bb278de62e352b363cb38339629a61f5Ihab Awad    }
400cb387ac1bb278de62e352b363cb38339629a61f5Ihab Awad
401672321e603555849831dd88d5c9f93d88143ee48Santos Cordon    boolean isConference() {
402672321e603555849831dd88d5c9f93d88143ee48Santos Cordon        return mIsConference;
403672321e603555849831dd88d5c9f93d88143ee48Santos Cordon    }
404672321e603555849831dd88d5c9f93d88143ee48Santos Cordon
405ce704b9a5d9cf7db30a8c865975c70e5cbc0dc5cSailesh Nepal    Uri getHandle() {
4060bf5b912285e328a8f5eeec158d6caf17845b9f8Ben Gilad        return mHandle;
4070bf5b912285e328a8f5eeec158d6caf17845b9f8Ben Gilad    }
4080bf5b912285e328a8f5eeec158d6caf17845b9f8Ben Gilad
409e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal    int getHandlePresentation() {
410e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal        return mHandlePresentation;
411e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal    }
412e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal
4130d3076c3dfa54f1102a843735ca774759e52d8b8Nancy Chen
4140d3076c3dfa54f1102a843735ca774759e52d8b8Nancy Chen    void setHandle(Uri handle) {
4157cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunn        setHandle(handle, TelecomManager.PRESENTATION_ALLOWED);
4160d3076c3dfa54f1102a843735ca774759e52d8b8Nancy Chen    }
4170d3076c3dfa54f1102a843735ca774759e52d8b8Nancy Chen
418e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal    void setHandle(Uri handle, int presentation) {
419e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal        if (!Objects.equals(handle, mHandle) || presentation != mHandlePresentation) {
420fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon            mHandle = handle;
421e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal            mHandlePresentation = presentation;
42291d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn            mIsEmergencyCall = mHandle != null && PhoneNumberUtils.isLocalEmergencyNumber(mContext,
42391d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn                    mHandle.getSchemeSpecificPart());
424fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon            startCallerInfoLookup();
425e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal            for (Listener l : mListeners) {
426e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal                l.onHandleChanged(this);
427e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal            }
428e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal        }
429e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal    }
430e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal
431e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal    String getCallerDisplayName() {
432e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal        return mCallerDisplayName;
433e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal    }
434e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal
435e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal    int getCallerDisplayNamePresentation() {
436e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal        return mCallerDisplayNamePresentation;
437e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal    }
438e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal
439e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal    void setCallerDisplayName(String callerDisplayName, int presentation) {
440e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal        if (!TextUtils.equals(callerDisplayName, mCallerDisplayName) ||
441e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal                presentation != mCallerDisplayNamePresentation) {
442e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal            mCallerDisplayName = callerDisplayName;
443e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal            mCallerDisplayNamePresentation = presentation;
444e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal            for (Listener l : mListeners) {
445e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal                l.onCallerDisplayNameChanged(this);
446e8ecb98d5341395e073d02c065143ae3ac76ef71Sailesh Nepal            }
447fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon        }
4486aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal    }
4496aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal
45099c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon    String getName() {
45199c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon        return mCallerInfo == null ? null : mCallerInfo.name;
45299c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon    }
45399c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon
45499c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon    Bitmap getPhotoIcon() {
45599c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon        return mCallerInfo == null ? null : mCallerInfo.cachedPhotoIcon;
45699c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon    }
45799c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon
45899c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon    Drawable getPhoto() {
45999c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon        return mCallerInfo == null ? null : mCallerInfo.cachedPhoto;
46099c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon    }
46199c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon
46279ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon    /**
463701dc006ac11625b55d872f1639107b028933895Andrew Lee     * @param disconnectCause The reason for the disconnection, represented by
464701dc006ac11625b55d872f1639107b028933895Andrew Lee     *         {@link android.telecom.DisconnectCause}.
46579ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon     */
466701dc006ac11625b55d872f1639107b028933895Andrew Lee    void setDisconnectCause(DisconnectCause disconnectCause) {
46779ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon        // TODO: Consider combining this method with a setDisconnected() method that is totally
46879ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon        // separate from setState.
46979ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon        mDisconnectCause = disconnectCause;
47079ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon    }
47179ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon
472701dc006ac11625b55d872f1639107b028933895Andrew Lee    DisconnectCause getDisconnectCause() {
47379ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon        return mDisconnectCause;
47479ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon    }
47579ff2bcdbdf1c28f229f4acec9433beb1cd7a57eSantos Cordon
4766aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal    boolean isEmergencyCall() {
4776aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal        return mIsEmergencyCall;
47861d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon    }
47961d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon
48033501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee    /**
48133501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee     * @return The original handle this call is associated with. In-call services should use this
48233501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee     * handle when indicating in their UI the handle that is being called.
48333501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee     */
48433501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee    public Uri getOriginalHandle() {
48533501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee        if (mGatewayInfo != null && !mGatewayInfo.isEmpty()) {
486201b437535ebd07a3d8bf771920a4cb72d145ff3Nancy Chen            return mGatewayInfo.getOriginalAddress();
48733501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee        }
48833501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee        return getHandle();
48933501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee    }
49033501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee
49133501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee    GatewayInfo getGatewayInfo() {
49233501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee        return mGatewayInfo;
49333501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee    }
49433501635c2cd21f40793041eff3b8ce3a5710d49Yorke Lee
4950d3076c3dfa54f1102a843735ca774759e52d8b8Nancy Chen    void setGatewayInfo(GatewayInfo gatewayInfo) {
4960d3076c3dfa54f1102a843735ca774759e52d8b8Nancy Chen        mGatewayInfo = gatewayInfo;
4970d3076c3dfa54f1102a843735ca774759e52d8b8Nancy Chen    }
4980d3076c3dfa54f1102a843735ca774759e52d8b8Nancy Chen
499b78b27693afbe9736f0a54ec473328955251f885Ihab Awad    PhoneAccountHandle getConnectionManagerPhoneAccount() {
500b78b27693afbe9736f0a54ec473328955251f885Ihab Awad        return mConnectionManagerPhoneAccountHandle;
501b78b27693afbe9736f0a54ec473328955251f885Ihab Awad    }
502b78b27693afbe9736f0a54ec473328955251f885Ihab Awad
503b78b27693afbe9736f0a54ec473328955251f885Ihab Awad    void setConnectionManagerPhoneAccount(PhoneAccountHandle accountHandle) {
504b78b27693afbe9736f0a54ec473328955251f885Ihab Awad        if (!Objects.equals(mConnectionManagerPhoneAccountHandle, accountHandle)) {
505b78b27693afbe9736f0a54ec473328955251f885Ihab Awad            mConnectionManagerPhoneAccountHandle = accountHandle;
506b78b27693afbe9736f0a54ec473328955251f885Ihab Awad            for (Listener l : mListeners) {
507b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                l.onConnectionManagerPhoneAccountChanged(this);
508b78b27693afbe9736f0a54ec473328955251f885Ihab Awad            }
509b78b27693afbe9736f0a54ec473328955251f885Ihab Awad        }
510b78b27693afbe9736f0a54ec473328955251f885Ihab Awad
511b78b27693afbe9736f0a54ec473328955251f885Ihab Awad    }
512b78b27693afbe9736f0a54ec473328955251f885Ihab Awad
513b78b27693afbe9736f0a54ec473328955251f885Ihab Awad    PhoneAccountHandle getTargetPhoneAccount() {
514b78b27693afbe9736f0a54ec473328955251f885Ihab Awad        return mTargetPhoneAccountHandle;
51577d2d0e90bc2a67d526743b8e32f920a0d755fbaNancy Chen    }
51677d2d0e90bc2a67d526743b8e32f920a0d755fbaNancy Chen
517b78b27693afbe9736f0a54ec473328955251f885Ihab Awad    void setTargetPhoneAccount(PhoneAccountHandle accountHandle) {
518b78b27693afbe9736f0a54ec473328955251f885Ihab Awad        if (!Objects.equals(mTargetPhoneAccountHandle, accountHandle)) {
519b78b27693afbe9736f0a54ec473328955251f885Ihab Awad            mTargetPhoneAccountHandle = accountHandle;
52069eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad            for (Listener l : mListeners) {
521b78b27693afbe9736f0a54ec473328955251f885Ihab Awad                l.onTargetPhoneAccountChanged(this);
52269eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad            }
52369eb0f582babcedc1dc5e6613a27867be6e8d0e0Ihab Awad        }
52453ceedc1f5ae5a075c7a3186db8bb4db32cbe583Nancy Chen    }
52553ceedc1f5ae5a075c7a3186db8bb4db32cbe583Nancy Chen
526810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal    boolean isIncoming() {
527810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal        return mIsIncoming;
528810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal    }
529810735e3f0a4fe924a805981d32b6916ec834b38Sailesh Nepal
5300407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad    /**
5310407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad     * @return The "age" of this call object in milliseconds, which typically also represents the
5328c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal     *     period since this call was added to the set pending outgoing calls, see
5338c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal     *     mCreationTimeMillis.
5340407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad     */
5358c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal    long getAgeMillis() {
5368c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal        return System.currentTimeMillis() - mCreationTimeMillis;
5370407fb2c5a8358cfae92bbd6f8cdc103d66c7b13Ben Gilad    }
5380b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon
539f98fb5790ed62a3d4893362554f8d251c74d0ecdYorke Lee    /**
540f98fb5790ed62a3d4893362554f8d251c74d0ecdYorke Lee     * @return The time when this call object was created and added to the set of pending outgoing
541f98fb5790ed62a3d4893362554f8d251c74d0ecdYorke Lee     *     calls.
542f98fb5790ed62a3d4893362554f8d251c74d0ecdYorke Lee     */
5438c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal    long getCreationTimeMillis() {
5448c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal        return mCreationTimeMillis;
5458c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal    }
5468c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal
5478c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal    long getConnectTimeMillis() {
5488c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal        return mConnectTimeMillis;
5498c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal    }
5508c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal
5518c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal    void setConnectTimeMillis(long connectTimeMillis) {
5528c85dee84fbbd8c36cf1c7b061001c6129623f92Sailesh Nepal        mConnectTimeMillis = connectTimeMillis;
553f98fb5790ed62a3d4893362554f8d251c74d0ecdYorke Lee    }
554f98fb5790ed62a3d4893362554f8d251c74d0ecdYorke Lee
555e20bc974ffc24d852d09e153a280b51e0329299cSailesh Nepal    int getCallCapabilities() {
556e20bc974ffc24d852d09e153a280b51e0329299cSailesh Nepal        return mCallCapabilities;
557a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon    }
558a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon
559e20bc974ffc24d852d09e153a280b51e0329299cSailesh Nepal    void setCallCapabilities(int callCapabilities) {
560604a90f596deb41998e021151b3ddc8019e28eacYorke Lee        setCallCapabilities(callCapabilities, false /* forceUpdate */);
561604a90f596deb41998e021151b3ddc8019e28eacYorke Lee    }
562604a90f596deb41998e021151b3ddc8019e28eacYorke Lee
563604a90f596deb41998e021151b3ddc8019e28eacYorke Lee    void setCallCapabilities(int callCapabilities, boolean forceUpdate) {
5646fb37c87836b5245046bd3b14320823ab839a10cIhab Awad        Log.v(this, "setCallCapabilities: %s", PhoneCapabilities.toString(callCapabilities));
565604a90f596deb41998e021151b3ddc8019e28eacYorke Lee        if (forceUpdate || mCallCapabilities != callCapabilities) {
56612d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon           mCallCapabilities = callCapabilities;
567a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon            for (Listener l : mListeners) {
568e20bc974ffc24d852d09e153a280b51e0329299cSailesh Nepal                l.onCallCapabilitiesChanged(this);
569a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon            }
570a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon        }
571a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon    }
572a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon
573a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon    Call getParentCall() {
574a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon        return mParentCall;
575a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon    }
576a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon
577a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon    List<Call> getChildCalls() {
578a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon        return mChildCalls;
579a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon    }
580a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon
58188a4a60284de8e1222488667b810b098c16d22acSantos Cordon    boolean wasConferencePreviouslyMerged() {
58288a4a60284de8e1222488667b810b098c16d22acSantos Cordon        return mWasConferencePreviouslyMerged;
58388a4a60284de8e1222488667b810b098c16d22acSantos Cordon    }
58488a4a60284de8e1222488667b810b098c16d22acSantos Cordon
58588a4a60284de8e1222488667b810b098c16d22acSantos Cordon    Call getConferenceLevelActiveCall() {
58688a4a60284de8e1222488667b810b098c16d22acSantos Cordon        return mConferenceLevelActiveCall;
58788a4a60284de8e1222488667b810b098c16d22acSantos Cordon    }
58888a4a60284de8e1222488667b810b098c16d22acSantos Cordon
589c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal    ConnectionServiceWrapper getConnectionService() {
590c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal        return mConnectionService;
591681663d17b6d92b604526a54b196fa88f25b6957Santos Cordon    }
592681663d17b6d92b604526a54b196fa88f25b6957Santos Cordon
59391d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn    /**
59491d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn     * Retrieves the {@link Context} for the call.
59591d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn     *
59691d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn     * @return The {@link Context}.
59791d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn     */
59891d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn    Context getContext() {
59991d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn        return mContext;
60091d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn    }
60191d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn
602c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal    void setConnectionService(ConnectionServiceWrapper service) {
603c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal        Preconditions.checkNotNull(service);
6048e55d1d7ea86f768acb90f88dc9e5b5368d3398aBen Gilad
605c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal        clearConnectionService();
6068e55d1d7ea86f768acb90f88dc9e5b5368d3398aBen Gilad
607c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal        service.incrementAssociatedCallCount();
608c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal        mConnectionService = service;
609c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal        mConnectionService.addCall(this);
610681663d17b6d92b604526a54b196fa88f25b6957Santos Cordon    }
611681663d17b6d92b604526a54b196fa88f25b6957Santos Cordon
612681663d17b6d92b604526a54b196fa88f25b6957Santos Cordon    /**
613c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal     * Clears the associated connection service.
614681663d17b6d92b604526a54b196fa88f25b6957Santos Cordon     */
615c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal    void clearConnectionService() {
616c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal        if (mConnectionService != null) {
617c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal            ConnectionServiceWrapper serviceTemp = mConnectionService;
618c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal            mConnectionService = null;
619c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal            serviceTemp.removeCall(this);
620c499c1c0758dcb4b02048df96e7405994660ab3fSantos Cordon
621c499c1c0758dcb4b02048df96e7405994660ab3fSantos Cordon            // Decrementing the count can cause the service to unbind, which itself can trigger the
622c499c1c0758dcb4b02048df96e7405994660ab3fSantos Cordon            // service-death code.  Since the service death code tries to clean up any associated
623c499c1c0758dcb4b02048df96e7405994660ab3fSantos Cordon            // calls, we need to make sure to remove that information (e.g., removeCall()) before
624c499c1c0758dcb4b02048df96e7405994660ab3fSantos Cordon            // we decrement. Technically, invoking removeCall() prior to decrementing is all that is
625c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal            // necessary, but cleaning up mConnectionService prior to triggering an unbind is good
626c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal            // to do.
627c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal            decrementAssociatedCallCount(serviceTemp);
628adee12dd6b3e85ce3ae419329226c9aa72c184fcYorke Lee        }
6298e55d1d7ea86f768acb90f88dc9e5b5368d3398aBen Gilad    }
6308e55d1d7ea86f768acb90f88dc9e5b5368d3398aBen Gilad
631664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal    private void processDirectToVoicemail() {
632c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal        if (mDirectToVoicemailQueryPending) {
6332174fb56907fddf5680355e097f4425f837983e2Santos Cordon            if (mCallerInfo != null && mCallerInfo.shouldSendToVoicemail) {
6342174fb56907fddf5680355e097f4425f837983e2Santos Cordon                Log.i(this, "Directing call to voicemail: %s.", this);
635df39986de36d40aaa45e61d19a21eca536765ca5Santos Cordon                // TODO: Once we move State handling from CallsManager to Call, we
6366fb37c87836b5245046bd3b14320823ab839a10cIhab Awad                // will not need to set STATE_RINGING state prior to calling reject.
6372174fb56907fddf5680355e097f4425f837983e2Santos Cordon                setState(CallState.RINGING);
638ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad                reject(false, null);
6392174fb56907fddf5680355e097f4425f837983e2Santos Cordon            } else {
640df39986de36d40aaa45e61d19a21eca536765ca5Santos Cordon                // TODO: Make this class (not CallsManager) responsible for changing
6416fb37c87836b5245046bd3b14320823ab839a10cIhab Awad                // the call state to STATE_RINGING.
6422174fb56907fddf5680355e097f4425f837983e2Santos Cordon
6436fb37c87836b5245046bd3b14320823ab839a10cIhab Awad                // TODO: Replace this with state transition to STATE_RINGING.
6442174fb56907fddf5680355e097f4425f837983e2Santos Cordon                for (Listener l : mListeners) {
645c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal                    l.onSuccessfulIncomingCall(this);
6462174fb56907fddf5680355e097f4425f837983e2Santos Cordon                }
6472174fb56907fddf5680355e097f4425f837983e2Santos Cordon            }
648766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon
649c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal            mDirectToVoicemailQueryPending = false;
650766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon        }
651766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon    }
652766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon
653766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon    /**
654664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal     * Starts the create connection sequence. Upon completion, there should exist an active
655664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal     * connection through a connection service (or the call will have failed).
65691d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn     *
65791d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn     * @param phoneAccountRegistrar The phone account registrar.
658766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon     */
65991d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn    void startCreateConnection(PhoneAccountRegistrar phoneAccountRegistrar) {
660664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        Preconditions.checkState(mCreateConnectionProcessor == null);
66191d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn        mCreateConnectionProcessor = new CreateConnectionProcessor(this, mRepository, this,
66291d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn                phoneAccountRegistrar, mContext);
663664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        mCreateConnectionProcessor.process();
664766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon    }
665766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon
6665a73b03be0a2a929cf9974578445b90f773937b4Sailesh Nepal    @Override
6678000845a81fd6a88ff69cb11e1b6dff5f47c2332Ihab Awad    public void handleCreateConnectionSuccess(
6688000845a81fd6a88ff69cb11e1b6dff5f47c2332Ihab Awad            CallIdMapper idMapper,
6698000845a81fd6a88ff69cb11e1b6dff5f47c2332Ihab Awad            ParcelableConnection connection) {
67012d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon        Log.v(this, "handleCreateConnectionSuccessful %s", connection);
671664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        mCreateConnectionProcessor = null;
672b78b27693afbe9736f0a54ec473328955251f885Ihab Awad        setTargetPhoneAccount(connection.getPhoneAccount());
67372890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon        setHandle(connection.getHandle(), connection.getHandlePresentation());
67472890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon        setCallerDisplayName(
67572890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon                connection.getCallerDisplayName(), connection.getCallerDisplayNamePresentation());
676b2920b3dfe8782a61db7ecd4b783bb11856cfda3Yorke Lee        setCallCapabilities(connection.getCapabilities());
6776fb37c87836b5245046bd3b14320823ab839a10cIhab Awad        setVideoProvider(connection.getVideoProvider());
678b1a95a77522b2a1c98b378a2e538d819918b7f2cTyler Gunn        setVideoState(connection.getVideoState());
6795be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee        setRingbackRequested(connection.isRingbackRequested());
6805be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee        setIsVoipAudioMode(connection.getIsVoipAudioMode());
681604a4fe52c7de1347f40aadfba1964e9dcfb223cSailesh Nepal        setStatusHints(connection.getStatusHints());
682664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
6838000845a81fd6a88ff69cb11e1b6dff5f47c2332Ihab Awad        mConferenceableCalls.clear();
6848000845a81fd6a88ff69cb11e1b6dff5f47c2332Ihab Awad        for (String id : connection.getConferenceableConnectionIds()) {
6858000845a81fd6a88ff69cb11e1b6dff5f47c2332Ihab Awad            mConferenceableCalls.add(idMapper.getCall(id));
6868000845a81fd6a88ff69cb11e1b6dff5f47c2332Ihab Awad        }
6878000845a81fd6a88ff69cb11e1b6dff5f47c2332Ihab Awad
6889250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee        if (mIsUnknown) {
6899250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee            for (Listener l : mListeners) {
6909250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee                l.onSuccessfulUnknownCall(this, getStateFromConnectionState(connection.getState()));
6919250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee            }
6929250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee        } else if (mIsIncoming) {
693664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            // We do not handle incoming calls immediately when they are verified by the connection
694664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            // service. We allow the caller-info-query code to execute first so that we can read the
695664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            // direct-to-voicemail property before deciding if we want to show the incoming call to
696664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            // the user or if we want to reject the call.
697664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            mDirectToVoicemailQueryPending = true;
698664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
699664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            // Timeout the direct-to-voicemail lookup execution so that we dont wait too long before
700664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            // showing the user the incoming call screen.
70191d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn            mHandler.postDelayed(mDirectToVoicemailRunnable, Timeouts.getDirectToVoicemailMillis(
70291d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn                    mContext.getContentResolver()));
703664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        } else {
704664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            for (Listener l : mListeners) {
705cde2e5062b1b1689cd8962e28763fa0a35e2476aTyler Gunn                l.onSuccessfulOutgoingCall(this,
706cde2e5062b1b1689cd8962e28763fa0a35e2476aTyler Gunn                        getStateFromConnectionState(connection.getState()));
707664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            }
708766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon        }
7095a73b03be0a2a929cf9974578445b90f773937b4Sailesh Nepal    }
7105a73b03be0a2a929cf9974578445b90f773937b4Sailesh Nepal
7115a73b03be0a2a929cf9974578445b90f773937b4Sailesh Nepal    @Override
712701dc006ac11625b55d872f1639107b028933895Andrew Lee    public void handleCreateConnectionFailure(DisconnectCause disconnectCause) {
713664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        mCreateConnectionProcessor = null;
714fb5560d634aef745466e8869f8acf496447da17bIhab Awad        clearConnectionService();
715701dc006ac11625b55d872f1639107b028933895Andrew Lee        setDisconnectCause(disconnectCause);
716701dc006ac11625b55d872f1639107b028933895Andrew Lee        CallsManager.getInstance().markCallAsDisconnected(this, disconnectCause);
717664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal
7189250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee        if (mIsUnknown) {
7199250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee            for (Listener listener : mListeners) {
7209250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee                listener.onFailedUnknownCall(this);
7219250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee            }
7229250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee        } else if (mIsIncoming) {
723a82c8f794a0a1a9eaa1329a6361abe28043d139aJay Shrauner            for (Listener listener : mListeners) {
724a82c8f794a0a1a9eaa1329a6361abe28043d139aJay Shrauner                listener.onFailedIncomingCall(this);
725664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            }
726664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        } else {
727a82c8f794a0a1a9eaa1329a6361abe28043d139aJay Shrauner            for (Listener listener : mListeners) {
728701dc006ac11625b55d872f1639107b028933895Andrew Lee                listener.onFailedOutgoingCall(this, disconnectCause);
729664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            }
730766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon        }
731766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon    }
732766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon
733766d04f7cad00b0b09e39db6835676354acd2cdaSantos Cordon    /**
73474549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad     * Plays the specified DTMF tone.
73574549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad     */
73674549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad    void playDtmfTone(char digit) {
737c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal        if (mConnectionService == null) {
738c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal            Log.w(this, "playDtmfTone() request on a call without a connection service.");
73974549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad        } else {
740c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal            Log.i(this, "Send playDtmfTone to connection service for call %s", this);
741c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal            mConnectionService.playDtmfTone(this, digit);
74274549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad        }
74374549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad    }
74474549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad
74574549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad    /**
74674549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad     * Stops playing any currently playing DTMF tone.
74774549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad     */
74874549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad    void stopDtmfTone() {
749c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal        if (mConnectionService == null) {
750fd4d7b5c86bb3ae9fc78b6dd820654ab977b7092Jay Shrauner            Log.w(this, "stopDtmfTone() request on a call without a connection service.");
75174549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad        } else {
752c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal            Log.i(this, "Send stopDtmfTone to connection service for call %s", this);
753c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal            mConnectionService.stopDtmfTone(this);
75474549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad        }
75574549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad    }
75674549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad
75774549ec95acf0d2ddbe4feca91c6febdf8008074Ihab Awad    /**
758c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal     * Attempts to disconnect the call through the connection service.
759049b7b6a8d0cf44d687d827cb57a18fa23358206Santos Cordon     */
760049b7b6a8d0cf44d687d827cb57a18fa23358206Santos Cordon    void disconnect() {
761aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn        // Track that the call is now locally disconnecting.
762aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn        setLocallyDisconnecting(true);
763aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn
764fd4d7b5c86bb3ae9fc78b6dd820654ab977b7092Jay Shrauner        if (mState == CallState.NEW || mState == CallState.PRE_DIAL_WAIT ||
765fd4d7b5c86bb3ae9fc78b6dd820654ab977b7092Jay Shrauner                mState == CallState.CONNECTING) {
766682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon            Log.v(this, "Aborting call %s", this);
767682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon            abort();
76874d420be72fa30735fe9b7a25715f6db046c0398Santos Cordon        } else if (mState != CallState.ABORTED && mState != CallState.DISCONNECTED) {
769fd4d7b5c86bb3ae9fc78b6dd820654ab977b7092Jay Shrauner            if (mConnectionService == null) {
770fd4d7b5c86bb3ae9fc78b6dd820654ab977b7092Jay Shrauner                Log.e(this, new Exception(), "disconnect() request on a call without a"
771fd4d7b5c86bb3ae9fc78b6dd820654ab977b7092Jay Shrauner                        + " connection service.");
772fd4d7b5c86bb3ae9fc78b6dd820654ab977b7092Jay Shrauner            } else {
773fd4d7b5c86bb3ae9fc78b6dd820654ab977b7092Jay Shrauner                Log.i(this, "Send disconnect to connection service for call: %s", this);
774fd4d7b5c86bb3ae9fc78b6dd820654ab977b7092Jay Shrauner                // The call isn't officially disconnected until the connection service
775fd4d7b5c86bb3ae9fc78b6dd820654ab977b7092Jay Shrauner                // confirms that the call was actually disconnected. Only then is the
776fd4d7b5c86bb3ae9fc78b6dd820654ab977b7092Jay Shrauner                // association between call and connection service severed, see
777fd4d7b5c86bb3ae9fc78b6dd820654ab977b7092Jay Shrauner                // {@link CallsManager#markCallAsDisconnected}.
778fd4d7b5c86bb3ae9fc78b6dd820654ab977b7092Jay Shrauner                mConnectionService.disconnect(this);
779fd4d7b5c86bb3ae9fc78b6dd820654ab977b7092Jay Shrauner            }
780049b7b6a8d0cf44d687d827cb57a18fa23358206Santos Cordon        }
781049b7b6a8d0cf44d687d827cb57a18fa23358206Santos Cordon    }
782049b7b6a8d0cf44d687d827cb57a18fa23358206Santos Cordon
783682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon    void abort() {
784664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal        if (mCreateConnectionProcessor != null) {
785664837f9a8a98f98876417a0bfff64834e8032faSailesh Nepal            mCreateConnectionProcessor.abort();
78643df90f875f867e1e5cfd32b0cbc45440606c946Yorke Lee        } else if (mState == CallState.NEW || mState == CallState.PRE_DIAL_WAIT
78743df90f875f867e1e5cfd32b0cbc45440606c946Yorke Lee                || mState == CallState.CONNECTING) {
788504eb83ea06f4c737a4f4fdbd65aa2450505420cTyler Gunn            handleCreateConnectionFailure(new DisconnectCause(DisconnectCause.CANCELED));
7892d0b331f659e4e95621e738bbddaa38a80a70d4cSantos Cordon        } else {
7902d0b331f659e4e95621e738bbddaa38a80a70d4cSantos Cordon            Log.v(this, "Cannot abort a call which isn't either PRE_DIAL_WAIT or CONNECTING");
791682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon        }
792682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon    }
793682fe6ba2fe99e209d72a051539697a755b994c0Santos Cordon
7940b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon    /**
79561d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon     * Answers the call if it is ringing.
79638931d0ad60f00a9f50c90cef446166731f0b871Andrew Lee     *
79738931d0ad60f00a9f50c90cef446166731f0b871Andrew Lee     * @param videoState The video state in which to answer the call.
79861d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon     */
79938931d0ad60f00a9f50c90cef446166731f0b871Andrew Lee    void answer(int videoState) {
800c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal        Preconditions.checkNotNull(mConnectionService);
80161d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon
80261d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon        // Check to verify that the call is still in the ringing state. A call can change states
8037cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunn        // between the time the user hits 'answer' and Telecom receives the command.
80461d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon        if (isRinging("answer")) {
805c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal            // At this point, we are asking the connection service to answer but we don't assume
806c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal            // that it will work. Instead, we wait until confirmation from the connectino service
8076fb37c87836b5245046bd3b14320823ab839a10cIhab Awad            // that the call is in a non-STATE_RINGING state before changing the UI. See
808c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal            // {@link ConnectionServiceAdapter#setActive} and other set* methods.
80938931d0ad60f00a9f50c90cef446166731f0b871Andrew Lee            mConnectionService.answer(this, videoState);
81061d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon        }
81161d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon    }
81261d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon
81361d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon    /**
81461d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon     * Rejects the call if it is ringing.
815ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad     *
816ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad     * @param rejectWithMessage Whether to send a text message as part of the call rejection.
817ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad     * @param textMessage An optional text message to send as part of the rejection.
81861d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon     */
819ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad    void reject(boolean rejectWithMessage, String textMessage) {
820c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal        Preconditions.checkNotNull(mConnectionService);
82161d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon
82261d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon        // Check to verify that the call is still in the ringing state. A call can change states
82361d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon        // between the time the user hits 'reject' and Telecomm receives the command.
82461d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon        if (isRinging("reject")) {
825c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal            mConnectionService.reject(this);
82661d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon        }
82761d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon    }
82861d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon
82961d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon    /**
830cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee     * Puts the call on hold if it is currently active.
831cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee     */
832cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee    void hold() {
833c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal        Preconditions.checkNotNull(mConnectionService);
834cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee
835cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee        if (mState == CallState.ACTIVE) {
836c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal            mConnectionService.hold(this);
837cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee        }
838cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee    }
839cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee
840cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee    /**
841cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee     * Releases the call from hold if it is currently active.
842cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee     */
843cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee    void unhold() {
844c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal        Preconditions.checkNotNull(mConnectionService);
845cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee
846cdf3ebd3ea6505668304b7e0a39df354ebbb52fbYorke Lee        if (mState == CallState.ON_HOLD) {
847c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal            mConnectionService.unhold(this);
848571f0737002251f09b9ef696dc8b4c9ce02abbaeSantos Cordon        }
8490b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon    }
8500b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon
8516aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal    /** Checks if this is a live call or not. */
8526aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal    boolean isAlive() {
8536aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal        switch (mState) {
8546fb37c87836b5245046bd3b14320823ab839a10cIhab Awad            case CallState.NEW:
8556fb37c87836b5245046bd3b14320823ab839a10cIhab Awad            case CallState.RINGING:
8566fb37c87836b5245046bd3b14320823ab839a10cIhab Awad            case CallState.DISCONNECTED:
8576fb37c87836b5245046bd3b14320823ab839a10cIhab Awad            case CallState.ABORTED:
8586aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal                return false;
8596aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal            default:
8606aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal                return true;
8616aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal        }
8626aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal    }
8636aca10a0efa2771ccdef5920f4276f0db4a7ee1fSailesh Nepal
86440f78c210512570f14cdfde9613dd85c510a1c0cSantos Cordon    boolean isActive() {
86584bfe47a2447c4983bcc58468000f04683eec55bIhab Awad        return mState == CallState.ACTIVE;
86640f78c210512570f14cdfde9613dd85c510a1c0cSantos Cordon    }
86740f78c210512570f14cdfde9613dd85c510a1c0cSantos Cordon
86884fa5f8c59a1cd3c5716c239fb19c58244fc81feSailesh Nepal    Bundle getExtras() {
86984fa5f8c59a1cd3c5716c239fb19c58244fc81feSailesh Nepal        return mExtras;
87084fa5f8c59a1cd3c5716c239fb19c58244fc81feSailesh Nepal    }
87184fa5f8c59a1cd3c5716c239fb19c58244fc81feSailesh Nepal
87284fa5f8c59a1cd3c5716c239fb19c58244fc81feSailesh Nepal    void setExtras(Bundle extras) {
87384fa5f8c59a1cd3c5716c239fb19c58244fc81feSailesh Nepal        mExtras = extras;
87484fa5f8c59a1cd3c5716c239fb19c58244fc81feSailesh Nepal    }
87584fa5f8c59a1cd3c5716c239fb19c58244fc81feSailesh Nepal
8768a736a887b50d4d042c008b2073e24e1b4681dfbYorke Lee    /**
8778a736a887b50d4d042c008b2073e24e1b4681dfbYorke Lee     * @return the uri of the contact associated with this call.
8788a736a887b50d4d042c008b2073e24e1b4681dfbYorke Lee     */
8798a736a887b50d4d042c008b2073e24e1b4681dfbYorke Lee    Uri getContactUri() {
8808a736a887b50d4d042c008b2073e24e1b4681dfbYorke Lee        if (mCallerInfo == null || !mCallerInfo.contactExists) {
881a7fa743f76242e9f039eea2fea0911f59255522eYorke Lee            return getHandle();
8828a736a887b50d4d042c008b2073e24e1b4681dfbYorke Lee        }
8838a736a887b50d4d042c008b2073e24e1b4681dfbYorke Lee        return Contacts.getLookupUri(mCallerInfo.contactIdOrZero, mCallerInfo.lookupKey);
8848a736a887b50d4d042c008b2073e24e1b4681dfbYorke Lee    }
8858a736a887b50d4d042c008b2073e24e1b4681dfbYorke Lee
8865ba7f27491e287f39a999ddd3d1ed6a7bad78272Santos Cordon    Uri getRingtone() {
8875ba7f27491e287f39a999ddd3d1ed6a7bad78272Santos Cordon        return mCallerInfo == null ? null : mCallerInfo.contactRingtoneUri;
8885ba7f27491e287f39a999ddd3d1ed6a7bad78272Santos Cordon    }
8895ba7f27491e287f39a999ddd3d1ed6a7bad78272Santos Cordon
890352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton    void onPostDialWait(String remaining) {
891352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton        for (Listener l : mListeners) {
892352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton            l.onPostDialWait(this, remaining);
893352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton        }
894352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton    }
895352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton
896352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton    void postDialContinue(boolean proceed) {
897c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal        mConnectionService.onPostDialContinue(this, proceed);
898352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton    }
899352105c5d33ac94e5ad0cb5ac2e9268731423e65Evan Charlton
9000fbe6321e341ddce186634266dba2db3fa426b88Santos Cordon    void conferenceWith(Call otherCall) {
901c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal        if (mConnectionService == null) {
902c92c436d84de46bb85100df9138378d9ffe0f2f2Sailesh Nepal            Log.w(this, "conference requested on a call without a connection service.");
903a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon        } else {
9040fbe6321e341ddce186634266dba2db3fa426b88Santos Cordon            mConnectionService.conference(this, otherCall);
905a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon        }
906a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon    }
907a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon
908a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon    void splitFromConference() {
909672321e603555849831dd88d5c9f93d88143ee48Santos Cordon        if (mConnectionService == null) {
910672321e603555849831dd88d5c9f93d88143ee48Santos Cordon            Log.w(this, "splitting from conference call without a connection service");
911672321e603555849831dd88d5c9f93d88143ee48Santos Cordon        } else {
912672321e603555849831dd88d5c9f93d88143ee48Santos Cordon            mConnectionService.splitFromConference(this);
913672321e603555849831dd88d5c9f93d88143ee48Santos Cordon        }
914a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon    }
915a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon
9166805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon    void mergeConference() {
9176805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon        if (mConnectionService == null) {
9186805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon            Log.w(this, "merging conference calls without a connection service.");
9196805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon        } else if (can(PhoneCapabilities.MERGE_CONFERENCE)) {
9206805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon            mConnectionService.mergeConference(this);
92188a4a60284de8e1222488667b810b098c16d22acSantos Cordon            mWasConferencePreviouslyMerged = true;
9226805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon        }
9236805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon    }
9246805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon
9256805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon    void swapConference() {
9266805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon        if (mConnectionService == null) {
9276805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon            Log.w(this, "swapping conference calls without a connection service.");
9286805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon        } else if (can(PhoneCapabilities.SWAP_CONFERENCE)) {
9296805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon            mConnectionService.swapConference(this);
93088a4a60284de8e1222488667b810b098c16d22acSantos Cordon            switch (mChildCalls.size()) {
93188a4a60284de8e1222488667b810b098c16d22acSantos Cordon                case 1:
93288a4a60284de8e1222488667b810b098c16d22acSantos Cordon                    mConferenceLevelActiveCall = mChildCalls.get(0);
93388a4a60284de8e1222488667b810b098c16d22acSantos Cordon                    break;
93488a4a60284de8e1222488667b810b098c16d22acSantos Cordon                case 2:
93588a4a60284de8e1222488667b810b098c16d22acSantos Cordon                    // swap
93688a4a60284de8e1222488667b810b098c16d22acSantos Cordon                    mConferenceLevelActiveCall = mChildCalls.get(0) == mConferenceLevelActiveCall ?
93788a4a60284de8e1222488667b810b098c16d22acSantos Cordon                            mChildCalls.get(1) : mChildCalls.get(0);
93888a4a60284de8e1222488667b810b098c16d22acSantos Cordon                    break;
93988a4a60284de8e1222488667b810b098c16d22acSantos Cordon                default:
94088a4a60284de8e1222488667b810b098c16d22acSantos Cordon                    // For anything else 0, or 3+, set it to null since it is impossible to tell.
94188a4a60284de8e1222488667b810b098c16d22acSantos Cordon                    mConferenceLevelActiveCall = null;
94288a4a60284de8e1222488667b810b098c16d22acSantos Cordon                    break;
94388a4a60284de8e1222488667b810b098c16d22acSantos Cordon            }
9446805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon        }
9456805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon    }
9466805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon
947a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon    void setParentCall(Call parentCall) {
948a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon        if (parentCall == this) {
949a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon            Log.e(this, new Exception(), "setting the parent to self");
950a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon            return;
951a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon        }
9520fbe6321e341ddce186634266dba2db3fa426b88Santos Cordon        if (parentCall == mParentCall) {
9530fbe6321e341ddce186634266dba2db3fa426b88Santos Cordon            // nothing to do
9540fbe6321e341ddce186634266dba2db3fa426b88Santos Cordon            return;
9550fbe6321e341ddce186634266dba2db3fa426b88Santos Cordon        }
956a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon        Preconditions.checkState(parentCall == null || mParentCall == null);
957a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon
958a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon        Call oldParent = mParentCall;
959a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon        if (mParentCall != null) {
960a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon            mParentCall.removeChildCall(this);
961a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon        }
962a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon        mParentCall = parentCall;
963a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon        if (mParentCall != null) {
964a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon            mParentCall.addChildCall(this);
965a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon        }
966a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon
967a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon        for (Listener l : mListeners) {
968a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon            l.onParentChanged(this);
969a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon        }
970a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon    }
971a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon
97212d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon    void setConferenceableCalls(List<Call> conferenceableCalls) {
97312d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon        mConferenceableCalls.clear();
97412d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon        mConferenceableCalls.addAll(conferenceableCalls);
975703d7cfdab59f84221fd803dd5810bea0e26cc56Tyler Gunn
976703d7cfdab59f84221fd803dd5810bea0e26cc56Tyler Gunn        for (Listener l : mListeners) {
977703d7cfdab59f84221fd803dd5810bea0e26cc56Tyler Gunn            l.onConferenceableCallsChanged(this);
978703d7cfdab59f84221fd803dd5810bea0e26cc56Tyler Gunn        }
97912d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon    }
98012d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon
98112d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon    List<Call> getConferenceableCalls() {
98212d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon        return mConferenceableCalls;
98312d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon    }
98412d61825cd0d6aa06272db3f77b5e30dce379951Santos Cordon
985f193ba45fae5bc87e6a57779e4f5b56be59d08b0Santos Cordon    boolean can(int capability) {
9866805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon        return (mCallCapabilities & capability) == capability;
9876805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon    }
9886805923a2d91f9e193a4dd33f7a655587d2f173cSantos Cordon
989a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon    private void addChildCall(Call call) {
990a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon        if (!mChildCalls.contains(call)) {
99188a4a60284de8e1222488667b810b098c16d22acSantos Cordon            // Set the pseudo-active call to the latest child added to the conference.
99288a4a60284de8e1222488667b810b098c16d22acSantos Cordon            // See definition of mConferenceLevelActiveCall for more detail.
99388a4a60284de8e1222488667b810b098c16d22acSantos Cordon            mConferenceLevelActiveCall = call;
994a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon            mChildCalls.add(call);
995a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon
996a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon            for (Listener l : mListeners) {
997a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon                l.onChildrenChanged(this);
998a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon            }
999a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon        }
1000a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon    }
1001a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon
1002a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon    private void removeChildCall(Call call) {
1003a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon        if (mChildCalls.remove(call)) {
1004a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon            for (Listener l : mListeners) {
1005a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon                l.onChildrenChanged(this);
1006a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon            }
1007a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon        }
1008a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon    }
1009a161070ea054f91a5b2d5b4e3413381134d548b8Santos Cordon
10100b03b4b143234302f098ea18de3c32658b455ecaSantos Cordon    /**
1011ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad     * Return whether the user can respond to this {@code Call} via an SMS message.
1012ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad     *
1013ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad     * @return true if the "Respond via SMS" feature should be enabled
1014ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad     * for this incoming call.
1015ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad     *
1016ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad     * The general rule is that we *do* allow "Respond via SMS" except for
1017ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad     * the few (relatively rare) cases where we know for sure it won't
1018ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad     * work, namely:
1019ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad     *   - a bogus or blank incoming number
1020ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad     *   - a call from a SIP address
1021ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad     *   - a "call presentation" that doesn't allow the number to be revealed
1022ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad     *
1023ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad     * In all other cases, we allow the user to respond via SMS.
1024ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad     *
1025ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad     * Note that this behavior isn't perfect; for example we have no way
1026ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad     * to detect whether the incoming call is from a landline (with most
1027ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad     * networks at least), so we still enable this feature even though
1028ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad     * SMSes to that number will silently fail.
1029ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad     */
1030ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad    boolean isRespondViaSmsCapable() {
1031ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad        if (mState != CallState.RINGING) {
1032ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad            return false;
1033ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad        }
1034ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad
1035ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad        if (getHandle() == null) {
1036ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad            // No incoming number known or call presentation is "PRESENTATION_RESTRICTED", in
1037ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad            // other words, the user should not be able to see the incoming phone number.
1038ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad            return false;
1039ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad        }
1040ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad
1041ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad        if (PhoneNumberUtils.isUriNumber(getHandle().toString())) {
1042ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad            // The incoming number is actually a URI (i.e. a SIP address),
1043ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad            // not a regular PSTN phone number, and we can't send SMSes to
1044ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad            // SIP addresses.
1045ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad            // (TODO: That might still be possible eventually, though. Is
1046ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad            // there some SIP-specific equivalent to sending a text message?)
1047ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad            return false;
1048ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad        }
1049ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad
1050ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad        // Is there a valid SMS application on the phone?
105191d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn        if (SmsApplication.getDefaultRespondViaMessageApplication(mContext,
1052ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad                true /*updateIfNeeded*/) == null) {
1053ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad            return false;
1054ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad        }
1055ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad
1056ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad        // TODO: with some carriers (in certain countries) you *can* actually
1057ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad        // tell whether a given number is a mobile phone or not. So in that
1058ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad        // case we could potentially return false here if the incoming call is
1059ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad        // from a land line.
1060ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad
1061ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad        // If none of the above special cases apply, it's OK to enable the
1062ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad        // "Respond via SMS" feature.
1063ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad        return true;
1064ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad    }
1065ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad
1066ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad    List<String> getCannedSmsResponses() {
1067ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad        return mCannedSmsResponses;
1068ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad    }
1069ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad
1070ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad    /**
1071672321e603555849831dd88d5c9f93d88143ee48Santos Cordon     * We need to make sure that before we move a call to the disconnected state, it no
1072672321e603555849831dd88d5c9f93d88143ee48Santos Cordon     * longer has any parent/child relationships.  We want to do this to ensure that the InCall
10737cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunn     * Service always has the right data in the right order.  We also want to do it in telecom so
1074672321e603555849831dd88d5c9f93d88143ee48Santos Cordon     * that the insurance policy lives in the framework side of things.
1075672321e603555849831dd88d5c9f93d88143ee48Santos Cordon     */
1076672321e603555849831dd88d5c9f93d88143ee48Santos Cordon    private void fixParentAfterDisconnect() {
1077672321e603555849831dd88d5c9f93d88143ee48Santos Cordon        setParentCall(null);
1078672321e603555849831dd88d5c9f93d88143ee48Santos Cordon    }
1079672321e603555849831dd88d5c9f93d88143ee48Santos Cordon
1080672321e603555849831dd88d5c9f93d88143ee48Santos Cordon    /**
108161d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon     * @return True if the call is ringing, else logs the action name.
108261d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon     */
108361d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon    private boolean isRinging(String actionName) {
108461d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon        if (mState == CallState.RINGING) {
108561d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon            return true;
108661d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon        }
108761d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon
1088f1c191d3974fed3f57680c63571ae0212c4622e7Sailesh Nepal        Log.i(this, "Request to %s a non-ringing call %s", actionName, this);
108961d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon        return false;
109061d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon    }
109161d0f70cf45036f9cdeb41b96538f792b7c9764bSantos Cordon
10928e55d1d7ea86f768acb90f88dc9e5b5368d3398aBen Gilad    @SuppressWarnings("rawtypes")
10938e55d1d7ea86f768acb90f88dc9e5b5368d3398aBen Gilad    private void decrementAssociatedCallCount(ServiceBinder binder) {
10948e55d1d7ea86f768acb90f88dc9e5b5368d3398aBen Gilad        if (binder != null) {
10958e55d1d7ea86f768acb90f88dc9e5b5368d3398aBen Gilad            binder.decrementAssociatedCallCount();
10968e55d1d7ea86f768acb90f88dc9e5b5368d3398aBen Gilad        }
10978e55d1d7ea86f768acb90f88dc9e5b5368d3398aBen Gilad    }
1098fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon
1099fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon    /**
1100fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon     * Looks up contact information based on the current handle.
1101fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon     */
1102fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon    private void startCallerInfoLookup() {
1103fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon        String number = mHandle == null ? null : mHandle.getSchemeSpecificPart();
1104fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon
1105fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon        mQueryToken++;  // Updated so that previous queries can no longer set the information.
1106fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon        mCallerInfo = null;
1107fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon        if (!TextUtils.isEmpty(number)) {
11085ba7f27491e287f39a999ddd3d1ed6a7bad78272Santos Cordon            Log.v(this, "Looking up information for: %s.", Log.piiHandle(number));
1109fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon            CallerInfoAsyncQuery.startQuery(
1110fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon                    mQueryToken,
111191d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn                    mContext,
1112fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon                    number,
1113fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon                    sCallerInfoQueryListener,
1114fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon                    this);
1115fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon        }
1116fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon    }
1117fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon
1118fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon    /**
111999c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon     * Saves the specified caller info if the specified token matches that of the last query
1120fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon     * that was made.
1121fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon     *
1122fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon     * @param callerInfo The new caller information to set.
1123fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon     * @param token The token used with this query.
1124fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon     */
1125fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon    private void setCallerInfo(CallerInfo callerInfo, int token) {
112699c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon        Preconditions.checkNotNull(callerInfo);
112799c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon
1128fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon        if (mQueryToken == token) {
1129fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon            mCallerInfo = callerInfo;
11305ba7f27491e287f39a999ddd3d1ed6a7bad78272Santos Cordon            Log.i(this, "CallerInfo received for %s: %s", Log.piiHandle(mHandle), callerInfo);
113199c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon
1132a1662d0ae89d9fb514a5ac68cbc76660e34dae00Makoto Onuki            if (mCallerInfo.contactDisplayPhotoUri != null) {
1133a1662d0ae89d9fb514a5ac68cbc76660e34dae00Makoto Onuki                Log.d(this, "Searching person uri %s for call %s",
1134a1662d0ae89d9fb514a5ac68cbc76660e34dae00Makoto Onuki                        mCallerInfo.contactDisplayPhotoUri, this);
113599c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon                ContactsAsyncHelper.startObtainPhotoAsync(
113699c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon                        token,
113791d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn                        mContext,
1138a1662d0ae89d9fb514a5ac68cbc76660e34dae00Makoto Onuki                        mCallerInfo.contactDisplayPhotoUri,
113999c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon                        sPhotoLoadListener,
114099c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon                        this);
1141a1662d0ae89d9fb514a5ac68cbc76660e34dae00Makoto Onuki                // Do not call onCallerInfoChanged yet in this case.  We call it in setPhoto().
114264c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon            } else {
114364c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon                for (Listener l : mListeners) {
114464c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon                    l.onCallerInfoChanged(this);
114564c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon                }
114699c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon            }
11472174fb56907fddf5680355e097f4425f837983e2Santos Cordon
11482174fb56907fddf5680355e097f4425f837983e2Santos Cordon            processDirectToVoicemail();
114999c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon        }
115099c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon    }
115199c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon
11526f3f7affb13e93cb70868d3114f02f1ed593194eYorke Lee    CallerInfo getCallerInfo() {
11536f3f7affb13e93cb70868d3114f02f1ed593194eYorke Lee        return mCallerInfo;
11546f3f7affb13e93cb70868d3114f02f1ed593194eYorke Lee    }
11556f3f7affb13e93cb70868d3114f02f1ed593194eYorke Lee
115699c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon    /**
115799c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon     * Saves the specified photo information if the specified token matches that of the last query.
115899c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon     *
115999c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon     * @param photo The photo as a drawable.
116099c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon     * @param photoIcon The photo as a small icon.
116199c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon     * @param token The token used with this query.
116299c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon     */
116399c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon    private void setPhoto(Drawable photo, Bitmap photoIcon, int token) {
116499c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon        if (mQueryToken == token) {
116599c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon            mCallerInfo.cachedPhoto = photo;
116699c8a6fc0ae4c50878a748280a0ae2d8dd6b040eSantos Cordon            mCallerInfo.cachedPhotoIcon = photoIcon;
116764c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon
116864c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon            for (Listener l : mListeners) {
116964c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon                l.onCallerInfoChanged(this);
117064c7e965de50c6321415942ab4a84d22514b39a1Santos Cordon            }
1171fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon        }
1172fd71f4adb6f04ab485563133f5ccf541de04b002Santos Cordon    }
1173ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad
1174ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad    private void maybeLoadCannedSmsResponses() {
1175ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad        if (mIsIncoming && isRespondViaSmsCapable() && !mCannedSmsResponsesLoadingStarted) {
1176ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad            Log.d(this, "maybeLoadCannedSmsResponses: starting task to load messages");
1177ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad            mCannedSmsResponsesLoadingStarted = true;
1178ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad            RespondViaSmsManager.getInstance().loadCannedTextMessages(
1179ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad                    new Response<Void, List<String>>() {
1180ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad                        @Override
1181ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad                        public void onResult(Void request, List<String>... result) {
1182ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad                            if (result.length > 0) {
1183ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad                                Log.d(this, "maybeLoadCannedSmsResponses: got %s", result[0]);
1184ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad                                mCannedSmsResponses = result[0];
1185ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad                                for (Listener l : mListeners) {
1186ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad                                    l.onCannedSmsResponsesLoaded(Call.this);
1187ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad                                }
1188ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad                            }
1189ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad                        }
1190ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad
1191ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad                        @Override
1192ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad                        public void onError(Void request, int code, String msg) {
1193ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad                            Log.w(Call.this, "Error obtaining canned SMS responses: %d %s", code,
1194ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad                                    msg);
1195ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad                        }
119691d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn                    },
119791d43cf9c985cc5a83795f256ef5c46ebb8fbdc1Tyler Gunn                    mContext
1198ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad            );
1199ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad        } else {
1200ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad            Log.d(this, "maybeLoadCannedSmsResponses: doing nothing");
1201ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad        }
1202ff7493a8f620509d41dd8a5106c1d0dcd27cd274Ihab Awad    }
1203b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati
1204b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati    /**
1205b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati     * Sets speakerphone option on when call begins.
1206b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati     */
1207b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati    public void setStartWithSpeakerphoneOn(boolean startWithSpeakerphone) {
1208b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati        mSpeakerphoneOn = startWithSpeakerphone;
1209b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati    }
1210b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati
1211b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati    /**
1212b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati     * Returns speakerphone option.
1213b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati     *
1214b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati     * @return Whether or not speakerphone should be set automatically when call begins.
1215b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati     */
1216b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati    public boolean getStartWithSpeakerphoneOn() {
1217b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati        return mSpeakerphoneOn;
1218b7157e9f7dbf151c4c6ff4ebcc171632af00616eSai Cheemalapati    }
1219e9a776560dfe6f000cfc0dc1ea36c0f37d937f53Andrew Lee
1220e9a776560dfe6f000cfc0dc1ea36c0f37d937f53Andrew Lee    /**
12213bcf935b25470e94c8c6855862434d15b785c54aAndrew Lee     * Sets a video call provider for the call.
1222e9a776560dfe6f000cfc0dc1ea36c0f37d937f53Andrew Lee     */
12236fb37c87836b5245046bd3b14320823ab839a10cIhab Awad    public void setVideoProvider(IVideoProvider videoProvider) {
12246fb37c87836b5245046bd3b14320823ab839a10cIhab Awad        mVideoProvider = videoProvider;
1225a65d41fb134e323ab43c3f9454313b262959b1d0Nancy Chen        for (Listener l : mListeners) {
12263bcf935b25470e94c8c6855862434d15b785c54aAndrew Lee            l.onVideoCallProviderChanged(Call.this);
1227a65d41fb134e323ab43c3f9454313b262959b1d0Nancy Chen        }
1228a65d41fb134e323ab43c3f9454313b262959b1d0Nancy Chen    }
1229a65d41fb134e323ab43c3f9454313b262959b1d0Nancy Chen
1230a65d41fb134e323ab43c3f9454313b262959b1d0Nancy Chen    /**
12316fb37c87836b5245046bd3b14320823ab839a10cIhab Awad     * @return Return the {@link Connection.VideoProvider} binder.
1232a65d41fb134e323ab43c3f9454313b262959b1d0Nancy Chen     */
12336fb37c87836b5245046bd3b14320823ab839a10cIhab Awad    public IVideoProvider getVideoProvider() {
12346fb37c87836b5245046bd3b14320823ab839a10cIhab Awad        return mVideoProvider;
1235e9a776560dfe6f000cfc0dc1ea36c0f37d937f53Andrew Lee    }
1236e19cc005ddbff5313d6f7288587630b2410d005cTyler Gunn
1237e19cc005ddbff5313d6f7288587630b2410d005cTyler Gunn    /**
1238c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn     * The current video state for the call.
12396fb37c87836b5245046bd3b14320823ab839a10cIhab Awad     * Valid values: see {@link VideoProfile.VideoState}.
1240c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn     */
1241c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn    public int getVideoState() {
1242c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn        return mVideoState;
1243c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn    }
1244c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn
1245c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn    /**
12460a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn     * Returns the video states which were applicable over the duration of a call.
12476fb37c87836b5245046bd3b14320823ab839a10cIhab Awad     * See {@link VideoProfile} for a list of valid video states.
12480a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn     *
12490a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn     * @return The video states applicable over the duration of the call.
12500a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn     */
12510a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn    public int getVideoStateHistory() {
12520a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn        return mVideoStateHistory;
12530a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn    }
12540a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn
12550a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn    /**
12560a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn     * Determines the current video state for the call.
12570a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn     * For an outgoing call determines the desired video state for the call.
12586fb37c87836b5245046bd3b14320823ab839a10cIhab Awad     * Valid values: see {@link VideoProfile.VideoState}
1259c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn     *
12600a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn     * @param videoState The video state for the call.
1261c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn     */
1262c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn    public void setVideoState(int videoState) {
12630a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn        // Track which video states were applicable over the duration of the call.
12640a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn        mVideoStateHistory = mVideoStateHistory | videoState;
12650a388fc566576513f54610c4427fb30feb88ab02Tyler Gunn
1266c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn        mVideoState = videoState;
12674a79660c984d54679ad4d2bdc89e224d9c8c375bAndrew Lee        for (Listener l : mListeners) {
12684a79660c984d54679ad4d2bdc89e224d9c8c375bAndrew Lee            l.onVideoStateChanged(this);
12694a79660c984d54679ad4d2bdc89e224d9c8c375bAndrew Lee        }
1270c4abd91cd8a67b530ebafe146af10136db8e6605Tyler Gunn    }
12717e66957928c5c23a1028c8e2a2d7cf359cbfa44eSailesh Nepal
12725be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee    public boolean getIsVoipAudioMode() {
12735be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee        return mIsVoipAudioMode;
12747e66957928c5c23a1028c8e2a2d7cf359cbfa44eSailesh Nepal    }
12757e66957928c5c23a1028c8e2a2d7cf359cbfa44eSailesh Nepal
12765be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee    public void setIsVoipAudioMode(boolean audioModeIsVoip) {
12775be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee        mIsVoipAudioMode = audioModeIsVoip;
12787e66957928c5c23a1028c8e2a2d7cf359cbfa44eSailesh Nepal        for (Listener l : mListeners) {
12795be64bc46c23b614d5452ca398a6bb7a512f1887Andrew Lee            l.onIsVoipAudioModeChanged(this);
128035faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal        }
128135faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal    }
128235faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal
128335faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal    public StatusHints getStatusHints() {
128435faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal        return mStatusHints;
128535faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal    }
128635faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal
128735faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal    public void setStatusHints(StatusHints statusHints) {
128835faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal        mStatusHints = statusHints;
128935faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal        for (Listener l : mListeners) {
129035faf8cf29dc0f4a73935478e0fba957df9619d6Sailesh Nepal            l.onStatusHintsChanged(this);
12917e66957928c5c23a1028c8e2a2d7cf359cbfa44eSailesh Nepal        }
12927e66957928c5c23a1028c8e2a2d7cf359cbfa44eSailesh Nepal    }
12939d58de5df05d0358fc8ae57ab7e9a0c45337c602Sailesh Nepal
12949250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee    public boolean isUnknown() {
12959250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee        return mIsUnknown;
12969250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee    }
12979250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee
12989250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee    public void setIsUnknown(boolean isUnknown) {
12999250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee        mIsUnknown = isUnknown;
13009250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee    }
13019250e5fa9987c3ab80e11e1955657055f5866539Yorke Lee
1302aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn    /**
1303aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn     * Determines if this call is in a disconnecting state.
1304aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn     *
1305aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn     * @return {@code true} if this call is locally disconnecting.
1306aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn     */
1307aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn    public boolean isLocallyDisconnecting() {
1308aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn        return mIsLocallyDisconnecting;
1309aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn    }
1310aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn
1311aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn    /**
1312aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn     * Sets whether this call is in a disconnecting state.
1313aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn     *
1314aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn     * @param isLocallyDisconnecting {@code true} if this call is locally disconnecting.
1315aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn     */
1316aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn    private void setLocallyDisconnecting(boolean isLocallyDisconnecting) {
1317aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn        mIsLocallyDisconnecting = isLocallyDisconnecting;
1318aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn    }
1319aa47937652d80d8bd19860ec521d28ffea745e63Tyler Gunn
13200fbe6321e341ddce186634266dba2db3fa426b88Santos Cordon    static int getStateFromConnectionState(int state) {
132172890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon        switch (state) {
1322a02bef5d67f261d7457d0dab9e51595f1960128bIhab Awad            case Connection.STATE_INITIALIZING:
1323a02bef5d67f261d7457d0dab9e51595f1960128bIhab Awad                return CallState.CONNECTING;
13246fb37c87836b5245046bd3b14320823ab839a10cIhab Awad            case Connection.STATE_ACTIVE:
132572890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon                return CallState.ACTIVE;
13266fb37c87836b5245046bd3b14320823ab839a10cIhab Awad            case Connection.STATE_DIALING:
132772890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon                return CallState.DIALING;
13286fb37c87836b5245046bd3b14320823ab839a10cIhab Awad            case Connection.STATE_DISCONNECTED:
132972890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon                return CallState.DISCONNECTED;
13306fb37c87836b5245046bd3b14320823ab839a10cIhab Awad            case Connection.STATE_HOLDING:
133172890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon                return CallState.ON_HOLD;
13326fb37c87836b5245046bd3b14320823ab839a10cIhab Awad            case Connection.STATE_NEW:
133372890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon                return CallState.NEW;
13346fb37c87836b5245046bd3b14320823ab839a10cIhab Awad            case Connection.STATE_RINGING:
133572890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon                return CallState.RINGING;
133672890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon        }
133772890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon        return CallState.DISCONNECTED;
133872890ce844f92f45c56f3cccd1f2fd03ff12c3c2Santos Cordon    }
13399f2bed31374a56487f370be01224baf6ce97e8adBen Gilad}
1340