diff --git a/common/src/com/android/services/telephony/common/Call.java b/common/src/com/android/services/telephony/common/Call.java
index 0aaf12d..f5cc904 100644
--- a/common/src/com/android/services/telephony/common/Call.java
+++ b/common/src/com/android/services/telephony/common/Call.java
@@ -48,8 +48,9 @@
         public static final int CALL_WAITING = 4;   /* Incoming call while another is active */
         public static final int DIALING = 5;        /* An outgoing call during dial phase */
         public static final int ONHOLD = 6;         /* An active phone call placed on hold */
-        public static final int DISCONNECTED = 7;   /* State after a call disconnects */
-        public static final int CONFERENCED = 8;    /* Call part of a conference call */
+        public static final int DISCONNECTING = 7;  /* A call is being ended. */
+        public static final int DISCONNECTED = 8;   /* State after a call disconnects */
+        public static final int CONFERENCED = 9;    /* Call part of a conference call */
 
         public static boolean isConnected(int state) {
             switch(state) {
@@ -142,6 +143,7 @@
             .put(Call.State.INCOMING, "INCOMING")
             .put(Call.State.ONHOLD, "ONHOLD")
             .put(Call.State.INVALID, "INVALID")
+            .put(Call.State.DISCONNECTING, "DISCONNECTING")
             .put(Call.State.DISCONNECTED, "DISCONNECTED")
             .put(Call.State.CONFERENCED, "CONFERENCED")
             .build();
diff --git a/common/src/com/android/services/telephony/common/ICallCommandService.aidl b/common/src/com/android/services/telephony/common/ICallCommandService.aidl
index 660d8aa..7f3afe6 100644
--- a/common/src/com/android/services/telephony/common/ICallCommandService.aidl
+++ b/common/src/com/android/services/telephony/common/ICallCommandService.aidl
@@ -96,4 +96,12 @@
     void postDialCancel(int callId);
 
     void postDialWaitContinue(int callId);
+
+    /**
+     * Enables or disables navigation using the system bar, and also prevents the
+     * notification shade from being dragged down.
+     * Hides or shows the home, recent and back buttons in the navigation bar if the
+     * device has soft navigation buttons.
+     */
+    void setSystemBarNavigationEnabled(boolean enable);
 }
diff --git a/proguard.flags b/proguard.flags
index c5f4c72..c4af490 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -1,6 +1 @@
-# Keep names that are used only by animation framework.
--keepclasseswithmembers class com.android.phone.AnimationUtils$CrossFadeDrawable {
-  *** setCrossFadeAlpha(...);
-}
-
--verbose
\ No newline at end of file
+-verbose
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 5d257f5..003f4d0 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -103,7 +103,7 @@
     <string name="reverting_settings" msgid="4752151682666912828">"מאחזר הגדרות הקודמות…"</string>
     <string name="response_error" msgid="6674110501330139405">"תגובה לא צפויה מהרשת."</string>
     <string name="exception_error" msgid="7027667130619518211">"שגיאת רשת או שגיאה של כרטיס SIM."</string>
-    <string name="fdn_check_failure" msgid="18200614306525434">"הגדרת מספרי החיוג הקבועים של יישום הטלפון שלך מופעלת. כתוצאה מכך, חלק מהתכונות הקשורות לשיחות לא פועלות."</string>
+    <string name="fdn_check_failure" msgid="18200614306525434">"הגדרת מספרי החיוג הקבועים של אפליקציית הטלפון שלך מופעלת. כתוצאה מכך, חלק מהתכונות הקשורות לשיחות לא פועלות."</string>
     <string name="radio_off_error" msgid="2304459933248513376">"הפעל את הרדיו לפני ההצגה של הגדרות אלה."</string>
     <string name="close_dialog" msgid="2365884406356986917">"אישור"</string>
     <string name="enable" msgid="1059008390636773574">"הפעל"</string>
@@ -477,8 +477,8 @@
     <item quantity="other" msgid="3122217344579273583">"אין חיבור נתונים במשך <xliff:g id="COUNT">%s</xliff:g> דקות"</item>
   </plurals>
   <plurals name="alert_dialog_exit_ecm">
-    <item quantity="one" msgid="8060210887681426682">"הטלפון יהיה במצב התקשרות חזרה בחירום למשך דקה <xliff:g id="COUNT">%s</xliff:g>. במצב זה לא ניתן להשתמש ביישומים המשתמשים בחיבור נתונים. האם אתה רוצה לצאת כעת?"</item>
-    <item quantity="other" msgid="8617116564023933114">"הטלפון יהיה במצב התקשרות חזרה בחירום למשך <xliff:g id="COUNT">%s</xliff:g> דקות. במצב זה לא ניתן להשתמש ביישומים המשתמשים בחיבור נתונים. האם אתה רוצה לצאת כעת?"</item>
+    <item quantity="one" msgid="8060210887681426682">"הטלפון יהיה במצב התקשרות חזרה בחירום למשך דקה <xliff:g id="COUNT">%s</xliff:g>. במצב זה לא ניתן להשתמש באפליקציות המשתמשות בחיבור נתונים. האם אתה רוצה לצאת כעת?"</item>
+    <item quantity="other" msgid="8617116564023933114">"הטלפון יהיה במצב התקשרות חזרה בחירום למשך <xliff:g id="COUNT">%s</xliff:g> דקות. במצב זה לא ניתן להשתמש באפליקציות המשתמשים בחיבור נתונים. האם אתה רוצה לצאת כעת?"</item>
   </plurals>
   <plurals name="alert_dialog_not_avaialble_in_ecm">
     <item quantity="one" msgid="2585506997024726599">"הפעולה שנבחרה אינה זמינה במצב התקשרות חזרה בחירום. הטלפון יהיה במצב זה במשך <xliff:g id="COUNT">%s</xliff:g> דקות. האם אתה רוצה לצאת כעת?"</item>
@@ -539,7 +539,7 @@
     <string name="registration_status_failed_try_later" msgid="5214474354451220581">"הרשמת החשבון נכשלה: (<xliff:g id="REGISTRATION_ERROR_MESSAGE">%s</xliff:g>); יתבצע ניסיון חוזר מאוחר יותר"</string>
     <string name="registration_status_invalid_credentials" msgid="4908446367559341757">"רישום החשבון נכשל: שם המשתמש או הסיסמה שגויים."</string>
     <string name="registration_status_server_unreachable" msgid="5733421582468991276">"רישום החשבון נכשל: בדוק את שם השרת."</string>
-    <string name="third_party_account_summary" msgid="2532526738862533028">"היישום <xliff:g id="ACCOUNT_OWNER">%s</xliff:g> משתמש כרגע בחשבון זה."</string>
+    <string name="third_party_account_summary" msgid="2532526738862533028">"האפליקציה <xliff:g id="ACCOUNT_OWNER">%s</xliff:g> משתמש כרגע בחשבון זה."</string>
     <string name="sip_edit_title" msgid="489288416435014385">"פרטי חשבון SIP"</string>
     <string name="sip_edit_new_title" msgid="3659149255856520385">"פרטי חשבון SIP"</string>
     <string name="domain_address_title" msgid="9071787581316160480">"שרת"</string>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 3ea28af..d77be93 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -117,7 +117,7 @@
     <string name="vm_changed" msgid="380744030726254139">"Промењен је број говорне поште."</string>
     <string name="vm_change_failed" msgid="3352934863246208918">"Није могуће променити број говорне поште.\nКонтактирајте мобилног оператера ако се овај проблем настави."</string>
     <string name="fw_change_failed" msgid="5298103228470214665">"Није могуће променити број за преусмеравање.\nКонтактирајте мобилног оператера ако се овај проблем настави."</string>
-    <string name="fw_get_in_vm_failed" msgid="8862896836093833973">"Није било могуће преузети и сачувати тренутна подешавања броја за прослеђивање.\nЖелите ли да ипак пређете на новог добављача?"</string>
+    <string name="fw_get_in_vm_failed" msgid="8862896836093833973">"Није могуће преузети и сачувати тренутна подешавања броја за прослеђивање.\nЖелите ли да ипак пређете на новог добављача?"</string>
     <string name="no_change" msgid="3186040086622435212">"Нису начињене промене."</string>
     <string name="sum_voicemail_choose_provider" msgid="59911196126278922">"Одаберите услугу говорне поште"</string>
     <string name="voicemail_default" msgid="5902099213882352338">" Мој мобилни оператер"</string>
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/BluetoothManager.java b/src/com/android/phone/BluetoothManager.java
index ffce465..443c950 100644
--- a/src/com/android/phone/BluetoothManager.java
+++ b/src/com/android/phone/BluetoothManager.java
@@ -32,6 +32,7 @@
 import android.util.Log;
 
 import com.android.internal.telephony.CallManager;
+import com.android.internal.telephony.Connection;
 import com.android.services.telephony.common.Call;
 
 import java.util.List;
@@ -416,7 +417,7 @@
     }
 
     @Override
