1a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon/* 2a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon * Copyright (C) 2013 The Android Open Source Project 3a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon * 4a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon * Licensed under the Apache License, Version 2.0 (the "License"); 5a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon * you may not use this file except in compliance with the License. 6a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon * You may obtain a copy of the License at 7a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon * 8a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon * http://www.apache.org/licenses/LICENSE-2.0 9a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon * 10a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon * Unless required by applicable law or agreed to in writing, software 11a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon * distributed under the License is distributed on an "AS IS" BASIS, 12a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon * See the License for the specific language governing permissions and 14a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon * limitations under the License 15a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon */ 16a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon 17a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordonpackage com.android.incallui; 18a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon 19f2b1401b9680fa4344cec18a01b11fc9e100ae17Evan Charltonimport android.Manifest; 203d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordonimport android.content.Context; 21f2b1401b9680fa4344cec18a01b11fc9e100ae17Evan Charltonimport android.content.Intent; 223d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordonimport android.content.pm.ApplicationInfo; 233d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordonimport android.content.pm.PackageManager; 24988d06b64b99a13f4f060dc82594edcb738d9113Yorke Leeimport android.graphics.drawable.Drawable; 25e038ead8b0e520787b41e5dbd6f4c534881e10d5Santos Cordonimport android.net.Uri; 263f4f33bc27ee1c9a12c9e55856b29079301c8a08Evan Charltonimport android.os.Bundle; 27017f23c5f9ee2585454b43ae15c14c98e48e8f17Andrew Leeimport android.os.Handler; 28017f23c5f9ee2585454b43ae15c14c98e48e8f17Andrew Leeimport android.telecom.DisconnectCause; 296cddf46812634fadc194830774110780f14e9462Tyler Gunnimport android.telecom.PhoneCapabilities; 306cddf46812634fadc194830774110780f14e9462Tyler Gunnimport android.telecom.PhoneAccount; 316cddf46812634fadc194830774110780f14e9462Tyler Gunnimport android.telecom.PhoneAccountHandle; 326cddf46812634fadc194830774110780f14e9462Tyler Gunnimport android.telecom.StatusHints; 336cddf46812634fadc194830774110780f14e9462Tyler Gunnimport android.telecom.TelecomManager; 346cddf46812634fadc194830774110780f14e9462Tyler Gunnimport android.telecom.VideoProfile; 353f4f33bc27ee1c9a12c9e55856b29079301c8a08Evan Charltonimport android.telephony.PhoneNumberUtils; 364940f9ff450d1054ed4ad0e61179196007ad5531Evan Charltonimport android.telephony.TelephonyManager; 371df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordonimport android.text.TextUtils; 3888dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordonimport android.text.format.DateUtils; 397ef707319c0e3563ff92a772ba53cb5dca0e3ae1Yorke Lee 404bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordonimport com.android.incallui.ContactInfoCache.ContactCacheEntry; 414bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordonimport com.android.incallui.ContactInfoCache.ContactInfoCacheCallback; 423f4f33bc27ee1c9a12c9e55856b29079301c8a08Evan Charltonimport com.android.incallui.InCallPresenter.InCallDetailsListener; 4315a8e3cb2c01b59b5328a74e6c46144843103205Tyler Gunnimport com.android.incallui.InCallPresenter.InCallEventListener; 44671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordonimport com.android.incallui.InCallPresenter.InCallState; 45671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordonimport com.android.incallui.InCallPresenter.InCallStateListener; 461ee82fcea79556c90eec0f55ea2e2ab5c6dfaddaSantos Cordonimport com.android.incallui.InCallPresenter.IncomingCallListener; 47f2b1401b9680fa4344cec18a01b11fc9e100ae17Evan Charltonimport com.android.incalluibind.ObjectFactory; 48e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee 49e89ee6f3c48374bfdea5450d6311763bc061885fYorke Leeimport java.lang.ref.WeakReference; 50e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee 518b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Chengimport com.google.common.base.Preconditions; 52a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon 53a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon/** 54a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon * Presenter for the Call Card Fragment. 551fa0782281ef7774ddcdfdf8efb7d8f65cf589e7Chiao Cheng * <p> 56671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon * This class listens for changes to InCallState and passes it along to the fragment. 57a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon */ 584bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordonpublic class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi> 594b0d86229cf80a4d85652ca097b0f3bcf902b4acAndrew Lee implements InCallStateListener, IncomingCallListener, InCallDetailsListener, 60fe4982c221c8ee734afedc4d005661d9c6c1ac31Andrew Lee InCallEventListener { 617ef707319c0e3563ff92a772ba53cb5dca0e3ae1Yorke Lee 621fa0782281ef7774ddcdfdf8efb7d8f65cf589e7Chiao Cheng private static final String TAG = CallCardPresenter.class.getSimpleName(); 63aed98fccfc2af12f8c24f93242fecdab23758c8dAndrew Lee private static final long CALL_TIME_UPDATE_INTERVAL_MS = 1000; 6488dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon 65b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon private Call mPrimary; 664bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon private Call mSecondary; 674bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon private ContactCacheEntry mPrimaryContactInfo; 684bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon private ContactCacheEntry mSecondaryContactInfo; 6978b97bbc961a2d11c108c11b68d30d916fedd4ccAndrew Lee private CallTimer mCallTimer; 703d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon private Context mContext; 716cddf46812634fadc194830774110780f14e9462Tyler Gunn private TelecomManager mTelecomManager; 72988d06b64b99a13f4f060dc82594edcb738d9113Yorke Lee 73e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee public static class ContactLookupCallback implements ContactInfoCacheCallback { 74e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee private final WeakReference<CallCardPresenter> mCallCardPresenter; 75e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee private final boolean mIsPrimary; 76e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee 77e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee public ContactLookupCallback(CallCardPresenter callCardPresenter, boolean isPrimary) { 78e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee mCallCardPresenter = new WeakReference<CallCardPresenter>(callCardPresenter); 79e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee mIsPrimary = isPrimary; 80e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee } 81e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee 82e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee @Override 83e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee public void onContactInfoComplete(String callId, ContactCacheEntry entry) { 84e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee CallCardPresenter presenter = mCallCardPresenter.get(); 85e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee if (presenter != null) { 86e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee presenter.onContactInfoComplete(callId, entry, mIsPrimary); 87e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee } 88e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee } 89e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee 90e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee @Override 91e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee public void onImageLoadComplete(String callId, ContactCacheEntry entry) { 92e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee CallCardPresenter presenter = mCallCardPresenter.get(); 93e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee if (presenter != null) { 94e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee presenter.onImageLoadComplete(callId, entry); 95e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee } 96e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee } 97e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee 98e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee } 99e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee 1009de3d7c5188c02cabf03799f87d494ee7dc702cbSantos Cordon public CallCardPresenter() { 10188dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon // create the call timer 10288dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon mCallTimer = new CallTimer(new Runnable() { 10388dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon @Override 10488dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon public void run() { 10588dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon updateCallTime(); 10688dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon } 10788dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon }); 108988d06b64b99a13f4f060dc82594edcb738d9113Yorke Lee } 109988d06b64b99a13f4f060dc82594edcb738d9113Yorke Lee 110101bed44998ff35c3a56f431345fac5c8229ec0eJay Shrauner public void init(Context context, Call call) { 1118b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng mContext = Preconditions.checkNotNull(context); 1128b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng 113bf62e69f8f029b616726577df7aa100c0900d6e5Chiao Cheng // Call may be null if disconnect happened already. 114bf62e69f8f029b616726577df7aa100c0900d6e5Chiao Cheng if (call != null) { 11541457dce3ca531178ca07946868afb0cc1579a6bChiao Cheng mPrimary = call; 11641457dce3ca531178ca07946868afb0cc1579a6bChiao Cheng 117bf62e69f8f029b616726577df7aa100c0900d6e5Chiao Cheng // start processing lookups right away. 118625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon if (!call.isConferenceCall()) { 119fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal startContactInfoSearch(call, true, call.getState() == Call.State.INCOMING); 120625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon } else { 121625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon updateContactEntry(null, true, true); 122625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon } 123bf62e69f8f029b616726577df7aa100c0900d6e5Chiao Cheng } 1241fa0782281ef7774ddcdfdf8efb7d8f65cf589e7Chiao Cheng } 1251fa0782281ef7774ddcdfdf8efb7d8f65cf589e7Chiao Cheng 126a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon @Override 127a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon public void onUiReady(CallCardUi ui) { 128a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon super.onUiReady(ui); 129b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon 1308b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng // Contact search may have completed before ui is ready. 1318b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng if (mPrimaryContactInfo != null) { 1326d93245c0c9067d7a6ff30fd6fb79431da124946Christine Chen updatePrimaryDisplayInfo(mPrimaryContactInfo, isConference(mPrimary)); 1338b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng } 1348b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng 135b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon // Register for call state changes last 136b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon InCallPresenter.getInstance().addListener(this); 1371ee82fcea79556c90eec0f55ea2e2ab5c6dfaddaSantos Cordon InCallPresenter.getInstance().addIncomingCallListener(this); 1383f4f33bc27ee1c9a12c9e55856b29079301c8a08Evan Charlton InCallPresenter.getInstance().addDetailsListener(this); 13915a8e3cb2c01b59b5328a74e6c46144843103205Tyler Gunn InCallPresenter.getInstance().addInCallEventListener(this); 140b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon } 141b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon 142b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon @Override 143b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon public void onUiUnready(CallCardUi ui) { 144b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon super.onUiUnready(ui); 145b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon 146b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon // stop getting call state changes 147b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon InCallPresenter.getInstance().removeListener(this); 1481ee82fcea79556c90eec0f55ea2e2ab5c6dfaddaSantos Cordon InCallPresenter.getInstance().removeIncomingCallListener(this); 1493f4f33bc27ee1c9a12c9e55856b29079301c8a08Evan Charlton InCallPresenter.getInstance().removeDetailsListener(this); 15015a8e3cb2c01b59b5328a74e6c46144843103205Tyler Gunn InCallPresenter.getInstance().removeInCallEventListener(this); 151b0d08a16da088e01f416f52a7b74ee9630c1493aSantos Cordon 152b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon mPrimary = null; 1534bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon mPrimaryContactInfo = null; 1544bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon mSecondaryContactInfo = null; 155a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon } 156a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon 157a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon @Override 158f3d0654f2b6d77b7eef8bdcb4c39ee59e55017deNancy Chen public void onIncomingCall(InCallState oldState, InCallState newState, Call call) { 1591ee82fcea79556c90eec0f55ea2e2ab5c6dfaddaSantos Cordon // same logic should happen as with onStateChange() 160f3d0654f2b6d77b7eef8bdcb4c39ee59e55017deNancy Chen onStateChange(oldState, newState, CallList.getInstance()); 1611ee82fcea79556c90eec0f55ea2e2ab5c6dfaddaSantos Cordon } 1621ee82fcea79556c90eec0f55ea2e2ab5c6dfaddaSantos Cordon 1631ee82fcea79556c90eec0f55ea2e2ab5c6dfaddaSantos Cordon @Override 164f3d0654f2b6d77b7eef8bdcb4c39ee59e55017deNancy Chen public void onStateChange(InCallState oldState, InCallState newState, CallList callList) { 165f3d0654f2b6d77b7eef8bdcb4c39ee59e55017deNancy Chen Log.d(this, "onStateChange() " + newState); 166150a5c58c67f230c8fd7293b180bbf50aa761480Santos Cordon final CallCardUi ui = getUi(); 167b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon if (ui == null) { 168b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon return; 169b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon } 170a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon 171671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon Call primary = null; 172671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon Call secondary = null; 173671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon 174f3d0654f2b6d77b7eef8bdcb4c39ee59e55017deNancy Chen if (newState == InCallState.INCOMING) { 175671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon primary = callList.getIncomingCall(); 176f3d0654f2b6d77b7eef8bdcb4c39ee59e55017deNancy Chen } else if (newState == InCallState.PENDING_OUTGOING || newState == InCallState.OUTGOING) { 177e7be13fb0556e62b07bc271b130412d82d7f7521Santos Cordon primary = callList.getOutgoingCall(); 178f3d0654f2b6d77b7eef8bdcb4c39ee59e55017deNancy Chen if (primary == null) { 179f3d0654f2b6d77b7eef8bdcb4c39ee59e55017deNancy Chen primary = callList.getPendingOutgoingCall(); 180f3d0654f2b6d77b7eef8bdcb4c39ee59e55017deNancy Chen } 181e7be13fb0556e62b07bc271b130412d82d7f7521Santos Cordon 182a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon // getCallToDisplay doesn't go through outgoing or incoming calls. It will return the 183a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon // highest priority call to display as the secondary call. 1841df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon secondary = getCallToDisplay(callList, null, true); 185f3d0654f2b6d77b7eef8bdcb4c39ee59e55017deNancy Chen } else if (newState == InCallState.INCALL) { 1861df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon primary = getCallToDisplay(callList, null, false); 1871df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon secondary = getCallToDisplay(callList, primary, true); 188671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon } 189671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon 1901a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng Log.d(this, "Primary call: " + primary); 1911a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng Log.d(this, "Secondary call: " + secondary); 192671b221ccadea34fb9327ef5342b26419eb5ca99Santos Cordon 193fe4982c221c8ee734afedc4d005661d9c6c1ac31Andrew Lee final boolean primaryChanged = !Call.areSame(mPrimary, primary); 194fe4982c221c8ee734afedc4d005661d9c6c1ac31Andrew Lee final boolean secondaryChanged = !Call.areSame(mSecondary, secondary); 195fe4982c221c8ee734afedc4d005661d9c6c1ac31Andrew Lee 196625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon mSecondary = secondary; 197625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon mPrimary = primary; 198625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon 199625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon if (primaryChanged && mPrimary != null) { 200625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon // primary call has changed 201fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal mPrimaryContactInfo = ContactInfoCache.buildCacheEntryFromCall(mContext, mPrimary, 202fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal mPrimary.getState() == Call.State.INCOMING); 203625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon updatePrimaryDisplayInfo(mPrimaryContactInfo, isConference(mPrimary)); 204625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon maybeStartSearch(mPrimary, true); 205aed98fccfc2af12f8c24f93242fecdab23758c8dAndrew Lee mPrimary.setSessionModificationState(Call.SessionModificationState.NO_REQUEST); 2068b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng } 2078b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng 208625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon if (mSecondary == null) { 2098b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng // Secondary call may have ended. Update the ui. 2108b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng mSecondaryContactInfo = null; 2110f09a02be361d5bb36fac6981649204f5d6987faChristine Chen updateSecondaryDisplayInfo(false); 212625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon } else if (secondaryChanged) { 213625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon // secondary call has changed 214fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal mSecondaryContactInfo = ContactInfoCache.buildCacheEntryFromCall(mContext, mSecondary, 215fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal mSecondary.getState() == Call.State.INCOMING); 216625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon updateSecondaryDisplayInfo(mSecondary.isConferenceCall()); 217625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon maybeStartSearch(mSecondary, false); 218aed98fccfc2af12f8c24f93242fecdab23758c8dAndrew Lee mSecondary.setSessionModificationState(Call.SessionModificationState.NO_REQUEST); 2198b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng } 2208b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng 221aed98fccfc2af12f8c24f93242fecdab23758c8dAndrew Lee // Start/stop timers. 22288dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon if (mPrimary != null && mPrimary.getState() == Call.State.ACTIVE) { 2231a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng Log.d(this, "Starting the calltime timer"); 224aed98fccfc2af12f8c24f93242fecdab23758c8dAndrew Lee mCallTimer.start(CALL_TIME_UPDATE_INTERVAL_MS); 22588dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon } else { 2261a7f2bcab2d2023f2ee4cfb0bc57bc265b5aab87Chiao Cheng Log.d(this, "Canceling the calltime timer"); 22788dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon mCallTimer.cancel(); 22888dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon ui.setPrimaryCallElapsedTime(false, null); 22988dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon } 23088dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon 2314bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon // Set the call state 232776d937b539b9e9b3672a1d860adec309f65d0adEvan Charlton int callState = Call.State.IDLE; 2334bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon if (mPrimary != null) { 23429d9a2f4f60715267c73044e327f65f812dfc2cdYorke Lee callState = mPrimary.getState(); 23516cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal updatePrimaryCallState(); 236a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon } else { 237aed98fccfc2af12f8c24f93242fecdab23758c8dAndrew Lee getUi().setCallState( 238aed98fccfc2af12f8c24f93242fecdab23758c8dAndrew Lee callState, 23943f3e6e0760ea774e479935733d8a30b724457cdIhab Awad VideoProfile.VideoState.AUDIO_ONLY, 240aed98fccfc2af12f8c24f93242fecdab23758c8dAndrew Lee Call.SessionModificationState.NO_REQUEST, 241017f23c5f9ee2585454b43ae15c14c98e48e8f17Andrew Lee new DisconnectCause(DisconnectCause.UNKNOWN), 242aed98fccfc2af12f8c24f93242fecdab23758c8dAndrew Lee null, 243aed98fccfc2af12f8c24f93242fecdab23758c8dAndrew Lee null, 244aed98fccfc2af12f8c24f93242fecdab23758c8dAndrew Lee null); 245a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon } 2464c3e9e8e45ecafcb9aaf0da9901a5e9cebc59bc4Andrew Lee 24715a8e3cb2c01b59b5328a74e6c46144843103205Tyler Gunn // Hide/show the contact photo based on the video state. 24815a8e3cb2c01b59b5328a74e6c46144843103205Tyler Gunn // If the primary call is a video call on hold, still show the contact photo. 24915a8e3cb2c01b59b5328a74e6c46144843103205Tyler Gunn // If the primary call is an active video call, hide the contact photo. 250e59cd0f067d5630742ffe4724f18720c94053194Tyler Gunn if (mPrimary != null) { 25135224e8ff0e3707b92626767f048f1bf83352a2dTyler Gunn getUi().setPhotoVisible(!(mPrimary.isVideoCall(mContext) && 25235224e8ff0e3707b92626767f048f1bf83352a2dTyler Gunn callState != Call.State.ONHOLD)); 253e59cd0f067d5630742ffe4724f18720c94053194Tyler Gunn } 254e59cd0f067d5630742ffe4724f18720c94053194Tyler Gunn 255cb6f599ecb7c30e00ed8b07c5c10505322aae89cAndrew Lee maybeShowManageConferenceCallButton(); 256cb6f599ecb7c30e00ed8b07c5c10505322aae89cAndrew Lee 257f3d0654f2b6d77b7eef8bdcb4c39ee59e55017deNancy Chen final boolean enableEndCallButton = Call.State.isConnectingOrConnected(callState) && 258776d937b539b9e9b3672a1d860adec309f65d0adEvan Charlton callState != Call.State.INCOMING && mPrimary != null; 259b8249f3727e4d233215f4cfbecdd7ed175ce5231Andrew Lee // Hide the end call button instantly if we're receiving an incoming call. 260b8249f3727e4d233215f4cfbecdd7ed175ce5231Andrew Lee getUi().setEndCallButtonEnabled( 261b8249f3727e4d233215f4cfbecdd7ed175ce5231Andrew Lee enableEndCallButton, callState != Call.State.INCOMING /* animate */); 262b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon } 263b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon 264b70af18a174fa334d15b28a2cdaa617f9ba2a4b7Santos Cordon @Override 2656cddf46812634fadc194830774110780f14e9462Tyler Gunn public void onDetailsChanged(Call call, android.telecom.Call.Details details) { 26616cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal updatePrimaryCallState(); 2674940f9ff450d1054ed4ad0e61179196007ad5531Evan Charlton } 2684940f9ff450d1054ed4ad0e61179196007ad5531Evan Charlton 2694940f9ff450d1054ed4ad0e61179196007ad5531Evan Charlton private String getSubscriptionNumber() { 2704940f9ff450d1054ed4ad0e61179196007ad5531Evan Charlton // If it's an emergency call, and they're not populating the callback number, 2714940f9ff450d1054ed4ad0e61179196007ad5531Evan Charlton // then try to fall back to the phone sub info (to hopefully get the SIM's 2724940f9ff450d1054ed4ad0e61179196007ad5531Evan Charlton // number directly from the telephony layer). 2732b22a35ee4c94adae074b1dd720fa8734d8461b7Evan Charlton PhoneAccountHandle accountHandle = mPrimary.getAccountHandle(); 2742b22a35ee4c94adae074b1dd720fa8734d8461b7Evan Charlton if (accountHandle != null) { 2756cddf46812634fadc194830774110780f14e9462Tyler Gunn TelecomManager mgr = 2766cddf46812634fadc194830774110780f14e9462Tyler Gunn (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); 277bfb48c19b99fb1e2412f9c722f6f55a967c45233Evan Charlton PhoneAccount account = mgr.getPhoneAccount(accountHandle); 278bfb48c19b99fb1e2412f9c722f6f55a967c45233Evan Charlton if (account != null) { 2798612291d139f5afb35761bcbc729c096eda910bfAndrew Lee return getNumberFromHandle(account.getSubscriptionAddress()); 280856194f36d7e8048f7f83e5e6025ff45d89de980Ihab Awad } 2813f4f33bc27ee1c9a12c9e55856b29079301c8a08Evan Charlton } 2824940f9ff450d1054ed4ad0e61179196007ad5531Evan Charlton return null; 2833f4f33bc27ee1c9a12c9e55856b29079301c8a08Evan Charlton } 2843f4f33bc27ee1c9a12c9e55856b29079301c8a08Evan Charlton 28516cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal private void updatePrimaryCallState() { 28616cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal if (getUi() != null && mPrimary != null) { 28716cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal getUi().setCallState( 28816cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal mPrimary.getState(), 28916cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal mPrimary.getVideoState(), 29016cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal mPrimary.getSessionModificationState(), 29116cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal mPrimary.getDisconnectCause(), 29216cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal getConnectionLabel(), 29316cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal getConnectionIcon(), 29416cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal getGatewayNumber()); 29516cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal setCallbackNumber(); 29616cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal } 29716cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal } 2984940f9ff450d1054ed4ad0e61179196007ad5531Evan Charlton 299cb6f599ecb7c30e00ed8b07c5c10505322aae89cAndrew Lee /** 30052c30ebe11e132c5b00a15aabdf4a411355bf0f4Santos Cordon * Only show the conference call button if we can manage the conference. 301cb6f599ecb7c30e00ed8b07c5c10505322aae89cAndrew Lee */ 302cb6f599ecb7c30e00ed8b07c5c10505322aae89cAndrew Lee private void maybeShowManageConferenceCallButton() { 30383e061107b3f0b6f3b2f82151dd585234173ceb7Andrew Lee if (mPrimary == null) { 30483e061107b3f0b6f3b2f82151dd585234173ceb7Andrew Lee getUi().showManageConferenceCallButton(false); 30583e061107b3f0b6f3b2f82151dd585234173ceb7Andrew Lee return; 30683e061107b3f0b6f3b2f82151dd585234173ceb7Andrew Lee } 30783e061107b3f0b6f3b2f82151dd585234173ceb7Andrew Lee 30852c30ebe11e132c5b00a15aabdf4a411355bf0f4Santos Cordon final boolean canManageConference = mPrimary.can(PhoneCapabilities.MANAGE_CONFERENCE); 30952c30ebe11e132c5b00a15aabdf4a411355bf0f4Santos Cordon getUi().showManageConferenceCallButton(mPrimary.isConferenceCall() && canManageConference); 310cb6f599ecb7c30e00ed8b07c5c10505322aae89cAndrew Lee } 311cb6f599ecb7c30e00ed8b07c5c10505322aae89cAndrew Lee 31216cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal private void setCallbackNumber() { 31316cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal String callbackNumber = null; 3144940f9ff450d1054ed4ad0e61179196007ad5531Evan Charlton 31516cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal boolean isEmergencyCall = PhoneNumberUtils.isEmergencyNumber( 31616cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal getNumberFromHandle(mPrimary.getHandle())); 31716cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal if (isEmergencyCall) { 31816cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal callbackNumber = getSubscriptionNumber(); 31916cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal } else { 32016cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal StatusHints statusHints = mPrimary.getTelecommCall().getDetails().getStatusHints(); 32116cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal if (statusHints != null) { 32216cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal Bundle extras = statusHints.getExtras(); 32316cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal if (extras != null) { 3246cddf46812634fadc194830774110780f14e9462Tyler Gunn callbackNumber = extras.getString(TelecomManager.EXTRA_CALL_BACK_NUMBER); 3254940f9ff450d1054ed4ad0e61179196007ad5531Evan Charlton } 3263f4f33bc27ee1c9a12c9e55856b29079301c8a08Evan Charlton } 3274940f9ff450d1054ed4ad0e61179196007ad5531Evan Charlton } 3284940f9ff450d1054ed4ad0e61179196007ad5531Evan Charlton 32916cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal TelephonyManager telephonyManager = 3308e98c93f1806e1a23da1b1b3e67b996b233b0ed3Yorke Lee (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); 3318e98c93f1806e1a23da1b1b3e67b996b233b0ed3Yorke Lee String simNumber = telephonyManager.getLine1Number(); 33216cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal if (PhoneNumberUtils.compare(callbackNumber, simNumber)) { 3334940f9ff450d1054ed4ad0e61179196007ad5531Evan Charlton Log.d(this, "Numbers are the same; not showing the callback number"); 33416cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal callbackNumber = null; 3354940f9ff450d1054ed4ad0e61179196007ad5531Evan Charlton } 33616cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal 3374940f9ff450d1054ed4ad0e61179196007ad5531Evan Charlton getUi().setCallbackNumber(callbackNumber, isEmergencyCall); 3383f4f33bc27ee1c9a12c9e55856b29079301c8a08Evan Charlton } 3393f4f33bc27ee1c9a12c9e55856b29079301c8a08Evan Charlton 34088dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon public void updateCallTime() { 34188dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon final CallCardUi ui = getUi(); 34288dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon 34388dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon if (ui == null || mPrimary == null || mPrimary.getState() != Call.State.ACTIVE) { 3440b77eb307c0a99bfb6aca0e38990c2d03a879bfcSantos Cordon if (ui != null) { 3450b77eb307c0a99bfb6aca0e38990c2d03a879bfcSantos Cordon ui.setPrimaryCallElapsedTime(false, null); 3460b77eb307c0a99bfb6aca0e38990c2d03a879bfcSantos Cordon } 34788dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon mCallTimer.cancel(); 3480b77eb307c0a99bfb6aca0e38990c2d03a879bfcSantos Cordon } else { 349a481914300fbe10a76635242eb778e1976947065Sailesh Nepal final long callStart = mPrimary.getConnectTimeMillis(); 3500b77eb307c0a99bfb6aca0e38990c2d03a879bfcSantos Cordon final long duration = System.currentTimeMillis() - callStart; 3510b77eb307c0a99bfb6aca0e38990c2d03a879bfcSantos Cordon ui.setPrimaryCallElapsedTime(true, DateUtils.formatElapsedTime(duration / 1000)); 35288dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon } 35388dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon } 35488dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon 355f2b1401b9680fa4344cec18a01b11fc9e100ae17Evan Charlton public void onCallStateButtonTouched() { 3566bfbae405c734c3000320d5b2d65654b2caa8d4eEvan Charlton Intent broadcastIntent = ObjectFactory.getCallStateButtonBroadcastIntent(mContext); 357f2b1401b9680fa4344cec18a01b11fc9e100ae17Evan Charlton if (broadcastIntent != null) { 358f2b1401b9680fa4344cec18a01b11fc9e100ae17Evan Charlton Log.d(this, "Sending call state button broadcast: ", broadcastIntent); 359f2b1401b9680fa4344cec18a01b11fc9e100ae17Evan Charlton mContext.sendBroadcast(broadcastIntent, Manifest.permission.READ_PHONE_STATE); 360f2b1401b9680fa4344cec18a01b11fc9e100ae17Evan Charlton } 361f2b1401b9680fa4344cec18a01b11fc9e100ae17Evan Charlton } 362f2b1401b9680fa4344cec18a01b11fc9e100ae17Evan Charlton 363625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon private void maybeStartSearch(Call call, boolean isPrimary) { 364625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon // no need to start search for conference calls which show generic info. 365625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon if (call != null && !call.isConferenceCall()) { 366fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal startContactInfoSearch(call, isPrimary, call.getState() == Call.State.INCOMING); 367625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon } 368625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon } 369625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon 370a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon /** 3714bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon * Starts a query for more contact data for the save primary and secondary calls. 3724bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon */ 373fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal private void startContactInfoSearch(final Call call, final boolean isPrimary, 374fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal boolean isIncoming) { 3758b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng final ContactInfoCache cache = ContactInfoCache.getInstance(mContext); 3768b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng 377e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee cache.findInfo(call, isIncoming, new ContactLookupCallback(this, isPrimary)); 378e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee } 379af2589a6aa68d9906fe46b31ffaf214010632c02Chiao Cheng 380e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee private void onContactInfoComplete(String callId, ContactCacheEntry entry, boolean isPrimary) { 381e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee updateContactEntry(entry, isPrimary, false); 382e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee if (entry.name != null) { 383e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee Log.d(TAG, "Contact found: " + entry); 384e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee } 385e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee if (entry.contactUri != null) { 386e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee CallerInfoUtils.sendViewNotification(mContext, entry.contactUri); 387e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee } 388e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee } 389e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee 390e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee private void onImageLoadComplete(String callId, ContactCacheEntry entry) { 391e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee if (getUi() == null) { 392e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee return; 393e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee } 394f3d0654f2b6d77b7eef8bdcb4c39ee59e55017deNancy Chen 395e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee if (entry.photo != null) { 396e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee if (mPrimary != null && callId.equals(mPrimary.getId())) { 397e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee getUi().setPrimaryImage(entry.photo); 398e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee } 399e89ee6f3c48374bfdea5450d6311763bc061885fYorke Lee } 4008b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng } 4018b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng 402625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon private static boolean isConference(Call call) { 403625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon return call != null && call.isConferenceCall(); 404625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon } 405625ac576cb403744ef0baeba8e8993da963461eeSantos Cordon 40652c30ebe11e132c5b00a15aabdf4a411355bf0f4Santos Cordon private static boolean canManageConference(Call call) { 40752c30ebe11e132c5b00a15aabdf4a411355bf0f4Santos Cordon return call != null && call.can(PhoneCapabilities.MANAGE_CONFERENCE); 4088b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng } 4094bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon 4108b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng private void updateContactEntry(ContactCacheEntry entry, boolean isPrimary, 4118b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng boolean isConference) { 4128b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng if (isPrimary) { 4138b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng mPrimaryContactInfo = entry; 4148b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng updatePrimaryDisplayInfo(entry, isConference); 4154bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon } else { 4168b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng mSecondaryContactInfo = entry; 4170f09a02be361d5bb36fac6981649204f5d6987faChristine Chen updateSecondaryDisplayInfo(isConference); 4184bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon } 4194bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon } 4204bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon 4214bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon /** 422a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon * Get the highest priority call to display. 423a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon * Goes through the calls and chooses which to return based on priority of which type of call 424a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon * to display to the user. Callers can use the "ignore" feature to get the second best call 425a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon * by passing a previously found primary call as ignore. 426a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon * 427a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon * @param ignore A call to ignore if found. 428a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon */ 4291df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon private Call getCallToDisplay(CallList callList, Call ignore, boolean skipDisconnected) { 430a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon 4311df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon // Active calls come second. An active call always gets precedent. 4321df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon Call retval = callList.getActiveCall(); 433a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon if (retval != null && retval != ignore) { 434a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon return retval; 435a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon } 436a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon 4371df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon // Disconnected calls get primary position if there are no active calls 4381df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon // to let user know quickly what call has disconnected. Disconnected 4391df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon // calls are very short lived. 4401df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon if (!skipDisconnected) { 441ecabb6923e6587e0f0ca98cc895be7d99e694015Christine Chen retval = callList.getDisconnectingCall(); 442ecabb6923e6587e0f0ca98cc895be7d99e694015Christine Chen if (retval != null && retval != ignore) { 443ecabb6923e6587e0f0ca98cc895be7d99e694015Christine Chen return retval; 444ecabb6923e6587e0f0ca98cc895be7d99e694015Christine Chen } 4451df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon retval = callList.getDisconnectedCall(); 4461df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon if (retval != null && retval != ignore) { 4471df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon return retval; 4481df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon } 449a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon } 450a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon 451a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon // Then we go to background call (calls on hold) 452a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon retval = callList.getBackgroundCall(); 453a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon if (retval != null && retval != ignore) { 454a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon return retval; 455a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon } 456a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon 457a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon // Lastly, we go to a second background call. 458a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon retval = callList.getSecondBackgroundCall(); 459a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon 460a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon return retval; 461a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon } 462a12f2589f424e26c63c8ee5b6fad89e30b69d7fbSantos Cordon 4638b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng private void updatePrimaryDisplayInfo(ContactCacheEntry entry, boolean isConference) { 4648b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng Log.d(TAG, "Update primary display " + entry); 465988d06b64b99a13f4f060dc82594edcb738d9113Yorke Lee final CallCardUi ui = getUi(); 4664bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon if (ui == null) { 4678b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng // TODO: May also occur if search result comes back after ui is destroyed. Look into 4688b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng // removing that case completely. 4698b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng Log.d(TAG, "updatePrimaryDisplayInfo called but ui is null!"); 4704bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon return; 471988d06b64b99a13f4f060dc82594edcb738d9113Yorke Lee } 4727ef707319c0e3563ff92a772ba53cb5dca0e3ae1Yorke Lee 47352c30ebe11e132c5b00a15aabdf4a411355bf0f4Santos Cordon final boolean canManageConference = canManageConference(mPrimary); 474b6b3df38e14990595bce4bcaec548ee371d21151Yorke Lee if (entry != null && mPrimary != null) { 4758b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng final String name = getNameForCall(entry); 4768b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng final String number = getNumberForCall(entry); 4778b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng final boolean nameIsNumber = name != null && name.equals(entry.number); 4788b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng ui.setPrimary(number, name, nameIsNumber, entry.label, 47952c30ebe11e132c5b00a15aabdf4a411355bf0f4Santos Cordon entry.photo, isConference, canManageConference, entry.isSipCall); 480988d06b64b99a13f4f060dc82594edcb738d9113Yorke Lee } else { 48152c30ebe11e132c5b00a15aabdf4a411355bf0f4Santos Cordon ui.setPrimary(null, null, false, null, null, isConference, canManageConference, false); 4821df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon } 4831df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon 4841df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon } 4851df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon 4860f09a02be361d5bb36fac6981649204f5d6987faChristine Chen private void updateSecondaryDisplayInfo(boolean isConference) { 4878b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng final CallCardUi ui = getUi(); 4888b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng if (ui == null) { 4898b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng return; 4908b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng } 4918b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng 49252c30ebe11e132c5b00a15aabdf4a411355bf0f4Santos Cordon final boolean canManageConference = canManageConference(mSecondary); 493b6b3df38e14990595bce4bcaec548ee371d21151Yorke Lee if (mSecondaryContactInfo != null && mSecondary != null) { 4948b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng Log.d(TAG, "updateSecondaryDisplayInfo() " + mSecondaryContactInfo); 4954be1bdd9ee8e9d3afa1aaa765e86b963fb6c7b3dYorke Lee final String nameForCall = getNameForCall(mSecondaryContactInfo); 4964be1bdd9ee8e9d3afa1aaa765e86b963fb6c7b3dYorke Lee 4974be1bdd9ee8e9d3afa1aaa765e86b963fb6c7b3dYorke Lee final boolean nameIsNumber = nameForCall != null && nameForCall.equals( 4984be1bdd9ee8e9d3afa1aaa765e86b963fb6c7b3dYorke Lee mSecondaryContactInfo.number); 4998e303d6ad3f2a0e99b1d0674b9cf91565511f066Andrew Lee ui.setSecondary(true /* show */, nameForCall, nameIsNumber, mSecondaryContactInfo.label, 500a05e4e2595f4d41eab092f13cdf068b8709ab323Nancy Chen getCallProviderLabel(mSecondary), getCallProviderIcon(mSecondary), 50152c30ebe11e132c5b00a15aabdf4a411355bf0f4Santos Cordon isConference, canManageConference); 5028b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng } else { 5038b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng // reset to nothing so that it starts off blank next time we use it. 50452c30ebe11e132c5b00a15aabdf4a411355bf0f4Santos Cordon ui.setSecondary(false, null, false, null, null, null, isConference, canManageConference); 5058b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng } 5068b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng } 5078b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng 508a05e4e2595f4d41eab092f13cdf068b8709ab323Nancy Chen 509a05e4e2595f4d41eab092f13cdf068b8709ab323Nancy Chen /** 510a05e4e2595f4d41eab092f13cdf068b8709ab323Nancy Chen * Gets the phone account to display for a call. 511a05e4e2595f4d41eab092f13cdf068b8709ab323Nancy Chen */ 512a05e4e2595f4d41eab092f13cdf068b8709ab323Nancy Chen private PhoneAccount getAccountForCall(Call call) { 513a05e4e2595f4d41eab092f13cdf068b8709ab323Nancy Chen PhoneAccountHandle accountHandle = call.getAccountHandle(); 514a05e4e2595f4d41eab092f13cdf068b8709ab323Nancy Chen if (accountHandle == null) { 515a05e4e2595f4d41eab092f13cdf068b8709ab323Nancy Chen return null; 516a05e4e2595f4d41eab092f13cdf068b8709ab323Nancy Chen } 5176cddf46812634fadc194830774110780f14e9462Tyler Gunn return getTelecomManager().getPhoneAccount(accountHandle); 518a05e4e2595f4d41eab092f13cdf068b8709ab323Nancy Chen } 519a05e4e2595f4d41eab092f13cdf068b8709ab323Nancy Chen 5203d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon /** 5213d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon * Returns the gateway number for any existing outgoing call. 5223d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon */ 5233d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon private String getGatewayNumber() { 5243d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon if (hasOutgoingGatewayCall()) { 525e2814d578ed59624f3720302e8a99773d7c6a9c5Nancy Chen return getNumberFromHandle(mPrimary.getGatewayInfo().getGatewayAddress()); 5263d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon } 5273d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon return null; 5283d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon } 5293d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon 5303d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon /** 5316d0ace011dfb4ccfbf87f5e48361767fa6825b75Nancy Chen * Return the Drawable object of the icon to display to the left of the connection label. 5326d0ace011dfb4ccfbf87f5e48361767fa6825b75Nancy Chen */ 533a05e4e2595f4d41eab092f13cdf068b8709ab323Nancy Chen private Drawable getCallProviderIcon(Call call) { 534a05e4e2595f4d41eab092f13cdf068b8709ab323Nancy Chen PhoneAccount account = getAccountForCall(call); 535a3584bc7adc64bc271e82bb2533d30b75db27d2fNancy Chen if (account != null && getTelecomManager().hasMultipleCallCapableAccounts()) { 536a05e4e2595f4d41eab092f13cdf068b8709ab323Nancy Chen return account.getIcon(mContext); 537a05e4e2595f4d41eab092f13cdf068b8709ab323Nancy Chen } 538a05e4e2595f4d41eab092f13cdf068b8709ab323Nancy Chen return null; 539a05e4e2595f4d41eab092f13cdf068b8709ab323Nancy Chen } 540a05e4e2595f4d41eab092f13cdf068b8709ab323Nancy Chen 541a05e4e2595f4d41eab092f13cdf068b8709ab323Nancy Chen /** 542a05e4e2595f4d41eab092f13cdf068b8709ab323Nancy Chen * Return the string label to represent the call provider 543a05e4e2595f4d41eab092f13cdf068b8709ab323Nancy Chen */ 544a05e4e2595f4d41eab092f13cdf068b8709ab323Nancy Chen private String getCallProviderLabel(Call call) { 545a05e4e2595f4d41eab092f13cdf068b8709ab323Nancy Chen PhoneAccount account = getAccountForCall(call); 546a3584bc7adc64bc271e82bb2533d30b75db27d2fNancy Chen if (account != null && getTelecomManager().hasMultipleCallCapableAccounts()) { 547a05e4e2595f4d41eab092f13cdf068b8709ab323Nancy Chen return account.getLabel().toString(); 5486d0ace011dfb4ccfbf87f5e48361767fa6825b75Nancy Chen } 5496d0ace011dfb4ccfbf87f5e48361767fa6825b75Nancy Chen return null; 5506d0ace011dfb4ccfbf87f5e48361767fa6825b75Nancy Chen } 5516d0ace011dfb4ccfbf87f5e48361767fa6825b75Nancy Chen 5526d0ace011dfb4ccfbf87f5e48361767fa6825b75Nancy Chen /** 5536d0ace011dfb4ccfbf87f5e48361767fa6825b75Nancy Chen * Returns the label (line of text above the number/name) for any given call. 5546d0f6679a1afb1afa3053bd9511aea8f5945a5d7Sailesh Nepal * For example, "calling via [Account/Google Voice]" for outgoing calls. 5553d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon */ 5566d0ace011dfb4ccfbf87f5e48361767fa6825b75Nancy Chen private String getConnectionLabel() { 55716cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal StatusHints statusHints = mPrimary.getTelecommCall().getDetails().getStatusHints(); 55816cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal if (statusHints != null && !TextUtils.isEmpty(statusHints.getLabel())) { 55916cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal return statusHints.getLabel().toString(); 56016cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal } 56116cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal 5623d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon if (hasOutgoingGatewayCall() && getUi() != null) { 5636d0ace011dfb4ccfbf87f5e48361767fa6825b75Nancy Chen // Return the label for the gateway app on outgoing calls. 5643d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon final PackageManager pm = mContext.getPackageManager(); 5653d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon try { 56607a822b2ea92dc5b68cd43139be7efe4c6640cd4Sailesh Nepal ApplicationInfo info = pm.getApplicationInfo( 56707a822b2ea92dc5b68cd43139be7efe4c6640cd4Sailesh Nepal mPrimary.getGatewayInfo().getGatewayProviderPackageName(), 0); 5686d0ace011dfb4ccfbf87f5e48361767fa6825b75Nancy Chen return pm.getApplicationLabel(info).toString(); 5693d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon } catch (PackageManager.NameNotFoundException e) { 5706d0ace011dfb4ccfbf87f5e48361767fa6825b75Nancy Chen Log.e(this, "Gateway Application Not Found.", e); 5716d0ace011dfb4ccfbf87f5e48361767fa6825b75Nancy Chen return null; 5723d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon } 5733d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon } 574a05e4e2595f4d41eab092f13cdf068b8709ab323Nancy Chen return getCallProviderLabel(mPrimary); 5753d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon } 5763d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon 57716cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal private Drawable getConnectionIcon() { 57816cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal StatusHints statusHints = mPrimary.getTelecommCall().getDetails().getStatusHints(); 57943f3e6e0760ea774e479935733d8a30b724457cdIhab Awad if (statusHints != null && statusHints.getIconResId() != 0) { 58016cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal Drawable icon = statusHints.getIcon(mContext); 58116cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal if (icon != null) { 58216cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal return icon; 58316cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal } 58416cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal } 58516cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal return getCallProviderIcon(mPrimary); 58616cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal } 58716cadfad5458d6a1095fd23bcd6bf5120de43c98Sailesh Nepal 5883d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon private boolean hasOutgoingGatewayCall() { 58943f3e6e0760ea774e479935733d8a30b724457cdIhab Awad // We only display the gateway information while STATE_DIALING so return false for any othe 5903d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon // call state. 5918b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng // TODO: mPrimary can be null because this is called from updatePrimaryDisplayInfo which 5928b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng // is also called after a contact search completes (call is not present yet). Split the 5938b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng // UI update so it can receive independent updates. 5948b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng if (mPrimary == null) { 5958b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng return false; 5968b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng } 59707a822b2ea92dc5b68cd43139be7efe4c6640cd4Sailesh Nepal return Call.State.isDialing(mPrimary.getState()) && mPrimary.getGatewayInfo() != null && 59807a822b2ea92dc5b68cd43139be7efe4c6640cd4Sailesh Nepal !mPrimary.getGatewayInfo().isEmpty(); 5993d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon } 6003d9e39bef65a67b9b04a2584b12f8b655fcc2e7cSantos Cordon 6011df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon /** 6021df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon * Gets the name to display for the call. 6031df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon */ 6041df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon private static String getNameForCall(ContactCacheEntry contactInfo) { 6051df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon if (TextUtils.isEmpty(contactInfo.name)) { 6061df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon return contactInfo.number; 607988d06b64b99a13f4f060dc82594edcb738d9113Yorke Lee } 6081df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon return contactInfo.name; 6091df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon } 610988d06b64b99a13f4f060dc82594edcb738d9113Yorke Lee 6111df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon /** 6121df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon * Gets the number to display for a call. 6131df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon */ 6141df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon private static String getNumberForCall(ContactCacheEntry contactInfo) { 6151df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon // If the name is empty, we use the number for the name...so dont show a second 6161df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon // number in the number field 6171df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon if (TextUtils.isEmpty(contactInfo.name)) { 618101bed44998ff35c3a56f431345fac5c8229ec0eJay Shrauner return contactInfo.location; 6191df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon } 6201df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon return contactInfo.number; 6214bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon } 622988d06b64b99a13f4f060dc82594edcb738d9113Yorke Lee 6238e303d6ad3f2a0e99b1d0674b9cf91565511f066Andrew Lee public void secondaryInfoClicked() { 6246f767fb5d92b7e07315b86ddf1de1f25e7354bc0Yorke Lee if (mSecondary == null) { 6258e303d6ad3f2a0e99b1d0674b9cf91565511f066Andrew Lee Log.wtf(this, "Secondary info clicked but no secondary call."); 6266f767fb5d92b7e07315b86ddf1de1f25e7354bc0Yorke Lee return; 6276f767fb5d92b7e07315b86ddf1de1f25e7354bc0Yorke Lee } 6286f767fb5d92b7e07315b86ddf1de1f25e7354bc0Yorke Lee 629fc22ba88566ef70e202128335231c367de6c52afSailesh Nepal Log.i(this, "Swapping call to foreground: " + mSecondary); 6306cddf46812634fadc194830774110780f14e9462Tyler Gunn TelecomAdapter.getInstance().unholdCall(mSecondary.getId()); 6319240895e9df2fcae8f0baea707eb4d24c6e50997Yorke Lee } 6329240895e9df2fcae8f0baea707eb4d24c6e50997Yorke Lee 6337b4cfe59218ff0876587933f5f22845881fdbe40Andrew Lee public void endCallClicked() { 6347b4cfe59218ff0876587933f5f22845881fdbe40Andrew Lee if (mPrimary == null) { 6357b4cfe59218ff0876587933f5f22845881fdbe40Andrew Lee return; 6367b4cfe59218ff0876587933f5f22845881fdbe40Andrew Lee } 6377b4cfe59218ff0876587933f5f22845881fdbe40Andrew Lee 6388a81f277540cd6e7c8da5efd7ecbd342912ae29bEvan Charlton Log.i(this, "Disconnecting call: " + mPrimary); 639766c1e05845fa4d22b22acb32ad76d4b9e0eecabIhab Awad mPrimary.setState(Call.State.DISCONNECTING); 640766c1e05845fa4d22b22acb32ad76d4b9e0eecabIhab Awad CallList.getInstance().onUpdate(mPrimary); 6416cddf46812634fadc194830774110780f14e9462Tyler Gunn TelecomAdapter.getInstance().disconnectCall(mPrimary.getId()); 6427b4cfe59218ff0876587933f5f22845881fdbe40Andrew Lee } 6437b4cfe59218ff0876587933f5f22845881fdbe40Andrew Lee 644e038ead8b0e520787b41e5dbd6f4c534881e10d5Santos Cordon private String getNumberFromHandle(Uri handle) { 645e038ead8b0e520787b41e5dbd6f4c534881e10d5Santos Cordon return handle == null ? "" : handle.getSchemeSpecificPart(); 646e038ead8b0e520787b41e5dbd6f4c534881e10d5Santos Cordon } 647e038ead8b0e520787b41e5dbd6f4c534881e10d5Santos Cordon 64815a8e3cb2c01b59b5328a74e6c46144843103205Tyler Gunn /** 64915a8e3cb2c01b59b5328a74e6c46144843103205Tyler Gunn * Handles a change to the full screen video state. 65015a8e3cb2c01b59b5328a74e6c46144843103205Tyler Gunn * 65115a8e3cb2c01b59b5328a74e6c46144843103205Tyler Gunn * @param isFullScreenVideo {@code True} if the application is entering full screen video mode. 65215a8e3cb2c01b59b5328a74e6c46144843103205Tyler Gunn */ 65315a8e3cb2c01b59b5328a74e6c46144843103205Tyler Gunn @Override 65415a8e3cb2c01b59b5328a74e6c46144843103205Tyler Gunn public void onFullScreenVideoStateChanged(boolean isFullScreenVideo) { 65515a8e3cb2c01b59b5328a74e6c46144843103205Tyler Gunn final CallCardUi ui = getUi(); 65615a8e3cb2c01b59b5328a74e6c46144843103205Tyler Gunn if (ui == null) { 65715a8e3cb2c01b59b5328a74e6c46144843103205Tyler Gunn return; 65815a8e3cb2c01b59b5328a74e6c46144843103205Tyler Gunn } 65915a8e3cb2c01b59b5328a74e6c46144843103205Tyler Gunn ui.setCallCardVisible(!isFullScreenVideo); 66015a8e3cb2c01b59b5328a74e6c46144843103205Tyler Gunn } 66115a8e3cb2c01b59b5328a74e6c46144843103205Tyler Gunn 6624bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon public interface CallCardUi extends Ui { 6634bbe4c6900dfe3584f674161dbe15e248d5adbe7Santos Cordon void setVisible(boolean on); 66415a8e3cb2c01b59b5328a74e6c46144843103205Tyler Gunn void setCallCardVisible(boolean visible); 6651df52df7a0248814fbd4575103059a8b427f5d9aSantos Cordon void setPrimary(String number, String name, boolean nameIsNumber, String label, 66652c30ebe11e132c5b00a15aabdf4a411355bf0f4Santos Cordon Drawable photo, boolean isConference, boolean canManageConference, 66752c30ebe11e132c5b00a15aabdf4a411355bf0f4Santos Cordon boolean isSipCall); 6684be1bdd9ee8e9d3afa1aaa765e86b963fb6c7b3dYorke Lee void setSecondary(boolean show, String name, boolean nameIsNumber, String label, 6696d0ace011dfb4ccfbf87f5e48361767fa6825b75Nancy Chen String providerLabel, Drawable providerIcon, boolean isConference, 67052c30ebe11e132c5b00a15aabdf4a411355bf0f4Santos Cordon boolean canManageConference); 671017f23c5f9ee2585454b43ae15c14c98e48e8f17Andrew Lee void setCallState(int state, int videoState, int sessionModificationState, 672017f23c5f9ee2585454b43ae15c14c98e48e8f17Andrew Lee DisconnectCause disconnectCause, String connectionLabel, 673017f23c5f9ee2585454b43ae15c14c98e48e8f17Andrew Lee Drawable connectionIcon, String gatewayNumber); 67488dbc6b3dbf35b322fe09c1a289c7e884e8fba22Santos Cordon void setPrimaryCallElapsedTime(boolean show, String duration); 6758b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng void setPrimaryName(String name, boolean nameIsNumber); 67614dbc3f0ca3a7998c9c5d28aba637487724f529fSantos Cordon void setPrimaryImage(Drawable image); 6778b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng void setPrimaryPhoneNumber(String phoneNumber); 6788b6c8d0dbfba6eabe3d835f8cdcec8a13e253d0cChiao Cheng void setPrimaryLabel(String label); 679b8249f3727e4d233215f4cfbecdd7ed175ce5231Andrew Lee void setEndCallButtonEnabled(boolean enabled, boolean animate); 6804940f9ff450d1054ed4ad0e61179196007ad5531Evan Charlton void setCallbackNumber(String number, boolean isEmergencyCalls); 681e59cd0f067d5630742ffe4724f18720c94053194Tyler Gunn void setPhotoVisible(boolean isVisible); 68215a8e3cb2c01b59b5328a74e6c46144843103205Tyler Gunn void setProgressSpinnerVisible(boolean visible); 683cb6f599ecb7c30e00ed8b07c5c10505322aae89cAndrew Lee void showManageConferenceCallButton(boolean visible); 6847ef707319c0e3563ff92a772ba53cb5dca0e3ae1Yorke Lee } 68527003ad538e84cc3a5bd6f04d9c679afffc455e2Ihab Awad 6866cddf46812634fadc194830774110780f14e9462Tyler Gunn private TelecomManager getTelecomManager() { 6876cddf46812634fadc194830774110780f14e9462Tyler Gunn if (mTelecomManager == null) { 6886cddf46812634fadc194830774110780f14e9462Tyler Gunn mTelecomManager = 6896cddf46812634fadc194830774110780f14e9462Tyler Gunn (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); 69027003ad538e84cc3a5bd6f04d9c679afffc455e2Ihab Awad } 6916cddf46812634fadc194830774110780f14e9462Tyler Gunn return mTelecomManager; 69227003ad538e84cc3a5bd6f04d9c679afffc455e2Ihab Awad } 693a012c22dfbfedffe2e751f9b1ab776baa325a26fSantos Cordon} 694