CallCardPresenter.java revision 1da81ce59cfbebd4e53fdfd2011e859069120de7
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;
253718dcb345e77e421ab18a760e48f0c3a760fccaIhab Awadimport android.os.Handler;
263718dcb345e77e421ab18a760e48f0c3a760fccaIhab Awadimport android.telecomm.PhoneCapabilities;
27b6f45c2768f5af916ee3257542a3ab03611c1f5eEvan Charltonimport android.telecomm.PhoneAccount;
2876e1b4bfb2e21300068f10cc94922214e62c8f86Evan Charltonimport android.telecomm.PhoneAccountHandle;
290e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charltonimport android.telecomm.StatusHints;
304feb57b986dc6b1edc5dc026a926b4934778716dIhab Awadimport android.telecomm.TelecommManager;
313718dcb345e77e421ab18a760e48f0c3a760fccaIhab Awadimport android.telecomm.VideoProfile;
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
38d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordonimport com.android.incallui.ContactInfoCache.ContactCacheEntry;
39d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordonimport com.android.incallui.ContactInfoCache.ContactInfoCacheCallback;
400e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charltonimport com.android.incallui.InCallPresenter.InCallDetailsListener;
41350fff554bf7ed5b9e91985935488771156953abTyler Gunnimport com.android.incallui.InCallPresenter.InCallEventListener;
427ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordonimport com.android.incallui.InCallPresenter.InCallState;
437ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordonimport com.android.incallui.InCallPresenter.InCallStateListener;
441c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordonimport com.android.incallui.InCallPresenter.IncomingCallListener;
455b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee
465b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Leeimport java.lang.ref.WeakReference;
475b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee
4842373eb59cbef15ec61ebb5c919031f293291a53Chiao Chengimport com.google.common.base.Preconditions;
49c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon
50c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon/**
51c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon * Presenter for the Call Card Fragment.
52033ed5926d2924d35b9c82898ab4e835da56b3afChiao Cheng * <p>
537ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon * This class listens for changes to InCallState and passes it along to the fragment.
54c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon */
55d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordonpublic class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
5691a369b019b39c5335a4f5d251691c0cdb657f7dAndrew Lee        implements InCallStateListener, IncomingCallListener, InCallDetailsListener,
579c98346835b8e902e0c2c11f14a35f4e91578e9fAndrew Lee        InCallEventListener {
58be8060acf5ecbb916c161d3249813098c0611ed5Yorke Lee
59033ed5926d2924d35b9c82898ab4e835da56b3afChiao Cheng    private static final String TAG = CallCardPresenter.class.getSimpleName();
609c4226952c74f024c09e0bd381048493993c974eAndrew Lee    private static final long CALL_TIME_UPDATE_INTERVAL_MS = 1000;
618cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon
621b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    private Call mPrimary;
63d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    private Call mSecondary;
64d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    private ContactCacheEntry mPrimaryContactInfo;
65d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    private ContactCacheEntry mSecondaryContactInfo;
6686a7f5639fd0798c3b4500166f97649949237215Andrew Lee    private CallTimer mCallTimer;
673d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    private Context mContext;
684feb57b986dc6b1edc5dc026a926b4934778716dIhab Awad    private TelecommManager mTelecommManager;
696d231f52e4f00399330d772f2a337283803f3a9dYorke Lee
705b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee    public static class ContactLookupCallback implements ContactInfoCacheCallback {
715b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        private final WeakReference<CallCardPresenter> mCallCardPresenter;
725b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        private final boolean mIsPrimary;
735b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee
745b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        public ContactLookupCallback(CallCardPresenter callCardPresenter, boolean isPrimary) {
755b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            mCallCardPresenter = new WeakReference<CallCardPresenter>(callCardPresenter);
765b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            mIsPrimary = isPrimary;
775b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        }
785b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee
795b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        @Override
805b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        public void onContactInfoComplete(String callId, ContactCacheEntry entry) {
815b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            CallCardPresenter presenter = mCallCardPresenter.get();
825b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            if (presenter != null) {
835b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee                presenter.onContactInfoComplete(callId, entry, mIsPrimary);
845b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            }
855b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        }
865b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee
875b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        @Override
885b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        public void onImageLoadComplete(String callId, ContactCacheEntry entry) {
895b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            CallCardPresenter presenter = mCallCardPresenter.get();
905b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            if (presenter != null) {
915b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee                presenter.onImageLoadComplete(callId, entry);
925b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            }
935b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        }
945b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee
955b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee    }
965b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee
97b8eedb3b9796873eaa22847205239a51092f1a43Santos Cordon    public CallCardPresenter() {
988cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        // create the call timer
998cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        mCallTimer = new CallTimer(new Runnable() {
1008cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon            @Override
1018cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon            public void run() {
1028cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon                updateCallTime();
1038cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon            }
1048cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        });
1056d231f52e4f00399330d772f2a337283803f3a9dYorke Lee    }
1066d231f52e4f00399330d772f2a337283803f3a9dYorke Lee
1071c6bb983216392b5ceb36cea42a46631f68a3dd6Jay Shrauner    public void init(Context context, Call call) {
10842373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        mContext = Preconditions.checkNotNull(context);
10942373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
1104a5339c4a266891ce560dfb6e348c3779a0a3ca1Chiao Cheng        // Call may be null if disconnect happened already.
1114a5339c4a266891ce560dfb6e348c3779a0a3ca1Chiao Cheng        if (call != null) {
112656dd4a0d8571b47ecf0ecf3e4c2eeacfd1099b3Chiao Cheng            mPrimary = call;
113656dd4a0d8571b47ecf0ecf3e4c2eeacfd1099b3Chiao Cheng
1144a5339c4a266891ce560dfb6e348c3779a0a3ca1Chiao Cheng            // start processing lookups right away.
115812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            if (!call.isConferenceCall()) {
116248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal                startContactInfoSearch(call, true, call.getState() == Call.State.INCOMING);
117812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            } else {
118812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon                updateContactEntry(null, true, true);
119812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            }
1204a5339c4a266891ce560dfb6e348c3779a0a3ca1Chiao Cheng        }
121033ed5926d2924d35b9c82898ab4e835da56b3afChiao Cheng    }
122033ed5926d2924d35b9c82898ab4e835da56b3afChiao Cheng
123c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon    @Override
124c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon    public void onUiReady(CallCardUi ui) {
125c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon        super.onUiReady(ui);
1261b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon
12742373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        // Contact search may have completed before ui is ready.
12842373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        if (mPrimaryContactInfo != null) {
129314b2aaa1fa1ef799270987e964f7df4d983b9eeChristine Chen            updatePrimaryDisplayInfo(mPrimaryContactInfo, isConference(mPrimary));
13042373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        }
13142373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
1321f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon        // Register for call state changes last
1331f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon        InCallPresenter.getInstance().addListener(this);
1341c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon        InCallPresenter.getInstance().addIncomingCallListener(this);
1350e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton        InCallPresenter.getInstance().addDetailsListener(this);
136350fff554bf7ed5b9e91985935488771156953abTyler Gunn        InCallPresenter.getInstance().addInCallEventListener(this);
1371b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    }
1381b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon
1391b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    @Override
1401b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    public void onUiUnready(CallCardUi ui) {
1411b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon        super.onUiUnready(ui);
1421b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon
1431f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon        // stop getting call state changes
1441f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon        InCallPresenter.getInstance().removeListener(this);
1451c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon        InCallPresenter.getInstance().removeIncomingCallListener(this);
1460e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton        InCallPresenter.getInstance().removeDetailsListener(this);
147350fff554bf7ed5b9e91985935488771156953abTyler Gunn        InCallPresenter.getInstance().removeInCallEventListener(this);
1481f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon
1491b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon        mPrimary = null;
150d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        mPrimaryContactInfo = null;
151d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        mSecondaryContactInfo = null;
152c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon    }
153c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon
154c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon    @Override
155f003346e5f9ba29e869a881bcca2e59d6ea8e0f6Nancy Chen    public void onIncomingCall(InCallState oldState, InCallState newState, Call call) {
1561c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon        // same logic should happen as with onStateChange()
157f003346e5f9ba29e869a881bcca2e59d6ea8e0f6Nancy Chen        onStateChange(oldState, newState, CallList.getInstance());
1581c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon    }
1591c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon
1601c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon    @Override
161f003346e5f9ba29e869a881bcca2e59d6ea8e0f6Nancy Chen    public void onStateChange(InCallState oldState, InCallState newState, CallList callList) {
162f003346e5f9ba29e869a881bcca2e59d6ea8e0f6Nancy Chen        Log.d(this, "onStateChange() " + newState);
16375c86b55d45b1725c46ed2e5d77c9c43fcfd93daSantos Cordon        final CallCardUi ui = getUi();
1641b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon        if (ui == null) {
1651b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon            return;
1661b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon        }
167c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon
1687ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon        Call primary = null;
1697ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon        Call secondary = null;
1707ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon
171f003346e5f9ba29e869a881bcca2e59d6ea8e0f6Nancy Chen        if (newState == InCallState.INCOMING) {
1727ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon            primary = callList.getIncomingCall();
173f003346e5f9ba29e869a881bcca2e59d6ea8e0f6Nancy Chen        } else if (newState == InCallState.PENDING_OUTGOING || newState == InCallState.OUTGOING) {
174950e3df8ac744daf2a890d279566bdba424710f9Santos Cordon            primary = callList.getOutgoingCall();
175f003346e5f9ba29e869a881bcca2e59d6ea8e0f6Nancy Chen            if (primary == null) {
176f003346e5f9ba29e869a881bcca2e59d6ea8e0f6Nancy Chen                primary = callList.getPendingOutgoingCall();
177f003346e5f9ba29e869a881bcca2e59d6ea8e0f6Nancy Chen            }
178950e3df8ac744daf2a890d279566bdba424710f9Santos Cordon
17982f5d003e675dfd56735c745744c3d968883b23cSantos Cordon            // getCallToDisplay doesn't go through outgoing or incoming calls. It will return the
18082f5d003e675dfd56735c745744c3d968883b23cSantos Cordon            // highest priority call to display as the secondary call.
181d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            secondary = getCallToDisplay(callList, null, true);
182f003346e5f9ba29e869a881bcca2e59d6ea8e0f6Nancy Chen        } else if (newState == InCallState.INCALL) {
183d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            primary = getCallToDisplay(callList, null, false);
184d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            secondary = getCallToDisplay(callList, primary, true);
1857ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon        }
1867ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon
187a4bd83ad639b349fa16dbd07225017fcbf6ed550Chiao Cheng        Log.d(this, "Primary call: " + primary);
188a4bd83ad639b349fa16dbd07225017fcbf6ed550Chiao Cheng        Log.d(this, "Secondary call: " + secondary);
1897ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon
1909c98346835b8e902e0c2c11f14a35f4e91578e9fAndrew Lee        final boolean primaryChanged = !Call.areSame(mPrimary, primary);
1919c98346835b8e902e0c2c11f14a35f4e91578e9fAndrew Lee        final boolean secondaryChanged = !Call.areSame(mSecondary, secondary);
1929c98346835b8e902e0c2c11f14a35f4e91578e9fAndrew Lee
193812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        mSecondary = secondary;
194812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        mPrimary = primary;
195812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon
196812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        if (primaryChanged && mPrimary != null) {
197812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            // primary call has changed
198248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal            mPrimaryContactInfo = ContactInfoCache.buildCacheEntryFromCall(mContext, mPrimary,
199248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal                    mPrimary.getState() == Call.State.INCOMING);
200812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            updatePrimaryDisplayInfo(mPrimaryContactInfo, isConference(mPrimary));
201812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            maybeStartSearch(mPrimary, true);
2029c4226952c74f024c09e0bd381048493993c974eAndrew Lee            mPrimary.setSessionModificationState(Call.SessionModificationState.NO_REQUEST);
20342373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        }
20442373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
205812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        if (mSecondary == null) {
20642373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            // Secondary call may have ended.  Update the ui.
20742373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            mSecondaryContactInfo = null;
2085345442d7238c1db00dc8d55a49f7f5dd713d994Christine Chen            updateSecondaryDisplayInfo(false);
209812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        } else if (secondaryChanged) {
210812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            // secondary call has changed
211248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal            mSecondaryContactInfo = ContactInfoCache.buildCacheEntryFromCall(mContext, mSecondary,
212248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal                    mSecondary.getState() == Call.State.INCOMING);
213812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            updateSecondaryDisplayInfo(mSecondary.isConferenceCall());
214812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            maybeStartSearch(mSecondary, false);
2159c4226952c74f024c09e0bd381048493993c974eAndrew Lee            mSecondary.setSessionModificationState(Call.SessionModificationState.NO_REQUEST);
21642373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        }
21742373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
2189c4226952c74f024c09e0bd381048493993c974eAndrew Lee        // Start/stop timers.
2198cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        if (mPrimary != null && mPrimary.getState() == Call.State.ACTIVE) {
220a4bd83ad639b349fa16dbd07225017fcbf6ed550Chiao Cheng            Log.d(this, "Starting the calltime timer");
2219c4226952c74f024c09e0bd381048493993c974eAndrew Lee            mCallTimer.start(CALL_TIME_UPDATE_INTERVAL_MS);
2228cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        } else {
223a4bd83ad639b349fa16dbd07225017fcbf6ed550Chiao Cheng            Log.d(this, "Canceling the calltime timer");
2248cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon            mCallTimer.cancel();
2258cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon            ui.setPrimaryCallElapsedTime(false, null);
2268cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        }
2278cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon
228d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        // Set the call state
2298aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton        int callState = Call.State.IDLE;
230d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        if (mPrimary != null) {
23132027ae1f52232258cc8133d383459f3b4ee57e4Yorke Lee            callState = mPrimary.getState();
232ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal            updatePrimaryCallState();
23382f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        } else {
2349c4226952c74f024c09e0bd381048493993c974eAndrew Lee            getUi().setCallState(
2359c4226952c74f024c09e0bd381048493993c974eAndrew Lee                    callState,
2363718dcb345e77e421ab18a760e48f0c3a760fccaIhab Awad                    VideoProfile.VideoState.AUDIO_ONLY,
2379c4226952c74f024c09e0bd381048493993c974eAndrew Lee                    Call.SessionModificationState.NO_REQUEST,
2389c4226952c74f024c09e0bd381048493993c974eAndrew Lee                    DisconnectCause.NOT_VALID,
2399c4226952c74f024c09e0bd381048493993c974eAndrew Lee                    null,
2409c4226952c74f024c09e0bd381048493993c974eAndrew Lee                    null,
2419c4226952c74f024c09e0bd381048493993c974eAndrew Lee                    null);
24282f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        }
243e26b887e90d5e9566a5054a1ccb3ed32ae2eea2dAndrew Lee
244350fff554bf7ed5b9e91985935488771156953abTyler Gunn        // Hide/show the contact photo based on the video state.
245350fff554bf7ed5b9e91985935488771156953abTyler Gunn        // If the primary call is a video call on hold, still show the contact photo.
246350fff554bf7ed5b9e91985935488771156953abTyler Gunn        // If the primary call is an active video call, hide the contact photo.
247804baccc3aeed4ed00d1f0a62ecc37fb5ea6d9fdTyler Gunn        if (mPrimary != null) {
248cda81c2ef1ba595c35ae1d4ad72c44f3443e08fdTyler Gunn            getUi().setPhotoVisible(!(mPrimary.isVideoCall(mContext) &&
249cda81c2ef1ba595c35ae1d4ad72c44f3443e08fdTyler Gunn                    callState != Call.State.ONHOLD));
250804baccc3aeed4ed00d1f0a62ecc37fb5ea6d9fdTyler Gunn        }
251804baccc3aeed4ed00d1f0a62ecc37fb5ea6d9fdTyler Gunn
2521da81ce59cfbebd4e53fdfd2011e859069120de7Andrew Lee        maybeShowManageConferenceCallButton();
2531da81ce59cfbebd4e53fdfd2011e859069120de7Andrew Lee
254f003346e5f9ba29e869a881bcca2e59d6ea8e0f6Nancy Chen        final boolean enableEndCallButton = Call.State.isConnectingOrConnected(callState) &&
2558aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton                callState != Call.State.INCOMING && mPrimary != null;
256c44f654b992c6ab8a4acff9cb5aa2678c58755d9Andrew Lee        // Hide the end call button instantly if we're receiving an incoming call.
257c44f654b992c6ab8a4acff9cb5aa2678c58755d9Andrew Lee        getUi().setEndCallButtonEnabled(
258c44f654b992c6ab8a4acff9cb5aa2678c58755d9Andrew Lee                enableEndCallButton, callState != Call.State.INCOMING /* animate */);
2591b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    }
2601b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon
2611b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    @Override
2621869dcf386a96f060a16ac74f1722d816b69aa7dTyler Gunn    public void onDetailsChanged(Call call, android.telecomm.Call.Details details) {
263ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal        updatePrimaryCallState();
2640786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton    }
2650786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton
2660786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton    private String getSubscriptionNumber() {
2670786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton        // If it's an emergency call, and they're not populating the callback number,
2680786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton        // then try to fall back to the phone sub info (to hopefully get the SIM's
2690786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton        // number directly from the telephony layer).
27076e1b4bfb2e21300068f10cc94922214e62c8f86Evan Charlton        PhoneAccountHandle accountHandle = mPrimary.getAccountHandle();
27176e1b4bfb2e21300068f10cc94922214e62c8f86Evan Charlton        if (accountHandle != null) {
272d5b908ee536eb33d80abc4b28110b10d18fe0a8eYorke Lee            TelecommManager mgr =
273d5b908ee536eb33d80abc4b28110b10d18fe0a8eYorke Lee                    (TelecommManager) mContext.getSystemService(Context.TELECOMM_SERVICE);
274b6f45c2768f5af916ee3257542a3ab03611c1f5eEvan Charlton            PhoneAccount account = mgr.getPhoneAccount(accountHandle);
275b6f45c2768f5af916ee3257542a3ab03611c1f5eEvan Charlton            if (account != null) {
276b6f45c2768f5af916ee3257542a3ab03611c1f5eEvan Charlton                return account.getSubscriptionNumber();
277c108b49ad5440fbf381c9a589d8a217da3efcb64Ihab Awad            }
2780e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton        }
2790786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton        return null;
2800e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton    }
2810e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton
282ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal    private void updatePrimaryCallState() {
283ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal        if (getUi() != null && mPrimary != null) {
284ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal            getUi().setCallState(
285ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal                    mPrimary.getState(),
286ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal                    mPrimary.getVideoState(),
287ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal                    mPrimary.getSessionModificationState(),
288ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal                    mPrimary.getDisconnectCause(),
289ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal                    getConnectionLabel(),
290ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal                    getConnectionIcon(),
291ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal                    getGatewayNumber());
292ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal            setCallbackNumber();
293ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal        }
294ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal    }
2950786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton
2961da81ce59cfbebd4e53fdfd2011e859069120de7Andrew Lee    /**
2971da81ce59cfbebd4e53fdfd2011e859069120de7Andrew Lee     * Only show the conference call button if we are not in a generic conference.
2981da81ce59cfbebd4e53fdfd2011e859069120de7Andrew Lee     * On CDMA devices, instead of a manage conference call button, we show "add" and "merge"
2991da81ce59cfbebd4e53fdfd2011e859069120de7Andrew Lee     * buttons in the {@link CallButtonFragment}.
3001da81ce59cfbebd4e53fdfd2011e859069120de7Andrew Lee     */
3011da81ce59cfbebd4e53fdfd2011e859069120de7Andrew Lee    private void maybeShowManageConferenceCallButton() {
3021da81ce59cfbebd4e53fdfd2011e859069120de7Andrew Lee        final boolean isGenericConference = mPrimary.can(PhoneCapabilities.GENERIC_CONFERENCE);
3031da81ce59cfbebd4e53fdfd2011e859069120de7Andrew Lee        getUi().showManageConferenceCallButton(mPrimary.isConferenceCall() && !isGenericConference);
3041da81ce59cfbebd4e53fdfd2011e859069120de7Andrew Lee    }
3051da81ce59cfbebd4e53fdfd2011e859069120de7Andrew Lee
306ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal    private void setCallbackNumber() {
307ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal        String callbackNumber = null;
3080786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton
309ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal        boolean isEmergencyCall = PhoneNumberUtils.isEmergencyNumber(
310ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal                getNumberFromHandle(mPrimary.getHandle()));
311ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal        if (isEmergencyCall) {
312ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal            callbackNumber = getSubscriptionNumber();
313ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal        } else {
314ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal            StatusHints statusHints = mPrimary.getTelecommCall().getDetails().getStatusHints();
315ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal            if (statusHints != null) {
316ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal                Bundle extras = statusHints.getExtras();
317ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal                if (extras != null) {
318ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal                    callbackNumber = extras.getString(TelecommManager.EXTRA_CALL_BACK_NUMBER);
3190786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton                }
3200e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton            }
3210786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton        }
3220786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton
323ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal        TelephonyManager telephonyManager =
324d5b908ee536eb33d80abc4b28110b10d18fe0a8eYorke Lee                (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
325d5b908ee536eb33d80abc4b28110b10d18fe0a8eYorke Lee        String simNumber = telephonyManager.getLine1Number();
326ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal        if (PhoneNumberUtils.compare(callbackNumber, simNumber)) {
3270786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton            Log.d(this, "Numbers are the same; not showing the callback number");
328ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal            callbackNumber = null;
3290786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton        }
330ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal
3310786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton        getUi().setCallbackNumber(callbackNumber, isEmergencyCall);
3320e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton    }
3330e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton
3348cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon    public void updateCallTime() {
3358cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        final CallCardUi ui = getUi();
3368cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon
3378cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        if (ui == null || mPrimary == null || mPrimary.getState() != Call.State.ACTIVE) {
338899251968ee4ee3cb375032185653ecd888e3f8dSantos Cordon            if (ui != null) {
339899251968ee4ee3cb375032185653ecd888e3f8dSantos Cordon                ui.setPrimaryCallElapsedTime(false, null);
340899251968ee4ee3cb375032185653ecd888e3f8dSantos Cordon            }
3418cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon            mCallTimer.cancel();
342899251968ee4ee3cb375032185653ecd888e3f8dSantos Cordon        } else {
343c6f4e50a4130fb8f7247f5eab6849829701ad484Sailesh Nepal            final long callStart = mPrimary.getConnectTimeMillis();
344899251968ee4ee3cb375032185653ecd888e3f8dSantos Cordon            final long duration = System.currentTimeMillis() - callStart;
345899251968ee4ee3cb375032185653ecd888e3f8dSantos Cordon            ui.setPrimaryCallElapsedTime(true, DateUtils.formatElapsedTime(duration / 1000));
3468cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        }
3478cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon    }
3488cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon
349f8b0677bed382046cb26e38a8442a9509d1e835cSailesh Nepal    public void phoneAccountClicked() {
3508aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton        if (mPrimary == null) {
3518aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton            return;
3528aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton        }
3538d38cf6761ae048b1a42504f1b59e872cf43df47Ihab Awad        TelecommAdapter.getInstance().phoneAccountClicked(mPrimary.getId());
3548aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton    }
3558aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton
356812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon    private void maybeStartSearch(Call call, boolean isPrimary) {
357812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        // no need to start search for conference calls which show generic info.
358812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        if (call != null && !call.isConferenceCall()) {
359248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal            startContactInfoSearch(call, isPrimary, call.getState() == Call.State.INCOMING);
360812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        }
361812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon    }
362812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon
36382f5d003e675dfd56735c745744c3d968883b23cSantos Cordon    /**
364d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon     * Starts a query for more contact data for the save primary and secondary calls.
365d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon     */
366248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal    private void startContactInfoSearch(final Call call, final boolean isPrimary,
367248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal            boolean isIncoming) {
36842373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        final ContactInfoCache cache = ContactInfoCache.getInstance(mContext);
36942373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
3705b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        cache.findInfo(call, isIncoming, new ContactLookupCallback(this, isPrimary));
3715b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee    }
3727d2fb8620b808c28c49bde99dc54f6de46fdcb44Chiao Cheng
3735b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee    private void onContactInfoComplete(String callId, ContactCacheEntry entry, boolean isPrimary) {
3745b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        updateContactEntry(entry, isPrimary, false);
3755b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        if (entry.name != null) {
3765b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            Log.d(TAG, "Contact found: " + entry);
3775b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        }
3785b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        if (entry.contactUri != null) {
3795b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            CallerInfoUtils.sendViewNotification(mContext, entry.contactUri);
3805b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        }
3815b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee    }
3825b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee
3835b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee    private void onImageLoadComplete(String callId, ContactCacheEntry entry) {
3845b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        if (getUi() == null) {
3855b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            return;
3865b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        }
387f003346e5f9ba29e869a881bcca2e59d6ea8e0f6Nancy Chen
3885b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        if (entry.photo != null) {
3895b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            if (mPrimary != null && callId.equals(mPrimary.getId())) {
3905b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee                getUi().setPrimaryImage(entry.photo);
3915b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            }
3925b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        }
39342373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng    }
39442373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
395812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon    private static boolean isConference(Call call) {
396812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        return call != null && call.isConferenceCall();
397812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon    }
398812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon
399812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon    private static boolean isGenericConference(Call call) {
4003718dcb345e77e421ab18a760e48f0c3a760fccaIhab Awad        return call != null && call.can(PhoneCapabilities.GENERIC_CONFERENCE);
40142373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng    }
402d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon
40342373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng    private void updateContactEntry(ContactCacheEntry entry, boolean isPrimary,
40442373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            boolean isConference) {
40542373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        if (isPrimary) {
40642373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            mPrimaryContactInfo = entry;
40742373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            updatePrimaryDisplayInfo(entry, isConference);
408d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        } else {
40942373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            mSecondaryContactInfo = entry;
4105345442d7238c1db00dc8d55a49f7f5dd713d994Christine Chen            updateSecondaryDisplayInfo(isConference);
411d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        }
412d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    }
413d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon
414d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    /**
41582f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     * Get the highest priority call to display.
41682f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     * Goes through the calls and chooses which to return based on priority of which type of call
41782f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     * to display to the user. Callers can use the "ignore" feature to get the second best call
41882f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     * by passing a previously found primary call as ignore.
41982f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     *
42082f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     * @param ignore A call to ignore if found.
42182f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     */
422d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    private Call getCallToDisplay(CallList callList, Call ignore, boolean skipDisconnected) {
42382f5d003e675dfd56735c745744c3d968883b23cSantos Cordon
424d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        // Active calls come second.  An active call always gets precedent.
425d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        Call retval = callList.getActiveCall();
42682f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        if (retval != null && retval != ignore) {
42782f5d003e675dfd56735c745744c3d968883b23cSantos Cordon            return retval;
42882f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        }
42982f5d003e675dfd56735c745744c3d968883b23cSantos Cordon
430d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        // Disconnected calls get primary position if there are no active calls
431d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        // to let user know quickly what call has disconnected. Disconnected
432d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        // calls are very short lived.
433d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        if (!skipDisconnected) {
4346258ff60a7edc760facc3f387fc9c8ceee3fb518Christine Chen            retval = callList.getDisconnectingCall();
4356258ff60a7edc760facc3f387fc9c8ceee3fb518Christine Chen            if (retval != null && retval != ignore) {
4366258ff60a7edc760facc3f387fc9c8ceee3fb518Christine Chen                return retval;
4376258ff60a7edc760facc3f387fc9c8ceee3fb518Christine Chen            }
438d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            retval = callList.getDisconnectedCall();
439d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            if (retval != null && retval != ignore) {
440d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon                return retval;
441d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            }
44282f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        }
44382f5d003e675dfd56735c745744c3d968883b23cSantos Cordon
44482f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        // Then we go to background call (calls on hold)
44582f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        retval = callList.getBackgroundCall();
44682f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        if (retval != null && retval != ignore) {
44782f5d003e675dfd56735c745744c3d968883b23cSantos Cordon            return retval;
44882f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        }
44982f5d003e675dfd56735c745744c3d968883b23cSantos Cordon
45082f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        // Lastly, we go to a second background call.
45182f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        retval = callList.getSecondBackgroundCall();
45282f5d003e675dfd56735c745744c3d968883b23cSantos Cordon
45382f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        return retval;
45482f5d003e675dfd56735c745744c3d968883b23cSantos Cordon    }
45582f5d003e675dfd56735c745744c3d968883b23cSantos Cordon
45642373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng    private void updatePrimaryDisplayInfo(ContactCacheEntry entry, boolean isConference) {
45742373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        Log.d(TAG, "Update primary display " + entry);
4586d231f52e4f00399330d772f2a337283803f3a9dYorke Lee        final CallCardUi ui = getUi();
459d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        if (ui == null) {
46042373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            // TODO: May also occur if search result comes back after ui is destroyed. Look into
46142373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            // removing that case completely.
46242373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            Log.d(TAG, "updatePrimaryDisplayInfo called but ui is null!");
463d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon            return;
4646d231f52e4f00399330d772f2a337283803f3a9dYorke Lee        }
465be8060acf5ecbb916c161d3249813098c0611ed5Yorke Lee
466812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        final boolean isGenericConf = isGenericConference(mPrimary);
46742373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        if (entry != null) {
46842373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            final String name = getNameForCall(entry);
46942373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            final String number = getNumberForCall(entry);
47042373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            final boolean nameIsNumber = name != null && name.equals(entry.number);
47142373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            ui.setPrimary(number, name, nameIsNumber, entry.label,
472812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon                    entry.photo, isConference, isGenericConf, entry.isSipCall);
4736d231f52e4f00399330d772f2a337283803f3a9dYorke Lee        } else {
474812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            ui.setPrimary(null, null, false, null, null, isConference, isGenericConf, false);
475d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        }
476d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon
477d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    }
478d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon
4795345442d7238c1db00dc8d55a49f7f5dd713d994Christine Chen    private void updateSecondaryDisplayInfo(boolean isConference) {
48042373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
48142373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        final CallCardUi ui = getUi();
48242373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        if (ui == null) {
48342373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            return;
48442373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        }
48542373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
486812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        final boolean isGenericConf = isGenericConference(mSecondary);
48742373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        if (mSecondaryContactInfo != null) {
48842373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            Log.d(TAG, "updateSecondaryDisplayInfo() " + mSecondaryContactInfo);
489c4bacb09c398a615154dc97b066179e77dc57599Yorke Lee            final String nameForCall = getNameForCall(mSecondaryContactInfo);
490c4bacb09c398a615154dc97b066179e77dc57599Yorke Lee
491c4bacb09c398a615154dc97b066179e77dc57599Yorke Lee            final boolean nameIsNumber = nameForCall != null && nameForCall.equals(
492c4bacb09c398a615154dc97b066179e77dc57599Yorke Lee                    mSecondaryContactInfo.number);
493e5c0d8bdf8269f9435e0381889e4870f36a43f07Andrew Lee            ui.setSecondary(true /* show */, nameForCall, nameIsNumber, mSecondaryContactInfo.label,
4948a80413884d1afbd7e021d581546c2245f068619Nancy Chen                    getCallProviderLabel(mSecondary), getCallProviderIcon(mSecondary),
495e5c0d8bdf8269f9435e0381889e4870f36a43f07Andrew Lee                    isConference, isGenericConf);
49642373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        } else {
49742373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            // reset to nothing so that it starts off blank next time we use it.
498bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen            ui.setSecondary(false, null, false, null, null, null, isConference, isGenericConf);
49942373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        }
50042373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng    }
50142373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
5028a80413884d1afbd7e021d581546c2245f068619Nancy Chen
5038a80413884d1afbd7e021d581546c2245f068619Nancy Chen    /**
5048a80413884d1afbd7e021d581546c2245f068619Nancy Chen     * Gets the phone account to display for a call.
5058a80413884d1afbd7e021d581546c2245f068619Nancy Chen     */
5068a80413884d1afbd7e021d581546c2245f068619Nancy Chen    private PhoneAccount getAccountForCall(Call call) {
5078a80413884d1afbd7e021d581546c2245f068619Nancy Chen        PhoneAccountHandle accountHandle = call.getAccountHandle();
5088a80413884d1afbd7e021d581546c2245f068619Nancy Chen        if (accountHandle == null) {
5098a80413884d1afbd7e021d581546c2245f068619Nancy Chen            return null;
5108a80413884d1afbd7e021d581546c2245f068619Nancy Chen        }
5118a80413884d1afbd7e021d581546c2245f068619Nancy Chen        return getTelecommManager().getPhoneAccount(accountHandle);
5128a80413884d1afbd7e021d581546c2245f068619Nancy Chen    }
5138a80413884d1afbd7e021d581546c2245f068619Nancy Chen
5143d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    /**
5153d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon     * Returns the gateway number for any existing outgoing call.
5163d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon     */
5173d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    private String getGatewayNumber() {
5183d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        if (hasOutgoingGatewayCall()) {
519da7f422a46db4bfe5cf76312d23b44e60fa9d806Santos Cordon            return getNumberFromHandle(mPrimary.getGatewayInfo().getGatewayHandle());
5203d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        }
5213d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        return null;
5223d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    }
5233d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon
5243d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    /**
525bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen     * Return the Drawable object of the icon to display to the left of the connection label.
526bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen     */
5278a80413884d1afbd7e021d581546c2245f068619Nancy Chen    private Drawable getCallProviderIcon(Call call) {
5288a80413884d1afbd7e021d581546c2245f068619Nancy Chen        PhoneAccount account = getAccountForCall(call);
5298a80413884d1afbd7e021d581546c2245f068619Nancy Chen        if (account != null && getTelecommManager().hasMultipleEnabledAccounts()) {
5308a80413884d1afbd7e021d581546c2245f068619Nancy Chen            return account.getIcon(mContext);
5318a80413884d1afbd7e021d581546c2245f068619Nancy Chen        }
5328a80413884d1afbd7e021d581546c2245f068619Nancy Chen        return null;
5338a80413884d1afbd7e021d581546c2245f068619Nancy Chen    }
5348a80413884d1afbd7e021d581546c2245f068619Nancy Chen
5358a80413884d1afbd7e021d581546c2245f068619Nancy Chen    /**
5368a80413884d1afbd7e021d581546c2245f068619Nancy Chen     * Return the string label to represent the call provider
5378a80413884d1afbd7e021d581546c2245f068619Nancy Chen     */
5388a80413884d1afbd7e021d581546c2245f068619Nancy Chen    private String getCallProviderLabel(Call call) {
5398a80413884d1afbd7e021d581546c2245f068619Nancy Chen        PhoneAccount account = getAccountForCall(call);
5408a80413884d1afbd7e021d581546c2245f068619Nancy Chen        if (account != null && getTelecommManager().hasMultipleEnabledAccounts()) {
5418a80413884d1afbd7e021d581546c2245f068619Nancy Chen            return account.getLabel().toString();
542bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen        }
543bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen        return null;
544bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen    }
545bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen
546bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen    /**
547bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen     * Returns the label (line of text above the number/name) for any given call.
548f8b0677bed382046cb26e38a8442a9509d1e835cSailesh Nepal     * For example, "calling via [Account/Google Voice]" for outgoing calls.
5493d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon     */
550bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen    private String getConnectionLabel() {
551ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal        StatusHints statusHints = mPrimary.getTelecommCall().getDetails().getStatusHints();
552ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal        if (statusHints != null && !TextUtils.isEmpty(statusHints.getLabel())) {
553ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal            return statusHints.getLabel().toString();
554ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal        }
555ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal
5563d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        if (hasOutgoingGatewayCall() && getUi() != null) {
557bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen            // Return the label for the gateway app on outgoing calls.
5583d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon            final PackageManager pm = mContext.getPackageManager();
5593d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon            try {
560ae73c9aab1c716d9ef85f4f0dbc6f69e97a8f7e6Sailesh Nepal                ApplicationInfo info = pm.getApplicationInfo(
561ae73c9aab1c716d9ef85f4f0dbc6f69e97a8f7e6Sailesh Nepal                        mPrimary.getGatewayInfo().getGatewayProviderPackageName(), 0);
562bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen                return pm.getApplicationLabel(info).toString();
5633d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon            } catch (PackageManager.NameNotFoundException e) {
564bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen                Log.e(this, "Gateway Application Not Found.", e);
565bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen                return null;
5663d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon            }
5673d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        }
5688a80413884d1afbd7e021d581546c2245f068619Nancy Chen        return getCallProviderLabel(mPrimary);
5693d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    }
5703d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon
571ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal    private Drawable getConnectionIcon() {
572ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal        StatusHints statusHints = mPrimary.getTelecommCall().getDetails().getStatusHints();
5733718dcb345e77e421ab18a760e48f0c3a760fccaIhab Awad        if (statusHints != null && statusHints.getIconResId() != 0) {
574ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal            Drawable icon = statusHints.getIcon(mContext);
575ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal            if (icon != null) {
576ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal                return icon;
577ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal            }
578ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal        }
579ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal        return getCallProviderIcon(mPrimary);
580ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal    }
581ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal
5823d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    private boolean hasOutgoingGatewayCall() {
5833718dcb345e77e421ab18a760e48f0c3a760fccaIhab Awad        // We only display the gateway information while STATE_DIALING so return false for any othe
5843d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        // call state.
58542373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        // TODO: mPrimary can be null because this is called from updatePrimaryDisplayInfo which
58642373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        // is also called after a contact search completes (call is not present yet).  Split the
58742373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        // UI update so it can receive independent updates.
58842373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        if (mPrimary == null) {
58942373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            return false;
59042373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        }
591ae73c9aab1c716d9ef85f4f0dbc6f69e97a8f7e6Sailesh Nepal        return Call.State.isDialing(mPrimary.getState()) && mPrimary.getGatewayInfo() != null &&
592ae73c9aab1c716d9ef85f4f0dbc6f69e97a8f7e6Sailesh Nepal                !mPrimary.getGatewayInfo().isEmpty();
5933d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    }
5943d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon
595d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    /**
596d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon     * Gets the name to display for the call.
597d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon     */
598d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    private static String getNameForCall(ContactCacheEntry contactInfo) {
599d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        if (TextUtils.isEmpty(contactInfo.name)) {
600d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            return contactInfo.number;
6016d231f52e4f00399330d772f2a337283803f3a9dYorke Lee        }
602d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        return contactInfo.name;
603d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    }
6046d231f52e4f00399330d772f2a337283803f3a9dYorke Lee
605d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    /**
606d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon     * Gets the number to display for a call.
607d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon     */
608d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    private static String getNumberForCall(ContactCacheEntry contactInfo) {
609d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        // If the name is empty, we use the number for the name...so dont show a second
610d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        // number in the number field
611d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        if (TextUtils.isEmpty(contactInfo.name)) {
6121c6bb983216392b5ceb36cea42a46631f68a3dd6Jay Shrauner            return contactInfo.location;
613d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        }
614d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        return contactInfo.number;
615d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    }
6166d231f52e4f00399330d772f2a337283803f3a9dYorke Lee
617e5c0d8bdf8269f9435e0381889e4870f36a43f07Andrew Lee    public void secondaryInfoClicked() {
61880c49a823543c9fb93420d05a6375fb1ff4ca631Yorke Lee        if (mSecondary == null) {
619e5c0d8bdf8269f9435e0381889e4870f36a43f07Andrew Lee            Log.wtf(this, "Secondary info clicked but no secondary call.");
62080c49a823543c9fb93420d05a6375fb1ff4ca631Yorke Lee            return;
62180c49a823543c9fb93420d05a6375fb1ff4ca631Yorke Lee        }
62280c49a823543c9fb93420d05a6375fb1ff4ca631Yorke Lee
623248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal        Log.i(this, "Swapping call to foreground: " + mSecondary);
6248d38cf6761ae048b1a42504f1b59e872cf43df47Ihab Awad        TelecommAdapter.getInstance().unholdCall(mSecondary.getId());
62590995fcb6778a9cb6dc35be12aeb1a5d0dcbb5aeYorke Lee    }
62690995fcb6778a9cb6dc35be12aeb1a5d0dcbb5aeYorke Lee
6277e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee    public void endCallClicked() {
6287e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee        if (mPrimary == null) {
6297e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee            return;
6307e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee        }
6317e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee
632cb2f51bf1acf387f391ca9c8cae8a2344eb2936aEvan Charlton        Log.i(this, "Disconnecting call: " + mPrimary);
6338d38cf6761ae048b1a42504f1b59e872cf43df47Ihab Awad        TelecommAdapter.getInstance().disconnectCall(mPrimary.getId());
6347e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee    }
6357e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee
636da7f422a46db4bfe5cf76312d23b44e60fa9d806Santos Cordon    private String getNumberFromHandle(Uri handle) {
637da7f422a46db4bfe5cf76312d23b44e60fa9d806Santos Cordon        return handle == null ? "" : handle.getSchemeSpecificPart();
638da7f422a46db4bfe5cf76312d23b44e60fa9d806Santos Cordon    }
639da7f422a46db4bfe5cf76312d23b44e60fa9d806Santos Cordon
640350fff554bf7ed5b9e91985935488771156953abTyler Gunn    /**
641350fff554bf7ed5b9e91985935488771156953abTyler Gunn     * Handles a change to the full screen video state.
642350fff554bf7ed5b9e91985935488771156953abTyler Gunn     *
643350fff554bf7ed5b9e91985935488771156953abTyler Gunn     * @param isFullScreenVideo {@code True} if the application is entering full screen video mode.
644350fff554bf7ed5b9e91985935488771156953abTyler Gunn     */
645350fff554bf7ed5b9e91985935488771156953abTyler Gunn    @Override
646350fff554bf7ed5b9e91985935488771156953abTyler Gunn    public void onFullScreenVideoStateChanged(boolean isFullScreenVideo) {
647350fff554bf7ed5b9e91985935488771156953abTyler Gunn        final CallCardUi ui = getUi();
648350fff554bf7ed5b9e91985935488771156953abTyler Gunn        if (ui == null) {
649350fff554bf7ed5b9e91985935488771156953abTyler Gunn            return;
650350fff554bf7ed5b9e91985935488771156953abTyler Gunn        }
651350fff554bf7ed5b9e91985935488771156953abTyler Gunn        ui.setCallCardVisible(!isFullScreenVideo);
652350fff554bf7ed5b9e91985935488771156953abTyler Gunn    }
653350fff554bf7ed5b9e91985935488771156953abTyler Gunn
654d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    public interface CallCardUi extends Ui {
655d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        void setVisible(boolean on);
656350fff554bf7ed5b9e91985935488771156953abTyler Gunn        void setCallCardVisible(boolean visible);
657d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        void setPrimary(String number, String name, boolean nameIsNumber, String label,
658812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon                Drawable photo, boolean isConference, boolean isGeneric, boolean isSipCall);
659c4bacb09c398a615154dc97b066179e77dc57599Yorke Lee        void setSecondary(boolean show, String name, boolean nameIsNumber, String label,
660bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen                String providerLabel, Drawable providerIcon, boolean isConference,
661bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen                boolean isGeneric);
6629c4226952c74f024c09e0bd381048493993c974eAndrew Lee        void setCallState(int state, int videoState, int sessionModificationState, int cause,
6639c4226952c74f024c09e0bd381048493993c974eAndrew Lee                String connectionLabel, Drawable connectionIcon, String gatewayNumber);
6648cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        void setPrimaryCallElapsedTime(boolean show, String duration);
66542373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        void setPrimaryName(String name, boolean nameIsNumber);
66649ff6571403695e81dbbd83e4f61790ce9c75f6dSantos Cordon        void setPrimaryImage(Drawable image);
66742373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        void setPrimaryPhoneNumber(String phoneNumber);
66842373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        void setPrimaryLabel(String label);
669c44f654b992c6ab8a4acff9cb5aa2678c58755d9Andrew Lee        void setEndCallButtonEnabled(boolean enabled, boolean animate);
6700786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton        void setCallbackNumber(String number, boolean isEmergencyCalls);
671804baccc3aeed4ed00d1f0a62ecc37fb5ea6d9fdTyler Gunn        void setPhotoVisible(boolean isVisible);
672350fff554bf7ed5b9e91985935488771156953abTyler Gunn        void setProgressSpinnerVisible(boolean visible);
6731da81ce59cfbebd4e53fdfd2011e859069120de7Andrew Lee        void showManageConferenceCallButton(boolean visible);
674be8060acf5ecbb916c161d3249813098c0611ed5Yorke Lee    }
6754feb57b986dc6b1edc5dc026a926b4934778716dIhab Awad
6764feb57b986dc6b1edc5dc026a926b4934778716dIhab Awad    private TelecommManager getTelecommManager() {
6774feb57b986dc6b1edc5dc026a926b4934778716dIhab Awad        if (mTelecommManager == null) {
678d5b908ee536eb33d80abc4b28110b10d18fe0a8eYorke Lee            mTelecommManager =
679d5b908ee536eb33d80abc4b28110b10d18fe0a8eYorke Lee                    (TelecommManager) mContext.getSystemService(Context.TELECOMM_SERVICE);
6804feb57b986dc6b1edc5dc026a926b4934778716dIhab Awad        }
6814feb57b986dc6b1edc5dc026a926b4934778716dIhab Awad        return mTelecommManager;
6824feb57b986dc6b1edc5dc026a926b4934778716dIhab Awad    }
683c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon}
684