CallCard.java revision 8bb467d9a1106dedd79e42166c7b6e9fc9a897a7
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 com.android.internal.telephony.Call;
20b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport com.android.internal.telephony.CallerInfo;
21b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport com.android.internal.telephony.CallerInfoAsyncQuery;
22b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport com.android.internal.telephony.Connection;
23b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport com.android.internal.telephony.Phone;
24b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
25b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.content.ContentUris;
26b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.content.Context;
27b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.graphics.drawable.Drawable;
28b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.net.Uri;
29b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.pim.ContactsAsyncHelper;
30b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.provider.Contacts.People;
31b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.text.TextUtils;
32b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.text.format.DateUtils;
33b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.util.AttributeSet;
34b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.util.Log;
35b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.view.LayoutInflater;
36b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.view.MotionEvent;
37b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.view.View;
38b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.view.ViewGroup;
39b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.widget.FrameLayout;
40b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.widget.ImageView;
41b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.widget.TextView;
42b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
43b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project/**
44b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * "Call card" UI element: the in-call screen contains a tiled layout of call
45b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * cards, each representing the state of a current "call" (ie. an active call,
46b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * a call on hold, or an incoming call.)
47b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */
48b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectpublic class CallCard extends FrameLayout
49b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        implements CallTime.OnTickListener, CallerInfoAsyncQuery.OnQueryCompleteListener,
50b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                ContactsAsyncHelper.OnImageLoadCompleteListener{
51b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private static final String LOG_TAG = "PHONE/CallCard";
52b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private static final boolean DBG = false;
53b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private static final boolean PROFILE = true;
54b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
558bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project    /**
568bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     * Reference to the InCallScreen activity that owns us.  This may be
578bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     * null if we haven't been initialized yet *or* after the InCallScreen
588bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     * activity has been destroyed.
598bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     */
608bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project    private InCallScreen mInCallScreen;
618bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project
62b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // Top-level subviews of the CallCard
63b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private ViewGroup mMainCallCard;
64b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private ViewGroup mOtherCallOngoingInfoArea;
65b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private ViewGroup mOtherCallOnHoldInfoArea;
66b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
67b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // "Upper" and "lower" title widgets
68b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private TextView mUpperTitle;
69b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private ViewGroup mLowerTitleViewGroup;
70b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private TextView mLowerTitle;
71b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private ImageView mLowerTitleIcon;
72b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private TextView mElapsedTime;
73b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
74b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // Text colors, used with the lower title and "other call" info areas
75b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private int mTextColorConnected;
768bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project    private int mTextColorConnectedBluetooth;
77b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private int mTextColorEnded;
78b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private int mTextColorOnHold;
79b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
80b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private ImageView mPhoto;
81b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private TextView mName;
82b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private TextView mPhoneNumber;
83b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private TextView mLabel;
84b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
85b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // "Other call" info area
868bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project    private ImageView mOtherCallOngoingIcon;
87b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private TextView mOtherCallOngoingName;
88b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private TextView mOtherCallOngoingStatus;
89b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private TextView mOtherCallOnHoldName;
90b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private TextView mOtherCallOnHoldStatus;
91b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
92b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // Menu button hint
93b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private TextView mMenuButtonHint;
94b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
95b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private boolean mRingerSilenced;
96b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
97b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private CallTime mCallTime;
98b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
99b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // Track the state for the photo.
100b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private ContactsAsyncHelper.ImageTracker mPhotoTracker;
101b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
102b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // A few hardwired constants used in our screen layout.
103b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // TODO: These should all really come from resources, but that's
104b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // nontrivial; see the javadoc for the ConfigurationHelper class.
105b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // For now, let's at least keep them all here in one place
106b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // rather than sprinkled througout this file.
107b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    //
108b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    static final int MAIN_CALLCARD_MIN_HEIGHT_LANDSCAPE = 200;
109b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    static final int CALLCARD_SIDE_MARGIN_LANDSCAPE = 50;
110b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    static final float TITLE_TEXT_SIZE_LANDSCAPE = 22F;  // scaled pixels
111b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
112b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public CallCard(Context context, AttributeSet attrs) {
113b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        super(context, attrs);
114b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
115b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("CallCard constructor...");
116b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("- this = " + this);
117b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("- context " + context + ", attrs " + attrs);
118b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
119b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Inflate the contents of this CallCard, and add it (to ourself) as a child.
120b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        LayoutInflater inflater = LayoutInflater.from(context);
121b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        inflater.inflate(
122b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                R.layout.call_card,  // resource
123b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                this,                // root
124b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                true);
125b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
126b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mCallTime = new CallTime(this);
127b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
128b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // create a new object to track the state for the photo.
129b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mPhotoTracker = new ContactsAsyncHelper.ImageTracker();
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    void reset() {
137b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("reset()...");
138b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
139b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mRingerSilenced = false;
140b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
141b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // default to show ACTIVE call style, with empty title and status text
142b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        showCallConnected();
1438bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project        setUpperTitle("");
144b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
145b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
146b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public void onTickForCallTimeElapsed(long timeElapsed) {
147b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // While a call is in progress, update the elapsed time shown
148b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // onscreen.
149b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        updateElapsedTimeWidget(timeElapsed);
150b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
151b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
152b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /* package */
153b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    void stopTimer() {
154b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mCallTime.cancelTimer();
155b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
156b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
157b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    @Override
158b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    protected void onFinishInflate() {
159b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        super.onFinishInflate();
160b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
161b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("CallCard onFinishInflate(this = " + this + ")...");
162b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
163b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        LayoutInflater inflater = LayoutInflater.from(getContext());
164b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
165b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mMainCallCard = (ViewGroup) findViewById(R.id.mainCallCard);
166b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mOtherCallOngoingInfoArea = (ViewGroup) findViewById(R.id.otherCallOngoingInfoArea);
167b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mOtherCallOnHoldInfoArea = (ViewGroup) findViewById(R.id.otherCallOnHoldInfoArea);
168b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
169b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // "Upper" and "lower" title widgets
170b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mUpperTitle = (TextView) findViewById(R.id.upperTitle);
171b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mLowerTitleViewGroup = (ViewGroup) findViewById(R.id.lowerTitleViewGroup);
172b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mLowerTitle = (TextView) findViewById(R.id.lowerTitle);
173b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mLowerTitleIcon = (ImageView) findViewById(R.id.lowerTitleIcon);
174b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mElapsedTime = (TextView) findViewById(R.id.elapsedTime);
175b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
176b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Text colors
177b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mTextColorConnected = getResources().getColor(R.color.incall_textConnected);
1788bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project        mTextColorConnectedBluetooth =
1798bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                getResources().getColor(R.color.incall_textConnectedBluetooth);
180b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mTextColorEnded = getResources().getColor(R.color.incall_textEnded);
181b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mTextColorOnHold = getResources().getColor(R.color.incall_textOnHold);
182b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
183b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // "Caller info" area, including photo / name / phone numbers / etc
184b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mPhoto = (ImageView) findViewById(R.id.photo);
185b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mName = (TextView) findViewById(R.id.name);
186b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mPhoneNumber = (TextView) findViewById(R.id.phoneNumber);
187b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mLabel = (TextView) findViewById(R.id.label);
188b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
189b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // "Other call" info area
1908bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project        mOtherCallOngoingIcon = (ImageView) findViewById(R.id.otherCallOngoingIcon);
191b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mOtherCallOngoingName = (TextView) findViewById(R.id.otherCallOngoingName);
192b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mOtherCallOngoingStatus = (TextView) findViewById(R.id.otherCallOngoingStatus);
193b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mOtherCallOnHoldName = (TextView) findViewById(R.id.otherCallOnHoldName);
194b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mOtherCallOnHoldStatus = (TextView) findViewById(R.id.otherCallOnHoldStatus);
195b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
196b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Menu Button hint
197b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mMenuButtonHint = (TextView) findViewById(R.id.menuButtonHint);
198b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
199b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
200b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    void updateState(Phone phone) {
201b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("updateState(" + phone + ")...");
202b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
203b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Update some internal state based on the current state of the phone.
204b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // TODO: This code, and updateForegroundCall() / updateRingingCall(),
205b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // can probably still be simplified some more.
206b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
207b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Phone.State state = phone.getState();  // IDLE, RINGING, or OFFHOOK
208b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (state == Phone.State.RINGING) {
209b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // A phone call is ringing *or* call waiting
210b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // (ie. another call may also be active as well.)
211b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            updateRingingCall(phone);
212b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        } else if (state == Phone.State.OFFHOOK) {
213b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // The phone is off hook. At least one call exists that is
214b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // dialing, active, or holding, and no calls are ringing or waiting.
215b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            updateForegroundCall(phone);
216b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        } else {
217b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // The phone state is IDLE!
218b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            //
219b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // The most common reason for this is if a call just
220b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // ended: the phone will be idle, but we *will* still
221b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // have a call in the DISCONNECTED state:
222b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            Call fgCall = phone.getForegroundCall();
223b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            Call bgCall = phone.getBackgroundCall();
224b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if ((fgCall.getState() == Call.State.DISCONNECTED)
225b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                || (bgCall.getState() == Call.State.DISCONNECTED)) {
226b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // In this case, we want the main CallCard to display
227b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // the "Call ended" state.  The normal "foreground call"
228b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // code path handles that.
229b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                updateForegroundCall(phone);
230b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            } else {
231b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // We don't have any DISCONNECTED calls, which means
232b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // that the phone is *truly* idle.
233b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                //
234b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // It's very rare to be on the InCallScreen at all in this
235b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // state, but it can happen in some cases:
236b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // - A stray onPhoneStateChanged() event came in to the
237b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                //   InCallScreen *after* it was dismissed.
238b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // - We're allowed to be on the InCallScreen because
239b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                //   an MMI or USSD is running, but there's no actual "call"
240b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                //   to display.
241b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // - We're displaying an error dialog to the user
242b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                //   (explaining why the call failed), so we need to stay on
243b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                //   the InCallScreen so that the dialog will be visible.
244b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                //
245b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // In these cases, put the callcard into a sane but "blank" state:
246b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                updateNoCall(phone);
247b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
248b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
249b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
250b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
251b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
252b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Updates the UI for the state where the phone is in use, but not ringing.
253b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
254b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void updateForegroundCall(Phone phone) {
255b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("updateForegroundCall()...");
256b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
257b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Call fgCall = phone.getForegroundCall();
258b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Call bgCall = phone.getBackgroundCall();
259b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
260b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (fgCall.isIdle() && !fgCall.hasConnections()) {
261b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (DBG) log("updateForegroundCall: no active call, show holding call");
262b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // TODO: make sure this case agrees with the latest UI spec.
263b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
264b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // Display the background call in the main info area of the
265b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // CallCard, since there is no foreground call.  Note that
266b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // displayMainCallStatus() will notice if the call we passed in is on
267b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // hold, and display the "on hold" indication.
268b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            fgCall = bgCall;
269b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
270b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // And be sure to not display anything in the "on hold" box.
271b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            bgCall = null;
272b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
273b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
274b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        displayMainCallStatus(phone, fgCall);
275b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        displayOnHoldCallStatus(phone, bgCall);
276b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        displayOngoingCallStatus(phone, null);
277b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
278b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
279b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
280b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Updates the UI for the state where an incoming call is ringing (or
281b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * call waiting), regardless of whether the phone's already offhook.
282b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
283b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void updateRingingCall(Phone phone) {
284b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("updateRingingCall()...");
285b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
286b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Call ringingCall = phone.getRingingCall();
287b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Call fgCall = phone.getForegroundCall();
288b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Call bgCall = phone.getBackgroundCall();
289b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
290b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        displayMainCallStatus(phone, ringingCall);
291b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        displayOnHoldCallStatus(phone, bgCall);
292b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        displayOngoingCallStatus(phone, fgCall);
293b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
294b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
295b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
296b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Updates the UI for the state where the phone is not in use.
297b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
298b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * This is analogous to updateForegroundCall() and updateRingingCall(),
299b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
300b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * but for the (uncommon) case where the phone is
301b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * totally idle.  (See comments in updateState() above.)
302b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
303b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * This puts the callcard into a sane but "blank" state.
304b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
305b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void updateNoCall(Phone phone) {
306b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("updateNoCall()...");
307b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
308b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        displayMainCallStatus(phone, null);
309b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        displayOnHoldCallStatus(phone, null);
310b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        displayOngoingCallStatus(phone, null);
311b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
312b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
313b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
314b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Updates the main block of caller info on the CallCard
315b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * (ie. the stuff in the mainCallCard block) based on the specified Call.
316b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
317b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void displayMainCallStatus(Phone phone, Call call) {
318b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("displayMainCallStatus(phone " + phone
319b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                     + ", call " + call + ")...");
320b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
321b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (call == null) {
322b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // There's no call to display, presumably because the phone is idle.
323b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mMainCallCard.setVisibility(View.GONE);
324b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return;
325b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
326b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mMainCallCard.setVisibility(View.VISIBLE);
327b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
328b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Call.State state = call.getState();
329b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("  - call.state: " + call.getState());
330b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
331b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        int callCardBackgroundResid = 0;
332b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
3338bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project        // Background frame resources are different between portrait/landscape.
3348bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project        // TODO: Don't do this manually.  Instead let the resource system do
3358bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project        // it: just move the *_land assets over to the res/drawable-land
3368bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project        // directory (but with the same filename as the corresponding
3378bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project        // portrait asset.)
338b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        boolean landscapeMode = InCallScreen.ConfigurationHelper.isLandscape();
339b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
3408bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project        // Background images are also different if Bluetooth is active.
3418bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project        final boolean bluetoothActive = PhoneApp.getInstance().showBluetoothIndication();
3428bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project
343b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        switch (state) {
344b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case ACTIVE:
345b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                showCallConnected();
346b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
3478bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                if (bluetoothActive) {
3488bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                    callCardBackgroundResid =
3498bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                            landscapeMode ? R.drawable.incall_frame_bluetooth_tall_land
3508bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                            : R.drawable.incall_frame_bluetooth_tall_port;
3518bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                } else {
3528bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                    callCardBackgroundResid =
3538bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                            landscapeMode ? R.drawable.incall_frame_connected_tall_land
3548bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                            : R.drawable.incall_frame_connected_tall_port;
3558bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                }
3568bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project
357b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
358b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // update timer field
359b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (DBG) log("displayMainCallStatus: start periodicUpdateTimer");
360b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mCallTime.setActiveCallMode(call);
361b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mCallTime.reset();
362b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mCallTime.periodicUpdateTimer();
363b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
364b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
365b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
366b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case HOLDING:
367b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                showCallOnhold();
368b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
369b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                callCardBackgroundResid =
370b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        landscapeMode ? R.drawable.incall_frame_hold_tall_land
371b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        : R.drawable.incall_frame_hold_tall_port;
372b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
373b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // update timer field
374b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mCallTime.cancelTimer();
375b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
376b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
377b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
378b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case DISCONNECTED:
379b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                reset();
380b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                showCallEnded();
381b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
382b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                callCardBackgroundResid =
383b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        landscapeMode ? R.drawable.incall_frame_ended_tall_land
384b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        : R.drawable.incall_frame_ended_tall_port;
385b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
386b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // Stop getting timer ticks from this call
387b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mCallTime.cancelTimer();
388b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
389b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
390b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
391b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case DIALING:
392b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case ALERTING:
393b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                showCallConnecting();
394b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
3958bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                if (bluetoothActive) {
3968bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                    callCardBackgroundResid =
3978bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                            landscapeMode ? R.drawable.incall_frame_bluetooth_tall_land
3988bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                            : R.drawable.incall_frame_bluetooth_tall_port;
3998bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                } else {
4008bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                    callCardBackgroundResid =
4018bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                            landscapeMode ? R.drawable.incall_frame_normal_tall_land
4028bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                            : R.drawable.incall_frame_normal_tall_port;
4038bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                }
404b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
405b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // Stop getting timer ticks from a previous call
406b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mCallTime.cancelTimer();
407b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
408b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
409b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
410b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case INCOMING:
411b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case WAITING:
412b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                showCallIncoming();
413b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
4148bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                if (bluetoothActive) {
4158bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                    callCardBackgroundResid =
4168bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                            landscapeMode ? R.drawable.incall_frame_bluetooth_tall_land
4178bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                            : R.drawable.incall_frame_bluetooth_tall_port;
4188bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                } else {
4198bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                    callCardBackgroundResid =
4208bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                            landscapeMode ? R.drawable.incall_frame_normal_tall_land
4218bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                            : R.drawable.incall_frame_normal_tall_port;
4228bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                }
423b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
424b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // Stop getting timer ticks from a previous call
425b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mCallTime.cancelTimer();
426b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
427b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
428b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
429b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case IDLE:
430b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // The "main CallCard" should never be trying to display
431b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // an idle call!  In updateState(), if the phone is idle,
432b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // we call updateNoCall(), which means that we shouldn't
433b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // have passed a call into this method at all.
434b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                Log.w(LOG_TAG, "displayMainCallStatus: IDLE call in the main call card!");
435b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
436b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // (It is possible, though, that we had a valid call which
437b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // became idle *after* the check in updateState() but
438b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // before we get here...  So continue the best we can,
439b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // with whatever (stale) info we can get from the
440b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // passed-in Call object.)
441b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
442b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
443b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
444b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            default:
445b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                Log.w(LOG_TAG, "displayMainCallStatus: unexpected call state: " + state);
446b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
447b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
448b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
449b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        updateCardTitleWidgets(phone, call);
450b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
451b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (PhoneUtils.isConferenceCall(call)) {
452b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // Update onscreen info for a conference call.
453b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            updateDisplayForConference();
454b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        } else {
455b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // Update onscreen info for a regular call (which presumably
456b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // has only one connection.)
457b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            Connection conn = call.getEarliestConnection();
458b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
459b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            boolean isPrivateNumber = false; // TODO: need isPrivate() API
460b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
461b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (conn == null) {
462b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (DBG) log("displayMainCallStatus: connection is null, using default values.");
463b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // if the connection is null, we run through the behaviour
464b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // we had in the past, which breaks down into trivial steps
465b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // with the current implementation of getCallerInfo and
466b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // updateDisplayForPerson.
467b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                CallerInfo info = PhoneUtils.getCallerInfo(getContext(), conn);
468b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                updateDisplayForPerson(info, isPrivateNumber, false, call);
469b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            } else {
470b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (DBG) log("  - CONN: " + conn + ", state = " + conn.getState());
471b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
472b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // make sure that we only make a new query when the current
473b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // callerinfo differs from what we've been requested to display.
474b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                boolean runQuery = true;
475b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                Object o = conn.getUserData();
476b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (o instanceof PhoneUtils.CallerInfoToken) {
477b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    runQuery = mPhotoTracker.isDifferentImageRequest(
478b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                            ((PhoneUtils.CallerInfoToken) o).currentInfo);
479b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                } else {
480b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    runQuery = mPhotoTracker.isDifferentImageRequest(conn);
481b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
482b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
483b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (runQuery) {
484b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (DBG) log("- displayMainCallStatus: starting CallerInfo query...");
485b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    PhoneUtils.CallerInfoToken info =
486b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                            PhoneUtils.startGetCallerInfo(getContext(), conn, this, call);
487b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    updateDisplayForPerson(info.currentInfo, isPrivateNumber, !info.isFinal, call);
488b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                } else {
489b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // No need to fire off a new query.  We do still need
490b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // to update the display, though (since we might have
491b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // previously been in the "conference call" state.)
492b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (DBG) log("- displayMainCallStatus: using data we already have...");
493b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (o instanceof CallerInfo) {
494b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        CallerInfo ci = (CallerInfo) o;
495b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        if (DBG) log("   ==> Got CallerInfo; updating display: ci = " + ci);
496b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        updateDisplayForPerson(ci, false, false, call);
497b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    } else if (o instanceof PhoneUtils.CallerInfoToken){
498b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        CallerInfo ci = ((PhoneUtils.CallerInfoToken) o).currentInfo;
499b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        if (DBG) log("   ==> Got CallerInfoToken; updating display: ci = " + ci);
500b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        updateDisplayForPerson(ci, false, true, call);
501b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    } else {
502b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        Log.w(LOG_TAG, "displayMainCallStatus: runQuery was false, "
503b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                              + "but we didn't have a cached CallerInfo object!  o = " + o);
504b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        // TODO: any easy way to recover here (given that
505b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        // the CallCard is probably displaying stale info
506b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        // right now?)  Maybe force the CallCard into the
507b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        // "Unknown" state?
508b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    }
509b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
510b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
511b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
512b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
513b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // In some states we override the "photo" ImageView to be an
514b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // indication of the current state, rather than displaying the
515b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // regular photo as set above.
516b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        updatePhotoForCallState(call);
517b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
518b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Set the background frame color based on the state of the call.
519b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        setMainCallCardBackgroundResource(callCardBackgroundResid);
520b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // (Text colors are set in updateCardTitleWidgets().)
521b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
522b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
523b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
524b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Implemented for CallerInfoAsyncQuery.OnQueryCompleteListener interface.
525b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * refreshes the CallCard data when it called.
526b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
527b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public void onQueryComplete(int token, Object cookie, CallerInfo ci) {
528b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("onQueryComplete: token " + token + ", cookie " + cookie + ", ci " + ci);
529b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
530b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (cookie instanceof Call) {
531b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // grab the call object and update the display for an individual call,
532b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // as well as the successive call to update image via call state.
533b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // If the object is a textview instead, we update it as we need to.
534b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (DBG) log("callerinfo query complete, updating ui from displayMainCallStatus()");
535b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            Call call = (Call) cookie;
536b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            updateDisplayForPerson(ci, false, false, call);
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    /**
557b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Updates the "upper" and "lower" titles based on the current state of this call.
558b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
559b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void updateCardTitleWidgets(Phone phone, Call call) {
560b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("updateCardTitleWidgets(call " + call + ")...");
561b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Call.State state = call.getState();
562b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
563b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // TODO: Still need clearer spec on exactly how title *and* status get
564b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // set in all states.  (Then, given that info, refactor the code
565b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // here to be more clear about exactly which widgets on the card
566b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // need to be set.)
567b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
568b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Normal "foreground" call card:
569b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        String cardTitle = getTitleForCallCard(call);
570b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
571b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("updateCardTitleWidgets: " + cardTitle);
572b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
573b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // We display *either* the "upper title" or the "lower title", but
574b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // never both.
575b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (state == Call.State.ACTIVE) {
576b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // Use the "lower title" (in green).
577b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mLowerTitleViewGroup.setVisibility(View.VISIBLE);
5788bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project
5798bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project            final boolean bluetoothActive = PhoneApp.getInstance().showBluetoothIndication();
5808bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project            int ongoingCallIcon = bluetoothActive ? R.drawable.ic_incall_ongoing_bluetooth
5818bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                    : R.drawable.ic_incall_ongoing;
5828bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project            mLowerTitleIcon.setImageResource(ongoingCallIcon);
5838bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project
584b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mLowerTitle.setText(cardTitle);
5858bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project
5868bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project            int textColor = bluetoothActive ? mTextColorConnectedBluetooth : mTextColorConnected;
5878bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project            mLowerTitle.setTextColor(textColor);
5888bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project            mElapsedTime.setTextColor(textColor);
5898bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project            setUpperTitle("");
590b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        } else if (state == Call.State.DISCONNECTED) {
591b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // Use the "lower title" (in red).
592b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // TODO: We may not *always* want to use the lower title for
593b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // the DISCONNECTED state.  "Error" states like BUSY or
594b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // CONGESTION (see getCallFailedString()) should probably go
595b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // in the upper title, for example.  In fact, the lower title
596b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // should probably be used *only* for the normal "Call ended"
597b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // case.
598b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mLowerTitleViewGroup.setVisibility(View.VISIBLE);
599b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mLowerTitleIcon.setImageResource(R.drawable.ic_incall_end);
600b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mLowerTitle.setText(cardTitle);
601b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mLowerTitle.setTextColor(mTextColorEnded);
602b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mElapsedTime.setTextColor(mTextColorEnded);
6038bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project            setUpperTitle("");
604b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        } else {
6058bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project            // All other states (DIALING, INCOMING, etc.) use the "upper title":
6068bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project            setUpperTitle(cardTitle, state);
607b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mLowerTitleViewGroup.setVisibility(View.INVISIBLE);
608b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
609b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
610b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Draw the onscreen "elapsed time" indication EXCEPT if we're in
611b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // the "Call ended" state.  (In that case, don't touch the
612b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // mElapsedTime widget, so we continue to see the elapsed time of
613b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // the call that just ended.)
614b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (call.getState() == Call.State.DISCONNECTED) {
615b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // "Call ended" state -- don't touch the onscreen elapsed time.
616b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        } else {
617b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            long duration = CallTime.getCallDuration(call);  // msec
618b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            updateElapsedTimeWidget(duration / 1000);
619b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // Also see onTickForCallTimeElapsed(), which updates this
620b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // widget once per second while the call is active.
621b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
622b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
623b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
624b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
625b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Updates mElapsedTime based on the specified number of seconds.
626b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * A timeElapsed value of zero means to not show an elapsed time at all.
627b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
628b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void updateElapsedTimeWidget(long timeElapsed) {
629b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // if (DBG) log("updateElapsedTimeWidget: " + timeElapsed);
630b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (timeElapsed == 0) {
631b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mElapsedTime.setText("");
632b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        } else {
633b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mElapsedTime.setText(DateUtils.formatElapsedTime(timeElapsed));
634b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
635b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
636b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
637b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
638b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Returns the "card title" displayed at the top of a foreground
639b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * ("active") CallCard to indicate the current state of this call, like
640b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * "Dialing" or "In call" or "On hold".  A null return value means that
641b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * there's no title string for this state.
642b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
643b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private String getTitleForCallCard(Call call) {
644b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        String retVal = null;
645b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Call.State state = call.getState();
646b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Context context = getContext();
647b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        int resId;
648b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
649b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("- getTitleForCallCard(Call " + call + ")...");
650b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
651b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        switch (state) {
652b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case IDLE:
653b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
654b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
655b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case ACTIVE:
656b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // Title is "Call in progress".  (Note this appears in the
657b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // "lower title" area of the CallCard.)
658b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                retVal = context.getString(R.string.card_title_in_progress);
659b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
660b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
661b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case HOLDING:
662b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                retVal = context.getString(R.string.card_title_on_hold);
663b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // TODO: if this is a conference call on hold,
664b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // maybe have a special title here too?
665b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
666b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
667b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case DIALING:
668b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case ALERTING:
669b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                retVal = context.getString(R.string.card_title_dialing);
670b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
671b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
672b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case INCOMING:
673b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case WAITING:
674b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                retVal = context.getString(R.string.card_title_incoming_call);
675b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
676b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
677b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case DISCONNECTED:
678b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                retVal = getCallFailedString(call);
679b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
680b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
681b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
682b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("  ==> result: " + retVal);
683b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return retVal;
684b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
685b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
686b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
687b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Updates the "on hold" box in the "other call" info area
688b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * (ie. the stuff in the otherCallOnHoldInfo block)
689b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * based on the specified Call.
690b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Or, clear out the "on hold" box if the specified call
691b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * is null or idle.
692b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
693b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void displayOnHoldCallStatus(Phone phone, Call call) {
694b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("displayOnHoldCallStatus(call =" + call + ")...");
695b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (call == null) {
696b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mOtherCallOnHoldInfoArea.setVisibility(View.GONE);
697b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return;
698b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
699b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
700b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Call.State state = call.getState();
701b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        switch (state) {
702b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case HOLDING:
703b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // Ok, there actually is a background call on hold.
704b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // Display the "on hold" box.
705b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                String name;
706b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
707b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // First, see if we need to query.
708b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (PhoneUtils.isConferenceCall(call)) {
709b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (DBG) log("==> conference call.");
710b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    name = getContext().getString(R.string.confCall);
711b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                } else {
712b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // perform query and update the name temporarily
713b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // make sure we hand the textview we want updated to the
714b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // callback function.
715b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (DBG) log("==> NOT a conf call; call startGetCallerInfo...");
716b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    PhoneUtils.CallerInfoToken info = PhoneUtils.startGetCallerInfo(
717b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                            getContext(), call, this, mOtherCallOnHoldName);
718b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    name = PhoneUtils.getCompactNameFromCallerInfo(info.currentInfo, getContext());
719b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
720b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
721b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mOtherCallOnHoldName.setText(name);
722b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
723b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // The call here is always "on hold", so use the orange "hold" frame
724b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // and orange text color:
725b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                setOnHoldInfoAreaBackgroundResource(R.drawable.incall_frame_hold_short);
726b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mOtherCallOnHoldName.setTextColor(mTextColorOnHold);
727b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mOtherCallOnHoldStatus.setTextColor(mTextColorOnHold);
728b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
729b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mOtherCallOnHoldInfoArea.setVisibility(View.VISIBLE);
730b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
731b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
732b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
733b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            default:
734b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // There's actually no call on hold.  (Presumably this call's
735b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // state is IDLE, since any other state is meaningless for the
736b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // background call.)
737b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mOtherCallOnHoldInfoArea.setVisibility(View.GONE);
738b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
739b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
740b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
741b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
742b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
743b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Updates the "Ongoing call" box in the "other call" info area
744b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * (ie. the stuff in the otherCallOngoingInfo block)
745b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * based on the specified Call.
746b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Or, clear out the "ongoing call" box if the specified call
747b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * is null or idle.
748b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
749b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void displayOngoingCallStatus(Phone phone, Call call) {
750b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("displayOngoingCallStatus(call =" + call + ")...");
751b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (call == null) {
752b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mOtherCallOngoingInfoArea.setVisibility(View.GONE);
753b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return;
754b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
755b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
756b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Call.State state = call.getState();
757b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        switch (state) {
758b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case ACTIVE:
759b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case DIALING:
760b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case ALERTING:
761b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // Ok, there actually is an ongoing call.
762b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // Display the "ongoing call" box.
763b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                String name;
764b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
765b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // First, see if we need to query.
766b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (PhoneUtils.isConferenceCall(call)) {
767b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    name = getContext().getString(R.string.confCall);
768b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                } else {
769b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // perform query and update the name temporarily
770b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // make sure we hand the textview we want updated to the
771b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // callback function.
772b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    PhoneUtils.CallerInfoToken info = PhoneUtils.startGetCallerInfo(
773b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                            getContext(), call, this, mOtherCallOngoingName);
774b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    name = PhoneUtils.getCompactNameFromCallerInfo(info.currentInfo, getContext());
775b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
776b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
777b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mOtherCallOngoingName.setText(name);
778b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
7798bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                // This is an "ongoing" call: we normally use the green
7808bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                // background frame and text color, but we use blue
7818bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                // instead if bluetooth is in use.
7828bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                boolean bluetoothActive = PhoneApp.getInstance().showBluetoothIndication();
7838bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project
7848bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                int ongoingCallBackground =
7858bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                        bluetoothActive ? R.drawable.incall_frame_bluetooth_short
7868bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                        : R.drawable.incall_frame_connected_short;
7878bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                setOngoingInfoAreaBackgroundResource(ongoingCallBackground);
7888bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project
7898bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                int ongoingCallIcon = bluetoothActive ? R.drawable.ic_incall_ongoing_bluetooth
7908bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                        : R.drawable.ic_incall_ongoing;
7918bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                mOtherCallOngoingIcon.setImageResource(ongoingCallIcon);
7928bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project
7938bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                int textColor = bluetoothActive ? mTextColorConnectedBluetooth
7948bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                        : mTextColorConnected;
7958bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                mOtherCallOngoingName.setTextColor(textColor);
7968bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                mOtherCallOngoingStatus.setTextColor(textColor);
797b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
798b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mOtherCallOngoingInfoArea.setVisibility(View.VISIBLE);
799b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
800b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
801b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
802b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            default:
803b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // There's actually no ongoing call.  (Presumably this call's
804b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // state is IDLE, since any other state is meaningless for the
805b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // foreground call.)
806b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mOtherCallOngoingInfoArea.setVisibility(View.GONE);
807b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
808b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
809b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
810b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
811b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
812b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private String getCallFailedString(Call call) {
813b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Phone phone = PhoneApp.getInstance().phone;
814b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Connection c = call.getEarliestConnection();
815b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        int resID;
816b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
817b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (c == null) {
818b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (DBG) log("getCallFailedString: connection is null, using default values.");
819b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // if this connection is null, just assume that the
820b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // default case occurs.
821b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            resID = R.string.card_title_call_ended;
822b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        } else {
823b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
824b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            Connection.DisconnectCause cause = c.getDisconnectCause();
825b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
826b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // TODO: The card *title* should probably be "Call ended" in all
827b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // cases, but if the DisconnectCause was an error condition we should
828b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // probably also display the specific failure reason somewhere...
829b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
830b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            switch (cause) {
831b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case BUSY:
832b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    resID = R.string.callFailed_userBusy;
833b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
834b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
835b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case CONGESTION:
836b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    resID = R.string.callFailed_congestion;
837b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
838b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
839b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case LOST_SIGNAL:
840b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    resID = R.string.callFailed_noSignal;
841b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
842b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
843b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case LIMIT_EXCEEDED:
844b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    resID = R.string.callFailed_limitExceeded;
845b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
846b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
847b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case POWER_OFF:
848b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    resID = R.string.callFailed_powerOff;
849b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
850b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
851b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case SIM_ERROR:
852b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    resID = R.string.callFailed_simError;
853b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
854b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
855b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case OUT_OF_SERVICE:
856b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    resID = R.string.callFailed_outOfService;
857b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
858b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
859b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                default:
860b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    resID = R.string.card_title_call_ended;
861b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
862b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
863b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
864b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return getContext().getString(resID);
865b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
866b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
867b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void showCallConnecting() {
868b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("showCallConnecting()...");
869b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // TODO: remove if truly unused
870b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
871b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
872b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void showCallIncoming() {
873b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("showCallIncoming()...");
874b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // TODO: remove if truly unused
875b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
876b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
877b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void showCallConnected() {
878b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("showCallConnected()...");
879b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // TODO: remove if truly unused
880b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
881b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
882b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void showCallEnded() {
883b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("showCallEnded()...");
884b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // TODO: remove if truly unused
885b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
886b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void showCallOnhold() {
887b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("showCallOnhold()...");
888b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // TODO: remove if truly unused
889b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
890b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
891b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
892b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *  Add the Call object to these next 2 apis since the callbacks from
893b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *  updateImageViewWithContactPhotoAsync call will need to use it.
894b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
895b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
896b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void updateDisplayForPerson(CallerInfo info, boolean isPrivateNumber, Call call) {
897b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        updateDisplayForPerson(info, isPrivateNumber, false, call);
898b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
899b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
900b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
901b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Updates the name / photo / number / label fields on the CallCard
902b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * based on the specified CallerInfo.
903b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
904b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * If the current call is a conference call, use
905b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * updateDisplayForConference() instead.
906b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
907b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void updateDisplayForPerson(CallerInfo info,
908b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                                        boolean isPrivateNumber,
909b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                                        boolean isTemporary,
910b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                                        Call call) {
911b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("updateDisplayForPerson(" + info + ")...");
912b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
913b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // inform the state machine that we are displaying a photo.
914b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mPhotoTracker.setPhotoRequest(info);
915b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mPhotoTracker.setPhotoState(ContactsAsyncHelper.ImageTracker.DISPLAY_IMAGE);
916b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
917b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        String name;
918b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        String displayNumber = null;
919b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        String label = null;
920b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Uri personUri = null;
921b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
922b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (info != null) {
923b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // It appears that there is a small change in behaviour with the
924b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // PhoneUtils' startGetCallerInfo whereby if we query with an
925b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // empty number, we will get a valid CallerInfo object, but with
926b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // fields that are all null, and the isTemporary boolean input
927b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // parameter as true.
928b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
929b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // In the past, we would see a NULL callerinfo object, but this
930b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // ends up causing null pointer exceptions elsewhere down the
931b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // line in other cases, so we need to make this fix instead. It
932b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // appears that this was the ONLY call to PhoneUtils
933b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // .getCallerInfo() that relied on a NULL CallerInfo to indicate
934b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // an unknown contact.
935b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
936b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (TextUtils.isEmpty(info.name)) {
937b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (TextUtils.isEmpty(info.phoneNumber)) {
938b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (isPrivateNumber) {
939b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        name = getContext().getString(R.string.private_num);
940b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    } else {
941b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        name = getContext().getString(R.string.unknown);
942b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    }
943b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                } else {
944b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    name = info.phoneNumber;
945b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
946b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            } else {
947b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                name = info.name;
948b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                displayNumber = info.phoneNumber;
949b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                label = info.phoneLabel;
950b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
951b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            personUri = ContentUris.withAppendedId(People.CONTENT_URI, info.person_id);
952b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        } else {
953b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (isPrivateNumber) {
954b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                name = getContext().getString(R.string.private_num);
955b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            } else {
956b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                name = getContext().getString(R.string.unknown);
957b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
958b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
959b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mName.setText(name);
960b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mName.setVisibility(View.VISIBLE);
961b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
962b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Update mPhoto
963b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // if the temporary flag is set, we know we'll be getting another call after
964b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // the CallerInfo has been correctly updated.  So, we can skip the image
965b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // loading until then.
966b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
967b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // If the photoResource is filled in for the CallerInfo, (like with the
968b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Emergency Number case), then we can just set the photo image without
969b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // requesting for an image load. Please refer to CallerInfoAsyncQuery.java
970b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // for cases where CallerInfo.photoResource may be set.  We can also avoid
971b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // the image load step if the image data is cached.
972b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (isTemporary && (info == null || !info.isCachedPhotoCurrent)) {
973b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mPhoto.setVisibility(View.INVISIBLE);
974b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        } else if (info != null && info.photoResource != 0){
975b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            showImage(mPhoto, info.photoResource);
976b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        } else if (!showCachedImage(mPhoto, info)) {
977b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // Load the image with a callback to update the image state.
978b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // Use a placeholder image value of -1 to indicate no image.
979b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            ContactsAsyncHelper.updateImageViewWithContactPhotoAsync(info, 0, this, call,
980b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    getContext(), mPhoto, personUri, -1);
981b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
982b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (displayNumber != null) {
983b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mPhoneNumber.setText(displayNumber);
984b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mPhoneNumber.setVisibility(View.VISIBLE);
985b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        } else {
986b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mPhoneNumber.setVisibility(View.GONE);
987b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
988b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
989b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (label != null) {
990b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mLabel.setText(label);
991b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mLabel.setVisibility(View.VISIBLE);
992b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        } else {
993b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mLabel.setVisibility(View.GONE);
994b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
995b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
996b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
997b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
998b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
999b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Updates the name / photo / number / label fields
1000b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * for the special "conference call" state.
1001b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
1002b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * If the current call has only a single connection, use
1003b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * updateDisplayForPerson() instead.
1004b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
1005b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void updateDisplayForConference() {
1006b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("updateDisplayForConference()...");
1007b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1008b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Display the "conference call" image in the photo slot,
1009b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // with no other information.
1010b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1011b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        showImage(mPhoto, R.drawable.picture_conference);
1012b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1013b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mName.setText(R.string.card_title_conf_call);
1014b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mName.setVisibility(View.VISIBLE);
1015b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1016b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // TODO: For a conference call, the "phone number" slot is specced
1017b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // to contain a summary of who's on the call, like "Bill Foldes
1018b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // and Hazel Nutt" or "Bill Foldes and 2 others".
1019b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // But for now, just hide it:
1020b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mPhoneNumber.setVisibility(View.GONE);
1021b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1022b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mLabel.setVisibility(View.GONE);
1023b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1024b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // TODO: consider also showing names / numbers / photos of some of the
1025b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // people on the conference here, so you can see that info without
1026b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // having to click "Manage conference".  We probably have enough
1027b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // space to show info for 2 people, at least.
1028b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        //
1029b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // To do this, our caller would pass us the activeConnections
1030b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // list, and we'd call PhoneUtils.getCallerInfo() separately for
1031b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // each connection.
1032b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
1033b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1034b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
1035b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Updates the CallCard "photo" IFF the specified Call is in a state
1036b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * that needs a special photo (like "busy" or "dialing".)
1037b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
1038b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * If the current call does not require a special image in the "photo"
1039b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * slot onscreen, don't do anything, since presumably the photo image
1040b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * has already been set (to the photo of the person we're talking, or
1041b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * the generic "picture_unknown" image, or the "conference call"
1042b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * image.)
1043b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
1044b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void updatePhotoForCallState(Call call) {
1045b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("updatePhotoForCallState(" + call + ")...");
1046b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        int photoImageResource = 0;
1047b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1048b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Check for the (relatively few) telephony states that need a
1049b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // special image in the "photo" slot.
1050b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Call.State state = call.getState();
1051b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        switch (state) {
1052b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case DISCONNECTED:
1053b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // Display the special "busy" photo for BUSY or CONGESTION.
1054b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // Otherwise (presumably the normal "call ended" state)
1055b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // leave the photo alone.
1056b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                Connection c = call.getEarliestConnection();
1057b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // if the connection is null, we assume the default case,
1058b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // otherwise update the image resource normally.
1059b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (c != null) {
1060b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    Connection.DisconnectCause cause = c.getDisconnectCause();
1061b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if ((cause == Connection.DisconnectCause.BUSY)
1062b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        || (cause == Connection.DisconnectCause.CONGESTION)) {
1063b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        photoImageResource = R.drawable.picture_busy;
1064b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    }
1065b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                } else if (DBG) {
1066b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    log("updatePhotoForCallState: connection is null, ignoring.");
1067b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
1068b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1069b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // TODO: add special images for any other DisconnectCauses?
1070b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
1071b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1072b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case DIALING:
1073b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case ALERTING:
1074b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                photoImageResource = R.drawable.picture_dialing;
1075b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
1076b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1077b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            default:
1078b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // Leave the photo alone in all other states.
1079b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // If this call is an individual call, and the image is currently
1080b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // displaying a state, (rather than a photo), we'll need to update
1081b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // the image.
1082b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // This is for the case where we've been displaying the state and
1083b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // now we need to restore the photo.  This can happen because we
1084b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // only query the CallerInfo once, and limit the number of times
1085b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // the image is loaded. (So a state image may overwrite the photo
1086b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // and we would otherwise have no way of displaying the photo when
1087b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // the state goes away.)
1088b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1089b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // if the photoResource field is filled-in in the Connection's
1090b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // caller info, then we can just use that instead of requesting
1091b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // for a photo load.
1092b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1093b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // look for the photoResource if it is available.
1094b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                CallerInfo ci = null;
1095b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                {
1096b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    Connection conn = call.getEarliestConnection();
1097b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (conn != null) {
1098b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        Object o = conn.getUserData();
1099b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        if (o instanceof CallerInfo) {
1100b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                            ci = (CallerInfo) o;
1101b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        } else if (o instanceof PhoneUtils.CallerInfoToken) {
1102b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                            ci = ((PhoneUtils.CallerInfoToken) o).currentInfo;
1103b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        }
1104b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    }
1105b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
1106b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1107b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (ci != null) {
1108b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    photoImageResource = ci.photoResource;
1109b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
1110b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1111b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // If no photoResource found, check to see if this is a conference call. If
1112b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // it is not a conference call:
1113b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                //   1. Try to show the cached image
1114b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                //   2. If the image is not cached, check to see if a load request has been
1115b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                //      made already.
1116b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                //   3. If the load request has not been made [DISPLAY_DEFAULT], start the
1117b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                //      request and note that it has started by updating photo state with
1118b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                //      [DISPLAY_IMAGE].
1119b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // Load requests started in (3) use a placeholder image of -1 to hide the
1120b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // image by default.  Please refer to CallerInfoAsyncQuery.java for cases
1121b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // where CallerInfo.photoResource may be set.
1122b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (photoImageResource == 0) {
1123b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (!PhoneUtils.isConferenceCall(call)) {
1124b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        if (!showCachedImage(mPhoto, ci) && (mPhotoTracker.getPhotoState() ==
1125b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                                ContactsAsyncHelper.ImageTracker.DISPLAY_DEFAULT)) {
1126b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                            ContactsAsyncHelper.updateImageViewWithContactPhotoAsync(ci,
1127b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                                    getContext(), mPhoto, mPhotoTracker.getPhotoUri(), -1);
1128b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                            mPhotoTracker.setPhotoState(
1129b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                                    ContactsAsyncHelper.ImageTracker.DISPLAY_IMAGE);
1130b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        }
1131b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    }
1132b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                } else {
1133b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    showImage(mPhoto, photoImageResource);
1134b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    mPhotoTracker.setPhotoState(ContactsAsyncHelper.ImageTracker.DISPLAY_IMAGE);
1135b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    return;
1136b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
1137b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
1138b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
1139b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1140b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (photoImageResource != 0) {
1141b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (DBG) log("- overrriding photo image: " + photoImageResource);
1142b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            showImage(mPhoto, photoImageResource);
1143b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // Track the image state.
1144b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mPhotoTracker.setPhotoState(ContactsAsyncHelper.ImageTracker.DISPLAY_DEFAULT);
1145b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
1146b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
1147b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1148b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
1149b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Try to display the cached image from the callerinfo object.
1150b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
1151b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *  @return true if we were able to find the image in the cache, false otherwise.
1152b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
1153b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private static final boolean showCachedImage (ImageView view, CallerInfo ci) {
1154b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if ((ci != null) && ci.isCachedPhotoCurrent) {
1155b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (ci.cachedPhoto != null) {
1156b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                showImage(view, ci.cachedPhoto);
1157b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            } else {
1158b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                showImage(view, R.drawable.picture_unknown);
1159b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
1160b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return true;
1161b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
1162b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return false;
1163b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
1164b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1165b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /** Helper function to display the resource in the imageview AND ensure its visibility.*/
1166b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private static final void showImage(ImageView view, int resource) {
1167b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        view.setImageResource(resource);
1168b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        view.setVisibility(View.VISIBLE);
1169b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
1170b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1171b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /** Helper function to display the drawable in the imageview AND ensure its visibility.*/
1172b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private static final void showImage(ImageView view, Drawable drawable) {
1173b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        view.setImageDrawable(drawable);
1174b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        view.setVisibility(View.VISIBLE);
1175b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
1176b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1177b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
1178b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Intercepts (and discards) any touch events to the CallCard.
1179b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
1180b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    @Override
1181b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public boolean dispatchTouchEvent(MotionEvent ev) {
1182b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // if (DBG) log("CALLCARD: dispatchTouchEvent(): ev = " + ev);
1183b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1184b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // We *never* let touch events get thru to the UI inside the
1185b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // CallCard, since there's nothing touchable there.
1186b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return true;
1187b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
1188b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1189b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
1190b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Sets the background drawable of the main call card.
1191b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
1192b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void setMainCallCardBackgroundResource(int resid) {
1193b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mMainCallCard.setBackgroundResource(resid);
1194b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
1195b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1196b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
1197b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Sets the background drawable of the "ongoing call" info area.
1198b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
1199b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void setOngoingInfoAreaBackgroundResource(int resid) {
1200b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mOtherCallOngoingInfoArea.setBackgroundResource(resid);
1201b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
1202b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1203b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
1204b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Sets the background drawable of the "call on hold" info area.
1205b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
1206b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void setOnHoldInfoAreaBackgroundResource(int resid) {
1207b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mOtherCallOnHoldInfoArea.setBackgroundResource(resid);
1208b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
1209b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1210b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
1211b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Returns the "Menu button hint" TextView (which is manipulated
1212b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * directly by the InCallScreen.)
1213b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * @see InCallScreen.updateMenuButtonHint()
1214b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
1215b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /* package */ TextView getMenuButtonHint() {
1216b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return mMenuButtonHint;
1217b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
1218b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1219b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
1220b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Updates anything about our View hierarchy or internal state
1221b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * that needs to be different in landscape mode.
1222b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
1223b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * @see InCallScreen.applyConfigurationToLayout()
1224b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
1225b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /* package */ void updateForLandscapeMode() {
1226b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("updateForLandscapeMode()...");
1227b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1228b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // The main CallCard's minimum height is smaller in landscape mode
1229b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // than in portrait mode.
1230b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mMainCallCard.setMinimumHeight(MAIN_CALLCARD_MIN_HEIGHT_LANDSCAPE);
1231b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1232b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Add some left and right margin to the top-level elements, since
1233b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // there's no need to use the full width of the screen (which is
1234b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // much wider in landscape mode.)
1235b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        setSideMargins(mMainCallCard, CALLCARD_SIDE_MARGIN_LANDSCAPE);
1236b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        setSideMargins(mOtherCallOngoingInfoArea, CALLCARD_SIDE_MARGIN_LANDSCAPE);
1237b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        setSideMargins(mOtherCallOnHoldInfoArea, CALLCARD_SIDE_MARGIN_LANDSCAPE);
1238b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1239b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // A couple of TextViews are slightly smaller in landscape mode.
1240b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mUpperTitle.setTextSize(TITLE_TEXT_SIZE_LANDSCAPE);
1241b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
1242b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1243b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
1244b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Sets the left and right margins of the specified ViewGroup (whose
1245b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * LayoutParams object which must inherit from
1246b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * ViewGroup.MarginLayoutParams.)
1247b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
1248b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * TODO: Is there already a convenience method like this somewhere?
1249b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
1250b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void setSideMargins(ViewGroup vg, int margin) {
1251b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        ViewGroup.MarginLayoutParams lp =
1252b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                (ViewGroup.MarginLayoutParams) vg.getLayoutParams();
1253b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Equivalent to setting android:layout_marginLeft/Right in XML
1254b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        lp.leftMargin = margin;
1255b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        lp.rightMargin = margin;
1256b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        vg.setLayoutParams(lp);
1257b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
1258b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
12598bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project    /**
12608bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     * Sets the CallCard "upper title" to a plain string, with no icon.
12618bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     */
12628bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project    private void setUpperTitle(String title) {
12638bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project        mUpperTitle.setText(title);
12648bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project        mUpperTitle.setCompoundDrawables(null, null, null, null);
12658bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project    }
12668bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project
12678bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project    /**
12688bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     * Sets the CallCard "upper title".  Also, depending on the passed-in
12698bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     * Call state, possibly display an icon along with the title.
12708bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     */
12718bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project    private void setUpperTitle(String title, Call.State state) {
12728bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project        mUpperTitle.setText(title);
12738bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project
12748bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project        int bluetoothIconId = 0;
12758bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project        if (((state == Call.State.INCOMING) || (state == Call.State.WAITING))
12768bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                && PhoneApp.getInstance().showBluetoothIndication()) {
12778bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project            // Display the special bluetooth icon also, if this is an incoming
12788bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project            // call and the audio will be routed to bluetooth.
12798bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project            bluetoothIconId = R.drawable.ic_incoming_call_bluetooth;
12808bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project        }
12818bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project
12828bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project        mUpperTitle.setCompoundDrawablesWithIntrinsicBounds(bluetoothIconId, 0, 0, 0);
12838bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project        if (bluetoothIconId != 0) mUpperTitle.setCompoundDrawablePadding(5);
12848bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project    }
12858bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project
1286b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1287b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // Debugging / testing code
1288b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1289b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void log(String msg) {
1290b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Log.d(LOG_TAG, "[CallCard " + this + "] " + msg);
1291b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
1292b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
1293b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private static void logErr(String msg) {
1294b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Log.e(LOG_TAG, "[CallCard] " + msg);
1295b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
1296b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project}
1297