CallCardPresenter.java revision 9c4226952c74f024c09e0bd381048493993c974e
1c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon/*
2c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon * Copyright (C) 2013 The Android Open Source Project
3c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon *
4c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon * Licensed under the Apache License, Version 2.0 (the "License");
5c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon * you may not use this file except in compliance with the License.
6c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon * You may obtain a copy of the License at
7c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon *
8c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon *      http://www.apache.org/licenses/LICENSE-2.0
9c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon *
10c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon * Unless required by applicable law or agreed to in writing, software
11c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon * distributed under the License is distributed on an "AS IS" BASIS,
12c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon * See the License for the specific language governing permissions and
14c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon * limitations under the License
15c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon */
16c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon
17c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordonpackage com.android.incallui;
18c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon
193d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordonimport android.content.Context;
203d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordonimport android.content.pm.ApplicationInfo;
213d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordonimport android.content.pm.PackageManager;
226d231f52e4f00399330d772f2a337283803f3a9dYorke Leeimport android.graphics.drawable.Drawable;
23da7f422a46db4bfe5cf76312d23b44e60fa9d806Santos Cordonimport android.net.Uri;
240e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charltonimport android.os.Bundle;
259c4226952c74f024c09e0bd381048493993c974eAndrew Leeimport android.os.Handler;
26f27342bc5d594dfc32dc2bfafe109dcaa6b6d506Sailesh Nepalimport android.telecomm.CallCapabilities;
27b6f45c2768f5af916ee3257542a3ab03611c1f5eEvan Charltonimport android.telecomm.PhoneAccount;
2876e1b4bfb2e21300068f10cc94922214e62c8f86Evan Charltonimport android.telecomm.PhoneAccountHandle;
290e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charltonimport android.telecomm.StatusHints;
304feb57b986dc6b1edc5dc026a926b4934778716dIhab Awadimport android.telecomm.TelecommManager;
319c4226952c74f024c09e0bd381048493993c974eAndrew Leeimport android.telecomm.VideoCallProfile;
32479c50f6d4fac0fa44210c9bad4346f64dba3f1eAnders Kristensenimport android.telephony.DisconnectCause;
330e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charltonimport android.telephony.PhoneNumberUtils;
340786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charltonimport android.telephony.TelephonyManager;
35d28fc12696fa706fed70e04698275af7be7fee82Santos Cordonimport android.text.TextUtils;
368cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordonimport android.text.format.DateUtils;
37be8060acf5ecbb916c161d3249813098c0611ed5Yorke Lee
381b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordonimport com.android.incallui.AudioModeProvider.AudioModeListener;
39d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordonimport com.android.incallui.ContactInfoCache.ContactCacheEntry;
40d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordonimport com.android.incallui.ContactInfoCache.ContactInfoCacheCallback;
410e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charltonimport com.android.incallui.InCallPresenter.InCallDetailsListener;
42350fff554bf7ed5b9e91985935488771156953abTyler Gunnimport com.android.incallui.InCallPresenter.InCallEventListener;
437ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordonimport com.android.incallui.InCallPresenter.InCallState;
447ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordonimport com.android.incallui.InCallPresenter.InCallStateListener;
451c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordonimport com.android.incallui.InCallPresenter.IncomingCallListener;
465b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee
475b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Leeimport java.lang.ref.WeakReference;
485b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee
4942373eb59cbef15ec61ebb5c919031f293291a53Chiao Chengimport com.google.common.base.Preconditions;
50c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon
51c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon/**
52c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon * Presenter for the Call Card Fragment.
53033ed5926d2924d35b9c82898ab4e835da56b3afChiao Cheng * <p>
547ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon * This class listens for changes to InCallState and passes it along to the fragment.
55c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon */
56d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordonpublic class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
570e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton        implements InCallStateListener, AudioModeListener, IncomingCallListener,
589c4226952c74f024c09e0bd381048493993c974eAndrew Lee        InCallDetailsListener, InCallEventListener,
599c4226952c74f024c09e0bd381048493993c974eAndrew Lee        InCallVideoCallListenerNotifier.SessionModificationListener {
60be8060acf5ecbb916c161d3249813098c0611ed5Yorke Lee
61033ed5926d2924d35b9c82898ab4e835da56b3afChiao Cheng    private static final String TAG = CallCardPresenter.class.getSimpleName();
629c4226952c74f024c09e0bd381048493993c974eAndrew Lee    private static final long CALL_TIME_UPDATE_INTERVAL_MS = 1000;
639c4226952c74f024c09e0bd381048493993c974eAndrew Lee    private static final long SESSION_MODIFICATION_RESET_DELAY_MS = 3000;
648cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon
651b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    private Call mPrimary;
66d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    private Call mSecondary;
67d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    private ContactCacheEntry mPrimaryContactInfo;
68d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    private ContactCacheEntry mSecondaryContactInfo;
698cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon    private CallTimer mCallTimer;
709c4226952c74f024c09e0bd381048493993c974eAndrew Lee    private Handler mSessionModificationResetHandler;
713d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    private Context mContext;
724feb57b986dc6b1edc5dc026a926b4934778716dIhab Awad    private TelecommManager mTelecommManager;
736d231f52e4f00399330d772f2a337283803f3a9dYorke Lee
745b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee    public static class ContactLookupCallback implements ContactInfoCacheCallback {
755b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        private final WeakReference<CallCardPresenter> mCallCardPresenter;
765b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        private final boolean mIsPrimary;
775b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee
785b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        public ContactLookupCallback(CallCardPresenter callCardPresenter, boolean isPrimary) {
795b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            mCallCardPresenter = new WeakReference<CallCardPresenter>(callCardPresenter);
805b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            mIsPrimary = isPrimary;
815b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        }
825b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee
835b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        @Override
845b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        public void onContactInfoComplete(String callId, ContactCacheEntry entry) {
855b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            CallCardPresenter presenter = mCallCardPresenter.get();
865b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            if (presenter != null) {
875b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee                presenter.onContactInfoComplete(callId, entry, mIsPrimary);
885b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            }
895b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        }
905b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee
915b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        @Override
925b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        public void onImageLoadComplete(String callId, ContactCacheEntry entry) {
935b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            CallCardPresenter presenter = mCallCardPresenter.get();
945b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            if (presenter != null) {
955b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee                presenter.onImageLoadComplete(callId, entry);
965b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            }
975b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        }
985b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee
995b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee    }
1005b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee
101b8eedb3b9796873eaa22847205239a51092f1a43Santos Cordon    public CallCardPresenter() {
1028cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        // create the call timer
1038cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        mCallTimer = new CallTimer(new Runnable() {
1048cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon            @Override
1058cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon            public void run() {
1068cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon                updateCallTime();
1078cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon            }
1088cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        });
1099c4226952c74f024c09e0bd381048493993c974eAndrew Lee        mSessionModificationResetHandler = new Handler();
1106d231f52e4f00399330d772f2a337283803f3a9dYorke Lee    }
1116d231f52e4f00399330d772f2a337283803f3a9dYorke Lee
1121c6bb983216392b5ceb36cea42a46631f68a3dd6Jay Shrauner    public void init(Context context, Call call) {
11342373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        mContext = Preconditions.checkNotNull(context);
11442373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
1154a5339c4a266891ce560dfb6e348c3779a0a3ca1Chiao Cheng        // Call may be null if disconnect happened already.
1164a5339c4a266891ce560dfb6e348c3779a0a3ca1Chiao Cheng        if (call != null) {
117656dd4a0d8571b47ecf0ecf3e4c2eeacfd1099b3Chiao Cheng            mPrimary = call;
118656dd4a0d8571b47ecf0ecf3e4c2eeacfd1099b3Chiao Cheng
1194a5339c4a266891ce560dfb6e348c3779a0a3ca1Chiao Cheng            // start processing lookups right away.
120812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            if (!call.isConferenceCall()) {
121248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal                startContactInfoSearch(call, true, call.getState() == Call.State.INCOMING);
122812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            } else {
123812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon                updateContactEntry(null, true, true);
124812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            }
1254a5339c4a266891ce560dfb6e348c3779a0a3ca1Chiao Cheng        }
126033ed5926d2924d35b9c82898ab4e835da56b3afChiao Cheng    }
127033ed5926d2924d35b9c82898ab4e835da56b3afChiao Cheng
128c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon    @Override
129c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon    public void onUiReady(CallCardUi ui) {
130c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon        super.onUiReady(ui);
1311b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon
1321f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon        AudioModeProvider.getInstance().addListener(this);
1331f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon
13442373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        // Contact search may have completed before ui is ready.
13542373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        if (mPrimaryContactInfo != null) {
136314b2aaa1fa1ef799270987e964f7df4d983b9eeChristine Chen            updatePrimaryDisplayInfo(mPrimaryContactInfo, isConference(mPrimary));
13742373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        }
13842373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
1391f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon        // Register for call state changes last
1401f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon        InCallPresenter.getInstance().addListener(this);
1411c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon        InCallPresenter.getInstance().addIncomingCallListener(this);
1420e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton        InCallPresenter.getInstance().addDetailsListener(this);
143350fff554bf7ed5b9e91985935488771156953abTyler Gunn        InCallPresenter.getInstance().addInCallEventListener(this);
1449c4226952c74f024c09e0bd381048493993c974eAndrew Lee
1459c4226952c74f024c09e0bd381048493993c974eAndrew Lee        InCallVideoCallListenerNotifier.getInstance().addSessionModificationListener(this);
1461b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    }
1471b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon
1481b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    @Override
1491b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    public void onUiUnready(CallCardUi ui) {
1501b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon        super.onUiUnready(ui);
1511b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon
1529c4226952c74f024c09e0bd381048493993c974eAndrew Lee        InCallVideoCallListenerNotifier.getInstance().removeSessionModificationListener(this);
1539c4226952c74f024c09e0bd381048493993c974eAndrew Lee
1541f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon        // stop getting call state changes
1551f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon        InCallPresenter.getInstance().removeListener(this);
1561c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon        InCallPresenter.getInstance().removeIncomingCallListener(this);
1570e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton        InCallPresenter.getInstance().removeDetailsListener(this);
158350fff554bf7ed5b9e91985935488771156953abTyler Gunn        InCallPresenter.getInstance().removeInCallEventListener(this);
1591f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon
1601f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon        AudioModeProvider.getInstance().removeListener(this);
1611f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon
1621b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon        mPrimary = null;
163d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        mPrimaryContactInfo = null;
164d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        mSecondaryContactInfo = null;
165c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon    }
166c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon
167c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon    @Override
1681c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon    public void onIncomingCall(InCallState state, Call call) {
1691c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon        // same logic should happen as with onStateChange()
1701c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon        onStateChange(state, CallList.getInstance());
1711c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon    }
1721c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon
1731c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon    @Override
1747ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon    public void onStateChange(InCallState state, CallList callList) {
1757a863a056a96638c32171f721d99c694a1890df8Christine Chen        Log.d(this, "onStateChange() " + state);
17675c86b55d45b1725c46ed2e5d77c9c43fcfd93daSantos Cordon        final CallCardUi ui = getUi();
1771b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon        if (ui == null) {
1781b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon            return;
1791b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon        }
180c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon
1817ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon        Call primary = null;
1827ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon        Call secondary = null;
1837ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon
1847ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon        if (state == InCallState.INCOMING) {
1857ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon            primary = callList.getIncomingCall();
186950e3df8ac744daf2a890d279566bdba424710f9Santos Cordon        } else if (state == InCallState.OUTGOING) {
187950e3df8ac744daf2a890d279566bdba424710f9Santos Cordon            primary = callList.getOutgoingCall();
188950e3df8ac744daf2a890d279566bdba424710f9Santos Cordon
18982f5d003e675dfd56735c745744c3d968883b23cSantos Cordon            // getCallToDisplay doesn't go through outgoing or incoming calls. It will return the
19082f5d003e675dfd56735c745744c3d968883b23cSantos Cordon            // highest priority call to display as the secondary call.
191d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            secondary = getCallToDisplay(callList, null, true);
1927ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon        } else if (state == InCallState.INCALL) {
193d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            primary = getCallToDisplay(callList, null, false);
194d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            secondary = getCallToDisplay(callList, primary, true);
1957ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon        }
1967ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon
197a4bd83ad639b349fa16dbd07225017fcbf6ed550Chiao Cheng        Log.d(this, "Primary call: " + primary);
198a4bd83ad639b349fa16dbd07225017fcbf6ed550Chiao Cheng        Log.d(this, "Secondary call: " + secondary);
1997ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon
200812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        final boolean primaryChanged = !areCallsSame(mPrimary, primary);
201812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        final boolean secondaryChanged = !areCallsSame(mSecondary, secondary);
202812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        mSecondary = secondary;
203812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        mPrimary = primary;
204812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon
205812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        if (primaryChanged && mPrimary != null) {
206812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            // primary call has changed
207248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal            mPrimaryContactInfo = ContactInfoCache.buildCacheEntryFromCall(mContext, mPrimary,
208248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal                    mPrimary.getState() == Call.State.INCOMING);
209812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            updatePrimaryDisplayInfo(mPrimaryContactInfo, isConference(mPrimary));
210812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            maybeStartSearch(mPrimary, true);
2119c4226952c74f024c09e0bd381048493993c974eAndrew Lee            mPrimary.setSessionModificationState(Call.SessionModificationState.NO_REQUEST);
21242373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        }
21342373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
214812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        if (mSecondary == null) {
21542373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            // Secondary call may have ended.  Update the ui.
21642373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            mSecondaryContactInfo = null;
2175345442d7238c1db00dc8d55a49f7f5dd713d994Christine Chen            updateSecondaryDisplayInfo(false);
218812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        } else if (secondaryChanged) {
219812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            // secondary call has changed
220248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal            mSecondaryContactInfo = ContactInfoCache.buildCacheEntryFromCall(mContext, mSecondary,
221248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal                    mSecondary.getState() == Call.State.INCOMING);
222812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            updateSecondaryDisplayInfo(mSecondary.isConferenceCall());
223812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            maybeStartSearch(mSecondary, false);
2249c4226952c74f024c09e0bd381048493993c974eAndrew Lee            mSecondary.setSessionModificationState(Call.SessionModificationState.NO_REQUEST);
22542373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        }
22642373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
2279c4226952c74f024c09e0bd381048493993c974eAndrew Lee        // Start/stop timers.
2288cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        if (mPrimary != null && mPrimary.getState() == Call.State.ACTIVE) {
229a4bd83ad639b349fa16dbd07225017fcbf6ed550Chiao Cheng            Log.d(this, "Starting the calltime timer");
2309c4226952c74f024c09e0bd381048493993c974eAndrew Lee            mCallTimer.start(CALL_TIME_UPDATE_INTERVAL_MS);
2318cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        } else {
232a4bd83ad639b349fa16dbd07225017fcbf6ed550Chiao Cheng            Log.d(this, "Canceling the calltime timer");
2338cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon            mCallTimer.cancel();
2348cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon            ui.setPrimaryCallElapsedTime(false, null);
2358cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        }
2368cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon
237d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        // Set the call state
2388aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton        int callState = Call.State.IDLE;
239d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        if (mPrimary != null) {
24032027ae1f52232258cc8133d383459f3b4ee57e4Yorke Lee            callState = mPrimary.getState();
24146848bb9b89cc5417afae19aaab38fe331a7b474Sailesh Nepal
2429c4226952c74f024c09e0bd381048493993c974eAndrew Lee            getUi().setCallState(
2439c4226952c74f024c09e0bd381048493993c974eAndrew Lee                    callState,
2449c4226952c74f024c09e0bd381048493993c974eAndrew Lee                    mPrimary.getVideoState(),
2459c4226952c74f024c09e0bd381048493993c974eAndrew Lee                    mPrimary.getSessionModificationState(),
2469c4226952c74f024c09e0bd381048493993c974eAndrew Lee                    mPrimary.getDisconnectCause(),
2479c4226952c74f024c09e0bd381048493993c974eAndrew Lee                    getConnectionLabel(),
2489c4226952c74f024c09e0bd381048493993c974eAndrew Lee                    getCallProviderIcon(mPrimary),
2499c4226952c74f024c09e0bd381048493993c974eAndrew Lee                    getGatewayNumber());
2500786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton
251da7f422a46db4bfe5cf76312d23b44e60fa9d806Santos Cordon            String currentNumber = getNumberFromHandle(mPrimary.getHandle());
2520786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton            if (PhoneNumberUtils.isEmergencyNumber(currentNumber)) {
2530786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton                String callbackNumber = getSubscriptionNumber();
2540786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton                setCallbackNumber(callbackNumber, true);
2550786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton            }
25682f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        } else {
2579c4226952c74f024c09e0bd381048493993c974eAndrew Lee            getUi().setCallState(
2589c4226952c74f024c09e0bd381048493993c974eAndrew Lee                    callState,
2599c4226952c74f024c09e0bd381048493993c974eAndrew Lee                    VideoCallProfile.VideoState.AUDIO_ONLY,
2609c4226952c74f024c09e0bd381048493993c974eAndrew Lee                    Call.SessionModificationState.NO_REQUEST,
2619c4226952c74f024c09e0bd381048493993c974eAndrew Lee                    DisconnectCause.NOT_VALID,
2629c4226952c74f024c09e0bd381048493993c974eAndrew Lee                    null,
2639c4226952c74f024c09e0bd381048493993c974eAndrew Lee                    null,
2649c4226952c74f024c09e0bd381048493993c974eAndrew Lee                    null);
26582f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        }
266e26b887e90d5e9566a5054a1ccb3ed32ae2eea2dAndrew Lee
267350fff554bf7ed5b9e91985935488771156953abTyler Gunn        // Hide/show the contact photo based on the video state.
268350fff554bf7ed5b9e91985935488771156953abTyler Gunn        // If the primary call is a video call on hold, still show the contact photo.
269350fff554bf7ed5b9e91985935488771156953abTyler Gunn        // If the primary call is an active video call, hide the contact photo.
270804baccc3aeed4ed00d1f0a62ecc37fb5ea6d9fdTyler Gunn        if (mPrimary != null) {
271350fff554bf7ed5b9e91985935488771156953abTyler Gunn            getUi().setPhotoVisible(!(mPrimary.isVideoCall() && callState != Call.State.ONHOLD));
272804baccc3aeed4ed00d1f0a62ecc37fb5ea6d9fdTyler Gunn        }
273804baccc3aeed4ed00d1f0a62ecc37fb5ea6d9fdTyler Gunn
2748aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton        final boolean enableEndCallButton = Call.State.isConnected(callState) &&
2758aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton                callState != Call.State.INCOMING && mPrimary != null;
2769fc169931b9904ee8eac27bacd858ab87753e33dEvan Charlton        getUi().setEndCallButtonEnabled(enableEndCallButton);
2771b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    }
2781b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon
2791b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    @Override
2801869dcf386a96f060a16ac74f1722d816b69aa7dTyler Gunn    public void onDetailsChanged(Call call, android.telecomm.Call.Details details) {
2810e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton        getUi().setCallDetails(details);
2820e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton
283c108b49ad5440fbf381c9a589d8a217da3efcb64Ihab Awad        if (mPrimary != null) {
2840786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton            setCallbackNumberIfSet(details);
2850786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton        }
2860786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton    }
2870786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton
2880786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton    private String getSubscriptionNumber() {
2890786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton        // If it's an emergency call, and they're not populating the callback number,
2900786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton        // then try to fall back to the phone sub info (to hopefully get the SIM's
2910786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton        // number directly from the telephony layer).
29276e1b4bfb2e21300068f10cc94922214e62c8f86Evan Charlton        PhoneAccountHandle accountHandle = mPrimary.getAccountHandle();
29376e1b4bfb2e21300068f10cc94922214e62c8f86Evan Charlton        if (accountHandle != null) {
294d5b908ee536eb33d80abc4b28110b10d18fe0a8eYorke Lee            TelecommManager mgr =
295d5b908ee536eb33d80abc4b28110b10d18fe0a8eYorke Lee                    (TelecommManager) mContext.getSystemService(Context.TELECOMM_SERVICE);
296b6f45c2768f5af916ee3257542a3ab03611c1f5eEvan Charlton            PhoneAccount account = mgr.getPhoneAccount(accountHandle);
297b6f45c2768f5af916ee3257542a3ab03611c1f5eEvan Charlton            if (account != null) {
298b6f45c2768f5af916ee3257542a3ab03611c1f5eEvan Charlton                return account.getSubscriptionNumber();
299c108b49ad5440fbf381c9a589d8a217da3efcb64Ihab Awad            }
3000e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton        }
3010786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton        return null;
3020e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton    }
3030e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton
3040786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton    private void setCallbackNumberIfSet(android.telecomm.Call.Details details) {
3050e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton        String callbackNumber = null;
3060e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton
307da7f422a46db4bfe5cf76312d23b44e60fa9d806Santos Cordon        String currentNumber = getNumberFromHandle(mPrimary.getHandle());
3080786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton        boolean isEmergencyCall = PhoneNumberUtils.isEmergencyNumber(currentNumber);
3090786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton
3100e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton        StatusHints statusHints = details.getStatusHints();
3110e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton        if (statusHints != null) {
3120e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton            Bundle extras = statusHints.getExtras();
3130e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton            if (extras != null) {
3140e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton                callbackNumber = extras.getString(
31521130801fcf542ac33cea4ebc4cfa7803a90cacbEvan Charlton                        TelecommManager.EXTRA_CALL_BACK_NUMBER, null);
3160786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton
3170786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton                if (isEmergencyCall) {
3180786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton                    callbackNumber = getSubscriptionNumber();
3190786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton                }
3200e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton            } else {
3210e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton                Log.d(this, "No extras; not updating callback number");
3220e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton            }
3230e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton        } else {
3240e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton            Log.d(this, "No status hints; not updating callback number");
3250e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton        }
3260e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton
3270786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton        setCallbackNumber(callbackNumber, isEmergencyCall);
3280786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton    }
3290786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton
3300786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton    private void setCallbackNumber(String callbackNumber, boolean isEmergencyCall) {
3310786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton        if (TextUtils.isEmpty(callbackNumber)) {
3320786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton            Log.d(this, "No callback number; aborting");
3330786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton            return;
3340786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton        }
3350786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton
336d5b908ee536eb33d80abc4b28110b10d18fe0a8eYorke Lee        final TelephonyManager telephonyManager =
337d5b908ee536eb33d80abc4b28110b10d18fe0a8eYorke Lee                (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
338d5b908ee536eb33d80abc4b28110b10d18fe0a8eYorke Lee        String simNumber = telephonyManager.getLine1Number();
3390786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton        if (!PhoneNumberUtils.compare(callbackNumber, simNumber) && !isEmergencyCall) {
3400786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton            Log.d(this, "Numbers are the same; not showing the callback number");
3410786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton            return;
3420786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton        }
3430786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton        getUi().setCallbackNumber(callbackNumber, isEmergencyCall);
3440e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton    }
3450e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton
3460e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton    @Override
3471b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    public void onAudioMode(int mode) {
3481b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    }
3491b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon
3501b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    @Override
3511b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    public void onSupportedAudioMode(int mask) {
352c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon    }
353c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon
3548c478132fbc07bd075df6aba85bcfd2990bbd66aSantos Cordon    @Override
3558c478132fbc07bd075df6aba85bcfd2990bbd66aSantos Cordon    public void onMute(boolean muted) {
3568c478132fbc07bd075df6aba85bcfd2990bbd66aSantos Cordon    }
3578c478132fbc07bd075df6aba85bcfd2990bbd66aSantos Cordon
3588cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon    public void updateCallTime() {
3598cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        final CallCardUi ui = getUi();
3608cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon
3618cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        if (ui == null || mPrimary == null || mPrimary.getState() != Call.State.ACTIVE) {
362899251968ee4ee3cb375032185653ecd888e3f8dSantos Cordon            if (ui != null) {
363899251968ee4ee3cb375032185653ecd888e3f8dSantos Cordon                ui.setPrimaryCallElapsedTime(false, null);
364899251968ee4ee3cb375032185653ecd888e3f8dSantos Cordon            }
3658cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon            mCallTimer.cancel();
366899251968ee4ee3cb375032185653ecd888e3f8dSantos Cordon        } else {
367c6f4e50a4130fb8f7247f5eab6849829701ad484Sailesh Nepal            final long callStart = mPrimary.getConnectTimeMillis();
368899251968ee4ee3cb375032185653ecd888e3f8dSantos Cordon            final long duration = System.currentTimeMillis() - callStart;
369899251968ee4ee3cb375032185653ecd888e3f8dSantos Cordon            ui.setPrimaryCallElapsedTime(true, DateUtils.formatElapsedTime(duration / 1000));
3708cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        }
3718cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon    }
3728cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon
373f8b0677bed382046cb26e38a8442a9509d1e835cSailesh Nepal    public void phoneAccountClicked() {
3748aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton        if (mPrimary == null) {
3758aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton            return;
3768aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton        }
3778d38cf6761ae048b1a42504f1b59e872cf43df47Ihab Awad        TelecommAdapter.getInstance().phoneAccountClicked(mPrimary.getId());
3788aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton    }
3798aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton
3809c4226952c74f024c09e0bd381048493993c974eAndrew Lee    @Override
3819c4226952c74f024c09e0bd381048493993c974eAndrew Lee    public void onUpgradeToVideoRequest(Call call) {
3829c4226952c74f024c09e0bd381048493993c974eAndrew Lee        // Implementing to satsify interface.
3839c4226952c74f024c09e0bd381048493993c974eAndrew Lee    }
3849c4226952c74f024c09e0bd381048493993c974eAndrew Lee
3859c4226952c74f024c09e0bd381048493993c974eAndrew Lee    @Override
3869c4226952c74f024c09e0bd381048493993c974eAndrew Lee    public void onUpgradeToVideoSuccess(Call call) {
3879c4226952c74f024c09e0bd381048493993c974eAndrew Lee        if (mPrimary == null || !areCallsSame(mPrimary, call)) {
3889c4226952c74f024c09e0bd381048493993c974eAndrew Lee            return;
3899c4226952c74f024c09e0bd381048493993c974eAndrew Lee        }
3909c4226952c74f024c09e0bd381048493993c974eAndrew Lee
3919c4226952c74f024c09e0bd381048493993c974eAndrew Lee        mPrimary.setSessionModificationState(Call.SessionModificationState.NO_REQUEST);
3929c4226952c74f024c09e0bd381048493993c974eAndrew Lee    }
3939c4226952c74f024c09e0bd381048493993c974eAndrew Lee
3949c4226952c74f024c09e0bd381048493993c974eAndrew Lee    @Override
3959c4226952c74f024c09e0bd381048493993c974eAndrew Lee    public void onUpgradeToVideoFail(Call call) {
3969c4226952c74f024c09e0bd381048493993c974eAndrew Lee        if (mPrimary == null || !areCallsSame(mPrimary, call)) {
3979c4226952c74f024c09e0bd381048493993c974eAndrew Lee            return;
3989c4226952c74f024c09e0bd381048493993c974eAndrew Lee        }
3999c4226952c74f024c09e0bd381048493993c974eAndrew Lee
4009c4226952c74f024c09e0bd381048493993c974eAndrew Lee        call.setSessionModificationState(Call.SessionModificationState.REQUEST_FAILED);
4019c4226952c74f024c09e0bd381048493993c974eAndrew Lee
4029c4226952c74f024c09e0bd381048493993c974eAndrew Lee        // Start handler to change state from REQUEST_FAILED to NO_REQUEST after an interval.
4039c4226952c74f024c09e0bd381048493993c974eAndrew Lee        mSessionModificationResetHandler.postDelayed(new Runnable() {
4049c4226952c74f024c09e0bd381048493993c974eAndrew Lee            @Override
4059c4226952c74f024c09e0bd381048493993c974eAndrew Lee            public void run() {
4069c4226952c74f024c09e0bd381048493993c974eAndrew Lee                mPrimary.setSessionModificationState(Call.SessionModificationState.NO_REQUEST);
4079c4226952c74f024c09e0bd381048493993c974eAndrew Lee            }
4089c4226952c74f024c09e0bd381048493993c974eAndrew Lee        }, SESSION_MODIFICATION_RESET_DELAY_MS);
4099c4226952c74f024c09e0bd381048493993c974eAndrew Lee    }
4109c4226952c74f024c09e0bd381048493993c974eAndrew Lee
4119c4226952c74f024c09e0bd381048493993c974eAndrew Lee    @Override
4129c4226952c74f024c09e0bd381048493993c974eAndrew Lee    public void onDowngradeToAudio(Call call) {
4139c4226952c74f024c09e0bd381048493993c974eAndrew Lee        // Implementing to satsify interface.
4149c4226952c74f024c09e0bd381048493993c974eAndrew Lee    }
4159c4226952c74f024c09e0bd381048493993c974eAndrew Lee
416812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon    private boolean areCallsSame(Call call1, Call call2) {
417812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        if (call1 == null && call2 == null) {
418812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            return true;
419812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        } else if (call1 == null || call2 == null) {
420812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            return false;
421812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        }
422812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon
423812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        // otherwise compare call Ids
4248d38cf6761ae048b1a42504f1b59e872cf43df47Ihab Awad        return call1.getId().equals(call2.getId());
425812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon    }
426812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon
427812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon    private void maybeStartSearch(Call call, boolean isPrimary) {
428812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        // no need to start search for conference calls which show generic info.
429812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        if (call != null && !call.isConferenceCall()) {
430248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal            startContactInfoSearch(call, isPrimary, call.getState() == Call.State.INCOMING);
431812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        }
432812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon    }
433812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon
43482f5d003e675dfd56735c745744c3d968883b23cSantos Cordon    /**
435d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon     * Starts a query for more contact data for the save primary and secondary calls.
436d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon     */
437248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal    private void startContactInfoSearch(final Call call, final boolean isPrimary,
438248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal            boolean isIncoming) {
43942373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        final ContactInfoCache cache = ContactInfoCache.getInstance(mContext);
44042373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
4415b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        cache.findInfo(call, isIncoming, new ContactLookupCallback(this, isPrimary));
4425b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee    }
4437d2fb8620b808c28c49bde99dc54f6de46fdcb44Chiao Cheng
4445b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee    private void onContactInfoComplete(String callId, ContactCacheEntry entry, boolean isPrimary) {
4455b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        updateContactEntry(entry, isPrimary, false);
4465b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        if (entry.name != null) {
4475b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            Log.d(TAG, "Contact found: " + entry);
4485b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        }
4495b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        if (entry.contactUri != null) {
4505b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            CallerInfoUtils.sendViewNotification(mContext, entry.contactUri);
4515b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        }
4525b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee    }
4535b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee
4545b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee    private void onImageLoadComplete(String callId, ContactCacheEntry entry) {
4555b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        if (getUi() == null) {
4565b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            return;
4575b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        }
4585b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        if (entry.photo != null) {
4595b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            if (mPrimary != null && callId.equals(mPrimary.getId())) {
4605b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee                getUi().setPrimaryImage(entry.photo);
4615b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            }
4625b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        }
46342373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng    }
46442373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
465812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon    private static boolean isConference(Call call) {
466812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        return call != null && call.isConferenceCall();
467812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon    }
468812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon
469812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon    private static boolean isGenericConference(Call call) {
470f27342bc5d594dfc32dc2bfafe109dcaa6b6d506Sailesh Nepal        return call != null && call.can(CallCapabilities.GENERIC_CONFERENCE);
47142373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng    }
472d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon
47342373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng    private void updateContactEntry(ContactCacheEntry entry, boolean isPrimary,
47442373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            boolean isConference) {
47542373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        if (isPrimary) {
47642373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            mPrimaryContactInfo = entry;
47742373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            updatePrimaryDisplayInfo(entry, isConference);
478d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        } else {
47942373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            mSecondaryContactInfo = entry;
4805345442d7238c1db00dc8d55a49f7f5dd713d994Christine Chen            updateSecondaryDisplayInfo(isConference);
481d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        }
482d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    }
483d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon
484d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    /**
48582f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     * Get the highest priority call to display.
48682f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     * Goes through the calls and chooses which to return based on priority of which type of call
48782f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     * to display to the user. Callers can use the "ignore" feature to get the second best call
48882f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     * by passing a previously found primary call as ignore.
48982f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     *
49082f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     * @param ignore A call to ignore if found.
49182f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     */
492d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    private Call getCallToDisplay(CallList callList, Call ignore, boolean skipDisconnected) {
49382f5d003e675dfd56735c745744c3d968883b23cSantos Cordon
494d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        // Active calls come second.  An active call always gets precedent.
495d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        Call retval = callList.getActiveCall();
49682f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        if (retval != null && retval != ignore) {
49782f5d003e675dfd56735c745744c3d968883b23cSantos Cordon            return retval;
49882f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        }
49982f5d003e675dfd56735c745744c3d968883b23cSantos Cordon
500d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        // Disconnected calls get primary position if there are no active calls
501d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        // to let user know quickly what call has disconnected. Disconnected
502d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        // calls are very short lived.
503d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        if (!skipDisconnected) {
5046258ff60a7edc760facc3f387fc9c8ceee3fb518Christine Chen            retval = callList.getDisconnectingCall();
5056258ff60a7edc760facc3f387fc9c8ceee3fb518Christine Chen            if (retval != null && retval != ignore) {
5066258ff60a7edc760facc3f387fc9c8ceee3fb518Christine Chen                return retval;
5076258ff60a7edc760facc3f387fc9c8ceee3fb518Christine Chen            }
508d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            retval = callList.getDisconnectedCall();
509d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            if (retval != null && retval != ignore) {
510d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon                return retval;
511d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            }
51282f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        }
51382f5d003e675dfd56735c745744c3d968883b23cSantos Cordon
51482f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        // Then we go to background call (calls on hold)
51582f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        retval = callList.getBackgroundCall();
51682f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        if (retval != null && retval != ignore) {
51782f5d003e675dfd56735c745744c3d968883b23cSantos Cordon            return retval;
51882f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        }
51982f5d003e675dfd56735c745744c3d968883b23cSantos Cordon
52082f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        // Lastly, we go to a second background call.
52182f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        retval = callList.getSecondBackgroundCall();
52282f5d003e675dfd56735c745744c3d968883b23cSantos Cordon
52382f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        return retval;
52482f5d003e675dfd56735c745744c3d968883b23cSantos Cordon    }
52582f5d003e675dfd56735c745744c3d968883b23cSantos Cordon
52642373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng    private void updatePrimaryDisplayInfo(ContactCacheEntry entry, boolean isConference) {
52742373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        Log.d(TAG, "Update primary display " + entry);
5286d231f52e4f00399330d772f2a337283803f3a9dYorke Lee        final CallCardUi ui = getUi();
529d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        if (ui == null) {
53042373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            // TODO: May also occur if search result comes back after ui is destroyed. Look into
53142373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            // removing that case completely.
53242373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            Log.d(TAG, "updatePrimaryDisplayInfo called but ui is null!");
533d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon            return;
5346d231f52e4f00399330d772f2a337283803f3a9dYorke Lee        }
535be8060acf5ecbb916c161d3249813098c0611ed5Yorke Lee
536812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        final boolean isGenericConf = isGenericConference(mPrimary);
53742373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        if (entry != null) {
53842373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            final String name = getNameForCall(entry);
53942373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            final String number = getNumberForCall(entry);
54042373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            final boolean nameIsNumber = name != null && name.equals(entry.number);
54142373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            ui.setPrimary(number, name, nameIsNumber, entry.label,
542812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon                    entry.photo, isConference, isGenericConf, entry.isSipCall);
5436d231f52e4f00399330d772f2a337283803f3a9dYorke Lee        } else {
544812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            ui.setPrimary(null, null, false, null, null, isConference, isGenericConf, false);
545d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        }
546d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon
547d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    }
548d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon
5495345442d7238c1db00dc8d55a49f7f5dd713d994Christine Chen    private void updateSecondaryDisplayInfo(boolean isConference) {
55042373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
55142373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        final CallCardUi ui = getUi();
55242373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        if (ui == null) {
55342373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            return;
55442373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        }
55542373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
556812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        final boolean isGenericConf = isGenericConference(mSecondary);
55742373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        if (mSecondaryContactInfo != null) {
55842373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            Log.d(TAG, "updateSecondaryDisplayInfo() " + mSecondaryContactInfo);
559c4bacb09c398a615154dc97b066179e77dc57599Yorke Lee            final String nameForCall = getNameForCall(mSecondaryContactInfo);
560c4bacb09c398a615154dc97b066179e77dc57599Yorke Lee
561c4bacb09c398a615154dc97b066179e77dc57599Yorke Lee            final boolean nameIsNumber = nameForCall != null && nameForCall.equals(
562c4bacb09c398a615154dc97b066179e77dc57599Yorke Lee                    mSecondaryContactInfo.number);
563e5c0d8bdf8269f9435e0381889e4870f36a43f07Andrew Lee            ui.setSecondary(true /* show */, nameForCall, nameIsNumber, mSecondaryContactInfo.label,
5648a80413884d1afbd7e021d581546c2245f068619Nancy Chen                    getCallProviderLabel(mSecondary), getCallProviderIcon(mSecondary),
565e5c0d8bdf8269f9435e0381889e4870f36a43f07Andrew Lee                    isConference, isGenericConf);
56642373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        } else {
56742373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            // reset to nothing so that it starts off blank next time we use it.
568bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen            ui.setSecondary(false, null, false, null, null, null, isConference, isGenericConf);
56942373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        }
57042373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng    }
57142373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
5728a80413884d1afbd7e021d581546c2245f068619Nancy Chen
5738a80413884d1afbd7e021d581546c2245f068619Nancy Chen    /**
5748a80413884d1afbd7e021d581546c2245f068619Nancy Chen     * Gets the phone account to display for a call.
5758a80413884d1afbd7e021d581546c2245f068619Nancy Chen     */
5768a80413884d1afbd7e021d581546c2245f068619Nancy Chen    private PhoneAccount getAccountForCall(Call call) {
5778a80413884d1afbd7e021d581546c2245f068619Nancy Chen        PhoneAccountHandle accountHandle = call.getAccountHandle();
5788a80413884d1afbd7e021d581546c2245f068619Nancy Chen        if (accountHandle == null) {
5798a80413884d1afbd7e021d581546c2245f068619Nancy Chen            return null;
5808a80413884d1afbd7e021d581546c2245f068619Nancy Chen        }
5818a80413884d1afbd7e021d581546c2245f068619Nancy Chen        return getTelecommManager().getPhoneAccount(accountHandle);
5828a80413884d1afbd7e021d581546c2245f068619Nancy Chen    }
5838a80413884d1afbd7e021d581546c2245f068619Nancy Chen
5843d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    /**
5853d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon     * Returns the gateway number for any existing outgoing call.
5863d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon     */
5873d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    private String getGatewayNumber() {
5883d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        if (hasOutgoingGatewayCall()) {
589da7f422a46db4bfe5cf76312d23b44e60fa9d806Santos Cordon            return getNumberFromHandle(mPrimary.getGatewayInfo().getGatewayHandle());
5903d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        }
5913d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        return null;
5923d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    }
5933d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon
5943d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    /**
595bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen     * Return the Drawable object of the icon to display to the left of the connection label.
596bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen     */
5978a80413884d1afbd7e021d581546c2245f068619Nancy Chen    private Drawable getCallProviderIcon(Call call) {
5988a80413884d1afbd7e021d581546c2245f068619Nancy Chen        PhoneAccount account = getAccountForCall(call);
5998a80413884d1afbd7e021d581546c2245f068619Nancy Chen        if (account != null && getTelecommManager().hasMultipleEnabledAccounts()) {
6008a80413884d1afbd7e021d581546c2245f068619Nancy Chen            return account.getIcon(mContext);
6018a80413884d1afbd7e021d581546c2245f068619Nancy Chen        }
6028a80413884d1afbd7e021d581546c2245f068619Nancy Chen        return null;
6038a80413884d1afbd7e021d581546c2245f068619Nancy Chen    }
6048a80413884d1afbd7e021d581546c2245f068619Nancy Chen
6058a80413884d1afbd7e021d581546c2245f068619Nancy Chen    /**
6068a80413884d1afbd7e021d581546c2245f068619Nancy Chen     * Return the string label to represent the call provider
6078a80413884d1afbd7e021d581546c2245f068619Nancy Chen     */
6088a80413884d1afbd7e021d581546c2245f068619Nancy Chen    private String getCallProviderLabel(Call call) {
6098a80413884d1afbd7e021d581546c2245f068619Nancy Chen        PhoneAccount account = getAccountForCall(call);
6108a80413884d1afbd7e021d581546c2245f068619Nancy Chen        if (account != null && getTelecommManager().hasMultipleEnabledAccounts()) {
6118a80413884d1afbd7e021d581546c2245f068619Nancy Chen            return account.getLabel().toString();
612bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen        }
613bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen        return null;
614bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen    }
615bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen
616bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen    /**
617bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen     * Returns the label (line of text above the number/name) for any given call.
618f8b0677bed382046cb26e38a8442a9509d1e835cSailesh Nepal     * For example, "calling via [Account/Google Voice]" for outgoing calls.
6193d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon     */
620bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen    private String getConnectionLabel() {
6213d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        if (hasOutgoingGatewayCall() && getUi() != null) {
622bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen            // Return the label for the gateway app on outgoing calls.
6233d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon            final PackageManager pm = mContext.getPackageManager();
6243d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon            try {
625ae73c9aab1c716d9ef85f4f0dbc6f69e97a8f7e6Sailesh Nepal                ApplicationInfo info = pm.getApplicationInfo(
626ae73c9aab1c716d9ef85f4f0dbc6f69e97a8f7e6Sailesh Nepal                        mPrimary.getGatewayInfo().getGatewayProviderPackageName(), 0);
627bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen                return pm.getApplicationLabel(info).toString();
6283d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon            } catch (PackageManager.NameNotFoundException e) {
629bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen                Log.e(this, "Gateway Application Not Found.", e);
630bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen                return null;
6313d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon            }
6323d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        }
6338a80413884d1afbd7e021d581546c2245f068619Nancy Chen        return getCallProviderLabel(mPrimary);
6343d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    }
6353d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon
6363d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    private boolean hasOutgoingGatewayCall() {
6373d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        // We only display the gateway information while DIALING so return false for any othe
6383d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        // call state.
63942373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        // TODO: mPrimary can be null because this is called from updatePrimaryDisplayInfo which
64042373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        // is also called after a contact search completes (call is not present yet).  Split the
64142373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        // UI update so it can receive independent updates.
64242373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        if (mPrimary == null) {
64342373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            return false;
64442373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        }
645ae73c9aab1c716d9ef85f4f0dbc6f69e97a8f7e6Sailesh Nepal        return Call.State.isDialing(mPrimary.getState()) && mPrimary.getGatewayInfo() != null &&
646ae73c9aab1c716d9ef85f4f0dbc6f69e97a8f7e6Sailesh Nepal                !mPrimary.getGatewayInfo().isEmpty();
6473d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    }
6483d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon
649d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    /**
650d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon     * Gets the name to display for the call.
651d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon     */
652d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    private static String getNameForCall(ContactCacheEntry contactInfo) {
653d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        if (TextUtils.isEmpty(contactInfo.name)) {
654d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            return contactInfo.number;
6556d231f52e4f00399330d772f2a337283803f3a9dYorke Lee        }
656d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        return contactInfo.name;
657d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    }
6586d231f52e4f00399330d772f2a337283803f3a9dYorke Lee
659d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    /**
660d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon     * Gets the number to display for a call.
661d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon     */
662d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    private static String getNumberForCall(ContactCacheEntry contactInfo) {
663d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        // If the name is empty, we use the number for the name...so dont show a second
664d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        // number in the number field
665d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        if (TextUtils.isEmpty(contactInfo.name)) {
6661c6bb983216392b5ceb36cea42a46631f68a3dd6Jay Shrauner            return contactInfo.location;
667d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        }
668d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        return contactInfo.number;
669d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    }
6706d231f52e4f00399330d772f2a337283803f3a9dYorke Lee
671e5c0d8bdf8269f9435e0381889e4870f36a43f07Andrew Lee    public void secondaryInfoClicked() {
67280c49a823543c9fb93420d05a6375fb1ff4ca631Yorke Lee        if (mSecondary == null) {
673e5c0d8bdf8269f9435e0381889e4870f36a43f07Andrew Lee            Log.wtf(this, "Secondary info clicked but no secondary call.");
67480c49a823543c9fb93420d05a6375fb1ff4ca631Yorke Lee            return;
67580c49a823543c9fb93420d05a6375fb1ff4ca631Yorke Lee        }
67680c49a823543c9fb93420d05a6375fb1ff4ca631Yorke Lee
677248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal        Log.i(this, "Swapping call to foreground: " + mSecondary);
6788d38cf6761ae048b1a42504f1b59e872cf43df47Ihab Awad        TelecommAdapter.getInstance().unholdCall(mSecondary.getId());
67990995fcb6778a9cb6dc35be12aeb1a5d0dcbb5aeYorke Lee    }
68090995fcb6778a9cb6dc35be12aeb1a5d0dcbb5aeYorke Lee
6817e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee    public void endCallClicked() {
6827e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee        if (mPrimary == null) {
6837e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee            return;
6847e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee        }
6857e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee
686cb2f51bf1acf387f391ca9c8cae8a2344eb2936aEvan Charlton        Log.i(this, "Disconnecting call: " + mPrimary);
6878d38cf6761ae048b1a42504f1b59e872cf43df47Ihab Awad        TelecommAdapter.getInstance().disconnectCall(mPrimary.getId());
6887e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee    }
6897e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee
690da7f422a46db4bfe5cf76312d23b44e60fa9d806Santos Cordon    private String getNumberFromHandle(Uri handle) {
691da7f422a46db4bfe5cf76312d23b44e60fa9d806Santos Cordon        return handle == null ? "" : handle.getSchemeSpecificPart();
692da7f422a46db4bfe5cf76312d23b44e60fa9d806Santos Cordon    }
693da7f422a46db4bfe5cf76312d23b44e60fa9d806Santos Cordon
694350fff554bf7ed5b9e91985935488771156953abTyler Gunn    /**
695350fff554bf7ed5b9e91985935488771156953abTyler Gunn     * Handles a change to the full screen video state.
696350fff554bf7ed5b9e91985935488771156953abTyler Gunn     *
697350fff554bf7ed5b9e91985935488771156953abTyler Gunn     * @param isFullScreenVideo {@code True} if the application is entering full screen video mode.
698350fff554bf7ed5b9e91985935488771156953abTyler Gunn     */
699350fff554bf7ed5b9e91985935488771156953abTyler Gunn    @Override
700350fff554bf7ed5b9e91985935488771156953abTyler Gunn    public void onFullScreenVideoStateChanged(boolean isFullScreenVideo) {
701350fff554bf7ed5b9e91985935488771156953abTyler Gunn        final CallCardUi ui = getUi();
702350fff554bf7ed5b9e91985935488771156953abTyler Gunn        if (ui == null) {
703350fff554bf7ed5b9e91985935488771156953abTyler Gunn            return;
704350fff554bf7ed5b9e91985935488771156953abTyler Gunn        }
705350fff554bf7ed5b9e91985935488771156953abTyler Gunn        ui.setCallCardVisible(!isFullScreenVideo);
706350fff554bf7ed5b9e91985935488771156953abTyler Gunn    }
707350fff554bf7ed5b9e91985935488771156953abTyler Gunn
708d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    public interface CallCardUi extends Ui {
709d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        void setVisible(boolean on);
710350fff554bf7ed5b9e91985935488771156953abTyler Gunn        void setCallCardVisible(boolean visible);
711d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        void setPrimary(String number, String name, boolean nameIsNumber, String label,
712812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon                Drawable photo, boolean isConference, boolean isGeneric, boolean isSipCall);
713c4bacb09c398a615154dc97b066179e77dc57599Yorke Lee        void setSecondary(boolean show, String name, boolean nameIsNumber, String label,
714bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen                String providerLabel, Drawable providerIcon, boolean isConference,
715bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen                boolean isGeneric);
7169c4226952c74f024c09e0bd381048493993c974eAndrew Lee        void setCallState(int state, int videoState, int sessionModificationState, int cause,
7179c4226952c74f024c09e0bd381048493993c974eAndrew Lee                String connectionLabel, Drawable connectionIcon, String gatewayNumber);
7188cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        void setPrimaryCallElapsedTime(boolean show, String duration);
71942373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        void setPrimaryName(String name, boolean nameIsNumber);
72049ff6571403695e81dbbd83e4f61790ce9c75f6dSantos Cordon        void setPrimaryImage(Drawable image);
72142373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        void setPrimaryPhoneNumber(String phoneNumber);
72242373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        void setPrimaryLabel(String label);
723e26b887e90d5e9566a5054a1ccb3ed32ae2eea2dAndrew Lee        void setEndCallButtonEnabled(boolean enabled);
7240786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton        void setCallbackNumber(String number, boolean isEmergencyCalls);
7250e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton        void setCallDetails(android.telecomm.Call.Details details);
726804baccc3aeed4ed00d1f0a62ecc37fb5ea6d9fdTyler Gunn        void setPhotoVisible(boolean isVisible);
727350fff554bf7ed5b9e91985935488771156953abTyler Gunn        void setProgressSpinnerVisible(boolean visible);
728be8060acf5ecbb916c161d3249813098c0611ed5Yorke Lee    }
7294feb57b986dc6b1edc5dc026a926b4934778716dIhab Awad
7304feb57b986dc6b1edc5dc026a926b4934778716dIhab Awad    private TelecommManager getTelecommManager() {
7314feb57b986dc6b1edc5dc026a926b4934778716dIhab Awad        if (mTelecommManager == null) {
732d5b908ee536eb33d80abc4b28110b10d18fe0a8eYorke Lee            mTelecommManager =
733d5b908ee536eb33d80abc4b28110b10d18fe0a8eYorke Lee                    (TelecommManager) mContext.getSystemService(Context.TELECOMM_SERVICE);
7344feb57b986dc6b1edc5dc026a926b4934778716dIhab Awad        }
7354feb57b986dc6b1edc5dc026a926b4934778716dIhab Awad        return mTelecommManager;
7364feb57b986dc6b1edc5dc026a926b4934778716dIhab Awad    }
737c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon}
738