CallCardPresenter.java revision 8e303d6ad3f2a0e99b1d0674b9cf91565511f066
1a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon/*
2a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon * Copyright (C) 2013 The Android Open Source Project
3a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon *
4a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon * Licensed under the Apache License, Version 2.0 (the "License");
5a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon * you may not use this file except in compliance with the License.
6a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon * You may obtain a copy of the License at
7a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon *
8a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon *      http://www.apache.org/licenses/LICENSE-2.0
9a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon *
10a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon * Unless required by applicable law or agreed to in writing, software
11a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon * distributed under the License is distributed on an "AS IS" BASIS,
12a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon * See the License for the specific language governing permissions and
14a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon * limitations under the License
15a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon */
16a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon
17a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordonpackage com.android.incallui;
18a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon
193d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordonimport android.content.Context;
203d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordonimport android.content.pm.ApplicationInfo;
213d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordonimport android.content.pm.PackageManager;
22988d06b64b99a13f4f060dc82594edcb738d9113Yorke Leeimport android.graphics.drawable.Drawable;
231fa0782281ef7774ddcdfdf8efb7d8f65cf589e7Chiao Chengimport android.graphics.Bitmap;
240be676b7151d87f4d4d5244a859b14cb12621bf3Chiao Chengimport android.net.wifi.WifiInfo;
250be676b7151d87f4d4d5244a859b14cb12621bf3Chiao Chengimport android.net.wifi.WifiManager;
26b48e2280930b5ed0b04dd34d59dc5980b379a475Sailesh Nepalimport android.telecomm.CallCapabilities;
27a481914300fbe10a76635242eb778e1976947065Sailesh Nepalimport android.telecomm.CallServiceDescriptor;
28a81667248196be225849f7739f64752dc578f6bbAnders Kristensenimport android.telephony.DisconnectCause;
294be1bdd9ee8e9d3afa1aaa765e86b963fb6c7b3dYorke Leeimport android.telephony.PhoneNumberUtils;
301df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordonimport android.text.TextUtils;
3188dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordonimport android.text.format.DateUtils;
327ef707319c0e3563ff92a772ba53cb5dca0e3ae1Yorke Lee
33b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordonimport com.android.incallui.AudioModeProvider.AudioModeListener;
344bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordonimport com.android.incallui.ContactInfoCache.ContactCacheEntry;
354bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordonimport com.android.incallui.ContactInfoCache.ContactInfoCacheCallback;
36671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordonimport com.android.incallui.InCallPresenter.InCallState;
37671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordonimport com.android.incallui.InCallPresenter.InCallStateListener;
381ee82fcea79556c90eec0f55ea2e2ab5c6dfaddaSantos Cordonimport com.android.incallui.InCallPresenter.IncomingCallListener;
39b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordonimport com.android.services.telephony.common.AudioMode;
408b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Chengimport com.google.common.base.Preconditions;
41a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon
42a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon/**
43a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon * Presenter for the Call Card Fragment.
441fa0782281ef7774ddcdfdf8efb7d8f65cf589e7Chiao Cheng * <p>
45671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon * This class listens for changes to InCallState and passes it along to the fragment.
46a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon */
474bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordonpublic class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
481ee82fcea79556c90eec0f55ea2e2ab5c6dfaddaSantos Cordon        implements InCallStateListener, AudioModeListener, IncomingCallListener {
497ef707319c0e3563ff92a772ba53cb5dca0e3ae1Yorke Lee
501fa0782281ef7774ddcdfdf8efb7d8f65cf589e7Chiao Cheng    private static final String TAG = CallCardPresenter.class.getSimpleName();
5188dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon    private static final long CALL_TIME_UPDATE_INTERVAL = 1000; // in milliseconds
5288dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon
53b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon    private Call mPrimary;
544bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon    private Call mSecondary;
554bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon    private ContactCacheEntry mPrimaryContactInfo;
564bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon    private ContactCacheEntry mSecondaryContactInfo;
5788dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon    private CallTimer mCallTimer;
583d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon    private Context mContext;
59988d06b64b99a13f4f060dc82594edcb738d9113Yorke Lee
601771e5a1295eac5ad0d59fe2ff750ab450eab90eSailesh Nepal    private boolean mIsWiFiCachedValue;
61988d06b64b99a13f4f060dc82594edcb738d9113Yorke Lee
629de3d7c5188c02cabf03799f87d494ee7dc702cbSantos Cordon    public CallCardPresenter() {
6388dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon        // create the call timer
6488dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon        mCallTimer = new CallTimer(new Runnable() {
6588dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon            @Override
6688dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon            public void run() {
6788dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon                updateCallTime();
6888dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon            }
6988dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon        });
70988d06b64b99a13f4f060dc82594edcb738d9113Yorke Lee    }
71988d06b64b99a13f4f060dc82594edcb738d9113Yorke Lee
728b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng
73101bed44998ff35c3a56f431345fac5c8229ec0eJay Shrauner    public void init(Context context, Call call) {
748b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        mContext = Preconditions.checkNotNull(context);
758b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng
76bf62e69f8f029b616726577df7aa100c0900d6e5Chiao Cheng        // Call may be null if disconnect happened already.
77bf62e69f8f029b616726577df7aa100c0900d6e5Chiao Cheng        if (call != null) {
7841457dce3ca531178ca07946868afb0cc1579a6bChiao Cheng            mPrimary = call;
7941457dce3ca531178ca07946868afb0cc1579a6bChiao Cheng
80bf62e69f8f029b616726577df7aa100c0900d6e5Chiao Cheng            // start processing lookups right away.
81625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon            if (!call.isConferenceCall()) {
82fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal                startContactInfoSearch(call, true, call.getState() == Call.State.INCOMING);
83625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon            } else {
84625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon                updateContactEntry(null, true, true);
85625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon            }
86bf62e69f8f029b616726577df7aa100c0900d6e5Chiao Cheng        }
871fa0782281ef7774ddcdfdf8efb7d8f65cf589e7Chiao Cheng    }
881fa0782281ef7774ddcdfdf8efb7d8f65cf589e7Chiao Cheng
89a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon    @Override
90a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon    public void onUiReady(CallCardUi ui) {
91a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon        super.onUiReady(ui);
92b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon
93b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon        AudioModeProvider.getInstance().addListener(this);
94b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon
958b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        // Contact search may have completed before ui is ready.
968b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        if (mPrimaryContactInfo != null) {
976d93245c0c9067d7a6ff30fd6fb79431da124946Christine Chen            updatePrimaryDisplayInfo(mPrimaryContactInfo, isConference(mPrimary));
988b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        }
998b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng
100b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon        // Register for call state changes last
101b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon        InCallPresenter.getInstance().addListener(this);
1021ee82fcea79556c90eec0f55ea2e2ab5c6dfaddaSantos Cordon        InCallPresenter.getInstance().addIncomingCallListener(this);
103b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon    }
104b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon
105b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon    @Override
106b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon    public void onUiUnready(CallCardUi ui) {
107b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon        super.onUiUnready(ui);
108b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon
109b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon        // stop getting call state changes
110b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon        InCallPresenter.getInstance().removeListener(this);
1111ee82fcea79556c90eec0f55ea2e2ab5c6dfaddaSantos Cordon        InCallPresenter.getInstance().removeIncomingCallListener(this);
112b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon
113b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon        AudioModeProvider.getInstance().removeListener(this);
114b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon
115b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon        mPrimary = null;
1164bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon        mPrimaryContactInfo = null;
1174bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon        mSecondaryContactInfo = null;
118a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon    }
119a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon
120a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon    @Override
1211ee82fcea79556c90eec0f55ea2e2ab5c6dfaddaSantos Cordon    public void onIncomingCall(InCallState state, Call call) {
1221ee82fcea79556c90eec0f55ea2e2ab5c6dfaddaSantos Cordon        // same logic should happen as with onStateChange()
1231ee82fcea79556c90eec0f55ea2e2ab5c6dfaddaSantos Cordon        onStateChange(state, CallList.getInstance());
1241ee82fcea79556c90eec0f55ea2e2ab5c6dfaddaSantos Cordon    }
1251ee82fcea79556c90eec0f55ea2e2ab5c6dfaddaSantos Cordon
1261ee82fcea79556c90eec0f55ea2e2ab5c6dfaddaSantos Cordon    @Override
127671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon    public void onStateChange(InCallState state, CallList callList) {
128b7f61237d6057baeff343b2728454d40705dd387Christine Chen        Log.d(this, "onStateChange() " + state);
129150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordon        final CallCardUi ui = getUi();
130b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon        if (ui == null) {
131b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon            return;
132b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon        }
133a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon
134671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon        Call primary = null;
135671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon        Call secondary = null;
136671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon
137671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon        if (state == InCallState.INCOMING) {
138671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon            primary = callList.getIncomingCall();
139e7be13fb0556e62b07bc271b130412d82d7f7521Santos Cordon        } else if (state == InCallState.OUTGOING) {
140e7be13fb0556e62b07bc271b130412d82d7f7521Santos Cordon            primary = callList.getOutgoingCall();
141e7be13fb0556e62b07bc271b130412d82d7f7521Santos Cordon
142a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon            // getCallToDisplay doesn't go through outgoing or incoming calls. It will return the
143a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon            // highest priority call to display as the secondary call.
1441df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon            secondary = getCallToDisplay(callList, null, true);
145671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon        } else if (state == InCallState.INCALL) {
1461df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon            primary = getCallToDisplay(callList, null, false);
1471df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon            secondary = getCallToDisplay(callList, primary, true);
148671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon        }
149671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon
1501a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng        Log.d(this, "Primary call: " + primary);
1511a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng        Log.d(this, "Secondary call: " + secondary);
152671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon
153625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon        final boolean primaryChanged = !areCallsSame(mPrimary, primary);
154625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon        final boolean secondaryChanged = !areCallsSame(mSecondary, secondary);
155625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon        mSecondary = secondary;
156625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon        mPrimary = primary;
157625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon
158625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon        if (primaryChanged && mPrimary != null) {
159625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon            // primary call has changed
160fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal            mPrimaryContactInfo = ContactInfoCache.buildCacheEntryFromCall(mContext, mPrimary,
161fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal                    mPrimary.getState() == Call.State.INCOMING);
162625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon            updatePrimaryDisplayInfo(mPrimaryContactInfo, isConference(mPrimary));
163625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon            maybeStartSearch(mPrimary, true);
1648b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        }
1658b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng
166625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon        if (mSecondary == null) {
1678b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            // Secondary call may have ended.  Update the ui.
1688b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            mSecondaryContactInfo = null;
1690f09a02be361d5bb36fac6981649204f5d6987faChristine Chen            updateSecondaryDisplayInfo(false);
170625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon        } else if (secondaryChanged) {
171625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon            // secondary call has changed
172fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal            mSecondaryContactInfo = ContactInfoCache.buildCacheEntryFromCall(mContext, mSecondary,
173fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal                    mSecondary.getState() == Call.State.INCOMING);
174625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon            updateSecondaryDisplayInfo(mSecondary.isConferenceCall());
175625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon            maybeStartSearch(mSecondary, false);
1768b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        }
1778b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng
17888dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon        // Start/Stop the call time update timer
17988dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon        if (mPrimary != null && mPrimary.getState() == Call.State.ACTIVE) {
1801a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng            Log.d(this, "Starting the calltime timer");
18188dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon            mCallTimer.start(CALL_TIME_UPDATE_INTERVAL);
18288dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon        } else {
1831a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng            Log.d(this, "Canceling the calltime timer");
18488dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon            mCallTimer.cancel();
18588dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon            ui.setPrimaryCallElapsedTime(false, null);
18688dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon        }
18788dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon
1884bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon        // Set the call state
189776d937b539b9e9b3672a1d860adec309f65d0adEvan Charlton        int callState = Call.State.IDLE;
1904bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon        if (mPrimary != null) {
19129d9a2f4f60715267c73044e327f65f812dfc2cdYorke Lee            callState = mPrimary.getState();
192b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon            final boolean bluetoothOn =
193b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon                    (AudioModeProvider.getInstance().getAudioMode() == AudioMode.BLUETOOTH);
194776d937b539b9e9b3672a1d860adec309f65d0adEvan Charlton            boolean isHandoffCapable = isHandoffCapable();
195776d937b539b9e9b3672a1d860adec309f65d0adEvan Charlton            boolean isHandoffPending = isHandoffPending();
1961771e5a1295eac5ad0d59fe2ff750ab450eab90eSailesh Nepal
197776d937b539b9e9b3672a1d860adec309f65d0adEvan Charlton            boolean isWiFi = isWifiCall();
1981771e5a1295eac5ad0d59fe2ff750ab450eab90eSailesh Nepal            // Cache the value so the UI doesn't change when the call ends.
1991771e5a1295eac5ad0d59fe2ff750ab450eab90eSailesh Nepal            mIsWiFiCachedValue = isWiFi;
2001771e5a1295eac5ad0d59fe2ff750ab450eab90eSailesh Nepal
201776d937b539b9e9b3672a1d860adec309f65d0adEvan Charlton            getUi().setCallState(callState, mPrimary.getDisconnectCause(), bluetoothOn,
2021771e5a1295eac5ad0d59fe2ff750ab450eab90eSailesh Nepal                    getGatewayLabel(), getGatewayNumber(), isWiFi, isHandoffCapable,
2031771e5a1295eac5ad0d59fe2ff750ab450eab90eSailesh Nepal                    isHandoffPending);
204a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon        } else {
205776d937b539b9e9b3672a1d860adec309f65d0adEvan Charlton            getUi().setCallState(callState, DisconnectCause.NOT_VALID, false, null, null,
2061771e5a1295eac5ad0d59fe2ff750ab450eab90eSailesh Nepal                    mIsWiFiCachedValue, false, false);
207a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon        }
2084c3e9e8e45ecafcb9aaf0da9901a5e9cebc59bc4Andrew Lee
209776d937b539b9e9b3672a1d860adec309f65d0adEvan Charlton        final boolean enableEndCallButton = Call.State.isConnected(callState) &&
210776d937b539b9e9b3672a1d860adec309f65d0adEvan Charlton                callState != Call.State.INCOMING && mPrimary != null;
2113306c8648fab5dfca386ca8a3c2d7f2e3fb01239Evan Charlton        getUi().setEndCallButtonEnabled(enableEndCallButton);
212b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon    }
213b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon
214b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon    @Override
215b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon    public void onAudioMode(int mode) {
216b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon        if (mPrimary != null && getUi() != null) {
217b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon            final boolean bluetoothOn = (AudioMode.BLUETOOTH == mode);
218b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon
2195c1830662d8daca84aae65c2eddf88c19c7772f1Makoto Onuki            getUi().setCallState(mPrimary.getState(), mPrimary.getDisconnectCause(), bluetoothOn,
220776d937b539b9e9b3672a1d860adec309f65d0adEvan Charlton                    getGatewayLabel(), getGatewayNumber(), isWifiCall(),
221776d937b539b9e9b3672a1d860adec309f65d0adEvan Charlton                    isHandoffCapable(), isHandoffPending());
222b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon        }
223b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon    }
224b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon
225776d937b539b9e9b3672a1d860adec309f65d0adEvan Charlton    private boolean isWifiCall() {
226a481914300fbe10a76635242eb778e1976947065Sailesh Nepal        CallServiceDescriptor descriptor = mPrimary.getCurrentCallServiceDescriptor();
227776d937b539b9e9b3672a1d860adec309f65d0adEvan Charlton        return descriptor != null &&
228776d937b539b9e9b3672a1d860adec309f65d0adEvan Charlton                descriptor.getNetworkType() == CallServiceDescriptor.FLAG_WIFI;
229776d937b539b9e9b3672a1d860adec309f65d0adEvan Charlton    }
230776d937b539b9e9b3672a1d860adec309f65d0adEvan Charlton
231776d937b539b9e9b3672a1d860adec309f65d0adEvan Charlton    private boolean isHandoffCapable() {
232776d937b539b9e9b3672a1d860adec309f65d0adEvan Charlton        return mPrimary.can(CallCapabilities.CONNECTION_HANDOFF);
233776d937b539b9e9b3672a1d860adec309f65d0adEvan Charlton    }
234776d937b539b9e9b3672a1d860adec309f65d0adEvan Charlton
235776d937b539b9e9b3672a1d860adec309f65d0adEvan Charlton    private boolean isHandoffPending() {
236776d937b539b9e9b3672a1d860adec309f65d0adEvan Charlton        return mPrimary.getHandoffCallServiceDescriptor() != null;
2370be676b7151d87f4d4d5244a859b14cb12621bf3Chiao Cheng    }
2380be676b7151d87f4d4d5244a859b14cb12621bf3Chiao Cheng
239b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon    @Override
240b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon    public void onSupportedAudioMode(int mask) {
241a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon    }
242a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon
2433e69e4fe0e6dbce738cc6b3f9a71fc177e9fe1b6Santos Cordon    @Override
2443e69e4fe0e6dbce738cc6b3f9a71fc177e9fe1b6Santos Cordon    public void onMute(boolean muted) {
2453e69e4fe0e6dbce738cc6b3f9a71fc177e9fe1b6Santos Cordon    }
2463e69e4fe0e6dbce738cc6b3f9a71fc177e9fe1b6Santos Cordon
24788dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon    public void updateCallTime() {
24888dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon        final CallCardUi ui = getUi();
24988dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon
25088dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon        if (ui == null || mPrimary == null || mPrimary.getState() != Call.State.ACTIVE) {
2510b77eb307c0a99bfb6aca0e38990c2d03a879bfcSantos Cordon            if (ui != null) {
2520b77eb307c0a99bfb6aca0e38990c2d03a879bfcSantos Cordon                ui.setPrimaryCallElapsedTime(false, null);
2530b77eb307c0a99bfb6aca0e38990c2d03a879bfcSantos Cordon            }
25488dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon            mCallTimer.cancel();
2550b77eb307c0a99bfb6aca0e38990c2d03a879bfcSantos Cordon        } else {
256a481914300fbe10a76635242eb778e1976947065Sailesh Nepal            final long callStart = mPrimary.getConnectTimeMillis();
2570b77eb307c0a99bfb6aca0e38990c2d03a879bfcSantos Cordon            final long duration = System.currentTimeMillis() - callStart;
2580b77eb307c0a99bfb6aca0e38990c2d03a879bfcSantos Cordon            ui.setPrimaryCallElapsedTime(true, DateUtils.formatElapsedTime(duration / 1000));
25988dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon        }
26088dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon    }
26188dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon
262776d937b539b9e9b3672a1d860adec309f65d0adEvan Charlton    public void connectionHandoffClicked() {
263776d937b539b9e9b3672a1d860adec309f65d0adEvan Charlton        if (mPrimary == null) {
264776d937b539b9e9b3672a1d860adec309f65d0adEvan Charlton            return;
265776d937b539b9e9b3672a1d860adec309f65d0adEvan Charlton        }
266776d937b539b9e9b3672a1d860adec309f65d0adEvan Charlton
267776d937b539b9e9b3672a1d860adec309f65d0adEvan Charlton        TelecommAdapter.getInstance().handoffCall(mPrimary.getCallId());
268776d937b539b9e9b3672a1d860adec309f65d0adEvan Charlton    }
269776d937b539b9e9b3672a1d860adec309f65d0adEvan Charlton
270625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon    private boolean areCallsSame(Call call1, Call call2) {
271625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon        if (call1 == null && call2 == null) {
272625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon            return true;
273625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon        } else if (call1 == null || call2 == null) {
274625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon            return false;
275625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon        }
276625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon
277625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon        // otherwise compare call Ids
2786af0c61c32da6cfb400168ae3b0cf9f802abfed4Sailesh Nepal        return call1.getCallId().equals(call2.getCallId());
279625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon    }
280625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon
281625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon    private void maybeStartSearch(Call call, boolean isPrimary) {
282625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon        // no need to start search for conference calls which show generic info.
283625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon        if (call != null && !call.isConferenceCall()) {
284fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal            startContactInfoSearch(call, isPrimary, call.getState() == Call.State.INCOMING);
285625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon        }
286625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon    }
287625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon
288a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon    /**
2894bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon     * Starts a query for more contact data for the save primary and secondary calls.
2904bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon     */
291fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal    private void startContactInfoSearch(final Call call, final boolean isPrimary,
292fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal            boolean isIncoming) {
2938b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        final ContactInfoCache cache = ContactInfoCache.getInstance(mContext);
2948b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng
295fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal        cache.findInfo(call, isIncoming, new ContactInfoCacheCallback() {
2968b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng                @Override
2976af0c61c32da6cfb400168ae3b0cf9f802abfed4Sailesh Nepal                public void onContactInfoComplete(String callId, ContactCacheEntry entry) {
298625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon                    updateContactEntry(entry, isPrimary, false);
299101bed44998ff35c3a56f431345fac5c8229ec0eJay Shrauner                    if (entry.name != null) {
300101bed44998ff35c3a56f431345fac5c8229ec0eJay Shrauner                        Log.d(TAG, "Contact found: " + entry);
3018b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng                    }
302fd76bfcd5bd3ee6cc1eb53019a23738192972180Yorke Lee                    if (entry.personUri != null) {
303fd76bfcd5bd3ee6cc1eb53019a23738192972180Yorke Lee                        CallerInfoUtils.sendViewNotification(mContext, entry.personUri);
304fd76bfcd5bd3ee6cc1eb53019a23738192972180Yorke Lee                    }
3058b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng                }
306af2589a6aa68d9906fe46b31ffaf214010632c02Chiao Cheng
307af2589a6aa68d9906fe46b31ffaf214010632c02Chiao Cheng                @Override
3086af0c61c32da6cfb400168ae3b0cf9f802abfed4Sailesh Nepal                public void onImageLoadComplete(String callId, ContactCacheEntry entry) {
309abec664bf7c7338f9e44ff4752413cf42932d38dChristine Chen                    if (getUi() == null) {
310abec664bf7c7338f9e44ff4752413cf42932d38dChristine Chen                        return;
311abec664bf7c7338f9e44ff4752413cf42932d38dChristine Chen                    }
31214dbc3f0ca3a7998c9c5d28aba637487724f529fSantos Cordon                    if (entry.photo != null) {
3136af0c61c32da6cfb400168ae3b0cf9f802abfed4Sailesh Nepal                        if (mPrimary != null && callId.equals(mPrimary.getCallId())) {
31414dbc3f0ca3a7998c9c5d28aba637487724f529fSantos Cordon                            getUi().setPrimaryImage(entry.photo);
31514dbc3f0ca3a7998c9c5d28aba637487724f529fSantos Cordon                        }
316af2589a6aa68d9906fe46b31ffaf214010632c02Chiao Cheng                    }
317af2589a6aa68d9906fe46b31ffaf214010632c02Chiao Cheng                }
3188b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            });
3198b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng    }
3208b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng
321625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon    private static boolean isConference(Call call) {
322625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon        return call != null && call.isConferenceCall();
323625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon    }
324625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon
325625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon    private static boolean isGenericConference(Call call) {
326b48e2280930b5ed0b04dd34d59dc5980b379a475Sailesh Nepal        return call != null && call.can(CallCapabilities.GENERIC_CONFERENCE);
3278b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng    }
3284bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon
3298b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng    private void updateContactEntry(ContactCacheEntry entry, boolean isPrimary,
3308b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            boolean isConference) {
3318b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        if (isPrimary) {
3328b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            mPrimaryContactInfo = entry;
3338b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            updatePrimaryDisplayInfo(entry, isConference);
3344bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon        } else {
3358b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            mSecondaryContactInfo = entry;
3360f09a02be361d5bb36fac6981649204f5d6987faChristine Chen            updateSecondaryDisplayInfo(isConference);
3374bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon        }
3384bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon    }
3394bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon
3404bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon    /**
341a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon     * Get the highest priority call to display.
342a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon     * Goes through the calls and chooses which to return based on priority of which type of call
343a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon     * to display to the user. Callers can use the "ignore" feature to get the second best call
344a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon     * by passing a previously found primary call as ignore.
345a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon     *
346a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon     * @param ignore A call to ignore if found.
347a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon     */
3481df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon    private Call getCallToDisplay(CallList callList, Call ignore, boolean skipDisconnected) {
349a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon
3501df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon        // Active calls come second.  An active call always gets precedent.
3511df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon        Call retval = callList.getActiveCall();
352a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon        if (retval != null && retval != ignore) {
353a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon            return retval;
354a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon        }
355a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon
3561df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon        // Disconnected calls get primary position if there are no active calls
3571df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon        // to let user know quickly what call has disconnected. Disconnected
3581df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon        // calls are very short lived.
3591df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon        if (!skipDisconnected) {
360ecabb6923e6587e0f0ca98cc895be7d99e694015Christine Chen            retval = callList.getDisconnectingCall();
361ecabb6923e6587e0f0ca98cc895be7d99e694015Christine Chen            if (retval != null && retval != ignore) {
362ecabb6923e6587e0f0ca98cc895be7d99e694015Christine Chen                return retval;
363ecabb6923e6587e0f0ca98cc895be7d99e694015Christine Chen            }
3641df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon            retval = callList.getDisconnectedCall();
3651df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon            if (retval != null && retval != ignore) {
3661df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon                return retval;
3671df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon            }
368a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon        }
369a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon
370a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon        // Then we go to background call (calls on hold)
371a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon        retval = callList.getBackgroundCall();
372a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon        if (retval != null && retval != ignore) {
373a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon            return retval;
374a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon        }
375a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon
376a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon        // Lastly, we go to a second background call.
377a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon        retval = callList.getSecondBackgroundCall();
378a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon
379a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon        return retval;
380a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon    }
381a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon
3828b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng    private void updatePrimaryDisplayInfo(ContactCacheEntry entry, boolean isConference) {
3838b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        Log.d(TAG, "Update primary display " + entry);
384988d06b64b99a13f4f060dc82594edcb738d9113Yorke Lee        final CallCardUi ui = getUi();
3854bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon        if (ui == null) {
3868b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            // TODO: May also occur if search result comes back after ui is destroyed. Look into
3878b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            // removing that case completely.
3888b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            Log.d(TAG, "updatePrimaryDisplayInfo called but ui is null!");
3894bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon            return;
390988d06b64b99a13f4f060dc82594edcb738d9113Yorke Lee        }
3917ef707319c0e3563ff92a772ba53cb5dca0e3ae1Yorke Lee
392625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon        final boolean isGenericConf = isGenericConference(mPrimary);
3938b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        if (entry != null) {
3948b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            final String name = getNameForCall(entry);
3958b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            final String number = getNumberForCall(entry);
3968b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            final boolean nameIsNumber = name != null && name.equals(entry.number);
3978b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            ui.setPrimary(number, name, nameIsNumber, entry.label,
398625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon                    entry.photo, isConference, isGenericConf, entry.isSipCall);
399988d06b64b99a13f4f060dc82594edcb738d9113Yorke Lee        } else {
400625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon            ui.setPrimary(null, null, false, null, null, isConference, isGenericConf, false);
4011df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon        }
4021df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon
4031df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon    }
4041df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon
4050f09a02be361d5bb36fac6981649204f5d6987faChristine Chen    private void updateSecondaryDisplayInfo(boolean isConference) {
4068b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng
4078b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        final CallCardUi ui = getUi();
4088b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        if (ui == null) {
4098b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            return;
4108b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        }
4118b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng
412625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon        final boolean isGenericConf = isGenericConference(mSecondary);
4138b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        if (mSecondaryContactInfo != null) {
4148b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            Log.d(TAG, "updateSecondaryDisplayInfo() " + mSecondaryContactInfo);
4154be1bdd9ee8e9d3afa1aaa765e86b963fb6c7b3dYorke Lee            final String nameForCall = getNameForCall(mSecondaryContactInfo);
4164be1bdd9ee8e9d3afa1aaa765e86b963fb6c7b3dYorke Lee
4174be1bdd9ee8e9d3afa1aaa765e86b963fb6c7b3dYorke Lee            final boolean nameIsNumber = nameForCall != null && nameForCall.equals(
4184be1bdd9ee8e9d3afa1aaa765e86b963fb6c7b3dYorke Lee                    mSecondaryContactInfo.number);
4198e303d6ad3f2a0e99b1d0674b9cf91565511f066Andrew Lee            ui.setSecondary(true /* show */, nameForCall, nameIsNumber, mSecondaryContactInfo.label,
4208e303d6ad3f2a0e99b1d0674b9cf91565511f066Andrew Lee                    isConference, isGenericConf);
4218b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        } else {
4228b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            // reset to nothing so that it starts off blank next time we use it.
4238e303d6ad3f2a0e99b1d0674b9cf91565511f066Andrew Lee            ui.setSecondary(false, null, false, null, isConference, isGenericConf);
4248b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        }
4258b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng    }
4268b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng
4273d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon    /**
4283d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon     * Returns the gateway number for any existing outgoing call.
4293d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon     */
4303d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon    private String getGatewayNumber() {
4313d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon        if (hasOutgoingGatewayCall()) {
43207a822b2ea92dc5b68cd43139be7efe4c6640cd4Sailesh Nepal            return mPrimary.getGatewayInfo().getGatewayHandle().getSchemeSpecificPart();
4333d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon        }
4343d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon        return null;
4353d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon    }
4363d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon
4373d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon    /**
4383d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon     * Returns the label for the gateway app for any existing outgoing call.
4393d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon     */
4403d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon    private String getGatewayLabel() {
4413d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon        if (hasOutgoingGatewayCall() && getUi() != null) {
4423d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon            final PackageManager pm = mContext.getPackageManager();
4433d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon            try {
44407a822b2ea92dc5b68cd43139be7efe4c6640cd4Sailesh Nepal                ApplicationInfo info = pm.getApplicationInfo(
44507a822b2ea92dc5b68cd43139be7efe4c6640cd4Sailesh Nepal                        mPrimary.getGatewayInfo().getGatewayProviderPackageName(), 0);
4463d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon                return mContext.getString(R.string.calling_via_template,
4473d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon                        pm.getApplicationLabel(info).toString());
4483d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon            } catch (PackageManager.NameNotFoundException e) {
4493d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon            }
4503d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon        }
4513d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon        return null;
4523d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon    }
4533d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon
4543d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon    private boolean hasOutgoingGatewayCall() {
4553d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon        // We only display the gateway information while DIALING so return false for any othe
4563d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon        // call state.
4578b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        // TODO: mPrimary can be null because this is called from updatePrimaryDisplayInfo which
4588b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        // is also called after a contact search completes (call is not present yet).  Split the
4598b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        // UI update so it can receive independent updates.
4608b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        if (mPrimary == null) {
4618b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            return false;
4628b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        }
46307a822b2ea92dc5b68cd43139be7efe4c6640cd4Sailesh Nepal        return Call.State.isDialing(mPrimary.getState()) && mPrimary.getGatewayInfo() != null &&
46407a822b2ea92dc5b68cd43139be7efe4c6640cd4Sailesh Nepal                !mPrimary.getGatewayInfo().isEmpty();
4653d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon    }
4663d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon
4671df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon    /**
4681df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon     * Gets the name to display for the call.
4691df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon     */
4701df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon    private static String getNameForCall(ContactCacheEntry contactInfo) {
4711df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon        if (TextUtils.isEmpty(contactInfo.name)) {
4721df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon            return contactInfo.number;
473988d06b64b99a13f4f060dc82594edcb738d9113Yorke Lee        }
4741df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon        return contactInfo.name;
4751df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon    }
476988d06b64b99a13f4f060dc82594edcb738d9113Yorke Lee
4771df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon    /**
4781df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon     * Gets the number to display for a call.
4791df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon     */
4801df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon    private static String getNumberForCall(ContactCacheEntry contactInfo) {
4811df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon        // If the name is empty, we use the number for the name...so dont show a second
4821df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon        // number in the number field
4831df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon        if (TextUtils.isEmpty(contactInfo.name)) {
484101bed44998ff35c3a56f431345fac5c8229ec0eJay Shrauner            return contactInfo.location;
4851df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon        }
4861df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon        return contactInfo.number;
4874bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon    }
488988d06b64b99a13f4f060dc82594edcb738d9113Yorke Lee
4898e303d6ad3f2a0e99b1d0674b9cf91565511f066Andrew Lee    public void secondaryInfoClicked() {
4906f767fb5d92b7e07315b86ddf1de1f25e7354bc0Yorke Lee        if (mSecondary == null) {
4918e303d6ad3f2a0e99b1d0674b9cf91565511f066Andrew Lee            Log.wtf(this, "Secondary info clicked but no secondary call.");
4926f767fb5d92b7e07315b86ddf1de1f25e7354bc0Yorke Lee            return;
4936f767fb5d92b7e07315b86ddf1de1f25e7354bc0Yorke Lee        }
4946f767fb5d92b7e07315b86ddf1de1f25e7354bc0Yorke Lee
495fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal        Log.i(this, "Swapping call to foreground: " + mSecondary);
496fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal        TelecommAdapter.getInstance().unholdCall(mSecondary.getCallId());
4979240895e9df2fcae8f0baea707eb4d24c6e50997Yorke Lee    }
4989240895e9df2fcae8f0baea707eb4d24c6e50997Yorke Lee
4997b4cfe59218ff0876587933f5f22845881fdbe40Andrew Lee    public void endCallClicked() {
5007b4cfe59218ff0876587933f5f22845881fdbe40Andrew Lee        if (mPrimary == null) {
5017b4cfe59218ff0876587933f5f22845881fdbe40Andrew Lee            return;
5027b4cfe59218ff0876587933f5f22845881fdbe40Andrew Lee        }
5037b4cfe59218ff0876587933f5f22845881fdbe40Andrew Lee
5048a81f277540cd6e7c8da5efd7ecbd342912ae29bEvan Charlton        Log.i(this, "Disconnecting call: " + mPrimary);
5058a81f277540cd6e7c8da5efd7ecbd342912ae29bEvan Charlton        TelecommAdapter.getInstance().disconnectCall(mPrimary.getCallId());
5067b4cfe59218ff0876587933f5f22845881fdbe40Andrew Lee    }
5077b4cfe59218ff0876587933f5f22845881fdbe40Andrew Lee
5084bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon    public interface CallCardUi extends Ui {
5094bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon        void setVisible(boolean on);
5101df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon        void setPrimary(String number, String name, boolean nameIsNumber, String label,
511625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon                Drawable photo, boolean isConference, boolean isGeneric, boolean isSipCall);
5124be1bdd9ee8e9d3afa1aaa765e86b963fb6c7b3dYorke Lee        void setSecondary(boolean show, String name, boolean nameIsNumber, String label,
5138e303d6ad3f2a0e99b1d0674b9cf91565511f066Andrew Lee                boolean isConference, boolean isGeneric);
514a81667248196be225849f7739f64752dc578f6bbAnders Kristensen        void setCallState(int state, int cause, boolean bluetoothOn,
515776d937b539b9e9b3672a1d860adec309f65d0adEvan Charlton                String gatewayLabel, String gatewayNumber, boolean isWifi, boolean isHandoffCapable,
516776d937b539b9e9b3672a1d860adec309f65d0adEvan Charlton                boolean isHandoffPending);
51788dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon        void setPrimaryCallElapsedTime(boolean show, String duration);
5188b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        void setPrimaryName(String name, boolean nameIsNumber);
51914dbc3f0ca3a7998c9c5d28aba637487724f529fSantos Cordon        void setPrimaryImage(Drawable image);
5208b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        void setPrimaryPhoneNumber(String phoneNumber);
5218b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        void setPrimaryLabel(String label);
5224c3e9e8e45ecafcb9aaf0da9901a5e9cebc59bc4Andrew Lee        void setEndCallButtonEnabled(boolean enabled);
5237ef707319c0e3563ff92a772ba53cb5dca0e3ae1Yorke Lee    }
524a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon}
525