-    public void onPostDialWait(int callId, String chars) {
+    public void onPostDialAction(Connection.PostDialState state, int callId, String chars, char c) {
         // no-op
     }
 
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/CallCommandService.java b/src/com/android/phone/CallCommandService.java
index b38517e..212ce45 100644
--- a/src/com/android/phone/CallCommandService.java
+++ b/src/com/android/phone/CallCommandService.java
@@ -25,6 +25,7 @@
 import com.android.internal.telephony.CallManager;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.phone.CallModeler.CallResult;
+import com.android.phone.NotificationMgr.StatusBarHelper;
 import com.android.services.telephony.common.AudioMode;
 import com.android.services.telephony.common.Call;
 import com.android.services.telephony.common.ICallCommandService;
@@ -252,4 +253,17 @@
             result.getConnection().proceedAfterWaitChar();
         }
     }
+
+    @Override
+    public void setSystemBarNavigationEnabled(boolean enable) {
+        try {
+            final StatusBarHelper statusBarHelper = PhoneGlobals.getInstance().notificationMgr.
+                    statusBarHelper;
+            statusBarHelper.enableSystemBarNavigation(enable);
+            statusBarHelper.enableExpandedView(enable);
+        } catch (Exception e) {
+            Log.e(TAG, "Error enabling or disabling system bar navigation", e);
+        }
+    }
+
 }
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/CallHandlerServiceProxy.java b/src/com/android/phone/CallHandlerServiceProxy.java
index c6d4346..1b05214 100644
--- a/src/com/android/phone/CallHandlerServiceProxy.java
+++ b/src/com/android/phone/CallHandlerServiceProxy.java
@@ -31,9 +31,13 @@
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.SystemProperties;
+import android.text.TextUtils;
 import android.util.Log;
 
