1b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project/* 2b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 3b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 4b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * you may not use this file except in compliance with the License. 6b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * You may obtain a copy of the License at 7b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 8b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 10b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * See the License for the specific language governing permissions and 14b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * limitations under the License. 15b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 16b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 17b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectpackage com.android.phone; 18b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 195cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brownimport android.animation.Animator; 205cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brownimport android.animation.AnimatorListenerAdapter; 21b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.content.ContentUris; 22b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.content.Context; 23b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.graphics.drawable.Drawable; 24b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.net.Uri; 25b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.pim.ContactsAsyncHelper; 263d6d70562622660e581b53308e675386d299dd19Dmitri Plotnikovimport android.provider.ContactsContract.Contacts; 27f3602b0659d01fef19159e7111be76102549f7a1David Brownimport android.telephony.PhoneNumberUtils; 28b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.text.TextUtils; 29b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.text.format.DateUtils; 30b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.util.AttributeSet; 31b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.util.Log; 32b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.view.LayoutInflater; 33b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.view.View; 34b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.view.ViewGroup; 35dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brownimport android.view.accessibility.AccessibilityEvent; 366d5544932495d81ff7ce53f4678c4beb25acc1b0David Brownimport android.widget.Button; 37b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.widget.FrameLayout; 38b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.widget.ImageView; 39d5f6f5f0c3dd6f4c939c1e432bc75fd4da0d4b74David Brownimport android.widget.RelativeLayout; 40b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.widget.TextView; 41b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 426b7d0da33af02960736da204eb7a25ccf91d5396David Brownimport com.android.internal.telephony.Call; 436b7d0da33af02960736da204eb7a25ccf91d5396David Brownimport com.android.internal.telephony.CallerInfo; 446b7d0da33af02960736da204eb7a25ccf91d5396David Brownimport com.android.internal.telephony.CallerInfoAsyncQuery; 456b7d0da33af02960736da204eb7a25ccf91d5396David Brownimport com.android.internal.telephony.Connection; 466b7d0da33af02960736da204eb7a25ccf91d5396David Brownimport com.android.internal.telephony.Phone; 478343169cc89621d46dce86449f5ee1ff5d3a4919John Wangimport com.android.internal.telephony.CallManager; 486b7d0da33af02960736da204eb7a25ccf91d5396David Brown 490fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Savilleimport java.util.List; 500fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 516b7d0da33af02960736da204eb7a25ccf91d5396David Brown 52b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project/** 53b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * "Call card" UI element: the in-call screen contains a tiled layout of call 54b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * cards, each representing the state of a current "call" (ie. an active call, 55b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * a call on hold, or an incoming call.) 56b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 57b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectpublic class CallCard extends FrameLayout 58b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project implements CallTime.OnTickListener, CallerInfoAsyncQuery.OnQueryCompleteListener, 59507ee75639e41c17edd410ef787e0617778071aaDavid Brown ContactsAsyncHelper.OnImageLoadCompleteListener { 60796c70c99bc39295bf685061056f06ab8949c742David Brown private static final String LOG_TAG = "CallCard"; 61796c70c99bc39295bf685061056f06ab8949c742David Brown private static final boolean DBG = (PhoneApp.DBG_LEVEL >= 2); 62b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 638bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project /** 648bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project * Reference to the InCallScreen activity that owns us. This may be 658bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project * null if we haven't been initialized yet *or* after the InCallScreen 668bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project * activity has been destroyed. 678bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project */ 688bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project private InCallScreen mInCallScreen; 698bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project 700fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // Phone app instance 710fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville private PhoneApp mApplication; 720fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 73b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Top-level subviews of the CallCard 74d5f6f5f0c3dd6f4c939c1e432bc75fd4da0d4b74David Brown private ViewGroup mCallInfoContainer; // Container for info about the current call(s) 75d5f6f5f0c3dd6f4c939c1e432bc75fd4da0d4b74David Brown private ViewGroup mPrimaryCallInfo; // "Call info" block #1 (the foreground or ringing call) 76d5f6f5f0c3dd6f4c939c1e432bc75fd4da0d4b74David Brown private ViewGroup mPrimaryCallBanner; // "Call banner" for the primary call 77d5f6f5f0c3dd6f4c939c1e432bc75fd4da0d4b74David Brown private ViewGroup mSecondaryCallInfo; // "Call info" block #2 (the background "on hold" call) 78b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 7930c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown // "Call state" widgets 8030c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown private TextView mCallStateLabel; 81b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private TextView mElapsedTime; 82b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 8334a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // Text colors, used for various labels / titles 849d14e16e8214b4a396dad293b6f0941608ee4798David Brown private int mTextColorCallTypeSip; 85b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 860d315275d08cd33f801ae3a74e8fc265520f6246David Brown // The main block of info about the "primary" or "active" call, 870d315275d08cd33f801ae3a74e8fc265520f6246David Brown // including photo / name / phone number / etc. 88b424ca2073702aff4ac1d9297d8bbe73ee4cd8b9David Brown private InCallContactPhoto mPhoto; 89b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private TextView mName; 90b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private TextView mPhoneNumber; 91b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private TextView mLabel; 929d14e16e8214b4a396dad293b6f0941608ee4798David Brown private TextView mCallTypeLabel; 9329d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown private TextView mSocialStatus; 94b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 950d315275d08cd33f801ae3a74e8fc265520f6246David Brown // Info about the "secondary" call, which is the "call on hold" when 960d315275d08cd33f801ae3a74e8fc265520f6246David Brown // two lines are in use. 970d315275d08cd33f801ae3a74e8fc265520f6246David Brown private TextView mSecondaryCallName; 980d315275d08cd33f801ae3a74e8fc265520f6246David Brown private TextView mSecondaryCallStatus; 99b424ca2073702aff4ac1d9297d8bbe73ee4cd8b9David Brown private InCallContactPhoto mSecondaryCallPhoto; 100b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1019688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown // Onscreen hint for the incoming call RotarySelector widget. 102ea505da2d0ebae37b07fece15297b5432fe96c5dJim Miller private int mIncomingCallWidgetHintTextResId; 103ea505da2d0ebae37b07fece15297b5432fe96c5dJim Miller private int mIncomingCallWidgetHintColorResId; 1049688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown 105b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private CallTime mCallTime; 106b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 107b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Track the state for the photo. 108b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private ContactsAsyncHelper.ImageTracker mPhotoTracker; 109b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 11029d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown // Cached DisplayMetrics density. 11129d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown private float mDensity; 11229d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown 113b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public CallCard(Context context, AttributeSet attrs) { 114b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project super(context, attrs); 115b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 116b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("CallCard constructor..."); 117b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("- this = " + this); 118b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("- context " + context + ", attrs " + attrs); 119b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 120b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Inflate the contents of this CallCard, and add it (to ourself) as a child. 121b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project LayoutInflater inflater = LayoutInflater.from(context); 122b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project inflater.inflate( 123b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project R.layout.call_card, // resource 124b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project this, // root 125b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project true); 126b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1270fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville mApplication = PhoneApp.getInstance(); 1280fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 129b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mCallTime = new CallTime(this); 130b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 131b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // create a new object to track the state for the photo. 132b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhotoTracker = new ContactsAsyncHelper.ImageTracker(); 13329d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown 13429d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown mDensity = getResources().getDisplayMetrics().density; 13529d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown if (DBG) log("- Density: " + mDensity); 136b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 137b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1388bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project void setInCallScreenInstance(InCallScreen inCallScreen) { 1398bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project mInCallScreen = inCallScreen; 1408bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project } 1418bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project 142b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public void onTickForCallTimeElapsed(long timeElapsed) { 143b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // While a call is in progress, update the elapsed time shown 144b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // onscreen. 145b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project updateElapsedTimeWidget(timeElapsed); 146b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 147b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 148b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /* package */ 149b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project void stopTimer() { 150b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mCallTime.cancelTimer(); 151b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 152b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 153b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project @Override 154b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project protected void onFinishInflate() { 155b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project super.onFinishInflate(); 156b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 157b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("CallCard onFinishInflate(this = " + this + ")..."); 158b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 159d5f6f5f0c3dd6f4c939c1e432bc75fd4da0d4b74David Brown mCallInfoContainer = (ViewGroup) findViewById(R.id.call_info_container); 1609033b29f9a5c890e676aebe957c368c3679aac3cDavid Brown mPrimaryCallInfo = (ViewGroup) findViewById(R.id.call_info_1); 161d5f6f5f0c3dd6f4c939c1e432bc75fd4da0d4b74David Brown mPrimaryCallBanner = (ViewGroup) findViewById(R.id.call_banner_1); 1629033b29f9a5c890e676aebe957c368c3679aac3cDavid Brown mSecondaryCallInfo = (ViewGroup) findViewById(R.id.call_info_2); 16330c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown mCallStateLabel = (TextView) findViewById(R.id.callStateLabel); 164b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mElapsedTime = (TextView) findViewById(R.id.elapsedTime); 165b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 166b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Text colors 1679d14e16e8214b4a396dad293b6f0941608ee4798David Brown mTextColorCallTypeSip = getResources().getColor(R.color.incall_callTypeSip); 168b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 169b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // "Caller info" area, including photo / name / phone numbers / etc 170b424ca2073702aff4ac1d9297d8bbe73ee4cd8b9David Brown mPhoto = (InCallContactPhoto) findViewById(R.id.photo); 171b424ca2073702aff4ac1d9297d8bbe73ee4cd8b9David Brown ImageView inset = (ImageView) findViewById(R.id.insetPhoto); 172b424ca2073702aff4ac1d9297d8bbe73ee4cd8b9David Brown mPhoto.setInsetImageView(inset); 173b424ca2073702aff4ac1d9297d8bbe73ee4cd8b9David Brown 174b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mName = (TextView) findViewById(R.id.name); 175b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhoneNumber = (TextView) findViewById(R.id.phoneNumber); 176b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mLabel = (TextView) findViewById(R.id.label); 1779d14e16e8214b4a396dad293b6f0941608ee4798David Brown mCallTypeLabel = (TextView) findViewById(R.id.callTypeLabel); 17829d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown mSocialStatus = (TextView) findViewById(R.id.socialStatus); 179b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1809033b29f9a5c890e676aebe957c368c3679aac3cDavid Brown // Secondary info area, for the background ("on hold") call 1810d315275d08cd33f801ae3a74e8fc265520f6246David Brown mSecondaryCallName = (TextView) findViewById(R.id.secondaryCallName); 1820d315275d08cd33f801ae3a74e8fc265520f6246David Brown mSecondaryCallStatus = (TextView) findViewById(R.id.secondaryCallStatus); 183b424ca2073702aff4ac1d9297d8bbe73ee4cd8b9David Brown mSecondaryCallPhoto = (InCallContactPhoto) findViewById(R.id.secondaryCallPhoto); 184b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 185b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 186b15bef0ddcb4f744dff92013a9b596f2fcc2a008David Brown /** 187b15bef0ddcb4f744dff92013a9b596f2fcc2a008David Brown * Updates the state of all UI elements on the CallCard, based on the 188b15bef0ddcb4f744dff92013a9b596f2fcc2a008David Brown * current state of the phone. 189b15bef0ddcb4f744dff92013a9b596f2fcc2a008David Brown */ 1908343169cc89621d46dce86449f5ee1ff5d3a4919John Wang void updateState(CallManager cm) { 1918343169cc89621d46dce86449f5ee1ff5d3a4919John Wang if (DBG) log("updateState(" + cm + ")..."); 192b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 193d5f6f5f0c3dd6f4c939c1e432bc75fd4da0d4b74David Brown // Update the onscreen UI based on the current state of the phone. 194b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1958343169cc89621d46dce86449f5ee1ff5d3a4919John Wang Phone.State state = cm.getState(); // IDLE, RINGING, or OFFHOOK 196091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan Call ringingCall = cm.getFirstActiveRingingCall(); 197091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan Call fgCall = cm.getActiveFgCall(); 198091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan Call bgCall = cm.getFirstActiveBgCall(); 199091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan 200d5f6f5f0c3dd6f4c939c1e432bc75fd4da0d4b74David Brown // Update the overall layout of the onscreen elements. 201d5f6f5f0c3dd6f4c939c1e432bc75fd4da0d4b74David Brown updateCallInfoLayout(state); 202d5f6f5f0c3dd6f4c939c1e432bc75fd4da0d4b74David Brown 2037f09c1629141416c489ede69e70e2aa59453ddedHung-ying Tyan // If the FG call is dialing/alerting, we should display for that call 2047f09c1629141416c489ede69e70e2aa59453ddedHung-ying Tyan // and ignore the ringing call. This case happens when the telephony 2057f09c1629141416c489ede69e70e2aa59453ddedHung-ying Tyan // layer rejects the ringing call while the FG call is dialing/alerting, 2067f09c1629141416c489ede69e70e2aa59453ddedHung-ying Tyan // but the incoming call *does* briefly exist in the DISCONNECTING or 2077f09c1629141416c489ede69e70e2aa59453ddedHung-ying Tyan // DISCONNECTED state. 2087f09c1629141416c489ede69e70e2aa59453ddedHung-ying Tyan if ((ringingCall.getState() != Call.State.IDLE) 2097f09c1629141416c489ede69e70e2aa59453ddedHung-ying Tyan && !fgCall.getState().isDialing()) { 210091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // A phone call is ringing, call waiting *or* being rejected 211b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // (ie. another call may also be active as well.) 2128343169cc89621d46dce86449f5ee1ff5d3a4919John Wang updateRingingCall(cm); 213091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan } else if ((fgCall.getState() != Call.State.IDLE) 214091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan || (bgCall.getState() != Call.State.IDLE)) { 215091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // We are here because either: 216091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // (1) the phone is off hook. At least one call exists that is 217091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // dialing, active, or holding, and no calls are ringing or waiting, 218091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // or: 219091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // (2) the phone is IDLE but a call just ended and it's still in 220091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // the DISCONNECTING or DISCONNECTED state. In this case, we want 221091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // the main CallCard to display "Hanging up" or "Call ended". 222091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // The normal "foreground call" code path handles both cases. 2238343169cc89621d46dce86449f5ee1ff5d3a4919John Wang updateForegroundCall(cm); 224b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 225091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // We don't have any DISCONNECTED calls, which means 226091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // that the phone is *truly* idle. 227b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // 228091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // It's very rare to be on the InCallScreen at all in this 229091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // state, but it can happen in some cases: 230091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // - A stray onPhoneStateChanged() event came in to the 231091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // InCallScreen *after* it was dismissed. 232091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // - We're allowed to be on the InCallScreen because 233091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // an MMI or USSD is running, but there's no actual "call" 234091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // to display. 235091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // - We're displaying an error dialog to the user 236091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // (explaining why the call failed), so we need to stay on 237091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // the InCallScreen so that the dialog will be visible. 238091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // 239091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // In these cases, put the callcard into a sane but "blank" state: 240091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan updateNoCall(cm); 241b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 242b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 243b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 244b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 245d5f6f5f0c3dd6f4c939c1e432bc75fd4da0d4b74David Brown * Updates the overall size and positioning of mCallInfoContainer and 246d5f6f5f0c3dd6f4c939c1e432bc75fd4da0d4b74David Brown * the "Call info" blocks, based on the phone state. 247d5f6f5f0c3dd6f4c939c1e432bc75fd4da0d4b74David Brown */ 248d5f6f5f0c3dd6f4c939c1e432bc75fd4da0d4b74David Brown private void updateCallInfoLayout(Phone.State state) { 249d5f6f5f0c3dd6f4c939c1e432bc75fd4da0d4b74David Brown boolean ringing = (state == Phone.State.RINGING); 250ee6be3c53945e69acce6c2c852ce1ebf69015c9dDavid Brown if (DBG) log("updateCallInfoLayout()... ringing = " + ringing); 251d5f6f5f0c3dd6f4c939c1e432bc75fd4da0d4b74David Brown 252507ee75639e41c17edd410ef787e0617778071aaDavid Brown // Based on the current state, update the overall 253ee6be3c53945e69acce6c2c852ce1ebf69015c9dDavid Brown // CallCard layout: 254ee6be3c53945e69acce6c2c852ce1ebf69015c9dDavid Brown 255ee6be3c53945e69acce6c2c852ce1ebf69015c9dDavid Brown // - Update the bottom margin of mCallInfoContainer to make sure 256ee6be3c53945e69acce6c2c852ce1ebf69015c9dDavid Brown // the call info area won't overlap with the touchable 257ee6be3c53945e69acce6c2c852ce1ebf69015c9dDavid Brown // controls on the bottom part of the screen. 258d5f6f5f0c3dd6f4c939c1e432bc75fd4da0d4b74David Brown 259507ee75639e41c17edd410ef787e0617778071aaDavid Brown int reservedVerticalSpace = mInCallScreen.getInCallTouchUi().getTouchUiHeight(); 260d5f6f5f0c3dd6f4c939c1e432bc75fd4da0d4b74David Brown ViewGroup.MarginLayoutParams callInfoLp = 261d5f6f5f0c3dd6f4c939c1e432bc75fd4da0d4b74David Brown (ViewGroup.MarginLayoutParams) mCallInfoContainer.getLayoutParams(); 262d5f6f5f0c3dd6f4c939c1e432bc75fd4da0d4b74David Brown callInfoLp.bottomMargin = reservedVerticalSpace; // Equivalent to setting 263d5f6f5f0c3dd6f4c939c1e432bc75fd4da0d4b74David Brown // android:layout_marginBottom in XML 264ee6be3c53945e69acce6c2c852ce1ebf69015c9dDavid Brown if (DBG) log(" ==> callInfoLp.bottomMargin: " + reservedVerticalSpace); 265d5f6f5f0c3dd6f4c939c1e432bc75fd4da0d4b74David Brown mCallInfoContainer.setLayoutParams(callInfoLp); 266d5f6f5f0c3dd6f4c939c1e432bc75fd4da0d4b74David Brown } 267d5f6f5f0c3dd6f4c939c1e432bc75fd4da0d4b74David Brown 268d5f6f5f0c3dd6f4c939c1e432bc75fd4da0d4b74David Brown /** 269b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Updates the UI for the state where the phone is in use, but not ringing. 270b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 2718343169cc89621d46dce86449f5ee1ff5d3a4919John Wang private void updateForegroundCall(CallManager cm) { 272b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("updateForegroundCall()..."); 27302d1c632adde606031c1fe6ea0e3be1e288fd6c6David Brown // if (DBG) PhoneUtils.dumpCallManager(); 2748343169cc89621d46dce86449f5ee1ff5d3a4919John Wang 2758343169cc89621d46dce86449f5ee1ff5d3a4919John Wang Call fgCall = cm.getActiveFgCall(); 2768343169cc89621d46dce86449f5ee1ff5d3a4919John Wang Call bgCall = cm.getFirstActiveBgCall(); 2778343169cc89621d46dce86449f5ee1ff5d3a4919John Wang 278091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan if (fgCall.getState() == Call.State.IDLE) { 279b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("updateForegroundCall: no active call, show holding call"); 280b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // TODO: make sure this case agrees with the latest UI spec. 281b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 282b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Display the background call in the main info area of the 283b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // CallCard, since there is no foreground call. Note that 284b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // displayMainCallStatus() will notice if the call we passed in is on 285b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // hold, and display the "on hold" indication. 286b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project fgCall = bgCall; 287b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 288b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // And be sure to not display anything in the "on hold" box. 289b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project bgCall = null; 290b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 291b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2928343169cc89621d46dce86449f5ee1ff5d3a4919John Wang displayMainCallStatus(cm, fgCall); 2938343169cc89621d46dce86449f5ee1ff5d3a4919John Wang 2948343169cc89621d46dce86449f5ee1ff5d3a4919John Wang Phone phone = fgCall.getPhone(); 2950fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 29679b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink int phoneType = phone.getPhoneType(); 29779b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink if (phoneType == Phone.PHONE_TYPE_CDMA) { 29839a84144262f12df44861d746788b9de92259e4fAbhishek Pillai if ((mApplication.cdmaPhoneCallState.getCurrentCallState() 29939a84144262f12df44861d746788b9de92259e4fAbhishek Pillai == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) 30039a84144262f12df44861d746788b9de92259e4fAbhishek Pillai && mApplication.cdmaPhoneCallState.IsThreeWayCallOrigStateDialing()) { 3018343169cc89621d46dce86449f5ee1ff5d3a4919John Wang displayOnHoldCallStatus(cm, fgCall); 3020fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } else { 3030fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville //This is required so that even if a background call is not present 3040fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // we need to clean up the background call area. 3058343169cc89621d46dce86449f5ee1ff5d3a4919John Wang displayOnHoldCallStatus(cm, bgCall); 3060fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 307872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan } else if ((phoneType == Phone.PHONE_TYPE_GSM) 308872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan || (phoneType == Phone.PHONE_TYPE_SIP)) { 3098343169cc89621d46dce86449f5ee1ff5d3a4919John Wang displayOnHoldCallStatus(cm, bgCall); 3100fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 311b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 312b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 313b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 314b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Updates the UI for the state where an incoming call is ringing (or 315b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * call waiting), regardless of whether the phone's already offhook. 316b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 3178343169cc89621d46dce86449f5ee1ff5d3a4919John Wang private void updateRingingCall(CallManager cm) { 318b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("updateRingingCall()..."); 319b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3208343169cc89621d46dce86449f5ee1ff5d3a4919John Wang Call ringingCall = cm.getFirstActiveRingingCall(); 321b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3226b7d0da33af02960736da204eb7a25ccf91d5396David Brown // Display caller-id info and photo from the incoming call: 3238343169cc89621d46dce86449f5ee1ff5d3a4919John Wang displayMainCallStatus(cm, ringingCall); 3246b7d0da33af02960736da204eb7a25ccf91d5396David Brown 3256b7d0da33af02960736da204eb7a25ccf91d5396David Brown // And even in the Call Waiting case, *don't* show any info about 3266b7d0da33af02960736da204eb7a25ccf91d5396David Brown // the current ongoing call and/or the current call on hold. 3276b7d0da33af02960736da204eb7a25ccf91d5396David Brown // (Since the caller-id info for the incoming call totally trumps 3286b7d0da33af02960736da204eb7a25ccf91d5396David Brown // any info about the current call(s) in progress.) 3298343169cc89621d46dce86449f5ee1ff5d3a4919John Wang displayOnHoldCallStatus(cm, null); 330b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 331b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 332b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 333b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Updates the UI for the state where the phone is not in use. 334b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * This is analogous to updateForegroundCall() and updateRingingCall(), 335b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * but for the (uncommon) case where the phone is 336b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * totally idle. (See comments in updateState() above.) 337b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 338b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * This puts the callcard into a sane but "blank" state. 339b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 3408343169cc89621d46dce86449f5ee1ff5d3a4919John Wang private void updateNoCall(CallManager cm) { 341b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("updateNoCall()..."); 342b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3438343169cc89621d46dce86449f5ee1ff5d3a4919John Wang displayMainCallStatus(cm, null); 3448343169cc89621d46dce86449f5ee1ff5d3a4919John Wang displayOnHoldCallStatus(cm, null); 345b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 346b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 347b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 348b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Updates the main block of caller info on the CallCard 3490d315275d08cd33f801ae3a74e8fc265520f6246David Brown * (ie. the stuff in the primaryCallInfo block) based on the specified Call. 350b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 3518343169cc89621d46dce86449f5ee1ff5d3a4919John Wang private void displayMainCallStatus(CallManager cm, Call call) { 35202d1c632adde606031c1fe6ea0e3be1e288fd6c6David Brown if (DBG) log("displayMainCallStatus(call " + call + ")..."); 353b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 354b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (call == null) { 355b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // There's no call to display, presumably because the phone is idle. 3560d315275d08cd33f801ae3a74e8fc265520f6246David Brown mPrimaryCallInfo.setVisibility(View.GONE); 357b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return; 358b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 3590d315275d08cd33f801ae3a74e8fc265520f6246David Brown mPrimaryCallInfo.setVisibility(View.VISIBLE); 360b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 361b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Call.State state = call.getState(); 362b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log(" - call.state: " + call.getState()); 363b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 364b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project switch (state) { 365b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case ACTIVE: 3665eff1e7d582679b3a85f580eb1d550b2e6ca111cDavid Brown case DISCONNECTING: 367b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // update timer field 368b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("displayMainCallStatus: start periodicUpdateTimer"); 369b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mCallTime.setActiveCallMode(call); 370b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mCallTime.reset(); 371b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mCallTime.periodicUpdateTimer(); 372b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 373b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 374b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 375b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case HOLDING: 376b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // update timer field 377b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mCallTime.cancelTimer(); 378b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 379b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 380b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 381b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case DISCONNECTED: 382b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Stop getting timer ticks from this call 383b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mCallTime.cancelTimer(); 384b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 385b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 386b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 387b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case DIALING: 388b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case ALERTING: 389b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Stop getting timer ticks from a previous call 390b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mCallTime.cancelTimer(); 391b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 392b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 393b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 394b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case INCOMING: 395b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case WAITING: 396b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Stop getting timer ticks from a previous call 397b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mCallTime.cancelTimer(); 398b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 399b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 400b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 401b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case IDLE: 402b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // The "main CallCard" should never be trying to display 403b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // an idle call! In updateState(), if the phone is idle, 404b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // we call updateNoCall(), which means that we shouldn't 405b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // have passed a call into this method at all. 406b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Log.w(LOG_TAG, "displayMainCallStatus: IDLE call in the main call card!"); 407b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 408b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // (It is possible, though, that we had a valid call which 409b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // became idle *after* the check in updateState() but 410b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // before we get here... So continue the best we can, 411b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // with whatever (stale) info we can get from the 412b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // passed-in Call object.) 413b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 414b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 415b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 416b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project default: 417b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Log.w(LOG_TAG, "displayMainCallStatus: unexpected call state: " + state); 418b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 419b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 420b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 42130c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown updateCallStateWidgets(call); 422b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 423b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (PhoneUtils.isConferenceCall(call)) { 424b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Update onscreen info for a conference call. 425872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan updateDisplayForConference(call); 426b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 427b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Update onscreen info for a regular call (which presumably 428b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // has only one connection.) 4290fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville Connection conn = null; 4308343169cc89621d46dce86449f5ee1ff5d3a4919John Wang int phoneType = call.getPhone().getPhoneType(); 43179b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink if (phoneType == Phone.PHONE_TYPE_CDMA) { 4320fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville conn = call.getLatestConnection(); 433872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan } else if ((phoneType == Phone.PHONE_TYPE_GSM) 434872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan || (phoneType == Phone.PHONE_TYPE_SIP)) { 4350fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville conn = call.getEarliestConnection(); 43679b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink } else { 43779b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink throw new IllegalStateException("Unexpected phone type: " + phoneType); 4380fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 439b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 440b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (conn == null) { 441b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("displayMainCallStatus: connection is null, using default values."); 442b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if the connection is null, we run through the behaviour 443b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // we had in the past, which breaks down into trivial steps 444b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // with the current implementation of getCallerInfo and 445b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // updateDisplayForPerson. 4464359358c4f430cbb986a5e7640ec506f08f1e332David Brown CallerInfo info = PhoneUtils.getCallerInfo(getContext(), null /* conn */); 4475a4bc9222fc865b17e82c450fd878e9ee18bd643David Brown updateDisplayForPerson(info, Connection.PRESENTATION_ALLOWED, false, call, conn); 448b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 449b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log(" - CONN: " + conn + ", state = " + conn.getState()); 4504359358c4f430cbb986a5e7640ec506f08f1e332David Brown int presentation = conn.getNumberPresentation(); 451b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 452b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // make sure that we only make a new query when the current 453b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // callerinfo differs from what we've been requested to display. 454b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project boolean runQuery = true; 455b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Object o = conn.getUserData(); 456b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (o instanceof PhoneUtils.CallerInfoToken) { 457b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project runQuery = mPhotoTracker.isDifferentImageRequest( 458b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project ((PhoneUtils.CallerInfoToken) o).currentInfo); 459b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 460b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project runQuery = mPhotoTracker.isDifferentImageRequest(conn); 461b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 462b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 46346532b66a467f247380054270c6151aa3dc7a761Wink Saville // Adding a check to see if the update was caused due to a Phone number update 46446532b66a467f247380054270c6151aa3dc7a761Wink Saville // or CNAP update. If so then we need to start a new query 46579b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink if (phoneType == Phone.PHONE_TYPE_CDMA) { 46646532b66a467f247380054270c6151aa3dc7a761Wink Saville Object obj = conn.getUserData(); 46746532b66a467f247380054270c6151aa3dc7a761Wink Saville String updatedNumber = conn.getAddress(); 46846532b66a467f247380054270c6151aa3dc7a761Wink Saville String updatedCnapName = conn.getCnapName(); 46946532b66a467f247380054270c6151aa3dc7a761Wink Saville CallerInfo info = null; 47046532b66a467f247380054270c6151aa3dc7a761Wink Saville if (obj instanceof PhoneUtils.CallerInfoToken) { 47146532b66a467f247380054270c6151aa3dc7a761Wink Saville info = ((PhoneUtils.CallerInfoToken) o).currentInfo; 47246532b66a467f247380054270c6151aa3dc7a761Wink Saville } else if (o instanceof CallerInfo) { 47346532b66a467f247380054270c6151aa3dc7a761Wink Saville info = (CallerInfo) o; 47446532b66a467f247380054270c6151aa3dc7a761Wink Saville } 47546532b66a467f247380054270c6151aa3dc7a761Wink Saville 47646532b66a467f247380054270c6151aa3dc7a761Wink Saville if (info != null) { 47746532b66a467f247380054270c6151aa3dc7a761Wink Saville if (updatedNumber != null && !updatedNumber.equals(info.phoneNumber)) { 47846532b66a467f247380054270c6151aa3dc7a761Wink Saville if (DBG) log("- displayMainCallStatus: updatedNumber = " 47946532b66a467f247380054270c6151aa3dc7a761Wink Saville + updatedNumber); 48046532b66a467f247380054270c6151aa3dc7a761Wink Saville runQuery = true; 48146532b66a467f247380054270c6151aa3dc7a761Wink Saville } 48246532b66a467f247380054270c6151aa3dc7a761Wink Saville if (updatedCnapName != null && !updatedCnapName.equals(info.cnapName)) { 48346532b66a467f247380054270c6151aa3dc7a761Wink Saville if (DBG) log("- displayMainCallStatus: updatedCnapName = " 48446532b66a467f247380054270c6151aa3dc7a761Wink Saville + updatedCnapName); 48546532b66a467f247380054270c6151aa3dc7a761Wink Saville runQuery = true; 48646532b66a467f247380054270c6151aa3dc7a761Wink Saville } 48746532b66a467f247380054270c6151aa3dc7a761Wink Saville } 48846532b66a467f247380054270c6151aa3dc7a761Wink Saville } 48946532b66a467f247380054270c6151aa3dc7a761Wink Saville 490b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (runQuery) { 491b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("- displayMainCallStatus: starting CallerInfo query..."); 492b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project PhoneUtils.CallerInfoToken info = 493b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project PhoneUtils.startGetCallerInfo(getContext(), conn, this, call); 4945a4bc9222fc865b17e82c450fd878e9ee18bd643David Brown updateDisplayForPerson(info.currentInfo, presentation, !info.isFinal, 4955a4bc9222fc865b17e82c450fd878e9ee18bd643David Brown call, conn); 496b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 497b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // No need to fire off a new query. We do still need 498b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // to update the display, though (since we might have 499b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // previously been in the "conference call" state.) 500b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("- displayMainCallStatus: using data we already have..."); 501b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (o instanceof CallerInfo) { 502b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project CallerInfo ci = (CallerInfo) o; 503e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai // Update CNAP information if Phone state change occurred 504e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai ci.cnapName = conn.getCnapName(); 505e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai ci.numberPresentation = conn.getNumberPresentation(); 506e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai ci.namePresentation = conn.getCnapNamePresentation(); 507e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai if (DBG) log("- displayMainCallStatus: CNAP data from Connection: " 508e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai + "CNAP name=" + ci.cnapName 509e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai + ", Number/Name Presentation=" + ci.numberPresentation); 510b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log(" ==> Got CallerInfo; updating display: ci = " + ci); 5115a4bc9222fc865b17e82c450fd878e9ee18bd643David Brown updateDisplayForPerson(ci, presentation, false, call, conn); 512b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else if (o instanceof PhoneUtils.CallerInfoToken){ 513b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project CallerInfo ci = ((PhoneUtils.CallerInfoToken) o).currentInfo; 514e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai if (DBG) log("- displayMainCallStatus: CNAP data from Connection: " 515e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai + "CNAP name=" + ci.cnapName 516e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai + ", Number/Name Presentation=" + ci.numberPresentation); 517b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log(" ==> Got CallerInfoToken; updating display: ci = " + ci); 5185a4bc9222fc865b17e82c450fd878e9ee18bd643David Brown updateDisplayForPerson(ci, presentation, true, call, conn); 519b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 520b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Log.w(LOG_TAG, "displayMainCallStatus: runQuery was false, " 521b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project + "but we didn't have a cached CallerInfo object! o = " + o); 522b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // TODO: any easy way to recover here (given that 523b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // the CallCard is probably displaying stale info 524b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // right now?) Maybe force the CallCard into the 525b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // "Unknown" state? 526b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 527b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 528b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 529b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 530b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 531b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // In some states we override the "photo" ImageView to be an 532b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // indication of the current state, rather than displaying the 533b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // regular photo as set above. 534b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project updatePhotoForCallState(call); 5359688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown 5369688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown // One special feature of the "number" text field: For incoming 5379688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown // calls, while the user is dragging the RotarySelector widget, we 5389688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown // use mPhoneNumber to display a hint like "Rotate to answer". 539ea505da2d0ebae37b07fece15297b5432fe96c5dJim Miller if (mIncomingCallWidgetHintTextResId != 0) { 5409688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown // Display the hint! 541ea505da2d0ebae37b07fece15297b5432fe96c5dJim Miller mPhoneNumber.setText(mIncomingCallWidgetHintTextResId); 542ea505da2d0ebae37b07fece15297b5432fe96c5dJim Miller mPhoneNumber.setTextColor(getResources().getColor(mIncomingCallWidgetHintColorResId)); 5439688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown mPhoneNumber.setVisibility(View.VISIBLE); 5449688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown mLabel.setVisibility(View.GONE); 5459688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown } 5469688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown // If we don't have a hint to display, just don't touch 5479688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown // mPhoneNumber and mLabel. (Their text / color / visibility have 5489688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown // already been set correctly, by either updateDisplayForPerson() 5499688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown // or updateDisplayForConference().) 550b15bef0ddcb4f744dff92013a9b596f2fcc2a008David Brown } 551b15bef0ddcb4f744dff92013a9b596f2fcc2a008David Brown 552b15bef0ddcb4f744dff92013a9b596f2fcc2a008David Brown /** 553b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Implemented for CallerInfoAsyncQuery.OnQueryCompleteListener interface. 554b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * refreshes the CallCard data when it called. 555b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 556b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public void onQueryComplete(int token, Object cookie, CallerInfo ci) { 557b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("onQueryComplete: token " + token + ", cookie " + cookie + ", ci " + ci); 558b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 559b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (cookie instanceof Call) { 560b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // grab the call object and update the display for an individual call, 561b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // as well as the successive call to update image via call state. 562b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // If the object is a textview instead, we update it as we need to. 563b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("callerinfo query complete, updating ui from displayMainCallStatus()"); 564b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Call call = (Call) cookie; 565a0ea7a803c8953a14bc35d1fef0973fd1d9c64b9Abhishek Pillai Connection conn = null; 566872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan int phoneType = call.getPhone().getPhoneType(); 567a0ea7a803c8953a14bc35d1fef0973fd1d9c64b9Abhishek Pillai if (phoneType == Phone.PHONE_TYPE_CDMA) { 568a0ea7a803c8953a14bc35d1fef0973fd1d9c64b9Abhishek Pillai conn = call.getLatestConnection(); 569872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan } else if ((phoneType == Phone.PHONE_TYPE_GSM) 570872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan || (phoneType == Phone.PHONE_TYPE_SIP)) { 571a0ea7a803c8953a14bc35d1fef0973fd1d9c64b9Abhishek Pillai conn = call.getEarliestConnection(); 572a0ea7a803c8953a14bc35d1fef0973fd1d9c64b9Abhishek Pillai } else { 573a0ea7a803c8953a14bc35d1fef0973fd1d9c64b9Abhishek Pillai throw new IllegalStateException("Unexpected phone type: " + phoneType); 574a0ea7a803c8953a14bc35d1fef0973fd1d9c64b9Abhishek Pillai } 575e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai PhoneUtils.CallerInfoToken cit = 576e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai PhoneUtils.startGetCallerInfo(getContext(), conn, this, null); 577e066d6979acb39dbc0ba79ecc10bc12e84a15195David Brown 578e066d6979acb39dbc0ba79ecc10bc12e84a15195David Brown int presentation = Connection.PRESENTATION_ALLOWED; 579e066d6979acb39dbc0ba79ecc10bc12e84a15195David Brown if (conn != null) presentation = conn.getNumberPresentation(); 580e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai if (DBG) log("- onQueryComplete: presentation=" + presentation 581e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai + ", contactExists=" + ci.contactExists); 582e066d6979acb39dbc0ba79ecc10bc12e84a15195David Brown 583e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai // Depending on whether there was a contact match or not, we want to pass in different 584e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai // CallerInfo (for CNAP). Therefore if ci.contactExists then use the ci passed in. 585e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai // Otherwise, regenerate the CIT from the Connection and use the CallerInfo from there. 586e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai if (ci.contactExists) { 5875a4bc9222fc865b17e82c450fd878e9ee18bd643David Brown updateDisplayForPerson(ci, Connection.PRESENTATION_ALLOWED, false, call, conn); 588e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai } else { 5895a4bc9222fc865b17e82c450fd878e9ee18bd643David Brown updateDisplayForPerson(cit.currentInfo, presentation, false, call, conn); 590e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai } 591b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project updatePhotoForCallState(call); 592b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 593b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else if (cookie instanceof TextView){ 594b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("callerinfo query complete, updating ui from ongoing or onhold"); 595b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project ((TextView) cookie).setText(PhoneUtils.getCompactNameFromCallerInfo(ci, mContext)); 596b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 597b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 598b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 599b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 600b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Implemented for ContactsAsyncHelper.OnImageLoadCompleteListener interface. 601b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * make sure that the call state is reflected after the image is loaded. 602b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 603b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public void onImageLoadComplete(int token, Object cookie, ImageView iView, 604b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project boolean imagePresent){ 605b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (cookie != null) { 606b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project updatePhotoForCallState((Call) cookie); 607b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 608b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 609b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 610b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 61130c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown * Updates the "call state label" and the elapsed time widget based on the 61230c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown * current state of the call. 613b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 61430c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown private void updateCallStateWidgets(Call call) { 61530c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown if (DBG) log("updateCallStateWidgets(call " + call + ")..."); 61630c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown final Call.State state = call.getState(); 61730c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown final Context context = getContext(); 61830c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown final Phone phone = call.getPhone(); 61930c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown final int phoneType = phone.getPhoneType(); 620b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 62130c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown String callStateLabel = null; // Label to display as part of the call banner 62230c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown int bluetoothIconId = 0; // Icon to display alongside the call state label 62330c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown 62430c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown switch (state) { 62530c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown case IDLE: 62630c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown // "Call state" is meaningless in this state. 62730c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown break; 62830c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown 62930c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown case ACTIVE: 63030c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown // We normally don't show a "call state label" at all in 63130c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown // this state (but see below for some special cases). 63230c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown break; 63330c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown 63430c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown case HOLDING: 63530c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown callStateLabel = context.getString(R.string.card_title_on_hold); 63630c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown break; 63730c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown 63830c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown case DIALING: 63930c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown case ALERTING: 64030c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown callStateLabel = context.getString(R.string.card_title_dialing); 64130c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown break; 64230c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown 64330c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown case INCOMING: 64430c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown case WAITING: 64530c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown callStateLabel = context.getString(R.string.card_title_incoming_call); 64630c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown 64730c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown // Also, display a special icon (alongside the "Incoming call" 64830c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown // label) if there's an incoming call and audio will be routed 64930c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown // to bluetooth when you answer it. 65030c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown if (mApplication.showBluetoothIndication()) { 65130c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown bluetoothIconId = R.drawable.ic_incoming_call_bluetooth; 65230c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown } 65330c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown break; 65430c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown 65530c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown case DISCONNECTING: 65630c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown // While in the DISCONNECTING state we display a "Hanging up" 65730c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown // message in order to make the UI feel more responsive. (In 65830c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown // GSM it's normal to see a delay of a couple of seconds while 65930c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown // negotiating the disconnect with the network, so the "Hanging 66030c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown // up" state at least lets the user know that we're doing 66130c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown // something. This state is currently not used with CDMA.) 66230c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown callStateLabel = context.getString(R.string.card_title_hanging_up); 66330c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown break; 66430c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown 66530c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown case DISCONNECTED: 66630c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown callStateLabel = getCallFailedString(call); 66730c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown break; 66830c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown 66930c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown default: 67030c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown Log.wtf(LOG_TAG, "updateCallStateWidgets: unexpected call state: " + state); 67130c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown break; 67230c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown } 67330c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown 67430c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown // Check a couple of other special cases (these are all CDMA-specific). 675b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 67679b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink if (phoneType == Phone.PHONE_TYPE_CDMA) { 67730c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown if ((state == Call.State.ACTIVE) 67830c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown && mApplication.cdmaPhoneCallState.IsThreeWayCallOrigStateDialing()) { 67930c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown // Display "Dialing" while dialing a 3Way call, even 68030c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown // though the foreground call state is actually ACTIVE. 68130c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown callStateLabel = context.getString(R.string.card_title_dialing); 68230c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown } else if (PhoneApp.getInstance().notifier.getIsCdmaRedialCall()) { 68330c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown callStateLabel = context.getString(R.string.card_title_redialing); 6843800ac871d6548790ac6119bb68b9be0640af261David Krause } 68530c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown } 68630c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown if (PhoneUtils.isPhoneInEcm(phone)) { 68730c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown // In emergency callback mode (ECM), use a special label 68830c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown // that shows your own phone number. 68930c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown callStateLabel = getECMCardTitle(context, phone); 69030c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown } 69130c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown 69230c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown if (DBG) log("==> callStateLabel: '" + callStateLabel 69330c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown + "', bluetoothIconId = " + bluetoothIconId); 69430c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown 69530c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown // Update (or hide) the onscreen widget: 69630c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown if (TextUtils.isEmpty(callStateLabel)) { 6975cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown // When hiding, do a smooth fade-out animation. 6985cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown Fade.hide(mCallStateLabel, View.GONE); 69979b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink } else { 7005cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown // ... but when becoming visible, never animate (mainly to be 7015cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown // sure you don't see a fade-in at the very beginning of a 7025cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown // call.) 70330c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown mCallStateLabel.setVisibility(View.VISIBLE); 7045cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown 70530c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown mCallStateLabel.setText(callStateLabel); 70630c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown 70730c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown // ...and display the icon too if necessary. 70830c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown if (bluetoothIconId != 0) { 70930c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown mCallStateLabel.setCompoundDrawablesWithIntrinsicBounds(bluetoothIconId, 0, 0, 0); 71030c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown mCallStateLabel.setCompoundDrawablePadding((int) (mDensity * 5)); 71130c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown } else { 71230c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown // Clear out any icons 71330c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown mCallStateLabel.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0); 71430c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown } 7153800ac871d6548790ac6119bb68b9be0640af261David Krause } 716b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 71730c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown // ...and update the elapsed time widget too. 71834a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown switch (state) { 71934a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown case ACTIVE: 72034a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown case DISCONNECTING: 72134a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown mElapsedTime.setVisibility(View.VISIBLE); 72234a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown long duration = CallTime.getCallDuration(call); // msec 72334a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown updateElapsedTimeWidget(duration / 1000); 72434a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // Also see onTickForCallTimeElapsed(), which updates this 72534a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // widget once per second while the call is active. 72634a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown break; 72734a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown 72834a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown case DISCONNECTED: 72934a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // In the "Call ended" state, leave the mElapsedTime widget 73030c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown // visible, but don't touch it (so we continue to see the 73130c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown // elapsed time of the call that just ended.) 73234a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown mElapsedTime.setVisibility(View.VISIBLE); 73334a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown break; 73434a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown 73534a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown default: 73630c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown // In all other states (DIALING, INCOMING, HOLDING, etc.), 73730c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown // the "elapsed time" is meaningless, so don't show it. 73834a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown mElapsedTime.setVisibility(View.INVISIBLE); 73934a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown break; 740b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 741b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 742b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 743b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 744b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Updates mElapsedTime based on the specified number of seconds. 745b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * A timeElapsed value of zero means to not show an elapsed time at all. 746b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 747b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void updateElapsedTimeWidget(long timeElapsed) { 748b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if (DBG) log("updateElapsedTimeWidget: " + timeElapsed); 749b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (timeElapsed == 0) { 750b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mElapsedTime.setText(""); 751b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 752b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mElapsedTime.setText(DateUtils.formatElapsedTime(timeElapsed)); 753b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 754b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 755b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 756b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 757b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Updates the "on hold" box in the "other call" info area 7580d315275d08cd33f801ae3a74e8fc265520f6246David Brown * (ie. the stuff in the secondaryCallInfo block) 759b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * based on the specified Call. 760b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Or, clear out the "on hold" box if the specified call 761b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * is null or idle. 762b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 7638343169cc89621d46dce86449f5ee1ff5d3a4919John Wang private void displayOnHoldCallStatus(CallManager cm, Call call) { 764b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("displayOnHoldCallStatus(call =" + call + ")..."); 765af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville 766af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville if ((call == null) || (PhoneApp.getInstance().isOtaCallInActiveState())) { 7670d315275d08cd33f801ae3a74e8fc265520f6246David Brown mSecondaryCallInfo.setVisibility(View.GONE); 768b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return; 769b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 770b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 7718da4d90151c882972e15429d4d48bdaa45095d72David Brown boolean showSecondaryCallInfo = false; 772b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Call.State state = call.getState(); 773b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project switch (state) { 774b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case HOLDING: 775b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Ok, there actually is a background call on hold. 776b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Display the "on hold" box. 777b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 7780d315275d08cd33f801ae3a74e8fc265520f6246David Brown // Note this case occurs only on GSM devices. (On CDMA, 7790d315275d08cd33f801ae3a74e8fc265520f6246David Brown // the "call on hold" is actually the 2nd connection of 7800d315275d08cd33f801ae3a74e8fc265520f6246David Brown // that ACTIVE call; see the ACTIVE case below.) 7810d315275d08cd33f801ae3a74e8fc265520f6246David Brown 782b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (PhoneUtils.isConferenceCall(call)) { 783b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("==> conference call."); 7840d315275d08cd33f801ae3a74e8fc265520f6246David Brown mSecondaryCallName.setText(getContext().getString(R.string.confCall)); 7850d315275d08cd33f801ae3a74e8fc265520f6246David Brown showImage(mSecondaryCallPhoto, R.drawable.picture_conference); 786b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 787b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // perform query and update the name temporarily 788b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // make sure we hand the textview we want updated to the 789b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // callback function. 790b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("==> NOT a conf call; call startGetCallerInfo..."); 7910d315275d08cd33f801ae3a74e8fc265520f6246David Brown PhoneUtils.CallerInfoToken infoToken = PhoneUtils.startGetCallerInfo( 7920d315275d08cd33f801ae3a74e8fc265520f6246David Brown getContext(), call, this, mSecondaryCallName); 7930d315275d08cd33f801ae3a74e8fc265520f6246David Brown mSecondaryCallName.setText( 7940d315275d08cd33f801ae3a74e8fc265520f6246David Brown PhoneUtils.getCompactNameFromCallerInfo(infoToken.currentInfo, 7950d315275d08cd33f801ae3a74e8fc265520f6246David Brown getContext())); 7960d315275d08cd33f801ae3a74e8fc265520f6246David Brown 7970d315275d08cd33f801ae3a74e8fc265520f6246David Brown // Also pull the photo out of the current CallerInfo. 7980d315275d08cd33f801ae3a74e8fc265520f6246David Brown // (Note we assume we already have a valid photo at 7990d315275d08cd33f801ae3a74e8fc265520f6246David Brown // this point, since *presumably* the caller-id query 8000d315275d08cd33f801ae3a74e8fc265520f6246David Brown // was already run at some point *before* this call 8010d315275d08cd33f801ae3a74e8fc265520f6246David Brown // got put on hold. If there's no cached photo, just 8020d315275d08cd33f801ae3a74e8fc265520f6246David Brown // fall back to the default "unknown" image.) 8030d315275d08cd33f801ae3a74e8fc265520f6246David Brown if (infoToken.isFinal) { 8040d315275d08cd33f801ae3a74e8fc265520f6246David Brown showCachedImage(mSecondaryCallPhoto, infoToken.currentInfo); 8050d315275d08cd33f801ae3a74e8fc265520f6246David Brown } else { 8060d315275d08cd33f801ae3a74e8fc265520f6246David Brown showImage(mSecondaryCallPhoto, R.drawable.picture_unknown); 8070d315275d08cd33f801ae3a74e8fc265520f6246David Brown } 808b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 809b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 8108da4d90151c882972e15429d4d48bdaa45095d72David Brown showSecondaryCallInfo = true; 811b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 812b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 813b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 8140fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville case ACTIVE: 8150fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // CDMA: This is because in CDMA when the user originates the second call, 8160fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // although the Foreground call state is still ACTIVE in reality the network 8170fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // put the first call on hold. 81879b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink if (mApplication.phone.getPhoneType() == Phone.PHONE_TYPE_CDMA) { 8190fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville List<Connection> connections = call.getConnections(); 8200fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville if (connections.size() > 2) { 8210fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // This means that current Mobile Originated call is the not the first 3-Way 8220fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // call the user is making, which in turn tells the PhoneApp that we no 8230fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // longer know which previous caller/party had dropped out before the user 8240fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // made this call. 8250d315275d08cd33f801ae3a74e8fc265520f6246David Brown mSecondaryCallName.setText( 8260d315275d08cd33f801ae3a74e8fc265520f6246David Brown getContext().getString(R.string.card_title_in_call)); 8270d315275d08cd33f801ae3a74e8fc265520f6246David Brown showImage(mSecondaryCallPhoto, R.drawable.picture_unknown); 8280fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } else { 8290fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // This means that the current Mobile Originated call IS the first 3-Way 8300fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // and hence we display the first callers/party's info here. 8310fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville Connection conn = call.getEarliestConnection(); 832de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman PhoneUtils.CallerInfoToken infoToken = PhoneUtils.startGetCallerInfo( 8330d315275d08cd33f801ae3a74e8fc265520f6246David Brown getContext(), conn, this, mSecondaryCallName); 8340fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 835de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman // Get the compactName to be displayed, but then check that against 836de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman // the number presentation value for the call. If it's not an allowed 837de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman // presentation, then display the appropriate presentation string instead. 838de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman CallerInfo info = infoToken.currentInfo; 8390d315275d08cd33f801ae3a74e8fc265520f6246David Brown 8400d315275d08cd33f801ae3a74e8fc265520f6246David Brown String name = PhoneUtils.getCompactNameFromCallerInfo(info, getContext()); 8410d315275d08cd33f801ae3a74e8fc265520f6246David Brown boolean forceGenericPhoto = false; 842de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman if (info != null && info.numberPresentation != 843de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman Connection.PRESENTATION_ALLOWED) { 844de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman name = getPresentationString(info.numberPresentation); 8450d315275d08cd33f801ae3a74e8fc265520f6246David Brown forceGenericPhoto = true; 8460d315275d08cd33f801ae3a74e8fc265520f6246David Brown } 8470d315275d08cd33f801ae3a74e8fc265520f6246David Brown mSecondaryCallName.setText(name); 8480d315275d08cd33f801ae3a74e8fc265520f6246David Brown 8490d315275d08cd33f801ae3a74e8fc265520f6246David Brown // Also pull the photo out of the current CallerInfo. 8500d315275d08cd33f801ae3a74e8fc265520f6246David Brown // (Note we assume we already have a valid photo at 8510d315275d08cd33f801ae3a74e8fc265520f6246David Brown // this point, since *presumably* the caller-id query 8520d315275d08cd33f801ae3a74e8fc265520f6246David Brown // was already run at some point *before* this call 8530d315275d08cd33f801ae3a74e8fc265520f6246David Brown // got put on hold. If there's no cached photo, just 8540d315275d08cd33f801ae3a74e8fc265520f6246David Brown // fall back to the default "unknown" image.) 8550d315275d08cd33f801ae3a74e8fc265520f6246David Brown if (!forceGenericPhoto && infoToken.isFinal) { 8560d315275d08cd33f801ae3a74e8fc265520f6246David Brown showCachedImage(mSecondaryCallPhoto, info); 8570d315275d08cd33f801ae3a74e8fc265520f6246David Brown } else { 8580d315275d08cd33f801ae3a74e8fc265520f6246David Brown showImage(mSecondaryCallPhoto, R.drawable.picture_unknown); 859de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman } 8600fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 8618da4d90151c882972e15429d4d48bdaa45095d72David Brown showSecondaryCallInfo = true; 8620fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 8630d315275d08cd33f801ae3a74e8fc265520f6246David Brown } else { 8640d315275d08cd33f801ae3a74e8fc265520f6246David Brown // We shouldn't ever get here at all for non-CDMA devices. 8650d315275d08cd33f801ae3a74e8fc265520f6246David Brown Log.w(LOG_TAG, "displayOnHoldCallStatus: ACTIVE state on non-CDMA device"); 8668da4d90151c882972e15429d4d48bdaa45095d72David Brown showSecondaryCallInfo = false; 8670fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 8680fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville break; 8690fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 870b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project default: 871b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // There's actually no call on hold. (Presumably this call's 872b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // state is IDLE, since any other state is meaningless for the 873b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // background call.) 8748da4d90151c882972e15429d4d48bdaa45095d72David Brown showSecondaryCallInfo = false; 875b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 876b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 8778da4d90151c882972e15429d4d48bdaa45095d72David Brown 87872ed1d33448aebfd2dd9198e2d7384091fe2b9f7David Brown // Show or hide the entire "secondary call" info area. 87972ed1d33448aebfd2dd9198e2d7384091fe2b9f7David Brown mSecondaryCallInfo.setVisibility(showSecondaryCallInfo ? View.VISIBLE : View.GONE); 880b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 881b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 882b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private String getCallFailedString(Call call) { 883b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Connection c = call.getEarliestConnection(); 884b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project int resID; 885b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 886b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (c == null) { 887b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("getCallFailedString: connection is null, using default values."); 888b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if this connection is null, just assume that the 889b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // default case occurs. 890b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project resID = R.string.card_title_call_ended; 891b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 892b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 893b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Connection.DisconnectCause cause = c.getDisconnectCause(); 894b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 895b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // TODO: The card *title* should probably be "Call ended" in all 896b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // cases, but if the DisconnectCause was an error condition we should 897b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // probably also display the specific failure reason somewhere... 898b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 899b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project switch (cause) { 900b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case BUSY: 901b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project resID = R.string.callFailed_userBusy; 902b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 903b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 904b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case CONGESTION: 905b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project resID = R.string.callFailed_congestion; 906b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 907b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 9081d0075e4a480a32e26a673c58b94bd706f997620Hung-ying Tyan case TIMED_OUT: 9091d0075e4a480a32e26a673c58b94bd706f997620Hung-ying Tyan resID = R.string.callFailed_timedOut; 9101d0075e4a480a32e26a673c58b94bd706f997620Hung-ying Tyan break; 9111d0075e4a480a32e26a673c58b94bd706f997620Hung-ying Tyan 91268d060b8f52c6c1176d5c55358250b18d14f2b51Hung-ying Tyan case SERVER_UNREACHABLE: 91368d060b8f52c6c1176d5c55358250b18d14f2b51Hung-ying Tyan resID = R.string.callFailed_server_unreachable; 91468d060b8f52c6c1176d5c55358250b18d14f2b51Hung-ying Tyan break; 91568d060b8f52c6c1176d5c55358250b18d14f2b51Hung-ying Tyan 9166c17cfbbf0b1b6fed8c9f32da48a854c20c24af8Hung-ying Tyan case NUMBER_UNREACHABLE: 91768d060b8f52c6c1176d5c55358250b18d14f2b51Hung-ying Tyan resID = R.string.callFailed_number_unreachable; 9186c17cfbbf0b1b6fed8c9f32da48a854c20c24af8Hung-ying Tyan break; 9196c17cfbbf0b1b6fed8c9f32da48a854c20c24af8Hung-ying Tyan 9203a635c7dd2f3283f6a1bde0e9370977c4685882fHung-ying Tyan case INVALID_CREDENTIALS: 9213a635c7dd2f3283f6a1bde0e9370977c4685882fHung-ying Tyan resID = R.string.callFailed_invalid_credentials; 9223a635c7dd2f3283f6a1bde0e9370977c4685882fHung-ying Tyan break; 9233a635c7dd2f3283f6a1bde0e9370977c4685882fHung-ying Tyan 924a32036470be1cff3ce604c0dd83f0609243c6100Hung-ying Tyan case SERVER_ERROR: 925a32036470be1cff3ce604c0dd83f0609243c6100Hung-ying Tyan resID = R.string.callFailed_server_error; 926a32036470be1cff3ce604c0dd83f0609243c6100Hung-ying Tyan break; 927a32036470be1cff3ce604c0dd83f0609243c6100Hung-ying Tyan 9283a635c7dd2f3283f6a1bde0e9370977c4685882fHung-ying Tyan case OUT_OF_NETWORK: 9293a635c7dd2f3283f6a1bde0e9370977c4685882fHung-ying Tyan resID = R.string.callFailed_out_of_network; 9303a635c7dd2f3283f6a1bde0e9370977c4685882fHung-ying Tyan break; 9313a635c7dd2f3283f6a1bde0e9370977c4685882fHung-ying Tyan 932b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case LOST_SIGNAL: 9333800ac871d6548790ac6119bb68b9be0640af261David Krause case CDMA_DROP: 934b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project resID = R.string.callFailed_noSignal; 935b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 936b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 937b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case LIMIT_EXCEEDED: 938b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project resID = R.string.callFailed_limitExceeded; 939b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 940b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 941b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case POWER_OFF: 942b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project resID = R.string.callFailed_powerOff; 943b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 944b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 945a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville case ICC_ERROR: 946b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project resID = R.string.callFailed_simError; 947b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 948b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 949b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case OUT_OF_SERVICE: 950b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project resID = R.string.callFailed_outOfService; 951b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 952b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 95322e353c3d76a3dd649c6e87244c5d94cadf64c8eHung-ying Tyan case INVALID_NUMBER: 9549eb2ffdf7b4752c7199eba6a3b88f63edc4a0ac8Naveen Kalla case UNOBTAINABLE_NUMBER: 9559eb2ffdf7b4752c7199eba6a3b88f63edc4a0ac8Naveen Kalla resID = R.string.callFailed_unobtainable_number; 9569eb2ffdf7b4752c7199eba6a3b88f63edc4a0ac8Naveen Kalla break; 9579eb2ffdf7b4752c7199eba6a3b88f63edc4a0ac8Naveen Kalla 958b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project default: 959b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project resID = R.string.card_title_call_ended; 960b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 961b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 962b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 963b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return getContext().getString(resID); 964b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 965b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 966b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 967b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Updates the name / photo / number / label fields on the CallCard 968b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * based on the specified CallerInfo. 969b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 970b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * If the current call is a conference call, use 971b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * updateDisplayForConference() instead. 972b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 973b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void updateDisplayForPerson(CallerInfo info, 9744b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project int presentation, 975b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project boolean isTemporary, 9765a4bc9222fc865b17e82c450fd878e9ee18bd643David Brown Call call, 9775a4bc9222fc865b17e82c450fd878e9ee18bd643David Brown Connection conn) { 978a1c2398ade0e01d0bcfe23212bdaa18e4c19a1e5Nicolas Catania if (DBG) log("updateDisplayForPerson(" + info + ")\npresentation:" + 979a1c2398ade0e01d0bcfe23212bdaa18e4c19a1e5Nicolas Catania presentation + " isTemporary:" + isTemporary); 980b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 981b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // inform the state machine that we are displaying a photo. 982b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhotoTracker.setPhotoRequest(info); 983b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhotoTracker.setPhotoState(ContactsAsyncHelper.ImageTracker.DISPLAY_IMAGE); 984b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 985592fb0a9a5b079f168096907bd50822f94c69448David Brown // The actual strings we're going to display onscreen: 986592fb0a9a5b079f168096907bd50822f94c69448David Brown String displayName; 987b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project String displayNumber = null; 988b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project String label = null; 989b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Uri personUri = null; 99029d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown String socialStatusText = null; 99129d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown Drawable socialStatusBadge = null; 992b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 993b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (info != null) { 994b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // It appears that there is a small change in behaviour with the 995b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // PhoneUtils' startGetCallerInfo whereby if we query with an 996b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // empty number, we will get a valid CallerInfo object, but with 997b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // fields that are all null, and the isTemporary boolean input 998b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // parameter as true. 999b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1000b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // In the past, we would see a NULL callerinfo object, but this 1001b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // ends up causing null pointer exceptions elsewhere down the 1002b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // line in other cases, so we need to make this fix instead. It 1003b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // appears that this was the ONLY call to PhoneUtils 1004b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // .getCallerInfo() that relied on a NULL CallerInfo to indicate 1005b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // an unknown contact. 1006b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1007592fb0a9a5b079f168096907bd50822f94c69448David Brown // Currently, info.phoneNumber may actually be a SIP address, and 1008592fb0a9a5b079f168096907bd50822f94c69448David Brown // if so, it might sometimes include the "sip:" prefix. That 1009592fb0a9a5b079f168096907bd50822f94c69448David Brown // prefix isn't really useful to the user, though, so strip it off 1010592fb0a9a5b079f168096907bd50822f94c69448David Brown // if present. (For any other URI scheme, though, leave the 1011592fb0a9a5b079f168096907bd50822f94c69448David Brown // prefix alone.) 1012592fb0a9a5b079f168096907bd50822f94c69448David Brown // TODO: It would be cleaner for CallerInfo to explicitly support 1013592fb0a9a5b079f168096907bd50822f94c69448David Brown // SIP addresses instead of overloading the "phoneNumber" field. 1014592fb0a9a5b079f168096907bd50822f94c69448David Brown // Then we could remove this hack, and instead ask the CallerInfo 1015592fb0a9a5b079f168096907bd50822f94c69448David Brown // for a "user visible" form of the SIP address. 1016592fb0a9a5b079f168096907bd50822f94c69448David Brown String number = info.phoneNumber; 10179ec000a412524ed98d486ca4b160dd1e885db574David Brown if ((number != null) && number.startsWith("sip:")) { 1018592fb0a9a5b079f168096907bd50822f94c69448David Brown number = number.substring(4); 1019592fb0a9a5b079f168096907bd50822f94c69448David Brown } 1020592fb0a9a5b079f168096907bd50822f94c69448David Brown 1021b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (TextUtils.isEmpty(info.name)) { 1022592fb0a9a5b079f168096907bd50822f94c69448David Brown // No valid "name" in the CallerInfo, so fall back to 1023592fb0a9a5b079f168096907bd50822f94c69448David Brown // something else. 1024a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown // (Typically, we promote the phone number up to the "name" slot 1025a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown // onscreen, and possibly display a descriptive string in the 1026a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown // "number" slot.) 1027592fb0a9a5b079f168096907bd50822f94c69448David Brown if (TextUtils.isEmpty(number)) { 1028a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown // No name *or* number! Display a generic "unknown" string 1029a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown // (or potentially some other default based on the presentation.) 1030592fb0a9a5b079f168096907bd50822f94c69448David Brown displayName = getPresentationString(presentation); 1031a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown if (DBG) log(" ==> no name *or* number! displayName = " + displayName); 1032e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai } else if (presentation != Connection.PRESENTATION_ALLOWED) { 1033e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai // This case should never happen since the network should never send a phone # 1034e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai // AND a restricted presentation. However we leave it here in case of weird 1035e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai // network behavior 1036592fb0a9a5b079f168096907bd50822f94c69448David Brown displayName = getPresentationString(presentation); 1037a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown if (DBG) log(" ==> presentation not allowed! displayName = " + displayName); 1038e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai } else if (!TextUtils.isEmpty(info.cnapName)) { 1039a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown // No name, but we do have a valid CNAP name, so use that. 1040592fb0a9a5b079f168096907bd50822f94c69448David Brown displayName = info.cnapName; 1041e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai info.name = info.cnapName; 1042592fb0a9a5b079f168096907bd50822f94c69448David Brown displayNumber = number; 1043a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown if (DBG) log(" ==> cnapName available: displayName '" 1044a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown + displayName + "', displayNumber '" + displayNumber + "'"); 1045b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 1046a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown // No name; all we have is a number. This is the typical 10475a4bc9222fc865b17e82c450fd878e9ee18bd643David Brown // case when an incoming call doesn't match any contact, 10485a4bc9222fc865b17e82c450fd878e9ee18bd643David Brown // or if you manually dial an outgoing number using the 10495a4bc9222fc865b17e82c450fd878e9ee18bd643David Brown // dialpad. 1050a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown 10515a4bc9222fc865b17e82c450fd878e9ee18bd643David Brown // Promote the phone number up to the "name" slot: 1052592fb0a9a5b079f168096907bd50822f94c69448David Brown displayName = number; 10535a4bc9222fc865b17e82c450fd878e9ee18bd643David Brown 10545a4bc9222fc865b17e82c450fd878e9ee18bd643David Brown // ...and use the "number" slot for a geographical description 10555a4bc9222fc865b17e82c450fd878e9ee18bd643David Brown // string if available (but only for incoming calls.) 10565a4bc9222fc865b17e82c450fd878e9ee18bd643David Brown if ((conn != null) && (conn.isIncoming())) { 10575a4bc9222fc865b17e82c450fd878e9ee18bd643David Brown // TODO (CallerInfoAsyncQuery cleanup): Fix the CallerInfo 10585a4bc9222fc865b17e82c450fd878e9ee18bd643David Brown // query to only do the geoDescription lookup in the first 10595a4bc9222fc865b17e82c450fd878e9ee18bd643David Brown // place for incoming calls. 10605a4bc9222fc865b17e82c450fd878e9ee18bd643David Brown displayNumber = info.geoDescription; // may be null 10615a4bc9222fc865b17e82c450fd878e9ee18bd643David Brown } 10625a4bc9222fc865b17e82c450fd878e9ee18bd643David Brown 1063a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown if (DBG) log(" ==> no name; falling back to number: displayName '" 1064a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown + displayName + "', displayNumber '" + displayNumber + "'"); 1065b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1066b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 1067592fb0a9a5b079f168096907bd50822f94c69448David Brown // We do have a valid "name" in the CallerInfo. Display that 1068592fb0a9a5b079f168096907bd50822f94c69448David Brown // in the "name" slot, and the phone number in the "number" slot. 1069e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai if (presentation != Connection.PRESENTATION_ALLOWED) { 1070e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai // This case should never happen since the network should never send a name 1071e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai // AND a restricted presentation. However we leave it here in case of weird 1072e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai // network behavior 1073592fb0a9a5b079f168096907bd50822f94c69448David Brown displayName = getPresentationString(presentation); 1074a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown if (DBG) log(" ==> valid name, but presentation not allowed!" 1075a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown + " displayName = " + displayName); 1076e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai } else { 1077592fb0a9a5b079f168096907bd50822f94c69448David Brown displayName = info.name; 1078592fb0a9a5b079f168096907bd50822f94c69448David Brown displayNumber = number; 1079e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai label = info.phoneLabel; 1080a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown if (DBG) log(" ==> name is present in CallerInfo: displayName '" 1081a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown + displayName + "', displayNumber '" + displayNumber + "'"); 1082e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai } 1083b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 10843d6d70562622660e581b53308e675386d299dd19Dmitri Plotnikov personUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, info.person_id); 108502d1c632adde606031c1fe6ea0e3be1e288fd6c6David Brown if (DBG) log("- got personUri: '" + personUri 108602d1c632adde606031c1fe6ea0e3be1e288fd6c6David Brown + "', based on info.person_id: " + info.person_id); 1087b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 1088592fb0a9a5b079f168096907bd50822f94c69448David Brown displayName = getPresentationString(presentation); 1089b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 10900fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 10910fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville if (call.isGeneric()) { 10920fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville mName.setText(R.string.card_title_in_call); 10930fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } else { 1094592fb0a9a5b079f168096907bd50822f94c69448David Brown mName.setText(displayName); 10950fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 1096b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mName.setVisibility(View.VISIBLE); 1097b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1098b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Update mPhoto 1099b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if the temporary flag is set, we know we'll be getting another call after 1100b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // the CallerInfo has been correctly updated. So, we can skip the image 1101b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // loading until then. 1102b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1103b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // If the photoResource is filled in for the CallerInfo, (like with the 1104b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Emergency Number case), then we can just set the photo image without 1105b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // requesting for an image load. Please refer to CallerInfoAsyncQuery.java 1106b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // for cases where CallerInfo.photoResource may be set. We can also avoid 1107b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // the image load step if the image data is cached. 1108b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (isTemporary && (info == null || !info.isCachedPhotoCurrent)) { 1109b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhoto.setVisibility(View.INVISIBLE); 1110b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else if (info != null && info.photoResource != 0){ 1111b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project showImage(mPhoto, info.photoResource); 1112b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else if (!showCachedImage(mPhoto, info)) { 1113b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Load the image with a callback to update the image state. 1114a1c2398ade0e01d0bcfe23212bdaa18e4c19a1e5Nicolas Catania // Use the default unknown picture while the query is running. 1115a1c2398ade0e01d0bcfe23212bdaa18e4c19a1e5Nicolas Catania ContactsAsyncHelper.updateImageViewWithContactPhotoAsync( 1116a1c2398ade0e01d0bcfe23212bdaa18e4c19a1e5Nicolas Catania info, 0, this, call, getContext(), mPhoto, personUri, R.drawable.picture_unknown); 1117b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 11186d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown 11190fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville if (displayNumber != null && !call.isGeneric()) { 1120b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhoneNumber.setText(displayNumber); 1121b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhoneNumber.setVisibility(View.VISIBLE); 1122b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 1123b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhoneNumber.setVisibility(View.GONE); 1124b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1125b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1126153e79d8d413b1ccd4abf55a8dbe4e266aa92799Paul Berman if (label != null && !call.isGeneric()) { 1127b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mLabel.setText(label); 1128b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mLabel.setVisibility(View.VISIBLE); 1129b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 1130b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mLabel.setVisibility(View.GONE); 1131b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1132b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 11339d14e16e8214b4a396dad293b6f0941608ee4798David Brown // Other text fields: 11349d14e16e8214b4a396dad293b6f0941608ee4798David Brown updateCallTypeLabel(call); 11359d14e16e8214b4a396dad293b6f0941608ee4798David Brown updateSocialStatus(socialStatusText, socialStatusBadge, call); // Currently unused 113629d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown } 1137b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 11384b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project private String getPresentationString(int presentation) { 11394b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project String name = getContext().getString(R.string.unknown); 11404b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project if (presentation == Connection.PRESENTATION_RESTRICTED) { 11414b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project name = getContext().getString(R.string.private_num); 11424b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project } else if (presentation == Connection.PRESENTATION_PAYPHONE) { 11434b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project name = getContext().getString(R.string.payphone); 11444b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project } 11454b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project return name; 11464b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project } 11474b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project 1148b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 1149b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Updates the name / photo / number / label fields 1150b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * for the special "conference call" state. 1151b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 1152b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * If the current call has only a single connection, use 1153b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * updateDisplayForPerson() instead. 1154b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 1155872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan private void updateDisplayForConference(Call call) { 1156b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("updateDisplayForConference()..."); 1157b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1158872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan int phoneType = call.getPhone().getPhoneType(); 115979b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink if (phoneType == Phone.PHONE_TYPE_CDMA) { 11600fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // This state corresponds to both 3-Way merged call and 11610fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // Call Waiting accepted call. 116229d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown // In this case we display the UI in a "generic" state, with 116329d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown // the generic "dialing" icon and no caller information, 116429d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown // because in this state in CDMA the user does not really know 116529d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown // which caller party he is talking to. 11660fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville showImage(mPhoto, R.drawable.picture_dialing); 11670fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville mName.setText(R.string.card_title_in_call); 1168872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan } else if ((phoneType == Phone.PHONE_TYPE_GSM) 1169872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan || (phoneType == Phone.PHONE_TYPE_SIP)) { 1170507ee75639e41c17edd410ef787e0617778071aaDavid Brown // Normal GSM (or possibly SIP?) conference call. 1171507ee75639e41c17edd410ef787e0617778071aaDavid Brown // Display the "conference call" image as the contact photo. 1172507ee75639e41c17edd410ef787e0617778071aaDavid Brown // TODO: Better visual treatment for contact photos in a 1173507ee75639e41c17edd410ef787e0617778071aaDavid Brown // conference call (see bug 1313252). 1174507ee75639e41c17edd410ef787e0617778071aaDavid Brown showImage(mPhoto, R.drawable.picture_conference); 11750fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville mName.setText(R.string.card_title_conf_call); 117679b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink } else { 117779b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink throw new IllegalStateException("Unexpected phone type: " + phoneType); 11780fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 1179b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1180b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mName.setVisibility(View.VISIBLE); 1181b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1182b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // TODO: For a conference call, the "phone number" slot is specced 1183b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // to contain a summary of who's on the call, like "Bill Foldes 1184b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // and Hazel Nutt" or "Bill Foldes and 2 others". 1185b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // But for now, just hide it: 1186b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhoneNumber.setVisibility(View.GONE); 1187b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mLabel.setVisibility(View.GONE); 1188b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 11899d14e16e8214b4a396dad293b6f0941608ee4798David Brown // Other text fields: 11909d14e16e8214b4a396dad293b6f0941608ee4798David Brown updateCallTypeLabel(call); 11919d14e16e8214b4a396dad293b6f0941608ee4798David Brown updateSocialStatus(null, null, null); // socialStatus is never visible in this state 119229d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown 119329d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown // TODO: for a GSM conference call, since we do actually know who 119429d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown // you're talking to, consider also showing names / numbers / 119529d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown // photos of some of the people on the conference here, so you can 119629d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown // see that info without having to click "Manage conference". We 119729d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown // probably have enough space to show info for 2 people, at least. 1198b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // 1199b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // To do this, our caller would pass us the activeConnections 1200b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // list, and we'd call PhoneUtils.getCallerInfo() separately for 1201b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // each connection. 1202b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1203b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1204b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 1205b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Updates the CallCard "photo" IFF the specified Call is in a state 1206b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * that needs a special photo (like "busy" or "dialing".) 1207b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 1208b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * If the current call does not require a special image in the "photo" 1209b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * slot onscreen, don't do anything, since presumably the photo image 1210b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * has already been set (to the photo of the person we're talking, or 1211b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * the generic "picture_unknown" image, or the "conference call" 1212b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * image.) 1213b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 1214b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void updatePhotoForCallState(Call call) { 1215b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("updatePhotoForCallState(" + call + ")..."); 1216b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project int photoImageResource = 0; 1217b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1218b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Check for the (relatively few) telephony states that need a 1219b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // special image in the "photo" slot. 1220b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Call.State state = call.getState(); 1221b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project switch (state) { 1222b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case DISCONNECTED: 1223b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Display the special "busy" photo for BUSY or CONGESTION. 1224b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Otherwise (presumably the normal "call ended" state) 1225b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // leave the photo alone. 1226b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Connection c = call.getEarliestConnection(); 1227b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if the connection is null, we assume the default case, 1228b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // otherwise update the image resource normally. 1229b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (c != null) { 1230b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Connection.DisconnectCause cause = c.getDisconnectCause(); 1231b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if ((cause == Connection.DisconnectCause.BUSY) 1232b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project || (cause == Connection.DisconnectCause.CONGESTION)) { 1233b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project photoImageResource = R.drawable.picture_busy; 1234b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1235b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else if (DBG) { 1236b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project log("updatePhotoForCallState: connection is null, ignoring."); 1237b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1238b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1239b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // TODO: add special images for any other DisconnectCauses? 1240b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 1241b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1242b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case ALERTING: 124344e42e4eccd8ecdcdcca166c9f6f35a4d6c65591Nicolas Catania case DIALING: 1244b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project default: 1245b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Leave the photo alone in all other states. 1246b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // If this call is an individual call, and the image is currently 1247b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // displaying a state, (rather than a photo), we'll need to update 1248b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // the image. 1249b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // This is for the case where we've been displaying the state and 1250b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // now we need to restore the photo. This can happen because we 1251b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // only query the CallerInfo once, and limit the number of times 1252b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // the image is loaded. (So a state image may overwrite the photo 1253b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // and we would otherwise have no way of displaying the photo when 1254b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // the state goes away.) 1255b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1256b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if the photoResource field is filled-in in the Connection's 1257b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // caller info, then we can just use that instead of requesting 1258b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // for a photo load. 1259b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1260b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // look for the photoResource if it is available. 1261b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project CallerInfo ci = null; 1262b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project { 12630fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville Connection conn = null; 1264872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan int phoneType = call.getPhone().getPhoneType(); 126579b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink if (phoneType == Phone.PHONE_TYPE_CDMA) { 12660fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville conn = call.getLatestConnection(); 1267872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan } else if ((phoneType == Phone.PHONE_TYPE_GSM) 1268872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan || (phoneType == Phone.PHONE_TYPE_SIP)) { 12690fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville conn = call.getEarliestConnection(); 127079b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink } else { 127179b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink throw new IllegalStateException("Unexpected phone type: " + phoneType); 12720fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 12730fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 1274b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (conn != null) { 1275b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Object o = conn.getUserData(); 1276b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (o instanceof CallerInfo) { 1277b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project ci = (CallerInfo) o; 1278b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else if (o instanceof PhoneUtils.CallerInfoToken) { 1279b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project ci = ((PhoneUtils.CallerInfoToken) o).currentInfo; 1280b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1281b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1282b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1283b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1284b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (ci != null) { 1285b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project photoImageResource = ci.photoResource; 1286b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1287b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1288b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // If no photoResource found, check to see if this is a conference call. If 1289b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // it is not a conference call: 1290b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // 1. Try to show the cached image 1291b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // 2. If the image is not cached, check to see if a load request has been 1292b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // made already. 1293b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // 3. If the load request has not been made [DISPLAY_DEFAULT], start the 1294b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // request and note that it has started by updating photo state with 1295b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // [DISPLAY_IMAGE]. 1296b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Load requests started in (3) use a placeholder image of -1 to hide the 1297b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // image by default. Please refer to CallerInfoAsyncQuery.java for cases 1298b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // where CallerInfo.photoResource may be set. 1299b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (photoImageResource == 0) { 1300b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (!PhoneUtils.isConferenceCall(call)) { 1301b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (!showCachedImage(mPhoto, ci) && (mPhotoTracker.getPhotoState() == 1302b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project ContactsAsyncHelper.ImageTracker.DISPLAY_DEFAULT)) { 1303b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project ContactsAsyncHelper.updateImageViewWithContactPhotoAsync(ci, 1304b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project getContext(), mPhoto, mPhotoTracker.getPhotoUri(), -1); 1305b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhotoTracker.setPhotoState( 1306b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project ContactsAsyncHelper.ImageTracker.DISPLAY_IMAGE); 1307b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1308b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1309b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 1310b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project showImage(mPhoto, photoImageResource); 1311b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhotoTracker.setPhotoState(ContactsAsyncHelper.ImageTracker.DISPLAY_IMAGE); 1312b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return; 1313b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1314b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 1315b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1316b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1317b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (photoImageResource != 0) { 1318b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("- overrriding photo image: " + photoImageResource); 1319b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project showImage(mPhoto, photoImageResource); 1320b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Track the image state. 1321b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhotoTracker.setPhotoState(ContactsAsyncHelper.ImageTracker.DISPLAY_DEFAULT); 1322b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1323b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1324b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1325b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 1326b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Try to display the cached image from the callerinfo object. 1327b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 1328b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * @return true if we were able to find the image in the cache, false otherwise. 1329b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 13300d315275d08cd33f801ae3a74e8fc265520f6246David Brown private static final boolean showCachedImage(ImageView view, CallerInfo ci) { 1331b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if ((ci != null) && ci.isCachedPhotoCurrent) { 1332b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (ci.cachedPhoto != null) { 1333b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project showImage(view, ci.cachedPhoto); 1334b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 1335b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project showImage(view, R.drawable.picture_unknown); 1336b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1337b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return true; 1338b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1339b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return false; 1340b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1341b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1342b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** Helper function to display the resource in the imageview AND ensure its visibility.*/ 1343b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private static final void showImage(ImageView view, int resource) { 1344b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project view.setImageResource(resource); 1345b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project view.setVisibility(View.VISIBLE); 1346b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1347b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1348b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** Helper function to display the drawable in the imageview AND ensure its visibility.*/ 1349b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private static final void showImage(ImageView view, Drawable drawable) { 1350b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project view.setImageDrawable(drawable); 1351b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project view.setVisibility(View.VISIBLE); 1352b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1353b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1354b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 1355b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Sets the left and right margins of the specified ViewGroup (whose 1356b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * LayoutParams object which must inherit from 1357b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * ViewGroup.MarginLayoutParams.) 1358b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 1359b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * TODO: Is there already a convenience method like this somewhere? 1360b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 1361b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void setSideMargins(ViewGroup vg, int margin) { 1362b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project ViewGroup.MarginLayoutParams lp = 1363b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project (ViewGroup.MarginLayoutParams) vg.getLayoutParams(); 1364b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Equivalent to setting android:layout_marginLeft/Right in XML 1365b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project lp.leftMargin = margin; 1366b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project lp.rightMargin = margin; 1367b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project vg.setLayoutParams(lp); 1368b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1369b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 13708bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project /** 1371f3602b0659d01fef19159e7111be76102549f7a1David Brown * Returns the special card title used in emergency callback mode (ECM), 1372f3602b0659d01fef19159e7111be76102549f7a1David Brown * which shows your own phone number. 1373f3602b0659d01fef19159e7111be76102549f7a1David Brown */ 1374f3602b0659d01fef19159e7111be76102549f7a1David Brown private String getECMCardTitle(Context context, Phone phone) { 1375f3602b0659d01fef19159e7111be76102549f7a1David Brown String rawNumber = phone.getLine1Number(); // may be null or empty 1376f3602b0659d01fef19159e7111be76102549f7a1David Brown String formattedNumber; 1377f3602b0659d01fef19159e7111be76102549f7a1David Brown if (!TextUtils.isEmpty(rawNumber)) { 1378f3602b0659d01fef19159e7111be76102549f7a1David Brown formattedNumber = PhoneNumberUtils.formatNumber(rawNumber); 1379f3602b0659d01fef19159e7111be76102549f7a1David Brown } else { 1380f3602b0659d01fef19159e7111be76102549f7a1David Brown formattedNumber = context.getString(R.string.unknown); 1381f3602b0659d01fef19159e7111be76102549f7a1David Brown } 1382f3602b0659d01fef19159e7111be76102549f7a1David Brown String titleFormat = context.getString(R.string.card_title_my_phone_number); 1383f3602b0659d01fef19159e7111be76102549f7a1David Brown return String.format(titleFormat, formattedNumber); 1384f3602b0659d01fef19159e7111be76102549f7a1David Brown } 1385f3602b0659d01fef19159e7111be76102549f7a1David Brown 1386f3602b0659d01fef19159e7111be76102549f7a1David Brown /** 13879d14e16e8214b4a396dad293b6f0941608ee4798David Brown * Updates the "Call type" label, based on the current foreground call. 13889d14e16e8214b4a396dad293b6f0941608ee4798David Brown * This is a special label and/or branding we display for certain 13899d14e16e8214b4a396dad293b6f0941608ee4798David Brown * kinds of calls. 13909d14e16e8214b4a396dad293b6f0941608ee4798David Brown * 13919d14e16e8214b4a396dad293b6f0941608ee4798David Brown * (So far, this is used only for SIP calls, which get an 13929d14e16e8214b4a396dad293b6f0941608ee4798David Brown * "Internet call" label. TODO: But eventually, the telephony 13939d14e16e8214b4a396dad293b6f0941608ee4798David Brown * layer might allow each pluggable "provider" to specify a string 13949d14e16e8214b4a396dad293b6f0941608ee4798David Brown * and/or icon to be displayed here.) 13959d14e16e8214b4a396dad293b6f0941608ee4798David Brown */ 13969d14e16e8214b4a396dad293b6f0941608ee4798David Brown private void updateCallTypeLabel(Call call) { 13979d14e16e8214b4a396dad293b6f0941608ee4798David Brown int phoneType = (call != null) ? call.getPhone().getPhoneType() : Phone.PHONE_TYPE_NONE; 13989d14e16e8214b4a396dad293b6f0941608ee4798David Brown if (phoneType == Phone.PHONE_TYPE_SIP) { 13999d14e16e8214b4a396dad293b6f0941608ee4798David Brown mCallTypeLabel.setVisibility(View.VISIBLE); 14009d14e16e8214b4a396dad293b6f0941608ee4798David Brown mCallTypeLabel.setText(R.string.incall_call_type_label_sip); 14019d14e16e8214b4a396dad293b6f0941608ee4798David Brown mCallTypeLabel.setTextColor(mTextColorCallTypeSip); 14029d14e16e8214b4a396dad293b6f0941608ee4798David Brown // If desired, we could also display a "badge" next to the label, as follows: 14039d14e16e8214b4a396dad293b6f0941608ee4798David Brown // mCallTypeLabel.setCompoundDrawablesWithIntrinsicBounds( 14049d14e16e8214b4a396dad293b6f0941608ee4798David Brown // callTypeSpecificBadge, null, null, null); 14059d14e16e8214b4a396dad293b6f0941608ee4798David Brown // mCallTypeLabel.setCompoundDrawablePadding((int) (mDensity * 6)); 14069d14e16e8214b4a396dad293b6f0941608ee4798David Brown } else { 14079d14e16e8214b4a396dad293b6f0941608ee4798David Brown mCallTypeLabel.setVisibility(View.GONE); 14089d14e16e8214b4a396dad293b6f0941608ee4798David Brown } 14099d14e16e8214b4a396dad293b6f0941608ee4798David Brown } 14109d14e16e8214b4a396dad293b6f0941608ee4798David Brown 14119d14e16e8214b4a396dad293b6f0941608ee4798David Brown /** 14129d14e16e8214b4a396dad293b6f0941608ee4798David Brown * Updates the "social status" label with the specified text and 14139d14e16e8214b4a396dad293b6f0941608ee4798David Brown * (optional) badge. 14149d14e16e8214b4a396dad293b6f0941608ee4798David Brown */ 14159d14e16e8214b4a396dad293b6f0941608ee4798David Brown private void updateSocialStatus(String socialStatusText, 14169d14e16e8214b4a396dad293b6f0941608ee4798David Brown Drawable socialStatusBadge, 14179d14e16e8214b4a396dad293b6f0941608ee4798David Brown Call call) { 14189d14e16e8214b4a396dad293b6f0941608ee4798David Brown // The socialStatus field is *only* visible while an incoming call 14199d14e16e8214b4a396dad293b6f0941608ee4798David Brown // is ringing, never in any other call state. 14209d14e16e8214b4a396dad293b6f0941608ee4798David Brown if ((socialStatusText != null) 14219d14e16e8214b4a396dad293b6f0941608ee4798David Brown && (call != null) 14229d14e16e8214b4a396dad293b6f0941608ee4798David Brown && call.isRinging() 14239d14e16e8214b4a396dad293b6f0941608ee4798David Brown && !call.isGeneric()) { 14249d14e16e8214b4a396dad293b6f0941608ee4798David Brown mSocialStatus.setVisibility(View.VISIBLE); 14259d14e16e8214b4a396dad293b6f0941608ee4798David Brown mSocialStatus.setText(socialStatusText); 14269d14e16e8214b4a396dad293b6f0941608ee4798David Brown mSocialStatus.setCompoundDrawablesWithIntrinsicBounds( 14279d14e16e8214b4a396dad293b6f0941608ee4798David Brown socialStatusBadge, null, null, null); 14289d14e16e8214b4a396dad293b6f0941608ee4798David Brown mSocialStatus.setCompoundDrawablePadding((int) (mDensity * 6)); 14299d14e16e8214b4a396dad293b6f0941608ee4798David Brown } else { 14309d14e16e8214b4a396dad293b6f0941608ee4798David Brown mSocialStatus.setVisibility(View.GONE); 14319d14e16e8214b4a396dad293b6f0941608ee4798David Brown } 14329d14e16e8214b4a396dad293b6f0941608ee4798David Brown } 14339d14e16e8214b4a396dad293b6f0941608ee4798David Brown 14349d14e16e8214b4a396dad293b6f0941608ee4798David Brown /** 1435af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * Hides the top-level UI elements of the call card: The "main 1436af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * call card" element representing the current active or ringing call, 1437af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * and also the info areas for "ongoing" or "on hold" calls in some 1438af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * states. 1439af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * 1440af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * This is intended to be used in special states where the normal 1441af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * in-call UI is totally replaced by some other UI, like OTA mode on a 1442af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * CDMA device. 1443af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * 1444af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * To bring back the regular CallCard UI, just re-run the normal 1445af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * updateState() call sequence. 1446af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville */ 1447af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville public void hideCallCardElements() { 14480d315275d08cd33f801ae3a74e8fc265520f6246David Brown mPrimaryCallInfo.setVisibility(View.GONE); 14490d315275d08cd33f801ae3a74e8fc265520f6246David Brown mSecondaryCallInfo.setVisibility(View.GONE); 1450af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville } 1451b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 14529688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown /* 14539688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown * Updates the hint (like "Rotate to answer") that we display while 14549688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown * the user is dragging the incoming call RotarySelector widget. 14559688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown */ 1456ea505da2d0ebae37b07fece15297b5432fe96c5dJim Miller /* package */ void setIncomingCallWidgetHint(int hintTextResId, int hintColorResId) { 1457ea505da2d0ebae37b07fece15297b5432fe96c5dJim Miller mIncomingCallWidgetHintTextResId = hintTextResId; 1458ea505da2d0ebae37b07fece15297b5432fe96c5dJim Miller mIncomingCallWidgetHintColorResId = hintColorResId; 14599688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown } 14609688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown 1461dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown // Accessibility event support. 1462dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown // Since none of the CallCard elements are focusable, we need to manually 1463dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown // fill in the AccessibilityEvent here (so that the name / number / etc will 1464dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown // get pronounced by a screen reader, for example.) 1465dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown @Override 1466dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { 146730c2867bb3341e2b10cb95359e7c5b3b1dc0a6e0David Brown dispatchPopulateAccessibilityEvent(event, mCallStateLabel); 1468dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown dispatchPopulateAccessibilityEvent(event, mPhoto); 1469dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown dispatchPopulateAccessibilityEvent(event, mName); 1470dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown dispatchPopulateAccessibilityEvent(event, mPhoneNumber); 1471dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown dispatchPopulateAccessibilityEvent(event, mLabel); 1472dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown dispatchPopulateAccessibilityEvent(event, mSocialStatus); 1473dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown dispatchPopulateAccessibilityEvent(event, mSecondaryCallName); 1474dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown dispatchPopulateAccessibilityEvent(event, mSecondaryCallStatus); 1475dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown dispatchPopulateAccessibilityEvent(event, mSecondaryCallPhoto); 1476dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown return true; 1477dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown } 1478dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown 1479dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown private void dispatchPopulateAccessibilityEvent(AccessibilityEvent event, View view) { 1480dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown List<CharSequence> eventText = event.getText(); 1481dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown int size = eventText.size(); 1482dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown view.dispatchPopulateAccessibilityEvent(event); 1483dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown // if no text added write null to keep relative position 1484dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown if (size == eventText.size()) { 1485dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown eventText.add(null); 1486dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown } 1487dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown } 1488dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown 14895cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown /** 14905cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown * Simple Utility class that runs fading animations on specified views. 14915cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown */ 14925cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown public static class Fade { 14935cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown private static final boolean FADE_DBG = false; 14945cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown private static final long DURATION = 250; // msec 14955cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown 14965cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown // View tag that's set during the fade-out animation; see hide() and 14975cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown // isFadingOut(). 14985cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown private static final int FADE_STATE_KEY = R.id.fadeState; 14995cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown private static final String FADING_OUT = "fading_out"; 15005cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown 15015cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown /** 15025cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown * Sets the visibility of the specified view to View.VISIBLE and then 15035cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown * fades it in. If the view is already visible (and not in the middle 15045cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown * of a fade-out animation), this method will return without doing 15055cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown * anything. 15065cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown * 15075cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown * @param view The view to be faded in 15085cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown */ 15095cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown public static void show(final View view) { 15105cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown if (FADE_DBG) log("Fade: SHOW view " + view + "..."); 15115cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown if (FADE_DBG) log("Fade: - visibility = " + view.getVisibility()); 15125cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown if ((view.getVisibility() != View.VISIBLE) || isFadingOut(view)) { 15135cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown view.animate().cancel(); 15145cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown // ...and clear the FADE_STATE_KEY tag in case we just 15155cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown // canceled an in-progress fade-out animation. 15165cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown view.setTag(FADE_STATE_KEY, null); 15175cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown 15185cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown view.setAlpha(0); 15195cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown view.setVisibility(View.VISIBLE); 15205cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown view.animate().setDuration(DURATION); 15215cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown view.animate().alpha(1); 15225cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown if (FADE_DBG) log("Fade: ==> SHOW " + view 15235cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown + " DONE. Set visibility = " + View.VISIBLE); 15245cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown } else { 15255cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown if (FADE_DBG) log("Fade: ==> Ignoring, already visible AND not fading out."); 15265cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown } 15275cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown } 15285cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown 15295cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown /** 15305cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown * Fades out the specified view and then sets its visibility to the 15315cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown * specified value (either View.INVISIBLE or View.GONE). If the view 15325cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown * is not currently visibile, the method will return without doing 15335cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown * anything. 15345cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown * 15355cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown * Note that *during* the fade-out the view itself will still have 15365cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown * visibility View.VISIBLE, although the isFadingOut() method will 15375cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown * return true (in case the UI code needs to detect this state.) 15385cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown * 15395cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown * @param view The view to be hidden 15405cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown * @param visibility The value to which the view's visibility will be 15415cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown * set after it fades out. 15425cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown * Must be either View.VISIBLE or View.INVISIBLE. 15435cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown */ 15445cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown public static void hide(final View view, final int visibility) { 15455cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown if (FADE_DBG) log("Fade: HIDE view " + view + "..."); 15465cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown if (view.getVisibility() == View.VISIBLE && 15475cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown (visibility == View.INVISIBLE || visibility == View.GONE)) { 15485cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown 15495cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown // Use a view tag to mark this view as being in the middle 15505cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown // of a fade-out animation. 15515cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown view.setTag(FADE_STATE_KEY, FADING_OUT); 15525cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown 15535cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown view.animate().cancel(); 15545cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown view.animate().setDuration(DURATION); 15555cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown view.animate().alpha(0f).setListener(new AnimatorListenerAdapter() { 15565cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown public void onAnimationEnd(Animator animation) { 15575cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown view.setAlpha(1); 15585cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown view.setVisibility(visibility); 15595cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown view.animate().setListener(null); 15605cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown // ...and we're done with the fade-out, so clear the view tag. 15615cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown view.setTag(FADE_STATE_KEY, null); 15625cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown if (FADE_DBG) log("Fade: HIDE " + view 15635cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown + " DONE. Set visibility = " + visibility); 15645cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown } 15655cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown }); 15665cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown } 15675cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown } 15685cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown 15695cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown /** 15705cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown * @return true if the specified view is currently in the middle 15715cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown * of a fade-out animation. (During the fade-out, the view's 15725cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown * visibility is still VISIBLE, although in many cases the UI 15735cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown * should behave as if it's already invisible or gone. This 15745cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown * method allows the UI code to detect that state.) 15755cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown * 15765cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown * @see hide() 15775cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown */ 15785cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown public static boolean isFadingOut(final View view) { 15795cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown if (FADE_DBG) { 15805cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown log("Fade: isFadingOut view " + view + "..."); 15815cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown log("Fade: - getTag() returns: " + view.getTag(FADE_STATE_KEY)); 15825cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown log("Fade: - returning: " + (view.getTag(FADE_STATE_KEY) == FADING_OUT)); 15835cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown } 15845cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown return (view.getTag(FADE_STATE_KEY) == FADING_OUT); 15855cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown } 15865cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown 15875cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown } 15885cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown 15899688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown 1590b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Debugging / testing code 1591b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 15925cba7d9f89df5092d3ae5095acd0bea96b5aa174David Brown private static void log(String msg) { 1593796c70c99bc39295bf685061056f06ab8949c742David Brown Log.d(LOG_TAG, msg); 1594b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1595b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project} 1596