/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.phone;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.content.Context;
import android.graphics.drawable.LayerDrawable;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewPropertyAnimator;
import android.view.ViewStub;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.widget.CompoundButton;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.PopupMenu;
import android.widget.TextView;
import android.widget.Toast;

import com.android.internal.telephony.Call;
import com.android.internal.telephony.CallManager;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.widget.multiwaveview.GlowPadView;
import com.android.internal.widget.multiwaveview.GlowPadView.OnTriggerListener;
import com.android.phone.InCallUiState.InCallScreenMode;

/**
 * In-call onscreen touch UI elements, used on some platforms.
 *
 * This widget is a fullscreen overlay, drawn on top of the
 * non-touch-sensitive parts of the in-call UI (i.e. the call card).
 */
public class InCallTouchUi extends FrameLayout
        implements View.OnClickListener, View.OnLongClickListener, OnTriggerListener,
        PopupMenu.OnMenuItemClickListener, PopupMenu.OnDismissListener {
    private static final String LOG_TAG = "InCallTouchUi";
    private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);

    // Incoming call widget targets
    private static final int ANSWER_CALL_ID = 0;  // drag right
    private static final int SEND_SMS_ID = 1;  // drag up
    private static final int DECLINE_CALL_ID = 2;  // drag left

    /**
     * Reference to the InCallScreen activity that owns us.  This may be
     * null if we haven't been initialized yet *or* after the InCallScreen
     * activity has been destroyed.
     */
    private InCallScreen mInCallScreen;

    // Phone app instance
    private PhoneGlobals mApp;

    // UI containers / elements
    private GlowPadView mIncomingCallWidget;  // UI used for an incoming call
    private boolean mIncomingCallWidgetIsFadingOut;
    private boolean mIncomingCallWidgetShouldBeReset = true;

    /** UI elements while on a regular call (bottom buttons, DTMF dialpad) */
    private View mInCallControls;
    private boolean mShowInCallControlsDuringHidingAnimation;

    //
    private ImageButton mAddButton;
    private ImageButton mMergeButton;
    private ImageButton mEndButton;
    private CompoundButton mDialpadButton;
    private CompoundButton mMuteButton;
    private CompoundButton mAudioButton;
    private CompoundButton mHoldButton;
    private ImageButton mSwapButton;
    private View mHoldSwapSpacer;

    // "Extra button row"
    private ViewStub mExtraButtonRow;
    private ViewGroup mCdmaMergeButton;
    private ViewGroup mManageConferenceButton;
    private ImageButton mManageConferenceButtonImage;

    // "Audio mode" PopupMenu
    private PopupMenu mAudioModePopup;
    private boolean mAudioModePopupVisible = false;

    // Time of the most recent "answer" or "reject" action (see updateState())
    private long mLastIncomingCallActionTime;  // in SystemClock.uptimeMillis() time base

    // Parameters for the GlowPadView "ping" animation; see triggerPing().
    private static final boolean ENABLE_PING_ON_RING_EVENTS = false;
    private static final boolean ENABLE_PING_AUTO_REPEAT = true;
    private static final long PING_AUTO_REPEAT_DELAY_MSEC = 1200;

    private static final int INCOMING_CALL_WIDGET_PING = 101;
    private Handler mHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                // If the InCallScreen activity isn't around any more,
                // there's no point doing anything here.
                if (mInCallScreen == null) return;

                switch (msg.what) {
                    case INCOMING_CALL_WIDGET_PING:
                        if (DBG) log("INCOMING_CALL_WIDGET_PING...");
                        triggerPing();
                        break;
                    default:
                        Log.wtf(LOG_TAG, "mHandler: unexpected message: " + msg);
                        break;
                }
            }
        };

    public InCallTouchUi(Context context, AttributeSet attrs) {
        super(context, attrs);

        if (DBG) log("InCallTouchUi constructor...");
        if (DBG) log("- this = " + this);
        if (DBG) log("- context " + context + ", attrs " + attrs);
        mApp = PhoneGlobals.getInstance();
    }

    void setInCallScreenInstance(InCallScreen inCallScreen) {
        mInCallScreen = inCallScreen;
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        if (DBG) log("InCallTouchUi onFinishInflate(this = " + this + ")...");

        // Look up the various UI elements.

        // "Drag-to-answer" widget for incoming calls.
        mIncomingCallWidget = (GlowPadView) findViewById(R.id.incomingCallWidget);
        mIncomingCallWidget.setOnTriggerListener(this);

        // Container for the UI elements shown while on a regular call.
        mInCallControls = findViewById(R.id.inCallControls);

        // Regular (single-tap) buttons, where we listen for click events:
        // Main cluster of buttons:
        mAddButton = (ImageButton) mInCallControls.findViewById(R.id.addButton);
        mAddButton.setOnClickListener(this);
        mAddButton.setOnLongClickListener(this);
        mMergeButton = (ImageButton) mInCallControls.findViewById(R.id.mergeButton);
        mMergeButton.setOnClickListener(this);
        mMergeButton.setOnLongClickListener(this);
        mEndButton = (ImageButton) mInCallControls.findViewById(R.id.endButton);
        mEndButton.setOnClickListener(this);
        mDialpadButton = (CompoundButton) mInCallControls.findViewById(R.id.dialpadButton);
        mDialpadButton.setOnClickListener(this);
        mDialpadButton.setOnLongClickListener(this);
        mMuteButton = (CompoundButton) mInCallControls.findViewById(R.id.muteButton);
        mMuteButton.setOnClickListener(this);
        mMuteButton.setOnLongClickListener(this);
        mAudioButton = (CompoundButton) mInCallControls.findViewById(R.id.audioButton);
        mAudioButton.setOnClickListener(this);
        mAudioButton.setOnLongClickListener(this);
        mHoldButton = (CompoundButton) mInCallControls.findViewById(R.id.holdButton);
        mHoldButton.setOnClickListener(this);
        mHoldButton.setOnLongClickListener(this);
        mSwapButton = (ImageButton) mInCallControls.findViewById(R.id.swapButton);
        mSwapButton.setOnClickListener(this);
        mSwapButton.setOnLongClickListener(this);
        mHoldSwapSpacer = mInCallControls.findViewById(R.id.holdSwapSpacer);

        // TODO: Back when these buttons had text labels, we changed
        // the label of mSwapButton for CDMA as follows:
        //
        //      if (PhoneApp.getPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
        //          // In CDMA we use a generalized text - "Manage call", as behavior on selecting
        //          // this option depends entirely on what the current call state is.
        //          mSwapButtonLabel.setText(R.string.onscreenManageCallsText);
        //      } else {
        //          mSwapButtonLabel.setText(R.string.onscreenSwapCallsText);
        //      }
        //
        // If this is still needed, consider having a special icon for this
        // button in CDMA.

        // Buttons shown on the "extra button row", only visible in certain (rare) states.
        mExtraButtonRow = (ViewStub) mInCallControls.findViewById(R.id.extraButtonRow);

        // If in PORTRAIT, add a custom OnTouchListener to shrink the "hit target".
        if (!PhoneUtils.isLandscape(this.getContext())) {
            mEndButton.setOnTouchListener(new SmallerHitTargetTouchListener());
        }

    }

    /**
     * Updates the visibility and/or state of our UI elements, based on
     * the current state of the phone.
     *
     * TODO: This function should be relying on a state defined by InCallScreen,
     * and not generic call states. The incoming call screen handles more states
     * than Call.State or PhoneConstant.State know about.
     */
    /* package */ void updateState(CallManager cm) {
        if (mInCallScreen == null) {
            log("- updateState: mInCallScreen has been destroyed; bailing out...");
            return;
        }

        PhoneConstants.State state = cm.getState();  // IDLE, RINGING, or OFFHOOK
        if (DBG) log("updateState: current state = " + state);

        boolean showIncomingCallControls = false;
        boolean showInCallControls = false;

        final Call ringingCall = cm.getFirstActiveRingingCall();
        final Call.State fgCallState = cm.getActiveFgCallState();

        // If the FG call is dialing/alerting, we should display for that call
        // and ignore the ringing call. This case happens when the telephony
        // layer rejects the ringing call while the FG call is dialing/alerting,
        // but the incoming call *does* briefly exist in the DISCONNECTING or
        // DISCONNECTED state.
        if ((ringingCall.getState() != Call.State.IDLE) && !fgCallState.isDialing()) {
            // A phone call is ringing *or* call waiting.

            // Watch out: even if the phone state is RINGING, it's
            // possible for the ringing call to be in the DISCONNECTING
            // state.  (This typically happens immediately after the user
            // rejects an incoming call, and in that case we *don't* show
            // the incoming call controls.)
            if (ringingCall.getState().isAlive()) {
                if (DBG) log("- updateState: RINGING!  Showing incoming call controls...");
                showIncomingCallControls = true;
            }

            // Ugly hack to cover up slow response from the radio:
            // if we get an updateState() call immediately after answering/rejecting a call
            // (via onTrigger()), *don't* show the incoming call
            // UI even if the phone is still in the RINGING state.
            // This covers up a slow response from the radio for some actions.
            // To detect that situation, we are using "500 msec" heuristics.
            //
            // Watch out: we should *not* rely on this behavior when "instant text response" action
            // has been chosen. See also onTrigger() for why.
            long now = SystemClock.uptimeMillis();
            if (now < mLastIncomingCallActionTime + 500) {
                log("updateState: Too soon after last action; not drawing!");
                showIncomingCallControls = false;
            }

            // b/6765896
            // If the glowview triggers two hits of the respond-via-sms gadget in
            // quick succession, it can cause the incoming call widget to show and hide
            // twice in a row.  However, the second hide doesn't get triggered because
            // we are already attemping to hide.  This causes an additional glowview to
            // stay up above all other screens.
            // In reality, we shouldn't even be showing incoming-call UI while we are
            // showing the respond-via-sms popup, so we check for that here.
            //
            // TODO: In the future, this entire state machine
            // should be reworked.  Respond-via-sms was stapled onto the current
            // design (and so were other states) and should be made a first-class
            // citizen in a new state machine.
            if (mInCallScreen.isQuickResponseDialogShowing()) {
                log("updateState: quickResponse visible. Cancel showing incoming call controls.");
                showIncomingCallControls = false;
            }
        } else {
            // Ok, show the regular in-call touch UI (with some exceptions):
            if (okToShowInCallControls()) {
                showInCallControls = true;
            } else {
                if (DBG) log("- updateState: NOT OK to show touch UI; disabling...");
            }
        }

        // In usual cases we don't allow showing both incoming call controls and in-call controls.
        //
        // There's one exception: if this call is during fading-out animation for the incoming
        // call controls, we need to show both for smoother transition.
        if (showIncomingCallControls && showInCallControls) {
            throw new IllegalStateException(
                "'Incoming' and 'in-call' touch controls visible at the same time!");
        }
        if (mShowInCallControlsDuringHidingAnimation) {
            if (DBG) {
                log("- updateState: FORCE showing in-call controls during incoming call widget"
                        + " being hidden with animation");
            }
            showInCallControls = true;
        }

        // Update visibility and state of the incoming call controls or
        // the normal in-call controls.

        if (showInCallControls) {
            if (DBG) log("- updateState: showing in-call controls...");
            updateInCallControls(cm);
            mInCallControls.setVisibility(View.VISIBLE);
        } else {
            if (DBG) log("- updateState: HIDING in-call controls...");
            mInCallControls.setVisibility(View.GONE);
        }

        if (showIncomingCallControls) {
            if (DBG) log("- updateState: showing incoming call widget...");
            showIncomingCallWidget(ringingCall);

            // On devices with a system bar (soft buttons at the bottom of
            // the screen), disable navigation while the incoming-call UI
            // is up.
            // This prevents false touches (e.g. on the "Recents" button)
            // from interfering with the incoming call UI, like if you
            // accidentally touch the system bar while pulling the phone
            // out of your pocket.
            mApp.notificationMgr.statusBarHelper.enableSystemBarNavigation(false);
        } else {
            if (DBG) log("- updateState: HIDING incoming call widget...");
            hideIncomingCallWidget();

            // The system bar is allowed to work normally in regular
            // in-call states.
            mApp.notificationMgr.statusBarHelper.enableSystemBarNavigation(true);
        }

        // Dismiss the "Audio mode" PopupMenu if necessary.
        //
        // The "Audio mode" popup is only relevant in call states that support
        // in-call audio, namely when the phone is OFFHOOK (not RINGING), *and*
        // the foreground call is either ALERTING (where you can hear the other
        // end ringing) or ACTIVE (when the call is actually connected.)  In any
        // state *other* than these, the popup should not be visible.

        if ((state == PhoneConstants.State.OFFHOOK)
            && (fgCallState == Call.State.ALERTING || fgCallState == Call.State.ACTIVE)) {
            // The audio mode popup is allowed to be visible in this state.
            // So if it's up, leave it alone.
        } else {
            // The Audio mode popup isn't relevant in this state, so make sure
            // it's not visible.
            dismissAudioModePopup();  // safe even if not active
        }
    }

    private boolean okToShowInCallControls() {
        // Note that this method is concerned only with the internal state
        // of the InCallScreen.  (The InCallTouchUi widget has separate
        // logic to make sure it's OK to display the touch UI given the
        // current telephony state, and that it's allowed on the current
        // device in the first place.)

        // The touch UI is available in the following InCallScreenModes:
        // - NORMAL (obviously)
        // - CALL_ENDED (which is intended to look mostly the same as
        //               a normal in-call state, even though the in-call
        //               buttons are mostly disabled)
        // and is hidden in any of the other modes, like MANAGE_CONFERENCE
        // or one of the OTA modes (which use totally different UIs.)

        return ((mApp.inCallUiState.inCallScreenMode == InCallScreenMode.NORMAL)
                || (mApp.inCallUiState.inCallScreenMode == InCallScreenMode.CALL_ENDED));
    }

    @Override
    public void onClick(View view) {
        int id = view.getId();
        if (DBG) log("onClick(View " + view + ", id " + id + ")...");

        switch (id) {
            case R.id.addButton:
            case R.id.mergeButton:
            case R.id.endButton:
            case R.id.dialpadButton:
            case R.id.muteButton:
            case R.id.holdButton:
            case R.id.swapButton:
            case R.id.cdmaMergeButton:
            case R.id.manageConferenceButton:
                // Clicks on the regular onscreen buttons get forwarded
                // straight to the InCallScreen.
                mInCallScreen.handleOnscreenButtonClick(id);
                break;

            case R.id.audioButton:
                handleAudioButtonClick();
                break;

            default:
                Log.w(LOG_TAG, "onClick: unexpected click: View " + view + ", id " + id);
                break;
        }
    }

    @Override
    public boolean onLongClick(View view) {
        final int id = view.getId();
        if (DBG) log("onLongClick(View " + view + ", id " + id + ")...");

        switch (id) {
            case R.id.addButton:
            case R.id.mergeButton:
            case R.id.dialpadButton:
            case R.id.muteButton:
            case R.id.holdButton:
            case R.id.swapButton:
            case R.id.audioButton: {
                final CharSequence description = view.getContentDescription();
                if (!TextUtils.isEmpty(description)) {
                    // Show description as ActionBar's menu buttons do.
                    // See also ActionMenuItemView#onLongClick() for the original implementation.
                    final Toast cheatSheet =
                            Toast.makeText(view.getContext(), description, Toast.LENGTH_SHORT);
                    cheatSheet.setGravity(
                            Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, view.getHeight());
                    cheatSheet.show();
                }
                return true;
            }
            default:
                Log.w(LOG_TAG, "onLongClick() with unexpected View " + view + ". Ignoring it.");
                break;
        }
        return false;
    }

    /**
     * Updates the enabledness and "checked" state of the buttons on the
     * "inCallControls" panel, based on the current telephony state.
     */
    private void updateInCallControls(CallManager cm) {
        int phoneType = cm.getActiveFgCall().getPhone().getPhoneType();

        // Note we do NOT need to worry here about cases where the entire
        // in-call touch UI is disabled, like during an OTA call or if the
        // dtmf dialpad is up.  (That's handled by updateState(), which
        // calls okToShowInCallControls().)
        //
        // If we get here, it *is* OK to show the in-call touch UI, so we
        // now need to update the enabledness and/or "checked" state of
        // each individual button.
        //

        // The InCallControlState object tells us the enabledness and/or
        // state of the various onscreen buttons:
        InCallControlState inCallControlState = mInCallScreen.getUpdatedInCallControlState();

        if (DBG) {
            log("updateInCallControls()...");
            inCallControlState.dumpState();
        }

        // "Add" / "Merge":
        // These two buttons occupy the same space onscreen, so at any
        // given point exactly one of them must be VISIBLE and the other
        // must be GONE.
        if (inCallControlState.canAddCall) {
            mAddButton.setVisibility(View.VISIBLE);
            mAddButton.setEnabled(true);
            mMergeButton.setVisibility(View.GONE);
        } else if (inCallControlState.canMerge) {
            if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
                // In CDMA "Add" option is always given to the user and the
                // "Merge" option is provided as a button on the top left corner of the screen,
                // we always set the mMergeButton to GONE
                mMergeButton.setVisibility(View.GONE);
            } else if ((phoneType == PhoneConstants.PHONE_TYPE_GSM)
                    || (phoneType == PhoneConstants.PHONE_TYPE_SIP)) {
                mMergeButton.setVisibility(View.VISIBLE);
                mMergeButton.setEnabled(true);
                mAddButton.setVisibility(View.GONE);
            } else {
                throw new IllegalStateException("Unexpected phone type: " + phoneType);
            }
        } else {
            // Neither "Add" nor "Merge" is available.  (This happens in
            // some transient states, like while dialing an outgoing call,
            // and in other rare cases like if you have both lines in use
            // *and* there are already 5 people on the conference call.)
            // Since the common case here is "while dialing", we show the
            // "Add" button in a disabled state so that there won't be any
            // jarring change in the UI when the call finally connects.
            mAddButton.setVisibility(View.VISIBLE);
            mAddButton.setEnabled(false);
            mMergeButton.setVisibility(View.GONE);
        }
        if (inCallControlState.canAddCall && inCallControlState.canMerge) {
            if ((phoneType == PhoneConstants.PHONE_TYPE_GSM)
                    || (phoneType == PhoneConstants.PHONE_TYPE_SIP)) {
                // Uh oh, the InCallControlState thinks that "Add" *and* "Merge"
                // should both be available right now.  This *should* never
                // happen with GSM, but if it's possible on any
                // future devices we may need to re-layout Add and Merge so
                // they can both be visible at the same time...
                Log.w(LOG_TAG, "updateInCallControls: Add *and* Merge enabled," +
                        " but can't show both!");
            } else if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
                // In CDMA "Add" option is always given to the user and the hence
                // in this case both "Add" and "Merge" options would be available to user
                if (DBG) log("updateInCallControls: CDMA: Add and Merge both enabled");
            } else {
                throw new IllegalStateException("Unexpected phone type: " + phoneType);
            }
        }

        // "End call"
        mEndButton.setEnabled(inCallControlState.canEndCall);

        // "Dialpad": Enabled only when it's OK to use the dialpad in the
        // first place.
        mDialpadButton.setEnabled(inCallControlState.dialpadEnabled);
        mDialpadButton.setChecked(inCallControlState.dialpadVisible);

        // "Mute"
        mMuteButton.setEnabled(inCallControlState.canMute);
        mMuteButton.setChecked(inCallControlState.muteIndicatorOn);

        // "Audio"
        updateAudioButton(inCallControlState);

        // "Hold" / "Swap":
        // These two buttons occupy the same space onscreen, so at any
        // given point exactly one of them must be VISIBLE and the other
        // must be GONE.
        if (inCallControlState.canHold) {
            mHoldButton.setVisibility(View.VISIBLE);
            mHoldButton.setEnabled(true);
            mHoldButton.setChecked(inCallControlState.onHold);
            mSwapButton.setVisibility(View.GONE);
            mHoldSwapSpacer.setVisibility(View.VISIBLE);
        } else if (inCallControlState.canSwap) {
            mSwapButton.setVisibility(View.VISIBLE);
            mSwapButton.setEnabled(true);
            mHoldButton.setVisibility(View.GONE);
            mHoldSwapSpacer.setVisibility(View.VISIBLE);
        } else {
            // Neither "Hold" nor "Swap" is available.  This can happen for two
            // reasons:
            //   (1) this is a transient state on a device that *can*
            //       normally hold or swap, or
            //   (2) this device just doesn't have the concept of hold/swap.
            //
            // In case (1), show the "Hold" button in a disabled state.  In case
            // (2), remove the button entirely.  (This means that the button row
            // will only have 4 buttons on some devices.)

            if (inCallControlState.supportsHold) {
                mHoldButton.setVisibility(View.VISIBLE);
                mHoldButton.setEnabled(false);
                mHoldButton.setChecked(false);
                mSwapButton.setVisibility(View.GONE);
                mHoldSwapSpacer.setVisibility(View.VISIBLE);
            } else {
                mHoldButton.setVisibility(View.GONE);
                mSwapButton.setVisibility(View.GONE);
                mHoldSwapSpacer.setVisibility(View.GONE);
            }
        }
        mInCallScreen.updateButtonStateOutsideInCallTouchUi();
        if (inCallControlState.canSwap && inCallControlState.canHold) {
            // Uh oh, the InCallControlState thinks that Swap *and* Hold
            // should both be available.  This *should* never happen with
            // either GSM or CDMA, but if it's possible on any future
            // devices we may need to re-layout Hold and Swap so they can
            // both be visible at the same time...
            Log.w(LOG_TAG, "updateInCallControls: Hold *and* Swap enabled, but can't show both!");
        }

        if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
            if (inCallControlState.canSwap && inCallControlState.canMerge) {
                // Uh oh, the InCallControlState thinks that Swap *and* Merge
                // should both be available.  This *should* never happen with
                // CDMA, but if it's possible on any future
                // devices we may need to re-layout Merge and Swap so they can
                // both be visible at the same time...
                Log.w(LOG_TAG, "updateInCallControls: Merge *and* Swap" +
                        "enabled, but can't show both!");
            }
        }

        // Finally, update the "extra button row": It's displayed above the
        // "End" button, but only if necessary.  Also, it's never displayed
        // while the dialpad is visible (since it would overlap.)
        //
        // The row contains two buttons:
        //
        // - "Manage conference" (used only on GSM devices)
        // - "Merge" button (used only on CDMA devices)
        //
        // Note that mExtraButtonRow is ViewStub, which will be inflated for the first time when
        // any of its buttons becomes visible.
        final boolean showCdmaMerge =
                (phoneType == PhoneConstants.PHONE_TYPE_CDMA) && inCallControlState.canMerge;
        final boolean showExtraButtonRow =
                showCdmaMerge || inCallControlState.manageConferenceVisible;
        if (showExtraButtonRow && !inCallControlState.dialpadVisible) {
            // This will require the ViewStub inflate itself.
            mExtraButtonRow.setVisibility(View.VISIBLE);

            // Need to set up mCdmaMergeButton and mManageConferenceButton if this is the first
            // time they're visible.
            if (mCdmaMergeButton == null) {
                setupExtraButtons();
            }
            mCdmaMergeButton.setVisibility(showCdmaMerge ? View.VISIBLE : View.GONE);
            if (inCallControlState.manageConferenceVisible) {
                mManageConferenceButton.setVisibility(View.VISIBLE);
                mManageConferenceButtonImage.setEnabled(inCallControlState.manageConferenceEnabled);
            } else {
                mManageConferenceButton.setVisibility(View.GONE);
            }
        } else {
            mExtraButtonRow.setVisibility(View.GONE);
        }

        if (DBG) {
            log("At the end of updateInCallControls().");
            dumpBottomButtonState();
        }
    }

    /**
     * Set up the buttons that are part of the "extra button row"
     */
    private void setupExtraButtons() {
        // The two "buttons" here (mCdmaMergeButton and mManageConferenceButton)
        // are actually layouts containing an icon and a text label side-by-side.
        mCdmaMergeButton = (ViewGroup) mInCallControls.findViewById(R.id.cdmaMergeButton);
        if (mCdmaMergeButton == null) {
            Log.wtf(LOG_TAG, "CDMA Merge button is null even after ViewStub being inflated.");
            return;
        }
        mCdmaMergeButton.setOnClickListener(this);

        mManageConferenceButton =
                (ViewGroup) mInCallControls.findViewById(R.id.manageConferenceButton);
        mManageConferenceButton.setOnClickListener(this);
        mManageConferenceButtonImage =
                (ImageButton) mInCallControls.findViewById(R.id.manageConferenceButtonImage);
    }

    private void dumpBottomButtonState() {
        log(" - dialpad: " + getButtonState(mDialpadButton));
        log(" - speaker: " + getButtonState(mAudioButton));
        log(" - mute: " + getButtonState(mMuteButton));
        log(" - hold: " + getButtonState(mHoldButton));
        log(" - swap: " + getButtonState(mSwapButton));
        log(" - add: " + getButtonState(mAddButton));
        log(" - merge: " + getButtonState(mMergeButton));
        log(" - cdmaMerge: " + getButtonState(mCdmaMergeButton));
        log(" - swap: " + getButtonState(mSwapButton));
        log(" - manageConferenceButton: " + getButtonState(mManageConferenceButton));
    }

    private static String getButtonState(View view) {
        if (view == null) {
            return "(null)";
        }
        StringBuilder builder = new StringBuilder();
        builder.append("visibility: " + (view.getVisibility() == View.VISIBLE ? "VISIBLE"
                : view.getVisibility() == View.INVISIBLE ? "INVISIBLE" : "GONE"));
        if (view instanceof ImageButton) {
            builder.append(", enabled: " + ((ImageButton) view).isEnabled());
        } else if (view instanceof CompoundButton) {
            builder.append(", enabled: " + ((CompoundButton) view).isEnabled());
            builder.append(", checked: " + ((CompoundButton) view).isChecked());
        }
        return builder.toString();
    }

    /**
     * Updates the onscreen "Audio mode" button based on the current state.
     *
     * - If bluetooth is available, this button's function is to bring up the
     *   "Audio mode" popup (which provides a 3-way choice between earpiece /
     *   speaker / bluetooth).  So it should look like a regular action button,
     *   but should also have the small "more_indicator" triangle that indicates
     *   that a menu will pop up.
     *
     * - If speaker (but not bluetooth) is available, this button should look like
     *   a regular toggle button (and indicate the current speaker state.)
     *
     * - If even speaker isn't available, disable the button entirely.
     */
    private void updateAudioButton(InCallControlState inCallControlState) {
        if (DBG) log("updateAudioButton()...");

        // The various layers of artwork for this button come from
        // btn_compound_audio.xml.  Keep track of which layers we want to be
        // visible:
        //
        // - This selector shows the blue bar below the button icon when
        //   this button is a toggle *and* it's currently "checked".
        boolean showToggleStateIndication = false;
        //
        // - This is visible if the popup menu is enabled:
        boolean showMoreIndicator = false;
        //
        // - Foreground icons for the button.  Exactly one of these is enabled:
        boolean showSpeakerOnIcon = false;
        boolean showSpeakerOffIcon = false;
        boolean showHandsetIcon = false;
        boolean showBluetoothIcon = false;

        if (inCallControlState.bluetoothEnabled) {
            if (DBG) log("- updateAudioButton: 'popup menu action button' mode...");

            mAudioButton.setEnabled(true);

            // The audio button is NOT a toggle in this state.  (And its
            // setChecked() state is irrelevant since we completely hide the
            // btn_compound_background layer anyway.)

            // Update desired layers:
            showMoreIndicator = true;
            if (inCallControlState.bluetoothIndicatorOn) {
                showBluetoothIcon = true;
            } else if (inCallControlState.speakerOn) {
                showSpeakerOnIcon = true;
            } else {
                showHandsetIcon = true;
                // TODO: if a wired headset is plugged in, that takes precedence
                // over the handset earpiece.  If so, maybe we should show some
                // sort of "wired headset" icon here instead of the "handset
                // earpiece" icon.  (Still need an asset for that, though.)
            }
        } else if (inCallControlState.speakerEnabled) {
            if (DBG) log("- updateAudioButton: 'speaker toggle' mode...");

            mAudioButton.setEnabled(true);

            // The audio button *is* a toggle in this state, and indicates the
            // current state of the speakerphone.
            mAudioButton.setChecked(inCallControlState.speakerOn);

            // Update desired layers:
            showToggleStateIndication = true;

            showSpeakerOnIcon = inCallControlState.speakerOn;
            showSpeakerOffIcon = !inCallControlState.speakerOn;
        } else {
            if (DBG) log("- updateAudioButton: disabled...");

            // The audio button is a toggle in this state, but that's mostly
            // irrelevant since it's always disabled and unchecked.
            mAudioButton.setEnabled(false);
            mAudioButton.setChecked(false);

            // Update desired layers:
            showToggleStateIndication = true;
            showSpeakerOffIcon = true;
        }

        // Finally, update the drawable layers (see btn_compound_audio.xml).

        // Constants used below with Drawable.setAlpha():
        final int HIDDEN = 0;
        final int VISIBLE = 255;

        LayerDrawable layers = (LayerDrawable) mAudioButton.getBackground();
        if (DBG) log("- 'layers' drawable: " + layers);

        layers.findDrawableByLayerId(R.id.compoundBackgroundItem)
                .setAlpha(showToggleStateIndication ? VISIBLE : HIDDEN);

        layers.findDrawableByLayerId(R.id.moreIndicatorItem)
                .setAlpha(showMoreIndicator ? VISIBLE : HIDDEN);

        layers.findDrawableByLayerId(R.id.bluetoothItem)
                .setAlpha(showBluetoothIcon ? VISIBLE : HIDDEN);

        layers.findDrawableByLayerId(R.id.handsetItem)
                .setAlpha(showHandsetIcon ? VISIBLE : HIDDEN);

        layers.findDrawableByLayerId(R.id.speakerphoneOnItem)
                .setAlpha(showSpeakerOnIcon ? VISIBLE : HIDDEN);

        layers.findDrawableByLayerId(R.id.speakerphoneOffItem)
                .setAlpha(showSpeakerOffIcon ? VISIBLE : HIDDEN);
    }

    /**
     * Handles a click on the "Audio mode" button.
     * - If bluetooth is available, bring up the "Audio mode" popup
     *   (which provides a 3-way choice between earpiece / speaker / bluetooth).
     * - If bluetooth is *not* available, just toggle between earpiece and
     *   speaker, with no popup at all.
     */
    private void handleAudioButtonClick() {
        InCallControlState inCallControlState = mInCallScreen.getUpdatedInCallControlState();
        if (inCallControlState.bluetoothEnabled) {
            if (DBG) log("- handleAudioButtonClick: 'popup menu' mode...");
            showAudioModePopup();
        } else {
            if (DBG) log("- handleAudioButtonClick: 'speaker toggle' mode...");
            mInCallScreen.toggleSpeaker();
        }
    }

    /**
     * Brings up the "Audio mode" popup.
     */
    private void showAudioModePopup() {
        if (DBG) log("showAudioModePopup()...");

        mAudioModePopup = new PopupMenu(mInCallScreen /* context */,
                                        mAudioButton /* anchorView */);
        mAudioModePopup.getMenuInflater().inflate(R.menu.incall_audio_mode_menu,
                                                  mAudioModePopup.getMenu());
        mAudioModePopup.setOnMenuItemClickListener(this);
        mAudioModePopup.setOnDismissListener(this);

        // Update the enabled/disabledness of menu items based on the
        // current call state.
        InCallControlState inCallControlState = mInCallScreen.getUpdatedInCallControlState();

        Menu menu = mAudioModePopup.getMenu();

        // TODO: Still need to have the "currently active" audio mode come
        // up pre-selected (or focused?) with a blue highlight.  Still
        // need exact visual design, and possibly framework support for this.
        // See comments below for the exact logic.

        MenuItem speakerItem = menu.findItem(R.id.audio_mode_speaker);
        speakerItem.setEnabled(inCallControlState.speakerEnabled);
        // TODO: Show speakerItem as initially "selected" if
        // inCallControlState.speakerOn is true.

        // We display *either* "earpiece" or "wired headset", never both,
        // depending on whether a wired headset is physically plugged in.
        MenuItem earpieceItem = menu.findItem(R.id.audio_mode_earpiece);
        MenuItem wiredHeadsetItem = menu.findItem(R.id.audio_mode_wired_headset);
        final boolean usingHeadset = mApp.isHeadsetPlugged();
        earpieceItem.setVisible(!usingHeadset);
        earpieceItem.setEnabled(!usingHeadset);
        wiredHeadsetItem.setVisible(usingHeadset);
        wiredHeadsetItem.setEnabled(usingHeadset);
        // TODO: Show the above item (either earpieceItem or wiredHeadsetItem)
        // as initially "selected" if inCallControlState.speakerOn and
        // inCallControlState.bluetoothIndicatorOn are both false.

        MenuItem bluetoothItem = menu.findItem(R.id.audio_mode_bluetooth);
        bluetoothItem.setEnabled(inCallControlState.bluetoothEnabled);
        // TODO: Show bluetoothItem as initially "selected" if
        // inCallControlState.bluetoothIndicatorOn is true.

        mAudioModePopup.show();

        // Unfortunately we need to manually keep track of the popup menu's
        // visiblity, since PopupMenu doesn't have an isShowing() method like
        // Dialogs do.
        mAudioModePopupVisible = true;
    }

    /**
     * Dismisses the "Audio mode" popup if it's visible.
     *
     * This is safe to call even if the popup is already dismissed, or even if
     * you never called showAudioModePopup() in the first place.
     */
    public void dismissAudioModePopup() {
        if (mAudioModePopup != null) {
            mAudioModePopup.dismiss();  // safe even if already dismissed
            mAudioModePopup = null;
            mAudioModePopupVisible = false;
        }
    }

    /**
     * Refreshes the "Audio mode" popup if it's visible.  This is useful
     * (for example) when a wired headset is plugged or unplugged,
     * since we need to switch back and forth between the "earpiece"
     * and "wired headset" items.
     *
     * This is safe to call even if the popup is already dismissed, or even if
     * you never called showAudioModePopup() in the first place.
     */
    public void refreshAudioModePopup() {
        if (mAudioModePopup != null && mAudioModePopupVisible) {
            // Dismiss the previous one
            mAudioModePopup.dismiss();  // safe even if already dismissed
            // And bring up a fresh PopupMenu
            showAudioModePopup();
        }
    }

    // PopupMenu.OnMenuItemClickListener implementation; see showAudioModePopup()
    @Override
    public boolean onMenuItemClick(MenuItem item) {
        if (DBG) log("- onMenuItemClick: " + item);
        if (DBG) log("  id: " + item.getItemId());
        if (DBG) log("  title: '" + item.getTitle() + "'");

        if (mInCallScreen == null) {
            Log.w(LOG_TAG, "onMenuItemClick(" + item + "), but null mInCallScreen!");
            return true;
        }

        switch (item.getItemId()) {
            case R.id.audio_mode_speaker:
                mInCallScreen.switchInCallAudio(InCallScreen.InCallAudioMode.SPEAKER);
                break;
            case R.id.audio_mode_earpiece:
            case R.id.audio_mode_wired_headset:
                // InCallAudioMode.EARPIECE means either the handset earpiece,
                // or the wired headset (if connected.)
                mInCallScreen.switchInCallAudio(InCallScreen.InCallAudioMode.EARPIECE);
                break;
            case R.id.audio_mode_bluetooth:
                mInCallScreen.switchInCallAudio(InCallScreen.InCallAudioMode.BLUETOOTH);
                break;
            default:
                Log.wtf(LOG_TAG,
                        "onMenuItemClick:  unexpected View ID " + item.getItemId()
                        + " (MenuItem = '" + item + "')");
                break;
        }
        return true;
    }

    // PopupMenu.OnDismissListener implementation; see showAudioModePopup().
    // This gets called when the PopupMenu gets dismissed for *any* reason, like
    // the user tapping outside its bounds, or pressing Back, or selecting one
    // of the menu items.
    @Override
    public void onDismiss(PopupMenu menu) {
        if (DBG) log("- onDismiss: " + menu);
        mAudioModePopupVisible = false;
    }

    /**
     * @return the amount of vertical space (in pixels) that needs to be
     * reserved for the button cluster at the bottom of the screen.
     * (The CallCard uses this measurement to determine how big
     * the main "contact photo" area can be.)
     *
     * NOTE that this returns the "canonical height" of the main in-call
     * button cluster, which may not match the amount of vertical space
     * actually used.  Specifically:
     *
     *   - If an incoming call is ringing, the button cluster isn't
     *     visible at all.  (And the GlowPadView widget is actually
     *     much taller than the button cluster.)
     *
     *   - If the InCallTouchUi widget's "extra button row" is visible
     *     (in some rare phone states) the button cluster will actually
     *     be slightly taller than the "canonical height".
     *
     * In either of these cases, we allow the bottom edge of the contact
     * photo to be covered up by whatever UI is actually onscreen.
     */
    public int getTouchUiHeight() {
        // Add up the vertical space consumed by the various rows of buttons.
        int height = 0;

        // - The main row of buttons:
        height += (int) getResources().getDimension(R.dimen.in_call_button_height);

        // - The End button:
        height += (int) getResources().getDimension(R.dimen.in_call_end_button_height);

        // - Note we *don't* consider the InCallTouchUi widget's "extra
        //   button row" here.

        //- And an extra bit of margin:
        height += (int) getResources().getDimension(R.dimen.in_call_touch_ui_upper_margin);

        return height;
    }


    //
    // GlowPadView.OnTriggerListener implementation
    //

    @Override
    public void onGrabbed(View v, int handle) {

    }

    @Override
    public void onReleased(View v, int handle) {

    }

    /**
     * Handles "Answer" and "Reject" actions for an incoming call.
     * We get this callback from the incoming call widget
     * when the user triggers an action.
     */
    @Override
    public void onTrigger(View view, int whichHandle) {
        if (DBG) log("onTrigger(whichHandle = " + whichHandle + ")...");

        if (mInCallScreen == null) {
            Log.wtf(LOG_TAG, "onTrigger(" + whichHandle
                    + ") from incoming-call widget, but null mInCallScreen!");
            return;
        }

        // The InCallScreen actually implements all of these actions.
        // Each possible action from the incoming call widget corresponds
        // to an R.id value; we pass those to the InCallScreen's "button
        // click" handler (even though the UI elements aren't actually
        // buttons; see InCallScreen.handleOnscreenButtonClick().)

        mShowInCallControlsDuringHidingAnimation = false;
        switch (whichHandle) {
            case ANSWER_CALL_ID:
                if (DBG) log("ANSWER_CALL_ID: answer!");
                mInCallScreen.handleOnscreenButtonClick(R.id.incomingCallAnswer);
                mShowInCallControlsDuringHidingAnimation = true;

                // ...and also prevent it from reappearing right away.
                // (This covers up a slow response from the radio for some
                // actions; see updateState().)
                mLastIncomingCallActionTime = SystemClock.uptimeMillis();
                break;

            case SEND_SMS_ID:
                if (DBG) log("SEND_SMS_ID!");
                mInCallScreen.handleOnscreenButtonClick(R.id.incomingCallRespondViaSms);

                // Watch out: mLastIncomingCallActionTime should not be updated for this case.
                //
                // The variable is originally for avoiding a problem caused by delayed phone state
                // update; RINGING state may remain just after answering/declining an incoming
                // call, so we need to wait a bit (500ms) until we get the effective phone state.
                // For this case, we shouldn't rely on that hack.
                //
                // When the user selects this case, there are two possibilities, neither of which
                // should rely on the hack.
                //
                // 1. The first possibility is that, the device eventually sends one of canned
                //    responses per the user's "send" request, and reject the call after sending it.
                //    At that moment the code introducing the canned responses should handle the
                //    case separately.
                //
                // 2. The second possibility is that, the device will show incoming call widget
                //    again per the user's "cancel" request, where the incoming call will still
                //    remain. At that moment the incoming call will keep its RINGING state.
                //    The remaining phone state should never be ignored by the hack for
                //    answering/declining calls because the RINGING state is legitimate. If we
                //    use the hack for answer/decline cases, the user loses the incoming call
                //    widget, until further screen update occurs afterward, which often results in
                //    missed calls.
                break;

            case DECLINE_CALL_ID:
                if (DBG) log("DECLINE_CALL_ID: reject!");
                mInCallScreen.handleOnscreenButtonClick(R.id.incomingCallReject);

                // Same as "answer" case.
                mLastIncomingCallActionTime = SystemClock.uptimeMillis();
                break;

            default:
                Log.wtf(LOG_TAG, "onDialTrigger: unexpected whichHandle value: " + whichHandle);
                break;
        }

        // On any action by the user, hide the widget.
        //
        // If requested above (i.e. if mShowInCallControlsDuringHidingAnimation is set to true),
        // in-call controls will start being shown too.
        //
        // TODO: The decision to hide this should be made by the controller
        // (InCallScreen), and not this view.
        hideIncomingCallWidget();

        // Regardless of what action the user did, be sure to clear out
        // the hint text we were displaying while the user was dragging.
        mInCallScreen.updateIncomingCallWidgetHint(0, 0);
    }

    public void onFinishFinalAnimation() {
        // Not used
    }

    /**
     * Apply an animation to hide the incoming call widget.
     */
    private void hideIncomingCallWidget() {
        if (DBG) log("hideIncomingCallWidget()...");
        if (mIncomingCallWidget.getVisibility() != View.VISIBLE
                || mIncomingCallWidgetIsFadingOut) {
            if (DBG) log("Skipping hideIncomingCallWidget action");
            // Widget is already hidden or in the process of being hidden
            return;
        }

        // Hide the incoming call screen with a transition
        mIncomingCallWidgetIsFadingOut = true;
        ViewPropertyAnimator animator = mIncomingCallWidget.animate();
        animator.cancel();
        animator.setDuration(AnimationUtils.ANIMATION_DURATION);
        animator.setListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(Animator animation) {
                if (mShowInCallControlsDuringHidingAnimation) {
                    if (DBG) log("IncomingCallWidget's hiding animation started");
                    updateInCallControls(mApp.mCM);
                    mInCallControls.setVisibility(View.VISIBLE);
                }
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                if (DBG) log("IncomingCallWidget's hiding animation ended");
                mIncomingCallWidget.setAlpha(1);
                mIncomingCallWidget.setVisibility(View.GONE);
                mIncomingCallWidget.animate().setListener(null);
                mShowInCallControlsDuringHidingAnimation = false;
                mIncomingCallWidgetIsFadingOut = false;
                mIncomingCallWidgetShouldBeReset = true;
            }

            @Override
            public void onAnimationCancel(Animator animation) {
                mIncomingCallWidget.animate().setListener(null);
                mShowInCallControlsDuringHidingAnimation = false;
                mIncomingCallWidgetIsFadingOut = false;
                mIncomingCallWidgetShouldBeReset = true;

                // Note: the code which reset this animation should be responsible for
                // alpha and visibility.
            }
        });
        animator.alpha(0f);
    }

    /**
     * Shows the incoming call widget and cancels any animation that may be fading it out.
     */
    private void showIncomingCallWidget(Call ringingCall) {
        if (DBG) log("showIncomingCallWidget()...");

        // TODO: wouldn't be ok to suppress this whole request if the widget is already VISIBLE
        //       and we don't need to reset it?
        // log("showIncomingCallWidget(). widget visibility: " + mIncomingCallWidget.getVisibility());

        ViewPropertyAnimator animator = mIncomingCallWidget.animate();
        if (animator != null) {
            animator.cancel();
        }
        mIncomingCallWidget.setAlpha(1.0f);

        // Update the GlowPadView widget's targets based on the state of
        // the ringing call.  (Specifically, we need to disable the
        // "respond via SMS" option for certain types of calls, like SIP
        // addresses or numbers with blocked caller-id.)
        final boolean allowRespondViaSms =
                RespondViaSmsManager.allowRespondViaSmsForCall(mInCallScreen, ringingCall);
        final int targetResourceId = allowRespondViaSms
                ? R.array.incoming_call_widget_3way_targets
                : R.array.incoming_call_widget_2way_targets;
        // The widget should be updated only when appropriate; if the previous choice can be reused
        // for this incoming call, we'll just keep using it. Otherwise we'll see UI glitch
        // everytime when this method is called during a single incoming call.
        if (targetResourceId != mIncomingCallWidget.getTargetResourceId()) {
            if (allowRespondViaSms) {
                // The GlowPadView widget is allowed to have all 3 choices:
                // Answer, Decline, and Respond via SMS.
                mIncomingCallWidget.setTargetResources(targetResourceId);
                mIncomingCallWidget.setTargetDescriptionsResourceId(
                        R.array.incoming_call_widget_3way_target_descriptions);
                mIncomingCallWidget.setDirectionDescriptionsResourceId(
                        R.array.incoming_call_widget_3way_direction_descriptions);
            } else {
                // You only get two choices: Answer or Decline.
                mIncomingCallWidget.setTargetResources(targetResourceId);
                mIncomingCallWidget.setTargetDescriptionsResourceId(
                        R.array.incoming_call_widget_2way_target_descriptions);
                mIncomingCallWidget.setDirectionDescriptionsResourceId(
                        R.array.incoming_call_widget_2way_direction_descriptions);
            }

            // This will be used right after this block.
            mIncomingCallWidgetShouldBeReset = true;
        }
        if (mIncomingCallWidgetShouldBeReset) {
            // Watch out: be sure to call reset() and setVisibility() *after*
            // updating the target resources, since otherwise the GlowPadView
            // widget will make the targets visible initially (even before you
            // touch the widget.)
            mIncomingCallWidget.reset(false);
            mIncomingCallWidgetShouldBeReset = false;
        }

        // On an incoming call, if the layout is landscape, then align the "incoming call" text
        // to the left, because the incomingCallWidget (black background with glowing ring)
        // is aligned to the right and would cover the "incoming call" text.
        // Note that callStateLabel is within CallCard, outside of the context of InCallTouchUi
        if (PhoneUtils.isLandscape(this.getContext())) {
            TextView callStateLabel = (TextView) mIncomingCallWidget
                    .getRootView().findViewById(R.id.callStateLabel);
            if (callStateLabel != null) callStateLabel.setGravity(Gravity.LEFT);
        }

        mIncomingCallWidget.setVisibility(View.VISIBLE);

        // Finally, manually trigger a "ping" animation.
        //
        // Normally, the ping animation is triggered by RING events from
        // the telephony layer (see onIncomingRing().)  But that *doesn't*
        // happen for the very first RING event of an incoming call, since
        // the incoming-call UI hasn't been set up yet at that point!
        //
        // So trigger an explicit ping() here, to force the animation to
        // run when the widget first appears.
        //
        mHandler.removeMessages(INCOMING_CALL_WIDGET_PING);
        mHandler.sendEmptyMessageDelayed(
                INCOMING_CALL_WIDGET_PING,
                // Visual polish: add a small delay here, to make the
                // GlowPadView widget visible for a brief moment
                // *before* starting the ping animation.
                // This value doesn't need to be very precise.
                250 /* msec */);
    }

    /**
     * Handles state changes of the incoming-call widget.
     *
     * In previous releases (where we used a SlidingTab widget) we would
     * display an onscreen hint depending on which "handle" the user was
     * dragging.  But we now use a GlowPadView widget, which has only
     * one handle, so for now we don't display a hint at all (see the TODO
     * comment below.)
     */
    @Override
    public void onGrabbedStateChange(View v, int grabbedState) {
        if (mInCallScreen != null) {
            // Look up the hint based on which handle is currently grabbed.
            // (Note we don't simply pass grabbedState thru to the InCallScreen,
            // since *this* class is the only place that knows that the left
            // handle means "Answer" and the right handle means "Decline".)
            int hintTextResId, hintColorResId;
            switch (grabbedState) {
                case GlowPadView.OnTriggerListener.NO_HANDLE:
                case GlowPadView.OnTriggerListener.CENTER_HANDLE:
                    hintTextResId = 0;
                    hintColorResId = 0;
                    break;
                default:
                    Log.e(LOG_TAG, "onGrabbedStateChange: unexpected grabbedState: "
                          + grabbedState);
                    hintTextResId = 0;
                    hintColorResId = 0;
                    break;
            }

            // Tell the InCallScreen to update the CallCard and force the
            // screen to redraw.
            mInCallScreen.updateIncomingCallWidgetHint(hintTextResId, hintColorResId);
        }
    }

    /**
     * Handles an incoming RING event from the telephony layer.
     */
    public void onIncomingRing() {
        if (ENABLE_PING_ON_RING_EVENTS) {
            // Each RING from the telephony layer triggers a "ping" animation
            // of the GlowPadView widget.  (The intent here is to make the
            // pinging appear to be synchronized with the ringtone, although
            // that only works for non-looping ringtones.)
            triggerPing();
        }
    }

    /**
     * Runs a single "ping" animation of the GlowPadView widget,
     * or do nothing if the GlowPadView widget is no longer visible.
     *
     * Also, if ENABLE_PING_AUTO_REPEAT is true, schedule the next ping as
     * well (but again, only if the GlowPadView widget is still visible.)
     */
    public void triggerPing() {
        if (DBG) log("triggerPing: mIncomingCallWidget = " + mIncomingCallWidget);

        if (!mInCallScreen.isForegroundActivity()) {
            // InCallScreen has been dismissed; no need to run a ping *or*
            // schedule another one.
            log("- triggerPing: InCallScreen no longer in foreground; ignoring...");
            return;
        }

        if (mIncomingCallWidget == null) {
            // This shouldn't happen; the GlowPadView widget should
            // always be present in our layout file.
            Log.w(LOG_TAG, "- triggerPing: null mIncomingCallWidget!");
            return;
        }

        if (DBG) log("- triggerPing: mIncomingCallWidget visibility = "
                     + mIncomingCallWidget.getVisibility());

        if (mIncomingCallWidget.getVisibility() != View.VISIBLE) {
            if (DBG) log("- triggerPing: mIncomingCallWidget no longer visible; ignoring...");
            return;
        }

        // Ok, run a ping (and schedule the next one too, if desired...)

        mIncomingCallWidget.ping();

        if (ENABLE_PING_AUTO_REPEAT) {
            // Schedule the next ping.  (ENABLE_PING_AUTO_REPEAT mode
            // allows the ping animation to repeat much faster than in
            // the ENABLE_PING_ON_RING_EVENTS case, since telephony RING
            // events come fairly slowly (about 3 seconds apart.))

            // No need to check here if the call is still ringing, by
            // the way, since we hide mIncomingCallWidget as soon as the
            // ringing stops, or if the user answers.  (And at that
            // point, any future triggerPing() call will be a no-op.)

            // TODO: Rather than having a separate timer here, maybe try
            // having these pings synchronized with the vibrator (see
            // VibratorThread in Ringer.java; we'd just need to get
            // events routed from there to here, probably via the
            // PhoneApp instance.)  (But watch out: make sure pings
            // still work even if the Vibrate setting is turned off!)

            mHandler.sendEmptyMessageDelayed(INCOMING_CALL_WIDGET_PING,
                                             PING_AUTO_REPEAT_DELAY_MSEC);
        }
    }

    // Debugging / testing code

    private void log(String msg) {
        Log.d(LOG_TAG, msg);
    }
}
