CallCardPresenter.java revision e5c0d8bdf8269f9435e0381889e4870f36a43f07
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;
23033ed5926d2924d35b9c82898ab4e835da56b3afChiao Chengimport android.graphics.Bitmap;
2447dbbd2cd27647360cd13d200c983f788df28c5bChiao Chengimport android.net.wifi.WifiInfo;
2547dbbd2cd27647360cd13d200c983f788df28c5bChiao Chengimport android.net.wifi.WifiManager;
26f27342bc5d594dfc32dc2bfafe109dcaa6b6d506Sailesh Nepalimport android.telecomm.CallCapabilities;
27c6f4e50a4130fb8f7247f5eab6849829701ad484Sailesh Nepalimport android.telecomm.CallServiceDescriptor;
28479c50f6d4fac0fa44210c9bad4346f64dba3f1eAnders Kristensenimport android.telephony.DisconnectCause;
29c4bacb09c398a615154dc97b066179e77dc57599Yorke Leeimport android.telephony.PhoneNumberUtils;
30d28fc12696fa706fed70e04698275af7be7fee82Santos Cordonimport android.text.TextUtils;
318cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordonimport android.text.format.DateUtils;
32be8060acf5ecbb916c161d3249813098c0611ed5Yorke Lee
331b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordonimport com.android.incallui.AudioModeProvider.AudioModeListener;
34d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordonimport com.android.incallui.ContactInfoCache.ContactCacheEntry;
35d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordonimport com.android.incallui.ContactInfoCache.ContactInfoCacheCallback;
367ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordonimport com.android.incallui.InCallPresenter.InCallState;
377ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordonimport com.android.incallui.InCallPresenter.InCallStateListener;
381c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordonimport com.android.incallui.InCallPresenter.IncomingCallListener;
391b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordonimport com.android.services.telephony.common.AudioMode;
4042373eb59cbef15ec61ebb5c919031f293291a53Chiao Chengimport com.google.common.base.Preconditions;
41c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon
42c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon/**
43c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon * Presenter for the Call Card Fragment.
44033ed5926d2924d35b9c82898ab4e835da56b3afChiao Cheng * <p>
457ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon * This class listens for changes to InCallState and passes it along to the fragment.
46c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon */
47d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordonpublic class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
481c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon        implements InCallStateListener, AudioModeListener, IncomingCallListener {
49be8060acf5ecbb916c161d3249813098c0611ed5Yorke Lee
50033ed5926d2924d35b9c82898ab4e835da56b3afChiao Cheng    private static final String TAG = CallCardPresenter.class.getSimpleName();
518cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon    private static final long CALL_TIME_UPDATE_INTERVAL = 1000; // in milliseconds
528cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon
531b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    private Call mPrimary;
54d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    private Call mSecondary;
55d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    private ContactCacheEntry mPrimaryContactInfo;
56d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    private ContactCacheEntry mSecondaryContactInfo;
578cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon    private CallTimer mCallTimer;
583d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    private Context mContext;
596d231f52e4f00399330d772f2a337283803f3a9dYorke Lee
6046848bb9b89cc5417afae19aaab38fe331a7b474Sailesh Nepal    private boolean mIsWiFiCachedValue;
616d231f52e4f00399330d772f2a337283803f3a9dYorke Lee
62b8eedb3b9796873eaa22847205239a51092f1a43Santos Cordon    public CallCardPresenter() {
638cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        // create the call timer
648cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        mCallTimer = new CallTimer(new Runnable() {
658cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon            @Override
668cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon            public void run() {
678cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon                updateCallTime();
688cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon            }
698cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        });
706d231f52e4f00399330d772f2a337283803f3a9dYorke Lee    }
716d231f52e4f00399330d772f2a337283803f3a9dYorke Lee
7242373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
731c6bb983216392b5ceb36cea42a46631f68a3dd6Jay Shrauner    public void init(Context context, Call call) {
7442373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        mContext = Preconditions.checkNotNull(context);
7542373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
764a5339c4a266891ce560dfb6e348c3779a0a3ca1Chiao Cheng        // Call may be null if disconnect happened already.
774a5339c4a266891ce560dfb6e348c3779a0a3ca1Chiao Cheng        if (call != null) {
78656dd4a0d8571b47ecf0ecf3e4c2eeacfd1099b3Chiao Cheng            mPrimary = call;
79656dd4a0d8571b47ecf0ecf3e4c2eeacfd1099b3Chiao Cheng
804a5339c4a266891ce560dfb6e348c3779a0a3ca1Chiao Cheng            // start processing lookups right away.
81812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            if (!call.isConferenceCall()) {
82248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal                startContactInfoSearch(call, true, call.getState() == Call.State.INCOMING);
83812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            } else {
84812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon                updateContactEntry(null, true, true);
85812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            }
864a5339c4a266891ce560dfb6e348c3779a0a3ca1Chiao Cheng        }
87033ed5926d2924d35b9c82898ab4e835da56b3afChiao Cheng    }
88033ed5926d2924d35b9c82898ab4e835da56b3afChiao Cheng
89c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon    @Override
90c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon    public void onUiReady(CallCardUi ui) {
91c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon        super.onUiReady(ui);
921b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon
931f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon        AudioModeProvider.getInstance().addListener(this);
941f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon
9542373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        // Contact search may have completed before ui is ready.
9642373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        if (mPrimaryContactInfo != null) {
97314b2aaa1fa1ef799270987e964f7df4d983b9eeChristine Chen            updatePrimaryDisplayInfo(mPrimaryContactInfo, isConference(mPrimary));
9842373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        }
9942373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
1001f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon        // Register for call state changes last
1011f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon        InCallPresenter.getInstance().addListener(this);
1021c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon        InCallPresenter.getInstance().addIncomingCallListener(this);
1031b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    }
1041b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon
1051b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    @Override
1061b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    public void onUiUnready(CallCardUi ui) {
1071b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon        super.onUiUnready(ui);
1081b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon
1091f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon        // stop getting call state changes
1101f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon        InCallPresenter.getInstance().removeListener(this);
1111c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon        InCallPresenter.getInstance().removeIncomingCallListener(this);
1121f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon
1131f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon        AudioModeProvider.getInstance().removeListener(this);
1141f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon
1151b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon        mPrimary = null;
116d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        mPrimaryContactInfo = null;
117d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        mSecondaryContactInfo = null;
118c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon    }
119c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon
120c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon    @Override
1211c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon    public void onIncomingCall(InCallState state, Call call) {
1221c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon        // same logic should happen as with onStateChange()
1231c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon        onStateChange(state, CallList.getInstance());
1241c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon    }
1251c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon
1261c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon    @Override
1277ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon    public void onStateChange(InCallState state, CallList callList) {
1287a863a056a96638c32171f721d99c694a1890df8Christine Chen        Log.d(this, "onStateChange() " + state);
12975c86b55d45b1725c46ed2e5d77c9c43fcfd93daSantos Cordon        final CallCardUi ui = getUi();
1301b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon        if (ui == null) {
1311b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon            return;
1321b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon        }
133c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon
1347ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon        Call primary = null;
1357ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon        Call secondary = null;
1367ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon
1377ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon        if (state == InCallState.INCOMING) {
1387ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon            primary = callList.getIncomingCall();
139950e3df8ac744daf2a890d279566bdba424710f9Santos Cordon        } else if (state == InCallState.OUTGOING) {
140950e3df8ac744daf2a890d279566bdba424710f9Santos Cordon            primary = callList.getOutgoingCall();
141950e3df8ac744daf2a890d279566bdba424710f9Santos Cordon
14282f5d003e675dfd56735c745744c3d968883b23cSantos Cordon            // getCallToDisplay doesn't go through outgoing or incoming calls. It will return the
14382f5d003e675dfd56735c745744c3d968883b23cSantos Cordon            // highest priority call to display as the secondary call.
144d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            secondary = getCallToDisplay(callList, null, true);
1457ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon        } else if (state == InCallState.INCALL) {
146d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            primary = getCallToDisplay(callList, null, false);
147d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            secondary = getCallToDisplay(callList, primary, true);
1487ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon        }
1497ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon
150a4bd83ad639b349fa16dbd07225017fcbf6ed550Chiao Cheng        Log.d(this, "Primary call: " + primary);
151a4bd83ad639b349fa16dbd07225017fcbf6ed550Chiao Cheng        Log.d(this, "Secondary call: " + secondary);
1527ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon
153812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        final boolean primaryChanged = !areCallsSame(mPrimary, primary);
154812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        final boolean secondaryChanged = !areCallsSame(mSecondary, secondary);
155812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        mSecondary = secondary;
156812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        mPrimary = primary;
157812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon
158812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        if (primaryChanged && mPrimary != null) {
159812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            // primary call has changed
160248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal            mPrimaryContactInfo = ContactInfoCache.buildCacheEntryFromCall(mContext, mPrimary,
161248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal                    mPrimary.getState() == Call.State.INCOMING);
162812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            updatePrimaryDisplayInfo(mPrimaryContactInfo, isConference(mPrimary));
163812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            maybeStartSearch(mPrimary, true);
16442373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        }
16542373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
166812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        if (mSecondary == null) {
16742373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            // Secondary call may have ended.  Update the ui.
16842373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            mSecondaryContactInfo = null;
1695345442d7238c1db00dc8d55a49f7f5dd713d994Christine Chen            updateSecondaryDisplayInfo(false);
170812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        } else if (secondaryChanged) {
171812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            // secondary call has changed
172248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal            mSecondaryContactInfo = ContactInfoCache.buildCacheEntryFromCall(mContext, mSecondary,
173248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal                    mSecondary.getState() == Call.State.INCOMING);
174812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            updateSecondaryDisplayInfo(mSecondary.isConferenceCall());
175812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            maybeStartSearch(mSecondary, false);
17642373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        }
17742373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
1788cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        // Start/Stop the call time update timer
1798cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        if (mPrimary != null && mPrimary.getState() == Call.State.ACTIVE) {
180a4bd83ad639b349fa16dbd07225017fcbf6ed550Chiao Cheng            Log.d(this, "Starting the calltime timer");
1818cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon            mCallTimer.start(CALL_TIME_UPDATE_INTERVAL);
1828cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        } else {
183a4bd83ad639b349fa16dbd07225017fcbf6ed550Chiao Cheng            Log.d(this, "Canceling the calltime timer");
1848cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon            mCallTimer.cancel();
1858cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon            ui.setPrimaryCallElapsedTime(false, null);
1868cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        }
1878cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon
188d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        // Set the call state
1898aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton        int callState = Call.State.IDLE;
190d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        if (mPrimary != null) {
19132027ae1f52232258cc8133d383459f3b4ee57e4Yorke Lee            callState = mPrimary.getState();
1921f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon            final boolean bluetoothOn =
1931f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon                    (AudioModeProvider.getInstance().getAudioMode() == AudioMode.BLUETOOTH);
1948aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton            boolean isHandoffCapable = isHandoffCapable();
1958aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton            boolean isHandoffPending = isHandoffPending();
19646848bb9b89cc5417afae19aaab38fe331a7b474Sailesh Nepal
1978aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton            boolean isWiFi = isWifiCall();
19846848bb9b89cc5417afae19aaab38fe331a7b474Sailesh Nepal            // Cache the value so the UI doesn't change when the call ends.
19946848bb9b89cc5417afae19aaab38fe331a7b474Sailesh Nepal            mIsWiFiCachedValue = isWiFi;
20046848bb9b89cc5417afae19aaab38fe331a7b474Sailesh Nepal
2018aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton            getUi().setCallState(callState, mPrimary.getDisconnectCause(), bluetoothOn,
20246848bb9b89cc5417afae19aaab38fe331a7b474Sailesh Nepal                    getGatewayLabel(), getGatewayNumber(), isWiFi, isHandoffCapable,
20346848bb9b89cc5417afae19aaab38fe331a7b474Sailesh Nepal                    isHandoffPending);
20482f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        } else {
2058aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton            getUi().setCallState(callState, DisconnectCause.NOT_VALID, false, null, null,
20646848bb9b89cc5417afae19aaab38fe331a7b474Sailesh Nepal                    mIsWiFiCachedValue, false, false);
20782f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        }
208e26b887e90d5e9566a5054a1ccb3ed32ae2eea2dAndrew Lee
2098aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton        final boolean enableEndCallButton = Call.State.isConnected(callState) &&
2108aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton                callState != Call.State.INCOMING && mPrimary != null;
2119fc169931b9904ee8eac27bacd858ab87753e33dEvan Charlton        getUi().setEndCallButtonEnabled(enableEndCallButton);
2121b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    }
2131b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon
2141b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    @Override
2151b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    public void onAudioMode(int mode) {
2161b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon        if (mPrimary != null && getUi() != null) {
2171b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon            final boolean bluetoothOn = (AudioMode.BLUETOOTH == mode);
2181b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon
219ad4f3ea753b6dc43b1a82110c9fdf505966e74fbMakoto Onuki            getUi().setCallState(mPrimary.getState(), mPrimary.getDisconnectCause(), bluetoothOn,
2208aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton                    getGatewayLabel(), getGatewayNumber(), isWifiCall(),
2218aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton                    isHandoffCapable(), isHandoffPending());
2221b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon        }
2231b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    }
2241b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon
2258aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton    private boolean isWifiCall() {
226c6f4e50a4130fb8f7247f5eab6849829701ad484Sailesh Nepal        CallServiceDescriptor descriptor = mPrimary.getCurrentCallServiceDescriptor();
2278aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton        return descriptor != null &&
2288aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton                descriptor.getNetworkType() == CallServiceDescriptor.FLAG_WIFI;
2298aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton    }
2308aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton
2318aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton    private boolean isHandoffCapable() {
2328aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton        return mPrimary.can(CallCapabilities.CONNECTION_HANDOFF);
2338aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton    }
2348aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton
2358aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton    private boolean isHandoffPending() {
2368aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton        return mPrimary.getHandoffCallServiceDescriptor() != null;
23747dbbd2cd27647360cd13d200c983f788df28c5bChiao Cheng    }
23847dbbd2cd27647360cd13d200c983f788df28c5bChiao Cheng
2391b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    @Override
2401b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    public void onSupportedAudioMode(int mask) {
241c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon    }
242c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon
2438c478132fbc07bd075df6aba85bcfd2990bbd66aSantos Cordon    @Override
2448c478132fbc07bd075df6aba85bcfd2990bbd66aSantos Cordon    public void onMute(boolean muted) {
2458c478132fbc07bd075df6aba85bcfd2990bbd66aSantos Cordon    }
2468c478132fbc07bd075df6aba85bcfd2990bbd66aSantos Cordon
2478cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon    public void updateCallTime() {
2488cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        final CallCardUi ui = getUi();
2498cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon
2508cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        if (ui == null || mPrimary == null || mPrimary.getState() != Call.State.ACTIVE) {
251899251968ee4ee3cb375032185653ecd888e3f8dSantos Cordon            if (ui != null) {
252899251968ee4ee3cb375032185653ecd888e3f8dSantos Cordon                ui.setPrimaryCallElapsedTime(false, null);
253899251968ee4ee3cb375032185653ecd888e3f8dSantos Cordon            }
2548cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon            mCallTimer.cancel();
255899251968ee4ee3cb375032185653ecd888e3f8dSantos Cordon        } else {
256c6f4e50a4130fb8f7247f5eab6849829701ad484Sailesh Nepal            final long callStart = mPrimary.getConnectTimeMillis();
257899251968ee4ee3cb375032185653ecd888e3f8dSantos Cordon            final long duration = System.currentTimeMillis() - callStart;
258899251968ee4ee3cb375032185653ecd888e3f8dSantos Cordon            ui.setPrimaryCallElapsedTime(true, DateUtils.formatElapsedTime(duration / 1000));
2598cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        }
2608cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon    }
2618cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon
2628aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton    public void connectionHandoffClicked() {
2638aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton        if (mPrimary == null) {
2648aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton            return;
2658aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton        }
2668aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton
2678aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton        TelecommAdapter.getInstance().handoffCall(mPrimary.getCallId());
2688aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton    }
2698aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton
270812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon    private boolean areCallsSame(Call call1, Call call2) {
271812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        if (call1 == null && call2 == null) {
272812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            return true;
273812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        } else if (call1 == null || call2 == null) {
274812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            return false;
275812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        }
276812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon
277812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        // otherwise compare call Ids
2787b2248bfff11c50e208908cb74b5f94b3ad7a3c0Sailesh Nepal        return call1.getCallId().equals(call2.getCallId());
279812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon    }
280812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon
281812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon    private void maybeStartSearch(Call call, boolean isPrimary) {
282812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        // no need to start search for conference calls which show generic info.
283812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        if (call != null && !call.isConferenceCall()) {
284248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal            startContactInfoSearch(call, isPrimary, call.getState() == Call.State.INCOMING);
285812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        }
286812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon    }
287812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon
28882f5d003e675dfd56735c745744c3d968883b23cSantos Cordon    /**
289d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon     * Starts a query for more contact data for the save primary and secondary calls.
290d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon     */
291248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal    private void startContactInfoSearch(final Call call, final boolean isPrimary,
292248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal            boolean isIncoming) {
29342373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        final ContactInfoCache cache = ContactInfoCache.getInstance(mContext);
29442373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
295248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal        cache.findInfo(call, isIncoming, new ContactInfoCacheCallback() {
29642373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng                @Override
2977b2248bfff11c50e208908cb74b5f94b3ad7a3c0Sailesh Nepal                public void onContactInfoComplete(String callId, ContactCacheEntry entry) {
298812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon                    updateContactEntry(entry, isPrimary, false);
2991c6bb983216392b5ceb36cea42a46631f68a3dd6Jay Shrauner                    if (entry.name != null) {
3001c6bb983216392b5ceb36cea42a46631f68a3dd6Jay Shrauner                        Log.d(TAG, "Contact found: " + entry);
30142373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng                    }
3027e7fd2a0642515834a96028937f60ec955edfd91Yorke Lee                    if (entry.personUri != null) {
3037e7fd2a0642515834a96028937f60ec955edfd91Yorke Lee                        CallerInfoUtils.sendViewNotification(mContext, entry.personUri);
3047e7fd2a0642515834a96028937f60ec955edfd91Yorke Lee                    }
30542373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng                }
3067d2fb8620b808c28c49bde99dc54f6de46fdcb44Chiao Cheng
3077d2fb8620b808c28c49bde99dc54f6de46fdcb44Chiao Cheng                @Override
3087b2248bfff11c50e208908cb74b5f94b3ad7a3c0Sailesh Nepal                public void onImageLoadComplete(String callId, ContactCacheEntry entry) {
30902ade580384ccd853b6a9909aa0b4423fada84dfChristine Chen                    if (getUi() == null) {
31002ade580384ccd853b6a9909aa0b4423fada84dfChristine Chen                        return;
31102ade580384ccd853b6a9909aa0b4423fada84dfChristine Chen                    }
31249ff6571403695e81dbbd83e4f61790ce9c75f6dSantos Cordon                    if (entry.photo != null) {
3137b2248bfff11c50e208908cb74b5f94b3ad7a3c0Sailesh Nepal                        if (mPrimary != null && callId.equals(mPrimary.getCallId())) {
31449ff6571403695e81dbbd83e4f61790ce9c75f6dSantos Cordon                            getUi().setPrimaryImage(entry.photo);
31549ff6571403695e81dbbd83e4f61790ce9c75f6dSantos Cordon                        }
3167d2fb8620b808c28c49bde99dc54f6de46fdcb44Chiao Cheng                    }
3177d2fb8620b808c28c49bde99dc54f6de46fdcb44Chiao Cheng                }
31842373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            });
31942373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng    }
32042373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
321812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon    private static boolean isConference(Call call) {
322812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        return call != null && call.isConferenceCall();
323812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon    }
324812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon
325812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon    private static boolean isGenericConference(Call call) {
326f27342bc5d594dfc32dc2bfafe109dcaa6b6d506Sailesh Nepal        return call != null && call.can(CallCapabilities.GENERIC_CONFERENCE);
32742373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng    }
328d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon
32942373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng    private void updateContactEntry(ContactCacheEntry entry, boolean isPrimary,
33042373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            boolean isConference) {
33142373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        if (isPrimary) {
33242373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            mPrimaryContactInfo = entry;
33342373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            updatePrimaryDisplayInfo(entry, isConference);
334d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        } else {
33542373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            mSecondaryContactInfo = entry;
3365345442d7238c1db00dc8d55a49f7f5dd713d994Christine Chen            updateSecondaryDisplayInfo(isConference);
337d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        }
338d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    }
339d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon
340d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    /**
34182f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     * Get the highest priority call to display.
34282f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     * Goes through the calls and chooses which to return based on priority of which type of call
34382f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     * to display to the user. Callers can use the "ignore" feature to get the second best call
34482f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     * by passing a previously found primary call as ignore.
34582f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     *
34682f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     * @param ignore A call to ignore if found.
34782f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     */
348d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    private Call getCallToDisplay(CallList callList, Call ignore, boolean skipDisconnected) {
34982f5d003e675dfd56735c745744c3d968883b23cSantos Cordon
350d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        // Active calls come second.  An active call always gets precedent.
351d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        Call retval = callList.getActiveCall();
35282f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        if (retval != null && retval != ignore) {
35382f5d003e675dfd56735c745744c3d968883b23cSantos Cordon            return retval;
35482f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        }
35582f5d003e675dfd56735c745744c3d968883b23cSantos Cordon
356d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        // Disconnected calls get primary position if there are no active calls
357d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        // to let user know quickly what call has disconnected. Disconnected
358d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        // calls are very short lived.
359d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        if (!skipDisconnected) {
3606258ff60a7edc760facc3f387fc9c8ceee3fb518Christine Chen            retval = callList.getDisconnectingCall();
3616258ff60a7edc760facc3f387fc9c8ceee3fb518Christine Chen            if (retval != null && retval != ignore) {
3626258ff60a7edc760facc3f387fc9c8ceee3fb518Christine Chen                return retval;
3636258ff60a7edc760facc3f387fc9c8ceee3fb518Christine Chen            }
364d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            retval = callList.getDisconnectedCall();
365d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            if (retval != null && retval != ignore) {
366d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon                return retval;
367d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            }
36882f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        }
36982f5d003e675dfd56735c745744c3d968883b23cSantos Cordon
37082f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        // Then we go to background call (calls on hold)
37182f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        retval = callList.getBackgroundCall();
37282f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        if (retval != null && retval != ignore) {
37382f5d003e675dfd56735c745744c3d968883b23cSantos Cordon            return retval;
37482f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        }
37582f5d003e675dfd56735c745744c3d968883b23cSantos Cordon
37682f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        // Lastly, we go to a second background call.
37782f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        retval = callList.getSecondBackgroundCall();
37882f5d003e675dfd56735c745744c3d968883b23cSantos Cordon
37982f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        return retval;
38082f5d003e675dfd56735c745744c3d968883b23cSantos Cordon    }
38182f5d003e675dfd56735c745744c3d968883b23cSantos Cordon
38242373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng    private void updatePrimaryDisplayInfo(ContactCacheEntry entry, boolean isConference) {
38342373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        Log.d(TAG, "Update primary display " + entry);
3846d231f52e4f00399330d772f2a337283803f3a9dYorke Lee        final CallCardUi ui = getUi();
385d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        if (ui == null) {
38642373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            // TODO: May also occur if search result comes back after ui is destroyed. Look into
38742373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            // removing that case completely.
38842373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            Log.d(TAG, "updatePrimaryDisplayInfo called but ui is null!");
389d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon            return;
3906d231f52e4f00399330d772f2a337283803f3a9dYorke Lee        }
391be8060acf5ecbb916c161d3249813098c0611ed5Yorke Lee
392812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        final boolean isGenericConf = isGenericConference(mPrimary);
39342373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        if (entry != null) {
39442373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            final String name = getNameForCall(entry);
39542373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            final String number = getNumberForCall(entry);
39642373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            final boolean nameIsNumber = name != null && name.equals(entry.number);
39742373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            ui.setPrimary(number, name, nameIsNumber, entry.label,
398812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon                    entry.photo, isConference, isGenericConf, entry.isSipCall);
3996d231f52e4f00399330d772f2a337283803f3a9dYorke Lee        } else {
400812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            ui.setPrimary(null, null, false, null, null, isConference, isGenericConf, false);
401d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        }
402d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon
403d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    }
404d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon
4055345442d7238c1db00dc8d55a49f7f5dd713d994Christine Chen    private void updateSecondaryDisplayInfo(boolean isConference) {
40642373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
40742373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        final CallCardUi ui = getUi();
40842373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        if (ui == null) {
40942373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            return;
41042373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        }
41142373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
412812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        final boolean isGenericConf = isGenericConference(mSecondary);
41342373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        if (mSecondaryContactInfo != null) {
41442373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            Log.d(TAG, "updateSecondaryDisplayInfo() " + mSecondaryContactInfo);
415c4bacb09c398a615154dc97b066179e77dc57599Yorke Lee            final String nameForCall = getNameForCall(mSecondaryContactInfo);
416c4bacb09c398a615154dc97b066179e77dc57599Yorke Lee
417c4bacb09c398a615154dc97b066179e77dc57599Yorke Lee            final boolean nameIsNumber = nameForCall != null && nameForCall.equals(
418c4bacb09c398a615154dc97b066179e77dc57599Yorke Lee                    mSecondaryContactInfo.number);
419e5c0d8bdf8269f9435e0381889e4870f36a43f07Andrew Lee            ui.setSecondary(true /* show */, nameForCall, nameIsNumber, mSecondaryContactInfo.label,
420e5c0d8bdf8269f9435e0381889e4870f36a43f07Andrew Lee                    isConference, isGenericConf);
42142373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        } else {
42242373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            // reset to nothing so that it starts off blank next time we use it.
423e5c0d8bdf8269f9435e0381889e4870f36a43f07Andrew Lee            ui.setSecondary(false, null, false, null, isConference, isGenericConf);
42442373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        }
42542373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng    }
42642373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
4273d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    /**
4283d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon     * Returns the gateway number for any existing outgoing call.
4293d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon     */
4303d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    private String getGatewayNumber() {
4313d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        if (hasOutgoingGatewayCall()) {
432ae73c9aab1c716d9ef85f4f0dbc6f69e97a8f7e6Sailesh Nepal            return mPrimary.getGatewayInfo().getGatewayHandle().getSchemeSpecificPart();
4333d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        }
4343d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        return null;
4353d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    }
4363d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon
4373d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    /**
4383d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon     * Returns the label for the gateway app for any existing outgoing call.
4393d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon     */
4403d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    private String getGatewayLabel() {
4413d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        if (hasOutgoingGatewayCall() && getUi() != null) {
4423d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon            final PackageManager pm = mContext.getPackageManager();
4433d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon            try {
444ae73c9aab1c716d9ef85f4f0dbc6f69e97a8f7e6Sailesh Nepal                ApplicationInfo info = pm.getApplicationInfo(
445ae73c9aab1c716d9ef85f4f0dbc6f69e97a8f7e6Sailesh Nepal                        mPrimary.getGatewayInfo().getGatewayProviderPackageName(), 0);
4463d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon                return mContext.getString(R.string.calling_via_template,
4473d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon                        pm.getApplicationLabel(info).toString());
4483d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon            } catch (PackageManager.NameNotFoundException e) {
4493d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon            }
4503d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        }
4513d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        return null;
4523d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    }
4533d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon
4543d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    private boolean hasOutgoingGatewayCall() {
4553d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        // We only display the gateway information while DIALING so return false for any othe
4563d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        // call state.
45742373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        // TODO: mPrimary can be null because this is called from updatePrimaryDisplayInfo which
45842373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        // is also called after a contact search completes (call is not present yet).  Split the
45942373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        // UI update so it can receive independent updates.
46042373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        if (mPrimary == null) {
46142373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            return false;
46242373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        }
463ae73c9aab1c716d9ef85f4f0dbc6f69e97a8f7e6Sailesh Nepal        return Call.State.isDialing(mPrimary.getState()) && mPrimary.getGatewayInfo() != null &&
464ae73c9aab1c716d9ef85f4f0dbc6f69e97a8f7e6Sailesh Nepal                !mPrimary.getGatewayInfo().isEmpty();
4653d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    }
4663d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon
467d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    /**
468d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon     * Gets the name to display for the call.
469d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon     */
470d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    private static String getNameForCall(ContactCacheEntry contactInfo) {
471d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        if (TextUtils.isEmpty(contactInfo.name)) {
472d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            return contactInfo.number;
4736d231f52e4f00399330d772f2a337283803f3a9dYorke Lee        }
474d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        return contactInfo.name;
475d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    }
4766d231f52e4f00399330d772f2a337283803f3a9dYorke Lee
477d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    /**
478d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon     * Gets the number to display for a call.
479d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon     */
480d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    private static String getNumberForCall(ContactCacheEntry contactInfo) {
481d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        // If the name is empty, we use the number for the name...so dont show a second
482d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        // number in the number field
483d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        if (TextUtils.isEmpty(contactInfo.name)) {
4841c6bb983216392b5ceb36cea42a46631f68a3dd6Jay Shrauner            return contactInfo.location;
485d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        }
486d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        return contactInfo.number;
487d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    }
4886d231f52e4f00399330d772f2a337283803f3a9dYorke Lee
489e5c0d8bdf8269f9435e0381889e4870f36a43f07Andrew Lee    public void secondaryInfoClicked() {
49080c49a823543c9fb93420d05a6375fb1ff4ca631Yorke Lee        if (mSecondary == null) {
491e5c0d8bdf8269f9435e0381889e4870f36a43f07Andrew Lee            Log.wtf(this, "Secondary info clicked but no secondary call.");
49280c49a823543c9fb93420d05a6375fb1ff4ca631Yorke Lee            return;
49380c49a823543c9fb93420d05a6375fb1ff4ca631Yorke Lee        }
49480c49a823543c9fb93420d05a6375fb1ff4ca631Yorke Lee
495248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal        Log.i(this, "Swapping call to foreground: " + mSecondary);
496248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal        TelecommAdapter.getInstance().unholdCall(mSecondary.getCallId());
49790995fcb6778a9cb6dc35be12aeb1a5d0dcbb5aeYorke Lee    }
49890995fcb6778a9cb6dc35be12aeb1a5d0dcbb5aeYorke Lee
4997e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee    public void endCallClicked() {
5007e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee        if (mPrimary == null) {
5017e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee            return;
5027e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee        }
5037e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee
504cb2f51bf1acf387f391ca9c8cae8a2344eb2936aEvan Charlton        Log.i(this, "Disconnecting call: " + mPrimary);
505cb2f51bf1acf387f391ca9c8cae8a2344eb2936aEvan Charlton        TelecommAdapter.getInstance().disconnectCall(mPrimary.getCallId());
5067e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee    }
5077e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee
508d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    public interface CallCardUi extends Ui {
509d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        void setVisible(boolean on);
510d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        void setPrimary(String number, String name, boolean nameIsNumber, String label,
511812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon                Drawable photo, boolean isConference, boolean isGeneric, boolean isSipCall);
512c4bacb09c398a615154dc97b066179e77dc57599Yorke Lee        void setSecondary(boolean show, String name, boolean nameIsNumber, String label,
513e5c0d8bdf8269f9435e0381889e4870f36a43f07Andrew Lee                boolean isConference, boolean isGeneric);
514479c50f6d4fac0fa44210c9bad4346f64dba3f1eAnders Kristensen        void setCallState(int state, int cause, boolean bluetoothOn,
5158aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton                String gatewayLabel, String gatewayNumber, boolean isWifi, boolean isHandoffCapable,
5168aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton                boolean isHandoffPending);
5178cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        void setPrimaryCallElapsedTime(boolean show, String duration);
51842373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        void setPrimaryName(String name, boolean nameIsNumber);
51949ff6571403695e81dbbd83e4f61790ce9c75f6dSantos Cordon        void setPrimaryImage(Drawable image);
52042373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        void setPrimaryPhoneNumber(String phoneNumber);
52142373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        void setPrimaryLabel(String label);
522e26b887e90d5e9566a5054a1ccb3ed32ae2eea2dAndrew Lee        void setEndCallButtonEnabled(boolean enabled);
523be8060acf5ecbb916c161d3249813098c0611ed5Yorke Lee    }
524c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon}
525