CallCard.java revision 8da4d90151c882972e15429d4d48bdaa45095d72
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.MotionEvent;
31b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.view.View;
32b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.view.ViewGroup;
33b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.widget.FrameLayout;
34b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.widget.ImageView;
35b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.widget.TextView;
36b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
376b7d0da33af02960736da204eb7a25ccf91d5396David Brownimport com.android.internal.telephony.Call;
386b7d0da33af02960736da204eb7a25ccf91d5396David Brownimport com.android.internal.telephony.CallerInfo;
396b7d0da33af02960736da204eb7a25ccf91d5396David Brownimport com.android.internal.telephony.CallerInfoAsyncQuery;
406b7d0da33af02960736da204eb7a25ccf91d5396David Brownimport com.android.internal.telephony.Connection;
416b7d0da33af02960736da204eb7a25ccf91d5396David Brownimport com.android.internal.telephony.Phone;
426b7d0da33af02960736da204eb7a25ccf91d5396David Brown
430fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Savilleimport java.util.List;
440fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville
456b7d0da33af02960736da204eb7a25ccf91d5396David Brown
46b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project/**
47b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * "Call card" UI element: the in-call screen contains a tiled layout of call
48b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * cards, each representing the state of a current "call" (ie. an active call,
49b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * a call on hold, or an incoming call.)
50b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */
51b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectpublic class CallCard extends FrameLayout
52b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        implements CallTime.OnTickListener, CallerInfoAsyncQuery.OnQueryCompleteListener,
53b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                ContactsAsyncHelper.OnImageLoadCompleteListener{
54796c70c99bc39295bf685061056f06ab8949c742David Brown    private static final String LOG_TAG = "CallCard";
55796c70c99bc39295bf685061056f06ab8949c742David Brown    private static final boolean DBG = (PhoneApp.DBG_LEVEL >= 2);
56b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
578bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project    /**
588bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     * Reference to the InCallScreen activity that owns us.  This may be
598bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     * null if we haven't been initialized yet *or* after the InCallScreen
608bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     * activity has been destroyed.
618bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     */
628bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project    private InCallScreen mInCallScreen;
638bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project
640fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville    // Phone app instance
650fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville    private PhoneApp mApplication;
660fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville
67b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // Top-level subviews of the CallCard
680d315275d08cd33f801ae3a74e8fc265520f6246David Brown    private ViewGroup mPrimaryCallInfo;
690d315275d08cd33f801ae3a74e8fc265520f6246David Brown    private ViewGroup mSecondaryCallInfo;
70b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
7134a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown    // Title and elapsed-time widgets
72b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private TextView mUpperTitle;
73b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private TextView mElapsedTime;
74b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
7534a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown    // Text colors, used for various labels / titles
7634a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown    private int mTextColorTitleDefault;
77b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private int mTextColorConnected;
788bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project    private int mTextColorConnectedBluetooth;
79b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private int mTextColorEnded;
80b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private int mTextColorOnHold;
81b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
820d315275d08cd33f801ae3a74e8fc265520f6246David Brown    // The main block of info about the "primary" or "active" call,
830d315275d08cd33f801ae3a74e8fc265520f6246David Brown    // including photo / name / phone number / etc.
84b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private ImageView mPhoto;
85b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private TextView mName;
86b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private TextView mPhoneNumber;
87b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private TextView mLabel;
8829d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown    private TextView mSocialStatus;
89b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
900d315275d08cd33f801ae3a74e8fc265520f6246David Brown    // Info about the "secondary" call, which is the "call on hold" when
910d315275d08cd33f801ae3a74e8fc265520f6246David Brown    // two lines are in use.
920d315275d08cd33f801ae3a74e8fc265520f6246David Brown    private TextView mSecondaryCallName;
930d315275d08cd33f801ae3a74e8fc265520f6246David Brown    private TextView mSecondaryCallStatus;
940d315275d08cd33f801ae3a74e8fc265520f6246David Brown    private ImageView mSecondaryCallPhoto;
95b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
96b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // Menu button hint
97b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private TextView mMenuButtonHint;
98b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
99b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private CallTime mCallTime;
100b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
101b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // Track the state for the photo.
102b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private ContactsAsyncHelper.ImageTracker mPhotoTracker;
103b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
10429d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown    // Cached DisplayMetrics density.
10529d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown    private float mDensity;
10629d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown
107b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public CallCard(Context context, AttributeSet attrs) {
108b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        super(context, attrs);
109b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
110b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("CallCard constructor...");
111b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("- this = " + this);
112b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("- context " + context + ", attrs " + attrs);
113b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
114b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Inflate the contents of this CallCard, and add it (to ourself) as a child.
115b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        LayoutInflater inflater = LayoutInflater.from(context);
116b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        inflater.inflate(
117b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                R.layout.call_card,  // resource
118b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                this,                // root
119b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                true);
120b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1210fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville        mApplication = PhoneApp.getInstance();
1220fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville
123b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mCallTime = new CallTime(this);
124b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
125b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // create a new object to track the state for the photo.
126b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mPhotoTracker = new ContactsAsyncHelper.ImageTracker();
12729d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown
12829d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown        mDensity = getResources().getDisplayMetrics().density;
12929d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown        if (DBG) log("- Density: " + mDensity);
130b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
131b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1328bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project    void setInCallScreenInstance(InCallScreen inCallScreen) {
1338bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project        mInCallScreen = inCallScreen;
1348bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project    }
1358bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project
136b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public void onTickForCallTimeElapsed(long timeElapsed) {
137b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // While a call is in progress, update the elapsed time shown
138b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // onscreen.
139b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        updateElapsedTimeWidget(timeElapsed);
140b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
141b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
142b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /* package */
143b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    void stopTimer() {
144b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mCallTime.cancelTimer();
145b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
146b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
147b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    @Override
148b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    protected void onFinishInflate() {
149b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        super.onFinishInflate();
150b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
151b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("CallCard onFinishInflate(this = " + this + ")...");
152b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1530d315275d08cd33f801ae3a74e8fc265520f6246David Brown        mPrimaryCallInfo = (ViewGroup) findViewById(R.id.primaryCallInfo);
1540d315275d08cd33f801ae3a74e8fc265520f6246David Brown        mSecondaryCallInfo = (ViewGroup) findViewById(R.id.secondaryCallInfo);
155b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
156b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // "Upper" and "lower" title widgets
157b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mUpperTitle = (TextView) findViewById(R.id.upperTitle);
158b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mElapsedTime = (TextView) findViewById(R.id.elapsedTime);
159b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
160b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Text colors
16134a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown        mTextColorTitleDefault = getResources().getColor(android.R.color.primary_text_dark);
162b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mTextColorConnected = getResources().getColor(R.color.incall_textConnected);
1638bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project        mTextColorConnectedBluetooth =
1648bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                getResources().getColor(R.color.incall_textConnectedBluetooth);
165b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mTextColorEnded = getResources().getColor(R.color.incall_textEnded);
166b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mTextColorOnHold = getResources().getColor(R.color.incall_textOnHold);
167b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
168b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // "Caller info" area, including photo / name / phone numbers / etc
169b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mPhoto = (ImageView) findViewById(R.id.photo);
170b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mName = (TextView) findViewById(R.id.name);
171b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mPhoneNumber = (TextView) findViewById(R.id.phoneNumber);
172b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mLabel = (TextView) findViewById(R.id.label);
17329d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown        mSocialStatus = (TextView) findViewById(R.id.socialStatus);
174b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
175b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // "Other call" info area
1760d315275d08cd33f801ae3a74e8fc265520f6246David Brown        mSecondaryCallName = (TextView) findViewById(R.id.secondaryCallName);
1770d315275d08cd33f801ae3a74e8fc265520f6246David Brown        mSecondaryCallStatus = (TextView) findViewById(R.id.secondaryCallStatus);
1780d315275d08cd33f801ae3a74e8fc265520f6246David Brown        mSecondaryCallPhoto = (ImageView) findViewById(R.id.secondaryCallPhoto);
179b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
180b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Menu Button hint
181b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mMenuButtonHint = (TextView) findViewById(R.id.menuButtonHint);
182b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
183b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
184b15bef0ddcb4f744dff92013a9b596f2fcc2a008David Brown    /**
185b15bef0ddcb4f744dff92013a9b596f2fcc2a008David Brown     * Updates the state of all UI elements on the CallCard, based on the
186b15bef0ddcb4f744dff92013a9b596f2fcc2a008David Brown     * current state of the phone.
187b15bef0ddcb4f744dff92013a9b596f2fcc2a008David Brown     */
188b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    void updateState(Phone phone) {
189b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("updateState(" + phone + ")...");
190b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
191b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Update some internal state based on the current state of the phone.
1926b7d0da33af02960736da204eb7a25ccf91d5396David Brown
1936b7d0da33af02960736da204eb7a25ccf91d5396David Brown        // TODO: clean up this method to just fully update EVERYTHING in
1946b7d0da33af02960736da204eb7a25ccf91d5396David Brown        // the callcard based on the current phone state: set the overall
1956b7d0da33af02960736da204eb7a25ccf91d5396David Brown        // type of the CallCard, load up the main caller info area, and
1966b7d0da33af02960736da204eb7a25ccf91d5396David Brown        // load up and show or hide the "other call" area if necessary.
197b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
198b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Phone.State state = phone.getState();  // IDLE, RINGING, or OFFHOOK
199b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (state == Phone.State.RINGING) {
200b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // A phone call is ringing *or* call waiting
201b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // (ie. another call may also be active as well.)
202b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            updateRingingCall(phone);
203b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        } else if (state == Phone.State.OFFHOOK) {
204b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // The phone is off hook. At least one call exists that is
205b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // dialing, active, or holding, and no calls are ringing or waiting.
206b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            updateForegroundCall(phone);
207b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        } else {
208b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // The phone state is IDLE!
209b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            //
210b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // The most common reason for this is if a call just
211b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // ended: the phone will be idle, but we *will* still
212b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // have a call in the DISCONNECTED state:
213b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            Call fgCall = phone.getForegroundCall();
214b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            Call bgCall = phone.getBackgroundCall();
215b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if ((fgCall.getState() == Call.State.DISCONNECTED)
216b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                || (bgCall.getState() == Call.State.DISCONNECTED)) {
217b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // In this case, we want the main CallCard to display
218b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // the "Call ended" state.  The normal "foreground call"
219b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // code path handles that.
220b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                updateForegroundCall(phone);
221b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            } else {
222b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // We don't have any DISCONNECTED calls, which means
223b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // that the phone is *truly* idle.
224b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                //
225b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // It's very rare to be on the InCallScreen at all in this
226b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // state, but it can happen in some cases:
227b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // - A stray onPhoneStateChanged() event came in to the
228b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                //   InCallScreen *after* it was dismissed.
229b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // - We're allowed to be on the InCallScreen because
230b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                //   an MMI or USSD is running, but there's no actual "call"
231b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                //   to display.
232b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // - We're displaying an error dialog to the user
233b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                //   (explaining why the call failed), so we need to stay on
234b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                //   the InCallScreen so that the dialog will be visible.
235b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                //
236b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // In these cases, put the callcard into a sane but "blank" state:
237b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                updateNoCall(phone);
238b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
239b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
240b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
241b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
242b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
243b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Updates the UI for the state where the phone is in use, but not ringing.
244b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
245b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void updateForegroundCall(Phone phone) {
246b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("updateForegroundCall()...");
247b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
248b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Call fgCall = phone.getForegroundCall();
249b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Call bgCall = phone.getBackgroundCall();
250b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
251b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (fgCall.isIdle() && !fgCall.hasConnections()) {
252b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (DBG) log("updateForegroundCall: no active call, show holding call");
253b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // TODO: make sure this case agrees with the latest UI spec.
254b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
255b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // Display the background call in the main info area of the
256b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // CallCard, since there is no foreground call.  Note that
257b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // displayMainCallStatus() will notice if the call we passed in is on
258b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // hold, and display the "on hold" indication.
259b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            fgCall = bgCall;
260b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
261b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // And be sure to not display anything in the "on hold" box.
262b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            bgCall = null;
263b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
264b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
265b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        displayMainCallStatus(phone, fgCall);
2660fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville
26779b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink        int phoneType = phone.getPhoneType();
26879b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink        if (phoneType == Phone.PHONE_TYPE_CDMA) {
2690fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville            if (mApplication.cdmaPhoneCallState.getCurrentCallState()
2700fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville                    == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
2710fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville                displayOnHoldCallStatus(phone, fgCall);
2720fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville            } else {
2730fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville                //This is required so that even if a background call is not present
2740fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville                // we need to clean up the background call area.
2750fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville                displayOnHoldCallStatus(phone, bgCall);
2760fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville            }
27779b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink        } else if (phoneType == Phone.PHONE_TYPE_GSM) {
2780fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville            displayOnHoldCallStatus(phone, bgCall);
2790fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville        }
280b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
281b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
282b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
283b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Updates the UI for the state where an incoming call is ringing (or
284b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * call waiting), regardless of whether the phone's already offhook.
285b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
286b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void updateRingingCall(Phone phone) {
287b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("updateRingingCall()...");
288b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
289b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Call ringingCall = phone.getRingingCall();
290b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Call fgCall = phone.getForegroundCall();
291b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Call bgCall = phone.getBackgroundCall();
292b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
2936b7d0da33af02960736da204eb7a25ccf91d5396David Brown        // Display caller-id info and photo from the incoming call:
294b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        displayMainCallStatus(phone, ringingCall);
2956b7d0da33af02960736da204eb7a25ccf91d5396David Brown
2966b7d0da33af02960736da204eb7a25ccf91d5396David Brown        // And even in the Call Waiting case, *don't* show any info about
2976b7d0da33af02960736da204eb7a25ccf91d5396David Brown        // the current ongoing call and/or the current call on hold.
2986b7d0da33af02960736da204eb7a25ccf91d5396David Brown        // (Since the caller-id info for the incoming call totally trumps
2996b7d0da33af02960736da204eb7a25ccf91d5396David Brown        // any info about the current call(s) in progress.)
3006b7d0da33af02960736da204eb7a25ccf91d5396David Brown        displayOnHoldCallStatus(phone, null);
301b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
302b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
303b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
304b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Updates the UI for the state where the phone is not in use.
305b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * This is analogous to updateForegroundCall() and updateRingingCall(),
306b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * but for the (uncommon) case where the phone is
307b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * totally idle.  (See comments in updateState() above.)
308b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
309b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * This puts the callcard into a sane but "blank" state.
310b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
311b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void updateNoCall(Phone phone) {
312b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("updateNoCall()...");
313b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
314b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        displayMainCallStatus(phone, null);
315b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        displayOnHoldCallStatus(phone, null);
316b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
317b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
318b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
319b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Updates the main block of caller info on the CallCard
3200d315275d08cd33f801ae3a74e8fc265520f6246David Brown     * (ie. the stuff in the primaryCallInfo block) based on the specified Call.
321b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
322b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void displayMainCallStatus(Phone phone, Call call) {
323b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("displayMainCallStatus(phone " + phone
324b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                     + ", call " + call + ")...");
325b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
326b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (call == null) {
327b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // There's no call to display, presumably because the phone is idle.
3280d315275d08cd33f801ae3a74e8fc265520f6246David Brown            mPrimaryCallInfo.setVisibility(View.GONE);
329b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return;
330b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
3310d315275d08cd33f801ae3a74e8fc265520f6246David Brown        mPrimaryCallInfo.setVisibility(View.VISIBLE);
332b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
333b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Call.State state = call.getState();
334b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("  - call.state: " + call.getState());
335b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
336b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        switch (state) {
337b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case ACTIVE:
3385eff1e7d582679b3a85f580eb1d550b2e6ca111cDavid Brown            case DISCONNECTING:
339b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // update timer field
340b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (DBG) log("displayMainCallStatus: start periodicUpdateTimer");
341b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mCallTime.setActiveCallMode(call);
342b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mCallTime.reset();
343b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mCallTime.periodicUpdateTimer();
344b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
345b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
346b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
347b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case HOLDING:
348b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // update timer field
349b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mCallTime.cancelTimer();
350b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
351b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
352b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
353b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case DISCONNECTED:
354b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // Stop getting timer ticks from this call
355b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mCallTime.cancelTimer();
356b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
357b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
358b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
359b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case DIALING:
360b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case ALERTING:
361b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // Stop getting timer ticks from a previous call
362b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mCallTime.cancelTimer();
363b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
364b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
365b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
366b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case INCOMING:
367b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case WAITING:
368b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // Stop getting timer ticks from a previous call
369b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mCallTime.cancelTimer();
370b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
371b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
372b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
373b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case IDLE:
374b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // The "main CallCard" should never be trying to display
375b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // an idle call!  In updateState(), if the phone is idle,
376b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // we call updateNoCall(), which means that we shouldn't
377b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // have passed a call into this method at all.
378b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                Log.w(LOG_TAG, "displayMainCallStatus: IDLE call in the main call card!");
379b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
380b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // (It is possible, though, that we had a valid call which
381b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // became idle *after* the check in updateState() but
382b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // before we get here...  So continue the best we can,
383b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // with whatever (stale) info we can get from the
384b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // passed-in Call object.)
385b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
386b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
387b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
388b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            default:
389b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                Log.w(LOG_TAG, "displayMainCallStatus: unexpected call state: " + state);
390b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
391b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
392b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
393b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        updateCardTitleWidgets(phone, call);
394b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
395b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (PhoneUtils.isConferenceCall(call)) {
396b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // Update onscreen info for a conference call.
397b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            updateDisplayForConference();
398b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        } else {
399b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // Update onscreen info for a regular call (which presumably
400b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // has only one connection.)
4010fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville            Connection conn = null;
40279b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink            int phoneType = phone.getPhoneType();
40379b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink            if (phoneType == Phone.PHONE_TYPE_CDMA) {
4040fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville                conn = call.getLatestConnection();
40579b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink            } else if (phoneType == Phone.PHONE_TYPE_GSM) {
4060fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville                conn = call.getEarliestConnection();
40779b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink            } else {
40879b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink                throw new IllegalStateException("Unexpected phone type: " + phoneType);
4090fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville            }
410b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
411b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (conn == null) {
412b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (DBG) log("displayMainCallStatus: connection is null, using default values.");
413b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // if the connection is null, we run through the behaviour
414b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // we had in the past, which breaks down into trivial steps
415b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // with the current implementation of getCallerInfo and
416b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // updateDisplayForPerson.
4174359358c4f430cbb986a5e7640ec506f08f1e332David Brown                CallerInfo info = PhoneUtils.getCallerInfo(getContext(), null /* conn */);
4184359358c4f430cbb986a5e7640ec506f08f1e332David Brown                updateDisplayForPerson(info, Connection.PRESENTATION_ALLOWED, false, call);
419b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            } else {
420b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (DBG) log("  - CONN: " + conn + ", state = " + conn.getState());
4214359358c4f430cbb986a5e7640ec506f08f1e332David Brown                int presentation = conn.getNumberPresentation();
422b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
423b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // make sure that we only make a new query when the current
424b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // callerinfo differs from what we've been requested to display.
425b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                boolean runQuery = true;
426b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                Object o = conn.getUserData();
427b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (o instanceof PhoneUtils.CallerInfoToken) {
428b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    runQuery = mPhotoTracker.isDifferentImageRequest(
429b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                            ((PhoneUtils.CallerInfoToken) o).currentInfo);
430b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                } else {
431b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    runQuery = mPhotoTracker.isDifferentImageRequest(conn);
432b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
433b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
43446532b66a467f247380054270c6151aa3dc7a761Wink Saville                // Adding a check to see if the update was caused due to a Phone number update
43546532b66a467f247380054270c6151aa3dc7a761Wink Saville                // or CNAP update. If so then we need to start a new query
43679b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink                if (phoneType == Phone.PHONE_TYPE_CDMA) {
43746532b66a467f247380054270c6151aa3dc7a761Wink Saville                    Object obj = conn.getUserData();
43846532b66a467f247380054270c6151aa3dc7a761Wink Saville                    String updatedNumber = conn.getAddress();
43946532b66a467f247380054270c6151aa3dc7a761Wink Saville                    String updatedCnapName = conn.getCnapName();
44046532b66a467f247380054270c6151aa3dc7a761Wink Saville                    CallerInfo info = null;
44146532b66a467f247380054270c6151aa3dc7a761Wink Saville                    if (obj instanceof PhoneUtils.CallerInfoToken) {
44246532b66a467f247380054270c6151aa3dc7a761Wink Saville                        info = ((PhoneUtils.CallerInfoToken) o).currentInfo;
44346532b66a467f247380054270c6151aa3dc7a761Wink Saville                    } else if (o instanceof CallerInfo) {
44446532b66a467f247380054270c6151aa3dc7a761Wink Saville                        info = (CallerInfo) o;
44546532b66a467f247380054270c6151aa3dc7a761Wink Saville                    }
44646532b66a467f247380054270c6151aa3dc7a761Wink Saville
44746532b66a467f247380054270c6151aa3dc7a761Wink Saville                    if (info != null) {
44846532b66a467f247380054270c6151aa3dc7a761Wink Saville                        if (updatedNumber != null && !updatedNumber.equals(info.phoneNumber)) {
44946532b66a467f247380054270c6151aa3dc7a761Wink Saville                            if (DBG) log("- displayMainCallStatus: updatedNumber = "
45046532b66a467f247380054270c6151aa3dc7a761Wink Saville                                    + updatedNumber);
45146532b66a467f247380054270c6151aa3dc7a761Wink Saville                            runQuery = true;
45246532b66a467f247380054270c6151aa3dc7a761Wink Saville                        }
45346532b66a467f247380054270c6151aa3dc7a761Wink Saville                        if (updatedCnapName != null && !updatedCnapName.equals(info.cnapName)) {
45446532b66a467f247380054270c6151aa3dc7a761Wink Saville                            if (DBG) log("- displayMainCallStatus: updatedCnapName = "
45546532b66a467f247380054270c6151aa3dc7a761Wink Saville                                    + updatedCnapName);
45646532b66a467f247380054270c6151aa3dc7a761Wink Saville                            runQuery = true;
45746532b66a467f247380054270c6151aa3dc7a761Wink Saville                        }
45846532b66a467f247380054270c6151aa3dc7a761Wink Saville                    }
45946532b66a467f247380054270c6151aa3dc7a761Wink Saville                }
46046532b66a467f247380054270c6151aa3dc7a761Wink Saville
461b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (runQuery) {
462b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (DBG) log("- displayMainCallStatus: starting CallerInfo query...");
463b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    PhoneUtils.CallerInfoToken info =
464b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                            PhoneUtils.startGetCallerInfo(getContext(), conn, this, call);
4654b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project                    updateDisplayForPerson(info.currentInfo, presentation, !info.isFinal, call);
466b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                } else {
467b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // No need to fire off a new query.  We do still need
468b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // to update the display, though (since we might have
469b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // previously been in the "conference call" state.)
470b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (DBG) log("- displayMainCallStatus: using data we already have...");
471b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (o instanceof CallerInfo) {
472b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        CallerInfo ci = (CallerInfo) o;
473e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai                        // Update CNAP information if Phone state change occurred
474e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai                        ci.cnapName = conn.getCnapName();
475e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai                        ci.numberPresentation = conn.getNumberPresentation();
476e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai                        ci.namePresentation = conn.getCnapNamePresentation();
477e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai                        if (DBG) log("- displayMainCallStatus: CNAP data from Connection: "
478e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai                                + "CNAP name=" + ci.cnapName
479e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai                                + ", Number/Name Presentation=" + ci.numberPresentation);
480b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        if (DBG) log("   ==> Got CallerInfo; updating display: ci = " + ci);
4814b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project                        updateDisplayForPerson(ci, presentation, false, call);
482b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    } else if (o instanceof PhoneUtils.CallerInfoToken){
483b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        CallerInfo ci = ((PhoneUtils.CallerInfoToken) o).currentInfo;
484e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai                        if (DBG) log("- displayMainCallStatus: CNAP data from Connection: "
485e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai                                + "CNAP name=" + ci.cnapName
486e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai                                + ", Number/Name Presentation=" + ci.numberPresentation);
487b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        if (DBG) log("   ==> Got CallerInfoToken; updating display: ci = " + ci);
4884b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project                        updateDisplayForPerson(ci, presentation, true, call);
489b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    } else {
490b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        Log.w(LOG_TAG, "displayMainCallStatus: runQuery was false, "
491b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                              + "but we didn't have a cached CallerInfo object!  o = " + o);
492b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        // TODO: any easy way to recover here (given that
493b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        // the CallCard is probably displaying stale info
494b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        // right now?)  Maybe force the CallCard into the
495b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        // "Unknown" state?
496b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    }
497b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
498b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
499b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
500b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
501b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // In some states we override the "photo" ImageView to be an
502b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // indication of the current state, rather than displaying the
503b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // regular photo as set above.
504b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        updatePhotoForCallState(call);
505b15bef0ddcb4f744dff92013a9b596f2fcc2a008David Brown    }
506b15bef0ddcb4f744dff92013a9b596f2fcc2a008David Brown
507b15bef0ddcb4f744dff92013a9b596f2fcc2a008David Brown    /**
508b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Implemented for CallerInfoAsyncQuery.OnQueryCompleteListener interface.
509b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * refreshes the CallCard data when it called.
510b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
511b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public void onQueryComplete(int token, Object cookie, CallerInfo ci) {
512b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("onQueryComplete: token " + token + ", cookie " + cookie + ", ci " + ci);
513b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
514b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (cookie instanceof Call) {
515b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // grab the call object and update the display for an individual call,
516b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // as well as the successive call to update image via call state.
517b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // If the object is a textview instead, we update it as we need to.
518b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (DBG) log("callerinfo query complete, updating ui from displayMainCallStatus()");
519b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            Call call = (Call) cookie;
520e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai            Connection conn = call.getEarliestConnection();
521e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai            PhoneUtils.CallerInfoToken cit =
522e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai                   PhoneUtils.startGetCallerInfo(getContext(), conn, this, null);
523e066d6979acb39dbc0ba79ecc10bc12e84a15195David Brown
524e066d6979acb39dbc0ba79ecc10bc12e84a15195David Brown            int presentation = Connection.PRESENTATION_ALLOWED;
525e066d6979acb39dbc0ba79ecc10bc12e84a15195David Brown            if (conn != null) presentation = conn.getNumberPresentation();
526e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai            if (DBG) log("- onQueryComplete: presentation=" + presentation
527e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai                    + ", contactExists=" + ci.contactExists);
528e066d6979acb39dbc0ba79ecc10bc12e84a15195David Brown
529e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai            // Depending on whether there was a contact match or not, we want to pass in different
530e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai            // CallerInfo (for CNAP). Therefore if ci.contactExists then use the ci passed in.
531e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai            // Otherwise, regenerate the CIT from the Connection and use the CallerInfo from there.
532e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai            if (ci.contactExists) {
533e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai                updateDisplayForPerson(ci, Connection.PRESENTATION_ALLOWED, false, call);
534e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai            } else {
535e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai                updateDisplayForPerson(cit.currentInfo, presentation, false, call);
536e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai            }
537b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            updatePhotoForCallState(call);
538b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
539b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        } else if (cookie instanceof TextView){
540b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (DBG) log("callerinfo query complete, updating ui from ongoing or onhold");
541b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            ((TextView) cookie).setText(PhoneUtils.getCompactNameFromCallerInfo(ci, mContext));
542b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
543b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
544b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
545b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
546b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Implemented for ContactsAsyncHelper.OnImageLoadCompleteListener interface.
547b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * make sure that the call state is reflected after the image is loaded.
548b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
549b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public void onImageLoadComplete(int token, Object cookie, ImageView iView,
550b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            boolean imagePresent){
551b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (cookie != null) {
552b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            updatePhotoForCallState((Call) cookie);
553b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
554b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
555b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
556b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
55734a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown     * Updates the "card title" (and also elapsed time widget) based on
55834a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown     * the current state of the call.
559b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
560b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void updateCardTitleWidgets(Phone phone, Call call) {
561b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("updateCardTitleWidgets(call " + call + ")...");
562b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Call.State state = call.getState();
563b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
564b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // TODO: Still need clearer spec on exactly how title *and* status get
565b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // set in all states.  (Then, given that info, refactor the code
566b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // here to be more clear about exactly which widgets on the card
567b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // need to be set.)
568b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
5693800ac871d6548790ac6119bb68b9be0640af261David Krause        String cardTitle;
57079b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink        int phoneType = mApplication.phone.getPhoneType();
57179b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink        if (phoneType == Phone.PHONE_TYPE_CDMA) {
5723800ac871d6548790ac6119bb68b9be0640af261David Krause            if (!PhoneApp.getInstance().notifier.getIsCdmaRedialCall()) {
5736b7d0da33af02960736da204eb7a25ccf91d5396David Brown                cardTitle = getTitleForCallCard(call);  // Normal "foreground" call card
5743800ac871d6548790ac6119bb68b9be0640af261David Krause            } else {
5753800ac871d6548790ac6119bb68b9be0640af261David Krause                cardTitle = getContext().getString(R.string.card_title_redialing);
5763800ac871d6548790ac6119bb68b9be0640af261David Krause            }
57779b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink        } else if (phoneType == Phone.PHONE_TYPE_GSM) {
5783800ac871d6548790ac6119bb68b9be0640af261David Krause            cardTitle = getTitleForCallCard(call);
57979b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink        } else {
58079b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink            throw new IllegalStateException("Unexpected phone type: " + phoneType);
5813800ac871d6548790ac6119bb68b9be0640af261David Krause        }
582b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("updateCardTitleWidgets: " + cardTitle);
583b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
58434a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown        // Update the title and elapsed time widgets based on the current call state.
58534a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown        switch (state) {
58634a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown            case ACTIVE:
58734a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown            case DISCONNECTING:
58834a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                final boolean bluetoothActive = mApplication.showBluetoothIndication();
58934a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                int ongoingCallIcon = bluetoothActive ? R.drawable.ic_incall_ongoing_bluetooth
59034a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                        : R.drawable.ic_incall_ongoing;
59134a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                int connectedTextColor = bluetoothActive
59234a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                        ? mTextColorConnectedBluetooth : mTextColorConnected;
593b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
59479b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink                if (phoneType == Phone.PHONE_TYPE_CDMA) {
59534a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                    // Check if the "Dialing" 3Way call needs to be displayed
59634a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                    // as the Foreground Call state still remains ACTIVE
59734a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                    if (mApplication.cdmaPhoneCallState.IsThreeWayCallOrigStateDialing()) {
59834a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                        // Use the "upper title":
59934a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                        setUpperTitle(cardTitle, mTextColorTitleDefault, state);
60034a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                    } else {
60134a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                        // Normal "ongoing call" state; don't use any "title" at all.
60234a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                        clearUpperTitle();
60334a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                    }
60479b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink                } else if (phoneType == Phone.PHONE_TYPE_GSM) {
60534a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                    // Normal "ongoing call" state; don't use any "title" at all.
60634a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                    clearUpperTitle();
60734a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                }
60834a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown
60934a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                // Use the elapsed time widget to show the current call duration.
61034a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                mElapsedTime.setVisibility(View.VISIBLE);
61134a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                mElapsedTime.setTextColor(connectedTextColor);
61234a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                long duration = CallTime.getCallDuration(call);  // msec
61334a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                updateElapsedTimeWidget(duration / 1000);
61434a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                // Also see onTickForCallTimeElapsed(), which updates this
61534a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                // widget once per second while the call is active.
61634a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                break;
61734a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown
61834a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown            case DISCONNECTED:
61934a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                // Display "Call ended" (or possibly some error indication;
62034a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                // see getCallFailedString()) in the upper title, in red.
62134a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown
62234a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                // TODO: display a "call ended" icon somewhere, like the old
62334a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                // R.drawable.ic_incall_end?
62434a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown
62534a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                setUpperTitle(cardTitle, mTextColorEnded, state);
62634a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown
62734a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                // In the "Call ended" state, leave the mElapsedTime widget
62834a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                // visible, but don't touch it (so  we continue to see the elapsed time of
62934a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                // the call that just ended.)
63034a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                mElapsedTime.setVisibility(View.VISIBLE);
63134a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                mElapsedTime.setTextColor(mTextColorEnded);
63234a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                break;
63334a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown
63434a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown            case HOLDING:
63534a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                // For a single call on hold, display the title "On hold" in
63634a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                // orange.
63734a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                // (But since the upper title overlaps the label of the
63834a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                // Hold/Unhold button, we actually use the elapsedTime widget
63934a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                // to display the title in this case.)
64034a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown
64134a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                // TODO: display an "On hold" icon somewhere, like the old
64234a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                // R.drawable.ic_incall_onhold?
64334a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown
64434a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                clearUpperTitle();
64534a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                mElapsedTime.setText(cardTitle);
64634a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown
64734a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                // While on hold, the elapsed time widget displays an
64834a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                // "on hold" indication rather than an amount of time.
64934a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                mElapsedTime.setVisibility(View.VISIBLE);
65034a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                mElapsedTime.setTextColor(mTextColorOnHold);
65134a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                break;
65234a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown
65334a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown            default:
65434a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                // All other states (DIALING, INCOMING, etc.) use the "upper title":
65534a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                setUpperTitle(cardTitle, mTextColorTitleDefault, state);
65634a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown
65734a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                // ...and we don't show the elapsed time.
65834a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                mElapsedTime.setVisibility(View.INVISIBLE);
65934a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                break;
660b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
661b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
662b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
663b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
664b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Updates mElapsedTime based on the specified number of seconds.
665b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * A timeElapsed value of zero means to not show an elapsed time at all.
666b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
667b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void updateElapsedTimeWidget(long timeElapsed) {
668b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // if (DBG) log("updateElapsedTimeWidget: " + timeElapsed);
669b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (timeElapsed == 0) {
670b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mElapsedTime.setText("");
671b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        } else {
672b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mElapsedTime.setText(DateUtils.formatElapsedTime(timeElapsed));
673b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
674b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
675b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
676b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
677b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Returns the "card title" displayed at the top of a foreground
678b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * ("active") CallCard to indicate the current state of this call, like
679b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * "Dialing" or "In call" or "On hold".  A null return value means that
680b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * there's no title string for this state.
681b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
682b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private String getTitleForCallCard(Call call) {
683b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        String retVal = null;
684b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Call.State state = call.getState();
685b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Context context = getContext();
686b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        int resId;
687b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
688b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("- getTitleForCallCard(Call " + call + ")...");
689b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
690b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        switch (state) {
691b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case IDLE:
692b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
693b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
694b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case ACTIVE:
695b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // Title is "Call in progress".  (Note this appears in the
696b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // "lower title" area of the CallCard.)
69779b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink                int phoneType = mApplication.phone.getPhoneType();
69879b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink                if (phoneType == Phone.PHONE_TYPE_CDMA) {
6990fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville                    if (mApplication.cdmaPhoneCallState.IsThreeWayCallOrigStateDialing()) {
7000fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville                        retVal = context.getString(R.string.card_title_dialing);
7010fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville                    } else {
7020fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville                        retVal = context.getString(R.string.card_title_in_progress);
7030fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville                    }
70479b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink                } else if (phoneType == Phone.PHONE_TYPE_GSM) {
7050fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville                    retVal = context.getString(R.string.card_title_in_progress);
70679b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink                } else {
70779b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink                    throw new IllegalStateException("Unexpected phone type: " + phoneType);
7080fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville                }
709b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
710b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
711b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case HOLDING:
712b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                retVal = context.getString(R.string.card_title_on_hold);
713b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // TODO: if this is a conference call on hold,
714b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // maybe have a special title here too?
715b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
716b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
717b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case DIALING:
718b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case ALERTING:
719b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                retVal = context.getString(R.string.card_title_dialing);
720b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
721b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
722b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case INCOMING:
723b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case WAITING:
724b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                retVal = context.getString(R.string.card_title_incoming_call);
725b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
726b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
7275eff1e7d582679b3a85f580eb1d550b2e6ca111cDavid Brown            case DISCONNECTING:
7285eff1e7d582679b3a85f580eb1d550b2e6ca111cDavid Brown                retVal = context.getString(R.string.card_title_hanging_up);
7295eff1e7d582679b3a85f580eb1d550b2e6ca111cDavid Brown                break;
7305eff1e7d582679b3a85f580eb1d550b2e6ca111cDavid Brown
731b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case DISCONNECTED:
732b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                retVal = getCallFailedString(call);
733b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
734b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
735b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
736b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("  ==> result: " + retVal);
737b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return retVal;
738b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
739b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
740b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
741b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Updates the "on hold" box in the "other call" info area
7420d315275d08cd33f801ae3a74e8fc265520f6246David Brown     * (ie. the stuff in the secondaryCallInfo block)
743b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * based on the specified Call.
744b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Or, clear out the "on hold" box if the specified call
745b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * is null or idle.
746b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
747b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void displayOnHoldCallStatus(Phone phone, Call call) {
748b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("displayOnHoldCallStatus(call =" + call + ")...");
749af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
750af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville        if ((call == null) || (PhoneApp.getInstance().isOtaCallInActiveState())) {
7510d315275d08cd33f801ae3a74e8fc265520f6246David Brown            mSecondaryCallInfo.setVisibility(View.GONE);
752b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return;
753b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
754b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
7558da4d90151c882972e15429d4d48bdaa45095d72David Brown        boolean showSecondaryCallInfo = false;
756b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Call.State state = call.getState();
757b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        switch (state) {
758b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case HOLDING:
759b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // Ok, there actually is a background call on hold.
760b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // Display the "on hold" box.
761b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
7620d315275d08cd33f801ae3a74e8fc265520f6246David Brown                // Note this case occurs only on GSM devices.  (On CDMA,
7630d315275d08cd33f801ae3a74e8fc265520f6246David Brown                // the "call on hold" is actually the 2nd connection of
7640d315275d08cd33f801ae3a74e8fc265520f6246David Brown                // that ACTIVE call; see the ACTIVE case below.)
7650d315275d08cd33f801ae3a74e8fc265520f6246David Brown
766b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (PhoneUtils.isConferenceCall(call)) {
767b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (DBG) log("==> conference call.");
7680d315275d08cd33f801ae3a74e8fc265520f6246David Brown                    mSecondaryCallName.setText(getContext().getString(R.string.confCall));
7690d315275d08cd33f801ae3a74e8fc265520f6246David Brown                    showImage(mSecondaryCallPhoto, R.drawable.picture_conference);
770b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                } else {
771b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // perform query and update the name temporarily
772b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // make sure we hand the textview we want updated to the
773b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // callback function.
774b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (DBG) log("==> NOT a conf call; call startGetCallerInfo...");
7750d315275d08cd33f801ae3a74e8fc265520f6246David Brown                    PhoneUtils.CallerInfoToken infoToken = PhoneUtils.startGetCallerInfo(
7760d315275d08cd33f801ae3a74e8fc265520f6246David Brown                            getContext(), call, this, mSecondaryCallName);
7770d315275d08cd33f801ae3a74e8fc265520f6246David Brown                    mSecondaryCallName.setText(
7780d315275d08cd33f801ae3a74e8fc265520f6246David Brown                            PhoneUtils.getCompactNameFromCallerInfo(infoToken.currentInfo,
7790d315275d08cd33f801ae3a74e8fc265520f6246David Brown                                                                    getContext()));
7800d315275d08cd33f801ae3a74e8fc265520f6246David Brown
7810d315275d08cd33f801ae3a74e8fc265520f6246David Brown                    // Also pull the photo out of the current CallerInfo.
7820d315275d08cd33f801ae3a74e8fc265520f6246David Brown                    // (Note we assume we already have a valid photo at
7830d315275d08cd33f801ae3a74e8fc265520f6246David Brown                    // this point, since *presumably* the caller-id query
7840d315275d08cd33f801ae3a74e8fc265520f6246David Brown                    // was already run at some point *before* this call
7850d315275d08cd33f801ae3a74e8fc265520f6246David Brown                    // got put on hold.  If there's no cached photo, just
7860d315275d08cd33f801ae3a74e8fc265520f6246David Brown                    // fall back to the default "unknown" image.)
7870d315275d08cd33f801ae3a74e8fc265520f6246David Brown                    if (infoToken.isFinal) {
7880d315275d08cd33f801ae3a74e8fc265520f6246David Brown                        showCachedImage(mSecondaryCallPhoto, infoToken.currentInfo);
7890d315275d08cd33f801ae3a74e8fc265520f6246David Brown                    } else {
7900d315275d08cd33f801ae3a74e8fc265520f6246David Brown                        showImage(mSecondaryCallPhoto, R.drawable.picture_unknown);
7910d315275d08cd33f801ae3a74e8fc265520f6246David Brown                    }
792b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
793b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
7948da4d90151c882972e15429d4d48bdaa45095d72David Brown                showSecondaryCallInfo = true;
795b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
796b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
797b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
7980fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville            case ACTIVE:
7990fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville                // CDMA: This is because in CDMA when the user originates the second call,
8000fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville                // although the Foreground call state is still ACTIVE in reality the network
8010fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville                // put the first call on hold.
80279b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink                if (mApplication.phone.getPhoneType() == Phone.PHONE_TYPE_CDMA) {
8030fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville                    List<Connection> connections = call.getConnections();
8040fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville                    if (connections.size() > 2) {
8050fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville                        // This means that current Mobile Originated call is the not the first 3-Way
8060fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville                        // call the user is making, which in turn tells the PhoneApp that we no
8070fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville                        // longer know which previous caller/party had dropped out before the user
8080fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville                        // made this call.
8090d315275d08cd33f801ae3a74e8fc265520f6246David Brown                        mSecondaryCallName.setText(
8100d315275d08cd33f801ae3a74e8fc265520f6246David Brown                                getContext().getString(R.string.card_title_in_call));
8110d315275d08cd33f801ae3a74e8fc265520f6246David Brown                        showImage(mSecondaryCallPhoto, R.drawable.picture_unknown);
8120fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville                    } else {
8130fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville                        // This means that the current Mobile Originated call IS the first 3-Way
8140fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville                        // and hence we display the first callers/party's info here.
8150fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville                        Connection conn = call.getEarliestConnection();
816de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman                        PhoneUtils.CallerInfoToken infoToken = PhoneUtils.startGetCallerInfo(
8170d315275d08cd33f801ae3a74e8fc265520f6246David Brown                                getContext(), conn, this, mSecondaryCallName);
8180fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville
819de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman                        // Get the compactName to be displayed, but then check that against
820de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman                        // the number presentation value for the call. If it's not an allowed
821de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman                        // presentation, then display the appropriate presentation string instead.
822de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman                        CallerInfo info = infoToken.currentInfo;
8230d315275d08cd33f801ae3a74e8fc265520f6246David Brown
8240d315275d08cd33f801ae3a74e8fc265520f6246David Brown                        String name = PhoneUtils.getCompactNameFromCallerInfo(info, getContext());
8250d315275d08cd33f801ae3a74e8fc265520f6246David Brown                        boolean forceGenericPhoto = false;
826de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman                        if (info != null && info.numberPresentation !=
827de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman                                Connection.PRESENTATION_ALLOWED) {
828de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman                            name = getPresentationString(info.numberPresentation);
8290d315275d08cd33f801ae3a74e8fc265520f6246David Brown                            forceGenericPhoto = true;
8300d315275d08cd33f801ae3a74e8fc265520f6246David Brown                        }
8310d315275d08cd33f801ae3a74e8fc265520f6246David Brown                        mSecondaryCallName.setText(name);
8320d315275d08cd33f801ae3a74e8fc265520f6246David Brown
8330d315275d08cd33f801ae3a74e8fc265520f6246David Brown                        // Also pull the photo out of the current CallerInfo.
8340d315275d08cd33f801ae3a74e8fc265520f6246David Brown                        // (Note we assume we already have a valid photo at
8350d315275d08cd33f801ae3a74e8fc265520f6246David Brown                        // this point, since *presumably* the caller-id query
8360d315275d08cd33f801ae3a74e8fc265520f6246David Brown                        // was already run at some point *before* this call
8370d315275d08cd33f801ae3a74e8fc265520f6246David Brown                        // got put on hold.  If there's no cached photo, just
8380d315275d08cd33f801ae3a74e8fc265520f6246David Brown                        // fall back to the default "unknown" image.)
8390d315275d08cd33f801ae3a74e8fc265520f6246David Brown                        if (!forceGenericPhoto && infoToken.isFinal) {
8400d315275d08cd33f801ae3a74e8fc265520f6246David Brown                            showCachedImage(mSecondaryCallPhoto, info);
8410d315275d08cd33f801ae3a74e8fc265520f6246David Brown                        } else {
8420d315275d08cd33f801ae3a74e8fc265520f6246David Brown                            showImage(mSecondaryCallPhoto, R.drawable.picture_unknown);
843de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman                        }
8440fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville                    }
8458da4d90151c882972e15429d4d48bdaa45095d72David Brown                    showSecondaryCallInfo = true;
8460fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville
8470d315275d08cd33f801ae3a74e8fc265520f6246David Brown                } else {
8480d315275d08cd33f801ae3a74e8fc265520f6246David Brown                    // We shouldn't ever get here at all for non-CDMA devices.
8490d315275d08cd33f801ae3a74e8fc265520f6246David Brown                    Log.w(LOG_TAG, "displayOnHoldCallStatus: ACTIVE state on non-CDMA device");
8508da4d90151c882972e15429d4d48bdaa45095d72David Brown                    showSecondaryCallInfo = false;
8510fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville                }
8520fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville                break;
8530fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville
854b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            default:
855b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // There's actually no call on hold.  (Presumably this call's
856b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // state is IDLE, since any other state is meaningless for the
857b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // background call.)
8588da4d90151c882972e15429d4d48bdaa45095d72David Brown                showSecondaryCallInfo = false;
859b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
860b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
8618da4d90151c882972e15429d4d48bdaa45095d72David Brown
8628da4d90151c882972e15429d4d48bdaa45095d72David Brown        if (showSecondaryCallInfo) {
8638da4d90151c882972e15429d4d48bdaa45095d72David Brown            // Ok, we have something useful to display in the "secondary
8648da4d90151c882972e15429d4d48bdaa45095d72David Brown            // call" info area.
8658da4d90151c882972e15429d4d48bdaa45095d72David Brown            mSecondaryCallInfo.setVisibility(View.VISIBLE);
8668da4d90151c882972e15429d4d48bdaa45095d72David Brown
8678da4d90151c882972e15429d4d48bdaa45095d72David Brown            // Watch out: there are some cases where we need to display the
8688da4d90151c882972e15429d4d48bdaa45095d72David Brown            // secondary call photo but *not* the two lines of text above it.
8698da4d90151c882972e15429d4d48bdaa45095d72David Brown            // Specifically, that's any state where the CallCard "upper title" is
8708da4d90151c882972e15429d4d48bdaa45095d72David Brown            // in use, since the title (e.g. "Dialing" or "Call ended") might
8718da4d90151c882972e15429d4d48bdaa45095d72David Brown            // collide with the secondaryCallStatus and secondaryCallName widgets.
8728da4d90151c882972e15429d4d48bdaa45095d72David Brown            //
8738da4d90151c882972e15429d4d48bdaa45095d72David Brown            // We detect this case by simply seeing whether or not there's any text
8748da4d90151c882972e15429d4d48bdaa45095d72David Brown            // in mUpperTitle.  (This is much simpler than detecting all possible
8758da4d90151c882972e15429d4d48bdaa45095d72David Brown            // telephony states where the "upper title" is used!  But note it does
8768da4d90151c882972e15429d4d48bdaa45095d72David Brown            // rely on the fact that updateCardTitleWidgets() gets called *earlier*
8778da4d90151c882972e15429d4d48bdaa45095d72David Brown            // than this method, in the CallCard.updateState() sequence...)
8788da4d90151c882972e15429d4d48bdaa45095d72David Brown            boolean okToShowLabels = TextUtils.isEmpty(mUpperTitle.getText());
8798da4d90151c882972e15429d4d48bdaa45095d72David Brown            mSecondaryCallName.setVisibility(okToShowLabels ? View.VISIBLE : View.INVISIBLE);
8808da4d90151c882972e15429d4d48bdaa45095d72David Brown            mSecondaryCallStatus.setVisibility(okToShowLabels ? View.VISIBLE : View.INVISIBLE);
8818da4d90151c882972e15429d4d48bdaa45095d72David Brown        } else {
8828da4d90151c882972e15429d4d48bdaa45095d72David Brown            // Hide the entire "secondary call" info area.
8838da4d90151c882972e15429d4d48bdaa45095d72David Brown            mSecondaryCallInfo.setVisibility(View.GONE);
8848da4d90151c882972e15429d4d48bdaa45095d72David Brown        }
885b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
886b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
887b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private String getCallFailedString(Call call) {
888b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Connection c = call.getEarliestConnection();
889b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        int resID;
890b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
891b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (c == null) {
892b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (DBG) log("getCallFailedString: connection is null, using default values.");
893b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // if this connection is null, just assume that the
894b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // default case occurs.
895b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            resID = R.string.card_title_call_ended;
896b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        } else {
897b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
898b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            Connection.DisconnectCause cause = c.getDisconnectCause();
899b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
900b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // TODO: The card *title* should probably be "Call ended" in all
901b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // cases, but if the DisconnectCause was an error condition we should
902b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // probably also display the specific failure reason somewhere...
903b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
904b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            switch (cause) {
905b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case BUSY:
906b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    resID = R.string.callFailed_userBusy;
907b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
908b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
909b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case CONGESTION:
910b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    resID = R.string.callFailed_congestion;
911b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
912b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
913b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case LOST_SIGNAL:
9143800ac871d6548790ac6119bb68b9be0640af261David Krause                case CDMA_DROP:
915b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    resID = R.string.callFailed_noSignal;
916b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
917b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
918b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case LIMIT_EXCEEDED:
919b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    resID = R.string.callFailed_limitExceeded;
920b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
921b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
922b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case POWER_OFF:
923b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    resID = R.string.callFailed_powerOff;
924b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
925b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
926a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville                case ICC_ERROR:
927b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    resID = R.string.callFailed_simError;
928b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
929b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
930b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case OUT_OF_SERVICE:
931b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    resID = R.string.callFailed_outOfService;
932b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
933b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
934b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                default:
935b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    resID = R.string.card_title_call_ended;
936b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
937b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
938b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
939b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return getContext().getString(resID);
940b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
941b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
942b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
943b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Updates the name / photo / number / label fields on the CallCard
944b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * based on the specified CallerInfo.
945b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
946b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * If the current call is a conference call, use
947b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * updateDisplayForConference() instead.
948b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
949b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void updateDisplayForPerson(CallerInfo info,
9504b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project                                        int presentation,
951b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                                        boolean isTemporary,
952b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                                        Call call) {
953b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("updateDisplayForPerson(" + info + ")...");
954b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
955b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // inform the state machine that we are displaying a photo.
956b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mPhotoTracker.setPhotoRequest(info);
957b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mPhotoTracker.setPhotoState(ContactsAsyncHelper.ImageTracker.DISPLAY_IMAGE);
958b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
959b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        String name;
960b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        String displayNumber = null;
961b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        String label = null;
962b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Uri personUri = null;
96329d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown        String socialStatusText = null;
96429d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown        Drawable socialStatusBadge = null;
965b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
966b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (info != null) {
967b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // It appears that there is a small change in behaviour with the
968b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // PhoneUtils' startGetCallerInfo whereby if we query with an
969b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // empty number, we will get a valid CallerInfo object, but with
970b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // fields that are all null, and the isTemporary boolean input
971b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // parameter as true.
972b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
973b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // In the past, we would see a NULL callerinfo object, but this
974b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // ends up causing null pointer exceptions elsewhere down the
975b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // line in other cases, so we need to make this fix instead. It
976b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // appears that this was the ONLY call to PhoneUtils
977b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // .getCallerInfo() that relied on a NULL CallerInfo to indicate
978b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // an unknown contact.
979b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
980b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (TextUtils.isEmpty(info.name)) {
981b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (TextUtils.isEmpty(info.phoneNumber)) {
9824b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project                    name =  getPresentationString(presentation);
983e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai                } else if (presentation != Connection.PRESENTATION_ALLOWED) {
984e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai                    // This case should never happen since the network should never send a phone #
985e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai                    // AND a restricted presentation. However we leave it here in case of weird
986e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai                    // network behavior
987e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai                    name = getPresentationString(presentation);
988e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai                } else if (!TextUtils.isEmpty(info.cnapName)) {
989e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai                    name = info.cnapName;
990e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai                    info.name = info.cnapName;
991e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai                    displayNumber = info.phoneNumber;
992b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                } else {
993b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    name = info.phoneNumber;
994b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
995b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            } else {
996e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai                if (presentation != Connection.PRESENTATION_ALLOWED) {
997e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai                    // This case should never happen since the network should never send a name
998e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai                    // AND a restricted presentation. However we leave it here in case of weird
999e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai                    // network behavior
1000e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai                    name = getPresentationString(presentation);
1001e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai                } else {
1002e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai                    name = info.name;
1003e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai                    displayNumber = info.phoneNumber;
1004e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai                    label = info.phoneLabel;
1005e2c9e16a099b6a120db0a589ad1959b8787b9f9bAbhishek Pillai                }
1006b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
10073d6d70562622660e581b53308e675386d299dd19Dmitri Plotnikov            personUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, info.person_id);
1008b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        } else {
10094b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project            name =  getPresentationString(presentation);
1010b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
10110fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville
10120fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville        if (call.isGeneric()) {
10130fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville            mName.setText(R.string.card_title_in_call);
10140fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville        } else {
10150fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville            mName.setText(name);
10160fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville        }
1017b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mName.setVisibility(View.VISIBLE);
1018b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1019b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Update mPhoto
1020b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // if the temporary flag is set, we know we'll be getting another call after
1021b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // the CallerInfo has been correctly updated.  So, we can skip the image
1022b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // loading until then.
1023b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1024b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // If the photoResource is filled in for the CallerInfo, (like with the
1025b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Emergency Number case), then we can just set the photo image without
1026b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // requesting for an image load. Please refer to CallerInfoAsyncQuery.java
1027b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // for cases where CallerInfo.photoResource may be set.  We can also avoid
1028b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // the image load step if the image data is cached.
1029b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (isTemporary && (info == null || !info.isCachedPhotoCurrent)) {
1030b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mPhoto.setVisibility(View.INVISIBLE);
1031b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        } else if (info != null && info.photoResource != 0){
1032b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            showImage(mPhoto, info.photoResource);
1033b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        } else if (!showCachedImage(mPhoto, info)) {
1034b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // Load the image with a callback to update the image state.
1035b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // Use a placeholder image value of -1 to indicate no image.
1036b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            ContactsAsyncHelper.updateImageViewWithContactPhotoAsync(info, 0, this, call,
1037b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    getContext(), mPhoto, personUri, -1);
1038b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
10390fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville        if (displayNumber != null && !call.isGeneric()) {
1040b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mPhoneNumber.setText(displayNumber);
1041b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mPhoneNumber.setVisibility(View.VISIBLE);
1042b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        } else {
1043b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mPhoneNumber.setVisibility(View.GONE);
1044b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
1045b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1046153e79d8d413b1ccd4abf55a8dbe4e266aa92799Paul Berman        if (label != null && !call.isGeneric()) {
1047b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mLabel.setText(label);
1048b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mLabel.setVisibility(View.VISIBLE);
1049b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        } else {
1050b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mLabel.setVisibility(View.GONE);
1051b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
1052b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
105329d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown        // "Social status": currently unused.
105429d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown        // Note socialStatus is *only* visible while an incoming
105529d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown        // call is ringing, never in any other call state.
105629d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown        if ((socialStatusText != null) && call.isRinging() && !call.isGeneric()) {
105729d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown            mSocialStatus.setVisibility(View.VISIBLE);
105829d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown            mSocialStatus.setText(socialStatusText);
105929d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown            mSocialStatus.setCompoundDrawablesWithIntrinsicBounds(
106029d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown                    socialStatusBadge, null, null, null);
106129d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown            mSocialStatus.setCompoundDrawablePadding((int) (mDensity * 6));
106229d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown        } else {
106329d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown            mSocialStatus.setVisibility(View.GONE);
106429d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown        }
106529d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown    }
1066b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
10674b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project    private String getPresentationString(int presentation) {
10684b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project        String name = getContext().getString(R.string.unknown);
10694b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project        if (presentation == Connection.PRESENTATION_RESTRICTED) {
10704b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project            name = getContext().getString(R.string.private_num);
10714b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project        } else if (presentation == Connection.PRESENTATION_PAYPHONE) {
10724b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project            name = getContext().getString(R.string.payphone);
10734b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project        }
10744b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project        return name;
10754b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project    }
10764b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project
1077b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
1078b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Updates the name / photo / number / label fields
1079b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * for the special "conference call" state.
1080b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
1081b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * If the current call has only a single connection, use
1082b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * updateDisplayForPerson() instead.
1083b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
1084b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void updateDisplayForConference() {
1085b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("updateDisplayForConference()...");
1086b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
108779b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink        int phoneType = mApplication.phone.getPhoneType();
108879b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink        if (phoneType == Phone.PHONE_TYPE_CDMA) {
10890fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville            // This state corresponds to both 3-Way merged call and
10900fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville            // Call Waiting accepted call.
109129d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown            // In this case we display the UI in a "generic" state, with
109229d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown            // the generic "dialing" icon and no caller information,
109329d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown            // because in this state in CDMA the user does not really know
109429d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown            // which caller party he is talking to.
10950fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville            showImage(mPhoto, R.drawable.picture_dialing);
10960fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville            mName.setText(R.string.card_title_in_call);
109779b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink        } else if (phoneType == Phone.PHONE_TYPE_GSM) {
10980fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville            // Display the "conference call" image in the photo slot,
10990fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville            // with no other information.
11000fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville            showImage(mPhoto, R.drawable.picture_conference);
11010fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville            mName.setText(R.string.card_title_conf_call);
110279b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink        } else {
110379b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink            throw new IllegalStateException("Unexpected phone type: " + phoneType);
11040fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville        }
1105b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1106b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mName.setVisibility(View.VISIBLE);
1107b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1108b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // TODO: For a conference call, the "phone number" slot is specced
1109b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // to contain a summary of who's on the call, like "Bill Foldes
1110b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // and Hazel Nutt" or "Bill Foldes and 2 others".
1111b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // But for now, just hide it:
1112b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mPhoneNumber.setVisibility(View.GONE);
1113b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mLabel.setVisibility(View.GONE);
1114b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
111529d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown        // socialStatus is never visible in this state.
111629d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown        mSocialStatus.setVisibility(View.GONE);
111729d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown
111829d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown        // TODO: for a GSM conference call, since we do actually know who
111929d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown        // you're talking to, consider also showing names / numbers /
112029d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown        // photos of some of the people on the conference here, so you can
112129d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown        // see that info without having to click "Manage conference".  We
112229d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown        // probably have enough space to show info for 2 people, at least.
1123b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        //
1124b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // To do this, our caller would pass us the activeConnections
1125b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // list, and we'd call PhoneUtils.getCallerInfo() separately for
1126b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // each connection.
1127b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
1128b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1129b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
1130b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Updates the CallCard "photo" IFF the specified Call is in a state
1131b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * that needs a special photo (like "busy" or "dialing".)
1132b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
1133b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * If the current call does not require a special image in the "photo"
1134b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * slot onscreen, don't do anything, since presumably the photo image
1135b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * has already been set (to the photo of the person we're talking, or
1136b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * the generic "picture_unknown" image, or the "conference call"
1137b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * image.)
1138b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
1139b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void updatePhotoForCallState(Call call) {
1140b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("updatePhotoForCallState(" + call + ")...");
1141b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        int photoImageResource = 0;
1142b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1143b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Check for the (relatively few) telephony states that need a
1144b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // special image in the "photo" slot.
1145b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Call.State state = call.getState();
1146b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        switch (state) {
1147b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case DISCONNECTED:
1148b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // Display the special "busy" photo for BUSY or CONGESTION.
1149b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // Otherwise (presumably the normal "call ended" state)
1150b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // leave the photo alone.
1151b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                Connection c = call.getEarliestConnection();
1152b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // if the connection is null, we assume the default case,
1153b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // otherwise update the image resource normally.
1154b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (c != null) {
1155b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    Connection.DisconnectCause cause = c.getDisconnectCause();
1156b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if ((cause == Connection.DisconnectCause.BUSY)
1157b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        || (cause == Connection.DisconnectCause.CONGESTION)) {
1158b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        photoImageResource = R.drawable.picture_busy;
1159b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    }
1160b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                } else if (DBG) {
1161b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    log("updatePhotoForCallState: connection is null, ignoring.");
1162b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
1163b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1164b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // TODO: add special images for any other DisconnectCauses?
1165b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
1166b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1167b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case DIALING:
1168b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case ALERTING:
1169b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                photoImageResource = R.drawable.picture_dialing;
1170b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
1171b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1172b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            default:
1173b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // Leave the photo alone in all other states.
1174b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // If this call is an individual call, and the image is currently
1175b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // displaying a state, (rather than a photo), we'll need to update
1176b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // the image.
1177b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // This is for the case where we've been displaying the state and
1178b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // now we need to restore the photo.  This can happen because we
1179b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // only query the CallerInfo once, and limit the number of times
1180b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // the image is loaded. (So a state image may overwrite the photo
1181b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // and we would otherwise have no way of displaying the photo when
1182b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // the state goes away.)
1183b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1184b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // if the photoResource field is filled-in in the Connection's
1185b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // caller info, then we can just use that instead of requesting
1186b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // for a photo load.
1187b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1188b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // look for the photoResource if it is available.
1189b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                CallerInfo ci = null;
1190b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                {
11910fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville                    Connection conn = null;
119279b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink                    int phoneType = mApplication.phone.getPhoneType();
119379b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink                    if (phoneType == Phone.PHONE_TYPE_CDMA) {
11940fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville                        conn = call.getLatestConnection();
119579b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink                    } else if (phoneType == Phone.PHONE_TYPE_GSM) {
11960fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville                        conn = call.getEarliestConnection();
119779b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink                    } else {
119879b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink                        throw new IllegalStateException("Unexpected phone type: " + phoneType);
11990fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville                    }
12000fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville
1201b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (conn != null) {
1202b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        Object o = conn.getUserData();
1203b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        if (o instanceof CallerInfo) {
1204b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                            ci = (CallerInfo) o;
1205b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        } else if (o instanceof PhoneUtils.CallerInfoToken) {
1206b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                            ci = ((PhoneUtils.CallerInfoToken) o).currentInfo;
1207b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        }
1208b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    }
1209b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
1210b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1211b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (ci != null) {
1212b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    photoImageResource = ci.photoResource;
1213b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
1214b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1215b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // If no photoResource found, check to see if this is a conference call. If
1216b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // it is not a conference call:
1217b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                //   1. Try to show the cached image
1218b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                //   2. If the image is not cached, check to see if a load request has been
1219b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                //      made already.
1220b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                //   3. If the load request has not been made [DISPLAY_DEFAULT], start the
1221b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                //      request and note that it has started by updating photo state with
1222b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                //      [DISPLAY_IMAGE].
1223b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // Load requests started in (3) use a placeholder image of -1 to hide the
1224b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // image by default.  Please refer to CallerInfoAsyncQuery.java for cases
1225b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // where CallerInfo.photoResource may be set.
1226b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (photoImageResource == 0) {
1227b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (!PhoneUtils.isConferenceCall(call)) {
1228b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        if (!showCachedImage(mPhoto, ci) && (mPhotoTracker.getPhotoState() ==
1229b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                                ContactsAsyncHelper.ImageTracker.DISPLAY_DEFAULT)) {
1230b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                            ContactsAsyncHelper.updateImageViewWithContactPhotoAsync(ci,
1231b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                                    getContext(), mPhoto, mPhotoTracker.getPhotoUri(), -1);
1232b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                            mPhotoTracker.setPhotoState(
1233b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                                    ContactsAsyncHelper.ImageTracker.DISPLAY_IMAGE);
1234b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        }
1235b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    }
1236b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                } else {
1237b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    showImage(mPhoto, photoImageResource);
1238b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    mPhotoTracker.setPhotoState(ContactsAsyncHelper.ImageTracker.DISPLAY_IMAGE);
1239b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    return;
1240b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
1241b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
1242b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
1243b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1244b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (photoImageResource != 0) {
1245b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (DBG) log("- overrriding photo image: " + photoImageResource);
1246b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            showImage(mPhoto, photoImageResource);
1247b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // Track the image state.
1248b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mPhotoTracker.setPhotoState(ContactsAsyncHelper.ImageTracker.DISPLAY_DEFAULT);
1249b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
1250b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
1251b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1252b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
1253b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Try to display the cached image from the callerinfo object.
1254b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
1255b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *  @return true if we were able to find the image in the cache, false otherwise.
1256b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
12570d315275d08cd33f801ae3a74e8fc265520f6246David Brown    private static final boolean showCachedImage(ImageView view, CallerInfo ci) {
1258b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if ((ci != null) && ci.isCachedPhotoCurrent) {
1259b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (ci.cachedPhoto != null) {
1260b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                showImage(view, ci.cachedPhoto);
1261b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            } else {
1262b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                showImage(view, R.drawable.picture_unknown);
1263b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
1264b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return true;
1265b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
1266b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return false;
1267b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
1268b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1269b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /** Helper function to display the resource in the imageview AND ensure its visibility.*/
1270b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private static final void showImage(ImageView view, int resource) {
1271b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        view.setImageResource(resource);
1272b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        view.setVisibility(View.VISIBLE);
1273b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
1274b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1275b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /** Helper function to display the drawable in the imageview AND ensure its visibility.*/
1276b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private static final void showImage(ImageView view, Drawable drawable) {
1277b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        view.setImageDrawable(drawable);
1278b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        view.setVisibility(View.VISIBLE);
1279b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
1280b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1281b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
1282b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Intercepts (and discards) any touch events to the CallCard.
1283b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
1284b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    @Override
1285b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public boolean dispatchTouchEvent(MotionEvent ev) {
1286b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // if (DBG) log("CALLCARD: dispatchTouchEvent(): ev = " + ev);
1287b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1288b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // We *never* let touch events get thru to the UI inside the
1289b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // CallCard, since there's nothing touchable there.
1290b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return true;
1291b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
1292b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1293b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
1294b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Returns the "Menu button hint" TextView (which is manipulated
1295b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * directly by the InCallScreen.)
1296b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * @see InCallScreen.updateMenuButtonHint()
1297b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
1298b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /* package */ TextView getMenuButtonHint() {
1299b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return mMenuButtonHint;
1300b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
1301b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1302b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
1303b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Sets the left and right margins of the specified ViewGroup (whose
1304b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * LayoutParams object which must inherit from
1305b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * ViewGroup.MarginLayoutParams.)
1306b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
1307b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * TODO: Is there already a convenience method like this somewhere?
1308b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
1309b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void setSideMargins(ViewGroup vg, int margin) {
1310b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        ViewGroup.MarginLayoutParams lp =
1311b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                (ViewGroup.MarginLayoutParams) vg.getLayoutParams();
1312b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Equivalent to setting android:layout_marginLeft/Right in XML
1313b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        lp.leftMargin = margin;
1314b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        lp.rightMargin = margin;
1315b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        vg.setLayoutParams(lp);
1316b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
1317b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
13188bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project    /**
13198bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     * Sets the CallCard "upper title".  Also, depending on the passed-in
13208bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     * Call state, possibly display an icon along with the title.
13218bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     */
132234a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown    private void setUpperTitle(String title, int color, Call.State state) {
13238bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project        mUpperTitle.setText(title);
132434a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown        mUpperTitle.setTextColor(color);
13258bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project
13268bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project        int bluetoothIconId = 0;
132734a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown        if (!TextUtils.isEmpty(title)
132834a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown                && ((state == Call.State.INCOMING) || (state == Call.State.WAITING))
13290fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville                && mApplication.showBluetoothIndication()) {
13308bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project            // Display the special bluetooth icon also, if this is an incoming
13318bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project            // call and the audio will be routed to bluetooth.
13328bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project            bluetoothIconId = R.drawable.ic_incoming_call_bluetooth;
13338bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project        }
13348bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project
13358bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project        mUpperTitle.setCompoundDrawablesWithIntrinsicBounds(bluetoothIconId, 0, 0, 0);
133629d71cebdbcfe433f851899b91a650ad9352c15fDavid Brown        if (bluetoothIconId != 0) mUpperTitle.setCompoundDrawablePadding((int) (mDensity * 5));
13378bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project    }
13388bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project
1339af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    /**
134034a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown     * Clears the CallCard "upper title", for states (like a normal
134134a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown     * ongoing call) where we don't use any "title" at all.
134234a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown     */
134334a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown    private void clearUpperTitle() {
134434a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown        setUpperTitle("", 0, Call.State.IDLE);  // Use dummy values for "color" and "state"
134534a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown    }
134634a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown
134734a38b7ed4a63f8e6264030735911fdeadb21e5cDavid Brown    /**
1348af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * Hides the top-level UI elements of the call card:  The "main
1349af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * call card" element representing the current active or ringing call,
1350af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * and also the info areas for "ongoing" or "on hold" calls in some
1351af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * states.
1352af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     *
1353af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * This is intended to be used in special states where the normal
1354af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * in-call UI is totally replaced by some other UI, like OTA mode on a
1355af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * CDMA device.
1356af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     *
1357af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * To bring back the regular CallCard UI, just re-run the normal
1358af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     * updateState() call sequence.
1359af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville     */
1360af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville
1361af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    public void hideCallCardElements() {
13620d315275d08cd33f801ae3a74e8fc265520f6246David Brown        mPrimaryCallInfo.setVisibility(View.GONE);
13630d315275d08cd33f801ae3a74e8fc265520f6246David Brown        mSecondaryCallInfo.setVisibility(View.GONE);
1364af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville    }
1365b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1366b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // Debugging / testing code
1367b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1368b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void log(String msg) {
1369796c70c99bc39295bf685061056f06ab8949c742David Brown        Log.d(LOG_TAG, msg);
1370b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
1371b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project}
1372