diff --git a/proguard.flags b/proguard.flags
index c5f4c72..c4af490 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -1,6 +1 @@
-# Keep names that are used only by animation framework.
--keepclasseswithmembers class com.android.phone.AnimationUtils$CrossFadeDrawable {
-  *** setCrossFadeAlpha(...);
-}
-
--verbose
\ No newline at end of file
+-verbose
diff --git a/src/com/android/phone/AnimationUtils.java b/src/com/android/phone/AnimationUtils.java
deleted file mode 100644
index f7d9e2e..0000000
--- a/src/com/android/phone/AnimationUtils.java
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Copyright (C) 2012 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.animation.ObjectAnimator;
-import android.graphics.Canvas;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.LayerDrawable;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewPropertyAnimator;
-import android.widget.ImageView;
-
-/**
- * Utilities for Animation.
- */
-public class AnimationUtils {
-    private static final String LOG_TAG = AnimationUtils.class.getSimpleName();
-    /**
-     * Turn on when you're interested in fading animation. Intentionally untied from other debug
-     * settings.
-     */
-    private static final boolean FADE_DBG = false;
-
-    /**
-     * Duration for animations in msec, which can be used with
-     * {@link ViewPropertyAnimator#setDuration(long)} for example.
-     */
-    public static final int ANIMATION_DURATION = 250;
-
-    private AnimationUtils() {
-    }
-
-    /**
-     * Simple Utility class that runs fading animations on specified views.
-     */
-    public static class Fade {
-
-        // View tag that's set during the fade-out animation; see hide() and
-        // isFadingOut().
-        private static final int FADE_STATE_KEY = R.id.fadeState;
-        private static final String FADING_OUT = "fading_out";
-
-        /**
-         * Sets the visibility of the specified view to View.VISIBLE and then
-         * fades it in. If the view is already visible (and not in the middle
-         * of a fade-out animation), this method will return without doing
-         * anything.
-         *
-         * @param view The view to be faded in
-         */
-        public static void show(final View view) {
-            if (FADE_DBG) log("Fade: SHOW view " + view + "...");
-            if (FADE_DBG) log("Fade: - visibility = " + view.getVisibility());
-            if ((view.getVisibility() != View.VISIBLE) || isFadingOut(view)) {
-                view.animate().cancel();
-                // ...and clear the FADE_STATE_KEY tag in case we just
-                // canceled an in-progress fade-out animation.
-                view.setTag(FADE_STATE_KEY, null);
-
-                view.setAlpha(0);
-                view.setVisibility(View.VISIBLE);
-                view.animate().setDuration(ANIMATION_DURATION);
-                view.animate().alpha(1);
-                if (FADE_DBG) log("Fade: ==> SHOW " + view
-                                  + " DONE.  Set visibility = " + View.VISIBLE);
-            } else {
-                if (FADE_DBG) log("Fade: ==> Ignoring, already visible AND not fading out.");
-            }
-        }
-
-        /**
-         * Fades out the specified view and then sets its visibility to the
-         * specified value (either View.INVISIBLE or View.GONE). If the view
-         * is not currently visibile, the method will return without doing
-         * anything.
-         *
-         * Note that *during* the fade-out the view itself will still have
-         * visibility View.VISIBLE, although the isFadingOut() method will
-         * return true (in case the UI code needs to detect this state.)
-         *
-         * @param view The view to be hidden
-         * @param visibility The value to which the view's visibility will be
-         *                   set after it fades out.
-         *                   Must be either View.INVISIBLE or View.GONE.
-         */
-        public static void hide(final View view, final int visibility) {
-            if (FADE_DBG) log("Fade: HIDE view " + view + "...");
-            if (view.getVisibility() == View.VISIBLE &&
-                (visibility == View.INVISIBLE || visibility == View.GONE)) {
-
-                // Use a view tag to mark this view as being in the middle
-                // of a fade-out animation.
-                view.setTag(FADE_STATE_KEY, FADING_OUT);
-
-                view.animate().cancel();
-                view.animate().setDuration(ANIMATION_DURATION);
-                view.animate().alpha(0f).setListener(new AnimatorListenerAdapter() {
-                    @Override
-                    public void onAnimationEnd(Animator animation) {
-                        view.setAlpha(1);
-                        view.setVisibility(visibility);
-                        view.animate().setListener(null);
-                        // ...and we're done with the fade-out, so clear the view tag.
-                        view.setTag(FADE_STATE_KEY, null);
-                        if (FADE_DBG) log("Fade: HIDE " + view
-                                + " DONE.  Set visibility = " + visibility);
-                    }
-                });
-            }
-        }
-
-        /**
-         * @return true if the specified view is currently in the middle
-         * of a fade-out animation.  (During the fade-out, the view's
-         * visibility is still VISIBLE, although in many cases the UI
-         * should behave as if it's already invisible or gone.  This
-         * method allows the UI code to detect that state.)
-         *
-         * @see #hide(View, int)
-         */
-        public static boolean isFadingOut(final View view) {
-            if (FADE_DBG) {
-                log("Fade: isFadingOut view " + view + "...");
-                log("Fade:   - getTag() returns: " + view.getTag(FADE_STATE_KEY));
-                log("Fade:   - returning: " + (view.getTag(FADE_STATE_KEY) == FADING_OUT));
-            }
-            return (view.getTag(FADE_STATE_KEY) == FADING_OUT);
-        }
-
-    }
-
-    /**
-     * Drawable achieving cross-fade, just like TransitionDrawable. We can have
-     * call-backs via animator object (see also {@link CrossFadeDrawable#getAnimator()}).
-     */
-    private static class CrossFadeDrawable extends LayerDrawable {
-        private final ObjectAnimator mAnimator;
-
-        public CrossFadeDrawable(Drawable[] layers) {
-            super(layers);
-            mAnimator = ObjectAnimator.ofInt(this, "crossFadeAlpha", 0xff, 0);
-        }
-
-        private int mCrossFadeAlpha;
-
-        /**
-         * This will be used from ObjectAnimator.
-         * Note: this method is protected by proguard.flags so that it won't be removed
-         * automatically.
-         */
-        @SuppressWarnings("unused")
-        public void setCrossFadeAlpha(int alpha) {
-            mCrossFadeAlpha = alpha;
-            invalidateSelf();
-        }
-
-        public ObjectAnimator getAnimator() {
-            return mAnimator;
-        }
-
-        @Override
-        public void draw(Canvas canvas) {
-            Drawable first = getDrawable(0);
-            Drawable second = getDrawable(1);
-
-            if (mCrossFadeAlpha > 0) {
-                first.setAlpha(mCrossFadeAlpha);
-                first.draw(canvas);
-                first.setAlpha(255);
-            }
-
-            if (mCrossFadeAlpha < 0xff) {
-                second.setAlpha(0xff - mCrossFadeAlpha);
-                second.draw(canvas);
-                second.setAlpha(0xff);
-            }
-        }
-    }
-
-    private static CrossFadeDrawable newCrossFadeDrawable(Drawable first, Drawable second) {
-        Drawable[] layers = new Drawable[2];
-        layers[0] = first;
-        layers[1] = second;
-        return new CrossFadeDrawable(layers);
-    }
-
-    /**
-     * Starts cross-fade animation using TransitionDrawable. Nothing will happen if "from" and "to"
-     * are the same.
-     */
-    public static void startCrossFade(
-            final ImageView imageView, final Drawable from, final Drawable to) {
-        // We skip the cross-fade when those two Drawables are equal, or they are BitmapDrawables
-        // pointing to the same Bitmap.
-        final boolean areSameImage = from.equals(to) ||
-                ((from instanceof BitmapDrawable)
-                        && (to instanceof BitmapDrawable)
-                        && ((BitmapDrawable) from).getBitmap()
-                                .equals(((BitmapDrawable) to).getBitmap()));
-        if (!areSameImage) {
-            if (FADE_DBG) {
-                log("Start cross-fade animation for " + imageView
-                        + "(" + Integer.toHexString(from.hashCode()) + " -> "
-                        + Integer.toHexString(to.hashCode()) + ")");
-            }
-
-            CrossFadeDrawable crossFadeDrawable = newCrossFadeDrawable(from, to);
-            ObjectAnimator animator = crossFadeDrawable.getAnimator();
-            imageView.setImageDrawable(crossFadeDrawable);
-            animator.setDuration(ANIMATION_DURATION);
-            animator.addListener(new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationStart(Animator animation) {
-                    if (FADE_DBG) {
-                        log("cross-fade animation start ("
-                                + Integer.toHexString(from.hashCode()) + " -> "
-                                + Integer.toHexString(to.hashCode()) + ")");
-                    }
-                }
-
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    if (FADE_DBG) {
-                        log("cross-fade animation ended ("
-                                + Integer.toHexString(from.hashCode()) + " -> "
-                                + Integer.toHexString(to.hashCode()) + ")");
-                    }
-                    animation.removeAllListeners();
-                    // Workaround for issue 6300562; this will force the drawable to the
-                    // resultant one regardless of animation glitch.
-                    imageView.setImageDrawable(to);
-                }
-            });
-            animator.start();
-
-            /* We could use TransitionDrawable here, but it may cause some weird animation in
-             * some corner cases. See issue 6300562
-             * TODO: decide which to be used in the long run. TransitionDrawable is old but system
-             * one. Ours uses new animation framework and thus have callback (great for testing),
-             * while no framework support for the exact class.
-
-            Drawable[] layers = new Drawable[2];
-            layers[0] = from;
-            layers[1] = to;
-            TransitionDrawable transitionDrawable = new TransitionDrawable(layers);
-            imageView.setImageDrawable(transitionDrawable);
-            transitionDrawable.startTransition(ANIMATION_DURATION); */
-            imageView.setTag(to);
-        } else {
-            if (FADE_DBG) {
-                log("*Not* start cross-fade. " + imageView);
-            }
-        }
-    }
-
-    // Debugging / testing code
-
-    private static void log(String msg) {
-        Log.d(LOG_TAG, msg);
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/phone/BitmapUtils.java b/src/com/android/phone/BitmapUtils.java
deleted file mode 100644
index 94d4bf9..0000000
--- a/src/com/android/phone/BitmapUtils.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2011 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.graphics.Bitmap;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.util.Log;
-
-
-/**
- * Image effects used by the in-call UI.
- */
-public class BitmapUtils {
-    private static final String TAG = "BitmapUtils";
-    private static final boolean DBG =
-            (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
-
-    /** This class is never instantiated. */
-    private BitmapUtils() {
-    }
-
-    //
-    // Gaussian blur effect
-    //
-    // gaussianBlur() and related methods are borrowed from
-    // BackgroundUtils.java in the Music2 code (which itself was based on
-    // code from the old Cooliris android Gallery app.)
-    //
-    // TODO: possibly consider caching previously-generated blurred bitmaps;
-    // see getAdaptedBitmap() and mAdaptedBitmapCache in the music app code.
-    //
-
-    private static final int RED_MASK = 0xff0000;
-    private static final int RED_MASK_SHIFT = 16;
-    private static final int GREEN_MASK = 0x00ff00;
-    private static final int GREEN_MASK_SHIFT = 8;
-    private static final int BLUE_MASK = 0x0000ff;
-
-    /**
-     * Creates a blurred version of the given Bitmap.
-     *
-     * @param bitmap the input bitmap, presumably a 96x96 pixel contact
-     *               thumbnail.
-     */
-    public static Bitmap createBlurredBitmap(Bitmap bitmap) {
-        if (DBG) log("createBlurredBitmap()...");
-        long startTime = SystemClock.uptimeMillis();
-        if (bitmap == null) {
-            Log.w(TAG, "createBlurredBitmap: null bitmap");
-            return null;
-        }
-
-        if (DBG) log("- input bitmap: " + bitmap.getWidth() + " x " + bitmap.getHeight());
-
-        // The bitmap we pass to gaussianBlur() needs to have a width
-        // that's a power of 2, so scale up to 128x128.
-        final int scaledSize = 128;
-        bitmap = Bitmap.createScaledBitmap(bitmap,
-                                           scaledSize, scaledSize,
-                                           true /* filter */);
-        if (DBG) log("- after resize: " + bitmap.getWidth() + " x " + bitmap.getHeight());
-
-        bitmap = gaussianBlur(bitmap);
-        if (DBG) log("- after blur: " + bitmap.getWidth() + " x " + bitmap.getHeight());
-
-        long endTime = SystemClock.uptimeMillis();
-        if (DBG) log("createBlurredBitmap() done (elapsed = " + (endTime - startTime) + " msec)");
-        return bitmap;
-    }
-
-    /**
-     * Apply a gaussian blur filter, and return a new (blurred) bitmap
-     * that's the same size as the input bitmap.
-     *
-     * @param source input bitmap, whose width must be a power of 2
-     */
-    public static Bitmap gaussianBlur(Bitmap source) {
-        int width = source.getWidth();
-        int height = source.getHeight();
-        if (DBG) log("gaussianBlur(): input: " + width + " x " + height);
-
-        // Create a source and destination buffer for the image.
-        int numPixels = width * height;
-        int[] in = new int[numPixels];
-        int[] tmp = new int[numPixels];
-
-        // Get the source pixels as 32-bit ARGB.
-        source.getPixels(in, 0, width, 0, 0, width, height);
-
-        // Gaussian is a separable kernel, so it is decomposed into a horizontal
-        // and vertical pass.
-        // The filter function applies the kernel across each row and transposes
-        // the output.
-        // Hence we apply it twice to provide efficient horizontal and vertical
-        // convolution.
-        // The filter discards the alpha channel.
-        gaussianBlurFilter(in, tmp, width, height);
-        gaussianBlurFilter(tmp, in, width, height);
-
-        // Return a bitmap scaled to the desired size.
-        Bitmap filtered = Bitmap.createBitmap(in, width, height, Bitmap.Config.ARGB_8888);
-        source.recycle();
-        return filtered;
-    }
-
-    private static void gaussianBlurFilter(int[] in, int[] out, int width, int height) {
-        // This function is currently hardcoded to blur with RADIUS = 4.
-        // (If you change RADIUS, you'll have to change the weights[] too.)
-        final int RADIUS = 4;
-        final int[] weights = { 13, 23, 32, 39, 42, 39, 32, 23, 13}; // Adds up to 256
-        int inPos = 0;
-        int widthMask = width - 1; // width must be a power of two.
-        for (int y = 0; y < height; ++y) {
-            // Compute the alpha value.
-            int alpha = 0xff;
-            // Compute output values for the row.
-            int outPos = y;
-            for (int x = 0; x < width; ++x) {
-                int red = 0;
-                int green = 0;
-                int blue = 0;
-                for (int i = -RADIUS; i <= RADIUS; ++i) {
-                    int argb = in[inPos + (widthMask & (x + i))];
-                    int weight = weights[i+RADIUS];
-                    red += weight *((argb & RED_MASK) >> RED_MASK_SHIFT);
-                    green += weight *((argb & GREEN_MASK) >> GREEN_MASK_SHIFT);
-                    blue += weight *(argb & BLUE_MASK);
-                }
-                // Output the current pixel.
-                out[outPos] = (alpha << 24) | ((red >> 8) << RED_MASK_SHIFT)
-                    | ((green >> 8) << GREEN_MASK_SHIFT)
-                        | (blue >> 8);
-                outPos += height;
-            }
-            inPos += width;
-        }
-    }
-
-    //
-    // Debugging
-    //
-
-    private static void log(String msg) {
-        Log.d(TAG, msg);
-    }
-}
diff --git a/src/com/android/phone/CallCard.java b/src/com/android/phone/CallCard.java
deleted file mode 100644
index bfb14ac..0000000
--- a/src/com/android/phone/CallCard.java
+++ /dev/null
@@ -1,1746 +0,0 @@
-/*
- * Copyright (C) 2006 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.LayoutTransition;
-import android.content.ContentUris;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.Message;
-import android.provider.ContactsContract.Contacts;
-import android.telephony.PhoneNumberUtils;
-import android.text.TextUtils;
-import android.text.format.DateUtils;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.Gravity;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewStub;
-import android.view.accessibility.AccessibilityEvent;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import com.android.internal.telephony.Call;
-import com.android.internal.telephony.CallManager;
-import com.android.internal.telephony.CallerInfo;
-import com.android.internal.telephony.CallerInfoAsyncQuery;
-import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConstants;
-
-import java.util.List;
-
-
-/**
- * "Call card" UI element: the in-call screen contains a tiled layout of call
- * cards, each representing the state of a current "call" (ie. an active call,
- * a call on hold, or an incoming call.)
- */
-public class CallCard extends LinearLayout
-        implements CallTime.OnTickListener, CallerInfoAsyncQuery.OnQueryCompleteListener,
-                   ContactsAsyncHelper.OnImageLoadCompleteListener {
-    private static final String LOG_TAG = "CallCard";
-    private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
-
-    private static final int TOKEN_UPDATE_PHOTO_FOR_CALL_STATE = 0;
-    private static final int TOKEN_DO_NOTHING = 1;
-
-    /**
-     * Used with {@link ContactsAsyncHelper#startObtainPhotoAsync(int, Context, Uri,
-     * ContactsAsyncHelper.OnImageLoadCompleteListener, Object)}
-     */
-    private static class AsyncLoadCookie {
-        public final ImageView imageView;
-        public final CallerInfo callerInfo;
-        public final Call call;
-        public AsyncLoadCookie(ImageView imageView, CallerInfo callerInfo, Call call) {
-            this.imageView = imageView;
-            this.callerInfo = callerInfo;
-            this.call = call;
-        }
-    }
-
-    /**
-     * 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 mApplication;
-
-    // Top-level subviews of the CallCard
-    /** Container for info about the current call(s) */
-    private ViewGroup mCallInfoContainer;
-    /** Primary "call info" block (the foreground or ringing call) */
-    private ViewGroup mPrimaryCallInfo;
-    /** "Call banner" for the primary call */
-    private ViewGroup mPrimaryCallBanner;
-    /** Secondary "call info" block (the background "on hold" call) */
-    private ViewStub mSecondaryCallInfo;
-
-
-    // "Call state" widgets
-    private TextView mCallStateLabel;
-    private TextView mElapsedTime;
-
-    // Text colors, used for various labels / titles
-    private int mTextColorCallTypeSip;
-
-    // The main block of info about the "primary" or "active" call,
-    // including photo / name / phone number / etc.
-    private ImageView mPhoto;
-    private View mPhotoDimEffect;
-
-    private TextView mName;
-    private TextView mPhoneNumber;
-    private TextView mLabel;
-    private TextView mCallTypeLabel;
-    // private TextView mSocialStatus;
-
-    /**
-     * Uri being used to load contact photo for mPhoto. Will be null when nothing is being loaded,
-     * or a photo is already loaded.
-     */
-    private Uri mLoadingPersonUri;
-
-    // Info about the "secondary" call, which is the "call on hold" when
-    // two lines are in use.
-    private TextView mSecondaryCallName;
-    private ImageView mSecondaryCallPhoto;
-    private View mSecondaryCallPhotoDimEffect;
-
-    // Onscreen hint for the incoming call RotarySelector widget.
-    private int mIncomingCallWidgetHintTextResId;
-    private int mIncomingCallWidgetHintColorResId;
-
-    private CallTime mCallTime;
-
-    // Track the state for the photo.
-    private ContactsAsyncHelper.ImageTracker mPhotoTracker;
-
-    // Cached DisplayMetrics density.
-    private float mDensity;
-
-    /**
-     * Sent when it takes too long (MESSAGE_DELAY msec) to load a contact photo for the given
-     * person, at which we just start showing the default avatar picture instead of the person's
-     * one. Note that we will *not* cancel the ongoing query and eventually replace the avatar
-     * with the person's photo, when it is available anyway.
-     */
-    private static final int MESSAGE_SHOW_UNKNOWN_PHOTO = 101;
-    private static final int MESSAGE_DELAY = 500; // msec
-    private final Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MESSAGE_SHOW_UNKNOWN_PHOTO:
-                    showImage(mPhoto, R.drawable.picture_unknown);
-                    break;
-                default:
-                    Log.wtf(LOG_TAG, "mHandler: unexpected message: " + msg);
-                    break;
-            }
-        }
-    };
-
-    public CallCard(Context context, AttributeSet attrs) {
-        super(context, attrs);
-
-        if (DBG) log("CallCard constructor...");
-        if (DBG) log("- this = " + this);
-        if (DBG) log("- context " + context + ", attrs " + attrs);
-
-        mApplication = PhoneGlobals.getInstance();
-
-        mCallTime = new CallTime(this);
-
-        // create a new object to track the state for the photo.
-        mPhotoTracker = new ContactsAsyncHelper.ImageTracker();
-
-        mDensity = getResources().getDisplayMetrics().density;
-        if (DBG) log("- Density: " + mDensity);
-    }
-
-    /* package */ void setInCallScreenInstance(InCallScreen inCallScreen) {
-        mInCallScreen = inCallScreen;
-    }
-
-    @Override
-    public void onTickForCallTimeElapsed(long timeElapsed) {
-        // While a call is in progress, update the elapsed time shown
-        // onscreen.
-        updateElapsedTimeWidget(timeElapsed);
-    }
-
-    /* package */ void stopTimer() {
-        mCallTime.cancelTimer();
-    }
-
-    @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
-
-        if (DBG) log("CallCard onFinishInflate(this = " + this + ")...");
-
-        mCallInfoContainer = (ViewGroup) findViewById(R.id.call_info_container);
-        mPrimaryCallInfo = (ViewGroup) findViewById(R.id.primary_call_info);
-        mPrimaryCallBanner = (ViewGroup) findViewById(R.id.primary_call_banner);
-
-        mCallStateLabel = (TextView) findViewById(R.id.callStateLabel);
-        mElapsedTime = (TextView) findViewById(R.id.elapsedTime);
-
-        // Text colors
-        mTextColorCallTypeSip = getResources().getColor(R.color.incall_callTypeSip);
-
-        // "Caller info" area, including photo / name / phone numbers / etc
-        mPhoto = (ImageView) findViewById(R.id.photo);
-        mPhotoDimEffect = findViewById(R.id.dim_effect_for_primary_photo);
-
-        mName = (TextView) findViewById(R.id.name);
-        mPhoneNumber = (TextView) findViewById(R.id.phoneNumber);
-        mLabel = (TextView) findViewById(R.id.label);
-        mCallTypeLabel = (TextView) findViewById(R.id.callTypeLabel);
-        // mSocialStatus = (TextView) findViewById(R.id.socialStatus);
-
-        // Secondary info area, for the background ("on hold") call
-        mSecondaryCallInfo = (ViewStub) findViewById(R.id.secondary_call_info);
-    }
-
-    /**
-     * Updates the state of all UI elements on the CallCard, based on the
-     * current state of the phone.
-     */
-    /* package */ void updateState(CallManager cm) {
-        if (DBG) log("updateState(" + cm + ")...");
-
-        // Update the onscreen UI based on the current state of the phone.
-
-        PhoneConstants.State state = cm.getState();  // IDLE, RINGING, or OFFHOOK
-        Call ringingCall = cm.getFirstActiveRingingCall();
-        Call fgCall = cm.getActiveFgCall();
-        Call bgCall = cm.getFirstActiveBgCall();
-
-        // Update the overall layout of the onscreen elements, if in PORTRAIT.
-        // Portrait uses a programatically altered layout, whereas landscape uses layout xml's.
-        // Landscape view has the views side by side, so no shifting of the picture is needed
-        if (!PhoneUtils.isLandscape(this.getContext())) {
-            updateCallInfoLayout(state);
-        }
-
-        // 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)
-                && !fgCall.getState().isDialing()) {
-            // A phone call is ringing, call waiting *or* being rejected
-            // (ie. another call may also be active as well.)
-            updateRingingCall(cm);
-        } else if ((fgCall.getState() != Call.State.IDLE)
-                || (bgCall.getState() != Call.State.IDLE)) {
-            // We are here because either:
-            // (1) the phone is off hook. At least one call exists that is
-            // dialing, active, or holding, and no calls are ringing or waiting,
-            // or:
-            // (2) the phone is IDLE but a call just ended and it's still in
-            // the DISCONNECTING or DISCONNECTED state. In this case, we want
-            // the main CallCard to display "Hanging up" or "Call ended".
-            // The normal "foreground call" code path handles both cases.
-            updateForegroundCall(cm);
-        } else {
-            // We don't have any DISCONNECTED calls, which means that the phone
-            // is *truly* idle.
-            if (mApplication.inCallUiState.showAlreadyDisconnectedState) {
-                // showAlreadyDisconnectedState implies the phone call is disconnected
-                // and we want to show the disconnected phone call for a moment.
-                //
-                // This happens when a phone call ends while the screen is off,
-                // which means the user had no chance to see the last status of
-                // the call. We'll turn off showAlreadyDisconnectedState flag
-                // and bail out of the in-call screen soon.
-                updateAlreadyDisconnected(cm);
-            } else {
-                // It's very rare to be on the InCallScreen at all in this
-                // state, but it can happen in some cases:
-                // - A stray onPhoneStateChanged() event came in to the
-                //   InCallScreen *after* it was dismissed.
-                // - We're allowed to be on the InCallScreen because
-                //   an MMI or USSD is running, but there's no actual "call"
-                //   to display.
-                // - We're displaying an error dialog to the user
-                //   (explaining why the call failed), so we need to stay on
-                //   the InCallScreen so that the dialog will be visible.
-                //
-                // In these cases, put the callcard into a sane but "blank" state:
-                updateNoCall(cm);
-            }
-        }
-    }
-
-    /**
-     * Updates the overall size and positioning of mCallInfoContainer and
-     * the "Call info" blocks, based on the phone state.
-     */
-    private void updateCallInfoLayout(PhoneConstants.State state) {
-        boolean ringing = (state == PhoneConstants.State.RINGING);
-        if (DBG) log("updateCallInfoLayout()...  ringing = " + ringing);
-
-        // Based on the current state, update the overall
-        // CallCard layout:
-
-        // - Update the bottom margin of mCallInfoContainer to make sure
-        //   the call info area won't overlap with the touchable
-        //   controls on the bottom part of the screen.
-
-        int reservedVerticalSpace = mInCallScreen.getInCallTouchUi().getTouchUiHeight();
-        ViewGroup.MarginLayoutParams callInfoLp =
-                (ViewGroup.MarginLayoutParams) mCallInfoContainer.getLayoutParams();
-        callInfoLp.bottomMargin = reservedVerticalSpace;  // Equivalent to setting
-                                                          // android:layout_marginBottom in XML
-        if (DBG) log("  ==> callInfoLp.bottomMargin: " + reservedVerticalSpace);
-        mCallInfoContainer.setLayoutParams(callInfoLp);
-    }
-
-    /**
-     * Updates the UI for the state where the phone is in use, but not ringing.
-     */
-    private void updateForegroundCall(CallManager cm) {
-        if (DBG) log("updateForegroundCall()...");
-        // if (DBG) PhoneUtils.dumpCallManager();
-
-        Call fgCall = cm.getActiveFgCall();
-        Call bgCall = cm.getFirstActiveBgCall();
-
-        if (fgCall.getState() == Call.State.IDLE) {
-            if (DBG) log("updateForegroundCall: no active call, show holding call");
-            // TODO: make sure this case agrees with the latest UI spec.
-
-            // Display the background call in the main info area of the
-            // CallCard, since there is no foreground call.  Note that
-            // displayMainCallStatus() will notice if the call we passed in is on
-            // hold, and display the "on hold" indication.
-            fgCall = bgCall;
-
-            // And be sure to not display anything in the "on hold" box.
-            bgCall = null;
-        }
-
-        displayMainCallStatus(cm, fgCall);
-
-        Phone phone = fgCall.getPhone();
-
-        int phoneType = phone.getPhoneType();
-        if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-            if ((mApplication.cdmaPhoneCallState.getCurrentCallState()
-                    == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE)
-                    && mApplication.cdmaPhoneCallState.IsThreeWayCallOrigStateDialing()) {
-                displaySecondaryCallStatus(cm, fgCall);
-            } else {
-                //This is required so that even if a background call is not present
-                // we need to clean up the background call area.
-                displaySecondaryCallStatus(cm, bgCall);
-            }
-        } else if ((phoneType == PhoneConstants.PHONE_TYPE_GSM)
-                || (phoneType == PhoneConstants.PHONE_TYPE_SIP)) {
-            displaySecondaryCallStatus(cm, bgCall);
-        }
-    }
-
-    /**
-     * Updates the UI for the state where an incoming call is ringing (or
-     * call waiting), regardless of whether the phone's already offhook.
-     */
-    private void updateRingingCall(CallManager cm) {
-        if (DBG) log("updateRingingCall()...");
-
-        Call ringingCall = cm.getFirstActiveRingingCall();
-
-        // Display caller-id info and photo from the incoming call:
-        displayMainCallStatus(cm, ringingCall);
-
-        // And even in the Call Waiting case, *don't* show any info about
-        // the current ongoing call and/or the current call on hold.
-        // (Since the caller-id info for the incoming call totally trumps
-        // any info about the current call(s) in progress.)
-        displaySecondaryCallStatus(cm, null);
-    }
-
-    /**
-     * Updates the UI for the state where an incoming call is just disconnected while we want to
-     * show the screen for a moment.
-     *
-     * This case happens when the whole in-call screen is in background when phone calls are hanged
-     * up, which means there's no way to determine which call was the last call finished. Right now
-     * this method simply shows the previous primary call status with a photo, closing the
-     * secondary call status. In most cases (including conference call or misc call happening in
-     * CDMA) this behaves right.
-     *
-     * If there were two phone calls both of which were hung up but the primary call was the
-     * first, this would behave a bit odd (since the first one still appears as the
-     * "last disconnected").
-     */
-    private void updateAlreadyDisconnected(CallManager cm) {
-        // For the foreground call, we manually set up every component based on previous state.
-        mPrimaryCallInfo.setVisibility(View.VISIBLE);
-        mCallStateLabel.setVisibility(View.VISIBLE);
-        mCallStateLabel.setText(mContext.getString(R.string.card_title_call_ended));
-        mElapsedTime.setVisibility(View.VISIBLE);
-        mCallTime.cancelTimer();
-
-        // Just hide it.
-        displaySecondaryCallStatus(cm, null);
-    }
-
-    /**
-     * Updates the UI for the state where the phone is not in use.
-     * This is analogous to updateForegroundCall() and updateRingingCall(),
-     * but for the (uncommon) case where the phone is
-     * totally idle.  (See comments in updateState() above.)
-     *
-     * This puts the callcard into a sane but "blank" state.
-     */
-    private void updateNoCall(CallManager cm) {
-        if (DBG) log("updateNoCall()...");
-
-        displayMainCallStatus(cm, null);
-        displaySecondaryCallStatus(cm, null);
-    }
-
-    /**
-     * Updates the main block of caller info on the CallCard
-     * (ie. the stuff in the primaryCallInfo block) based on the specified Call.
-     */
-    private void displayMainCallStatus(CallManager cm, Call call) {
-        if (DBG) log("displayMainCallStatus(call " + call + ")...");
-
-        if (call == null) {
-            // There's no call to display, presumably because the phone is idle.
-            mPrimaryCallInfo.setVisibility(View.GONE);
-            return;
-        }
-        mPrimaryCallInfo.setVisibility(View.VISIBLE);
-
-        Call.State state = call.getState();
-        if (DBG) log("  - call.state: " + call.getState());
-
-        switch (state) {
-            case ACTIVE:
-            case DISCONNECTING:
-                // update timer field
-                if (DBG) log("displayMainCallStatus: start periodicUpdateTimer");
-                mCallTime.setActiveCallMode(call);
-                mCallTime.reset();
-                mCallTime.periodicUpdateTimer();
-
-                break;
-
-            case HOLDING:
-                // update timer field
-                mCallTime.cancelTimer();
-
-                break;
-
-            case DISCONNECTED:
-                // Stop getting timer ticks from this call
-                mCallTime.cancelTimer();
-
-                break;
-
-            case DIALING:
-            case ALERTING:
-                // Stop getting timer ticks from a previous call
-                mCallTime.cancelTimer();
-
-                break;
-
-            case INCOMING:
-            case WAITING:
-                // Stop getting timer ticks from a previous call
-                mCallTime.cancelTimer();
-
-                break;
-
-            case IDLE:
-                // The "main CallCard" should never be trying to display
-                // an idle call!  In updateState(), if the phone is idle,
-                // we call updateNoCall(), which means that we shouldn't
-                // have passed a call into this method at all.
-                Log.w(LOG_TAG, "displayMainCallStatus: IDLE call in the main call card!");
-
-                // (It is possible, though, that we had a valid call which
-                // became idle *after* the check in updateState() but
-                // before we get here...  So continue the best we can,
-                // with whatever (stale) info we can get from the
-                // passed-in Call object.)
-
-                break;
-
-            default:
-                Log.w(LOG_TAG, "displayMainCallStatus: unexpected call state: " + state);
-                break;
-        }
-
-        updateCallStateWidgets(call);
-
-        if (PhoneUtils.isConferenceCall(call)) {
-            // Update onscreen info for a conference call.
-            updateDisplayForConference(call);
-        } else {
-            // Update onscreen info for a regular call (which presumably
-            // has only one connection.)
-            Connection conn = null;
-            int phoneType = call.getPhone().getPhoneType();
-            if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-                conn = call.getLatestConnection();
-            } else if ((phoneType == PhoneConstants.PHONE_TYPE_GSM)
-                  || (phoneType == PhoneConstants.PHONE_TYPE_SIP)) {
-                conn = call.getEarliestConnection();
-            } else {
-                throw new IllegalStateException("Unexpected phone type: " + phoneType);
-            }
-
-            if (conn == null) {
-                if (DBG) log("displayMainCallStatus: connection is null, using default values.");
-                // if the connection is null, we run through the behaviour
-                // we had in the past, which breaks down into trivial steps
-                // with the current implementation of getCallerInfo and
-                // updateDisplayForPerson.
-                CallerInfo info = PhoneUtils.getCallerInfo(getContext(), null /* conn */);
-                updateDisplayForPerson(info, PhoneConstants.PRESENTATION_ALLOWED, false, call,
-                        conn);
-            } else {
-                if (DBG) log("  - CONN: " + conn + ", state = " + conn.getState());
-                int presentation = conn.getNumberPresentation();
-
-                // make sure that we only make a new query when the current
-                // callerinfo differs from what we've been requested to display.
-                boolean runQuery = true;
-                Object o = conn.getUserData();
-                if (o instanceof PhoneUtils.CallerInfoToken) {
-                    runQuery = mPhotoTracker.isDifferentImageRequest(
-                            ((PhoneUtils.CallerInfoToken) o).currentInfo);
-                } else {
-                    runQuery = mPhotoTracker.isDifferentImageRequest(conn);
-                }
-
-                // Adding a check to see if the update was caused due to a Phone number update
-                // or CNAP update. If so then we need to start a new query
-                if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-                    Object obj = conn.getUserData();
-                    String updatedNumber = conn.getAddress();
-                    String updatedCnapName = conn.getCnapName();
-                    CallerInfo info = null;
-                    if (obj instanceof PhoneUtils.CallerInfoToken) {
-                        info = ((PhoneUtils.CallerInfoToken) o).currentInfo;
-                    } else if (o instanceof CallerInfo) {
-                        info = (CallerInfo) o;
-                    }
-
-                    if (info != null) {
-                        if (updatedNumber != null && !updatedNumber.equals(info.phoneNumber)) {
-                            if (DBG) log("- displayMainCallStatus: updatedNumber = "
-                                    + updatedNumber);
-                            runQuery = true;
-                        }
-                        if (updatedCnapName != null && !updatedCnapName.equals(info.cnapName)) {
-                            if (DBG) log("- displayMainCallStatus: updatedCnapName = "
-                                    + updatedCnapName);
-                            runQuery = true;
-                        }
-                    }
-                }
-
-                if (runQuery) {
-                    if (DBG) log("- displayMainCallStatus: starting CallerInfo query...");
-                    PhoneUtils.CallerInfoToken info =
-                            PhoneUtils.startGetCallerInfo(getContext(), conn, this, call);
-                    updateDisplayForPerson(info.currentInfo, presentation, !info.isFinal,
-                                           call, conn);
-                } else {
-                    // No need to fire off a new query.  We do still need
-                    // to update the display, though (since we might have
-                    // previously been in the "conference call" state.)
-                    if (DBG) log("- displayMainCallStatus: using data we already have...");
-                    if (o instanceof CallerInfo) {
-                        CallerInfo ci = (CallerInfo) o;
-                        // Update CNAP information if Phone state change occurred
-                        ci.cnapName = conn.getCnapName();
-                        ci.numberPresentation = conn.getNumberPresentation();
-                        ci.namePresentation = conn.getCnapNamePresentation();
-                        if (DBG) log("- displayMainCallStatus: CNAP data from Connection: "
-                                + "CNAP name=" + ci.cnapName
-                                + ", Number/Name Presentation=" + ci.numberPresentation);
-                        if (DBG) log("   ==> Got CallerInfo; updating display: ci = " + ci);
-                        updateDisplayForPerson(ci, presentation, false, call, conn);
-                    } else if (o instanceof PhoneUtils.CallerInfoToken){
-                        CallerInfo ci = ((PhoneUtils.CallerInfoToken) o).currentInfo;
-                        if (DBG) log("- displayMainCallStatus: CNAP data from Connection: "
-                                + "CNAP name=" + ci.cnapName
-                                + ", Number/Name Presentation=" + ci.numberPresentation);
-                        if (DBG) log("   ==> Got CallerInfoToken; updating display: ci = " + ci);
-                        updateDisplayForPerson(ci, presentation, true, call, conn);
-                    } else {
-                        Log.w(LOG_TAG, "displayMainCallStatus: runQuery was false, "
-                              + "but we didn't have a cached CallerInfo object!  o = " + o);
-                        // TODO: any easy way to recover here (given that
-                        // the CallCard is probably displaying stale info
-                        // right now?)  Maybe force the CallCard into the
-                        // "Unknown" state?
-                    }
-                }
-            }
-        }
-
-        // In some states we override the "photo" ImageView to be an
-        // indication of the current state, rather than displaying the
-        // regular photo as set above.
-        updatePhotoForCallState(call);
-
-        // One special feature of the "number" text field: For incoming
-        // calls, while the user is dragging the RotarySelector widget, we
-        // use mPhoneNumber to display a hint like "Rotate to answer".
-        if (mIncomingCallWidgetHintTextResId != 0) {
-            // Display the hint!
-            mPhoneNumber.setText(mIncomingCallWidgetHintTextResId);
-            mPhoneNumber.setTextColor(getResources().getColor(mIncomingCallWidgetHintColorResId));
-            mPhoneNumber.setVisibility(View.VISIBLE);
-            mLabel.setVisibility(View.GONE);
-        }
-        // If we don't have a hint to display, just don't touch
-        // mPhoneNumber and mLabel. (Their text / color / visibility have
-        // already been set correctly, by either updateDisplayForPerson()
-        // or updateDisplayForConference().)
-    }
-
-    /**
-     * Implemented for CallerInfoAsyncQuery.OnQueryCompleteListener interface.
-     * refreshes the CallCard data when it called.
-     */
-    @Override
-    public void onQueryComplete(int token, Object cookie, CallerInfo ci) {
-        if (DBG) log("onQueryComplete: token " + token + ", cookie " + cookie + ", ci " + ci);
-
-        if (cookie instanceof Call) {
-            // grab the call object and update the display for an individual call,
-            // as well as the successive call to update image via call state.
-            // If the object is a textview instead, we update it as we need to.
-            if (DBG) log("callerinfo query complete, updating ui from displayMainCallStatus()");
-            Call call = (Call) cookie;
-            Connection conn = null;
-            int phoneType = call.getPhone().getPhoneType();
-            if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-                conn = call.getLatestConnection();
-            } else if ((phoneType == PhoneConstants.PHONE_TYPE_GSM)
-                  || (phoneType == PhoneConstants.PHONE_TYPE_SIP)) {
-                conn = call.getEarliestConnection();
-            } else {
-                throw new IllegalStateException("Unexpected phone type: " + phoneType);
-            }
-            PhoneUtils.CallerInfoToken cit =
-                   PhoneUtils.startGetCallerInfo(getContext(), conn, this, null);
-
-            int presentation = PhoneConstants.PRESENTATION_ALLOWED;
-            if (conn != null) presentation = conn.getNumberPresentation();
-            if (DBG) log("- onQueryComplete: presentation=" + presentation
-                    + ", contactExists=" + ci.contactExists);
-
-            // Depending on whether there was a contact match or not, we want to pass in different
-            // CallerInfo (for CNAP). Therefore if ci.contactExists then use the ci passed in.
-            // Otherwise, regenerate the CIT from the Connection and use the CallerInfo from there.
-            if (ci.contactExists) {
-                updateDisplayForPerson(ci, PhoneConstants.PRESENTATION_ALLOWED, false, call, conn);
-            } else {
-                updateDisplayForPerson(cit.currentInfo, presentation, false, call, conn);
-            }
-            updatePhotoForCallState(call);
-
-        } else if (cookie instanceof TextView){
-            if (DBG) log("callerinfo query complete, updating ui from ongoing or onhold");
-            ((TextView) cookie).setText(PhoneUtils.getCompactNameFromCallerInfo(ci, mContext));
-        }
-    }
-
-    /**
-     * Implemented for ContactsAsyncHelper.OnImageLoadCompleteListener interface.
-     * make sure that the call state is reflected after the image is loaded.
-     */
-    @Override
-    public void onImageLoadComplete(int token, Drawable photo, Bitmap photoIcon, Object cookie) {
-        mHandler.removeMessages(MESSAGE_SHOW_UNKNOWN_PHOTO);
-        if (mLoadingPersonUri != null) {
-            // Start sending view notification after the current request being done.
-            // New image may possibly be available from the next phone calls.
-            //
-            // TODO: may be nice to update the image view again once the newer one
-            // is available on contacts database.
-            PhoneUtils.sendViewNotificationAsync(mApplication, mLoadingPersonUri);
-        } else {
-            // This should not happen while we need some verbose info if it happens..
-            Log.w(LOG_TAG, "Person Uri isn't available while Image is successfully loaded.");
-        }
-        mLoadingPersonUri = null;
-
-        AsyncLoadCookie asyncLoadCookie = (AsyncLoadCookie) cookie;
-        CallerInfo callerInfo = asyncLoadCookie.callerInfo;
-        ImageView imageView = asyncLoadCookie.imageView;
-        Call call = asyncLoadCookie.call;
-
-        callerInfo.cachedPhoto = photo;
-        callerInfo.cachedPhotoIcon = photoIcon;
-        callerInfo.isCachedPhotoCurrent = true;
-
-        // Note: previously ContactsAsyncHelper has done this job.
-        // TODO: We will need fade-in animation. See issue 5236130.
-        if (photo != null) {
-            showImage(imageView, photo);
-        } else if (photoIcon != null) {
-            showImage(imageView, photoIcon);
-        } else {
-            showImage(imageView, R.drawable.picture_unknown);
-        }
-
-        if (token == TOKEN_UPDATE_PHOTO_FOR_CALL_STATE) {
-            updatePhotoForCallState(call);
-        }
-    }
-
-    /**
-     * Updates the "call state label" and the elapsed time widget based on the
-     * current state of the call.
-     */
-    private void updateCallStateWidgets(Call call) {
-        if (DBG) log("updateCallStateWidgets(call " + call + ")...");
-        final Call.State state = call.getState();
-        final Context context = getContext();
-        final Phone phone = call.getPhone();
-        final int phoneType = phone.getPhoneType();
-
-        String callStateLabel = null;  // Label to display as part of the call banner
-        int bluetoothIconId = 0;  // Icon to display alongside the call state label
-
-        switch (state) {
-            case IDLE:
-                // "Call state" is meaningless in this state.
-                break;
-
-            case ACTIVE:
-                // We normally don't show a "call state label" at all in
-                // this state (but see below for some special cases).
-                break;
-
-            case HOLDING:
-                callStateLabel = context.getString(R.string.card_title_on_hold);
-                break;
-
-            case DIALING:
-            case ALERTING:
-                callStateLabel = context.getString(R.string.card_title_dialing);
-                break;
-
-            case INCOMING:
-            case WAITING:
-                callStateLabel = context.getString(R.string.card_title_incoming_call);
-                break;
-
-            case DISCONNECTING:
-                // While in the DISCONNECTING state we display a "Hanging up"
-                // message in order to make the UI feel more responsive.  (In
-                // GSM it's normal to see a delay of a couple of seconds while
-                // negotiating the disconnect with the network, so the "Hanging
-                // up" state at least lets the user know that we're doing
-                // something.  This state is currently not used with CDMA.)
-                callStateLabel = context.getString(R.string.card_title_hanging_up);
-                break;
-
-            case DISCONNECTED:
-                callStateLabel = getCallFailedString(call);
-                break;
-
-            default:
-                Log.wtf(LOG_TAG, "updateCallStateWidgets: unexpected call state: " + state);
-                break;
-        }
-
-        // Check a couple of other special cases (these are all CDMA-specific).
-
-        // TODO(klp): This code should go into the CallModeler logic instead of the UI.
-        if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-            if ((state == Call.State.ACTIVE)
-                && mApplication.cdmaPhoneCallState.IsThreeWayCallOrigStateDialing()) {
-                // Display "Dialing" while dialing a 3Way call, even
-                // though the foreground call state is actually ACTIVE.
-                callStateLabel = context.getString(R.string.card_title_dialing);
-            } else if (PhoneGlobals.getInstance().notifier.getIsCdmaRedialCall()) {
-                callStateLabel = context.getString(R.string.card_title_redialing);
-            }
-        }
-        if (PhoneUtils.isPhoneInEcm(phone)) {
-            // In emergency callback mode (ECM), use a special label
-            // that shows your own phone number.
-            callStateLabel = getECMCardTitle(context, phone);
-        }
-
-        final InCallUiState inCallUiState = mApplication.inCallUiState;
-        if (DBG) {
-            log("==> callStateLabel: '" + callStateLabel
-                    + "', bluetoothIconId = " + bluetoothIconId);
-        }
-
-        // Animation will be done by mCallerDetail's LayoutTransition, but in some cases, we don't
-        // want that.
-        // - DIALING: This is at the beginning of the phone call.
-        // - DISCONNECTING, DISCONNECTED: Screen will disappear soon; we have no time for animation.
-        final boolean skipAnimation = (state == Call.State.DIALING
-                || state == Call.State.DISCONNECTING
-                || state == Call.State.DISCONNECTED);
-        LayoutTransition layoutTransition = null;
-
-        if (!TextUtils.isEmpty(callStateLabel)) {
-            mCallStateLabel.setVisibility(View.VISIBLE);
-            mCallStateLabel.setText(callStateLabel);
-
-            // ...and display the icon too if necessary.
-            if (bluetoothIconId != 0) {
-                mCallStateLabel.setCompoundDrawablesWithIntrinsicBounds(bluetoothIconId, 0, 0, 0);
-                mCallStateLabel.setCompoundDrawablePadding((int) (mDensity * 5));
-            } else {
-                // Clear out any icons
-                mCallStateLabel.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
-            }
-        } else {
-            mCallStateLabel.setVisibility(View.GONE);
-            // Gravity is aligned left when receiving an incoming call in landscape.
-            // In that rare case, the gravity needs to be reset to the right.
-            // Also, setText("") is used since there is a delay in making the view GONE,
-            // so the user will otherwise see the text jump to the right side before disappearing.
-            if(mCallStateLabel.getGravity() != Gravity.END) {
-                mCallStateLabel.setText("");
-                mCallStateLabel.setGravity(Gravity.END);
-            }
-        }
-
-        // ...and update the elapsed time widget too.
-        switch (state) {
-            case ACTIVE:
-            case DISCONNECTING:
-                // Show the time with fade-in animation.
-                AnimationUtils.Fade.show(mElapsedTime);
-                updateElapsedTimeWidget(call);
-                break;
-
-            case DISCONNECTED:
-                // In the "Call ended" state, leave the mElapsedTime widget
-                // visible, but don't touch it (so we continue to see the
-                // elapsed time of the call that just ended.)
-                // Check visibility to keep possible fade-in animation.
-                if (mElapsedTime.getVisibility() != View.VISIBLE) {
-                    mElapsedTime.setVisibility(View.VISIBLE);
-                }
-                break;
-
-            default:
-                // Call state here is IDLE, ACTIVE, HOLDING, DIALING, ALERTING,
-                // INCOMING, or WAITING.
-                // In all of these states, the "elapsed time" is meaningless, so
-                // don't show it.
-                AnimationUtils.Fade.hide(mElapsedTime, View.INVISIBLE);
-
-                // Additionally, in call states that can only occur at the start
-                // of a call, reset the elapsed time to be sure we won't display
-                // stale info later (like if we somehow go straight from DIALING
-                // or ALERTING to DISCONNECTED, which can actually happen in
-                // some failure cases like "line busy").
-                if ((state ==  Call.State.DIALING) || (state == Call.State.ALERTING)) {
-                    updateElapsedTimeWidget(0);
-                }
-
-                break;
-        }
-    }
-
-    /**
-     * Updates mElapsedTime based on the given {@link Call} object's information.
-     *
-     * @see CallTime#getCallDuration(Call)
-     * @see Connection#getDurationMillis()
-     */
-    /* package */ void updateElapsedTimeWidget(Call call) {
-        long duration = CallTime.getCallDuration(call);  // msec
-        updateElapsedTimeWidget(duration / 1000);
-        // Also see onTickForCallTimeElapsed(), which updates this
-        // widget once per second while the call is active.
-    }
-
-    /**
-     * Updates mElapsedTime based on the specified number of seconds.
-     */
-    private void updateElapsedTimeWidget(long timeElapsed) {
-        // if (DBG) log("updateElapsedTimeWidget: " + timeElapsed);
-        mElapsedTime.setText(DateUtils.formatElapsedTime(timeElapsed));
-    }
-
-    /**
-     * Updates the "on hold" box in the "other call" info area
-     * (ie. the stuff in the secondaryCallInfo block)
-     * based on the specified Call.
-     * Or, clear out the "on hold" box if the specified call
-     * is null or idle.
-     */
-    private void displaySecondaryCallStatus(CallManager cm, Call call) {
-        if (DBG) log("displayOnHoldCallStatus(call =" + call + ")...");
-
-        if ((call == null) || (PhoneGlobals.getInstance().isOtaCallInActiveState())) {
-            mSecondaryCallInfo.setVisibility(View.GONE);
-            return;
-        }
-
-        Call.State state = call.getState();
-        switch (state) {
-            case HOLDING:
-                // Ok, there actually is a background call on hold.
-                // Display the "on hold" box.
-
-                // Note this case occurs only on GSM devices.  (On CDMA,
-                // the "call on hold" is actually the 2nd connection of
-                // that ACTIVE call; see the ACTIVE case below.)
-                showSecondaryCallInfo();
-
-                if (PhoneUtils.isConferenceCall(call)) {
-                    if (DBG) log("==> conference call.");
-                    mSecondaryCallName.setText(getContext().getString(R.string.confCall));
-                    showImage(mSecondaryCallPhoto, R.drawable.picture_conference);
-                } else {
-                    // perform query and update the name temporarily
-                    // make sure we hand the textview we want updated to the
-                    // callback function.
-                    if (DBG) log("==> NOT a conf call; call startGetCallerInfo...");
-                    PhoneUtils.CallerInfoToken infoToken = PhoneUtils.startGetCallerInfo(
-                            getContext(), call, this, mSecondaryCallName);
-                    mSecondaryCallName.setText(
-                            PhoneUtils.getCompactNameFromCallerInfo(infoToken.currentInfo,
-                                                                    getContext()));
-
-                    // Also pull the photo out of the current CallerInfo.
-                    // (Note we assume we already have a valid photo at
-                    // this point, since *presumably* the caller-id query
-                    // was already run at some point *before* this call
-                    // got put on hold.  If there's no cached photo, just
-                    // fall back to the default "unknown" image.)
-                    if (infoToken.isFinal) {
-                        showCachedImage(mSecondaryCallPhoto, infoToken.currentInfo);
-                    } else {
-                        showImage(mSecondaryCallPhoto, R.drawable.picture_unknown);
-                    }
-                }
-
-                AnimationUtils.Fade.show(mSecondaryCallPhotoDimEffect);
-                break;
-
-            case ACTIVE:
-                // CDMA: This is because in CDMA when the user originates the second call,
-                // although the Foreground call state is still ACTIVE in reality the network
-                // put the first call on hold.
-                if (mApplication.phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
-                    showSecondaryCallInfo();
-
-                    List<Connection> connections = call.getConnections();
-                    if (connections.size() > 2) {
-                        // This means that current Mobile Originated call is the not the first 3-Way
-                        // call the user is making, which in turn tells the PhoneGlobals that we no
-                        // longer know which previous caller/party had dropped out before the user
-                        // made this call.
-                        mSecondaryCallName.setText(
-                                getContext().getString(R.string.card_title_in_call));
-                        showImage(mSecondaryCallPhoto, R.drawable.picture_unknown);
-                    } else {
-                        // This means that the current Mobile Originated call IS the first 3-Way
-                        // and hence we display the first callers/party's info here.
-                        Connection conn = call.getEarliestConnection();
-                        PhoneUtils.CallerInfoToken infoToken = PhoneUtils.startGetCallerInfo(
-                                getContext(), conn, this, mSecondaryCallName);
-
-                        // Get the compactName to be displayed, but then check that against
-                        // the number presentation value for the call. If it's not an allowed
-                        // presentation, then display the appropriate presentation string instead.
-                        CallerInfo info = infoToken.currentInfo;
-
-                        String name = PhoneUtils.getCompactNameFromCallerInfo(info, getContext());
-                        boolean forceGenericPhoto = false;
-                        if (info != null && info.numberPresentation !=
-                                PhoneConstants.PRESENTATION_ALLOWED) {
-                            name = PhoneUtils.getPresentationString(
-                                    getContext(), info.numberPresentation);
-                            forceGenericPhoto = true;
-                        }
-                        mSecondaryCallName.setText(name);
-
-                        // Also pull the photo out of the current CallerInfo.
-                        // (Note we assume we already have a valid photo at
-                        // this point, since *presumably* the caller-id query
-                        // was already run at some point *before* this call
-                        // got put on hold.  If there's no cached photo, just
-                        // fall back to the default "unknown" image.)
-                        if (!forceGenericPhoto && infoToken.isFinal) {
-                            showCachedImage(mSecondaryCallPhoto, info);
-                        } else {
-                            showImage(mSecondaryCallPhoto, R.drawable.picture_unknown);
-                        }
-                    }
-                } else {
-                    // We shouldn't ever get here at all for non-CDMA devices.
-                    Log.w(LOG_TAG, "displayOnHoldCallStatus: ACTIVE state on non-CDMA device");
-                    mSecondaryCallInfo.setVisibility(View.GONE);
-                }
-
-                AnimationUtils.Fade.hide(mSecondaryCallPhotoDimEffect, View.GONE);
-                break;
-
-            default:
-                // There's actually no call on hold.  (Presumably this call's
-                // state is IDLE, since any other state is meaningless for the
-                // background call.)
-                mSecondaryCallInfo.setVisibility(View.GONE);
-                break;
-        }
-    }
-
-    private void showSecondaryCallInfo() {
-        // This will call ViewStub#inflate() when needed.
-        mSecondaryCallInfo.setVisibility(View.VISIBLE);
-        if (mSecondaryCallName == null) {
-            mSecondaryCallName = (TextView) findViewById(R.id.secondaryCallName);
-        }
-        if (mSecondaryCallPhoto == null) {
-            mSecondaryCallPhoto = (ImageView) findViewById(R.id.secondaryCallPhoto);
-        }
-        if (mSecondaryCallPhotoDimEffect == null) {
-            mSecondaryCallPhotoDimEffect = findViewById(R.id.dim_effect_for_secondary_photo);
-            mSecondaryCallPhotoDimEffect.setOnClickListener(mInCallScreen);
-            // Add a custom OnTouchListener to manually shrink the "hit target".
-            mSecondaryCallPhotoDimEffect.setOnTouchListener(new SmallerHitTargetTouchListener());
-        }
-        mInCallScreen.updateButtonStateOutsideInCallTouchUi();
-    }
-
-    /**
-     * Method which is expected to be called from
-     * {@link InCallScreen#updateButtonStateOutsideInCallTouchUi()}.
-     */
-    /* package */ void setSecondaryCallClickable(boolean clickable) {
-        if (mSecondaryCallPhotoDimEffect != null) {
-            mSecondaryCallPhotoDimEffect.setEnabled(clickable);
-        }
-    }
-
-    private String getCallFailedString(Call call) {
-        Connection c = call.getEarliestConnection();
-        int resID;
-
-        if (c == null) {
-            if (DBG) log("getCallFailedString: connection is null, using default values.");
-            // if this connection is null, just assume that the
-            // default case occurs.
-            resID = R.string.card_title_call_ended;
-        } else {
-
-            Connection.DisconnectCause cause = c.getDisconnectCause();
-
-            // TODO: The card *title* should probably be "Call ended" in all
-            // cases, but if the DisconnectCause was an error condition we should
-            // probably also display the specific failure reason somewhere...
-
-            switch (cause) {
-                case BUSY:
-                    resID = R.string.callFailed_userBusy;
-                    break;
-
-                case CONGESTION:
-                    resID = R.string.callFailed_congestion;
-                    break;
-
-                case TIMED_OUT:
-                    resID = R.string.callFailed_timedOut;
-                    break;
-
-                case SERVER_UNREACHABLE:
-                    resID = R.string.callFailed_server_unreachable;
-                    break;
-
-                case NUMBER_UNREACHABLE:
-                    resID = R.string.callFailed_number_unreachable;
-                    break;
-
-                case INVALID_CREDENTIALS:
-                    resID = R.string.callFailed_invalid_credentials;
-                    break;
-
-                case SERVER_ERROR:
-                    resID = R.string.callFailed_server_error;
-                    break;
-
-                case OUT_OF_NETWORK:
-                    resID = R.string.callFailed_out_of_network;
-                    break;
-
-                case LOST_SIGNAL:
-                case CDMA_DROP:
-                    resID = R.string.callFailed_noSignal;
-                    break;
-
-                case LIMIT_EXCEEDED:
-                    resID = R.string.callFailed_limitExceeded;
-                    break;
-
-                case POWER_OFF:
-                    resID = R.string.callFailed_powerOff;
-                    break;
-
-                case ICC_ERROR:
-                    resID = R.string.callFailed_simError;
-                    break;
-
-                case OUT_OF_SERVICE:
-                    resID = R.string.callFailed_outOfService;
-                    break;
-
-                case INVALID_NUMBER:
-                case UNOBTAINABLE_NUMBER:
-                    resID = R.string.callFailed_unobtainable_number;
-                    break;
-
-                default:
-                    resID = R.string.card_title_call_ended;
-                    break;
-            }
-        }
-        return getContext().getString(resID);
-    }
-
-    /**
-     * Updates the name / photo / number / label fields on the CallCard
-     * based on the specified CallerInfo.
-     *
-     * If the current call is a conference call, use
-     * updateDisplayForConference() instead.
-     */
-    private void updateDisplayForPerson(CallerInfo info,
-                                        int presentation,
-                                        boolean isTemporary,
-                                        Call call,
-                                        Connection conn) {
-        if (DBG) log("updateDisplayForPerson(" + info + ")\npresentation:" +
-                     presentation + " isTemporary:" + isTemporary);
-
-        // inform the state machine that we are displaying a photo.
-        mPhotoTracker.setPhotoRequest(info);
-        mPhotoTracker.setPhotoState(ContactsAsyncHelper.ImageTracker.DISPLAY_IMAGE);
-
-        // The actual strings we're going to display onscreen:
-        String displayName;
-        String displayNumber = null;
-        String label = null;
-        Uri personUri = null;
-        // String socialStatusText = null;
-        // Drawable socialStatusBadge = null;
-
-        // Gather missing info unless the call is generic, in which case we wouldn't use
-        // the gathered information anyway.
-        if (info != null && !call.isGeneric()) {
-
-            // It appears that there is a small change in behaviour with the
-            // PhoneUtils' startGetCallerInfo whereby if we query with an
-            // empty number, we will get a valid CallerInfo object, but with
-            // fields that are all null, and the isTemporary boolean input
-            // parameter as true.
-
-            // In the past, we would see a NULL callerinfo object, but this
-            // ends up causing null pointer exceptions elsewhere down the
-            // line in other cases, so we need to make this fix instead. It
-            // appears that this was the ONLY call to PhoneUtils
-            // .getCallerInfo() that relied on a NULL CallerInfo to indicate
-            // an unknown contact.
-
-            // Currently, infi.phoneNumber may actually be a SIP address, and
-            // if so, it might sometimes include the "sip:" prefix.  That
-            // prefix isn't really useful to the user, though, so strip it off
-            // if present.  (For any other URI scheme, though, leave the
-            // prefix alone.)
-            // TODO: It would be cleaner for CallerInfo to explicitly support
-            // SIP addresses instead of overloading the "phoneNumber" field.
-            // Then we could remove this hack, and instead ask the CallerInfo
-            // for a "user visible" form of the SIP address.
-            String number = info.phoneNumber;
-            if ((number != null) && number.startsWith("sip:")) {
-                number = number.substring(4);
-            }
-
-            if (TextUtils.isEmpty(info.name)) {
-                // No valid "name" in the CallerInfo, so fall back to
-                // something else.
-                // (Typically, we promote the phone number up to the "name" slot
-                // onscreen, and possibly display a descriptive string in the
-                // "number" slot.)
-                if (TextUtils.isEmpty(number)) {
-                    // No name *or* number!  Display a generic "unknown" string
-                    // (or potentially some other default based on the presentation.)
-                    displayName = PhoneUtils.getPresentationString(getContext(), presentation);
-                    if (DBG) log("  ==> no name *or* number! displayName = " + displayName);
-                } else if (presentation != PhoneConstants.PRESENTATION_ALLOWED) {
-                    // This case should never happen since the network should never send a phone #
-                    // AND a restricted presentation. However we leave it here in case of weird
-                    // network behavior
-                    displayName = PhoneUtils.getPresentationString(getContext(), presentation);
-                    if (DBG) log("  ==> presentation not allowed! displayName = " + displayName);
-                } else if (!TextUtils.isEmpty(info.cnapName)) {
-                    // No name, but we do have a valid CNAP name, so use that.
-                    displayName = info.cnapName;
-                    info.name = info.cnapName;
-                    displayNumber = number;
-                    if (DBG) log("  ==> cnapName available: displayName '"
-                                 + displayName + "', displayNumber '" + displayNumber + "'");
-                } else {
-                    // No name; all we have is a number.  This is the typical
-                    // case when an incoming call doesn't match any contact,
-                    // or if you manually dial an outgoing number using the
-                    // dialpad.
-
-                    // Promote the phone number up to the "name" slot:
-                    displayName = number;
-
-                    // ...and use the "number" slot for a geographical description
-                    // string if available (but only for incoming calls.)
-                    if ((conn != null) && (conn.isIncoming())) {
-                        // TODO (CallerInfoAsyncQuery cleanup): Fix the CallerInfo
-                        // query to only do the geoDescription lookup in the first
-                        // place for incoming calls.
-                        displayNumber = info.geoDescription;  // may be null
-                    }
-
-                    if (DBG) log("  ==>  no name; falling back to number: displayName '"
-                                 + displayName + "', displayNumber '" + displayNumber + "'");
-                }
-            } else {
-                // We do have a valid "name" in the CallerInfo.  Display that
-                // in the "name" slot, and the phone number in the "number" slot.
-                if (presentation != PhoneConstants.PRESENTATION_ALLOWED) {
-                    // This case should never happen since the network should never send a name
-                    // AND a restricted presentation. However we leave it here in case of weird
-                    // network behavior
-                    displayName = PhoneUtils.getPresentationString(getContext(), presentation);
-                    if (DBG) log("  ==> valid name, but presentation not allowed!"
-                                 + " displayName = " + displayName);
-                } else {
-                    displayName = info.name;
-                    displayNumber = number;
-                    label = info.phoneLabel;
-                    if (DBG) log("  ==>  name is present in CallerInfo: displayName '"
-                                 + displayName + "', displayNumber '" + displayNumber + "'");
-                }
-            }
-            personUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, info.person_id);
-            if (DBG) log("- got personUri: '" + personUri
-                         + "', based on info.person_id: " + info.person_id);
-        } else {
-            displayName = PhoneUtils.getPresentationString(getContext(), presentation);
-        }
-
-        if (call.isGeneric()) {
-            updateGenericInfoUi();
-        } else {
-            updateInfoUi(displayName, displayNumber, label);
-        }
-
-        // Update mPhoto
-        // if the temporary flag is set, we know we'll be getting another call after
-        // the CallerInfo has been correctly updated.  So, we can skip the image
-        // loading until then.
-
-        // If the photoResource is filled in for the CallerInfo, (like with the
-        // Emergency Number case), then we can just set the photo image without
-        // requesting for an image load. Please refer to CallerInfoAsyncQuery.java
-        // for cases where CallerInfo.photoResource may be set.  We can also avoid
-        // the image load step if the image data is cached.
-        if (isTemporary && (info == null || !info.isCachedPhotoCurrent)) {
-            mPhoto.setTag(null);
-            mPhoto.setVisibility(View.INVISIBLE);
-        } else if (info != null && info.photoResource != 0){
-            showImage(mPhoto, info.photoResource);
-        } else if (!showCachedImage(mPhoto, info)) {
-            if (personUri == null) {
-                Log.w(LOG_TAG, "personPri is null. Just use Unknown picture.");
-                showImage(mPhoto, R.drawable.picture_unknown);
-            } else if (personUri.equals(mLoadingPersonUri)) {
-                if (DBG) {
-                    log("The requested Uri (" + personUri + ") is being loaded already."
-                            + " Ignoret the duplicate load request.");
-                }
-            } else {
-                // Remember which person's photo is being loaded right now so that we won't issue
-                // unnecessary load request multiple times, which will mess up animation around
-                // the contact photo.
-                mLoadingPersonUri = personUri;
-
-                // Forget the drawable previously used.
-                mPhoto.setTag(null);
-                // Show empty screen for a moment.
-                mPhoto.setVisibility(View.INVISIBLE);
-                // Load the image with a callback to update the image state.
-                // When the load is finished, onImageLoadComplete() will be called.
-                ContactsAsyncHelper.startObtainPhotoAsync(TOKEN_UPDATE_PHOTO_FOR_CALL_STATE,
-                        getContext(), personUri, this, new AsyncLoadCookie(mPhoto, info, call));
-
-                // If the image load is too slow, we show a default avatar icon afterward.
-                // If it is fast enough, this message will be canceled on onImageLoadComplete().
-                mHandler.removeMessages(MESSAGE_SHOW_UNKNOWN_PHOTO);
-                mHandler.sendEmptyMessageDelayed(MESSAGE_SHOW_UNKNOWN_PHOTO, MESSAGE_DELAY);
-            }
-        }
-
-        // If the phone call is on hold, show it with darker status.
-        // Right now we achieve it by overlaying opaque View.
-        // Note: See also layout file about why so and what is the other possibilities.
-        if (call.getState() == Call.State.HOLDING) {
-            AnimationUtils.Fade.show(mPhotoDimEffect);
-        } else {
-            AnimationUtils.Fade.hide(mPhotoDimEffect, View.GONE);
-        }
-
-        // Other text fields:
-        updateCallTypeLabel(call);
-        // updateSocialStatus(socialStatusText, socialStatusBadge, call);  // Currently unused
-    }
-
-    /**
-     * Updates the info portion of the UI to be generic.  Used for CDMA 3-way calls.
-     */
-    private void updateGenericInfoUi() {
-        mName.setText(R.string.card_title_in_call);
-        mPhoneNumber.setVisibility(View.GONE);
-        mLabel.setVisibility(View.GONE);
-    }
-
-    /**
-     * Updates the info portion of the call card with passed in values.
-     */
-    private void updateInfoUi(String displayName, String displayNumber, String label) {
-        mName.setText(displayName);
-        mName.setVisibility(View.VISIBLE);
-
-        if (TextUtils.isEmpty(displayNumber)) {
-            mPhoneNumber.setVisibility(View.GONE);
-            // We have a real phone number as "mName" so make it always LTR
-            mName.setTextDirection(View.TEXT_DIRECTION_LTR);
-        } else {
-            mPhoneNumber.setText(displayNumber);
-            mPhoneNumber.setVisibility(View.VISIBLE);
-            // We have a real phone number as "mPhoneNumber" so make it always LTR
-            mPhoneNumber.setTextDirection(View.TEXT_DIRECTION_LTR);
-        }
-
-        if (TextUtils.isEmpty(label)) {
-            mLabel.setVisibility(View.GONE);
-        } else {
-            mLabel.setText(label);
-            mLabel.setVisibility(View.VISIBLE);
-        }
-    }
-
-    /**
-     * Updates the name / photo / number / label fields
-     * for the special "conference call" state.
-     *
-     * If the current call has only a single connection, use
-     * updateDisplayForPerson() instead.
-     */
-    private void updateDisplayForConference(Call call) {
-        if (DBG) log("updateDisplayForConference()...");
-
-        int phoneType = call.getPhone().getPhoneType();
-        if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-            // This state corresponds to both 3-Way merged call and
-            // Call Waiting accepted call.
-            // In this case we display the UI in a "generic" state, with
-            // the generic "dialing" icon and no caller information,
-            // because in this state in CDMA the user does not really know
-            // which caller party he is talking to.
-            showImage(mPhoto, R.drawable.picture_dialing);
-            mName.setText(R.string.card_title_in_call);
-        } else if ((phoneType == PhoneConstants.PHONE_TYPE_GSM)
-                || (phoneType == PhoneConstants.PHONE_TYPE_SIP)) {
-            // Normal GSM (or possibly SIP?) conference call.
-            // Display the "conference call" image as the contact photo.
-            // TODO: Better visual treatment for contact photos in a
-            // conference call (see bug 1313252).
-            showImage(mPhoto, R.drawable.picture_conference);
-            mName.setText(R.string.card_title_conf_call);
-        } else {
-            throw new IllegalStateException("Unexpected phone type: " + phoneType);
-        }
-
-        mName.setVisibility(View.VISIBLE);
-
-        // TODO: For a conference call, the "phone number" slot is specced
-        // to contain a summary of who's on the call, like "Bill Foldes
-        // and Hazel Nutt" or "Bill Foldes and 2 others".
-        // But for now, just hide it:
-        mPhoneNumber.setVisibility(View.GONE);
-        mLabel.setVisibility(View.GONE);
-
-        // Other text fields:
-        updateCallTypeLabel(call);
-        // updateSocialStatus(null, null, null);  // socialStatus is never visible in this state
-
-        // TODO: for a GSM conference call, since we do actually know who
-        // you're talking to, consider also showing names / numbers /
-        // photos of some of the people on the conference here, so you can
-        // see that info without having to click "Manage conference".  We
-        // probably have enough space to show info for 2 people, at least.
-        //
-        // To do this, our caller would pass us the activeConnections
-        // list, and we'd call PhoneUtils.getCallerInfo() separately for
-        // each connection.
-    }
-
-    /**
-     * Updates the CallCard "photo" IFF the specified Call is in a state
-     * that needs a special photo (like "busy" or "dialing".)
-     *
-     * If the current call does not require a special image in the "photo"
-     * slot onscreen, don't do anything, since presumably the photo image
-     * has already been set (to the photo of the person we're talking, or
-     * the generic "picture_unknown" image, or the "conference call"
-     * image.)
-     */
-    private void updatePhotoForCallState(Call call) {
-        if (DBG) log("updatePhotoForCallState(" + call + ")...");
-        int photoImageResource = 0;
-
-        // Check for the (relatively few) telephony states that need a
-        // special image in the "photo" slot.
-        Call.State state = call.getState();
-        switch (state) {
-            case DISCONNECTED:
-                // Display the special "busy" photo for BUSY or CONGESTION.
-                // Otherwise (presumably the normal "call ended" state)
-                // leave the photo alone.
-                Connection c = call.getEarliestConnection();
-                // if the connection is null, we assume the default case,
-                // otherwise update the image resource normally.
-                if (c != null) {
-                    Connection.DisconnectCause cause = c.getDisconnectCause();
-                    if ((cause == Connection.DisconnectCause.BUSY)
-                        || (cause == Connection.DisconnectCause.CONGESTION)) {
-                        photoImageResource = R.drawable.picture_busy;
-                    }
-                } else if (DBG) {
-                    log("updatePhotoForCallState: connection is null, ignoring.");
-                }
-
-                // TODO: add special images for any other DisconnectCauses?
-                break;
-
-            case ALERTING:
-            case DIALING:
-            default:
-                // Leave the photo alone in all other states.
-                // If this call is an individual call, and the image is currently
-                // displaying a state, (rather than a photo), we'll need to update
-                // the image.
-                // This is for the case where we've been displaying the state and
-                // now we need to restore the photo.  This can happen because we
-                // only query the CallerInfo once, and limit the number of times
-                // the image is loaded. (So a state image may overwrite the photo
-                // and we would otherwise have no way of displaying the photo when
-                // the state goes away.)
-
-                // if the photoResource field is filled-in in the Connection's
-                // caller info, then we can just use that instead of requesting
-                // for a photo load.
-
-                // look for the photoResource if it is available.
-                CallerInfo ci = null;
-                {
-                    Connection conn = null;
-                    int phoneType = call.getPhone().getPhoneType();
-                    if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-                        conn = call.getLatestConnection();
-                    } else if ((phoneType == PhoneConstants.PHONE_TYPE_GSM)
-                            || (phoneType == PhoneConstants.PHONE_TYPE_SIP)) {
-                        conn = call.getEarliestConnection();
-                    } else {
-                        throw new IllegalStateException("Unexpected phone type: " + phoneType);
-                    }
-
-                    if (conn != null) {
-                        Object o = conn.getUserData();
-                        if (o instanceof CallerInfo) {
-                            ci = (CallerInfo) o;
-                        } else if (o instanceof PhoneUtils.CallerInfoToken) {
-                            ci = ((PhoneUtils.CallerInfoToken) o).currentInfo;
-                        }
-                    }
-                }
-
-                if (ci != null) {
-                    photoImageResource = ci.photoResource;
-                }
-
-                // If no photoResource found, check to see if this is a conference call. If
-                // it is not a conference call:
-                //   1. Try to show the cached image
-                //   2. If the image is not cached, check to see if a load request has been
-                //      made already.
-                //   3. If the load request has not been made [DISPLAY_DEFAULT], start the
-                //      request and note that it has started by updating photo state with
-                //      [DISPLAY_IMAGE].
-                if (photoImageResource == 0) {
-                    if (!PhoneUtils.isConferenceCall(call)) {
-                        if (!showCachedImage(mPhoto, ci) && (mPhotoTracker.getPhotoState() ==
-                                ContactsAsyncHelper.ImageTracker.DISPLAY_DEFAULT)) {
-                            Uri photoUri = mPhotoTracker.getPhotoUri();
-                            if (photoUri == null) {
-                                Log.w(LOG_TAG, "photoUri became null. Show default avatar icon");
-                                showImage(mPhoto, R.drawable.picture_unknown);
-                            } else {
-                                if (DBG) {
-                                    log("start asynchronous load inside updatePhotoForCallState()");
-                                }
-                                mPhoto.setTag(null);
-                                // Make it invisible for a moment
-                                mPhoto.setVisibility(View.INVISIBLE);
-                                ContactsAsyncHelper.startObtainPhotoAsync(TOKEN_DO_NOTHING,
-                                        getContext(), photoUri, this,
-                                        new AsyncLoadCookie(mPhoto, ci, null));
-                            }
-                            mPhotoTracker.setPhotoState(
-                                    ContactsAsyncHelper.ImageTracker.DISPLAY_IMAGE);
-                        }
-                    }
-                } else {
-                    showImage(mPhoto, photoImageResource);
-                    mPhotoTracker.setPhotoState(ContactsAsyncHelper.ImageTracker.DISPLAY_IMAGE);
-                    return;
-                }
-                break;
-        }
-
-        if (photoImageResource != 0) {
-            if (DBG) log("- overrriding photo image: " + photoImageResource);
-            showImage(mPhoto, photoImageResource);
-            // Track the image state.
-            mPhotoTracker.setPhotoState(ContactsAsyncHelper.ImageTracker.DISPLAY_DEFAULT);
-        }
-    }
-
-    /**
-     * Try to display the cached image from the callerinfo object.
-     *
-     *  @return true if we were able to find the image in the cache, false otherwise.
-     */
-    private static final boolean showCachedImage(ImageView view, CallerInfo ci) {
-        if ((ci != null) && ci.isCachedPhotoCurrent) {
-            if (ci.cachedPhoto != null) {
-                showImage(view, ci.cachedPhoto);
-            } else {
-                showImage(view, R.drawable.picture_unknown);
-            }
-            return true;
-        }
-        return false;
-    }
-
-    /** Helper function to display the resource in the imageview AND ensure its visibility.*/
-    private static final void showImage(ImageView view, int resource) {
-        showImage(view, view.getContext().getResources().getDrawable(resource));
-    }
-
-    private static final void showImage(ImageView view, Bitmap bitmap) {
-        showImage(view, new BitmapDrawable(view.getContext().getResources(), bitmap));
-    }
-
-    /** Helper function to display the drawable in the imageview AND ensure its visibility.*/
-    private static final void showImage(ImageView view, Drawable drawable) {
-        Resources res = view.getContext().getResources();
-        Drawable current = (Drawable) view.getTag();
-
-        if (current == null) {
-            if (DBG) log("Start fade-in animation for " + view);
-            view.setImageDrawable(drawable);
-            AnimationUtils.Fade.show(view);
-            view.setTag(drawable);
-        } else {
-            AnimationUtils.startCrossFade(view, current, drawable);
-            view.setVisibility(View.VISIBLE);
-        }
-    }
-
-    /**
-     * Returns the special card title used in emergency callback mode (ECM),
-     * which shows your own phone number.
-     */
-    private String getECMCardTitle(Context context, Phone phone) {
-        String rawNumber = phone.getLine1Number();  // may be null or empty
-        String formattedNumber;
-        if (!TextUtils.isEmpty(rawNumber)) {
-            formattedNumber = PhoneNumberUtils.formatNumber(rawNumber);
-        } else {
-            formattedNumber = context.getString(R.string.unknown);
-        }
-        String titleFormat = context.getString(R.string.card_title_my_phone_number);
-        return String.format(titleFormat, formattedNumber);
-    }
-
-    /**
-     * Updates the "Call type" label, based on the current foreground call.
-     * This is a special label and/or branding we display for certain
-     * kinds of calls.
-     *
-     * (So far, this is used only for SIP calls, which get an
-     * "Internet call" label.  TODO: But eventually, the telephony
-     * layer might allow each pluggable "provider" to specify a string
-     * and/or icon to be displayed here.)
-     */
-    private void updateCallTypeLabel(Call call) {
-        int phoneType = (call != null) ? call.getPhone().getPhoneType() :
-                PhoneConstants.PHONE_TYPE_NONE;
-        if (phoneType == PhoneConstants.PHONE_TYPE_SIP) {
-            mCallTypeLabel.setVisibility(View.VISIBLE);
-            mCallTypeLabel.setText(R.string.incall_call_type_label_sip);
-            mCallTypeLabel.setTextColor(mTextColorCallTypeSip);
-            // If desired, we could also display a "badge" next to the label, as follows:
-            //   mCallTypeLabel.setCompoundDrawablesWithIntrinsicBounds(
-            //           callTypeSpecificBadge, null, null, null);
-            //   mCallTypeLabel.setCompoundDrawablePadding((int) (mDensity * 6));
-        } else {
-            mCallTypeLabel.setVisibility(View.GONE);
-        }
-    }
-
-    /**
-     * Updates the "social status" label with the specified text and
-     * (optional) badge.
-     */
-    /*private void updateSocialStatus(String socialStatusText,
-                                    Drawable socialStatusBadge,
-                                    Call call) {
-        // The socialStatus field is *only* visible while an incoming call
-        // is ringing, never in any other call state.
-        if ((socialStatusText != null)
-                && (call != null)
-                && call.isRinging()
-                && !call.isGeneric()) {
-            mSocialStatus.setVisibility(View.VISIBLE);
-            mSocialStatus.setText(socialStatusText);
-            mSocialStatus.setCompoundDrawablesWithIntrinsicBounds(
-                    socialStatusBadge, null, null, null);
-            mSocialStatus.setCompoundDrawablePadding((int) (mDensity * 6));
-        } else {
-            mSocialStatus.setVisibility(View.GONE);
-        }
-    }*/
-
-    /**
-     * Hides the top-level UI elements of the call card:  The "main
-     * call card" element representing the current active or ringing call,
-     * and also the info areas for "ongoing" or "on hold" calls in some
-     * states.
-     *
-     * This is intended to be used in special states where the normal
-     * in-call UI is totally replaced by some other UI, like OTA mode on a
-     * CDMA device.
-     *
-     * To bring back the regular CallCard UI, just re-run the normal
-     * updateState() call sequence.
-     */
-    public void hideCallCardElements() {
-        mPrimaryCallInfo.setVisibility(View.GONE);
-        mSecondaryCallInfo.setVisibility(View.GONE);
-    }
-
-    /*
-     * Updates the hint (like "Rotate to answer") that we display while
-     * the user is dragging the incoming call RotarySelector widget.
-     */
-    /* package */ void setIncomingCallWidgetHint(int hintTextResId, int hintColorResId) {
-        mIncomingCallWidgetHintTextResId = hintTextResId;
-        mIncomingCallWidgetHintColorResId = hintColorResId;
-    }
-
-    // Accessibility event support.
-    // Since none of the CallCard elements are focusable, we need to manually
-    // fill in the AccessibilityEvent here (so that the name / number / etc will
-    // get pronounced by a screen reader, for example.)
-    @Override
-    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
-        if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
-            dispatchPopulateAccessibilityEvent(event, mName);
-            dispatchPopulateAccessibilityEvent(event, mPhoneNumber);
-            return true;
-        }
-
-        dispatchPopulateAccessibilityEvent(event, mCallStateLabel);
-        dispatchPopulateAccessibilityEvent(event, mPhoto);
-        dispatchPopulateAccessibilityEvent(event, mName);
-        dispatchPopulateAccessibilityEvent(event, mPhoneNumber);
-        dispatchPopulateAccessibilityEvent(event, mLabel);
-        // dispatchPopulateAccessibilityEvent(event, mSocialStatus);
-        if (mSecondaryCallName != null) {
-            dispatchPopulateAccessibilityEvent(event, mSecondaryCallName);
-        }
-        if (mSecondaryCallPhoto != null) {
-            dispatchPopulateAccessibilityEvent(event, mSecondaryCallPhoto);
-        }
-        return true;
-    }
-
-    private void dispatchPopulateAccessibilityEvent(AccessibilityEvent event, View view) {
-        List<CharSequence> eventText = event.getText();
-        int size = eventText.size();
-        view.dispatchPopulateAccessibilityEvent(event);
-        // if no text added write null to keep relative position
-        if (size == eventText.size()) {
-            eventText.add(null);
-        }
-    }
-
-    public void clear() {
-        // The existing phone design is to keep an instance of call card forever.  Until that
-        // design changes, this method is needed to clear (reset) the call card for the next call
-        // so old data is not shown.
-
-        // Other elements can also be cleared here.  Starting with elapsed time to fix a bug.
-        mElapsedTime.setVisibility(View.GONE);
-        mElapsedTime.setText(null);
-    }
-
-
-    // Debugging / testing code
-
-    private static void log(String msg) {
-        Log.d(LOG_TAG, msg);
-    }
-}
diff --git a/src/com/android/phone/CallController.java b/src/com/android/phone/CallController.java
index 2cceed0..52dbf76 100644
--- a/src/com/android/phone/CallController.java
+++ b/src/com/android/phone/CallController.java
@@ -23,7 +23,6 @@
 import com.android.phone.CallGatewayManager.RawGatewayInfo;
 import com.android.phone.Constants.CallStatusCode;
 import com.android.phone.ErrorDialogActivity;
-import com.android.phone.InCallUiState.InCallScreenMode;
 import com.android.phone.OtaUtils.CdmaOtaScreenState;
 
 import android.app.AlertDialog;
@@ -194,8 +193,6 @@
         log("placeCall()...  intent = " + intent);
         if (VDBG) log("                extras = " + intent.getExtras());
 
-        final InCallUiState inCallUiState = mApp.inCallUiState;
-
         // TODO: Do we need to hold a wake lock while this method runs?
         //       Or did we already acquire one somewhere earlier
         //       in this sequence (like when we first received the CALL intent?)
@@ -256,18 +253,6 @@
             case SUCCESS:
             case EXITED_ECM:
                 if (DBG) log("==> placeCall(): success from placeCallInternal(): " + status);
-
-                if (status == CallStatusCode.EXITED_ECM) {
-                    // Call succeeded, but we also need to tell the
-                    // InCallScreen to show the "Exiting ECM" warning.
-                    inCallUiState.setPendingCallStatusCode(CallStatusCode.EXITED_ECM);
-                } else {
-                    // Call succeeded.  There's no "error condition" that
-                    // needs to be displayed to the user, so clear out the
-                    // InCallUiState's "pending call status code".
-                    inCallUiState.clearPendingCallStatusCode();
-                }
-
                 break;
 
             default:
@@ -289,20 +274,6 @@
         // in-call UI.  Or if there was an error, the InCallScreen will
         // notice the InCallUiState pending call status code flag and display an
         // error indication instead.)
-
-        // TODO: double-check the behavior of mApp.displayCallScreen()
-        // if the InCallScreen is already visible:
-        // - make sure it forces the UI to refresh
-        // - make sure it does NOT launch a new InCallScreen on top
-        //   of the current one (i.e. the Back button should not take
-        //   you back to the previous InCallScreen)
-        // - it's probably OK to go thru a fresh pause/resume sequence
-        //   though (since that should be fast now)
-        // - if necessary, though, maybe PhoneApp.displayCallScreen()
-        //   could notice that the InCallScreen is already in the foreground,
-        //   and if so simply call updateInCallScreen() instead.
-
-        mApp.displayCallScreen();
     }
 
     /**
@@ -324,7 +295,6 @@
         // TODO: This method is too long.  Break it down into more
         // manageable chunks.
 
-        final InCallUiState inCallUiState = mApp.inCallUiState;
         final Uri uri = intent.getData();
         final String scheme = (uri != null) ? uri.getScheme() : null;
         String number;
@@ -461,13 +431,6 @@
             }
         }
 
-        // Ok, we can proceed with this outgoing call.
-
-        // Reset some InCallUiState flags, just in case they're still set
-        // from a prior call.
-        inCallUiState.needToShowCallLostDialog = false;
-        inCallUiState.clearProgressIndication();
-
         // We have a valid number, so try to actually place a call:
         // make sure we pass along the intent's URI which is a
         // reference to the contact. We may have a provider gateway
@@ -501,40 +464,7 @@
                 //   app.cdmaOtaInCallScreenUiState.state are redundant.
                 //   Combine them.
 
-                if (VDBG) log ("- inCallUiState.inCallScreenMode = "
-                               + inCallUiState.inCallScreenMode);
-                if (inCallUiState.inCallScreenMode == InCallScreenMode.OTA_NORMAL) {
-                    if (VDBG) log ("==>  OTA_NORMAL note: switching to OTA_STATUS_LISTENING.");
-                    mApp.cdmaOtaScreenState.otaScreenState =
-                            CdmaOtaScreenState.OtaScreenState.OTA_STATUS_LISTENING;
-                }
-
                 boolean voicemailUriSpecified = scheme != null && scheme.equals("voicemail");
-                // When voicemail is requested most likely the user wants to open
-                // dialpad immediately, so we show it in the first place.
-                // Otherwise we want to make sure the user can see the regular
-                // in-call UI while the new call is dialing, and when it
-                // first gets connected.)
-                inCallUiState.showDialpad = voicemailUriSpecified;
-
-                // For voicemails, we add context text to let the user know they
-                // are dialing their voicemail.
-                // TODO: This is only set here and becomes problematic when swapping calls
-                inCallUiState.dialpadContextText = voicemailUriSpecified ?
-                    phone.getVoiceMailAlphaTag() : "";
-
-                // Also, in case a previous call was already active (i.e. if
-                // we just did "Add call"), clear out the "history" of DTMF
-                // digits you typed, to make sure it doesn't persist from the
-                // previous call to the new call.
-                // TODO: it would be more precise to do this when the actual
-                // phone state change happens (i.e. when a new foreground
-                // call appears and the previous call moves to the
-                // background), but the InCallScreen doesn't keep enough
-                // state right now to notice that specific transition in
-                // onPhoneStateChanged().
-                inCallUiState.dialpadDigits = null;
-
                 // Check for an obscure ECM-related scenario: If the phone
                 // is currently in ECM (Emergency callback mode) and we
                 // dial a non-emergency number, that automatically
diff --git a/src/com/android/phone/CallNotifier.java b/src/com/android/phone/CallNotifier.java
index bbffbd2..a5b467d 100644
--- a/src/com/android/phone/CallNotifier.java
+++ b/src/com/android/phone/CallNotifier.java
@@ -304,7 +304,6 @@
                 if (DBG) log("Received CALLWAITING_ADDCALL_DISABLE_TIMEOUT event ...");
                 // Set the mAddCallMenuStateAfterCW state to true
                 mApplication.cdmaPhoneCallState.setAddCallMenuStateAfterCallWaiting(true);
-                mApplication.updateInCallScreen();
                 break;
 
             case CallStateMonitor.PHONE_STATE_DISPLAYINFO:
@@ -526,7 +525,6 @@
                 // we should instead provide a higher-level API via OtaUtils.
                 if (dialogState) mApplication.dismissOtaDialogs();
                 mApplication.clearOtaState();
-                mApplication.clearInCallScreenMode();
                 return false;
             }
         }
@@ -738,12 +736,6 @@
             // make sure audio is in in-call mode now
             PhoneUtils.setAudioMode(mCM);
 
-            // if the call screen is showing, let it handle the event,
-            // otherwise handle it here.
-            if (!mApplication.isShowingCallScreen()) {
-                mApplication.requestWakeState(PhoneGlobals.WakeState.SLEEP);
-            }
-
             // Since we're now in-call, the Ringer should definitely *not*
             // be ringing any more.  (This is just a sanity-check; we
             // already stopped the ringer explicitly back in
diff --git a/src/com/android/phone/DTMFTwelveKeyDialer.java b/src/com/android/phone/DTMFTwelveKeyDialer.java
deleted file mode 100644
index 4dd4a88..0000000
--- a/src/com/android/phone/DTMFTwelveKeyDialer.java
+++ /dev/null
@@ -1,1116 +0,0 @@
-/*
- * Copyright (C) 2008 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.content.Context;
-import android.media.AudioManager;
-import android.media.ToneGenerator;
-import android.os.Handler;
-import android.os.Message;
-import android.provider.Settings;
-import android.telephony.PhoneNumberUtils;
-import android.text.Editable;
-import android.text.SpannableString;
-import android.text.method.DialerKeyListener;
-import android.text.style.RelativeSizeSpan;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.accessibility.AccessibilityManager;
-import android.view.ViewStub;
-import android.widget.EditText;
-
-import com.android.internal.telephony.CallManager;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConstants;
-
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.Queue;
-
-
-/**
- * Dialer class that encapsulates the DTMF twelve key behaviour.
- * This model backs up the UI behaviour in DTMFTwelveKeyDialerView.java.
- */
-public class DTMFTwelveKeyDialer implements View.OnTouchListener, View.OnKeyListener,
-        View.OnHoverListener, View.OnClickListener {
-    private static final String LOG_TAG = "DTMFTwelveKeyDialer";
-    private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
-
-    // events
-    private static final int PHONE_DISCONNECT = 100;
-    private static final int DTMF_SEND_CNF = 101;
-    private static final int DTMF_STOP = 102;
-
-    /** Accessibility manager instance used to check touch exploration state. */
-    private final AccessibilityManager mAccessibilityManager;
-
-    private CallManager mCM;
-    private ToneGenerator mToneGenerator;
-    private final Object mToneGeneratorLock = new Object();
-
-    // indicate if we want to enable the local tone playback.
-    private boolean mLocalToneEnabled;
-
-    // indicates that we are using automatically shortened DTMF tones
-    boolean mShortTone;
-
-    // indicate if the confirmation from TelephonyFW is pending.
-    private boolean mDTMFBurstCnfPending = false;
-
-    // Queue to queue the short dtmf characters.
-    private Queue<Character> mDTMFQueue = new LinkedList<Character>();
-
-    //  Short Dtmf tone duration
-    private static final int DTMF_DURATION_MS = 120;
-
-
-    /** Hash Map to map a character to a tone*/
-    private static final HashMap<Character, Integer> mToneMap =
-        new HashMap<Character, Integer>();
-    /** Hash Map to map a view id to a character*/
-    private static final HashMap<Integer, Character> mDisplayMap =
-        new HashMap<Integer, Character>();
-    /** Set up the static maps*/
-    static {
-        // Map the key characters to tones
-        mToneMap.put('1', ToneGenerator.TONE_DTMF_1);
-        mToneMap.put('2', ToneGenerator.TONE_DTMF_2);
-        mToneMap.put('3', ToneGenerator.TONE_DTMF_3);
-        mToneMap.put('4', ToneGenerator.TONE_DTMF_4);
-        mToneMap.put('5', ToneGenerator.TONE_DTMF_5);
-        mToneMap.put('6', ToneGenerator.TONE_DTMF_6);
-        mToneMap.put('7', ToneGenerator.TONE_DTMF_7);
-        mToneMap.put('8', ToneGenerator.TONE_DTMF_8);
-        mToneMap.put('9', ToneGenerator.TONE_DTMF_9);
-        mToneMap.put('0', ToneGenerator.TONE_DTMF_0);
-        mToneMap.put('#', ToneGenerator.TONE_DTMF_P);
-        mToneMap.put('*', ToneGenerator.TONE_DTMF_S);
-
-        // Map the buttons to the display characters
-        mDisplayMap.put(R.id.one, '1');
-        mDisplayMap.put(R.id.two, '2');
-        mDisplayMap.put(R.id.three, '3');
-        mDisplayMap.put(R.id.four, '4');
-        mDisplayMap.put(R.id.five, '5');
-        mDisplayMap.put(R.id.six, '6');
-        mDisplayMap.put(R.id.seven, '7');
-        mDisplayMap.put(R.id.eight, '8');
-        mDisplayMap.put(R.id.nine, '9');
-        mDisplayMap.put(R.id.zero, '0');
-        mDisplayMap.put(R.id.pound, '#');
-        mDisplayMap.put(R.id.star, '*');
-    }
-
-    /** EditText field used to display the DTMF digits sent so far.
-        Note this is null in some modes (like during the CDMA OTA call,
-        where there's no onscreen "digits" display.) */
-    private EditText mDialpadDigits;
-
-    // InCallScreen reference.
-    private InCallScreen mInCallScreen;
-
-    /**
-     * The DTMFTwelveKeyDialerView we use to display the dialpad.
-     *
-     * Only one of mDialerView or mDialerStub will have a legitimate object; the other one will be
-     * null at that moment. Either of following scenarios will occur:
-     *
-     * - If the constructor with {@link DTMFTwelveKeyDialerView} is called, mDialerView will
-     *   obtain that object, and mDialerStub will be null. mDialerStub won't be used in this case.
-     *
-     * - If the constructor with {@link ViewStub} is called, mDialerView will be null at that
-     *   moment, and mDialerStub will obtain the ViewStub object.
-     *   When the dialer is required by the user (i.e. until {@link #openDialer(boolean)} being
-     *   called), mDialerStub will inflate the dialer, and make mDialerStub itself null.
-     *   mDialerStub won't be used afterward.
-     */
-    private DTMFTwelveKeyDialerView mDialerView;
-
-    /**
-     * {@link ViewStub} holding {@link DTMFTwelveKeyDialerView}. See the comments for mDialerView.
-     */
-    private ViewStub mDialerStub;
-
-    // KeyListener used with the "dialpad digits" EditText widget.
-    private DTMFKeyListener mDialerKeyListener;
-
-    /**
-     * Our own key listener, specialized for dealing with DTMF codes.
-     *   1. Ignore the backspace since it is irrelevant.
-     *   2. Allow ONLY valid DTMF characters to generate a tone and be
-     *      sent as a DTMF code.
-     *   3. All other remaining characters are handled by the superclass.
-     *
-     * This code is purely here to handle events from the hardware keyboard
-     * while the DTMF dialpad is up.
-     */
-    private class DTMFKeyListener extends DialerKeyListener {
-
-        private DTMFKeyListener() {
-            super();
-        }
-
-        /**
-         * Overriden to return correct DTMF-dialable characters.
-         */
-        @Override
-        protected char[] getAcceptedChars(){
-            return DTMF_CHARACTERS;
-        }
-
-        /** special key listener ignores backspace. */
-        @Override
-        public boolean backspace(View view, Editable content, int keyCode,
-                KeyEvent event) {
-            return false;
-        }
-
-        /**
-         * Return true if the keyCode is an accepted modifier key for the
-         * dialer (ALT or SHIFT).
-         */
-        private boolean isAcceptableModifierKey(int keyCode) {
-            switch (keyCode) {
-                case KeyEvent.KEYCODE_ALT_LEFT:
-                case KeyEvent.KEYCODE_ALT_RIGHT:
-                case KeyEvent.KEYCODE_SHIFT_LEFT:
-                case KeyEvent.KEYCODE_SHIFT_RIGHT:
-                    return true;
-                default:
-                    return false;
-            }
-        }
-
-        /**
-         * Overriden so that with each valid button press, we start sending
-         * a dtmf code and play a local dtmf tone.
-         */
-        @Override
-        public boolean onKeyDown(View view, Editable content,
-                                 int keyCode, KeyEvent event) {
-            // if (DBG) log("DTMFKeyListener.onKeyDown, keyCode " + keyCode + ", view " + view);
-
-            // find the character
-            char c = (char) lookup(event, content);
-
-            // if not a long press, and parent onKeyDown accepts the input
-            if (event.getRepeatCount() == 0 && super.onKeyDown(view, content, keyCode, event)) {
-
-                boolean keyOK = ok(getAcceptedChars(), c);
-
-                // if the character is a valid dtmf code, start playing the tone and send the
-                // code.
-                if (keyOK) {
-                    if (DBG) log("DTMFKeyListener reading '" + c + "' from input.");
-                    processDtmf(c);
-                } else if (DBG) {
-                    log("DTMFKeyListener rejecting '" + c + "' from input.");
-                }
-                return true;
-            }
-            return false;
-        }
-
-        /**
-         * Overriden so that with each valid button up, we stop sending
-         * a dtmf code and the dtmf tone.
-         */
-        @Override
-        public boolean onKeyUp(View view, Editable content,
-                                 int keyCode, KeyEvent event) {
-            // if (DBG) log("DTMFKeyListener.onKeyUp, keyCode " + keyCode + ", view " + view);
-
-            super.onKeyUp(view, content, keyCode, event);
-
-            // find the character
-            char c = (char) lookup(event, content);
-
-            boolean keyOK = ok(getAcceptedChars(), c);
-
-            if (keyOK) {
-                if (DBG) log("Stopping the tone for '" + c + "'");
-                stopTone();
-                return true;
-            }
-
-            return false;
-        }
-
-        /**
-         * Handle individual keydown events when we DO NOT have an Editable handy.
-         */
-        public boolean onKeyDown(KeyEvent event) {
-            char c = lookup(event);
-            if (DBG) log("DTMFKeyListener.onKeyDown: event '" + c + "'");
-
-            // if not a long press, and parent onKeyDown accepts the input
-            if (event.getRepeatCount() == 0 && c != 0) {
-                // if the character is a valid dtmf code, start playing the tone and send the
-                // code.
-                if (ok(getAcceptedChars(), c)) {
-                    if (DBG) log("DTMFKeyListener reading '" + c + "' from input.");
-                    processDtmf(c);
-                    return true;
-                } else if (DBG) {
-                    log("DTMFKeyListener rejecting '" + c + "' from input.");
-                }
-            }
-            return false;
-        }
-
-        /**
-         * Handle individual keyup events.
-         *
-         * @param event is the event we are trying to stop.  If this is null,
-         * then we just force-stop the last tone without checking if the event
-         * is an acceptable dialer event.
-         */
-        public boolean onKeyUp(KeyEvent event) {
-            if (event == null) {
-                //the below piece of code sends stopDTMF event unnecessarily even when a null event
-                //is received, hence commenting it.
-                /*if (DBG) log("Stopping the last played tone.");
-                stopTone();*/
-                return true;
-            }
-
-            char c = lookup(event);
-            if (DBG) log("DTMFKeyListener.onKeyUp: event '" + c + "'");
-
-            // TODO: stopTone does not take in character input, we may want to
-            // consider checking for this ourselves.
-            if (ok(getAcceptedChars(), c)) {
-                if (DBG) log("Stopping the tone for '" + c + "'");
-                stopTone();
-                return true;
-            }
-
-            return false;
-        }
-
-        /**
-         * Find the Dialer Key mapped to this event.
-         *
-         * @return The char value of the input event, otherwise
-         * 0 if no matching character was found.
-         */
-        private char lookup(KeyEvent event) {
-            // This code is similar to {@link DialerKeyListener#lookup(KeyEvent, Spannable) lookup}
-            int meta = event.getMetaState();
-            int number = event.getNumber();
-
-            if (!((meta & (KeyEvent.META_ALT_ON | KeyEvent.META_SHIFT_ON)) == 0) || (number == 0)) {
-                int match = event.getMatch(getAcceptedChars(), meta);
-                number = (match != 0) ? match : number;
-            }
-
-            return (char) number;
-        }
-
-        /**
-         * Check to see if the keyEvent is dialable.
-         */
-        boolean isKeyEventAcceptable (KeyEvent event) {
-            return (ok(getAcceptedChars(), lookup(event)));
-        }
-
-        /**
-         * Overrides the characters used in {@link DialerKeyListener#CHARACTERS}
-         * These are the valid dtmf characters.
-         */
-        public final char[] DTMF_CHARACTERS = new char[] {
-            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '#', '*'
-        };
-    }
-
-    /**
-     * Our own handler to take care of the messages from the phone state changes
-     */
-    private final Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                // disconnect action
-                // make sure to close the dialer on ALL disconnect actions.
-                case PHONE_DISCONNECT:
-                    if (DBG) log("disconnect message recieved, shutting down.");
-                    // unregister since we are closing.
-                    mCM.unregisterForDisconnect(this);
-                    closeDialer(false);
-                    break;
-                case DTMF_SEND_CNF:
-                    if (DBG) log("dtmf confirmation received from FW.");
-                    // handle burst dtmf confirmation
-                    handleBurstDtmfConfirmation();
-                    break;
-                case DTMF_STOP:
-                    if (DBG) log("dtmf stop received");
-                    stopTone();
-                    break;
-            }
-        }
-    };
-
-
-    /**
-     * DTMFTwelveKeyDialer constructor with {@link DTMFTwelveKeyDialerView}
-     *
-     * @param parent the InCallScreen instance that owns us.
-     * @param dialerView the DTMFTwelveKeyDialerView we should use to display the dialpad.
-     */
-    public DTMFTwelveKeyDialer(InCallScreen parent,
-                                DTMFTwelveKeyDialerView dialerView) {
-        this(parent);
-
-        // The passed-in DTMFTwelveKeyDialerView *should* always be
-        // non-null, now that the in-call UI uses only portrait mode.
-        if (dialerView == null) {
-            Log.e(LOG_TAG, "DTMFTwelveKeyDialer: null dialerView!", new IllegalStateException());
-            // ...continue as best we can, although things will
-            // be pretty broken without the mDialerView UI elements!
-        }
-        mDialerView = dialerView;
-        if (DBG) log("- Got passed-in mDialerView: " + mDialerView);
-
-        if (mDialerView != null) {
-            setupDialerView();
-        }
-    }
-
-    /**
-     * DTMFTwelveKeyDialer constructor with {@link ViewStub}.
-     *
-     * When the dialer is required for the first time (e.g. when {@link #openDialer(boolean)} is
-     * called), the object will inflate the ViewStub by itself, assuming the ViewStub will return
-     * {@link DTMFTwelveKeyDialerView} on {@link ViewStub#inflate()}.
-     *
-     * @param parent the InCallScreen instance that owns us.
-     * @param dialerStub ViewStub which will return {@link DTMFTwelveKeyDialerView} on
-     * {@link ViewStub#inflate()}.
-     */
-    public DTMFTwelveKeyDialer(InCallScreen parent, ViewStub dialerStub) {
-        this(parent);
-
-        mDialerStub = dialerStub;
-        if (DBG) log("- Got passed-in mDialerStub: " + mDialerStub);
-
-        // At this moment mDialerView is still null. We delay calling setupDialerView().
-    }
-
-    /**
-     * Private constructor used for initialization calls common to all public
-     * constructors.
-     *
-     * @param parent the InCallScreen instance that owns us.
-     */
-    private DTMFTwelveKeyDialer(InCallScreen parent) {
-        if (DBG) log("DTMFTwelveKeyDialer constructor... this = " + this);
-
-        mInCallScreen = parent;
-        mCM = PhoneGlobals.getInstance().mCM;
-        mAccessibilityManager = (AccessibilityManager) parent.getSystemService(
-                Context.ACCESSIBILITY_SERVICE);
-    }
-
-    /**
-     * Prepare the dialer view and relevant variables.
-     */
-    private void setupDialerView() {
-        if (DBG) log("setupDialerView()");
-        mDialerView.setDialer(this);
-
-        // In the normal in-call DTMF dialpad, mDialpadDigits is an
-        // EditText used to display the digits the user has typed so
-        // far.  But some other modes (like the OTA call) have no
-        // "digits" display at all, in which case mDialpadDigits will
-        // be null.
-        mDialpadDigits = (EditText) mDialerView.findViewById(R.id.dtmfDialerField);
-        if (mDialpadDigits != null) {
-            mDialerKeyListener = new DTMFKeyListener();
-            mDialpadDigits.setKeyListener(mDialerKeyListener);
-
-            // remove the long-press context menus that support
-            // the edit (copy / paste / select) functions.
-            mDialpadDigits.setLongClickable(false);
-        }
-
-        // Hook up touch / key listeners for the buttons in the onscreen
-        // keypad.
-        setupKeypad(mDialerView);
-    }
-
-    /**
-     * Null out our reference to the InCallScreen activity.
-     * This indicates that the InCallScreen activity has been destroyed.
-     * At the same time, get rid of listeners since we're not going to
-     * be valid anymore.
-     */
-    /* package */ void clearInCallScreenReference() {
-        if (DBG) log("clearInCallScreenReference()...");
-        mInCallScreen = null;
-        mDialerKeyListener = null;
-        mHandler.removeMessages(DTMF_SEND_CNF);
-        synchronized (mDTMFQueue) {
-            mDTMFBurstCnfPending = false;
-            mDTMFQueue.clear();
-        }
-        closeDialer(false);
-    }
-
-    /**
-     * Dialer code that runs when the dialer is brought up.
-     * This includes layout changes, etc, and just prepares the dialer model for use.
-     */
-    private void onDialerOpen(boolean animate) {
-        if (DBG) log("onDialerOpen()...");
-
-        // Any time the dialer is open, listen for "disconnect" events (so
-        // we can close ourself.)
-        mCM.registerForDisconnect(mHandler, PHONE_DISCONNECT, null);
-
-        // On some devices the screen timeout is set to a special value
-        // while the dialpad is up.
-        PhoneGlobals.getInstance().updateWakeState();
-
-        // Give the InCallScreen a chance to do any necessary UI updates.
-        if (mInCallScreen != null) {
-            mInCallScreen.onDialerOpen(animate);
-        } else {
-            Log.e(LOG_TAG, "InCallScreen object was null during onDialerOpen()");
-        }
-    }
-
-    /**
-     * Allocates some resources we keep around during a "dialer session".
-     *
-     * (Currently, a "dialer session" just means any situation where we
-     * might need to play local DTMF tones, which means that we need to
-     * keep a ToneGenerator instance around.  A ToneGenerator instance
-     * keeps an AudioTrack resource busy in AudioFlinger, so we don't want
-     * to keep it around forever.)
-     *
-     * Call {@link stopDialerSession} to release the dialer session
-     * resources.
-     */
-    public void startDialerSession() {
-        if (DBG) log("startDialerSession()... this = " + this);
-
-        // see if we need to play local tones.
-        if (PhoneGlobals.getInstance().getResources().getBoolean(R.bool.allow_local_dtmf_tones)) {
-            mLocalToneEnabled = Settings.System.getInt(mInCallScreen.getContentResolver(),
-                    Settings.System.DTMF_TONE_WHEN_DIALING, 1) == 1;
-        } else {
-            mLocalToneEnabled = false;
-        }
-        if (DBG) log("- startDialerSession: mLocalToneEnabled = " + mLocalToneEnabled);
-
-        // create the tone generator
-        // if the mToneGenerator creation fails, just continue without it.  It is
-        // a local audio signal, and is not as important as the dtmf tone itself.
-        if (mLocalToneEnabled) {
-            synchronized (mToneGeneratorLock) {
-                if (mToneGenerator == null) {
-                    try {
-                        mToneGenerator = new ToneGenerator(AudioManager.STREAM_DTMF, 80);
-                    } catch (RuntimeException e) {
-                        if (DBG) log("Exception caught while creating local tone generator: " + e);
-                        mToneGenerator = null;
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Dialer code that runs when the dialer is closed.
-     * This releases resources acquired when we start the dialer.
-     */
-    private void onDialerClose(boolean animate) {
-        if (DBG) log("onDialerClose()...");
-
-        // reset back to a short delay for the poke lock.
-        PhoneGlobals app = PhoneGlobals.getInstance();
-        app.updateWakeState();
-
-        mCM.unregisterForDisconnect(mHandler);
-
-        // Give the InCallScreen a chance to do any necessary UI updates.
-        if (mInCallScreen != null) {
-            mInCallScreen.onDialerClose(animate);
-        } else {
-            Log.e(LOG_TAG, "InCallScreen object was null during onDialerClose()");
-        }
-    }
-
-    /**
-     * Releases resources we keep around during a "dialer session"
-     * (see {@link startDialerSession}).
-     *
-     * It's safe to call this even without a corresponding
-     * startDialerSession call.
-     */
-    public void stopDialerSession() {
-        // release the tone generator.
-        synchronized (mToneGeneratorLock) {
-            if (mToneGenerator != null) {
-                mToneGenerator.release();
-                mToneGenerator = null;
-            }
-        }
-    }
-
-    /**
-     * Called externally (from InCallScreen) to play a DTMF Tone.
-     */
-    public boolean onDialerKeyDown(KeyEvent event) {
-        if (DBG) log("Notifying dtmf key down.");
-        if (mDialerKeyListener != null) {
-            return mDialerKeyListener.onKeyDown(event);
-        } else {
-            return false;
-        }
-    }
-
-    /**
-     * Called externally (from InCallScreen) to cancel the last DTMF Tone played.
-     */
-    public boolean onDialerKeyUp(KeyEvent event) {
-        if (DBG) log("Notifying dtmf key up.");
-        if (mDialerKeyListener != null) {
-            return mDialerKeyListener.onKeyUp(event);
-        } else {
-            return false;
-        }
-    }
-
-    /**
-     * setup the keys on the dialer activity, using the keymaps.
-     */
-    private void setupKeypad(DTMFTwelveKeyDialerView dialerView) {
-        // for each view id listed in the displaymap
-        View button;
-        for (int viewId : mDisplayMap.keySet()) {
-            // locate the view
-            button = dialerView.findViewById(viewId);
-            // Setup the listeners for the buttons
-            button.setOnTouchListener(this);
-            button.setClickable(true);
-            button.setOnKeyListener(this);
-            button.setOnHoverListener(this);
-            button.setOnClickListener(this);
-        }
-    }
-
-    /**
-     * catch the back and call buttons to return to the in call activity.
-     */
-    public boolean onKeyDown(int keyCode, KeyEvent event) {
-        // if (DBG) log("onKeyDown:  keyCode " + keyCode);
-        switch (keyCode) {
-            // finish for these events
-            case KeyEvent.KEYCODE_BACK:
-            case KeyEvent.KEYCODE_CALL:
-                if (DBG) log("exit requested");
-                closeDialer(true);  // do the "closing" animation
-                return true;
-        }
-        return mInCallScreen.onKeyDown(keyCode, event);
-    }
-
-    /**
-     * catch the back and call buttons to return to the in call activity.
-     */
-    public boolean onKeyUp(int keyCode, KeyEvent event) {
-        // if (DBG) log("onKeyUp:  keyCode " + keyCode);
-        return mInCallScreen.onKeyUp(keyCode, event);
-    }
-
-    /**
-     * Implemented for {@link android.view.View.OnHoverListener}. Handles touch
-     * events for accessibility when touch exploration is enabled.
-     */
-    @Override
-    public boolean onHover(View v, MotionEvent event) {
-        // When touch exploration is turned on, lifting a finger while inside
-        // the button's hover target bounds should perform a click action.
-        if (mAccessibilityManager.isEnabled()
-                && mAccessibilityManager.isTouchExplorationEnabled()) {
-            final int left = v.getPaddingLeft();
-            final int right = (v.getWidth() - v.getPaddingRight());
-            final int top = v.getPaddingTop();
-            final int bottom = (v.getHeight() - v.getPaddingBottom());
-
-            switch (event.getActionMasked()) {
-                case MotionEvent.ACTION_HOVER_ENTER:
-                    // Lift-to-type temporarily disables double-tap activation.
-                    v.setClickable(false);
-                    break;
-                case MotionEvent.ACTION_HOVER_EXIT:
-                    final int x = (int) event.getX();
-                    final int y = (int) event.getY();
-                    if ((x > left) && (x < right) && (y > top) && (y < bottom)) {
-                        v.performClick();
-                    }
-                    v.setClickable(true);
-                    break;
-            }
-        }
-
-        return false;
-    }
-
-    @Override
-    public void onClick(View v) {
-        // When accessibility is on, simulate press and release to preserve the
-        // semantic meaning of performClick(). Required for Braille support.
-        if (mAccessibilityManager.isEnabled()) {
-            final int id = v.getId();
-            // Checking the press state prevents double activation.
-            if (!v.isPressed() && mDisplayMap.containsKey(id)) {
-                processDtmf(mDisplayMap.get(id), true /* timedShortTone */);
-            }
-        }
-    }
-
-    /**
-     * Implemented for the TouchListener, process the touch events.
-     */
-    @Override
-    public boolean onTouch(View v, MotionEvent event) {
-        int viewId = v.getId();
-
-        // if the button is recognized
-        if (mDisplayMap.containsKey(viewId)) {
-            switch (event.getAction()) {
-                case MotionEvent.ACTION_DOWN:
-                    // Append the character mapped to this button, to the display.
-                    // start the tone
-                    processDtmf(mDisplayMap.get(viewId));
-                    break;
-                case MotionEvent.ACTION_UP:
-                case MotionEvent.ACTION_CANCEL:
-                    // stop the tone on ANY other event, except for MOVE.
-                    stopTone();
-                    break;
-            }
-            // do not return true [handled] here, since we want the
-            // press / click animation to be handled by the framework.
-        }
-        return false;
-    }
-
-    /**
-     * Implements View.OnKeyListener for the DTMF buttons.  Enables dialing with trackball/dpad.
-     */
-    @Override
-    public boolean onKey(View v, int keyCode, KeyEvent event) {
-        // if (DBG) log("onKey:  keyCode " + keyCode + ", view " + v);
-
-        if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
-            int viewId = v.getId();
-            if (mDisplayMap.containsKey(viewId)) {
-                switch (event.getAction()) {
-                case KeyEvent.ACTION_DOWN:
-                    if (event.getRepeatCount() == 0) {
-                        processDtmf(mDisplayMap.get(viewId));
-                    }
-                    break;
-                case KeyEvent.ACTION_UP:
-                    stopTone();
-                    break;
-                }
-                // do not return true [handled] here, since we want the
-                // press / click animation to be handled by the framework.
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Returns true if the dialer is in "open" state, meaning it is already visible *and* it
-     * isn't fading out. Note that during fade-out animation the View will return VISIBLE but
-     * will become GONE soon later, so you would want to use this method instead of
-     * {@link View#getVisibility()}.
-     *
-     * Fade-in animation, on the other hand, will set the View's visibility VISIBLE soon after
-     * the request, so we don't need to take care much of it. In other words,
-     * {@link #openDialer(boolean)} soon makes the visibility VISIBLE and thus this method will
-     * return true just after the method call.
-     *
-     * Note: during the very early stage of "open" state, users may not see the dialpad yet because
-     * of its fading-in animation, while they will see it shortly anyway. Similarly, during the
-     * early stage of "closed" state (opposite of "open" state), users may still see the dialpad
-     * due to fading-out animation, but it will vanish shortly and thus we can treat it as "closed",
-     * or "not open". To make the transition clearer, we call the state "open", not "shown" nor
-     * "visible".
-     */
-    public boolean isOpened() {
-        // Return whether or not the dialer view is visible.
-        // (Note that if we're in the middle of a fade-out animation, that
-        // also counts as "not visible" even though mDialerView itself is
-        // technically still VISIBLE.)
-        return (mDialerView != null
-                &&(mDialerView.getVisibility() == View.VISIBLE)
-                && !AnimationUtils.Fade.isFadingOut(mDialerView));
-    }
-
-    /**
-     * Forces the dialer into the "open" state.
-     * Does nothing if the dialer is already open.
-     *
-     * The "open" state includes the state the dialer is fading in.
-     * {@link InCallScreen#onDialerOpen(boolean)} will change visibility state and do
-     * actual animation.
-     *
-     * @param animate if true, open the dialer with an animation.
-     *
-     * @see #isOpened
-     */
-    public void openDialer(boolean animate) {
-        if (DBG) log("openDialer()...");
-
-        if (mDialerView == null && mDialerStub != null) {
-            if (DBG) log("Dialer isn't ready. Inflate it from ViewStub.");
-            mDialerView = (DTMFTwelveKeyDialerView) mDialerStub.inflate();
-            setupDialerView();
-            mDialerStub = null;
-        }
-
-        if (!isOpened()) {
-            // Make the dialer view visible.
-            if (animate) {
-                AnimationUtils.Fade.show(mDialerView);
-            } else {
-                mDialerView.setVisibility(View.VISIBLE);
-            }
-            onDialerOpen(animate);
-        }
-    }
-
-    /**
-     * Forces the dialer into the "closed" state.
-     * Does nothing if the dialer is already closed.
-     *
-     * {@link InCallScreen#onDialerOpen(boolean)} will change visibility state and do
-     * actual animation.
-     *
-     * @param animate if true, close the dialer with an animation.
-     *
-     * @see #isOpened
-     */
-    public void closeDialer(boolean animate) {
-        if (DBG) log("closeDialer()...");
-
-        if (isOpened()) {
-            // Hide the dialer view.
-            if (animate) {
-                AnimationUtils.Fade.hide(mDialerView, View.GONE);
-            } else {
-                mDialerView.setVisibility(View.GONE);
-            }
-            onDialerClose(animate);
-        }
-    }
-
-    /**
-     * Processes the specified digit as a DTMF key, by playing the
-     * appropriate DTMF tone, and appending the digit to the EditText
-     * field that displays the DTMF digits sent so far.
-     *
-     * @see #processDtmf(char, boolean)
-     */
-    private final void processDtmf(char c) {
-        processDtmf(c, false);
-    }
-
-    /**
-     * Processes the specified digit as a DTMF key, by playing the appropriate
-     * DTMF tone (or short tone if requested), and appending the digit to the
-     * EditText field that displays the DTMF digits sent so far.
-     */
-    private final void processDtmf(char c, boolean timedShortTone) {
-        // if it is a valid key, then update the display and send the dtmf tone.
-        if (PhoneNumberUtils.is12Key(c)) {
-            if (DBG) log("updating display and sending dtmf tone for '" + c + "'");
-
-            // Append this key to the "digits" widget.
-            if (mDialpadDigits != null) {
-                // TODO: maybe *don't* manually append this digit if
-                // mDialpadDigits is focused and this key came from the HW
-                // keyboard, since in that case the EditText field will
-                // get the key event directly and automatically appends
-                // whetever the user types.
-                // (Or, a cleaner fix would be to just make mDialpadDigits
-                // *not* handle HW key presses.  That seems to be more
-                // complicated than just setting focusable="false" on it,
-                // though.)
-                mDialpadDigits.getText().append(c);
-            }
-
-            // Play the tone if it exists.
-            if (mToneMap.containsKey(c)) {
-                // begin tone playback.
-                startTone(c, timedShortTone);
-            }
-        } else if (DBG) {
-            log("ignoring dtmf request for '" + c + "'");
-        }
-
-        // Any DTMF keypress counts as explicit "user activity".
-        PhoneGlobals.getInstance().pokeUserActivity();
-    }
-
-    /**
-     * Clears out the display of "DTMF digits typed so far" that's kept in
-     * mDialpadDigits.
-     *
-     * The InCallScreen is responsible for calling this method any time a
-     * new call becomes active (or, more simply, any time a call ends).
-     * This is how we make sure that the "history" of DTMF digits you type
-     * doesn't persist from one call to the next.
-     *
-     * TODO: it might be more elegent if the dialpad itself could remember
-     * the call that we're associated with, and clear the digits if the
-     * "current call" has changed since last time.  (This would require
-     * some unique identifier that's different for each call.  We can't
-     * just use the foreground Call object, since that's a singleton that
-     * lasts the whole life of the phone process.  Instead, maybe look at
-     * the Connection object that comes back from getEarliestConnection()?
-     * Or getEarliestConnectTime()?)
-     *
-     * Or to be even fancier, we could keep a mapping of *multiple*
-     * "active calls" to DTMF strings.  That way you could have two lines
-     * in use and swap calls multiple times, and we'd still remember the
-     * digits for each call.  (But that's such an obscure use case that
-     * it's probably not worth the extra complexity.)
-     */
-    public void clearDigits() {
-        if (DBG) log("clearDigits()...");
-
-        if (mDialpadDigits != null) {
-            mDialpadDigits.setText("");
-        }
-
-        setDialpadContext("");
-    }
-
-    /**
-     * Set the context text (hint) to show in the dialpad Digits EditText.
-     *
-     * This is currently only used for displaying a value for "Voice Mail"
-     * calls since they default to the dialpad and we want to give users better
-     * context when they dial voicemail.
-     *
-     * TODO: Is there value in extending this functionality for all contacts
-     * and not just Voice Mail calls?
-     * TODO: This should include setting the digits as well as the context
-     * once we start saving the digits properly...and properly in this case
-     * ideally means moving some of processDtmf() out of this class.
-     */
-    public void setDialpadContext(String contextValue) {
-        if (mDialpadDigits != null) {
-            if (contextValue == null) {
-              contextValue = "";
-            }
-            final SpannableString hint = new SpannableString(contextValue);
-            hint.setSpan(new RelativeSizeSpan(0.8f), 0, hint.length(), 0);
-            mDialpadDigits.setHint(hint);
-        }
-    }
-
-    /**
-     * Plays the local tone based the phone type.
-     */
-    public void startTone(char c, boolean timedShortTone) {
-        // Only play the tone if it exists.
-        if (!mToneMap.containsKey(c)) {
-            return;
-        }
-
-        if (!mInCallScreen.okToDialDTMFTones()) {
-            return;
-        }
-
-        // Read the settings as it may be changed by the user during the call
-        Phone phone = mCM.getFgPhone();
-        mShortTone = useShortDtmfTones(phone, phone.getContext());
-
-        // Before we go ahead and start a tone, we need to make sure that any pending
-        // stop-tone message is processed.
-        if (mHandler.hasMessages(DTMF_STOP)) {
-            mHandler.removeMessages(DTMF_STOP);
-            stopTone();
-        }
-
-        if (DBG) log("startDtmfTone()...");
-
-        // For Short DTMF we need to play the local tone for fixed duration
-        if (mShortTone) {
-            sendShortDtmfToNetwork(c);
-        } else {
-            // Pass as a char to be sent to network
-            if (DBG) log("send long dtmf for " + c);
-            mCM.startDtmf(c);
-
-            // If it is a timed tone, queue up the stop command in DTMF_DURATION_MS.
-            if (timedShortTone) {
-                mHandler.sendMessageDelayed(mHandler.obtainMessage(DTMF_STOP), DTMF_DURATION_MS);
-            }
-        }
-        startLocalToneIfNeeded(c);
-    }
-
-
-    /**
-     * Plays the local tone based the phone type, optionally forcing a short
-     * tone.
-     */
-    public void startLocalToneIfNeeded(char c) {
-        // if local tone playback is enabled, start it.
-        // Only play the tone if it exists.
-        if (!mToneMap.containsKey(c)) {
-            return;
-        }
-        if (mLocalToneEnabled) {
-            synchronized (mToneGeneratorLock) {
-                if (mToneGenerator == null) {
-                    if (DBG) log("startDtmfTone: mToneGenerator == null, tone: " + c);
-                } else {
-                    if (DBG) log("starting local tone " + c);
-                    int toneDuration = -1;
-                    if (mShortTone) {
-                        toneDuration = DTMF_DURATION_MS;
-                    }
-                    mToneGenerator.startTone(mToneMap.get(c), toneDuration);
-                }
-            }
-        }
-    }
-
-    /**
-     * Check to see if the keyEvent is dialable.
-     */
-    boolean isKeyEventAcceptable (KeyEvent event) {
-        return (mDialerKeyListener != null && mDialerKeyListener.isKeyEventAcceptable(event));
-    }
-
-    /**
-     * static logging method
-     */
-    private static void log(String msg) {
-        Log.d(LOG_TAG, msg);
-    }
-
-    /**
-     * Stops the local tone based on the phone type.
-     */
-    public void stopTone() {
-        // We do not rely on InCallScreen#okToDialDTMFTones() here since it is ok to stop tones
-        // without starting them.
-
-        if (!mShortTone) {
-            if (DBG) log("stopping remote tone.");
-            mCM.stopDtmf();
-            stopLocalToneIfNeeded();
-        }
-    }
-
-    /**
-     * Stops the local tone based on the phone type.
-     */
-    public void stopLocalToneIfNeeded() {
-        if (!mShortTone) {
-            // if local tone playback is enabled, stop it.
-            if (DBG) log("trying to stop local tone...");
-            if (mLocalToneEnabled) {
-                synchronized (mToneGeneratorLock) {
-                    if (mToneGenerator == null) {
-                        if (DBG) log("stopLocalTone: mToneGenerator == null");
-                    } else {
-                        if (DBG) log("stopping local tone.");
-                        mToneGenerator.stopTone();
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Sends the dtmf character over the network for short DTMF settings
-     * When the characters are entered in quick succession,
-     * the characters are queued before sending over the network.
-     */
-    private void sendShortDtmfToNetwork(char dtmfDigit) {
-        synchronized (mDTMFQueue) {
-            if (mDTMFBurstCnfPending == true) {
-                // Insert the dtmf char to the queue
-                mDTMFQueue.add(new Character(dtmfDigit));
-            } else {
-                String dtmfStr = Character.toString(dtmfDigit);
-                mCM.sendBurstDtmf(dtmfStr, 0, 0, mHandler.obtainMessage(DTMF_SEND_CNF));
-                // Set flag to indicate wait for Telephony confirmation.
-                mDTMFBurstCnfPending = true;
-            }
-        }
-    }
-
-    /**
-     * Handles Burst Dtmf Confirmation from the Framework.
-     */
-    void handleBurstDtmfConfirmation() {
-        Character dtmfChar = null;
-        synchronized (mDTMFQueue) {
-            mDTMFBurstCnfPending = false;
-            if (!mDTMFQueue.isEmpty()) {
-                dtmfChar = mDTMFQueue.remove();
-                Log.i(LOG_TAG, "The dtmf character removed from queue" + dtmfChar);
-            }
-        }
-        if (dtmfChar != null) {
-            sendShortDtmfToNetwork(dtmfChar);
-        }
-    }
-
-    /**
-     * On GSM devices, we never use short tones.
-     * On CDMA devices, it depends upon the settings.
-     */
-    private static boolean useShortDtmfTones(Phone phone, Context context) {
-        int phoneType = phone.getPhoneType();
-        if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
-            return false;
-        } else if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-            int toneType = android.provider.Settings.System.getInt(
-                    context.getContentResolver(),
-                    Settings.System.DTMF_TONE_TYPE_WHEN_DIALING,
-                    Constants.DTMF_TONE_TYPE_NORMAL);
-            if (toneType == Constants.DTMF_TONE_TYPE_NORMAL) {
-                return true;
-            } else {
-                return false;
-            }
-        } else if (phoneType == PhoneConstants.PHONE_TYPE_SIP) {
-            return false;
-        } else {
-            throw new IllegalStateException("Unexpected phone type: " + phoneType);
-        }
-    }
-
-}
diff --git a/src/com/android/phone/DTMFTwelveKeyDialerView.java b/src/com/android/phone/DTMFTwelveKeyDialerView.java
deleted file mode 100644
index e0502b7..0000000
--- a/src/com/android/phone/DTMFTwelveKeyDialerView.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2008 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.content.Context;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.FocusFinder;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewConfiguration;
-import android.view.ViewGroup;
-import android.widget.LinearLayout;
-
-import java.util.ArrayList;
-
-/**
- * DTMFTwelveKeyDialerView is the view logic that the DTMFDialer uses.
- * This is really a thin wrapper around Linear Layout that intercepts
- * some user interactions to provide the correct UI behaviour for the
- * dialer.
- *
- * See dtmf_twelve_key_dialer_view.xml.
- */
-class DTMFTwelveKeyDialerView extends LinearLayout {
-
-    private static final String LOG_TAG = "PHONE/DTMFTwelveKeyDialerView";
-    private static final boolean DBG = false;
-
-    private DTMFTwelveKeyDialer mDialer;
-
-
-    public DTMFTwelveKeyDialerView (Context context) {
-        super(context);
-    }
-
-    public DTMFTwelveKeyDialerView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    void setDialer (DTMFTwelveKeyDialer dialer) {
-        mDialer = dialer;
-    }
-
-    /**
-     * Normally we ignore everything except for the BACK and CALL keys.
-     * For those, we pass them to the model (and then the InCallScreen).
-     */
-    @Override
-    public boolean dispatchKeyEvent(KeyEvent event) {
-        if (DBG) log("dispatchKeyEvent(" + event + ")...");
-
-        int keyCode = event.getKeyCode();
-        if (mDialer != null) {
-            switch (keyCode) {
-                case KeyEvent.KEYCODE_BACK:
-                case KeyEvent.KEYCODE_CALL:
-                    return event.isDown() ? mDialer.onKeyDown(keyCode, event) :
-                        mDialer.onKeyUp(keyCode, event);
-            }
-        }
-
-        if (DBG) log("==> dispatchKeyEvent: forwarding event to the DTMFDialer");
-        return super.dispatchKeyEvent(event);
-    }
-
-    private void log(String msg) {
-        Log.d(LOG_TAG, msg);
-    }
-}
diff --git a/src/com/android/phone/EmergencyCallHelper.java b/src/com/android/phone/EmergencyCallHelper.java
index a23e3e0..866f2be 100644
--- a/src/com/android/phone/EmergencyCallHelper.java
+++ b/src/com/android/phone/EmergencyCallHelper.java
@@ -21,7 +21,6 @@
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.phone.Constants.CallStatusCode;
-import com.android.phone.InCallUiState.ProgressIndicationType;
 
 import android.content.Context;
 import android.content.Intent;
@@ -183,10 +182,6 @@
         // for some reason.
         startRetryTimer();
 
-        // And finally, let the in-call UI know that we need to
-        // display the "Turning on radio..." progress indication.
-        mApp.inCallUiState.setProgressIndication(ProgressIndicationType.TURNING_ON_RADIO);
-
         // (Our caller is responsible for calling mApp.displayCallScreen().)
     }
 
@@ -220,14 +215,7 @@
             // Deregister for the service state change events.
             unregisterForServiceStateChanged();
 
-            // Take down the "Turning on radio..." indication.
-            mApp.inCallUiState.clearProgressIndication();
-
             placeEmergencyCall();
-
-            // The in-call UI is probably still up at this point,
-            // but make sure of that:
-            mApp.displayCallScreen();
         } else {
             // The service state changed, but we're still not ready to call yet.
             // (This probably was the transition from STATE_POWER_OFF to
@@ -307,9 +295,6 @@
             // these any more now that the radio is powered-on.
             unregisterForServiceStateChanged();
 
-            // Take down the "Turning on radio..." indication.
-            mApp.inCallUiState.clearProgressIndication();
-
             placeEmergencyCall();  // If the call fails, placeEmergencyCall()
                                    // will schedule a retry.
         } else {
@@ -324,10 +309,6 @@
             // totally if we've had too many failures.)
             scheduleRetryOrBailOut();
         }
-
-        // Finally, the in-call UI is probably still up at this point,
-        // but make sure of that:
-        mApp.displayCallScreen();
     }
 
     /**
@@ -441,13 +422,9 @@
         if (mNumRetriesSoFar > MAX_NUM_RETRIES) {
             Log.w(TAG, "scheduleRetryOrBailOut: hit MAX_NUM_RETRIES; giving up...");
             cleanup();
-            // ...and have the InCallScreen display a generic failure
-            // message.
-            mApp.inCallUiState.setPendingCallStatusCode(CallStatusCode.CALL_FAILED);
         } else {
             if (DBG) log("- Scheduling another retry...");
             startRetryTimer();
-            mApp.inCallUiState.setProgressIndication(ProgressIndicationType.RETRYING);
         }
     }
 
@@ -475,9 +452,6 @@
     private void cleanup() {
         if (DBG) log("cleanup()...");
 
-        // Take down the "Turning on radio..." indication.
-        mApp.inCallUiState.clearProgressIndication();
-
         unregisterForServiceStateChanged();
         unregisterForDisconnect();
         cancelRetryTimer();
@@ -490,10 +464,6 @@
             }
             mPartialWakeLock = null;
         }
-
-        // And finally, ask the in-call UI to refresh itself (to clean up the
-        // progress indication if necessary), if it's currently visible.
-        mApp.updateInCallScreen();
     }
 
     private void startRetryTimer() {
diff --git a/src/com/android/phone/InCallControlState.java b/src/com/android/phone/InCallControlState.java
deleted file mode 100644
index 38eaf5c..0000000
--- a/src/com/android/phone/InCallControlState.java
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * 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.telephony.PhoneNumberUtils;
-import android.util.Log;
-
-import com.android.internal.telephony.Call;
-import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.CallManager;
-import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.TelephonyCapabilities;
-
-/**
- * Helper class to keep track of enabledness, visibility, and "on/off"
- * or "checked" state of the various controls available in the in-call
- * UI, based on the current telephony state.
- *
- * This class is independent of the exact UI controls used on any given
- * device.  To avoid cluttering up the "view" code (i.e. InCallTouchUi)
- * with logic about which functions are available right now, we instead
- * have that logic here, and provide simple boolean flags to indicate the
- * state and/or enabledness of all possible in-call user operations.
- *
- * (In other words, this is the "model" that corresponds to the "view"
- * implemented by InCallTouchUi.)
- */
-public class InCallControlState {
-    private static final String LOG_TAG = "InCallControlState";
-    private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
-
-    private final BluetoothManager mBluetoothManager;
-    private InCallScreen mInCallScreen;
-    private CallManager mCM;
-
-    //
-    // Our "public API": Boolean flags to indicate the state and/or
-    // enabledness of all possible in-call user operations:
-    //
-
-    public boolean manageConferenceVisible;
-    public boolean manageConferenceEnabled;
-    //
-    public boolean canAddCall;
-    //
-    public boolean canEndCall;
-    //
-    public boolean canSwap;
-    public boolean canMerge;
-    //
-    public boolean bluetoothEnabled;
-    public boolean bluetoothIndicatorOn;
-    //
-    public boolean speakerEnabled;
-    public boolean speakerOn;
-    //
-    public boolean canMute;
-    public boolean muteIndicatorOn;
-    //
-    public boolean dialpadEnabled;
-    public boolean dialpadVisible;
-    //
-    /** True if the "Hold" function is *ever* available on this device */
-    public boolean supportsHold;
-    /** True if the call is currently on hold */
-    public boolean onHold;
-    /** True if the "Hold" or "Unhold" function should be available right now */
-    // TODO: this name is misleading.  Let's break this apart into
-    // separate canHold and canUnhold flags, and have the caller look at
-    // "canHold || canUnhold" to decide whether the hold/unhold UI element
-    // should be visible.
-    public boolean canHold;
-
-
-    public InCallControlState(InCallScreen inCallScreen, CallManager cm,
-            BluetoothManager bluetoothManager) {
-        if (DBG) log("InCallControlState constructor...");
-        mInCallScreen = inCallScreen;
-        mCM = cm;
-        mBluetoothManager = bluetoothManager;
-    }
-
-    /**
-     * Updates all our public boolean flags based on the current state of
-     * the Phone.
-     */
-    public void update() {
-        final PhoneConstants.State state = mCM.getState();  // coarse-grained voice call state
-        final Call fgCall = mCM.getActiveFgCall();
-        final Call.State fgCallState = fgCall.getState();
-        final boolean hasActiveForegroundCall = (fgCallState == Call.State.ACTIVE);
-        final boolean hasHoldingCall = mCM.hasActiveBgCall();
-
-        // Manage conference:
-        if (TelephonyCapabilities.supportsConferenceCallManagement(fgCall.getPhone())) {
-            // This item is visible only if the foreground call is a
-            // conference call, and it's enabled unless the "Manage
-            // conference" UI is already up.
-            manageConferenceVisible = PhoneUtils.isConferenceCall(fgCall);
-            manageConferenceEnabled =
-                    manageConferenceVisible && !mInCallScreen.isManageConferenceMode();
-        } else {
-            // This device has no concept of managing a conference call.
-            manageConferenceVisible = false;
-            manageConferenceEnabled = false;
-        }
-
-        // "Add call":
-        canAddCall = PhoneUtils.okToAddCall(mCM);
-
-        // "End call": always enabled unless the phone is totally idle.
-        // Note that while the phone is ringing, the InCallTouchUi widget isn't
-        // visible at all, so the state of the End button doesn't matter.  However
-        // we *do* still set canEndCall to true in this case, purely to prevent a
-        // UI glitch when the InCallTouchUi widget first appears, immediately after
-        // answering an incoming call.
-        canEndCall = (mCM.hasActiveFgCall() || mCM.hasActiveRingingCall() || mCM.hasActiveBgCall());
-
-        // Swap / merge calls
-        canSwap = PhoneUtils.okToSwapCalls(mCM);
-        canMerge = PhoneUtils.okToMergeCalls(mCM);
-
-        // "Bluetooth":
-        if (mBluetoothManager.isBluetoothAvailable()) {
-            bluetoothEnabled = true;
-            bluetoothIndicatorOn = mBluetoothManager.isBluetoothAudioConnectedOrPending();
-        } else {
-            bluetoothEnabled = false;
-            bluetoothIndicatorOn = false;
-        }
-
-        // "Speaker": always enabled unless the phone is totally idle.
-        // The current speaker state comes from the AudioManager.
-        speakerEnabled = (state != PhoneConstants.State.IDLE);
-        speakerOn = PhoneUtils.isSpeakerOn(mInCallScreen);
-
-        // "Mute": only enabled when the foreground call is ACTIVE.
-        // (It's meaningless while on hold, or while DIALING/ALERTING.)
-        // It's also explicitly disabled during emergency calls or if
-        // emergency callback mode (ECM) is active.
-        Connection c = fgCall.getLatestConnection();
-        boolean isEmergencyCall = false;
-        if (c != null) isEmergencyCall =
-                PhoneNumberUtils.isLocalEmergencyNumber(c.getAddress(),
-                                                        fgCall.getPhone().getContext());
-        boolean isECM = PhoneUtils.isPhoneInEcm(fgCall.getPhone());
-        if (isEmergencyCall || isECM) {  // disable "Mute" item
-            canMute = false;
-            muteIndicatorOn = false;
-        } else {
-            canMute = hasActiveForegroundCall;
-            muteIndicatorOn = PhoneUtils.getMute();
-        }
-
-        // "Dialpad": Enabled only when it's OK to use the dialpad in the
-        // first place.
-        dialpadEnabled = mInCallScreen.okToShowDialpad();
-
-        // Also keep track of whether the dialpad is currently "opened"
-        // (i.e. visible).
-        dialpadVisible = mInCallScreen.isDialerOpened();
-
-        // "Hold:
-        if (TelephonyCapabilities.supportsHoldAndUnhold(fgCall.getPhone())) {
-            // This phone has the concept of explicit "Hold" and "Unhold" actions.
-            supportsHold = true;
-            // "On hold" means that there's a holding call and
-            // *no* foreground call.  (If there *is* a foreground call,
-            // that's "two lines in use".)
-            onHold = hasHoldingCall && (fgCallState == Call.State.IDLE);
-            // The "Hold" control is disabled entirely if there's
-            // no way to either hold or unhold in the current state.
-            boolean okToHold = hasActiveForegroundCall && !hasHoldingCall;
-            boolean okToUnhold = onHold;
-            canHold = okToHold || okToUnhold;
-        } else if (hasHoldingCall && (fgCallState == Call.State.IDLE)) {
-            // Even when foreground phone device doesn't support hold/unhold, phone devices
-            // for background holding calls may do.
-            //
-            // If the foreground call is ACTIVE,  we should turn on "swap" button instead.
-            final Call bgCall = mCM.getFirstActiveBgCall();
-            if (bgCall != null &&
-                    TelephonyCapabilities.supportsHoldAndUnhold(bgCall.getPhone())) {
-                supportsHold = true;
-                onHold = true;
-                canHold = true;
-            }
-        } else {
-            // This device has no concept of "putting a call on hold."
-            supportsHold = false;
-            onHold = false;
-            canHold = false;
-        }
-
-        if (DBG) dumpState();
-    }
-
-    public void dumpState() {
-        log("InCallControlState:");
-        log("  manageConferenceVisible: " + manageConferenceVisible);
-        log("  manageConferenceEnabled: " + manageConferenceEnabled);
-        log("  canAddCall: " + canAddCall);
-        log("  canEndCall: " + canEndCall);
-        log("  canSwap: " + canSwap);
-        log("  canMerge: " + canMerge);
-        log("  bluetoothEnabled: " + bluetoothEnabled);
-        log("  bluetoothIndicatorOn: " + bluetoothIndicatorOn);
-        log("  speakerEnabled: " + speakerEnabled);
-        log("  speakerOn: " + speakerOn);
-        log("  canMute: " + canMute);
-        log("  muteIndicatorOn: " + muteIndicatorOn);
-        log("  dialpadEnabled: " + dialpadEnabled);
-        log("  dialpadVisible: " + dialpadVisible);
-        log("  onHold: " + onHold);
-        log("  canHold: " + canHold);
-    }
-
-    private void log(String msg) {
-        Log.d(LOG_TAG, msg);
-    }
-}
diff --git a/src/com/android/phone/InCallScreen.java b/src/com/android/phone/InCallScreen.java
index 53cd40d..b18cc43 100644
--- a/src/com/android/phone/InCallScreen.java
+++ b/src/com/android/phone/InCallScreen.java
@@ -16,101 +16,7 @@
 
 package com.android.phone;
 
-import android.app.Activity;
-import android.app.ActivityOptions;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.ProgressDialog;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothHeadset;
-import android.bluetooth.BluetoothProfile;
-import android.bluetooth.IBluetoothHeadsetPhone;
-import android.content.ActivityNotFoundException;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnCancelListener;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.graphics.Typeface;
-import android.media.AudioManager;
-import android.os.AsyncResult;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.telephony.ServiceState;
-import android.text.TextUtils;
-import android.text.method.DialerKeyListener;
-import android.util.EventLog;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewStub;
-import android.view.Window;
-import android.view.WindowManager;
-import android.view.accessibility.AccessibilityEvent;
-import android.widget.EditText;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-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.Connection;
-import com.android.internal.telephony.MmiCode;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.TelephonyCapabilities;
-import com.android.phone.Constants.CallStatusCode;
-import com.android.phone.InCallUiState.InCallScreenMode;
-import com.android.phone.OtaUtils.CdmaOtaScreenState;
-
-import java.util.List;
-
-
-/**
- * Phone app "in call" screen.
- */
-public class InCallScreen extends Activity
-        implements View.OnClickListener {
-    private static final String LOG_TAG = "InCallScreen";
-
-    private static final boolean DBG =
-            (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
-    private static final boolean VDBG = (PhoneGlobals.DBG_LEVEL >= 2);
-
-    /**
-     * Intent extra used to specify whether the DTMF dialpad should be
-     * initially visible when bringing up the InCallScreen.  (If this
-     * extra is present, the dialpad will be initially shown if the extra
-     * has the boolean value true, and initially hidden otherwise.)
-     */
-    // TODO: Should be EXTRA_SHOW_DIALPAD for consistency.
-    static final String SHOW_DIALPAD_EXTRA = "com.android.phone.ShowDialpad";
-
-    // Amount of time (in msec) that we display the "Call ended" state.
-    // The "short" value is for calls ended by the local user, and the
-    // "long" value is for calls ended by the remote caller.
-    private static final int CALL_ENDED_SHORT_DELAY =  200;  // msec
-    private static final int CALL_ENDED_LONG_DELAY = 2000;  // msec
-    private static final int CALL_ENDED_EXTRA_LONG_DELAY = 5000;  // msec
-
-    // Amount of time that we display the PAUSE alert Dialog showing the
-    // post dial string yet to be send out to the n/w
-    private static final int PAUSE_PROMPT_DIALOG_TIMEOUT = 2000;  //msec
-
-    // Amount of time that we display the provider info if applicable.
-    private static final int PROVIDER_INFO_TIMEOUT = 5000;  // msec
-
+public class InCallScreen {
     // These are values for the settings of the auto retry mode:
     // 0 = disabled
     // 1 = enabled
@@ -118,4071 +24,4 @@
     // they should be moved to Settings where the value is being looked up in the first place
     static final int AUTO_RETRY_OFF = 0;
     static final int AUTO_RETRY_ON = 1;
-
-    // Message codes; see mHandler below.
-    // Note message codes < 100 are reserved for the PhoneApp.
-    private static final int PHONE_STATE_CHANGED = 101;
-    private static final int PHONE_DISCONNECT = 102;
-    private static final int EVENT_HEADSET_PLUG_STATE_CHANGED = 103;
-    private static final int POST_ON_DIAL_CHARS = 104;
-    private static final int WILD_PROMPT_CHAR_ENTERED = 105;
-    private static final int ADD_VOICEMAIL_NUMBER = 106;
-    private static final int DONT_ADD_VOICEMAIL_NUMBER = 107;
-    private static final int DELAYED_CLEANUP_AFTER_DISCONNECT = 108;
-    private static final int SUPP_SERVICE_FAILED = 110;
-    private static final int PHONE_CDMA_CALL_WAITING = 115;
-    private static final int REQUEST_CLOSE_SPC_ERROR_NOTICE = 118;
-    private static final int REQUEST_CLOSE_OTA_FAILURE_NOTICE = 119;
-    private static final int EVENT_PAUSE_DIALOG_COMPLETE = 120;
-    private static final int EVENT_HIDE_PROVIDER_INFO = 121;  // Time to remove the info.
-    private static final int REQUEST_UPDATE_SCREEN = 122;
-    private static final int PHONE_INCOMING_RING = 123;
-    private static final int PHONE_NEW_RINGING_CONNECTION = 124;
-
-    // When InCallScreenMode is UNDEFINED set the default action
-    // to ACTION_UNDEFINED so if we are resumed the activity will
-    // know its undefined. In particular checkIsOtaCall will return
-    // false.
-    public static final String ACTION_UNDEFINED = "com.android.phone.InCallScreen.UNDEFINED";
-
-    /** Status codes returned from syncWithPhoneState(). */
-    private enum SyncWithPhoneStateStatus {
-        /**
-         * Successfully updated our internal state based on the telephony state.
-         */
-        SUCCESS,
-
-        /**
-         * There was no phone state to sync with (i.e. the phone was
-         * completely idle).  In most cases this means that the
-         * in-call UI shouldn't be visible in the first place, unless
-         * we need to remain in the foreground while displaying an
-         * error message.
-         */
-        PHONE_NOT_IN_USE
-    }
-
-    private boolean mRegisteredForPhoneStates;
-
-    private PhoneGlobals mApp;
-    private CallManager mCM;
-
-    // TODO: need to clean up all remaining uses of mPhone.
-    // (There may be more than one Phone instance on the device, so it's wrong
-    // to just keep a single mPhone field.  Instead, any time we need a Phone
-    // reference we should get it dynamically from the CallManager, probably
-    // based on the current foreground Call.)
-    private Phone mPhone;
-
-    /** Main in-call UI elements. */
-    private CallCard mCallCard;
-
-    // UI controls:
-    private InCallControlState mInCallControlState;
-    private InCallTouchUi mInCallTouchUi;
-    private RespondViaSmsManager mRespondViaSmsManager;  // see internalRespondViaSms()
-    private ManageConferenceUtils mManageConferenceUtils;
-
-    // DTMF Dialer controller and its view:
-    private DTMFTwelveKeyDialer mDialer;
-
-    private EditText mWildPromptText;
-
-    // Various dialogs we bring up (see dismissAllDialogs()).
-    // TODO: convert these all to use the "managed dialogs" framework.
-    //
-    // The MMI started dialog can actually be one of 2 items:
-    //   1. An alert dialog if the MMI code is a normal MMI
-    //   2. A progress dialog if the user requested a USSD
-    private Dialog mMmiStartedDialog;
-    private AlertDialog mMissingVoicemailDialog;
-    private AlertDialog mGenericErrorDialog;
-    private AlertDialog mSuppServiceFailureDialog;
-    private AlertDialog mWaitPromptDialog;
-    private AlertDialog mWildPromptDialog;
-    private AlertDialog mCallLostDialog;
-    private AlertDialog mPausePromptDialog;
-    private AlertDialog mExitingECMDialog;
-    // NOTE: if you add a new dialog here, be sure to add it to dismissAllDialogs() also.
-
-    // ProgressDialog created by showProgressIndication()
-    private ProgressDialog mProgressDialog;
-
-    // TODO: If the Activity class ever provides an easy way to get the
-    // current "activity lifecycle" state, we can remove these flags.
-    private boolean mIsDestroyed = false;
-    private boolean mIsForegroundActivity = false;
-    private PowerManager mPowerManager;
-
-    // For use with Pause/Wait dialogs
-    private String mPostDialStrAfterPause;
-    private boolean mPauseInProgress = false;
-
-    // Info about the most-recently-disconnected Connection, which is used
-    // to determine what should happen when exiting the InCallScreen after a
-    // call.  (This info is set by onDisconnect(), and used by
-    // delayedCleanupAfterDisconnect().)
-    private Connection.DisconnectCause mLastDisconnectCause;
-
-    /** In-call audio routing options; see switchInCallAudio(). */
-    public enum InCallAudioMode {
-        SPEAKER,    // Speakerphone
-        BLUETOOTH,  // Bluetooth headset (if available)
-        EARPIECE,   // Handset earpiece (or wired headset, if connected)
-    }
-
-
-    private Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            if (mIsDestroyed) {
-                if (DBG) log("Handler: ignoring message " + msg + "; we're destroyed!");
-                return;
-            }
-            if (!mIsForegroundActivity) {
-                if (DBG) log("Handler: handling message " + msg + " while not in foreground");
-                // Continue anyway; some of the messages below *want* to
-                // be handled even if we're not the foreground activity
-                // (like DELAYED_CLEANUP_AFTER_DISCONNECT), and they all
-                // should at least be safe to handle if we're not in the
-                // foreground...
-            }
-
-            switch (msg.what) {
-                case SUPP_SERVICE_FAILED:
-                    onSuppServiceFailed((AsyncResult) msg.obj);
-                    break;
-
-                case PHONE_STATE_CHANGED:
-                    onPhoneStateChanged((AsyncResult) msg.obj);
-                    break;
-
-                case PHONE_DISCONNECT:
-                    onDisconnect((AsyncResult) msg.obj);
-                    break;
-
-                case EVENT_HEADSET_PLUG_STATE_CHANGED:
-                    // Update the in-call UI, since some UI elements (such
-                    // as the "Speaker" button) may change state depending on
-                    // whether a headset is plugged in.
-                    // TODO: A full updateScreen() is overkill here, since
-                    // the value of PhoneApp.isHeadsetPlugged() only affects a
-                    // single onscreen UI element.  (But even a full updateScreen()
-                    // is still pretty cheap, so let's keep this simple
-                    // for now.)
-                    updateScreen();
-
-                    // Also, force the "audio mode" popup to refresh itself if
-                    // it's visible, since one of its items is either "Wired
-                    // headset" or "Handset earpiece" depending on whether the
-                    // headset is plugged in or not.
-                    mInCallTouchUi.refreshAudioModePopup();  // safe even if the popup's not active
-
-                    break;
-
-                // TODO: sort out MMI code (probably we should remove this method entirely).
-                // See also MMI handling code in onResume()
-                // case PhoneApp.MMI_INITIATE:
-                // onMMIInitiate((AsyncResult) msg.obj);
-                //    break;
-
-                case PhoneGlobals.MMI_CANCEL:
-                    onMMICancel();
-                    break;
-
-                // handle the mmi complete message.
-                // since the message display class has been replaced with
-                // a system dialog in PhoneUtils.displayMMIComplete(), we
-                // should finish the activity here to close the window.
-                case PhoneGlobals.MMI_COMPLETE:
-                    onMMIComplete((MmiCode) ((AsyncResult) msg.obj).result);
-                    break;
-
-                case POST_ON_DIAL_CHARS:
-                    handlePostOnDialChars((AsyncResult) msg.obj, (char) msg.arg1);
-                    break;
-
-                case ADD_VOICEMAIL_NUMBER:
-                    addVoiceMailNumberPanel();
-                    break;
-
-                case DONT_ADD_VOICEMAIL_NUMBER:
-                    dontAddVoiceMailNumber();
-                    break;
-
-                case DELAYED_CLEANUP_AFTER_DISCONNECT:
-                    delayedCleanupAfterDisconnect();
-                    break;
-
-                case PHONE_CDMA_CALL_WAITING:
-                    if (DBG) log("Received PHONE_CDMA_CALL_WAITING event ...");
-                    Connection cn = mCM.getFirstActiveRingingCall().getLatestConnection();
-
-                    // Only proceed if we get a valid connection object
-                    if (cn != null) {
-                        // Finally update screen with Call waiting info and request
-                        // screen to wake up
-                        updateScreen();
-                        mApp.updateWakeState();
-                    }
-                    break;
-
-                case REQUEST_CLOSE_SPC_ERROR_NOTICE:
-                    if (mApp.otaUtils != null) {
-                        mApp.otaUtils.onOtaCloseSpcNotice();
-                    }
-                    break;
-
-                case REQUEST_CLOSE_OTA_FAILURE_NOTICE:
-                    if (mApp.otaUtils != null) {
-                        mApp.otaUtils.onOtaCloseFailureNotice();
-                    }
-                    break;
-
-                case EVENT_PAUSE_DIALOG_COMPLETE:
-                    if (mPausePromptDialog != null) {
-                        if (DBG) log("- DISMISSING mPausePromptDialog.");
-                        mPausePromptDialog.dismiss();  // safe even if already dismissed
-                        mPausePromptDialog = null;
-                    }
-                    break;
-
-                case EVENT_HIDE_PROVIDER_INFO:
-                    if (mCallCard != null) {
-                        mCallCard.updateState(mCM);
-                    }
-                    break;
-                case REQUEST_UPDATE_SCREEN:
-                    updateScreen();
-                    break;
-
-                case PHONE_INCOMING_RING:
-                    onIncomingRing();
-                    break;
-
-                case PHONE_NEW_RINGING_CONNECTION:
-                    onNewRingingConnection();
-                    break;
-
-                default:
-                    Log.wtf(LOG_TAG, "mHandler: unexpected message: " + msg);
-                    break;
-            }
-        }
-    };
-
-    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                String action = intent.getAction();
-                if (action.equals(Intent.ACTION_HEADSET_PLUG)) {
-                    // Listen for ACTION_HEADSET_PLUG broadcasts so that we
-                    // can update the onscreen UI when the headset state changes.
-                    // if (DBG) log("mReceiver: ACTION_HEADSET_PLUG");
-                    // if (DBG) log("==> intent: " + intent);
-                    // if (DBG) log("    state: " + intent.getIntExtra("state", 0));
-                    // if (DBG) log("    name: " + intent.getStringExtra("name"));
-                    // send the event and add the state as an argument.
-                    Message message = Message.obtain(mHandler, EVENT_HEADSET_PLUG_STATE_CHANGED,
-                            intent.getIntExtra("state", 0), 0);
-                    mHandler.sendMessage(message);
-                }
-            }
-        };
-
-
-    @Override
-    protected void onCreate(Bundle icicle) {
-        Log.i(LOG_TAG, "onCreate()...  this = " + this);
-        Profiler.callScreenOnCreate();
-        super.onCreate(icicle);
-
-        // Make sure this is a voice-capable device.
-        if (!PhoneGlobals.sVoiceCapable) {
-            // There should be no way to ever reach the InCallScreen on a
-            // non-voice-capable device, since this activity is not exported by
-            // our manifest, and we explicitly disable any other external APIs
-            // like the CALL intent and ITelephony.showCallScreen().
-            // So the fact that we got here indicates a phone app bug.
-            Log.wtf(LOG_TAG, "onCreate() reached on non-voice-capable device");
-            finish();
-            return;
-        }
-
-        mApp = PhoneGlobals.getInstance();
-        mApp.setInCallScreenInstance(this);
-
-        // set this flag so this activity will stay in front of the keyguard
-        int flags = WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
-                | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
-        if (mApp.getPhoneState() == PhoneConstants.State.OFFHOOK) {
-            // While we are in call, the in-call screen should dismiss the keyguard.
-            // This allows the user to press Home to go directly home without going through
-            // an insecure lock screen.
-            // But we do not want to do this if there is no active call so we do not
-            // bypass the keyguard if the call is not answered or declined.
-            flags |= WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
-        }
-
-        WindowManager.LayoutParams lp = getWindow().getAttributes();
-        lp.flags |= flags;
-
-        setPhone(mApp.phone);  // Sets mPhone
-
-        mCM =  mApp.mCM;
-        log("- onCreate: phone state = " + mCM.getState());
-
-        requestWindowFeature(Window.FEATURE_NO_TITLE);
-
-        // Inflate everything in incall_screen.xml and add it to the screen.
-        setContentView(R.layout.incall_screen);
-
-        // If in landscape, then one of the ViewStubs (instead of <include>) is used for the
-        // incall_touch_ui, because CDMA and GSM button layouts are noticeably different.
-        final ViewStub touchUiStub = (ViewStub) findViewById(
-                mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA
-                ? R.id.inCallTouchUiCdmaStub : R.id.inCallTouchUiStub);
-        if (touchUiStub != null) touchUiStub.inflate();
-
-        initInCallScreen();
-
-        registerForPhoneStates();
-
-        // No need to change wake state here; that happens in onResume() when we
-        // are actually displayed.
-
-        // Handle the Intent we were launched with, but only if this is the
-        // the very first time we're being launched (ie. NOT if we're being
-        // re-initialized after previously being shut down.)
-        // Once we're up and running, any future Intents we need
-        // to handle will come in via the onNewIntent() method.
-        if (icicle == null) {
-            if (DBG) log("onCreate(): this is our very first launch, checking intent...");
-            internalResolveIntent(getIntent());
-        }
-
-        Profiler.callScreenCreated();
-        if (DBG) log("onCreate(): exit");
-    }
-
-    /**
-     * Sets the Phone object used internally by the InCallScreen.
-     *
-     * In normal operation this is called from onCreate(), and the
-     * passed-in Phone object comes from the PhoneApp.
-     * For testing, test classes can use this method to
-     * inject a test Phone instance.
-     */
-    /* package */ void setPhone(Phone phone) {
-        mPhone = phone;
-    }
-
-    @Override
-    protected void onResume() {
-        if (DBG) log("onResume()...");
-        super.onResume();
-
-        mIsForegroundActivity = true;
-
-        // The flag shouldn't be turned on when there are actual phone calls.
-        if (mCM.hasActiveFgCall() || mCM.hasActiveBgCall() || mCM.hasActiveRingingCall()) {
-            mApp.inCallUiState.showAlreadyDisconnectedState = false;
-        }
-
-        final InCallUiState inCallUiState = mApp.inCallUiState;
-        if (VDBG) inCallUiState.dumpState();
-
-        updateExpandedViewState();
-
-        // Listen for broadcast intents that might affect the onscreen UI.
-        registerReceiver(mReceiver, new IntentFilter(Intent.ACTION_HEADSET_PLUG));
-
-        // Keep a "dialer session" active when we're in the foreground.
-        // (This is needed to play DTMF tones.)
-        mDialer.startDialerSession();
-
-        // Restore various other state from the InCallUiState object:
-
-        // Update the onscreen dialpad state to match the InCallUiState.
-        if (inCallUiState.showDialpad) {
-            openDialpadInternal(false);  // no "opening" animation
-        } else {
-            closeDialpadInternal(false);  // no "closing" animation
-        }
-
-        // Reset the dialpad context
-        // TODO: Dialpad digits should be set here as well (once they are saved)
-        mDialer.setDialpadContext(inCallUiState.dialpadContextText);
-
-        // If there's a "Respond via SMS" popup still around since the
-        // last time we were the foreground activity, make sure it's not
-        // still active!
-        // (The popup should *never* be visible initially when we first
-        // come to the foreground; it only ever comes up in response to
-        // the user selecting the "SMS" option from the incoming call
-        // widget.)
-        mRespondViaSmsManager.dismissPopup();  // safe even if already dismissed
-
-        // Display an error / diagnostic indication if necessary.
-        //
-        // When the InCallScreen comes to the foreground, we normally we
-        // display the in-call UI in whatever state is appropriate based on
-        // the state of the telephony framework (e.g. an outgoing call in
-        // DIALING state, an incoming call, etc.)
-        //
-        // But if the InCallUiState has a "pending call status code" set,
-        // that means we need to display some kind of status or error
-        // indication to the user instead of the regular in-call UI.  (The
-        // most common example of this is when there's some kind of
-        // failure while initiating an outgoing call; see
-        // CallController.placeCall().)
-        boolean handledStartupError = false;
-        if (inCallUiState.hasPendingCallStatusCode()) {
-            if (DBG) log("- onResume: need to show status indication!");
-            showStatusIndication(inCallUiState.getPendingCallStatusCode());
-
-            // Set handledStartupError to ensure that we won't bail out below.
-            // (We need to stay here in the InCallScreen so that the user
-            // is able to see the error dialog!)
-            handledStartupError = true;
-        }
-
-        // Set the volume control handler while we are in the foreground.
-        final boolean bluetoothConnected = false; //isBluetoothAudioConnected();
-
-        // TODO(klp): Move this volume button control code to the UI
-        if (bluetoothConnected) {
-            setVolumeControlStream(AudioManager.STREAM_BLUETOOTH_SCO);
-        } else {
-            setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);
-        }
-
-        takeKeyEvents(true);
-
-        // If an OTASP call is in progress, use the special OTASP-specific UI.
-        boolean inOtaCall = false;
-        if (TelephonyCapabilities.supportsOtasp(mPhone)) {
-            inOtaCall = checkOtaspStateOnResume();
-        }
-        if (!inOtaCall) {
-            // Always start off in NORMAL mode
-            setInCallScreenMode(InCallScreenMode.NORMAL);
-        }
-
-        // Before checking the state of the CallManager, clean up any
-        // connections in the DISCONNECTED state.
-        // (The DISCONNECTED state is used only to drive the "call ended"
-        // UI; it's totally useless when *entering* the InCallScreen.)
-        mCM.clearDisconnected();
-
-        // Update the onscreen UI to reflect the current telephony state.
-        SyncWithPhoneStateStatus status = syncWithPhoneState();
-
-        // Note there's no need to call updateScreen() here;
-        // syncWithPhoneState() already did that if necessary.
-
-        if (status != SyncWithPhoneStateStatus.SUCCESS) {
-            if (DBG) log("- onResume: syncWithPhoneState failed! status = " + status);
-            // Couldn't update the UI, presumably because the phone is totally
-            // idle.
-
-            // Even though the phone is idle, though, we do still need to
-            // stay here on the InCallScreen if we're displaying an
-            // error dialog (see "showStatusIndication()" above).
-
-            if (handledStartupError) {
-                // Stay here for now.  We'll eventually leave the
-                // InCallScreen when the user presses the dialog's OK
-                // button (see bailOutAfterErrorDialog()), or when the
-                // progress indicator goes away.
-                Log.i(LOG_TAG, "  ==> syncWithPhoneState failed, but staying here anyway.");
-            } else {
-                // The phone is idle, and we did NOT handle a
-                // startup error during this pass thru onResume.
-                //
-                // This basically means that we're being resumed because of
-                // some action *other* than a new intent.  (For example,
-                // the user pressing POWER to wake up the device, causing
-                // the InCallScreen to come back to the foreground.)
-                //
-                // In this scenario we do NOT want to stay here on the
-                // InCallScreen: we're not showing any useful info to the
-                // user (like a dialog), and the in-call UI itself is
-                // useless if there's no active call.  So bail out.
-
-                Log.i(LOG_TAG, "  ==> syncWithPhoneState failed; bailing out!");
-                dismissAllDialogs();
-
-                // Force the InCallScreen to truly finish(), rather than just
-                // moving it to the back of the activity stack (which is what
-                // our finish() method usually does.)
-                // This is necessary to avoid an obscure scenario where the
-                // InCallScreen can get stuck in an inconsistent state, somehow
-                // causing a *subsequent* outgoing call to fail (bug 4172599).
-                endInCallScreenSession(true /* force a real finish() call */);
-                return;
-            }
-        } else if (TelephonyCapabilities.supportsOtasp(mPhone)) {
-            if (inCallUiState.inCallScreenMode == InCallScreenMode.OTA_NORMAL ||
-                    inCallUiState.inCallScreenMode == InCallScreenMode.OTA_ENDED) {
-                if (mCallCard != null) mCallCard.setVisibility(View.GONE);
-                updateScreen();
-                return;
-            }
-        }
-
-        // InCallScreen is now active.
-        EventLog.writeEvent(EventLogTags.PHONE_UI_ENTER);
-
-        // Update the poke lock and wake lock when we move to the foreground.
-        // This will be no-op when prox sensor is effective.
-        mApp.updateWakeState();
-
-        // Restore the mute state if the last mute state change was NOT
-        // done by the user.
-        if (mApp.getRestoreMuteOnInCallResume()) {
-            // Mute state is based on the foreground call
-            PhoneUtils.restoreMuteState();
-            mApp.setRestoreMuteOnInCallResume(false);
-        }
-
-        Profiler.profileViewCreate(getWindow(), InCallScreen.class.getName());
-
-        // If there's a pending MMI code, we'll show a dialog here.
-        //
-        // Note: previously we had shown the dialog when MMI_INITIATE event's coming
-        // from telephony layer, while right now we don't because the event comes
-        // too early (before in-call screen is prepared).
-        // Now we instead check pending MMI code and show the dialog here.
-        //
-        // This *may* cause some problem, e.g. when the user really quickly starts
-        // MMI sequence and calls an actual phone number before the MMI request
-        // being completed, which is rather rare.
-        //
-        // TODO: streamline this logic and have a UX in a better manner.
-        // Right now syncWithPhoneState() above will return SUCCESS based on
-        // mPhone.getPendingMmiCodes().isEmpty(), while we check it again here.
-        // Also we show pre-populated in-call UI under the dialog, which looks
-        // not great. (issue 5210375, 5545506)
-        // After cleaning them, remove commented-out MMI handling code elsewhere.
-        if (!mPhone.getPendingMmiCodes().isEmpty()) {
-            if (mMmiStartedDialog == null) {
-                MmiCode mmiCode = mPhone.getPendingMmiCodes().get(0);
-                Message message = Message.obtain(mHandler, PhoneGlobals.MMI_CANCEL);
-                mMmiStartedDialog = PhoneUtils.displayMMIInitiate(this, mmiCode,
-                        message, mMmiStartedDialog);
-                // mInCallScreen needs to receive MMI_COMPLETE/MMI_CANCEL event from telephony,
-                // which will dismiss the entire screen.
-            }
-        }
-
-        // This means the screen is shown even though there's no connection, which only happens
-        // when the phone call has hung up while the screen is turned off at that moment.
-        // We want to show "disconnected" state with photos with appropriate elapsed time for
-        // the finished phone call.
-        if (mApp.inCallUiState.showAlreadyDisconnectedState) {
-            // if (DBG) {
-            log("onResume(): detected \"show already disconnected state\" situation."
-                    + " set up DELAYED_CLEANUP_AFTER_DISCONNECT message with "
-                    + CALL_ENDED_LONG_DELAY + " msec delay.");
-            //}
-            mHandler.removeMessages(DELAYED_CLEANUP_AFTER_DISCONNECT);
-            mHandler.sendEmptyMessageDelayed(DELAYED_CLEANUP_AFTER_DISCONNECT,
-                    CALL_ENDED_LONG_DELAY);
-        }
-
-        if (VDBG) log("onResume() done.");
-    }
-
-    // onPause is guaranteed to be called when the InCallScreen goes
-    // in the background.
-    @Override
-    protected void onPause() {
-        if (DBG) log("onPause()...");
-        super.onPause();
-
-        mIsForegroundActivity = false;
-
-        // "show-already-disconnected-state" should be effective just during the first wake-up.
-        // We should never allow it to stay true after that.
-        mApp.inCallUiState.showAlreadyDisconnectedState = false;
-
-        // Make sure the "Manage conference" chronometer is stopped when
-        // we move away from the foreground.
-        mManageConferenceUtils.stopConferenceTime();
-
-        // as a catch-all, make sure that any dtmf tones are stopped
-        // when the UI is no longer in the foreground.
-        mDialer.onDialerKeyUp(null);
-
-        // Release any "dialer session" resources, now that we're no
-        // longer in the foreground.
-        mDialer.stopDialerSession();
-
-        // If the device is put to sleep as the phone call is ending,
-        // we may see cases where the DELAYED_CLEANUP_AFTER_DISCONNECT
-        // event gets handled AFTER the device goes to sleep and wakes
-        // up again.
-
-        // This is because it is possible for a sleep command
-        // (executed with the End Call key) to come during the 2
-        // seconds that the "Call Ended" screen is up.  Sleep then
-        // pauses the device (including the cleanup event) and
-        // resumes the event when it wakes up.
-
-        // To fix this, we introduce a bit of code that pushes the UI
-        // to the background if we pause and see a request to
-        // DELAYED_CLEANUP_AFTER_DISCONNECT.
-
-        // Note: We can try to finish directly, by:
-        //  1. Removing the DELAYED_CLEANUP_AFTER_DISCONNECT messages
-        //  2. Calling delayedCleanupAfterDisconnect directly
-
-        // However, doing so can cause problems between the phone
-        // app and the keyguard - the keyguard is trying to sleep at
-        // the same time that the phone state is changing.  This can
-        // end up causing the sleep request to be ignored.
-        if (mHandler.hasMessages(DELAYED_CLEANUP_AFTER_DISCONNECT)
-                && mCM.getState() != PhoneConstants.State.RINGING) {
-            if (DBG) log("DELAYED_CLEANUP_AFTER_DISCONNECT detected, moving UI to background.");
-            endInCallScreenSession();
-        }
-
-        EventLog.writeEvent(EventLogTags.PHONE_UI_EXIT);
-
-        // Dismiss any dialogs we may have brought up, just to be 100%
-        // sure they won't still be around when we get back here.
-        dismissAllDialogs();
-
-        updateExpandedViewState();
-
-        // ...and *always* reset the system bar back to its normal state
-        // when leaving the in-call UI.
-        // (While we're the foreground activity, we disable navigation in
-        // some call states; see InCallTouchUi.updateState().)
-        mApp.notificationMgr.statusBarHelper.enableSystemBarNavigation(true);
-
-        // Unregister for broadcast intents.  (These affect the visible UI
-        // of the InCallScreen, so we only care about them while we're in the
-        // foreground.)
-        unregisterReceiver(mReceiver);
-
-        // Make sure we revert the poke lock and wake lock when we move to
-        // the background.
-        mApp.updateWakeState();
-
-        // clear the dismiss keyguard flag so we are back to the default state
-        // when we next resume
-        updateKeyguardPolicy(false);
-
-        // See also PhoneApp#updatePhoneState(), which takes care of all the other release() calls.
-        if (mApp.getUpdateLock().isHeld() && mApp.getPhoneState() == PhoneConstants.State.IDLE) {
-            if (DBG) {
-                log("Release UpdateLock on onPause() because there's no active phone call.");
-            }
-            mApp.getUpdateLock().release();
-        }
-    }
-
-    @Override
-    protected void onStop() {
-        if (DBG) log("onStop()...");
-        super.onStop();
-
-        stopTimer();
-
-        PhoneConstants.State state = mCM.getState();
-        if (DBG) log("onStop: state = " + state);
-
-        if (state == PhoneConstants.State.IDLE) {
-            if (mRespondViaSmsManager.isShowingPopup()) {
-                // This means that the user has been opening the "Respond via SMS" dialog even
-                // after the incoming call hanging up, and the screen finally went background.
-                // In that case we just close the dialog and exit the whole in-call screen.
-                mRespondViaSmsManager.dismissPopup();
-            }
-
-            // when OTA Activation, OTA Success/Failure dialog or OTA SPC
-            // failure dialog is running, do not destroy inCallScreen. Because call
-            // is already ended and dialog will not get redrawn on slider event.
-            if ((mApp.cdmaOtaProvisionData != null) && (mApp.cdmaOtaScreenState != null)
-                    && ((mApp.cdmaOtaScreenState.otaScreenState !=
-                            CdmaOtaScreenState.OtaScreenState.OTA_STATUS_ACTIVATION)
-                        && (mApp.cdmaOtaScreenState.otaScreenState !=
-                            CdmaOtaScreenState.OtaScreenState.OTA_STATUS_SUCCESS_FAILURE_DLG)
-                        && (!mApp.cdmaOtaProvisionData.inOtaSpcState))) {
-                // we don't want the call screen to remain in the activity history
-                // if there are not active or ringing calls.
-                if (DBG) log("- onStop: calling finish() to clear activity history...");
-                moveTaskToBack(true);
-                if (mApp.otaUtils != null) {
-                    mApp.otaUtils.cleanOtaScreen(true);
-                }
-            }
-        }
-    }
-
-    @Override
-    protected void onDestroy() {
-        Log.i(LOG_TAG, "onDestroy()...  this = " + this);
-        super.onDestroy();
-
-        // Set the magic flag that tells us NOT to handle any handler
-        // messages that come in asynchronously after we get destroyed.
-        mIsDestroyed = true;
-
-        mApp.setInCallScreenInstance(null);
-
-        // Clear out the InCallScreen references in various helper objects
-        // (to let them know we've been destroyed).
-        if (mCallCard != null) {
-            mCallCard.setInCallScreenInstance(null);
-        }
-        if (mInCallTouchUi != null) {
-            mInCallTouchUi.setInCallScreenInstance(null);
-        }
-        mRespondViaSmsManager.setInCallScreenInstance(null);
-
-        mDialer.clearInCallScreenReference();
-        mDialer = null;
-
-        unregisterForPhoneStates();
-        // No need to change wake state here; that happens in onPause() when we
-        // are moving out of the foreground.
-
-        // Dismiss all dialogs, to be absolutely sure we won't leak any of
-        // them while changing orientation.
-        dismissAllDialogs();
-
-        // If there's an OtaUtils instance around, clear out its
-        // references to our internal widgets.
-        if (mApp.otaUtils != null) {
-            mApp.otaUtils.clearUiWidgets();
-        }
-    }
-
-    /**
-     * Dismisses the in-call screen.
-     *
-     * We never *really* finish() the InCallScreen, since we don't want to
-     * get destroyed and then have to be re-created from scratch for the
-     * next call.  Instead, we just move ourselves to the back of the
-     * activity stack.
-     *
-     * This also means that we'll no longer be reachable via the BACK
-     * button (since moveTaskToBack() puts us behind the Home app, but the
-     * home app doesn't allow the BACK key to move you any farther down in
-     * the history stack.)
-     *
-     * (Since the Phone app itself is never killed, this basically means
-     * that we'll keep a single InCallScreen instance around for the
-     * entire uptime of the device.  This noticeably improves the UI
-     * responsiveness for incoming calls.)
-     */
-    @Override
-    public void finish() {
-        if (DBG) log("finish()...");
-        moveTaskToBack(true);
-    }
-
-    /**
-     * End the current in call screen session.
-     *
-     * This must be called when an InCallScreen session has
-     * complete so that the next invocation via an onResume will
-     * not be in an old state.
-     */
-    public void endInCallScreenSession() {
-        if (DBG) log("endInCallScreenSession()... phone state = " + mCM.getState());
-        endInCallScreenSession(false);
-    }
-
-    /**
-     * Internal version of endInCallScreenSession().
-     *
-     * @param forceFinish If true, force the InCallScreen to
-     *        truly finish() rather than just calling moveTaskToBack().
-     *        @see finish()
-     */
-    private void endInCallScreenSession(boolean forceFinish) {
-        if (DBG) {
-            log("endInCallScreenSession(" + forceFinish + ")...  phone state = " + mCM.getState());
-        }
-        if (forceFinish) {
-            Log.i(LOG_TAG, "endInCallScreenSession(): FORCING a call to super.finish()!");
-            super.finish();  // Call super.finish() rather than our own finish() method,
-                             // which actually just calls moveTaskToBack().
-        } else {
-            moveTaskToBack(true);
-        }
-        setInCallScreenMode(InCallScreenMode.UNDEFINED);
-
-        // Call update screen so that the in-call screen goes back to a normal state.
-        // This avoids bugs where a previous state will filcker the next time phone is
-        // opened.
-        updateScreen();
-
-        if (mCallCard != null) {
-            mCallCard.clear();
-        }
-    }
-
-    /**
-     * True when this Activity is in foreground (between onResume() and onPause()).
-     */
-    /* package */ boolean isForegroundActivity() {
-        return mIsForegroundActivity;
-    }
-
-    /* package */ void updateKeyguardPolicy(boolean dismissKeyguard) {
-        if (dismissKeyguard) {
-            getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
-        } else {
-            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
-        }
-    }
-
-    private void registerForPhoneStates() {
-        if (!mRegisteredForPhoneStates) {
-            mCM.registerForPreciseCallStateChanged(mHandler, PHONE_STATE_CHANGED, null);
-            mCM.registerForDisconnect(mHandler, PHONE_DISCONNECT, null);
-            // TODO: sort out MMI code (probably we should remove this method entirely).
-            // See also MMI handling code in onResume()
-            // mCM.registerForMmiInitiate(mHandler, PhoneApp.MMI_INITIATE, null);
-
-            // register for the MMI complete message.  Upon completion,
-            // PhoneUtils will bring up a system dialog instead of the
-            // message display class in PhoneUtils.displayMMIComplete().
-            // We'll listen for that message too, so that we can finish
-            // the activity at the same time.
-            mCM.registerForMmiComplete(mHandler, PhoneGlobals.MMI_COMPLETE, null);
-            mCM.registerForCallWaiting(mHandler, PHONE_CDMA_CALL_WAITING, null);
-            mCM.registerForPostDialCharacter(mHandler, POST_ON_DIAL_CHARS, null);
-            mCM.registerForSuppServiceFailed(mHandler, SUPP_SERVICE_FAILED, null);
-            mCM.registerForIncomingRing(mHandler, PHONE_INCOMING_RING, null);
-            mCM.registerForNewRingingConnection(mHandler, PHONE_NEW_RINGING_CONNECTION, null);
-            mRegisteredForPhoneStates = true;
-        }
-    }
-
-    private void unregisterForPhoneStates() {
-        mCM.unregisterForPreciseCallStateChanged(mHandler);
-        mCM.unregisterForDisconnect(mHandler);
-        mCM.unregisterForMmiInitiate(mHandler);
-        mCM.unregisterForMmiComplete(mHandler);
-        mCM.unregisterForCallWaiting(mHandler);
-        mCM.unregisterForPostDialCharacter(mHandler);
-        mCM.unregisterForSuppServiceFailed(mHandler);
-        mCM.unregisterForIncomingRing(mHandler);
-        mCM.unregisterForNewRingingConnection(mHandler);
-        mRegisteredForPhoneStates = false;
-    }
-
-    /* package */ void updateAfterRadioTechnologyChange() {
-        if (DBG) Log.d(LOG_TAG, "updateAfterRadioTechnologyChange()...");
-
-        // Reset the call screen since the calls cannot be transferred
-        // across radio technologies.
-        resetInCallScreenMode();
-
-        // Unregister for all events from the old obsolete phone
-        unregisterForPhoneStates();
-
-        // (Re)register for all events relevant to the new active phone
-        registerForPhoneStates();
-
-        // And finally, refresh the onscreen UI.  (Note that it's safe
-        // to call requestUpdateScreen() even if the radio change ended up
-        // causing us to exit the InCallScreen.)
-        requestUpdateScreen();
-    }
-
-    @Override
-    protected void onNewIntent(Intent intent) {
-        log("onNewIntent: intent = " + intent + ", phone state = " + mCM.getState());
-
-        // We're being re-launched with a new Intent.  Since it's possible for a
-        // single InCallScreen instance to persist indefinitely (even if we
-        // finish() ourselves), this sequence can potentially happen any time
-        // the InCallScreen needs to be displayed.
-
-        // Stash away the new intent so that we can get it in the future
-        // by calling getIntent().  (Otherwise getIntent() will return the
-        // original Intent from when we first got created!)
-        setIntent(intent);
-
-        // Activities are always paused before receiving a new intent, so
-        // we can count on our onResume() method being called next.
-
-        // Just like in onCreate(), handle the intent.
-        internalResolveIntent(intent);
-    }
-
-    private void internalResolveIntent(Intent intent) {
-        if (intent == null || intent.getAction() == null) {
-            return;
-        }
-        String action = intent.getAction();
-        if (DBG) log("internalResolveIntent: action=" + action);
-
-        // In gingerbread and earlier releases, the InCallScreen used to
-        // directly handle certain intent actions that could initiate phone
-        // calls, namely ACTION_CALL and ACTION_CALL_EMERGENCY, and also
-        // OtaUtils.ACTION_PERFORM_CDMA_PROVISIONING.
-        //
-        // But it doesn't make sense to tie those actions to the InCallScreen
-        // (or especially to the *activity lifecycle* of the InCallScreen).
-        // Instead, the InCallScreen should only be concerned with running the
-        // onscreen UI while in a call.  So we've now offloaded the call-control
-        // functionality to a new module called CallController, and OTASP calls
-        // are now launched from the OtaUtils startInteractiveOtasp() or
-        // startNonInteractiveOtasp() methods.
-        //
-        // So now, the InCallScreen is only ever launched using the ACTION_MAIN
-        // action, and (upon launch) performs no functionality other than
-        // displaying the UI in a state that matches the current telephony
-        // state.
-
-        if (action.equals(intent.ACTION_MAIN)) {
-            // This action is the normal way to bring up the in-call UI.
-            //
-            // Most of the interesting work of updating the onscreen UI (to
-            // match the current telephony state) happens in the
-            // syncWithPhoneState() => updateScreen() sequence that happens in
-            // onResume().
-            //
-            // But we do check here for one extra that can come along with the
-            // ACTION_MAIN intent:
-
-            if (intent.hasExtra(SHOW_DIALPAD_EXTRA)) {
-                // SHOW_DIALPAD_EXTRA can be used here to specify whether the DTMF
-                // dialpad should be initially visible.  If the extra isn't
-                // present at all, we just leave the dialpad in its previous state.
-
-                boolean showDialpad = intent.getBooleanExtra(SHOW_DIALPAD_EXTRA, false);
-                if (VDBG) log("- internalResolveIntent: SHOW_DIALPAD_EXTRA: " + showDialpad);
-
-                // If SHOW_DIALPAD_EXTRA is specified, that overrides whatever
-                // the previous state of inCallUiState.showDialpad was.
-                mApp.inCallUiState.showDialpad = showDialpad;
-
-                final boolean hasActiveCall = mCM.hasActiveFgCall();
-                final boolean hasHoldingCall = mCM.hasActiveBgCall();
-
-                // There's only one line in use, AND it's on hold, at which we're sure the user
-                // wants to use the dialpad toward the exact line, so un-hold the holding line.
-                if (showDialpad && !hasActiveCall && hasHoldingCall) {
-                    PhoneUtils.switchHoldingAndActive(mCM.getFirstActiveBgCall());
-                }
-            }
-            // ...and in onResume() we'll update the onscreen dialpad state to
-            // match the InCallUiState.
-
-            return;
-        }
-
-        if (action.equals(OtaUtils.ACTION_DISPLAY_ACTIVATION_SCREEN)) {
-            // Bring up the in-call UI in the OTASP-specific "activate" state;
-            // see OtaUtils.startInteractiveOtasp().  Note that at this point
-            // the OTASP call has not been started yet; we won't actually make
-            // the call until the user presses the "Activate" button.
-
-            if (!TelephonyCapabilities.supportsOtasp(mPhone)) {
-                throw new IllegalStateException(
-                    "Received ACTION_DISPLAY_ACTIVATION_SCREEN intent on non-OTASP-capable device: "
-                    + intent);
-            }
-
-            setInCallScreenMode(InCallScreenMode.OTA_NORMAL);
-            if ((mApp.cdmaOtaProvisionData != null)
-                && (!mApp.cdmaOtaProvisionData.isOtaCallIntentProcessed)) {
-                mApp.cdmaOtaProvisionData.isOtaCallIntentProcessed = true;
-                mApp.cdmaOtaScreenState.otaScreenState =
-                        CdmaOtaScreenState.OtaScreenState.OTA_STATUS_ACTIVATION;
-            }
-            return;
-        }
-
-        // Various intent actions that should no longer come here directly:
-        if (action.equals(OtaUtils.ACTION_PERFORM_CDMA_PROVISIONING)) {
-            // This intent is now handled by the InCallScreenShowActivation
-            // activity, which translates it into a call to
-            // OtaUtils.startInteractiveOtasp().
-            throw new IllegalStateException(
-                "Unexpected ACTION_PERFORM_CDMA_PROVISIONING received by InCallScreen: "
-                + intent);
-        } else if (action.equals(Intent.ACTION_CALL)
-                   || action.equals(Intent.ACTION_CALL_EMERGENCY)) {
-            // ACTION_CALL* intents go to the OutgoingCallBroadcaster, which now
-            // translates them into CallController.placeCall() calls rather than
-            // launching the InCallScreen directly.
-            throw new IllegalStateException("Unexpected CALL action received by InCallScreen: "
-                                            + intent);
-        } else if (action.equals(ACTION_UNDEFINED)) {
-            // This action is only used for internal bookkeeping; we should
-            // never actually get launched with it.
-            Log.wtf(LOG_TAG, "internalResolveIntent: got launched with ACTION_UNDEFINED");
-            return;
-        } else {
-            Log.wtf(LOG_TAG, "internalResolveIntent: unexpected intent action: " + action);
-            // But continue the best we can (basically treating this case
-            // like ACTION_MAIN...)
-            return;
-        }
-    }
-
-    private void stopTimer() {
-        if (mCallCard != null) mCallCard.stopTimer();
-    }
-
-    private void initInCallScreen() {
-        if (VDBG) log("initInCallScreen()...");
-
-        // Have the WindowManager filter out touch events that are "too fat".
-        getWindow().addFlags(WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES);
-
-        // Initialize the CallCard.
-        mCallCard = (CallCard) findViewById(R.id.callCard);
-        if (VDBG) log("  - mCallCard = " + mCallCard);
-        mCallCard.setInCallScreenInstance(this);
-
-        // Initialize the onscreen UI elements.
-        initInCallTouchUi();
-
-        // Helper class to keep track of enabledness/state of UI controls
-        mInCallControlState = new InCallControlState(this, mCM, mApp.getBluetoothManager());
-
-        // Helper class to run the "Manage conference" UI
-        mManageConferenceUtils = new ManageConferenceUtils(this, mCM);
-
-        // The DTMF Dialpad.
-        ViewStub stub = (ViewStub) findViewById(R.id.dtmf_twelve_key_dialer_stub);
-        mDialer = new DTMFTwelveKeyDialer(this, stub);
-        mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
-    }
-
-    /**
-     * Returns true if the phone is "in use", meaning that at least one line
-     * is active (ie. off hook or ringing or dialing).  Conversely, a return
-     * value of false means there's currently no phone activity at all.
-     */
-    private boolean phoneIsInUse() {
-        return mCM.getState() != PhoneConstants.State.IDLE;
-    }
-
-    private boolean handleDialerKeyDown(int keyCode, KeyEvent event) {
-        if (VDBG) log("handleDialerKeyDown: keyCode " + keyCode + ", event " + event + "...");
-
-        // As soon as the user starts typing valid dialable keys on the
-        // keyboard (presumably to type DTMF tones) we start passing the
-        // key events to the DTMFDialer's onDialerKeyDown.  We do so
-        // only if the okToDialDTMFTones() conditions pass.
-        if (okToDialDTMFTones()) {
-            return mDialer.onDialerKeyDown(event);
-
-            // TODO: If the dialpad isn't currently visible, maybe
-            // consider automatically bringing it up right now?
-            // (Just to make sure the user sees the digits widget...)
-            // But this probably isn't too critical since it's awkward to
-            // use the hard keyboard while in-call in the first place,
-            // especially now that the in-call UI is portrait-only...
-        }
-
-        return false;
-    }
-
-    @Override
-    public void onBackPressed() {
-        if (DBG) log("onBackPressed()...");
-
-        // To consume this BACK press, the code here should just do
-        // something and return.  Otherwise, call super.onBackPressed() to
-        // get the default implementation (which simply finishes the
-        // current activity.)
-
-        if (mCM.hasActiveRingingCall()) {
-            // The Back key, just like the Home key, is always disabled
-            // while an incoming call is ringing.  (The user *must* either
-            // answer or reject the call before leaving the incoming-call
-            // screen.)
-            if (DBG) log("BACK key while ringing: ignored");
-
-            // And consume this event; *don't* call super.onBackPressed().
-            return;
-        }
-
-        // BACK is also used to exit out of any "special modes" of the
-        // in-call UI:
-
-        if (mDialer.isOpened()) {
-            closeDialpadInternal(true);  // do the "closing" animation
-            return;
-        }
-
-        if (mApp.inCallUiState.inCallScreenMode == InCallScreenMode.MANAGE_CONFERENCE) {
-            // Hide the Manage Conference panel, return to NORMAL mode.
-            setInCallScreenMode(InCallScreenMode.NORMAL);
-            requestUpdateScreen();
-            return;
-        }
-
-        // Nothing special to do.  Fall back to the default behavior.
-        super.onBackPressed();
-    }
-
-    /**
-     * Handles the green CALL key while in-call.
-     * @return true if we consumed the event.
-     */
-    private boolean handleCallKey() {
-        // The green CALL button means either "Answer", "Unhold", or
-        // "Swap calls", or can be a no-op, depending on the current state
-        // of the Phone.
-
-        final boolean hasRingingCall = mCM.hasActiveRingingCall();
-        final boolean hasActiveCall = mCM.hasActiveFgCall();
-        final boolean hasHoldingCall = mCM.hasActiveBgCall();
-
-        int phoneType = mPhone.getPhoneType();
-        if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-            // The green CALL button means either "Answer", "Swap calls/On Hold", or
-            // "Add to 3WC", depending on the current state of the Phone.
-
-            CdmaPhoneCallState.PhoneCallState currCallState =
-                mApp.cdmaPhoneCallState.getCurrentCallState();
-            if (hasRingingCall) {
-                //Scenario 1: Accepting the First Incoming and Call Waiting call
-                if (DBG) log("answerCall: First Incoming and Call Waiting scenario");
-                internalAnswerCall();  // Automatically holds the current active call,
-                                       // if there is one
-            } else if ((currCallState == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE)
-                    && (hasActiveCall)) {
-                //Scenario 2: Merging 3Way calls
-                if (DBG) log("answerCall: Merge 3-way call scenario");
-                // Merge calls
-                PhoneUtils.mergeCalls(mCM);
-            } else if (currCallState == CdmaPhoneCallState.PhoneCallState.CONF_CALL) {
-                //Scenario 3: Switching between two Call waiting calls or drop the latest
-                // connection if in a 3Way merge scenario
-                if (DBG) log("answerCall: Switch btwn 2 calls scenario");
-                internalSwapCalls();
-            }
-        } else if ((phoneType == PhoneConstants.PHONE_TYPE_GSM)
-                || (phoneType == PhoneConstants.PHONE_TYPE_SIP)) {
-            if (hasRingingCall) {
-                // If an incoming call is ringing, the CALL button is actually
-                // handled by the PhoneWindowManager.  (We do this to make
-                // sure that we'll respond to the key even if the InCallScreen
-                // hasn't come to the foreground yet.)
-                //
-                // We'd only ever get here in the extremely rare case that the
-                // incoming call started ringing *after*
-                // PhoneWindowManager.interceptKeyTq() but before the event
-                // got here, or else if the PhoneWindowManager had some
-                // problem connecting to the ITelephony service.
-                Log.w(LOG_TAG, "handleCallKey: incoming call is ringing!"
-                      + " (PhoneWindowManager should have handled this key.)");
-                // But go ahead and handle the key as normal, since the
-                // PhoneWindowManager presumably did NOT handle it:
-
-                // There's an incoming ringing call: CALL means "Answer".
-                internalAnswerCall();
-            } else if (hasActiveCall && hasHoldingCall) {
-                // Two lines are in use: CALL means "Swap calls".
-                if (DBG) log("handleCallKey: both lines in use ==> swap calls.");
-                internalSwapCalls();
-            } else if (hasHoldingCall) {
-                // There's only one line in use, AND it's on hold.
-                // In this case CALL is a shortcut for "unhold".
-                if (DBG) log("handleCallKey: call on hold ==> unhold.");
-                PhoneUtils.switchHoldingAndActive(
-                    mCM.getFirstActiveBgCall());  // Really means "unhold" in this state
-            } else {
-                // The most common case: there's only one line in use, and
-                // it's an active call (i.e. it's not on hold.)
-                // In this case CALL is a no-op.
-                // (This used to be a shortcut for "add call", but that was a
-                // bad idea because "Add call" is so infrequently-used, and
-                // because the user experience is pretty confusing if you
-                // inadvertently trigger it.)
-                if (VDBG) log("handleCallKey: call in foregound ==> ignoring.");
-                // But note we still consume this key event; see below.
-            }
-        } else {
-            throw new IllegalStateException("Unexpected phone type: " + phoneType);
-        }
-
-        // We *always* consume the CALL key, since the system-wide default
-        // action ("go to the in-call screen") is useless here.
-        return true;
-    }
-
-    boolean isKeyEventAcceptableDTMF (KeyEvent event) {
-        return (mDialer != null && mDialer.isKeyEventAcceptable(event));
-    }
-
-    /**
-     * Overriden to track relevant focus changes.
-     *
-     * If a key is down and some time later the focus changes, we may
-     * NOT recieve the keyup event; logically the keyup event has not
-     * occured in this window.  This issue is fixed by treating a focus
-     * changed event as an interruption to the keydown, making sure
-     * that any code that needs to be run in onKeyUp is ALSO run here.
-     */
-    @Override
-    public void onWindowFocusChanged(boolean hasFocus) {
-        // the dtmf tones should no longer be played
-        if (VDBG) log("onWindowFocusChanged(" + hasFocus + ")...");
-        if (!hasFocus && mDialer != null) {
-            if (VDBG) log("- onWindowFocusChanged: faking onDialerKeyUp()...");
-            mDialer.onDialerKeyUp(null);
-        }
-    }
-
-    @Override
-    public boolean onKeyUp(int keyCode, KeyEvent event) {
-        // if (DBG) log("onKeyUp(keycode " + keyCode + ")...");
-
-        // push input to the dialer.
-        if ((mDialer != null) && (mDialer.onDialerKeyUp(event))){
-            return true;
-        } else if (keyCode == KeyEvent.KEYCODE_CALL) {
-            // Always consume CALL to be sure the PhoneWindow won't do anything with it
-            return true;
-        }
-        return super.onKeyUp(keyCode, event);
-    }
-
-    @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event) {
-        // if (DBG) log("onKeyDown(keycode " + keyCode + ")...");
-
-        switch (keyCode) {
-            case KeyEvent.KEYCODE_CALL:
-                boolean handled = handleCallKey();
-                if (!handled) {
-                    Log.w(LOG_TAG, "InCallScreen should always handle KEYCODE_CALL in onKeyDown");
-                }
-                // Always consume CALL to be sure the PhoneWindow won't do anything with it
-                return true;
-
-            // Note there's no KeyEvent.KEYCODE_ENDCALL case here.
-            // The standard system-wide handling of the ENDCALL key
-            // (see PhoneWindowManager's handling of KEYCODE_ENDCALL)
-            // already implements exactly what the UI spec wants,
-            // namely (1) "hang up" if there's a current active call,
-            // or (2) "don't answer" if there's a current ringing call.
-
-            case KeyEvent.KEYCODE_CAMERA:
-                // Disable the CAMERA button while in-call since it's too
-                // easy to press accidentally.
-                return true;
-
-            case KeyEvent.KEYCODE_VOLUME_UP:
-            case KeyEvent.KEYCODE_VOLUME_DOWN:
-            case KeyEvent.KEYCODE_VOLUME_MUTE:
-                if (mCM.getState() == PhoneConstants.State.RINGING) {
-                    // If an incoming call is ringing, the VOLUME buttons are
-                    // actually handled by the PhoneWindowManager.  (We do
-                    // this to make sure that we'll respond to them even if
-                    // the InCallScreen hasn't come to the foreground yet.)
-                    //
-                    // We'd only ever get here in the extremely rare case that the
-                    // incoming call started ringing *after*
-                    // PhoneWindowManager.interceptKeyTq() but before the event
-                    // got here, or else if the PhoneWindowManager had some
-                    // problem connecting to the ITelephony service.
-                    Log.w(LOG_TAG, "VOLUME key: incoming call is ringing!"
-                          + " (PhoneWindowManager should have handled this key.)");
-                    // But go ahead and handle the key as normal, since the
-                    // PhoneWindowManager presumably did NOT handle it:
-                    internalSilenceRinger();
-
-                    // As long as an incoming call is ringing, we always
-                    // consume the VOLUME keys.
-                    return true;
-                }
-                break;
-
-            case KeyEvent.KEYCODE_MUTE:
-                onMuteClick();
-                return true;
-
-            // Various testing/debugging features, enabled ONLY when VDBG == true.
-            case KeyEvent.KEYCODE_SLASH:
-                if (VDBG) {
-                    log("----------- InCallScreen View dump --------------");
-                    // Dump starting from the top-level view of the entire activity:
-                    Window w = this.getWindow();
-                    View decorView = w.getDecorView();
-                    decorView.debug();
-                    return true;
-                }
-                break;
-            case KeyEvent.KEYCODE_EQUALS:
-                if (VDBG) {
-                    log("----------- InCallScreen call state dump --------------");
-                    PhoneUtils.dumpCallState(mPhone);
-                    PhoneUtils.dumpCallManager();
-                    return true;
-                }
-                break;
-            case KeyEvent.KEYCODE_GRAVE:
-                if (VDBG) {
-                    // Placeholder for other misc temp testing
-                    log("------------ Temp testing -----------------");
-                    return true;
-                }
-                break;
-        }
-
-        if (event.getRepeatCount() == 0 && handleDialerKeyDown(keyCode, event)) {
-            return true;
-        }
-
-        return super.onKeyDown(keyCode, event);
-    }
-
-    /**
-     * Handle a failure notification for a supplementary service
-     * (i.e. conference, switch, separate, transfer, etc.).
-     */
-    void onSuppServiceFailed(AsyncResult r) {
-        Phone.SuppService service = (Phone.SuppService) r.result;
-        if (DBG) log("onSuppServiceFailed: " + service);
-
-        int errorMessageResId;
-        switch (service) {
-            case SWITCH:
-                // Attempt to switch foreground and background/incoming calls failed
-                // ("Failed to switch calls")
-                errorMessageResId = R.string.incall_error_supp_service_switch;
-                break;
-
-            case SEPARATE:
-                // Attempt to separate a call from a conference call
-                // failed ("Failed to separate out call")
-                errorMessageResId = R.string.incall_error_supp_service_separate;
-                break;
-
-            case TRANSFER:
-                // Attempt to connect foreground and background calls to
-                // each other (and hanging up user's line) failed ("Call
-                // transfer failed")
-                errorMessageResId = R.string.incall_error_supp_service_transfer;
-                break;
-
-            case CONFERENCE:
-                // Attempt to add a call to conference call failed
-                // ("Conference call failed")
-                errorMessageResId = R.string.incall_error_supp_service_conference;
-                break;
-
-            case REJECT:
-                // Attempt to reject an incoming call failed
-                // ("Call rejection failed")
-                errorMessageResId = R.string.incall_error_supp_service_reject;
-                break;
-
-            case HANGUP:
-                // Attempt to release a call failed ("Failed to release call(s)")
-                errorMessageResId = R.string.incall_error_supp_service_hangup;
-                break;
-
-            case UNKNOWN:
-            default:
-                // Attempt to use a service we don't recognize or support
-                // ("Unsupported service" or "Selected service failed")
-                errorMessageResId = R.string.incall_error_supp_service_unknown;
-                break;
-        }
-
-        // mSuppServiceFailureDialog is a generic dialog used for any
-        // supp service failure, and there's only ever have one
-        // instance at a time.  So just in case a previous dialog is
-        // still around, dismiss it.
-        if (mSuppServiceFailureDialog != null) {
-            if (DBG) log("- DISMISSING mSuppServiceFailureDialog.");
-            mSuppServiceFailureDialog.dismiss();  // It's safe to dismiss() a dialog
-                                                  // that's already dismissed.
-            mSuppServiceFailureDialog = null;
-        }
-
-        mSuppServiceFailureDialog = new AlertDialog.Builder(this)
-                .setMessage(errorMessageResId)
-                .setPositiveButton(R.string.ok, null)
-                .create();
-        mSuppServiceFailureDialog.getWindow().addFlags(
-                WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
-        mSuppServiceFailureDialog.show();
-    }
-
-    /**
-     * Something has changed in the phone's state.  Update the UI.
-     */
-    private void onPhoneStateChanged(AsyncResult r) {
-        PhoneConstants.State state = mCM.getState();
-        if (DBG) log("onPhoneStateChanged: current state = " + state);
-
-        // There's nothing to do here if we're not the foreground activity.
-        // (When we *do* eventually come to the foreground, we'll do a
-        // full update then.)
-        if (!mIsForegroundActivity) {
-            if (DBG) log("onPhoneStateChanged: Activity not in foreground! Bailing out...");
-            return;
-        }
-
-        updateExpandedViewState();
-
-        // Update the onscreen UI.
-        // We use requestUpdateScreen() here (which posts a handler message)
-        // instead of calling updateScreen() directly, which allows us to avoid
-        // unnecessary work if multiple onPhoneStateChanged() events come in all
-        // at the same time.
-
-        requestUpdateScreen();
-
-        // Make sure we update the poke lock and wake lock when certain
-        // phone state changes occur.
-        mApp.updateWakeState();
-    }
-
-    /**
-     * Updates the UI after a phone connection is disconnected, as follows:
-     *
-     * - If this was a missed or rejected incoming call, and no other
-     *   calls are active, dismiss the in-call UI immediately.  (The
-     *   CallNotifier will still create a "missed call" notification if
-     *   necessary.)
-     *
-     * - With any other disconnect cause, if the phone is now totally
-     *   idle, display the "Call ended" state for a couple of seconds.
-     *
-     * - Or, if the phone is still in use, stay on the in-call screen
-     *   (and update the UI to reflect the current state of the Phone.)
-     *
-     * @param r r.result contains the connection that just ended
-     */
-    private void onDisconnect(AsyncResult r) {
-        Connection c = (Connection) r.result;
-        Connection.DisconnectCause cause = c.getDisconnectCause();
-        if (DBG) log("onDisconnect: connection '" + c + "', cause = " + cause
-                + ", showing screen: " + mApp.isShowingCallScreen());
-
-        boolean currentlyIdle = !phoneIsInUse();
-        int autoretrySetting = AUTO_RETRY_OFF;
-        boolean phoneIsCdma = (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA);
-        if (phoneIsCdma) {
-            // Get the Auto-retry setting only if Phone State is IDLE,
-            // else let it stay as AUTO_RETRY_OFF
-            if (currentlyIdle) {
-                autoretrySetting = android.provider.Settings.Global.getInt(mPhone.getContext().
-                        getContentResolver(), android.provider.Settings.Global.CALL_AUTO_RETRY, 0);
-            }
-        }
-
-        // for OTA Call, only if in OTA NORMAL mode, handle OTA END scenario
-        if ((mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_NORMAL)
-                && ((mApp.cdmaOtaProvisionData != null)
-                && (!mApp.cdmaOtaProvisionData.inOtaSpcState))) {
-            setInCallScreenMode(InCallScreenMode.OTA_ENDED);
-            updateScreen();
-            return;
-        } else if ((mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_ENDED)
-                   || ((mApp.cdmaOtaProvisionData != null)
-                       && mApp.cdmaOtaProvisionData.inOtaSpcState)) {
-           if (DBG) log("onDisconnect: OTA Call end already handled");
-           return;
-        }
-
-        // Any time a call disconnects, clear out the "history" of DTMF
-        // digits you typed (to make sure it doesn't persist from one call
-        // to the next.)
-        mDialer.clearDigits();
-
-        // Under certain call disconnected states, we want to alert the user
-        // with a dialog instead of going through the normal disconnect
-        // routine.
-        if (cause == Connection.DisconnectCause.CALL_BARRED) {
-            showGenericErrorDialog(R.string.callFailed_cb_enabled, false);
-            return;
-        } else if (cause == Connection.DisconnectCause.FDN_BLOCKED) {
-            showGenericErrorDialog(R.string.callFailed_fdn_only, false);
-            return;
-        } else if (cause == Connection.DisconnectCause.CS_RESTRICTED) {
-            showGenericErrorDialog(R.string.callFailed_dsac_restricted, false);
-            return;
-        } else if (cause == Connection.DisconnectCause.CS_RESTRICTED_EMERGENCY) {
-            showGenericErrorDialog(R.string.callFailed_dsac_restricted_emergency, false);
-            return;
-        } else if (cause == Connection.DisconnectCause.CS_RESTRICTED_NORMAL) {
-            showGenericErrorDialog(R.string.callFailed_dsac_restricted_normal, false);
-            return;
-        }
-
-        if (phoneIsCdma) {
-            Call.State callState = mApp.notifier.getPreviousCdmaCallState();
-            if ((callState == Call.State.ACTIVE)
-                    && (cause != Connection.DisconnectCause.INCOMING_MISSED)
-                    && (cause != Connection.DisconnectCause.NORMAL)
-                    && (cause != Connection.DisconnectCause.LOCAL)
-                    && (cause != Connection.DisconnectCause.INCOMING_REJECTED)) {
-                showCallLostDialog();
-            } else if ((callState == Call.State.DIALING || callState == Call.State.ALERTING)
-                        && (cause != Connection.DisconnectCause.INCOMING_MISSED)
-                        && (cause != Connection.DisconnectCause.NORMAL)
-                        && (cause != Connection.DisconnectCause.LOCAL)
-                        && (cause != Connection.DisconnectCause.INCOMING_REJECTED)) {
-
-                if (mApp.inCallUiState.needToShowCallLostDialog) {
-                    // Show the dialog now since the call that just failed was a retry.
-                    showCallLostDialog();
-                    mApp.inCallUiState.needToShowCallLostDialog = false;
-                } else {
-                    if (autoretrySetting == AUTO_RETRY_OFF) {
-                        // Show the dialog for failed call if Auto Retry is OFF in Settings.
-                        showCallLostDialog();
-                        mApp.inCallUiState.needToShowCallLostDialog = false;
-                    } else {
-                        // Set the needToShowCallLostDialog flag now, so we'll know to show
-                        // the dialog if *this* call fails.
-                        mApp.inCallUiState.needToShowCallLostDialog = true;
-                    }
-                }
-            }
-        }
-
-        // Explicitly clean up up any DISCONNECTED connections
-        // in a conference call.
-        // [Background: Even after a connection gets disconnected, its
-        // Connection object still stays around for a few seconds, in the
-        // DISCONNECTED state.  With regular calls, this state drives the
-        // "call ended" UI.  But when a single person disconnects from a
-        // conference call there's no "call ended" state at all; in that
-        // case we blow away any DISCONNECTED connections right now to make sure
-        // the UI updates instantly to reflect the current state.]
-        final Call call = c.getCall();
-        if (call != null) {
-            // We only care about situation of a single caller
-            // disconnecting from a conference call.  In that case, the
-            // call will have more than one Connection (including the one
-            // that just disconnected, which will be in the DISCONNECTED
-            // state) *and* at least one ACTIVE connection.  (If the Call
-            // has *no* ACTIVE connections, that means that the entire
-            // conference call just ended, so we *do* want to show the
-            // "Call ended" state.)
-            List<Connection> connections = call.getConnections();
-            if (connections != null && connections.size() > 1) {
-                for (Connection conn : connections) {
-                    if (conn.getState() == Call.State.ACTIVE) {
-                        // This call still has at least one ACTIVE connection!
-                        // So blow away any DISCONNECTED connections
-                        // (including, presumably, the one that just
-                        // disconnected from this conference call.)
-
-                        // We also force the wake state to refresh, just in
-                        // case the disconnected connections are removed
-                        // before the phone state change.
-                        if (VDBG) log("- Still-active conf call; clearing DISCONNECTED...");
-                        mApp.updateWakeState();
-                        mCM.clearDisconnected();  // This happens synchronously.
-                        break;
-                    }
-                }
-            }
-        }
-
-        // Note: see CallNotifier.onDisconnect() for some other behavior
-        // that might be triggered by a disconnect event, like playing the
-        // busy/congestion tone.
-
-        // Stash away some info about the call that just disconnected.
-        // (This might affect what happens after we exit the InCallScreen; see
-        // delayedCleanupAfterDisconnect().)
-        // TODO: rather than stashing this away now and then reading it in
-        // delayedCleanupAfterDisconnect(), it would be cleaner to just pass
-        // this as an argument to delayedCleanupAfterDisconnect() (if we call
-        // it directly) or else pass it as a Message argument when we post the
-        // DELAYED_CLEANUP_AFTER_DISCONNECT message.
-        mLastDisconnectCause = cause;
-
-        // We bail out immediately (and *don't* display the "call ended"
-        // state at all) if this was an incoming call.
-        boolean bailOutImmediately =
-                ((cause == Connection.DisconnectCause.INCOMING_MISSED)
-                 || (cause == Connection.DisconnectCause.INCOMING_REJECTED))
-                && currentlyIdle;
-
-        boolean showingQuickResponseDialog =
-                mRespondViaSmsManager != null && mRespondViaSmsManager.isShowingPopup();
-
-        // Note: we also do some special handling for the case when a call
-        // disconnects with cause==OUT_OF_SERVICE while making an
-        // emergency call from airplane mode.  That's handled by
-        // EmergencyCallHelper.onDisconnect().
-
-        if (bailOutImmediately && showingQuickResponseDialog) {
-            if (DBG) log("- onDisconnect: Respond-via-SMS dialog is still being displayed...");
-
-            // Do *not* exit the in-call UI yet!
-            // If the call was an incoming call that was missed *and* the user is using
-            // quick response screen, we keep showing the screen for a moment, assuming the
-            // user wants to reply the call anyway.
-            //
-            // For this case, we will exit the screen when:
-            // - the message is sent (RespondViaSmsManager)
-            // - the message is canceled (RespondViaSmsManager), or
-            // - when the whole in-call UI becomes background (onPause())
-        } else if (bailOutImmediately) {
-            if (DBG) log("- onDisconnect: bailOutImmediately...");
-
-            // Exit the in-call UI!
-            // (This is basically the same "delayed cleanup" we do below,
-            // just with zero delay.  Since the Phone is currently idle,
-            // this call is guaranteed to immediately finish this activity.)
-            delayedCleanupAfterDisconnect();
-        } else {
-            if (DBG) log("- onDisconnect: delayed bailout...");
-            // Stay on the in-call screen for now.  (Either the phone is
-            // still in use, or the phone is idle but we want to display
-            // the "call ended" state for a couple of seconds.)
-
-            // Switch to the special "Call ended" state when the phone is idle
-            // but there's still a call in the DISCONNECTED state:
-            if (currentlyIdle
-                && (mCM.hasDisconnectedFgCall() || mCM.hasDisconnectedBgCall())) {
-                if (DBG) log("- onDisconnect: switching to 'Call ended' state...");
-                setInCallScreenMode(InCallScreenMode.CALL_ENDED);
-            }
-
-            // Force a UI update in case we need to display anything
-            // special based on this connection's DisconnectCause
-            // (see CallCard.getCallFailedString()).
-            updateScreen();
-
-            // Some other misc cleanup that we do if the call that just
-            // disconnected was the foreground call.
-            final boolean hasActiveCall = mCM.hasActiveFgCall();
-            if (!hasActiveCall) {
-                if (DBG) log("- onDisconnect: cleaning up after FG call disconnect...");
-
-                // Dismiss any dialogs which are only meaningful for an
-                // active call *and* which become moot if the call ends.
-                if (mWaitPromptDialog != null) {
-                    if (VDBG) log("- DISMISSING mWaitPromptDialog.");
-                    mWaitPromptDialog.dismiss();  // safe even if already dismissed
-                    mWaitPromptDialog = null;
-                }
-                if (mWildPromptDialog != null) {
-                    if (VDBG) log("- DISMISSING mWildPromptDialog.");
-                    mWildPromptDialog.dismiss();  // safe even if already dismissed
-                    mWildPromptDialog = null;
-                }
-                if (mPausePromptDialog != null) {
-                    if (DBG) log("- DISMISSING mPausePromptDialog.");
-                    mPausePromptDialog.dismiss();  // safe even if already dismissed
-                    mPausePromptDialog = null;
-                }
-            }
-
-            // Updating the screen wake state is done in onPhoneStateChanged().
-
-
-            // CDMA: We only clean up if the Phone state is IDLE as we might receive an
-            // onDisconnect for a Call Collision case (rare but possible).
-            // For Call collision cases i.e. when the user makes an out going call
-            // and at the same time receives an Incoming Call, the Incoming Call is given
-            // higher preference. At this time framework sends a disconnect for the Out going
-            // call connection hence we should *not* bring down the InCallScreen as the Phone
-            // State would be RINGING
-            if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
-                if (!currentlyIdle) {
-                    // Clean up any connections in the DISCONNECTED state.
-                    // This is necessary cause in CallCollision the foreground call might have
-                    // connections in DISCONNECTED state which needs to be cleared.
-                    mCM.clearDisconnected();
-
-                    // The phone is still in use.  Stay here in this activity.
-                    // But we don't need to keep the screen on.
-                    if (DBG) log("onDisconnect: Call Collision case - staying on InCallScreen.");
-                    if (DBG) PhoneUtils.dumpCallState(mPhone);
-                    return;
-                }
-            }
-
-            // This is onDisconnect() request from the last phone call; no available call anymore.
-            //
-            // When the in-call UI is in background *because* the screen is turned off (unlike the
-            // other case where the other activity is being shown), we wake up the screen and
-            // show "DISCONNECTED" state once, with appropriate elapsed time. After showing that
-            // we *must* bail out of the screen again, showing screen lock if needed.
-            //
-            //
-            // TODO: Consider moving this to CallNotifier. This code assumes the InCallScreen
-            // never gets destroyed. For this exact case, it works (since InCallScreen won't be
-            // destroyed), while technically this isn't right; Activity may be destroyed when
-            // in background.
-            if (currentlyIdle && !isForegroundActivity()) {
-                log("Force waking up the screen to let users see \"disconnected\" state");
-                if (call != null) {
-                    mCallCard.updateElapsedTimeWidget(call);
-                }
-                // This variable will be kept true until the next InCallScreen#onPause(), which
-                // forcibly turns it off regardless of the situation (for avoiding unnecessary
-                // confusion around this special case).
-                mApp.inCallUiState.showAlreadyDisconnectedState = true;
-
-                // Finally request wake-up..
-                mApp.wakeUpScreen();
-
-                // InCallScreen#onResume() will set DELAYED_CLEANUP_AFTER_DISCONNECT message,
-                // so skip the following section.
-                return;
-            }
-
-            // Finally, arrange for delayedCleanupAfterDisconnect() to get
-            // called after a short interval (during which we display the
-            // "call ended" state.)  At that point, if the
-            // Phone is idle, we'll finish out of this activity.
-            final int callEndedDisplayDelay;
-            switch (cause) {
-                // When the local user hanged up the ongoing call, it is ok to dismiss the screen
-                // soon. In other cases, we show the "hung up" screen longer.
-                //
-                // - For expected reasons we will use CALL_ENDED_LONG_DELAY.
-                // -- when the peer hanged up the call
-                // -- when the local user rejects the incoming call during the other ongoing call
-                // (TODO: there may be other cases which should be in this category)
-                //
-                // - For other unexpected reasons, we will use CALL_ENDED_EXTRA_LONG_DELAY,
-                //   assuming the local user wants to confirm the disconnect reason.
-                case LOCAL:
-                    callEndedDisplayDelay = CALL_ENDED_SHORT_DELAY;
-                    break;
-                case NORMAL:
-                case INCOMING_REJECTED:
-                    callEndedDisplayDelay = CALL_ENDED_LONG_DELAY;
-                    break;
-                default:
-                    callEndedDisplayDelay = CALL_ENDED_EXTRA_LONG_DELAY;
-                    break;
-            }
-            mHandler.removeMessages(DELAYED_CLEANUP_AFTER_DISCONNECT);
-            mHandler.sendEmptyMessageDelayed(DELAYED_CLEANUP_AFTER_DISCONNECT,
-                    callEndedDisplayDelay);
-        }
-
-        // Remove 3way timer (only meaningful for CDMA)
-        // TODO: this call needs to happen in the CallController, not here.
-        // (It should probably be triggered by the CallNotifier's onDisconnect method.)
-        // mHandler.removeMessages(THREEWAY_CALLERINFO_DISPLAY_DONE);
-    }
-
-    /**
-     * Brings up the "MMI Started" dialog.
-     */
-    /* TODO: sort out MMI code (probably we should remove this method entirely). See also
-       MMI handling code in onResume()
-    private void onMMIInitiate(AsyncResult r) {
-        if (VDBG) log("onMMIInitiate()...  AsyncResult r = " + r);
-
-        // Watch out: don't do this if we're not the foreground activity,
-        // mainly since in the Dialog.show() might fail if we don't have a
-        // valid window token any more...
-        // (Note that this exact sequence can happen if you try to start
-        // an MMI code while the radio is off or out of service.)
-        if (!mIsForegroundActivity) {
-            if (VDBG) log("Activity not in foreground! Bailing out...");
-            return;
-        }
-
-        // Also, if any other dialog is up right now (presumably the
-        // generic error dialog displaying the "Starting MMI..."  message)
-        // take it down before bringing up the real "MMI Started" dialog
-        // in its place.
-        dismissAllDialogs();
-
-        MmiCode mmiCode = (MmiCode) r.result;
-        if (VDBG) log("  - MmiCode: " + mmiCode);
-
-        Message message = Message.obtain(mHandler, PhoneApp.MMI_CANCEL);
-        mMmiStartedDialog = PhoneUtils.displayMMIInitiate(this, mmiCode,
-                                                          message, mMmiStartedDialog);
-    }*/
-
-    /**
-     * Handles an MMI_CANCEL event, which is triggered by the button
-     * (labeled either "OK" or "Cancel") on the "MMI Started" dialog.
-     * @see PhoneUtils#cancelMmiCode(Phone)
-     */
-    private void onMMICancel() {
-        if (VDBG) log("onMMICancel()...");
-
-        // First of all, cancel the outstanding MMI code (if possible.)
-        PhoneUtils.cancelMmiCode(mPhone);
-
-        // Regardless of whether the current MMI code was cancelable, the
-        // PhoneApp will get an MMI_COMPLETE event very soon, which will
-        // take us to the MMI Complete dialog (see
-        // PhoneUtils.displayMMIComplete().)
-        //
-        // But until that event comes in, we *don't* want to stay here on
-        // the in-call screen, since we'll be visible in a
-        // partially-constructed state as soon as the "MMI Started" dialog
-        // gets dismissed.  So let's forcibly bail out right now.
-        if (DBG) log("onMMICancel: finishing InCallScreen...");
-        dismissAllDialogs();
-        endInCallScreenSession();
-    }
-
-    /**
-     * Handles an MMI_COMPLETE event, which is triggered by telephony,
-     * implying MMI
-     */
-    private void onMMIComplete(MmiCode mmiCode) {
-        // Check the code to see if the request is ready to
-        // finish, this includes any MMI state that is not
-        // PENDING.
-
-        // if phone is a CDMA phone display feature code completed message
-        int phoneType = mPhone.getPhoneType();
-        if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-            PhoneUtils.displayMMIComplete(mPhone, mApp, mmiCode, null, null);
-        } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
-            if (mmiCode.getState() != MmiCode.State.PENDING) {
-                if (DBG) log("Got MMI_COMPLETE, finishing InCallScreen...");
-                dismissAllDialogs();
-                endInCallScreenSession();
-            }
-        }
-    }
-
-    /**
-     * Handles the POST_ON_DIAL_CHARS message from the Phone
-     * (see our call to mPhone.setOnPostDialCharacter() above.)
-     *
-     * TODO: NEED TO TEST THIS SEQUENCE now that we no longer handle
-     * "dialable" key events here in the InCallScreen: we do directly to the
-     * Dialer UI instead.  Similarly, we may now need to go directly to the
-     * Dialer to handle POST_ON_DIAL_CHARS too.
-     */
-    private void handlePostOnDialChars(AsyncResult r, char ch) {
-        Connection c = (Connection) r.result;
-
-        if (c != null) {
-            Connection.PostDialState state =
-                    (Connection.PostDialState) r.userObj;
-
-            if (VDBG) log("handlePostOnDialChar: state = " +
-                    state + ", ch = " + ch);
-
-            switch (state) {
-                case STARTED:
-                    mDialer.stopLocalToneIfNeeded();
-                    if (mPauseInProgress) {
-                        /**
-                         * Note that on some devices, this will never happen,
-                         * because we will not ever enter the PAUSE state.
-                         */
-                        showPausePromptDialog(c, mPostDialStrAfterPause);
-                    }
-                    mPauseInProgress = false;
-                    mDialer.startLocalToneIfNeeded(ch);
-
-                    // TODO: is this needed, now that you can't actually
-                    // type DTMF chars or dial directly from here?
-                    // If so, we'd need to yank you out of the in-call screen
-                    // here too (and take you to the 12-key dialer in "in-call" mode.)
-                    // displayPostDialedChar(ch);
-                    break;
-
-                case WAIT:
-                    // wait shows a prompt.
-                    if (DBG) log("handlePostOnDialChars: show WAIT prompt...");
-                    mDialer.stopLocalToneIfNeeded();
-                    String postDialStr = c.getRemainingPostDialString();
-                    showWaitPromptDialog(c, postDialStr);
-                    break;
-
-                case WILD:
-                    if (DBG) log("handlePostOnDialChars: show WILD prompt");
-                    mDialer.stopLocalToneIfNeeded();
-                    showWildPromptDialog(c);
-                    break;
-
-                case COMPLETE:
-                    mDialer.stopLocalToneIfNeeded();
-                    break;
-
-                case PAUSE:
-                    // pauses for a brief period of time then continue dialing.
-                    mDialer.stopLocalToneIfNeeded();
-                    mPostDialStrAfterPause = c.getRemainingPostDialString();
-                    mPauseInProgress = true;
-                    break;
-
-                default:
-                    break;
-            }
-        }
-    }
-
-    /**
-     * Pop up an alert dialog with OK and Cancel buttons to allow user to
-     * Accept or Reject the WAIT inserted as part of the Dial string.
-     */
-    private void showWaitPromptDialog(final Connection c, String postDialStr) {
-        if (DBG) log("showWaitPromptDialogChoice: '" + postDialStr + "'...");
-
-        Resources r = getResources();
-        StringBuilder buf = new StringBuilder();
-        buf.append(r.getText(R.string.wait_prompt_str));
-        buf.append(postDialStr);
-
-        // if (DBG) log("- mWaitPromptDialog = " + mWaitPromptDialog);
-        if (mWaitPromptDialog != null) {
-            if (DBG) log("- DISMISSING mWaitPromptDialog.");
-            mWaitPromptDialog.dismiss();  // safe even if already dismissed
-            mWaitPromptDialog = null;
-        }
-
-        mWaitPromptDialog = new AlertDialog.Builder(this)
-                .setMessage(buf.toString())
-                .setPositiveButton(R.string.pause_prompt_yes,
-                        new DialogInterface.OnClickListener() {
-                            @Override
-                            public void onClick(DialogInterface dialog, int whichButton) {
-                                if (DBG) log("handle WAIT_PROMPT_CONFIRMED, proceed...");
-                                c.proceedAfterWaitChar();
-                            }
-                        })
-                .setNegativeButton(R.string.pause_prompt_no,
-                        new DialogInterface.OnClickListener() {
-                            @Override
-                            public void onClick(DialogInterface dialog, int whichButton) {
-                                if (DBG) log("handle POST_DIAL_CANCELED!");
-                                c.cancelPostDial();
-                            }
-                        })
-                .create();
-        mWaitPromptDialog.getWindow().addFlags(
-                WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
-
-        mWaitPromptDialog.show();
-    }
-
-    /**
-     * Pop up an alert dialog which waits for 2 seconds for each P (Pause) Character entered
-     * as part of the Dial String.
-     */
-    private void showPausePromptDialog(final Connection c, String postDialStrAfterPause) {
-        Resources r = getResources();
-        StringBuilder buf = new StringBuilder();
-        buf.append(r.getText(R.string.pause_prompt_str));
-        buf.append(postDialStrAfterPause);
-
-        if (mPausePromptDialog != null) {
-            if (DBG) log("- DISMISSING mPausePromptDialog.");
-            mPausePromptDialog.dismiss();  // safe even if already dismissed
-            mPausePromptDialog = null;
-        }
-
-        mPausePromptDialog = new AlertDialog.Builder(this)
-                .setMessage(buf.toString())
-                .create();
-        mPausePromptDialog.show();
-        // 2 second timer
-        Message msg = Message.obtain(mHandler, EVENT_PAUSE_DIALOG_COMPLETE);
-        mHandler.sendMessageDelayed(msg, PAUSE_PROMPT_DIALOG_TIMEOUT);
-    }
-
-    private View createWildPromptView() {
-        LinearLayout result = new LinearLayout(this);
-        result.setOrientation(LinearLayout.VERTICAL);
-        result.setPadding(5, 5, 5, 5);
-
-        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
-                        ViewGroup.LayoutParams.MATCH_PARENT,
-                        ViewGroup.LayoutParams.WRAP_CONTENT);
-
-        TextView promptMsg = new TextView(this);
-        promptMsg.setTextSize(14);
-        promptMsg.setTypeface(Typeface.DEFAULT_BOLD);
-        promptMsg.setText(getResources().getText(R.string.wild_prompt_str));
-
-        result.addView(promptMsg, lp);
-
-        mWildPromptText = new EditText(this);
-        mWildPromptText.setKeyListener(DialerKeyListener.getInstance());
-        mWildPromptText.setMovementMethod(null);
-        mWildPromptText.setTextSize(14);
-        mWildPromptText.setMaxLines(1);
-        mWildPromptText.setHorizontallyScrolling(true);
-        mWildPromptText.setBackgroundResource(android.R.drawable.editbox_background);
-
-        LinearLayout.LayoutParams lp2 = new LinearLayout.LayoutParams(
-                        ViewGroup.LayoutParams.MATCH_PARENT,
-                        ViewGroup.LayoutParams.WRAP_CONTENT);
-        lp2.setMargins(0, 3, 0, 0);
-
-        result.addView(mWildPromptText, lp2);
-
-        return result;
-    }
-
-    private void showWildPromptDialog(final Connection c) {
-        View v = createWildPromptView();
-
-        if (mWildPromptDialog != null) {
-            if (VDBG) log("- DISMISSING mWildPromptDialog.");
-            mWildPromptDialog.dismiss();  // safe even if already dismissed
-            mWildPromptDialog = null;
-        }
-
-        mWildPromptDialog = new AlertDialog.Builder(this)
-                .setView(v)
-                .setPositiveButton(
-                        R.string.send_button,
-                        new DialogInterface.OnClickListener() {
-                            @Override
-                            public void onClick(DialogInterface dialog, int whichButton) {
-                                if (VDBG) log("handle WILD_PROMPT_CHAR_ENTERED, proceed...");
-                                String replacement = null;
-                                if (mWildPromptText != null) {
-                                    replacement = mWildPromptText.getText().toString();
-                                    mWildPromptText = null;
-                                }
-                                c.proceedAfterWildChar(replacement);
-                                mApp.pokeUserActivity();
-                            }
-                        })
-                .setOnCancelListener(
-                        new DialogInterface.OnCancelListener() {
-                            @Override
-                            public void onCancel(DialogInterface dialog) {
-                                if (VDBG) log("handle POST_DIAL_CANCELED!");
-                                c.cancelPostDial();
-                                mApp.pokeUserActivity();
-                            }
-                        })
-                .create();
-        mWildPromptDialog.getWindow().addFlags(
-                WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
-        mWildPromptDialog.show();
-
-        mWildPromptText.requestFocus();
-    }
-
-    /**
-     * Updates the state of the in-call UI based on the current state of
-     * the Phone.  This call has no effect if we're not currently the
-     * foreground activity.
-     *
-     * This method is only allowed to be called from the UI thread (since it
-     * manipulates our View hierarchy).  If you need to update the screen from
-     * some other thread, or if you just want to "post a request" for the screen
-     * to be updated (rather than doing it synchronously), call
-     * requestUpdateScreen() instead.
-     *
-     * Right now this method will update UI visibility immediately, with no animation.
-     * TODO: have animate flag here and use it anywhere possible.
-     */
-    private void updateScreen() {
-        if (DBG) log("updateScreen()...");
-        final InCallScreenMode inCallScreenMode = mApp.inCallUiState.inCallScreenMode;
-        if (VDBG) {
-            PhoneConstants.State state = mCM.getState();
-            log("  - phone state = " + state);
-            log("  - inCallScreenMode = " + inCallScreenMode);
-        }
-
-        // Don't update anything if we're not in the foreground (there's
-        // no point updating our UI widgets since we're not visible!)
-        // Also note this check also ensures we won't update while we're
-        // in the middle of pausing, which could cause a visible glitch in
-        // the "activity ending" transition.
-        if (!mIsForegroundActivity) {
-            if (DBG) log("- updateScreen: not the foreground Activity! Bailing out...");
-            return;
-        }
-
-        if (inCallScreenMode == InCallScreenMode.OTA_NORMAL) {
-            if (DBG) log("- updateScreen: OTA call state NORMAL (NOT updating in-call UI)...");
-            mCallCard.setVisibility(View.GONE);
-            if (mApp.otaUtils != null) {
-                mApp.otaUtils.otaShowProperScreen();
-            } else {
-                Log.w(LOG_TAG, "OtaUtils object is null, not showing any screen for that.");
-            }
-            return;  // Return without updating in-call UI.
-        } else if (inCallScreenMode == InCallScreenMode.OTA_ENDED) {
-            if (DBG) log("- updateScreen: OTA call ended state (NOT updating in-call UI)...");
-            mCallCard.setVisibility(View.GONE);
-            // Wake up the screen when we get notification, good or bad.
-            mApp.wakeUpScreen();
-            if (mApp.cdmaOtaScreenState.otaScreenState
-                    == CdmaOtaScreenState.OtaScreenState.OTA_STATUS_ACTIVATION) {
-                if (DBG) log("- updateScreen: OTA_STATUS_ACTIVATION");
-                if (mApp.otaUtils != null) {
-                    if (DBG) log("- updateScreen: mApp.otaUtils is not null, "
-                                  + "call otaShowActivationScreen");
-                    mApp.otaUtils.otaShowActivateScreen();
-                }
-            } else {
-                if (DBG) log("- updateScreen: OTA Call end state for Dialogs");
-                if (mApp.otaUtils != null) {
-                    if (DBG) log("- updateScreen: Show OTA Success Failure dialog");
-                    mApp.otaUtils.otaShowSuccessFailure();
-                }
-            }
-            return;  // Return without updating in-call UI.
-        } else if (inCallScreenMode == InCallScreenMode.MANAGE_CONFERENCE) {
-            if (DBG) log("- updateScreen: manage conference mode (NOT updating in-call UI)...");
-            mCallCard.setVisibility(View.GONE);
-            updateManageConferencePanelIfNecessary();
-            return;  // Return without updating in-call UI.
-        } else if (inCallScreenMode == InCallScreenMode.CALL_ENDED) {
-            if (DBG) log("- updateScreen: call ended state...");
-            // Continue with the rest of updateScreen() as usual, since we do
-            // need to update the background (to the special "call ended" color)
-            // and the CallCard (to show the "Call ended" label.)
-        }
-
-        if (DBG) log("- updateScreen: updating the in-call UI...");
-        // Note we update the InCallTouchUi widget before the CallCard,
-        // since the CallCard adjusts its size based on how much vertical
-        // space the InCallTouchUi widget needs.
-        updateInCallTouchUi();
-        mCallCard.updateState(mCM);
-
-        // If an incoming call is ringing, make sure the dialpad is
-        // closed.  (We do this to make sure we're not covering up the
-        // "incoming call" UI.)
-        if (mCM.getState() == PhoneConstants.State.RINGING) {
-            if (mDialer.isOpened()) {
-              Log.i(LOG_TAG, "During RINGING state we force hiding dialpad.");
-              closeDialpadInternal(false);  // don't do the "closing" animation
-            }
-
-            // At this point, we are guranteed that the dialer is closed.
-            // This means that it is safe to clear out the "history" of DTMF digits
-            // you may have typed into the previous call (so you don't see the
-            // previous call's digits if you answer this call and then bring up the
-            // dialpad.)
-            //
-            // TODO: it would be more precise to do this when you *answer* the
-            // incoming call, rather than as soon as it starts ringing, but
-            // the InCallScreen doesn't keep enough state right now to notice
-            // that specific transition in onPhoneStateChanged().
-            // TODO: This clears out the dialpad context as well so when a second
-            // call comes in while a voicemail call is happening, the voicemail
-            // dialpad will no longer have the "Voice Mail" context. It's a small
-            // case so not terribly bad, but we need to maintain a better
-            // call-to-callstate mapping before we can fix this.
-            mDialer.clearDigits();
-        }
-
-
-        // Now that we're sure DTMF dialpad is in an appropriate state, reflect
-        // the dialpad state into CallCard
-        updateCallCardVisibilityPerDialerState(false);
-
-        updateProgressIndication();
-
-        // Forcibly take down all dialog if an incoming call is ringing.
-        if (mCM.hasActiveRingingCall()) {
-            dismissAllDialogs();
-        } else {
-            // Wait prompt dialog is not currently up.  But it *should* be
-            // up if the FG call has a connection in the WAIT state and
-            // the phone isn't ringing.
-            String postDialStr = null;
-            List<Connection> fgConnections = mCM.getFgCallConnections();
-            int phoneType = mCM.getFgPhone().getPhoneType();
-            if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-                Connection fgLatestConnection = mCM.getFgCallLatestConnection();
-                if (mApp.cdmaPhoneCallState.getCurrentCallState() ==
-                        CdmaPhoneCallState.PhoneCallState.CONF_CALL) {
-                    for (Connection cn : fgConnections) {
-                        if ((cn != null) && (cn.getPostDialState() ==
-                                Connection.PostDialState.WAIT)) {
-                            cn.cancelPostDial();
-                        }
-                    }
-                } else if ((fgLatestConnection != null)
-                     && (fgLatestConnection.getPostDialState() == Connection.PostDialState.WAIT)) {
-                    if(DBG) log("show the Wait dialog for CDMA");
-                    postDialStr = fgLatestConnection.getRemainingPostDialString();
-                    showWaitPromptDialog(fgLatestConnection, postDialStr);
-                }
-            } else if ((phoneType == PhoneConstants.PHONE_TYPE_GSM)
-                    || (phoneType == PhoneConstants.PHONE_TYPE_SIP)) {
-                for (Connection cn : fgConnections) {
-                    if ((cn != null) && (cn.getPostDialState() == Connection.PostDialState.WAIT)) {
-                        postDialStr = cn.getRemainingPostDialString();
-                        showWaitPromptDialog(cn, postDialStr);
-                    }
-                }
-            } else {
-                throw new IllegalStateException("Unexpected phone type: " + phoneType);
-            }
-        }
-    }
-
-    /**
-     * (Re)synchronizes the onscreen UI with the current state of the
-     * telephony framework.
-     *
-     * @return SyncWithPhoneStateStatus.SUCCESS if we successfully updated the UI, or
-     *    SyncWithPhoneStateStatus.PHONE_NOT_IN_USE if there was no phone state to sync
-     *    with (ie. the phone was completely idle).  In the latter case, we
-     *    shouldn't even be in the in-call UI in the first place, and it's
-     *    the caller's responsibility to bail out of this activity by
-     *    calling endInCallScreenSession if appropriate.
-     *
-     * This method directly calls updateScreen() in the normal "phone is
-     * in use" case, so there's no need for the caller to do so.
-     */
-    private SyncWithPhoneStateStatus syncWithPhoneState() {
-        boolean updateSuccessful = false;
-        if (DBG) log("syncWithPhoneState()...");
-        if (DBG) PhoneUtils.dumpCallState(mPhone);
-
-        // Make sure the Phone is "in use".  (If not, we shouldn't be on
-        // this screen in the first place.)
-
-        // An active or just-ended OTA call counts as "in use".
-        if (TelephonyCapabilities.supportsOtasp(mCM.getFgPhone())
-                && ((mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_NORMAL)
-                    || (mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_ENDED))) {
-            // Even when OTA Call ends, need to show OTA End UI,
-            // so return Success to allow UI update.
-            return SyncWithPhoneStateStatus.SUCCESS;
-        }
-
-        // If an MMI code is running that also counts as "in use".
-        //
-        // TODO: We currently only call getPendingMmiCodes() for GSM
-        //   phones.  (The code's been that way all along.)  But CDMAPhone
-        //   does in fact implement getPendingMmiCodes(), so should we
-        //   check that here regardless of the phone type?
-        boolean hasPendingMmiCodes =
-                (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_GSM)
-                && !mPhone.getPendingMmiCodes().isEmpty();
-
-        // Finally, it's also OK to stay here on the InCallScreen if we
-        // need to display a progress indicator while something's
-        // happening in the background.
-        boolean showProgressIndication = mApp.inCallUiState.isProgressIndicationActive();
-
-        boolean showScreenEvenAfterDisconnect = mApp.inCallUiState.showAlreadyDisconnectedState;
-
-        if (mCM.hasActiveFgCall() || mCM.hasActiveBgCall() || mCM.hasActiveRingingCall()
-                || hasPendingMmiCodes || showProgressIndication || showScreenEvenAfterDisconnect) {
-            if (VDBG) log("syncWithPhoneState: it's ok to be here; update the screen...");
-            updateScreen();
-            return SyncWithPhoneStateStatus.SUCCESS;
-        }
-
-        Log.i(LOG_TAG, "syncWithPhoneState: phone is idle (shouldn't be here)");
-        return SyncWithPhoneStateStatus.PHONE_NOT_IN_USE;
-    }
-
-
-
-    private void handleMissingVoiceMailNumber() {
-        if (DBG) log("handleMissingVoiceMailNumber");
-
-        final Message msg = Message.obtain(mHandler);
-        msg.what = DONT_ADD_VOICEMAIL_NUMBER;
-
-        final Message msg2 = Message.obtain(mHandler);
-        msg2.what = ADD_VOICEMAIL_NUMBER;
-
-        mMissingVoicemailDialog = new AlertDialog.Builder(this)
-                .setTitle(R.string.no_vm_number)
-                .setMessage(R.string.no_vm_number_msg)
-                .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
-                        public void onClick(DialogInterface dialog, int which) {
-                            if (VDBG) log("Missing voicemail AlertDialog: POSITIVE click...");
-                            msg.sendToTarget();  // see dontAddVoiceMailNumber()
-                            mApp.pokeUserActivity();
-                        }})
-                .setNegativeButton(R.string.add_vm_number_str,
-                                   new DialogInterface.OnClickListener() {
-                        public void onClick(DialogInterface dialog, int which) {
-                            if (VDBG) log("Missing voicemail AlertDialog: NEGATIVE click...");
-                            msg2.sendToTarget();  // see addVoiceMailNumber()
-                            mApp.pokeUserActivity();
-                        }})
-                .setOnCancelListener(new OnCancelListener() {
-                        public void onCancel(DialogInterface dialog) {
-                            if (VDBG) log("Missing voicemail AlertDialog: CANCEL handler...");
-                            msg.sendToTarget();  // see dontAddVoiceMailNumber()
-                            mApp.pokeUserActivity();
-                        }})
-                .create();
-
-        // When the dialog is up, completely hide the in-call UI
-        // underneath (which is in a partially-constructed state).
-        mMissingVoicemailDialog.getWindow().addFlags(
-                WindowManager.LayoutParams.FLAG_DIM_BEHIND);
-
-        mMissingVoicemailDialog.show();
-    }
-
-    private void addVoiceMailNumberPanel() {
-        if (mMissingVoicemailDialog != null) {
-            mMissingVoicemailDialog.dismiss();
-            mMissingVoicemailDialog = null;
-        }
-        if (DBG) log("addVoiceMailNumberPanel: finishing InCallScreen...");
-        endInCallScreenSession();
-
-        if (DBG) log("show vm setting");
-
-        // navigate to the Voicemail setting in the Call Settings activity.
-        Intent intent = new Intent(CallFeaturesSetting.ACTION_ADD_VOICEMAIL);
-        intent.setClass(this, CallFeaturesSetting.class);
-        startActivity(intent);
-    }
-
-    private void dontAddVoiceMailNumber() {
-        if (mMissingVoicemailDialog != null) {
-            mMissingVoicemailDialog.dismiss();
-            mMissingVoicemailDialog = null;
-        }
-        if (DBG) log("dontAddVoiceMailNumber: finishing InCallScreen...");
-        endInCallScreenSession();
-    }
-
-    /**
-     * Do some delayed cleanup after a Phone call gets disconnected.
-     *
-     * This method gets called a couple of seconds after any DISCONNECT
-     * event from the Phone; it's triggered by the
-     * DELAYED_CLEANUP_AFTER_DISCONNECT message we send in onDisconnect().
-     *
-     * If the Phone is totally idle right now, that means we've already
-     * shown the "call ended" state for a couple of seconds, and it's now
-     * time to endInCallScreenSession this activity.
-     *
-     * If the Phone is *not* idle right now, that probably means that one
-     * call ended but the other line is still in use.  In that case, do
-     * nothing, and instead stay here on the InCallScreen.
-     */
-    private void delayedCleanupAfterDisconnect() {
-        if (VDBG) log("delayedCleanupAfterDisconnect()...  Phone state = " + mCM.getState());
-
-        // Clean up any connections in the DISCONNECTED state.
-        //
-        // [Background: Even after a connection gets disconnected, its
-        // Connection object still stays around, in the special
-        // DISCONNECTED state.  This is necessary because we we need the
-        // caller-id information from that Connection to properly draw the
-        // "Call ended" state of the CallCard.
-        //   But at this point we truly don't need that connection any
-        // more, so tell the Phone that it's now OK to to clean up any
-        // connections still in that state.]
-        mCM.clearDisconnected();
-
-        // There are two cases where we should *not* exit the InCallScreen:
-        //   (1) Phone is still in use
-        // or
-        //   (2) There's an active progress indication (i.e. the "Retrying..."
-        //       progress dialog) that we need to continue to display.
-
-        boolean stayHere = phoneIsInUse() || mApp.inCallUiState.isProgressIndicationActive();
-
-        if (stayHere) {
-            if (DBG) log("- delayedCleanupAfterDisconnect: staying on the InCallScreen...");
-        } else {
-            // Phone is idle!  We should exit the in-call UI now.
-            if (DBG) log("- delayedCleanupAfterDisconnect: phone is idle...");
-
-            // And (finally!) exit from the in-call screen
-            // (but not if we're already in the process of pausing...)
-            if (mIsForegroundActivity) {
-                if (DBG) log("- delayedCleanupAfterDisconnect: finishing InCallScreen...");
-
-                // In some cases we finish the call by taking the user to the
-                // Call Log.  Otherwise, we simply call endInCallScreenSession,
-                // which will take us back to wherever we came from.
-                //
-                // UI note: In eclair and earlier, we went to the Call Log
-                // after outgoing calls initiated on the device, but never for
-                // incoming calls.  Now we do it for incoming calls too, as
-                // long as the call was answered by the user.  (We always go
-                // back where you came from after a rejected or missed incoming
-                // call.)
-                //
-                // And in any case, *never* go to the call log if we're in
-                // emergency mode (i.e. if the screen is locked and a lock
-                // pattern or PIN/password is set), or if we somehow got here
-                // on a non-voice-capable device.
-
-                if (VDBG) log("- Post-call behavior:");
-                if (VDBG) log("  - mLastDisconnectCause = " + mLastDisconnectCause);
-                if (VDBG) log("  - isPhoneStateRestricted() = " + isPhoneStateRestricted());
-
-                // DisconnectCause values in the most common scenarios:
-                // - INCOMING_MISSED: incoming ringing call times out, or the
-                //                    other end hangs up while still ringing
-                // - INCOMING_REJECTED: user rejects the call while ringing
-                // - LOCAL: user hung up while a call was active (after
-                //          answering an incoming call, or after making an
-                //          outgoing call)
-                // - NORMAL: the other end hung up (after answering an incoming
-                //           call, or after making an outgoing call)
-
-                if ((mLastDisconnectCause != Connection.DisconnectCause.INCOMING_MISSED)
-                        && (mLastDisconnectCause != Connection.DisconnectCause.INCOMING_REJECTED)
-                        && !isPhoneStateRestricted()
-                        && PhoneGlobals.sVoiceCapable) {
-                    final Intent intent = mApp.createPhoneEndIntentUsingCallOrigin();
-                    ActivityOptions opts = ActivityOptions.makeCustomAnimation(this,
-                            R.anim.activity_close_enter, R.anim.activity_close_exit);
-                    if (VDBG) {
-                        log("- Show Call Log (or Dialtacts) after disconnect. Current intent: "
-                                + intent);
-                    }
-                    try {
-                        startActivity(intent, opts.toBundle());
-                    } catch (ActivityNotFoundException e) {
-                        // Don't crash if there's somehow no "Call log" at
-                        // all on this device.
-                        // (This should never happen, though, since we already
-                        // checked PhoneApp.sVoiceCapable above, and any
-                        // voice-capable device surely *should* have a call
-                        // log activity....)
-                        Log.w(LOG_TAG, "delayedCleanupAfterDisconnect: "
-                              + "transition to call log failed; intent = " + intent);
-                        // ...so just return back where we came from....
-                    }
-                    // Even if we did go to the call log, note that we still
-                    // call endInCallScreenSession (below) to make sure we don't
-                    // stay in the activity history.
-                }
-
-            }
-            endInCallScreenSession();
-
-            // Reset the call origin when the session ends and this in-call UI is being finished.
-            mApp.setLatestActiveCallOrigin(null);
-        }
-    }
-
-
-    /**
-     * View.OnClickListener implementation.
-     *
-     * This method handles clicks from UI elements that use the
-     * InCallScreen itself as their OnClickListener.
-     *
-     * Note: Currently this method is used only for a few special buttons:
-     * - the mButtonManageConferenceDone "Back to call" button
-     * - the "dim" effect for the secondary call photo in CallCard as the second "swap" button
-     * - other OTASP-specific buttons managed by OtaUtils.java.
-     *
-     * *Most* in-call controls are handled by the handleOnscreenButtonClick() method, via the
-     * InCallTouchUi widget.
-     */
-    @Override
-    public void onClick(View view) {
-        int id = view.getId();
-        if (VDBG) log("onClick(View " + view + ", id " + id + ")...");
-
-        switch (id) {
-            case R.id.manage_done:  // mButtonManageConferenceDone
-                if (VDBG) log("onClick: mButtonManageConferenceDone...");
-                // Hide the Manage Conference panel, return to NORMAL mode.
-                setInCallScreenMode(InCallScreenMode.NORMAL);
-                requestUpdateScreen();
-                break;
-
-            case R.id.dim_effect_for_secondary_photo:
-                if (mInCallControlState.canSwap) {
-                    internalSwapCalls();
-                }
-                break;
-
-            default:
-                // Presumably one of the OTASP-specific buttons managed by
-                // OtaUtils.java.
-                // (TODO: It would be cleaner for the OtaUtils instance itself to
-                // be the OnClickListener for its own buttons.)
-
-                if ((mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_NORMAL
-                     || mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_ENDED)
-                    && mApp.otaUtils != null) {
-                    mApp.otaUtils.onClickHandler(id);
-                } else {
-                    // Uh oh: we *should* only receive clicks here from the
-                    // buttons managed by OtaUtils.java, but if we're not in one
-                    // of the special OTASP modes, those buttons shouldn't have
-                    // been visible in the first place.
-                    Log.w(LOG_TAG,
-                          "onClick: unexpected click from ID " + id + " (View = " + view + ")");
-                }
-                break;
-        }
-
-        EventLog.writeEvent(EventLogTags.PHONE_UI_BUTTON_CLICK,
-                (view instanceof TextView) ? ((TextView) view).getText() : "");
-
-        // Clicking any onscreen UI element counts as explicit "user activity".
-        mApp.pokeUserActivity();
-    }
-
-    private void onHoldClick() {
-        final boolean hasActiveCall = mCM.hasActiveFgCall();
-        final boolean hasHoldingCall = mCM.hasActiveBgCall();
-        log("onHoldClick: hasActiveCall = " + hasActiveCall
-            + ", hasHoldingCall = " + hasHoldingCall);
-        boolean newHoldState;
-        boolean holdButtonEnabled;
-        if (hasActiveCall && !hasHoldingCall) {
-            // There's only one line in use, and that line is active.
-            PhoneUtils.switchHoldingAndActive(
-                mCM.getFirstActiveBgCall());  // Really means "hold" in this state
-            newHoldState = true;
-            holdButtonEnabled = true;
-        } else if (!hasActiveCall && hasHoldingCall) {
-            // There's only one line in use, and that line is on hold.
-            PhoneUtils.switchHoldingAndActive(
-                mCM.getFirstActiveBgCall());  // Really means "unhold" in this state
-            newHoldState = false;
-            holdButtonEnabled = true;
-        } else {
-            // Either zero or 2 lines are in use; "hold/unhold" is meaningless.
-            newHoldState = false;
-            holdButtonEnabled = false;
-        }
-        // No need to forcibly update the onscreen UI; just wait for the
-        // onPhoneStateChanged() callback.  (This seems to be responsive
-        // enough.)
-
-        // Also, any time we hold or unhold, force the DTMF dialpad to close.
-        closeDialpadInternal(true);  // do the "closing" animation
-    }
-
-    /**
-     * Toggles in-call audio between speaker and the built-in earpiece (or
-     * wired headset.)
-     */
-    public void toggleSpeaker() {
-        // TODO: Turning on the speaker seems to enable the mic
-        //   whether or not the "mute" feature is active!
-        // Not sure if this is an feature of the telephony API
-        //   that I need to handle specially, or just a bug.
-        boolean newSpeakerState = !PhoneUtils.isSpeakerOn(this);
-        log("toggleSpeaker(): newSpeakerState = " + newSpeakerState);
-
-        PhoneUtils.turnOnSpeaker(this, newSpeakerState, true);
-
-        // And update the InCallTouchUi widget (since the "audio mode"
-        // button might need to change its appearance based on the new
-        // audio state.)
-        updateInCallTouchUi();
-    }
-
-    /*
-     * onMuteClick is called only when there is a foreground call
-     */
-    private void onMuteClick() {
-        boolean newMuteState = !PhoneUtils.getMute();
-        log("onMuteClick(): newMuteState = " + newMuteState);
-        PhoneUtils.setMute(newMuteState);
-    }
-
-    /**
-     * Handle a click on the "Open/Close dialpad" button.
-     *
-     * @see DTMFTwelveKeyDialer#openDialer(boolean)
-     * @see DTMFTwelveKeyDialer#closeDialer(boolean)
-     */
-    private void onOpenCloseDialpad() {
-        if (VDBG) log("onOpenCloseDialpad()...");
-        if (mDialer.isOpened()) {
-            closeDialpadInternal(true);  // do the "closing" animation
-        } else {
-            openDialpadInternal(true);  // do the "opening" animation
-        }
-    }
-
-    /** Internal wrapper around {@link DTMFTwelveKeyDialer#openDialer(boolean)} */
-    private void openDialpadInternal(boolean animate) {
-        mDialer.openDialer(animate);
-        // And update the InCallUiState (so that we'll restore the dialpad
-        // to the correct state if we get paused/resumed).
-        mApp.inCallUiState.showDialpad = true;
-    }
-
-    // Internal wrapper around DTMFTwelveKeyDialer.closeDialer()
-    private void closeDialpadInternal(boolean animate) {
-        mDialer.closeDialer(animate);
-        // And update the InCallUiState (so that we'll restore the dialpad
-        // to the correct state if we get paused/resumed).
-        mApp.inCallUiState.showDialpad = false;
-    }
-
-    /**
-     * Handles button clicks from the InCallTouchUi widget.
-     */
-    /* package */ void handleOnscreenButtonClick(int id) {
-        if (DBG) log("handleOnscreenButtonClick(id " + id + ")...");
-
-        switch (id) {
-            // Actions while an incoming call is ringing:
-            case R.id.incomingCallAnswer:
-                internalAnswerCall();
-                break;
-            case R.id.incomingCallReject:
-                hangupRingingCall();
-                break;
-            case R.id.incomingCallRespondViaSms:
-                internalRespondViaSms();
-                break;
-
-            // The other regular (single-tap) buttons used while in-call:
-            case R.id.holdButton:
-                onHoldClick();
-                break;
-            case R.id.swapButton:
-                internalSwapCalls();
-                break;
-            case R.id.endButton:
-                internalHangup();
-                break;
-            case R.id.dialpadButton:
-                onOpenCloseDialpad();
-                break;
-            case R.id.muteButton:
-                onMuteClick();
-                break;
-            case R.id.addButton:
-                PhoneUtils.startNewCall(mCM);  // Fires off an ACTION_DIAL intent
-                break;
-            case R.id.mergeButton:
-            case R.id.cdmaMergeButton:
-                PhoneUtils.mergeCalls(mCM);
-                break;
-            case R.id.manageConferenceButton:
-                // Show the Manage Conference panel.
-                setInCallScreenMode(InCallScreenMode.MANAGE_CONFERENCE);
-                requestUpdateScreen();
-                break;
-
-            default:
-                Log.w(LOG_TAG, "handleOnscreenButtonClick: unexpected ID " + id);
-                break;
-        }
-
-        // Clicking any onscreen UI element counts as explicit "user activity".
-        mApp.pokeUserActivity();
-
-        // Just in case the user clicked a "stateful" UI element (like one
-        // of the toggle buttons), we force the in-call buttons to update,
-        // to make sure the user sees the *new* current state.
-        //
-        // Note that some in-call buttons will *not* immediately change the
-        // state of the UI, namely those that send a request to the telephony
-        // layer (like "Hold" or "End call".)  For those buttons, the
-        // updateInCallTouchUi() call here won't have any visible effect.
-        // Instead, the UI will be updated eventually when the next
-        // onPhoneStateChanged() event comes in and triggers an updateScreen()
-        // call.
-        //
-        // TODO: updateInCallTouchUi() is overkill here; it would be
-        // more efficient to update *only* the affected button(s).
-        // (But this isn't a big deal since updateInCallTouchUi() is pretty
-        // cheap anyway...)
-        updateInCallTouchUi();
-    }
-
-    /**
-     * Display a status or error indication to the user according to the
-     * specified InCallUiState.CallStatusCode value.
-     */
-    private void showStatusIndication(CallStatusCode status) {
-        switch (status) {
-            case SUCCESS:
-                // The InCallScreen does not need to display any kind of error indication,
-                // so we shouldn't have gotten here in the first place.
-                Log.wtf(LOG_TAG, "showStatusIndication: nothing to display");
-                break;
-
-            case POWER_OFF:
-                // Radio is explictly powered off, presumably because the
-                // device is in airplane mode.
-                //
-                // TODO: For now this UI is ultra-simple: we simply display
-                // a message telling the user to turn off airplane mode.
-                // But it might be nicer for the dialog to offer the option
-                // to turn the radio on right there (and automatically retry
-                // the call once network registration is complete.)
-                showGenericErrorDialog(R.string.incall_error_power_off,
-                                       true /* isStartupError */);
-                break;
-
-            case EMERGENCY_ONLY:
-                // Only emergency numbers are allowed, but we tried to dial
-                // a non-emergency number.
-                // (This state is currently unused; see comments above.)
-                showGenericErrorDialog(R.string.incall_error_emergency_only,
-                                       true /* isStartupError */);
-                break;
-
-            case OUT_OF_SERVICE:
-                // No network connection.
-                showGenericErrorDialog(R.string.incall_error_out_of_service,
-                                       true /* isStartupError */);
-                break;
-
-            case NO_PHONE_NUMBER_SUPPLIED:
-                // The supplied Intent didn't contain a valid phone number.
-                // (This is rare and should only ever happen with broken
-                // 3rd-party apps.)  For now just show a generic error.
-                showGenericErrorDialog(R.string.incall_error_no_phone_number_supplied,
-                                       true /* isStartupError */);
-                break;
-
-            case DIALED_MMI:
-                // Our initial phone number was actually an MMI sequence.
-                // There's no real "error" here, but we do bring up the
-                // a Toast (as requested of the New UI paradigm).
-                //
-                // In-call MMIs do not trigger the normal MMI Initiate
-                // Notifications, so we should notify the user here.
-                // Otherwise, the code in PhoneUtils.java should handle
-                // user notifications in the form of Toasts or Dialogs.
-                if (mCM.getState() == PhoneConstants.State.OFFHOOK) {
-                    Toast.makeText(mApp, R.string.incall_status_dialed_mmi, Toast.LENGTH_SHORT)
-                            .show();
-                }
-                break;
-
-            case CALL_FAILED:
-                // We couldn't successfully place the call; there was some
-                // failure in the telephony layer.
-                // TODO: Need UI spec for this failure case; for now just
-                // show a generic error.
-                showGenericErrorDialog(R.string.incall_error_call_failed,
-                                       true /* isStartupError */);
-                break;
-
-            case VOICEMAIL_NUMBER_MISSING:
-                // We tried to call a voicemail: URI but the device has no
-                // voicemail number configured.
-                handleMissingVoiceMailNumber();
-                break;
-
-            case CDMA_CALL_LOST:
-                // This status indicates that InCallScreen should display the
-                // CDMA-specific "call lost" dialog.  (If an outgoing call fails,
-                // and the CDMA "auto-retry" feature is enabled, *and* the retried
-                // call fails too, we display this specific dialog.)
-                //
-                // TODO: currently unused; see InCallUiState.needToShowCallLostDialog
-                break;
-
-            case EXITED_ECM:
-                // This status indicates that InCallScreen needs to display a
-                // warning that we're exiting ECM (emergency callback mode).
-                showExitingECMDialog();
-                break;
-
-            default:
-                throw new IllegalStateException(
-                    "showStatusIndication: unexpected status code: " + status);
-        }
-
-        // TODO: still need to make sure that pressing OK or BACK from
-        // *any* of the dialogs we launch here ends up calling
-        // inCallUiState.clearPendingCallStatusCode()
-        //  *and*
-        // make sure the Dialog handles both OK *and* cancel by calling
-        // endInCallScreenSession.  (See showGenericErrorDialog() for an
-        // example.)
-        //
-        // (showGenericErrorDialog() currently does this correctly,
-        // but handleMissingVoiceMailNumber() probably needs to be fixed too.)
-        //
-        // Also need to make sure that bailing out of any of these dialogs by
-        // pressing Home clears out the pending status code too.  (If you do
-        // that, neither the dialog's clickListener *or* cancelListener seems
-        // to run...)
-    }
-
-    /**
-     * Utility function to bring up a generic "error" dialog, and then bail
-     * out of the in-call UI when the user hits OK (or the BACK button.)
-     */
-    private void showGenericErrorDialog(int resid, boolean isStartupError) {
-        CharSequence msg = getResources().getText(resid);
-        if (DBG) log("showGenericErrorDialog('" + msg + "')...");
-
-        // create the clicklistener and cancel listener as needed.
-        DialogInterface.OnClickListener clickListener;
-        OnCancelListener cancelListener;
-        if (isStartupError) {
-            clickListener = new DialogInterface.OnClickListener() {
-                public void onClick(DialogInterface dialog, int which) {
-                    bailOutAfterErrorDialog();
-                }};
-            cancelListener = new OnCancelListener() {
-                public void onCancel(DialogInterface dialog) {
-                    bailOutAfterErrorDialog();
-                }};
-        } else {
-            clickListener = new DialogInterface.OnClickListener() {
-                public void onClick(DialogInterface dialog, int which) {
-                    delayedCleanupAfterDisconnect();
-                }};
-            cancelListener = new OnCancelListener() {
-                public void onCancel(DialogInterface dialog) {
-                    delayedCleanupAfterDisconnect();
-                }};
-        }
-
-        // TODO: Consider adding a setTitle() call here (with some generic
-        // "failure" title?)
-        mGenericErrorDialog = new AlertDialog.Builder(this)
-                .setMessage(msg)
-                .setPositiveButton(R.string.ok, clickListener)
-                .setOnCancelListener(cancelListener)
-                .create();
-
-        // When the dialog is up, completely hide the in-call UI
-        // underneath (which is in a partially-constructed state).
-        mGenericErrorDialog.getWindow().addFlags(
-                WindowManager.LayoutParams.FLAG_DIM_BEHIND);
-
-        mGenericErrorDialog.show();
-    }
-
-    private void showCallLostDialog() {
-        if (DBG) log("showCallLostDialog()...");
-
-        // Don't need to show the dialog if InCallScreen isn't in the forgeround
-        if (!mIsForegroundActivity) {
-            if (DBG) log("showCallLostDialog: not the foreground Activity! Bailing out...");
-            return;
-        }
-
-        // Don't need to show the dialog again, if there is one already.
-        if (mCallLostDialog != null) {
-            if (DBG) log("showCallLostDialog: There is a mCallLostDialog already.");
-            return;
-        }
-
-        mCallLostDialog = new AlertDialog.Builder(this)
-                .setMessage(R.string.call_lost)
-                .setIconAttribute(android.R.attr.alertDialogIcon)
-                .create();
-        mCallLostDialog.show();
-    }
-
-    /**
-     * Displays the "Exiting ECM" warning dialog.
-     *
-     * Background: If the phone is currently in ECM (Emergency callback
-     * mode) and we dial a non-emergency number, that automatically
-     * *cancels* ECM.  (That behavior comes from CdmaCallTracker.dial().)
-     * When that happens, we need to warn the user that they're no longer
-     * in ECM (bug 4207607.)
-     *
-     * So bring up a dialog explaining what's happening.  There's nothing
-     * for the user to do, by the way; we're simply providing an
-     * indication that they're exiting ECM.  We *could* use a Toast for
-     * this, but toasts are pretty easy to miss, so instead use a dialog
-     * with a single "OK" button.
-     *
-     * TODO: it's ugly that the code here has to make assumptions about
-     *   the behavior of the telephony layer (namely that dialing a
-     *   non-emergency number while in ECM causes us to exit ECM.)
-     *
-     *   Instead, this warning dialog should really be triggered by our
-     *   handler for the
-     *   TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED intent in
-     *   PhoneApp.java.  But that won't work until that intent also
-     *   includes a *reason* why we're exiting ECM, since we need to
-     *   display this dialog when exiting ECM because of an outgoing call,
-     *   but NOT if we're exiting ECM because the user manually turned it
-     *   off via the EmergencyCallbackModeExitDialog.
-     *
-     *   Or, it might be simpler to just have outgoing non-emergency calls
-     *   *not* cancel ECM.  That way the UI wouldn't have to do anything
-     *   special here.
-     */
-    private void showExitingECMDialog() {
-        Log.i(LOG_TAG, "showExitingECMDialog()...");
-
-        if (mExitingECMDialog != null) {
-            if (DBG) log("- DISMISSING mExitingECMDialog.");
-            mExitingECMDialog.dismiss();  // safe even if already dismissed
-            mExitingECMDialog = null;
-        }
-
-        // When the user dismisses the "Exiting ECM" dialog, we clear out
-        // the pending call status code field (since we're done with this
-        // dialog), but do *not* bail out of the InCallScreen.
-
-        final InCallUiState inCallUiState = mApp.inCallUiState;
-        DialogInterface.OnClickListener clickListener = new DialogInterface.OnClickListener() {
-                public void onClick(DialogInterface dialog, int which) {
-                    inCallUiState.clearPendingCallStatusCode();
-                }};
-        OnCancelListener cancelListener = new OnCancelListener() {
-                public void onCancel(DialogInterface dialog) {
-                    inCallUiState.clearPendingCallStatusCode();
-                }};
-
-        // Ultra-simple AlertDialog with only an OK button:
-        mExitingECMDialog = new AlertDialog.Builder(this)
-                .setMessage(R.string.progress_dialog_exiting_ecm)
-                .setPositiveButton(R.string.ok, clickListener)
-                .setOnCancelListener(cancelListener)
-                .create();
-        mExitingECMDialog.getWindow().addFlags(
-                WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
-        mExitingECMDialog.show();
-    }
-
-    private void bailOutAfterErrorDialog() {
-        if (mGenericErrorDialog != null) {
-            if (DBG) log("bailOutAfterErrorDialog: DISMISSING mGenericErrorDialog.");
-            mGenericErrorDialog.dismiss();
-            mGenericErrorDialog = null;
-        }
-        if (DBG) log("bailOutAfterErrorDialog(): end InCallScreen session...");
-
-        // Now that the user has dismissed the error dialog (presumably by
-        // either hitting the OK button or pressing Back, we can now reset
-        // the pending call status code field.
-        //
-        // (Note that the pending call status is NOT cleared simply
-        // by the InCallScreen being paused or finished, since the resulting
-        // dialog is supposed to persist across orientation changes or if the
-        // screen turns off.)
-        //
-        // See the "Error / diagnostic indications" section of
-        // InCallUiState.java for more detailed info about the
-        // pending call status code field.
-        final InCallUiState inCallUiState = mApp.inCallUiState;
-        inCallUiState.clearPendingCallStatusCode();
-
-        // Force the InCallScreen to truly finish(), rather than just
-        // moving it to the back of the activity stack (which is what
-        // our finish() method usually does.)
-        // This is necessary to avoid an obscure scenario where the
-        // InCallScreen can get stuck in an inconsistent state, somehow
-        // causing a *subsequent* outgoing call to fail (bug 4172599).
-        endInCallScreenSession(true /* force a real finish() call */);
-    }
-
-    /**
-     * Dismisses (and nulls out) all persistent Dialogs managed
-     * by the InCallScreen.  Useful if (a) we're about to bring up
-     * a dialog and want to pre-empt any currently visible dialogs,
-     * or (b) as a cleanup step when the Activity is going away.
-     */
-    private void dismissAllDialogs() {
-        if (DBG) log("dismissAllDialogs()...");
-
-        // Note it's safe to dismiss() a dialog that's already dismissed.
-        // (Even if the AlertDialog object(s) below are still around, it's
-        // possible that the actual dialog(s) may have already been
-        // dismissed by the user.)
-
-        if (mMissingVoicemailDialog != null) {
-            if (VDBG) log("- DISMISSING mMissingVoicemailDialog.");
-            mMissingVoicemailDialog.dismiss();
-            mMissingVoicemailDialog = null;
-        }
-        if (mMmiStartedDialog != null) {
-            if (VDBG) log("- DISMISSING mMmiStartedDialog.");
-            mMmiStartedDialog.dismiss();
-            mMmiStartedDialog = null;
-        }
-        if (mGenericErrorDialog != null) {
-            if (VDBG) log("- DISMISSING mGenericErrorDialog.");
-            mGenericErrorDialog.dismiss();
-            mGenericErrorDialog = null;
-        }
-        if (mSuppServiceFailureDialog != null) {
-            if (VDBG) log("- DISMISSING mSuppServiceFailureDialog.");
-            mSuppServiceFailureDialog.dismiss();
-            mSuppServiceFailureDialog = null;
-        }
-        if (mWaitPromptDialog != null) {
-            if (VDBG) log("- DISMISSING mWaitPromptDialog.");
-            mWaitPromptDialog.dismiss();
-            mWaitPromptDialog = null;
-        }
-        if (mWildPromptDialog != null) {
-            if (VDBG) log("- DISMISSING mWildPromptDialog.");
-            mWildPromptDialog.dismiss();
-            mWildPromptDialog = null;
-        }
-        if (mCallLostDialog != null) {
-            if (VDBG) log("- DISMISSING mCallLostDialog.");
-            mCallLostDialog.dismiss();
-            mCallLostDialog = null;
-        }
-        if ((mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_NORMAL
-                || mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_ENDED)
-                && mApp.otaUtils != null) {
-            mApp.otaUtils.dismissAllOtaDialogs();
-        }
-        if (mPausePromptDialog != null) {
-            if (DBG) log("- DISMISSING mPausePromptDialog.");
-            mPausePromptDialog.dismiss();
-            mPausePromptDialog = null;
-        }
-        if (mExitingECMDialog != null) {
-            if (DBG) log("- DISMISSING mExitingECMDialog.");
-            mExitingECMDialog.dismiss();
-            mExitingECMDialog = null;
-        }
-    }
-
-    /**
-     * Updates the state of the onscreen "progress indication" used in
-     * some (relatively rare) scenarios where we need to wait for
-     * something to happen before enabling the in-call UI.
-     *
-     * If necessary, this method will cause a ProgressDialog (i.e. a
-     * spinning wait cursor) to be drawn *on top of* whatever the current
-     * state of the in-call UI is.
-     *
-     * @see InCallUiState.ProgressIndicationType
-     */
-    private void updateProgressIndication() {
-        // If an incoming call is ringing, that takes priority over any
-        // possible value of inCallUiState.progressIndication.
-        if (mCM.hasActiveRingingCall()) {
-            dismissProgressIndication();
-            return;
-        }
-
-        // Otherwise, put up a progress indication if indicated by the
-        // inCallUiState.progressIndication field.
-        final InCallUiState inCallUiState = mApp.inCallUiState;
-        switch (inCallUiState.getProgressIndication()) {
-            case NONE:
-                // No progress indication necessary, so make sure it's dismissed.
-                dismissProgressIndication();
-                break;
-
-            case TURNING_ON_RADIO:
-                showProgressIndication(
-                    R.string.emergency_enable_radio_dialog_title,
-                    R.string.emergency_enable_radio_dialog_message);
-                break;
-
-            case RETRYING:
-                showProgressIndication(
-                    R.string.emergency_enable_radio_dialog_title,
-                    R.string.emergency_enable_radio_dialog_retry);
-                break;
-
-            default:
-                Log.wtf(LOG_TAG, "updateProgressIndication: unexpected value: "
-                        + inCallUiState.getProgressIndication());
-                dismissProgressIndication();
-                break;
-        }
-    }
-
-    /**
-     * Show an onscreen "progress indication" with the specified title and message.
-     */
-    private void showProgressIndication(int titleResId, int messageResId) {
-        if (DBG) log("showProgressIndication(message " + messageResId + ")...");
-
-        // TODO: make this be a no-op if the progress indication is
-        // already visible with the exact same title and message.
-
-        dismissProgressIndication();  // Clean up any prior progress indication
-        mProgressDialog = new ProgressDialog(this);
-        mProgressDialog.setTitle(getText(titleResId));
-        mProgressDialog.setMessage(getText(messageResId));
-        mProgressDialog.setIndeterminate(true);
-        mProgressDialog.setCancelable(false);
-        mProgressDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
-        mProgressDialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
-        mProgressDialog.show();
-    }
-
-    /**
-     * Dismiss the onscreen "progress indication" (if present).
-     */
-    private void dismissProgressIndication() {
-        if (DBG) log("dismissProgressIndication()...");
-        if (mProgressDialog != null) {
-            mProgressDialog.dismiss();  // safe even if already dismissed
-            mProgressDialog = null;
-        }
-    }
-
-
-    //
-    // Helper functions for answering incoming calls.
-    //
-
-    /**
-     * Answer a ringing call.  This method does nothing if there's no
-     * ringing or waiting call.
-     */
-    private void internalAnswerCall() {
-        if (DBG) log("internalAnswerCall()...");
-        // if (DBG) PhoneUtils.dumpCallState(mPhone);
-
-        final boolean hasRingingCall = mCM.hasActiveRingingCall();
-
-        if (hasRingingCall) {
-            Phone phone = mCM.getRingingPhone();
-            Call ringing = mCM.getFirstActiveRingingCall();
-            int phoneType = phone.getPhoneType();
-            if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-                if (DBG) log("internalAnswerCall: answering (CDMA)...");
-                if (mCM.hasActiveFgCall()
-                        && mCM.getFgPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_SIP) {
-                    // The incoming call is CDMA call and the ongoing
-                    // call is a SIP call. The CDMA network does not
-                    // support holding an active call, so there's no
-                    // way to swap between a CDMA call and a SIP call.
-                    // So for now, we just don't allow a CDMA call and
-                    // a SIP call to be active at the same time.We'll
-                    // "answer incoming, end ongoing" in this case.
-                    if (DBG) log("internalAnswerCall: answer "
-                            + "CDMA incoming and end SIP ongoing");
-                    PhoneUtils.answerAndEndActive(mCM, ringing);
-                } else {
-                    PhoneUtils.answerCall(ringing);
-                }
-            } else if (phoneType == PhoneConstants.PHONE_TYPE_SIP) {
-                if (DBG) log("internalAnswerCall: answering (SIP)...");
-                if (mCM.hasActiveFgCall()
-                        && mCM.getFgPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
-                    // Similar to the PHONE_TYPE_CDMA handling.
-                    // The incoming call is SIP call and the ongoing
-                    // call is a CDMA call. The CDMA network does not
-                    // support holding an active call, so there's no
-                    // way to swap between a CDMA call and a SIP call.
-                    // So for now, we just don't allow a CDMA call and
-                    // a SIP call to be active at the same time.We'll
-                    // "answer incoming, end ongoing" in this case.
-                    if (DBG) log("internalAnswerCall: answer "
-                            + "SIP incoming and end CDMA ongoing");
-                    PhoneUtils.answerAndEndActive(mCM, ringing);
-                } else {
-                    PhoneUtils.answerCall(ringing);
-                }
-            } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
-                if (DBG) log("internalAnswerCall: answering (GSM)...");
-                // GSM: this is usually just a wrapper around
-                // PhoneUtils.answerCall(), *but* we also need to do
-                // something special for the "both lines in use" case.
-
-                final boolean hasActiveCall = mCM.hasActiveFgCall();
-                final boolean hasHoldingCall = mCM.hasActiveBgCall();
-
-                if (hasActiveCall && hasHoldingCall) {
-                    if (DBG) log("internalAnswerCall: answering (both lines in use!)...");
-                    // The relatively rare case where both lines are
-                    // already in use.  We "answer incoming, end ongoing"
-                    // in this case, according to the current UI spec.
-                    PhoneUtils.answerAndEndActive(mCM, ringing);
-
-                    // Alternatively, we could use
-                    // PhoneUtils.answerAndEndHolding(mPhone);
-                    // here to end the on-hold call instead.
-                } else {
-                    if (DBG) log("internalAnswerCall: answering...");
-                    PhoneUtils.answerCall(ringing);  // Automatically holds the current active call,
-                                                    // if there is one
-                }
-            } else {
-                throw new IllegalStateException("Unexpected phone type: " + phoneType);
-            }
-
-            // Call origin is valid only with outgoing calls. Disable it on incoming calls.
-            mApp.setLatestActiveCallOrigin(null);
-        }
-    }
-
-    /**
-     * Hang up the ringing call (aka "Don't answer").
-     */
-    /* package */ void hangupRingingCall() {
-        if (DBG) log("hangupRingingCall()...");
-        if (VDBG) PhoneUtils.dumpCallManager();
-        // In the rare case when multiple calls are ringing, the UI policy
-        // it to always act on the first ringing call.
-        PhoneUtils.hangupRingingCall(mCM.getFirstActiveRingingCall());
-    }
-
-    /**
-     * Silence the ringer (if an incoming call is ringing.)
-     */
-    private void internalSilenceRinger() {
-        if (DBG) log("internalSilenceRinger()...");
-        final CallNotifier notifier = mApp.notifier;
-        if (notifier.isRinging()) {
-            // ringer is actually playing, so silence it.
-            notifier.silenceRinger();
-        }
-    }
-
-    /**
-     * Respond via SMS to the ringing call.
-     * @see RespondViaSmsManager
-     */
-    private void internalRespondViaSms() {
-        log("internalRespondViaSms()...");
-        if (VDBG) PhoneUtils.dumpCallManager();
-
-        // In the rare case when multiple calls are ringing, the UI policy
-        // it to always act on the first ringing call.
-        Call ringingCall = mCM.getFirstActiveRingingCall();
-
-        // Silence the ringer, since it would be distracting while you're trying
-        // to pick a response.  (Note that we'll restart the ringer if you bail
-        // out of the popup, though; see RespondViaSmsCancelListener.)
-        internalSilenceRinger();
-    }
-
-    /**
-     * Hang up the current active call.
-     */
-    private void internalHangup() {
-        PhoneConstants.State state = mCM.getState();
-        log("internalHangup()...  phone state = " + state);
-
-        // Regardless of the phone state, issue a hangup request.
-        // (If the phone is already idle, this call will presumably have no
-        // effect (but also see the note below.))
-        PhoneUtils.hangup(mCM);
-
-        // If the user just hung up the only active call, we'll eventually exit
-        // the in-call UI after the following sequence:
-        // - When the hangup() succeeds, we'll get a DISCONNECT event from
-        //   the telephony layer (see onDisconnect()).
-        // - We immediately switch to the "Call ended" state (see the "delayed
-        //   bailout" code path in onDisconnect()) and also post a delayed
-        //   DELAYED_CLEANUP_AFTER_DISCONNECT message.
-        // - When the DELAYED_CLEANUP_AFTER_DISCONNECT message comes in (see
-        //   delayedCleanupAfterDisconnect()) we do some final cleanup, and exit
-        //   this activity unless the phone is still in use (i.e. if there's
-        //   another call, or something else going on like an active MMI
-        //   sequence.)
-
-        if (state == PhoneConstants.State.IDLE) {
-            // The user asked us to hang up, but the phone was (already) idle!
-            Log.w(LOG_TAG, "internalHangup(): phone is already IDLE!");
-
-            // This is rare, but can happen in a few cases:
-            // (a) If the user quickly double-taps the "End" button.  In this case
-            //   we'll see that 2nd press event during the brief "Call ended"
-            //   state (where the phone is IDLE), or possibly even before the
-            //   radio has been able to respond to the initial hangup request.
-            // (b) More rarely, this can happen if the user presses "End" at the
-            //   exact moment that the call ends on its own (like because of the
-            //   other person hanging up.)
-            // (c) Finally, this could also happen if we somehow get stuck here on
-            //   the InCallScreen with the phone truly idle, perhaps due to a
-            //   bug where we somehow *didn't* exit when the phone became idle
-            //   in the first place.
-
-            // TODO: as a "safety valve" for case (c), consider immediately
-            // bailing out of the in-call UI right here.  (The user can always
-            // bail out by pressing Home, of course, but they'll probably try
-            // pressing End first.)
-            //
-            //    Log.i(LOG_TAG, "internalHangup(): phone is already IDLE!  Bailing out...");
-            //    endInCallScreenSession();
-        }
-    }
-
-    /**
-     * InCallScreen-specific wrapper around PhoneUtils.switchHoldingAndActive().
-     */
-    private void internalSwapCalls() {
-        if (DBG) log("internalSwapCalls()...");
-
-        // Any time we swap calls, force the DTMF dialpad to close.
-        // (We want the regular in-call UI to be visible right now, so the
-        // user can clearly see which call is now in the foreground.)
-        closeDialpadInternal(true);  // do the "closing" animation
-
-        // Also, clear out the "history" of DTMF digits you typed, to make
-        // sure you don't see digits from call #1 while call #2 is active.
-        // (Yes, this does mean that swapping calls twice will cause you
-        // to lose any previous digits from the current call; see the TODO
-        // comment on DTMFTwelvKeyDialer.clearDigits() for more info.)
-        mDialer.clearDigits();
-    }
-
-    /**
-     * Sets the current high-level "mode" of the in-call UI.
-     *
-     * NOTE: if newMode is CALL_ENDED, the caller is responsible for
-     * posting a delayed DELAYED_CLEANUP_AFTER_DISCONNECT message, to make
-     * sure the "call ended" state goes away after a couple of seconds.
-     *
-     * Note this method does NOT refresh of the onscreen UI; the caller is
-     * responsible for calling updateScreen() or requestUpdateScreen() if
-     * necessary.
-     */
-    private void setInCallScreenMode(InCallScreenMode newMode) {
-        if (DBG) log("setInCallScreenMode: " + newMode);
-        mApp.inCallUiState.inCallScreenMode = newMode;
-
-        switch (newMode) {
-            case MANAGE_CONFERENCE:
-                if (!PhoneUtils.isConferenceCall(mCM.getActiveFgCall())) {
-                    Log.w(LOG_TAG, "MANAGE_CONFERENCE: no active conference call!");
-                    // Hide the Manage Conference panel, return to NORMAL mode.
-                    setInCallScreenMode(InCallScreenMode.NORMAL);
-                    return;
-                }
-                List<Connection> connections = mCM.getFgCallConnections();
-                // There almost certainly will be > 1 connection,
-                // since isConferenceCall() just returned true.
-                if ((connections == null) || (connections.size() <= 1)) {
-                    Log.w(LOG_TAG,
-                          "MANAGE_CONFERENCE: Bogus TRUE from isConferenceCall(); connections = "
-                          + connections);
-                    // Hide the Manage Conference panel, return to NORMAL mode.
-                    setInCallScreenMode(InCallScreenMode.NORMAL);
-                    return;
-                }
-
-                // TODO: Don't do this here. The call to
-                // initManageConferencePanel() should instead happen
-                // automagically in ManageConferenceUtils the very first
-                // time you call updateManageConferencePanel() or
-                // setPanelVisible(true).
-                mManageConferenceUtils.initManageConferencePanel();  // if necessary
-
-                mManageConferenceUtils.updateManageConferencePanel(connections);
-
-                // The "Manage conference" UI takes up the full main frame,
-                // replacing the CallCard PopupWindow.
-                mManageConferenceUtils.setPanelVisible(true);
-
-                // Start the chronometer.
-                // TODO: Similarly, we shouldn't expose startConferenceTime()
-                // and stopConferenceTime(); the ManageConferenceUtils
-                // class ought to manage the conferenceTime widget itself
-                // based on setPanelVisible() calls.
-
-                // Note: there is active Fg call since we are in conference call
-                long callDuration =
-                        mCM.getActiveFgCall().getEarliestConnection().getDurationMillis();
-                mManageConferenceUtils.startConferenceTime(
-                        SystemClock.elapsedRealtime() - callDuration);
-
-                // No need to close the dialer here, since the Manage
-                // Conference UI will just cover it up anyway.
-
-                break;
-
-            case CALL_ENDED:
-            case NORMAL:
-                mManageConferenceUtils.setPanelVisible(false);
-                mManageConferenceUtils.stopConferenceTime();
-                break;
-
-            case OTA_NORMAL:
-                mApp.otaUtils.setCdmaOtaInCallScreenUiState(
-                        OtaUtils.CdmaOtaInCallScreenUiState.State.NORMAL);
-                break;
-
-            case OTA_ENDED:
-                mApp.otaUtils.setCdmaOtaInCallScreenUiState(
-                        OtaUtils.CdmaOtaInCallScreenUiState.State.ENDED);
-                break;
-
-            case UNDEFINED:
-                // Set our Activities intent to ACTION_UNDEFINED so
-                // that if we get resumed after we've completed a call
-                // the next call will not cause checkIsOtaCall to
-                // return true.
-                //
-                // TODO(OTASP): update these comments
-                //
-                // With the framework as of October 2009 the sequence below
-                // causes the framework to call onResume, onPause, onNewIntent,
-                // onResume. If we don't call setIntent below then when the
-                // first onResume calls checkIsOtaCall via checkOtaspStateOnResume it will
-                // return true and the Activity will be confused.
-                //
-                //  1) Power up Phone A
-                //  2) Place *22899 call and activate Phone A
-                //  3) Press the power key on Phone A to turn off the display
-                //  4) Call Phone A from Phone B answering Phone A
-                //  5) The screen will be blank (Should be normal InCallScreen)
-                //  6) Hang up the Phone B
-                //  7) Phone A displays the activation screen.
-                //
-                // Step 3 is the critical step to cause the onResume, onPause
-                // onNewIntent, onResume sequence. If step 3 is skipped the
-                // sequence will be onNewIntent, onResume and all will be well.
-                setIntent(new Intent(ACTION_UNDEFINED));
-
-                // Cleanup Ota Screen if necessary and set the panel
-                // to VISIBLE.
-                if (mCM.getState() != PhoneConstants.State.OFFHOOK) {
-                    if (mApp.otaUtils != null) {
-                        mApp.otaUtils.cleanOtaScreen(true);
-                    }
-                } else {
-                    log("WARNING: Setting mode to UNDEFINED but phone is OFFHOOK,"
-                            + " skip cleanOtaScreen.");
-                }
-                break;
-        }
-    }
-
-    /**
-     * @return true if the "Manage conference" UI is currently visible.
-     */
-    /* package */ boolean isManageConferenceMode() {
-        return (mApp.inCallUiState.inCallScreenMode == InCallScreenMode.MANAGE_CONFERENCE);
-    }
-
-    /**
-     * Checks if the "Manage conference" UI needs to be updated.
-     * If the state of the current conference call has changed
-     * since our previous call to updateManageConferencePanel()),
-     * do a fresh update.  Also, if the current call is no longer a
-     * conference call at all, bail out of the "Manage conference" UI and
-     * return to InCallScreenMode.NORMAL mode.
-     */
-    private void updateManageConferencePanelIfNecessary() {
-        if (VDBG) log("updateManageConferencePanelIfNecessary: " + mCM.getActiveFgCall() + "...");
-
-        List<Connection> connections = mCM.getFgCallConnections();
-        if (connections == null) {
-            if (VDBG) log("==> no connections on foreground call!");
-            // Hide the Manage Conference panel, return to NORMAL mode.
-            setInCallScreenMode(InCallScreenMode.NORMAL);
-            SyncWithPhoneStateStatus status = syncWithPhoneState();
-            if (status != SyncWithPhoneStateStatus.SUCCESS) {
-                Log.w(LOG_TAG, "- syncWithPhoneState failed! status = " + status);
-                // We shouldn't even be in the in-call UI in the first
-                // place, so bail out:
-                if (DBG) log("updateManageConferencePanelIfNecessary: endInCallScreenSession... 1");
-                endInCallScreenSession();
-                return;
-            }
-            return;
-        }
-
-        int numConnections = connections.size();
-        if (numConnections <= 1) {
-            if (VDBG) log("==> foreground call no longer a conference!");
-            // Hide the Manage Conference panel, return to NORMAL mode.
-            setInCallScreenMode(InCallScreenMode.NORMAL);
-            SyncWithPhoneStateStatus status = syncWithPhoneState();
-            if (status != SyncWithPhoneStateStatus.SUCCESS) {
-                Log.w(LOG_TAG, "- syncWithPhoneState failed! status = " + status);
-                // We shouldn't even be in the in-call UI in the first
-                // place, so bail out:
-                if (DBG) log("updateManageConferencePanelIfNecessary: endInCallScreenSession... 2");
-                endInCallScreenSession();
-                return;
-            }
-            return;
-        }
-
-        // TODO: the test to see if numConnections has changed can go in
-        // updateManageConferencePanel(), rather than here.
-        if (numConnections != mManageConferenceUtils.getNumCallersInConference()) {
-            if (VDBG) log("==> Conference size has changed; need to rebuild UI!");
-            mManageConferenceUtils.updateManageConferencePanel(connections);
-        }
-    }
-
-    /**
-     * Updates {@link #mCallCard}'s visibility state per DTMF dialpad visibility. They
-     * cannot be shown simultaneously and thus we should reflect DTMF dialpad visibility into
-     * another.
-     *
-     * Note: During OTA calls or users' managing conference calls, we should *not* call this method
-     * but manually manage both visibility.
-     *
-     * @see #updateScreen()
-     */
-    private void updateCallCardVisibilityPerDialerState(boolean animate) {
-        // We need to hide the CallCard while the dialpad is visible.
-        if (isDialerOpened()) {
-            if (VDBG) {
-                log("- updateCallCardVisibilityPerDialerState(animate="
-                        + animate + "): dialpad open, hide mCallCard...");
-            }
-            if (animate) {
-                AnimationUtils.Fade.hide(mCallCard, View.GONE);
-            } else {
-                mCallCard.setVisibility(View.GONE);
-            }
-        } else {
-            // Dialpad is dismissed; bring back the CallCard if it's supposed to be visible.
-            if ((mApp.inCallUiState.inCallScreenMode == InCallScreenMode.NORMAL)
-                || (mApp.inCallUiState.inCallScreenMode == InCallScreenMode.CALL_ENDED)) {
-                if (VDBG) {
-                    log("- updateCallCardVisibilityPerDialerState(animate="
-                            + animate + "): dialpad dismissed, show mCallCard...");
-                }
-                if (animate) {
-                    AnimationUtils.Fade.show(mCallCard);
-                } else {
-                    mCallCard.setVisibility(View.VISIBLE);
-                }
-            }
-        }
-    }
-
-    /**
-     * @see DTMFTwelveKeyDialer#isOpened()
-     */
-    /* package */ boolean isDialerOpened() {
-        return (mDialer != null && mDialer.isOpened());
-    }
-
-    /**
-     * Called any time the DTMF dialpad is opened.
-     * @see DTMFTwelveKeyDialer#openDialer(boolean)
-     */
-    /* package */ void onDialerOpen(boolean animate) {
-        if (DBG) log("onDialerOpen()...");
-
-        // Update the in-call touch UI.
-        updateInCallTouchUi();
-
-        // Update CallCard UI, which depends on the dialpad.
-        updateCallCardVisibilityPerDialerState(animate);
-
-        // This counts as explicit "user activity".
-        mApp.pokeUserActivity();
-
-        //If on OTA Call, hide OTA Screen
-        // TODO: This may not be necessary, now that the dialpad is
-        // always visible in OTA mode.
-        if  ((mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_NORMAL
-                || mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_ENDED)
-                && mApp.otaUtils != null) {
-            mApp.otaUtils.hideOtaScreen();
-        }
-    }
-
-    /**
-     * Called any time the DTMF dialpad is closed.
-     * @see DTMFTwelveKeyDialer#closeDialer(boolean)
-     */
-    /* package */ void onDialerClose(boolean animate) {
-        if (DBG) log("onDialerClose()...");
-
-        // OTA-specific cleanup upon closing the dialpad.
-        if ((mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_NORMAL)
-            || (mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_ENDED)
-            || ((mApp.cdmaOtaScreenState != null)
-                && (mApp.cdmaOtaScreenState.otaScreenState ==
-                    CdmaOtaScreenState.OtaScreenState.OTA_STATUS_ACTIVATION))) {
-            if (mApp.otaUtils != null) {
-                mApp.otaUtils.otaShowProperScreen();
-            }
-        }
-
-        // Update the in-call touch UI.
-        updateInCallTouchUi();
-
-        // Update CallCard UI, which depends on the dialpad.
-        updateCallCardVisibilityPerDialerState(animate);
-
-        // This counts as explicit "user activity".
-        mApp.pokeUserActivity();
-    }
-
-    /**
-     * Determines when we can dial DTMF tones.
-     */
-    /* package */ boolean okToDialDTMFTones() {
-        final boolean hasRingingCall = mCM.hasActiveRingingCall();
-        final Call.State fgCallState = mCM.getActiveFgCallState();
-
-        // We're allowed to send DTMF tones when there's an ACTIVE
-        // foreground call, and not when an incoming call is ringing
-        // (since DTMF tones are useless in that state), or if the
-        // Manage Conference UI is visible (since the tab interferes
-        // with the "Back to call" button.)
-
-        // We can also dial while in ALERTING state because there are
-        // some connections that never update to an ACTIVE state (no
-        // indication from the network).
-        boolean canDial =
-            (fgCallState == Call.State.ACTIVE || fgCallState == Call.State.ALERTING)
-            && !hasRingingCall
-            && (mApp.inCallUiState.inCallScreenMode != InCallScreenMode.MANAGE_CONFERENCE);
-
-        if (VDBG) log ("[okToDialDTMFTones] foreground state: " + fgCallState +
-                ", ringing state: " + hasRingingCall +
-                ", call screen mode: " + mApp.inCallUiState.inCallScreenMode +
-                ", result: " + canDial);
-
-        return canDial;
-    }
-
-    /**
-     * @return true if the in-call DTMF dialpad should be available to the
-     *      user, given the current state of the phone and the in-call UI.
-     *      (This is used to control the enabledness of the "Show
-     *      dialpad" onscreen button; see InCallControlState.dialpadEnabled.)
-     */
-    /* package */ boolean okToShowDialpad() {
-        // Very similar to okToDialDTMFTones(), but allow DIALING here.
-        final Call.State fgCallState = mCM.getActiveFgCallState();
-        return okToDialDTMFTones() || (fgCallState == Call.State.DIALING);
-    }
-
-    /**
-     * Initializes the in-call touch UI on devices that need it.
-     */
-    private void initInCallTouchUi() {
-        if (DBG) log("initInCallTouchUi()...");
-        // TODO: we currently use the InCallTouchUi widget in at least
-        // some states on ALL platforms.  But if some devices ultimately
-        // end up not using *any* onscreen touch UI, we should make sure
-        // to not even inflate the InCallTouchUi widget on those devices.
-        mInCallTouchUi = (InCallTouchUi) findViewById(R.id.inCallTouchUi);
-        mInCallTouchUi.setInCallScreenInstance(this);
-
-        // RespondViaSmsManager implements the "Respond via SMS"
-        // feature that's triggered from the incoming call widget.
-        mRespondViaSmsManager = new RespondViaSmsManager();
-        mRespondViaSmsManager.setInCallScreenInstance(this);
-    }
-
-    /**
-     * Updates the state of the in-call touch UI.
-     */
-    private void updateInCallTouchUi() {
-        if (mInCallTouchUi != null) {
-            mInCallTouchUi.updateState(mCM);
-        }
-    }
-
-    /**
-     * @return the InCallTouchUi widget
-     */
-    /* package */ InCallTouchUi getInCallTouchUi() {
-        return mInCallTouchUi;
-    }
-
-    /**
-     * Posts a handler message telling the InCallScreen to refresh the
-     * onscreen in-call UI.
-     *
-     * This is just a wrapper around updateScreen(), for use by the
-     * rest of the phone app or from a thread other than the UI thread.
-     *
-     * updateScreen() is a no-op if the InCallScreen is not the foreground
-     * activity, so it's safe to call this whether or not the InCallScreen
-     * is currently visible.
-     */
-    /* package */ void requestUpdateScreen() {
-        if (DBG) log("requestUpdateScreen()...");
-        mHandler.removeMessages(REQUEST_UPDATE_SCREEN);
-        mHandler.sendEmptyMessage(REQUEST_UPDATE_SCREEN);
-    }
-
-    /**
-     * @return true if we're in restricted / emergency dialing only mode.
-     */
-    public boolean isPhoneStateRestricted() {
-        // TODO:  This needs to work IN TANDEM with the KeyGuardViewMediator Code.
-        // Right now, it looks like the mInputRestricted flag is INTERNAL to the
-        // KeyGuardViewMediator and SPECIFICALLY set to be FALSE while the emergency
-        // phone call is being made, to allow for input into the InCallScreen.
-        // Having the InCallScreen judge the state of the device from this flag
-        // becomes meaningless since it is always false for us.  The mediator should
-        // have an additional API to let this app know that it should be restricted.
-        int serviceState = mCM.getServiceState();
-        return ((serviceState == ServiceState.STATE_EMERGENCY_ONLY) ||
-                (serviceState == ServiceState.STATE_OUT_OF_SERVICE) ||
-                (mApp.getKeyguardManager().inKeyguardRestrictedInputMode()));
-    }
-
-    /**
-     * Posts a handler message telling the InCallScreen to close
-     * the OTA failure notice after the specified delay.
-     * @see OtaUtils.otaShowProgramFailureNotice
-     */
-    /* package */ void requestCloseOtaFailureNotice(long timeout) {
-        if (DBG) log("requestCloseOtaFailureNotice() with timeout: " + timeout);
-        mHandler.sendEmptyMessageDelayed(REQUEST_CLOSE_OTA_FAILURE_NOTICE, timeout);
-
-        // TODO: we probably ought to call removeMessages() for this
-        // message code in either onPause or onResume, just to be 100%
-        // sure that the message we just posted has no way to affect a
-        // *different* call if the user quickly backs out and restarts.
-        // (This is also true for requestCloseSpcErrorNotice() below, and
-        // probably anywhere else we use mHandler.sendEmptyMessageDelayed().)
-    }
-
-    /**
-     * Posts a handler message telling the InCallScreen to close
-     * the SPC error notice after the specified delay.
-     * @see OtaUtils.otaShowSpcErrorNotice
-     */
-    /* package */ void requestCloseSpcErrorNotice(long timeout) {
-        if (DBG) log("requestCloseSpcErrorNotice() with timeout: " + timeout);
-        mHandler.sendEmptyMessageDelayed(REQUEST_CLOSE_SPC_ERROR_NOTICE, timeout);
-    }
-
-    public boolean isOtaCallInActiveState() {
-        if ((mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_NORMAL)
-                || ((mApp.cdmaOtaScreenState != null)
-                    && (mApp.cdmaOtaScreenState.otaScreenState ==
-                        CdmaOtaScreenState.OtaScreenState.OTA_STATUS_ACTIVATION))) {
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    /**
-     * Handle OTA Call End scenario when display becomes dark during OTA Call
-     * and InCallScreen is in pause mode.  CallNotifier will listen for call
-     * end indication and call this api to handle OTA Call end scenario
-     */
-    public void handleOtaCallEnd() {
-        if (DBG) log("handleOtaCallEnd entering");
-        if (((mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_NORMAL)
-                || ((mApp.cdmaOtaScreenState != null)
-                && (mApp.cdmaOtaScreenState.otaScreenState !=
-                    CdmaOtaScreenState.OtaScreenState.OTA_STATUS_UNDEFINED)))
-                && ((mApp.cdmaOtaProvisionData != null)
-                && (!mApp.cdmaOtaProvisionData.inOtaSpcState))) {
-            if (DBG) log("handleOtaCallEnd - Set OTA Call End stater");
-            setInCallScreenMode(InCallScreenMode.OTA_ENDED);
-            updateScreen();
-        }
-    }
-
-    public boolean isOtaCallInEndState() {
-        return (mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_ENDED);
-    }
-
-
-    /**
-     * Upon resuming the in-call UI, check to see if an OTASP call is in
-     * progress, and if so enable the special OTASP-specific UI.
-     *
-     * TODO: have a simple single flag in InCallUiState for this rather than
-     * needing to know about all those mApp.cdma*State objects.
-     *
-     * @return true if any OTASP-related UI is active
-     */
-    private boolean checkOtaspStateOnResume() {
-        // If there's no OtaUtils instance, that means we haven't even tried
-        // to start an OTASP call (yet), so there's definitely nothing to do here.
-        if (mApp.otaUtils == null) {
-            if (DBG) log("checkOtaspStateOnResume: no OtaUtils instance; nothing to do.");
-            return false;
-        }
-
-        if ((mApp.cdmaOtaScreenState == null) || (mApp.cdmaOtaProvisionData == null)) {
-            // Uh oh -- something wrong with our internal OTASP state.
-            // (Since this is an OTASP-capable device, these objects
-            // *should* have already been created by PhoneApp.onCreate().)
-            throw new IllegalStateException("checkOtaspStateOnResume: "
-                                            + "app.cdmaOta* objects(s) not initialized");
-        }
-
-        // The PhoneApp.cdmaOtaInCallScreenUiState instance is the
-        // authoritative source saying whether or not the in-call UI should
-        // show its OTASP-related UI.
-
-        OtaUtils.CdmaOtaInCallScreenUiState.State cdmaOtaInCallScreenState =
-                mApp.otaUtils.getCdmaOtaInCallScreenUiState();
-        // These states are:
-        // - UNDEFINED: no OTASP-related UI is visible
-        // - NORMAL: OTASP call in progress, so show in-progress OTASP UI
-        // - ENDED: OTASP call just ended, so show success/failure indication
-
-        boolean otaspUiActive =
-                (cdmaOtaInCallScreenState == OtaUtils.CdmaOtaInCallScreenUiState.State.NORMAL)
-                || (cdmaOtaInCallScreenState == OtaUtils.CdmaOtaInCallScreenUiState.State.ENDED);
-
-        if (otaspUiActive) {
-            // Make sure the OtaUtils instance knows about the InCallScreen's
-            // OTASP-related UI widgets.
-            //
-            // (This call has no effect if the UI widgets have already been set up.
-            // It only really matters  the very first time that the InCallScreen instance
-            // is onResume()d after starting an OTASP call.)
-            mApp.otaUtils.updateUiWidgets(this, mInCallTouchUi, mCallCard);
-
-            // Also update the InCallScreenMode based on the cdmaOtaInCallScreenState.
-
-            if (cdmaOtaInCallScreenState == OtaUtils.CdmaOtaInCallScreenUiState.State.NORMAL) {
-                if (DBG) log("checkOtaspStateOnResume - in OTA Normal mode");
-                setInCallScreenMode(InCallScreenMode.OTA_NORMAL);
-            } else if (cdmaOtaInCallScreenState ==
-                       OtaUtils.CdmaOtaInCallScreenUiState.State.ENDED) {
-                if (DBG) log("checkOtaspStateOnResume - in OTA END mode");
-                setInCallScreenMode(InCallScreenMode.OTA_ENDED);
-            }
-
-            // TODO(OTASP): we might also need to go into OTA_ENDED mode
-            // in one extra case:
-            //
-            // else if (mApp.cdmaOtaScreenState.otaScreenState ==
-            //            CdmaOtaScreenState.OtaScreenState.OTA_STATUS_SUCCESS_FAILURE_DLG) {
-            //     if (DBG) log("checkOtaspStateOnResume - set OTA END Mode");
-            //     setInCallScreenMode(InCallScreenMode.OTA_ENDED);
-            // }
-
-        } else {
-            // OTASP is not active; reset to regular in-call UI.
-
-            if (DBG) log("checkOtaspStateOnResume - Set OTA NORMAL Mode");
-            setInCallScreenMode(InCallScreenMode.OTA_NORMAL);
-
-            if (mApp.otaUtils != null) {
-                mApp.otaUtils.cleanOtaScreen(false);
-            }
-        }
-
-        // TODO(OTASP):
-        // The original check from checkIsOtaCall() when handling ACTION_MAIN was this:
-        //
-        //        [ . . . ]
-        //        else if (action.equals(intent.ACTION_MAIN)) {
-        //            if (DBG) log("checkIsOtaCall action ACTION_MAIN");
-        //            boolean isRingingCall = mCM.hasActiveRingingCall();
-        //            if (isRingingCall) {
-        //                if (DBG) log("checkIsOtaCall isRingingCall: " + isRingingCall);
-        //                return false;
-        //            } else if ((mApp.cdmaOtaInCallScreenUiState.state
-        //                            == CdmaOtaInCallScreenUiState.State.NORMAL)
-        //                    || (mApp.cdmaOtaInCallScreenUiState.state
-        //                            == CdmaOtaInCallScreenUiState.State.ENDED)) {
-        //                if (DBG) log("action ACTION_MAIN, OTA call already in progress");
-        //                isOtaCall = true;
-        //            } else {
-        //                if (mApp.cdmaOtaScreenState.otaScreenState !=
-        //                        CdmaOtaScreenState.OtaScreenState.OTA_STATUS_UNDEFINED) {
-        //                    if (DBG) log("checkIsOtaCall action ACTION_MAIN, "
-        //                                 + "OTA call in progress with UNDEFINED");
-        //                    isOtaCall = true;
-        //                }
-        //            }
-        //        }
-        //
-        // Also, in internalResolveIntent() we used to do this:
-        //
-        //        if ((mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_NORMAL)
-        //                || (mApp.inCallUiState.inCallScreenMode == InCallScreenMode.OTA_ENDED)) {
-        //            // If in OTA Call, update the OTA UI
-        //            updateScreen();
-        //            return;
-        //        }
-        //
-        // We still need more cleanup to simplify the mApp.cdma*State objects.
-
-        return otaspUiActive;
-    }
-
-    /**
-     * Updates and returns the InCallControlState instance.
-     */
-    public InCallControlState getUpdatedInCallControlState() {
-        if (VDBG) log("getUpdatedInCallControlState()...");
-        mInCallControlState.update();
-        return mInCallControlState;
-    }
-
-    public void resetInCallScreenMode() {
-        if (DBG) log("resetInCallScreenMode: setting mode to UNDEFINED...");
-        setInCallScreenMode(InCallScreenMode.UNDEFINED);
-    }
-
-    /**
-     * Updates the onscreen hint displayed while the user is dragging one
-     * of the handles of the RotarySelector widget used for incoming
-     * calls.
-     *
-     * @param hintTextResId resource ID of the hint text to display,
-     *        or 0 if no hint should be visible.
-     * @param hintColorResId resource ID for the color of the hint text
-     */
-    /* package */ void updateIncomingCallWidgetHint(int hintTextResId, int hintColorResId) {
-        if (VDBG) log("updateIncomingCallWidgetHint(" + hintTextResId + ")...");
-        if (mCallCard != null) {
-            mCallCard.setIncomingCallWidgetHint(hintTextResId, hintColorResId);
-            mCallCard.updateState(mCM);
-            // TODO: if hintTextResId == 0, consider NOT clearing the onscreen
-            // hint right away, but instead post a delayed handler message to
-            // keep it onscreen for an extra second or two.  (This might make
-            // the hint more helpful if the user quickly taps one of the
-            // handles without dragging at all...)
-            // (Or, maybe this should happen completely within the RotarySelector
-            // widget, since the widget itself probably wants to keep the colored
-            // arrow visible for some extra time also...)
-        }
-    }
-
-
-    /**
-     * Used when we need to update buttons outside InCallTouchUi's updateInCallControls() along
-     * with that method being called. CallCard may call this too because it doesn't have
-     * enough information to update buttons inside itself (more specifically, the class cannot
-     * obtain mInCallControllState without some side effect. See also
-     * {@link #getUpdatedInCallControlState()}. We probably don't want a method like
-     * getRawCallControlState() which returns raw intance with no side effect just for this
-     * corner case scenario)
-     *
-     * TODO: need better design for buttons outside InCallTouchUi.
-     */
-    /* package */ void updateButtonStateOutsideInCallTouchUi() {
-        if (mCallCard != null) {
-            mCallCard.setSecondaryCallClickable(mInCallControlState.canSwap);
-        }
-    }
-
-    @Override
-    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
-        super.dispatchPopulateAccessibilityEvent(event);
-        mCallCard.dispatchPopulateAccessibilityEvent(event);
-        return true;
-    }
-
-    /**
-     * Manually handle configuration changes.
-     *
-     * Originally android:configChanges was set to "orientation|keyboardHidden|uiMode"
-     * in order "to make sure the system doesn't destroy and re-create us due to the
-     * above config changes". However it is currently set to "keyboardHidden" since
-     * the system needs to handle rotation when inserted into a compatible cardock.
-     * Even without explicitly handling orientation and uiMode, the app still runs
-     * and does not drop the call when rotated.
-     *
-     */
-    public void onConfigurationChanged(Configuration newConfig) {
-        if (DBG) log("onConfigurationChanged: newConfig = " + newConfig);
-
-        // Note: At the time this function is called, our Resources object
-        // will have already been updated to return resource values matching
-        // the new configuration.
-
-        // Watch out: we *can* still get destroyed and recreated if a
-        // configuration change occurs that is *not* listed in the
-        // android:configChanges attribute.  TODO: Any others we need to list?
-
-        super.onConfigurationChanged(newConfig);
-
-        // Nothing else to do here, since (currently) the InCallScreen looks
-        // exactly the same regardless of configuration.
-        // (Specifically, we'll never be in landscape mode because we set
-        // android:screenOrientation="portrait" in our manifest, and we don't
-        // change our UI at all based on newConfig.keyboardHidden or
-        // newConfig.uiMode.)
-
-        // TODO: we do eventually want to handle at least some config changes, such as:
-        boolean isKeyboardOpen = (newConfig.keyboardHidden == Configuration.KEYBOARDHIDDEN_NO);
-        if (DBG) log("  - isKeyboardOpen = " + isKeyboardOpen);
-        boolean isLandscape = (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE);
-        if (DBG) log("  - isLandscape = " + isLandscape);
-        if (DBG) log("  - uiMode = " + newConfig.uiMode);
-        // See bug 2089513.
-    }
-
-    /**
-     * Handles an incoming RING event from the telephony layer.
-     */
-    private void onIncomingRing() {
-        if (DBG) log("onIncomingRing()...");
-        // IFF we're visible, forward this event to the InCallTouchUi
-        // instance (which uses this event to drive the animation of the
-        // incoming-call UI.)
-        if (mIsForegroundActivity && (mInCallTouchUi != null)) {
-            mInCallTouchUi.onIncomingRing();
-        }
-    }
-
-    /**
-     * Handles a "new ringing connection" event from the telephony layer.
-     *
-     * This event comes in right at the start of the incoming-call sequence,
-     * exactly once per incoming call.
-     *
-     * Watch out: this won't be called if InCallScreen isn't ready yet,
-     * which typically happens for the first incoming phone call (even before
-     * the possible first outgoing call).
-     */
-    private void onNewRingingConnection() {
-        if (DBG) log("onNewRingingConnection()...");
-
-        // We use this event to reset any incoming-call-related UI elements
-        // that might have been left in an inconsistent state after a prior
-        // incoming call.
-        // (Note we do this whether or not we're the foreground activity,
-        // since this event comes in *before* we actually get launched to
-        // display the incoming-call UI.)
-
-        // If there's a "Respond via SMS" popup still around since the
-        // last time we were the foreground activity, make sure it's not
-        // still active(!) since that would interfere with *this* incoming
-        // call.
-        // (Note that we also do this same check in onResume().  But we
-        // need it here too, to make sure the popup gets reset in the case
-        // where a call-waiting call comes in while the InCallScreen is
-        // already in the foreground.)
-        mRespondViaSmsManager.dismissPopup();  // safe even if already dismissed
-    }
-
-    /**
-     * Enables or disables the status bar "window shade" based on the current situation.
-     */
-    private void updateExpandedViewState() {
-        if (mIsForegroundActivity) {
-            // We should not enable notification's expanded view on RINGING state.
-            mApp.notificationMgr.statusBarHelper.enableExpandedView(
-                    mCM.getState() != PhoneConstants.State.RINGING);
-        } else {
-            mApp.notificationMgr.statusBarHelper.enableExpandedView(true);
-        }
-    }
-
-    private void log(String msg) {
-        Log.d(LOG_TAG, msg);
-    }
-
-    /**
-     * Requests to remove provider info frame after having
-     * {@link #PROVIDER_INFO_TIMEOUT}) msec delay.
-     */
-    /* package */ void requestRemoveProviderInfoWithDelay() {
-        // Remove any zombie messages and then send a message to
-        // self to remove the provider info after some time.
-        mHandler.removeMessages(EVENT_HIDE_PROVIDER_INFO);
-        Message msg = Message.obtain(mHandler, EVENT_HIDE_PROVIDER_INFO);
-        mHandler.sendMessageDelayed(msg, PROVIDER_INFO_TIMEOUT);
-        if (DBG) {
-            log("Requested to remove provider info after " + PROVIDER_INFO_TIMEOUT + " msec.");
-        }
-    }
-
-    /**
-     * Indicates whether or not the QuickResponseDialog is currently showing in the call screen
-     */
-    public boolean isQuickResponseDialogShowing() {
-        return mRespondViaSmsManager != null && mRespondViaSmsManager.isShowingPopup();
-    }
 }
diff --git a/src/com/android/phone/InCallTouchUi.java b/src/com/android/phone/InCallTouchUi.java
deleted file mode 100644
index 9cb2a52..0000000
--- a/src/com/android/phone/InCallTouchUi.java
+++ /dev/null
@@ -1,1337 +0,0 @@
-/*
- * 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.View;
-import android.view.ViewGroup;
-import android.view.ViewPropertyAnimator;
-import android.view.ViewStub;
-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.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;
-    private View mVideoSpacer;
-    private ImageButton mVideoButton;
-
-    // "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);
-        mVideoButton = (ImageButton) mInCallControls.findViewById(R.id.videoCallButton);
-        mVideoButton.setOnClickListener(this);
-        mVideoButton.setOnLongClickListener(this);
-        mVideoSpacer = mInCallControls.findViewById(R.id.videoCallSpacer);
-
-        // 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:
-            case R.id.videoCallButton:
-                // 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:
-            case R.id.videoCallButton: {
-                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);
-        }
-
-        setupVideoCallButton();
-
-        if (DBG) {
-            log("At the end of updateInCallControls().");
-            dumpBottomButtonState();
-        }
-    }
-
-    /**
-     * Set up the video call button.  Checks the system for any video call providers before
-     * displaying the video chat button.
-     */
-    private void setupVideoCallButton() {
-        // TODO: Check system to see if there are video chat providers and if not, disable the
-        // button.
-    }
-
-
-    /**
-     * 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 = false; //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();
-            // If animation is cancelled before it's running,
-            // onAnimationCancel will not be called and mIncomingCallWidgetIsFadingOut
-            // will be alway true. hideIncomingCallWidget() will not be excuted in this case.
-            mIncomingCallWidgetIsFadingOut = false;
-        }
-        mIncomingCallWidget.setAlpha(1.0f);
-
-        // 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.START);
-        }
-
-        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);
-    }
-}
diff --git a/src/com/android/phone/InCallUiState.java b/src/com/android/phone/InCallUiState.java
deleted file mode 100644
index 126ef63..0000000
--- a/src/com/android/phone/InCallUiState.java
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.phone.Constants.CallStatusCode;
-
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.text.TextUtils;
-import android.util.Log;
-
-
-/**
- * Helper class to keep track of "persistent state" of the in-call UI.
- *
- * The onscreen appearance of the in-call UI mostly depends on the current
- * Call/Connection state, which is owned by the telephony framework.  But
- * there's some application-level "UI state" too, which lives here in the
- * phone app.
- *
- * This application-level state information is *not* maintained by the
- * InCallScreen, since it needs to persist throughout an entire phone call,
- * not just a single resume/pause cycle of the InCallScreen.  So instead, that
- * state is stored here, in a singleton instance of this class.
- *
- * The state kept here is a high-level abstraction of in-call UI state: we
- * don't know about implementation details like specific widgets or strings or
- * resources, but we do understand higher level concepts (for example "is the
- * dialpad visible") and high-level modes (like InCallScreenMode) and error
- * conditions (like CallStatusCode).
- *
- * @see InCallControlState for a separate collection of "UI state" that
- * controls all the onscreen buttons of the in-call UI, based on the state of
- * the telephony layer.
- *
- * The singleton instance of this class is owned by the PhoneApp instance.
- */
-public class InCallUiState {
-    private static final String TAG = "InCallUiState";
-    private static final boolean DBG = false;
-
-    /** The singleton InCallUiState instance. */
-    private static InCallUiState sInstance;
-
-    private Context mContext;
-
-    /**
-     * Initialize the singleton InCallUiState instance.
-     *
-     * This is only done once, at startup, from PhoneApp.onCreate().
-     * From then on, the InCallUiState instance is available via the
-     * PhoneApp's public "inCallUiState" field, which is why there's no
-     * getInstance() method here.
-     */
-    /* package */ static InCallUiState init(Context context) {
-        synchronized (InCallUiState.class) {
-            if (sInstance == null) {
-                sInstance = new InCallUiState(context);
-            } else {
-                Log.wtf(TAG, "init() called multiple times!  sInstance = " + sInstance);
-            }
-            return sInstance;
-        }
-    }
-
-    /**
-     * Private constructor (this is a singleton).
-     * @see init()
-     */
-    private InCallUiState(Context context) {
-        mContext = context;
-    }
-
-
-    //
-    // (1) High-level state of the whole in-call UI
-    //
-
-    /** High-level "modes" of the in-call UI. */
-    public enum InCallScreenMode {
-        /**
-         * Normal in-call UI elements visible.
-         */
-        NORMAL,
-        /**
-         * "Manage conference" UI is visible, totally replacing the
-         * normal in-call UI.
-         */
-        MANAGE_CONFERENCE,
-        /**
-         * Non-interactive UI state.  Call card is visible,
-         * displaying information about the call that just ended.
-         */
-        CALL_ENDED,
-        /**
-         * Normal OTA in-call UI elements visible.
-         */
-        OTA_NORMAL,
-        /**
-         * OTA call ended UI visible, replacing normal OTA in-call UI.
-         */
-        OTA_ENDED,
-        /**
-         * Default state when not on call
-         */
-        UNDEFINED
-    }
-
-    /** Current high-level "mode" of the in-call UI. */
-    InCallScreenMode inCallScreenMode = InCallScreenMode.UNDEFINED;
-
-
-    //
-    // (2) State of specific UI elements
-    //
-
-    /**
-     * Is the onscreen twelve-key dialpad visible?
-     */
-    boolean showDialpad;
-
-    /**
-     * The contents of the twelve-key dialpad's "digits" display, which is
-     * visible only when the dialpad itself is visible.
-     *
-     * (This is basically the "history" of DTMF digits you've typed so far
-     * in the current call.  It's cleared out any time a new call starts,
-     * to make sure the digits don't persist between two separate calls.)
-     */
-    String dialpadDigits;
-
-    /**
-     * The contact/dialed number information shown in the DTMF digits text
-     * when the user has not yet typed any digits.
-     *
-     * Currently only used for displaying "Voice Mail" since voicemail calls
-     * start directly in the dialpad view.
-     */
-    String dialpadContextText;
-
-    //
-    // (3) Error / diagnostic indications
-    //
-
-    // This section provides an abstract concept of an "error status
-    // indication" for some kind of exceptional condition that needs to be
-    // communicated to the user, in the context of the in-call UI.
-    //
-    // If mPendingCallStatusCode is any value other than SUCCESS, that
-    // indicates that the in-call UI needs to display a dialog to the user
-    // with the specified title and message text.
-    //
-    // When an error occurs outside of the InCallScreen itself (like
-    // during CallController.placeCall() for example), we inform the user
-    // by doing the following steps:
-    //
-    // (1) set the "pending call status code" to a value other than SUCCESS
-    //     (based on the specific error that happened)
-    // (2) force the InCallScreen to be launched (or relaunched)
-    // (3) InCallScreen.onResume() will notice that pending call status code
-    //     is set, and will actually bring up the desired dialog.
-    //
-    // Watch out: any time you set (or change!) the pending call status code
-    // field you must be sure to always (re)launch the InCallScreen.
-    //
-    // Finally, the InCallScreen itself is responsible for resetting the
-    // pending call status code, when the user dismisses the dialog (like by
-    // hitting the OK button or pressing Back).  The pending call status code
-    // field is NOT cleared simply by the InCallScreen being paused or
-    // finished, since the resulting dialog needs to persist across
-    // orientation changes or if the screen turns off.
-
-    // TODO: other features we might eventually need here:
-    //
-    //   - Some error status messages stay in force till reset,
-    //     others may automatically clear themselves after
-    //     a fixed delay
-    //
-    //   - Some error statuses may be visible as a dialog with an OK
-    //     button (like "call failed"), others may be an indefinite
-    //     progress dialog (like "turning on radio for emergency call").
-    //
-    //   - Eventually some error statuses may have extra actions (like a
-    //     "retry call" button that we might provide at the bottom of the
-    //     "call failed because you have no signal" dialog.)
-
-    /**
-     * The current pending "error status indication" that we need to
-     * display to the user.
-     *
-     * If this field is set to a value other than SUCCESS, this indicates to
-     * the InCallScreen that we need to show some kind of message to the user
-     * (usually an error dialog) based on the specified status code.
-     */
-    private CallStatusCode mPendingCallStatusCode = CallStatusCode.SUCCESS;
-
-    /**
-     * @return true if there's a pending "error status indication"
-     * that we need to display to the user.
-     */
-    public boolean hasPendingCallStatusCode() {
-        if (DBG) log("hasPendingCallStatusCode() ==> "
-                     + (mPendingCallStatusCode != CallStatusCode.SUCCESS));
-        return (mPendingCallStatusCode != CallStatusCode.SUCCESS);
-    }
-
-    /**
-     * @return the pending "error status indication" code
-     * that we need to display to the user.
-     */
-    public CallStatusCode getPendingCallStatusCode() {
-        if (DBG) log("getPendingCallStatusCode() ==> " + mPendingCallStatusCode);
-        return mPendingCallStatusCode;
-    }
-
-    /**
-     * Sets the pending "error status indication" code.
-     */
-    public void setPendingCallStatusCode(CallStatusCode status) {
-        if (DBG) log("setPendingCallStatusCode( " + status + " )...");
-        if (mPendingCallStatusCode != CallStatusCode.SUCCESS) {
-            // Uh oh: mPendingCallStatusCode is already set to some value
-            // other than SUCCESS (which indicates that there was some kind of
-            // failure), and now we're trying to indicate another (potentially
-            // different) failure.  But we can only indicate one failure at a
-            // time to the user, so the previous pending code is now going to
-            // be lost.
-            Log.w(TAG, "setPendingCallStatusCode: setting new code " + status
-                  + ", but a previous code " + mPendingCallStatusCode
-                  + " was already pending!");
-        }
-        mPendingCallStatusCode = status;
-    }
-
-    /**
-     * Clears out the pending "error status indication" code.
-     *
-     * This indicates that there's no longer any error or "exceptional
-     * condition" that needs to be displayed to the user.  (Typically, this
-     * method is called when the user dismisses the error dialog that came up
-     * because of a previous call status code.)
-     */
-    public void clearPendingCallStatusCode() {
-        if (DBG) log("clearPendingCallStatusCode()...");
-        mPendingCallStatusCode = CallStatusCode.SUCCESS;
-    }
-
-    /**
-     * Flag used to control the CDMA-specific "call lost" dialog.
-     *
-     * If true, that means that if the *next* outgoing call fails with an
-     * abnormal disconnection cause, we need to display the "call lost"
-     * dialog.  (Normally, in CDMA we handle some types of call failures
-     * by automatically retrying the call.  This flag is set to true when
-     * we're about to auto-retry, which means that if the *retry* also
-     * fails we'll give up and display an error.)
-     * See the logic in InCallScreen.onDisconnect() for the full story.
-     *
-     * TODO: the state machine that maintains the needToShowCallLostDialog
-     * flag in InCallScreen.onDisconnect() should really be moved into the
-     * CallController.  Then we can get rid of this extra flag, and
-     * instead simply use the CallStatusCode value CDMA_CALL_LOST to
-     * trigger the "call lost" dialog.
-     */
-    boolean needToShowCallLostDialog;
-
-
-    //
-    // Progress indications
-    //
-
-    /**
-     * Possible messages we might need to display along with
-     * an indefinite progress spinner.
-     */
-    public enum ProgressIndicationType {
-        /**
-         * No progress indication needs to be shown.
-         */
-        NONE,
-
-        /**
-         * Shown when making an emergency call from airplane mode;
-         * see CallController$EmergencyCallHelper.
-         */
-        TURNING_ON_RADIO,
-
-        /**
-         * Generic "retrying" state.  (Specifically, this is shown while
-         * retrying after an initial failure from the "emergency call from
-         * airplane mode" sequence.)
-         */
-         RETRYING
-    }
-
-    /**
-     * The current progress indication that should be shown
-     * to the user.  Any value other than NONE will cause the InCallScreen
-     * to bring up an indefinite progress spinner along with a message
-     * corresponding to the specified ProgressIndicationType.
-     */
-    private ProgressIndicationType progressIndication = ProgressIndicationType.NONE;
-
-    /** Sets the current progressIndication. */
-    public void setProgressIndication(ProgressIndicationType value) {
-        progressIndication = value;
-    }
-
-    /** Clears the current progressIndication. */
-    public void clearProgressIndication() {
-        progressIndication = ProgressIndicationType.NONE;
-    }
-
-    /**
-     * @return the current progress indication type, or ProgressIndicationType.NONE
-     * if no progress indication is currently active.
-     */
-    public ProgressIndicationType getProgressIndication() {
-        return progressIndication;
-    }
-
-    /** @return true if a progress indication is currently active. */
-    public boolean isProgressIndicationActive() {
-        return (progressIndication != ProgressIndicationType.NONE);
-    }
-
-    /**
-     * "Call origin" of the most recent phone call.
-     *
-     * Watch out: right now this is only used to determine where the user should go after the phone
-     * call. See also {@link InCallScreen} for more detail. There is *no* specific specification
-     * about how this variable will be used.
-     *
-     * @see PhoneGlobals#setLatestActiveCallOrigin(String)
-     * @see PhoneGlobals#createPhoneEndIntentUsingCallOrigin()
-     *
-     * TODO: we should determine some public behavior for this variable.
-     */
-    String latestActiveCallOrigin;
-
-    /**
-     * Timestamp for "Call origin". This will be used to preserve when the call origin was set.
-     * {@link android.os.SystemClock#elapsedRealtime()} will be used.
-     */
-    long latestActiveCallOriginTimeStamp;
-
-    /**
-     * Flag forcing Phone app to show in-call UI even when there's no phone call and thus Phone
-     * is in IDLE state. This will be turned on only when:
-     *
-     * - the last phone call is hung up, and
-     * - the screen is being turned off in the middle of in-call UI (and thus when the screen being
-     *   turned on in-call UI is expected to be the next foreground activity)
-     *
-     * At that moment whole UI should show "previously disconnected phone call" for a moment and
-     * exit itself. {@link InCallScreen#onPause()} will turn this off and prevent possible weird
-     * cases which may happen with that exceptional case.
-     */
-    boolean showAlreadyDisconnectedState;
-
-    //
-    // Debugging
-    //
-
-    public void dumpState() {
-        log("dumpState():");
-        log("  - showDialpad: " + showDialpad);
-        log("    - dialpadContextText: " + dialpadContextText);
-        if (hasPendingCallStatusCode()) {
-            log("  - status indication is pending!");
-            log("    - pending call status code = " + mPendingCallStatusCode);
-        } else {
-            log("  - pending call status code: none");
-        }
-        log("  - progressIndication: " + progressIndication);
-        log("  - latestActiveCallOrigin: " + latestActiveCallOrigin);
-    }
-
-    private static void log(String msg) {
-        Log.d(TAG, msg);
-    }
-}
diff --git a/src/com/android/phone/ManageConferenceUtils.java b/src/com/android/phone/ManageConferenceUtils.java
deleted file mode 100644
index 62e9a99..0000000
--- a/src/com/android/phone/ManageConferenceUtils.java
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * 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.os.SystemProperties;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewStub;
-import android.widget.Chronometer;
-import android.widget.TextView;
-
-import com.android.internal.telephony.CallerInfo;
-import com.android.internal.telephony.CallerInfoAsyncQuery;
-import com.android.internal.telephony.CallManager;
-import com.android.internal.telephony.Connection;
-
-import java.util.List;
-
-
-/**
- * Helper class to initialize and run the InCallScreen's "Manage conference" UI.
- */
-public class ManageConferenceUtils {
-    private static final String LOG_TAG = "ManageConferenceUtils";
-    private static final boolean DBG =
-            (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
-
-    /**
-     * CallerInfoAsyncQuery.OnQueryCompleteListener implementation.
-     *
-     * This object listens for results from the caller-id info queries we
-     * fire off in updateManageConferenceRow(), and updates the
-     * corresponding conference row.
-     */
-    private final class QueryCompleteListener
-            implements CallerInfoAsyncQuery.OnQueryCompleteListener {
-        private final int mConferencCallListIndex;
-
-        public QueryCompleteListener(int index) {
-            mConferencCallListIndex = index;
-        }
-
-        @Override
-        public void onQueryComplete(int token, Object cookie, CallerInfo ci) {
-            if (DBG) log("callerinfo query complete, updating UI." + ci);
-
-            Connection connection = (Connection) cookie;
-            int presentation = connection.getNumberPresentation();
-
-            // get the viewgroup (conference call list item) and make it visible
-            ViewGroup viewGroup = mConferenceCallList[mConferencCallListIndex];
-            viewGroup.setVisibility(View.VISIBLE);
-
-            // update the list item with this information.
-            displayCallerInfoForConferenceRow(ci, presentation,
-                    (TextView) viewGroup.findViewById(R.id.conferenceCallerName),
-                    (TextView) viewGroup.findViewById(R.id.conferenceCallerNumberType),
-                    (TextView) viewGroup.findViewById(R.id.conferenceCallerNumber));
-        }
-    }
-
-    private InCallScreen mInCallScreen;
-    private CallManager mCM;
-
-    // "Manage conference" UI elements and state
-    private ViewGroup mManageConferencePanel;
-    private View mButtonManageConferenceDone;
-    private ViewGroup[] mConferenceCallList;
-    private int mNumCallersInConference;
-    private Chronometer mConferenceTime;
-
-    // See CallTracker.MAX_CONNECTIONS_PER_CALL
-    private static final int MAX_CALLERS_IN_CONFERENCE = 5;
-
-    public ManageConferenceUtils(InCallScreen inCallScreen, CallManager cm) {
-        if (DBG) log("ManageConferenceUtils constructor...");
-        mInCallScreen = inCallScreen;
-        mCM = cm;
-    }
-
-    public void initManageConferencePanel() {
-        if (DBG) log("initManageConferencePanel()...");
-        if (mManageConferencePanel == null) {
-            if (DBG) log("initManageConferencePanel: first-time initialization!");
-
-            // Inflate the ViewStub, look up and initialize the UI elements.
-            ViewStub stub = (ViewStub) mInCallScreen.findViewById(R.id.manageConferencePanelStub);
-            stub.inflate();
-
-            mManageConferencePanel =
-                    (ViewGroup) mInCallScreen.findViewById(R.id.manageConferencePanel);
-            if (mManageConferencePanel == null) {
-                throw new IllegalStateException("Couldn't find manageConferencePanel!");
-            }
-
-            // set up the Conference Call chronometer
-            mConferenceTime =
-                    (Chronometer) mInCallScreen.findViewById(R.id.manageConferencePanelHeader);
-            mConferenceTime.setFormat(mInCallScreen.getString(R.string.caller_manage_header));
-
-            // Create list of conference call widgets
-            mConferenceCallList = new ViewGroup[MAX_CALLERS_IN_CONFERENCE];
-
-            final int[] viewGroupIdList = { R.id.caller0, R.id.caller1, R.id.caller2,
-                                            R.id.caller3, R.id.caller4 };
-            for (int i = 0; i < MAX_CALLERS_IN_CONFERENCE; i++) {
-                mConferenceCallList[i] =
-                        (ViewGroup) mInCallScreen.findViewById(viewGroupIdList[i]);
-            }
-
-            mButtonManageConferenceDone = mInCallScreen.findViewById(R.id.manage_done);
-            mButtonManageConferenceDone.setOnClickListener(mInCallScreen);
-        }
-    }
-
-    /**
-     * Shows or hides the manageConferencePanel.
-     */
-    public void setPanelVisible(boolean visible) {
-        if (mManageConferencePanel != null) {
-            mManageConferencePanel.setVisibility(visible ? View.VISIBLE : View.GONE);
-        }
-    }
-
-    /**
-     * Starts the "conference time" chronometer.
-     */
-    public void startConferenceTime(long base) {
-        if (mConferenceTime != null) {
-            mConferenceTime.setBase(base);
-            mConferenceTime.start();
-        }
-    }
-
-    /**
-     * Stops the "conference time" chronometer.
-     */
-    public void stopConferenceTime() {
-        if (mConferenceTime != null) {
-            mConferenceTime.stop();
-        }
-    }
-
-    public int getNumCallersInConference() {
-        return mNumCallersInConference;
-    }
-
-    /**
-     * Updates the "Manage conference" UI based on the specified List of
-     * connections.
-     *
-     * @param connections the List of connections belonging to
-     *        the current foreground call; size must be greater than 1
-     *        (or it wouldn't be a conference call in the first place.)
-     */
-    public void updateManageConferencePanel(List<Connection> connections) {
-        mNumCallersInConference = connections.size();
-        if (DBG) log("updateManageConferencePanel()... num connections in conference = "
-                      + mNumCallersInConference);
-
-        // Can we give the user the option to separate out ("go private with") a single
-        // caller from this conference?
-        final boolean hasActiveCall = mCM.hasActiveFgCall();
-        final boolean hasHoldingCall = mCM.hasActiveBgCall();
-        boolean canSeparate = !(hasActiveCall && hasHoldingCall);
-
-        for (int i = 0; i < MAX_CALLERS_IN_CONFERENCE; i++) {
-            if (i < mNumCallersInConference) {
-                // Fill in the row in the UI for this caller.
-                Connection connection = (Connection) connections.get(i);
-                updateManageConferenceRow(i, connection, canSeparate);
-            } else {
-                // Blank out this row in the UI
-                updateManageConferenceRow(i, null, false);
-            }
-        }
-    }
-
-    /**
-     * Updates a single row of the "Manage conference" UI.  (One row in this
-     * UI represents a single caller in the conference.)
-     *
-     * @param i the row to update
-     * @param connection the Connection corresponding to this caller.
-     *        If null, that means this is an "empty slot" in the conference,
-     *        so hide this row in the UI.
-     * @param canSeparate if true, show a "Separate" (i.e. "Private") button
-     *        on this row in the UI.
-     */
-    public void updateManageConferenceRow(final int i,
-                                          final Connection connection,
-                                          boolean canSeparate) {
-        if (DBG) log("updateManageConferenceRow(" + i + ")...  connection = " + connection);
-
-        if (connection != null) {
-            // Activate this row of the Manage conference panel:
-            mConferenceCallList[i].setVisibility(View.VISIBLE);
-
-            // get the relevant children views
-            View endButton = mConferenceCallList[i].findViewById(R.id.conferenceCallerDisconnect);
-            View separateButton = mConferenceCallList[i].findViewById(
-                    R.id.conferenceCallerSeparate);
-            TextView nameTextView = (TextView) mConferenceCallList[i].findViewById(
-                    R.id.conferenceCallerName);
-            TextView numberTextView = (TextView) mConferenceCallList[i].findViewById(
-                    R.id.conferenceCallerNumber);
-            TextView numberTypeTextView = (TextView) mConferenceCallList[i].findViewById(
-                    R.id.conferenceCallerNumberType);
-
-            if (DBG) log("- button: " + endButton + ", nameTextView: " + nameTextView);
-
-            // Hook up this row's buttons.
-            View.OnClickListener endThisConnection = new View.OnClickListener() {
-                    @Override
-                    public void onClick(View v) {
-                        endConferenceConnection(i, connection);
-                        PhoneGlobals.getInstance().pokeUserActivity();
-                    }
-                };
-            endButton.setOnClickListener(endThisConnection);
-            //
-            if (canSeparate) {
-                View.OnClickListener separateThisConnection = new View.OnClickListener() {
-                        @Override
-                        public void onClick(View v) {
-                            separateConferenceConnection(i, connection);
-                            PhoneGlobals.getInstance().pokeUserActivity();
-                        }
-                    };
-                separateButton.setOnClickListener(separateThisConnection);
-                separateButton.setVisibility(View.VISIBLE);
-            } else {
-                separateButton.setVisibility(View.INVISIBLE);
-            }
-
-            // Name/number for this caller.
-            QueryCompleteListener listener = new QueryCompleteListener(i);
-            PhoneUtils.CallerInfoToken info =
-                    PhoneUtils.startGetCallerInfo(mInCallScreen,
-                            connection, listener, connection);
-            if (DBG) log("  - got info from startGetCallerInfo(): " + info);
-
-            // display the CallerInfo.
-            displayCallerInfoForConferenceRow(info.currentInfo, connection.getNumberPresentation(),
-                    nameTextView, numberTypeTextView, numberTextView);
-        } else {
-            // Disable this row of the Manage conference panel:
-            mConferenceCallList[i].setVisibility(View.GONE);
-        }
-    }
-
-    /**
-     * Helper function to fill out the Conference Call(er) information
-     * for each item in the "Manage Conference Call" list.
-     *
-     * @param presentation presentation specified by {@link Connection}.
-     */
-    public final void displayCallerInfoForConferenceRow(CallerInfo ci, int presentation,
-            TextView nameTextView, TextView numberTypeTextView, TextView numberTextView) {
-        // gather the correct name and number information.
-        String callerName = "";
-        String callerNumber = "";
-        String callerNumberType = "";
-        if (ci != null) {
-            callerName = ci.name;
-            if (TextUtils.isEmpty(callerName)) {
-                // Do similar fallback as CallCard does.
-                // See also CallCard#updateDisplayForPerson().
-                if (TextUtils.isEmpty(ci.phoneNumber)) {
-                    callerName = PhoneUtils.getPresentationString(mInCallScreen, presentation);
-                } else if (!TextUtils.isEmpty(ci.cnapName)) {
-                    // No name, but we do have a valid CNAP name, so use that.
-                    callerName = ci.cnapName;
-                } else {
-                    callerName = ci.phoneNumber;
-                }
-            } else {
-                callerNumber = ci.phoneNumber;
-                callerNumberType = ci.phoneLabel;
-            }
-        }
-
-        // set the caller name
-        nameTextView.setText(callerName);
-
-        // set the caller number in subscript, or make the field disappear.
-        if (TextUtils.isEmpty(callerNumber)) {
-            numberTextView.setVisibility(View.GONE);
-            numberTypeTextView.setVisibility(View.GONE);
-        } else {
-            numberTextView.setVisibility(View.VISIBLE);
-            numberTextView.setText(callerNumber);
-            numberTypeTextView.setVisibility(View.VISIBLE);
-            numberTypeTextView.setText(callerNumberType);
-        }
-    }
-
-    /**
-     * Ends the specified connection on a conference call.  This method is
-     * run (via a closure containing a row index and Connection) when the
-     * user clicks the "End" button on a specific row in the Manage
-     * conference UI.
-     */
-    public void endConferenceConnection(int i, Connection connection) {
-        if (DBG) log("===> ENDING conference connection " + i
-                      + ": Connection " + connection);
-        // The actual work of ending the connection:
-        PhoneUtils.hangup(connection);
-        // No need to manually update the "Manage conference" UI here;
-        // that'll happen automatically very soon (when we get the
-        // onDisconnect() callback triggered by this hangup() call.)
-    }
-
-    /**
-     * Separates out the specified connection on a conference call.  This
-     * method is run (via a closure containing a row index and Connection)
-     * when the user clicks the "Separate" (i.e. "Private") button on a
-     * specific row in the Manage conference UI.
-     */
-    public void separateConferenceConnection(int i, Connection connection) {
-        if (DBG) log("===> SEPARATING conference connection " + i
-                      + ": Connection " + connection);
-
-        PhoneUtils.separateCall(connection);
-
-        // Note that separateCall() automagically makes the
-        // newly-separated call into the foreground call (which is the
-        // desired UI), so there's no need to do any further
-        // call-switching here.
-        // There's also no need to manually update (or hide) the "Manage
-        // conference" UI; that'll happen on its own in a moment (when we
-        // get the phone state change event triggered by the call to
-        // separateCall().)
-    }
-
-
-    private void log(String msg) {
-        Log.d(LOG_TAG, msg);
-    }
-}
diff --git a/src/com/android/phone/NotificationMgr.java b/src/com/android/phone/NotificationMgr.java
index 7771fa9..8ead0ce 100644
--- a/src/com/android/phone/NotificationMgr.java
+++ b/src/com/android/phone/NotificationMgr.java
@@ -645,10 +645,6 @@
         // activity, since the in-call UI already provides an onscreen
         // indication of the speaker state.  (This reduces clutter in the
         // status bar.)
-        if (mApp.isShowingCallScreen()) {
-            cancelSpeakerphone();
-            return;
-        }
 
         if (showNotification) {
             notifySpeakerphone();
@@ -684,10 +680,6 @@
         // foreground activity, since the in-call UI already provides an
         // onscreen indication of the mute state.  (This reduces clutter
         // in the status bar.)
-        if (mApp.isShowingCallScreen()) {
-            cancelMute();
-            return;
-        }
 
         if ((mCM.getState() == PhoneConstants.State.OFFHOOK) && PhoneUtils.getMute()) {
             if (DBG) log("updateMuteNotification: MUTED");
diff --git a/src/com/android/phone/OtaUtils.java b/src/com/android/phone/OtaUtils.java
index e713df9..8b67148 100644
--- a/src/com/android/phone/OtaUtils.java
+++ b/src/com/android/phone/OtaUtils.java
@@ -141,17 +141,9 @@
     private static final String OTASP_NUMBER = "*228";
     private static final String OTASP_NUMBER_NON_INTERACTIVE = "*22899";
 
-    private InCallScreen mInCallScreen;
     private Context mContext;
     private PhoneGlobals mApplication;
     private OtaWidgetData mOtaWidgetData;
-    private ViewGroup mInCallTouchUi;  // UI controls for regular calls
-    private CallCard mCallCard;
-
-    // The DTMFTwelveKeyDialer instance.   We create this in
-    // initOtaInCallScreen(), and attach it to the DTMFTwelveKeyDialerView
-    // ("otaDtmfDialerView") that comes from otacall_card.xml.
-    private DTMFTwelveKeyDialer mOtaCallCardDtmfDialer;
 
     private static boolean sIsWizardMode = true;
 
@@ -201,7 +193,6 @@
         public AlertDialog otaFailureDialog;
         public AlertDialog otaSkipConfirmationDialog;
         public TextView otaTitle;
-        public DTMFTwelveKeyDialerView otaDtmfDialerView;
         public Button otaTryAgainButton;
     }
 
@@ -225,59 +216,6 @@
     }
 
     /**
-     * Updates the OtaUtils object's references to some UI elements belonging to
-     * the InCallScreen.  This is used only in interactive mode.
-     *
-     * Use clearUiWidgets() to clear out these references.  (The InCallScreen
-     * is responsible for doing this from its onDestroy() method.)
-     *
-     * This method has no effect if the UI widgets have already been set up.
-     * (In other words, it's safe to call this every time through
-     * InCallScreen.onResume().)
-     */
-    public void updateUiWidgets(InCallScreen inCallScreen,
-            ViewGroup inCallTouchUi, CallCard callCard) {
-        if (DBG) log("updateUiWidgets()...  mInCallScreen = " + mInCallScreen);
-
-        if (!mInteractive) {
-            throw new IllegalStateException("updateUiWidgets() called in non-interactive mode");
-        }
-
-        if (mInCallScreen != null) {
-            if (DBG) log("updateUiWidgets(): widgets already set up, nothing to do...");
-            return;
-        }
-
-        mInCallScreen = inCallScreen;
-        mInCallTouchUi = inCallTouchUi;
-        mCallCard = callCard;
-        mOtaWidgetData = new OtaWidgetData();
-
-        // Inflate OTASP-specific UI elements:
-        ViewStub otaCallCardStub = (ViewStub) mInCallScreen.findViewById(R.id.otaCallCardStub);
-        if (otaCallCardStub != null) {
-            // If otaCallCardStub is null here, that means it's already been
-            // inflated (which could have happened in the current InCallScreen
-            // instance for a *prior* OTASP call.)
-            otaCallCardStub.inflate();
-        }
-
-        readXmlSettings();
-        initOtaInCallScreen();
-    }
-
-    /**
-     * Clear out the OtaUtils object's references to any InCallScreen UI
-     * elements.  This is the opposite of updateUiWidgets().
-     */
-    public void clearUiWidgets() {
-        mInCallScreen = null;
-        mInCallTouchUi = null;
-        mCallCard = null;
-        mOtaWidgetData = null;
-    }
-
-    /**
      * Starts the OTA provisioning call.  If the MIN isn't available yet, it returns false and adds
      * an event to return the request to the calling app when it becomes available.
      *
@@ -583,7 +521,7 @@
 
         // TODO(OTASP): note app.inCallUiState.inCallScreenMode and
         // app.cdmaOtaInCallScreenUiState.state are mostly redundant.  Combine them.
-        app.inCallUiState.inCallScreenMode = InCallUiState.InCallScreenMode.OTA_NORMAL;
+        // app.inCallUiState.inCallScreenMode = InCallUiState.InCallScreenMode.OTA_NORMAL;
 
         // TODO(OTASP / bug 5092031): we ideally should call
         // otaShowListeningScreen() here to make sure that the DTMF dialpad
@@ -714,7 +652,7 @@
         if (DBG) log("otaShowHome()...");
         mApplication.cdmaOtaScreenState.otaScreenState =
                 CdmaOtaScreenState.OtaScreenState.OTA_STATUS_UNDEFINED;
-        mInCallScreen.endInCallScreenSession();
+        // mInCallScreen.endInCallScreenSession();
         Intent intent = new Intent(Intent.ACTION_MAIN);
         intent.addCategory (Intent.CATEGORY_HOME);
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
@@ -727,7 +665,7 @@
 
         sendOtaspResult(OTASP_USER_SKIPPED);
 
-        if (mInteractive) mInCallScreen.finish();
+        // if (mInteractive) mInCallScreen.finish();
         return;
     }
 
@@ -753,7 +691,7 @@
 
             // ...and get the OTASP-specific UI into the right state.
             otaShowListeningScreen();
-            mInCallScreen.requestUpdateScreen();
+            // mInCallScreen.requestUpdateScreen();
         }
         return;
     }
@@ -804,7 +742,7 @@
                 otaScreenInitialize();
                 mOtaWidgetData.otaTextListenProgress.setVisibility(View.VISIBLE);
                 mOtaWidgetData.otaTextListenProgress.setText(R.string.ota_listen);
-                mOtaWidgetData.otaDtmfDialerView.setVisibility(View.VISIBLE);
+                // mOtaWidgetData.otaDtmfDialerView.setVisibility(View.VISIBLE);
                 mOtaWidgetData.callCardOtaButtonsListenProgress.setVisibility(View.VISIBLE);
                 mOtaWidgetData.otaSpeakerButton.setVisibility(View.VISIBLE);
                 boolean speakerOn = PhoneUtils.isSpeakerOn(mContext);
@@ -923,7 +861,7 @@
         mApplication.cdmaOtaScreenState.otaScreenState =
             CdmaOtaScreenState.OtaScreenState.OTA_STATUS_PROGRESS;
 
-        if ((mOtaWidgetData == null) || (mInCallScreen == null)) {
+        if ((mOtaWidgetData == null) /* || (mInCallScreen == null) */) {
             Log.w(LOG_TAG, "otaShowInProgressScreen: UI widgets not set up yet!");
 
             // TODO(OTASP): our CdmaOtaScreenState is now correct; we just set
@@ -1008,9 +946,9 @@
         mOtaWidgetData.callCardOtaButtonsFailSuccess.setVisibility(View.VISIBLE);
         mOtaWidgetData.otaTryAgainButton.setVisibility(View.VISIBLE);
         //close the dialer if open
-        if (isDialerOpened()) {
-            mOtaCallCardDtmfDialer.closeDialer(false);
-        }
+        // if (isDialerOpened()) {
+        //     mOtaCallCardDtmfDialer.closeDialer(false);
+        // }
     }
 
     /**
@@ -1026,9 +964,9 @@
         mOtaWidgetData.callCardOtaButtonsFailSuccess.setVisibility(View.VISIBLE);
         mOtaWidgetData.otaNextButton.setVisibility(View.VISIBLE);
         //close the dialer if open
-        if (isDialerOpened()) {
-            mOtaCallCardDtmfDialer.closeDialer(false);
-        }
+        // if (isDialerOpened()) {
+        //     mOtaCallCardDtmfDialer.closeDialer(false);
+        // }
     }
 
     /**
@@ -1047,7 +985,7 @@
                     log("Ignoring key events...");
                     return true;
                 }};
-            mOtaWidgetData.spcErrorDialog = new AlertDialog.Builder(mInCallScreen)
+            mOtaWidgetData.spcErrorDialog = new AlertDialog.Builder(null /* mInCallScreen */)
                     .setMessage(R.string.ota_spc_failure)
                     .setOnKeyListener(keyListener)
                     .create();
@@ -1056,12 +994,12 @@
                     | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
             mOtaWidgetData.spcErrorDialog.show();
             //close the dialer if open
-            if (isDialerOpened()) {
-                mOtaCallCardDtmfDialer.closeDialer(false);
-            }
+            // if (isDialerOpened()) {
+            //     mOtaCallCardDtmfDialer.closeDialer(false);
+            // }
             long noticeTime = length*1000;
             if (DBG) log("otaShowSpcErrorNotice(), remaining SPC noticeTime" + noticeTime);
-            mInCallScreen.requestCloseSpcErrorNotice(noticeTime);
+            // mInCallScreen.requestCloseSpcErrorNotice(noticeTime);
         }
     }
 
@@ -1083,7 +1021,7 @@
     private void otaShowProgramFailureNotice(int length) {
         if (DBG) log("otaShowProgramFailureNotice()...");
         if (mOtaWidgetData.otaFailureDialog == null) {
-            mOtaWidgetData.otaFailureDialog = new AlertDialog.Builder(mInCallScreen)
+            mOtaWidgetData.otaFailureDialog = new AlertDialog.Builder(null /* mInCallScreen */)
                     .setMessage(R.string.ota_failure)
                     .create();
             mOtaWidgetData.otaFailureDialog.getWindow().addFlags(
@@ -1092,7 +1030,7 @@
             mOtaWidgetData.otaFailureDialog.show();
 
             long noticeTime = length*1000;
-            mInCallScreen.requestCloseOtaFailureNotice(noticeTime);
+            // mInCallScreen.requestCloseOtaFailureNotice(noticeTime);
         }
     }
 
@@ -1124,12 +1062,12 @@
             return;
         }
 
-        if (mInCallTouchUi != null) mInCallTouchUi.setVisibility(View.GONE);
-        if (mCallCard != null) {
-            mCallCard.setVisibility(View.GONE);
-            // TODO: try removing this.
-            mCallCard.hideCallCardElements();
-        }
+        // if (mInCallTouchUi != null) mInCallTouchUi.setVisibility(View.GONE);
+        // if (mCallCard != null) {
+        //     mCallCard.setVisibility(View.GONE);
+        //     // TODO: try removing this.
+        //     mCallCard.hideCallCardElements();
+        // }
 
         mOtaWidgetData.otaTitle.setText(R.string.ota_title_activate);
         mOtaWidgetData.otaTextActivate.setVisibility(View.GONE);
@@ -1139,7 +1077,7 @@
         mOtaWidgetData.callCardOtaButtonsActivate.setVisibility(View.GONE);
         mOtaWidgetData.callCardOtaButtonsListenProgress.setVisibility(View.GONE);
         mOtaWidgetData.callCardOtaButtonsFailSuccess.setVisibility(View.GONE);
-        mOtaWidgetData.otaDtmfDialerView.setVisibility(View.GONE);
+        // mOtaWidgetData.otaDtmfDialerView.setVisibility(View.GONE);
         mOtaWidgetData.otaSpeakerButton.setVisibility(View.GONE);
         mOtaWidgetData.otaTryAgainButton.setVisibility(View.GONE);
         mOtaWidgetData.otaNextButton.setVisibility(View.GONE);
@@ -1157,7 +1095,8 @@
     }
 
     public boolean isDialerOpened() {
-        boolean retval = (mOtaCallCardDtmfDialer != null && mOtaCallCardDtmfDialer.isOpened());
+        // boolean retval = (mOtaCallCardDtmfDialer != null && mOtaCallCardDtmfDialer.isOpened());
+        boolean retval = false;
         if (DBG) log("- isDialerOpened() ==> " + retval);
         return retval;
     }
@@ -1180,30 +1119,30 @@
             return;
         }
 
-        if ((mInCallScreen != null) && mInCallScreen.isForegroundActivity()) {
-            if (DBG) log("otaShowProperScreen(): InCallScreen in foreground, currentstate = "
-                    + mApplication.cdmaOtaScreenState.otaScreenState);
-            if (mInCallTouchUi != null) {
-                mInCallTouchUi.setVisibility(View.GONE);
-            }
-            if (mCallCard != null) {
-                mCallCard.setVisibility(View.GONE);
-            }
-            if (mApplication.cdmaOtaScreenState.otaScreenState
-                    == CdmaOtaScreenState.OtaScreenState.OTA_STATUS_ACTIVATION) {
-                otaShowActivateScreen();
-            } else if (mApplication.cdmaOtaScreenState.otaScreenState
-                    == CdmaOtaScreenState.OtaScreenState.OTA_STATUS_LISTENING) {
-                otaShowListeningScreen();
-            } else if (mApplication.cdmaOtaScreenState.otaScreenState
-                    == CdmaOtaScreenState.OtaScreenState.OTA_STATUS_PROGRESS) {
-                otaShowInProgressScreen();
-            }
+        // if ((mInCallScreen != null) && mInCallScreen.isForegroundActivity()) {
+        //     if (DBG) log("otaShowProperScreen(): InCallScreen in foreground, currentstate = "
+        //             + mApplication.cdmaOtaScreenState.otaScreenState);
+        //     if (mInCallTouchUi != null) {
+        //         mInCallTouchUi.setVisibility(View.GONE);
+        //     }
+        //     if (mCallCard != null) {
+        //         mCallCard.setVisibility(View.GONE);
+        //     }
+        //     if (mApplication.cdmaOtaScreenState.otaScreenState
+        //             == CdmaOtaScreenState.OtaScreenState.OTA_STATUS_ACTIVATION) {
+        //         otaShowActivateScreen();
+        //     } else if (mApplication.cdmaOtaScreenState.otaScreenState
+        //             == CdmaOtaScreenState.OtaScreenState.OTA_STATUS_LISTENING) {
+        //         otaShowListeningScreen();
+        //     } else if (mApplication.cdmaOtaScreenState.otaScreenState
+        //             == CdmaOtaScreenState.OtaScreenState.OTA_STATUS_PROGRESS) {
+        //         otaShowInProgressScreen();
+        //     }
 
-            if (mApplication.cdmaOtaProvisionData.inOtaSpcState) {
-                otaShowSpcErrorNotice(getOtaSpcDisplayTime());
-            }
-        }
+        //     if (mApplication.cdmaOtaProvisionData.inOtaSpcState) {
+        //         otaShowSpcErrorNotice(getOtaSpcDisplayTime());
+        //     }
+        // }
     }
 
     /**
@@ -1292,7 +1231,7 @@
                 // the screen is not updated by the call disconnect
                 // handler and we have to do it here
                 setSpeaker(false);
-                mInCallScreen.handleOtaCallEnd();
+                // mInCallScreen.handleOtaCallEnd();
             }
         }
     }
@@ -1320,7 +1259,7 @@
                 return true;
             }
         };
-        mOtaWidgetData.otaSkipConfirmationDialog = new AlertDialog.Builder(mInCallScreen)
+        mOtaWidgetData.otaSkipConfirmationDialog = new AlertDialog.Builder(null /* mInCallScreen */)
                 .setTitle(R.string.ota_skip_activation_dialog_title)
                 .setMessage(R.string.ota_skip_activation_dialog_message)
                 .setPositiveButton(
@@ -1389,60 +1328,60 @@
      */
     private void initOtaInCallScreen() {
         if (DBG) log("initOtaInCallScreen()...");
-        mOtaWidgetData.otaTitle = (TextView) mInCallScreen.findViewById(R.id.otaTitle);
-        mOtaWidgetData.otaTextActivate = (TextView) mInCallScreen.findViewById(R.id.otaActivate);
+        // mOtaWidgetData.otaTitle = (TextView) mInCallScreen.findViewById(R.id.otaTitle);
+        // mOtaWidgetData.otaTextActivate = (TextView) mInCallScreen.findViewById(R.id.otaActivate);
         mOtaWidgetData.otaTextActivate.setVisibility(View.GONE);
-        mOtaWidgetData.otaTextListenProgress =
-                (TextView) mInCallScreen.findViewById(R.id.otaListenProgress);
-        mOtaWidgetData.otaTextProgressBar =
-                (ProgressBar) mInCallScreen.findViewById(R.id.progress_large);
+        // mOtaWidgetData.otaTextListenProgress =
+        //         (TextView) mInCallScreen.findViewById(R.id.otaListenProgress);
+        // mOtaWidgetData.otaTextProgressBar =
+        //         (ProgressBar) mInCallScreen.findViewById(R.id.progress_large);
         mOtaWidgetData.otaTextProgressBar.setIndeterminate(true);
-        mOtaWidgetData.otaTextSuccessFail =
-                (TextView) mInCallScreen.findViewById(R.id.otaSuccessFailStatus);
+        // mOtaWidgetData.otaTextSuccessFail =
+        //         (TextView) mInCallScreen.findViewById(R.id.otaSuccessFailStatus);
 
-        mOtaWidgetData.otaUpperWidgets =
-                (ViewGroup) mInCallScreen.findViewById(R.id.otaUpperWidgets);
-        mOtaWidgetData.callCardOtaButtonsListenProgress =
-                (View) mInCallScreen.findViewById(R.id.callCardOtaListenProgress);
-        mOtaWidgetData.callCardOtaButtonsActivate =
-                (View) mInCallScreen.findViewById(R.id.callCardOtaActivate);
-        mOtaWidgetData.callCardOtaButtonsFailSuccess =
-                (View) mInCallScreen.findViewById(R.id.callCardOtaFailOrSuccessful);
+        // mOtaWidgetData.otaUpperWidgets =
+        //         (ViewGroup) mInCallScreen.findViewById(R.id.otaUpperWidgets);
+        // mOtaWidgetData.callCardOtaButtonsListenProgress =
+        //         (View) mInCallScreen.findViewById(R.id.callCardOtaListenProgress);
+        // mOtaWidgetData.callCardOtaButtonsActivate =
+        //         (View) mInCallScreen.findViewById(R.id.callCardOtaActivate);
+        // mOtaWidgetData.callCardOtaButtonsFailSuccess =
+        //         (View) mInCallScreen.findViewById(R.id.callCardOtaFailOrSuccessful);
 
-        mOtaWidgetData.otaEndButton = (Button) mInCallScreen.findViewById(R.id.otaEndButton);
-        mOtaWidgetData.otaEndButton.setOnClickListener(mInCallScreen);
-        mOtaWidgetData.otaSpeakerButton =
-                (ToggleButton) mInCallScreen.findViewById(R.id.otaSpeakerButton);
-        mOtaWidgetData.otaSpeakerButton.setOnClickListener(mInCallScreen);
-        mOtaWidgetData.otaActivateButton =
-                (Button) mInCallScreen.findViewById(R.id.otaActivateButton);
-        mOtaWidgetData.otaActivateButton.setOnClickListener(mInCallScreen);
-        mOtaWidgetData.otaSkipButton = (Button) mInCallScreen.findViewById(R.id.otaSkipButton);
-        mOtaWidgetData.otaSkipButton.setOnClickListener(mInCallScreen);
-        mOtaWidgetData.otaNextButton = (Button) mInCallScreen.findViewById(R.id.otaNextButton);
-        mOtaWidgetData.otaNextButton.setOnClickListener(mInCallScreen);
-        mOtaWidgetData.otaTryAgainButton =
-                (Button) mInCallScreen.findViewById(R.id.otaTryAgainButton);
-        mOtaWidgetData.otaTryAgainButton.setOnClickListener(mInCallScreen);
+        // mOtaWidgetData.otaEndButton = (Button) mInCallScreen.findViewById(R.id.otaEndButton);
+        // mOtaWidgetData.otaEndButton.setOnClickListener(mInCallScreen);
+        // mOtaWidgetData.otaSpeakerButton =
+        //         (ToggleButton) mInCallScreen.findViewById(R.id.otaSpeakerButton);
+        // mOtaWidgetData.otaSpeakerButton.setOnClickListener(mInCallScreen);
+        // mOtaWidgetData.otaActivateButton =
+        //         (Button) mInCallScreen.findViewById(R.id.otaActivateButton);
+        // mOtaWidgetData.otaActivateButton.setOnClickListener(mInCallScreen);
+        // mOtaWidgetData.otaSkipButton = (Button) mInCallScreen.findViewById(R.id.otaSkipButton);
+        // mOtaWidgetData.otaSkipButton.setOnClickListener(mInCallScreen);
+        // mOtaWidgetData.otaNextButton = (Button) mInCallScreen.findViewById(R.id.otaNextButton);
+        // mOtaWidgetData.otaNextButton.setOnClickListener(mInCallScreen);
+        // mOtaWidgetData.otaTryAgainButton =
+        //         (Button) mInCallScreen.findViewById(R.id.otaTryAgainButton);
+        // mOtaWidgetData.otaTryAgainButton.setOnClickListener(mInCallScreen);
 
-        mOtaWidgetData.otaDtmfDialerView =
-                (DTMFTwelveKeyDialerView) mInCallScreen.findViewById(R.id.otaDtmfDialerView);
+        // mOtaWidgetData.otaDtmfDialerView =
+        //         (DTMFTwelveKeyDialerView) mInCallScreen.findViewById(R.id.otaDtmfDialerView);
         // Sanity-check: the otaDtmfDialerView widget should *always* be present.
-        if (mOtaWidgetData.otaDtmfDialerView == null) {
-            throw new IllegalStateException("initOtaInCallScreen: couldn't find otaDtmfDialerView");
-        }
+        // if (mOtaWidgetData.otaDtmfDialerView == null) {
+        //     throw new IllegalStateException("initOtaInCallScreen: couldn't find otaDtmfDialerView");
+        // }
 
         // Create a new DTMFTwelveKeyDialer instance purely for use by the
         // DTMFTwelveKeyDialerView ("otaDtmfDialerView") that comes from
         // otacall_card.xml.
-        mOtaCallCardDtmfDialer = new DTMFTwelveKeyDialer(mInCallScreen,
-                                                         mOtaWidgetData.otaDtmfDialerView);
+        // mOtaCallCardDtmfDialer = new DTMFTwelveKeyDialer(mInCallScreen,
+        //                                                  mOtaWidgetData.otaDtmfDialerView);
 
         // Initialize the new DTMFTwelveKeyDialer instance.  This is
         // needed to play local DTMF tones.
-        mOtaCallCardDtmfDialer.startDialerSession();
+        // mOtaCallCardDtmfDialer.startDialerSession();
 
-        mOtaWidgetData.otaDtmfDialerView.setDialer(mOtaCallCardDtmfDialer);
+        // mOtaWidgetData.otaDtmfDialerView.setDialer(mOtaCallCardDtmfDialer);
     }
 
     /**
@@ -1463,17 +1402,17 @@
         mApplication.cdmaOtaInCallScreenUiState.state = State.UNDEFINED;
 
         if (mInteractive && (mOtaWidgetData != null)) {
-            if (mInCallTouchUi != null) mInCallTouchUi.setVisibility(View.VISIBLE);
-            if (mCallCard != null) {
-                mCallCard.setVisibility(View.VISIBLE);
-                mCallCard.hideCallCardElements();
-            }
+            // if (mInCallTouchUi != null) mInCallTouchUi.setVisibility(View.VISIBLE);
+            // if (mCallCard != null) {
+            //     mCallCard.setVisibility(View.VISIBLE);
+            //     mCallCard.hideCallCardElements();
+            // }
 
             // Free resources from the DTMFTwelveKeyDialer instance we created
             // in initOtaInCallScreen().
-            if (mOtaCallCardDtmfDialer != null) {
-                mOtaCallCardDtmfDialer.stopDialerSession();
-            }
+            // if (mOtaCallCardDtmfDialer != null) {
+            //     mOtaCallCardDtmfDialer.stopDialerSession();
+            // }
 
             mOtaWidgetData.otaTextActivate.setVisibility(View.GONE);
             mOtaWidgetData.otaTextListenProgress.setVisibility(View.GONE);
@@ -1483,7 +1422,7 @@
             mOtaWidgetData.callCardOtaButtonsListenProgress.setVisibility(View.GONE);
             mOtaWidgetData.callCardOtaButtonsFailSuccess.setVisibility(View.GONE);
             mOtaWidgetData.otaUpperWidgets.setVisibility(View.GONE);
-            mOtaWidgetData.otaDtmfDialerView.setVisibility(View.GONE);
+            // mOtaWidgetData.otaDtmfDialerView.setVisibility(View.GONE);
             mOtaWidgetData.otaNextButton.setVisibility(View.GONE);
             mOtaWidgetData.otaTryAgainButton.setVisibility(View.GONE);
         }
diff --git a/src/com/android/phone/OutgoingCallBroadcaster.java b/src/com/android/phone/OutgoingCallBroadcaster.java
index c5e8953..a4f7178 100644
--- a/src/com/android/phone/OutgoingCallBroadcaster.java
+++ b/src/com/android/phone/OutgoingCallBroadcaster.java
@@ -203,7 +203,6 @@
                     // to take down any OTASP-related UI first.
                     if (dialogState) app.dismissOtaDialogs();
                     app.clearOtaState();
-                    app.clearInCallScreenMode();
                 } else if (isOtaCallActive) {
                     // The actual OTASP call is active.  Don't allow new
                     // outgoing calls at all from this state.
@@ -600,17 +599,6 @@
             // EXTRA_ALREADY_CALLED extra.)
         }
 
-        // Remember the call origin so that users will be able to see an appropriate screen
-        // after the phone call. This should affect both phone calls and SIP calls.
-        final String callOrigin = intent.getStringExtra(PhoneGlobals.EXTRA_CALL_ORIGIN);
-        if (callOrigin != null) {
-            if (DBG) Log.v(TAG, " - Call origin is passed (" + callOrigin + ")");
-            PhoneGlobals.getInstance().setLatestActiveCallOrigin(callOrigin);
-        } else {
-            if (DBG) Log.v(TAG, " - Call origin is not passed. Reset current one.");
-            PhoneGlobals.getInstance().resetLatestActiveCallOrigin();
-        }
-
         // For now, SIP calls will be processed directly without a
         // NEW_OUTGOING_CALL broadcast.
         //
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index b70b159..06b8969 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -163,7 +163,6 @@
     CallManager mCM;
     CallNotifier notifier;
     CallerInfoCache callerInfoCache;
-    InCallUiState inCallUiState;
     NotificationMgr notificationMgr;
     Phone phone;
     PhoneInterfaceManager phoneMgr;
@@ -187,10 +186,6 @@
     // Internal PhoneApp Call state tracker
     CdmaPhoneCallState cdmaPhoneCallState;
 
-    // The InCallScreen instance (or null if the InCallScreen hasn't been
-    // created yet.)
-    private InCallScreen mInCallScreen;
-
     // The currently-active PUK entry activity and progress dialog.
     // Normally, these are the Emergency Dialer and the subsequent
     // progress dialog.  null if there is are no such objects in
@@ -259,15 +254,6 @@
         mShouldRestoreMuteOnInCallResume = mode;
     }
 
-    /**
-     * Get the restore mute state flag.
-     * This is used by the InCallScreen {@link InCallScreen#onResume()} to figure
-     * out if we need to restore the mute state for the current active call.
-     */
-    /*package*/boolean getRestoreMuteOnInCallResume () {
-        return mShouldRestoreMuteOnInCallResume;
-    }
-
     Handler mHandler = new Handler() {
         @Override
         public void handleMessage(Message msg) {
@@ -356,7 +342,6 @@
                         audioRouter.setSpeaker(inDockMode);
 
                         PhoneUtils.turnOnSpeaker(getApplicationContext(), inDockMode, true);
-                        updateInCallScreen();  // Has no effect if the InCallScreen isn't visible
                     }
                     break;
 
@@ -470,10 +455,6 @@
             // (like making outgoing calls.)
             callController = CallController.init(this, callLogger, callGatewayManager);
 
-            // ...and also the InCallUiState instance, used by the CallController to
-            // keep track of some "persistent state" of the in-call UI.
-            inCallUiState = InCallUiState.init(this);
-
             // Create the CallerInfoCache singleton, which remembers custom ring tone and
             // send-to-voicemail settings.
             //
@@ -692,32 +673,6 @@
     }
 
     /**
-     * Return an Intent that can be used to bring up the in-call screen.
-     *
-     * This intent can only be used from within the Phone app, since the
-     * InCallScreen is not exported from our AndroidManifest.
-     */
-    /* package */ static Intent createInCallIntent() {
-        Intent intent = new Intent(Intent.ACTION_MAIN, null);
-        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
-                | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
-                | Intent.FLAG_ACTIVITY_NO_USER_ACTION);
-        intent.setClassName("com.android.phone", getCallScreenClassName());
-        return intent;
-    }
-
-    /**
-     * Variation of createInCallIntent() that also specifies whether the
-     * DTMF dialpad should be initially visible when the InCallScreen
-     * comes up.
-     */
-    /* package */ static Intent createInCallIntent(boolean showDialpad) {
-        Intent intent = createInCallIntent();
-        intent.putExtra(InCallScreen.SHOW_DIALPAD_EXTRA, showDialpad);
-        return intent;
-    }
-
-    /**
      * Returns PendingIntent for hanging up ongoing phone call. This will typically be used from
      * Notification context.
      */
@@ -742,37 +697,6 @@
         return PendingIntent.getBroadcast(context, 0, intent, 0);
     }
 
-    private static String getCallScreenClassName() {
-        //InCallScreen.class.getName();
-        return "blah";
-    }
-
-    /**
-     * Starts the InCallScreen Activity.
-     */
-    /* package */ void displayCallScreen() {
-        if (VDBG) Log.d(LOG_TAG, "displayCallScreen()...");
-
-        // On non-voice-capable devices we shouldn't ever be trying to
-        // bring up the InCallScreen in the first place.
-        if (!sVoiceCapable) {
-            Log.w(LOG_TAG, "displayCallScreen() not allowed: non-voice-capable device",
-                  new Throwable("stack dump"));  // Include a stack trace since this warning
-                                                 // indicates a bug in our caller
-            return;
-        }
-
-        try {
-            //startActivity(createInCallIntent());
-        } catch (ActivityNotFoundException e) {
-            // It's possible that the in-call UI might not exist (like on
-            // non-voice-capable devices), so don't crash if someone
-            // accidentally tries to bring it up...
-            Log.w(LOG_TAG, "displayCallScreen: transition to InCallScreen failed: " + e);
-        }
-        Profiler.callScreenRequested();
-    }
-
     boolean isSimPinEnabled() {
         return mIsSimPinEnabled;
     }
@@ -785,59 +709,6 @@
         mCachedSimPin = pin;
     }
 
-    void setInCallScreenInstance(InCallScreen inCallScreen) {
-        mInCallScreen = inCallScreen;
-    }
-
-    /**
-     * @return true if the in-call UI is running as the foreground
-     * activity.  (In other words, from the perspective of the
-     * InCallScreen activity, return true between onResume() and
-     * onPause().)
-     *
-     * Note this method will return false if the screen is currently off,
-     * even if the InCallScreen *was* in the foreground just before the
-     * screen turned off.  (This is because the foreground activity is
-     * always "paused" while the screen is off.)
-     */
-    boolean isShowingCallScreen() {
-        if (mInCallScreen == null) return false;
-        return mInCallScreen.isForegroundActivity();
-    }
-
-    /**
-     * Dismisses the in-call UI.
-     *
-     * This also ensures that you won't be able to get back to the in-call
-     * UI via the BACK button (since this call removes the InCallScreen
-     * from the activity history.)
-     * For OTA Call, it call InCallScreen api to handle OTA Call End scenario
-     * to display OTA Call End screen.
-     */
-    /* package */ void dismissCallScreen() {
-        if (mInCallScreen != null) {
-            if ((TelephonyCapabilities.supportsOtasp(phone)) &&
-                    (mInCallScreen.isOtaCallInActiveState()
-                    || mInCallScreen.isOtaCallInEndState()
-                    || ((cdmaOtaScreenState != null)
-                    && (cdmaOtaScreenState.otaScreenState
-                            != CdmaOtaScreenState.OtaScreenState.OTA_STATUS_UNDEFINED)))) {
-                // TODO: During OTA Call, display should not become dark to
-                // allow user to see OTA UI update. Phone app needs to hold
-                // a SCREEN_DIM_WAKE_LOCK wake lock during the entire OTA call.
-                wakeUpScreen();
-                // If InCallScreen is not in foreground we resume it to show the OTA call end screen
-                // Fire off the InCallScreen intent
-                displayCallScreen();
-
-                mInCallScreen.handleOtaCallEnd();
-                return;
-            } else {
-                mInCallScreen.finish();
-            }
-        }
-    }
-
     /**
      * Handles OTASP-related events from the telephony layer.
      *
@@ -985,16 +856,6 @@
     /* package */ void updateWakeState() {
         PhoneConstants.State state = mCM.getState();
 
-        // True if the in-call UI is the foreground activity.
-        // (Note this will be false if the screen is currently off,
-        // since in that case *no* activity is in the foreground.)
-        boolean isShowingCallScreen = isShowingCallScreen();
-
-        // True if the InCallScreen's DTMF dialer is currently opened.
-        // (Note this does NOT imply whether or not the InCallScreen
-        // itself is visible.)
-        boolean isDialerOpened = (mInCallScreen != null) && mInCallScreen.isDialerOpened();
-
         // True if the speakerphone is in use.  (If so, we *always* use
         // the default timeout.  Since the user is obviously not holding
         // the phone up to his/her face, we don't need to worry about
@@ -1011,11 +872,6 @@
         // user to put the phone straight into a pocket, in which case the
         // timeout should probably still be short.)
 
-        if (DBG) Log.d(LOG_TAG, "updateWakeState: callscreen " + isShowingCallScreen
-                       + ", dialer " + isDialerOpened
-                       + ", speaker " + isSpeakerInUse + "...");
-
-        //
         // Decide whether to force the screen on or not.
         //
         // Force the screen to be on if the phone is ringing or dialing,
@@ -1027,13 +883,7 @@
         //
         boolean isRinging = (state == PhoneConstants.State.RINGING);
         boolean isDialing = (phone.getForegroundCall().getState() == Call.State.DIALING);
-        boolean showingDisconnectedConnection =
-                PhoneUtils.hasDisconnectedConnections(phone) && isShowingCallScreen;
-        boolean keepScreenOn = isRinging || isDialing || showingDisconnectedConnection;
-        if (DBG) Log.d(LOG_TAG, "updateWakeState: keepScreenOn = " + keepScreenOn
-                       + " (isRinging " + isRinging
-                       + ", isDialing " + isDialing
-                       + ", showingDisc " + showingDisconnectedConnection + ")");
+        boolean keepScreenOn = isRinging || isDialing;
         // keepScreenOn == true means we'll hold a full wake lock:
         requestWakeState(keepScreenOn ? WakeState.FULL : WakeState.SLEEP);
     }
@@ -1072,23 +922,11 @@
                     mUpdateLock.acquire();
                 }
             } else {
-                if (!isShowingCallScreen()) {
-                    if (!mUpdateLock.isHeld()) {
-                        mUpdateLock.release();
-                    }
+                if (!mUpdateLock.isHeld()) {
+                    mUpdateLock.release();
                 } else {
-                    // For this case InCallScreen will take care of the release() call.
                 }
             }
-
-            // While we are in call, the in-call screen should dismiss the keyguard.
-            // This allows the user to press Home to go directly home without going through
-            // an insecure lock screen.
-            // But we do not want to do this if there is no active call so we do not
-            // bypass the keyguard if the call is not answered or declined.
-            if (mInCallScreen != null) {
-                mInCallScreen.updateKeyguardPolicy(state == PhoneConstants.State.OFFHOOK);
-            }
         }
     }
 
@@ -1151,9 +989,6 @@
                 Log.e(LOG_TAG, Log.getStackTraceString(new Throwable()));
             }
         }
-        if (mInCallScreen != null) {
-            mInCallScreen.updateAfterRadioTechnologyChange();
-        }
 
         // Update registration for ICC status after radio technology change
         IccCard sim = phone.getIccCard();
@@ -1277,10 +1112,6 @@
                 boolean consumed = PhoneUtils.handleHeadsetHook(phone, event);
                 if (VDBG) Log.d(LOG_TAG, "==> handleHeadsetHook(): consumed = " + consumed);
                 if (consumed) {
-                    // If a headset is attached and the press is consumed, also update
-                    // any UI items (such as an InCallScreen mute button) that may need to
-                    // be updated if their state changed.
-                    updateInCallScreen();  // Has no effect if the InCallScreen isn't visible
                     abortBroadcast();
                 }
             } else {
@@ -1366,18 +1197,12 @@
 
     public boolean isOtaCallInActiveState() {
         boolean otaCallActive = false;
-        if (mInCallScreen != null) {
-            otaCallActive = mInCallScreen.isOtaCallInActiveState();
-        }
         if (VDBG) Log.d(LOG_TAG, "- isOtaCallInActiveState " + otaCallActive);
         return otaCallActive;
     }
 
     public boolean isOtaCallInEndState() {
         boolean otaCallEnded = false;
-        if (mInCallScreen != null) {
-            otaCallEnded = mInCallScreen.isOtaCallInEndState();
-        }
         if (VDBG) Log.d(LOG_TAG, "- isOtaCallInEndState " + otaCallEnded);
         return otaCallEnded;
     }
@@ -1385,8 +1210,7 @@
     // it is safe to call clearOtaState() even if the InCallScreen isn't active
     public void clearOtaState() {
         if (DBG) Log.d(LOG_TAG, "- clearOtaState ...");
-        if ((mInCallScreen != null)
-                && (otaUtils != null)) {
+        if (otaUtils != null) {
             otaUtils.cleanOtaScreen(true);
             if (DBG) Log.d(LOG_TAG, "  - clearOtaState clears OTA screen");
         }
@@ -1395,45 +1219,12 @@
     // it is safe to call dismissOtaDialogs() even if the InCallScreen isn't active
     public void dismissOtaDialogs() {
         if (DBG) Log.d(LOG_TAG, "- dismissOtaDialogs ...");
-        if ((mInCallScreen != null)
-                && (otaUtils != null)) {
+        if (otaUtils != null) {
             otaUtils.dismissAllOtaDialogs();
             if (DBG) Log.d(LOG_TAG, "  - dismissOtaDialogs clears OTA dialogs");
         }
     }
 
-    // it is safe to call clearInCallScreenMode() even if the InCallScreen isn't active
-    public void clearInCallScreenMode() {
-        if (DBG) Log.d(LOG_TAG, "- clearInCallScreenMode ...");
-        if (mInCallScreen != null) {
-            mInCallScreen.resetInCallScreenMode();
-        }
-    }
-
-    /**
-     * Force the in-call UI to refresh itself, if it's currently visible.
-     *
-     * This method can be used any time there's a state change anywhere in
-     * the phone app that needs to be reflected in the onscreen UI.
-     *
-     * Note that it's *not* necessary to manually refresh the in-call UI
-     * (via this method) for regular telephony state changes like
-     * DIALING -> ALERTING -> ACTIVE, since the InCallScreen already
-     * listens for those state changes itself.
-     *
-     * This method does *not* force the in-call UI to come up if it's not
-     * already visible.  To do that, use displayCallScreen().
-     */
-    /* package */ void updateInCallScreen() {
-        if (DBG) Log.d(LOG_TAG, "- updateInCallScreen()...");
-        if (mInCallScreen != null) {
-            // Post an updateScreen() request.  Note that the
-            // updateScreen() call will end up being a no-op if the
-            // InCallScreen isn't the foreground activity.
-            mInCallScreen.requestUpdateScreen();
-        }
-    }
-
     private void handleQueryTTYModeResponse(Message msg) {
         AsyncResult ar = (AsyncResult) msg.obj;
         if (ar.exception != null) {
@@ -1499,73 +1290,6 @@
      */
     private static final long CALL_ORIGIN_EXPIRATION_MILLIS = 30 * 1000;
 
-    public void setLatestActiveCallOrigin(String callOrigin) {
-        inCallUiState.latestActiveCallOrigin = callOrigin;
-        if (callOrigin != null) {
-            inCallUiState.latestActiveCallOriginTimeStamp = SystemClock.elapsedRealtime();
-        } else {
-            inCallUiState.latestActiveCallOriginTimeStamp = 0;
-        }
-    }
-
-    /**
-     * Reset call origin depending on its timestamp.
-     *
-     * See if the current call origin preserved by the app is fresh enough or not. If it is,
-     * previous call origin will be used as is. If not, call origin will be reset.
-     *
-     * This will be effective especially for 3rd party apps which want to bypass phone calls with
-     * their own telephone lines. In that case Phone app may finish the phone call once and make
-     * another for the external apps, which will drop call origin information in Intent.
-     * Even in that case we are sure the second phone call should be initiated just after the first
-     * phone call, so here we restore it from the previous information iff the second call is done
-     * fairly soon.
-     */
-    public void resetLatestActiveCallOrigin() {
-        final long callOriginTimestamp = inCallUiState.latestActiveCallOriginTimeStamp;
-        final long currentTimestamp = SystemClock.elapsedRealtime();
-        if (VDBG) {
-            Log.d(LOG_TAG, "currentTimeMillis: " + currentTimestamp
-                    + ", saved timestamp for call origin: " + callOriginTimestamp);
-        }
-        if (inCallUiState.latestActiveCallOriginTimeStamp > 0
-                && (currentTimestamp - callOriginTimestamp < CALL_ORIGIN_EXPIRATION_MILLIS)) {
-            if (VDBG) {
-                Log.d(LOG_TAG, "Resume previous call origin (" +
-                        inCallUiState.latestActiveCallOrigin + ")");
-            }
-            // Do nothing toward call origin itself but update the timestamp just in case.
-            inCallUiState.latestActiveCallOriginTimeStamp = currentTimestamp;
-        } else {
-            if (VDBG) Log.d(LOG_TAG, "Drop previous call origin and set the current one to null");
-            setLatestActiveCallOrigin(null);
-        }
-    }
-
-    /**
-     * @return Intent which will be used when in-call UI is shown and the phone call is hang up.
-     * By default CallLog screen will be introduced, but the destination may change depending on
-     * its latest call origin state.
-     */
-    public Intent createPhoneEndIntentUsingCallOrigin() {
-        if (TextUtils.equals(inCallUiState.latestActiveCallOrigin, ALLOWED_EXTRA_CALL_ORIGIN)) {
-            if (VDBG) Log.d(LOG_TAG, "Valid latestActiveCallOrigin("
-                    + inCallUiState.latestActiveCallOrigin + ") was found. "
-                    + "Go back to the previous screen.");
-            // Right now we just launch the Activity which launched in-call UI. Note that we're
-            // assuming the origin is from "com.android.dialer", which may be incorrect in the
-            // future.
-            final Intent intent = new Intent();
-            intent.setClassName(DEFAULT_CALL_ORIGIN_PACKAGE, inCallUiState.latestActiveCallOrigin);
-            return intent;
-        } else {
-            if (VDBG) Log.d(LOG_TAG, "Current latestActiveCallOrigin ("
-                    + inCallUiState.latestActiveCallOrigin + ") is not valid. "
-                    + "Just use CallLog as a default destination.");
-            return PhoneGlobals.createCallLogIntent();
-        }
-    }
-
     /** Service connection */
     private final ServiceConnection mBluetoothPhoneConnection = new ServiceConnection() {
 
diff --git a/src/com/android/phone/RespondViaSmsManager.java b/src/com/android/phone/RespondViaSmsManager.java
index ffce899..a842f34 100644
--- a/src/com/android/phone/RespondViaSmsManager.java
+++ b/src/com/android/phone/RespondViaSmsManager.java
@@ -80,39 +80,6 @@
     // Do not check in with VDBG = true, since that may write PII to the system log.
     private static final boolean VDBG = false;
 
-    private static final String PERMISSION_SEND_RESPOND_VIA_MESSAGE =
-            "android.permission.SEND_RESPOND_VIA_MESSAGE";
-
-    private int mIconSize = -1;
-
-    /**
-     * 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;
-
-    /**
-     * The popup showing the list of canned responses.
-     *
-     * This is an AlertDialog containing a ListView showing the possible
-     * choices.  This may be null if the InCallScreen hasn't ever called
-     * showRespondViaSmsPopup() yet, or if the popup was visible once but
-     * then got dismissed.
-     */
-    private Dialog mCannedResponsePopup;
-
-    /**
-     * The popup dialog allowing the user to chose which app handles respond-via-sms.
-     *
-     * An AlertDialog showing the Resolve-App UI resource from the framework wchih we then fill in
-     * with the appropriate data set. Can be null when not visible.
-     */
-    private Dialog mPackageSelectionPopup;
-
-    /** The array of "canned responses"; see loadCannedResponses(). */
-    private String[] mCannedResponses;
-
     /** SharedPreferences file name for our persistent settings. */
     private static final String SHARED_PREFERENCES_NAME = "respond_via_sms_prefs";
 
@@ -129,518 +96,6 @@
     private static final String KEY_INSTANT_TEXT_DEFAULT_COMPONENT = "instant_text_def_component";
 
     /**
-     * RespondViaSmsManager constructor.
-     */
-    public RespondViaSmsManager() {
-    }
-
-    public void setInCallScreenInstance(InCallScreen inCallScreen) {
-        mInCallScreen = inCallScreen;
-
-        if (mInCallScreen != null) {
-            // Prefetch shared preferences to make the first canned response lookup faster
-            // (and to prevent StrictMode violation)
-            mInCallScreen.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
-        }
-    }
-
-    /**
-     * Brings up the "Respond via SMS" popup for an incoming call.
-     *
-     * @param ringingCall the current incoming call
-     */
-    public void showRespondViaSmsPopup(Call ringingCall) {
-        if (DBG) log("showRespondViaSmsPopup()...");
-
-        // Very quick succession of clicks can cause this to run twice.
-        // Stop here to avoid creating more than one popup.
-        if (isShowingPopup()) {
-            if (DBG) log("Skip showing popup when one is already shown.");
-            return;
-        }
-
-        ListView lv = new ListView(mInCallScreen);
-
-        // Refresh the array of "canned responses".
-        mCannedResponses = loadCannedResponses();
-
-        // Build the list: start with the canned responses, but manually add
-        // the write-your-own option as the last choice.
-        int numPopupItems = mCannedResponses.length + 1;
-        String[] popupItems = Arrays.copyOf(mCannedResponses, numPopupItems);
-        popupItems[numPopupItems - 1] = mInCallScreen.getResources()
-                .getString(R.string.respond_via_sms_custom_message);
-
-        ArrayAdapter<String> adapter =
-                new ArrayAdapter<String>(mInCallScreen,
-                                         android.R.layout.simple_list_item_1,
-                                         android.R.id.text1,
-                                         popupItems);
-        lv.setAdapter(adapter);
-
-        // Create a RespondViaSmsItemClickListener instance to handle item
-        // clicks from the popup.
-        // (Note we create a fresh instance for each incoming call, and
-        // stash away the call's phone number, since we can't necessarily
-        // assume this call will still be ringing when the user finally
-        // chooses a response.)
-
-        Connection c = ringingCall.getLatestConnection();
-        if (VDBG) log("- connection: " + c);
-
-        if (c == null) {
-            // Uh oh -- the "ringingCall" doesn't have any connections any more.
-            // (In other words, it's no longer ringing.)  This is rare, but can
-            // happen if the caller hangs up right at the exact moment the user
-            // selects the "Respond via SMS" option.
-            // There's nothing to do here (since the incoming call is gone),
-            // so just bail out.
-            Log.i(TAG, "showRespondViaSmsPopup: null connection; bailing out...");
-            return;
-        }
-
-        // TODO: at this point we probably should re-check c.getAddress()
-        // and c.getNumberPresentation() for validity.  (i.e. recheck the
-        // same cases in InCallTouchUi.showIncomingCallWidget() where we
-        // should have disallowed the "respond via SMS" feature in the
-        // first place.)
-
-        String phoneNumber = c.getAddress();
-        if (VDBG) log("- phoneNumber: " + phoneNumber);
-        lv.setOnItemClickListener(new RespondViaSmsItemClickListener(phoneNumber));
-
-        AlertDialog.Builder builder = new AlertDialog.Builder(mInCallScreen)
-                .setCancelable(true)
-                .setOnCancelListener(new RespondViaSmsCancelListener())
-                .setView(lv);
-        mCannedResponsePopup = builder.create();
-        mCannedResponsePopup.show();
-    }
-
-    /**
-     * Dismiss currently visible popups.
-     *
-     * This is safe to call even if the popup is already dismissed, and
-     * even if you never called showRespondViaSmsPopup() in the first
-     * place.
-     */
-    public void dismissPopup() {
-        if (mCannedResponsePopup != null) {
-            mCannedResponsePopup.dismiss();  // safe even if already dismissed
-            mCannedResponsePopup = null;
-        }
-        if (mPackageSelectionPopup != null) {
-            mPackageSelectionPopup.dismiss();
-            mPackageSelectionPopup = null;
-        }
-    }
-
-    public boolean isShowingPopup() {
-        return (mCannedResponsePopup != null && mCannedResponsePopup.isShowing())
-                || (mPackageSelectionPopup != null && mPackageSelectionPopup.isShowing());
-    }
-
-    /**
-     * OnItemClickListener for the "Respond via SMS" popup.
-     */
-    public class RespondViaSmsItemClickListener implements AdapterView.OnItemClickListener {
-        // Phone number to send the SMS to.
-        private String mPhoneNumber;
-
-        public RespondViaSmsItemClickListener(String phoneNumber) {
-            mPhoneNumber = phoneNumber;
-        }
-
-        /**
-         * Handles the user selecting an item from the popup.
-         */
-        @Override
-        public void onItemClick(AdapterView<?> parent,  // The ListView
-                                View view,  // The TextView that was clicked
-                                int position,
-                                long id) {
-            if (DBG) log("RespondViaSmsItemClickListener.onItemClick(" + position + ")...");
-            String message = (String) parent.getItemAtPosition(position);
-            if (VDBG) log("- message: '" + message + "'");
-
-            // The "Custom" choice is a special case.
-            // (For now, it's guaranteed to be the last item.)
-            if (position == (parent.getCount() - 1)) {
-                // Take the user to the standard SMS compose UI.
-                launchSmsCompose(mPhoneNumber);
-                onPostMessageSent();
-            } else {
-                sendTextToDefaultActivity(mPhoneNumber, message);
-            }
-        }
-    }
-
-
-    /**
-     * OnCancelListener for the "Respond via SMS" popup.
-     */
-    public class RespondViaSmsCancelListener implements DialogInterface.OnCancelListener {
-        public RespondViaSmsCancelListener() {
-        }
-
-        /**
-         * Handles the user canceling the popup, either by touching
-         * outside the popup or by pressing Back.
-         */
-        @Override
-        public void onCancel(DialogInterface dialog) {
-            if (DBG) log("RespondViaSmsCancelListener.onCancel()...");
-
-            dismissPopup();
-
-            final PhoneConstants.State state = PhoneGlobals.getInstance().mCM.getState();
-            if (state == PhoneConstants.State.IDLE) {
-                // This means the incoming call is already hung up when the user chooses not to
-                // use "Respond via SMS" feature. Let's just exit the whole in-call screen.
-                PhoneGlobals.getInstance().dismissCallScreen();
-            } else {
-
-                // If the user cancels the popup, this presumably means that
-                // they didn't actually mean to bring up the "Respond via SMS"
-                // UI in the first place (and instead want to go back to the
-                // state where they can either answer or reject the call.)
-                // So restart the ringer and bring back the regular incoming
-                // call UI.
-
-                // This will have no effect if the incoming call isn't still ringing.
-                PhoneGlobals.getInstance().notifier.restartRinger();
-
-                // We hid the GlowPadView widget way back in
-                // InCallTouchUi.onTrigger(), when the user first selected
-                // the "SMS" trigger.
-                //
-                // To bring it back, just force the entire InCallScreen to
-                // update itself based on the current telephony state.
-                // (Assuming the incoming call is still ringing, this will
-                // cause the incoming call widget to reappear.)
-                mInCallScreen.requestUpdateScreen();
-            }
-        }
-    }
-
-    private void sendTextToDefaultActivity(String phoneNumber, String message) {
-        if (DBG) log("sendTextToDefaultActivity()...");
-        final PackageManager packageManager = mInCallScreen.getPackageManager();
-
-        // Check to see if the default component to receive this intent is already saved
-        // and check to see if it still has the corrent permissions.
-        final SharedPreferences prefs = mInCallScreen.getSharedPreferences(SHARED_PREFERENCES_NAME,
-                Context.MODE_PRIVATE);
-        final String flattenedName = prefs.getString(KEY_INSTANT_TEXT_DEFAULT_COMPONENT, null);
-        if (flattenedName != null) {
-            if (DBG) log("Default package was found." + flattenedName);
-
-            final ComponentName componentName = ComponentName.unflattenFromString(flattenedName);
-            ServiceInfo serviceInfo = null;
-            try {
-                serviceInfo = packageManager.getServiceInfo(componentName, 0);
-            } catch (PackageManager.NameNotFoundException e) {
-                Log.w(TAG, "Default service does not have permission.");
-            }
-
-            if (serviceInfo != null &&
-                    PERMISSION_SEND_RESPOND_VIA_MESSAGE.equals(serviceInfo.permission)) {
-                sendTextAndExit(phoneNumber, message, componentName, false);
-                return;
-            } else {
-                SharedPreferences.Editor editor = prefs.edit();
-                editor.remove(KEY_INSTANT_TEXT_DEFAULT_COMPONENT);
-                editor.apply();
-            }
-        }
-
-        final ArrayList<ComponentName> componentsWithPermission =
-            getPackagesWithInstantTextPermission();
-
-        final int size = componentsWithPermission.size();
-        if (size == 0) {
-            Log.e(TAG, "No appropriate package receiving the Intent. Don't send anything");
-            onPostMessageSent();
-        } else if (size == 1) {
-            sendTextAndExit(phoneNumber, message, componentsWithPermission.get(0), false);
-        } else {
-            showPackageSelectionDialog(phoneNumber, message, componentsWithPermission);
-        }
-    }
-
-    /**
-     * Queries the System to determine what packages contain services that can handle the instant
-     * text response Action AND have permissions to do so.
-     */
-    private ArrayList<ComponentName> getPackagesWithInstantTextPermission() {
-        PackageManager packageManager = mInCallScreen.getPackageManager();
-
-        ArrayList<ComponentName> componentsWithPermission = Lists.newArrayList();
-
-        // Get list of all services set up to handle the Instant Text intent.
-        final List<ResolveInfo> infos = packageManager.queryIntentServices(
-                getInstantTextIntent("", null, null), 0);
-
-        // Collect all the valid services
-        for (ResolveInfo resolveInfo : infos) {
-            final ServiceInfo serviceInfo = resolveInfo.serviceInfo;
-            if (serviceInfo == null) {
-                Log.w(TAG, "Ignore package without proper service.");
-                continue;
-            }
-
-            // A Service is valid only if it requires the permission
-            // PERMISSION_SEND_RESPOND_VIA_MESSAGE
-            if (PERMISSION_SEND_RESPOND_VIA_MESSAGE.equals(serviceInfo.permission)) {
-                componentsWithPermission.add(new ComponentName(serviceInfo.packageName,
-                    serviceInfo.name));
-            }
-        }
-
-        return componentsWithPermission;
-    }
-
-    private void showPackageSelectionDialog(String phoneNumber, String message,
-            List<ComponentName> components) {
-        if (DBG) log("showPackageSelectionDialog()...");
-
-        dismissPopup();
-
-        BaseAdapter adapter = new PackageSelectionAdapter(mInCallScreen, components);
-
-        PackageClickListener clickListener =
-                new PackageClickListener(phoneNumber, message, components);
-
-        final CharSequence title = mInCallScreen.getResources().getText(
-                com.android.internal.R.string.whichApplication);
-        LayoutInflater inflater =
-                (LayoutInflater) mInCallScreen.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-
-        final View view = inflater.inflate(com.android.internal.R.layout.always_use_checkbox, null);
-        final CheckBox alwaysUse = (CheckBox) view.findViewById(
-                com.android.internal.R.id.alwaysUse);
-        alwaysUse.setText(com.android.internal.R.string.alwaysUse);
-        alwaysUse.setOnCheckedChangeListener(clickListener);
-
-        AlertDialog.Builder builder = new AlertDialog.Builder(mInCallScreen)
-                .setTitle(title)
-                .setCancelable(true)
-                .setOnCancelListener(new RespondViaSmsCancelListener())
-                .setAdapter(adapter, clickListener)
-                .setView(view);
-        mPackageSelectionPopup = builder.create();
-        mPackageSelectionPopup.show();
-    }
-
-    private class PackageSelectionAdapter extends BaseAdapter {
-        private final LayoutInflater mInflater;
-        private final List<ComponentName> mComponents;
-
-        public PackageSelectionAdapter(Context context, List<ComponentName> components) {
-            mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-            mComponents = components;
-        }
-
-        @Override
-        public int getCount() {
-            return mComponents.size();
-        }
-
-        @Override
-        public Object getItem(int position) {
-            return mComponents.get(position);
-        }
-
-        @Override
-        public long getItemId(int position) {
-            return position;
-        }
-
-        @Override
-        public View getView(int position, View convertView, ViewGroup parent) {
-            if (convertView == null) {
-                convertView = mInflater.inflate(
-                        com.android.internal.R.layout.resolve_list_item, parent, false);
-            }
-
-            final ComponentName component = mComponents.get(position);
-            final String packageName = component.getPackageName();
-            final PackageManager packageManager = mInCallScreen.getPackageManager();
-
-            // Set the application label
-            final TextView text = (TextView) convertView.findViewById(
-                    com.android.internal.R.id.text1);
-            final TextView text2 = (TextView) convertView.findViewById(
-                    com.android.internal.R.id.text2);
-
-            // Reset any previous values
-            text.setText("");
-            text2.setVisibility(View.GONE);
-            try {
-                final ApplicationInfo appInfo = packageManager.getApplicationInfo(packageName, 0);
-                final CharSequence label = packageManager.getApplicationLabel(appInfo);
-                if (label != null) {
-                    text.setText(label);
-                }
-            } catch (PackageManager.NameNotFoundException e) {
-                Log.w(TAG, "Failed to load app label because package was not found.");
-            }
-
-            // Set the application icon
-            final ImageView icon = (ImageView) convertView.findViewById(android.R.id.icon);
-            Drawable drawable = null;
-            try {
-                drawable = mInCallScreen.getPackageManager().getApplicationIcon(packageName);
-            } catch (PackageManager.NameNotFoundException e) {
-                Log.w(TAG, "Failed to load icon because it wasn't found.");
-            }
-            if (drawable == null) {
-                drawable = mInCallScreen.getPackageManager().getDefaultActivityIcon();
-            }
-            icon.setImageDrawable(drawable);
-            ViewGroup.LayoutParams lp = (ViewGroup.LayoutParams) icon.getLayoutParams();
-            lp.width = lp.height = getIconSize();
-
-            return convertView;
-        }
-
-    }
-
-    private class PackageClickListener implements DialogInterface.OnClickListener,
-            CompoundButton.OnCheckedChangeListener {
-        /** Phone number to send the SMS to. */
-        final private String mPhoneNumber;
-        final private String mMessage;
-        final private List<ComponentName> mComponents;
-        private boolean mMakeDefault = false;
-
-        public PackageClickListener(String phoneNumber, String message,
-                List<ComponentName> components) {
-            mPhoneNumber = phoneNumber;
-            mMessage = message;
-            mComponents = components;
-        }
-
-        @Override
-        public void onClick(DialogInterface dialog, int which) {
-            ComponentName component = mComponents.get(which);
-            sendTextAndExit(mPhoneNumber, mMessage, component, mMakeDefault);
-        }
-
-        @Override
-        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
-            Log.i(TAG, "mMakeDefault : " + isChecked);
-            mMakeDefault = isChecked;
-        }
-    }
-
-    private void sendTextAndExit(String phoneNumber, String message, ComponentName component,
-            boolean setDefaultComponent) {
-        // Send the selected message immediately with no user interaction.
-        sendText(phoneNumber, message, component);
-
-        if (setDefaultComponent) {
-            final SharedPreferences prefs = mInCallScreen.getSharedPreferences(
-                    SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
-            prefs.edit()
-                    .putString(KEY_INSTANT_TEXT_DEFAULT_COMPONENT, component.flattenToString())
-                    .apply();
-        }
-
-        // ...and show a brief confirmation to the user (since
-        // otherwise it's hard to be sure that anything actually
-        // happened.)
-        final Resources res = mInCallScreen.getResources();
-        final String formatString = res.getString(R.string.respond_via_sms_confirmation_format);
-        final String confirmationMsg = String.format(formatString, phoneNumber);
-        Toast.makeText(mInCallScreen,
-                       confirmationMsg,
-                       Toast.LENGTH_LONG).show();
-
-        // TODO: If the device is locked, this toast won't actually ever
-        // be visible!  (That's because we're about to dismiss the call
-        // screen, which means that the device will return to the
-        // keyguard.  But toasts aren't visible on top of the keyguard.)
-        // Possible fixes:
-        // (1) Is it possible to allow a specific Toast to be visible
-        //     on top of the keyguard?
-        // (2) Artifically delay the dismissCallScreen() call by 3
-        //     seconds to allow the toast to be seen?
-        // (3) Don't use a toast at all; instead use a transient state
-        //     of the InCallScreen (perhaps via the InCallUiState
-        //     progressIndication feature), and have that state be
-        //     visible for 3 seconds before calling dismissCallScreen().
-
-        onPostMessageSent();
-    }
-
-    /**
-     * Sends a text message without any interaction from the user.
-     */
-    private void sendText(String phoneNumber, String message, ComponentName component) {
-        if (VDBG) log("sendText: number "
-                      + phoneNumber + ", message '" + message + "'");
-
-        mInCallScreen.startService(getInstantTextIntent(phoneNumber, message, component));
-    }
-
-    private void onPostMessageSent() {
-        // At this point the user is done dealing with the incoming call, so
-        // there's no reason to keep it around.  (It's also confusing for
-        // the "incoming call" icon in the status bar to still be visible.)
-        // So reject the call now.
-        mInCallScreen.hangupRingingCall();
-
-        dismissPopup();
-
-        final PhoneConstants.State state = PhoneGlobals.getInstance().mCM.getState();
-        if (state == PhoneConstants.State.IDLE) {
-            // There's no other phone call to interact. Exit the entire in-call screen.
-            PhoneGlobals.getInstance().dismissCallScreen();
-        } else {
-            // The user is still in the middle of other phone calls, so we should keep the
-            // in-call screen.
-            mInCallScreen.requestUpdateScreen();
-        }
-    }
-
-    /**
-     * Brings up the standard SMS compose UI.
-     */
-    private void launchSmsCompose(String phoneNumber) {
-        if (VDBG) log("launchSmsCompose: number " + phoneNumber);
-
-        Intent intent = getInstantTextIntent(phoneNumber, null, null);
-
-        if (VDBG) log("- Launching SMS compose UI: " + intent);
-        mInCallScreen.startService(intent);
-    }
-
-    /**
-     * @param phoneNumber Must not be null.
-     * @param message Can be null. If message is null, the returned Intent will be configured to
-     * launch the SMS compose UI. If non-null, the returned Intent will cause the specified message
-     * to be sent with no interaction from the user.
-     * @param component The component that should handle this intent.
-     * @return Service Intent for the instant response.
-     */
-    private static Intent getInstantTextIntent(String phoneNumber, String message,
-            ComponentName component) {
-        final Uri uri = Uri.fromParts(Constants.SCHEME_SMSTO, phoneNumber, null);
-        Intent intent = new Intent(TelephonyManager.ACTION_RESPOND_VIA_MESSAGE, uri);
-        if (message != null) {
-            intent.putExtra(Intent.EXTRA_TEXT, message);
-        } else {
-            intent.putExtra("exit_on_sent", true);
-            intent.putExtra("showUI", true);
-        }
-        if (component != null) {
-            intent.setComponent(component);
-        }
-        return intent;
-    }
-
-    /**
      * Settings activity under "Call settings" to let you manage the
      * canned responses; see respond_via_sms_settings.xml
      */
@@ -737,51 +192,7 @@
         }
     }
 
-    /**
-     * Read the (customizable) canned responses from SharedPreferences,
-     * or from defaults if the user has never actually brought up
-     * the Settings UI.
-     *
-     * This method does disk I/O (reading the SharedPreferences file)
-     * so don't call it from the main thread.
-     *
-     * @see RespondViaSmsManager.Settings
-     */
-    private String[] loadCannedResponses() {
-        if (DBG) log("loadCannedResponses()...");
-
-        SharedPreferences prefs = mInCallScreen.getSharedPreferences(SHARED_PREFERENCES_NAME,
-                Context.MODE_PRIVATE);
-        final Resources res = mInCallScreen.getResources();
-
-        String[] responses = new String[NUM_CANNED_RESPONSES];
-
-        // Note the default values here must agree with the corresponding
-        // android:defaultValue attributes in respond_via_sms_settings.xml.
-
-        responses[0] = prefs.getString(KEY_CANNED_RESPONSE_PREF_1,
-                                       res.getString(R.string.respond_via_sms_canned_response_1));
-        responses[1] = prefs.getString(KEY_CANNED_RESPONSE_PREF_2,
-                                       res.getString(R.string.respond_via_sms_canned_response_2));
-        responses[2] = prefs.getString(KEY_CANNED_RESPONSE_PREF_3,
-                                       res.getString(R.string.respond_via_sms_canned_response_3));
-        responses[3] = prefs.getString(KEY_CANNED_RESPONSE_PREF_4,
-                                       res.getString(R.string.respond_via_sms_canned_response_4));
-        return responses;
-    }
-
-    private int getIconSize() {
-      if (mIconSize < 0) {
-          final ActivityManager am =
-              (ActivityManager) mInCallScreen.getSystemService(Context.ACTIVITY_SERVICE);
-          mIconSize = am.getLauncherLargeIconSize();
-      }
-
-      return mIconSize;
-    }
-
-
     private static void log(String msg) {
-        Log.d(TAG, msg);
+        Log.e(TAG, msg);
     }
 }
