CallCard.java revision 872a3a7af50ce6a4efb180336614bddefe102ac5
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; 25b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.text.TextUtils; 26b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.text.format.DateUtils; 27b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.util.AttributeSet; 28b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.util.Log; 29b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.view.LayoutInflater; 30b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.view.View; 31b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.view.ViewGroup; 32dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brownimport android.view.accessibility.AccessibilityEvent; 336d5544932495d81ff7ce53f4678c4beb25acc1b0David Brownimport android.widget.Button; 34b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.widget.FrameLayout; 35b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.widget.ImageView; 36b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.widget.TextView; 37b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 386b7d0da33af02960736da204eb7a25ccf91d5396David Brownimport com.android.internal.telephony.Call; 396b7d0da33af02960736da204eb7a25ccf91d5396David Brownimport com.android.internal.telephony.CallerInfo; 406b7d0da33af02960736da204eb7a25ccf91d5396David Brownimport com.android.internal.telephony.CallerInfoAsyncQuery; 416b7d0da33af02960736da204eb7a25ccf91d5396David Brownimport com.android.internal.telephony.Connection; 426b7d0da33af02960736da204eb7a25ccf91d5396David Brownimport com.android.internal.telephony.Phone; 438343169cc89621d46dce86449f5ee1ff5d3a4919John Wangimport com.android.internal.telephony.CallManager; 446b7d0da33af02960736da204eb7a25ccf91d5396David Brown 450fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Savilleimport java.util.List; 460fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 476b7d0da33af02960736da204eb7a25ccf91d5396David Brown 48b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project/** 49b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * "Call card" UI element: the in-call screen contains a tiled layout of call 50b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * cards, each representing the state of a current "call" (ie. an active call, 51b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * a call on hold, or an incoming call.) 52b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 53b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectpublic class CallCard extends FrameLayout 54b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project implements CallTime.OnTickListener, CallerInfoAsyncQuery.OnQueryCompleteListener, 556d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown ContactsAsyncHelper.OnImageLoadCompleteListener, View.OnClickListener { 56796c70c99bc39295bf685061056f06ab8949c742David Brown private static final String LOG_TAG = "CallCard"; 57796c70c99bc39295bf685061056f06ab8949c742David Brown private static final boolean DBG = (PhoneApp.DBG_LEVEL >= 2); 58b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 598bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project /** 608bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project * Reference to the InCallScreen activity that owns us. This may be 618bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project * null if we haven't been initialized yet *or* after the InCallScreen 628bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project * activity has been destroyed. 638bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project */ 648bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project private InCallScreen mInCallScreen; 658bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project 660fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // Phone app instance 670fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville private PhoneApp mApplication; 680fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 69b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Top-level subviews of the CallCard 700d315275d08cd33f801ae3a74e8fc265520f6246David Brown private ViewGroup mPrimaryCallInfo; 710d315275d08cd33f801ae3a74e8fc265520f6246David Brown private ViewGroup mSecondaryCallInfo; 72b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 7334a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // Title and elapsed-time widgets 74b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private TextView mUpperTitle; 75b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private TextView mElapsedTime; 76b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 7734a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // Text colors, used for various labels / titles 789688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown private int mTextColorDefaultPrimary; 799688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown private int mTextColorDefaultSecondary; 80b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private int mTextColorConnected; 818bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project private int mTextColorConnectedBluetooth; 82b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private int mTextColorEnded; 83b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private int mTextColorOnHold; 84b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 850d315275d08cd33f801ae3a74e8fc265520f6246David Brown // The main block of info about the "primary" or "active" call, 860d315275d08cd33f801ae3a74e8fc265520f6246David Brown // including photo / name / phone number / etc. 87b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private ImageView mPhoto; 886d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown private Button mManageConferencePhotoButton; // Possibly shown in place of mPhoto 89b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private TextView mName; 90b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private TextView mPhoneNumber; 91b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private TextView mLabel; 9229d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown private TextView mSocialStatus; 93b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 940d315275d08cd33f801ae3a74e8fc265520f6246David Brown // Info about the "secondary" call, which is the "call on hold" when 950d315275d08cd33f801ae3a74e8fc265520f6246David Brown // two lines are in use. 960d315275d08cd33f801ae3a74e8fc265520f6246David Brown private TextView mSecondaryCallName; 970d315275d08cd33f801ae3a74e8fc265520f6246David Brown private TextView mSecondaryCallStatus; 980d315275d08cd33f801ae3a74e8fc265520f6246David Brown private ImageView mSecondaryCallPhoto; 99b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 100b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Menu button hint 101b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private TextView mMenuButtonHint; 102b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1039688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown // Onscreen hint for the incoming call RotarySelector widget. 1049688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown private int mRotarySelectorHintTextResId; 1059688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown private int mRotarySelectorHintColorResId; 1069688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown 107b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private CallTime mCallTime; 108b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 109b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Track the state for the photo. 110b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private ContactsAsyncHelper.ImageTracker mPhotoTracker; 111b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 11229d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown // Cached DisplayMetrics density. 11329d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown private float mDensity; 11429d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown 115b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public CallCard(Context context, AttributeSet attrs) { 116b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project super(context, attrs); 117b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 118b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("CallCard constructor..."); 119b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("- this = " + this); 120b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("- context " + context + ", attrs " + attrs); 121b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 122b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Inflate the contents of this CallCard, and add it (to ourself) as a child. 123b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project LayoutInflater inflater = LayoutInflater.from(context); 124b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project inflater.inflate( 125b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project R.layout.call_card, // resource 126b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project this, // root 127b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project true); 128b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1290fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville mApplication = PhoneApp.getInstance(); 1300fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 131b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mCallTime = new CallTime(this); 132b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 133b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // create a new object to track the state for the photo. 134b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhotoTracker = new ContactsAsyncHelper.ImageTracker(); 13529d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown 13629d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown mDensity = getResources().getDisplayMetrics().density; 13729d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown if (DBG) log("- Density: " + mDensity); 138b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 139b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1408bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project void setInCallScreenInstance(InCallScreen inCallScreen) { 1418bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project mInCallScreen = inCallScreen; 1428bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project } 1438bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project 144b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public void onTickForCallTimeElapsed(long timeElapsed) { 145b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // While a call is in progress, update the elapsed time shown 146b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // onscreen. 147b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project updateElapsedTimeWidget(timeElapsed); 148b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 149b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 150b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /* package */ 151b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project void stopTimer() { 152b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mCallTime.cancelTimer(); 153b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 154b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 155b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project @Override 156b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project protected void onFinishInflate() { 157b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project super.onFinishInflate(); 158b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 159b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("CallCard onFinishInflate(this = " + this + ")..."); 160b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1610d315275d08cd33f801ae3a74e8fc265520f6246David Brown mPrimaryCallInfo = (ViewGroup) findViewById(R.id.primaryCallInfo); 1620d315275d08cd33f801ae3a74e8fc265520f6246David Brown mSecondaryCallInfo = (ViewGroup) findViewById(R.id.secondaryCallInfo); 163b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 164b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // "Upper" and "lower" title widgets 165b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mUpperTitle = (TextView) findViewById(R.id.upperTitle); 166b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mElapsedTime = (TextView) findViewById(R.id.elapsedTime); 167b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 168b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Text colors 1699688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown mTextColorDefaultPrimary = // corresponds to textAppearanceLarge 1709688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown getResources().getColor(android.R.color.primary_text_dark); 1719688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown mTextColorDefaultSecondary = // corresponds to textAppearanceSmall 1729688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown getResources().getColor(android.R.color.secondary_text_dark); 173b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mTextColorConnected = getResources().getColor(R.color.incall_textConnected); 1748bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project mTextColorConnectedBluetooth = 1758bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project getResources().getColor(R.color.incall_textConnectedBluetooth); 176b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mTextColorEnded = getResources().getColor(R.color.incall_textEnded); 177b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mTextColorOnHold = getResources().getColor(R.color.incall_textOnHold); 178b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 179b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // "Caller info" area, including photo / name / phone numbers / etc 180b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhoto = (ImageView) findViewById(R.id.photo); 1816d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown mManageConferencePhotoButton = (Button) findViewById(R.id.manageConferencePhotoButton); 1826d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown mManageConferencePhotoButton.setOnClickListener(this); 183b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mName = (TextView) findViewById(R.id.name); 184b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhoneNumber = (TextView) findViewById(R.id.phoneNumber); 185b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mLabel = (TextView) findViewById(R.id.label); 18629d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown mSocialStatus = (TextView) findViewById(R.id.socialStatus); 187b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 188b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // "Other call" info area 1890d315275d08cd33f801ae3a74e8fc265520f6246David Brown mSecondaryCallName = (TextView) findViewById(R.id.secondaryCallName); 1900d315275d08cd33f801ae3a74e8fc265520f6246David Brown mSecondaryCallStatus = (TextView) findViewById(R.id.secondaryCallStatus); 1910d315275d08cd33f801ae3a74e8fc265520f6246David Brown mSecondaryCallPhoto = (ImageView) findViewById(R.id.secondaryCallPhoto); 192b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 193b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Menu Button hint 194b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mMenuButtonHint = (TextView) findViewById(R.id.menuButtonHint); 195b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 196b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 197b15bef0ddcb4f744dff92013a9b596f2fcc2a008David Brown /** 198b15bef0ddcb4f744dff92013a9b596f2fcc2a008David Brown * Updates the state of all UI elements on the CallCard, based on the 199b15bef0ddcb4f744dff92013a9b596f2fcc2a008David Brown * current state of the phone. 200b15bef0ddcb4f744dff92013a9b596f2fcc2a008David Brown */ 2018343169cc89621d46dce86449f5ee1ff5d3a4919John Wang void updateState(CallManager cm) { 2028343169cc89621d46dce86449f5ee1ff5d3a4919John Wang if (DBG) log("updateState(" + cm + ")..."); 203b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 204b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Update some internal state based on the current state of the phone. 2056b7d0da33af02960736da204eb7a25ccf91d5396David Brown 2066b7d0da33af02960736da204eb7a25ccf91d5396David Brown // TODO: clean up this method to just fully update EVERYTHING in 2076b7d0da33af02960736da204eb7a25ccf91d5396David Brown // the callcard based on the current phone state: set the overall 2086b7d0da33af02960736da204eb7a25ccf91d5396David Brown // type of the CallCard, load up the main caller info area, and 2096b7d0da33af02960736da204eb7a25ccf91d5396David Brown // load up and show or hide the "other call" area if necessary. 210b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2118343169cc89621d46dce86449f5ee1ff5d3a4919John Wang Phone.State state = cm.getState(); // IDLE, RINGING, or OFFHOOK 212b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (state == Phone.State.RINGING) { 213b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // A phone call is ringing *or* call waiting 214b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // (ie. another call may also be active as well.) 2158343169cc89621d46dce86449f5ee1ff5d3a4919John Wang updateRingingCall(cm); 216b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else if (state == Phone.State.OFFHOOK) { 217b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // The phone is off hook. At least one call exists that is 218b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // dialing, active, or holding, and no calls are ringing or waiting. 2198343169cc89621d46dce86449f5ee1ff5d3a4919John Wang updateForegroundCall(cm); 220b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 221b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // The phone state is IDLE! 222b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // 223b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // The most common reason for this is if a call just 224b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // ended: the phone will be idle, but we *will* still 225b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // have a call in the DISCONNECTED state: 226ba72aa717c41d96e57209b3a74f0bedc8599ec15John Wang if (mApplication.mCM.hasDisconnectedFgCall() 227ba72aa717c41d96e57209b3a74f0bedc8599ec15John Wang || mApplication.mCM.hasDisconnectedBgCall()) { 228b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // In this case, we want the main CallCard to display 229b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // the "Call ended" state. The normal "foreground call" 230b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // code path handles that. 2318343169cc89621d46dce86449f5ee1ff5d3a4919John Wang updateForegroundCall(cm); 232b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 233b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // We don't have any DISCONNECTED calls, which means 234b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // that the phone is *truly* idle. 235b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // 236b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // It's very rare to be on the InCallScreen at all in this 237b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // state, but it can happen in some cases: 238b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // - A stray onPhoneStateChanged() event came in to the 239b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // InCallScreen *after* it was dismissed. 240b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // - We're allowed to be on the InCallScreen because 241b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // an MMI or USSD is running, but there's no actual "call" 242b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // to display. 243b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // - We're displaying an error dialog to the user 244b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // (explaining why the call failed), so we need to stay on 245b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // the InCallScreen so that the dialog will be visible. 246b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // 247b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // In these cases, put the callcard into a sane but "blank" state: 2488343169cc89621d46dce86449f5ee1ff5d3a4919John Wang updateNoCall(cm); 249b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 250b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 251b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 252b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 253b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 254b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Updates the UI for the state where the phone is in use, but not ringing. 255b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 2568343169cc89621d46dce86449f5ee1ff5d3a4919John Wang private void updateForegroundCall(CallManager cm) { 257b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("updateForegroundCall()..."); 2588343169cc89621d46dce86449f5ee1ff5d3a4919John Wang if (DBG) PhoneUtils.dumpCallManager(); 2598343169cc89621d46dce86449f5ee1ff5d3a4919John Wang 2608343169cc89621d46dce86449f5ee1ff5d3a4919John Wang Call fgCall = cm.getActiveFgCall(); 2618343169cc89621d46dce86449f5ee1ff5d3a4919John Wang Call bgCall = cm.getFirstActiveBgCall(); 2628343169cc89621d46dce86449f5ee1ff5d3a4919John Wang 263b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 264b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 265b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (fgCall.isIdle() && !fgCall.hasConnections()) { 266b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("updateForegroundCall: no active call, show holding call"); 267b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // TODO: make sure this case agrees with the latest UI spec. 268b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 269b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Display the background call in the main info area of the 270b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // CallCard, since there is no foreground call. Note that 271b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // displayMainCallStatus() will notice if the call we passed in is on 272b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // hold, and display the "on hold" indication. 273b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project fgCall = bgCall; 274b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 275b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // And be sure to not display anything in the "on hold" box. 276b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project bgCall = null; 277b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 278b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2798343169cc89621d46dce86449f5ee1ff5d3a4919John Wang displayMainCallStatus(cm, fgCall); 2808343169cc89621d46dce86449f5ee1ff5d3a4919John Wang 2818343169cc89621d46dce86449f5ee1ff5d3a4919John Wang Phone phone = fgCall.getPhone(); 2820fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 28379b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink int phoneType = phone.getPhoneType(); 28479b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink if (phoneType == Phone.PHONE_TYPE_CDMA) { 28539a84144262f12df44861d746788b9de92259e4fAbhishek Pillai if ((mApplication.cdmaPhoneCallState.getCurrentCallState() 28639a84144262f12df44861d746788b9de92259e4fAbhishek Pillai == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) 28739a84144262f12df44861d746788b9de92259e4fAbhishek Pillai && mApplication.cdmaPhoneCallState.IsThreeWayCallOrigStateDialing()) { 2888343169cc89621d46dce86449f5ee1ff5d3a4919John Wang displayOnHoldCallStatus(cm, fgCall); 2890fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } else { 2900fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville //This is required so that even if a background call is not present 2910fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // we need to clean up the background call area. 2928343169cc89621d46dce86449f5ee1ff5d3a4919John Wang displayOnHoldCallStatus(cm, bgCall); 2930fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 294872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan } else if ((phoneType == Phone.PHONE_TYPE_GSM) 295872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan || (phoneType == Phone.PHONE_TYPE_SIP)) { 2968343169cc89621d46dce86449f5ee1ff5d3a4919John Wang displayOnHoldCallStatus(cm, bgCall); 2970fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 298b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 299b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 300b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 301b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Updates the UI for the state where an incoming call is ringing (or 302b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * call waiting), regardless of whether the phone's already offhook. 303b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 3048343169cc89621d46dce86449f5ee1ff5d3a4919John Wang private void updateRingingCall(CallManager cm) { 305b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("updateRingingCall()..."); 306b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3078343169cc89621d46dce86449f5ee1ff5d3a4919John Wang Call ringingCall = cm.getFirstActiveRingingCall(); 308b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3096b7d0da33af02960736da204eb7a25ccf91d5396David Brown // Display caller-id info and photo from the incoming call: 3108343169cc89621d46dce86449f5ee1ff5d3a4919John Wang displayMainCallStatus(cm, ringingCall); 3116b7d0da33af02960736da204eb7a25ccf91d5396David Brown 3126b7d0da33af02960736da204eb7a25ccf91d5396David Brown // And even in the Call Waiting case, *don't* show any info about 3136b7d0da33af02960736da204eb7a25ccf91d5396David Brown // the current ongoing call and/or the current call on hold. 3146b7d0da33af02960736da204eb7a25ccf91d5396David Brown // (Since the caller-id info for the incoming call totally trumps 3156b7d0da33af02960736da204eb7a25ccf91d5396David Brown // any info about the current call(s) in progress.) 3168343169cc89621d46dce86449f5ee1ff5d3a4919John Wang displayOnHoldCallStatus(cm, null); 317b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 318b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 319b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 320b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Updates the UI for the state where the phone is not in use. 321b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * This is analogous to updateForegroundCall() and updateRingingCall(), 322b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * but for the (uncommon) case where the phone is 323b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * totally idle. (See comments in updateState() above.) 324b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 325b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * This puts the callcard into a sane but "blank" state. 326b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 3278343169cc89621d46dce86449f5ee1ff5d3a4919John Wang private void updateNoCall(CallManager cm) { 328b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("updateNoCall()..."); 329b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 3308343169cc89621d46dce86449f5ee1ff5d3a4919John Wang displayMainCallStatus(cm, null); 3318343169cc89621d46dce86449f5ee1ff5d3a4919John Wang displayOnHoldCallStatus(cm, null); 332b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 333b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 334b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 335b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Updates the main block of caller info on the CallCard 3360d315275d08cd33f801ae3a74e8fc265520f6246David Brown * (ie. the stuff in the primaryCallInfo block) based on the specified Call. 337b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 3388343169cc89621d46dce86449f5ee1ff5d3a4919John Wang private void displayMainCallStatus(CallManager cm, Call call) { 3398343169cc89621d46dce86449f5ee1ff5d3a4919John Wang if (DBG) log("displayMainCallStatus(phone " + cm 340b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project + ", call " + call + ")..."); 341b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 342b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (call == null) { 343b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // There's no call to display, presumably because the phone is idle. 3440d315275d08cd33f801ae3a74e8fc265520f6246David Brown mPrimaryCallInfo.setVisibility(View.GONE); 345b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return; 346b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 3470d315275d08cd33f801ae3a74e8fc265520f6246David Brown mPrimaryCallInfo.setVisibility(View.VISIBLE); 348b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 349b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Call.State state = call.getState(); 350b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log(" - call.state: " + call.getState()); 351b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 352b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project switch (state) { 353b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case ACTIVE: 3545eff1e7d582679b3a85f580eb1d550b2e6ca111cDavid Brown case DISCONNECTING: 355b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // update timer field 356b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("displayMainCallStatus: start periodicUpdateTimer"); 357b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mCallTime.setActiveCallMode(call); 358b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mCallTime.reset(); 359b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mCallTime.periodicUpdateTimer(); 360b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 361b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 362b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 363b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case HOLDING: 364b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // update timer field 365b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mCallTime.cancelTimer(); 366b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 367b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 368b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 369b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case DISCONNECTED: 370b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Stop getting timer ticks from this call 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 DIALING: 376b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case ALERTING: 377b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Stop getting timer ticks from a previous call 378b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mCallTime.cancelTimer(); 379b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 380b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 381b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 382b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case INCOMING: 383b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case WAITING: 384b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Stop getting timer ticks from a previous call 385b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mCallTime.cancelTimer(); 386b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 387b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 388b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 389b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case IDLE: 390b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // The "main CallCard" should never be trying to display 391b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // an idle call! In updateState(), if the phone is idle, 392b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // we call updateNoCall(), which means that we shouldn't 393b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // have passed a call into this method at all. 394b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Log.w(LOG_TAG, "displayMainCallStatus: IDLE call in the main call card!"); 395b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 396b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // (It is possible, though, that we had a valid call which 397b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // became idle *after* the check in updateState() but 398b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // before we get here... So continue the best we can, 399b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // with whatever (stale) info we can get from the 400b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // passed-in Call object.) 401b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 402b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 403b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 404b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project default: 405b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Log.w(LOG_TAG, "displayMainCallStatus: unexpected call state: " + state); 406b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 407b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 408b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 4098343169cc89621d46dce86449f5ee1ff5d3a4919John Wang updateCardTitleWidgets(call.getPhone(), call); 410b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 411b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (PhoneUtils.isConferenceCall(call)) { 412b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Update onscreen info for a conference call. 413872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan updateDisplayForConference(call); 414b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 415b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Update onscreen info for a regular call (which presumably 416b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // has only one connection.) 4170fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville Connection conn = null; 4188343169cc89621d46dce86449f5ee1ff5d3a4919John Wang int phoneType = call.getPhone().getPhoneType(); 41979b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink if (phoneType == Phone.PHONE_TYPE_CDMA) { 4200fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville conn = call.getLatestConnection(); 421872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan } else if ((phoneType == Phone.PHONE_TYPE_GSM) 422872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan || (phoneType == Phone.PHONE_TYPE_SIP)) { 4230fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville conn = call.getEarliestConnection(); 42479b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink } else { 42579b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink throw new IllegalStateException("Unexpected phone type: " + phoneType); 4260fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 427b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 428b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (conn == null) { 429b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("displayMainCallStatus: connection is null, using default values."); 430b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if the connection is null, we run through the behaviour 431b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // we had in the past, which breaks down into trivial steps 432b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // with the current implementation of getCallerInfo and 433b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // updateDisplayForPerson. 4344359358c4f430cbb986a5e7640ec506f08f1e332David Brown CallerInfo info = PhoneUtils.getCallerInfo(getContext(), null /* conn */); 4354359358c4f430cbb986a5e7640ec506f08f1e332David Brown updateDisplayForPerson(info, Connection.PRESENTATION_ALLOWED, false, call); 436b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 437b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log(" - CONN: " + conn + ", state = " + conn.getState()); 4384359358c4f430cbb986a5e7640ec506f08f1e332David Brown int presentation = conn.getNumberPresentation(); 439b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 440b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // make sure that we only make a new query when the current 441b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // callerinfo differs from what we've been requested to display. 442b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project boolean runQuery = true; 443b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Object o = conn.getUserData(); 444b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (o instanceof PhoneUtils.CallerInfoToken) { 445b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project runQuery = mPhotoTracker.isDifferentImageRequest( 446b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project ((PhoneUtils.CallerInfoToken) o).currentInfo); 447b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 448b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project runQuery = mPhotoTracker.isDifferentImageRequest(conn); 449b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 450b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 45146532b66a467f247380054270c6151aa3dc7a761Wink Saville // Adding a check to see if the update was caused due to a Phone number update 45246532b66a467f247380054270c6151aa3dc7a761Wink Saville // or CNAP update. If so then we need to start a new query 45379b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink if (phoneType == Phone.PHONE_TYPE_CDMA) { 45446532b66a467f247380054270c6151aa3dc7a761Wink Saville Object obj = conn.getUserData(); 45546532b66a467f247380054270c6151aa3dc7a761Wink Saville String updatedNumber = conn.getAddress(); 45646532b66a467f247380054270c6151aa3dc7a761Wink Saville String updatedCnapName = conn.getCnapName(); 45746532b66a467f247380054270c6151aa3dc7a761Wink Saville CallerInfo info = null; 45846532b66a467f247380054270c6151aa3dc7a761Wink Saville if (obj instanceof PhoneUtils.CallerInfoToken) { 45946532b66a467f247380054270c6151aa3dc7a761Wink Saville info = ((PhoneUtils.CallerInfoToken) o).currentInfo; 46046532b66a467f247380054270c6151aa3dc7a761Wink Saville } else if (o instanceof CallerInfo) { 46146532b66a467f247380054270c6151aa3dc7a761Wink Saville info = (CallerInfo) o; 46246532b66a467f247380054270c6151aa3dc7a761Wink Saville } 46346532b66a467f247380054270c6151aa3dc7a761Wink Saville 46446532b66a467f247380054270c6151aa3dc7a761Wink Saville if (info != null) { 46546532b66a467f247380054270c6151aa3dc7a761Wink Saville if (updatedNumber != null && !updatedNumber.equals(info.phoneNumber)) { 46646532b66a467f247380054270c6151aa3dc7a761Wink Saville if (DBG) log("- displayMainCallStatus: updatedNumber = " 46746532b66a467f247380054270c6151aa3dc7a761Wink Saville + updatedNumber); 46846532b66a467f247380054270c6151aa3dc7a761Wink Saville runQuery = true; 46946532b66a467f247380054270c6151aa3dc7a761Wink Saville } 47046532b66a467f247380054270c6151aa3dc7a761Wink Saville if (updatedCnapName != null && !updatedCnapName.equals(info.cnapName)) { 47146532b66a467f247380054270c6151aa3dc7a761Wink Saville if (DBG) log("- displayMainCallStatus: updatedCnapName = " 47246532b66a467f247380054270c6151aa3dc7a761Wink Saville + updatedCnapName); 47346532b66a467f247380054270c6151aa3dc7a761Wink Saville runQuery = true; 47446532b66a467f247380054270c6151aa3dc7a761Wink Saville } 47546532b66a467f247380054270c6151aa3dc7a761Wink Saville } 47646532b66a467f247380054270c6151aa3dc7a761Wink Saville } 47746532b66a467f247380054270c6151aa3dc7a761Wink Saville 478b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (runQuery) { 479b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("- displayMainCallStatus: starting CallerInfo query..."); 480b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project PhoneUtils.CallerInfoToken info = 481b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project PhoneUtils.startGetCallerInfo(getContext(), conn, this, call); 4824b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project updateDisplayForPerson(info.currentInfo, presentation, !info.isFinal, call); 483b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 484b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // No need to fire off a new query. We do still need 485b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // to update the display, though (since we might have 486b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // previously been in the "conference call" state.) 487b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("- displayMainCallStatus: using data we already have..."); 488b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (o instanceof CallerInfo) { 489b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project CallerInfo ci = (CallerInfo) o; 490e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai // Update CNAP information if Phone state change occurred 491e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai ci.cnapName = conn.getCnapName(); 492e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai ci.numberPresentation = conn.getNumberPresentation(); 493e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai ci.namePresentation = conn.getCnapNamePresentation(); 494e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai if (DBG) log("- displayMainCallStatus: CNAP data from Connection: " 495e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai + "CNAP name=" + ci.cnapName 496e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai + ", Number/Name Presentation=" + ci.numberPresentation); 497b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log(" ==> Got CallerInfo; updating display: ci = " + ci); 4984b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project updateDisplayForPerson(ci, presentation, false, call); 499b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else if (o instanceof PhoneUtils.CallerInfoToken){ 500b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project CallerInfo ci = ((PhoneUtils.CallerInfoToken) o).currentInfo; 501e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai if (DBG) log("- displayMainCallStatus: CNAP data from Connection: " 502e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai + "CNAP name=" + ci.cnapName 503e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai + ", Number/Name Presentation=" + ci.numberPresentation); 504b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log(" ==> Got CallerInfoToken; updating display: ci = " + ci); 5054b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project updateDisplayForPerson(ci, presentation, true, call); 506b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 507b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Log.w(LOG_TAG, "displayMainCallStatus: runQuery was false, " 508b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project + "but we didn't have a cached CallerInfo object! o = " + o); 509b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // TODO: any easy way to recover here (given that 510b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // the CallCard is probably displaying stale info 511b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // right now?) Maybe force the CallCard into the 512b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // "Unknown" state? 513b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 514b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 515b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 516b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 517b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 518b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // In some states we override the "photo" ImageView to be an 519b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // indication of the current state, rather than displaying the 520b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // regular photo as set above. 521b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project updatePhotoForCallState(call); 5229688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown 5239688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown // One special feature of the "number" text field: For incoming 5249688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown // calls, while the user is dragging the RotarySelector widget, we 5259688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown // use mPhoneNumber to display a hint like "Rotate to answer". 5269688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown if (mRotarySelectorHintTextResId != 0) { 5279688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown // Display the hint! 5289688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown mPhoneNumber.setText(mRotarySelectorHintTextResId); 5299688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown mPhoneNumber.setTextColor(getResources().getColor(mRotarySelectorHintColorResId)); 5309688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown mPhoneNumber.setVisibility(View.VISIBLE); 5319688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown mLabel.setVisibility(View.GONE); 5329688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown } 5339688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown // If we don't have a hint to display, just don't touch 5349688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown // mPhoneNumber and mLabel. (Their text / color / visibility have 5359688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown // already been set correctly, by either updateDisplayForPerson() 5369688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown // or updateDisplayForConference().) 537b15bef0ddcb4f744dff92013a9b596f2fcc2a008David Brown } 538b15bef0ddcb4f744dff92013a9b596f2fcc2a008David Brown 539b15bef0ddcb4f744dff92013a9b596f2fcc2a008David Brown /** 540b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Implemented for CallerInfoAsyncQuery.OnQueryCompleteListener interface. 541b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * refreshes the CallCard data when it called. 542b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 543b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public void onQueryComplete(int token, Object cookie, CallerInfo ci) { 544b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("onQueryComplete: token " + token + ", cookie " + cookie + ", ci " + ci); 545b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 546b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (cookie instanceof Call) { 547b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // grab the call object and update the display for an individual call, 548b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // as well as the successive call to update image via call state. 549b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // If the object is a textview instead, we update it as we need to. 550b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("callerinfo query complete, updating ui from displayMainCallStatus()"); 551b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Call call = (Call) cookie; 552a0ea7a803c8953a14bc35d1fef0973fd1d9c64b9Abhishek Pillai Connection conn = null; 553872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan int phoneType = call.getPhone().getPhoneType(); 554a0ea7a803c8953a14bc35d1fef0973fd1d9c64b9Abhishek Pillai if (phoneType == Phone.PHONE_TYPE_CDMA) { 555a0ea7a803c8953a14bc35d1fef0973fd1d9c64b9Abhishek Pillai conn = call.getLatestConnection(); 556872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan } else if ((phoneType == Phone.PHONE_TYPE_GSM) 557872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan || (phoneType == Phone.PHONE_TYPE_SIP)) { 558a0ea7a803c8953a14bc35d1fef0973fd1d9c64b9Abhishek Pillai conn = call.getEarliestConnection(); 559a0ea7a803c8953a14bc35d1fef0973fd1d9c64b9Abhishek Pillai } else { 560a0ea7a803c8953a14bc35d1fef0973fd1d9c64b9Abhishek Pillai throw new IllegalStateException("Unexpected phone type: " + phoneType); 561a0ea7a803c8953a14bc35d1fef0973fd1d9c64b9Abhishek Pillai } 562e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai PhoneUtils.CallerInfoToken cit = 563e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai PhoneUtils.startGetCallerInfo(getContext(), conn, this, null); 564e066d6979acb39dbc0ba79ecc10bc12e84a15195David Brown 565e066d6979acb39dbc0ba79ecc10bc12e84a15195David Brown int presentation = Connection.PRESENTATION_ALLOWED; 566e066d6979acb39dbc0ba79ecc10bc12e84a15195David Brown if (conn != null) presentation = conn.getNumberPresentation(); 567e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai if (DBG) log("- onQueryComplete: presentation=" + presentation 568e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai + ", contactExists=" + ci.contactExists); 569e066d6979acb39dbc0ba79ecc10bc12e84a15195David Brown 570e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai // Depending on whether there was a contact match or not, we want to pass in different 571e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai // CallerInfo (for CNAP). Therefore if ci.contactExists then use the ci passed in. 572e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai // Otherwise, regenerate the CIT from the Connection and use the CallerInfo from there. 573e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai if (ci.contactExists) { 574e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai updateDisplayForPerson(ci, Connection.PRESENTATION_ALLOWED, false, call); 575e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai } else { 576e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai updateDisplayForPerson(cit.currentInfo, presentation, false, call); 577e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai } 578b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project updatePhotoForCallState(call); 579b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 580b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else if (cookie instanceof TextView){ 581b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("callerinfo query complete, updating ui from ongoing or onhold"); 582b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project ((TextView) cookie).setText(PhoneUtils.getCompactNameFromCallerInfo(ci, mContext)); 583b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 584b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 585b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 586b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 587b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Implemented for ContactsAsyncHelper.OnImageLoadCompleteListener interface. 588b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * make sure that the call state is reflected after the image is loaded. 589b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 590b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public void onImageLoadComplete(int token, Object cookie, ImageView iView, 591b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project boolean imagePresent){ 592b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (cookie != null) { 593b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project updatePhotoForCallState((Call) cookie); 594b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 595b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 596b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 597b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 59834a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown * Updates the "card title" (and also elapsed time widget) based on 59934a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown * the current state of the call. 600b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 601e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown // TODO: it's confusing for updateCardTitleWidgets() and 602e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown // getTitleForCallCard() to be separate methods, since they both 603e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown // just list out the exact same "phone state" cases. 604e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown // Let's merge the getTitleForCallCard() logic into here. 605b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void updateCardTitleWidgets(Phone phone, Call call) { 606b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("updateCardTitleWidgets(call " + call + ")..."); 607b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Call.State state = call.getState(); 608b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 609b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // TODO: Still need clearer spec on exactly how title *and* status get 610b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // set in all states. (Then, given that info, refactor the code 611b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // here to be more clear about exactly which widgets on the card 612b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // need to be set.) 613b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 6143800ac871d6548790ac6119bb68b9be0640af261David Krause String cardTitle; 615872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan int phoneType = phone.getPhoneType(); 61679b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink if (phoneType == Phone.PHONE_TYPE_CDMA) { 6173800ac871d6548790ac6119bb68b9be0640af261David Krause if (!PhoneApp.getInstance().notifier.getIsCdmaRedialCall()) { 6186b7d0da33af02960736da204eb7a25ccf91d5396David Brown cardTitle = getTitleForCallCard(call); // Normal "foreground" call card 6193800ac871d6548790ac6119bb68b9be0640af261David Krause } else { 6203800ac871d6548790ac6119bb68b9be0640af261David Krause cardTitle = getContext().getString(R.string.card_title_redialing); 6213800ac871d6548790ac6119bb68b9be0640af261David Krause } 622872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan } else if ((phoneType == Phone.PHONE_TYPE_GSM) 623872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan || (phoneType == Phone.PHONE_TYPE_SIP)) { 6243800ac871d6548790ac6119bb68b9be0640af261David Krause cardTitle = getTitleForCallCard(call); 62579b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink } else { 62679b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink throw new IllegalStateException("Unexpected phone type: " + phoneType); 6273800ac871d6548790ac6119bb68b9be0640af261David Krause } 628b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("updateCardTitleWidgets: " + cardTitle); 629b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 63034a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // Update the title and elapsed time widgets based on the current call state. 63134a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown switch (state) { 63234a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown case ACTIVE: 63334a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown case DISCONNECTING: 63434a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown final boolean bluetoothActive = mApplication.showBluetoothIndication(); 63534a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown int ongoingCallIcon = bluetoothActive ? R.drawable.ic_incall_ongoing_bluetooth 63634a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown : R.drawable.ic_incall_ongoing; 63734a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown int connectedTextColor = bluetoothActive 63834a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown ? mTextColorConnectedBluetooth : mTextColorConnected; 639b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 64079b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink if (phoneType == Phone.PHONE_TYPE_CDMA) { 64134a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // Check if the "Dialing" 3Way call needs to be displayed 64234a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // as the Foreground Call state still remains ACTIVE 64334a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown if (mApplication.cdmaPhoneCallState.IsThreeWayCallOrigStateDialing()) { 64434a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // Use the "upper title": 6459688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown setUpperTitle(cardTitle, mTextColorDefaultPrimary, state); 64634a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown } else { 64734a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // Normal "ongoing call" state; don't use any "title" at all. 64834a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown clearUpperTitle(); 64934a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown } 650872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan } else if ((phoneType == Phone.PHONE_TYPE_GSM) 651872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan || (phoneType == Phone.PHONE_TYPE_SIP)) { 652e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown // While in the DISCONNECTING state we display a 653e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown // "Hanging up" message in order to make the UI feel more 654e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown // responsive. (In GSM it's normal to see a delay of a 655e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown // couple of seconds while negotiating the disconnect with 656e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown // the network, so the "Hanging up" state at least lets 657e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown // the user know that we're doing something.) 658e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown // TODO: consider displaying the "Hanging up" state for 659e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown // CDMA also if the latency there ever gets high enough. 660e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown if (state == Call.State.DISCONNECTING) { 661e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown // Display the brief "Hanging up" indication. 662e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown setUpperTitle(cardTitle, mTextColorDefaultPrimary, state); 663e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown } else { // state == Call.State.ACTIVE 664e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown // Normal "ongoing call" state; don't use any "title" at all. 665e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown clearUpperTitle(); 666e806935bab812a8ebf71846cdf342bb1a46a45f4David Brown } 66734a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown } 66834a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown 66934a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // Use the elapsed time widget to show the current call duration. 67034a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown mElapsedTime.setVisibility(View.VISIBLE); 67134a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown mElapsedTime.setTextColor(connectedTextColor); 67234a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown long duration = CallTime.getCallDuration(call); // msec 67334a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown updateElapsedTimeWidget(duration / 1000); 67434a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // Also see onTickForCallTimeElapsed(), which updates this 67534a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // widget once per second while the call is active. 67634a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown break; 67734a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown 67834a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown case DISCONNECTED: 67934a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // Display "Call ended" (or possibly some error indication; 68034a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // see getCallFailedString()) in the upper title, in red. 68134a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown 68234a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // TODO: display a "call ended" icon somewhere, like the old 68334a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // R.drawable.ic_incall_end? 68434a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown 68534a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown setUpperTitle(cardTitle, mTextColorEnded, state); 68634a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown 68734a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // In the "Call ended" state, leave the mElapsedTime widget 68834a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // visible, but don't touch it (so we continue to see the elapsed time of 68934a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // the call that just ended.) 69034a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown mElapsedTime.setVisibility(View.VISIBLE); 69134a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown mElapsedTime.setTextColor(mTextColorEnded); 69234a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown break; 69334a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown 69434a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown case HOLDING: 69534a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // For a single call on hold, display the title "On hold" in 69634a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // orange. 69734a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // (But since the upper title overlaps the label of the 69834a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // Hold/Unhold button, we actually use the elapsedTime widget 69934a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // to display the title in this case.) 70034a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown 70134a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // TODO: display an "On hold" icon somewhere, like the old 70234a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // R.drawable.ic_incall_onhold? 70334a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown 70434a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown clearUpperTitle(); 70534a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown mElapsedTime.setText(cardTitle); 70634a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown 70734a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // While on hold, the elapsed time widget displays an 70834a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // "on hold" indication rather than an amount of time. 70934a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown mElapsedTime.setVisibility(View.VISIBLE); 71034a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown mElapsedTime.setTextColor(mTextColorOnHold); 71134a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown break; 71234a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown 71334a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown default: 71434a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // All other states (DIALING, INCOMING, etc.) use the "upper title": 7159688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown setUpperTitle(cardTitle, mTextColorDefaultPrimary, state); 71634a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown 71734a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown // ...and we don't show the elapsed time. 71834a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown mElapsedTime.setVisibility(View.INVISIBLE); 71934a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown break; 720b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 721b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 722b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 723b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 724b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Updates mElapsedTime based on the specified number of seconds. 725b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * A timeElapsed value of zero means to not show an elapsed time at all. 726b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 727b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void updateElapsedTimeWidget(long timeElapsed) { 728b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if (DBG) log("updateElapsedTimeWidget: " + timeElapsed); 729b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (timeElapsed == 0) { 730b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mElapsedTime.setText(""); 731b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 732b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mElapsedTime.setText(DateUtils.formatElapsedTime(timeElapsed)); 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 * Returns the "card title" displayed at the top of a foreground 738b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * ("active") CallCard to indicate the current state of this call, like 739b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * "Dialing" or "In call" or "On hold". A null return value means that 740b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * there's no title string for this state. 741b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 742b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private String getTitleForCallCard(Call call) { 743b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project String retVal = null; 744b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Call.State state = call.getState(); 745b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Context context = getContext(); 746b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project int resId; 747b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 748b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("- getTitleForCallCard(Call " + call + ")..."); 749b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 750b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project switch (state) { 751b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case IDLE: 752b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 753b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 754b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case ACTIVE: 755b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Title is "Call in progress". (Note this appears in the 756b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // "lower title" area of the CallCard.) 757872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan int phoneType = call.getPhone().getPhoneType(); 75879b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink if (phoneType == Phone.PHONE_TYPE_CDMA) { 7590fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville if (mApplication.cdmaPhoneCallState.IsThreeWayCallOrigStateDialing()) { 7600fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville retVal = context.getString(R.string.card_title_dialing); 7610fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } else { 7620fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville retVal = context.getString(R.string.card_title_in_progress); 7630fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 764872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan } else if ((phoneType == Phone.PHONE_TYPE_GSM) 765872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan || (phoneType == Phone.PHONE_TYPE_SIP)) { 7660fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville retVal = context.getString(R.string.card_title_in_progress); 76779b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink } else { 76879b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink throw new IllegalStateException("Unexpected phone type: " + phoneType); 7690fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 770b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 771b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 772b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case HOLDING: 773b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project retVal = context.getString(R.string.card_title_on_hold); 774b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // TODO: if this is a conference call on hold, 775b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // maybe have a special title here too? 776b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 777b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 778b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case DIALING: 779b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case ALERTING: 780b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project retVal = context.getString(R.string.card_title_dialing); 781b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 782b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 783b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case INCOMING: 784b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case WAITING: 785b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project retVal = context.getString(R.string.card_title_incoming_call); 786b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 787b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 7885eff1e7d582679b3a85f580eb1d550b2e6ca111cDavid Brown case DISCONNECTING: 7895eff1e7d582679b3a85f580eb1d550b2e6ca111cDavid Brown retVal = context.getString(R.string.card_title_hanging_up); 7905eff1e7d582679b3a85f580eb1d550b2e6ca111cDavid Brown break; 7915eff1e7d582679b3a85f580eb1d550b2e6ca111cDavid Brown 792b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case DISCONNECTED: 793b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project retVal = getCallFailedString(call); 794b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 795b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 796b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 797b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log(" ==> result: " + retVal); 798b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return retVal; 799b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 800b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 801b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 802b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Updates the "on hold" box in the "other call" info area 8030d315275d08cd33f801ae3a74e8fc265520f6246David Brown * (ie. the stuff in the secondaryCallInfo block) 804b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * based on the specified Call. 805b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Or, clear out the "on hold" box if the specified call 806b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * is null or idle. 807b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 8088343169cc89621d46dce86449f5ee1ff5d3a4919John Wang private void displayOnHoldCallStatus(CallManager cm, Call call) { 809b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("displayOnHoldCallStatus(call =" + call + ")..."); 810af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville 811af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville if ((call == null) || (PhoneApp.getInstance().isOtaCallInActiveState())) { 8120d315275d08cd33f801ae3a74e8fc265520f6246David Brown mSecondaryCallInfo.setVisibility(View.GONE); 813b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return; 814b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 815b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 8168da4d90151c882972e15429d4d48bdaa45095d72David Brown boolean showSecondaryCallInfo = false; 817b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Call.State state = call.getState(); 818b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project switch (state) { 819b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case HOLDING: 820b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Ok, there actually is a background call on hold. 821b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Display the "on hold" box. 822b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 8230d315275d08cd33f801ae3a74e8fc265520f6246David Brown // Note this case occurs only on GSM devices. (On CDMA, 8240d315275d08cd33f801ae3a74e8fc265520f6246David Brown // the "call on hold" is actually the 2nd connection of 8250d315275d08cd33f801ae3a74e8fc265520f6246David Brown // that ACTIVE call; see the ACTIVE case below.) 8260d315275d08cd33f801ae3a74e8fc265520f6246David Brown 827b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (PhoneUtils.isConferenceCall(call)) { 828b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("==> conference call."); 8290d315275d08cd33f801ae3a74e8fc265520f6246David Brown mSecondaryCallName.setText(getContext().getString(R.string.confCall)); 8300d315275d08cd33f801ae3a74e8fc265520f6246David Brown showImage(mSecondaryCallPhoto, R.drawable.picture_conference); 831b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 832b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // perform query and update the name temporarily 833b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // make sure we hand the textview we want updated to the 834b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // callback function. 835b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("==> NOT a conf call; call startGetCallerInfo..."); 8360d315275d08cd33f801ae3a74e8fc265520f6246David Brown PhoneUtils.CallerInfoToken infoToken = PhoneUtils.startGetCallerInfo( 8370d315275d08cd33f801ae3a74e8fc265520f6246David Brown getContext(), call, this, mSecondaryCallName); 8380d315275d08cd33f801ae3a74e8fc265520f6246David Brown mSecondaryCallName.setText( 8390d315275d08cd33f801ae3a74e8fc265520f6246David Brown PhoneUtils.getCompactNameFromCallerInfo(infoToken.currentInfo, 8400d315275d08cd33f801ae3a74e8fc265520f6246David Brown getContext())); 8410d315275d08cd33f801ae3a74e8fc265520f6246David Brown 8420d315275d08cd33f801ae3a74e8fc265520f6246David Brown // Also pull the photo out of the current CallerInfo. 8430d315275d08cd33f801ae3a74e8fc265520f6246David Brown // (Note we assume we already have a valid photo at 8440d315275d08cd33f801ae3a74e8fc265520f6246David Brown // this point, since *presumably* the caller-id query 8450d315275d08cd33f801ae3a74e8fc265520f6246David Brown // was already run at some point *before* this call 8460d315275d08cd33f801ae3a74e8fc265520f6246David Brown // got put on hold. If there's no cached photo, just 8470d315275d08cd33f801ae3a74e8fc265520f6246David Brown // fall back to the default "unknown" image.) 8480d315275d08cd33f801ae3a74e8fc265520f6246David Brown if (infoToken.isFinal) { 8490d315275d08cd33f801ae3a74e8fc265520f6246David Brown showCachedImage(mSecondaryCallPhoto, infoToken.currentInfo); 8500d315275d08cd33f801ae3a74e8fc265520f6246David Brown } else { 8510d315275d08cd33f801ae3a74e8fc265520f6246David Brown showImage(mSecondaryCallPhoto, R.drawable.picture_unknown); 8520d315275d08cd33f801ae3a74e8fc265520f6246David Brown } 853b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 854b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 8558da4d90151c882972e15429d4d48bdaa45095d72David Brown showSecondaryCallInfo = true; 856b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 857b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 858b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 8590fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville case ACTIVE: 8600fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // CDMA: This is because in CDMA when the user originates the second call, 8610fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // although the Foreground call state is still ACTIVE in reality the network 8620fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // put the first call on hold. 86379b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink if (mApplication.phone.getPhoneType() == Phone.PHONE_TYPE_CDMA) { 8640fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville List<Connection> connections = call.getConnections(); 8650fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville if (connections.size() > 2) { 8660fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // This means that current Mobile Originated call is the not the first 3-Way 8670fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // call the user is making, which in turn tells the PhoneApp that we no 8680fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // longer know which previous caller/party had dropped out before the user 8690fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // made this call. 8700d315275d08cd33f801ae3a74e8fc265520f6246David Brown mSecondaryCallName.setText( 8710d315275d08cd33f801ae3a74e8fc265520f6246David Brown getContext().getString(R.string.card_title_in_call)); 8720d315275d08cd33f801ae3a74e8fc265520f6246David Brown showImage(mSecondaryCallPhoto, R.drawable.picture_unknown); 8730fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } else { 8740fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // This means that the current Mobile Originated call IS the first 3-Way 8750fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // and hence we display the first callers/party's info here. 8760fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville Connection conn = call.getEarliestConnection(); 877de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman PhoneUtils.CallerInfoToken infoToken = PhoneUtils.startGetCallerInfo( 8780d315275d08cd33f801ae3a74e8fc265520f6246David Brown getContext(), conn, this, mSecondaryCallName); 8790fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 880de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman // Get the compactName to be displayed, but then check that against 881de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman // the number presentation value for the call. If it's not an allowed 882de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman // presentation, then display the appropriate presentation string instead. 883de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman CallerInfo info = infoToken.currentInfo; 8840d315275d08cd33f801ae3a74e8fc265520f6246David Brown 8850d315275d08cd33f801ae3a74e8fc265520f6246David Brown String name = PhoneUtils.getCompactNameFromCallerInfo(info, getContext()); 8860d315275d08cd33f801ae3a74e8fc265520f6246David Brown boolean forceGenericPhoto = false; 887de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman if (info != null && info.numberPresentation != 888de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman Connection.PRESENTATION_ALLOWED) { 889de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman name = getPresentationString(info.numberPresentation); 8900d315275d08cd33f801ae3a74e8fc265520f6246David Brown forceGenericPhoto = true; 8910d315275d08cd33f801ae3a74e8fc265520f6246David Brown } 8920d315275d08cd33f801ae3a74e8fc265520f6246David Brown mSecondaryCallName.setText(name); 8930d315275d08cd33f801ae3a74e8fc265520f6246David Brown 8940d315275d08cd33f801ae3a74e8fc265520f6246David Brown // Also pull the photo out of the current CallerInfo. 8950d315275d08cd33f801ae3a74e8fc265520f6246David Brown // (Note we assume we already have a valid photo at 8960d315275d08cd33f801ae3a74e8fc265520f6246David Brown // this point, since *presumably* the caller-id query 8970d315275d08cd33f801ae3a74e8fc265520f6246David Brown // was already run at some point *before* this call 8980d315275d08cd33f801ae3a74e8fc265520f6246David Brown // got put on hold. If there's no cached photo, just 8990d315275d08cd33f801ae3a74e8fc265520f6246David Brown // fall back to the default "unknown" image.) 9000d315275d08cd33f801ae3a74e8fc265520f6246David Brown if (!forceGenericPhoto && infoToken.isFinal) { 9010d315275d08cd33f801ae3a74e8fc265520f6246David Brown showCachedImage(mSecondaryCallPhoto, info); 9020d315275d08cd33f801ae3a74e8fc265520f6246David Brown } else { 9030d315275d08cd33f801ae3a74e8fc265520f6246David Brown showImage(mSecondaryCallPhoto, R.drawable.picture_unknown); 904de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman } 9050fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 9068da4d90151c882972e15429d4d48bdaa45095d72David Brown showSecondaryCallInfo = true; 9070fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 9080d315275d08cd33f801ae3a74e8fc265520f6246David Brown } else { 9090d315275d08cd33f801ae3a74e8fc265520f6246David Brown // We shouldn't ever get here at all for non-CDMA devices. 9100d315275d08cd33f801ae3a74e8fc265520f6246David Brown Log.w(LOG_TAG, "displayOnHoldCallStatus: ACTIVE state on non-CDMA device"); 9118da4d90151c882972e15429d4d48bdaa45095d72David Brown showSecondaryCallInfo = false; 9120fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 9130fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville break; 9140fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 915b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project default: 916b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // There's actually no call on hold. (Presumably this call's 917b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // state is IDLE, since any other state is meaningless for the 918b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // background call.) 9198da4d90151c882972e15429d4d48bdaa45095d72David Brown showSecondaryCallInfo = false; 920b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 921b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 9228da4d90151c882972e15429d4d48bdaa45095d72David Brown 9238da4d90151c882972e15429d4d48bdaa45095d72David Brown if (showSecondaryCallInfo) { 9248da4d90151c882972e15429d4d48bdaa45095d72David Brown // Ok, we have something useful to display in the "secondary 9258da4d90151c882972e15429d4d48bdaa45095d72David Brown // call" info area. 9268da4d90151c882972e15429d4d48bdaa45095d72David Brown mSecondaryCallInfo.setVisibility(View.VISIBLE); 9278da4d90151c882972e15429d4d48bdaa45095d72David Brown 9288da4d90151c882972e15429d4d48bdaa45095d72David Brown // Watch out: there are some cases where we need to display the 9298da4d90151c882972e15429d4d48bdaa45095d72David Brown // secondary call photo but *not* the two lines of text above it. 9308da4d90151c882972e15429d4d48bdaa45095d72David Brown // Specifically, that's any state where the CallCard "upper title" is 9318da4d90151c882972e15429d4d48bdaa45095d72David Brown // in use, since the title (e.g. "Dialing" or "Call ended") might 9328da4d90151c882972e15429d4d48bdaa45095d72David Brown // collide with the secondaryCallStatus and secondaryCallName widgets. 9338da4d90151c882972e15429d4d48bdaa45095d72David Brown // 9348da4d90151c882972e15429d4d48bdaa45095d72David Brown // We detect this case by simply seeing whether or not there's any text 9358da4d90151c882972e15429d4d48bdaa45095d72David Brown // in mUpperTitle. (This is much simpler than detecting all possible 9368da4d90151c882972e15429d4d48bdaa45095d72David Brown // telephony states where the "upper title" is used! But note it does 9378da4d90151c882972e15429d4d48bdaa45095d72David Brown // rely on the fact that updateCardTitleWidgets() gets called *earlier* 9388da4d90151c882972e15429d4d48bdaa45095d72David Brown // than this method, in the CallCard.updateState() sequence...) 9398da4d90151c882972e15429d4d48bdaa45095d72David Brown boolean okToShowLabels = TextUtils.isEmpty(mUpperTitle.getText()); 9408da4d90151c882972e15429d4d48bdaa45095d72David Brown mSecondaryCallName.setVisibility(okToShowLabels ? View.VISIBLE : View.INVISIBLE); 9418da4d90151c882972e15429d4d48bdaa45095d72David Brown mSecondaryCallStatus.setVisibility(okToShowLabels ? View.VISIBLE : View.INVISIBLE); 9428da4d90151c882972e15429d4d48bdaa45095d72David Brown } else { 9438da4d90151c882972e15429d4d48bdaa45095d72David Brown // Hide the entire "secondary call" info area. 9448da4d90151c882972e15429d4d48bdaa45095d72David Brown mSecondaryCallInfo.setVisibility(View.GONE); 9458da4d90151c882972e15429d4d48bdaa45095d72David Brown } 946b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 947b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 948b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private String getCallFailedString(Call call) { 949b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Connection c = call.getEarliestConnection(); 950b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project int resID; 951b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 952b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (c == null) { 953b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("getCallFailedString: connection is null, using default values."); 954b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if this connection is null, just assume that the 955b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // default case occurs. 956b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project resID = R.string.card_title_call_ended; 957b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 958b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 959b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Connection.DisconnectCause cause = c.getDisconnectCause(); 960b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 961b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // TODO: The card *title* should probably be "Call ended" in all 962b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // cases, but if the DisconnectCause was an error condition we should 963b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // probably also display the specific failure reason somewhere... 964b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 965b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project switch (cause) { 966b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case BUSY: 967b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project resID = R.string.callFailed_userBusy; 968b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 969b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 970b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case CONGESTION: 971b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project resID = R.string.callFailed_congestion; 972b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 973b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 974b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case LOST_SIGNAL: 9753800ac871d6548790ac6119bb68b9be0640af261David Krause case CDMA_DROP: 976b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project resID = R.string.callFailed_noSignal; 977b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 978b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 979b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case LIMIT_EXCEEDED: 980b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project resID = R.string.callFailed_limitExceeded; 981b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 982b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 983b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case POWER_OFF: 984b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project resID = R.string.callFailed_powerOff; 985b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 986b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 987a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville case ICC_ERROR: 988b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project resID = R.string.callFailed_simError; 989b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 990b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 991b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case OUT_OF_SERVICE: 992b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project resID = R.string.callFailed_outOfService; 993b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 994b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 9959eb2ffdf7b4752c7199eba6a3b88f63edc4a0ac8Naveen Kalla case UNOBTAINABLE_NUMBER: 9969eb2ffdf7b4752c7199eba6a3b88f63edc4a0ac8Naveen Kalla resID = R.string.callFailed_unobtainable_number; 9979eb2ffdf7b4752c7199eba6a3b88f63edc4a0ac8Naveen Kalla break; 9989eb2ffdf7b4752c7199eba6a3b88f63edc4a0ac8Naveen Kalla 999b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project default: 1000b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project resID = R.string.card_title_call_ended; 1001b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 1002b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1003b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1004b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return getContext().getString(resID); 1005b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1006b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1007b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 1008b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Updates the name / photo / number / label fields on the CallCard 1009b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * based on the specified CallerInfo. 1010b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 1011b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * If the current call is a conference call, use 1012b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * updateDisplayForConference() instead. 1013b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 1014b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void updateDisplayForPerson(CallerInfo info, 10154b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project int presentation, 1016b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project boolean isTemporary, 1017b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Call call) { 1018a1c2398ade0e01d0bcfe23212bdaa18e4c19a1e5Nicolas Catania if (DBG) log("updateDisplayForPerson(" + info + ")\npresentation:" + 1019a1c2398ade0e01d0bcfe23212bdaa18e4c19a1e5Nicolas Catania presentation + " isTemporary:" + isTemporary); 1020b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1021b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // inform the state machine that we are displaying a photo. 1022b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhotoTracker.setPhotoRequest(info); 1023b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhotoTracker.setPhotoState(ContactsAsyncHelper.ImageTracker.DISPLAY_IMAGE); 1024b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1025b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project String name; 1026b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project String displayNumber = null; 1027b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project String label = null; 1028b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Uri personUri = null; 102929d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown String socialStatusText = null; 103029d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown Drawable socialStatusBadge = null; 1031b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1032b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (info != null) { 1033b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // It appears that there is a small change in behaviour with the 1034b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // PhoneUtils' startGetCallerInfo whereby if we query with an 1035b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // empty number, we will get a valid CallerInfo object, but with 1036b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // fields that are all null, and the isTemporary boolean input 1037b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // parameter as true. 1038b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1039b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // In the past, we would see a NULL callerinfo object, but this 1040b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // ends up causing null pointer exceptions elsewhere down the 1041b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // line in other cases, so we need to make this fix instead. It 1042b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // appears that this was the ONLY call to PhoneUtils 1043b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // .getCallerInfo() that relied on a NULL CallerInfo to indicate 1044b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // an unknown contact. 1045b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1046b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (TextUtils.isEmpty(info.name)) { 1047b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (TextUtils.isEmpty(info.phoneNumber)) { 10484b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project name = getPresentationString(presentation); 1049e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai } else if (presentation != Connection.PRESENTATION_ALLOWED) { 1050e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai // This case should never happen since the network should never send a phone # 1051e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai // AND a restricted presentation. However we leave it here in case of weird 1052e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai // network behavior 1053e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai name = getPresentationString(presentation); 1054e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai } else if (!TextUtils.isEmpty(info.cnapName)) { 1055e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai name = info.cnapName; 1056e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai info.name = info.cnapName; 1057e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai displayNumber = info.phoneNumber; 1058b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 1059b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project name = info.phoneNumber; 1060b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1061b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 1062e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai if (presentation != Connection.PRESENTATION_ALLOWED) { 1063e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai // This case should never happen since the network should never send a name 1064e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai // AND a restricted presentation. However we leave it here in case of weird 1065e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai // network behavior 1066e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai name = getPresentationString(presentation); 1067e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai } else { 1068e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai name = info.name; 1069e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai displayNumber = info.phoneNumber; 1070e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai label = info.phoneLabel; 1071e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai } 1072b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 10733d6d70562622660e581b53308e675386d299dd19Dmitri Plotnikov personUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, info.person_id); 1074b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 10754b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project name = getPresentationString(presentation); 1076b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 10770fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 10780fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville if (call.isGeneric()) { 10790fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville mName.setText(R.string.card_title_in_call); 10800fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } else { 10810fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville mName.setText(name); 10820fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 1083b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mName.setVisibility(View.VISIBLE); 1084b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1085b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Update mPhoto 1086b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if the temporary flag is set, we know we'll be getting another call after 1087b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // the CallerInfo has been correctly updated. So, we can skip the image 1088b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // loading until then. 1089b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1090b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // If the photoResource is filled in for the CallerInfo, (like with the 1091b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Emergency Number case), then we can just set the photo image without 1092b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // requesting for an image load. Please refer to CallerInfoAsyncQuery.java 1093b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // for cases where CallerInfo.photoResource may be set. We can also avoid 1094b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // the image load step if the image data is cached. 1095b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (isTemporary && (info == null || !info.isCachedPhotoCurrent)) { 1096b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhoto.setVisibility(View.INVISIBLE); 1097b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else if (info != null && info.photoResource != 0){ 1098b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project showImage(mPhoto, info.photoResource); 1099b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else if (!showCachedImage(mPhoto, info)) { 1100b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Load the image with a callback to update the image state. 1101a1c2398ade0e01d0bcfe23212bdaa18e4c19a1e5Nicolas Catania // Use the default unknown picture while the query is running. 1102a1c2398ade0e01d0bcfe23212bdaa18e4c19a1e5Nicolas Catania ContactsAsyncHelper.updateImageViewWithContactPhotoAsync( 1103a1c2398ade0e01d0bcfe23212bdaa18e4c19a1e5Nicolas Catania info, 0, this, call, getContext(), mPhoto, personUri, R.drawable.picture_unknown); 1104b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 11056d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown // And no matter what, on all devices, we never see the "manage 11066d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown // conference" button in this state. 11076d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown mManageConferencePhotoButton.setVisibility(View.INVISIBLE); 11086d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown 11090fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville if (displayNumber != null && !call.isGeneric()) { 1110b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhoneNumber.setText(displayNumber); 11119688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown mPhoneNumber.setTextColor(mTextColorDefaultSecondary); 1112b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhoneNumber.setVisibility(View.VISIBLE); 1113b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 1114b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhoneNumber.setVisibility(View.GONE); 1115b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1116b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1117153e79d8d413b1ccd4abf55a8dbe4e266aa92799Paul Berman if (label != null && !call.isGeneric()) { 1118b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mLabel.setText(label); 1119b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mLabel.setVisibility(View.VISIBLE); 1120b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 1121b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mLabel.setVisibility(View.GONE); 1122b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1123b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 112429d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown // "Social status": currently unused. 112529d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown // Note socialStatus is *only* visible while an incoming 112629d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown // call is ringing, never in any other call state. 112729d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown if ((socialStatusText != null) && call.isRinging() && !call.isGeneric()) { 112829d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown mSocialStatus.setVisibility(View.VISIBLE); 112929d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown mSocialStatus.setText(socialStatusText); 113029d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown mSocialStatus.setCompoundDrawablesWithIntrinsicBounds( 113129d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown socialStatusBadge, null, null, null); 113229d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown mSocialStatus.setCompoundDrawablePadding((int) (mDensity * 6)); 113329d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown } else { 113429d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown mSocialStatus.setVisibility(View.GONE); 113529d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown } 113629d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown } 1137b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 11384b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project private String getPresentationString(int presentation) { 11394b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project String name = getContext().getString(R.string.unknown); 11404b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project if (presentation == Connection.PRESENTATION_RESTRICTED) { 11414b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project name = getContext().getString(R.string.private_num); 11424b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project } else if (presentation == Connection.PRESENTATION_PAYPHONE) { 11434b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project name = getContext().getString(R.string.payphone); 11444b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project } 11454b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project return name; 11464b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project } 11474b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project 1148b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 1149b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Updates the name / photo / number / label fields 1150b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * for the special "conference call" state. 1151b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 1152b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * If the current call has only a single connection, use 1153b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * updateDisplayForPerson() instead. 1154b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 1155872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan private void updateDisplayForConference(Call call) { 1156b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("updateDisplayForConference()..."); 1157b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1158872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan int phoneType = call.getPhone().getPhoneType(); 115979b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink if (phoneType == Phone.PHONE_TYPE_CDMA) { 11600fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // This state corresponds to both 3-Way merged call and 11610fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // Call Waiting accepted call. 116229d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown // In this case we display the UI in a "generic" state, with 116329d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown // the generic "dialing" icon and no caller information, 116429d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown // because in this state in CDMA the user does not really know 116529d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown // which caller party he is talking to. 11660fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville showImage(mPhoto, R.drawable.picture_dialing); 11670fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville mName.setText(R.string.card_title_in_call); 1168872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan } else if ((phoneType == Phone.PHONE_TYPE_GSM) 1169872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan || (phoneType == Phone.PHONE_TYPE_SIP)) { 11706d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown if (mInCallScreen.isTouchUiEnabled()) { 11716d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown // Display the "manage conference" button in place of the photo. 11726d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown mManageConferencePhotoButton.setVisibility(View.VISIBLE); 11736d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown mPhoto.setVisibility(View.INVISIBLE); // Not GONE, since that would break 11746d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown // other views in our RelativeLayout. 11756d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown } else { 11766d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown // Display the "conference call" image in the photo slot, 11776d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown // with no other information. 11786d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown showImage(mPhoto, R.drawable.picture_conference); 11796d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown } 11800fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville mName.setText(R.string.card_title_conf_call); 118179b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink } else { 118279b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink throw new IllegalStateException("Unexpected phone type: " + phoneType); 11830fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 1184b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1185b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mName.setVisibility(View.VISIBLE); 1186b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1187b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // TODO: For a conference call, the "phone number" slot is specced 1188b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // to contain a summary of who's on the call, like "Bill Foldes 1189b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // and Hazel Nutt" or "Bill Foldes and 2 others". 1190b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // But for now, just hide it: 1191b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhoneNumber.setVisibility(View.GONE); 1192b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mLabel.setVisibility(View.GONE); 1193b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 119429d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown // socialStatus is never visible in this state. 119529d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown mSocialStatus.setVisibility(View.GONE); 119629d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown 119729d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown // TODO: for a GSM conference call, since we do actually know who 119829d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown // you're talking to, consider also showing names / numbers / 119929d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown // photos of some of the people on the conference here, so you can 120029d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown // see that info without having to click "Manage conference". We 120129d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown // probably have enough space to show info for 2 people, at least. 1202b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // 1203b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // To do this, our caller would pass us the activeConnections 1204b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // list, and we'd call PhoneUtils.getCallerInfo() separately for 1205b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // each connection. 1206b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1207b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1208b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 1209b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Updates the CallCard "photo" IFF the specified Call is in a state 1210b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * that needs a special photo (like "busy" or "dialing".) 1211b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 1212b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * If the current call does not require a special image in the "photo" 1213b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * slot onscreen, don't do anything, since presumably the photo image 1214b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * has already been set (to the photo of the person we're talking, or 1215b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * the generic "picture_unknown" image, or the "conference call" 1216b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * image.) 1217b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 1218b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void updatePhotoForCallState(Call call) { 1219b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("updatePhotoForCallState(" + call + ")..."); 1220b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project int photoImageResource = 0; 1221b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1222b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Check for the (relatively few) telephony states that need a 1223b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // special image in the "photo" slot. 1224b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Call.State state = call.getState(); 1225b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project switch (state) { 1226b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case DISCONNECTED: 1227b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Display the special "busy" photo for BUSY or CONGESTION. 1228b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Otherwise (presumably the normal "call ended" state) 1229b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // leave the photo alone. 1230b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Connection c = call.getEarliestConnection(); 1231b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if the connection is null, we assume the default case, 1232b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // otherwise update the image resource normally. 1233b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (c != null) { 1234b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Connection.DisconnectCause cause = c.getDisconnectCause(); 1235b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if ((cause == Connection.DisconnectCause.BUSY) 1236b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project || (cause == Connection.DisconnectCause.CONGESTION)) { 1237b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project photoImageResource = R.drawable.picture_busy; 1238b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1239b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else if (DBG) { 1240b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project log("updatePhotoForCallState: connection is null, ignoring."); 1241b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1242b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1243b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // TODO: add special images for any other DisconnectCauses? 1244b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 1245b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1246b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case ALERTING: 124744e42e4eccd8ecdcdcca166c9f6f35a4d6c65591Nicolas Catania case DIALING: 1248b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project default: 1249b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Leave the photo alone in all other states. 1250b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // If this call is an individual call, and the image is currently 1251b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // displaying a state, (rather than a photo), we'll need to update 1252b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // the image. 1253b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // This is for the case where we've been displaying the state and 1254b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // now we need to restore the photo. This can happen because we 1255b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // only query the CallerInfo once, and limit the number of times 1256b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // the image is loaded. (So a state image may overwrite the photo 1257b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // and we would otherwise have no way of displaying the photo when 1258b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // the state goes away.) 1259b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1260b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if the photoResource field is filled-in in the Connection's 1261b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // caller info, then we can just use that instead of requesting 1262b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // for a photo load. 1263b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1264b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // look for the photoResource if it is available. 1265b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project CallerInfo ci = null; 1266b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project { 12670fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville Connection conn = null; 1268872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan int phoneType = call.getPhone().getPhoneType(); 126979b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink if (phoneType == Phone.PHONE_TYPE_CDMA) { 12700fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville conn = call.getLatestConnection(); 1271872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan } else if ((phoneType == Phone.PHONE_TYPE_GSM) 1272872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan || (phoneType == Phone.PHONE_TYPE_SIP)) { 12730fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville conn = call.getEarliestConnection(); 127479b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink } else { 127579b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink throw new IllegalStateException("Unexpected phone type: " + phoneType); 12760fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 12770fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 1278b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (conn != null) { 1279b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Object o = conn.getUserData(); 1280b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (o instanceof CallerInfo) { 1281b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project ci = (CallerInfo) o; 1282b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else if (o instanceof PhoneUtils.CallerInfoToken) { 1283b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project ci = ((PhoneUtils.CallerInfoToken) o).currentInfo; 1284b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1285b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1286b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1287b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1288b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (ci != null) { 1289b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project photoImageResource = ci.photoResource; 1290b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1291b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1292b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // If no photoResource found, check to see if this is a conference call. If 1293b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // it is not a conference call: 1294b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // 1. Try to show the cached image 1295b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // 2. If the image is not cached, check to see if a load request has been 1296b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // made already. 1297b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // 3. If the load request has not been made [DISPLAY_DEFAULT], start the 1298b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // request and note that it has started by updating photo state with 1299b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // [DISPLAY_IMAGE]. 1300b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Load requests started in (3) use a placeholder image of -1 to hide the 1301b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // image by default. Please refer to CallerInfoAsyncQuery.java for cases 1302b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // where CallerInfo.photoResource may be set. 1303b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (photoImageResource == 0) { 1304b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (!PhoneUtils.isConferenceCall(call)) { 1305b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (!showCachedImage(mPhoto, ci) && (mPhotoTracker.getPhotoState() == 1306b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project ContactsAsyncHelper.ImageTracker.DISPLAY_DEFAULT)) { 1307b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project ContactsAsyncHelper.updateImageViewWithContactPhotoAsync(ci, 1308b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project getContext(), mPhoto, mPhotoTracker.getPhotoUri(), -1); 1309b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhotoTracker.setPhotoState( 1310b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project ContactsAsyncHelper.ImageTracker.DISPLAY_IMAGE); 1311b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1312b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1313b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 1314b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project showImage(mPhoto, photoImageResource); 1315b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhotoTracker.setPhotoState(ContactsAsyncHelper.ImageTracker.DISPLAY_IMAGE); 1316b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return; 1317b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1318b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 1319b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1320b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1321b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (photoImageResource != 0) { 1322b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("- overrriding photo image: " + photoImageResource); 1323b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project showImage(mPhoto, photoImageResource); 1324b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Track the image state. 1325b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mPhotoTracker.setPhotoState(ContactsAsyncHelper.ImageTracker.DISPLAY_DEFAULT); 1326b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1327b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1328b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1329b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 1330b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Try to display the cached image from the callerinfo object. 1331b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 1332b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * @return true if we were able to find the image in the cache, false otherwise. 1333b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 13340d315275d08cd33f801ae3a74e8fc265520f6246David Brown private static final boolean showCachedImage(ImageView view, CallerInfo ci) { 1335b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if ((ci != null) && ci.isCachedPhotoCurrent) { 1336b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (ci.cachedPhoto != null) { 1337b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project showImage(view, ci.cachedPhoto); 1338b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 1339b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project showImage(view, R.drawable.picture_unknown); 1340b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1341b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return true; 1342b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1343b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return false; 1344b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1345b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1346b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** Helper function to display the resource in the imageview AND ensure its visibility.*/ 1347b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private static final void showImage(ImageView view, int resource) { 1348b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project view.setImageResource(resource); 1349b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project view.setVisibility(View.VISIBLE); 1350b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1351b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1352b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** Helper function to display the drawable in the imageview AND ensure its visibility.*/ 1353b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private static final void showImage(ImageView view, Drawable drawable) { 1354b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project view.setImageDrawable(drawable); 1355b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project view.setVisibility(View.VISIBLE); 1356b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1357b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1358b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 1359b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Returns the "Menu button hint" TextView (which is manipulated 1360b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * directly by the InCallScreen.) 1361b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * @see InCallScreen.updateMenuButtonHint() 1362b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 1363b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /* package */ TextView getMenuButtonHint() { 1364b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return mMenuButtonHint; 1365b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1366b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1367b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 1368b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Sets the left and right margins of the specified ViewGroup (whose 1369b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * LayoutParams object which must inherit from 1370b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * ViewGroup.MarginLayoutParams.) 1371b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 1372b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * TODO: Is there already a convenience method like this somewhere? 1373b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 1374b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void setSideMargins(ViewGroup vg, int margin) { 1375b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project ViewGroup.MarginLayoutParams lp = 1376b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project (ViewGroup.MarginLayoutParams) vg.getLayoutParams(); 1377b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Equivalent to setting android:layout_marginLeft/Right in XML 1378b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project lp.leftMargin = margin; 1379b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project lp.rightMargin = margin; 1380b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project vg.setLayoutParams(lp); 1381b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1382b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 13838bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project /** 13848bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project * Sets the CallCard "upper title". Also, depending on the passed-in 13858bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project * Call state, possibly display an icon along with the title. 13868bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project */ 138734a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown private void setUpperTitle(String title, int color, Call.State state) { 13888bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project mUpperTitle.setText(title); 138934a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown mUpperTitle.setTextColor(color); 13908bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project 13918bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project int bluetoothIconId = 0; 139234a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown if (!TextUtils.isEmpty(title) 139334a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown && ((state == Call.State.INCOMING) || (state == Call.State.WAITING)) 13940fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville && mApplication.showBluetoothIndication()) { 13958bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project // Display the special bluetooth icon also, if this is an incoming 13968bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project // call and the audio will be routed to bluetooth. 13978bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project bluetoothIconId = R.drawable.ic_incoming_call_bluetooth; 13988bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project } 13998bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project 14008bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project mUpperTitle.setCompoundDrawablesWithIntrinsicBounds(bluetoothIconId, 0, 0, 0); 140129d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown if (bluetoothIconId != 0) mUpperTitle.setCompoundDrawablePadding((int) (mDensity * 5)); 14028bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project } 14038bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project 1404af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville /** 140534a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown * Clears the CallCard "upper title", for states (like a normal 140634a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown * ongoing call) where we don't use any "title" at all. 140734a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown */ 140834a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown private void clearUpperTitle() { 140934a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown setUpperTitle("", 0, Call.State.IDLE); // Use dummy values for "color" and "state" 141034a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown } 141134a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown 141234a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown /** 1413af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * Hides the top-level UI elements of the call card: The "main 1414af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * call card" element representing the current active or ringing call, 1415af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * and also the info areas for "ongoing" or "on hold" calls in some 1416af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * states. 1417af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * 1418af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * This is intended to be used in special states where the normal 1419af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * in-call UI is totally replaced by some other UI, like OTA mode on a 1420af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * CDMA device. 1421af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * 1422af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * To bring back the regular CallCard UI, just re-run the normal 1423af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville * updateState() call sequence. 1424af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville */ 1425af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville public void hideCallCardElements() { 14260d315275d08cd33f801ae3a74e8fc265520f6246David Brown mPrimaryCallInfo.setVisibility(View.GONE); 14270d315275d08cd33f801ae3a74e8fc265520f6246David Brown mSecondaryCallInfo.setVisibility(View.GONE); 1428af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville } 1429b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 14309688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown /* 14319688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown * Updates the hint (like "Rotate to answer") that we display while 14329688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown * the user is dragging the incoming call RotarySelector widget. 14339688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown */ 14349688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown /* package */ void setRotarySelectorHint(int hintTextResId, int hintColorResId) { 14359688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown mRotarySelectorHintTextResId = hintTextResId; 14369688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown mRotarySelectorHintColorResId = hintColorResId; 14379688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown } 14389688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown 14396d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown // View.OnClickListener implementation 14406d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown public void onClick(View view) { 14416d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown int id = view.getId(); 14426d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown if (DBG) log("onClick(View " + view + ", id " + id + ")..."); 14436d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown 14446d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown switch (id) { 14456d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown case R.id.manageConferencePhotoButton: 14466d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown // A click on anything here gets forwarded 14476d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown // straight to the InCallScreen. 14486d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown mInCallScreen.handleOnscreenButtonClick(id); 14496d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown break; 14506d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown 14516d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown default: 14526d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown Log.w(LOG_TAG, "onClick: unexpected click: View " + view + ", id " + id); 14536d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown break; 14546d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown } 14556d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown } 14566d5544932495d81ff7ce53f4678c4beb25acc1b0David Brown 1457dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown // Accessibility event support. 1458dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown // Since none of the CallCard elements are focusable, we need to manually 1459dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown // fill in the AccessibilityEvent here (so that the name / number / etc will 1460dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown // get pronounced by a screen reader, for example.) 1461dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown @Override 1462dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { 1463dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown dispatchPopulateAccessibilityEvent(event, mUpperTitle); 1464dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown dispatchPopulateAccessibilityEvent(event, mPhoto); 1465dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown dispatchPopulateAccessibilityEvent(event, mManageConferencePhotoButton); 1466dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown dispatchPopulateAccessibilityEvent(event, mName); 1467dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown dispatchPopulateAccessibilityEvent(event, mPhoneNumber); 1468dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown dispatchPopulateAccessibilityEvent(event, mLabel); 1469dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown dispatchPopulateAccessibilityEvent(event, mSocialStatus); 1470dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown dispatchPopulateAccessibilityEvent(event, mSecondaryCallName); 1471dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown dispatchPopulateAccessibilityEvent(event, mSecondaryCallStatus); 1472dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown dispatchPopulateAccessibilityEvent(event, mSecondaryCallPhoto); 1473dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown return true; 1474dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown } 1475dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown 1476dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown private void dispatchPopulateAccessibilityEvent(AccessibilityEvent event, View view) { 1477dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown List<CharSequence> eventText = event.getText(); 1478dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown int size = eventText.size(); 1479dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown view.dispatchPopulateAccessibilityEvent(event); 1480dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown // if no text added write null to keep relative position 1481dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown if (size == eventText.size()) { 1482dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown eventText.add(null); 1483dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown } 1484dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown } 1485dc66301e77d854b6cef2101bf7029c9bbb816f3eDavid Brown 14869688349b8750a9ac7282d83993e0112c5f51e7acDavid Brown 1487b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Debugging / testing code 1488b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1489b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void log(String msg) { 1490796c70c99bc39295bf685061056f06ab8949c742David Brown Log.d(LOG_TAG, msg); 1491b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1492b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project} 1493