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);
     }
 }
