CallCardPresenter.java revision f8b0677bed382046cb26e38a8442a9509d1e835c
1c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon/*
2c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon * Copyright (C) 2013 The Android Open Source Project
3c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon *
4c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon * Licensed under the Apache License, Version 2.0 (the "License");
5c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon * you may not use this file except in compliance with the License.
6c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon * You may obtain a copy of the License at
7c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon *
8c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon *      http://www.apache.org/licenses/LICENSE-2.0
9c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon *
10c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon * Unless required by applicable law or agreed to in writing, software
11c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon * distributed under the License is distributed on an "AS IS" BASIS,
12c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon * See the License for the specific language governing permissions and
14c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon * limitations under the License
15c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon */
16c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon
17c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordonpackage com.android.incallui;
18c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon
193d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordonimport android.content.Context;
203d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordonimport android.content.pm.ApplicationInfo;
213d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordonimport android.content.pm.PackageManager;
226d231f52e4f00399330d772f2a337283803f3a9dYorke Leeimport android.graphics.drawable.Drawable;
23f27342bc5d594dfc32dc2bfafe109dcaa6b6d506Sailesh Nepalimport android.telecomm.CallCapabilities;
24c6f4e50a4130fb8f7247f5eab6849829701ad484Sailesh Nepalimport android.telecomm.CallServiceDescriptor;
25df22018185375d2de96673ee8f16d1520283d662Ihab Awadimport android.telecomm.PhoneAccount;
26479c50f6d4fac0fa44210c9bad4346f64dba3f1eAnders Kristensenimport android.telephony.DisconnectCause;
27d28fc12696fa706fed70e04698275af7be7fee82Santos Cordonimport android.text.TextUtils;
288cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordonimport android.text.format.DateUtils;
29be8060acf5ecbb916c161d3249813098c0611ed5Yorke Lee
301b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordonimport com.android.incallui.AudioModeProvider.AudioModeListener;
31d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordonimport com.android.incallui.ContactInfoCache.ContactCacheEntry;
32d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordonimport com.android.incallui.ContactInfoCache.ContactInfoCacheCallback;
337ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordonimport com.android.incallui.InCallPresenter.InCallState;
347ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordonimport com.android.incallui.InCallPresenter.InCallStateListener;
351c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordonimport com.android.incallui.InCallPresenter.IncomingCallListener;
361b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordonimport com.android.services.telephony.common.AudioMode;
37bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen
3842373eb59cbef15ec61ebb5c919031f293291a53Chiao Chengimport com.google.common.base.Preconditions;
39c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon
40c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon/**
41c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon * Presenter for the Call Card Fragment.
42033ed5926d2924d35b9c82898ab4e835da56b3afChiao Cheng * <p>
437ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon * This class listens for changes to InCallState and passes it along to the fragment.
44c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon */
45d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordonpublic class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
461c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon        implements InCallStateListener, AudioModeListener, IncomingCallListener {
47be8060acf5ecbb916c161d3249813098c0611ed5Yorke Lee
48033ed5926d2924d35b9c82898ab4e835da56b3afChiao Cheng    private static final String TAG = CallCardPresenter.class.getSimpleName();
498cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon    private static final long CALL_TIME_UPDATE_INTERVAL = 1000; // in milliseconds
508cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon
511b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    private Call mPrimary;
52d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    private Call mSecondary;
53d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    private ContactCacheEntry mPrimaryContactInfo;
54d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    private ContactCacheEntry mSecondaryContactInfo;
558cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon    private CallTimer mCallTimer;
563d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    private Context mContext;
576d231f52e4f00399330d772f2a337283803f3a9dYorke Lee
58b8eedb3b9796873eaa22847205239a51092f1a43Santos Cordon    public CallCardPresenter() {
598cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        // create the call timer
608cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        mCallTimer = new CallTimer(new Runnable() {
618cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon            @Override
628cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon            public void run() {
638cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon                updateCallTime();
648cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon            }
658cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        });
666d231f52e4f00399330d772f2a337283803f3a9dYorke Lee    }
676d231f52e4f00399330d772f2a337283803f3a9dYorke Lee
6842373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
691c6bb983216392b5ceb36cea42a46631f68a3dd6Jay Shrauner    public void init(Context context, Call call) {
7042373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        mContext = Preconditions.checkNotNull(context);
7142373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
724a5339c4a266891ce560dfb6e348c3779a0a3ca1Chiao Cheng        // Call may be null if disconnect happened already.
734a5339c4a266891ce560dfb6e348c3779a0a3ca1Chiao Cheng        if (call != null) {
74656dd4a0d8571b47ecf0ecf3e4c2eeacfd1099b3Chiao Cheng            mPrimary = call;
75656dd4a0d8571b47ecf0ecf3e4c2eeacfd1099b3Chiao Cheng
764a5339c4a266891ce560dfb6e348c3779a0a3ca1Chiao Cheng            // start processing lookups right away.
77812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            if (!call.isConferenceCall()) {
78248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal                startContactInfoSearch(call, true, call.getState() == Call.State.INCOMING);
79812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            } else {
80812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon                updateContactEntry(null, true, true);
81812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            }
824a5339c4a266891ce560dfb6e348c3779a0a3ca1Chiao Cheng        }
83033ed5926d2924d35b9c82898ab4e835da56b3afChiao Cheng    }
84033ed5926d2924d35b9c82898ab4e835da56b3afChiao Cheng
85c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon    @Override
86c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon    public void onUiReady(CallCardUi ui) {
87c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon        super.onUiReady(ui);
881b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon
891f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon        AudioModeProvider.getInstance().addListener(this);
901f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon
9142373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        // Contact search may have completed before ui is ready.
9242373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        if (mPrimaryContactInfo != null) {
93314b2aaa1fa1ef799270987e964f7df4d983b9eeChristine Chen            updatePrimaryDisplayInfo(mPrimaryContactInfo, isConference(mPrimary));
9442373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        }
9542373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
961f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon        // Register for call state changes last
971f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon        InCallPresenter.getInstance().addListener(this);
981c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon        InCallPresenter.getInstance().addIncomingCallListener(this);
991b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    }
1001b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon
1011b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    @Override
1021b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    public void onUiUnready(CallCardUi ui) {
1031b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon        super.onUiUnready(ui);
1041b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon
1051f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon        // stop getting call state changes
1061f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon        InCallPresenter.getInstance().removeListener(this);
1071c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon        InCallPresenter.getInstance().removeIncomingCallListener(this);
1081f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon
1091f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon        AudioModeProvider.getInstance().removeListener(this);
1101f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon
1111b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon        mPrimary = null;
112d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        mPrimaryContactInfo = null;
113d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        mSecondaryContactInfo = null;
114c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon    }
115c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon
116c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon    @Override
1171c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon    public void onIncomingCall(InCallState state, Call call) {
1181c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon        // same logic should happen as with onStateChange()
1191c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon        onStateChange(state, CallList.getInstance());
1201c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon    }
1211c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon
1221c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon    @Override
1237ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon    public void onStateChange(InCallState state, CallList callList) {
1247a863a056a96638c32171f721d99c694a1890df8Christine Chen        Log.d(this, "onStateChange() " + state);
12575c86b55d45b1725c46ed2e5d77c9c43fcfd93daSantos Cordon        final CallCardUi ui = getUi();
1261b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon        if (ui == null) {
1271b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon            return;
1281b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon        }
129c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon
1307ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon        Call primary = null;
1317ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon        Call secondary = null;
1327ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon
1337ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon        if (state == InCallState.INCOMING) {
1347ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon            primary = callList.getIncomingCall();
135950e3df8ac744daf2a890d279566bdba424710f9Santos Cordon        } else if (state == InCallState.OUTGOING) {
136950e3df8ac744daf2a890d279566bdba424710f9Santos Cordon            primary = callList.getOutgoingCall();
137950e3df8ac744daf2a890d279566bdba424710f9Santos Cordon
13882f5d003e675dfd56735c745744c3d968883b23cSantos Cordon            // getCallToDisplay doesn't go through outgoing or incoming calls. It will return the
13982f5d003e675dfd56735c745744c3d968883b23cSantos Cordon            // highest priority call to display as the secondary call.
140d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            secondary = getCallToDisplay(callList, null, true);
1417ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon        } else if (state == InCallState.INCALL) {
142d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            primary = getCallToDisplay(callList, null, false);
143d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            secondary = getCallToDisplay(callList, primary, true);
1447ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon        }
1457ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon
146a4bd83ad639b349fa16dbd07225017fcbf6ed550Chiao Cheng        Log.d(this, "Primary call: " + primary);
147a4bd83ad639b349fa16dbd07225017fcbf6ed550Chiao Cheng        Log.d(this, "Secondary call: " + secondary);
1487ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon
149812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        final boolean primaryChanged = !areCallsSame(mPrimary, primary);
150812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        final boolean secondaryChanged = !areCallsSame(mSecondary, secondary);
151812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        mSecondary = secondary;
152812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        mPrimary = primary;
153812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon
154812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        if (primaryChanged && mPrimary != null) {
155812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            // primary call has changed
156248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal            mPrimaryContactInfo = ContactInfoCache.buildCacheEntryFromCall(mContext, mPrimary,
157248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal                    mPrimary.getState() == Call.State.INCOMING);
158812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            updatePrimaryDisplayInfo(mPrimaryContactInfo, isConference(mPrimary));
159812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            maybeStartSearch(mPrimary, true);
16042373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        }
16142373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
162812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        if (mSecondary == null) {
16342373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            // Secondary call may have ended.  Update the ui.
16442373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            mSecondaryContactInfo = null;
1655345442d7238c1db00dc8d55a49f7f5dd713d994Christine Chen            updateSecondaryDisplayInfo(false);
166812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        } else if (secondaryChanged) {
167812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            // secondary call has changed
168248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal            mSecondaryContactInfo = ContactInfoCache.buildCacheEntryFromCall(mContext, mSecondary,
169248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal                    mSecondary.getState() == Call.State.INCOMING);
170812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            updateSecondaryDisplayInfo(mSecondary.isConferenceCall());
171812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            maybeStartSearch(mSecondary, false);
17242373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        }
17342373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
1748cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        // Start/Stop the call time update timer
1758cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        if (mPrimary != null && mPrimary.getState() == Call.State.ACTIVE) {
176a4bd83ad639b349fa16dbd07225017fcbf6ed550Chiao Cheng            Log.d(this, "Starting the calltime timer");
1778cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon            mCallTimer.start(CALL_TIME_UPDATE_INTERVAL);
1788cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        } else {
179a4bd83ad639b349fa16dbd07225017fcbf6ed550Chiao Cheng            Log.d(this, "Canceling the calltime timer");
1808cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon            mCallTimer.cancel();
1818cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon            ui.setPrimaryCallElapsedTime(false, null);
1828cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        }
1838cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon
184d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        // Set the call state
1858aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton        int callState = Call.State.IDLE;
186d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        if (mPrimary != null) {
18732027ae1f52232258cc8133d383459f3b4ee57e4Yorke Lee            callState = mPrimary.getState();
1881f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon            final boolean bluetoothOn =
1891f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon                    (AudioModeProvider.getInstance().getAudioMode() == AudioMode.BLUETOOTH);
19046848bb9b89cc5417afae19aaab38fe331a7b474Sailesh Nepal
1918aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton            getUi().setCallState(callState, mPrimary.getDisconnectCause(), bluetoothOn,
192f8b0677bed382046cb26e38a8442a9509d1e835cSailesh Nepal                    getConnectionLabel(), getConnectionIcon(), getGatewayNumber());
19382f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        } else {
194f8b0677bed382046cb26e38a8442a9509d1e835cSailesh Nepal            getUi().setCallState(callState, DisconnectCause.NOT_VALID, false, null, null, null);
19582f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        }
196e26b887e90d5e9566a5054a1ccb3ed32ae2eea2dAndrew Lee
1978aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton        final boolean enableEndCallButton = Call.State.isConnected(callState) &&
1988aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton                callState != Call.State.INCOMING && mPrimary != null;
1999fc169931b9904ee8eac27bacd858ab87753e33dEvan Charlton        getUi().setEndCallButtonEnabled(enableEndCallButton);
2001b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    }
2011b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon
2021b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    @Override
2031b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    public void onAudioMode(int mode) {
2041b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon        if (mPrimary != null && getUi() != null) {
2051b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon            final boolean bluetoothOn = (AudioMode.BLUETOOTH == mode);
2061b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon
207ad4f3ea753b6dc43b1a82110c9fdf505966e74fbMakoto Onuki            getUi().setCallState(mPrimary.getState(), mPrimary.getDisconnectCause(), bluetoothOn,
208f8b0677bed382046cb26e38a8442a9509d1e835cSailesh Nepal                    getConnectionLabel(), getConnectionIcon(), getGatewayNumber());
2091b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon        }
2101b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    }
2111b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon
2121b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    @Override
2131b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    public void onSupportedAudioMode(int mask) {
214c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon    }
215c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon
2168c478132fbc07bd075df6aba85bcfd2990bbd66aSantos Cordon    @Override
2178c478132fbc07bd075df6aba85bcfd2990bbd66aSantos Cordon    public void onMute(boolean muted) {
2188c478132fbc07bd075df6aba85bcfd2990bbd66aSantos Cordon    }
2198c478132fbc07bd075df6aba85bcfd2990bbd66aSantos Cordon
2208cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon    public void updateCallTime() {
2218cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        final CallCardUi ui = getUi();
2228cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon
2238cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        if (ui == null || mPrimary == null || mPrimary.getState() != Call.State.ACTIVE) {
224899251968ee4ee3cb375032185653ecd888e3f8dSantos Cordon            if (ui != null) {
225899251968ee4ee3cb375032185653ecd888e3f8dSantos Cordon                ui.setPrimaryCallElapsedTime(false, null);
226899251968ee4ee3cb375032185653ecd888e3f8dSantos Cordon            }
2278cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon            mCallTimer.cancel();
228899251968ee4ee3cb375032185653ecd888e3f8dSantos Cordon        } else {
229c6f4e50a4130fb8f7247f5eab6849829701ad484Sailesh Nepal            final long callStart = mPrimary.getConnectTimeMillis();
230899251968ee4ee3cb375032185653ecd888e3f8dSantos Cordon            final long duration = System.currentTimeMillis() - callStart;
231899251968ee4ee3cb375032185653ecd888e3f8dSantos Cordon            ui.setPrimaryCallElapsedTime(true, DateUtils.formatElapsedTime(duration / 1000));
2328cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        }
2338cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon    }
2348cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon
235f8b0677bed382046cb26e38a8442a9509d1e835cSailesh Nepal    public void phoneAccountClicked() {
2368aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton        if (mPrimary == null) {
2378aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton            return;
2388aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton        }
239f8b0677bed382046cb26e38a8442a9509d1e835cSailesh Nepal        TelecommAdapter.getInstance().phoneAccountClicked(mPrimary.getCallId());
2408aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton    }
2418aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton
242812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon    private boolean areCallsSame(Call call1, Call call2) {
243812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        if (call1 == null && call2 == null) {
244812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            return true;
245812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        } else if (call1 == null || call2 == null) {
246812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            return false;
247812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        }
248812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon
249812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        // otherwise compare call Ids
2507b2248bfff11c50e208908cb74b5f94b3ad7a3c0Sailesh Nepal        return call1.getCallId().equals(call2.getCallId());
251812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon    }
252812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon
253812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon    private void maybeStartSearch(Call call, boolean isPrimary) {
254812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        // no need to start search for conference calls which show generic info.
255812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        if (call != null && !call.isConferenceCall()) {
256248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal            startContactInfoSearch(call, isPrimary, call.getState() == Call.State.INCOMING);
257812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        }
258812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon    }
259812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon
26082f5d003e675dfd56735c745744c3d968883b23cSantos Cordon    /**
261d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon     * Starts a query for more contact data for the save primary and secondary calls.
262d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon     */
263248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal    private void startContactInfoSearch(final Call call, final boolean isPrimary,
264248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal            boolean isIncoming) {
26542373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        final ContactInfoCache cache = ContactInfoCache.getInstance(mContext);
26642373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
267248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal        cache.findInfo(call, isIncoming, new ContactInfoCacheCallback() {
26842373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng                @Override
2697b2248bfff11c50e208908cb74b5f94b3ad7a3c0Sailesh Nepal                public void onContactInfoComplete(String callId, ContactCacheEntry entry) {
270812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon                    updateContactEntry(entry, isPrimary, false);
2711c6bb983216392b5ceb36cea42a46631f68a3dd6Jay Shrauner                    if (entry.name != null) {
2721c6bb983216392b5ceb36cea42a46631f68a3dd6Jay Shrauner                        Log.d(TAG, "Contact found: " + entry);
27342373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng                    }
2747e7fd2a0642515834a96028937f60ec955edfd91Yorke Lee                    if (entry.personUri != null) {
2757e7fd2a0642515834a96028937f60ec955edfd91Yorke Lee                        CallerInfoUtils.sendViewNotification(mContext, entry.personUri);
2767e7fd2a0642515834a96028937f60ec955edfd91Yorke Lee                    }
27742373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng                }
2787d2fb8620b808c28c49bde99dc54f6de46fdcb44Chiao Cheng
2797d2fb8620b808c28c49bde99dc54f6de46fdcb44Chiao Cheng                @Override
2807b2248bfff11c50e208908cb74b5f94b3ad7a3c0Sailesh Nepal                public void onImageLoadComplete(String callId, ContactCacheEntry entry) {
28102ade580384ccd853b6a9909aa0b4423fada84dfChristine Chen                    if (getUi() == null) {
28202ade580384ccd853b6a9909aa0b4423fada84dfChristine Chen                        return;
28302ade580384ccd853b6a9909aa0b4423fada84dfChristine Chen                    }
28449ff6571403695e81dbbd83e4f61790ce9c75f6dSantos Cordon                    if (entry.photo != null) {
2857b2248bfff11c50e208908cb74b5f94b3ad7a3c0Sailesh Nepal                        if (mPrimary != null && callId.equals(mPrimary.getCallId())) {
28649ff6571403695e81dbbd83e4f61790ce9c75f6dSantos Cordon                            getUi().setPrimaryImage(entry.photo);
28749ff6571403695e81dbbd83e4f61790ce9c75f6dSantos Cordon                        }
2887d2fb8620b808c28c49bde99dc54f6de46fdcb44Chiao Cheng                    }
2897d2fb8620b808c28c49bde99dc54f6de46fdcb44Chiao Cheng                }
29042373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            });
29142373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng    }
29242373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
293812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon    private static boolean isConference(Call call) {
294812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        return call != null && call.isConferenceCall();
295812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon    }
296812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon
297812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon    private static boolean isGenericConference(Call call) {
298f27342bc5d594dfc32dc2bfafe109dcaa6b6d506Sailesh Nepal        return call != null && call.can(CallCapabilities.GENERIC_CONFERENCE);
29942373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng    }
300d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon
30142373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng    private void updateContactEntry(ContactCacheEntry entry, boolean isPrimary,
30242373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            boolean isConference) {
30342373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        if (isPrimary) {
30442373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            mPrimaryContactInfo = entry;
30542373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            updatePrimaryDisplayInfo(entry, isConference);
306d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        } else {
30742373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            mSecondaryContactInfo = entry;
3085345442d7238c1db00dc8d55a49f7f5dd713d994Christine Chen            updateSecondaryDisplayInfo(isConference);
309d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        }
310d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    }
311d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon
312d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    /**
31382f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     * Get the highest priority call to display.
31482f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     * Goes through the calls and chooses which to return based on priority of which type of call
31582f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     * to display to the user. Callers can use the "ignore" feature to get the second best call
31682f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     * by passing a previously found primary call as ignore.
31782f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     *
31882f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     * @param ignore A call to ignore if found.
31982f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     */
320d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    private Call getCallToDisplay(CallList callList, Call ignore, boolean skipDisconnected) {
32182f5d003e675dfd56735c745744c3d968883b23cSantos Cordon
322d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        // Active calls come second.  An active call always gets precedent.
323d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        Call retval = callList.getActiveCall();
32482f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        if (retval != null && retval != ignore) {
32582f5d003e675dfd56735c745744c3d968883b23cSantos Cordon            return retval;
32682f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        }
32782f5d003e675dfd56735c745744c3d968883b23cSantos Cordon
328d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        // Disconnected calls get primary position if there are no active calls
329d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        // to let user know quickly what call has disconnected. Disconnected
330d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        // calls are very short lived.
331d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        if (!skipDisconnected) {
3326258ff60a7edc760facc3f387fc9c8ceee3fb518Christine Chen            retval = callList.getDisconnectingCall();
3336258ff60a7edc760facc3f387fc9c8ceee3fb518Christine Chen            if (retval != null && retval != ignore) {
3346258ff60a7edc760facc3f387fc9c8ceee3fb518Christine Chen                return retval;
3356258ff60a7edc760facc3f387fc9c8ceee3fb518Christine Chen            }
336d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            retval = callList.getDisconnectedCall();
337d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            if (retval != null && retval != ignore) {
338d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon                return retval;
339d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            }
34082f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        }
34182f5d003e675dfd56735c745744c3d968883b23cSantos Cordon
34282f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        // Then we go to background call (calls on hold)
34382f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        retval = callList.getBackgroundCall();
34482f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        if (retval != null && retval != ignore) {
34582f5d003e675dfd56735c745744c3d968883b23cSantos Cordon            return retval;
34682f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        }
34782f5d003e675dfd56735c745744c3d968883b23cSantos Cordon
34882f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        // Lastly, we go to a second background call.
34982f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        retval = callList.getSecondBackgroundCall();
35082f5d003e675dfd56735c745744c3d968883b23cSantos Cordon
35182f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        return retval;
35282f5d003e675dfd56735c745744c3d968883b23cSantos Cordon    }
35382f5d003e675dfd56735c745744c3d968883b23cSantos Cordon
35442373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng    private void updatePrimaryDisplayInfo(ContactCacheEntry entry, boolean isConference) {
35542373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        Log.d(TAG, "Update primary display " + entry);
3566d231f52e4f00399330d772f2a337283803f3a9dYorke Lee        final CallCardUi ui = getUi();
357d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        if (ui == null) {
35842373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            // TODO: May also occur if search result comes back after ui is destroyed. Look into
35942373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            // removing that case completely.
36042373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            Log.d(TAG, "updatePrimaryDisplayInfo called but ui is null!");
361d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon            return;
3626d231f52e4f00399330d772f2a337283803f3a9dYorke Lee        }
363be8060acf5ecbb916c161d3249813098c0611ed5Yorke Lee
364812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        final boolean isGenericConf = isGenericConference(mPrimary);
36542373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        if (entry != null) {
36642373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            final String name = getNameForCall(entry);
36742373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            final String number = getNumberForCall(entry);
36842373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            final boolean nameIsNumber = name != null && name.equals(entry.number);
36942373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            ui.setPrimary(number, name, nameIsNumber, entry.label,
370812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon                    entry.photo, isConference, isGenericConf, entry.isSipCall);
3716d231f52e4f00399330d772f2a337283803f3a9dYorke Lee        } else {
372812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            ui.setPrimary(null, null, false, null, null, isConference, isGenericConf, false);
373d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        }
374d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon
375d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    }
376d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon
3775345442d7238c1db00dc8d55a49f7f5dd713d994Christine Chen    private void updateSecondaryDisplayInfo(boolean isConference) {
37842373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
37942373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        final CallCardUi ui = getUi();
38042373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        if (ui == null) {
38142373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            return;
38242373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        }
38342373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
384812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        final boolean isGenericConf = isGenericConference(mSecondary);
38542373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        if (mSecondaryContactInfo != null) {
38642373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            Log.d(TAG, "updateSecondaryDisplayInfo() " + mSecondaryContactInfo);
387c4bacb09c398a615154dc97b066179e77dc57599Yorke Lee            final String nameForCall = getNameForCall(mSecondaryContactInfo);
388c4bacb09c398a615154dc97b066179e77dc57599Yorke Lee
389c4bacb09c398a615154dc97b066179e77dc57599Yorke Lee            final boolean nameIsNumber = nameForCall != null && nameForCall.equals(
390c4bacb09c398a615154dc97b066179e77dc57599Yorke Lee                    mSecondaryContactInfo.number);
391e5c0d8bdf8269f9435e0381889e4870f36a43f07Andrew Lee            ui.setSecondary(true /* show */, nameForCall, nameIsNumber, mSecondaryContactInfo.label,
392bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen                    getSecondaryCallProviderLabel(), getSecondaryCallProviderIcon(),
393e5c0d8bdf8269f9435e0381889e4870f36a43f07Andrew Lee                    isConference, isGenericConf);
39442373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        } else {
39542373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            // reset to nothing so that it starts off blank next time we use it.
396bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen            ui.setSecondary(false, null, false, null, null, null, isConference, isGenericConf);
39742373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        }
39842373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng    }
39942373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
4003d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    /**
4013d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon     * Returns the gateway number for any existing outgoing call.
4023d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon     */
4033d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    private String getGatewayNumber() {
4043d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        if (hasOutgoingGatewayCall()) {
405ae73c9aab1c716d9ef85f4f0dbc6f69e97a8f7e6Sailesh Nepal            return mPrimary.getGatewayInfo().getGatewayHandle().getSchemeSpecificPart();
4063d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        }
4073d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        return null;
4083d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    }
4093d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon
4103d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    /**
411bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen     * Return the Drawable object of the icon to display to the left of the connection label.
412bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen     */
413bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen    private Drawable getConnectionIcon() {
414df22018185375d2de96673ee8f16d1520283d662Ihab Awad        PhoneAccount account = mPrimary.getAccount();
415df22018185375d2de96673ee8f16d1520283d662Ihab Awad        if (account != null) {
416df22018185375d2de96673ee8f16d1520283d662Ihab Awad            return account.getIcon(mContext);
417bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen        }
418bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen        return null;
419bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen    }
420bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen
421bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen    /**
422bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen     * Returns the label (line of text above the number/name) for any given call.
423f8b0677bed382046cb26e38a8442a9509d1e835cSailesh Nepal     * For example, "calling via [Account/Google Voice]" for outgoing calls.
4243d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon     */
425bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen    private String getConnectionLabel() {
4263d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        if (hasOutgoingGatewayCall() && getUi() != null) {
427bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen            // Return the label for the gateway app on outgoing calls.
4283d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon            final PackageManager pm = mContext.getPackageManager();
4293d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon            try {
430ae73c9aab1c716d9ef85f4f0dbc6f69e97a8f7e6Sailesh Nepal                ApplicationInfo info = pm.getApplicationInfo(
431ae73c9aab1c716d9ef85f4f0dbc6f69e97a8f7e6Sailesh Nepal                        mPrimary.getGatewayInfo().getGatewayProviderPackageName(), 0);
432bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen                return pm.getApplicationLabel(info).toString();
4333d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon            } catch (PackageManager.NameNotFoundException e) {
434bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen                Log.e(this, "Gateway Application Not Found.", e);
435bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen                return null;
4363d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon            }
4373d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        }
438df22018185375d2de96673ee8f16d1520283d662Ihab Awad        PhoneAccount account = mPrimary.getAccount();
439f8b0677bed382046cb26e38a8442a9509d1e835cSailesh Nepal        if (account != null) {
440f8b0677bed382046cb26e38a8442a9509d1e835cSailesh Nepal            return account.getLabel(mContext);
441bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen        }
442bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen        return null;
443bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen    }
444bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen
445bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen    private String getSecondaryCallProviderLabel() {
446df22018185375d2de96673ee8f16d1520283d662Ihab Awad        PhoneAccount account = mSecondary.getAccount();
447df22018185375d2de96673ee8f16d1520283d662Ihab Awad        if (account != null) {
448df22018185375d2de96673ee8f16d1520283d662Ihab Awad            return account.getLabel(mContext);
449bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen        }
450bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen        return null;
451bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen    }
452bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen
453bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen    private Drawable getSecondaryCallProviderIcon() {
454df22018185375d2de96673ee8f16d1520283d662Ihab Awad        PhoneAccount account = mSecondary.getAccount();
455df22018185375d2de96673ee8f16d1520283d662Ihab Awad        if (account != null) {
456df22018185375d2de96673ee8f16d1520283d662Ihab Awad            return account.getIcon(mContext);
457bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen        }
4583d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        return null;
4593d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    }
4603d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon
4613d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    private boolean hasOutgoingGatewayCall() {
4623d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        // We only display the gateway information while DIALING so return false for any othe
4633d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        // call state.
46442373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        // TODO: mPrimary can be null because this is called from updatePrimaryDisplayInfo which
46542373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        // is also called after a contact search completes (call is not present yet).  Split the
46642373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        // UI update so it can receive independent updates.
46742373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        if (mPrimary == null) {
46842373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            return false;
46942373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        }
470ae73c9aab1c716d9ef85f4f0dbc6f69e97a8f7e6Sailesh Nepal        return Call.State.isDialing(mPrimary.getState()) && mPrimary.getGatewayInfo() != null &&
471ae73c9aab1c716d9ef85f4f0dbc6f69e97a8f7e6Sailesh Nepal                !mPrimary.getGatewayInfo().isEmpty();
4723d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    }
4733d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon
474d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    /**
475d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon     * Gets the name to display for the call.
476d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon     */
477d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    private static String getNameForCall(ContactCacheEntry contactInfo) {
478d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        if (TextUtils.isEmpty(contactInfo.name)) {
479d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            return contactInfo.number;
4806d231f52e4f00399330d772f2a337283803f3a9dYorke Lee        }
481d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        return contactInfo.name;
482d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    }
4836d231f52e4f00399330d772f2a337283803f3a9dYorke Lee
484d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    /**
485d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon     * Gets the number to display for a call.
486d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon     */
487d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    private static String getNumberForCall(ContactCacheEntry contactInfo) {
488d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        // If the name is empty, we use the number for the name...so dont show a second
489d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        // number in the number field
490d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        if (TextUtils.isEmpty(contactInfo.name)) {
4911c6bb983216392b5ceb36cea42a46631f68a3dd6Jay Shrauner            return contactInfo.location;
492d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        }
493d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        return contactInfo.number;
494d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    }
4956d231f52e4f00399330d772f2a337283803f3a9dYorke Lee
496e5c0d8bdf8269f9435e0381889e4870f36a43f07Andrew Lee    public void secondaryInfoClicked() {
49780c49a823543c9fb93420d05a6375fb1ff4ca631Yorke Lee        if (mSecondary == null) {
498e5c0d8bdf8269f9435e0381889e4870f36a43f07Andrew Lee            Log.wtf(this, "Secondary info clicked but no secondary call.");
49980c49a823543c9fb93420d05a6375fb1ff4ca631Yorke Lee            return;
50080c49a823543c9fb93420d05a6375fb1ff4ca631Yorke Lee        }
50180c49a823543c9fb93420d05a6375fb1ff4ca631Yorke Lee
502248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal        Log.i(this, "Swapping call to foreground: " + mSecondary);
503248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal        TelecommAdapter.getInstance().unholdCall(mSecondary.getCallId());
50490995fcb6778a9cb6dc35be12aeb1a5d0dcbb5aeYorke Lee    }
50590995fcb6778a9cb6dc35be12aeb1a5d0dcbb5aeYorke Lee
5067e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee    public void endCallClicked() {
5077e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee        if (mPrimary == null) {
5087e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee            return;
5097e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee        }
5107e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee
511cb2f51bf1acf387f391ca9c8cae8a2344eb2936aEvan Charlton        Log.i(this, "Disconnecting call: " + mPrimary);
512cb2f51bf1acf387f391ca9c8cae8a2344eb2936aEvan Charlton        TelecommAdapter.getInstance().disconnectCall(mPrimary.getCallId());
5137e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee    }
5147e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee
515d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    public interface CallCardUi extends Ui {
516d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        void setVisible(boolean on);
517d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        void setPrimary(String number, String name, boolean nameIsNumber, String label,
518812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon                Drawable photo, boolean isConference, boolean isGeneric, boolean isSipCall);
519c4bacb09c398a615154dc97b066179e77dc57599Yorke Lee        void setSecondary(boolean show, String name, boolean nameIsNumber, String label,
520bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen                String providerLabel, Drawable providerIcon, boolean isConference,
521bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen                boolean isGeneric);
522bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen        void setCallState(int state, int cause, boolean bluetoothOn, String connectionLabel,
523f8b0677bed382046cb26e38a8442a9509d1e835cSailesh Nepal                Drawable connectionIcon, String gatewayNumber);
5248cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        void setPrimaryCallElapsedTime(boolean show, String duration);
52542373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        void setPrimaryName(String name, boolean nameIsNumber);
52649ff6571403695e81dbbd83e4f61790ce9c75f6dSantos Cordon        void setPrimaryImage(Drawable image);
52742373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        void setPrimaryPhoneNumber(String phoneNumber);
52842373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        void setPrimaryLabel(String label);
529e26b887e90d5e9566a5054a1ccb3ed32ae2eea2dAndrew Lee        void setEndCallButtonEnabled(boolean enabled);
530be8060acf5ecbb916c161d3249813098c0611ed5Yorke Lee    }
531c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon}
532