CallCardPresenter.java revision b48e2280930b5ed0b04dd34d59dc5980b379a475
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;
27a81667248196be225849f7739f64752dc578f6bbAnders Kristensenimport android.telephony.DisconnectCause;
284be1bdd9ee8e9d3afa1aaa765e86b963fb6c7b3dYorke Leeimport android.telephony.PhoneNumberUtils;
291df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordonimport android.text.TextUtils;
3088dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordonimport android.text.format.DateUtils;
317ef707319c0e3563ff92a772ba53cb5dca0e3ae1Yorke Lee
32b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordonimport com.android.incallui.AudioModeProvider.AudioModeListener;
334bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordonimport com.android.incallui.ContactInfoCache.ContactCacheEntry;
344bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordonimport com.android.incallui.ContactInfoCache.ContactInfoCacheCallback;
35671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordonimport com.android.incallui.InCallPresenter.InCallState;
36671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordonimport com.android.incallui.InCallPresenter.InCallStateListener;
371ee82fcea79556c90eec0f55ea2e2ab5c6dfaddaSantos Cordonimport com.android.incallui.InCallPresenter.IncomingCallListener;
38b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordonimport com.android.services.telephony.common.AudioMode;
398b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Chengimport com.google.common.base.Preconditions;
40a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon
41a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon/**
42a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon * Presenter for the Call Card Fragment.
431fa0782281ef7774ddcdfdf8efb7d8f65cf589e7Chiao Cheng * <p>
44671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon * This class listens for changes to InCallState and passes it along to the fragment.
45a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon */
464bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordonpublic class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
471ee82fcea79556c90eec0f55ea2e2ab5c6dfaddaSantos Cordon        implements InCallStateListener, AudioModeListener, IncomingCallListener {
487ef707319c0e3563ff92a772ba53cb5dca0e3ae1Yorke Lee
491fa0782281ef7774ddcdfdf8efb7d8f65cf589e7Chiao Cheng    private static final String TAG = CallCardPresenter.class.getSimpleName();
5088dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon    private static final long CALL_TIME_UPDATE_INTERVAL = 1000; // in milliseconds
5188dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon
52b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon    private Call mPrimary;
534bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon    private Call mSecondary;
544bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon    private ContactCacheEntry mPrimaryContactInfo;
554bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon    private ContactCacheEntry mSecondaryContactInfo;
5688dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon    private CallTimer mCallTimer;
573d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon    private Context mContext;
58988d06b64b99a13f4f060dc82594edcb738d9113Yorke Lee
599de3d7c5188c02cabf03799f87d494ee7dc702cbSantos Cordon    public CallCardPresenter() {
6088dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon        // create the call timer
6188dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon        mCallTimer = new CallTimer(new Runnable() {
6288dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon            @Override
6388dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon            public void run() {
6488dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon                updateCallTime();
6588dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon            }
6688dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon        });
67988d06b64b99a13f4f060dc82594edcb738d9113Yorke Lee    }
68988d06b64b99a13f4f060dc82594edcb738d9113Yorke Lee
698b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng
70101bed44998ff35c3a56f431345fac5c8229ec0eJay Shrauner    public void init(Context context, Call call) {
718b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        mContext = Preconditions.checkNotNull(context);
728b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng
73bf62e69f8f029b616726577df7aa100c0900d6e5Chiao Cheng        // Call may be null if disconnect happened already.
74bf62e69f8f029b616726577df7aa100c0900d6e5Chiao Cheng        if (call != null) {
7541457dce3ca531178ca07946868afb0cc1579a6bChiao Cheng            mPrimary = call;
7641457dce3ca531178ca07946868afb0cc1579a6bChiao Cheng
77bf62e69f8f029b616726577df7aa100c0900d6e5Chiao Cheng            // start processing lookups right away.
78625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon            if (!call.isConferenceCall()) {
79fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal                startContactInfoSearch(call, true, call.getState() == Call.State.INCOMING);
80625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon            } else {
81625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon                updateContactEntry(null, true, true);
82625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon            }
83bf62e69f8f029b616726577df7aa100c0900d6e5Chiao Cheng        }
841fa0782281ef7774ddcdfdf8efb7d8f65cf589e7Chiao Cheng    }
851fa0782281ef7774ddcdfdf8efb7d8f65cf589e7Chiao Cheng
86a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon    @Override
87a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon    public void onUiReady(CallCardUi ui) {
88a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon        super.onUiReady(ui);
89b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon
90b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon        AudioModeProvider.getInstance().addListener(this);
91b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon
928b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        // Contact search may have completed before ui is ready.
938b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        if (mPrimaryContactInfo != null) {
946d93245c0c9067d7a6ff30fd6fb79431da124946Christine Chen            updatePrimaryDisplayInfo(mPrimaryContactInfo, isConference(mPrimary));
958b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        }
968b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng
97b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon        // Register for call state changes last
98b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon        InCallPresenter.getInstance().addListener(this);
991ee82fcea79556c90eec0f55ea2e2ab5c6dfaddaSantos Cordon        InCallPresenter.getInstance().addIncomingCallListener(this);
100b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon    }
101b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon
102b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon    @Override
103b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon    public void onUiUnready(CallCardUi ui) {
104b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon        super.onUiUnready(ui);
105b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon
106b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon        // stop getting call state changes
107b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon        InCallPresenter.getInstance().removeListener(this);
1081ee82fcea79556c90eec0f55ea2e2ab5c6dfaddaSantos Cordon        InCallPresenter.getInstance().removeIncomingCallListener(this);
109b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon
110b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon        AudioModeProvider.getInstance().removeListener(this);
111b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon
112b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon        mPrimary = null;
1134bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon        mPrimaryContactInfo = null;
1144bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon        mSecondaryContactInfo = null;
115a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon    }
116a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon
117a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon    @Override
1181ee82fcea79556c90eec0f55ea2e2ab5c6dfaddaSantos Cordon    public void onIncomingCall(InCallState state, Call call) {
1191ee82fcea79556c90eec0f55ea2e2ab5c6dfaddaSantos Cordon        // same logic should happen as with onStateChange()
1201ee82fcea79556c90eec0f55ea2e2ab5c6dfaddaSantos Cordon        onStateChange(state, CallList.getInstance());
1211ee82fcea79556c90eec0f55ea2e2ab5c6dfaddaSantos Cordon    }
1221ee82fcea79556c90eec0f55ea2e2ab5c6dfaddaSantos Cordon
1231ee82fcea79556c90eec0f55ea2e2ab5c6dfaddaSantos Cordon    @Override
124671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon    public void onStateChange(InCallState state, CallList callList) {
125b7f61237d6057baeff343b2728454d40705dd387Christine Chen        Log.d(this, "onStateChange() " + state);
126150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordon        final CallCardUi ui = getUi();
127b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon        if (ui == null) {
128b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon            return;
129b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon        }
130a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon
131671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon        Call primary = null;
132671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon        Call secondary = null;
133671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon
134671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon        if (state == InCallState.INCOMING) {
135671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon            primary = callList.getIncomingCall();
136e7be13fb0556e62b07bc271b130412d82d7f7521Santos Cordon        } else if (state == InCallState.OUTGOING) {
137e7be13fb0556e62b07bc271b130412d82d7f7521Santos Cordon            primary = callList.getOutgoingCall();
138e7be13fb0556e62b07bc271b130412d82d7f7521Santos Cordon
139a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon            // getCallToDisplay doesn't go through outgoing or incoming calls. It will return the
140a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon            // highest priority call to display as the secondary call.
1411df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon            secondary = getCallToDisplay(callList, null, true);
142671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon        } else if (state == InCallState.INCALL) {
1431df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon            primary = getCallToDisplay(callList, null, false);
1441df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon            secondary = getCallToDisplay(callList, primary, true);
145671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon        }
146671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon
1471a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng        Log.d(this, "Primary call: " + primary);
1481a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng        Log.d(this, "Secondary call: " + secondary);
149671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon
150625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon        final boolean primaryChanged = !areCallsSame(mPrimary, primary);
151625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon        final boolean secondaryChanged = !areCallsSame(mSecondary, secondary);
152625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon        mSecondary = secondary;
153625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon        mPrimary = primary;
154625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon
155625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon        if (primaryChanged && mPrimary != null) {
156625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon            // primary call has changed
157fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal            mPrimaryContactInfo = ContactInfoCache.buildCacheEntryFromCall(mContext, mPrimary,
158fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal                    mPrimary.getState() == Call.State.INCOMING);
159625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon            updatePrimaryDisplayInfo(mPrimaryContactInfo, isConference(mPrimary));
160625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon            maybeStartSearch(mPrimary, true);
1618b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        }
1628b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng
163625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon        if (mSecondary == null) {
1648b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            // Secondary call may have ended.  Update the ui.
1658b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            mSecondaryContactInfo = null;
1660f09a02be361d5bb36fac6981649204f5d6987faChristine Chen            updateSecondaryDisplayInfo(false);
167625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon        } else if (secondaryChanged) {
168625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon            // secondary call has changed
169fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal            mSecondaryContactInfo = ContactInfoCache.buildCacheEntryFromCall(mContext, mSecondary,
170fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal                    mSecondary.getState() == Call.State.INCOMING);
171625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon            updateSecondaryDisplayInfo(mSecondary.isConferenceCall());
172625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon            maybeStartSearch(mSecondary, false);
1738b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        }
1748b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng
17588dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon        // Start/Stop the call time update timer
17688dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon        if (mPrimary != null && mPrimary.getState() == Call.State.ACTIVE) {
1771a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng            Log.d(this, "Starting the calltime timer");
17888dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon            mCallTimer.start(CALL_TIME_UPDATE_INTERVAL);
17988dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon        } else {
1801a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng            Log.d(this, "Canceling the calltime timer");
18188dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon            mCallTimer.cancel();
18288dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon            ui.setPrimaryCallElapsedTime(false, null);
18388dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon        }
18488dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon
1854bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon        // Set the call state
1864bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon        if (mPrimary != null) {
187b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon            final boolean bluetoothOn =
188b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon                    (AudioModeProvider.getInstance().getAudioMode() == AudioMode.BLUETOOTH);
1895c1830662d8daca84aae65c2eddf88c19c7772f1Makoto Onuki            ui.setCallState(mPrimary.getState(), mPrimary.getDisconnectCause(), bluetoothOn,
1900be676b7151d87f4d4d5244a859b14cb12621bf3Chiao Cheng                    getGatewayLabel(), getGatewayNumber(), getWifiConnection());
191a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon        } else {
1929d031ca4cf14d2330a9491b24d13ba16b2ae958cColin Cross            ui.setCallState(Call.State.IDLE, DisconnectCause.NOT_VALID, false, null, null, null);
193a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon        }
194b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon    }
195b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon
196b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon    @Override
197b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon    public void onAudioMode(int mode) {
198b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon        if (mPrimary != null && getUi() != null) {
199b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon            final boolean bluetoothOn = (AudioMode.BLUETOOTH == mode);
200b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon
2015c1830662d8daca84aae65c2eddf88c19c7772f1Makoto Onuki            getUi().setCallState(mPrimary.getState(), mPrimary.getDisconnectCause(), bluetoothOn,
2020be676b7151d87f4d4d5244a859b14cb12621bf3Chiao Cheng                    getGatewayLabel(), getGatewayNumber(), getWifiConnection());
203b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon        }
204b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon    }
205b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon
2060be676b7151d87f4d4d5244a859b14cb12621bf3Chiao Cheng    private String getWifiConnection() {
2070be676b7151d87f4d4d5244a859b14cb12621bf3Chiao Cheng        if (mPrimary.isWifiCall()) {
2080be676b7151d87f4d4d5244a859b14cb12621bf3Chiao Cheng            final WifiManager wifiManager = (WifiManager) mContext.getSystemService(
2090be676b7151d87f4d4d5244a859b14cb12621bf3Chiao Cheng                    Context.WIFI_SERVICE);
2100be676b7151d87f4d4d5244a859b14cb12621bf3Chiao Cheng            final WifiInfo info = wifiManager.getConnectionInfo();
2110be676b7151d87f4d4d5244a859b14cb12621bf3Chiao Cheng            if (info != null) {
2120be676b7151d87f4d4d5244a859b14cb12621bf3Chiao Cheng                return info.getSSID();
2130be676b7151d87f4d4d5244a859b14cb12621bf3Chiao Cheng            }
2140be676b7151d87f4d4d5244a859b14cb12621bf3Chiao Cheng        }
2150be676b7151d87f4d4d5244a859b14cb12621bf3Chiao Cheng        return null;
2160be676b7151d87f4d4d5244a859b14cb12621bf3Chiao Cheng    }
2170be676b7151d87f4d4d5244a859b14cb12621bf3Chiao Cheng
218b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon    @Override
219b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon    public void onSupportedAudioMode(int mask) {
220a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon    }
221a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon
2223e69e4fe0e6dbce738cc6b3f9a71fc177e9fe1b6Santos Cordon    @Override
2233e69e4fe0e6dbce738cc6b3f9a71fc177e9fe1b6Santos Cordon    public void onMute(boolean muted) {
2243e69e4fe0e6dbce738cc6b3f9a71fc177e9fe1b6Santos Cordon    }
2253e69e4fe0e6dbce738cc6b3f9a71fc177e9fe1b6Santos Cordon
22688dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon    public void updateCallTime() {
22788dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon        final CallCardUi ui = getUi();
22888dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon
22988dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon        if (ui == null || mPrimary == null || mPrimary.getState() != Call.State.ACTIVE) {
2300b77eb307c0a99bfb6aca0e38990c2d03a879bfcSantos Cordon            if (ui != null) {
2310b77eb307c0a99bfb6aca0e38990c2d03a879bfcSantos Cordon                ui.setPrimaryCallElapsedTime(false, null);
2320b77eb307c0a99bfb6aca0e38990c2d03a879bfcSantos Cordon            }
23388dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon            mCallTimer.cancel();
2340b77eb307c0a99bfb6aca0e38990c2d03a879bfcSantos Cordon        } else {
2350b77eb307c0a99bfb6aca0e38990c2d03a879bfcSantos Cordon            final long callStart = mPrimary.getConnectTime();
2360b77eb307c0a99bfb6aca0e38990c2d03a879bfcSantos Cordon            final long duration = System.currentTimeMillis() - callStart;
2370b77eb307c0a99bfb6aca0e38990c2d03a879bfcSantos Cordon            ui.setPrimaryCallElapsedTime(true, DateUtils.formatElapsedTime(duration / 1000));
23888dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon        }
23988dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon    }
24088dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon
241625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon    private boolean areCallsSame(Call call1, Call call2) {
242625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon        if (call1 == null && call2 == null) {
243625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon            return true;
244625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon        } else if (call1 == null || call2 == null) {
245625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon            return false;
246625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon        }
247625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon
248625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon        // otherwise compare call Ids
2496af0c61c32da6cfb400168ae3b0cf9f802abfed4Sailesh Nepal        return call1.getCallId().equals(call2.getCallId());
250625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon    }
251625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon
252625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon    private void maybeStartSearch(Call call, boolean isPrimary) {
253625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon        // no need to start search for conference calls which show generic info.
254625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon        if (call != null && !call.isConferenceCall()) {
255fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal            startContactInfoSearch(call, isPrimary, call.getState() == Call.State.INCOMING);
256625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon        }
257625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon    }
258625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon
259a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon    /**
2604bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon     * Starts a query for more contact data for the save primary and secondary calls.
2614bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon     */
262fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal    private void startContactInfoSearch(final Call call, final boolean isPrimary,
263fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal            boolean isIncoming) {
2648b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        final ContactInfoCache cache = ContactInfoCache.getInstance(mContext);
2658b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng
266fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal        cache.findInfo(call, isIncoming, new ContactInfoCacheCallback() {
2678b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng                @Override
2686af0c61c32da6cfb400168ae3b0cf9f802abfed4Sailesh Nepal                public void onContactInfoComplete(String callId, ContactCacheEntry entry) {
269625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon                    updateContactEntry(entry, isPrimary, false);
270101bed44998ff35c3a56f431345fac5c8229ec0eJay Shrauner                    if (entry.name != null) {
271101bed44998ff35c3a56f431345fac5c8229ec0eJay Shrauner                        Log.d(TAG, "Contact found: " + entry);
2728b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng                    }
273fd76bfcd5bd3ee6cc1eb53019a23738192972180Yorke Lee                    if (entry.personUri != null) {
274fd76bfcd5bd3ee6cc1eb53019a23738192972180Yorke Lee                        CallerInfoUtils.sendViewNotification(mContext, entry.personUri);
275fd76bfcd5bd3ee6cc1eb53019a23738192972180Yorke Lee                    }
2768b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng                }
277af2589a6aa68d9906fe46b31ffaf214010632c02Chiao Cheng
278af2589a6aa68d9906fe46b31ffaf214010632c02Chiao Cheng                @Override
2796af0c61c32da6cfb400168ae3b0cf9f802abfed4Sailesh Nepal                public void onImageLoadComplete(String callId, ContactCacheEntry entry) {
280abec664bf7c7338f9e44ff4752413cf42932d38dChristine Chen                    if (getUi() == null) {
281abec664bf7c7338f9e44ff4752413cf42932d38dChristine Chen                        return;
282abec664bf7c7338f9e44ff4752413cf42932d38dChristine Chen                    }
28314dbc3f0ca3a7998c9c5d28aba637487724f529fSantos Cordon                    if (entry.photo != null) {
2846af0c61c32da6cfb400168ae3b0cf9f802abfed4Sailesh Nepal                        if (mPrimary != null && callId.equals(mPrimary.getCallId())) {
28514dbc3f0ca3a7998c9c5d28aba637487724f529fSantos Cordon                            getUi().setPrimaryImage(entry.photo);
2866af0c61c32da6cfb400168ae3b0cf9f802abfed4Sailesh Nepal                        } else if (mSecondary != null && callId.equals(mSecondary.getCallId())) {
28714dbc3f0ca3a7998c9c5d28aba637487724f529fSantos Cordon                            getUi().setSecondaryImage(entry.photo);
28814dbc3f0ca3a7998c9c5d28aba637487724f529fSantos Cordon                        }
289af2589a6aa68d9906fe46b31ffaf214010632c02Chiao Cheng                    }
290af2589a6aa68d9906fe46b31ffaf214010632c02Chiao Cheng                }
2918b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            });
2928b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng    }
2938b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng
294625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon    private static boolean isConference(Call call) {
295625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon        return call != null && call.isConferenceCall();
296625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon    }
297625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon
298625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon    private static boolean isGenericConference(Call call) {
299b48e2280930b5ed0b04dd34d59dc5980b379a475Sailesh Nepal        return call != null && call.can(CallCapabilities.GENERIC_CONFERENCE);
3008b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng    }
3014bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon
3028b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng    private void updateContactEntry(ContactCacheEntry entry, boolean isPrimary,
3038b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            boolean isConference) {
3048b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        if (isPrimary) {
3058b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            mPrimaryContactInfo = entry;
3068b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            updatePrimaryDisplayInfo(entry, isConference);
3074bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon        } else {
3088b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            mSecondaryContactInfo = entry;
3090f09a02be361d5bb36fac6981649204f5d6987faChristine Chen            updateSecondaryDisplayInfo(isConference);
3104bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon        }
3114bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon    }
3124bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon
3134bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon    /**
314a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon     * Get the highest priority call to display.
315a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon     * Goes through the calls and chooses which to return based on priority of which type of call
316a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon     * to display to the user. Callers can use the "ignore" feature to get the second best call
317a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon     * by passing a previously found primary call as ignore.
318a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon     *
319a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon     * @param ignore A call to ignore if found.
320a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon     */
3211df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon    private Call getCallToDisplay(CallList callList, Call ignore, boolean skipDisconnected) {
322a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon
3231df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon        // Active calls come second.  An active call always gets precedent.
3241df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon        Call retval = callList.getActiveCall();
325a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon        if (retval != null && retval != ignore) {
326a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon            return retval;
327a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon        }
328a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon
3291df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon        // Disconnected calls get primary position if there are no active calls
3301df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon        // to let user know quickly what call has disconnected. Disconnected
3311df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon        // calls are very short lived.
3321df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon        if (!skipDisconnected) {
333ecabb6923e6587e0f0ca98cc895be7d99e694015Christine Chen            retval = callList.getDisconnectingCall();
334ecabb6923e6587e0f0ca98cc895be7d99e694015Christine Chen            if (retval != null && retval != ignore) {
335ecabb6923e6587e0f0ca98cc895be7d99e694015Christine Chen                return retval;
336ecabb6923e6587e0f0ca98cc895be7d99e694015Christine Chen            }
3371df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon            retval = callList.getDisconnectedCall();
3381df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon            if (retval != null && retval != ignore) {
3391df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon                return retval;
3401df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon            }
341a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon        }
342a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon
343a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon        // Then we go to background call (calls on hold)
344a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon        retval = callList.getBackgroundCall();
345a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon        if (retval != null && retval != ignore) {
346a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon            return retval;
347a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon        }
348a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon
349a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon        // Lastly, we go to a second background call.
350a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon        retval = callList.getSecondBackgroundCall();
351a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon
352a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon        return retval;
353a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon    }
354a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon
3558b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng    private void updatePrimaryDisplayInfo(ContactCacheEntry entry, boolean isConference) {
3568b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        Log.d(TAG, "Update primary display " + entry);
357988d06b64b99a13f4f060dc82594edcb738d9113Yorke Lee        final CallCardUi ui = getUi();
3584bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon        if (ui == null) {
3598b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            // TODO: May also occur if search result comes back after ui is destroyed. Look into
3608b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            // removing that case completely.
3618b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            Log.d(TAG, "updatePrimaryDisplayInfo called but ui is null!");
3624bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon            return;
363988d06b64b99a13f4f060dc82594edcb738d9113Yorke Lee        }
3647ef707319c0e3563ff92a772ba53cb5dca0e3ae1Yorke Lee
365625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon        final boolean isGenericConf = isGenericConference(mPrimary);
3668b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        if (entry != null) {
3678b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            final String name = getNameForCall(entry);
3688b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            final String number = getNumberForCall(entry);
3698b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            final boolean nameIsNumber = name != null && name.equals(entry.number);
3708b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            ui.setPrimary(number, name, nameIsNumber, entry.label,
371625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon                    entry.photo, isConference, isGenericConf, entry.isSipCall);
372988d06b64b99a13f4f060dc82594edcb738d9113Yorke Lee        } else {
373625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon            ui.setPrimary(null, null, false, null, null, isConference, isGenericConf, false);
3741df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon        }
3751df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon
3761df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon    }
3771df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon
3780f09a02be361d5bb36fac6981649204f5d6987faChristine Chen    private void updateSecondaryDisplayInfo(boolean isConference) {
3798b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng
3808b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        final CallCardUi ui = getUi();
3818b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        if (ui == null) {
3828b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            return;
3838b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        }
3848b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng
385625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon        final boolean isGenericConf = isGenericConference(mSecondary);
3868b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        if (mSecondaryContactInfo != null) {
3878b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            Log.d(TAG, "updateSecondaryDisplayInfo() " + mSecondaryContactInfo);
3884be1bdd9ee8e9d3afa1aaa765e86b963fb6c7b3dYorke Lee            final String nameForCall = getNameForCall(mSecondaryContactInfo);
3894be1bdd9ee8e9d3afa1aaa765e86b963fb6c7b3dYorke Lee
3904be1bdd9ee8e9d3afa1aaa765e86b963fb6c7b3dYorke Lee            final boolean nameIsNumber = nameForCall != null && nameForCall.equals(
3914be1bdd9ee8e9d3afa1aaa765e86b963fb6c7b3dYorke Lee                    mSecondaryContactInfo.number);
3924be1bdd9ee8e9d3afa1aaa765e86b963fb6c7b3dYorke Lee            ui.setSecondary(true, nameForCall, nameIsNumber, mSecondaryContactInfo.label,
393625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon                    mSecondaryContactInfo.photo, isConference, isGenericConf);
3948b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        } else {
3958b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            // reset to nothing so that it starts off blank next time we use it.
396625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon            ui.setSecondary(false, null, false, null, null, isConference, isGenericConf);
3978b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        }
3988b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng    }
3998b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng
4003d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon    /**
4013d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon     * Returns the gateway number for any existing outgoing call.
4023d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon     */
4033d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon    private String getGatewayNumber() {
4043d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon        if (hasOutgoingGatewayCall()) {
40507a822b2ea92dc5b68cd43139be7efe4c6640cd4Sailesh Nepal            return mPrimary.getGatewayInfo().getGatewayHandle().getSchemeSpecificPart();
4063d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon        }
4073d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon        return null;
4083d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon    }
4093d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon
4103d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon    /**
4113d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon     * Returns the label for the gateway app for any existing outgoing call.
4123d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon     */
4133d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon    private String getGatewayLabel() {
4143d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon        if (hasOutgoingGatewayCall() && getUi() != null) {
4153d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon            final PackageManager pm = mContext.getPackageManager();
4163d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon            try {
41707a822b2ea92dc5b68cd43139be7efe4c6640cd4Sailesh Nepal                ApplicationInfo info = pm.getApplicationInfo(
41807a822b2ea92dc5b68cd43139be7efe4c6640cd4Sailesh Nepal                        mPrimary.getGatewayInfo().getGatewayProviderPackageName(), 0);
4193d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon                return mContext.getString(R.string.calling_via_template,
4203d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon                        pm.getApplicationLabel(info).toString());
4213d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon            } catch (PackageManager.NameNotFoundException e) {
4223d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon            }
4233d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon        }
4243d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon        return null;
4253d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon    }
4263d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon
4273d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon    private boolean hasOutgoingGatewayCall() {
4283d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon        // We only display the gateway information while DIALING so return false for any othe
4293d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon        // call state.
4308b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        // TODO: mPrimary can be null because this is called from updatePrimaryDisplayInfo which
4318b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        // is also called after a contact search completes (call is not present yet).  Split the
4328b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        // UI update so it can receive independent updates.
4338b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        if (mPrimary == null) {
4348b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng            return false;
4358b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        }
43607a822b2ea92dc5b68cd43139be7efe4c6640cd4Sailesh Nepal        return Call.State.isDialing(mPrimary.getState()) && mPrimary.getGatewayInfo() != null &&
43707a822b2ea92dc5b68cd43139be7efe4c6640cd4Sailesh Nepal                !mPrimary.getGatewayInfo().isEmpty();
4383d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon    }
4393d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon
4401df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon    /**
4411df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon     * Gets the name to display for the call.
4421df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon     */
4431df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon    private static String getNameForCall(ContactCacheEntry contactInfo) {
4441df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon        if (TextUtils.isEmpty(contactInfo.name)) {
4451df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon            return contactInfo.number;
446988d06b64b99a13f4f060dc82594edcb738d9113Yorke Lee        }
4471df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon        return contactInfo.name;
4481df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon    }
449988d06b64b99a13f4f060dc82594edcb738d9113Yorke Lee
4501df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon    /**
4511df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon     * Gets the number to display for a call.
4521df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon     */
4531df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon    private static String getNumberForCall(ContactCacheEntry contactInfo) {
4541df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon        // If the name is empty, we use the number for the name...so dont show a second
4551df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon        // number in the number field
4561df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon        if (TextUtils.isEmpty(contactInfo.name)) {
457101bed44998ff35c3a56f431345fac5c8229ec0eJay Shrauner            return contactInfo.location;
4581df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon        }
4591df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon        return contactInfo.number;
4604bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon    }
461988d06b64b99a13f4f060dc82594edcb738d9113Yorke Lee
4629240895e9df2fcae8f0baea707eb4d24c6e50997Yorke Lee    public void secondaryPhotoClicked() {
4636f767fb5d92b7e07315b86ddf1de1f25e7354bc0Yorke Lee        if (mSecondary == null) {
4646f767fb5d92b7e07315b86ddf1de1f25e7354bc0Yorke Lee            Log.wtf(this, "Secondary photo clicked but no secondary call.");
4656f767fb5d92b7e07315b86ddf1de1f25e7354bc0Yorke Lee            return;
4666f767fb5d92b7e07315b86ddf1de1f25e7354bc0Yorke Lee        }
4676f767fb5d92b7e07315b86ddf1de1f25e7354bc0Yorke Lee
468fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal        Log.i(this, "Swapping call to foreground: " + mSecondary);
469fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal        TelecommAdapter.getInstance().unholdCall(mSecondary.getCallId());
4709240895e9df2fcae8f0baea707eb4d24c6e50997Yorke Lee    }
4719240895e9df2fcae8f0baea707eb4d24c6e50997Yorke Lee
4724bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon    public interface CallCardUi extends Ui {
4734bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon        void setVisible(boolean on);
4741df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon        void setPrimary(String number, String name, boolean nameIsNumber, String label,
475625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon                Drawable photo, boolean isConference, boolean isGeneric, boolean isSipCall);
4764be1bdd9ee8e9d3afa1aaa765e86b963fb6c7b3dYorke Lee        void setSecondary(boolean show, String name, boolean nameIsNumber, String label,
477625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon                Drawable photo, boolean isConference, boolean isGeneric);
47814dbc3f0ca3a7998c9c5d28aba637487724f529fSantos Cordon        void setSecondaryImage(Drawable image);
479a81667248196be225849f7739f64752dc578f6bbAnders Kristensen        void setCallState(int state, int cause, boolean bluetoothOn,
4800be676b7151d87f4d4d5244a859b14cb12621bf3Chiao Cheng                String gatewayLabel, String gatewayNumber, String wifiConnection);
48188dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon        void setPrimaryCallElapsedTime(boolean show, String duration);
4828b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        void setPrimaryName(String name, boolean nameIsNumber);
48314dbc3f0ca3a7998c9c5d28aba637487724f529fSantos Cordon        void setPrimaryImage(Drawable image);
4848b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        void setPrimaryPhoneNumber(String phoneNumber);
4858b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng        void setPrimaryLabel(String label);
4867ef707319c0e3563ff92a772ba53cb5dca0e3ae1Yorke Lee    }
487a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon}
488