CallCard.java revision a232063e9bb9f7b8875a24af212287ba0d2cd0c3
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 19b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.content.ContentUris; 20b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.content.Context; 21b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.graphics.drawable.Drawable; 22b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.net.Uri; 23b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.pim.ContactsAsyncHelper; 243d6d70562622660e581b53308e675386d299dd19Dmitri Plotnikovimport android.provider.ContactsContract.Contacts; 25f3602b0659d01fef19159e7111be76102549f7a1David Brownimport android.telephony.PhoneNumberUtils; 26b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.text.TextUtils; 27b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.text.format.DateUtils; 28b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.util.AttributeSet; 29b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.util.Log; 30b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.view.LayoutInflater; 31b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.view.View; 32b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.view.ViewGroup; 33dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brownimport android.view.accessibility.AccessibilityEvent; 346d5544932495d81ff7ce53f4678c4beb25acc1b0David Brownimport android.widget.Button; 35b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.widget.FrameLayout; 36b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.widget.ImageView; 37b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.widget.TextView; 38b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 396b7d0da33af02960736da204eb7a25ccf91d5396David Brownimport com.android.internal.telephony.Call; 406b7d0da33af02960736da204eb7a25ccf91d5396David Brownimport com.android.internal.telephony.CallerInfo; 416b7d0da33af02960736da204eb7a25ccf91d5396David Brownimport com.android.internal.telephony.CallerInfoAsyncQuery; 426b7d0da33af02960736da204eb7a25ccf91d5396David Brownimport com.android.internal.telephony.Connection; 436b7d0da33af02960736da204eb7a25ccf91d5396David Brownimport com.android.internal.telephony.Phone; 448343169cc89621d46dce86449f5ee1ff5d3a4919John Wangimport com.android.internal.telephony.CallManager; 456b7d0da33af02960736da204eb7a25ccf91d5396David Brown 460fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Savilleimport java.util.List; 470fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 486b7d0da33af02960736da204eb7a25ccf91d5396David Brown 49b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project/** 50b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * "Call card" UI element: the in-call screen contains a tiled layout of call 51b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * cards, each representing the state of a current "call" (ie. an active call, 52b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * a call on hold, or an incoming call.) 53b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 54b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectpublic class CallCard extends FrameLayout 55b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project implements CallTime.OnTickListener, CallerInfoAsyncQuery.OnQueryCompleteListener, 566d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown ContactsAsyncHelper.OnImageLoadCompleteListener, View.OnClickListener { 57796c70c99bc39295bf685061056f06ab8949c742David Brown private static final String LOG_TAG = "CallCard"; 58796c70c99bc39295bf685061056f06ab8949c742David Brown private static final boolean DBG = (PhoneApp.DBG_LEVEL >= 2); 59b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 608bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project /** 618bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project * Reference to the InCallScreen activity that owns us. This may be 628bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project * null if we haven't been initialized yet *or* after the InCallScreen 638bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project * activity has been destroyed. 648bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project */ 658bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project private InCallScreen mInCallScreen; 668bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project 670fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // Phone app instance 680fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville private PhoneApp mApplication; 690fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 70b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Top-level subviews of the CallCard 710d315275d08cd33f801ae3a74e8fc265520f6246David Brown private ViewGroup mPrimaryCallInfo; 720d315275d08cd33f801ae3a74e8fc265520f6246David Brown private ViewGroup mSecondaryCallInfo; 73b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 7434a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // Title and elapsed-time widgets 75b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private TextView mUpperTitle; 76b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private TextView mElapsedTime; 77b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 7834a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // Text colors, used for various labels / titles 799688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown private int mTextColorDefaultPrimary; 809688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown private int mTextColorDefaultSecondary; 81b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private int mTextColorConnected; 828bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project private int mTextColorConnectedBluetooth; 83b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private int mTextColorEnded; 84b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private int mTextColorOnHold; 859d14e16e8214b4a396dad293b6f0941608ee4798David Brown private int mTextColorCallTypeSip; 86b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 870d315275d08cd33f801ae3a74e8fc265520f6246David Brown // The main block of info about the "primary" or "active" call, 880d315275d08cd33f801ae3a74e8fc265520f6246David Brown // including photo / name / phone number / etc. 89b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private ImageView mPhoto; 906d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown private Button mManageConferencePhotoButton; // Possibly shown in place of mPhoto 91b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private TextView mName; 92b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private TextView mPhoneNumber; 93b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private TextView mLabel; 949d14e16e8214b4a396dad293b6f0941608ee4798David Brown private TextView mCallTypeLabel; 9529d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown private TextView mSocialStatus; 96b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 970d315275d08cd33f801ae3a74e8fc265520f6246David Brown // Info about the "secondary" call, which is the "call on hold" when 980d315275d08cd33f801ae3a74e8fc265520f6246David Brown // two lines are in use. 990d315275d08cd33f801ae3a74e8fc265520f6246David Brown private TextView mSecondaryCallName; 1000d315275d08cd33f801ae3a74e8fc265520f6246David Brown private TextView mSecondaryCallStatus; 1010d315275d08cd33f801ae3a74e8fc265520f6246David Brown private ImageView mSecondaryCallPhoto; 102b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 103b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Menu button hint 104b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private TextView mMenuButtonHint; 105b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1069688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown // Onscreen hint for the incoming call RotarySelector widget. 107ea505da2d0ebae37b07fece15297b5432fe96c5dJim Miller private int mIncomingCallWidgetHintTextResId; 108ea505da2d0ebae37b07fece15297b5432fe96c5dJim Miller private int mIncomingCallWidgetHintColorResId; 1099688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown 110b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private CallTime mCallTime; 111b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 112b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Track the state for the photo. 113b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private ContactsAsyncHelper.ImageTracker mPhotoTracker; 114b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 11529d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown // Cached DisplayMetrics density. 11629d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown private float mDensity; 11729d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown 118b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public CallCard(Context context, AttributeSet attrs) { 119b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project super(context, attrs); 120b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 121b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("CallCard constructor..."); 122b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("- this = " + this); 123b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("- context " + context + ", attrs " + attrs); 124b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 125b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Inflate the contents of this CallCard, and add it (to ourself) as a child. 126b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project LayoutInflater inflater = LayoutInflater.from(context); 127b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project inflater.inflate( 128b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project R.layout.call_card, // resource 129b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project this, // root 130b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project true); 131b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1320fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville mApplication = PhoneApp.getInstance(); 1330fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 134b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mCallTime = new CallTime(this); 135b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 136b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // create a new object to track the state for the photo. 137b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhotoTracker = new ContactsAsyncHelper.ImageTracker(); 13829d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown 13929d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown mDensity = getResources().getDisplayMetrics().density; 14029d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown if (DBG) log("- Density: " + mDensity); 141b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 142b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1438bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project void setInCallScreenInstance(InCallScreen inCallScreen) { 1448bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project mInCallScreen = inCallScreen; 1458bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project } 1468bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project 147b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public void onTickForCallTimeElapsed(long timeElapsed) { 148b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // While a call is in progress, update the elapsed time shown 149b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // onscreen. 150b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project updateElapsedTimeWidget(timeElapsed); 151b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 152b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 153b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /* package */ 154b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project void stopTimer() { 155b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mCallTime.cancelTimer(); 156b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 157b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 158b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project @Override 159b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project protected void onFinishInflate() { 160b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project super.onFinishInflate(); 161b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 162b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("CallCard onFinishInflate(this = " + this + ")..."); 163b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1640d315275d08cd33f801ae3a74e8fc265520f6246David Brown mPrimaryCallInfo = (ViewGroup) findViewById(R.id.primaryCallInfo); 1650d315275d08cd33f801ae3a74e8fc265520f6246David Brown mSecondaryCallInfo = (ViewGroup) findViewById(R.id.secondaryCallInfo); 166b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 167b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // "Upper" and "lower" title widgets 168b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mUpperTitle = (TextView) findViewById(R.id.upperTitle); 169b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mElapsedTime = (TextView) findViewById(R.id.elapsedTime); 170b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 171b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Text colors 1729688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown mTextColorDefaultPrimary = // corresponds to textAppearanceLarge 1739688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown getResources().getColor(android.R.color.primary_text_dark); 1749688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown mTextColorDefaultSecondary = // corresponds to textAppearanceSmall 1759688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown getResources().getColor(android.R.color.secondary_text_dark); 176b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mTextColorConnected = getResources().getColor(R.color.incall_textConnected); 1778bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project mTextColorConnectedBluetooth = 1788bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project getResources().getColor(R.color.incall_textConnectedBluetooth); 179b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mTextColorEnded = getResources().getColor(R.color.incall_textEnded); 180b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mTextColorOnHold = getResources().getColor(R.color.incall_textOnHold); 1819d14e16e8214b4a396dad293b6f0941608ee4798David Brown mTextColorCallTypeSip = getResources().getColor(R.color.incall_callTypeSip); 182b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 183b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // "Caller info" area, including photo / name / phone numbers / etc 184b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhoto = (ImageView) findViewById(R.id.photo); 1856d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown mManageConferencePhotoButton = (Button) findViewById(R.id.manageConferencePhotoButton); 1866d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown mManageConferencePhotoButton.setOnClickListener(this); 187b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mName = (TextView) findViewById(R.id.name); 188b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhoneNumber = (TextView) findViewById(R.id.phoneNumber); 189b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mLabel = (TextView) findViewById(R.id.label); 1909d14e16e8214b4a396dad293b6f0941608ee4798David Brown mCallTypeLabel = (TextView) findViewById(R.id.callTypeLabel); 19129d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown mSocialStatus = (TextView) findViewById(R.id.socialStatus); 192b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 193b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // "Other call" info area 1940d315275d08cd33f801ae3a74e8fc265520f6246David Brown mSecondaryCallName = (TextView) findViewById(R.id.secondaryCallName); 1950d315275d08cd33f801ae3a74e8fc265520f6246David Brown mSecondaryCallStatus = (TextView) findViewById(R.id.secondaryCallStatus); 1960d315275d08cd33f801ae3a74e8fc265520f6246David Brown mSecondaryCallPhoto = (ImageView) findViewById(R.id.secondaryCallPhoto); 197b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 198b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Menu Button hint 199b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mMenuButtonHint = (TextView) findViewById(R.id.menuButtonHint); 200b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 201b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 202b15bef0ddcb4f744dff92013a9b596f2fcc2a008David Brown /** 203b15bef0ddcb4f744dff92013a9b596f2fcc2a008David Brown * Updates the state of all UI elements on the CallCard, based on the 204b15bef0ddcb4f744dff92013a9b596f2fcc2a008David Brown * current state of the phone. 205b15bef0ddcb4f744dff92013a9b596f2fcc2a008David Brown */ 2068343169cc89621d46dce86449f5ee1ff5d3a4919John Wang void updateState(CallManager cm) { 2078343169cc89621d46dce86449f5ee1ff5d3a4919John Wang if (DBG) log("updateState(" + cm + ")..."); 208b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 209b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Update some internal state based on the current state of the phone. 2106b7d0da33af02960736da204eb7a25ccf91d5396David Brown 2116b7d0da33af02960736da204eb7a25ccf91d5396David Brown // TODO: clean up this method to just fully update EVERYTHING in 2126b7d0da33af02960736da204eb7a25ccf91d5396David Brown // the callcard based on the current phone state: set the overall 2136b7d0da33af02960736da204eb7a25ccf91d5396David Brown // type of the CallCard, load up the main caller info area, and 2146b7d0da33af02960736da204eb7a25ccf91d5396David Brown // load up and show or hide the "other call" area if necessary. 215b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2168343169cc89621d46dce86449f5ee1ff5d3a4919John Wang Phone.State state = cm.getState(); // IDLE, RINGING, or OFFHOOK 217091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan Call ringingCall = cm.getFirstActiveRingingCall(); 218091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan Call fgCall = cm.getActiveFgCall(); 219091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan Call bgCall = cm.getFirstActiveBgCall(); 220091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan 2217f09c1629141416c489ede69e70e2aa59453ddedHung-ying Tyan // If the FG call is dialing/alerting, we should display for that call 2227f09c1629141416c489ede69e70e2aa59453ddedHung-ying Tyan // and ignore the ringing call. This case happens when the telephony 2237f09c1629141416c489ede69e70e2aa59453ddedHung-ying Tyan // layer rejects the ringing call while the FG call is dialing/alerting, 2247f09c1629141416c489ede69e70e2aa59453ddedHung-ying Tyan // but the incoming call *does* briefly exist in the DISCONNECTING or 2257f09c1629141416c489ede69e70e2aa59453ddedHung-ying Tyan // DISCONNECTED state. 2267f09c1629141416c489ede69e70e2aa59453ddedHung-ying Tyan if ((ringingCall.getState() != Call.State.IDLE) 2277f09c1629141416c489ede69e70e2aa59453ddedHung-ying Tyan && !fgCall.getState().isDialing()) { 228091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // A phone call is ringing, call waiting *or* being rejected 229b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // (ie. another call may also be active as well.) 2308343169cc89621d46dce86449f5ee1ff5d3a4919John Wang updateRingingCall(cm); 231091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan } else if ((fgCall.getState() != Call.State.IDLE) 232091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan || (bgCall.getState() != Call.State.IDLE)) { 233091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // We are here because either: 234091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // (1) the phone is off hook. At least one call exists that is 235091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // dialing, active, or holding, and no calls are ringing or waiting, 236091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // or: 237091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // (2) the phone is IDLE but a call just ended and it's still in 238091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // the DISCONNECTING or DISCONNECTED state. In this case, we want 239091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // the main CallCard to display "Hanging up" or "Call ended". 240091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // The normal "foreground call" code path handles both cases. 2418343169cc89621d46dce86449f5ee1ff5d3a4919John Wang updateForegroundCall(cm); 242b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 243091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // We don't have any DISCONNECTED calls, which means 244091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // that the phone is *truly* idle. 245b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // 246091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // It's very rare to be on the InCallScreen at all in this 247091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // state, but it can happen in some cases: 248091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // - A stray onPhoneStateChanged() event came in to the 249091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // InCallScreen *after* it was dismissed. 250091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // - We're allowed to be on the InCallScreen because 251091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // an MMI or USSD is running, but there's no actual "call" 252091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // to display. 253091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // - We're displaying an error dialog to the user 254091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // (explaining why the call failed), so we need to stay on 255091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // the InCallScreen so that the dialog will be visible. 256091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // 257091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan // In these cases, put the callcard into a sane but "blank" state: 258091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan updateNoCall(cm); 259b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 260b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 261b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 262b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 263b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Updates the UI for the state where the phone is in use, but not ringing. 264b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 2658343169cc89621d46dce86449f5ee1ff5d3a4919John Wang private void updateForegroundCall(CallManager cm) { 266b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("updateForegroundCall()..."); 26702d1c632adde606031c1fe6ea0e3be1e288fd6c6David Brown // if (DBG) PhoneUtils.dumpCallManager(); 2688343169cc89621d46dce86449f5ee1ff5d3a4919John Wang 2698343169cc89621d46dce86449f5ee1ff5d3a4919John Wang Call fgCall = cm.getActiveFgCall(); 2708343169cc89621d46dce86449f5ee1ff5d3a4919John Wang Call bgCall = cm.getFirstActiveBgCall(); 2718343169cc89621d46dce86449f5ee1ff5d3a4919John Wang 272091ccad8630a43e62d84fba9c7613441e9d0a597Hung-ying Tyan if (fgCall.getState() == Call.State.IDLE) { 273b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("updateForegroundCall: no active call, show holding call"); 274b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // TODO: make sure this case agrees with the latest UI spec. 275b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 276b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Display the background call in the main info area of the 277b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // CallCard, since there is no foreground call. Note that 278b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // displayMainCallStatus() will notice if the call we passed in is on 279b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // hold, and display the "on hold" indication. 280b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project fgCall = bgCall; 281b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 282b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // And be sure to not display anything in the "on hold" box. 283b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project bgCall = null; 284b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 285b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2868343169cc89621d46dce86449f5ee1ff5d3a4919John Wang displayMainCallStatus(cm, fgCall); 2878343169cc89621d46dce86449f5ee1ff5d3a4919John Wang 2888343169cc89621d46dce86449f5ee1ff5d3a4919John Wang Phone phone = fgCall.getPhone(); 2890fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 29079b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink int phoneType = phone.getPhoneType(); 29179b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink if (phoneType == Phone.PHONE_TYPE_CDMA) { 29239a84144262f12df44861d746788b9de92259e4fAbhishek Pillai if ((mApplication.cdmaPhoneCallState.getCurrentCallState() 29339a84144262f12df44861d746788b9de92259e4fAbhishek Pillai == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) 29439a84144262f12df44861d746788b9de92259e4fAbhishek Pillai && mApplication.cdmaPhoneCallState.IsThreeWayCallOrigStateDialing()) { 2958343169cc89621d46dce86449f5ee1ff5d3a4919John Wang displayOnHoldCallStatus(cm, fgCall); 2960fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } else { 2970fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville //This is required so that even if a background call is not present 2980fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // we need to clean up the background call area. 2998343169cc89621d46dce86449f5ee1ff5d3a4919John Wang displayOnHoldCallStatus(cm, bgCall); 3000fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 301872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan } else if ((phoneType == Phone.PHONE_TYPE_GSM) 302872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan || (phoneType == Phone.PHONE_TYPE_SIP)) { 3038343169cc89621d46dce86449f5ee1ff5d3a4919John Wang displayOnHoldCallStatus(cm, bgCall); 3040fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 305b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 306b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 307b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 308b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Updates the UI for the state where an incoming call is ringing (or 309b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * call waiting), regardless of whether the phone's already offhook. 310b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 3118343169cc89621d46dce86449f5ee1ff5d3a4919John Wang private void updateRingingCall(CallManager cm) { 312b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("updateRingingCall()..."); 313b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3148343169cc89621d46dce86449f5ee1ff5d3a4919John Wang Call ringingCall = cm.getFirstActiveRingingCall(); 315b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3166b7d0da33af02960736da204eb7a25ccf91d5396David Brown // Display caller-id info and photo from the incoming call: 3178343169cc89621d46dce86449f5ee1ff5d3a4919John Wang displayMainCallStatus(cm, ringingCall); 3186b7d0da33af02960736da204eb7a25ccf91d5396David Brown 3196b7d0da33af02960736da204eb7a25ccf91d5396David Brown // And even in the Call Waiting case, *don't* show any info about 3206b7d0da33af02960736da204eb7a25ccf91d5396David Brown // the current ongoing call and/or the current call on hold. 3216b7d0da33af02960736da204eb7a25ccf91d5396David Brown // (Since the caller-id info for the incoming call totally trumps 3226b7d0da33af02960736da204eb7a25ccf91d5396David Brown // any info about the current call(s) in progress.) 3238343169cc89621d46dce86449f5ee1ff5d3a4919John Wang displayOnHoldCallStatus(cm, null); 324b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 325b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 326b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 327b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Updates the UI for the state where the phone is not in use. 328b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * This is analogous to updateForegroundCall() and updateRingingCall(), 329b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * but for the (uncommon) case where the phone is 330b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * totally idle. (See comments in updateState() above.) 331b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 332b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * This puts the callcard into a sane but "blank" state. 333b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 3348343169cc89621d46dce86449f5ee1ff5d3a4919John Wang private void updateNoCall(CallManager cm) { 335b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("updateNoCall()..."); 336b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3378343169cc89621d46dce86449f5ee1ff5d3a4919John Wang displayMainCallStatus(cm, null); 3388343169cc89621d46dce86449f5ee1ff5d3a4919John Wang displayOnHoldCallStatus(cm, null); 339b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 340b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 341b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 342b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Updates the main block of caller info on the CallCard 3430d315275d08cd33f801ae3a74e8fc265520f6246David Brown * (ie. the stuff in the primaryCallInfo block) based on the specified Call. 344b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 3458343169cc89621d46dce86449f5ee1ff5d3a4919John Wang private void displayMainCallStatus(CallManager cm, Call call) { 34602d1c632adde606031c1fe6ea0e3be1e288fd6c6David Brown if (DBG) log("displayMainCallStatus(call " + call + ")..."); 347b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 348b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (call == null) { 349b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // There's no call to display, presumably because the phone is idle. 3500d315275d08cd33f801ae3a74e8fc265520f6246David Brown mPrimaryCallInfo.setVisibility(View.GONE); 351b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return; 352b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 3530d315275d08cd33f801ae3a74e8fc265520f6246David Brown mPrimaryCallInfo.setVisibility(View.VISIBLE); 354b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 355b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Call.State state = call.getState(); 356b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log(" - call.state: " + call.getState()); 357b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 358b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project switch (state) { 359b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case ACTIVE: 3605eff1e7d582679b3a85f580eb1d550b2e6ca111cDavid Brown case DISCONNECTING: 361b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // update timer field 362b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("displayMainCallStatus: start periodicUpdateTimer"); 363b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mCallTime.setActiveCallMode(call); 364b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mCallTime.reset(); 365b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mCallTime.periodicUpdateTimer(); 366b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 367b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 368b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 369b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case HOLDING: 370b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // update timer field 371b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mCallTime.cancelTimer(); 372b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 373b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 374b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 375b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case DISCONNECTED: 376b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Stop getting timer ticks from this call 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 DIALING: 382b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case ALERTING: 383b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Stop getting timer ticks from a previous call 384b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mCallTime.cancelTimer(); 385b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 386b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 387b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 388b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case INCOMING: 389b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case WAITING: 390b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Stop getting timer ticks from a previous call 391b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mCallTime.cancelTimer(); 392b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 393b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 394b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 395b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case IDLE: 396b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // The "main CallCard" should never be trying to display 397b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // an idle call! In updateState(), if the phone is idle, 398b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // we call updateNoCall(), which means that we shouldn't 399b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // have passed a call into this method at all. 400b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Log.w(LOG_TAG, "displayMainCallStatus: IDLE call in the main call card!"); 401b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 402b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // (It is possible, though, that we had a valid call which 403b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // became idle *after* the check in updateState() but 404b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // before we get here... So continue the best we can, 405b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // with whatever (stale) info we can get from the 406b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // passed-in Call object.) 407b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 408b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 409b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 410b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project default: 411b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Log.w(LOG_TAG, "displayMainCallStatus: unexpected call state: " + state); 412b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 413b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 414b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 4158343169cc89621d46dce86449f5ee1ff5d3a4919John Wang updateCardTitleWidgets(call.getPhone(), call); 416b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 417b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (PhoneUtils.isConferenceCall(call)) { 418b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Update onscreen info for a conference call. 419872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan updateDisplayForConference(call); 420b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 421b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Update onscreen info for a regular call (which presumably 422b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // has only one connection.) 4230fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville Connection conn = null; 4248343169cc89621d46dce86449f5ee1ff5d3a4919John Wang int phoneType = call.getPhone().getPhoneType(); 42579b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink if (phoneType == Phone.PHONE_TYPE_CDMA) { 4260fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville conn = call.getLatestConnection(); 427872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan } else if ((phoneType == Phone.PHONE_TYPE_GSM) 428872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan || (phoneType == Phone.PHONE_TYPE_SIP)) { 4290fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville conn = call.getEarliestConnection(); 43079b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink } else { 43179b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink throw new IllegalStateException("Unexpected phone type: " + phoneType); 4320fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 433b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 434b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (conn == null) { 435b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("displayMainCallStatus: connection is null, using default values."); 436b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if the connection is null, we run through the behaviour 437b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // we had in the past, which breaks down into trivial steps 438b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // with the current implementation of getCallerInfo and 439b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // updateDisplayForPerson. 4404359358c4f430cbb986a5e7640ec506f08f1e332David Brown CallerInfo info = PhoneUtils.getCallerInfo(getContext(), null /* conn */); 4414359358c4f430cbb986a5e7640ec506f08f1e332David Brown updateDisplayForPerson(info, Connection.PRESENTATION_ALLOWED, false, call); 442b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 443b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log(" - CONN: " + conn + ", state = " + conn.getState()); 4444359358c4f430cbb986a5e7640ec506f08f1e332David Brown int presentation = conn.getNumberPresentation(); 445b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 446b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // make sure that we only make a new query when the current 447b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // callerinfo differs from what we've been requested to display. 448b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project boolean runQuery = true; 449b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Object o = conn.getUserData(); 450b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (o instanceof PhoneUtils.CallerInfoToken) { 451b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project runQuery = mPhotoTracker.isDifferentImageRequest( 452b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project ((PhoneUtils.CallerInfoToken) o).currentInfo); 453b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 454b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project runQuery = mPhotoTracker.isDifferentImageRequest(conn); 455b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 456b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 45746532b66a467f247380054270c6151aa3dc7a761Wink Saville // Adding a check to see if the update was caused due to a Phone number update 45846532b66a467f247380054270c6151aa3dc7a761Wink Saville // or CNAP update. If so then we need to start a new query 45979b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink if (phoneType == Phone.PHONE_TYPE_CDMA) { 46046532b66a467f247380054270c6151aa3dc7a761Wink Saville Object obj = conn.getUserData(); 46146532b66a467f247380054270c6151aa3dc7a761Wink Saville String updatedNumber = conn.getAddress(); 46246532b66a467f247380054270c6151aa3dc7a761Wink Saville String updatedCnapName = conn.getCnapName(); 46346532b66a467f247380054270c6151aa3dc7a761Wink Saville CallerInfo info = null; 46446532b66a467f247380054270c6151aa3dc7a761Wink Saville if (obj instanceof PhoneUtils.CallerInfoToken) { 46546532b66a467f247380054270c6151aa3dc7a761Wink Saville info = ((PhoneUtils.CallerInfoToken) o).currentInfo; 46646532b66a467f247380054270c6151aa3dc7a761Wink Saville } else if (o instanceof CallerInfo) { 46746532b66a467f247380054270c6151aa3dc7a761Wink Saville info = (CallerInfo) o; 46846532b66a467f247380054270c6151aa3dc7a761Wink Saville } 46946532b66a467f247380054270c6151aa3dc7a761Wink Saville 47046532b66a467f247380054270c6151aa3dc7a761Wink Saville if (info != null) { 47146532b66a467f247380054270c6151aa3dc7a761Wink Saville if (updatedNumber != null && !updatedNumber.equals(info.phoneNumber)) { 47246532b66a467f247380054270c6151aa3dc7a761Wink Saville if (DBG) log("- displayMainCallStatus: updatedNumber = " 47346532b66a467f247380054270c6151aa3dc7a761Wink Saville + updatedNumber); 47446532b66a467f247380054270c6151aa3dc7a761Wink Saville runQuery = true; 47546532b66a467f247380054270c6151aa3dc7a761Wink Saville } 47646532b66a467f247380054270c6151aa3dc7a761Wink Saville if (updatedCnapName != null && !updatedCnapName.equals(info.cnapName)) { 47746532b66a467f247380054270c6151aa3dc7a761Wink Saville if (DBG) log("- displayMainCallStatus: updatedCnapName = " 47846532b66a467f247380054270c6151aa3dc7a761Wink Saville + updatedCnapName); 47946532b66a467f247380054270c6151aa3dc7a761Wink Saville runQuery = true; 48046532b66a467f247380054270c6151aa3dc7a761Wink Saville } 48146532b66a467f247380054270c6151aa3dc7a761Wink Saville } 48246532b66a467f247380054270c6151aa3dc7a761Wink Saville } 48346532b66a467f247380054270c6151aa3dc7a761Wink Saville 484b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (runQuery) { 485b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("- displayMainCallStatus: starting CallerInfo query..."); 486b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project PhoneUtils.CallerInfoToken info = 487b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project PhoneUtils.startGetCallerInfo(getContext(), conn, this, call); 4884b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project updateDisplayForPerson(info.currentInfo, presentation, !info.isFinal, call); 489b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 490b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // No need to fire off a new query. We do still need 491b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // to update the display, though (since we might have 492b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // previously been in the "conference call" state.) 493b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("- displayMainCallStatus: using data we already have..."); 494b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (o instanceof CallerInfo) { 495b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project CallerInfo ci = (CallerInfo) o; 496e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai // Update CNAP information if Phone state change occurred 497e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai ci.cnapName = conn.getCnapName(); 498e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai ci.numberPresentation = conn.getNumberPresentation(); 499e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai ci.namePresentation = conn.getCnapNamePresentation(); 500e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai if (DBG) log("- displayMainCallStatus: CNAP data from Connection: " 501e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai + "CNAP name=" + ci.cnapName 502e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai + ", Number/Name Presentation=" + ci.numberPresentation); 503b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log(" ==> Got CallerInfo; updating display: ci = " + ci); 5044b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project updateDisplayForPerson(ci, presentation, false, call); 505b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else if (o instanceof PhoneUtils.CallerInfoToken){ 506b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project CallerInfo ci = ((PhoneUtils.CallerInfoToken) o).currentInfo; 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 CallerInfoToken; updating display: ci = " + ci); 5114b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project updateDisplayForPerson(ci, presentation, true, call); 512b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 513b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Log.w(LOG_TAG, "displayMainCallStatus: runQuery was false, " 514b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project + "but we didn't have a cached CallerInfo object! o = " + o); 515b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // TODO: any easy way to recover here (given that 516b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // the CallCard is probably displaying stale info 517b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // right now?) Maybe force the CallCard into the 518b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // "Unknown" state? 519b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 520b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 521b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 522b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 523b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 524b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // In some states we override the "photo" ImageView to be an 525b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // indication of the current state, rather than displaying the 526b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // regular photo as set above. 527b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project updatePhotoForCallState(call); 5289688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown 5299688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown // One special feature of the "number" text field: For incoming 5309688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown // calls, while the user is dragging the RotarySelector widget, we 5319688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown // use mPhoneNumber to display a hint like "Rotate to answer". 532ea505da2d0ebae37b07fece15297b5432fe96c5dJim Miller if (mIncomingCallWidgetHintTextResId != 0) { 5339688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown // Display the hint! 534ea505da2d0ebae37b07fece15297b5432fe96c5dJim Miller mPhoneNumber.setText(mIncomingCallWidgetHintTextResId); 535ea505da2d0ebae37b07fece15297b5432fe96c5dJim Miller mPhoneNumber.setTextColor(getResources().getColor(mIncomingCallWidgetHintColorResId)); 5369688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown mPhoneNumber.setVisibility(View.VISIBLE); 5379688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown mLabel.setVisibility(View.GONE); 5389688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown } 5399688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown // If we don't have a hint to display, just don't touch 5409688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown // mPhoneNumber and mLabel. (Their text / color / visibility have 5419688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown // already been set correctly, by either updateDisplayForPerson() 5429688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown // or updateDisplayForConference().) 543b15bef0ddcb4f744dff92013a9b596f2fcc2a008David Brown } 544b15bef0ddcb4f744dff92013a9b596f2fcc2a008David Brown 545b15bef0ddcb4f744dff92013a9b596f2fcc2a008David Brown /** 546b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Implemented for CallerInfoAsyncQuery.OnQueryCompleteListener interface. 547b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * refreshes the CallCard data when it called. 548b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 549b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public void onQueryComplete(int token, Object cookie, CallerInfo ci) { 550b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("onQueryComplete: token " + token + ", cookie " + cookie + ", ci " + ci); 551b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 552b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (cookie instanceof Call) { 553b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // grab the call object and update the display for an individual call, 554b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // as well as the successive call to update image via call state. 555b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // If the object is a textview instead, we update it as we need to. 556b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("callerinfo query complete, updating ui from displayMainCallStatus()"); 557b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Call call = (Call) cookie; 558a0ea7a803c8953a14bc35d1fef0973fd1d9c64b9Abhishek Pillai Connection conn = null; 559872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan int phoneType = call.getPhone().getPhoneType(); 560a0ea7a803c8953a14bc35d1fef0973fd1d9c64b9Abhishek Pillai if (phoneType == Phone.PHONE_TYPE_CDMA) { 561a0ea7a803c8953a14bc35d1fef0973fd1d9c64b9Abhishek Pillai conn = call.getLatestConnection(); 562872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan } else if ((phoneType == Phone.PHONE_TYPE_GSM) 563872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan || (phoneType == Phone.PHONE_TYPE_SIP)) { 564a0ea7a803c8953a14bc35d1fef0973fd1d9c64b9Abhishek Pillai conn = call.getEarliestConnection(); 565a0ea7a803c8953a14bc35d1fef0973fd1d9c64b9Abhishek Pillai } else { 566a0ea7a803c8953a14bc35d1fef0973fd1d9c64b9Abhishek Pillai throw new IllegalStateException("Unexpected phone type: " + phoneType); 567a0ea7a803c8953a14bc35d1fef0973fd1d9c64b9Abhishek Pillai } 568e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai PhoneUtils.CallerInfoToken cit = 569e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai PhoneUtils.startGetCallerInfo(getContext(), conn, this, null); 570e066d6979acb39dbc0ba79ecc10bc12e84a15195David Brown 571e066d6979acb39dbc0ba79ecc10bc12e84a15195David Brown int presentation = Connection.PRESENTATION_ALLOWED; 572e066d6979acb39dbc0ba79ecc10bc12e84a15195David Brown if (conn != null) presentation = conn.getNumberPresentation(); 573e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai if (DBG) log("- onQueryComplete: presentation=" + presentation 574e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai + ", contactExists=" + ci.contactExists); 575e066d6979acb39dbc0ba79ecc10bc12e84a15195David Brown 576e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai // Depending on whether there was a contact match or not, we want to pass in different 577e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai // CallerInfo (for CNAP). Therefore if ci.contactExists then use the ci passed in. 578e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai // Otherwise, regenerate the CIT from the Connection and use the CallerInfo from there. 579e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai if (ci.contactExists) { 580e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai updateDisplayForPerson(ci, Connection.PRESENTATION_ALLOWED, false, call); 581e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai } else { 582e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai updateDisplayForPerson(cit.currentInfo, presentation, false, call); 583e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai } 584b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project updatePhotoForCallState(call); 585b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 586b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else if (cookie instanceof TextView){ 587b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("callerinfo query complete, updating ui from ongoing or onhold"); 588b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project ((TextView) cookie).setText(PhoneUtils.getCompactNameFromCallerInfo(ci, mContext)); 589b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 590b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 591b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 592b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 593b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Implemented for ContactsAsyncHelper.OnImageLoadCompleteListener interface. 594b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * make sure that the call state is reflected after the image is loaded. 595b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 596b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public void onImageLoadComplete(int token, Object cookie, ImageView iView, 597b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project boolean imagePresent){ 598b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (cookie != null) { 599b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project updatePhotoForCallState((Call) cookie); 600b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 601b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 602b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 603b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 60434a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown * Updates the "card title" (and also elapsed time widget) based on 60534a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown * the current state of the call. 606b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 607e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown // TODO: it's confusing for updateCardTitleWidgets() and 608e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown // getTitleForCallCard() to be separate methods, since they both 609e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown // just list out the exact same "phone state" cases. 610e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown // Let's merge the getTitleForCallCard() logic into here. 611b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void updateCardTitleWidgets(Phone phone, Call call) { 612b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("updateCardTitleWidgets(call " + call + ")..."); 613b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Call.State state = call.getState(); 614f3602b0659d01fef19159e7111be76102549f7a1David Brown Context context = getContext(); 615b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 616b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // TODO: Still need clearer spec on exactly how title *and* status get 617b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // set in all states. (Then, given that info, refactor the code 618b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // here to be more clear about exactly which widgets on the card 619b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // need to be set.) 620b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 6213800ac871d6548790ac6119bb68b9be0640af261David Krause String cardTitle; 622872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan int phoneType = phone.getPhoneType(); 62379b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink if (phoneType == Phone.PHONE_TYPE_CDMA) { 6243800ac871d6548790ac6119bb68b9be0640af261David Krause if (!PhoneApp.getInstance().notifier.getIsCdmaRedialCall()) { 6256b7d0da33af02960736da204eb7a25ccf91d5396David Brown cardTitle = getTitleForCallCard(call); // Normal "foreground" call card 6263800ac871d6548790ac6119bb68b9be0640af261David Krause } else { 627f3602b0659d01fef19159e7111be76102549f7a1David Brown cardTitle = context.getString(R.string.card_title_redialing); 6283800ac871d6548790ac6119bb68b9be0640af261David Krause } 629872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan } else if ((phoneType == Phone.PHONE_TYPE_GSM) 630872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan || (phoneType == Phone.PHONE_TYPE_SIP)) { 6313800ac871d6548790ac6119bb68b9be0640af261David Krause cardTitle = getTitleForCallCard(call); 63279b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink } else { 63379b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink throw new IllegalStateException("Unexpected phone type: " + phoneType); 6343800ac871d6548790ac6119bb68b9be0640af261David Krause } 635b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("updateCardTitleWidgets: " + cardTitle); 636b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 63734a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // Update the title and elapsed time widgets based on the current call state. 63834a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown switch (state) { 63934a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown case ACTIVE: 64034a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown case DISCONNECTING: 64134a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown final boolean bluetoothActive = mApplication.showBluetoothIndication(); 64234a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown int ongoingCallIcon = bluetoothActive ? R.drawable.ic_incall_ongoing_bluetooth 64334a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown : R.drawable.ic_incall_ongoing; 64434a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown int connectedTextColor = bluetoothActive 64534a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown ? mTextColorConnectedBluetooth : mTextColorConnected; 646b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 64779b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink if (phoneType == Phone.PHONE_TYPE_CDMA) { 648f3602b0659d01fef19159e7111be76102549f7a1David Brown // In normal operation we don't use an "upper title" at all, 649f3602b0659d01fef19159e7111be76102549f7a1David Brown // except for a couple of special cases: 65034a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown if (mApplication.cdmaPhoneCallState.IsThreeWayCallOrigStateDialing()) { 651f3602b0659d01fef19159e7111be76102549f7a1David Brown // Display "Dialing" while dialing a 3Way call, even 652f3602b0659d01fef19159e7111be76102549f7a1David Brown // though the foreground call state is still ACTIVE. 653f3602b0659d01fef19159e7111be76102549f7a1David Brown setUpperTitle(cardTitle, mTextColorDefaultPrimary, state); 654f3602b0659d01fef19159e7111be76102549f7a1David Brown } else if (PhoneUtils.isPhoneInEcm(phone)) { 655f3602b0659d01fef19159e7111be76102549f7a1David Brown // In emergency callback mode (ECM), use a special title 656f3602b0659d01fef19159e7111be76102549f7a1David Brown // that shows your own phone number. 657f3602b0659d01fef19159e7111be76102549f7a1David Brown cardTitle = getECMCardTitle(context, phone); 6589688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown setUpperTitle(cardTitle, mTextColorDefaultPrimary, state); 65934a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown } else { 66034a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // Normal "ongoing call" state; don't use any "title" at all. 66134a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown clearUpperTitle(); 66234a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown } 663872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan } else if ((phoneType == Phone.PHONE_TYPE_GSM) 664872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan || (phoneType == Phone.PHONE_TYPE_SIP)) { 665e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown // While in the DISCONNECTING state we display a 666e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown // "Hanging up" message in order to make the UI feel more 667e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown // responsive. (In GSM it's normal to see a delay of a 668e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown // couple of seconds while negotiating the disconnect with 669e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown // the network, so the "Hanging up" state at least lets 670e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown // the user know that we're doing something.) 671e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown // TODO: consider displaying the "Hanging up" state for 672e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown // CDMA also if the latency there ever gets high enough. 673e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown if (state == Call.State.DISCONNECTING) { 674e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown // Display the brief "Hanging up" indication. 675e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown setUpperTitle(cardTitle, mTextColorDefaultPrimary, state); 676e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown } else { // state == Call.State.ACTIVE 677e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown // Normal "ongoing call" state; don't use any "title" at all. 678e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown clearUpperTitle(); 679e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown } 68034a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown } 68134a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown 68234a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // Use the elapsed time widget to show the current call duration. 68334a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown mElapsedTime.setVisibility(View.VISIBLE); 68434a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown mElapsedTime.setTextColor(connectedTextColor); 68534a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown long duration = CallTime.getCallDuration(call); // msec 68634a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown updateElapsedTimeWidget(duration / 1000); 68734a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // Also see onTickForCallTimeElapsed(), which updates this 68834a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // widget once per second while the call is active. 68934a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown break; 69034a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown 69134a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown case DISCONNECTED: 69234a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // Display "Call ended" (or possibly some error indication; 69334a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // see getCallFailedString()) in the upper title, in red. 69434a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown 69534a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // TODO: display a "call ended" icon somewhere, like the old 69634a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // R.drawable.ic_incall_end? 69734a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown 69834a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown setUpperTitle(cardTitle, mTextColorEnded, state); 69934a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown 70034a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // In the "Call ended" state, leave the mElapsedTime widget 70134a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // visible, but don't touch it (so we continue to see the elapsed time of 70234a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // the call that just ended.) 70334a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown mElapsedTime.setVisibility(View.VISIBLE); 70434a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown mElapsedTime.setTextColor(mTextColorEnded); 70534a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown break; 70634a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown 70734a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown case HOLDING: 70834a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // For a single call on hold, display the title "On hold" in 70934a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // orange. 71034a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // (But since the upper title overlaps the label of the 71134a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // Hold/Unhold button, we actually use the elapsedTime widget 71234a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // to display the title in this case.) 71334a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown 71434a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // TODO: display an "On hold" icon somewhere, like the old 71534a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // R.drawable.ic_incall_onhold? 71634a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown 71734a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown clearUpperTitle(); 71834a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown mElapsedTime.setText(cardTitle); 71934a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown 72034a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // While on hold, the elapsed time widget displays an 72134a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // "on hold" indication rather than an amount of time. 72234a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown mElapsedTime.setVisibility(View.VISIBLE); 72334a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown mElapsedTime.setTextColor(mTextColorOnHold); 72434a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown break; 72534a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown 72634a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown default: 72734a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // All other states (DIALING, INCOMING, etc.) use the "upper title": 7289688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown setUpperTitle(cardTitle, mTextColorDefaultPrimary, state); 72934a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown 73034a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // ...and we don't show the elapsed time. 73134a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown mElapsedTime.setVisibility(View.INVISIBLE); 73234a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown break; 733b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 734b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 735b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 736b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 737b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Updates mElapsedTime based on the specified number of seconds. 738b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * A timeElapsed value of zero means to not show an elapsed time at all. 739b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 740b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void updateElapsedTimeWidget(long timeElapsed) { 741b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if (DBG) log("updateElapsedTimeWidget: " + timeElapsed); 742b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (timeElapsed == 0) { 743b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mElapsedTime.setText(""); 744b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 745b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mElapsedTime.setText(DateUtils.formatElapsedTime(timeElapsed)); 746b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 747b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 748b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 749b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 750b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Returns the "card title" displayed at the top of a foreground 751b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * ("active") CallCard to indicate the current state of this call, like 752b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * "Dialing" or "In call" or "On hold". A null return value means that 753b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * there's no title string for this state. 754b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 755b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private String getTitleForCallCard(Call call) { 756b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project String retVal = null; 757b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Call.State state = call.getState(); 758b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Context context = getContext(); 759b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 760b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("- getTitleForCallCard(Call " + call + ")..."); 761b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 762b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project switch (state) { 763b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case IDLE: 764b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 765b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 766b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case ACTIVE: 767b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Title is "Call in progress". (Note this appears in the 768b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // "lower title" area of the CallCard.) 769872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan int phoneType = call.getPhone().getPhoneType(); 77079b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink if (phoneType == Phone.PHONE_TYPE_CDMA) { 7710fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville if (mApplication.cdmaPhoneCallState.IsThreeWayCallOrigStateDialing()) { 7720fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville retVal = context.getString(R.string.card_title_dialing); 7730fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } else { 7740fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville retVal = context.getString(R.string.card_title_in_progress); 7750fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 776872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan } else if ((phoneType == Phone.PHONE_TYPE_GSM) 777872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan || (phoneType == Phone.PHONE_TYPE_SIP)) { 7780fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville retVal = context.getString(R.string.card_title_in_progress); 77979b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink } else { 78079b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink throw new IllegalStateException("Unexpected phone type: " + phoneType); 7810fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 782b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 783b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 784b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case HOLDING: 785b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project retVal = context.getString(R.string.card_title_on_hold); 786b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // TODO: if this is a conference call on hold, 787b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // maybe have a special title here too? 788b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 789b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 790b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case DIALING: 791b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case ALERTING: 792b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project retVal = context.getString(R.string.card_title_dialing); 793b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 794b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 795b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case INCOMING: 796b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case WAITING: 797b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project retVal = context.getString(R.string.card_title_incoming_call); 798b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 799b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 8005eff1e7d582679b3a85f580eb1d550b2e6ca111cDavid Brown case DISCONNECTING: 8015eff1e7d582679b3a85f580eb1d550b2e6ca111cDavid Brown retVal = context.getString(R.string.card_title_hanging_up); 8025eff1e7d582679b3a85f580eb1d550b2e6ca111cDavid Brown break; 8035eff1e7d582679b3a85f580eb1d550b2e6ca111cDavid Brown 804b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case DISCONNECTED: 805b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project retVal = getCallFailedString(call); 806b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 807b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 808b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 809b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log(" ==> result: " + retVal); 810b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return retVal; 811b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 812b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 813b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 814b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Updates the "on hold" box in the "other call" info area 8150d315275d08cd33f801ae3a74e8fc265520f6246David Brown * (ie. the stuff in the secondaryCallInfo block) 816b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * based on the specified Call. 817b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Or, clear out the "on hold" box if the specified call 818b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * is null or idle. 819b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 8208343169cc89621d46dce86449f5ee1ff5d3a4919John Wang private void displayOnHoldCallStatus(CallManager cm, Call call) { 821b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("displayOnHoldCallStatus(call =" + call + ")..."); 822af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville 823af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville if ((call == null) || (PhoneApp.getInstance().isOtaCallInActiveState())) { 8240d315275d08cd33f801ae3a74e8fc265520f6246David Brown mSecondaryCallInfo.setVisibility(View.GONE); 825b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return; 826b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 827b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 8288da4d90151c882972e15429d4d48bdaa45095d72David Brown boolean showSecondaryCallInfo = false; 829b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Call.State state = call.getState(); 830b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project switch (state) { 831b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case HOLDING: 832b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Ok, there actually is a background call on hold. 833b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Display the "on hold" box. 834b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 8350d315275d08cd33f801ae3a74e8fc265520f6246David Brown // Note this case occurs only on GSM devices. (On CDMA, 8360d315275d08cd33f801ae3a74e8fc265520f6246David Brown // the "call on hold" is actually the 2nd connection of 8370d315275d08cd33f801ae3a74e8fc265520f6246David Brown // that ACTIVE call; see the ACTIVE case below.) 8380d315275d08cd33f801ae3a74e8fc265520f6246David Brown 839b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (PhoneUtils.isConferenceCall(call)) { 840b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("==> conference call."); 8410d315275d08cd33f801ae3a74e8fc265520f6246David Brown mSecondaryCallName.setText(getContext().getString(R.string.confCall)); 8420d315275d08cd33f801ae3a74e8fc265520f6246David Brown showImage(mSecondaryCallPhoto, R.drawable.picture_conference); 843b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 844b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // perform query and update the name temporarily 845b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // make sure we hand the textview we want updated to the 846b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // callback function. 847b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("==> NOT a conf call; call startGetCallerInfo..."); 8480d315275d08cd33f801ae3a74e8fc265520f6246David Brown PhoneUtils.CallerInfoToken infoToken = PhoneUtils.startGetCallerInfo( 8490d315275d08cd33f801ae3a74e8fc265520f6246David Brown getContext(), call, this, mSecondaryCallName); 8500d315275d08cd33f801ae3a74e8fc265520f6246David Brown mSecondaryCallName.setText( 8510d315275d08cd33f801ae3a74e8fc265520f6246David Brown PhoneUtils.getCompactNameFromCallerInfo(infoToken.currentInfo, 8520d315275d08cd33f801ae3a74e8fc265520f6246David Brown getContext())); 8530d315275d08cd33f801ae3a74e8fc265520f6246David Brown 8540d315275d08cd33f801ae3a74e8fc265520f6246David Brown // Also pull the photo out of the current CallerInfo. 8550d315275d08cd33f801ae3a74e8fc265520f6246David Brown // (Note we assume we already have a valid photo at 8560d315275d08cd33f801ae3a74e8fc265520f6246David Brown // this point, since *presumably* the caller-id query 8570d315275d08cd33f801ae3a74e8fc265520f6246David Brown // was already run at some point *before* this call 8580d315275d08cd33f801ae3a74e8fc265520f6246David Brown // got put on hold. If there's no cached photo, just 8590d315275d08cd33f801ae3a74e8fc265520f6246David Brown // fall back to the default "unknown" image.) 8600d315275d08cd33f801ae3a74e8fc265520f6246David Brown if (infoToken.isFinal) { 8610d315275d08cd33f801ae3a74e8fc265520f6246David Brown showCachedImage(mSecondaryCallPhoto, infoToken.currentInfo); 8620d315275d08cd33f801ae3a74e8fc265520f6246David Brown } else { 8630d315275d08cd33f801ae3a74e8fc265520f6246David Brown showImage(mSecondaryCallPhoto, R.drawable.picture_unknown); 8640d315275d08cd33f801ae3a74e8fc265520f6246David Brown } 865b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 866b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 8678da4d90151c882972e15429d4d48bdaa45095d72David Brown showSecondaryCallInfo = true; 868b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 869b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 870b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 8710fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville case ACTIVE: 8720fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // CDMA: This is because in CDMA when the user originates the second call, 8730fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // although the Foreground call state is still ACTIVE in reality the network 8740fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // put the first call on hold. 87579b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink if (mApplication.phone.getPhoneType() == Phone.PHONE_TYPE_CDMA) { 8760fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville List<Connection> connections = call.getConnections(); 8770fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville if (connections.size() > 2) { 8780fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // This means that current Mobile Originated call is the not the first 3-Way 8790fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // call the user is making, which in turn tells the PhoneApp that we no 8800fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // longer know which previous caller/party had dropped out before the user 8810fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // made this call. 8820d315275d08cd33f801ae3a74e8fc265520f6246David Brown mSecondaryCallName.setText( 8830d315275d08cd33f801ae3a74e8fc265520f6246David Brown getContext().getString(R.string.card_title_in_call)); 8840d315275d08cd33f801ae3a74e8fc265520f6246David Brown showImage(mSecondaryCallPhoto, R.drawable.picture_unknown); 8850fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } else { 8860fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // This means that the current Mobile Originated call IS the first 3-Way 8870fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // and hence we display the first callers/party's info here. 8880fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville Connection conn = call.getEarliestConnection(); 889de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman PhoneUtils.CallerInfoToken infoToken = PhoneUtils.startGetCallerInfo( 8900d315275d08cd33f801ae3a74e8fc265520f6246David Brown getContext(), conn, this, mSecondaryCallName); 8910fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 892de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman // Get the compactName to be displayed, but then check that against 893de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman // the number presentation value for the call. If it's not an allowed 894de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman // presentation, then display the appropriate presentation string instead. 895de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman CallerInfo info = infoToken.currentInfo; 8960d315275d08cd33f801ae3a74e8fc265520f6246David Brown 8970d315275d08cd33f801ae3a74e8fc265520f6246David Brown String name = PhoneUtils.getCompactNameFromCallerInfo(info, getContext()); 8980d315275d08cd33f801ae3a74e8fc265520f6246David Brown boolean forceGenericPhoto = false; 899de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman if (info != null && info.numberPresentation != 900de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman Connection.PRESENTATION_ALLOWED) { 901de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman name = getPresentationString(info.numberPresentation); 9020d315275d08cd33f801ae3a74e8fc265520f6246David Brown forceGenericPhoto = true; 9030d315275d08cd33f801ae3a74e8fc265520f6246David Brown } 9040d315275d08cd33f801ae3a74e8fc265520f6246David Brown mSecondaryCallName.setText(name); 9050d315275d08cd33f801ae3a74e8fc265520f6246David Brown 9060d315275d08cd33f801ae3a74e8fc265520f6246David Brown // Also pull the photo out of the current CallerInfo. 9070d315275d08cd33f801ae3a74e8fc265520f6246David Brown // (Note we assume we already have a valid photo at 9080d315275d08cd33f801ae3a74e8fc265520f6246David Brown // this point, since *presumably* the caller-id query 9090d315275d08cd33f801ae3a74e8fc265520f6246David Brown // was already run at some point *before* this call 9100d315275d08cd33f801ae3a74e8fc265520f6246David Brown // got put on hold. If there's no cached photo, just 9110d315275d08cd33f801ae3a74e8fc265520f6246David Brown // fall back to the default "unknown" image.) 9120d315275d08cd33f801ae3a74e8fc265520f6246David Brown if (!forceGenericPhoto && infoToken.isFinal) { 9130d315275d08cd33f801ae3a74e8fc265520f6246David Brown showCachedImage(mSecondaryCallPhoto, info); 9140d315275d08cd33f801ae3a74e8fc265520f6246David Brown } else { 9150d315275d08cd33f801ae3a74e8fc265520f6246David Brown showImage(mSecondaryCallPhoto, R.drawable.picture_unknown); 916de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman } 9170fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 9188da4d90151c882972e15429d4d48bdaa45095d72David Brown showSecondaryCallInfo = true; 9190fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 9200d315275d08cd33f801ae3a74e8fc265520f6246David Brown } else { 9210d315275d08cd33f801ae3a74e8fc265520f6246David Brown // We shouldn't ever get here at all for non-CDMA devices. 9220d315275d08cd33f801ae3a74e8fc265520f6246David Brown Log.w(LOG_TAG, "displayOnHoldCallStatus: ACTIVE state on non-CDMA device"); 9238da4d90151c882972e15429d4d48bdaa45095d72David Brown showSecondaryCallInfo = false; 9240fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 9250fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville break; 9260fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 927b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project default: 928b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // There's actually no call on hold. (Presumably this call's 929b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // state is IDLE, since any other state is meaningless for the 930b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // background call.) 9318da4d90151c882972e15429d4d48bdaa45095d72David Brown showSecondaryCallInfo = false; 932b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 933b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 9348da4d90151c882972e15429d4d48bdaa45095d72David Brown 9358da4d90151c882972e15429d4d48bdaa45095d72David Brown if (showSecondaryCallInfo) { 9368da4d90151c882972e15429d4d48bdaa45095d72David Brown // Ok, we have something useful to display in the "secondary 9378da4d90151c882972e15429d4d48bdaa45095d72David Brown // call" info area. 9388da4d90151c882972e15429d4d48bdaa45095d72David Brown mSecondaryCallInfo.setVisibility(View.VISIBLE); 9398da4d90151c882972e15429d4d48bdaa45095d72David Brown 9408da4d90151c882972e15429d4d48bdaa45095d72David Brown // Watch out: there are some cases where we need to display the 9418da4d90151c882972e15429d4d48bdaa45095d72David Brown // secondary call photo but *not* the two lines of text above it. 9428da4d90151c882972e15429d4d48bdaa45095d72David Brown // Specifically, that's any state where the CallCard "upper title" is 9438da4d90151c882972e15429d4d48bdaa45095d72David Brown // in use, since the title (e.g. "Dialing" or "Call ended") might 9448da4d90151c882972e15429d4d48bdaa45095d72David Brown // collide with the secondaryCallStatus and secondaryCallName widgets. 9458da4d90151c882972e15429d4d48bdaa45095d72David Brown // 9468da4d90151c882972e15429d4d48bdaa45095d72David Brown // We detect this case by simply seeing whether or not there's any text 9478da4d90151c882972e15429d4d48bdaa45095d72David Brown // in mUpperTitle. (This is much simpler than detecting all possible 9488da4d90151c882972e15429d4d48bdaa45095d72David Brown // telephony states where the "upper title" is used! But note it does 9498da4d90151c882972e15429d4d48bdaa45095d72David Brown // rely on the fact that updateCardTitleWidgets() gets called *earlier* 9508da4d90151c882972e15429d4d48bdaa45095d72David Brown // than this method, in the CallCard.updateState() sequence...) 9518da4d90151c882972e15429d4d48bdaa45095d72David Brown boolean okToShowLabels = TextUtils.isEmpty(mUpperTitle.getText()); 9528da4d90151c882972e15429d4d48bdaa45095d72David Brown mSecondaryCallName.setVisibility(okToShowLabels ? View.VISIBLE : View.INVISIBLE); 9538da4d90151c882972e15429d4d48bdaa45095d72David Brown mSecondaryCallStatus.setVisibility(okToShowLabels ? View.VISIBLE : View.INVISIBLE); 9548da4d90151c882972e15429d4d48bdaa45095d72David Brown } else { 9558da4d90151c882972e15429d4d48bdaa45095d72David Brown // Hide the entire "secondary call" info area. 9568da4d90151c882972e15429d4d48bdaa45095d72David Brown mSecondaryCallInfo.setVisibility(View.GONE); 9578da4d90151c882972e15429d4d48bdaa45095d72David Brown } 958b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 959b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 960b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private String getCallFailedString(Call call) { 961b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Connection c = call.getEarliestConnection(); 962b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project int resID; 963b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 964b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (c == null) { 965b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("getCallFailedString: connection is null, using default values."); 966b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if this connection is null, just assume that the 967b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // default case occurs. 968b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project resID = R.string.card_title_call_ended; 969b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 970b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 971b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Connection.DisconnectCause cause = c.getDisconnectCause(); 972b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 973b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // TODO: The card *title* should probably be "Call ended" in all 974b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // cases, but if the DisconnectCause was an error condition we should 975b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // probably also display the specific failure reason somewhere... 976b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 977b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project switch (cause) { 978b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case BUSY: 979b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project resID = R.string.callFailed_userBusy; 980b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 981b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 982b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case CONGESTION: 983b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project resID = R.string.callFailed_congestion; 984b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 985b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 9861d0075e4a480a32e26a673c58b94bd706f997620Hung-ying Tyan case TIMED_OUT: 9871d0075e4a480a32e26a673c58b94bd706f997620Hung-ying Tyan resID = R.string.callFailed_timedOut; 9881d0075e4a480a32e26a673c58b94bd706f997620Hung-ying Tyan break; 9891d0075e4a480a32e26a673c58b94bd706f997620Hung-ying Tyan 99068d060b8f52c6c1176d5c55358250b18d14f2b51Hung-ying Tyan case SERVER_UNREACHABLE: 99168d060b8f52c6c1176d5c55358250b18d14f2b51Hung-ying Tyan resID = R.string.callFailed_server_unreachable; 99268d060b8f52c6c1176d5c55358250b18d14f2b51Hung-ying Tyan break; 99368d060b8f52c6c1176d5c55358250b18d14f2b51Hung-ying Tyan 9946c17cfbbf0b1b6fed8c9f32da48a854c20c24af8Hung-ying Tyan case NUMBER_UNREACHABLE: 99568d060b8f52c6c1176d5c55358250b18d14f2b51Hung-ying Tyan resID = R.string.callFailed_number_unreachable; 9966c17cfbbf0b1b6fed8c9f32da48a854c20c24af8Hung-ying Tyan break; 9976c17cfbbf0b1b6fed8c9f32da48a854c20c24af8Hung-ying Tyan 9983a635c7dd2f3283f6a1bde0e9370977c4685882fHung-ying Tyan case INVALID_CREDENTIALS: 9993a635c7dd2f3283f6a1bde0e9370977c4685882fHung-ying Tyan resID = R.string.callFailed_invalid_credentials; 10003a635c7dd2f3283f6a1bde0e9370977c4685882fHung-ying Tyan break; 10013a635c7dd2f3283f6a1bde0e9370977c4685882fHung-ying Tyan 1002a32036470be1cff3ce604c0dd83f0609243c6100Hung-ying Tyan case SERVER_ERROR: 1003a32036470be1cff3ce604c0dd83f0609243c6100Hung-ying Tyan resID = R.string.callFailed_server_error; 1004a32036470be1cff3ce604c0dd83f0609243c6100Hung-ying Tyan break; 1005a32036470be1cff3ce604c0dd83f0609243c6100Hung-ying Tyan 10063a635c7dd2f3283f6a1bde0e9370977c4685882fHung-ying Tyan case OUT_OF_NETWORK: 10073a635c7dd2f3283f6a1bde0e9370977c4685882fHung-ying Tyan resID = R.string.callFailed_out_of_network; 10083a635c7dd2f3283f6a1bde0e9370977c4685882fHung-ying Tyan break; 10093a635c7dd2f3283f6a1bde0e9370977c4685882fHung-ying Tyan 1010b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case LOST_SIGNAL: 10113800ac871d6548790ac6119bb68b9be0640af261David Krause case CDMA_DROP: 1012b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project resID = R.string.callFailed_noSignal; 1013b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 1014b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1015b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case LIMIT_EXCEEDED: 1016b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project resID = R.string.callFailed_limitExceeded; 1017b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 1018b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1019b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case POWER_OFF: 1020b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project resID = R.string.callFailed_powerOff; 1021b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 1022b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1023a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville case ICC_ERROR: 1024b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project resID = R.string.callFailed_simError; 1025b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 1026b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1027b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case OUT_OF_SERVICE: 1028b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project resID = R.string.callFailed_outOfService; 1029b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 1030b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 103122e353c3d76a3dd649c6e87244c5d94cadf64c8eHung-ying Tyan case INVALID_NUMBER: 10329eb2ffdf7b4752c7199eba6a3b88f63edc4a0ac8Naveen Kalla case UNOBTAINABLE_NUMBER: 10339eb2ffdf7b4752c7199eba6a3b88f63edc4a0ac8Naveen Kalla resID = R.string.callFailed_unobtainable_number; 10349eb2ffdf7b4752c7199eba6a3b88f63edc4a0ac8Naveen Kalla break; 10359eb2ffdf7b4752c7199eba6a3b88f63edc4a0ac8Naveen Kalla 1036b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project default: 1037b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project resID = R.string.card_title_call_ended; 1038b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 1039b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1040b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1041b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return getContext().getString(resID); 1042b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1043b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1044b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 1045b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Updates the name / photo / number / label fields on the CallCard 1046b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * based on the specified CallerInfo. 1047b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 1048b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * If the current call is a conference call, use 1049b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * updateDisplayForConference() instead. 1050b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 1051b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void updateDisplayForPerson(CallerInfo info, 10524b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project int presentation, 1053b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project boolean isTemporary, 1054b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Call call) { 1055a1c2398ade0e01d0bcfe23212bdaa18e4c19a1e5Nicolas Catania if (DBG) log("updateDisplayForPerson(" + info + ")\npresentation:" + 1056a1c2398ade0e01d0bcfe23212bdaa18e4c19a1e5Nicolas Catania presentation + " isTemporary:" + isTemporary); 1057b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1058b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // inform the state machine that we are displaying a photo. 1059b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhotoTracker.setPhotoRequest(info); 1060b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhotoTracker.setPhotoState(ContactsAsyncHelper.ImageTracker.DISPLAY_IMAGE); 1061b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1062592fb0a9a5b079f168096907bd50822f94c69448David Brown // The actual strings we're going to display onscreen: 1063592fb0a9a5b079f168096907bd50822f94c69448David Brown String displayName; 1064b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project String displayNumber = null; 1065b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project String label = null; 1066b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Uri personUri = null; 106729d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown String socialStatusText = null; 106829d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown Drawable socialStatusBadge = null; 1069b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1070b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (info != null) { 1071b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // It appears that there is a small change in behaviour with the 1072b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // PhoneUtils' startGetCallerInfo whereby if we query with an 1073b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // empty number, we will get a valid CallerInfo object, but with 1074b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // fields that are all null, and the isTemporary boolean input 1075b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // parameter as true. 1076b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1077b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // In the past, we would see a NULL callerinfo object, but this 1078b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // ends up causing null pointer exceptions elsewhere down the 1079b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // line in other cases, so we need to make this fix instead. It 1080b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // appears that this was the ONLY call to PhoneUtils 1081b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // .getCallerInfo() that relied on a NULL CallerInfo to indicate 1082b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // an unknown contact. 1083b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1084592fb0a9a5b079f168096907bd50822f94c69448David Brown // Currently, info.phoneNumber may actually be a SIP address, and 1085592fb0a9a5b079f168096907bd50822f94c69448David Brown // if so, it might sometimes include the "sip:" prefix. That 1086592fb0a9a5b079f168096907bd50822f94c69448David Brown // prefix isn't really useful to the user, though, so strip it off 1087592fb0a9a5b079f168096907bd50822f94c69448David Brown // if present. (For any other URI scheme, though, leave the 1088592fb0a9a5b079f168096907bd50822f94c69448David Brown // prefix alone.) 1089592fb0a9a5b079f168096907bd50822f94c69448David Brown // TODO: It would be cleaner for CallerInfo to explicitly support 1090592fb0a9a5b079f168096907bd50822f94c69448David Brown // SIP addresses instead of overloading the "phoneNumber" field. 1091592fb0a9a5b079f168096907bd50822f94c69448David Brown // Then we could remove this hack, and instead ask the CallerInfo 1092592fb0a9a5b079f168096907bd50822f94c69448David Brown // for a "user visible" form of the SIP address. 1093592fb0a9a5b079f168096907bd50822f94c69448David Brown String number = info.phoneNumber; 10949ec000a412524ed98d486ca4b160dd1e885db574David Brown if ((number != null) && number.startsWith("sip:")) { 1095592fb0a9a5b079f168096907bd50822f94c69448David Brown number = number.substring(4); 1096592fb0a9a5b079f168096907bd50822f94c69448David Brown } 1097592fb0a9a5b079f168096907bd50822f94c69448David Brown 1098b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (TextUtils.isEmpty(info.name)) { 1099592fb0a9a5b079f168096907bd50822f94c69448David Brown // No valid "name" in the CallerInfo, so fall back to 1100592fb0a9a5b079f168096907bd50822f94c69448David Brown // something else. 1101a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown // (Typically, we promote the phone number up to the "name" slot 1102a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown // onscreen, and possibly display a descriptive string in the 1103a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown // "number" slot.) 1104592fb0a9a5b079f168096907bd50822f94c69448David Brown if (TextUtils.isEmpty(number)) { 1105a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown // No name *or* number! Display a generic "unknown" string 1106a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown // (or potentially some other default based on the presentation.) 1107592fb0a9a5b079f168096907bd50822f94c69448David Brown displayName = getPresentationString(presentation); 1108a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown if (DBG) log(" ==> no name *or* number! displayName = " + displayName); 1109e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai } else if (presentation != Connection.PRESENTATION_ALLOWED) { 1110e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai // This case should never happen since the network should never send a phone # 1111e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai // AND a restricted presentation. However we leave it here in case of weird 1112e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai // network behavior 1113592fb0a9a5b079f168096907bd50822f94c69448David Brown displayName = getPresentationString(presentation); 1114a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown if (DBG) log(" ==> presentation not allowed! displayName = " + displayName); 1115e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai } else if (!TextUtils.isEmpty(info.cnapName)) { 1116a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown // No name, but we do have a valid CNAP name, so use that. 1117592fb0a9a5b079f168096907bd50822f94c69448David Brown displayName = info.cnapName; 1118e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai info.name = info.cnapName; 1119592fb0a9a5b079f168096907bd50822f94c69448David Brown displayNumber = number; 1120a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown if (DBG) log(" ==> cnapName available: displayName '" 1121a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown + displayName + "', displayNumber '" + displayNumber + "'"); 1122b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 1123a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown // No name; all we have is a number. This is the typical 1124a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown // case when an incoming call doesn't match any contact. 1125a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown 1126a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown // Promote the phone number up to the "name" slot, and use 1127a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown // the "number" slot for a geographical description string 1128a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown // if available. 1129592fb0a9a5b079f168096907bd50822f94c69448David Brown displayName = number; 1130a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown displayNumber = info.geoDescription; // may be null 1131a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown if (DBG) log(" ==> no name; falling back to number: displayName '" 1132a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown + displayName + "', displayNumber '" + displayNumber + "'"); 1133b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1134b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 1135592fb0a9a5b079f168096907bd50822f94c69448David Brown // We do have a valid "name" in the CallerInfo. Display that 1136592fb0a9a5b079f168096907bd50822f94c69448David Brown // in the "name" slot, and the phone number in the "number" slot. 1137e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai if (presentation != Connection.PRESENTATION_ALLOWED) { 1138e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai // This case should never happen since the network should never send a name 1139e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai // AND a restricted presentation. However we leave it here in case of weird 1140e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai // network behavior 1141592fb0a9a5b079f168096907bd50822f94c69448David Brown displayName = getPresentationString(presentation); 1142a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown if (DBG) log(" ==> valid name, but presentation not allowed!" 1143a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown + " displayName = " + displayName); 1144e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai } else { 1145592fb0a9a5b079f168096907bd50822f94c69448David Brown displayName = info.name; 1146592fb0a9a5b079f168096907bd50822f94c69448David Brown displayNumber = number; 1147e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai label = info.phoneLabel; 1148a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown if (DBG) log(" ==> name is present in CallerInfo: displayName '" 1149a232063e9bb9f7b8875a24af212287ba0d2cd0c3David Brown + displayName + "', displayNumber '" + displayNumber + "'"); 1150e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai } 1151b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 11523d6d70562622660e581b53308e675386d299dd19Dmitri Plotnikov personUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, info.person_id); 115302d1c632adde606031c1fe6ea0e3be1e288fd6c6David Brown if (DBG) log("- got personUri: '" + personUri 115402d1c632adde606031c1fe6ea0e3be1e288fd6c6David Brown + "', based on info.person_id: " + info.person_id); 1155b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 1156592fb0a9a5b079f168096907bd50822f94c69448David Brown displayName = getPresentationString(presentation); 1157b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 11580fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 11590fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville if (call.isGeneric()) { 11600fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville mName.setText(R.string.card_title_in_call); 11610fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } else { 1162592fb0a9a5b079f168096907bd50822f94c69448David Brown mName.setText(displayName); 11630fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 1164b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mName.setVisibility(View.VISIBLE); 1165b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1166b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Update mPhoto 1167b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if the temporary flag is set, we know we'll be getting another call after 1168b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // the CallerInfo has been correctly updated. So, we can skip the image 1169b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // loading until then. 1170b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1171b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // If the photoResource is filled in for the CallerInfo, (like with the 1172b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Emergency Number case), then we can just set the photo image without 1173b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // requesting for an image load. Please refer to CallerInfoAsyncQuery.java 1174b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // for cases where CallerInfo.photoResource may be set. We can also avoid 1175b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // the image load step if the image data is cached. 1176b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (isTemporary && (info == null || !info.isCachedPhotoCurrent)) { 1177b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhoto.setVisibility(View.INVISIBLE); 1178b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else if (info != null && info.photoResource != 0){ 1179b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project showImage(mPhoto, info.photoResource); 1180b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else if (!showCachedImage(mPhoto, info)) { 1181b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Load the image with a callback to update the image state. 1182a1c2398ade0e01d0bcfe23212bdaa18e4c19a1e5Nicolas Catania // Use the default unknown picture while the query is running. 1183a1c2398ade0e01d0bcfe23212bdaa18e4c19a1e5Nicolas Catania ContactsAsyncHelper.updateImageViewWithContactPhotoAsync( 1184a1c2398ade0e01d0bcfe23212bdaa18e4c19a1e5Nicolas Catania info, 0, this, call, getContext(), mPhoto, personUri, R.drawable.picture_unknown); 1185b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 11866d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown // And no matter what, on all devices, we never see the "manage 11876d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown // conference" button in this state. 11886d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown mManageConferencePhotoButton.setVisibility(View.INVISIBLE); 11896d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown 11900fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville if (displayNumber != null && !call.isGeneric()) { 1191b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhoneNumber.setText(displayNumber); 11929688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown mPhoneNumber.setTextColor(mTextColorDefaultSecondary); 1193b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhoneNumber.setVisibility(View.VISIBLE); 1194b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 1195b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhoneNumber.setVisibility(View.GONE); 1196b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1197b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1198153e79d8d413b1ccd4abf55a8dbe4e266aa92799Paul Berman if (label != null && !call.isGeneric()) { 1199b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mLabel.setText(label); 1200b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mLabel.setVisibility(View.VISIBLE); 1201b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 1202b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mLabel.setVisibility(View.GONE); 1203b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1204b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 12059d14e16e8214b4a396dad293b6f0941608ee4798David Brown // Other text fields: 12069d14e16e8214b4a396dad293b6f0941608ee4798David Brown updateCallTypeLabel(call); 12079d14e16e8214b4a396dad293b6f0941608ee4798David Brown updateSocialStatus(socialStatusText, socialStatusBadge, call); // Currently unused 120829d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown } 1209b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 12104b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project private String getPresentationString(int presentation) { 12114b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project String name = getContext().getString(R.string.unknown); 12124b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project if (presentation == Connection.PRESENTATION_RESTRICTED) { 12134b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project name = getContext().getString(R.string.private_num); 12144b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project } else if (presentation == Connection.PRESENTATION_PAYPHONE) { 12154b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project name = getContext().getString(R.string.payphone); 12164b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project } 12174b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project return name; 12184b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project } 12194b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project 1220b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 1221b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Updates the name / photo / number / label fields 1222b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * for the special "conference call" state. 1223b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 1224b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * If the current call has only a single connection, use 1225b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * updateDisplayForPerson() instead. 1226b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 1227872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan private void updateDisplayForConference(Call call) { 1228b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("updateDisplayForConference()..."); 1229b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1230872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan int phoneType = call.getPhone().getPhoneType(); 123179b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink if (phoneType == Phone.PHONE_TYPE_CDMA) { 12320fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // This state corresponds to both 3-Way merged call and 12330fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // Call Waiting accepted call. 123429d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown // In this case we display the UI in a "generic" state, with 123529d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown // the generic "dialing" icon and no caller information, 123629d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown // because in this state in CDMA the user does not really know 123729d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown // which caller party he is talking to. 12380fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville showImage(mPhoto, R.drawable.picture_dialing); 12390fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville mName.setText(R.string.card_title_in_call); 1240872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan } else if ((phoneType == Phone.PHONE_TYPE_GSM) 1241872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan || (phoneType == Phone.PHONE_TYPE_SIP)) { 12426d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown if (mInCallScreen.isTouchUiEnabled()) { 12436d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown // Display the "manage conference" button in place of the photo. 12446d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown mManageConferencePhotoButton.setVisibility(View.VISIBLE); 12456d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown mPhoto.setVisibility(View.INVISIBLE); // Not GONE, since that would break 12466d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown // other views in our RelativeLayout. 12476d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown } else { 12486d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown // Display the "conference call" image in the photo slot, 12496d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown // with no other information. 12506d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown showImage(mPhoto, R.drawable.picture_conference); 12516d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown } 12520fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville mName.setText(R.string.card_title_conf_call); 125379b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink } else { 125479b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink throw new IllegalStateException("Unexpected phone type: " + phoneType); 12550fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 1256b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1257b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mName.setVisibility(View.VISIBLE); 1258b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1259b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // TODO: For a conference call, the "phone number" slot is specced 1260b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // to contain a summary of who's on the call, like "Bill Foldes 1261b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // and Hazel Nutt" or "Bill Foldes and 2 others". 1262b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // But for now, just hide it: 1263b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhoneNumber.setVisibility(View.GONE); 1264b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mLabel.setVisibility(View.GONE); 1265b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 12669d14e16e8214b4a396dad293b6f0941608ee4798David Brown // Other text fields: 12679d14e16e8214b4a396dad293b6f0941608ee4798David Brown updateCallTypeLabel(call); 12689d14e16e8214b4a396dad293b6f0941608ee4798David Brown updateSocialStatus(null, null, null); // socialStatus is never visible in this state 126929d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown 127029d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown // TODO: for a GSM conference call, since we do actually know who 127129d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown // you're talking to, consider also showing names / numbers / 127229d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown // photos of some of the people on the conference here, so you can 127329d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown // see that info without having to click "Manage conference". We 127429d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown // probably have enough space to show info for 2 people, at least. 1275b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // 1276b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // To do this, our caller would pass us the activeConnections 1277b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // list, and we'd call PhoneUtils.getCallerInfo() separately for 1278b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // each connection. 1279b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1280b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1281b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 1282b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Updates the CallCard "photo" IFF the specified Call is in a state 1283b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * that needs a special photo (like "busy" or "dialing".) 1284b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 1285b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * If the current call does not require a special image in the "photo" 1286b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * slot onscreen, don't do anything, since presumably the photo image 1287b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * has already been set (to the photo of the person we're talking, or 1288b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * the generic "picture_unknown" image, or the "conference call" 1289b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * image.) 1290b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 1291b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void updatePhotoForCallState(Call call) { 1292b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("updatePhotoForCallState(" + call + ")..."); 1293b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project int photoImageResource = 0; 1294b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1295b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Check for the (relatively few) telephony states that need a 1296b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // special image in the "photo" slot. 1297b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Call.State state = call.getState(); 1298b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project switch (state) { 1299b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case DISCONNECTED: 1300b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Display the special "busy" photo for BUSY or CONGESTION. 1301b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Otherwise (presumably the normal "call ended" state) 1302b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // leave the photo alone. 1303b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Connection c = call.getEarliestConnection(); 1304b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if the connection is null, we assume the default case, 1305b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // otherwise update the image resource normally. 1306b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (c != null) { 1307b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Connection.DisconnectCause cause = c.getDisconnectCause(); 1308b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if ((cause == Connection.DisconnectCause.BUSY) 1309b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project || (cause == Connection.DisconnectCause.CONGESTION)) { 1310b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project photoImageResource = R.drawable.picture_busy; 1311b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1312b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else if (DBG) { 1313b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project log("updatePhotoForCallState: connection is null, ignoring."); 1314b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1315b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1316b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // TODO: add special images for any other DisconnectCauses? 1317b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 1318b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1319b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case ALERTING: 132044e42e4eccd8ecdcdcca166c9f6f35a4d6c65591Nicolas Catania case DIALING: 1321b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project default: 1322b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Leave the photo alone in all other states. 1323b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // If this call is an individual call, and the image is currently 1324b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // displaying a state, (rather than a photo), we'll need to update 1325b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // the image. 1326b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // This is for the case where we've been displaying the state and 1327b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // now we need to restore the photo. This can happen because we 1328b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // only query the CallerInfo once, and limit the number of times 1329b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // the image is loaded. (So a state image may overwrite the photo 1330b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // and we would otherwise have no way of displaying the photo when 1331b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // the state goes away.) 1332b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1333b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if the photoResource field is filled-in in the Connection's 1334b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // caller info, then we can just use that instead of requesting 1335b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // for a photo load. 1336b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1337b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // look for the photoResource if it is available. 1338b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project CallerInfo ci = null; 1339b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project { 13400fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville Connection conn = null; 1341872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan int phoneType = call.getPhone().getPhoneType(); 134279b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink if (phoneType == Phone.PHONE_TYPE_CDMA) { 13430fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville conn = call.getLatestConnection(); 1344872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan } else if ((phoneType == Phone.PHONE_TYPE_GSM) 1345872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan || (phoneType == Phone.PHONE_TYPE_SIP)) { 13460fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville conn = call.getEarliestConnection(); 134779b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink } else { 134879b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink throw new IllegalStateException("Unexpected phone type: " + phoneType); 13490fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 13500fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 1351b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (conn != null) { 1352b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Object o = conn.getUserData(); 1353b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (o instanceof CallerInfo) { 1354b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project ci = (CallerInfo) o; 1355b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else if (o instanceof PhoneUtils.CallerInfoToken) { 1356b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project ci = ((PhoneUtils.CallerInfoToken) o).currentInfo; 1357b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1358b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1359b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1360b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1361b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (ci != null) { 1362b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project photoImageResource = ci.photoResource; 1363b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1364b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1365b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // If no photoResource found, check to see if this is a conference call. If 1366b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // it is not a conference call: 1367b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // 1. Try to show the cached image 1368b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // 2. If the image is not cached, check to see if a load request has been 1369b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // made already. 1370b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // 3. If the load request has not been made [DISPLAY_DEFAULT], start the 1371b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // request and note that it has started by updating photo state with 1372b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // [DISPLAY_IMAGE]. 1373b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Load requests started in (3) use a placeholder image of -1 to hide the 1374b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // image by default. Please refer to CallerInfoAsyncQuery.java for cases 1375b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // where CallerInfo.photoResource may be set. 1376b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (photoImageResource == 0) { 1377b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (!PhoneUtils.isConferenceCall(call)) { 1378b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (!showCachedImage(mPhoto, ci) && (mPhotoTracker.getPhotoState() == 1379b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project ContactsAsyncHelper.ImageTracker.DISPLAY_DEFAULT)) { 1380b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project ContactsAsyncHelper.updateImageViewWithContactPhotoAsync(ci, 1381b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project getContext(), mPhoto, mPhotoTracker.getPhotoUri(), -1); 1382b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhotoTracker.setPhotoState( 1383b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project ContactsAsyncHelper.ImageTracker.DISPLAY_IMAGE); 1384b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1385b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1386b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 1387b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project showImage(mPhoto, photoImageResource); 1388b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhotoTracker.setPhotoState(ContactsAsyncHelper.ImageTracker.DISPLAY_IMAGE); 1389b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return; 1390b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1391b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 1392b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1393b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1394b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (photoImageResource != 0) { 1395b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("- overrriding photo image: " + photoImageResource); 1396b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project showImage(mPhoto, photoImageResource); 1397b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Track the image state. 1398b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhotoTracker.setPhotoState(ContactsAsyncHelper.ImageTracker.DISPLAY_DEFAULT); 1399b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1400b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1401b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1402b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 1403b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Try to display the cached image from the callerinfo object. 1404b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 1405b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * @return true if we were able to find the image in the cache, false otherwise. 1406b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 14070d315275d08cd33f801ae3a74e8fc265520f6246David Brown private static final boolean showCachedImage(ImageView view, CallerInfo ci) { 1408b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if ((ci != null) && ci.isCachedPhotoCurrent) { 1409b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (ci.cachedPhoto != null) { 1410b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project showImage(view, ci.cachedPhoto); 1411b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 1412b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project showImage(view, R.drawable.picture_unknown); 1413b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1414b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return true; 1415b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1416b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return false; 1417b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1418b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1419b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** Helper function to display the resource in the imageview AND ensure its visibility.*/ 1420b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private static final void showImage(ImageView view, int resource) { 1421b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project view.setImageResource(resource); 1422b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project view.setVisibility(View.VISIBLE); 1423b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1424b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1425b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** Helper function to display the drawable in the imageview AND ensure its visibility.*/ 1426b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private static final void showImage(ImageView view, Drawable drawable) { 1427b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project view.setImageDrawable(drawable); 1428b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project view.setVisibility(View.VISIBLE); 1429b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1430b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1431b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 1432b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Returns the "Menu button hint" TextView (which is manipulated 1433b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * directly by the InCallScreen.) 1434b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * @see InCallScreen.updateMenuButtonHint() 1435b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 1436b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /* package */ TextView getMenuButtonHint() { 1437b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return mMenuButtonHint; 1438b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1439b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1440b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 1441b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Sets the left and right margins of the specified ViewGroup (whose 1442b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * LayoutParams object which must inherit from 1443b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * ViewGroup.MarginLayoutParams.) 1444b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 1445b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * TODO: Is there already a convenience method like this somewhere? 1446b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 1447b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void setSideMargins(ViewGroup vg, int margin) { 1448b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project ViewGroup.MarginLayoutParams lp = 1449b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project (ViewGroup.MarginLayoutParams) vg.getLayoutParams(); 1450b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Equivalent to setting android:layout_marginLeft/Right in XML 1451b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project lp.leftMargin = margin; 1452b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project lp.rightMargin = margin; 1453b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project vg.setLayoutParams(lp); 1454b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1455b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 14568bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project /** 14578bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project * Sets the CallCard "upper title". Also, depending on the passed-in 14588bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project * Call state, possibly display an icon along with the title. 14598bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project */ 146034a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown private void setUpperTitle(String title, int color, Call.State state) { 14618bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project mUpperTitle.setText(title); 146234a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown mUpperTitle.setTextColor(color); 14638bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project 14648bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project int bluetoothIconId = 0; 146534a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown if (!TextUtils.isEmpty(title) 146634a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown && ((state == Call.State.INCOMING) || (state == Call.State.WAITING)) 14670fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville && mApplication.showBluetoothIndication()) { 14688bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project // Display the special bluetooth icon also, if this is an incoming 14698bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project // call and the audio will be routed to bluetooth. 14708bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project bluetoothIconId = R.drawable.ic_incoming_call_bluetooth; 14718bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project } 14728bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project 14738bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project mUpperTitle.setCompoundDrawablesWithIntrinsicBounds(bluetoothIconId, 0, 0, 0); 147429d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown if (bluetoothIconId != 0) mUpperTitle.setCompoundDrawablePadding((int) (mDensity * 5)); 14758bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project } 14768bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project 1477af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville /** 147834a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown * Clears the CallCard "upper title", for states (like a normal 147934a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown * ongoing call) where we don't use any "title" at all. 148034a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown */ 148134a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown private void clearUpperTitle() { 148234a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown setUpperTitle("", 0, Call.State.IDLE); // Use dummy values for "color" and "state" 148334a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown } 148434a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown 148534a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown /** 1486f3602b0659d01fef19159e7111be76102549f7a1David Brown * Returns the special card title used in emergency callback mode (ECM), 1487f3602b0659d01fef19159e7111be76102549f7a1David Brown * which shows your own phone number. 1488f3602b0659d01fef19159e7111be76102549f7a1David Brown */ 1489f3602b0659d01fef19159e7111be76102549f7a1David Brown private String getECMCardTitle(Context context, Phone phone) { 1490f3602b0659d01fef19159e7111be76102549f7a1David Brown String rawNumber = phone.getLine1Number(); // may be null or empty 1491f3602b0659d01fef19159e7111be76102549f7a1David Brown String formattedNumber; 1492f3602b0659d01fef19159e7111be76102549f7a1David Brown if (!TextUtils.isEmpty(rawNumber)) { 1493f3602b0659d01fef19159e7111be76102549f7a1David Brown formattedNumber = PhoneNumberUtils.formatNumber(rawNumber); 1494f3602b0659d01fef19159e7111be76102549f7a1David Brown } else { 1495f3602b0659d01fef19159e7111be76102549f7a1David Brown formattedNumber = context.getString(R.string.unknown); 1496f3602b0659d01fef19159e7111be76102549f7a1David Brown } 1497f3602b0659d01fef19159e7111be76102549f7a1David Brown String titleFormat = context.getString(R.string.card_title_my_phone_number); 1498f3602b0659d01fef19159e7111be76102549f7a1David Brown return String.format(titleFormat, formattedNumber); 1499f3602b0659d01fef19159e7111be76102549f7a1David Brown } 1500f3602b0659d01fef19159e7111be76102549f7a1David Brown 1501f3602b0659d01fef19159e7111be76102549f7a1David Brown /** 15029d14e16e8214b4a396dad293b6f0941608ee4798David Brown * Updates the "Call type" label, based on the current foreground call. 15039d14e16e8214b4a396dad293b6f0941608ee4798David Brown * This is a special label and/or branding we display for certain 15049d14e16e8214b4a396dad293b6f0941608ee4798David Brown * kinds of calls. 15059d14e16e8214b4a396dad293b6f0941608ee4798David Brown * 15069d14e16e8214b4a396dad293b6f0941608ee4798David Brown * (So far, this is used only for SIP calls, which get an 15079d14e16e8214b4a396dad293b6f0941608ee4798David Brown * "Internet call" label. TODO: But eventually, the telephony 15089d14e16e8214b4a396dad293b6f0941608ee4798David Brown * layer might allow each pluggable "provider" to specify a string 15099d14e16e8214b4a396dad293b6f0941608ee4798David Brown * and/or icon to be displayed here.) 15109d14e16e8214b4a396dad293b6f0941608ee4798David Brown */ 15119d14e16e8214b4a396dad293b6f0941608ee4798David Brown private void updateCallTypeLabel(Call call) { 15129d14e16e8214b4a396dad293b6f0941608ee4798David Brown int phoneType = (call != null) ? call.getPhone().getPhoneType() : Phone.PHONE_TYPE_NONE; 15139d14e16e8214b4a396dad293b6f0941608ee4798David Brown if (phoneType == Phone.PHONE_TYPE_SIP) { 15149d14e16e8214b4a396dad293b6f0941608ee4798David Brown mCallTypeLabel.setVisibility(View.VISIBLE); 15159d14e16e8214b4a396dad293b6f0941608ee4798David Brown mCallTypeLabel.setText(R.string.incall_call_type_label_sip); 15169d14e16e8214b4a396dad293b6f0941608ee4798David Brown mCallTypeLabel.setTextColor(mTextColorCallTypeSip); 15179d14e16e8214b4a396dad293b6f0941608ee4798David Brown // If desired, we could also display a "badge" next to the label, as follows: 15189d14e16e8214b4a396dad293b6f0941608ee4798David Brown // mCallTypeLabel.setCompoundDrawablesWithIntrinsicBounds( 15199d14e16e8214b4a396dad293b6f0941608ee4798David Brown // callTypeSpecificBadge, null, null, null); 15209d14e16e8214b4a396dad293b6f0941608ee4798David Brown // mCallTypeLabel.setCompoundDrawablePadding((int) (mDensity * 6)); 15219d14e16e8214b4a396dad293b6f0941608ee4798David Brown } else { 15229d14e16e8214b4a396dad293b6f0941608ee4798David Brown mCallTypeLabel.setVisibility(View.GONE); 15239d14e16e8214b4a396dad293b6f0941608ee4798David Brown } 15249d14e16e8214b4a396dad293b6f0941608ee4798David Brown } 15259d14e16e8214b4a396dad293b6f0941608ee4798David Brown 15269d14e16e8214b4a396dad293b6f0941608ee4798David Brown /** 15279d14e16e8214b4a396dad293b6f0941608ee4798David Brown * Updates the "social status" label with the specified text and 15289d14e16e8214b4a396dad293b6f0941608ee4798David Brown * (optional) badge. 15299d14e16e8214b4a396dad293b6f0941608ee4798David Brown */ 15309d14e16e8214b4a396dad293b6f0941608ee4798David Brown private void updateSocialStatus(String socialStatusText, 15319d14e16e8214b4a396dad293b6f0941608ee4798David Brown Drawable socialStatusBadge, 15329d14e16e8214b4a396dad293b6f0941608ee4798David Brown Call call) { 15339d14e16e8214b4a396dad293b6f0941608ee4798David Brown // The socialStatus field is *only* visible while an incoming call 15349d14e16e8214b4a396dad293b6f0941608ee4798David Brown // is ringing, never in any other call state. 15359d14e16e8214b4a396dad293b6f0941608ee4798David Brown if ((socialStatusText != null) 15369d14e16e8214b4a396dad293b6f0941608ee4798David Brown && (call != null) 15379d14e16e8214b4a396dad293b6f0941608ee4798David Brown && call.isRinging() 15389d14e16e8214b4a396dad293b6f0941608ee4798David Brown && !call.isGeneric()) { 15399d14e16e8214b4a396dad293b6f0941608ee4798David Brown mSocialStatus.setVisibility(View.VISIBLE); 15409d14e16e8214b4a396dad293b6f0941608ee4798David Brown mSocialStatus.setText(socialStatusText); 15419d14e16e8214b4a396dad293b6f0941608ee4798David Brown mSocialStatus.setCompoundDrawablesWithIntrinsicBounds( 15429d14e16e8214b4a396dad293b6f0941608ee4798David Brown socialStatusBadge, null, null, null); 15439d14e16e8214b4a396dad293b6f0941608ee4798David Brown mSocialStatus.setCompoundDrawablePadding((int) (mDensity * 6)); 15449d14e16e8214b4a396dad293b6f0941608ee4798David Brown } else { 15459d14e16e8214b4a396dad293b6f0941608ee4798David Brown mSocialStatus.setVisibility(View.GONE); 15469d14e16e8214b4a396dad293b6f0941608ee4798David Brown } 15479d14e16e8214b4a396dad293b6f0941608ee4798David Brown } 15489d14e16e8214b4a396dad293b6f0941608ee4798David Brown 15499d14e16e8214b4a396dad293b6f0941608ee4798David Brown /** 1550af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * Hides the top-level UI elements of the call card: The "main 1551af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * call card" element representing the current active or ringing call, 1552af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * and also the info areas for "ongoing" or "on hold" calls in some 1553af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * states. 1554af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * 1555af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * This is intended to be used in special states where the normal 1556af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * in-call UI is totally replaced by some other UI, like OTA mode on a 1557af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * CDMA device. 1558af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * 1559af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * To bring back the regular CallCard UI, just re-run the normal 1560af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * updateState() call sequence. 1561af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville */ 1562af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville public void hideCallCardElements() { 15630d315275d08cd33f801ae3a74e8fc265520f6246David Brown mPrimaryCallInfo.setVisibility(View.GONE); 15640d315275d08cd33f801ae3a74e8fc265520f6246David Brown mSecondaryCallInfo.setVisibility(View.GONE); 1565af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville } 1566b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 15679688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown /* 15689688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown * Updates the hint (like "Rotate to answer") that we display while 15699688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown * the user is dragging the incoming call RotarySelector widget. 15709688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown */ 1571ea505da2d0ebae37b07fece15297b5432fe96c5dJim Miller /* package */ void setIncomingCallWidgetHint(int hintTextResId, int hintColorResId) { 1572ea505da2d0ebae37b07fece15297b5432fe96c5dJim Miller mIncomingCallWidgetHintTextResId = hintTextResId; 1573ea505da2d0ebae37b07fece15297b5432fe96c5dJim Miller mIncomingCallWidgetHintColorResId = hintColorResId; 15749688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown } 15759688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown 15766d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown // View.OnClickListener implementation 15776d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown public void onClick(View view) { 15786d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown int id = view.getId(); 15796d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown if (DBG) log("onClick(View " + view + ", id " + id + ")..."); 15806d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown 15816d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown switch (id) { 15826d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown case R.id.manageConferencePhotoButton: 15836d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown // A click on anything here gets forwarded 15846d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown // straight to the InCallScreen. 15856d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown mInCallScreen.handleOnscreenButtonClick(id); 15866d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown break; 15876d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown 15886d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown default: 15896d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown Log.w(LOG_TAG, "onClick: unexpected click: View " + view + ", id " + id); 15906d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown break; 15916d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown } 15926d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown } 15936d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown 1594dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown // Accessibility event support. 1595dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown // Since none of the CallCard elements are focusable, we need to manually 1596dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown // fill in the AccessibilityEvent here (so that the name / number / etc will 1597dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown // get pronounced by a screen reader, for example.) 1598dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown @Override 1599dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { 1600dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown dispatchPopulateAccessibilityEvent(event, mUpperTitle); 1601dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown dispatchPopulateAccessibilityEvent(event, mPhoto); 1602dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown dispatchPopulateAccessibilityEvent(event, mManageConferencePhotoButton); 1603dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown dispatchPopulateAccessibilityEvent(event, mName); 1604dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown dispatchPopulateAccessibilityEvent(event, mPhoneNumber); 1605dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown dispatchPopulateAccessibilityEvent(event, mLabel); 1606dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown dispatchPopulateAccessibilityEvent(event, mSocialStatus); 1607dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown dispatchPopulateAccessibilityEvent(event, mSecondaryCallName); 1608dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown dispatchPopulateAccessibilityEvent(event, mSecondaryCallStatus); 1609dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown dispatchPopulateAccessibilityEvent(event, mSecondaryCallPhoto); 1610dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown return true; 1611dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown } 1612dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown 1613dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown private void dispatchPopulateAccessibilityEvent(AccessibilityEvent event, View view) { 1614dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown List<CharSequence> eventText = event.getText(); 1615dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown int size = eventText.size(); 1616dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown view.dispatchPopulateAccessibilityEvent(event); 1617dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown // if no text added write null to keep relative position 1618dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown if (size == eventText.size()) { 1619dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown eventText.add(null); 1620dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown } 1621dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown } 1622dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown 16239688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown 1624b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Debugging / testing code 1625b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1626b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void log(String msg) { 1627796c70c99bc39295bf685061056f06ab8949c742David Brown Log.d(LOG_TAG, msg); 1628b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1629b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project} 1630