CallCardPresenter.java revision 15b3fb7207bc356b2ee6ce1e8264d8242bb092ec
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
19f925b504266f80ec0b74212c403475f5cc790ab0Evan Charltonimport android.Manifest;
203d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordonimport android.content.Context;
21f925b504266f80ec0b74212c403475f5cc790ab0Evan Charltonimport android.content.Intent;
223d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordonimport android.content.pm.ApplicationInfo;
233d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordonimport android.content.pm.PackageManager;
246d231f52e4f00399330d772f2a337283803f3a9dYorke Leeimport android.graphics.drawable.Drawable;
25da7f422a46db4bfe5cf76312d23b44e60fa9d806Santos Cordonimport android.net.Uri;
260e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charltonimport android.os.Bundle;
2750dbb6eeca55cf78e0fd9eb132a26787d293620aAndrew Leeimport android.telecom.DisconnectCause;
284b293f0f08030c97e1bb54d2f79ac2fb1a6e29aeTyler Gunnimport android.telecom.PhoneCapabilities;
294b293f0f08030c97e1bb54d2f79ac2fb1a6e29aeTyler Gunnimport android.telecom.PhoneAccount;
304b293f0f08030c97e1bb54d2f79ac2fb1a6e29aeTyler Gunnimport android.telecom.PhoneAccountHandle;
314b293f0f08030c97e1bb54d2f79ac2fb1a6e29aeTyler Gunnimport android.telecom.StatusHints;
324b293f0f08030c97e1bb54d2f79ac2fb1a6e29aeTyler Gunnimport android.telecom.TelecomManager;
334b293f0f08030c97e1bb54d2f79ac2fb1a6e29aeTyler Gunnimport android.telecom.VideoProfile;
340e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charltonimport android.telephony.PhoneNumberUtils;
350786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charltonimport android.telephony.TelephonyManager;
36d28fc12696fa706fed70e04698275af7be7fee82Santos Cordonimport android.text.TextUtils;
378cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordonimport android.text.format.DateUtils;
38be8060acf5ecbb916c161d3249813098c0611ed5Yorke Lee
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;
46f925b504266f80ec0b74212c403475f5cc790ab0Evan Charltonimport com.android.incalluibind.ObjectFactory;
475b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee
485b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Leeimport java.lang.ref.WeakReference;
495b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee
5042373eb59cbef15ec61ebb5c919031f293291a53Chiao Chengimport com.google.common.base.Preconditions;
51c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon
52c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon/**
53c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon * Presenter for the Call Card Fragment.
54033ed5926d2924d35b9c82898ab4e835da56b3afChiao Cheng * <p>
557ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon * This class listens for changes to InCallState and passes it along to the fragment.
56c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon */
57d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordonpublic class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
5891a369b019b39c5335a4f5d251691c0cdb657f7dAndrew Lee        implements InCallStateListener, IncomingCallListener, InCallDetailsListener,
599c98346835b8e902e0c2c11f14a35f4e91578e9fAndrew Lee        InCallEventListener {
60be8060acf5ecbb916c161d3249813098c0611ed5Yorke Lee
61033ed5926d2924d35b9c82898ab4e835da56b3afChiao Cheng    private static final String TAG = CallCardPresenter.class.getSimpleName();
629c4226952c74f024c09e0bd381048493993c974eAndrew Lee    private static final long CALL_TIME_UPDATE_INTERVAL_MS = 1000;
638cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon
641b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    private Call mPrimary;
65d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    private Call mSecondary;
66d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    private ContactCacheEntry mPrimaryContactInfo;
67d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    private ContactCacheEntry mSecondaryContactInfo;
6886a7f5639fd0798c3b4500166f97649949237215Andrew Lee    private CallTimer mCallTimer;
693d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    private Context mContext;
704b293f0f08030c97e1bb54d2f79ac2fb1a6e29aeTyler Gunn    private TelecomManager mTelecomManager;
716d231f52e4f00399330d772f2a337283803f3a9dYorke Lee
725b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee    public static class ContactLookupCallback implements ContactInfoCacheCallback {
735b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        private final WeakReference<CallCardPresenter> mCallCardPresenter;
745b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        private final boolean mIsPrimary;
755b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee
765b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        public ContactLookupCallback(CallCardPresenter callCardPresenter, boolean isPrimary) {
775b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            mCallCardPresenter = new WeakReference<CallCardPresenter>(callCardPresenter);
785b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            mIsPrimary = isPrimary;
795b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        }
805b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee
815b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        @Override
825b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        public void onContactInfoComplete(String callId, ContactCacheEntry entry) {
835b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            CallCardPresenter presenter = mCallCardPresenter.get();
845b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            if (presenter != null) {
855b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee                presenter.onContactInfoComplete(callId, entry, mIsPrimary);
865b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            }
875b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        }
885b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee
895b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        @Override
905b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        public void onImageLoadComplete(String callId, ContactCacheEntry entry) {
915b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            CallCardPresenter presenter = mCallCardPresenter.get();
925b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            if (presenter != null) {
935b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee                presenter.onImageLoadComplete(callId, entry);
945b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            }
955b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        }
965b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee
975b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee    }
985b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee
99b8eedb3b9796873eaa22847205239a51092f1a43Santos Cordon    public CallCardPresenter() {
1008cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        // create the call timer
1018cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        mCallTimer = new CallTimer(new Runnable() {
1028cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon            @Override
1038cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon            public void run() {
1048cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon                updateCallTime();
1058cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon            }
1068cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        });
1076d231f52e4f00399330d772f2a337283803f3a9dYorke Lee    }
1086d231f52e4f00399330d772f2a337283803f3a9dYorke Lee
1091c6bb983216392b5ceb36cea42a46631f68a3dd6Jay Shrauner    public void init(Context context, Call call) {
11042373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        mContext = Preconditions.checkNotNull(context);
11142373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
1124a5339c4a266891ce560dfb6e348c3779a0a3ca1Chiao Cheng        // Call may be null if disconnect happened already.
1134a5339c4a266891ce560dfb6e348c3779a0a3ca1Chiao Cheng        if (call != null) {
114656dd4a0d8571b47ecf0ecf3e4c2eeacfd1099b3Chiao Cheng            mPrimary = call;
115656dd4a0d8571b47ecf0ecf3e4c2eeacfd1099b3Chiao Cheng
1164a5339c4a266891ce560dfb6e348c3779a0a3ca1Chiao Cheng            // start processing lookups right away.
117812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            if (!call.isConferenceCall()) {
118248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal                startContactInfoSearch(call, true, call.getState() == Call.State.INCOMING);
119812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            } else {
120017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                updateContactEntry(null, true);
121812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            }
1224a5339c4a266891ce560dfb6e348c3779a0a3ca1Chiao Cheng        }
123033ed5926d2924d35b9c82898ab4e835da56b3afChiao Cheng    }
124033ed5926d2924d35b9c82898ab4e835da56b3afChiao Cheng
125c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon    @Override
126c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon    public void onUiReady(CallCardUi ui) {
127c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon        super.onUiReady(ui);
1281b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon
12942373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        // Contact search may have completed before ui is ready.
13042373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        if (mPrimaryContactInfo != null) {
131017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            updatePrimaryDisplayInfo();
13242373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        }
13342373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
1341f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon        // Register for call state changes last
1351f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon        InCallPresenter.getInstance().addListener(this);
1361c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon        InCallPresenter.getInstance().addIncomingCallListener(this);
1370e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton        InCallPresenter.getInstance().addDetailsListener(this);
138350fff554bf7ed5b9e91985935488771156953abTyler Gunn        InCallPresenter.getInstance().addInCallEventListener(this);
1391b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    }
1401b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon
1411b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    @Override
1421b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    public void onUiUnready(CallCardUi ui) {
1431b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon        super.onUiUnready(ui);
1441b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon
1451f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon        // stop getting call state changes
1461f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon        InCallPresenter.getInstance().removeListener(this);
1471c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon        InCallPresenter.getInstance().removeIncomingCallListener(this);
1480e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton        InCallPresenter.getInstance().removeDetailsListener(this);
149350fff554bf7ed5b9e91985935488771156953abTyler Gunn        InCallPresenter.getInstance().removeInCallEventListener(this);
1501f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon
1511b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon        mPrimary = null;
152d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        mPrimaryContactInfo = null;
153d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        mSecondaryContactInfo = null;
154c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon    }
155c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon
156c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon    @Override
157f003346e5f9ba29e869a881bcca2e59d6ea8e0f6Nancy Chen    public void onIncomingCall(InCallState oldState, InCallState newState, Call call) {
1581c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon        // same logic should happen as with onStateChange()
159f003346e5f9ba29e869a881bcca2e59d6ea8e0f6Nancy Chen        onStateChange(oldState, newState, CallList.getInstance());
1601c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon    }
1611c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon
1621c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon    @Override
163f003346e5f9ba29e869a881bcca2e59d6ea8e0f6Nancy Chen    public void onStateChange(InCallState oldState, InCallState newState, CallList callList) {
164f003346e5f9ba29e869a881bcca2e59d6ea8e0f6Nancy Chen        Log.d(this, "onStateChange() " + newState);
16575c86b55d45b1725c46ed2e5d77c9c43fcfd93daSantos Cordon        final CallCardUi ui = getUi();
1661b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon        if (ui == null) {
1671b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon            return;
1681b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon        }
169c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon
1707ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon        Call primary = null;
1717ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon        Call secondary = null;
1727ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon
173f003346e5f9ba29e869a881bcca2e59d6ea8e0f6Nancy Chen        if (newState == InCallState.INCOMING) {
1747ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon            primary = callList.getIncomingCall();
175f003346e5f9ba29e869a881bcca2e59d6ea8e0f6Nancy Chen        } else if (newState == InCallState.PENDING_OUTGOING || newState == InCallState.OUTGOING) {
176950e3df8ac744daf2a890d279566bdba424710f9Santos Cordon            primary = callList.getOutgoingCall();
177f003346e5f9ba29e869a881bcca2e59d6ea8e0f6Nancy Chen            if (primary == null) {
178f003346e5f9ba29e869a881bcca2e59d6ea8e0f6Nancy Chen                primary = callList.getPendingOutgoingCall();
179f003346e5f9ba29e869a881bcca2e59d6ea8e0f6Nancy Chen            }
180950e3df8ac744daf2a890d279566bdba424710f9Santos Cordon
18182f5d003e675dfd56735c745744c3d968883b23cSantos Cordon            // getCallToDisplay doesn't go through outgoing or incoming calls. It will return the
18282f5d003e675dfd56735c745744c3d968883b23cSantos Cordon            // highest priority call to display as the secondary call.
183d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            secondary = getCallToDisplay(callList, null, true);
184f003346e5f9ba29e869a881bcca2e59d6ea8e0f6Nancy Chen        } else if (newState == InCallState.INCALL) {
185d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            primary = getCallToDisplay(callList, null, false);
186d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            secondary = getCallToDisplay(callList, primary, true);
1877ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon        }
1887ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon
189a4bd83ad639b349fa16dbd07225017fcbf6ed550Chiao Cheng        Log.d(this, "Primary call: " + primary);
190a4bd83ad639b349fa16dbd07225017fcbf6ed550Chiao Cheng        Log.d(this, "Secondary call: " + secondary);
1917ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon
1929c98346835b8e902e0c2c11f14a35f4e91578e9fAndrew Lee        final boolean primaryChanged = !Call.areSame(mPrimary, primary);
1939c98346835b8e902e0c2c11f14a35f4e91578e9fAndrew Lee        final boolean secondaryChanged = !Call.areSame(mSecondary, secondary);
1949c98346835b8e902e0c2c11f14a35f4e91578e9fAndrew Lee
195812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        mSecondary = secondary;
196812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        mPrimary = primary;
197812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon
1980cff18feff43a6915919ac8e32fa44502aa6c320Tyler Gunn        // Refresh primary call information if either:
1990cff18feff43a6915919ac8e32fa44502aa6c320Tyler Gunn        // 1. Primary call changed.
2000cff18feff43a6915919ac8e32fa44502aa6c320Tyler Gunn        // 2. The call's ability to manage conference has changed.
2010cff18feff43a6915919ac8e32fa44502aa6c320Tyler Gunn        if (mPrimary != null && (primaryChanged ||
2020cff18feff43a6915919ac8e32fa44502aa6c320Tyler Gunn                ui.isManageConferenceVisible() != shouldShowManageConference())) {
203812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            // primary call has changed
204248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal            mPrimaryContactInfo = ContactInfoCache.buildCacheEntryFromCall(mContext, mPrimary,
205248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal                    mPrimary.getState() == Call.State.INCOMING);
206017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            updatePrimaryDisplayInfo();
207812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            maybeStartSearch(mPrimary, true);
2089c4226952c74f024c09e0bd381048493993c974eAndrew Lee            mPrimary.setSessionModificationState(Call.SessionModificationState.NO_REQUEST);
20942373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        }
21042373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
211812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        if (mSecondary == null) {
21242373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            // Secondary call may have ended.  Update the ui.
21342373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            mSecondaryContactInfo = null;
214017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            updateSecondaryDisplayInfo();
215812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        } else if (secondaryChanged) {
216812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            // secondary call has changed
217248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal            mSecondaryContactInfo = ContactInfoCache.buildCacheEntryFromCall(mContext, mSecondary,
218248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal                    mSecondary.getState() == Call.State.INCOMING);
219017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            updateSecondaryDisplayInfo();
220812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            maybeStartSearch(mSecondary, false);
2219c4226952c74f024c09e0bd381048493993c974eAndrew Lee            mSecondary.setSessionModificationState(Call.SessionModificationState.NO_REQUEST);
22242373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        }
22342373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
2249c4226952c74f024c09e0bd381048493993c974eAndrew Lee        // Start/stop timers.
2258cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        if (mPrimary != null && mPrimary.getState() == Call.State.ACTIVE) {
226a4bd83ad639b349fa16dbd07225017fcbf6ed550Chiao Cheng            Log.d(this, "Starting the calltime timer");
2279c4226952c74f024c09e0bd381048493993c974eAndrew Lee            mCallTimer.start(CALL_TIME_UPDATE_INTERVAL_MS);
2288cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        } else {
229a4bd83ad639b349fa16dbd07225017fcbf6ed550Chiao Cheng            Log.d(this, "Canceling the calltime timer");
2308cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon            mCallTimer.cancel();
2318cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon            ui.setPrimaryCallElapsedTime(false, null);
2328cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        }
2338cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon
234d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        // Set the call state
2358aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton        int callState = Call.State.IDLE;
236d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        if (mPrimary != null) {
23732027ae1f52232258cc8133d383459f3b4ee57e4Yorke Lee            callState = mPrimary.getState();
238ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal            updatePrimaryCallState();
23982f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        } else {
2409c4226952c74f024c09e0bd381048493993c974eAndrew Lee            getUi().setCallState(
2419c4226952c74f024c09e0bd381048493993c974eAndrew Lee                    callState,
2423718dcb345e77e421ab18a760e48f0c3a760fccaIhab Awad                    VideoProfile.VideoState.AUDIO_ONLY,
2439c4226952c74f024c09e0bd381048493993c974eAndrew Lee                    Call.SessionModificationState.NO_REQUEST,
24450dbb6eeca55cf78e0fd9eb132a26787d293620aAndrew Lee                    new DisconnectCause(DisconnectCause.UNKNOWN),
2459c4226952c74f024c09e0bd381048493993c974eAndrew Lee                    null,
2469c4226952c74f024c09e0bd381048493993c974eAndrew Lee                    null,
2479c4226952c74f024c09e0bd381048493993c974eAndrew Lee                    null);
24882f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        }
249e26b887e90d5e9566a5054a1ccb3ed32ae2eea2dAndrew Lee
250350fff554bf7ed5b9e91985935488771156953abTyler Gunn        // Hide/show the contact photo based on the video state.
251350fff554bf7ed5b9e91985935488771156953abTyler Gunn        // If the primary call is a video call on hold, still show the contact photo.
252350fff554bf7ed5b9e91985935488771156953abTyler Gunn        // If the primary call is an active video call, hide the contact photo.
253804baccc3aeed4ed00d1f0a62ecc37fb5ea6d9fdTyler Gunn        if (mPrimary != null) {
254cda81c2ef1ba595c35ae1d4ad72c44f3443e08fdTyler Gunn            getUi().setPhotoVisible(!(mPrimary.isVideoCall(mContext) &&
255cda81c2ef1ba595c35ae1d4ad72c44f3443e08fdTyler Gunn                    callState != Call.State.ONHOLD));
256804baccc3aeed4ed00d1f0a62ecc37fb5ea6d9fdTyler Gunn        }
257804baccc3aeed4ed00d1f0a62ecc37fb5ea6d9fdTyler Gunn
2581da81ce59cfbebd4e53fdfd2011e859069120de7Andrew Lee        maybeShowManageConferenceCallButton();
2591da81ce59cfbebd4e53fdfd2011e859069120de7Andrew Lee
260f003346e5f9ba29e869a881bcca2e59d6ea8e0f6Nancy Chen        final boolean enableEndCallButton = Call.State.isConnectingOrConnected(callState) &&
2618aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton                callState != Call.State.INCOMING && mPrimary != null;
262c44f654b992c6ab8a4acff9cb5aa2678c58755d9Andrew Lee        // Hide the end call button instantly if we're receiving an incoming call.
263c44f654b992c6ab8a4acff9cb5aa2678c58755d9Andrew Lee        getUi().setEndCallButtonEnabled(
264c44f654b992c6ab8a4acff9cb5aa2678c58755d9Andrew Lee                enableEndCallButton, callState != Call.State.INCOMING /* animate */);
2651b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    }
2661b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon
2671b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    @Override
2684b293f0f08030c97e1bb54d2f79ac2fb1a6e29aeTyler Gunn    public void onDetailsChanged(Call call, android.telecom.Call.Details details) {
269ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal        updatePrimaryCallState();
270e0ec202ff354be3cd3bded7af8fca678dea7fb61Andrew Lee
271e0ec202ff354be3cd3bded7af8fca678dea7fb61Andrew Lee        if (call.can(PhoneCapabilities.MANAGE_CONFERENCE) != PhoneCapabilities.can(
272e0ec202ff354be3cd3bded7af8fca678dea7fb61Andrew Lee                details.getCallCapabilities(), PhoneCapabilities.MANAGE_CONFERENCE)) {
273e0ec202ff354be3cd3bded7af8fca678dea7fb61Andrew Lee            maybeShowManageConferenceCallButton();
274e0ec202ff354be3cd3bded7af8fca678dea7fb61Andrew Lee        }
2750786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton    }
2760786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton
2770786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton    private String getSubscriptionNumber() {
2780786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton        // If it's an emergency call, and they're not populating the callback number,
2790786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton        // then try to fall back to the phone sub info (to hopefully get the SIM's
2800786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton        // number directly from the telephony layer).
28176e1b4bfb2e21300068f10cc94922214e62c8f86Evan Charlton        PhoneAccountHandle accountHandle = mPrimary.getAccountHandle();
28276e1b4bfb2e21300068f10cc94922214e62c8f86Evan Charlton        if (accountHandle != null) {
2834b293f0f08030c97e1bb54d2f79ac2fb1a6e29aeTyler Gunn            TelecomManager mgr =
2844b293f0f08030c97e1bb54d2f79ac2fb1a6e29aeTyler Gunn                    (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
285b6f45c2768f5af916ee3257542a3ab03611c1f5eEvan Charlton            PhoneAccount account = mgr.getPhoneAccount(accountHandle);
286b6f45c2768f5af916ee3257542a3ab03611c1f5eEvan Charlton            if (account != null) {
2879e27dca4bc1be09bcb1d283b2fe3ba3d49f0748bAndrew Lee                return getNumberFromHandle(account.getSubscriptionAddress());
288c108b49ad5440fbf381c9a589d8a217da3efcb64Ihab Awad            }
2890e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton        }
2900786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton        return null;
2910e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton    }
2920e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton
293ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal    private void updatePrimaryCallState() {
294ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal        if (getUi() != null && mPrimary != null) {
295ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal            getUi().setCallState(
296ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal                    mPrimary.getState(),
297ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal                    mPrimary.getVideoState(),
298ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal                    mPrimary.getSessionModificationState(),
299ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal                    mPrimary.getDisconnectCause(),
300ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal                    getConnectionLabel(),
301ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal                    getConnectionIcon(),
302ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal                    getGatewayNumber());
303ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal            setCallbackNumber();
304ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal        }
305ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal    }
3060786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton
3071da81ce59cfbebd4e53fdfd2011e859069120de7Andrew Lee    /**
308289d53ed1c879e983dcb021fa677212ab4566bbdSantos Cordon     * Only show the conference call button if we can manage the conference.
3091da81ce59cfbebd4e53fdfd2011e859069120de7Andrew Lee     */
3101da81ce59cfbebd4e53fdfd2011e859069120de7Andrew Lee    private void maybeShowManageConferenceCallButton() {
3110cff18feff43a6915919ac8e32fa44502aa6c320Tyler Gunn        getUi().showManageConferenceCallButton(shouldShowManageConference());
3120cff18feff43a6915919ac8e32fa44502aa6c320Tyler Gunn    }
3130cff18feff43a6915919ac8e32fa44502aa6c320Tyler Gunn
3140cff18feff43a6915919ac8e32fa44502aa6c320Tyler Gunn    /**
3150cff18feff43a6915919ac8e32fa44502aa6c320Tyler Gunn     * Determines if the manage conference button should be visible, based on the current primary
3160cff18feff43a6915919ac8e32fa44502aa6c320Tyler Gunn     * call.
3170cff18feff43a6915919ac8e32fa44502aa6c320Tyler Gunn     *
3180cff18feff43a6915919ac8e32fa44502aa6c320Tyler Gunn     * @return {@code True} if the manage conference button should be visible.
3190cff18feff43a6915919ac8e32fa44502aa6c320Tyler Gunn     */
3200cff18feff43a6915919ac8e32fa44502aa6c320Tyler Gunn    private boolean shouldShowManageConference() {
321e16e53167b367656840df665457e71e66bc966deAndrew Lee        if (mPrimary == null) {
3220cff18feff43a6915919ac8e32fa44502aa6c320Tyler Gunn            return false;
323e16e53167b367656840df665457e71e66bc966deAndrew Lee        }
324e16e53167b367656840df665457e71e66bc966deAndrew Lee
3250cff18feff43a6915919ac8e32fa44502aa6c320Tyler Gunn        return mPrimary.can(PhoneCapabilities.MANAGE_CONFERENCE);
3261da81ce59cfbebd4e53fdfd2011e859069120de7Andrew Lee    }
3271da81ce59cfbebd4e53fdfd2011e859069120de7Andrew Lee
328ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal    private void setCallbackNumber() {
329ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal        String callbackNumber = null;
3300786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton
331ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal        boolean isEmergencyCall = PhoneNumberUtils.isEmergencyNumber(
332ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal                getNumberFromHandle(mPrimary.getHandle()));
333ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal        if (isEmergencyCall) {
334ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal            callbackNumber = getSubscriptionNumber();
335ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal        } else {
336ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal            StatusHints statusHints = mPrimary.getTelecommCall().getDetails().getStatusHints();
337ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal            if (statusHints != null) {
338ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal                Bundle extras = statusHints.getExtras();
339ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal                if (extras != null) {
3404b293f0f08030c97e1bb54d2f79ac2fb1a6e29aeTyler Gunn                    callbackNumber = extras.getString(TelecomManager.EXTRA_CALL_BACK_NUMBER);
3410786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton                }
3420e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton            }
3430786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton        }
3440786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton
345ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal        TelephonyManager telephonyManager =
346d5b908ee536eb33d80abc4b28110b10d18fe0a8eYorke Lee                (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
347d5b908ee536eb33d80abc4b28110b10d18fe0a8eYorke Lee        String simNumber = telephonyManager.getLine1Number();
348ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal        if (PhoneNumberUtils.compare(callbackNumber, simNumber)) {
3490786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton            Log.d(this, "Numbers are the same; not showing the callback number");
350ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal            callbackNumber = null;
3510786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton        }
352ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal
3530786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton        getUi().setCallbackNumber(callbackNumber, isEmergencyCall);
3540e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton    }
3550e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton
3568cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon    public void updateCallTime() {
3578cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        final CallCardUi ui = getUi();
3588cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon
3598cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        if (ui == null || mPrimary == null || mPrimary.getState() != Call.State.ACTIVE) {
360899251968ee4ee3cb375032185653ecd888e3f8dSantos Cordon            if (ui != null) {
361899251968ee4ee3cb375032185653ecd888e3f8dSantos Cordon                ui.setPrimaryCallElapsedTime(false, null);
362899251968ee4ee3cb375032185653ecd888e3f8dSantos Cordon            }
3638cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon            mCallTimer.cancel();
364899251968ee4ee3cb375032185653ecd888e3f8dSantos Cordon        } else {
365c6f4e50a4130fb8f7247f5eab6849829701ad484Sailesh Nepal            final long callStart = mPrimary.getConnectTimeMillis();
366899251968ee4ee3cb375032185653ecd888e3f8dSantos Cordon            final long duration = System.currentTimeMillis() - callStart;
367899251968ee4ee3cb375032185653ecd888e3f8dSantos Cordon            ui.setPrimaryCallElapsedTime(true, DateUtils.formatElapsedTime(duration / 1000));
3688cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        }
3698cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon    }
3708cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon
371f925b504266f80ec0b74212c403475f5cc790ab0Evan Charlton    public void onCallStateButtonTouched() {
37271afa1c7d1e1f49af56c24bdc64d30d80cf1ea68Evan Charlton        Intent broadcastIntent = ObjectFactory.getCallStateButtonBroadcastIntent(mContext);
373f925b504266f80ec0b74212c403475f5cc790ab0Evan Charlton        if (broadcastIntent != null) {
374f925b504266f80ec0b74212c403475f5cc790ab0Evan Charlton            Log.d(this, "Sending call state button broadcast: ", broadcastIntent);
375f925b504266f80ec0b74212c403475f5cc790ab0Evan Charlton            mContext.sendBroadcast(broadcastIntent, Manifest.permission.READ_PHONE_STATE);
376f925b504266f80ec0b74212c403475f5cc790ab0Evan Charlton        }
377f925b504266f80ec0b74212c403475f5cc790ab0Evan Charlton    }
378f925b504266f80ec0b74212c403475f5cc790ab0Evan Charlton
379812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon    private void maybeStartSearch(Call call, boolean isPrimary) {
380812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        // no need to start search for conference calls which show generic info.
381812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        if (call != null && !call.isConferenceCall()) {
382248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal            startContactInfoSearch(call, isPrimary, call.getState() == Call.State.INCOMING);
383812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        }
384812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon    }
385812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon
38682f5d003e675dfd56735c745744c3d968883b23cSantos Cordon    /**
387d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon     * Starts a query for more contact data for the save primary and secondary calls.
388d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon     */
389248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal    private void startContactInfoSearch(final Call call, final boolean isPrimary,
390248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal            boolean isIncoming) {
39142373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        final ContactInfoCache cache = ContactInfoCache.getInstance(mContext);
39242373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
3935b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        cache.findInfo(call, isIncoming, new ContactLookupCallback(this, isPrimary));
3945b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee    }
3957d2fb8620b808c28c49bde99dc54f6de46fdcb44Chiao Cheng
3965b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee    private void onContactInfoComplete(String callId, ContactCacheEntry entry, boolean isPrimary) {
397017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        updateContactEntry(entry, isPrimary);
3985b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        if (entry.name != null) {
3995b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            Log.d(TAG, "Contact found: " + entry);
4005b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        }
4015b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        if (entry.contactUri != null) {
4025b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            CallerInfoUtils.sendViewNotification(mContext, entry.contactUri);
4035b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        }
4045b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee    }
4055b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee
4065b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee    private void onImageLoadComplete(String callId, ContactCacheEntry entry) {
4075b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        if (getUi() == null) {
4085b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            return;
4095b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        }
410f003346e5f9ba29e869a881bcca2e59d6ea8e0f6Nancy Chen
4115b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        if (entry.photo != null) {
4125b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            if (mPrimary != null && callId.equals(mPrimary.getId())) {
4135b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee                getUi().setPrimaryImage(entry.photo);
4145b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            }
4155b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        }
41642373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng    }
41742373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
418017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee    private void updateContactEntry(ContactCacheEntry entry, boolean isPrimary) {
41942373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        if (isPrimary) {
42042373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            mPrimaryContactInfo = entry;
421017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            updatePrimaryDisplayInfo();
422d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        } else {
42342373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            mSecondaryContactInfo = entry;
424017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            updateSecondaryDisplayInfo();
425d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        }
426d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    }
427d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon
428d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    /**
42982f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     * Get the highest priority call to display.
43082f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     * Goes through the calls and chooses which to return based on priority of which type of call
43182f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     * to display to the user. Callers can use the "ignore" feature to get the second best call
43282f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     * by passing a previously found primary call as ignore.
43382f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     *
43482f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     * @param ignore A call to ignore if found.
43582f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     */
436d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    private Call getCallToDisplay(CallList callList, Call ignore, boolean skipDisconnected) {
43782f5d003e675dfd56735c745744c3d968883b23cSantos Cordon
438d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        // Active calls come second.  An active call always gets precedent.
439d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        Call retval = callList.getActiveCall();
44082f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        if (retval != null && retval != ignore) {
44182f5d003e675dfd56735c745744c3d968883b23cSantos Cordon            return retval;
44282f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        }
44382f5d003e675dfd56735c745744c3d968883b23cSantos Cordon
444d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        // Disconnected calls get primary position if there are no active calls
445d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        // to let user know quickly what call has disconnected. Disconnected
446d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        // calls are very short lived.
447d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        if (!skipDisconnected) {
4486258ff60a7edc760facc3f387fc9c8ceee3fb518Christine Chen            retval = callList.getDisconnectingCall();
4496258ff60a7edc760facc3f387fc9c8ceee3fb518Christine Chen            if (retval != null && retval != ignore) {
4506258ff60a7edc760facc3f387fc9c8ceee3fb518Christine Chen                return retval;
4516258ff60a7edc760facc3f387fc9c8ceee3fb518Christine Chen            }
452d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            retval = callList.getDisconnectedCall();
453d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            if (retval != null && retval != ignore) {
454d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon                return retval;
455d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            }
45682f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        }
45782f5d003e675dfd56735c745744c3d968883b23cSantos Cordon
45882f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        // Then we go to background call (calls on hold)
45982f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        retval = callList.getBackgroundCall();
46082f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        if (retval != null && retval != ignore) {
46182f5d003e675dfd56735c745744c3d968883b23cSantos Cordon            return retval;
46282f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        }
46382f5d003e675dfd56735c745744c3d968883b23cSantos Cordon
46482f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        // Lastly, we go to a second background call.
46582f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        retval = callList.getSecondBackgroundCall();
46682f5d003e675dfd56735c745744c3d968883b23cSantos Cordon
46782f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        return retval;
46882f5d003e675dfd56735c745744c3d968883b23cSantos Cordon    }
46982f5d003e675dfd56735c745744c3d968883b23cSantos Cordon
470017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee    private void updatePrimaryDisplayInfo() {
4716d231f52e4f00399330d772f2a337283803f3a9dYorke Lee        final CallCardUi ui = getUi();
472d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        if (ui == null) {
47342373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            // TODO: May also occur if search result comes back after ui is destroyed. Look into
47442373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            // removing that case completely.
47542373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            Log.d(TAG, "updatePrimaryDisplayInfo called but ui is null!");
476d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon            return;
4776d231f52e4f00399330d772f2a337283803f3a9dYorke Lee        }
478be8060acf5ecbb916c161d3249813098c0611ed5Yorke Lee
479017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        if (mPrimary == null) {
480017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            // Clear the primary display info.
481017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            ui.setPrimary(null, null, false, null, null, false);
482017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            return;
483017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        }
484017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee
485017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        if (mPrimary.isConferenceCall()) {
486017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            Log.d(TAG, "Update primary display info for conference call.");
487017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee
488017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            ui.setPrimary(
489017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    null /* number */,
490017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    getConferenceString(mPrimary),
491017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    false /* nameIsNumber */,
492017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    null /* label */,
493017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    getConferencePhoto(mPrimary),
494017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    false /* isSipCall */);
495017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        } else if (mPrimaryContactInfo != null) {
496017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            Log.d(TAG, "Update primary display info for " + mPrimaryContactInfo);
497017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee
498017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            String name = getNameForCall(mPrimaryContactInfo);
499017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            String number = getNumberForCall(mPrimaryContactInfo);
500017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            boolean nameIsNumber = name != null && name.equals(mPrimaryContactInfo.number);
501017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            ui.setPrimary(
502017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    number,
503017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    name,
504017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    nameIsNumber,
505017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    mPrimaryContactInfo.label,
506017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    mPrimaryContactInfo.photo,
507017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    mPrimaryContactInfo.isSipCall);
5086d231f52e4f00399330d772f2a337283803f3a9dYorke Lee        } else {
509017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            // Clear the primary display info.
510017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            ui.setPrimary(null, null, false, null, null, false);
511d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        }
512d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon
513d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    }
514d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon
515017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee    private void updateSecondaryDisplayInfo() {
51642373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        final CallCardUi ui = getUi();
51742373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        if (ui == null) {
51842373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            return;
51942373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        }
52042373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
521017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        if (mSecondary == null) {
522017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            // Clear the secondary display info.
523017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            ui.setSecondary(false, null, false, null, null, false /* isConference */);
524017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            return;
525017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        }
526c4bacb09c398a615154dc97b066179e77dc57599Yorke Lee
527017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        if (mSecondary.isConferenceCall()) {
528017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            ui.setSecondary(
529017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    true /* show */,
530017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    getConferenceString(mSecondary),
531017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    false /* nameIsNumber */,
532017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    null /* label */,
533017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    getCallProviderLabel(mSecondary),
534017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    true /* isConference */);
535017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        } else if (mSecondaryContactInfo != null) {
536017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            Log.d(TAG, "updateSecondaryDisplayInfo() " + mSecondaryContactInfo);
537017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            String name = getNameForCall(mSecondaryContactInfo);
538017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            boolean nameIsNumber = name != null && name.equals(mSecondaryContactInfo.number);
539017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            ui.setSecondary(
540017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    true /* show */,
541017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    name,
542017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    nameIsNumber,
543017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    mSecondaryContactInfo.label,
544017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    getCallProviderLabel(mSecondary),
545017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    false /* isConference */);
54642373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        } else {
547017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            // Clear the secondary display info.
548017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            ui.setSecondary(false, null, false, null, null, false /* isConference */);
54942373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        }
55042373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng    }
55142373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
5528a80413884d1afbd7e021d581546c2245f068619Nancy Chen
5538a80413884d1afbd7e021d581546c2245f068619Nancy Chen    /**
5548a80413884d1afbd7e021d581546c2245f068619Nancy Chen     * Gets the phone account to display for a call.
5558a80413884d1afbd7e021d581546c2245f068619Nancy Chen     */
5568a80413884d1afbd7e021d581546c2245f068619Nancy Chen    private PhoneAccount getAccountForCall(Call call) {
5578a80413884d1afbd7e021d581546c2245f068619Nancy Chen        PhoneAccountHandle accountHandle = call.getAccountHandle();
5588a80413884d1afbd7e021d581546c2245f068619Nancy Chen        if (accountHandle == null) {
5598a80413884d1afbd7e021d581546c2245f068619Nancy Chen            return null;
5608a80413884d1afbd7e021d581546c2245f068619Nancy Chen        }
5614b293f0f08030c97e1bb54d2f79ac2fb1a6e29aeTyler Gunn        return getTelecomManager().getPhoneAccount(accountHandle);
5628a80413884d1afbd7e021d581546c2245f068619Nancy Chen    }
5638a80413884d1afbd7e021d581546c2245f068619Nancy Chen
5643d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    /**
5653d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon     * Returns the gateway number for any existing outgoing call.
5663d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon     */
5673d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    private String getGatewayNumber() {
5683d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        if (hasOutgoingGatewayCall()) {
56907fd3fd3ac627faf1771ba4699fe53a0479f2293Nancy Chen            return getNumberFromHandle(mPrimary.getGatewayInfo().getGatewayAddress());
5703d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        }
5713d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        return null;
5723d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    }
5733d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon
5743d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    /**
5758a80413884d1afbd7e021d581546c2245f068619Nancy Chen     * Return the string label to represent the call provider
5768a80413884d1afbd7e021d581546c2245f068619Nancy Chen     */
5778a80413884d1afbd7e021d581546c2245f068619Nancy Chen    private String getCallProviderLabel(Call call) {
5788a80413884d1afbd7e021d581546c2245f068619Nancy Chen        PhoneAccount account = getAccountForCall(call);
57915b3fb7207bc356b2ee6ce1e8264d8242bb092ecJay Shrauner        if (account != null && !TextUtils.isEmpty(account.getLabel())
58015b3fb7207bc356b2ee6ce1e8264d8242bb092ecJay Shrauner                && getTelecomManager().hasMultipleCallCapableAccounts()) {
5818a80413884d1afbd7e021d581546c2245f068619Nancy Chen            return account.getLabel().toString();
582bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen        }
583bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen        return null;
584bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen    }
585bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen
586bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen    /**
587bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen     * Returns the label (line of text above the number/name) for any given call.
588f8b0677bed382046cb26e38a8442a9509d1e835cSailesh Nepal     * For example, "calling via [Account/Google Voice]" for outgoing calls.
5893d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon     */
590bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen    private String getConnectionLabel() {
591ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal        StatusHints statusHints = mPrimary.getTelecommCall().getDetails().getStatusHints();
592ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal        if (statusHints != null && !TextUtils.isEmpty(statusHints.getLabel())) {
593ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal            return statusHints.getLabel().toString();
594ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal        }
595ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal
5963d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        if (hasOutgoingGatewayCall() && getUi() != null) {
597bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen            // Return the label for the gateway app on outgoing calls.
5983d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon            final PackageManager pm = mContext.getPackageManager();
5993d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon            try {
600ae73c9aab1c716d9ef85f4f0dbc6f69e97a8f7e6Sailesh Nepal                ApplicationInfo info = pm.getApplicationInfo(
601ae73c9aab1c716d9ef85f4f0dbc6f69e97a8f7e6Sailesh Nepal                        mPrimary.getGatewayInfo().getGatewayProviderPackageName(), 0);
602bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen                return pm.getApplicationLabel(info).toString();
6033d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon            } catch (PackageManager.NameNotFoundException e) {
604bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen                Log.e(this, "Gateway Application Not Found.", e);
605bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen                return null;
6063d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon            }
6073d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        }
6088a80413884d1afbd7e021d581546c2245f068619Nancy Chen        return getCallProviderLabel(mPrimary);
6093d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    }
6103d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon
611ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal    private Drawable getConnectionIcon() {
612ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal        StatusHints statusHints = mPrimary.getTelecommCall().getDetails().getStatusHints();
6133718dcb345e77e421ab18a760e48f0c3a760fccaIhab Awad        if (statusHints != null && statusHints.getIconResId() != 0) {
614ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal            Drawable icon = statusHints.getIcon(mContext);
615ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal            if (icon != null) {
616ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal                return icon;
617ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal            }
618ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal        }
619ab86f04c5ed385eafcd9099fa4ca50fd2f4c5c33Nancy Chen        return null;
620ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal    }
621ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal
6223d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    private boolean hasOutgoingGatewayCall() {
6233718dcb345e77e421ab18a760e48f0c3a760fccaIhab Awad        // We only display the gateway information while STATE_DIALING so return false for any othe
6243d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        // call state.
62542373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        // TODO: mPrimary can be null because this is called from updatePrimaryDisplayInfo which
62642373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        // is also called after a contact search completes (call is not present yet).  Split the
62742373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        // UI update so it can receive independent updates.
62842373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        if (mPrimary == null) {
62942373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            return false;
63042373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        }
631ae73c9aab1c716d9ef85f4f0dbc6f69e97a8f7e6Sailesh Nepal        return Call.State.isDialing(mPrimary.getState()) && mPrimary.getGatewayInfo() != null &&
632ae73c9aab1c716d9ef85f4f0dbc6f69e97a8f7e6Sailesh Nepal                !mPrimary.getGatewayInfo().isEmpty();
6333d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    }
6343d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon
635d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    /**
636d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon     * Gets the name to display for the call.
637d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon     */
638d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    private static String getNameForCall(ContactCacheEntry contactInfo) {
639d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        if (TextUtils.isEmpty(contactInfo.name)) {
640d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            return contactInfo.number;
6416d231f52e4f00399330d772f2a337283803f3a9dYorke Lee        }
642d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        return contactInfo.name;
643d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    }
6446d231f52e4f00399330d772f2a337283803f3a9dYorke Lee
645d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    /**
646d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon     * Gets the number to display for a call.
647d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon     */
648d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    private static String getNumberForCall(ContactCacheEntry contactInfo) {
649d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        // If the name is empty, we use the number for the name...so dont show a second
650d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        // number in the number field
651d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        if (TextUtils.isEmpty(contactInfo.name)) {
6521c6bb983216392b5ceb36cea42a46631f68a3dd6Jay Shrauner            return contactInfo.location;
653d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        }
654d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        return contactInfo.number;
655d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    }
6566d231f52e4f00399330d772f2a337283803f3a9dYorke Lee
657e5c0d8bdf8269f9435e0381889e4870f36a43f07Andrew Lee    public void secondaryInfoClicked() {
65880c49a823543c9fb93420d05a6375fb1ff4ca631Yorke Lee        if (mSecondary == null) {
659e5c0d8bdf8269f9435e0381889e4870f36a43f07Andrew Lee            Log.wtf(this, "Secondary info clicked but no secondary call.");
66080c49a823543c9fb93420d05a6375fb1ff4ca631Yorke Lee            return;
66180c49a823543c9fb93420d05a6375fb1ff4ca631Yorke Lee        }
66280c49a823543c9fb93420d05a6375fb1ff4ca631Yorke Lee
663248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal        Log.i(this, "Swapping call to foreground: " + mSecondary);
6644b293f0f08030c97e1bb54d2f79ac2fb1a6e29aeTyler Gunn        TelecomAdapter.getInstance().unholdCall(mSecondary.getId());
66590995fcb6778a9cb6dc35be12aeb1a5d0dcbb5aeYorke Lee    }
66690995fcb6778a9cb6dc35be12aeb1a5d0dcbb5aeYorke Lee
6677e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee    public void endCallClicked() {
6687e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee        if (mPrimary == null) {
6697e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee            return;
6707e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee        }
6717e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee
672cb2f51bf1acf387f391ca9c8cae8a2344eb2936aEvan Charlton        Log.i(this, "Disconnecting call: " + mPrimary);
67333478eae2d380adfcc7ef3f51816ff391a42ebb7Ihab Awad        mPrimary.setState(Call.State.DISCONNECTING);
67433478eae2d380adfcc7ef3f51816ff391a42ebb7Ihab Awad        CallList.getInstance().onUpdate(mPrimary);
6754b293f0f08030c97e1bb54d2f79ac2fb1a6e29aeTyler Gunn        TelecomAdapter.getInstance().disconnectCall(mPrimary.getId());
6767e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee    }
6777e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee
678da7f422a46db4bfe5cf76312d23b44e60fa9d806Santos Cordon    private String getNumberFromHandle(Uri handle) {
679da7f422a46db4bfe5cf76312d23b44e60fa9d806Santos Cordon        return handle == null ? "" : handle.getSchemeSpecificPart();
680da7f422a46db4bfe5cf76312d23b44e60fa9d806Santos Cordon    }
681da7f422a46db4bfe5cf76312d23b44e60fa9d806Santos Cordon
682350fff554bf7ed5b9e91985935488771156953abTyler Gunn    /**
683350fff554bf7ed5b9e91985935488771156953abTyler Gunn     * Handles a change to the full screen video state.
684350fff554bf7ed5b9e91985935488771156953abTyler Gunn     *
685350fff554bf7ed5b9e91985935488771156953abTyler Gunn     * @param isFullScreenVideo {@code True} if the application is entering full screen video mode.
686350fff554bf7ed5b9e91985935488771156953abTyler Gunn     */
687350fff554bf7ed5b9e91985935488771156953abTyler Gunn    @Override
688350fff554bf7ed5b9e91985935488771156953abTyler Gunn    public void onFullScreenVideoStateChanged(boolean isFullScreenVideo) {
689350fff554bf7ed5b9e91985935488771156953abTyler Gunn        final CallCardUi ui = getUi();
690350fff554bf7ed5b9e91985935488771156953abTyler Gunn        if (ui == null) {
691350fff554bf7ed5b9e91985935488771156953abTyler Gunn            return;
692350fff554bf7ed5b9e91985935488771156953abTyler Gunn        }
693350fff554bf7ed5b9e91985935488771156953abTyler Gunn        ui.setCallCardVisible(!isFullScreenVideo);
694350fff554bf7ed5b9e91985935488771156953abTyler Gunn    }
695350fff554bf7ed5b9e91985935488771156953abTyler Gunn
696017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee    private TelecomManager getTelecomManager() {
697017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        if (mTelecomManager == null) {
698017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            mTelecomManager =
699017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
700017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        }
701017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        return mTelecomManager;
702017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee    }
703017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee
704017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee    private String getConferenceString(Call call) {
705017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        boolean isGenericConference = call.can(PhoneCapabilities.GENERIC_CONFERENCE);
706017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        Log.v(this, "getConferenceString: " + isGenericConference);
707017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee
708017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        final int resId = isGenericConference
709017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                ? R.string.card_title_in_call : R.string.card_title_conf_call;
710017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        return mContext.getResources().getString(resId);
711017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee    }
712017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee
713017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee    private Drawable getConferencePhoto(Call call) {
714017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        boolean isGenericConference = call.can(PhoneCapabilities.GENERIC_CONFERENCE);
715017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        Log.v(this, "getConferencePhoto: " + isGenericConference);
716017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee
717017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        final int resId = isGenericConference
718017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                ? R.drawable.img_phone : R.drawable.img_conference;
719017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        Drawable photo = mContext.getResources().getDrawable(resId);
720017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        photo.setAutoMirrored(true);
721017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        return photo;
722017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee    }
723017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee
724d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    public interface CallCardUi extends Ui {
725d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        void setVisible(boolean on);
726350fff554bf7ed5b9e91985935488771156953abTyler Gunn        void setCallCardVisible(boolean visible);
727d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        void setPrimary(String number, String name, boolean nameIsNumber, String label,
728017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                Drawable photo, boolean isSipCall);
729c4bacb09c398a615154dc97b066179e77dc57599Yorke Lee        void setSecondary(boolean show, String name, boolean nameIsNumber, String label,
730017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                String providerLabel, boolean isConference);
73150dbb6eeca55cf78e0fd9eb132a26787d293620aAndrew Lee        void setCallState(int state, int videoState, int sessionModificationState,
73250dbb6eeca55cf78e0fd9eb132a26787d293620aAndrew Lee                DisconnectCause disconnectCause, String connectionLabel,
73350dbb6eeca55cf78e0fd9eb132a26787d293620aAndrew Lee                Drawable connectionIcon, String gatewayNumber);
7348cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        void setPrimaryCallElapsedTime(boolean show, String duration);
73542373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        void setPrimaryName(String name, boolean nameIsNumber);
73649ff6571403695e81dbbd83e4f61790ce9c75f6dSantos Cordon        void setPrimaryImage(Drawable image);
73742373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        void setPrimaryPhoneNumber(String phoneNumber);
73842373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        void setPrimaryLabel(String label);
739c44f654b992c6ab8a4acff9cb5aa2678c58755d9Andrew Lee        void setEndCallButtonEnabled(boolean enabled, boolean animate);
7400786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton        void setCallbackNumber(String number, boolean isEmergencyCalls);
741804baccc3aeed4ed00d1f0a62ecc37fb5ea6d9fdTyler Gunn        void setPhotoVisible(boolean isVisible);
742350fff554bf7ed5b9e91985935488771156953abTyler Gunn        void setProgressSpinnerVisible(boolean visible);
7431da81ce59cfbebd4e53fdfd2011e859069120de7Andrew Lee        void showManageConferenceCallButton(boolean visible);
7440cff18feff43a6915919ac8e32fa44502aa6c320Tyler Gunn        boolean isManageConferenceVisible();
745be8060acf5ecbb916c161d3249813098c0611ed5Yorke Lee    }
746c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon}
747