+import com.android.internal.telephony.Connection;
+import com.android.internal.telephony.Connection.PostDialState;
 import com.android.phone.AudioRouter.AudioModeListener;
+import com.android.phone.NotificationMgr.StatusBarHelper;
 import com.android.services.telephony.common.AudioMode;
 import com.android.services.telephony.common.Call;
 import com.android.services.telephony.common.ICallHandlerService;
@@ -153,7 +157,7 @@
             Log.d(TAG, "onIncoming: " + call);
         }
         try {
-            // TODO(klp): check RespondViaSmsManager.allowRespondViaSmsForCall()
+            // TODO: check RespondViaSmsManager.allowRespondViaSmsForCall()
             // must refactor call method to accept proper call object.
             synchronized (mServiceAndQueueLock) {
                 if (mCallHandlerServiceGuarded != null) {
@@ -206,7 +210,9 @@
 
 
     @Override
-    public void onPostDialWait(int callId, String remainingChars) {
+    public void onPostDialAction(Connection.PostDialState state, int callId, String remainingChars,
+            char currentChar) {
+        if (state != PostDialState.WAIT) return;
         try {
             synchronized (mServiceAndQueueLock) {
                 if (mCallHandlerServiceGuarded == null) {
@@ -404,6 +410,12 @@
 
     private void unbind() {
         synchronized (mServiceAndQueueLock) {
+            // On unbind, reenable the notification shade and navigation bar just in case the
+            // in-call UI crashed on an incoming call.
+            final StatusBarHelper statusBarHelper = PhoneGlobals.getInstance().notificationMgr.
+                    statusBarHelper;
+            statusBarHelper.enableSystemBarNavigation(true);
+            statusBarHelper.enableExpandedView(true);
             if (mCallHandlerServiceGuarded != null) {
                 Log.d(TAG, "Unbinding service.");
                 mCallHandlerServiceGuarded = null;
diff --git a/src/com/android/phone/CallModeler.java b/src/com/android/phone/CallModeler.java
index 75da0be..02f0809 100644
--- a/src/com/android/phone/CallModeler.java
+++ b/src/com/android/phone/CallModeler.java
@@ -224,7 +224,8 @@
                     state == Call.State.CONFERENCED ||
                     state == Call.State.DIALING ||
                     state == Call.State.INCOMING ||
-                    state == Call.State.ONHOLD) {
+                    state == Call.State.ONHOLD ||
+                    state == Call.State.DISCONNECTING) {
                 return true;
             }
         }
@@ -265,20 +266,23 @@
             final Connection.PostDialState state = (Connection.PostDialState) r.userObj;
 
             switch (state) {
-                // TODO(klp): add other post dial related functions
                 case WAIT:
                     final Call call = getCallFromMap(mCallMap, c, false);
                     if (call == null) {
                         Log.i(TAG, "Call no longer exists. Skipping onPostDialWait().");
                     } else {
                         for (Listener mListener : mListeners) {
-                            mListener.onPostDialWait(call.getCallId(),
-                                    c.getRemainingPostDialString());
+                            mListener.onPostDialAction(state, call.getCallId(),
+                                    c.getRemainingPostDialString(), ch);
                         }
                     }
                     break;
-
                 default:
+                    // This is primarily to cause the DTMFTonePlayer to play local tones.
+                    // Other listeners simply perform no-ops.
+                    for (Listener mListener : mListeners) {
+                        mListener.onPostDialAction(state, 0, "", ch);
+                    }
                     break;
             }
         }
@@ -353,12 +357,16 @@
         for (com.android.internal.telephony.Call telephonyCall : telephonyCalls) {
 
             for (Connection connection : telephonyCall.getConnections()) {
-                if (DBG) Log.d(TAG, "connection: " + connection);
+                if (DBG) Log.d(TAG, "connection: " + connection + connection.getState());
 
                 // We only send updates for live calls which are not incoming (ringing).
                 // Disconnected and incoming calls are handled by onDisconnect and
                 // onNewRingingConnection.
-                boolean shouldUpdate = connection.getState().isAlive() &&
+                boolean shouldUpdate =
+                        connection.getState() !=
+                                com.android.internal.telephony.Call.State.DISCONNECTED &&
+                        connection.getState() !=
+                                com.android.internal.telephony.Call.State.IDLE &&
                         !connection.getState().isRinging();
 
                 // New connections return a Call with INVALID state, which does not translate to
@@ -705,8 +713,10 @@
             case HOLDING:
                 retval = State.ONHOLD;
                 break;
-            case DISCONNECTED:
             case DISCONNECTING:
+                retval = State.DISCONNECTING;
+                break;
+            case DISCONNECTED:
                 retval = State.DISCONNECTED;
             default:
         }
@@ -840,7 +850,8 @@
         void onDisconnect(Call call);
         void onIncoming(Call call);
         void onUpdate(List<Call> calls);
-        void onPostDialWait(int callId, String remainingChars);
+        void onPostDialAction(Connection.PostDialState state, int callId, String remainingChars,
+                char c);
     }
 
     /**
diff --git a/src/com/android/phone/CallNotifier.java b/src/com/android/phone/CallNotifier.java
index bbffbd2..9655371 100644
--- a/src/com/android/phone/CallNotifier.java
+++ b/src/com/android/phone/CallNotifier.java
@@ -41,7 +41,6 @@
 import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.Message;
-import android.os.RemoteException;
 import android.os.SystemProperties;
 import android.os.SystemVibrator;
 import android.os.Vibrator;
@@ -304,7 +303,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:
@@ -438,20 +436,9 @@
 
         // - don't ring for call waiting connections
         // - do this before showing the incoming call panel
-        if (PhoneUtils.isRealIncomingCall(state)) {
-            startIncomingCallQuery(c);
-        } else {
-            if (VDBG) log("- starting call waiting tone...");
-            if (mCallWaitingTonePlayer == null) {
-                mCallWaitingTonePlayer = new InCallTonePlayer(InCallTonePlayer.TONE_CALL_WAITING);
-                mCallWaitingTonePlayer.start();
-            }
+        startIncomingCallQuery(c);
 
-            // in this case, just fall through like before, and call
-            // showIncomingCall().
-            if (DBG) log("- showing incoming call (this is a WAITING call)...");
-            notifyCallModelerOfNewRingingCall(c);
-        }
+
 
         // Note we *don't* post a status bar notification here, since
         // we're not necessarily ready to actually show the incoming call
@@ -526,7 +513,6 @@
                 // we should instead provide a higher-level API via OtaUtils.
                 if (dialogState) mApplication.dismissOtaDialogs();
                 mApplication.clearOtaState();
-                mApplication.clearInCallScreenMode();
                 return false;
             }
         }
@@ -587,14 +573,7 @@
             // and before the timeout window has closed.
             EventLog.writeEvent(EventLogTags.PHONE_UI_MULTIPLE_QUERY);
 
-            // In this case, just log the request and ring.
-            if (VDBG) log("RINGING... (request to ring arrived while query is running)");
-            mRinger.ring();
-
-            // in this case, just fall through like before, and call
-            // showIncomingCall().
-            if (DBG) log("- showing incoming call (couldn't start query)...");
-            notifyCallModelerOfNewRingingCall(c);
+            ringAndNotifyOfIncomingCall(c);
         }
     }
 
@@ -654,13 +633,7 @@
         final Call ringingCall = mCM.getFirstActiveRingingCall();
 
         if (ringingCall != null && ringingCall.getLatestConnection() == c) {
-            // Ring, either with the queried ringtone or default one.
-            if (VDBG) log("RINGING... (onCustomRingQueryComplete)");
-            mRinger.ring();
-
-            // ...and display the incoming call to the user:
-            if (DBG) log("- showing incoming call (custom ring query complete)...");
-            notifyCallModelerOfNewRingingCall(c);
+            ringAndNotifyOfIncomingCall(c);
         }
     }
 
@@ -673,11 +646,26 @@
 
             if (DBG) log("- showing incoming call (unknown connection appeared)...");
             final Connection c = (Connection) r.result;
-            notifyCallModelerOfNewRingingCall(c);
+            ringAndNotifyOfIncomingCall(c);
         }
     }
 
-    private void notifyCallModelerOfNewRingingCall(Connection c) {
+    /**
+     * Notifies the Call Modeler that there is a new ringing connection.
+     * If it is not a waiting call (there is no other active call in foreground), we will ring the
+     * ringtone. Otherwise we will play the call waiting tone instead.
+     * @param c The new ringing connection.
+     */
+    private void ringAndNotifyOfIncomingCall(Connection c) {
+        if (PhoneUtils.isRealIncomingCall(c.getState())) {
+            mRinger.ring();
+        } else {
+            if (VDBG) log("- starting call waiting tone...");
+            if (mCallWaitingTonePlayer == null) {
+                mCallWaitingTonePlayer = new InCallTonePlayer(InCallTonePlayer.TONE_CALL_WAITING);
+                mCallWaitingTonePlayer.start();
+            }
+        }
         mCallModeler.onNewRingingConnection(c);
     }
 
@@ -738,12 +726,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/DTMFTonePlayer.java b/src/com/android/phone/DTMFTonePlayer.java
index 0acd114..b8adaf1 100644
--- a/src/com/android/phone/DTMFTonePlayer.java
+++ b/src/com/android/phone/DTMFTonePlayer.java
@@ -27,6 +27,7 @@
 import android.util.Log;
 
 import com.android.internal.telephony.CallManager;
+import com.android.internal.telephony.Connection.PostDialState;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.services.telephony.common.Call;
@@ -124,8 +125,25 @@
     }
 
     @Override
-    public void onPostDialWait(int callId, String chars) {
-        // no-op
+    public void onPostDialAction(PostDialState state, int callId, String remainingChars,
+            char currentChar) {
+        switch (state) {
+            case STARTED:
+                stopLocalToneIfNeeded();
+                if (!mToneMap.containsKey(currentChar)) {
+                    return;
+                }
+                startLocalToneIfNeeded(currentChar);
+                break;
+            case PAUSE:
+            case WAIT:
+            case WILD:
+            case COMPLETE:
+                stopLocalToneIfNeeded();
+                break;
+            default:
+                break;
+        }
     }
 
     /**
@@ -387,5 +405,4 @@
             Log.d(LOG_TAG, msg);
         }
     }
-
 }
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..6744d33 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,10 @@
                     mUpdateLock.acquire();
                 }
             } else {
-                if (!isShowingCallScreen()) {
-                    if (!mUpdateLock.isHeld()) {
-                        mUpdateLock.release();
-                    }
-                } else {
-                    // For this case InCallScreen will take care of the release() call.
+                if (mUpdateLock.isHeld()) {
+                    mUpdateLock.release();
                 }
             }
-
-            // 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);
-            }
         }
     }
 
@@ -1096,13 +933,6 @@
         return mLastPhoneState;
     }
 
-    /**
-     * Returns UpdateLock object.
-     */
-    /* package */ UpdateLock getUpdateLock() {
-        return mUpdateLock;
-    }
-
     KeyguardManager getKeyguardManager() {
         return mKeyguardManager;
     }
@@ -1151,9 +981,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 +1104,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 +1189,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 +1202,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 +1211,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 +1282,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/PhoneUtils.java b/src/com/android/phone/PhoneUtils.java
index 4b67db9..97be90b 100644
--- a/src/com/android/phone/PhoneUtils.java
+++ b/src/com/android/phone/PhoneUtils.java
@@ -2436,7 +2436,7 @@
             if (DBG) log("activateSpeakerIfDocked(): In a dock -> may need to turn on speaker.");
             final PhoneGlobals app = PhoneGlobals.getInstance();
 
-            // TODO(klp): This function should move to AudioRouter
+            // TODO: This function should move to AudioRouter
             final BluetoothManager btManager = app.getBluetoothManager();
             final WiredHeadsetManager wiredHeadset = app.getWiredHeadsetManager();
             final AudioRouter audioRouter = app.getAudioRouter();
diff --git a/src/com/android/phone/RejectWithTextMessageManager.java b/src/com/android/phone/RejectWithTextMessageManager.java
index 232de8e..b816eb0 100644
--- a/src/com/android/phone/RejectWithTextMessageManager.java
+++ b/src/com/android/phone/RejectWithTextMessageManager.java
@@ -32,6 +32,8 @@
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
 import android.telephony.PhoneNumberUtils;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
@@ -44,6 +46,7 @@
 import android.widget.CompoundButton;
 import android.widget.ImageView;
 import android.widget.TextView;
+import android.widget.Toast;
 
 import com.android.internal.telephony.Call;
 import com.android.internal.telephony.Connection;
@@ -91,6 +94,7 @@
 
     /* package */ static final String TAG_ALL_SMS_SERVICES = "com.android.phone.AvailablePackages";
     /* package */ static final String TAG_SEND_SMS = "com.android.phone.MessageIntent";
+    /* package */ static final String TAG_SMS_DESTINATION = "com.android.phone.SmsDestination";
 
     /**
      * Read the (customizable) canned responses from SharedPreferences,
@@ -125,18 +129,43 @@
         return responses;
     }
 
-    private void sendTextAndExit() {
+    private void sendTextAndExit(final String phoneNumber) {
         // Send the selected message immediately with no user interaction.
         if (mIntent.getComponent() != null) {
             PhoneGlobals.getInstance().startService(mIntent);
+
+            // ...and show a brief confirmation to the user (since
+            // otherwise it's hard to be sure that anything actually
+            // happened.)
+            // Ugly hack to show a toaster from a service.
+            (new Thread(new Runnable() {
+                @Override
+                public void run() {
+                    Looper.prepare();
+                    Handler innerHandler = new Handler() {
+                        @Override
+                        public void handleMessage(Message message) {
+                            final Resources res = PhoneGlobals.getInstance().getResources();
+                            final String formatString = res.getString(
+                                    R.string.respond_via_sms_confirmation_format);
+                            final String confirmationMsg = String.format(formatString, phoneNumber);
+                            Toast.makeText(PhoneGlobals.getInstance(), confirmationMsg,
+                                    Toast.LENGTH_LONG).show();
+                        }
+
+                        @Override
+                        public void dispatchMessage(Message message) {
+                            handleMessage(message);
+                        }
+                    };
+
+                    Message message = innerHandler.obtainMessage();
+                    innerHandler.dispatchMessage(message);
+                    Looper.loop();
+                }
+            })).start();
         }
 
-        // ...and show a brief confirmation to the user (since
-        // otherwise it's hard to be sure that anything actually
-        // happened.)
-        // TODO(klp): Ask the InCallUI to show a confirmation
-
-
         // 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
@@ -208,7 +237,7 @@
         return intent;
     }
 
-    private boolean getSmsService() {
+    private boolean getSmsService(String phoneNumber) {
         if (DBG) log("sendTextToDefaultActivity()...");
         final PackageManager packageManager = PhoneGlobals.getInstance().getPackageManager();
 
@@ -259,6 +288,7 @@
             intent.setClass(PhoneGlobals.getInstance(), TextMessagePackageChooser.class);
             intent.putExtra(TAG_ALL_SMS_SERVICES, mComponentsWithPermission);
             intent.putExtra(TAG_SEND_SMS, mIntent);
+            intent.putExtra(TAG_SMS_DESTINATION, phoneNumber);
             PhoneGlobals.getInstance().startActivity(intent);
             return false;
             // return componentsWithPermission.get(0);
@@ -267,9 +297,10 @@
 
     public void rejectCallWithMessage(Call call, String message) {
         mComponentsWithPermission.clear();
-        mIntent = getInstantTextIntent(call.getLatestConnection().getAddress(), message, null);
-        if (getSmsService())  {
-            sendTextAndExit();
+        final String phoneNumber = call.getLatestConnection().getAddress();
+        mIntent = getInstantTextIntent(phoneNumber, message, null);
+        if (getSmsService(phoneNumber))  {
+            sendTextAndExit(phoneNumber);
         }
     }
 
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);
     }
 }
diff --git a/src/com/android/phone/TextMessagePackageChooser.java b/src/com/android/phone/TextMessagePackageChooser.java
index ae638cb..6760a3a 100644
--- a/src/com/android/phone/TextMessagePackageChooser.java
+++ b/src/com/android/phone/TextMessagePackageChooser.java
@@ -27,6 +27,7 @@
 import android.content.SharedPreferences;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
+import android.content.res.Resources;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.util.Log;
@@ -38,6 +39,7 @@
 import android.widget.CompoundButton;
 import android.widget.ImageView;
 import android.widget.TextView;
+import android.widget.Toast;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -178,6 +180,17 @@
             if (messageIntent != null) {
                 messageIntent.setComponent(component);
                 PhoneGlobals.getInstance().startService(messageIntent);
+
+                // ...and show a brief confirmation to the user (since
+                // otherwise it's hard to be sure that anything actually
+                // happened.)
+                final Resources res = getResources();
+                final String formatString = res.getString(
+                        R.string.respond_via_sms_confirmation_format);
+                final String phoneNumber = (String) getIntent().getStringExtra(
+                        RejectWithTextMessageManager.TAG_SMS_DESTINATION);
+                final String confirmationMsg = String.format(formatString, phoneNumber);
+                Toast.makeText(PhoneGlobals.getInstance(), confirmationMsg, Toast.LENGTH_LONG).show();
             }
             finish();
         }
