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
198c03464c2c348af3bcd3bdfb911cd1bf17a760d0Brandon Maxwellimport com.google.common.base.Preconditions;
208c03464c2c348af3bcd3bdfb911cd1bf17a760d0Brandon Maxwell
21f925b504266f80ec0b74212c403475f5cc790ab0Evan Charltonimport android.Manifest;
223d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordonimport android.content.Context;
23f925b504266f80ec0b74212c403475f5cc790ab0Evan Charltonimport android.content.Intent;
243d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordonimport android.content.pm.ApplicationInfo;
253d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordonimport android.content.pm.PackageManager;
266d231f52e4f00399330d772f2a337283803f3a9dYorke Leeimport android.graphics.drawable.Drawable;
27da7f422a46db4bfe5cf76312d23b44e60fa9d806Santos Cordonimport android.net.Uri;
280e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charltonimport android.os.Bundle;
299cd03e1e3c319f7633638615074da3028eb45c2bBrandon Maxwellimport android.support.annotation.Nullable;
308cdac35f2aa80d1732dfc5fdaee1a21035a1bfcbAndrew Leeimport android.telecom.Call.Details;
3150dbb6eeca55cf78e0fd9eb132a26787d293620aAndrew Leeimport android.telecom.DisconnectCause;
324b293f0f08030c97e1bb54d2f79ac2fb1a6e29aeTyler Gunnimport android.telecom.PhoneAccount;
334b293f0f08030c97e1bb54d2f79ac2fb1a6e29aeTyler Gunnimport android.telecom.PhoneAccountHandle;
344b293f0f08030c97e1bb54d2f79ac2fb1a6e29aeTyler Gunnimport android.telecom.StatusHints;
354b293f0f08030c97e1bb54d2f79ac2fb1a6e29aeTyler Gunnimport android.telecom.TelecomManager;
364b293f0f08030c97e1bb54d2f79ac2fb1a6e29aeTyler Gunnimport android.telecom.VideoProfile;
370e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charltonimport android.telephony.PhoneNumberUtils;
38d28fc12696fa706fed70e04698275af7be7fee82Santos Cordonimport android.text.TextUtils;
39687390732d6253903141d89d734113373d0e3c13Nancy Chenimport android.view.View;
400dbdccd2aa0e6828e1332adf83e630a74527a248Yorke Leeimport android.view.accessibility.AccessibilityManager;
41e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chenimport android.widget.ListAdapter;
42be8060acf5ecbb916c161d3249813098c0611ed5Yorke Lee
437b2b43c0589ec79ba74359f7d9d6e0450fc322abVictor Changimport com.android.contacts.common.ContactsUtils;
447952f0a140d290f45f76917a3005e56bcb9b52c2Nancy Chenimport com.android.contacts.common.compat.telecom.TelecomManagerCompat;
458c03464c2c348af3bcd3bdfb911cd1bf17a760d0Brandon Maxwellimport com.android.contacts.common.preference.ContactsPreferences;
469cd03e1e3c319f7633638615074da3028eb45c2bBrandon Maxwellimport com.android.contacts.common.testing.NeededForTesting;
478c03464c2c348af3bcd3bdfb911cd1bf17a760d0Brandon Maxwellimport com.android.contacts.common.util.ContactDisplayUtils;
4868d86c656e5522dec1b04e85ebc0e0f78e436c3dSailesh Nepalimport com.android.dialer.R;
49e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chenimport com.android.incallui.Call.State;
50d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordonimport com.android.incallui.ContactInfoCache.ContactCacheEntry;
51d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordonimport com.android.incallui.ContactInfoCache.ContactInfoCacheCallback;
520e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charltonimport com.android.incallui.InCallPresenter.InCallDetailsListener;
53350fff554bf7ed5b9e91985935488771156953abTyler Gunnimport com.android.incallui.InCallPresenter.InCallEventListener;
547ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordonimport com.android.incallui.InCallPresenter.InCallState;
557ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordonimport com.android.incallui.InCallPresenter.InCallStateListener;
561c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordonimport com.android.incallui.InCallPresenter.IncomingCallListener;
57f925b504266f80ec0b74212c403475f5cc790ab0Evan Charltonimport com.android.incalluibind.ObjectFactory;
585b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee
595b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Leeimport java.lang.ref.WeakReference;
60c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon
61f75eb1ac9c28f1777ac375666b731d08630dbf1dTony Makimport static com.android.contacts.common.compat.CallSdkCompat.Details.PROPERTY_ENTERPRISE_CALL;
62c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon/**
63c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon * Presenter for the Call Card Fragment.
64033ed5926d2924d35b9c82898ab4e835da56b3afChiao Cheng * <p>
657ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon * This class listens for changes to InCallState and passes it along to the fragment.
66c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon */
67d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordonpublic class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
6891a369b019b39c5335a4f5d251691c0cdb657f7dAndrew Lee        implements InCallStateListener, IncomingCallListener, InCallDetailsListener,
69e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen        InCallEventListener, CallList.CallUpdateListener, DistanceHelper.Listener {
70be8060acf5ecbb916c161d3249813098c0611ed5Yorke Lee
7189aad4adce9cc66294f15391fa3e10f3123d3d92Andrew Lee    public interface EmergencyCallListener {
7289aad4adce9cc66294f15391fa3e10f3123d3d92Andrew Lee        public void onCallUpdated(BaseFragment fragment, boolean isEmergency);
7389aad4adce9cc66294f15391fa3e10f3123d3d92Andrew Lee    }
7489aad4adce9cc66294f15391fa3e10f3123d3d92Andrew Lee
75033ed5926d2924d35b9c82898ab4e835da56b3afChiao Cheng    private static final String TAG = CallCardPresenter.class.getSimpleName();
769c4226952c74f024c09e0bd381048493993c974eAndrew Lee    private static final long CALL_TIME_UPDATE_INTERVAL_MS = 1000;
778cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon
78061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn    private final EmergencyCallListener mEmergencyCallListener =
79061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn            ObjectFactory.newEmergencyCallListener();
80e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen    private DistanceHelper mDistanceHelper;
81df3ef3fc3d10573507c6451bffd1f55dfcb475ddAndrew Lee
821b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    private Call mPrimary;
83d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    private Call mSecondary;
84d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    private ContactCacheEntry mPrimaryContactInfo;
85d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    private ContactCacheEntry mSecondaryContactInfo;
8686a7f5639fd0798c3b4500166f97649949237215Andrew Lee    private CallTimer mCallTimer;
873d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    private Context mContext;
889cd03e1e3c319f7633638615074da3028eb45c2bBrandon Maxwell    @Nullable private ContactsPreferences mContactsPreferences;
89b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn    private boolean mSpinnerShowing = false;
9081ae21863de1fe836f5e62aa5e324a35a8eb7d06Tyler Gunn    private boolean mHasShownToast = false;
91e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen    private InCallContactInteractions mInCallContactInteractions;
92a860052619d1c3d13a33629e97a8e05509fa0e1bTyler Gunn    private boolean mIsFullscreen = false;
936d231f52e4f00399330d772f2a337283803f3a9dYorke Lee
945b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee    public static class ContactLookupCallback implements ContactInfoCacheCallback {
955b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        private final WeakReference<CallCardPresenter> mCallCardPresenter;
965b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        private final boolean mIsPrimary;
975b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee
985b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        public ContactLookupCallback(CallCardPresenter callCardPresenter, boolean isPrimary) {
995b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            mCallCardPresenter = new WeakReference<CallCardPresenter>(callCardPresenter);
1005b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            mIsPrimary = isPrimary;
1015b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        }
1025b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee
1035b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        @Override
1045b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        public void onContactInfoComplete(String callId, ContactCacheEntry entry) {
1055b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            CallCardPresenter presenter = mCallCardPresenter.get();
1065b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            if (presenter != null) {
1075b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee                presenter.onContactInfoComplete(callId, entry, mIsPrimary);
1085b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            }
1095b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        }
1105b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee
1115b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        @Override
1125b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        public void onImageLoadComplete(String callId, ContactCacheEntry entry) {
1135b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            CallCardPresenter presenter = mCallCardPresenter.get();
1145b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            if (presenter != null) {
1155b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee                presenter.onImageLoadComplete(callId, entry);
1165b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            }
1175b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        }
1185b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee
119e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen        @Override
120e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen        public void onContactInteractionsInfoComplete(String callId, ContactCacheEntry entry) {
121e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen            CallCardPresenter presenter = mCallCardPresenter.get();
122e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen            if (presenter != null) {
123e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen                presenter.onContactInteractionsInfoComplete(callId, entry);
124e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen            }
125e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen        }
1265b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee    }
1275b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee
128b8eedb3b9796873eaa22847205239a51092f1a43Santos Cordon    public CallCardPresenter() {
1298cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        // create the call timer
1308cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        mCallTimer = new CallTimer(new Runnable() {
1318cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon            @Override
1328cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon            public void run() {
1338cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon                updateCallTime();
1348cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon            }
1358cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        });
1366d231f52e4f00399330d772f2a337283803f3a9dYorke Lee    }
1376d231f52e4f00399330d772f2a337283803f3a9dYorke Lee
1381c6bb983216392b5ceb36cea42a46631f68a3dd6Jay Shrauner    public void init(Context context, Call call) {
13942373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        mContext = Preconditions.checkNotNull(context);
140e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen        mDistanceHelper = ObjectFactory.newDistanceHelper(mContext, this);
1419cd03e1e3c319f7633638615074da3028eb45c2bBrandon Maxwell        mContactsPreferences = ContactsPreferencesFactory.newContactsPreferences(mContext);
14242373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
1434a5339c4a266891ce560dfb6e348c3779a0a3ca1Chiao Cheng        // Call may be null if disconnect happened already.
1444a5339c4a266891ce560dfb6e348c3779a0a3ca1Chiao Cheng        if (call != null) {
145656dd4a0d8571b47ecf0ecf3e4c2eeacfd1099b3Chiao Cheng            mPrimary = call;
14681ae21863de1fe836f5e62aa5e324a35a8eb7d06Tyler Gunn            if (shouldShowNoteSentToast(mPrimary)) {
14781ae21863de1fe836f5e62aa5e324a35a8eb7d06Tyler Gunn                final CallCardUi ui = getUi();
14881ae21863de1fe836f5e62aa5e324a35a8eb7d06Tyler Gunn                if (ui != null) {
14981ae21863de1fe836f5e62aa5e324a35a8eb7d06Tyler Gunn                    ui.showNoteSentToast();
15081ae21863de1fe836f5e62aa5e324a35a8eb7d06Tyler Gunn                }
15181ae21863de1fe836f5e62aa5e324a35a8eb7d06Tyler Gunn            }
152b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn            CallList.getInstance().addCallUpdateListener(call.getId(), this);
153656dd4a0d8571b47ecf0ecf3e4c2eeacfd1099b3Chiao Cheng
1544a5339c4a266891ce560dfb6e348c3779a0a3ca1Chiao Cheng            // start processing lookups right away.
155812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            if (!call.isConferenceCall()) {
156248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal                startContactInfoSearch(call, true, call.getState() == Call.State.INCOMING);
157812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            } else {
158017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                updateContactEntry(null, true);
159812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            }
1604a5339c4a266891ce560dfb6e348c3779a0a3ca1Chiao Cheng        }
161fd0b577edffa5413adfda1503038a3bff3247106Yorke Lee
162fd0b577edffa5413adfda1503038a3bff3247106Yorke Lee        onStateChange(null, InCallPresenter.getInstance().getInCallState(), CallList.getInstance());
163033ed5926d2924d35b9c82898ab4e835da56b3afChiao Cheng    }
164033ed5926d2924d35b9c82898ab4e835da56b3afChiao Cheng
165c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon    @Override
166c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon    public void onUiReady(CallCardUi ui) {
167c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon        super.onUiReady(ui);
1681b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon
1698c03464c2c348af3bcd3bdfb911cd1bf17a760d0Brandon Maxwell        if (mContactsPreferences != null) {
1708c03464c2c348af3bcd3bdfb911cd1bf17a760d0Brandon Maxwell            mContactsPreferences.refreshValue(ContactsPreferences.DISPLAY_ORDER_KEY);
1718c03464c2c348af3bcd3bdfb911cd1bf17a760d0Brandon Maxwell        }
1728c03464c2c348af3bcd3bdfb911cd1bf17a760d0Brandon Maxwell
17342373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        // Contact search may have completed before ui is ready.
17442373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        if (mPrimaryContactInfo != null) {
175017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            updatePrimaryDisplayInfo();
17642373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        }
17742373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
1781f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon        // Register for call state changes last
1791f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon        InCallPresenter.getInstance().addListener(this);
1801c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon        InCallPresenter.getInstance().addIncomingCallListener(this);
1810e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton        InCallPresenter.getInstance().addDetailsListener(this);
182350fff554bf7ed5b9e91985935488771156953abTyler Gunn        InCallPresenter.getInstance().addInCallEventListener(this);
1831b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    }
1841b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon
1851b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    @Override
1861b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    public void onUiUnready(CallCardUi ui) {
1871b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon        super.onUiUnready(ui);
1881b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon
1891f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon        // stop getting call state changes
1901f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon        InCallPresenter.getInstance().removeListener(this);
1911c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon        InCallPresenter.getInstance().removeIncomingCallListener(this);
1920e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton        InCallPresenter.getInstance().removeDetailsListener(this);
193350fff554bf7ed5b9e91985935488771156953abTyler Gunn        InCallPresenter.getInstance().removeInCallEventListener(this);
194b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn        if (mPrimary != null) {
195b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn            CallList.getInstance().removeCallUpdateListener(mPrimary.getId(), this);
196b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn        }
1971f63d2d8e8db3616c16886952813b3d0473216e7Santos Cordon
198e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen        if (mDistanceHelper != null) {
199e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen            mDistanceHelper.cleanUp();
200e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen        }
201e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen
2021b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon        mPrimary = null;
203d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        mPrimaryContactInfo = null;
204d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        mSecondaryContactInfo = null;
205c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon    }
206c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon
207c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon    @Override
208f003346e5f9ba29e869a881bcca2e59d6ea8e0f6Nancy Chen    public void onIncomingCall(InCallState oldState, InCallState newState, Call call) {
2091c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon        // same logic should happen as with onStateChange()
210f003346e5f9ba29e869a881bcca2e59d6ea8e0f6Nancy Chen        onStateChange(oldState, newState, CallList.getInstance());
2111c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon    }
2121c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon
2131c22bde38cd15919e91afb0f12c558aa66f0bc91Santos Cordon    @Override
214f003346e5f9ba29e869a881bcca2e59d6ea8e0f6Nancy Chen    public void onStateChange(InCallState oldState, InCallState newState, CallList callList) {
215f003346e5f9ba29e869a881bcca2e59d6ea8e0f6Nancy Chen        Log.d(this, "onStateChange() " + newState);
21675c86b55d45b1725c46ed2e5d77c9c43fcfd93daSantos Cordon        final CallCardUi ui = getUi();
2171b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon        if (ui == null) {
2181b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon            return;
2191b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon        }
220c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon
2217ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon        Call primary = null;
2227ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon        Call secondary = null;
2237ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon
224f003346e5f9ba29e869a881bcca2e59d6ea8e0f6Nancy Chen        if (newState == InCallState.INCOMING) {
2257ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon            primary = callList.getIncomingCall();
226f003346e5f9ba29e869a881bcca2e59d6ea8e0f6Nancy Chen        } else if (newState == InCallState.PENDING_OUTGOING || newState == InCallState.OUTGOING) {
227950e3df8ac744daf2a890d279566bdba424710f9Santos Cordon            primary = callList.getOutgoingCall();
228f003346e5f9ba29e869a881bcca2e59d6ea8e0f6Nancy Chen            if (primary == null) {
229f003346e5f9ba29e869a881bcca2e59d6ea8e0f6Nancy Chen                primary = callList.getPendingOutgoingCall();
230f003346e5f9ba29e869a881bcca2e59d6ea8e0f6Nancy Chen            }
231950e3df8ac744daf2a890d279566bdba424710f9Santos Cordon
23282f5d003e675dfd56735c745744c3d968883b23cSantos Cordon            // getCallToDisplay doesn't go through outgoing or incoming calls. It will return the
23382f5d003e675dfd56735c745744c3d968883b23cSantos Cordon            // highest priority call to display as the secondary call.
234d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            secondary = getCallToDisplay(callList, null, true);
235f003346e5f9ba29e869a881bcca2e59d6ea8e0f6Nancy Chen        } else if (newState == InCallState.INCALL) {
236d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            primary = getCallToDisplay(callList, null, false);
237d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            secondary = getCallToDisplay(callList, primary, true);
2387ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon        }
2397ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon
240687390732d6253903141d89d734113373d0e3c13Nancy Chen        if (mInCallContactInteractions != null &&
241687390732d6253903141d89d734113373d0e3c13Nancy Chen                (oldState == InCallState.INCOMING || newState == InCallState.INCOMING)) {
242e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen            ui.showContactContext(newState != InCallState.INCOMING);
243e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen        }
244e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen
245a4bd83ad639b349fa16dbd07225017fcbf6ed550Chiao Cheng        Log.d(this, "Primary call: " + primary);
246a4bd83ad639b349fa16dbd07225017fcbf6ed550Chiao Cheng        Log.d(this, "Secondary call: " + secondary);
2477ac6cb331919db2a3a8985e4cb3299b309d9012aSantos Cordon
248fb008c2423a510a57be251d16bc963f64e98c2daRoshan Pius        final boolean primaryChanged = !(Call.areSame(mPrimary, primary) &&
249fb008c2423a510a57be251d16bc963f64e98c2daRoshan Pius                Call.areSameNumber(mPrimary, primary));
250fb008c2423a510a57be251d16bc963f64e98c2daRoshan Pius        final boolean secondaryChanged = !(Call.areSame(mSecondary, secondary) &&
251fb008c2423a510a57be251d16bc963f64e98c2daRoshan Pius                Call.areSameNumber(mSecondary, secondary));
2529c98346835b8e902e0c2c11f14a35f4e91578e9fAndrew Lee
253812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        mSecondary = secondary;
254b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn        Call previousPrimary = mPrimary;
255812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        mPrimary = primary;
256812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon
25781ae21863de1fe836f5e62aa5e324a35a8eb7d06Tyler Gunn        if (primaryChanged && shouldShowNoteSentToast(primary)) {
25881ae21863de1fe836f5e62aa5e324a35a8eb7d06Tyler Gunn            ui.showNoteSentToast();
25981ae21863de1fe836f5e62aa5e324a35a8eb7d06Tyler Gunn        }
26081ae21863de1fe836f5e62aa5e324a35a8eb7d06Tyler Gunn
2610cff18feff43a6915919ac8e32fa44502aa6c320Tyler Gunn        // Refresh primary call information if either:
2620cff18feff43a6915919ac8e32fa44502aa6c320Tyler Gunn        // 1. Primary call changed.
2630cff18feff43a6915919ac8e32fa44502aa6c320Tyler Gunn        // 2. The call's ability to manage conference has changed.
264435f5f690dfa576d08539a5987c52d0d23540327Nancy Chen        // 3. The call subject should be shown or hidden.
265435f5f690dfa576d08539a5987c52d0d23540327Nancy Chen        if (shouldRefreshPrimaryInfo(primaryChanged, ui, shouldShowCallSubject(mPrimary))) {
266812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            // primary call has changed
267b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn            if (previousPrimary != null) {
26814c3e88a486cb5cfb9ef5fee107118266d305edfTyler Gunn                //clear progess spinner (if any) related to previous primary call
26914c3e88a486cb5cfb9ef5fee107118266d305edfTyler Gunn                maybeShowProgressSpinner(previousPrimary.getState(),
27014c3e88a486cb5cfb9ef5fee107118266d305edfTyler Gunn                        Call.SessionModificationState.NO_REQUEST);
271b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn                CallList.getInstance().removeCallUpdateListener(previousPrimary.getId(), this);
272b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn            }
273b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn            CallList.getInstance().addCallUpdateListener(mPrimary.getId(), this);
274b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn
275248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal            mPrimaryContactInfo = ContactInfoCache.buildCacheEntryFromCall(mContext, mPrimary,
276248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal                    mPrimary.getState() == Call.State.INCOMING);
277017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            updatePrimaryDisplayInfo();
278812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            maybeStartSearch(mPrimary, true);
279207029be4c95b6d66ef4bd3c2277a9ba9e0c62a1Tyler Gunn            maybeClearSessionModificationState(mPrimary);
28042373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        }
28142373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
2822d7bf90875bea954ceacdacd9e52c840200bde37Yorke Lee        if (previousPrimary != null && mPrimary == null) {
28314c3e88a486cb5cfb9ef5fee107118266d305edfTyler Gunn            //clear progess spinner (if any) related to previous primary call
28414c3e88a486cb5cfb9ef5fee107118266d305edfTyler Gunn            maybeShowProgressSpinner(previousPrimary.getState(),
28514c3e88a486cb5cfb9ef5fee107118266d305edfTyler Gunn                    Call.SessionModificationState.NO_REQUEST);
2862d7bf90875bea954ceacdacd9e52c840200bde37Yorke Lee            CallList.getInstance().removeCallUpdateListener(previousPrimary.getId(), this);
2872d7bf90875bea954ceacdacd9e52c840200bde37Yorke Lee        }
2882d7bf90875bea954ceacdacd9e52c840200bde37Yorke Lee
289812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        if (mSecondary == null) {
29042373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            // Secondary call may have ended.  Update the ui.
29142373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            mSecondaryContactInfo = null;
292017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            updateSecondaryDisplayInfo();
293812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        } else if (secondaryChanged) {
294812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            // secondary call has changed
295248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal            mSecondaryContactInfo = ContactInfoCache.buildCacheEntryFromCall(mContext, mSecondary,
296248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal                    mSecondary.getState() == Call.State.INCOMING);
297017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            updateSecondaryDisplayInfo();
298812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon            maybeStartSearch(mSecondary, false);
299207029be4c95b6d66ef4bd3c2277a9ba9e0c62a1Tyler Gunn            maybeClearSessionModificationState(mSecondary);
30042373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        }
30142373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
3029c4226952c74f024c09e0bd381048493993c974eAndrew Lee        // Start/stop timers.
3038cdac35f2aa80d1732dfc5fdaee1a21035a1bfcbAndrew Lee        if (isPrimaryCallActive()) {
304a4bd83ad639b349fa16dbd07225017fcbf6ed550Chiao Cheng            Log.d(this, "Starting the calltime timer");
3059c4226952c74f024c09e0bd381048493993c974eAndrew Lee            mCallTimer.start(CALL_TIME_UPDATE_INTERVAL_MS);
3068cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        } else {
307a4bd83ad639b349fa16dbd07225017fcbf6ed550Chiao Cheng            Log.d(this, "Canceling the calltime timer");
3088cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon            mCallTimer.cancel();
309f0dfbe2e89df0d58efde8b290662072c081e146aNancy Chen            ui.setPrimaryCallElapsedTime(false, 0);
3108cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        }
3118cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon
312d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        // Set the call state
3138aac1a358f2caf6c21c603bae9c9d4bd075eb155Evan Charlton        int callState = Call.State.IDLE;
314d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        if (mPrimary != null) {
31532027ae1f52232258cc8133d383459f3b4ee57e4Yorke Lee            callState = mPrimary.getState();
316ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal            updatePrimaryCallState();
31782f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        } else {
3189c4226952c74f024c09e0bd381048493993c974eAndrew Lee            getUi().setCallState(
3199c4226952c74f024c09e0bd381048493993c974eAndrew Lee                    callState,
320678775006531155eec0da47ae6889bf03ad9a710Yorke Lee                    VideoProfile.STATE_AUDIO_ONLY,
3219c4226952c74f024c09e0bd381048493993c974eAndrew Lee                    Call.SessionModificationState.NO_REQUEST,
32250dbb6eeca55cf78e0fd9eb132a26787d293620aAndrew Lee                    new DisconnectCause(DisconnectCause.UNKNOWN),
3239c4226952c74f024c09e0bd381048493993c974eAndrew Lee                    null,
3249c4226952c74f024c09e0bd381048493993c974eAndrew Lee                    null,
32582332c921b8dcef213700822e2404b005adab00cAndrew Lee                    null,
326dc3122e9d7bc0c6f5fef00bed36bb300c40afadfAndrew Lee                    false /* isWifi */,
3277f07f9f6f1e209359cf069b1fa4b0dfc0b371f64Victor Chang                    false /* isConference */,
3287f07f9f6f1e209359cf069b1fa4b0dfc0b371f64Victor Chang                    false /* isWorkCall */);
3298cdac35f2aa80d1732dfc5fdaee1a21035a1bfcbAndrew Lee            getUi().showHdAudioIndicator(false);
33082f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        }
331e26b887e90d5e9566a5054a1ccb3ed32ae2eea2dAndrew Lee
3321da81ce59cfbebd4e53fdfd2011e859069120de7Andrew Lee        maybeShowManageConferenceCallButton();
3331da81ce59cfbebd4e53fdfd2011e859069120de7Andrew Lee
334c44f654b992c6ab8a4acff9cb5aa2678c58755d9Andrew Lee        // Hide the end call button instantly if we're receiving an incoming call.
335fdf53779ba6d68e28e005e3645378aea7bd76ec0Yorke Lee        getUi().setEndCallButtonEnabled(shouldShowEndCallButton(mPrimary, callState),
336fdf53779ba6d68e28e005e3645378aea7bd76ec0Yorke Lee                callState != Call.State.INCOMING /* animate */);
3370dbdccd2aa0e6828e1332adf83e630a74527a248Yorke Lee
338e1c196e04154815e2fb55801af73beb9fb2aa324Qi Wang        maybeSendAccessibilityEvent(oldState, newState, primaryChanged);
3391b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    }
3401b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon
3411b3e3f1056317fca5be4e7535d722da8876b2cbfSantos Cordon    @Override
3428cdac35f2aa80d1732dfc5fdaee1a21035a1bfcbAndrew Lee    public void onDetailsChanged(Call call, Details details) {
343ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal        updatePrimaryCallState();
344e0ec202ff354be3cd3bded7af8fca678dea7fb61Andrew Lee
3458cdac35f2aa80d1732dfc5fdaee1a21035a1bfcbAndrew Lee        if (call.can(Details.CAPABILITY_MANAGE_CONFERENCE) !=
3466a4e9d87031f1f803ce9b64844f71c73e9502a7eSailesh Nepal                details.can(Details.CAPABILITY_MANAGE_CONFERENCE)) {
347e0ec202ff354be3cd3bded7af8fca678dea7fb61Andrew Lee            maybeShowManageConferenceCallButton();
348e0ec202ff354be3cd3bded7af8fca678dea7fb61Andrew Lee        }
3490786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton    }
3500786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton
351b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn    @Override
352b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn    public void onCallChanged(Call call) {
353b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn        // No-op; specific call updates handled elsewhere.
354b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn    }
355b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn
356b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn    /**
357b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn     * Handles a change to the session modification state for a call.  Triggers showing the progress
358b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn     * spinner, as well as updating the call state label.
359b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn     *
360b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn     * @param sessionModificationState The new session modification state.
361b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn     */
362b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn    @Override
363b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn    public void onSessionModificationStateChange(int sessionModificationState) {
364b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn        Log.d(this, "onSessionModificationStateChange : sessionModificationState = " +
365b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn                sessionModificationState);
366b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn
367b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn        if (mPrimary == null) {
368b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn            return;
369b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn        }
370b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn        maybeShowProgressSpinner(mPrimary.getState(), sessionModificationState);
371b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn        getUi().setEndCallButtonEnabled(sessionModificationState !=
372b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn                        Call.SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST,
373b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn                true /* shouldAnimate */);
374b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn        updatePrimaryCallState();
375b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn    }
376b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn
377061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn    /**
378061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn     * Handles a change to the last forwarding number by refreshing the primary call info.
379061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn     */
380061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn    @Override
381061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn    public void onLastForwardedNumberChange() {
382061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn        Log.v(this, "onLastForwardedNumberChange");
383061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn
384061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn        if (mPrimary == null) {
385061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn            return;
386061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn        }
387061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn        updatePrimaryDisplayInfo();
388061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn    }
389061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn
390c82f0a1f9826d0002812748afa4906b8631a7b61Ta-wei Yen    /**
391c82f0a1f9826d0002812748afa4906b8631a7b61Ta-wei Yen     * Handles a change to the child number by refreshing the primary call info.
392c82f0a1f9826d0002812748afa4906b8631a7b61Ta-wei Yen     */
393c82f0a1f9826d0002812748afa4906b8631a7b61Ta-wei Yen    @Override
394c82f0a1f9826d0002812748afa4906b8631a7b61Ta-wei Yen    public void onChildNumberChange() {
395c82f0a1f9826d0002812748afa4906b8631a7b61Ta-wei Yen        Log.v(this, "onChildNumberChange");
396c82f0a1f9826d0002812748afa4906b8631a7b61Ta-wei Yen
397c82f0a1f9826d0002812748afa4906b8631a7b61Ta-wei Yen        if (mPrimary == null) {
398c82f0a1f9826d0002812748afa4906b8631a7b61Ta-wei Yen            return;
399c82f0a1f9826d0002812748afa4906b8631a7b61Ta-wei Yen        }
400c82f0a1f9826d0002812748afa4906b8631a7b61Ta-wei Yen        updatePrimaryDisplayInfo();
401c82f0a1f9826d0002812748afa4906b8631a7b61Ta-wei Yen    }
402c82f0a1f9826d0002812748afa4906b8631a7b61Ta-wei Yen
403435f5f690dfa576d08539a5987c52d0d23540327Nancy Chen    private boolean shouldRefreshPrimaryInfo(boolean primaryChanged, CallCardUi ui,
404435f5f690dfa576d08539a5987c52d0d23540327Nancy Chen            boolean shouldShowCallSubject) {
405435f5f690dfa576d08539a5987c52d0d23540327Nancy Chen        if (mPrimary == null) {
406435f5f690dfa576d08539a5987c52d0d23540327Nancy Chen            return false;
407435f5f690dfa576d08539a5987c52d0d23540327Nancy Chen        }
408435f5f690dfa576d08539a5987c52d0d23540327Nancy Chen        return primaryChanged ||
409435f5f690dfa576d08539a5987c52d0d23540327Nancy Chen                ui.isManageConferenceVisible() != shouldShowManageConference() ||
410435f5f690dfa576d08539a5987c52d0d23540327Nancy Chen                ui.isCallSubjectVisible() != shouldShowCallSubject;
411435f5f690dfa576d08539a5987c52d0d23540327Nancy Chen    }
412435f5f690dfa576d08539a5987c52d0d23540327Nancy Chen
4130786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton    private String getSubscriptionNumber() {
4140786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton        // If it's an emergency call, and they're not populating the callback number,
4150786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton        // then try to fall back to the phone sub info (to hopefully get the SIM's
4160786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton        // number directly from the telephony layer).
41776e1b4bfb2e21300068f10cc94922214e62c8f86Evan Charlton        PhoneAccountHandle accountHandle = mPrimary.getAccountHandle();
41876e1b4bfb2e21300068f10cc94922214e62c8f86Evan Charlton        if (accountHandle != null) {
419170e405691a237b74fbecbf41208cbaa5bd36442Nancy Chen            TelecomManager mgr = InCallPresenter.getInstance().getTelecomManager();
42029c01f36e9381b7bad135a9701aa3dffaf495b2fNancy Chen            PhoneAccount account = TelecomManagerCompat.getPhoneAccount(mgr, accountHandle);
421b6f45c2768f5af916ee3257542a3ab03611c1f5eEvan Charlton            if (account != null) {
4229e27dca4bc1be09bcb1d283b2fe3ba3d49f0748bAndrew Lee                return getNumberFromHandle(account.getSubscriptionAddress());
423c108b49ad5440fbf381c9a589d8a217da3efcb64Ihab Awad            }
4240e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton        }
4250786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton        return null;
4260e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton    }
4270e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton
428ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal    private void updatePrimaryCallState() {
429ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal        if (getUi() != null && mPrimary != null) {
430f75eb1ac9c28f1777ac375666b731d08630dbf1dTony Mak            boolean isWorkCall = mPrimary.hasProperty(PROPERTY_ENTERPRISE_CALL)
4317f07f9f6f1e209359cf069b1fa4b0dfc0b371f64Victor Chang                    || (mPrimaryContactInfo == null ? false
4327f07f9f6f1e209359cf069b1fa4b0dfc0b371f64Victor Chang                            : mPrimaryContactInfo.userType == ContactsUtils.USER_TYPE_WORK);
433ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal            getUi().setCallState(
434ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal                    mPrimary.getState(),
435ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal                    mPrimary.getVideoState(),
436ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal                    mPrimary.getSessionModificationState(),
437ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal                    mPrimary.getDisconnectCause(),
438ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal                    getConnectionLabel(),
4396c3061091e59e9ab06b620c2615b897e2eca233cAndrew Lee                    getCallStateIcon(),
44082332c921b8dcef213700822e2404b005adab00cAndrew Lee                    getGatewayNumber(),
44159585f80dce30e53ea30f08f11089f6cdd6e41fbAndrew Lee                    mPrimary.hasProperty(Details.PROPERTY_WIFI),
4427f07f9f6f1e209359cf069b1fa4b0dfc0b371f64Victor Chang                    mPrimary.isConferenceCall(),
4437f07f9f6f1e209359cf069b1fa4b0dfc0b371f64Victor Chang                    isWorkCall);
4448cdac35f2aa80d1732dfc5fdaee1a21035a1bfcbAndrew Lee
445061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn            maybeShowHdAudioIcon();
446ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal            setCallbackNumber();
447ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal        }
448ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal    }
4490786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton
4501da81ce59cfbebd4e53fdfd2011e859069120de7Andrew Lee    /**
451061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn     * Show the HD icon if the call is active and has {@link Details#PROPERTY_HIGH_DEF_AUDIO},
452061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn     * except if the call has a last forwarded number (we will show that icon instead).
453061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn     */
454061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn    private void maybeShowHdAudioIcon() {
455061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn        boolean showHdAudioIndicator =
456061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn                isPrimaryCallActive() && mPrimary.hasProperty(Details.PROPERTY_HIGH_DEF_AUDIO) &&
457061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn                TextUtils.isEmpty(mPrimary.getLastForwardedNumber());
458061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn        getUi().showHdAudioIndicator(showHdAudioIndicator);
459061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn    }
460061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn
461061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn    /**
462289d53ed1c879e983dcb021fa677212ab4566bbdSantos Cordon     * Only show the conference call button if we can manage the conference.
4631da81ce59cfbebd4e53fdfd2011e859069120de7Andrew Lee     */
4641da81ce59cfbebd4e53fdfd2011e859069120de7Andrew Lee    private void maybeShowManageConferenceCallButton() {
4650cff18feff43a6915919ac8e32fa44502aa6c320Tyler Gunn        getUi().showManageConferenceCallButton(shouldShowManageConference());
4660cff18feff43a6915919ac8e32fa44502aa6c320Tyler Gunn    }
4670cff18feff43a6915919ac8e32fa44502aa6c320Tyler Gunn
468b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn    /**
469b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn     * Determines if a pending session modification exists for the current call.  If so, the
470b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn     * progress spinner is shown, and the call state is updated.
471b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn     *
472b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn     * @param callState The call state.
473b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn     * @param sessionModificationState The session modification state.
474b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn     */
475b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn    private void maybeShowProgressSpinner(int callState, int sessionModificationState) {
476b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn        final boolean show = sessionModificationState ==
477b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn                Call.SessionModificationState.WAITING_FOR_RESPONSE
478b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn                && callState == Call.State.ACTIVE;
479b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn        if (show != mSpinnerShowing) {
480b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn            getUi().setProgressSpinnerVisible(show);
481b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn            mSpinnerShowing = show;
482b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn        }
48355576e529a3fa7183a698669374b9c2dd28ad5c5Yorke Lee    }
48455576e529a3fa7183a698669374b9c2dd28ad5c5Yorke Lee
4850cff18feff43a6915919ac8e32fa44502aa6c320Tyler Gunn    /**
4860cff18feff43a6915919ac8e32fa44502aa6c320Tyler Gunn     * Determines if the manage conference button should be visible, based on the current primary
4870cff18feff43a6915919ac8e32fa44502aa6c320Tyler Gunn     * call.
4880cff18feff43a6915919ac8e32fa44502aa6c320Tyler Gunn     *
4890cff18feff43a6915919ac8e32fa44502aa6c320Tyler Gunn     * @return {@code True} if the manage conference button should be visible.
4900cff18feff43a6915919ac8e32fa44502aa6c320Tyler Gunn     */
4910cff18feff43a6915919ac8e32fa44502aa6c320Tyler Gunn    private boolean shouldShowManageConference() {
492e16e53167b367656840df665457e71e66bc966deAndrew Lee        if (mPrimary == null) {
4930cff18feff43a6915919ac8e32fa44502aa6c320Tyler Gunn            return false;
494e16e53167b367656840df665457e71e66bc966deAndrew Lee        }
495e16e53167b367656840df665457e71e66bc966deAndrew Lee
49618c0feda76fe333f3db1bf7bd307458a9e6b6005Rekha Kumar        return mPrimary.can(android.telecom.Call.Details.CAPABILITY_MANAGE_CONFERENCE)
49784a1becf7d9a7055f16fc5b0e503e0512dcdfcf1Tyler Gunn                && !mIsFullscreen;
4981da81ce59cfbebd4e53fdfd2011e859069120de7Andrew Lee    }
4991da81ce59cfbebd4e53fdfd2011e859069120de7Andrew Lee
500ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal    private void setCallbackNumber() {
501ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal        String callbackNumber = null;
5020786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton
503c4fac46c65d20da815b37f3d1dbe2ff748fa1f00Tyler Gunn        // Show the emergency callback number if either:
504c4fac46c65d20da815b37f3d1dbe2ff748fa1f00Tyler Gunn        // 1. This is an emergency call.
505c4fac46c65d20da815b37f3d1dbe2ff748fa1f00Tyler Gunn        // 2. The phone is in Emergency Callback Mode, which means we should show the callback
506c4fac46c65d20da815b37f3d1dbe2ff748fa1f00Tyler Gunn        //    number.
50759585f80dce30e53ea30f08f11089f6cdd6e41fbAndrew Lee        boolean showCallbackNumber = mPrimary.hasProperty(Details.PROPERTY_EMERGENCY_CALLBACK_MODE);
508c4fac46c65d20da815b37f3d1dbe2ff748fa1f00Tyler Gunn
50993a6fd8d4a6f3ff4732cb4fb3b9df7c522b92823Tyler Gunn        if (mPrimary.isEmergencyCall() || showCallbackNumber) {
510ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal            callbackNumber = getSubscriptionNumber();
511ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal        } else {
5129124b77e489772fb7c6aac36f83d86ffdf83748fJay Shrauner            StatusHints statusHints = mPrimary.getTelecomCall().getDetails().getStatusHints();
513ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal            if (statusHints != null) {
514ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal                Bundle extras = statusHints.getExtras();
515ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal                if (extras != null) {
5164b293f0f08030c97e1bb54d2f79ac2fb1a6e29aeTyler Gunn                    callbackNumber = extras.getString(TelecomManager.EXTRA_CALL_BACK_NUMBER);
5170786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton                }
5180e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton            }
5190786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton        }
5200786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton
5219b70c293ad0a2bf343a93701a37a5f152c6a4214Brandon Maxwell        final String simNumber = TelecomManagerCompat.getLine1Number(
5229b70c293ad0a2bf343a93701a37a5f152c6a4214Brandon Maxwell                InCallPresenter.getInstance().getTelecomManager(),
5239b70c293ad0a2bf343a93701a37a5f152c6a4214Brandon Maxwell                InCallPresenter.getInstance().getTelephonyManager(),
5249b70c293ad0a2bf343a93701a37a5f152c6a4214Brandon Maxwell                mPrimary.getAccountHandle());
525c4fac46c65d20da815b37f3d1dbe2ff748fa1f00Tyler Gunn        if (!showCallbackNumber && PhoneNumberUtils.compare(callbackNumber, simNumber)) {
526c4fac46c65d20da815b37f3d1dbe2ff748fa1f00Tyler Gunn            Log.d(this, "Numbers are the same (and callback number is not being forced to show);" +
5273326f42f13f6f8cd8934aec615078a8890212402Tyler Gunn                    " not showing the callback number");
528ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal            callbackNumber = null;
5290786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton        }
530ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal
53193a6fd8d4a6f3ff4732cb4fb3b9df7c522b92823Tyler Gunn        getUi().setCallbackNumber(callbackNumber, mPrimary.isEmergencyCall() || showCallbackNumber);
5320e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton    }
5330e84b83f23af354872b64fc1d1d77d22d825c71cEvan Charlton
5348cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon    public void updateCallTime() {
5358cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        final CallCardUi ui = getUi();
5368cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon
5378cdac35f2aa80d1732dfc5fdaee1a21035a1bfcbAndrew Lee        if (ui == null) {
5388cdac35f2aa80d1732dfc5fdaee1a21035a1bfcbAndrew Lee            mCallTimer.cancel();
5398cdac35f2aa80d1732dfc5fdaee1a21035a1bfcbAndrew Lee        } else if (!isPrimaryCallActive()) {
5408cdac35f2aa80d1732dfc5fdaee1a21035a1bfcbAndrew Lee            ui.setPrimaryCallElapsedTime(false, 0);
5418cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon            mCallTimer.cancel();
542899251968ee4ee3cb375032185653ecd888e3f8dSantos Cordon        } else {
543c6f4e50a4130fb8f7247f5eab6849829701ad484Sailesh Nepal            final long callStart = mPrimary.getConnectTimeMillis();
544899251968ee4ee3cb375032185653ecd888e3f8dSantos Cordon            final long duration = System.currentTimeMillis() - callStart;
545f0dfbe2e89df0d58efde8b290662072c081e146aNancy Chen            ui.setPrimaryCallElapsedTime(true, duration);
5468cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon        }
5478cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon    }
5488cd746f0342f8c5def42f64b08cf6df741bb61bbSantos Cordon
549f925b504266f80ec0b74212c403475f5cc790ab0Evan Charlton    public void onCallStateButtonTouched() {
55071afa1c7d1e1f49af56c24bdc64d30d80cf1ea68Evan Charlton        Intent broadcastIntent = ObjectFactory.getCallStateButtonBroadcastIntent(mContext);
551f925b504266f80ec0b74212c403475f5cc790ab0Evan Charlton        if (broadcastIntent != null) {
552f925b504266f80ec0b74212c403475f5cc790ab0Evan Charlton            Log.d(this, "Sending call state button broadcast: ", broadcastIntent);
553f925b504266f80ec0b74212c403475f5cc790ab0Evan Charlton            mContext.sendBroadcast(broadcastIntent, Manifest.permission.READ_PHONE_STATE);
554f925b504266f80ec0b74212c403475f5cc790ab0Evan Charlton        }
555f925b504266f80ec0b74212c403475f5cc790ab0Evan Charlton    }
556f925b504266f80ec0b74212c403475f5cc790ab0Evan Charlton
5573326f42f13f6f8cd8934aec615078a8890212402Tyler Gunn    /**
5583326f42f13f6f8cd8934aec615078a8890212402Tyler Gunn     * Handles click on the contact photo by toggling fullscreen mode if the current call is a video
5593326f42f13f6f8cd8934aec615078a8890212402Tyler Gunn     * call.
5603326f42f13f6f8cd8934aec615078a8890212402Tyler Gunn     */
5613326f42f13f6f8cd8934aec615078a8890212402Tyler Gunn    public void onContactPhotoClick() {
5623326f42f13f6f8cd8934aec615078a8890212402Tyler Gunn        if (mPrimary != null && mPrimary.isVideoCall(mContext)) {
5633326f42f13f6f8cd8934aec615078a8890212402Tyler Gunn            InCallPresenter.getInstance().toggleFullscreenMode();
5643326f42f13f6f8cd8934aec615078a8890212402Tyler Gunn        }
5653326f42f13f6f8cd8934aec615078a8890212402Tyler Gunn    }
5663326f42f13f6f8cd8934aec615078a8890212402Tyler Gunn
567812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon    private void maybeStartSearch(Call call, boolean isPrimary) {
568812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        // no need to start search for conference calls which show generic info.
569812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        if (call != null && !call.isConferenceCall()) {
570248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal            startContactInfoSearch(call, isPrimary, call.getState() == Call.State.INCOMING);
571812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon        }
572812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon    }
573812c0e88d5d86c29e4942f9a1010a95cce789657Santos Cordon
574207029be4c95b6d66ef4bd3c2277a9ba9e0c62a1Tyler Gunn    private void maybeClearSessionModificationState(Call call) {
575207029be4c95b6d66ef4bd3c2277a9ba9e0c62a1Tyler Gunn        if (call.getSessionModificationState() !=
576207029be4c95b6d66ef4bd3c2277a9ba9e0c62a1Tyler Gunn                Call.SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST) {
577207029be4c95b6d66ef4bd3c2277a9ba9e0c62a1Tyler Gunn            call.setSessionModificationState(Call.SessionModificationState.NO_REQUEST);
578207029be4c95b6d66ef4bd3c2277a9ba9e0c62a1Tyler Gunn        }
579207029be4c95b6d66ef4bd3c2277a9ba9e0c62a1Tyler Gunn    }
580207029be4c95b6d66ef4bd3c2277a9ba9e0c62a1Tyler Gunn
58182f5d003e675dfd56735c745744c3d968883b23cSantos Cordon    /**
582d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon     * Starts a query for more contact data for the save primary and secondary calls.
583d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon     */
584248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal    private void startContactInfoSearch(final Call call, final boolean isPrimary,
585248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal            boolean isIncoming) {
58642373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        final ContactInfoCache cache = ContactInfoCache.getInstance(mContext);
58742373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
5885b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        cache.findInfo(call, isIncoming, new ContactLookupCallback(this, isPrimary));
5895b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee    }
5907d2fb8620b808c28c49bde99dc54f6de46fdcb44Chiao Cheng
5915b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee    private void onContactInfoComplete(String callId, ContactCacheEntry entry, boolean isPrimary) {
592a0eeeaa20c895d4ac15d7dd7045c816c81cedaf5Yorke Lee        final boolean entryMatchesExistingCall =
593a0eeeaa20c895d4ac15d7dd7045c816c81cedaf5Yorke Lee                (isPrimary && mPrimary != null && TextUtils.equals(callId,  mPrimary.getId())) ||
594a0eeeaa20c895d4ac15d7dd7045c816c81cedaf5Yorke Lee                (!isPrimary && mSecondary != null && TextUtils.equals(callId, mSecondary.getId()));
595a0eeeaa20c895d4ac15d7dd7045c816c81cedaf5Yorke Lee        if (entryMatchesExistingCall) {
596a0eeeaa20c895d4ac15d7dd7045c816c81cedaf5Yorke Lee            updateContactEntry(entry, isPrimary);
597a0eeeaa20c895d4ac15d7dd7045c816c81cedaf5Yorke Lee        } else {
598a0eeeaa20c895d4ac15d7dd7045c816c81cedaf5Yorke Lee            Log.w(this, "Dropping stale contact lookup info for " + callId);
599a0eeeaa20c895d4ac15d7dd7045c816c81cedaf5Yorke Lee        }
600a0eeeaa20c895d4ac15d7dd7045c816c81cedaf5Yorke Lee
60189fa8c5b9f3bcd0bdf4c3409216b7fe88a1486e4Yorke Lee        final Call call = CallList.getInstance().getCallById(callId);
60289fa8c5b9f3bcd0bdf4c3409216b7fe88a1486e4Yorke Lee        if (call != null) {
60389fa8c5b9f3bcd0bdf4c3409216b7fe88a1486e4Yorke Lee            call.getLogState().contactLookupResult = entry.contactLookupResult;
60489fa8c5b9f3bcd0bdf4c3409216b7fe88a1486e4Yorke Lee        }
6055b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        if (entry.contactUri != null) {
6065b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            CallerInfoUtils.sendViewNotification(mContext, entry.contactUri);
6075b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        }
6085b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee    }
6095b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee
6105b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee    private void onImageLoadComplete(String callId, ContactCacheEntry entry) {
6115b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        if (getUi() == null) {
6125b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            return;
6135b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        }
614f003346e5f9ba29e869a881bcca2e59d6ea8e0f6Nancy Chen
6155b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        if (entry.photo != null) {
6165b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            if (mPrimary != null && callId.equals(mPrimary.getId())) {
617fd640ab7b1efe30574c96a12b06627f365d0432aTyler Gunn                boolean showContactPhoto = !VideoCallPresenter.showIncomingVideo(
618fd640ab7b1efe30574c96a12b06627f365d0432aTyler Gunn                        mPrimary.getVideoState(), mPrimary.getState());
619fd640ab7b1efe30574c96a12b06627f365d0432aTyler Gunn                getUi().setPrimaryImage(entry.photo, showContactPhoto);
6205b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee            }
6215b3f5ed7d9ffa02c2255a68e6a4be969f0116104Yorke Lee        }
62242373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng    }
62342373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
624e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen    private void onContactInteractionsInfoComplete(String callId, ContactCacheEntry entry) {
625e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen        if (getUi() == null) {
626e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen            return;
627e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen        }
628e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen
629e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen        if (mPrimary != null && callId.equals(mPrimary.getId())) {
630e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen            mPrimaryContactInfo.locationAddress = entry.locationAddress;
631e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen            updateContactInteractions();
632e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen        }
633e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen    }
634e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen
635e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen    @Override
636e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen    public void onLocationReady() {
637e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen        // This will only update the contacts interactions data if the location returns after
638e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen        // the contact information is found.
639e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen        updateContactInteractions();
640e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen    }
641e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen
642e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen    private void updateContactInteractions() {
643e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen        if (mPrimary != null && mPrimaryContactInfo != null
644d2fda4ab69205fc672c02141f9b62c1958f73aceNancy Chen                && (mPrimaryContactInfo.locationAddress != null
645d2fda4ab69205fc672c02141f9b62c1958f73aceNancy Chen                        || mPrimaryContactInfo.openingHours != null)) {
646687390732d6253903141d89d734113373d0e3c13Nancy Chen            // TODO: This is hardcoded to "isBusiness" because functionality to differentiate
647687390732d6253903141d89d734113373d0e3c13Nancy Chen            // between business and personal has not yet been added.
648687390732d6253903141d89d734113373d0e3c13Nancy Chen            if (setInCallContactInteractionsType(true /* isBusiness */)) {
649687390732d6253903141d89d734113373d0e3c13Nancy Chen                getUi().setContactContextTitle(
650687390732d6253903141d89d734113373d0e3c13Nancy Chen                        mInCallContactInteractions.getBusinessListHeaderView());
651687390732d6253903141d89d734113373d0e3c13Nancy Chen            }
652e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen
653e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen            mInCallContactInteractions.setBusinessInfo(
654e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen                    mPrimaryContactInfo.locationAddress,
655d2fda4ab69205fc672c02141f9b62c1958f73aceNancy Chen                    mDistanceHelper.calculateDistance(mPrimaryContactInfo.locationAddress),
656d2fda4ab69205fc672c02141f9b62c1958f73aceNancy Chen                    mPrimaryContactInfo.openingHours);
657687390732d6253903141d89d734113373d0e3c13Nancy Chen            getUi().setContactContextContent(mInCallContactInteractions.getListAdapter());
658e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen            getUi().showContactContext(mPrimary.getState() != State.INCOMING);
659107c7da5da4e689b38433756244971d7543f7272Nancy Chen        } else {
660107c7da5da4e689b38433756244971d7543f7272Nancy Chen            getUi().showContactContext(false);
661e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen        }
662e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen    }
663e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen
664e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen    /**
665e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen     * Update the contact interactions type so that the correct UI is shown.
666e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen     *
667e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen     * @param isBusiness {@code true} if the interaction is a business interaction, {@code false} if
668e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen     * it is a personal contact.
669687390732d6253903141d89d734113373d0e3c13Nancy Chen     *
670687390732d6253903141d89d734113373d0e3c13Nancy Chen     * @return {@code true} if this is a new type of contact interaction (business or personal).
671687390732d6253903141d89d734113373d0e3c13Nancy Chen     * {@code false} if it hasn't changed.
672e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen     */
673687390732d6253903141d89d734113373d0e3c13Nancy Chen    private boolean setInCallContactInteractionsType(boolean isBusiness) {
674e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen        if (mInCallContactInteractions == null) {
675e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen            mInCallContactInteractions =
676e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen                    new InCallContactInteractions(mContext, isBusiness);
677687390732d6253903141d89d734113373d0e3c13Nancy Chen            return true;
678e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen        }
679687390732d6253903141d89d734113373d0e3c13Nancy Chen
680687390732d6253903141d89d734113373d0e3c13Nancy Chen        return mInCallContactInteractions.switchContactType(isBusiness);
681e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen    }
682e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen
683017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee    private void updateContactEntry(ContactCacheEntry entry, boolean isPrimary) {
68442373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        if (isPrimary) {
68542373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            mPrimaryContactInfo = entry;
686017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            updatePrimaryDisplayInfo();
687d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        } else {
68842373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            mSecondaryContactInfo = entry;
689017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            updateSecondaryDisplayInfo();
690d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        }
691d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    }
692d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon
693d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    /**
69482f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     * Get the highest priority call to display.
69582f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     * Goes through the calls and chooses which to return based on priority of which type of call
69682f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     * to display to the user. Callers can use the "ignore" feature to get the second best call
69782f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     * by passing a previously found primary call as ignore.
69882f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     *
69982f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     * @param ignore A call to ignore if found.
70082f5d003e675dfd56735c745744c3d968883b23cSantos Cordon     */
701d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    private Call getCallToDisplay(CallList callList, Call ignore, boolean skipDisconnected) {
702d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        // Active calls come second.  An active call always gets precedent.
703d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        Call retval = callList.getActiveCall();
70482f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        if (retval != null && retval != ignore) {
70582f5d003e675dfd56735c745744c3d968883b23cSantos Cordon            return retval;
70682f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        }
70782f5d003e675dfd56735c745744c3d968883b23cSantos Cordon
7088cc908aef3668de57a3991438e03c3863a4160d8Qi Wang        // Sometimes there is intemediate state that two calls are in active even one is about
7098cc908aef3668de57a3991438e03c3863a4160d8Qi Wang        // to be on hold.
7108cc908aef3668de57a3991438e03c3863a4160d8Qi Wang        retval = callList.getSecondActiveCall();
7118cc908aef3668de57a3991438e03c3863a4160d8Qi Wang        if (retval != null && retval != ignore) {
71282f5d003e675dfd56735c745744c3d968883b23cSantos Cordon            return retval;
71382f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        }
71482f5d003e675dfd56735c745744c3d968883b23cSantos Cordon
715d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        // Disconnected calls get primary position if there are no active calls
716d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        // to let user know quickly what call has disconnected. Disconnected
717d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        // calls are very short lived.
718d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        if (!skipDisconnected) {
7196258ff60a7edc760facc3f387fc9c8ceee3fb518Christine Chen            retval = callList.getDisconnectingCall();
7206258ff60a7edc760facc3f387fc9c8ceee3fb518Christine Chen            if (retval != null && retval != ignore) {
7216258ff60a7edc760facc3f387fc9c8ceee3fb518Christine Chen                return retval;
7226258ff60a7edc760facc3f387fc9c8ceee3fb518Christine Chen            }
723d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            retval = callList.getDisconnectedCall();
724d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            if (retval != null && retval != ignore) {
725d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon                return retval;
726d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            }
72782f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        }
72882f5d003e675dfd56735c745744c3d968883b23cSantos Cordon
72982f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        // Then we go to background call (calls on hold)
73082f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        retval = callList.getBackgroundCall();
73182f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        if (retval != null && retval != ignore) {
73282f5d003e675dfd56735c745744c3d968883b23cSantos Cordon            return retval;
73382f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        }
73482f5d003e675dfd56735c745744c3d968883b23cSantos Cordon
73582f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        // Lastly, we go to a second background call.
73682f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        retval = callList.getSecondBackgroundCall();
73782f5d003e675dfd56735c745744c3d968883b23cSantos Cordon
73882f5d003e675dfd56735c745744c3d968883b23cSantos Cordon        return retval;
73982f5d003e675dfd56735c745744c3d968883b23cSantos Cordon    }
74082f5d003e675dfd56735c745744c3d968883b23cSantos Cordon
741017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee    private void updatePrimaryDisplayInfo() {
7426d231f52e4f00399330d772f2a337283803f3a9dYorke Lee        final CallCardUi ui = getUi();
743d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        if (ui == null) {
74442373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            // TODO: May also occur if search result comes back after ui is destroyed. Look into
74542373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            // removing that case completely.
74642373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            Log.d(TAG, "updatePrimaryDisplayInfo called but ui is null!");
747d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon            return;
7486d231f52e4f00399330d772f2a337283803f3a9dYorke Lee        }
749be8060acf5ecbb916c161d3249813098c0611ed5Yorke Lee
750017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        if (mPrimary == null) {
751017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            // Clear the primary display info.
7527b2b43c0589ec79ba74359f7d9d6e0450fc322abVictor Chang            ui.setPrimary(null, null, false, null, null, false, false, false);
753017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            return;
754017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        }
755017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee
756fd640ab7b1efe30574c96a12b06627f365d0432aTyler Gunn        // Hide the contact photo if we are in a video call and the incoming video surface is
757fd640ab7b1efe30574c96a12b06627f365d0432aTyler Gunn        // showing.
758fd640ab7b1efe30574c96a12b06627f365d0432aTyler Gunn        boolean showContactPhoto = !VideoCallPresenter
759fd640ab7b1efe30574c96a12b06627f365d0432aTyler Gunn                .showIncomingVideo(mPrimary.getVideoState(), mPrimary.getState());
760fd640ab7b1efe30574c96a12b06627f365d0432aTyler Gunn
761f9aea95a921900b552bc808513f7c42c15e16f6cTony Mak        // Call placed through a work phone account.
762f75eb1ac9c28f1777ac375666b731d08630dbf1dTony Mak        boolean hasWorkCallProperty = mPrimary.hasProperty(PROPERTY_ENTERPRISE_CALL);
763f9aea95a921900b552bc808513f7c42c15e16f6cTony Mak
764017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        if (mPrimary.isConferenceCall()) {
765017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            Log.d(TAG, "Update primary display info for conference call.");
766017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee
767017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            ui.setPrimary(
768017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    null /* number */,
769017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    getConferenceString(mPrimary),
770017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    false /* nameIsNumber */,
771017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    null /* label */,
772017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    getConferencePhoto(mPrimary),
773fd640ab7b1efe30574c96a12b06627f365d0432aTyler Gunn                    false /* isSipCall */,
7747b2b43c0589ec79ba74359f7d9d6e0450fc322abVictor Chang                    showContactPhoto,
775f9aea95a921900b552bc808513f7c42c15e16f6cTony Mak                    hasWorkCallProperty);
776017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        } else if (mPrimaryContactInfo != null) {
777017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            Log.d(TAG, "Update primary display info for " + mPrimaryContactInfo);
778017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee
779017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            String name = getNameForCall(mPrimaryContactInfo);
780460ac2da6d15bd94fe31c1a30d12418d01d8976aTyler Gunn            String number;
781460ac2da6d15bd94fe31c1a30d12418d01d8976aTyler Gunn
782460ac2da6d15bd94fe31c1a30d12418d01d8976aTyler Gunn            boolean isChildNumberShown = !TextUtils.isEmpty(mPrimary.getChildNumber());
783061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn            boolean isForwardedNumberShown = !TextUtils.isEmpty(mPrimary.getLastForwardedNumber());
784061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn            boolean isCallSubjectShown = shouldShowCallSubject(mPrimary);
785061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn
786061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn            if (isCallSubjectShown) {
787061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn                ui.setCallSubject(mPrimary.getCallSubject());
788061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn            } else {
789061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn                ui.setCallSubject(null);
790061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn            }
791061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn
792061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn            if (isCallSubjectShown) {
793061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn                number = null;
794061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn            } else if (isChildNumberShown) {
795460ac2da6d15bd94fe31c1a30d12418d01d8976aTyler Gunn                number = mContext.getString(R.string.child_number, mPrimary.getChildNumber());
796061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn            } else if (isForwardedNumberShown) {
797061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn                // Use last forwarded number instead of second line, if present.
798061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn                number = mPrimary.getLastForwardedNumber();
799460ac2da6d15bd94fe31c1a30d12418d01d8976aTyler Gunn            } else {
800460ac2da6d15bd94fe31c1a30d12418d01d8976aTyler Gunn                number = getNumberForCall(mPrimaryContactInfo);
801460ac2da6d15bd94fe31c1a30d12418d01d8976aTyler Gunn            }
802460ac2da6d15bd94fe31c1a30d12418d01d8976aTyler Gunn
803061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn            ui.showForwardIndicator(isForwardedNumberShown);
804061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn            maybeShowHdAudioIcon();
805061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn
806017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            boolean nameIsNumber = name != null && name.equals(mPrimaryContactInfo.number);
807f9aea95a921900b552bc808513f7c42c15e16f6cTony Mak            // Call with caller that is a work contact.
8087b2b43c0589ec79ba74359f7d9d6e0450fc322abVictor Chang            boolean isWorkContact = (mPrimaryContactInfo.userType == ContactsUtils.USER_TYPE_WORK);
809017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            ui.setPrimary(
810017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    number,
811017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    name,
812017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    nameIsNumber,
813061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn                    isChildNumberShown || isCallSubjectShown ? null : mPrimaryContactInfo.label,
814017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    mPrimaryContactInfo.photo,
815fd640ab7b1efe30574c96a12b06627f365d0432aTyler Gunn                    mPrimaryContactInfo.isSipCall,
8167b2b43c0589ec79ba74359f7d9d6e0450fc322abVictor Chang                    showContactPhoto,
817f9aea95a921900b552bc808513f7c42c15e16f6cTony Mak                    hasWorkCallProperty || isWorkContact);
818687390732d6253903141d89d734113373d0e3c13Nancy Chen
819687390732d6253903141d89d734113373d0e3c13Nancy Chen            updateContactInteractions();
8206d231f52e4f00399330d772f2a337283803f3a9dYorke Lee        } else {
821017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            // Clear the primary display info.
8227b2b43c0589ec79ba74359f7d9d6e0450fc322abVictor Chang            ui.setPrimary(null, null, false, null, null, false, false, false);
823d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        }
824d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon
82589aad4adce9cc66294f15391fa3e10f3123d3d92Andrew Lee        if (mEmergencyCallListener != null) {
82693a6fd8d4a6f3ff4732cb4fb3b9df7c522b92823Tyler Gunn            boolean isEmergencyCall = mPrimary.isEmergencyCall();
82789aad4adce9cc66294f15391fa3e10f3123d3d92Andrew Lee            mEmergencyCallListener.onCallUpdated((BaseFragment) ui, isEmergencyCall);
82889aad4adce9cc66294f15391fa3e10f3123d3d92Andrew Lee        }
829d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    }
830d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon
831017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee    private void updateSecondaryDisplayInfo() {
83242373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        final CallCardUi ui = getUi();
83342373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        if (ui == null) {
83442373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            return;
83542373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        }
83642373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
837017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        if (mSecondary == null) {
838017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            // Clear the secondary display info.
839e96c83ad0a8f52a060d0ba7eac2290eb95b3b1c5Tyler Gunn            ui.setSecondary(false, null, false, null, null, false /* isConference */,
840a860052619d1c3d13a33629e97a8e05509fa0e1bTyler Gunn                    false /* isVideoCall */, mIsFullscreen);
841017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            return;
842017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        }
843c4bacb09c398a615154dc97b066179e77dc57599Yorke Lee
844017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        if (mSecondary.isConferenceCall()) {
845017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            ui.setSecondary(
846017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    true /* show */,
847017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    getConferenceString(mSecondary),
848017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    false /* nameIsNumber */,
849017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    null /* label */,
850017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    getCallProviderLabel(mSecondary),
851e96c83ad0a8f52a060d0ba7eac2290eb95b3b1c5Tyler Gunn                    true /* isConference */,
852a860052619d1c3d13a33629e97a8e05509fa0e1bTyler Gunn                    mSecondary.isVideoCall(mContext),
853a860052619d1c3d13a33629e97a8e05509fa0e1bTyler Gunn                    mIsFullscreen);
854017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        } else if (mSecondaryContactInfo != null) {
855017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            Log.d(TAG, "updateSecondaryDisplayInfo() " + mSecondaryContactInfo);
856017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            String name = getNameForCall(mSecondaryContactInfo);
857017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            boolean nameIsNumber = name != null && name.equals(mSecondaryContactInfo.number);
858017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            ui.setSecondary(
859017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    true /* show */,
860017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    name,
861017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    nameIsNumber,
862017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    mSecondaryContactInfo.label,
863017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                    getCallProviderLabel(mSecondary),
864e96c83ad0a8f52a060d0ba7eac2290eb95b3b1c5Tyler Gunn                    false /* isConference */,
865a860052619d1c3d13a33629e97a8e05509fa0e1bTyler Gunn                    mSecondary.isVideoCall(mContext),
866a860052619d1c3d13a33629e97a8e05509fa0e1bTyler Gunn                    mIsFullscreen);
86742373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        } else {
868017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee            // Clear the secondary display info.
869e96c83ad0a8f52a060d0ba7eac2290eb95b3b1c5Tyler Gunn            ui.setSecondary(false, null, false, null, null, false /* isConference */,
870a860052619d1c3d13a33629e97a8e05509fa0e1bTyler Gunn                    false /* isVideoCall */, mIsFullscreen);
87142373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        }
87242373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng    }
87342373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng
8748a80413884d1afbd7e021d581546c2245f068619Nancy Chen
8758a80413884d1afbd7e021d581546c2245f068619Nancy Chen    /**
8768a80413884d1afbd7e021d581546c2245f068619Nancy Chen     * Gets the phone account to display for a call.
8778a80413884d1afbd7e021d581546c2245f068619Nancy Chen     */
8788a80413884d1afbd7e021d581546c2245f068619Nancy Chen    private PhoneAccount getAccountForCall(Call call) {
8798a80413884d1afbd7e021d581546c2245f068619Nancy Chen        PhoneAccountHandle accountHandle = call.getAccountHandle();
8808a80413884d1afbd7e021d581546c2245f068619Nancy Chen        if (accountHandle == null) {
8818a80413884d1afbd7e021d581546c2245f068619Nancy Chen            return null;
8828a80413884d1afbd7e021d581546c2245f068619Nancy Chen        }
88329c01f36e9381b7bad135a9701aa3dffaf495b2fNancy Chen        return TelecomManagerCompat.getPhoneAccount(
88429c01f36e9381b7bad135a9701aa3dffaf495b2fNancy Chen                InCallPresenter.getInstance().getTelecomManager(),
88529c01f36e9381b7bad135a9701aa3dffaf495b2fNancy Chen                accountHandle);
8868a80413884d1afbd7e021d581546c2245f068619Nancy Chen    }
8878a80413884d1afbd7e021d581546c2245f068619Nancy Chen
8883d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    /**
8893d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon     * Returns the gateway number for any existing outgoing call.
8903d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon     */
8913d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    private String getGatewayNumber() {
8923d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        if (hasOutgoingGatewayCall()) {
89307fd3fd3ac627faf1771ba4699fe53a0479f2293Nancy Chen            return getNumberFromHandle(mPrimary.getGatewayInfo().getGatewayAddress());
8943d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        }
8953d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        return null;
8963d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    }
8973d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon
8983d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    /**
8998a80413884d1afbd7e021d581546c2245f068619Nancy Chen     * Return the string label to represent the call provider
9008a80413884d1afbd7e021d581546c2245f068619Nancy Chen     */
9018a80413884d1afbd7e021d581546c2245f068619Nancy Chen    private String getCallProviderLabel(Call call) {
9028a80413884d1afbd7e021d581546c2245f068619Nancy Chen        PhoneAccount account = getAccountForCall(call);
903170e405691a237b74fbecbf41208cbaa5bd36442Nancy Chen        TelecomManager mgr = InCallPresenter.getInstance().getTelecomManager();
90415b3fb7207bc356b2ee6ce1e8264d8242bb092ecJay Shrauner        if (account != null && !TextUtils.isEmpty(account.getLabel())
90529c01f36e9381b7bad135a9701aa3dffaf495b2fNancy Chen                && TelecomManagerCompat.getCallCapablePhoneAccounts(mgr).size() > 1) {
9068a80413884d1afbd7e021d581546c2245f068619Nancy Chen            return account.getLabel().toString();
907bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen        }
908bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen        return null;
909bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen    }
910bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen
911bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen    /**
912bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen     * Returns the label (line of text above the number/name) for any given call.
913f8b0677bed382046cb26e38a8442a9509d1e835cSailesh Nepal     * For example, "calling via [Account/Google Voice]" for outgoing calls.
9143d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon     */
915bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen    private String getConnectionLabel() {
9169124b77e489772fb7c6aac36f83d86ffdf83748fJay Shrauner        StatusHints statusHints = mPrimary.getTelecomCall().getDetails().getStatusHints();
917ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal        if (statusHints != null && !TextUtils.isEmpty(statusHints.getLabel())) {
918ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal            return statusHints.getLabel().toString();
919ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal        }
920ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal
9213d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        if (hasOutgoingGatewayCall() && getUi() != null) {
922bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen            // Return the label for the gateway app on outgoing calls.
9233d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon            final PackageManager pm = mContext.getPackageManager();
9243d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon            try {
925ae73c9aab1c716d9ef85f4f0dbc6f69e97a8f7e6Sailesh Nepal                ApplicationInfo info = pm.getApplicationInfo(
926ae73c9aab1c716d9ef85f4f0dbc6f69e97a8f7e6Sailesh Nepal                        mPrimary.getGatewayInfo().getGatewayProviderPackageName(), 0);
927bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen                return pm.getApplicationLabel(info).toString();
9283d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon            } catch (PackageManager.NameNotFoundException e) {
929bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen                Log.e(this, "Gateway Application Not Found.", e);
930bd93cb5444e886266b47e504138bcc65e6f09cbeNancy Chen                return null;
9313d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon            }
9323d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        }
9338a80413884d1afbd7e021d581546c2245f068619Nancy Chen        return getCallProviderLabel(mPrimary);
9343d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    }
9353d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon
9366c3061091e59e9ab06b620c2615b897e2eca233cAndrew Lee    private Drawable getCallStateIcon() {
9376c3061091e59e9ab06b620c2615b897e2eca233cAndrew Lee        // Return connection icon if one exists.
9389124b77e489772fb7c6aac36f83d86ffdf83748fJay Shrauner        StatusHints statusHints = mPrimary.getTelecomCall().getDetails().getStatusHints();
93918aaec1d250a5c5239ec5f06363f6fbb2519c55eIhab Awad        if (statusHints != null && statusHints.getIcon() != null) {
94018aaec1d250a5c5239ec5f06363f6fbb2519c55eIhab Awad            Drawable icon = statusHints.getIcon().loadDrawable(mContext);
941ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal            if (icon != null) {
942ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal                return icon;
943ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal            }
944ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal        }
9456c3061091e59e9ab06b620c2615b897e2eca233cAndrew Lee
946ab86f04c5ed385eafcd9099fa4ca50fd2f4c5c33Nancy Chen        return null;
947ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal    }
948ee9ec0928055307dc5d1f5c7509c301951a444a5Sailesh Nepal
9493d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    private boolean hasOutgoingGatewayCall() {
950b040158d7bb2f5c7d06bd2c1db5e96adafbcff3eTyler Gunn        // We only display the gateway information while STATE_DIALING so return false for any other
9513d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon        // call state.
95242373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        // TODO: mPrimary can be null because this is called from updatePrimaryDisplayInfo which
95342373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        // is also called after a contact search completes (call is not present yet).  Split the
95442373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        // UI update so it can receive independent updates.
95542373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        if (mPrimary == null) {
95642373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng            return false;
95742373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        }
958ae73c9aab1c716d9ef85f4f0dbc6f69e97a8f7e6Sailesh Nepal        return Call.State.isDialing(mPrimary.getState()) && mPrimary.getGatewayInfo() != null &&
959ae73c9aab1c716d9ef85f4f0dbc6f69e97a8f7e6Sailesh Nepal                !mPrimary.getGatewayInfo().isEmpty();
9603d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon    }
9613d3d25f2bee7cf9cdb91ef35d3028a6a62317e08Santos Cordon
962d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    /**
963d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon     * Gets the name to display for the call.
964d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon     */
9659cd03e1e3c319f7633638615074da3028eb45c2bBrandon Maxwell    @NeededForTesting
9669cd03e1e3c319f7633638615074da3028eb45c2bBrandon Maxwell    String getNameForCall(ContactCacheEntry contactInfo) {
9679cc21097e06859c8e3b36b9f18e5bad7c739c5f8Brandon Maxwell        String preferredName = ContactDisplayUtils.getPreferredDisplayName(
9689cc21097e06859c8e3b36b9f18e5bad7c739c5f8Brandon Maxwell                contactInfo.namePrimary,
9699cc21097e06859c8e3b36b9f18e5bad7c739c5f8Brandon Maxwell                contactInfo.nameAlternative,
9709cc21097e06859c8e3b36b9f18e5bad7c739c5f8Brandon Maxwell                mContactsPreferences);
9718c03464c2c348af3bcd3bdfb911cd1bf17a760d0Brandon Maxwell        if (TextUtils.isEmpty(preferredName)) {
972d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon            return contactInfo.number;
9736d231f52e4f00399330d772f2a337283803f3a9dYorke Lee        }
9748c03464c2c348af3bcd3bdfb911cd1bf17a760d0Brandon Maxwell        return preferredName;
975d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    }
9766d231f52e4f00399330d772f2a337283803f3a9dYorke Lee
977d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon    /**
978d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon     * Gets the number to display for a call.
979d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon     */
9809cd03e1e3c319f7633638615074da3028eb45c2bBrandon Maxwell    @NeededForTesting
9819cd03e1e3c319f7633638615074da3028eb45c2bBrandon Maxwell    String getNumberForCall(ContactCacheEntry contactInfo) {
9829cd03e1e3c319f7633638615074da3028eb45c2bBrandon Maxwell        // If the name is empty, we use the number for the name...so don't show a second
983d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        // number in the number field
9849cc21097e06859c8e3b36b9f18e5bad7c739c5f8Brandon Maxwell        String preferredName = ContactDisplayUtils.getPreferredDisplayName(
9859cd03e1e3c319f7633638615074da3028eb45c2bBrandon Maxwell                    contactInfo.namePrimary,
9869cd03e1e3c319f7633638615074da3028eb45c2bBrandon Maxwell                    contactInfo.nameAlternative,
9879cc21097e06859c8e3b36b9f18e5bad7c739c5f8Brandon Maxwell                    mContactsPreferences);
9889cd03e1e3c319f7633638615074da3028eb45c2bBrandon Maxwell        if (TextUtils.isEmpty(preferredName)) {
9891c6bb983216392b5ceb36cea42a46631f68a3dd6Jay Shrauner            return contactInfo.location;
990d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        }
991d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        return contactInfo.number;
992d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    }
9936d231f52e4f00399330d772f2a337283803f3a9dYorke Lee
994e5c0d8bdf8269f9435e0381889e4870f36a43f07Andrew Lee    public void secondaryInfoClicked() {
99580c49a823543c9fb93420d05a6375fb1ff4ca631Yorke Lee        if (mSecondary == null) {
9968b514c9571c587b2e87edfffa38afde4f0458579Nancy Chen            Log.w(this, "Secondary info clicked but no secondary call.");
99780c49a823543c9fb93420d05a6375fb1ff4ca631Yorke Lee            return;
99880c49a823543c9fb93420d05a6375fb1ff4ca631Yorke Lee        }
99980c49a823543c9fb93420d05a6375fb1ff4ca631Yorke Lee
1000248a6687e8075e9730217be73c54ee4f95501a0eSailesh Nepal        Log.i(this, "Swapping call to foreground: " + mSecondary);
10014b293f0f08030c97e1bb54d2f79ac2fb1a6e29aeTyler Gunn        TelecomAdapter.getInstance().unholdCall(mSecondary.getId());
100290995fcb6778a9cb6dc35be12aeb1a5d0dcbb5aeYorke Lee    }
100390995fcb6778a9cb6dc35be12aeb1a5d0dcbb5aeYorke Lee
10047e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee    public void endCallClicked() {
10057e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee        if (mPrimary == null) {
10067e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee            return;
10077e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee        }
10087e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee
1009cb2f51bf1acf387f391ca9c8cae8a2344eb2936aEvan Charlton        Log.i(this, "Disconnecting call: " + mPrimary);
1010d274e92414988c72708af270e3799b83b4e3b40cJay Shrauner        final String callId = mPrimary.getId();
101133478eae2d380adfcc7ef3f51816ff391a42ebb7Ihab Awad        mPrimary.setState(Call.State.DISCONNECTING);
101233478eae2d380adfcc7ef3f51816ff391a42ebb7Ihab Awad        CallList.getInstance().onUpdate(mPrimary);
1013d274e92414988c72708af270e3799b83b4e3b40cJay Shrauner        TelecomAdapter.getInstance().disconnectCall(callId);
10147e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee    }
10157e5763d2b5ee7211c5d19d2b1fd2736e407a7e83Andrew Lee
1016da7f422a46db4bfe5cf76312d23b44e60fa9d806Santos Cordon    private String getNumberFromHandle(Uri handle) {
1017da7f422a46db4bfe5cf76312d23b44e60fa9d806Santos Cordon        return handle == null ? "" : handle.getSchemeSpecificPart();
1018da7f422a46db4bfe5cf76312d23b44e60fa9d806Santos Cordon    }
1019da7f422a46db4bfe5cf76312d23b44e60fa9d806Santos Cordon
1020350fff554bf7ed5b9e91985935488771156953abTyler Gunn    /**
10213326f42f13f6f8cd8934aec615078a8890212402Tyler Gunn     * Handles a change to the fullscreen mode of the in-call UI.
1022350fff554bf7ed5b9e91985935488771156953abTyler Gunn     *
10233326f42f13f6f8cd8934aec615078a8890212402Tyler Gunn     * @param isFullscreenMode {@code True} if the in-call UI is entering full screen mode.
1024350fff554bf7ed5b9e91985935488771156953abTyler Gunn     */
1025350fff554bf7ed5b9e91985935488771156953abTyler Gunn    @Override
10263326f42f13f6f8cd8934aec615078a8890212402Tyler Gunn    public void onFullscreenModeChanged(boolean isFullscreenMode) {
1027a860052619d1c3d13a33629e97a8e05509fa0e1bTyler Gunn        mIsFullscreen = isFullscreenMode;
1028350fff554bf7ed5b9e91985935488771156953abTyler Gunn        final CallCardUi ui = getUi();
1029350fff554bf7ed5b9e91985935488771156953abTyler Gunn        if (ui == null) {
1030350fff554bf7ed5b9e91985935488771156953abTyler Gunn            return;
1031350fff554bf7ed5b9e91985935488771156953abTyler Gunn        }
10323326f42f13f6f8cd8934aec615078a8890212402Tyler Gunn        ui.setCallCardVisible(!isFullscreenMode);
1033a860052619d1c3d13a33629e97a8e05509fa0e1bTyler Gunn        ui.setSecondaryInfoVisible(!isFullscreenMode);
103484a1becf7d9a7055f16fc5b0e503e0512dcdfcf1Tyler Gunn        maybeShowManageConferenceCallButton();
1035a860052619d1c3d13a33629e97a8e05509fa0e1bTyler Gunn    }
1036a860052619d1c3d13a33629e97a8e05509fa0e1bTyler Gunn
1037a860052619d1c3d13a33629e97a8e05509fa0e1bTyler Gunn    @Override
1038a860052619d1c3d13a33629e97a8e05509fa0e1bTyler Gunn    public void onSecondaryCallerInfoVisibilityChanged(boolean isVisible, int height) {
1039a860052619d1c3d13a33629e97a8e05509fa0e1bTyler Gunn        // No-op - the Call Card is the origin of this event.
1040350fff554bf7ed5b9e91985935488771156953abTyler Gunn    }
1041350fff554bf7ed5b9e91985935488771156953abTyler Gunn
10428cdac35f2aa80d1732dfc5fdaee1a21035a1bfcbAndrew Lee    private boolean isPrimaryCallActive() {
10438cdac35f2aa80d1732dfc5fdaee1a21035a1bfcbAndrew Lee        return mPrimary != null && mPrimary.getState() == Call.State.ACTIVE;
10448cdac35f2aa80d1732dfc5fdaee1a21035a1bfcbAndrew Lee    }
10458cdac35f2aa80d1732dfc5fdaee1a21035a1bfcbAndrew Lee
1046017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee    private String getConferenceString(Call call) {
104759585f80dce30e53ea30f08f11089f6cdd6e41fbAndrew Lee        boolean isGenericConference = call.hasProperty(Details.PROPERTY_GENERIC_CONFERENCE);
1048017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        Log.v(this, "getConferenceString: " + isGenericConference);
1049017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee
1050017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        final int resId = isGenericConference
1051017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                ? R.string.card_title_in_call : R.string.card_title_conf_call;
1052017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        return mContext.getResources().getString(resId);
1053017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee    }
1054017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee
1055017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee    private Drawable getConferencePhoto(Call call) {
105659585f80dce30e53ea30f08f11089f6cdd6e41fbAndrew Lee        boolean isGenericConference = call.hasProperty(Details.PROPERTY_GENERIC_CONFERENCE);
1057017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        Log.v(this, "getConferencePhoto: " + isGenericConference);
1058017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee
1059017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        final int resId = isGenericConference
1060017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee                ? R.drawable.img_phone : R.drawable.img_conference;
1061017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        Drawable photo = mContext.getResources().getDrawable(resId);
1062017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        photo.setAutoMirrored(true);
1063017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee        return photo;
1064017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee    }
1065017ebaba75180c0a8deb9de3f819cbae92d45e72Andrew Lee
1066fdf53779ba6d68e28e005e3645378aea7bd76ec0Yorke Lee    private boolean shouldShowEndCallButton(Call primary, int callState) {
1067fdf53779ba6d68e28e005e3645378aea7bd76ec0Yorke Lee        if (primary == null) {
1068fdf53779ba6d68e28e005e3645378aea7bd76ec0Yorke Lee            return false;
1069fdf53779ba6d68e28e005e3645378aea7bd76ec0Yorke Lee        }
10704c058612097eba72b33d83f5612012a90167957aYorke Lee        if ((!Call.State.isConnectingOrConnected(callState)
10714c058612097eba72b33d83f5612012a90167957aYorke Lee                && callState != Call.State.DISCONNECTING) || callState == Call.State.INCOMING) {
1072fdf53779ba6d68e28e005e3645378aea7bd76ec0Yorke Lee            return false;
1073fdf53779ba6d68e28e005e3645378aea7bd76ec0Yorke Lee        }
1074fdf53779ba6d68e28e005e3645378aea7bd76ec0Yorke Lee        if (mPrimary.getSessionModificationState()
1075fdf53779ba6d68e28e005e3645378aea7bd76ec0Yorke Lee                == Call.SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST) {
1076fdf53779ba6d68e28e005e3645378aea7bd76ec0Yorke Lee            return false;
1077fdf53779ba6d68e28e005e3645378aea7bd76ec0Yorke Lee        }
1078fdf53779ba6d68e28e005e3645378aea7bd76ec0Yorke Lee        return true;
1079fdf53779ba6d68e28e005e3645378aea7bd76ec0Yorke Lee    }
1080fdf53779ba6d68e28e005e3645378aea7bd76ec0Yorke Lee
1081e1c196e04154815e2fb55801af73beb9fb2aa324Qi Wang    private void maybeSendAccessibilityEvent(InCallState oldState, InCallState newState,
1082e1c196e04154815e2fb55801af73beb9fb2aa324Qi Wang                                             boolean primaryChanged) {
10830dbdccd2aa0e6828e1332adf83e630a74527a248Yorke Lee        if (mContext == null) {
10840dbdccd2aa0e6828e1332adf83e630a74527a248Yorke Lee            return;
10850dbdccd2aa0e6828e1332adf83e630a74527a248Yorke Lee        }
10860dbdccd2aa0e6828e1332adf83e630a74527a248Yorke Lee        final AccessibilityManager am = (AccessibilityManager) mContext.getSystemService(
10870dbdccd2aa0e6828e1332adf83e630a74527a248Yorke Lee                Context.ACCESSIBILITY_SERVICE);
10880dbdccd2aa0e6828e1332adf83e630a74527a248Yorke Lee        if (!am.isEnabled()) {
10890dbdccd2aa0e6828e1332adf83e630a74527a248Yorke Lee            return;
10900dbdccd2aa0e6828e1332adf83e630a74527a248Yorke Lee        }
1091e1c196e04154815e2fb55801af73beb9fb2aa324Qi Wang        // Announce the current call if it's new incoming/outgoing call or primary call is changed
1092e1c196e04154815e2fb55801af73beb9fb2aa324Qi Wang        // due to switching calls between two ongoing calls (one is on hold).
10930dbdccd2aa0e6828e1332adf83e630a74527a248Yorke Lee        if ((oldState != InCallState.OUTGOING && newState == InCallState.OUTGOING)
1094e1c196e04154815e2fb55801af73beb9fb2aa324Qi Wang                || (oldState != InCallState.INCOMING && newState == InCallState.INCOMING)
1095e1c196e04154815e2fb55801af73beb9fb2aa324Qi Wang                || primaryChanged) {
10960dbdccd2aa0e6828e1332adf83e630a74527a248Yorke Lee            if (getUi() != null) {
10970dbdccd2aa0e6828e1332adf83e630a74527a248Yorke Lee                getUi().sendAccessibilityAnnouncement();
10980dbdccd2aa0e6828e1332adf83e630a74527a248Yorke Lee            }
10990dbdccd2aa0e6828e1332adf83e630a74527a248Yorke Lee        }
11000dbdccd2aa0e6828e1332adf83e630a74527a248Yorke Lee    }
11010dbdccd2aa0e6828e1332adf83e630a74527a248Yorke Lee
1102061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn    /**
1103061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn     * Determines whether the call subject should be visible on the UI.  For the call subject to be
1104061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn     * visible, the call has to be in an incoming or waiting state, and the subject must not be
1105061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn     * empty.
1106061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn     *
1107061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn     * @param call The call.
1108061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn     * @return {@code true} if the subject should be shown, {@code false} otherwise.
1109061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn     */
1110061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn    private boolean shouldShowCallSubject(Call call) {
1111061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn        if (call == null) {
1112061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn            return false;
1113061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn        }
1114061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn
1115061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn        boolean isIncomingOrWaiting = mPrimary.getState() == Call.State.INCOMING ||
1116061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn                mPrimary.getState() == Call.State.CALL_WAITING;
1117edf496040d42e16909ffdbf4810dc9b1e5b026f8Tyler Gunn        return isIncomingOrWaiting && !TextUtils.isEmpty(call.getCallSubject()) &&
1118edf496040d42e16909ffdbf4810dc9b1e5b026f8Tyler Gunn                call.getNumberPresentation() == TelecomManager.PRESENTATION_ALLOWED &&
1119edf496040d42e16909ffdbf4810dc9b1e5b026f8Tyler Gunn                call.isCallSubjectSupported();
1120061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn    }
1121061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn
112281ae21863de1fe836f5e62aa5e324a35a8eb7d06Tyler Gunn    /**
112381ae21863de1fe836f5e62aa5e324a35a8eb7d06Tyler Gunn     * Determines whether the "note sent" toast should be shown.  It should be shown for a new
112481ae21863de1fe836f5e62aa5e324a35a8eb7d06Tyler Gunn     * outgoing call with a subject.
112581ae21863de1fe836f5e62aa5e324a35a8eb7d06Tyler Gunn     *
112681ae21863de1fe836f5e62aa5e324a35a8eb7d06Tyler Gunn     * @param call The call
112781ae21863de1fe836f5e62aa5e324a35a8eb7d06Tyler Gunn     * @return {@code true} if the toast should be shown, {@code false} otherwise.
112881ae21863de1fe836f5e62aa5e324a35a8eb7d06Tyler Gunn     */
112981ae21863de1fe836f5e62aa5e324a35a8eb7d06Tyler Gunn    private boolean shouldShowNoteSentToast(Call call) {
113041c304dae70a534f0e9b345e905f30ec76b9ea73Brandon Maxwell        return call != null && hasCallSubject(call) && (call.getState() == Call.State.DIALING
113141c304dae70a534f0e9b345e905f30ec76b9ea73Brandon Maxwell                || call.getState() == Call.State.CONNECTING);
113241c304dae70a534f0e9b345e905f30ec76b9ea73Brandon Maxwell    }
113341c304dae70a534f0e9b345e905f30ec76b9ea73Brandon Maxwell
113441c304dae70a534f0e9b345e905f30ec76b9ea73Brandon Maxwell    private static boolean hasCallSubject(Call call) {
11356a4e9d87031f1f803ce9b64844f71c73e9502a7eSailesh Nepal        return !TextUtils.isEmpty(call.getTelecomCall().getDetails().getIntentExtras()
11366a4e9d87031f1f803ce9b64844f71c73e9502a7eSailesh Nepal                .getString(TelecomManager.EXTRA_CALL_SUBJECT));
113781ae21863de1fe836f5e62aa5e324a35a8eb7d06Tyler Gunn    }
113881ae21863de1fe836f5e62aa5e324a35a8eb7d06Tyler Gunn
1139d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon    public interface CallCardUi extends Ui {
1140d2bd93fe3929403f84367f826f07cbadc0c6366bSantos Cordon        void setVisible(boolean on);
1141687390732d6253903141d89d734113373d0e3c13Nancy Chen        void setContactContextTitle(View listHeaderView);
1142687390732d6253903141d89d734113373d0e3c13Nancy Chen        void setContactContextContent(ListAdapter listAdapter);
1143e838ba2b69cf85b0d938467477e47cce4af2bfb6Nancy Chen        void showContactContext(boolean show);
1144350fff554bf7ed5b9e91985935488771156953abTyler Gunn        void setCallCardVisible(boolean visible);
1145d28fc12696fa706fed70e04698275af7be7fee82Santos Cordon        void setPrimary(String number, String name, boolean nameIsNumber, String label,
1146f9aea95a921900b552bc808513f7c42c15e16f6cTony Mak                Drawable photo, boolean isSipCall, boolean isContactPhotoShown, boolean isWorkCall);
1147c4bacb09c398a615154dc97b066179e77dc57599Yorke Lee        void setSecondary(boolean show, String name, boolean nameIsNumber, String label,
1148a860052619d1c3d13a33629e97a8e05509fa0e1bTyler Gunn                String providerLabel, boolean isConference, boolean isVideoCall,
1149a860052619d1c3d13a33629e97a8e05509fa0e1bTyler Gunn                boolean isFullscreen);
1150a860052619d1c3d13a33629e97a8e05509fa0e1bTyler Gunn        void setSecondaryInfoVisible(boolean visible);
115150dbb6eeca55cf78e0fd9eb132a26787d293620aAndrew Lee        void setCallState(int state, int videoState, int sessionModificationState,
115250dbb6eeca55cf78e0fd9eb132a26787d293620aAndrew Lee                DisconnectCause disconnectCause, String connectionLabel,
1153dc3122e9d7bc0c6f5fef00bed36bb300c40afadfAndrew Lee                Drawable connectionIcon, String gatewayNumber, boolean isWifi,
11547f07f9f6f1e209359cf069b1fa4b0dfc0b371f64Victor Chang                boolean isConference, boolean isWorkCall);
1155f0dfbe2e89df0d58efde8b290662072c081e146aNancy Chen        void setPrimaryCallElapsedTime(boolean show, long duration);
115642373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        void setPrimaryName(String name, boolean nameIsNumber);
1157fd640ab7b1efe30574c96a12b06627f365d0432aTyler Gunn        void setPrimaryImage(Drawable image, boolean isVisible);
115842373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        void setPrimaryPhoneNumber(String phoneNumber);
115942373eb59cbef15ec61ebb5c919031f293291a53Chiao Cheng        void setPrimaryLabel(String label);
1160c44f654b992c6ab8a4acff9cb5aa2678c58755d9Andrew Lee        void setEndCallButtonEnabled(boolean enabled, boolean animate);
11610786dba0baa54fd12697b4795e7c646cfe4ae5c3Evan Charlton        void setCallbackNumber(String number, boolean isEmergencyCalls);
1162061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn        void setCallSubject(String callSubject);
1163350fff554bf7ed5b9e91985935488771156953abTyler Gunn        void setProgressSpinnerVisible(boolean visible);
11648cdac35f2aa80d1732dfc5fdaee1a21035a1bfcbAndrew Lee        void showHdAudioIndicator(boolean visible);
1165061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn        void showForwardIndicator(boolean visible);
11661da81ce59cfbebd4e53fdfd2011e859069120de7Andrew Lee        void showManageConferenceCallButton(boolean visible);
11670cff18feff43a6915919ac8e32fa44502aa6c320Tyler Gunn        boolean isManageConferenceVisible();
1168061fc22101930c3c69f454c85fbb85ff2c5c92fbTyler Gunn        boolean isCallSubjectVisible();
11696596e1be9d3e15e2cbe4a5e9c3824ee47a0e2744Yorke Lee        void animateForNewOutgoingCall();
11700dbdccd2aa0e6828e1332adf83e630a74527a248Yorke Lee        void sendAccessibilityAnnouncement();
117181ae21863de1fe836f5e62aa5e324a35a8eb7d06Tyler Gunn        void showNoteSentToast();
1172be8060acf5ecbb916c161d3249813098c0611ed5Yorke Lee    }
1173c2b430394ac612ba4dd455fb988e29bfcc4d5c5fSantos Cordon}
1174