diff --git a/src/com/android/phone/ADNList.java b/src/com/android/phone/ADNList.java
new file mode 100644
index 0000000..b4e8ac7
--- /dev/null
+++ b/src/com/android/phone/ADNList.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2007 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 static android.view.Window.PROGRESS_VISIBILITY_OFF;
+import static android.view.Window.PROGRESS_VISIBILITY_ON;
+
+import android.app.ListActivity;
+import android.content.AsyncQueryHandler;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.util.Log;
+import android.view.Window;
+import android.widget.CursorAdapter;
+import android.widget.SimpleCursorAdapter;
+import android.widget.TextView;
+
+/**
+ * ADN List activity for the Phone app.
+ */
+public class ADNList extends ListActivity {
+    protected static final String TAG = "ADNList";
+    protected static final boolean DBG = false;
+
+    private static final String[] COLUMN_NAMES = new String[] {
+        "name",
+        "number",
+        "emails"
+    };
+
+    protected static final int NAME_COLUMN = 0;
+    protected static final int NUMBER_COLUMN = 1;
+    protected static final int EMAILS_COLUMN = 2;
+
+    private static final int[] VIEW_NAMES = new int[] {
+        android.R.id.text1,
+        android.R.id.text2
+    };
+
+    protected static final int QUERY_TOKEN = 0;
+    protected static final int INSERT_TOKEN = 1;
+    protected static final int UPDATE_TOKEN = 2;
+    protected static final int DELETE_TOKEN = 3;
+
+
+    protected QueryHandler mQueryHandler;
+    protected CursorAdapter mCursorAdapter;
+    protected Cursor mCursor = null;
+
+    private TextView mEmptyText;
+
+    protected int mInitialSelection = -1;
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        getWindow().requestFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
+        setContentView(R.layout.adn_list);
+        mEmptyText = (TextView) findViewById(android.R.id.empty);
+        mQueryHandler = new QueryHandler(getContentResolver());
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        query();
+    }
+
+    @Override
+    protected void onStop() {
+        super.onStop();
+        if (mCursor != null) {
+            mCursor.deactivate();
+        }
+    }
+
+    protected Uri resolveIntent() {
+        Intent intent = getIntent();
+        if (intent.getData() == null) {
+            intent.setData(Uri.parse("content://icc/adn"));
+        }
+
+        return intent.getData();
+    }
+
+    private void query() {
+        Uri uri = resolveIntent();
+        if (DBG) log("query: starting an async query");
+        mQueryHandler.startQuery(QUERY_TOKEN, null, uri, COLUMN_NAMES,
+                null, null, null);
+        displayProgress(true);
+    }
+
+    private void reQuery() {
+        query();
+    }
+
+    private void setAdapter() {
+        // NOTE:
+        // As it it written, the positioning code below is NOT working.
+        // However, this current non-working state is in compliance with
+        // the UI paradigm, so we can't really do much to change it.
+
+        // In the future, if we wish to get this "positioning" correct,
+        // we'll need to do the following:
+        //   1. Change the layout to in the cursor adapter to:
+        //     android.R.layout.simple_list_item_checked
+        //   2. replace the selection / focus code with:
+        //     getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
+        //     getListView().setItemChecked(mInitialSelection, true);
+
+        // Since the positioning is really only useful for the dialer's
+        // SpecialCharSequence case (dialing '2#' to get to the 2nd
+        // contact for instance), it doesn't make sense to mess with
+        // the usability of the activity just for this case.
+
+        // These artifacts include:
+        //  1. UI artifacts (checkbox and highlight at the same time)
+        //  2. Allowing the user to edit / create new SIM contacts when
+        //    the user is simply trying to retrieve a number into the d
+        //    dialer.
+
+        if (mCursorAdapter == null) {
+            mCursorAdapter = newAdapter();
+
+            setListAdapter(mCursorAdapter);
+        } else {
+            mCursorAdapter.changeCursor(mCursor);
+        }
+
+        if (mInitialSelection >=0 && mInitialSelection < mCursorAdapter.getCount()) {
+            setSelection(mInitialSelection);
+            getListView().setFocusableInTouchMode(true);
+            boolean gotfocus = getListView().requestFocus();
+        }
+    }
+
+    protected CursorAdapter newAdapter() {
+        return new SimpleCursorAdapter(this,
+                    android.R.layout.simple_list_item_2,
+                    mCursor, COLUMN_NAMES, VIEW_NAMES);
+    }
+
+    private void displayProgress(boolean loading) {
+        if (DBG) log("displayProgress: " + loading);
+
+        mEmptyText.setText(loading ? R.string.simContacts_emptyLoading:
+            (isAirplaneModeOn(this) ? R.string.simContacts_airplaneMode :
+                R.string.simContacts_empty));
+        getWindow().setFeatureInt(
+                Window.FEATURE_INDETERMINATE_PROGRESS,
+                loading ? PROGRESS_VISIBILITY_ON : PROGRESS_VISIBILITY_OFF);
+    }
+
+    private static boolean isAirplaneModeOn(Context context) {
+        return Settings.System.getInt(context.getContentResolver(),
+                Settings.System.AIRPLANE_MODE_ON, 0) != 0;
+    }
+
+    private class QueryHandler extends AsyncQueryHandler {
+        public QueryHandler(ContentResolver cr) {
+            super(cr);
+        }
+
+        @Override
+        protected void onQueryComplete(int token, Object cookie, Cursor c) {
+            if (DBG) log("onQueryComplete: cursor.count=" + c.getCount());
+            mCursor = c;
+            setAdapter();
+            displayProgress(false);
+
+            // Cursor is refreshed and inherited classes may have menu items depending on it.
+            invalidateOptionsMenu();
+        }
+
+        @Override
+        protected void onInsertComplete(int token, Object cookie, Uri uri) {
+            if (DBG) log("onInsertComplete: requery");
+            reQuery();
+        }
+
+        @Override
+        protected void onUpdateComplete(int token, Object cookie, int result) {
+            if (DBG) log("onUpdateComplete: requery");
+            reQuery();
+        }
+
+        @Override
+        protected void onDeleteComplete(int token, Object cookie, int result) {
+            if (DBG) log("onDeleteComplete: requery");
+            reQuery();
+        }
+    }
+
+    protected void log(String msg) {
+        Log.d(TAG, "[ADNList] " + msg);
+    }
+}
diff --git a/src/com/android/phone/AccelerometerListener.java b/src/com/android/phone/AccelerometerListener.java
new file mode 100644
index 0000000..49d4a72
--- /dev/null
+++ b/src/com/android/phone/AccelerometerListener.java
@@ -0,0 +1,161 @@
+/*
+ * 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.content.Context;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+
+/**
+ * This class is used to listen to the accelerometer to monitor the
+ * orientation of the phone. The client of this class is notified when
+ * the orientation changes between horizontal and vertical.
+ */
+public final class AccelerometerListener {
+    private static final String TAG = "AccelerometerListener";
+    private static final boolean DEBUG = true;
+    private static final boolean VDEBUG = false;
+
+    private SensorManager mSensorManager;
+    private Sensor mSensor;
+
+    // mOrientation is the orientation value most recently reported to the client.
+    private int mOrientation;
+
+    // mPendingOrientation is the latest orientation computed based on the sensor value.
+    // This is sent to the client after a rebounce delay, at which point it is copied to
+    // mOrientation.
+    private int mPendingOrientation;
+
+    private OrientationListener mListener;
+
+    // Device orientation
+    public static final int ORIENTATION_UNKNOWN = 0;
+    public static final int ORIENTATION_VERTICAL = 1;
+    public static final int ORIENTATION_HORIZONTAL = 2;
+
+    private static final int ORIENTATION_CHANGED = 1234;
+
+    private static final int VERTICAL_DEBOUNCE = 100;
+    private static final int HORIZONTAL_DEBOUNCE = 500;
+    private static final double VERTICAL_ANGLE = 50.0;
+
+    public interface OrientationListener {
+        public void orientationChanged(int orientation);
+    }
+
+    public AccelerometerListener(Context context, OrientationListener listener) {
+        mListener = listener;
+        mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
+        mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
+    }
+
+    public void enable(boolean enable) {
+        if (DEBUG) Log.d(TAG, "enable(" + enable + ")");
+        synchronized (this) {
+            if (enable) {
+                mOrientation = ORIENTATION_UNKNOWN;
+                mPendingOrientation = ORIENTATION_UNKNOWN;
+                mSensorManager.registerListener(mSensorListener, mSensor,
+                        SensorManager.SENSOR_DELAY_NORMAL);
+            } else {
+                mSensorManager.unregisterListener(mSensorListener);
+                mHandler.removeMessages(ORIENTATION_CHANGED);
+            }
+        }
+    }
+
+    private void setOrientation(int orientation) {
+        synchronized (this) {
+            if (mPendingOrientation == orientation) {
+                // Pending orientation has not changed, so do nothing.
+                return;
+            }
+
+            // Cancel any pending messages.
+            // We will either start a new timer or cancel alltogether
+            // if the orientation has not changed.
+            mHandler.removeMessages(ORIENTATION_CHANGED);
+
+            if (mOrientation != orientation) {
+                // Set timer to send an event if the orientation has changed since its
+                // previously reported value.
+                mPendingOrientation = orientation;
+                Message m = mHandler.obtainMessage(ORIENTATION_CHANGED);
+                // set delay to our debounce timeout
+                int delay = (orientation == ORIENTATION_VERTICAL ? VERTICAL_DEBOUNCE
+                                                                 : HORIZONTAL_DEBOUNCE);
+                mHandler.sendMessageDelayed(m, delay);
+            } else {
+                // no message is pending
+                mPendingOrientation = ORIENTATION_UNKNOWN;
+            }
+        }
+    }
+
+    private void onSensorEvent(double x, double y, double z) {
+        if (VDEBUG) Log.d(TAG, "onSensorEvent(" + x + ", " + y + ", " + z + ")");
+
+        // If some values are exactly zero, then likely the sensor is not powered up yet.
+        // ignore these events to avoid false horizontal positives.
+        if (x == 0.0 || y == 0.0 || z == 0.0) return;
+
+        // magnitude of the acceleration vector projected onto XY plane
+        double xy = Math.sqrt(x*x + y*y);
+        // compute the vertical angle
+        double angle = Math.atan2(xy, z);
+        // convert to degrees
+        angle = angle * 180.0 / Math.PI;
+        int orientation = (angle >  VERTICAL_ANGLE ? ORIENTATION_VERTICAL : ORIENTATION_HORIZONTAL);
+        if (VDEBUG) Log.d(TAG, "angle: " + angle + " orientation: " + orientation);
+        setOrientation(orientation);
+    }
+
+    SensorEventListener mSensorListener = new SensorEventListener() {
+        public void onSensorChanged(SensorEvent event) {
+            onSensorEvent(event.values[0], event.values[1], event.values[2]);
+        }
+
+        public void onAccuracyChanged(Sensor sensor, int accuracy) {
+            // ignore
+        }
+    };
+
+    Handler mHandler = new Handler() {
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+            case ORIENTATION_CHANGED:
+                synchronized (this) {
+                    mOrientation = mPendingOrientation;
+                    if (DEBUG) {
+                        Log.d(TAG, "orientation: " +
+                            (mOrientation == ORIENTATION_HORIZONTAL ? "horizontal"
+                                : (mOrientation == ORIENTATION_VERTICAL ? "vertical"
+                                    : "unknown")));
+                    }
+                    mListener.orientationChanged(mOrientation);
+                }
+                break;
+            }
+        }
+    };
+}
diff --git a/src/com/android/phone/AnimationUtils.java b/src/com/android/phone/AnimationUtils.java
new file mode 100644
index 0000000..f7d9e2e
--- /dev/null
+++ b/src/com/android/phone/AnimationUtils.java
@@ -0,0 +1,279 @@
+/*
+ * 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
new file mode 100644
index 0000000..94d4bf9
--- /dev/null
+++ b/src/com/android/phone/BitmapUtils.java
@@ -0,0 +1,161 @@
+/*
+ * 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/BluetoothPhoneService.java b/src/com/android/phone/BluetoothPhoneService.java
new file mode 100644
index 0000000..aff6bf2
--- /dev/null
+++ b/src/com/android/phone/BluetoothPhoneService.java
@@ -0,0 +1,903 @@
+/*
+ * 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.app.Service;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothHeadset;
+import android.bluetooth.BluetoothProfile;
+import android.bluetooth.IBluetoothHeadsetPhone;
+import android.content.Context;
+import android.content.Intent;
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
+import android.os.SystemProperties;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.ServiceState;
+import android.util.Log;
+
+import com.android.internal.telephony.Call;
+import com.android.internal.telephony.Connection;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.telephony.CallManager;
+
+import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Bluetooth headset manager for the Phone app.
+ * @hide
+ */
+public class BluetoothPhoneService extends Service {
+    private static final String TAG = "BluetoothPhoneService";
+    private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 1)
+            && (SystemProperties.getInt("ro.debuggable", 0) == 1);
+    private static final boolean VDBG = (PhoneGlobals.DBG_LEVEL >= 2);  // even more logging
+
+    private static final String MODIFY_PHONE_STATE = android.Manifest.permission.MODIFY_PHONE_STATE;
+
+    private BluetoothAdapter mAdapter;
+    private CallManager mCM;
+
+    private BluetoothHeadset mBluetoothHeadset;
+
+    private PowerManager mPowerManager;
+
+    private WakeLock mStartCallWakeLock;  // held while waiting for the intent to start call
+
+    private PhoneConstants.State mPhoneState = PhoneConstants.State.IDLE;
+    CdmaPhoneCallState.PhoneCallState mCdmaThreeWayCallState =
+                                            CdmaPhoneCallState.PhoneCallState.IDLE;
+
+    private Call.State mForegroundCallState;
+    private Call.State mRingingCallState;
+    private CallNumber mRingNumber;
+    // number of active calls
+    int mNumActive;
+    // number of background (held) calls
+    int mNumHeld;
+
+    long mBgndEarliestConnectionTime = 0;
+
+    // CDMA specific flag used in context with BT devices having display capabilities
+    // to show which Caller is active. This state might not be always true as in CDMA
+    // networks if a caller drops off no update is provided to the Phone.
+    // This flag is just used as a toggle to provide a update to the BT device to specify
+    // which caller is active.
+    private boolean mCdmaIsSecondCallActive = false;
+    private boolean mCdmaCallsSwapped = false;
+
+    private long[] mClccTimestamps; // Timestamps associated with each clcc index
+    private boolean[] mClccUsed;     // Is this clcc index in use
+
+    private static final int GSM_MAX_CONNECTIONS = 6;  // Max connections allowed by GSM
+    private static final int CDMA_MAX_CONNECTIONS = 2;  // Max connections allowed by CDMA
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        mCM = CallManager.getInstance();
+        mAdapter = BluetoothAdapter.getDefaultAdapter();
+        if (mAdapter == null) {
+            if (VDBG) Log.d(TAG, "mAdapter null");
+            return;
+        }
+
+        mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
+        mStartCallWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
+                                                       TAG + ":StartCall");
+        mStartCallWakeLock.setReferenceCounted(false);
+
+        mAdapter.getProfileProxy(this, mProfileListener, BluetoothProfile.HEADSET);
+
+        mForegroundCallState = Call.State.IDLE;
+        mRingingCallState = Call.State.IDLE;
+        mNumActive = 0;
+        mNumHeld = 0;
+        mRingNumber = new CallNumber("", 0);;
+
+        handlePreciseCallStateChange(null);
+
+        if(VDBG) Log.d(TAG, "registerForServiceStateChanged");
+        // register for updates
+        mCM.registerForPreciseCallStateChanged(mHandler,
+                                               PRECISE_CALL_STATE_CHANGED, null);
+        mCM.registerForCallWaiting(mHandler,
+                                   PHONE_CDMA_CALL_WAITING, null);
+        // TODO(BT) registerForIncomingRing?
+        // TODO(BT) registerdisconnection?
+        mClccTimestamps = new long[GSM_MAX_CONNECTIONS];
+        mClccUsed = new boolean[GSM_MAX_CONNECTIONS];
+        for (int i = 0; i < GSM_MAX_CONNECTIONS; i++) {
+            mClccUsed[i] = false;
+        }
+    }
+
+    @Override
+    public void onStart(Intent intent, int startId) {
+        if (mAdapter == null) {
+            Log.w(TAG, "Stopping Bluetooth BluetoothPhoneService Service: device does not have BT");
+            stopSelf();
+        }
+        if (VDBG) Log.d(TAG, "BluetoothPhoneService started");
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        if (DBG) log("Stopping Bluetooth BluetoothPhoneService Service");
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return mBinder;
+    }
+
+    private static final int PRECISE_CALL_STATE_CHANGED = 1;
+    private static final int PHONE_CDMA_CALL_WAITING = 2;
+    private static final int LIST_CURRENT_CALLS = 3;
+    private static final int QUERY_PHONE_STATE = 4;
+    private static final int CDMA_SWAP_SECOND_CALL_STATE = 5;
+    private static final int CDMA_SET_SECOND_CALL_STATE = 6;
+
+    private Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            if (VDBG) Log.d(TAG, "handleMessage: " + msg.what);
+            switch(msg.what) {
+                case PRECISE_CALL_STATE_CHANGED:
+                case PHONE_CDMA_CALL_WAITING:
+                    Connection connection = null;
+                    if (((AsyncResult) msg.obj).result instanceof Connection) {
+                        connection = (Connection) ((AsyncResult) msg.obj).result;
+                    }
+                    handlePreciseCallStateChange(connection);
+                    break;
+                case LIST_CURRENT_CALLS:
+                    handleListCurrentCalls();
+                    break;
+                case QUERY_PHONE_STATE:
+                    handleQueryPhoneState();
+                    break;
+                case CDMA_SWAP_SECOND_CALL_STATE:
+                    handleCdmaSwapSecondCallState();
+                    break;
+                case CDMA_SET_SECOND_CALL_STATE:
+                    handleCdmaSetSecondCallState((Boolean) msg.obj);
+                    break;
+            }
+        }
+    };
+
+    private void updateBtPhoneStateAfterRadioTechnologyChange() {
+        if(VDBG) Log.d(TAG, "updateBtPhoneStateAfterRadioTechnologyChange...");
+
+        //Unregister all events from the old obsolete phone
+        mCM.unregisterForPreciseCallStateChanged(mHandler);
+        mCM.unregisterForCallWaiting(mHandler);
+
+        //Register all events new to the new active phone
+        mCM.registerForPreciseCallStateChanged(mHandler,
+                                               PRECISE_CALL_STATE_CHANGED, null);
+        mCM.registerForCallWaiting(mHandler,
+                                   PHONE_CDMA_CALL_WAITING, null);
+    }
+
+    private void handlePreciseCallStateChange(Connection connection) {
+        // get foreground call state
+        int oldNumActive = mNumActive;
+        int oldNumHeld = mNumHeld;
+        Call.State oldRingingCallState = mRingingCallState;
+        Call.State oldForegroundCallState = mForegroundCallState;
+        CallNumber oldRingNumber = mRingNumber;
+
+        Call foregroundCall = mCM.getActiveFgCall();
+
+        if (VDBG)
+            Log.d(TAG, " handlePreciseCallStateChange: foreground: " + foregroundCall +
+                " background: " + mCM.getFirstActiveBgCall() + " ringing: " +
+                mCM.getFirstActiveRingingCall());
+
+        mForegroundCallState = foregroundCall.getState();
+        /* if in transition, do not update */
+        if (mForegroundCallState == Call.State.DISCONNECTING)
+        {
+            Log.d(TAG, "handlePreciseCallStateChange. Call disconnecting, wait before update");
+            return;
+        }
+        else
+            mNumActive = (mForegroundCallState == Call.State.ACTIVE) ? 1 : 0;
+
+        Call ringingCall = mCM.getFirstActiveRingingCall();
+        mRingingCallState = ringingCall.getState();
+        mRingNumber = getCallNumber(connection, ringingCall);
+
+        if (mCM.getDefaultPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
+            mNumHeld = getNumHeldCdma();
+            PhoneGlobals app = PhoneGlobals.getInstance();
+            if (app.cdmaPhoneCallState != null) {
+                CdmaPhoneCallState.PhoneCallState currCdmaThreeWayCallState =
+                        app.cdmaPhoneCallState.getCurrentCallState();
+                CdmaPhoneCallState.PhoneCallState prevCdmaThreeWayCallState =
+                    app.cdmaPhoneCallState.getPreviousCallState();
+
+                log("CDMA call state: " + currCdmaThreeWayCallState + " prev state:" +
+                    prevCdmaThreeWayCallState);
+
+                if ((mBluetoothHeadset != null) &&
+                    (mCdmaThreeWayCallState != currCdmaThreeWayCallState)) {
+                    // In CDMA, the network does not provide any feedback
+                    // to the phone when the 2nd MO call goes through the
+                    // stages of DIALING > ALERTING -> ACTIVE we fake the
+                    // sequence
+                    log("CDMA 3way call state change. mNumActive: " + mNumActive +
+                        " mNumHeld: " + mNumHeld + " IsThreeWayCallOrigStateDialing: " +
+                        app.cdmaPhoneCallState.IsThreeWayCallOrigStateDialing());
+                    if ((currCdmaThreeWayCallState ==
+                            CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE)
+                                && app.cdmaPhoneCallState.IsThreeWayCallOrigStateDialing()) {
+                        // Mimic dialing, put the call on hold, alerting
+                        mBluetoothHeadset.phoneStateChanged(0, mNumHeld,
+                            convertCallState(Call.State.IDLE, Call.State.DIALING),
+                            mRingNumber.mNumber, mRingNumber.mType);
+
+                        mBluetoothHeadset.phoneStateChanged(0, mNumHeld,
+                            convertCallState(Call.State.IDLE, Call.State.ALERTING),
+                            mRingNumber.mNumber, mRingNumber.mType);
+
+                    }
+
+                    // In CDMA, the network does not provide any feedback to
+                    // the phone when a user merges a 3way call or swaps
+                    // between two calls we need to send a CIEV response
+                    // indicating that a call state got changed which should
+                    // trigger a CLCC update request from the BT client.
+                    if (currCdmaThreeWayCallState ==
+                            CdmaPhoneCallState.PhoneCallState.CONF_CALL &&
+                            prevCdmaThreeWayCallState ==
+                              CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
+                        log("CDMA 3way conf call. mNumActive: " + mNumActive +
+                            " mNumHeld: " + mNumHeld);
+                        mBluetoothHeadset.phoneStateChanged(mNumActive, mNumHeld,
+                            convertCallState(Call.State.IDLE, mForegroundCallState),
+                            mRingNumber.mNumber, mRingNumber.mType);
+                    }
+                }
+                mCdmaThreeWayCallState = currCdmaThreeWayCallState;
+            }
+        } else {
+            mNumHeld = getNumHeldUmts();
+        }
+
+        boolean callsSwitched = false;
+        if (mCM.getDefaultPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA &&
+            mCdmaThreeWayCallState == CdmaPhoneCallState.PhoneCallState.CONF_CALL) {
+            callsSwitched = mCdmaCallsSwapped;
+        } else {
+            Call backgroundCall = mCM.getFirstActiveBgCall();
+            callsSwitched =
+                (mNumHeld == 1 && ! (backgroundCall.getEarliestConnectTime() ==
+                    mBgndEarliestConnectionTime));
+            mBgndEarliestConnectionTime = backgroundCall.getEarliestConnectTime();
+        }
+
+        if (mNumActive != oldNumActive || mNumHeld != oldNumHeld ||
+            mRingingCallState != oldRingingCallState ||
+            mForegroundCallState != oldForegroundCallState ||
+            !mRingNumber.equalTo(oldRingNumber) ||
+            callsSwitched) {
+            if (mBluetoothHeadset != null) {
+                mBluetoothHeadset.phoneStateChanged(mNumActive, mNumHeld,
+                    convertCallState(mRingingCallState, mForegroundCallState),
+                    mRingNumber.mNumber, mRingNumber.mType);
+            }
+        }
+    }
+
+    private void handleListCurrentCalls() {
+        Phone phone = mCM.getDefaultPhone();
+        int phoneType = phone.getPhoneType();
+
+        // TODO(BT) handle virtual call
+
+        if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
+            listCurrentCallsCdma();
+        } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
+            listCurrentCallsGsm();
+        } else {
+            Log.e(TAG, "Unexpected phone type: " + phoneType);
+        }
+        // end the result
+        // when index is 0, other parameter does not matter
+        mBluetoothHeadset.clccResponse(0, 0, 0, 0, false, "", 0);
+    }
+
+    private void handleQueryPhoneState() {
+        if (mBluetoothHeadset != null) {
+            mBluetoothHeadset.phoneStateChanged(mNumActive, mNumHeld,
+                convertCallState(mRingingCallState, mForegroundCallState),
+                mRingNumber.mNumber, mRingNumber.mType);
+        }
+    }
+
+    private int getNumHeldUmts() {
+        int countHeld = 0;
+        List<Call> heldCalls = mCM.getBackgroundCalls();
+
+        for (Call call : heldCalls) {
+            if (call.getState() == Call.State.HOLDING) {
+                countHeld++;
+            }
+        }
+        return countHeld;
+    }
+
+    private int getNumHeldCdma() {
+        int numHeld = 0;
+        PhoneGlobals app = PhoneGlobals.getInstance();
+        if (app.cdmaPhoneCallState != null) {
+            CdmaPhoneCallState.PhoneCallState curr3WayCallState =
+                app.cdmaPhoneCallState.getCurrentCallState();
+            CdmaPhoneCallState.PhoneCallState prev3WayCallState =
+                app.cdmaPhoneCallState.getPreviousCallState();
+
+            log("CDMA call state: " + curr3WayCallState + " prev state:" +
+                prev3WayCallState);
+            if (curr3WayCallState == CdmaPhoneCallState.PhoneCallState.CONF_CALL) {
+                if (prev3WayCallState == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
+                    numHeld = 0; //0: no calls held, as now *both* the caller are active
+                } else {
+                    numHeld = 1; //1: held call and active call, as on answering a
+                    // Call Waiting, one of the caller *is* put on hold
+                }
+            } else if (curr3WayCallState == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
+                numHeld = 1; //1: held call and active call, as on make a 3 Way Call
+                // the first caller *is* put on hold
+            } else {
+                numHeld = 0; //0: no calls held as this is a SINGLE_ACTIVE call
+            }
+        }
+        return numHeld;
+    }
+
+    private CallNumber getCallNumber(Connection connection, Call call) {
+        String number = null;
+        int type = 128;
+        // find phone number and type
+        if (connection == null) {
+            connection = call.getEarliestConnection();
+            if (connection == null) {
+                Log.e(TAG, "Could not get a handle on Connection object for the call");
+            }
+        }
+        if (connection != null) {
+            number = connection.getAddress();
+            if (number != null) {
+                type = PhoneNumberUtils.toaFromString(number);
+            }
+        }
+        if (number == null) {
+            number = "";
+        }
+        return new CallNumber(number, type);
+    }
+
+    private class CallNumber
+    {
+        private String mNumber = null;
+        private int mType = 0;
+
+        private CallNumber(String number, int type) {
+            mNumber = number;
+            mType = type;
+        }
+
+        private boolean equalTo(CallNumber callNumber) 
+        {
+            if (mType != callNumber.mType) return false;
+            
+            if (mNumber != null && mNumber.compareTo(callNumber.mNumber) == 0) {
+                return true;
+            }
+            return false;
+        }
+    }
+
+    private BluetoothProfile.ServiceListener mProfileListener =
+            new BluetoothProfile.ServiceListener() {
+        public void onServiceConnected(int profile, BluetoothProfile proxy) {
+            mBluetoothHeadset = (BluetoothHeadset) proxy;
+        }
+        public void onServiceDisconnected(int profile) {
+            mBluetoothHeadset = null;
+        }
+    };
+
+    private void listCurrentCallsGsm() {
+        // Collect all known connections
+        // clccConnections isindexed by CLCC index
+        Connection[] clccConnections = new Connection[GSM_MAX_CONNECTIONS];
+        LinkedList<Connection> newConnections = new LinkedList<Connection>();
+        LinkedList<Connection> connections = new LinkedList<Connection>();
+
+        Call foregroundCall = mCM.getActiveFgCall();
+        Call backgroundCall = mCM.getFirstActiveBgCall();
+        Call ringingCall = mCM.getFirstActiveRingingCall();
+
+        if (ringingCall.getState().isAlive()) {
+            connections.addAll(ringingCall.getConnections());
+        }
+        if (foregroundCall.getState().isAlive()) {
+            connections.addAll(foregroundCall.getConnections());
+        }
+        if (backgroundCall.getState().isAlive()) {
+            connections.addAll(backgroundCall.getConnections());
+        }
+
+        // Mark connections that we already known about
+        boolean clccUsed[] = new boolean[GSM_MAX_CONNECTIONS];
+        for (int i = 0; i < GSM_MAX_CONNECTIONS; i++) {
+            clccUsed[i] = mClccUsed[i];
+            mClccUsed[i] = false;
+        }
+        for (Connection c : connections) {
+            boolean found = false;
+            long timestamp = c.getCreateTime();
+            for (int i = 0; i < GSM_MAX_CONNECTIONS; i++) {
+                if (clccUsed[i] && timestamp == mClccTimestamps[i]) {
+                    mClccUsed[i] = true;
+                    found = true;
+                    clccConnections[i] = c;
+                    break;
+                }
+            }
+            if (!found) {
+                newConnections.add(c);
+            }
+        }
+
+        // Find a CLCC index for new connections
+        while (!newConnections.isEmpty()) {
+            // Find lowest empty index
+            int i = 0;
+            while (mClccUsed[i]) i++;
+            // Find earliest connection
+            long earliestTimestamp = newConnections.get(0).getCreateTime();
+            Connection earliestConnection = newConnections.get(0);
+            for (int j = 0; j < newConnections.size(); j++) {
+                long timestamp = newConnections.get(j).getCreateTime();
+                if (timestamp < earliestTimestamp) {
+                    earliestTimestamp = timestamp;
+                    earliestConnection = newConnections.get(j);
+                }
+            }
+
+            // update
+            mClccUsed[i] = true;
+            mClccTimestamps[i] = earliestTimestamp;
+            clccConnections[i] = earliestConnection;
+            newConnections.remove(earliestConnection);
+        }
+
+        // Send CLCC response to Bluetooth headset service
+        for (int i = 0; i < clccConnections.length; i++) {
+            if (mClccUsed[i]) {
+                sendClccResponseGsm(i, clccConnections[i]);
+            }
+        }
+    }
+
+    /** Convert a Connection object into a single +CLCC result */
+    private void sendClccResponseGsm(int index, Connection connection) {
+        int state = convertCallState(connection.getState());
+        boolean mpty = false;
+        Call call = connection.getCall();
+        if (call != null) {
+            mpty = call.isMultiparty();
+        }
+
+        int direction = connection.isIncoming() ? 1 : 0;
+
+        String number = connection.getAddress();
+        int type = -1;
+        if (number != null) {
+            type = PhoneNumberUtils.toaFromString(number);
+        }
+
+        mBluetoothHeadset.clccResponse(index + 1, direction, state, 0, mpty, number, type);
+    }
+
+    /** Build the +CLCC result for CDMA
+     *  The complexity arises from the fact that we need to maintain the same
+     *  CLCC index even as a call moves between states. */
+    private synchronized void listCurrentCallsCdma() {
+        // In CDMA at one time a user can have only two live/active connections
+        Connection[] clccConnections = new Connection[CDMA_MAX_CONNECTIONS];// indexed by CLCC index
+        Call foregroundCall = mCM.getActiveFgCall();
+        Call ringingCall = mCM.getFirstActiveRingingCall();
+
+        Call.State ringingCallState = ringingCall.getState();
+        // If the Ringing Call state is INCOMING, that means this is the very first call
+        // hence there should not be any Foreground Call
+        if (ringingCallState == Call.State.INCOMING) {
+            if (VDBG) log("Filling clccConnections[0] for INCOMING state");
+            clccConnections[0] = ringingCall.getLatestConnection();
+        } else if (foregroundCall.getState().isAlive()) {
+            // Getting Foreground Call connection based on Call state
+            if (ringingCall.isRinging()) {
+                if (VDBG) log("Filling clccConnections[0] & [1] for CALL WAITING state");
+                clccConnections[0] = foregroundCall.getEarliestConnection();
+                clccConnections[1] = ringingCall.getLatestConnection();
+            } else {
+                if (foregroundCall.getConnections().size() <= 1) {
+                    // Single call scenario
+                    if (VDBG) {
+                        log("Filling clccConnections[0] with ForgroundCall latest connection");
+                    }
+                    clccConnections[0] = foregroundCall.getLatestConnection();
+                } else {
+                    // Multiple Call scenario. This would be true for both
+                    // CONF_CALL and THRWAY_ACTIVE state
+                    if (VDBG) {
+                        log("Filling clccConnections[0] & [1] with ForgroundCall connections");
+                    }
+                    clccConnections[0] = foregroundCall.getEarliestConnection();
+                    clccConnections[1] = foregroundCall.getLatestConnection();
+                }
+            }
+        }
+
+        // Update the mCdmaIsSecondCallActive flag based on the Phone call state
+        if (PhoneGlobals.getInstance().cdmaPhoneCallState.getCurrentCallState()
+                == CdmaPhoneCallState.PhoneCallState.SINGLE_ACTIVE) {
+            Message msg = mHandler.obtainMessage(CDMA_SET_SECOND_CALL_STATE, false);
+            mHandler.sendMessage(msg);
+        } else if (PhoneGlobals.getInstance().cdmaPhoneCallState.getCurrentCallState()
+                == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
+            Message msg = mHandler.obtainMessage(CDMA_SET_SECOND_CALL_STATE, true);
+            mHandler.sendMessage(msg);
+        }
+
+        // send CLCC result
+        for (int i = 0; (i < clccConnections.length) && (clccConnections[i] != null); i++) {
+            sendClccResponseCdma(i, clccConnections[i]);
+        }
+    }
+
+    /** Send ClCC results for a Connection object for CDMA phone */
+    private void sendClccResponseCdma(int index, Connection connection) {
+        int state;
+        PhoneGlobals app = PhoneGlobals.getInstance();
+        CdmaPhoneCallState.PhoneCallState currCdmaCallState =
+                app.cdmaPhoneCallState.getCurrentCallState();
+        CdmaPhoneCallState.PhoneCallState prevCdmaCallState =
+                app.cdmaPhoneCallState.getPreviousCallState();
+
+        if ((prevCdmaCallState == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE)
+                && (currCdmaCallState == CdmaPhoneCallState.PhoneCallState.CONF_CALL)) {
+            // If the current state is reached after merging two calls
+            // we set the state of all the connections as ACTIVE
+            state = CALL_STATE_ACTIVE;
+        } else {
+            Call.State callState = connection.getState();
+            switch (callState) {
+            case ACTIVE:
+                // For CDMA since both the connections are set as active by FW after accepting
+                // a Call waiting or making a 3 way call, we need to set the state specifically
+                // to ACTIVE/HOLDING based on the mCdmaIsSecondCallActive flag. This way the
+                // CLCC result will allow BT devices to enable the swap or merge options
+                if (index == 0) { // For the 1st active connection
+                    state = mCdmaIsSecondCallActive ? CALL_STATE_HELD : CALL_STATE_ACTIVE;
+                } else { // for the 2nd active connection
+                    state = mCdmaIsSecondCallActive ? CALL_STATE_ACTIVE : CALL_STATE_HELD;
+                }
+                break;
+            case HOLDING:
+                state = CALL_STATE_HELD;
+                break;
+            case DIALING:
+                state = CALL_STATE_DIALING;
+                break;
+            case ALERTING:
+                state = CALL_STATE_ALERTING;
+                break;
+            case INCOMING:
+                state = CALL_STATE_INCOMING;
+                break;
+            case WAITING:
+                state = CALL_STATE_WAITING;
+                break;
+            default:
+                Log.e(TAG, "bad call state: " + callState);
+                return;
+            }
+        }
+
+        boolean mpty = false;
+        if (currCdmaCallState == CdmaPhoneCallState.PhoneCallState.CONF_CALL) {
+            if (prevCdmaCallState == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
+                // If the current state is reached after merging two calls
+                // we set the multiparty call true.
+                mpty = true;
+            } // else
+                // CALL_CONF state is not from merging two calls, but from
+                // accepting the second call. In this case first will be on
+                // hold in most cases but in some cases its already merged.
+                // However, we will follow the common case and the test case
+                // as per Bluetooth SIG PTS
+        }
+
+        int direction = connection.isIncoming() ? 1 : 0;
+
+        String number = connection.getAddress();
+        int type = -1;
+        if (number != null) {
+            type = PhoneNumberUtils.toaFromString(number);
+        } else {
+            number = "";
+        }
+
+        mBluetoothHeadset.clccResponse(index + 1, direction, state, 0, mpty, number, type);
+    }
+
+    private void handleCdmaSwapSecondCallState() {
+        if (VDBG) log("cdmaSwapSecondCallState: Toggling mCdmaIsSecondCallActive");
+        mCdmaIsSecondCallActive = !mCdmaIsSecondCallActive;
+        mCdmaCallsSwapped = true;
+    }
+
+    private void handleCdmaSetSecondCallState(boolean state) {
+        if (VDBG) log("cdmaSetSecondCallState: Setting mCdmaIsSecondCallActive to " + state);
+        mCdmaIsSecondCallActive = state;
+
+        if (!mCdmaIsSecondCallActive) {
+            mCdmaCallsSwapped = false;
+        }
+    }
+
+    private final IBluetoothHeadsetPhone.Stub mBinder = new IBluetoothHeadsetPhone.Stub() {
+        public boolean answerCall() {
+            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
+            return PhoneUtils.answerCall(mCM.getFirstActiveRingingCall());
+        }
+
+        public boolean hangupCall() {
+            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
+            if (mCM.hasActiveFgCall()) {
+                return PhoneUtils.hangupActiveCall(mCM.getActiveFgCall());
+            } else if (mCM.hasActiveRingingCall()) {
+                return PhoneUtils.hangupRingingCall(mCM.getFirstActiveRingingCall());
+            } else if (mCM.hasActiveBgCall()) {
+                return PhoneUtils.hangupHoldingCall(mCM.getFirstActiveBgCall());
+            }
+            // TODO(BT) handle virtual voice call
+            return false;
+        }
+
+        public boolean sendDtmf(int dtmf) {
+            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
+            return mCM.sendDtmf((char) dtmf);
+        }
+
+        public boolean processChld(int chld) {
+            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
+            Phone phone = mCM.getDefaultPhone();
+            int phoneType = phone.getPhoneType();
+            Call ringingCall = mCM.getFirstActiveRingingCall();
+            Call backgroundCall = mCM.getFirstActiveBgCall();
+
+            if (chld == CHLD_TYPE_RELEASEHELD) {
+                if (ringingCall.isRinging()) {
+                    return PhoneUtils.hangupRingingCall(ringingCall);
+                } else {
+                    return PhoneUtils.hangupHoldingCall(backgroundCall);
+                }
+            } else if (chld == CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD) {
+                if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
+                    if (ringingCall.isRinging()) {
+                        // Hangup the active call and then answer call waiting call.
+                        if (VDBG) log("CHLD:1 Callwaiting Answer call");
+                        PhoneUtils.hangupRingingAndActive(phone);
+                    } else {
+                        // If there is no Call waiting then just hangup
+                        // the active call. In CDMA this mean that the complete
+                        // call session would be ended
+                        if (VDBG) log("CHLD:1 Hangup Call");
+                        PhoneUtils.hangup(PhoneGlobals.getInstance().mCM);
+                    }
+                    return true;
+                } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
+                    // Hangup active call, answer held call
+                    return PhoneUtils.answerAndEndActive(PhoneGlobals.getInstance().mCM, ringingCall);
+                } else {
+                    Log.e(TAG, "bad phone type: " + phoneType);
+                    return false;
+                }
+            } else if (chld == CHLD_TYPE_HOLDACTIVE_ACCEPTHELD) {
+                if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
+                    // For CDMA, the way we switch to a new incoming call is by
+                    // calling PhoneUtils.answerCall(). switchAndHoldActive() won't
+                    // properly update the call state within telephony.
+                    // If the Phone state is already in CONF_CALL then we simply send
+                    // a flash cmd by calling switchHoldingAndActive()
+                    if (ringingCall.isRinging()) {
+                        if (VDBG) log("CHLD:2 Callwaiting Answer call");
+                        PhoneUtils.answerCall(ringingCall);
+                        PhoneUtils.setMute(false);
+                        // Setting the second callers state flag to TRUE (i.e. active)
+                        cdmaSetSecondCallState(true);
+                        return true;
+                    } else if (PhoneGlobals.getInstance().cdmaPhoneCallState
+                               .getCurrentCallState()
+                               == CdmaPhoneCallState.PhoneCallState.CONF_CALL) {
+                        if (VDBG) log("CHLD:2 Swap Calls");
+                        PhoneUtils.switchHoldingAndActive(backgroundCall);
+                        // Toggle the second callers active state flag
+                        cdmaSwapSecondCallState();
+                        return true;
+                    }
+                    Log.e(TAG, "CDMA fail to do hold active and accept held");
+                    return false;
+                } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
+                    PhoneUtils.switchHoldingAndActive(backgroundCall);
+                    return true;
+                } else {
+                    Log.e(TAG, "Unexpected phone type: " + phoneType);
+                    return false;
+                }
+            } else if (chld == CHLD_TYPE_ADDHELDTOCONF) {
+                if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
+                    CdmaPhoneCallState.PhoneCallState state =
+                        PhoneGlobals.getInstance().cdmaPhoneCallState.getCurrentCallState();
+                    // For CDMA, we need to check if the call is in THRWAY_ACTIVE state
+                    if (state == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
+                        if (VDBG) log("CHLD:3 Merge Calls");
+                        PhoneUtils.mergeCalls();
+                        return true;
+                    }   else if (state == CdmaPhoneCallState.PhoneCallState.CONF_CALL) {
+                        // State is CONF_CALL already and we are getting a merge call
+                        // This can happen when CONF_CALL was entered from a Call Waiting
+                        // TODO(BT)
+                        return false;
+                    }
+                    Log.e(TAG, "GSG no call to add conference");
+                    return false;
+                } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
+                    if (mCM.hasActiveFgCall() && mCM.hasActiveBgCall()) {
+                        PhoneUtils.mergeCalls();
+                        return true;
+                    } else {
+                        Log.e(TAG, "GSG no call to merge");
+                        return false;
+                    }
+                } else {
+                    Log.e(TAG, "Unexpected phone type: " + phoneType);
+                    return false;
+                }                
+            } else {
+                Log.e(TAG, "bad CHLD value: " + chld);
+                return false;
+            }
+        }
+
+        public String getNetworkOperator() {
+            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
+            return mCM.getDefaultPhone().getServiceState().getOperatorAlphaLong();
+        }
+
+        public String getSubscriberNumber() {
+            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
+            return mCM.getDefaultPhone().getLine1Number();
+        }
+
+        public boolean listCurrentCalls() {
+            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
+            Message msg = Message.obtain(mHandler, LIST_CURRENT_CALLS);
+            mHandler.sendMessage(msg);
+            return true;
+        }
+
+        public boolean queryPhoneState() {
+            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
+            Message msg = Message.obtain(mHandler, QUERY_PHONE_STATE);
+            mHandler.sendMessage(msg);
+            return true;
+        }
+
+        public void updateBtHandsfreeAfterRadioTechnologyChange() {
+            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
+            if (VDBG) Log.d(TAG, "updateBtHandsfreeAfterRadioTechnologyChange...");
+            updateBtPhoneStateAfterRadioTechnologyChange();
+        }
+
+        public void cdmaSwapSecondCallState() {
+            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
+            Message msg = Message.obtain(mHandler, CDMA_SWAP_SECOND_CALL_STATE);
+            mHandler.sendMessage(msg);
+        }
+
+        public void cdmaSetSecondCallState(boolean state) {
+            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
+            Message msg = mHandler.obtainMessage(CDMA_SET_SECOND_CALL_STATE, state);
+            mHandler.sendMessage(msg);
+        }
+    };
+
+    // match up with bthf_call_state_t of bt_hf.h
+    final static int CALL_STATE_ACTIVE = 0;
+    final static int CALL_STATE_HELD = 1;
+    final static int CALL_STATE_DIALING = 2;
+    final static int CALL_STATE_ALERTING = 3;
+    final static int CALL_STATE_INCOMING = 4;
+    final static int CALL_STATE_WAITING = 5;
+    final static int CALL_STATE_IDLE = 6;
+
+    // match up with bthf_chld_type_t of bt_hf.h
+    final static int CHLD_TYPE_RELEASEHELD = 0;
+    final static int CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD = 1;
+    final static int CHLD_TYPE_HOLDACTIVE_ACCEPTHELD = 2;
+    final static int CHLD_TYPE_ADDHELDTOCONF = 3;
+
+     /* Convert telephony phone call state into hf hal call state */
+    static int convertCallState(Call.State ringingState, Call.State foregroundState) {
+        if ((ringingState == Call.State.INCOMING) ||
+            (ringingState == Call.State.WAITING) )
+            return CALL_STATE_INCOMING;
+        else if (foregroundState == Call.State.DIALING)
+            return CALL_STATE_DIALING;
+        else if (foregroundState == Call.State.ALERTING)
+            return CALL_STATE_ALERTING;
+        else
+            return CALL_STATE_IDLE;
+    }
+
+    static int convertCallState(Call.State callState) {
+        switch (callState) {
+        case IDLE:
+        case DISCONNECTED:
+        case DISCONNECTING:
+            return CALL_STATE_IDLE;
+        case ACTIVE:
+            return CALL_STATE_ACTIVE;
+        case HOLDING:
+            return CALL_STATE_HELD;
+        case DIALING:
+            return CALL_STATE_DIALING;
+        case ALERTING:
+            return CALL_STATE_ALERTING;
+        case INCOMING:
+            return CALL_STATE_INCOMING;
+        case WAITING:
+            return CALL_STATE_WAITING;
+        default:
+            Log.e(TAG, "bad call state: " + callState);
+            return CALL_STATE_IDLE;
+        }
+    }
+
+    private static void log(String msg) {
+        Log.d(TAG, msg);
+    }
+}
diff --git a/src/com/android/phone/CLIRListPreference.java b/src/com/android/phone/CLIRListPreference.java
new file mode 100644
index 0000000..198bdb0
--- /dev/null
+++ b/src/com/android/phone/CLIRListPreference.java
@@ -0,0 +1,170 @@
+package com.android.phone;
+
+import static com.android.phone.TimeConsumingPreferenceActivity.RESPONSE_ERROR;
+import com.android.internal.telephony.CommandException;
+import com.android.internal.telephony.CommandsInterface;
+import com.android.internal.telephony.Phone;
+
+import android.content.Context;
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Parcelable;
+import android.preference.ListPreference;
+import android.util.AttributeSet;
+import android.util.Log;
+
+/**
+ * {@link ListPreference} for CLIR (Calling Line Identification Restriction).
+ * Right now this is used for "Caller ID" setting.
+ */
+public class CLIRListPreference extends ListPreference {
+    private static final String LOG_TAG = "CLIRListPreference";
+    private final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
+
+    private final MyHandler mHandler = new MyHandler();
+    private final Phone mPhone;
+    private TimeConsumingPreferenceListener mTcpListener;
+
+    int clirArray[];
+
+    public CLIRListPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        mPhone = PhoneGlobals.getPhone();
+    }
+
+    public CLIRListPreference(Context context) {
+        this(context, null);
+    }
+
+    @Override
+    protected void onDialogClosed(boolean positiveResult) {
+        super.onDialogClosed(positiveResult);
+
+        mPhone.setOutgoingCallerIdDisplay(findIndexOfValue(getValue()),
+                mHandler.obtainMessage(MyHandler.MESSAGE_SET_CLIR));
+        if (mTcpListener != null) {
+            mTcpListener.onStarted(this, false);
+        }
+    }
+
+    /* package */ void init(TimeConsumingPreferenceListener listener, boolean skipReading) {
+        mTcpListener = listener;
+        if (!skipReading) {
+            mPhone.getOutgoingCallerIdDisplay(mHandler.obtainMessage(MyHandler.MESSAGE_GET_CLIR,
+                    MyHandler.MESSAGE_GET_CLIR, MyHandler.MESSAGE_GET_CLIR));
+            if (mTcpListener != null) {
+                mTcpListener.onStarted(this, true);
+            }
+        }
+    }
+
+    /* package */ void handleGetCLIRResult(int tmpClirArray[]) {
+        clirArray = tmpClirArray;
+        final boolean enabled =
+                tmpClirArray[1] == 1 || tmpClirArray[1] == 3 || tmpClirArray[1] == 4;
+        setEnabled(enabled);
+
+        // set the value of the preference based upon the clirArgs.
+        int value = CommandsInterface.CLIR_DEFAULT;
+        switch (tmpClirArray[1]) {
+            case 1: // Permanently provisioned
+            case 3: // Temporary presentation disallowed
+            case 4: // Temporary presentation allowed
+                switch (tmpClirArray[0]) {
+                    case 1: // CLIR invoked
+                        value = CommandsInterface.CLIR_INVOCATION;
+                        break;
+                    case 2: // CLIR suppressed
+                        value = CommandsInterface.CLIR_SUPPRESSION;
+                        break;
+                    case 0: // Network default
+                    default:
+                        value = CommandsInterface.CLIR_DEFAULT;
+                        break;
+                }
+                break;
+            case 0: // Not Provisioned
+            case 2: // Unknown (network error, etc)
+            default:
+                value = CommandsInterface.CLIR_DEFAULT;
+                break;
+        }
+        setValueIndex(value);
+
+        // set the string summary to reflect the value
+        int summary = R.string.sum_default_caller_id;
+        switch (value) {
+            case CommandsInterface.CLIR_SUPPRESSION:
+                summary = R.string.sum_show_caller_id;
+                break;
+            case CommandsInterface.CLIR_INVOCATION:
+                summary = R.string.sum_hide_caller_id;
+                break;
+            case CommandsInterface.CLIR_DEFAULT:
+                summary = R.string.sum_default_caller_id;
+                break;
+        }
+        setSummary(summary);
+    }
+
+    private class MyHandler extends Handler {
+        static final int MESSAGE_GET_CLIR = 0;
+        static final int MESSAGE_SET_CLIR = 1;
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MESSAGE_GET_CLIR:
+                    handleGetCLIRResponse(msg);
+                    break;
+                case MESSAGE_SET_CLIR:
+                    handleSetCLIRResponse(msg);
+                    break;
+            }
+        }
+
+        private void handleGetCLIRResponse(Message msg) {
+            AsyncResult ar = (AsyncResult) msg.obj;
+
+            if (msg.arg2 == MESSAGE_SET_CLIR) {
+                mTcpListener.onFinished(CLIRListPreference.this, false);
+            } else {
+                mTcpListener.onFinished(CLIRListPreference.this, true);
+            }
+            clirArray = null;
+            if (ar.exception != null) {
+                if (DBG) Log.d(LOG_TAG, "handleGetCLIRResponse: ar.exception="+ar.exception);
+                mTcpListener.onException(CLIRListPreference.this, (CommandException) ar.exception);
+            } else if (ar.userObj instanceof Throwable) {
+                mTcpListener.onError(CLIRListPreference.this, RESPONSE_ERROR);
+            } else {
+                int clirArray[] = (int[]) ar.result;
+                if (clirArray.length != 2) {
+                    mTcpListener.onError(CLIRListPreference.this, RESPONSE_ERROR);
+                } else {
+                    if (DBG) {
+                        Log.d(LOG_TAG, "handleGetCLIRResponse: CLIR successfully queried,"
+                                + " clirArray[0]=" + clirArray[0]
+                                + ", clirArray[1]=" + clirArray[1]);
+                    }
+                    handleGetCLIRResult(clirArray);
+                }
+            }
+        }
+
+        private void handleSetCLIRResponse(Message msg) {
+            AsyncResult ar = (AsyncResult) msg.obj;
+
+            if (ar.exception != null) {
+                if (DBG) Log.d(LOG_TAG, "handleSetCallWaitingResponse: ar.exception="+ar.exception);
+                //setEnabled(false);
+            }
+            if (DBG) Log.d(LOG_TAG, "handleSetCallWaitingResponse: re get");
+
+            mPhone.getOutgoingCallerIdDisplay(obtainMessage(MESSAGE_GET_CLIR,
+                    MESSAGE_SET_CLIR, MESSAGE_SET_CLIR, ar.exception));
+        }
+    }
+}
diff --git a/src/com/android/phone/CallCard.java b/src/com/android/phone/CallCard.java
new file mode 100644
index 0000000..682113f
--- /dev/null
+++ b/src/com/android/phone/CallCard.java
@@ -0,0 +1,1787 @@
+/*
+ * 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;
+
+    /**
+     * Container for both provider info and call state. This will take care of showing/hiding
+     * animation for those views.
+     */
+    private ViewGroup mSecondaryInfoContainer;
+    private ViewGroup mProviderInfo;
+    private TextView mProviderLabel;
+    private TextView mProviderAddress;
+
+    // "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);
+
+        mSecondaryInfoContainer = (ViewGroup) findViewById(R.id.secondary_info_container);
+        mProviderInfo = (ViewGroup) findViewById(R.id.providerInfo);
+        mProviderLabel = (TextView) findViewById(R.id.providerLabel);
+        mProviderAddress = (TextView) findViewById(R.id.providerAddress);
+        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);
+        mSecondaryInfoContainer.setLayoutTransition(null);
+        mProviderInfo.setVisibility(View.GONE);
+        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);
+
+                // Also, display a special icon (alongside the "Incoming call"
+                // label) if there's an incoming call and audio will be routed
+                // to bluetooth when you answer it.
+                if (mApplication.showBluetoothIndication()) {
+                    bluetoothIconId = R.drawable.ic_incoming_call_bluetooth;
+                }
+                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).
+
+        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
+                    + ", providerInfoVisible = " + inCallUiState.providerInfoVisible);
+        }
+
+        // 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 (skipAnimation) {
+            // Evict LayoutTransition object to skip animation.
+            layoutTransition = mSecondaryInfoContainer.getLayoutTransition();
+            mSecondaryInfoContainer.setLayoutTransition(null);
+        }
+
+        if (inCallUiState.providerInfoVisible) {
+            mProviderInfo.setVisibility(View.VISIBLE);
+            mProviderLabel.setText(context.getString(R.string.calling_via_template,
+                    inCallUiState.providerLabel));
+            mProviderAddress.setText(inCallUiState.providerAddress);
+
+            mInCallScreen.requestRemoveProviderInfoWithDelay();
+        } else {
+            mProviderInfo.setVisibility(View.GONE);
+        }
+
+        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);
+            }
+        }
+        if (skipAnimation) {
+            // Restore LayoutTransition object to recover animation.
+            mSecondaryInfoContainer.setLayoutTransition(layoutTransition);
+        }
+
+        // ...and update the elapsed time widget too.
+        switch (state) {
+            case ACTIVE:
+            case DISCONNECTING:
+                // Show the time with fade-in animation.
+                AnimationUtils.Fade.show(mElapsedTime);
+                updateElapsedTimeWidget(call);
+                break;
+
+            case DISCONNECTED:
+                // In the "Call ended" state, leave the mElapsedTime widget
+                // visible, but don't touch it (so we continue to see the
+                // elapsed time of the call that just ended.)
+                // Check visibility to keep possible fade-in animation.
+                if (mElapsedTime.getVisibility() != View.VISIBLE) {
+                    mElapsedTime.setVisibility(View.VISIBLE);
+                }
+                break;
+
+            default:
+                // Call state here is IDLE, ACTIVE, HOLDING, DIALING, ALERTING,
+                // INCOMING, or WAITING.
+                // In all of these states, the "elapsed time" is meaningless, so
+                // don't show it.
+                AnimationUtils.Fade.hide(mElapsedTime, View.INVISIBLE);
+
+                // Additionally, in call states that can only occur at the start
+                // of a call, reset the elapsed time to be sure we won't display
+                // stale info later (like if we somehow go straight from DIALING
+                // or ALERTING to DISCONNECTED, which can actually happen in
+                // some failure cases like "line busy").
+                if ((state ==  Call.State.DIALING) || (state == Call.State.ALERTING)) {
+                    updateElapsedTimeWidget(0);
+                }
+
+                break;
+        }
+    }
+
+    /**
+     * Updates mElapsedTime based on the given {@link Call} object's information.
+     *
+     * @see CallTime#getCallDuration(Call)
+     * @see Connection#getDurationMillis()
+     */
+    /* package */ void updateElapsedTimeWidget(Call call) {
+        long duration = CallTime.getCallDuration(call);  // msec
+        updateElapsedTimeWidget(duration / 1000);
+        // Also see onTickForCallTimeElapsed(), which updates this
+        // widget once per second while the call is active.
+    }
+
+    /**
+     * Updates mElapsedTime based on the specified number of seconds.
+     */
+    private void updateElapsedTimeWidget(long timeElapsed) {
+        // if (DBG) log("updateElapsedTimeWidget: " + timeElapsed);
+        mElapsedTime.setText(DateUtils.formatElapsedTime(timeElapsed));
+    }
+
+    /**
+     * Updates the "on hold" box in the "other call" info area
+     * (ie. the stuff in the secondaryCallInfo block)
+     * based on the specified Call.
+     * Or, clear out the "on hold" box if the specified call
+     * is null or idle.
+     */
+    private void displaySecondaryCallStatus(CallManager cm, Call call) {
+        if (DBG) log("displayOnHoldCallStatus(call =" + call + ")...");
+
+        if ((call == null) || (PhoneGlobals.getInstance().isOtaCallInActiveState())) {
+            mSecondaryCallInfo.setVisibility(View.GONE);
+            return;
+        }
+
+        Call.State state = call.getState();
+        switch (state) {
+            case HOLDING:
+                // Ok, there actually is a background call on hold.
+                // Display the "on hold" box.
+
+                // Note this case occurs only on GSM devices.  (On CDMA,
+                // the "call on hold" is actually the 2nd connection of
+                // that ACTIVE call; see the ACTIVE case below.)
+                showSecondaryCallInfo();
+
+                if (PhoneUtils.isConferenceCall(call)) {
+                    if (DBG) log("==> conference call.");
+                    mSecondaryCallName.setText(getContext().getString(R.string.confCall));
+                    showImage(mSecondaryCallPhoto, R.drawable.picture_conference);
+                } else {
+                    // perform query and update the name temporarily
+                    // make sure we hand the textview we want updated to the
+                    // callback function.
+                    if (DBG) log("==> NOT a conf call; call startGetCallerInfo...");
+                    PhoneUtils.CallerInfoToken infoToken = PhoneUtils.startGetCallerInfo(
+                            getContext(), call, this, mSecondaryCallName);
+                    mSecondaryCallName.setText(
+                            PhoneUtils.getCompactNameFromCallerInfo(infoToken.currentInfo,
+                                                                    getContext()));
+
+                    // Also pull the photo out of the current CallerInfo.
+                    // (Note we assume we already have a valid photo at
+                    // this point, since *presumably* the caller-id query
+                    // was already run at some point *before* this call
+                    // got put on hold.  If there's no cached photo, just
+                    // fall back to the default "unknown" image.)
+                    if (infoToken.isFinal) {
+                        showCachedImage(mSecondaryCallPhoto, infoToken.currentInfo);
+                    } else {
+                        showImage(mSecondaryCallPhoto, R.drawable.picture_unknown);
+                    }
+                }
+
+                AnimationUtils.Fade.show(mSecondaryCallPhotoDimEffect);
+                break;
+
+            case ACTIVE:
+                // CDMA: This is because in CDMA when the user originates the second call,
+                // although the Foreground call state is still ACTIVE in reality the network
+                // put the first call on hold.
+                if (mApplication.phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
+                    showSecondaryCallInfo();
+
+                    List<Connection> connections = call.getConnections();
+                    if (connections.size() > 2) {
+                        // This means that current Mobile Originated call is the not the first 3-Way
+                        // call the user is making, which in turn tells the PhoneGlobals that we no
+                        // longer know which previous caller/party had dropped out before the user
+                        // made this call.
+                        mSecondaryCallName.setText(
+                                getContext().getString(R.string.card_title_in_call));
+                        showImage(mSecondaryCallPhoto, R.drawable.picture_unknown);
+                    } else {
+                        // This means that the current Mobile Originated call IS the first 3-Way
+                        // and hence we display the first callers/party's info here.
+                        Connection conn = call.getEarliestConnection();
+                        PhoneUtils.CallerInfoToken infoToken = PhoneUtils.startGetCallerInfo(
+                                getContext(), conn, this, mSecondaryCallName);
+
+                        // Get the compactName to be displayed, but then check that against
+                        // the number presentation value for the call. If it's not an allowed
+                        // presentation, then display the appropriate presentation string instead.
+                        CallerInfo info = infoToken.currentInfo;
+
+                        String name = PhoneUtils.getCompactNameFromCallerInfo(info, getContext());
+                        boolean forceGenericPhoto = false;
+                        if (info != null && info.numberPresentation !=
+                                PhoneConstants.PRESENTATION_ALLOWED) {
+                            name = PhoneUtils.getPresentationString(
+                                    getContext(), info.numberPresentation);
+                            forceGenericPhoto = true;
+                        }
+                        mSecondaryCallName.setText(name);
+
+                        // Also pull the photo out of the current CallerInfo.
+                        // (Note we assume we already have a valid photo at
+                        // this point, since *presumably* the caller-id query
+                        // was already run at some point *before* this call
+                        // got put on hold.  If there's no cached photo, just
+                        // fall back to the default "unknown" image.)
+                        if (!forceGenericPhoto && infoToken.isFinal) {
+                            showCachedImage(mSecondaryCallPhoto, info);
+                        } else {
+                            showImage(mSecondaryCallPhoto, R.drawable.picture_unknown);
+                        }
+                    }
+                } else {
+                    // We shouldn't ever get here at all for non-CDMA devices.
+                    Log.w(LOG_TAG, "displayOnHoldCallStatus: ACTIVE state on non-CDMA device");
+                    mSecondaryCallInfo.setVisibility(View.GONE);
+                }
+
+                AnimationUtils.Fade.hide(mSecondaryCallPhotoDimEffect, View.GONE);
+                break;
+
+            default:
+                // There's actually no call on hold.  (Presumably this call's
+                // state is IDLE, since any other state is meaningless for the
+                // background call.)
+                mSecondaryCallInfo.setVisibility(View.GONE);
+                break;
+        }
+    }
+
+    private void showSecondaryCallInfo() {
+        // This will call ViewStub#inflate() when needed.
+        mSecondaryCallInfo.setVisibility(View.VISIBLE);
+        if (mSecondaryCallName == null) {
+            mSecondaryCallName = (TextView) findViewById(R.id.secondaryCallName);
+        }
+        if (mSecondaryCallPhoto == null) {
+            mSecondaryCallPhoto = (ImageView) findViewById(R.id.secondaryCallPhoto);
+        }
+        if (mSecondaryCallPhotoDimEffect == null) {
+            mSecondaryCallPhotoDimEffect = findViewById(R.id.dim_effect_for_secondary_photo);
+            mSecondaryCallPhotoDimEffect.setOnClickListener(mInCallScreen);
+            // Add a custom OnTouchListener to manually shrink the "hit target".
+            mSecondaryCallPhotoDimEffect.setOnTouchListener(new SmallerHitTargetTouchListener());
+        }
+        mInCallScreen.updateButtonStateOutsideInCallTouchUi();
+    }
+
+    /**
+     * Method which is expected to be called from
+     * {@link InCallScreen#updateButtonStateOutsideInCallTouchUi()}.
+     */
+    /* package */ void setSecondaryCallClickable(boolean clickable) {
+        if (mSecondaryCallPhotoDimEffect != null) {
+            mSecondaryCallPhotoDimEffect.setEnabled(clickable);
+        }
+    }
+
+    private String getCallFailedString(Call call) {
+        Connection c = call.getEarliestConnection();
+        int resID;
+
+        if (c == null) {
+            if (DBG) log("getCallFailedString: connection is null, using default values.");
+            // if this connection is null, just assume that the
+            // default case occurs.
+            resID = R.string.card_title_call_ended;
+        } else {
+
+            Connection.DisconnectCause cause = c.getDisconnectCause();
+
+            // TODO: The card *title* should probably be "Call ended" in all
+            // cases, but if the DisconnectCause was an error condition we should
+            // probably also display the specific failure reason somewhere...
+
+            switch (cause) {
+                case BUSY:
+                    resID = R.string.callFailed_userBusy;
+                    break;
+
+                case CONGESTION:
+                    resID = R.string.callFailed_congestion;
+                    break;
+
+                case TIMED_OUT:
+                    resID = R.string.callFailed_timedOut;
+                    break;
+
+                case SERVER_UNREACHABLE:
+                    resID = R.string.callFailed_server_unreachable;
+                    break;
+
+                case NUMBER_UNREACHABLE:
+                    resID = R.string.callFailed_number_unreachable;
+                    break;
+
+                case INVALID_CREDENTIALS:
+                    resID = R.string.callFailed_invalid_credentials;
+                    break;
+
+                case SERVER_ERROR:
+                    resID = R.string.callFailed_server_error;
+                    break;
+
+                case OUT_OF_NETWORK:
+                    resID = R.string.callFailed_out_of_network;
+                    break;
+
+                case LOST_SIGNAL:
+                case CDMA_DROP:
+                    resID = R.string.callFailed_noSignal;
+                    break;
+
+                case LIMIT_EXCEEDED:
+                    resID = R.string.callFailed_limitExceeded;
+                    break;
+
+                case POWER_OFF:
+                    resID = R.string.callFailed_powerOff;
+                    break;
+
+                case ICC_ERROR:
+                    resID = R.string.callFailed_simError;
+                    break;
+
+                case OUT_OF_SERVICE:
+                    resID = R.string.callFailed_outOfService;
+                    break;
+
+                case INVALID_NUMBER:
+                case UNOBTAINABLE_NUMBER:
+                    resID = R.string.callFailed_unobtainable_number;
+                    break;
+
+                default:
+                    resID = R.string.card_title_call_ended;
+                    break;
+            }
+        }
+        return getContext().getString(resID);
+    }
+
+    /**
+     * Updates the name / photo / number / label fields on the CallCard
+     * based on the specified CallerInfo.
+     *
+     * If the current call is a conference call, use
+     * updateDisplayForConference() instead.
+     */
+    private void updateDisplayForPerson(CallerInfo info,
+                                        int presentation,
+                                        boolean isTemporary,
+                                        Call call,
+                                        Connection conn) {
+        if (DBG) log("updateDisplayForPerson(" + info + ")\npresentation:" +
+                     presentation + " isTemporary:" + isTemporary);
+
+        // inform the state machine that we are displaying a photo.
+        mPhotoTracker.setPhotoRequest(info);
+        mPhotoTracker.setPhotoState(ContactsAsyncHelper.ImageTracker.DISPLAY_IMAGE);
+
+        // The actual strings we're going to display onscreen:
+        String displayName;
+        String displayNumber = null;
+        String label = null;
+        Uri personUri = null;
+        // String socialStatusText = null;
+        // Drawable socialStatusBadge = null;
+
+        // Gather missing info unless the call is generic, in which case we wouldn't use
+        // the gathered information anyway.
+        if (info != null && !call.isGeneric()) {
+
+            // It appears that there is a small change in behaviour with the
+            // PhoneUtils' startGetCallerInfo whereby if we query with an
+            // empty number, we will get a valid CallerInfo object, but with
+            // fields that are all null, and the isTemporary boolean input
+            // parameter as true.
+
+            // In the past, we would see a NULL callerinfo object, but this
+            // ends up causing null pointer exceptions elsewhere down the
+            // line in other cases, so we need to make this fix instead. It
+            // appears that this was the ONLY call to PhoneUtils
+            // .getCallerInfo() that relied on a NULL CallerInfo to indicate
+            // an unknown contact.
+
+            // Currently, infi.phoneNumber may actually be a SIP address, and
+            // if so, it might sometimes include the "sip:" prefix.  That
+            // prefix isn't really useful to the user, though, so strip it off
+            // if present.  (For any other URI scheme, though, leave the
+            // prefix alone.)
+            // TODO: It would be cleaner for CallerInfo to explicitly support
+            // SIP addresses instead of overloading the "phoneNumber" field.
+            // Then we could remove this hack, and instead ask the CallerInfo
+            // for a "user visible" form of the SIP address.
+            String number = info.phoneNumber;
+            if ((number != null) && number.startsWith("sip:")) {
+                number = number.substring(4);
+            }
+
+            if (TextUtils.isEmpty(info.name)) {
+                // No valid "name" in the CallerInfo, so fall back to
+                // something else.
+                // (Typically, we promote the phone number up to the "name" slot
+                // onscreen, and possibly display a descriptive string in the
+                // "number" slot.)
+                if (TextUtils.isEmpty(number)) {
+                    // No name *or* number!  Display a generic "unknown" string
+                    // (or potentially some other default based on the presentation.)
+                    displayName = PhoneUtils.getPresentationString(getContext(), presentation);
+                    if (DBG) log("  ==> no name *or* number! displayName = " + displayName);
+                } else if (presentation != PhoneConstants.PRESENTATION_ALLOWED) {
+                    // This case should never happen since the network should never send a phone #
+                    // AND a restricted presentation. However we leave it here in case of weird
+                    // network behavior
+                    displayName = PhoneUtils.getPresentationString(getContext(), presentation);
+                    if (DBG) log("  ==> presentation not allowed! displayName = " + displayName);
+                } else if (!TextUtils.isEmpty(info.cnapName)) {
+                    // No name, but we do have a valid CNAP name, so use that.
+                    displayName = info.cnapName;
+                    info.name = info.cnapName;
+                    displayNumber = number;
+                    if (DBG) log("  ==> cnapName available: displayName '"
+                                 + displayName + "', displayNumber '" + displayNumber + "'");
+                } else {
+                    // No name; all we have is a number.  This is the typical
+                    // case when an incoming call doesn't match any contact,
+                    // or if you manually dial an outgoing number using the
+                    // dialpad.
+
+                    // Promote the phone number up to the "name" slot:
+                    displayName = number;
+
+                    // ...and use the "number" slot for a geographical description
+                    // string if available (but only for incoming calls.)
+                    if ((conn != null) && (conn.isIncoming())) {
+                        // TODO (CallerInfoAsyncQuery cleanup): Fix the CallerInfo
+                        // query to only do the geoDescription lookup in the first
+                        // place for incoming calls.
+                        displayNumber = info.geoDescription;  // may be null
+                    }
+
+                    if (DBG) log("  ==>  no name; falling back to number: displayName '"
+                                 + displayName + "', displayNumber '" + displayNumber + "'");
+                }
+            } else {
+                // We do have a valid "name" in the CallerInfo.  Display that
+                // in the "name" slot, and the phone number in the "number" slot.
+                if (presentation != PhoneConstants.PRESENTATION_ALLOWED) {
+                    // This case should never happen since the network should never send a name
+                    // AND a restricted presentation. However we leave it here in case of weird
+                    // network behavior
+                    displayName = PhoneUtils.getPresentationString(getContext(), presentation);
+                    if (DBG) log("  ==> valid name, but presentation not allowed!"
+                                 + " displayName = " + displayName);
+                } else {
+                    displayName = info.name;
+                    displayNumber = number;
+                    label = info.phoneLabel;
+                    if (DBG) log("  ==>  name is present in CallerInfo: displayName '"
+                                 + displayName + "', displayNumber '" + displayNumber + "'");
+                }
+            }
+            personUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, info.person_id);
+            if (DBG) log("- got personUri: '" + personUri
+                         + "', based on info.person_id: " + info.person_id);
+        } else {
+            displayName = PhoneUtils.getPresentationString(getContext(), presentation);
+        }
+
+        if (call.isGeneric()) {
+            updateGenericInfoUi();
+        } else {
+            updateInfoUi(displayName, displayNumber, label);
+        }
+
+        // Update mPhoto
+        // if the temporary flag is set, we know we'll be getting another call after
+        // the CallerInfo has been correctly updated.  So, we can skip the image
+        // loading until then.
+
+        // If the photoResource is filled in for the CallerInfo, (like with the
+        // Emergency Number case), then we can just set the photo image without
+        // requesting for an image load. Please refer to CallerInfoAsyncQuery.java
+        // for cases where CallerInfo.photoResource may be set.  We can also avoid
+        // the image load step if the image data is cached.
+        if (isTemporary && (info == null || !info.isCachedPhotoCurrent)) {
+            mPhoto.setTag(null);
+            mPhoto.setVisibility(View.INVISIBLE);
+        } else if (info != null && info.photoResource != 0){
+            showImage(mPhoto, info.photoResource);
+        } else if (!showCachedImage(mPhoto, info)) {
+            if (personUri == null) {
+                Log.w(LOG_TAG, "personPri is null. Just use Unknown picture.");
+                showImage(mPhoto, R.drawable.picture_unknown);
+            } else if (personUri.equals(mLoadingPersonUri)) {
+                if (DBG) {
+                    log("The requested Uri (" + personUri + ") is being loaded already."
+                            + " Ignoret the duplicate load request.");
+                }
+            } else {
+                // Remember which person's photo is being loaded right now so that we won't issue
+                // unnecessary load request multiple times, which will mess up animation around
+                // the contact photo.
+                mLoadingPersonUri = personUri;
+
+                // Forget the drawable previously used.
+                mPhoto.setTag(null);
+                // Show empty screen for a moment.
+                mPhoto.setVisibility(View.INVISIBLE);
+                // Load the image with a callback to update the image state.
+                // When the load is finished, onImageLoadComplete() will be called.
+                ContactsAsyncHelper.startObtainPhotoAsync(TOKEN_UPDATE_PHOTO_FOR_CALL_STATE,
+                        getContext(), personUri, this, new AsyncLoadCookie(mPhoto, info, call));
+
+                // If the image load is too slow, we show a default avatar icon afterward.
+                // If it is fast enough, this message will be canceled on onImageLoadComplete().
+                mHandler.removeMessages(MESSAGE_SHOW_UNKNOWN_PHOTO);
+                mHandler.sendEmptyMessageDelayed(MESSAGE_SHOW_UNKNOWN_PHOTO, MESSAGE_DELAY);
+            }
+        }
+
+        // If the phone call is on hold, show it with darker status.
+        // Right now we achieve it by overlaying opaque View.
+        // Note: See also layout file about why so and what is the other possibilities.
+        if (call.getState() == Call.State.HOLDING) {
+            AnimationUtils.Fade.show(mPhotoDimEffect);
+        } else {
+            AnimationUtils.Fade.hide(mPhotoDimEffect, View.GONE);
+        }
+
+        // Other text fields:
+        updateCallTypeLabel(call);
+        // updateSocialStatus(socialStatusText, socialStatusBadge, call);  // Currently unused
+    }
+
+    /**
+     * Updates the info portion of the UI to be generic.  Used for CDMA 3-way calls.
+     */
+    private void updateGenericInfoUi() {
+        mName.setText(R.string.card_title_in_call);
+        mPhoneNumber.setVisibility(View.GONE);
+        mLabel.setVisibility(View.GONE);
+    }
+
+    /**
+     * Updates the info portion of the call card with passed in values.
+     */
+    private void updateInfoUi(String displayName, String displayNumber, String label) {
+        mName.setText(displayName);
+        mName.setVisibility(View.VISIBLE);
+
+        if (TextUtils.isEmpty(displayNumber)) {
+            mPhoneNumber.setVisibility(View.GONE);
+            // We have a real phone number as "mName" so make it always LTR
+            mName.setTextDirection(View.TEXT_DIRECTION_LTR);
+        } else {
+            mPhoneNumber.setText(displayNumber);
+            mPhoneNumber.setVisibility(View.VISIBLE);
+            // We have a real phone number as "mPhoneNumber" so make it always LTR
+            mPhoneNumber.setTextDirection(View.TEXT_DIRECTION_LTR);
+        }
+
+        if (TextUtils.isEmpty(label)) {
+            mLabel.setVisibility(View.GONE);
+        } else {
+            mLabel.setText(label);
+            mLabel.setVisibility(View.VISIBLE);
+        }
+    }
+
+    /**
+     * Updates the name / photo / number / label fields
+     * for the special "conference call" state.
+     *
+     * If the current call has only a single connection, use
+     * updateDisplayForPerson() instead.
+     */
+    private void updateDisplayForConference(Call call) {
+        if (DBG) log("updateDisplayForConference()...");
+
+        int phoneType = call.getPhone().getPhoneType();
+        if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
+            // This state corresponds to both 3-Way merged call and
+            // Call Waiting accepted call.
+            // In this case we display the UI in a "generic" state, with
+            // the generic "dialing" icon and no caller information,
+            // because in this state in CDMA the user does not really know
+            // which caller party he is talking to.
+            showImage(mPhoto, R.drawable.picture_dialing);
+            mName.setText(R.string.card_title_in_call);
+        } else if ((phoneType == PhoneConstants.PHONE_TYPE_GSM)
+                || (phoneType == PhoneConstants.PHONE_TYPE_SIP)) {
+            // Normal GSM (or possibly SIP?) conference call.
+            // Display the "conference call" image as the contact photo.
+            // TODO: Better visual treatment for contact photos in a
+            // conference call (see bug 1313252).
+            showImage(mPhoto, R.drawable.picture_conference);
+            mName.setText(R.string.card_title_conf_call);
+        } else {
+            throw new IllegalStateException("Unexpected phone type: " + phoneType);
+        }
+
+        mName.setVisibility(View.VISIBLE);
+
+        // TODO: For a conference call, the "phone number" slot is specced
+        // to contain a summary of who's on the call, like "Bill Foldes
+        // and Hazel Nutt" or "Bill Foldes and 2 others".
+        // But for now, just hide it:
+        mPhoneNumber.setVisibility(View.GONE);
+        mLabel.setVisibility(View.GONE);
+
+        // Other text fields:
+        updateCallTypeLabel(call);
+        // updateSocialStatus(null, null, null);  // socialStatus is never visible in this state
+
+        // TODO: for a GSM conference call, since we do actually know who
+        // you're talking to, consider also showing names / numbers /
+        // photos of some of the people on the conference here, so you can
+        // see that info without having to click "Manage conference".  We
+        // probably have enough space to show info for 2 people, at least.
+        //
+        // To do this, our caller would pass us the activeConnections
+        // list, and we'd call PhoneUtils.getCallerInfo() separately for
+        // each connection.
+    }
+
+    /**
+     * Updates the CallCard "photo" IFF the specified Call is in a state
+     * that needs a special photo (like "busy" or "dialing".)
+     *
+     * If the current call does not require a special image in the "photo"
+     * slot onscreen, don't do anything, since presumably the photo image
+     * has already been set (to the photo of the person we're talking, or
+     * the generic "picture_unknown" image, or the "conference call"
+     * image.)
+     */
+    private void updatePhotoForCallState(Call call) {
+        if (DBG) log("updatePhotoForCallState(" + call + ")...");
+        int photoImageResource = 0;
+
+        // Check for the (relatively few) telephony states that need a
+        // special image in the "photo" slot.
+        Call.State state = call.getState();
+        switch (state) {
+            case DISCONNECTED:
+                // Display the special "busy" photo for BUSY or CONGESTION.
+                // Otherwise (presumably the normal "call ended" state)
+                // leave the photo alone.
+                Connection c = call.getEarliestConnection();
+                // if the connection is null, we assume the default case,
+                // otherwise update the image resource normally.
+                if (c != null) {
+                    Connection.DisconnectCause cause = c.getDisconnectCause();
+                    if ((cause == Connection.DisconnectCause.BUSY)
+                        || (cause == Connection.DisconnectCause.CONGESTION)) {
+                        photoImageResource = R.drawable.picture_busy;
+                    }
+                } else if (DBG) {
+                    log("updatePhotoForCallState: connection is null, ignoring.");
+                }
+
+                // TODO: add special images for any other DisconnectCauses?
+                break;
+
+            case ALERTING:
+            case DIALING:
+            default:
+                // Leave the photo alone in all other states.
+                // If this call is an individual call, and the image is currently
+                // displaying a state, (rather than a photo), we'll need to update
+                // the image.
+                // This is for the case where we've been displaying the state and
+                // now we need to restore the photo.  This can happen because we
+                // only query the CallerInfo once, and limit the number of times
+                // the image is loaded. (So a state image may overwrite the photo
+                // and we would otherwise have no way of displaying the photo when
+                // the state goes away.)
+
+                // if the photoResource field is filled-in in the Connection's
+                // caller info, then we can just use that instead of requesting
+                // for a photo load.
+
+                // look for the photoResource if it is available.
+                CallerInfo ci = null;
+                {
+                    Connection conn = null;
+                    int phoneType = call.getPhone().getPhoneType();
+                    if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
+                        conn = call.getLatestConnection();
+                    } else if ((phoneType == PhoneConstants.PHONE_TYPE_GSM)
+                            || (phoneType == PhoneConstants.PHONE_TYPE_SIP)) {
+                        conn = call.getEarliestConnection();
+                    } else {
+                        throw new IllegalStateException("Unexpected phone type: " + phoneType);
+                    }
+
+                    if (conn != null) {
+                        Object o = conn.getUserData();
+                        if (o instanceof CallerInfo) {
+                            ci = (CallerInfo) o;
+                        } else if (o instanceof PhoneUtils.CallerInfoToken) {
+                            ci = ((PhoneUtils.CallerInfoToken) o).currentInfo;
+                        }
+                    }
+                }
+
+                if (ci != null) {
+                    photoImageResource = ci.photoResource;
+                }
+
+                // If no photoResource found, check to see if this is a conference call. If
+                // it is not a conference call:
+                //   1. Try to show the cached image
+                //   2. If the image is not cached, check to see if a load request has been
+                //      made already.
+                //   3. If the load request has not been made [DISPLAY_DEFAULT], start the
+                //      request and note that it has started by updating photo state with
+                //      [DISPLAY_IMAGE].
+                if (photoImageResource == 0) {
+                    if (!PhoneUtils.isConferenceCall(call)) {
+                        if (!showCachedImage(mPhoto, ci) && (mPhotoTracker.getPhotoState() ==
+                                ContactsAsyncHelper.ImageTracker.DISPLAY_DEFAULT)) {
+                            Uri photoUri = mPhotoTracker.getPhotoUri();
+                            if (photoUri == null) {
+                                Log.w(LOG_TAG, "photoUri became null. Show default avatar icon");
+                                showImage(mPhoto, R.drawable.picture_unknown);
+                            } else {
+                                if (DBG) {
+                                    log("start asynchronous load inside updatePhotoForCallState()");
+                                }
+                                mPhoto.setTag(null);
+                                // Make it invisible for a moment
+                                mPhoto.setVisibility(View.INVISIBLE);
+                                ContactsAsyncHelper.startObtainPhotoAsync(TOKEN_DO_NOTHING,
+                                        getContext(), photoUri, this,
+                                        new AsyncLoadCookie(mPhoto, ci, null));
+                            }
+                            mPhotoTracker.setPhotoState(
+                                    ContactsAsyncHelper.ImageTracker.DISPLAY_IMAGE);
+                        }
+                    }
+                } else {
+                    showImage(mPhoto, photoImageResource);
+                    mPhotoTracker.setPhotoState(ContactsAsyncHelper.ImageTracker.DISPLAY_IMAGE);
+                    return;
+                }
+                break;
+        }
+
+        if (photoImageResource != 0) {
+            if (DBG) log("- overrriding photo image: " + photoImageResource);
+            showImage(mPhoto, photoImageResource);
+            // Track the image state.
+            mPhotoTracker.setPhotoState(ContactsAsyncHelper.ImageTracker.DISPLAY_DEFAULT);
+        }
+    }
+
+    /**
+     * Try to display the cached image from the callerinfo object.
+     *
+     *  @return true if we were able to find the image in the cache, false otherwise.
+     */
+    private static final boolean showCachedImage(ImageView view, CallerInfo ci) {
+        if ((ci != null) && ci.isCachedPhotoCurrent) {
+            if (ci.cachedPhoto != null) {
+                showImage(view, ci.cachedPhoto);
+            } else {
+                showImage(view, R.drawable.picture_unknown);
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /** Helper function to display the resource in the imageview AND ensure its visibility.*/
+    private static final void showImage(ImageView view, int resource) {
+        showImage(view, view.getContext().getResources().getDrawable(resource));
+    }
+
+    private static final void showImage(ImageView view, Bitmap bitmap) {
+        showImage(view, new BitmapDrawable(view.getContext().getResources(), bitmap));
+    }
+
+    /** Helper function to display the drawable in the imageview AND ensure its visibility.*/
+    private static final void showImage(ImageView view, Drawable drawable) {
+        Resources res = view.getContext().getResources();
+        Drawable current = (Drawable) view.getTag();
+
+        if (current == null) {
+            if (DBG) log("Start fade-in animation for " + view);
+            view.setImageDrawable(drawable);
+            AnimationUtils.Fade.show(view);
+            view.setTag(drawable);
+        } else {
+            AnimationUtils.startCrossFade(view, current, drawable);
+            view.setVisibility(View.VISIBLE);
+        }
+    }
+
+    /**
+     * Returns the special card title used in emergency callback mode (ECM),
+     * which shows your own phone number.
+     */
+    private String getECMCardTitle(Context context, Phone phone) {
+        String rawNumber = phone.getLine1Number();  // may be null or empty
+        String formattedNumber;
+        if (!TextUtils.isEmpty(rawNumber)) {
+            formattedNumber = PhoneNumberUtils.formatNumber(rawNumber);
+        } else {
+            formattedNumber = context.getString(R.string.unknown);
+        }
+        String titleFormat = context.getString(R.string.card_title_my_phone_number);
+        return String.format(titleFormat, formattedNumber);
+    }
+
+    /**
+     * Updates the "Call type" label, based on the current foreground call.
+     * This is a special label and/or branding we display for certain
+     * kinds of calls.
+     *
+     * (So far, this is used only for SIP calls, which get an
+     * "Internet call" label.  TODO: But eventually, the telephony
+     * layer might allow each pluggable "provider" to specify a string
+     * and/or icon to be displayed here.)
+     */
+    private void updateCallTypeLabel(Call call) {
+        int phoneType = (call != null) ? call.getPhone().getPhoneType() :
+                PhoneConstants.PHONE_TYPE_NONE;
+        if (phoneType == PhoneConstants.PHONE_TYPE_SIP) {
+            mCallTypeLabel.setVisibility(View.VISIBLE);
+            mCallTypeLabel.setText(R.string.incall_call_type_label_sip);
+            mCallTypeLabel.setTextColor(mTextColorCallTypeSip);
+            // If desired, we could also display a "badge" next to the label, as follows:
+            //   mCallTypeLabel.setCompoundDrawablesWithIntrinsicBounds(
+            //           callTypeSpecificBadge, null, null, null);
+            //   mCallTypeLabel.setCompoundDrawablePadding((int) (mDensity * 6));
+        } else {
+            mCallTypeLabel.setVisibility(View.GONE);
+        }
+    }
+
+    /**
+     * Updates the "social status" label with the specified text and
+     * (optional) badge.
+     */
+    /*private void updateSocialStatus(String socialStatusText,
+                                    Drawable socialStatusBadge,
+                                    Call call) {
+        // The socialStatus field is *only* visible while an incoming call
+        // is ringing, never in any other call state.
+        if ((socialStatusText != null)
+                && (call != null)
+                && call.isRinging()
+                && !call.isGeneric()) {
+            mSocialStatus.setVisibility(View.VISIBLE);
+            mSocialStatus.setText(socialStatusText);
+            mSocialStatus.setCompoundDrawablesWithIntrinsicBounds(
+                    socialStatusBadge, null, null, null);
+            mSocialStatus.setCompoundDrawablePadding((int) (mDensity * 6));
+        } else {
+            mSocialStatus.setVisibility(View.GONE);
+        }
+    }*/
+
+    /**
+     * Hides the top-level UI elements of the call card:  The "main
+     * call card" element representing the current active or ringing call,
+     * and also the info areas for "ongoing" or "on hold" calls in some
+     * states.
+     *
+     * This is intended to be used in special states where the normal
+     * in-call UI is totally replaced by some other UI, like OTA mode on a
+     * CDMA device.
+     *
+     * To bring back the regular CallCard UI, just re-run the normal
+     * updateState() call sequence.
+     */
+    public void hideCallCardElements() {
+        mPrimaryCallInfo.setVisibility(View.GONE);
+        mSecondaryCallInfo.setVisibility(View.GONE);
+    }
+
+    /*
+     * Updates the hint (like "Rotate to answer") that we display while
+     * the user is dragging the incoming call RotarySelector widget.
+     */
+    /* package */ void setIncomingCallWidgetHint(int hintTextResId, int hintColorResId) {
+        mIncomingCallWidgetHintTextResId = hintTextResId;
+        mIncomingCallWidgetHintColorResId = hintColorResId;
+    }
+
+    // Accessibility event support.
+    // Since none of the CallCard elements are focusable, we need to manually
+    // fill in the AccessibilityEvent here (so that the name / number / etc will
+    // get pronounced by a screen reader, for example.)
+    @Override
+    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+        if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
+            dispatchPopulateAccessibilityEvent(event, mName);
+            dispatchPopulateAccessibilityEvent(event, mPhoneNumber);
+            return true;
+        }
+
+        dispatchPopulateAccessibilityEvent(event, mCallStateLabel);
+        dispatchPopulateAccessibilityEvent(event, mPhoto);
+        dispatchPopulateAccessibilityEvent(event, mName);
+        dispatchPopulateAccessibilityEvent(event, mPhoneNumber);
+        dispatchPopulateAccessibilityEvent(event, mLabel);
+        // dispatchPopulateAccessibilityEvent(event, mSocialStatus);
+        if (mSecondaryCallName != null) {
+            dispatchPopulateAccessibilityEvent(event, mSecondaryCallName);
+        }
+        if (mSecondaryCallPhoto != null) {
+            dispatchPopulateAccessibilityEvent(event, mSecondaryCallPhoto);
+        }
+        return true;
+    }
+
+    private void dispatchPopulateAccessibilityEvent(AccessibilityEvent event, View view) {
+        List<CharSequence> eventText = event.getText();
+        int size = eventText.size();
+        view.dispatchPopulateAccessibilityEvent(event);
+        // if no text added write null to keep relative position
+        if (size == eventText.size()) {
+            eventText.add(null);
+        }
+    }
+
+    public void clear() {
+        // The existing phone design is to keep an instance of call card forever.  Until that
+        // design changes, this method is needed to clear (reset) the call card for the next call
+        // so old data is not shown.
+
+        // Other elements can also be cleared here.  Starting with elapsed time to fix a bug.
+        mElapsedTime.setVisibility(View.GONE);
+        mElapsedTime.setText(null);
+    }
+
+
+    // Debugging / testing code
+
+    private static void log(String msg) {
+        Log.d(LOG_TAG, msg);
+    }
+}
diff --git a/src/com/android/phone/CallController.java b/src/com/android/phone/CallController.java
new file mode 100644
index 0000000..11340aa
--- /dev/null
+++ b/src/com/android/phone/CallController.java
@@ -0,0 +1,793 @@
+/*
+ * 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.internal.telephony.CallManager;
+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 android.content.Intent;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Message;
+import android.os.SystemProperties;
+import android.provider.CallLog.Calls;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.ServiceState;
+import android.text.TextUtils;
+import android.util.Log;
+import android.widget.Toast;
+
+/**
+ * Phone app module in charge of "call control".
+ *
+ * This is a singleton object which acts as the interface to the telephony layer
+ * (and other parts of the Android framework) for all user-initiated telephony
+ * functionality, like making outgoing calls.
+ *
+ * This functionality includes things like:
+ *   - actually running the placeCall() method and handling errors or retries
+ *   - running the whole "emergency call in airplane mode" sequence
+ *   - running the state machine of MMI sequences
+ *   - restoring/resetting mute and speaker state when a new call starts
+ *   - updating the prox sensor wake lock state
+ *   - resolving what the voicemail: intent should mean (and making the call)
+ *
+ * The single CallController instance stays around forever; it's not tied
+ * to the lifecycle of any particular Activity (like the InCallScreen).
+ * There's also no implementation of onscreen UI here (that's all in InCallScreen).
+ *
+ * Note that this class does not handle asynchronous events from the telephony
+ * layer, like reacting to an incoming call; see CallNotifier for that.  This
+ * class purely handles actions initiated by the user, like outgoing calls.
+ */
+public class CallController extends Handler {
+    private static final String TAG = "CallController";
+    private static final boolean DBG =
+            (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
+    // Do not check in with VDBG = true, since that may write PII to the system log.
+    private static final boolean VDBG = false;
+
+    /** The singleton CallController instance. */
+    private static CallController sInstance;
+
+    private PhoneGlobals mApp;
+    private CallManager mCM;
+    private CallLogger mCallLogger;
+
+    /** Helper object for emergency calls in some rare use cases.  Created lazily. */
+    private EmergencyCallHelper mEmergencyCallHelper;
+
+
+    //
+    // Message codes; see handleMessage().
+    //
+
+    private static final int THREEWAY_CALLERINFO_DISPLAY_DONE = 1;
+
+
+    //
+    // Misc constants.
+    //
+
+    // Amount of time the UI should display "Dialing" when initiating a CDMA
+    // 3way call.  (See comments on the THRWAY_ACTIVE case in
+    // placeCallInternal() for more info.)
+    private static final int THREEWAY_CALLERINFO_DISPLAY_TIME = 3000; // msec
+
+
+    /**
+     * Initialize the singleton CallController instance.
+     *
+     * This is only done once, at startup, from PhoneApp.onCreate().
+     * From then on, the CallController instance is available via the
+     * PhoneApp's public "callController" field, which is why there's no
+     * getInstance() method here.
+     */
+    /* package */ static CallController init(PhoneGlobals app, CallLogger callLogger) {
+        synchronized (CallController.class) {
+            if (sInstance == null) {
+                sInstance = new CallController(app, callLogger);
+            } else {
+                Log.wtf(TAG, "init() called multiple times!  sInstance = " + sInstance);
+            }
+            return sInstance;
+        }
+    }
+
+    /**
+     * Private constructor (this is a singleton).
+     * @see init()
+     */
+    private CallController(PhoneGlobals app, CallLogger callLogger) {
+        if (DBG) log("CallController constructor: app = " + app);
+        mApp = app;
+        mCM = app.mCM;
+        mCallLogger = callLogger;
+    }
+
+    @Override
+    public void handleMessage(Message msg) {
+        if (VDBG) log("handleMessage: " + msg);
+        switch (msg.what) {
+
+            case THREEWAY_CALLERINFO_DISPLAY_DONE:
+                if (DBG) log("THREEWAY_CALLERINFO_DISPLAY_DONE...");
+
+                if (mApp.cdmaPhoneCallState.getCurrentCallState()
+                    == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
+                    // Reset the mThreeWayCallOrigStateDialing state
+                    mApp.cdmaPhoneCallState.setThreeWayCallOrigState(false);
+
+                    // Refresh the in-call UI (based on the current ongoing call)
+                    mApp.updateInCallScreen();
+                }
+                break;
+
+            default:
+                Log.wtf(TAG, "handleMessage: unexpected code: " + msg);
+                break;
+        }
+    }
+
+    //
+    // Outgoing call sequence
+    //
+
+    /**
+     * Initiate an outgoing call.
+     *
+     * Here's the most typical outgoing call sequence:
+     *
+     *  (1) OutgoingCallBroadcaster receives a CALL intent and sends the
+     *      NEW_OUTGOING_CALL broadcast
+     *
+     *  (2) The broadcast finally reaches OutgoingCallReceiver, which stashes
+     *      away a copy of the original CALL intent and launches
+     *      SipCallOptionHandler
+     *
+     *  (3) SipCallOptionHandler decides whether this is a PSTN or SIP call (and
+     *      in some cases brings up a dialog to let the user choose), and
+     *      ultimately calls CallController.placeCall() (from the
+     *      setResultAndFinish() method) with the stashed-away intent from step
+     *      (2) as the "intent" parameter.
+     *
+     *  (4) Here in CallController.placeCall() we read the phone number or SIP
+     *      address out of the intent and actually initiate the call, and
+     *      simultaneously launch the InCallScreen to display the in-call UI.
+     *
+     *  (5) We handle various errors by directing the InCallScreen to
+     *      display error messages or dialogs (via the InCallUiState
+     *      "pending call status code" flag), and in some cases we also
+     *      sometimes continue working in the background to resolve the
+     *      problem (like in the case of an emergency call while in
+     *      airplane mode).  Any time that some onscreen indication to the
+     *      user needs to change, we update the "status dialog" info in
+     *      the inCallUiState and (re)launch the InCallScreen to make sure
+     *      it's visible.
+     */
+    public void placeCall(Intent intent) {
+        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?)
+
+        if (intent == null) {
+            Log.wtf(TAG, "placeCall: called with null intent");
+            throw new IllegalArgumentException("placeCall: called with null intent");
+        }
+
+        String action = intent.getAction();
+        Uri uri = intent.getData();
+        if (uri == null) {
+            Log.wtf(TAG, "placeCall: intent had no data");
+            throw new IllegalArgumentException("placeCall: intent had no data");
+        }
+
+        String scheme = uri.getScheme();
+        String number = PhoneNumberUtils.getNumberFromIntent(intent, mApp);
+        if (VDBG) {
+            log("- action: " + action);
+            log("- uri: " + uri);
+            log("- scheme: " + scheme);
+            log("- number: " + number);
+        }
+
+        // This method should only be used with the various flavors of CALL
+        // intents.  (It doesn't make sense for any other action to trigger an
+        // outgoing call!)
+        if (!(Intent.ACTION_CALL.equals(action)
+              || Intent.ACTION_CALL_EMERGENCY.equals(action)
+              || Intent.ACTION_CALL_PRIVILEGED.equals(action))) {
+            Log.wtf(TAG, "placeCall: unexpected intent action " + action);
+            throw new IllegalArgumentException("Unexpected action: " + action);
+        }
+
+        // Check to see if this is an OTASP call (the "activation" call
+        // used to provision CDMA devices), and if so, do some
+        // OTASP-specific setup.
+        Phone phone = mApp.mCM.getDefaultPhone();
+        if (TelephonyCapabilities.supportsOtasp(phone)) {
+            checkForOtaspCall(intent);
+        }
+
+        // Clear out the "restore mute state" flag since we're
+        // initiating a brand-new call.
+        //
+        // (This call to setRestoreMuteOnInCallResume(false) informs the
+        // phone app that we're dealing with a new connection
+        // (i.e. placing an outgoing call, and NOT handling an aborted
+        // "Add Call" request), so we should let the mute state be handled
+        // by the PhoneUtils phone state change handler.)
+        mApp.setRestoreMuteOnInCallResume(false);
+
+        // If a provider is used, extract the info to build the
+        // overlay and route the call.  The overlay will be
+        // displayed when the InCallScreen becomes visible.
+        if (PhoneUtils.hasPhoneProviderExtras(intent)) {
+            inCallUiState.setProviderInfo(intent);
+        } else {
+            inCallUiState.clearProviderInfo();
+        }
+
+        CallStatusCode status = placeCallInternal(intent);
+
+        switch (status) {
+            // Call was placed successfully:
+            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();
+                }
+
+                // Notify the phone app that a call is beginning so it can
+                // enable the proximity sensor
+                mApp.setBeginningCall(true);
+                break;
+
+            default:
+                // Any other status code is a failure.
+                log("==> placeCall(): failure code from placeCallInternal(): " + status);
+                // Handle the various error conditions that can occur when
+                // initiating an outgoing call, typically by directing the
+                // InCallScreen to display a diagnostic message (via the
+                // "pending call status code" flag.)
+                handleOutgoingCallError(status);
+                break;
+        }
+
+        // Finally, regardless of whether we successfully initiated the
+        // outgoing call or not, force the InCallScreen to come to the
+        // foreground.
+        //
+        // (For successful calls the the user will just see the normal
+        // 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();
+    }
+
+    /**
+     * Actually make a call to whomever the intent tells us to.
+     *
+     * Note that there's no need to explicitly update (or refresh) the
+     * in-call UI at any point in this method, since a fresh InCallScreen
+     * instance will be launched automatically after we return (see
+     * placeCall() above.)
+     *
+     * @param intent the CALL intent describing whom to call
+     * @return CallStatusCode.SUCCESS if we successfully initiated an
+     *    outgoing call.  If there was some kind of failure, return one of
+     *    the other CallStatusCode codes indicating what went wrong.
+     */
+    private CallStatusCode placeCallInternal(Intent intent) {
+        if (DBG) log("placeCallInternal()...  intent = " + intent);
+
+        // 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;
+        Phone phone = null;
+
+        // Check the current ServiceState to make sure it's OK
+        // to even try making a call.
+        CallStatusCode okToCallStatus = checkIfOkToInitiateOutgoingCall(
+                mCM.getServiceState());
+
+        // TODO: Streamline the logic here.  Currently, the code is
+        // unchanged from its original form in InCallScreen.java.  But we
+        // should fix a couple of things:
+        // - Don't call checkIfOkToInitiateOutgoingCall() more than once
+        // - Wrap the try/catch for VoiceMailNumberMissingException
+        //   around *only* the call that can throw that exception.
+
+        try {
+            number = PhoneUtils.getInitialNumber(intent);
+            if (VDBG) log("- actual number to dial: '" + number + "'");
+
+            // find the phone first
+            // TODO Need a way to determine which phone to place the call
+            // It could be determined by SIP setting, i.e. always,
+            // or by number, i.e. for international,
+            // or by user selection, i.e., dialog query,
+            // or any of combinations
+            String sipPhoneUri = intent.getStringExtra(
+                    OutgoingCallBroadcaster.EXTRA_SIP_PHONE_URI);
+            phone = PhoneUtils.pickPhoneBasedOnNumber(mCM, scheme, number, sipPhoneUri);
+            if (VDBG) log("- got Phone instance: " + phone + ", class = " + phone.getClass());
+
+            // update okToCallStatus based on new phone
+            okToCallStatus = checkIfOkToInitiateOutgoingCall(
+                    phone.getServiceState().getState());
+
+        } catch (PhoneUtils.VoiceMailNumberMissingException ex) {
+            // If the call status is NOT in an acceptable state, it
+            // may effect the way the voicemail number is being
+            // retrieved.  Mask the VoiceMailNumberMissingException
+            // with the underlying issue of the phone state.
+            if (okToCallStatus != CallStatusCode.SUCCESS) {
+                if (DBG) log("Voicemail number not reachable in current SIM card state.");
+                return okToCallStatus;
+            }
+            if (DBG) log("VoiceMailNumberMissingException from getInitialNumber()");
+            return CallStatusCode.VOICEMAIL_NUMBER_MISSING;
+        }
+
+        if (number == null) {
+            Log.w(TAG, "placeCall: couldn't get a phone number from Intent " + intent);
+            return CallStatusCode.NO_PHONE_NUMBER_SUPPLIED;
+        }
+
+
+        // Sanity-check that ACTION_CALL_EMERGENCY is used if and only if
+        // this is a call to an emergency number
+        // (This is just a sanity-check; this policy *should* really be
+        // enforced in OutgoingCallBroadcaster.onCreate(), which is the
+        // main entry point for the CALL and CALL_* intents.)
+        boolean isEmergencyNumber = PhoneNumberUtils.isLocalEmergencyNumber(number, mApp);
+        boolean isPotentialEmergencyNumber =
+                PhoneNumberUtils.isPotentialLocalEmergencyNumber(number, mApp);
+        boolean isEmergencyIntent = Intent.ACTION_CALL_EMERGENCY.equals(intent.getAction());
+
+        if (isPotentialEmergencyNumber && !isEmergencyIntent) {
+            Log.e(TAG, "Non-CALL_EMERGENCY Intent " + intent
+                    + " attempted to call potential emergency number " + number
+                    + ".");
+            return CallStatusCode.CALL_FAILED;
+        } else if (!isPotentialEmergencyNumber && isEmergencyIntent) {
+            Log.e(TAG, "Received CALL_EMERGENCY Intent " + intent
+                    + " with non-potential-emergency number " + number
+                    + " -- failing call.");
+            return CallStatusCode.CALL_FAILED;
+        }
+
+        // If we're trying to call an emergency number, then it's OK to
+        // proceed in certain states where we'd otherwise bring up
+        // an error dialog:
+        // - If we're in EMERGENCY_ONLY mode, then (obviously) you're allowed
+        //   to dial emergency numbers.
+        // - If we're OUT_OF_SERVICE, we still attempt to make a call,
+        //   since the radio will register to any available network.
+
+        if (isEmergencyNumber
+            && ((okToCallStatus == CallStatusCode.EMERGENCY_ONLY)
+                || (okToCallStatus == CallStatusCode.OUT_OF_SERVICE))) {
+            if (DBG) log("placeCall: Emergency number detected with status = " + okToCallStatus);
+            okToCallStatus = CallStatusCode.SUCCESS;
+            if (DBG) log("==> UPDATING status to: " + okToCallStatus);
+        }
+
+        if (okToCallStatus != CallStatusCode.SUCCESS) {
+            // If this is an emergency call, launch the EmergencyCallHelperService
+            // to turn on the radio and retry the call.
+            if (isEmergencyNumber && (okToCallStatus == CallStatusCode.POWER_OFF)) {
+                Log.i(TAG, "placeCall: Trying to make emergency call while POWER_OFF!");
+
+                // If needed, lazily instantiate an EmergencyCallHelper instance.
+                synchronized (this) {
+                    if (mEmergencyCallHelper == null) {
+                        mEmergencyCallHelper = new EmergencyCallHelper(this);
+                    }
+                }
+
+                // ...and kick off the "emergency call from airplane mode" sequence.
+                mEmergencyCallHelper.startEmergencyCallFromAirplaneModeSequence(number);
+
+                // Finally, return CallStatusCode.SUCCESS right now so
+                // that the in-call UI will remain visible (in order to
+                // display the progress indication.)
+                // TODO: or maybe it would be more clear to return a whole
+                // new CallStatusCode called "TURNING_ON_RADIO" here.
+                // That way, we'd update inCallUiState.progressIndication from
+                // the handleOutgoingCallError() method, rather than here.
+                return CallStatusCode.SUCCESS;
+            } else {
+                // Otherwise, just return the (non-SUCCESS) status code
+                // back to our caller.
+                if (DBG) log("==> placeCallInternal(): non-success status: " + okToCallStatus);
+
+                // Log failed call.
+                // Note: Normally, many of these values we gather from the Connection object but
+                // since no such object is created for unconnected calls, we have to build them
+                // manually.
+                // TODO(santoscordon): Try to restructure code so that we can handle failure-
+                // condition call logging in a single place (placeCall()) that also has access to
+                // the number we attempted to dial (not placeCall()).
+                mCallLogger.logCall(null /* callerInfo */, number, 0 /* presentation */,
+                        Calls.OUTGOING_TYPE, System.currentTimeMillis(), 0 /* duration */);
+
+                return okToCallStatus;
+            }
+        }
+
+        // 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
+        // phone number to use for the outgoing call.
+        Uri contactUri = intent.getData();
+
+        // Watch out: PhoneUtils.placeCall() returns one of the
+        // CALL_STATUS_* constants, not a CallStatusCode enum value.
+        int callStatus = PhoneUtils.placeCall(mApp,
+                                              phone,
+                                              number,
+                                              contactUri,
+                                              (isEmergencyNumber || isEmergencyIntent),
+                                              inCallUiState.providerGatewayUri);
+
+        switch (callStatus) {
+            case PhoneUtils.CALL_STATUS_DIALED:
+                if (VDBG) log("placeCall: PhoneUtils.placeCall() succeeded for regular call '"
+                             + number + "'.");
+
+
+                // TODO(OTASP): still need more cleanup to simplify the mApp.cdma*State objects:
+                // - Rather than checking inCallUiState.inCallScreenMode, the
+                //   code here could also check for
+                //   app.getCdmaOtaInCallScreenUiState() returning NORMAL.
+                // - But overall, app.inCallUiState.inCallScreenMode and
+                //   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
+                // *cancels* ECM.  So warn the user about it.
+                // (See InCallScreen.showExitingECMDialog() for more info.)
+                boolean exitedEcm = false;
+                if (PhoneUtils.isPhoneInEcm(phone) && !isEmergencyNumber) {
+                    Log.i(TAG, "About to exit ECM because of an outgoing non-emergency call");
+                    exitedEcm = true;  // this will cause us to return EXITED_ECM from this method
+                }
+
+                if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
+                    // Start the timer for 3 Way CallerInfo
+                    if (mApp.cdmaPhoneCallState.getCurrentCallState()
+                            == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
+                        //Unmute for the second MO call
+                        PhoneUtils.setMute(false);
+
+                        // This is a "CDMA 3-way call", which means that you're dialing a
+                        // 2nd outgoing call while a previous call is already in progress.
+                        //
+                        // Due to the limitations of CDMA this call doesn't actually go
+                        // through the DIALING/ALERTING states, so we can't tell for sure
+                        // when (or if) it's actually answered.  But we want to show
+                        // *some* indication of what's going on in the UI, so we "fake it"
+                        // by displaying the "Dialing" state for 3 seconds.
+
+                        // Set the mThreeWayCallOrigStateDialing state to true
+                        mApp.cdmaPhoneCallState.setThreeWayCallOrigState(true);
+
+                        // Schedule the "Dialing" indication to be taken down in 3 seconds:
+                        sendEmptyMessageDelayed(THREEWAY_CALLERINFO_DISPLAY_DONE,
+                                                THREEWAY_CALLERINFO_DISPLAY_TIME);
+                    }
+                }
+
+                // Success!
+                if (exitedEcm) {
+                    return CallStatusCode.EXITED_ECM;
+                } else {
+                    return CallStatusCode.SUCCESS;
+                }
+
+            case PhoneUtils.CALL_STATUS_DIALED_MMI:
+                if (DBG) log("placeCall: specified number was an MMI code: '" + number + "'.");
+                // The passed-in number was an MMI code, not a regular phone number!
+                // This isn't really a failure; the Dialer may have deliberately
+                // fired an ACTION_CALL intent to dial an MMI code, like for a
+                // USSD call.
+                //
+                // Presumably an MMI_INITIATE message will come in shortly
+                // (and we'll bring up the "MMI Started" dialog), or else
+                // an MMI_COMPLETE will come in (which will take us to a
+                // different Activity; see PhoneUtils.displayMMIComplete()).
+                return CallStatusCode.DIALED_MMI;
+
+            case PhoneUtils.CALL_STATUS_FAILED:
+                Log.w(TAG, "placeCall: PhoneUtils.placeCall() FAILED for number '"
+                      + number + "'.");
+                // We couldn't successfully place the call; there was some
+                // failure in the telephony layer.
+
+                // Log failed call.
+                mCallLogger.logCall(null /* callerInfo */, number, 0 /* presentation */,
+                        Calls.OUTGOING_TYPE, System.currentTimeMillis(), 0 /* duration */);
+
+                return CallStatusCode.CALL_FAILED;
+
+            default:
+                Log.wtf(TAG, "placeCall: unknown callStatus " + callStatus
+                        + " from PhoneUtils.placeCall() for number '" + number + "'.");
+                return CallStatusCode.SUCCESS;  // Try to continue anyway...
+        }
+    }
+
+    /**
+     * Checks the current ServiceState to make sure it's OK
+     * to try making an outgoing call to the specified number.
+     *
+     * @return CallStatusCode.SUCCESS if it's OK to try calling the specified
+     *    number.  If not, like if the radio is powered off or we have no
+     *    signal, return one of the other CallStatusCode codes indicating what
+     *    the problem is.
+     */
+    private CallStatusCode checkIfOkToInitiateOutgoingCall(int state) {
+        if (VDBG) log("checkIfOkToInitiateOutgoingCall: ServiceState = " + state);
+
+        switch (state) {
+            case ServiceState.STATE_IN_SERVICE:
+                // Normal operation.  It's OK to make outgoing calls.
+                return CallStatusCode.SUCCESS;
+
+            case ServiceState.STATE_POWER_OFF:
+                // Radio is explictly powered off.
+                return CallStatusCode.POWER_OFF;
+
+            case ServiceState.STATE_EMERGENCY_ONLY:
+                // The phone is registered, but locked. Only emergency
+                // numbers are allowed.
+                // Note that as of Android 2.0 at least, the telephony layer
+                // does not actually use ServiceState.STATE_EMERGENCY_ONLY,
+                // mainly since there's no guarantee that the radio/RIL can
+                // make this distinction.  So in practice the
+                // CallStatusCode.EMERGENCY_ONLY state and the string
+                // "incall_error_emergency_only" are totally unused.
+                return CallStatusCode.EMERGENCY_ONLY;
+
+            case ServiceState.STATE_OUT_OF_SERVICE:
+                // No network connection.
+                return CallStatusCode.OUT_OF_SERVICE;
+
+            default:
+                throw new IllegalStateException("Unexpected ServiceState: " + state);
+        }
+    }
+
+
+
+    /**
+     * Handles the various error conditions that can occur when initiating
+     * an outgoing call.
+     *
+     * Most error conditions are "handled" by simply displaying an error
+     * message to the user.  This is accomplished by setting the
+     * inCallUiState pending call status code flag, which tells the
+     * InCallScreen to display an appropriate message to the user when the
+     * in-call UI comes to the foreground.
+     *
+     * @param status one of the CallStatusCode error codes.
+     */
+    private void handleOutgoingCallError(CallStatusCode status) {
+        if (DBG) log("handleOutgoingCallError(): status = " + status);
+        final InCallUiState inCallUiState = mApp.inCallUiState;
+
+        // In most cases we simply want to have the InCallScreen display
+        // an appropriate error dialog, so we simply copy the specified
+        // status code into the InCallUiState "pending call status code"
+        // field.  (See InCallScreen.showStatusIndication() for the next
+        // step of the sequence.)
+
+        switch (status) {
+            case SUCCESS:
+                // This case shouldn't happen; you're only supposed to call
+                // handleOutgoingCallError() if there was actually an error!
+                Log.wtf(TAG, "handleOutgoingCallError: SUCCESS isn't an error");
+                break;
+
+            case VOICEMAIL_NUMBER_MISSING:
+                // Bring up the "Missing Voicemail Number" dialog, which
+                // will ultimately take us to some other Activity (or else
+                // just bail out of this activity.)
+
+                // Send a request to the InCallScreen to display the
+                // "voicemail missing" dialog when it (the InCallScreen)
+                // comes to the foreground.
+                inCallUiState.setPendingCallStatusCode(CallStatusCode.VOICEMAIL_NUMBER_MISSING);
+                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.)
+                inCallUiState.setPendingCallStatusCode(CallStatusCode.POWER_OFF);
+                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.)
+                inCallUiState.setPendingCallStatusCode(CallStatusCode.EMERGENCY_ONLY);
+                break;
+
+            case OUT_OF_SERVICE:
+                // No network connection.
+                inCallUiState.setPendingCallStatusCode(CallStatusCode.OUT_OF_SERVICE);
+                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.
+                inCallUiState.setPendingCallStatusCode(CallStatusCode.NO_PHONE_NUMBER_SUPPLIED);
+                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.
+                //
+                // TODO: Rather than launching a toast from here, it would
+                // be cleaner to just set a pending call status code here,
+                // and then let the InCallScreen display the toast...
+                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.
+                inCallUiState.setPendingCallStatusCode(CallStatusCode.CALL_FAILED);
+                break;
+
+            default:
+                Log.wtf(TAG, "handleOutgoingCallError: unexpected status code " + status);
+                // Show a generic "call failed" error.
+                inCallUiState.setPendingCallStatusCode(CallStatusCode.CALL_FAILED);
+                break;
+        }
+    }
+
+    /**
+     * Checks the current outgoing call to see if it's an OTASP call (the
+     * "activation" call used to provision CDMA devices).  If so, do any
+     * necessary OTASP-specific setup before actually placing the call.
+     */
+    private void checkForOtaspCall(Intent intent) {
+        if (OtaUtils.isOtaspCallIntent(intent)) {
+            Log.i(TAG, "checkForOtaspCall: handling OTASP intent! " + intent);
+
+            // ("OTASP-specific setup" basically means creating and initializing
+            // the OtaUtils instance.  Note that this setup needs to be here in
+            // the CallController.placeCall() sequence, *not* in
+            // OtaUtils.startInteractiveOtasp(), since it's also possible to
+            // start an OTASP call by manually dialing "*228" (in which case
+            // OtaUtils.startInteractiveOtasp() never gets run at all.)
+            OtaUtils.setupOtaspCall(intent);
+        } else {
+            if (DBG) log("checkForOtaspCall: not an OTASP call.");
+        }
+    }
+
+
+    //
+    // Debugging
+    //
+
+    private static void log(String msg) {
+        Log.d(TAG, msg);
+    }
+}
diff --git a/src/com/android/phone/CallFeaturesSetting.java b/src/com/android/phone/CallFeaturesSetting.java
new file mode 100644
index 0000000..1848e54
--- /dev/null
+++ b/src/com/android/phone/CallFeaturesSetting.java
@@ -0,0 +1,2205 @@
+/*
+ * 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.app.ActionBar;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.ProgressDialog;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteException;
+import android.media.AudioManager;
+import android.media.RingtoneManager;
+import android.net.Uri;
+import android.net.sip.SipManager;
+import android.os.AsyncResult;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.UserHandle;
+import android.os.Vibrator;
+import android.preference.CheckBoxPreference;
+import android.preference.ListPreference;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceGroup;
+import android.preference.PreferenceManager;
+import android.preference.PreferenceScreen;
+import android.provider.ContactsContract.CommonDataKinds;
+import android.provider.MediaStore;
+import android.provider.Settings;
+import android.provider.Settings.SettingNotFoundException;
+import android.telephony.PhoneNumberUtils;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.MenuItem;
+import android.view.WindowManager;
+import android.widget.ListAdapter;
+
+import com.android.internal.telephony.CallForwardInfo;
+import com.android.internal.telephony.CommandsInterface;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.cdma.TtyIntent;
+import com.android.phone.sip.SipSharedPreferences;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Top level "Call settings" UI; see res/xml/call_feature_setting.xml
+ *
+ * This preference screen is the root of the "Call settings" hierarchy
+ * available from the Phone app; the settings here let you control various
+ * features related to phone calls (including voicemail settings, SIP
+ * settings, the "Respond via SMS" feature, and others.)  It's used only
+ * on voice-capable phone devices.
+ *
+ * Note that this activity is part of the package com.android.phone, even
+ * though you reach it from the "Phone" app (i.e. DialtactsActivity) which
+ * is from the package com.android.contacts.
+ *
+ * For the "Mobile network settings" screen under the main Settings app,
+ * See {@link MobileNetworkSettings}.
+ *
+ * @see com.android.phone.MobileNetworkSettings
+ */
+public class CallFeaturesSetting extends PreferenceActivity
+        implements DialogInterface.OnClickListener,
+        Preference.OnPreferenceChangeListener,
+        EditPhoneNumberPreference.OnDialogClosedListener,
+        EditPhoneNumberPreference.GetDefaultNumberListener{
+    private static final String LOG_TAG = "CallFeaturesSetting";
+    private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
+
+    /**
+     * Intent action to bring up Voicemail Provider settings.
+     *
+     * @see #IGNORE_PROVIDER_EXTRA
+     */
+    public static final String ACTION_ADD_VOICEMAIL =
+            "com.android.phone.CallFeaturesSetting.ADD_VOICEMAIL";
+    // intent action sent by this activity to a voice mail provider
+    // to trigger its configuration UI
+    public static final String ACTION_CONFIGURE_VOICEMAIL =
+            "com.android.phone.CallFeaturesSetting.CONFIGURE_VOICEMAIL";
+    // Extra put in the return from VM provider config containing voicemail number to set
+    public static final String VM_NUMBER_EXTRA = "com.android.phone.VoicemailNumber";
+    // Extra put in the return from VM provider config containing call forwarding number to set
+    public static final String FWD_NUMBER_EXTRA = "com.android.phone.ForwardingNumber";
+    // Extra put in the return from VM provider config containing call forwarding number to set
+    public static final String FWD_NUMBER_TIME_EXTRA = "com.android.phone.ForwardingNumberTime";
+    // If the VM provider returns non null value in this extra we will force the user to
+    // choose another VM provider
+    public static final String SIGNOUT_EXTRA = "com.android.phone.Signout";
+    //Information about logical "up" Activity
+    private static final String UP_ACTIVITY_PACKAGE = "com.android.dialer";
+    private static final String UP_ACTIVITY_CLASS =
+            "com.android.dialer.DialtactsActivity";
+
+    // Used to tell the saving logic to leave forwarding number as is
+    public static final CallForwardInfo[] FWD_SETTINGS_DONT_TOUCH = null;
+    // Suffix appended to provider key for storing vm number
+    public static final String VM_NUMBER_TAG = "#VMNumber";
+    // Suffix appended to provider key for storing forwarding settings
+    public static final String FWD_SETTINGS_TAG = "#FWDSettings";
+    // Suffix appended to forward settings key for storing length of settings array
+    public static final String FWD_SETTINGS_LENGTH_TAG = "#Length";
+    // Suffix appended to forward settings key for storing an individual setting
+    public static final String FWD_SETTING_TAG = "#Setting";
+    // Suffixes appended to forward setting key for storing an individual setting properties
+    public static final String FWD_SETTING_STATUS = "#Status";
+    public static final String FWD_SETTING_REASON = "#Reason";
+    public static final String FWD_SETTING_NUMBER = "#Number";
+    public static final String FWD_SETTING_TIME = "#Time";
+
+    // Key identifying the default vocie mail provider
+    public static final String DEFAULT_VM_PROVIDER_KEY = "";
+
+    /**
+     * String Extra put into ACTION_ADD_VOICEMAIL call to indicate which provider should be hidden
+     * in the list of providers presented to the user. This allows a provider which is being
+     * disabled (e.g. GV user logging out) to force the user to pick some other provider.
+     */
+    public static final String IGNORE_PROVIDER_EXTRA = "com.android.phone.ProviderToIgnore";
+
+    // string constants
+    private static final String NUM_PROJECTION[] = {CommonDataKinds.Phone.NUMBER};
+
+    // String keys for preference lookup
+    // TODO: Naming these "BUTTON_*" is confusing since they're not actually buttons(!)
+    private static final String BUTTON_VOICEMAIL_KEY = "button_voicemail_key";
+    private static final String BUTTON_VOICEMAIL_PROVIDER_KEY = "button_voicemail_provider_key";
+    private static final String BUTTON_VOICEMAIL_SETTING_KEY = "button_voicemail_setting_key";
+    // New preference key for voicemail notification vibration
+    /* package */ static final String BUTTON_VOICEMAIL_NOTIFICATION_VIBRATE_KEY =
+            "button_voicemail_notification_vibrate_key";
+    // Old preference key for voicemail notification vibration. Used for migration to the new
+    // preference key only.
+    /* package */ static final String BUTTON_VOICEMAIL_NOTIFICATION_VIBRATE_WHEN_KEY =
+            "button_voicemail_notification_vibrate_when_key";
+    /* package */ static final String BUTTON_VOICEMAIL_NOTIFICATION_RINGTONE_KEY =
+            "button_voicemail_notification_ringtone_key";
+    private static final String BUTTON_FDN_KEY   = "button_fdn_key";
+    private static final String BUTTON_RESPOND_VIA_SMS_KEY   = "button_respond_via_sms_key";
+
+    private static final String BUTTON_RINGTONE_KEY    = "button_ringtone_key";
+    private static final String BUTTON_VIBRATE_ON_RING = "button_vibrate_on_ring";
+    private static final String BUTTON_PLAY_DTMF_TONE  = "button_play_dtmf_tone";
+    private static final String BUTTON_DTMF_KEY        = "button_dtmf_settings";
+    private static final String BUTTON_RETRY_KEY       = "button_auto_retry_key";
+    private static final String BUTTON_TTY_KEY         = "button_tty_mode_key";
+    private static final String BUTTON_HAC_KEY         = "button_hac_key";
+    private static final String BUTTON_DIALPAD_AUTOCOMPLETE = "button_dialpad_autocomplete";
+
+    private static final String BUTTON_GSM_UMTS_OPTIONS = "button_gsm_more_expand_key";
+    private static final String BUTTON_CDMA_OPTIONS = "button_cdma_more_expand_key";
+
+    private static final String VM_NUMBERS_SHARED_PREFERENCES_NAME = "vm_numbers";
+
+    private static final String BUTTON_SIP_CALL_OPTIONS =
+            "sip_call_options_key";
+    private static final String BUTTON_SIP_CALL_OPTIONS_WIFI_ONLY =
+            "sip_call_options_wifi_only_key";
+    private static final String SIP_SETTINGS_CATEGORY_KEY =
+            "sip_settings_category_key";
+
+    private Intent mContactListIntent;
+
+    /** Event for Async voicemail change call */
+    private static final int EVENT_VOICEMAIL_CHANGED        = 500;
+    private static final int EVENT_FORWARDING_CHANGED       = 501;
+    private static final int EVENT_FORWARDING_GET_COMPLETED = 502;
+
+    private static final int MSG_UPDATE_RINGTONE_SUMMARY = 1;
+    private static final int MSG_UPDATE_VOICEMAIL_RINGTONE_SUMMARY = 2;
+
+    // preferred TTY mode
+    // Phone.TTY_MODE_xxx
+    static final int preferredTtyMode = Phone.TTY_MODE_OFF;
+
+    public static final String HAC_KEY = "HACSetting";
+    public static final String HAC_VAL_ON = "ON";
+    public static final String HAC_VAL_OFF = "OFF";
+
+    /** Handle to voicemail pref */
+    private static final int VOICEMAIL_PREF_ID = 1;
+    private static final int VOICEMAIL_PROVIDER_CFG_ID = 2;
+
+    private Phone mPhone;
+
+    private AudioManager mAudioManager;
+    private SipManager mSipManager;
+
+    private static final int VM_NOCHANGE_ERROR = 400;
+    private static final int VM_RESPONSE_ERROR = 500;
+    private static final int FW_SET_RESPONSE_ERROR = 501;
+    private static final int FW_GET_RESPONSE_ERROR = 502;
+
+
+    // dialog identifiers for voicemail
+    private static final int VOICEMAIL_DIALOG_CONFIRM = 600;
+    private static final int VOICEMAIL_FWD_SAVING_DIALOG = 601;
+    private static final int VOICEMAIL_FWD_READING_DIALOG = 602;
+    private static final int VOICEMAIL_REVERTING_DIALOG = 603;
+
+    // status message sent back from handlers
+    private static final int MSG_OK = 100;
+
+    // special statuses for voicemail controls.
+    private static final int MSG_VM_EXCEPTION = 400;
+    private static final int MSG_FW_SET_EXCEPTION = 401;
+    private static final int MSG_FW_GET_EXCEPTION = 402;
+    private static final int MSG_VM_OK = 600;
+    private static final int MSG_VM_NOCHANGE = 700;
+
+    // voicemail notification vibration string constants
+    private static final String VOICEMAIL_VIBRATION_ALWAYS = "always";
+    private static final String VOICEMAIL_VIBRATION_NEVER = "never";
+
+    private EditPhoneNumberPreference mSubMenuVoicemailSettings;
+
+    private Runnable mRingtoneLookupRunnable;
+    private final Handler mRingtoneLookupComplete = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_UPDATE_RINGTONE_SUMMARY:
+                    mRingtonePreference.setSummary((CharSequence) msg.obj);
+                    break;
+                case MSG_UPDATE_VOICEMAIL_RINGTONE_SUMMARY:
+                    mVoicemailNotificationRingtone.setSummary((CharSequence) msg.obj);
+                    break;
+            }
+        }
+    };
+
+    private Preference mRingtonePreference;
+    private CheckBoxPreference mVibrateWhenRinging;
+    /** Whether dialpad plays DTMF tone or not. */
+    private CheckBoxPreference mPlayDtmfTone;
+    private CheckBoxPreference mDialpadAutocomplete;
+    private CheckBoxPreference mButtonAutoRetry;
+    private CheckBoxPreference mButtonHAC;
+    private ListPreference mButtonDTMF;
+    private ListPreference mButtonTTY;
+    private ListPreference mButtonSipCallOptions;
+    private ListPreference mVoicemailProviders;
+    private PreferenceScreen mVoicemailSettings;
+    private Preference mVoicemailNotificationRingtone;
+    private CheckBoxPreference mVoicemailNotificationVibrate;
+    private SipSharedPreferences mSipSharedPreferences;
+
+    private class VoiceMailProvider {
+        public VoiceMailProvider(String name, Intent intent) {
+            this.name = name;
+            this.intent = intent;
+        }
+        public String name;
+        public Intent intent;
+    }
+
+    /**
+     * Forwarding settings we are going to save.
+     */
+    private static final int [] FORWARDING_SETTINGS_REASONS = new int[] {
+        CommandsInterface.CF_REASON_UNCONDITIONAL,
+        CommandsInterface.CF_REASON_BUSY,
+        CommandsInterface.CF_REASON_NO_REPLY,
+        CommandsInterface.CF_REASON_NOT_REACHABLE
+    };
+
+    private class VoiceMailProviderSettings {
+        /**
+         * Constructs settings object, setting all conditional forwarding to the specified number
+         */
+        public VoiceMailProviderSettings(String voicemailNumber, String forwardingNumber,
+                int timeSeconds) {
+            this.voicemailNumber = voicemailNumber;
+            if (forwardingNumber == null || forwardingNumber.length() == 0) {
+                this.forwardingSettings = FWD_SETTINGS_DONT_TOUCH;
+            } else {
+                this.forwardingSettings = new CallForwardInfo[FORWARDING_SETTINGS_REASONS.length];
+                for (int i = 0; i < this.forwardingSettings.length; i++) {
+                    CallForwardInfo fi = new CallForwardInfo();
+                    this.forwardingSettings[i] = fi;
+                    fi.reason = FORWARDING_SETTINGS_REASONS[i];
+                    fi.status = (fi.reason == CommandsInterface.CF_REASON_UNCONDITIONAL) ? 0 : 1;
+                    fi.serviceClass = CommandsInterface.SERVICE_CLASS_VOICE;
+                    fi.toa = PhoneNumberUtils.TOA_International;
+                    fi.number = forwardingNumber;
+                    fi.timeSeconds = timeSeconds;
+                }
+            }
+        }
+
+        public VoiceMailProviderSettings(String voicemailNumber, CallForwardInfo[] infos) {
+            this.voicemailNumber = voicemailNumber;
+            this.forwardingSettings = infos;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o == null) return false;
+            if (!(o instanceof VoiceMailProviderSettings)) return false;
+            final VoiceMailProviderSettings v = (VoiceMailProviderSettings)o;
+
+            return ((this.voicemailNumber == null &&
+                        v.voicemailNumber == null) ||
+                    this.voicemailNumber != null &&
+                        this.voicemailNumber.equals(v.voicemailNumber))
+                    &&
+                    forwardingSettingsEqual(this.forwardingSettings,
+                            v.forwardingSettings);
+        }
+
+        private boolean forwardingSettingsEqual(CallForwardInfo[] infos1,
+                CallForwardInfo[] infos2) {
+            if (infos1 == infos2) return true;
+            if (infos1 == null || infos2 == null) return false;
+            if (infos1.length != infos2.length) return false;
+            for (int i = 0; i < infos1.length; i++) {
+                CallForwardInfo i1 = infos1[i];
+                CallForwardInfo i2 = infos2[i];
+                if (i1.status != i2.status ||
+                    i1.reason != i2.reason ||
+                    i1.serviceClass != i2.serviceClass ||
+                    i1.toa != i2.toa ||
+                    i1.number != i2.number ||
+                    i1.timeSeconds != i2.timeSeconds) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        @Override
+        public String toString() {
+            return voicemailNumber + ((forwardingSettings != null ) ? (", " +
+                    forwardingSettings.toString()) : "");
+        }
+
+        public String voicemailNumber;
+        public CallForwardInfo[] forwardingSettings;
+    }
+
+    private SharedPreferences mPerProviderSavedVMNumbers;
+
+    /**
+     * Results of reading forwarding settings
+     */
+    private CallForwardInfo[] mForwardingReadResults = null;
+
+    /**
+     * Result of forwarding number change.
+     * Keys are reasons (eg. unconditional forwarding).
+     */
+    private Map<Integer, AsyncResult> mForwardingChangeResults = null;
+
+    /**
+     * Expected CF read result types.
+     * This set keeps track of the CF types for which we've issued change
+     * commands so we can tell when we've received all of the responses.
+     */
+    private Collection<Integer> mExpectedChangeResultReasons = null;
+
+    /**
+     * Result of vm number change
+     */
+    private AsyncResult mVoicemailChangeResult = null;
+
+    /**
+     * Previous VM provider setting so we can return to it in case of failure.
+     */
+    private String mPreviousVMProviderKey = null;
+
+    /**
+     * Id of the dialog being currently shown.
+     */
+    private int mCurrentDialogId = 0;
+
+    /**
+     * Flag indicating that we are invoking settings for the voicemail provider programmatically
+     * due to vm provider change.
+     */
+    private boolean mVMProviderSettingsForced = false;
+
+    /**
+     * Flag indicating that we are making changes to vm or fwd numbers
+     * due to vm provider change.
+     */
+    private boolean mChangingVMorFwdDueToProviderChange = false;
+
+    /**
+     * True if we are in the process of vm & fwd number change and vm has already been changed.
+     * This is used to decide what to do in case of rollback.
+     */
+    private boolean mVMChangeCompletedSuccessfully = false;
+
+    /**
+     * True if we had full or partial failure setting forwarding numbers and so need to roll them
+     * back.
+     */
+    private boolean mFwdChangesRequireRollback = false;
+
+    /**
+     * Id of error msg to display to user once we are done reverting the VM provider to the previous
+     * one.
+     */
+    private int mVMOrFwdSetError = 0;
+
+    /**
+     * Data about discovered voice mail settings providers.
+     * Is populated by querying which activities can handle ACTION_CONFIGURE_VOICEMAIL.
+     * They key in this map is package name + activity name.
+     * We always add an entry for the default provider with a key of empty
+     * string and intent value of null.
+     * @see #initVoiceMailProviders()
+     */
+    private final Map<String, VoiceMailProvider> mVMProvidersData =
+            new HashMap<String, VoiceMailProvider>();
+
+    /** string to hold old voicemail number as it is being updated. */
+    private String mOldVmNumber;
+
+    // New call forwarding settings and vm number we will be setting
+    // Need to save these since before we get to saving we need to asynchronously
+    // query the existing forwarding settings.
+    private CallForwardInfo[] mNewFwdSettings;
+    private String mNewVMNumber;
+
+    private boolean mForeground;
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        mForeground = false;
+    }
+
+    /**
+     * We have to pull current settings from the network for all kinds of
+     * voicemail providers so we can tell whether we have to update them,
+     * so use this bit to keep track of whether we're reading settings for the
+     * default provider and should therefore save them out when done.
+     */
+    private boolean mReadingSettingsForDefaultProvider = false;
+
+    /*
+     * Click Listeners, handle click based on objects attached to UI.
+     */
+
+    // Click listener for all toggle events
+    @Override
+    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
+        if (preference == mSubMenuVoicemailSettings) {
+            return true;
+        } else if (preference == mPlayDtmfTone) {
+            Settings.System.putInt(getContentResolver(), Settings.System.DTMF_TONE_WHEN_DIALING,
+                    mPlayDtmfTone.isChecked() ? 1 : 0);
+        } else if (preference == mDialpadAutocomplete) {
+            Settings.Secure.putInt(getContentResolver(), Settings.Secure.DIALPAD_AUTOCOMPLETE,
+                    mDialpadAutocomplete.isChecked() ? 1 : 0);
+        } else if (preference == mButtonDTMF) {
+            return true;
+        } else if (preference == mButtonTTY) {
+            return true;
+        } else if (preference == mButtonAutoRetry) {
+            android.provider.Settings.Global.putInt(mPhone.getContext().getContentResolver(),
+                    android.provider.Settings.Global.CALL_AUTO_RETRY,
+                    mButtonAutoRetry.isChecked() ? 1 : 0);
+            return true;
+        } else if (preference == mButtonHAC) {
+            int hac = mButtonHAC.isChecked() ? 1 : 0;
+            // Update HAC value in Settings database
+            Settings.System.putInt(mPhone.getContext().getContentResolver(),
+                    Settings.System.HEARING_AID, hac);
+
+            // Update HAC Value in AudioManager
+            mAudioManager.setParameter(HAC_KEY, hac != 0 ? HAC_VAL_ON : HAC_VAL_OFF);
+            return true;
+        } else if (preference == mVoicemailSettings) {
+            if (DBG) log("onPreferenceTreeClick: Voicemail Settings Preference is clicked.");
+            if (preference.getIntent() != null) {
+                if (DBG) {
+                    log("onPreferenceTreeClick: Invoking cfg intent "
+                            + preference.getIntent().getPackage());
+                }
+
+                // onActivityResult() will be responsible for resetting some of variables.
+                this.startActivityForResult(preference.getIntent(), VOICEMAIL_PROVIDER_CFG_ID);
+                return true;
+            } else {
+                if (DBG) {
+                    log("onPreferenceTreeClick:"
+                            + " No Intent is available. Use default behavior defined in xml.");
+                }
+
+                // There's no onActivityResult(), so we need to take care of some of variables
+                // which should be reset here.
+                mPreviousVMProviderKey = DEFAULT_VM_PROVIDER_KEY;
+                mVMProviderSettingsForced = false;
+
+                // This should let the preference use default behavior in the xml.
+                return false;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Implemented to support onPreferenceChangeListener to look for preference
+     * changes.
+     *
+     * @param preference is the preference to be changed
+     * @param objValue should be the value of the selection, NOT its localized
+     * display value.
+     */
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object objValue) {
+        if (DBG) {
+            log("onPreferenceChange(). preferenece: \"" + preference + "\""
+                    + ", value: \"" + objValue + "\"");
+        }
+        if (preference == mVibrateWhenRinging) {
+            boolean doVibrate = (Boolean) objValue;
+            Settings.System.putInt(mPhone.getContext().getContentResolver(),
+                    Settings.System.VIBRATE_WHEN_RINGING, doVibrate ? 1 : 0);
+        } else if (preference == mButtonDTMF) {
+            int index = mButtonDTMF.findIndexOfValue((String) objValue);
+            Settings.System.putInt(mPhone.getContext().getContentResolver(),
+                    Settings.System.DTMF_TONE_TYPE_WHEN_DIALING, index);
+        } else if (preference == mButtonTTY) {
+            handleTTYChange(preference, objValue);
+        } else if (preference == mVoicemailProviders) {
+            final String newProviderKey = (String) objValue;
+            if (DBG) {
+                log("Voicemail Provider changes from \"" + mPreviousVMProviderKey
+                    + "\" to \"" + newProviderKey + "\".");
+            }
+            // If previous provider key and the new one is same, we don't need to handle it.
+            if (mPreviousVMProviderKey.equals(newProviderKey)) {
+                if (DBG) log("No change is made toward VM provider setting.");
+                return true;
+            }
+            updateVMPreferenceWidgets(newProviderKey);
+
+            final VoiceMailProviderSettings newProviderSettings =
+                    loadSettingsForVoiceMailProvider(newProviderKey);
+
+            // If the user switches to a voice mail provider and we have a
+            // numbers stored for it we will automatically change the
+            // phone's
+            // voice mail and forwarding number to the stored ones.
+            // Otherwise we will bring up provider's configuration UI.
+
+            if (newProviderSettings == null) {
+                // Force the user into a configuration of the chosen provider
+                Log.w(LOG_TAG, "Saved preferences not found - invoking config");
+                mVMProviderSettingsForced = true;
+                simulatePreferenceClick(mVoicemailSettings);
+            } else {
+                if (DBG) log("Saved preferences found - switching to them");
+                // Set this flag so if we get a failure we revert to previous provider
+                mChangingVMorFwdDueToProviderChange = true;
+                saveVoiceMailAndForwardingNumber(newProviderKey, newProviderSettings);
+            }
+        } else if (preference == mButtonSipCallOptions) {
+            handleSipCallOptionsChange(objValue);
+        }
+        // always let the preference setting proceed.
+        return true;
+    }
+
+    @Override
+    public void onDialogClosed(EditPhoneNumberPreference preference, int buttonClicked) {
+        if (DBG) log("onPreferenceClick: request preference click on dialog close: " +
+                buttonClicked);
+        if (buttonClicked == DialogInterface.BUTTON_NEGATIVE) {
+            return;
+        }
+
+        if (preference == mSubMenuVoicemailSettings) {
+            handleVMBtnClickRequest();
+        }
+    }
+
+    /**
+     * Implemented for EditPhoneNumberPreference.GetDefaultNumberListener.
+     * This method set the default values for the various
+     * EditPhoneNumberPreference dialogs.
+     */
+    @Override
+    public String onGetDefaultNumber(EditPhoneNumberPreference preference) {
+        if (preference == mSubMenuVoicemailSettings) {
+            // update the voicemail number field, which takes care of the
+            // mSubMenuVoicemailSettings itself, so we should return null.
+            if (DBG) log("updating default for voicemail dialog");
+            updateVoiceNumberField();
+            return null;
+        }
+
+        String vmDisplay = mPhone.getVoiceMailNumber();
+        if (TextUtils.isEmpty(vmDisplay)) {
+            // if there is no voicemail number, we just return null to
+            // indicate no contribution.
+            return null;
+        }
+
+        // Return the voicemail number prepended with "VM: "
+        if (DBG) log("updating default for call forwarding dialogs");
+        return getString(R.string.voicemail_abbreviated) + " " + vmDisplay;
+    }
+
+
+    // override the startsubactivity call to make changes in state consistent.
+    @Override
+    public void startActivityForResult(Intent intent, int requestCode) {
+        if (requestCode == -1) {
+            // this is an intent requested from the preference framework.
+            super.startActivityForResult(intent, requestCode);
+            return;
+        }
+
+        if (DBG) log("startSubActivity: starting requested subactivity");
+        super.startActivityForResult(intent, requestCode);
+    }
+
+    private void switchToPreviousVoicemailProvider() {
+        if (DBG) log("switchToPreviousVoicemailProvider " + mPreviousVMProviderKey);
+        if (mPreviousVMProviderKey != null) {
+            if (mVMChangeCompletedSuccessfully || mFwdChangesRequireRollback) {
+                // we have to revert with carrier
+                if (DBG) {
+                    log("Needs to rollback."
+                            + " mVMChangeCompletedSuccessfully=" + mVMChangeCompletedSuccessfully
+                            + ", mFwdChangesRequireRollback=" + mFwdChangesRequireRollback);
+                }
+
+                showDialogIfForeground(VOICEMAIL_REVERTING_DIALOG);
+                final VoiceMailProviderSettings prevSettings =
+                        loadSettingsForVoiceMailProvider(mPreviousVMProviderKey);
+                if (prevSettings == null) {
+                    // prevSettings never becomes null since it should be already loaded!
+                    Log.e(LOG_TAG, "VoiceMailProviderSettings for the key \""
+                            + mPreviousVMProviderKey + "\" becomes null, which is unexpected.");
+                    if (DBG) {
+                        Log.e(LOG_TAG,
+                                "mVMChangeCompletedSuccessfully: " + mVMChangeCompletedSuccessfully
+                                + ", mFwdChangesRequireRollback: " + mFwdChangesRequireRollback);
+                    }
+                }
+                if (mVMChangeCompletedSuccessfully) {
+                    mNewVMNumber = prevSettings.voicemailNumber;
+                    Log.i(LOG_TAG, "VM change is already completed successfully."
+                            + "Have to revert VM back to " + mNewVMNumber + " again.");
+                    mPhone.setVoiceMailNumber(
+                            mPhone.getVoiceMailAlphaTag().toString(),
+                            mNewVMNumber,
+                            Message.obtain(mRevertOptionComplete, EVENT_VOICEMAIL_CHANGED));
+                }
+                if (mFwdChangesRequireRollback) {
+                    Log.i(LOG_TAG, "Requested to rollback Fwd changes.");
+                    final CallForwardInfo[] prevFwdSettings =
+                        prevSettings.forwardingSettings;
+                    if (prevFwdSettings != null) {
+                        Map<Integer, AsyncResult> results =
+                            mForwardingChangeResults;
+                        resetForwardingChangeState();
+                        for (int i = 0; i < prevFwdSettings.length; i++) {
+                            CallForwardInfo fi = prevFwdSettings[i];
+                            if (DBG) log("Reverting fwd #: " + i + ": " + fi.toString());
+                            // Only revert the settings for which the update
+                            // succeeded
+                            AsyncResult result = results.get(fi.reason);
+                            if (result != null && result.exception == null) {
+                                mExpectedChangeResultReasons.add(fi.reason);
+                                mPhone.setCallForwardingOption(
+                                        (fi.status == 1 ?
+                                                CommandsInterface.CF_ACTION_REGISTRATION :
+                                                CommandsInterface.CF_ACTION_DISABLE),
+                                        fi.reason,
+                                        fi.number,
+                                        fi.timeSeconds,
+                                        mRevertOptionComplete.obtainMessage(
+                                                EVENT_FORWARDING_CHANGED, i, 0));
+                            }
+                        }
+                    }
+                }
+            } else {
+                if (DBG) log("No need to revert");
+                onRevertDone();
+            }
+        }
+    }
+
+    private void onRevertDone() {
+        if (DBG) log("Flipping provider key back to " + mPreviousVMProviderKey);
+        mVoicemailProviders.setValue(mPreviousVMProviderKey);
+        updateVMPreferenceWidgets(mPreviousVMProviderKey);
+        updateVoiceNumberField();
+        if (mVMOrFwdSetError != 0) {
+            showVMDialog(mVMOrFwdSetError);
+            mVMOrFwdSetError = 0;
+        }
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (DBG) {
+            log("onActivityResult: requestCode: " + requestCode
+                    + ", resultCode: " + resultCode
+                    + ", data: " + data);
+        }
+        // there are cases where the contact picker may end up sending us more than one
+        // request.  We want to ignore the request if we're not in the correct state.
+        if (requestCode == VOICEMAIL_PROVIDER_CFG_ID) {
+            boolean failure = false;
+
+            // No matter how the processing of result goes lets clear the flag
+            if (DBG) log("mVMProviderSettingsForced: " + mVMProviderSettingsForced);
+            final boolean isVMProviderSettingsForced = mVMProviderSettingsForced;
+            mVMProviderSettingsForced = false;
+
+            String vmNum = null;
+            if (resultCode != RESULT_OK) {
+                if (DBG) log("onActivityResult: vm provider cfg result not OK.");
+                failure = true;
+            } else {
+                if (data == null) {
+                    if (DBG) log("onActivityResult: vm provider cfg result has no data");
+                    failure = true;
+                } else {
+                    if (data.getBooleanExtra(SIGNOUT_EXTRA, false)) {
+                        if (DBG) log("Provider requested signout");
+                        if (isVMProviderSettingsForced) {
+                            if (DBG) log("Going back to previous provider on signout");
+                            switchToPreviousVoicemailProvider();
+                        } else {
+                            final String victim = getCurrentVoicemailProviderKey();
+                            if (DBG) log("Relaunching activity and ignoring " + victim);
+                            Intent i = new Intent(ACTION_ADD_VOICEMAIL);
+                            i.putExtra(IGNORE_PROVIDER_EXTRA, victim);
+                            i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+                            this.startActivity(i);
+                        }
+                        return;
+                    }
+                    vmNum = data.getStringExtra(VM_NUMBER_EXTRA);
+                    if (vmNum == null || vmNum.length() == 0) {
+                        if (DBG) log("onActivityResult: vm provider cfg result has no vmnum");
+                        failure = true;
+                    }
+                }
+            }
+            if (failure) {
+                if (DBG) log("Failure in return from voicemail provider");
+                if (isVMProviderSettingsForced) {
+                    switchToPreviousVoicemailProvider();
+                } else {
+                    if (DBG) log("Not switching back the provider since this is not forced config");
+                }
+                return;
+            }
+            mChangingVMorFwdDueToProviderChange = isVMProviderSettingsForced;
+            final String fwdNum = data.getStringExtra(FWD_NUMBER_EXTRA);
+
+            // TODO(iliat): It would be nice to load the current network setting for this and
+            // send it to the provider when it's config is invoked so it can use this as default
+            final int fwdNumTime = data.getIntExtra(FWD_NUMBER_TIME_EXTRA, 20);
+
+            if (DBG) log("onActivityResult: vm provider cfg result " +
+                    (fwdNum != null ? "has" : " does not have") + " forwarding number");
+            saveVoiceMailAndForwardingNumber(getCurrentVoicemailProviderKey(),
+                    new VoiceMailProviderSettings(vmNum, fwdNum, fwdNumTime));
+            return;
+        }
+
+        if (requestCode == VOICEMAIL_PREF_ID) {
+            if (resultCode != RESULT_OK) {
+                if (DBG) log("onActivityResult: contact picker result not OK.");
+                return;
+            }
+
+            Cursor cursor = null;
+            try {
+                cursor = getContentResolver().query(data.getData(),
+                    NUM_PROJECTION, null, null, null);
+                if ((cursor == null) || (!cursor.moveToFirst())) {
+                    if (DBG) log("onActivityResult: bad contact data, no results found.");
+                    return;
+                }
+                mSubMenuVoicemailSettings.onPickActivityResult(cursor.getString(0));
+                return;
+            } finally {
+                if (cursor != null) {
+                    cursor.close();
+                }
+            }
+        }
+
+        super.onActivityResult(requestCode, resultCode, data);
+    }
+
+    // Voicemail button logic
+    private void handleVMBtnClickRequest() {
+        // normally called on the dialog close.
+
+        // Since we're stripping the formatting out on the getPhoneNumber()
+        // call now, we won't need to do so here anymore.
+
+        saveVoiceMailAndForwardingNumber(
+                getCurrentVoicemailProviderKey(),
+                new VoiceMailProviderSettings(mSubMenuVoicemailSettings.getPhoneNumber(),
+                        FWD_SETTINGS_DONT_TOUCH));
+    }
+
+
+    /**
+     * Wrapper around showDialog() that will silently do nothing if we're
+     * not in the foreground.
+     *
+     * This is useful here because most of the dialogs we display from
+     * this class are triggered by asynchronous events (like
+     * success/failure messages from the telephony layer) and it's
+     * possible for those events to come in even after the user has gone
+     * to a different screen.
+     */
+    // TODO: this is too brittle: it's still easy to accidentally add new
+    // code here that calls showDialog() directly (which will result in a
+    // WindowManager$BadTokenException if called after the activity has
+    // been stopped.)
+    //
+    // It would be cleaner to do the "if (mForeground)" check in one
+    // central place, maybe by using a single Handler for all asynchronous
+    // events (and have *that* discard events if we're not in the
+    // foreground.)
+    //
+    // Unfortunately it's not that simple, since we sometimes need to do
+    // actual work to handle these events whether or not we're in the
+    // foreground (see the Handler code in mSetOptionComplete for
+    // example.)
+    private void showDialogIfForeground(int id) {
+        if (mForeground) {
+            showDialog(id);
+        }
+    }
+
+    private void dismissDialogSafely(int id) {
+        try {
+            dismissDialog(id);
+        } catch (IllegalArgumentException e) {
+            // This is expected in the case where we were in the background
+            // at the time we would normally have shown the dialog, so we didn't
+            // show it.
+        }
+    }
+
+    private void saveVoiceMailAndForwardingNumber(String key,
+            VoiceMailProviderSettings newSettings) {
+        if (DBG) log("saveVoiceMailAndForwardingNumber: " + newSettings.toString());
+        mNewVMNumber = newSettings.voicemailNumber;
+        // empty vm number == clearing the vm number ?
+        if (mNewVMNumber == null) {
+            mNewVMNumber = "";
+        }
+
+        mNewFwdSettings = newSettings.forwardingSettings;
+        if (DBG) log("newFwdNumber " +
+                String.valueOf((mNewFwdSettings != null ? mNewFwdSettings.length : 0))
+                + " settings");
+
+        // No fwd settings on CDMA
+        if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
+            if (DBG) log("ignoring forwarding setting since this is CDMA phone");
+            mNewFwdSettings = FWD_SETTINGS_DONT_TOUCH;
+        }
+
+        //throw a warning if the vm is the same and we do not touch forwarding.
+        if (mNewVMNumber.equals(mOldVmNumber) && mNewFwdSettings == FWD_SETTINGS_DONT_TOUCH) {
+            showVMDialog(MSG_VM_NOCHANGE);
+            return;
+        }
+
+        maybeSaveSettingsForVoicemailProvider(key, newSettings);
+        mVMChangeCompletedSuccessfully = false;
+        mFwdChangesRequireRollback = false;
+        mVMOrFwdSetError = 0;
+        if (!key.equals(mPreviousVMProviderKey)) {
+            mReadingSettingsForDefaultProvider =
+                    mPreviousVMProviderKey.equals(DEFAULT_VM_PROVIDER_KEY);
+            if (DBG) log("Reading current forwarding settings");
+            mForwardingReadResults = new CallForwardInfo[FORWARDING_SETTINGS_REASONS.length];
+            for (int i = 0; i < FORWARDING_SETTINGS_REASONS.length; i++) {
+                mForwardingReadResults[i] = null;
+                mPhone.getCallForwardingOption(FORWARDING_SETTINGS_REASONS[i],
+                        mGetOptionComplete.obtainMessage(EVENT_FORWARDING_GET_COMPLETED, i, 0));
+            }
+            showDialogIfForeground(VOICEMAIL_FWD_READING_DIALOG);
+        } else {
+            saveVoiceMailAndForwardingNumberStage2();
+        }
+    }
+
+    private final Handler mGetOptionComplete = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            AsyncResult result = (AsyncResult) msg.obj;
+            switch (msg.what) {
+                case EVENT_FORWARDING_GET_COMPLETED:
+                    handleForwardingSettingsReadResult(result, msg.arg1);
+                    break;
+            }
+        }
+    };
+
+    private void handleForwardingSettingsReadResult(AsyncResult ar, int idx) {
+        if (DBG) Log.d(LOG_TAG, "handleForwardingSettingsReadResult: " + idx);
+        Throwable error = null;
+        if (ar.exception != null) {
+            if (DBG) Log.d(LOG_TAG, "FwdRead: ar.exception=" +
+                    ar.exception.getMessage());
+            error = ar.exception;
+        }
+        if (ar.userObj instanceof Throwable) {
+            if (DBG) Log.d(LOG_TAG, "FwdRead: userObj=" +
+                    ((Throwable)ar.userObj).getMessage());
+            error = (Throwable)ar.userObj;
+        }
+
+        // We may have already gotten an error and decided to ignore the other results.
+        if (mForwardingReadResults == null) {
+            if (DBG) Log.d(LOG_TAG, "ignoring fwd reading result: " + idx);
+            return;
+        }
+
+        // In case of error ignore other results, show an error dialog
+        if (error != null) {
+            if (DBG) Log.d(LOG_TAG, "Error discovered for fwd read : " + idx);
+            mForwardingReadResults = null;
+            dismissDialogSafely(VOICEMAIL_FWD_READING_DIALOG);
+            showVMDialog(MSG_FW_GET_EXCEPTION);
+            return;
+        }
+
+        // Get the forwarding info
+        final CallForwardInfo cfInfoArray[] = (CallForwardInfo[]) ar.result;
+        CallForwardInfo fi = null;
+        for (int i = 0 ; i < cfInfoArray.length; i++) {
+            if ((cfInfoArray[i].serviceClass & CommandsInterface.SERVICE_CLASS_VOICE) != 0) {
+                fi = cfInfoArray[i];
+                break;
+            }
+        }
+        if (fi == null) {
+
+            // In case we go nothing it means we need this reason disabled
+            // so create a CallForwardInfo for capturing this
+            if (DBG) Log.d(LOG_TAG, "Creating default info for " + idx);
+            fi = new CallForwardInfo();
+            fi.status = 0;
+            fi.reason = FORWARDING_SETTINGS_REASONS[idx];
+            fi.serviceClass = CommandsInterface.SERVICE_CLASS_VOICE;
+        } else {
+            // if there is not a forwarding number, ensure the entry is set to "not active."
+            if (fi.number == null || fi.number.length() == 0) {
+                fi.status = 0;
+            }
+
+            if (DBG) Log.d(LOG_TAG, "Got  " + fi.toString() + " for " + idx);
+        }
+        mForwardingReadResults[idx] = fi;
+
+        // Check if we got all the results already
+        boolean done = true;
+        for (int i = 0; i < mForwardingReadResults.length; i++) {
+            if (mForwardingReadResults[i] == null) {
+                done = false;
+                break;
+            }
+        }
+        if (done) {
+            if (DBG) Log.d(LOG_TAG, "Done receiving fwd info");
+            dismissDialogSafely(VOICEMAIL_FWD_READING_DIALOG);
+            if (mReadingSettingsForDefaultProvider) {
+                maybeSaveSettingsForVoicemailProvider(DEFAULT_VM_PROVIDER_KEY,
+                        new VoiceMailProviderSettings(this.mOldVmNumber,
+                                mForwardingReadResults));
+                mReadingSettingsForDefaultProvider = false;
+            }
+            saveVoiceMailAndForwardingNumberStage2();
+        } else {
+            if (DBG) Log.d(LOG_TAG, "Not done receiving fwd info");
+        }
+    }
+
+    private CallForwardInfo infoForReason(CallForwardInfo[] infos, int reason) {
+        CallForwardInfo result = null;
+        if (null != infos) {
+            for (CallForwardInfo info : infos) {
+                if (info.reason == reason) {
+                    result = info;
+                    break;
+                }
+            }
+        }
+        return result;
+    }
+
+    private boolean isUpdateRequired(CallForwardInfo oldInfo,
+            CallForwardInfo newInfo) {
+        boolean result = true;
+        if (0 == newInfo.status) {
+            // If we're disabling a type of forwarding, and it's already
+            // disabled for the account, don't make any change
+            if (oldInfo != null && oldInfo.status == 0) {
+                result = false;
+            }
+        }
+        return result;
+    }
+
+    private void resetForwardingChangeState() {
+        mForwardingChangeResults = new HashMap<Integer, AsyncResult>();
+        mExpectedChangeResultReasons = new HashSet<Integer>();
+    }
+
+    // Called after we are done saving the previous forwarding settings if
+    // we needed.
+    private void saveVoiceMailAndForwardingNumberStage2() {
+        mForwardingChangeResults = null;
+        mVoicemailChangeResult = null;
+        if (mNewFwdSettings != FWD_SETTINGS_DONT_TOUCH) {
+            resetForwardingChangeState();
+            for (int i = 0; i < mNewFwdSettings.length; i++) {
+                CallForwardInfo fi = mNewFwdSettings[i];
+
+                final boolean doUpdate = isUpdateRequired(infoForReason(
+                            mForwardingReadResults, fi.reason), fi);
+
+                if (doUpdate) {
+                    if (DBG) log("Setting fwd #: " + i + ": " + fi.toString());
+                    mExpectedChangeResultReasons.add(i);
+
+                    mPhone.setCallForwardingOption(
+                            fi.status == 1 ?
+                                    CommandsInterface.CF_ACTION_REGISTRATION :
+                                    CommandsInterface.CF_ACTION_DISABLE,
+                            fi.reason,
+                            fi.number,
+                            fi.timeSeconds,
+                            mSetOptionComplete.obtainMessage(
+                                    EVENT_FORWARDING_CHANGED, fi.reason, 0));
+                }
+            }
+            showDialogIfForeground(VOICEMAIL_FWD_SAVING_DIALOG);
+        } else {
+            if (DBG) log("Not touching fwd #");
+            setVMNumberWithCarrier();
+        }
+    }
+
+    private void setVMNumberWithCarrier() {
+        if (DBG) log("save voicemail #: " + mNewVMNumber);
+        mPhone.setVoiceMailNumber(
+                mPhone.getVoiceMailAlphaTag().toString(),
+                mNewVMNumber,
+                Message.obtain(mSetOptionComplete, EVENT_VOICEMAIL_CHANGED));
+    }
+
+    /**
+     * Callback to handle option update completions
+     */
+    private final Handler mSetOptionComplete = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            AsyncResult result = (AsyncResult) msg.obj;
+            boolean done = false;
+            switch (msg.what) {
+                case EVENT_VOICEMAIL_CHANGED:
+                    mVoicemailChangeResult = result;
+                    mVMChangeCompletedSuccessfully = checkVMChangeSuccess() == null;
+                    if (DBG) log("VM change complete msg, VM change done = " +
+                            String.valueOf(mVMChangeCompletedSuccessfully));
+                    done = true;
+                    break;
+                case EVENT_FORWARDING_CHANGED:
+                    mForwardingChangeResults.put(msg.arg1, result);
+                    if (result.exception != null) {
+                        Log.w(LOG_TAG, "Error in setting fwd# " + msg.arg1 + ": " +
+                                result.exception.getMessage());
+                    } else {
+                        if (DBG) log("Success in setting fwd# " + msg.arg1);
+                    }
+                    final boolean completed = checkForwardingCompleted();
+                    if (completed) {
+                        if (checkFwdChangeSuccess() == null) {
+                            if (DBG) log("Overall fwd changes completed ok, starting vm change");
+                            setVMNumberWithCarrier();
+                        } else {
+                            Log.w(LOG_TAG, "Overall fwd changes completed in failure. " +
+                                    "Check if we need to try rollback for some settings.");
+                            mFwdChangesRequireRollback = false;
+                            Iterator<Map.Entry<Integer,AsyncResult>> it =
+                                mForwardingChangeResults.entrySet().iterator();
+                            while (it.hasNext()) {
+                                Map.Entry<Integer,AsyncResult> entry = it.next();
+                                if (entry.getValue().exception == null) {
+                                    // If at least one succeeded we have to revert
+                                    Log.i(LOG_TAG, "Rollback will be required");
+                                    mFwdChangesRequireRollback = true;
+                                    break;
+                                }
+                            }
+                            if (!mFwdChangesRequireRollback) {
+                                Log.i(LOG_TAG, "No rollback needed.");
+                            }
+                            done = true;
+                        }
+                    }
+                    break;
+                default:
+                    // TODO: should never reach this, may want to throw exception
+            }
+            if (done) {
+                if (DBG) log("All VM provider related changes done");
+                if (mForwardingChangeResults != null) {
+                    dismissDialogSafely(VOICEMAIL_FWD_SAVING_DIALOG);
+                }
+                handleSetVMOrFwdMessage();
+            }
+        }
+    };
+
+    /**
+     * Callback to handle option revert completions
+     */
+    private final Handler mRevertOptionComplete = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            AsyncResult result = (AsyncResult) msg.obj;
+            switch (msg.what) {
+                case EVENT_VOICEMAIL_CHANGED:
+                    mVoicemailChangeResult = result;
+                    if (DBG) log("VM revert complete msg");
+                    break;
+                case EVENT_FORWARDING_CHANGED:
+                    mForwardingChangeResults.put(msg.arg1, result);
+                    if (result.exception != null) {
+                        if (DBG) log("Error in reverting fwd# " + msg.arg1 + ": " +
+                                result.exception.getMessage());
+                    } else {
+                        if (DBG) log("Success in reverting fwd# " + msg.arg1);
+                    }
+                    if (DBG) log("FWD revert complete msg ");
+                    break;
+                default:
+                    // TODO: should never reach this, may want to throw exception
+            }
+            final boolean done =
+                (!mVMChangeCompletedSuccessfully || mVoicemailChangeResult != null) &&
+                (!mFwdChangesRequireRollback || checkForwardingCompleted());
+            if (done) {
+                if (DBG) log("All VM reverts done");
+                dismissDialogSafely(VOICEMAIL_REVERTING_DIALOG);
+                onRevertDone();
+            }
+        }
+    };
+
+    /**
+     * @return true if forwarding change has completed
+     */
+    private boolean checkForwardingCompleted() {
+        boolean result;
+        if (mForwardingChangeResults == null) {
+            result = true;
+        } else {
+            // return true iff there is a change result for every reason for
+            // which we expected a result
+            result = true;
+            for (Integer reason : mExpectedChangeResultReasons) {
+                if (mForwardingChangeResults.get(reason) == null) {
+                    result = false;
+                    break;
+                }
+            }
+        }
+        return result;
+    }
+    /**
+     * @return error string or null if successful
+     */
+    private String checkFwdChangeSuccess() {
+        String result = null;
+        Iterator<Map.Entry<Integer,AsyncResult>> it =
+            mForwardingChangeResults.entrySet().iterator();
+        while (it.hasNext()) {
+            Map.Entry<Integer,AsyncResult> entry = it.next();
+            Throwable exception = entry.getValue().exception;
+            if (exception != null) {
+                result = exception.getMessage();
+                if (result == null) {
+                    result = "";
+                }
+                break;
+            }
+        }
+        return result;
+    }
+
+    /**
+     * @return error string or null if successful
+     */
+    private String checkVMChangeSuccess() {
+        if (mVoicemailChangeResult.exception != null) {
+            final String msg = mVoicemailChangeResult.exception.getMessage();
+            if (msg == null) {
+                return "";
+            }
+            return msg;
+        }
+        return null;
+    }
+
+    private void handleSetVMOrFwdMessage() {
+        if (DBG) {
+            log("handleSetVMMessage: set VM request complete");
+        }
+        boolean success = true;
+        boolean fwdFailure = false;
+        String exceptionMessage = "";
+        if (mForwardingChangeResults != null) {
+            exceptionMessage = checkFwdChangeSuccess();
+            if (exceptionMessage != null) {
+                success = false;
+                fwdFailure = true;
+            }
+        }
+        if (success) {
+            exceptionMessage = checkVMChangeSuccess();
+            if (exceptionMessage != null) {
+                success = false;
+            }
+        }
+        if (success) {
+            if (DBG) log("change VM success!");
+            handleVMAndFwdSetSuccess(MSG_VM_OK);
+        } else {
+            if (fwdFailure) {
+                Log.w(LOG_TAG, "Failed to change fowarding setting. Reason: " + exceptionMessage);
+                handleVMOrFwdSetError(MSG_FW_SET_EXCEPTION);
+            } else {
+                Log.w(LOG_TAG, "Failed to change voicemail. Reason: " + exceptionMessage);
+                handleVMOrFwdSetError(MSG_VM_EXCEPTION);
+            }
+        }
+    }
+
+    /**
+     * Called when Voicemail Provider or its forwarding settings failed. Rolls back partly made
+     * changes to those settings and show "failure" dialog.
+     *
+     * @param msgId Message ID used for the specific error case. {@link #MSG_FW_SET_EXCEPTION} or
+     * {@link #MSG_VM_EXCEPTION}
+     */
+    private void handleVMOrFwdSetError(int msgId) {
+        if (mChangingVMorFwdDueToProviderChange) {
+            mVMOrFwdSetError = msgId;
+            mChangingVMorFwdDueToProviderChange = false;
+            switchToPreviousVoicemailProvider();
+            return;
+        }
+        mChangingVMorFwdDueToProviderChange = false;
+        showVMDialog(msgId);
+        updateVoiceNumberField();
+    }
+
+    /**
+     * Called when Voicemail Provider and its forwarding settings were successfully finished.
+     * This updates a bunch of variables and show "success" dialog.
+     */
+    private void handleVMAndFwdSetSuccess(int msg) {
+        if (DBG) {
+            log("handleVMAndFwdSetSuccess(). current voicemail provider key: "
+                    + getCurrentVoicemailProviderKey());
+        }
+        mPreviousVMProviderKey = getCurrentVoicemailProviderKey();
+        mChangingVMorFwdDueToProviderChange = false;
+        showVMDialog(msg);
+        updateVoiceNumberField();
+    }
+
+    /**
+     * Update the voicemail number from what we've recorded on the sim.
+     */
+    private void updateVoiceNumberField() {
+        if (DBG) {
+            log("updateVoiceNumberField(). mSubMenuVoicemailSettings=" + mSubMenuVoicemailSettings);
+        }
+        if (mSubMenuVoicemailSettings == null) {
+            return;
+        }
+
+        mOldVmNumber = mPhone.getVoiceMailNumber();
+        if (mOldVmNumber == null) {
+            mOldVmNumber = "";
+        }
+        mSubMenuVoicemailSettings.setPhoneNumber(mOldVmNumber);
+        final String summary = (mOldVmNumber.length() > 0) ? mOldVmNumber :
+                getString(R.string.voicemail_number_not_set);
+        mSubMenuVoicemailSettings.setSummary(summary);
+    }
+
+    /*
+     * Helper Methods for Activity class.
+     * The initial query commands are split into two pieces now
+     * for individual expansion.  This combined with the ability
+     * to cancel queries allows for a much better user experience,
+     * and also ensures that the user only waits to update the
+     * data that is relevant.
+     */
+
+    @Override
+    protected void onPrepareDialog(int id, Dialog dialog) {
+        super.onPrepareDialog(id, dialog);
+        mCurrentDialogId = id;
+    }
+
+    // dialog creation method, called by showDialog()
+    @Override
+    protected Dialog onCreateDialog(int id) {
+        if ((id == VM_RESPONSE_ERROR) || (id == VM_NOCHANGE_ERROR) ||
+            (id == FW_SET_RESPONSE_ERROR) || (id == FW_GET_RESPONSE_ERROR) ||
+                (id == VOICEMAIL_DIALOG_CONFIRM)) {
+
+            AlertDialog.Builder b = new AlertDialog.Builder(this);
+
+            int msgId;
+            int titleId = R.string.error_updating_title;
+            switch (id) {
+                case VOICEMAIL_DIALOG_CONFIRM:
+                    msgId = R.string.vm_changed;
+                    titleId = R.string.voicemail;
+                    // Set Button 2
+                    b.setNegativeButton(R.string.close_dialog, this);
+                    break;
+                case VM_NOCHANGE_ERROR:
+                    // even though this is technically an error,
+                    // keep the title friendly.
+                    msgId = R.string.no_change;
+                    titleId = R.string.voicemail;
+                    // Set Button 2
+                    b.setNegativeButton(R.string.close_dialog, this);
+                    break;
+                case VM_RESPONSE_ERROR:
+                    msgId = R.string.vm_change_failed;
+                    // Set Button 1
+                    b.setPositiveButton(R.string.close_dialog, this);
+                    break;
+                case FW_SET_RESPONSE_ERROR:
+                    msgId = R.string.fw_change_failed;
+                    // Set Button 1
+                    b.setPositiveButton(R.string.close_dialog, this);
+                    break;
+                case FW_GET_RESPONSE_ERROR:
+                    msgId = R.string.fw_get_in_vm_failed;
+                    b.setPositiveButton(R.string.alert_dialog_yes, this);
+                    b.setNegativeButton(R.string.alert_dialog_no, this);
+                    break;
+                default:
+                    msgId = R.string.exception_error;
+                    // Set Button 3, tells the activity that the error is
+                    // not recoverable on dialog exit.
+                    b.setNeutralButton(R.string.close_dialog, this);
+                    break;
+            }
+
+            b.setTitle(getText(titleId));
+            String message = getText(msgId).toString();
+            b.setMessage(message);
+            b.setCancelable(false);
+            AlertDialog dialog = b.create();
+
+            // make the dialog more obvious by bluring the background.
+            dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
+
+            return dialog;
+        } else if (id == VOICEMAIL_FWD_SAVING_DIALOG || id == VOICEMAIL_FWD_READING_DIALOG ||
+                id == VOICEMAIL_REVERTING_DIALOG) {
+            ProgressDialog dialog = new ProgressDialog(this);
+            dialog.setTitle(getText(R.string.updating_title));
+            dialog.setIndeterminate(true);
+            dialog.setCancelable(false);
+            dialog.setMessage(getText(
+                    id == VOICEMAIL_FWD_SAVING_DIALOG ? R.string.updating_settings :
+                    (id == VOICEMAIL_REVERTING_DIALOG ? R.string.reverting_settings :
+                    R.string.reading_settings)));
+            return dialog;
+        }
+
+
+        return null;
+    }
+
+    // This is a method implemented for DialogInterface.OnClickListener.
+    // Used with the error dialog to close the app, voicemail dialog to just dismiss.
+    // Close button is mapped to BUTTON_POSITIVE for the errors that close the activity,
+    // while those that are mapped to BUTTON_NEUTRAL only move the preference focus.
+    public void onClick(DialogInterface dialog, int which) {
+        dialog.dismiss();
+        switch (which){
+            case DialogInterface.BUTTON_NEUTRAL:
+                if (DBG) log("Neutral button");
+                break;
+            case DialogInterface.BUTTON_NEGATIVE:
+                if (DBG) log("Negative button");
+                if (mCurrentDialogId == FW_GET_RESPONSE_ERROR) {
+                    // We failed to get current forwarding settings and the user
+                    // does not wish to continue.
+                    switchToPreviousVoicemailProvider();
+                }
+                break;
+            case DialogInterface.BUTTON_POSITIVE:
+                if (DBG) log("Positive button");
+                if (mCurrentDialogId == FW_GET_RESPONSE_ERROR) {
+                    // We failed to get current forwarding settings but the user
+                    // wishes to continue changing settings to the new vm provider
+                    saveVoiceMailAndForwardingNumberStage2();
+                } else {
+                    finish();
+                }
+                return;
+            default:
+                // just let the dialog close and go back to the input
+        }
+        // In all dialogs, all buttons except BUTTON_POSITIVE lead to the end of user interaction
+        // with settings UI. If we were called to explicitly configure voice mail then
+        // we finish the settings activity here to come back to whatever the user was doing.
+        if (getIntent().getAction().equals(ACTION_ADD_VOICEMAIL)) {
+            finish();
+        }
+    }
+
+    // set the app state with optional status.
+    private void showVMDialog(int msgStatus) {
+        switch (msgStatus) {
+            // It's a bit worrisome to punt in the error cases here when we're
+            // not in the foreground; maybe toast instead?
+            case MSG_VM_EXCEPTION:
+                showDialogIfForeground(VM_RESPONSE_ERROR);
+                break;
+            case MSG_FW_SET_EXCEPTION:
+                showDialogIfForeground(FW_SET_RESPONSE_ERROR);
+                break;
+            case MSG_FW_GET_EXCEPTION:
+                showDialogIfForeground(FW_GET_RESPONSE_ERROR);
+                break;
+            case MSG_VM_NOCHANGE:
+                showDialogIfForeground(VM_NOCHANGE_ERROR);
+                break;
+            case MSG_VM_OK:
+                showDialogIfForeground(VOICEMAIL_DIALOG_CONFIRM);
+                break;
+            case MSG_OK:
+            default:
+                // This should never happen.
+        }
+    }
+
+    /*
+     * Activity class methods
+     */
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        if (DBG) log("onCreate(). Intent: " + getIntent());
+        mPhone = PhoneGlobals.getPhone();
+
+        addPreferencesFromResource(R.xml.call_feature_setting);
+
+        mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+
+        // get buttons
+        PreferenceScreen prefSet = getPreferenceScreen();
+        mSubMenuVoicemailSettings = (EditPhoneNumberPreference)findPreference(BUTTON_VOICEMAIL_KEY);
+        if (mSubMenuVoicemailSettings != null) {
+            mSubMenuVoicemailSettings.setParentActivity(this, VOICEMAIL_PREF_ID, this);
+            mSubMenuVoicemailSettings.setDialogOnClosedListener(this);
+            mSubMenuVoicemailSettings.setDialogTitle(R.string.voicemail_settings_number_label);
+        }
+
+        mRingtonePreference = findPreference(BUTTON_RINGTONE_KEY);
+        mVibrateWhenRinging = (CheckBoxPreference) findPreference(BUTTON_VIBRATE_ON_RING);
+        mPlayDtmfTone = (CheckBoxPreference) findPreference(BUTTON_PLAY_DTMF_TONE);
+        mDialpadAutocomplete = (CheckBoxPreference) findPreference(BUTTON_DIALPAD_AUTOCOMPLETE);
+        mButtonDTMF = (ListPreference) findPreference(BUTTON_DTMF_KEY);
+        mButtonAutoRetry = (CheckBoxPreference) findPreference(BUTTON_RETRY_KEY);
+        mButtonHAC = (CheckBoxPreference) findPreference(BUTTON_HAC_KEY);
+        mButtonTTY = (ListPreference) findPreference(BUTTON_TTY_KEY);
+        mVoicemailProviders = (ListPreference) findPreference(BUTTON_VOICEMAIL_PROVIDER_KEY);
+        if (mVoicemailProviders != null) {
+            mVoicemailProviders.setOnPreferenceChangeListener(this);
+            mVoicemailSettings = (PreferenceScreen)findPreference(BUTTON_VOICEMAIL_SETTING_KEY);
+            mVoicemailNotificationRingtone =
+                    findPreference(BUTTON_VOICEMAIL_NOTIFICATION_RINGTONE_KEY);
+            mVoicemailNotificationVibrate =
+                    (CheckBoxPreference) findPreference(BUTTON_VOICEMAIL_NOTIFICATION_VIBRATE_KEY);
+            initVoiceMailProviders();
+        }
+
+        if (mVibrateWhenRinging != null) {
+            Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
+            if (vibrator != null && vibrator.hasVibrator()) {
+                mVibrateWhenRinging.setOnPreferenceChangeListener(this);
+            } else {
+                prefSet.removePreference(mVibrateWhenRinging);
+                mVibrateWhenRinging = null;
+            }
+        }
+
+        final ContentResolver contentResolver = getContentResolver();
+
+        if (mPlayDtmfTone != null) {
+            mPlayDtmfTone.setChecked(Settings.System.getInt(contentResolver,
+                    Settings.System.DTMF_TONE_WHEN_DIALING, 1) != 0);
+        }
+
+        if (mDialpadAutocomplete != null) {
+            mDialpadAutocomplete.setChecked(Settings.Secure.getInt(contentResolver,
+                    Settings.Secure.DIALPAD_AUTOCOMPLETE, 0) != 0);
+        }
+
+        if (mButtonDTMF != null) {
+            if (getResources().getBoolean(R.bool.dtmf_type_enabled)) {
+                mButtonDTMF.setOnPreferenceChangeListener(this);
+            } else {
+                prefSet.removePreference(mButtonDTMF);
+                mButtonDTMF = null;
+            }
+        }
+
+        if (mButtonAutoRetry != null) {
+            if (getResources().getBoolean(R.bool.auto_retry_enabled)) {
+                mButtonAutoRetry.setOnPreferenceChangeListener(this);
+            } else {
+                prefSet.removePreference(mButtonAutoRetry);
+                mButtonAutoRetry = null;
+            }
+        }
+
+        if (mButtonHAC != null) {
+            if (getResources().getBoolean(R.bool.hac_enabled)) {
+
+                mButtonHAC.setOnPreferenceChangeListener(this);
+            } else {
+                prefSet.removePreference(mButtonHAC);
+                mButtonHAC = null;
+            }
+        }
+
+        if (mButtonTTY != null) {
+            if (getResources().getBoolean(R.bool.tty_enabled)) {
+                mButtonTTY.setOnPreferenceChangeListener(this);
+            } else {
+                prefSet.removePreference(mButtonTTY);
+                mButtonTTY = null;
+            }
+        }
+
+        if (!getResources().getBoolean(R.bool.world_phone)) {
+            Preference options = prefSet.findPreference(BUTTON_CDMA_OPTIONS);
+            if (options != null)
+                prefSet.removePreference(options);
+            options = prefSet.findPreference(BUTTON_GSM_UMTS_OPTIONS);
+            if (options != null)
+                prefSet.removePreference(options);
+
+            int phoneType = mPhone.getPhoneType();
+            if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
+                Preference fdnButton = prefSet.findPreference(BUTTON_FDN_KEY);
+                if (fdnButton != null)
+                    prefSet.removePreference(fdnButton);
+                if (!getResources().getBoolean(R.bool.config_voice_privacy_disable)) {
+                    addPreferencesFromResource(R.xml.cdma_call_privacy);
+                }
+            } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
+                addPreferencesFromResource(R.xml.gsm_umts_call_options);
+            } else {
+                throw new IllegalStateException("Unexpected phone type: " + phoneType);
+            }
+        }
+
+        // create intent to bring up contact list
+        mContactListIntent = new Intent(Intent.ACTION_GET_CONTENT);
+        mContactListIntent.setType(android.provider.Contacts.Phones.CONTENT_ITEM_TYPE);
+
+        // check the intent that started this activity and pop up the voicemail
+        // dialog if we've been asked to.
+        // If we have at least one non default VM provider registered then bring up
+        // the selection for the VM provider, otherwise bring up a VM number dialog.
+        // We only bring up the dialog the first time we are called (not after orientation change)
+        if (icicle == null) {
+            if (getIntent().getAction().equals(ACTION_ADD_VOICEMAIL) &&
+                    mVoicemailProviders != null) {
+                if (DBG) {
+                    log("ACTION_ADD_VOICEMAIL Intent is thrown. current VM data size: "
+                            + mVMProvidersData.size());
+                }
+                if (mVMProvidersData.size() > 1) {
+                    simulatePreferenceClick(mVoicemailProviders);
+                } else {
+                    onPreferenceChange(mVoicemailProviders, DEFAULT_VM_PROVIDER_KEY);
+                    mVoicemailProviders.setValue(DEFAULT_VM_PROVIDER_KEY);
+                }
+            }
+        }
+        updateVoiceNumberField();
+        mVMProviderSettingsForced = false;
+        createSipCallSettings();
+
+        mRingtoneLookupRunnable = new Runnable() {
+            @Override
+            public void run() {
+                if (mRingtonePreference != null) {
+                    updateRingtoneName(RingtoneManager.TYPE_RINGTONE, mRingtonePreference,
+                            MSG_UPDATE_RINGTONE_SUMMARY);
+                }
+                if (mVoicemailNotificationRingtone != null) {
+                    updateRingtoneName(RingtoneManager.TYPE_NOTIFICATION,
+                            mVoicemailNotificationRingtone, MSG_UPDATE_VOICEMAIL_RINGTONE_SUMMARY);
+                }
+            }
+        };
+
+        ActionBar actionBar = getActionBar();
+        if (actionBar != null) {
+            // android.R.id.home will be triggered in onOptionsItemSelected()
+            actionBar.setDisplayHomeAsUpEnabled(true);
+        }
+    }
+
+    /**
+     * Updates ringtone name. This is a method copied from com.android.settings.SoundSettings
+     *
+     * @see com.android.settings.SoundSettings
+     */
+    private void updateRingtoneName(int type, Preference preference, int msg) {
+        if (preference == null) return;
+        final Uri ringtoneUri;
+        boolean defaultRingtone = false;
+        if (type == RingtoneManager.TYPE_RINGTONE) {
+            // For ringtones, we can just lookup the system default because changing the settings
+            // in Call Settings changes the system default.
+            ringtoneUri = RingtoneManager.getActualDefaultRingtoneUri(this, type);
+        } else {
+            final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(
+                    mPhone.getContext());
+            // for voicemail notifications, we use the value saved in Phone's shared preferences.
+            String uriString = prefs.getString(preference.getKey(), null);
+            if (TextUtils.isEmpty(uriString)) {
+                // silent ringtone
+                ringtoneUri = null;
+            } else {
+                if (uriString.equals(Settings.System.DEFAULT_NOTIFICATION_URI.toString())) {
+                    // If it turns out that the voicemail notification is set to the system
+                    // default notification, we retrieve the actual URI to prevent it from showing
+                    // up as "Unknown Ringtone".
+                    defaultRingtone = true;
+                    ringtoneUri = RingtoneManager.getActualDefaultRingtoneUri(this, type);
+                } else {
+                    ringtoneUri = Uri.parse(uriString);
+                }
+            }
+        }
+        CharSequence summary = getString(com.android.internal.R.string.ringtone_unknown);
+        // Is it a silent ringtone?
+        if (ringtoneUri == null) {
+            summary = getString(com.android.internal.R.string.ringtone_silent);
+        } else {
+            // Fetch the ringtone title from the media provider
+            try {
+                Cursor cursor = getContentResolver().query(ringtoneUri,
+                        new String[] { MediaStore.Audio.Media.TITLE }, null, null, null);
+                if (cursor != null) {
+                    if (cursor.moveToFirst()) {
+                        summary = cursor.getString(0);
+                    }
+                    cursor.close();
+                }
+            } catch (SQLiteException sqle) {
+                // Unknown title for the ringtone
+            }
+        }
+        if (defaultRingtone) {
+            summary = mPhone.getContext().getString(
+                    R.string.default_notification_description, summary);
+        }
+        mRingtoneLookupComplete.sendMessage(mRingtoneLookupComplete.obtainMessage(msg, summary));
+    }
+
+    private void createSipCallSettings() {
+        // Add Internet call settings.
+        if (PhoneUtils.isVoipSupported()) {
+            mSipManager = SipManager.newInstance(this);
+            mSipSharedPreferences = new SipSharedPreferences(this);
+            addPreferencesFromResource(R.xml.sip_settings_category);
+            mButtonSipCallOptions = getSipCallOptionPreference();
+            mButtonSipCallOptions.setOnPreferenceChangeListener(this);
+            mButtonSipCallOptions.setValueIndex(
+                    mButtonSipCallOptions.findIndexOfValue(
+                            mSipSharedPreferences.getSipCallOption()));
+            mButtonSipCallOptions.setSummary(mButtonSipCallOptions.getEntry());
+        }
+    }
+
+    // Gets the call options for SIP depending on whether SIP is allowed only
+    // on Wi-Fi only; also make the other options preference invisible.
+    private ListPreference getSipCallOptionPreference() {
+        ListPreference wifiAnd3G = (ListPreference)
+                findPreference(BUTTON_SIP_CALL_OPTIONS);
+        ListPreference wifiOnly = (ListPreference)
+                findPreference(BUTTON_SIP_CALL_OPTIONS_WIFI_ONLY);
+        PreferenceGroup sipSettings = (PreferenceGroup)
+                findPreference(SIP_SETTINGS_CATEGORY_KEY);
+        if (SipManager.isSipWifiOnly(this)) {
+            sipSettings.removePreference(wifiAnd3G);
+            return wifiOnly;
+        } else {
+            sipSettings.removePreference(wifiOnly);
+            return wifiAnd3G;
+        }
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        mForeground = true;
+
+        if (isAirplaneModeOn()) {
+            Preference sipSettings = findPreference(SIP_SETTINGS_CATEGORY_KEY);
+            PreferenceScreen screen = getPreferenceScreen();
+            int count = screen.getPreferenceCount();
+            for (int i = 0 ; i < count ; ++i) {
+                Preference pref = screen.getPreference(i);
+                if (pref != sipSettings) pref.setEnabled(false);
+            }
+            return;
+        }
+
+        if (mVibrateWhenRinging != null) {
+            mVibrateWhenRinging.setChecked(getVibrateWhenRinging(this));
+        }
+
+        if (mButtonDTMF != null) {
+            int dtmf = Settings.System.getInt(getContentResolver(),
+                    Settings.System.DTMF_TONE_TYPE_WHEN_DIALING, Constants.DTMF_TONE_TYPE_NORMAL);
+            mButtonDTMF.setValueIndex(dtmf);
+        }
+
+        if (mButtonAutoRetry != null) {
+            int autoretry = Settings.Global.getInt(getContentResolver(),
+                    Settings.Global.CALL_AUTO_RETRY, 0);
+            mButtonAutoRetry.setChecked(autoretry != 0);
+        }
+
+        if (mButtonHAC != null) {
+            int hac = Settings.System.getInt(getContentResolver(), Settings.System.HEARING_AID, 0);
+            mButtonHAC.setChecked(hac != 0);
+        }
+
+        if (mButtonTTY != null) {
+            int settingsTtyMode = Settings.Secure.getInt(getContentResolver(),
+                    Settings.Secure.PREFERRED_TTY_MODE,
+                    Phone.TTY_MODE_OFF);
+            mButtonTTY.setValue(Integer.toString(settingsTtyMode));
+            updatePreferredTtyModeSummary(settingsTtyMode);
+        }
+
+        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(
+                mPhone.getContext());
+        if (migrateVoicemailVibrationSettingsIfNeeded(prefs)) {
+            mVoicemailNotificationVibrate.setChecked(prefs.getBoolean(
+                    BUTTON_VOICEMAIL_NOTIFICATION_VIBRATE_KEY, false));
+        }
+
+        lookupRingtoneName();
+    }
+
+    // Migrate settings from BUTTON_VOICEMAIL_NOTIFICATION_VIBRATE_WHEN_KEY to
+    // BUTTON_VOICEMAIL_NOTIFICATION_VIBRATE_KEY, if the latter does not exist.
+    // Returns true if migration was performed.
+    public static boolean migrateVoicemailVibrationSettingsIfNeeded(SharedPreferences prefs) {
+        if (!prefs.contains(BUTTON_VOICEMAIL_NOTIFICATION_VIBRATE_KEY)) {
+            String vibrateWhen = prefs.getString(
+                    BUTTON_VOICEMAIL_NOTIFICATION_VIBRATE_WHEN_KEY, VOICEMAIL_VIBRATION_NEVER);
+            // If vibrateWhen is always, then voicemailVibrate should be True.
+            // otherwise if vibrateWhen is "only in silent mode", or "never", then
+            // voicemailVibrate = False.
+            boolean voicemailVibrate = vibrateWhen.equals(VOICEMAIL_VIBRATION_ALWAYS);
+            final SharedPreferences.Editor editor = prefs.edit();
+            editor.putBoolean(BUTTON_VOICEMAIL_NOTIFICATION_VIBRATE_KEY, voicemailVibrate);
+            editor.commit();
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Obtain the setting for "vibrate when ringing" setting.
+     *
+     * Watch out: if the setting is missing in the device, this will try obtaining the old
+     * "vibrate on ring" setting from AudioManager, and save the previous setting to the new one.
+     */
+    public static boolean getVibrateWhenRinging(Context context) {
+        Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
+        if (vibrator == null || !vibrator.hasVibrator()) {
+            return false;
+        }
+        return Settings.System.getInt(context.getContentResolver(),
+                Settings.System.VIBRATE_WHEN_RINGING, 0) != 0;
+    }
+
+    /**
+     * Lookups ringtone name asynchronously and updates the relevant Preference.
+     */
+    private void lookupRingtoneName() {
+        new Thread(mRingtoneLookupRunnable).start();
+    }
+
+    private boolean isAirplaneModeOn() {
+        return Settings.System.getInt(getContentResolver(),
+                Settings.System.AIRPLANE_MODE_ON, 0) != 0;
+    }
+
+    private void handleTTYChange(Preference preference, Object objValue) {
+        int buttonTtyMode;
+        buttonTtyMode = Integer.valueOf((String) objValue).intValue();
+        int settingsTtyMode = android.provider.Settings.Secure.getInt(
+                getContentResolver(),
+                android.provider.Settings.Secure.PREFERRED_TTY_MODE, preferredTtyMode);
+        if (DBG) log("handleTTYChange: requesting set TTY mode enable (TTY) to" +
+                Integer.toString(buttonTtyMode));
+
+        if (buttonTtyMode != settingsTtyMode) {
+            switch(buttonTtyMode) {
+            case Phone.TTY_MODE_OFF:
+            case Phone.TTY_MODE_FULL:
+            case Phone.TTY_MODE_HCO:
+            case Phone.TTY_MODE_VCO:
+                android.provider.Settings.Secure.putInt(getContentResolver(),
+                        android.provider.Settings.Secure.PREFERRED_TTY_MODE, buttonTtyMode);
+                break;
+            default:
+                buttonTtyMode = Phone.TTY_MODE_OFF;
+            }
+
+            mButtonTTY.setValue(Integer.toString(buttonTtyMode));
+            updatePreferredTtyModeSummary(buttonTtyMode);
+            Intent ttyModeChanged = new Intent(TtyIntent.TTY_PREFERRED_MODE_CHANGE_ACTION);
+            ttyModeChanged.putExtra(TtyIntent.TTY_PREFFERED_MODE, buttonTtyMode);
+            sendBroadcastAsUser(ttyModeChanged, UserHandle.ALL);
+        }
+    }
+
+    private void handleSipCallOptionsChange(Object objValue) {
+        String option = objValue.toString();
+        mSipSharedPreferences.setSipCallOption(option);
+        mButtonSipCallOptions.setValueIndex(
+                mButtonSipCallOptions.findIndexOfValue(option));
+        mButtonSipCallOptions.setSummary(mButtonSipCallOptions.getEntry());
+    }
+
+    private void updatePreferredTtyModeSummary(int TtyMode) {
+        String [] txts = getResources().getStringArray(R.array.tty_mode_entries);
+        switch(TtyMode) {
+            case Phone.TTY_MODE_OFF:
+            case Phone.TTY_MODE_HCO:
+            case Phone.TTY_MODE_VCO:
+            case Phone.TTY_MODE_FULL:
+                mButtonTTY.setSummary(txts[TtyMode]);
+                break;
+            default:
+                mButtonTTY.setEnabled(false);
+                mButtonTTY.setSummary(txts[Phone.TTY_MODE_OFF]);
+        }
+    }
+
+    private static void log(String msg) {
+        Log.d(LOG_TAG, msg);
+    }
+
+    /**
+     * Updates the look of the VM preference widgets based on current VM provider settings.
+     * Note that the provider name is loaded form the found activity via loadLabel in
+     * {@link #initVoiceMailProviders()} in order for it to be localizable.
+     */
+    private void updateVMPreferenceWidgets(String currentProviderSetting) {
+        final String key = currentProviderSetting;
+        final VoiceMailProvider provider = mVMProvidersData.get(key);
+
+        /* This is the case when we are coming up on a freshly wiped phone and there is no
+         persisted value for the list preference mVoicemailProviders.
+         In this case we want to show the UI asking the user to select a voicemail provider as
+         opposed to silently falling back to default one. */
+        if (provider == null) {
+            if (DBG) {
+                log("updateVMPreferenceWidget: provider for the key \"" + key + "\" is null.");
+            }
+            mVoicemailProviders.setSummary(getString(R.string.sum_voicemail_choose_provider));
+            mVoicemailSettings.setEnabled(false);
+            mVoicemailSettings.setIntent(null);
+
+            mVoicemailNotificationVibrate.setEnabled(false);
+        } else {
+            if (DBG) {
+                log("updateVMPreferenceWidget: provider for the key \"" + key + "\".."
+                        + "name: " + provider.name
+                        + ", intent: " + provider.intent);
+            }
+            final String providerName = provider.name;
+            mVoicemailProviders.setSummary(providerName);
+            mVoicemailSettings.setEnabled(true);
+            mVoicemailSettings.setIntent(provider.intent);
+
+            mVoicemailNotificationVibrate.setEnabled(true);
+        }
+    }
+
+    /**
+     * Enumerates existing VM providers and puts their data into the list and populates
+     * the preference list objects with their names.
+     * In case we are called with ACTION_ADD_VOICEMAIL intent the intent may have
+     * an extra string called IGNORE_PROVIDER_EXTRA with "package.activityName" of the provider
+     * which should be hidden when we bring up the list of possible VM providers to choose.
+     */
+    private void initVoiceMailProviders() {
+        if (DBG) log("initVoiceMailProviders()");
+        mPerProviderSavedVMNumbers =
+                this.getApplicationContext().getSharedPreferences(
+                        VM_NUMBERS_SHARED_PREFERENCES_NAME, MODE_PRIVATE);
+
+        String providerToIgnore = null;
+        if (getIntent().getAction().equals(ACTION_ADD_VOICEMAIL)) {
+            if (getIntent().hasExtra(IGNORE_PROVIDER_EXTRA)) {
+                providerToIgnore = getIntent().getStringExtra(IGNORE_PROVIDER_EXTRA);
+            }
+            if (DBG) log("Found ACTION_ADD_VOICEMAIL. providerToIgnore=" + providerToIgnore);
+            if (providerToIgnore != null) {
+                // IGNORE_PROVIDER_EXTRA implies we want to remove the choice from the list.
+                deleteSettingsForVoicemailProvider(providerToIgnore);
+            }
+        }
+
+        mVMProvidersData.clear();
+
+        // Stick the default element which is always there
+        final String myCarrier = getString(R.string.voicemail_default);
+        mVMProvidersData.put(DEFAULT_VM_PROVIDER_KEY, new VoiceMailProvider(myCarrier, null));
+
+        // Enumerate providers
+        PackageManager pm = getPackageManager();
+        Intent intent = new Intent();
+        intent.setAction(ACTION_CONFIGURE_VOICEMAIL);
+        List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0);
+        int len = resolveInfos.size() + 1; // +1 for the default choice we will insert.
+
+        // Go through the list of discovered providers populating the data map
+        // skip the provider we were instructed to ignore if there was one
+        for (int i = 0; i < resolveInfos.size(); i++) {
+            final ResolveInfo ri= resolveInfos.get(i);
+            final ActivityInfo currentActivityInfo = ri.activityInfo;
+            final String key = makeKeyForActivity(currentActivityInfo);
+            if (key.equals(providerToIgnore)) {
+                if (DBG) log("Ignoring key: " + key);
+                len--;
+                continue;
+            }
+            if (DBG) log("Loading key: " + key);
+            final String nameForDisplay = ri.loadLabel(pm).toString();
+            Intent providerIntent = new Intent();
+            providerIntent.setAction(ACTION_CONFIGURE_VOICEMAIL);
+            providerIntent.setClassName(currentActivityInfo.packageName,
+                    currentActivityInfo.name);
+            if (DBG) {
+                log("Store loaded VoiceMailProvider. key: " + key
+                        + " -> name: " + nameForDisplay + ", intent: " + providerIntent);
+            }
+            mVMProvidersData.put(
+                    key,
+                    new VoiceMailProvider(nameForDisplay, providerIntent));
+
+        }
+
+        // Now we know which providers to display - create entries and values array for
+        // the list preference
+        String [] entries = new String [len];
+        String [] values = new String [len];
+        entries[0] = myCarrier;
+        values[0] = DEFAULT_VM_PROVIDER_KEY;
+        int entryIdx = 1;
+        for (int i = 0; i < resolveInfos.size(); i++) {
+            final String key = makeKeyForActivity(resolveInfos.get(i).activityInfo);
+            if (!mVMProvidersData.containsKey(key)) {
+                continue;
+            }
+            entries[entryIdx] = mVMProvidersData.get(key).name;
+            values[entryIdx] = key;
+            entryIdx++;
+        }
+
+        // ListPreference is now updated.
+        mVoicemailProviders.setEntries(entries);
+        mVoicemailProviders.setEntryValues(values);
+
+        // Remember the current Voicemail Provider key as a "previous" key. This will be used
+        // when we fail to update Voicemail Provider, which requires rollback.
+        // We will update this when the VM Provider setting is successfully updated.
+        mPreviousVMProviderKey = getCurrentVoicemailProviderKey();
+        if (DBG) log("Set up the first mPreviousVMProviderKey: " + mPreviousVMProviderKey);
+
+        // Finally update the preference texts.
+        updateVMPreferenceWidgets(mPreviousVMProviderKey);
+    }
+
+    private String makeKeyForActivity(ActivityInfo ai) {
+        return ai.name;
+    }
+
+    /**
+     * Simulates user clicking on a passed preference.
+     * Usually needed when the preference is a dialog preference and we want to invoke
+     * a dialog for this preference programmatically.
+     * TODO(iliat): figure out if there is a cleaner way to cause preference dlg to come up
+     */
+    private void simulatePreferenceClick(Preference preference) {
+        // Go through settings until we find our setting
+        // and then simulate a click on it to bring up the dialog
+        final ListAdapter adapter = getPreferenceScreen().getRootAdapter();
+        for (int idx = 0; idx < adapter.getCount(); idx++) {
+            if (adapter.getItem(idx) == preference) {
+                getPreferenceScreen().onItemClick(this.getListView(),
+                        null, idx, adapter.getItemId(idx));
+                break;
+            }
+        }
+    }
+
+    /**
+     * Saves new VM provider settings associating them with the currently selected
+     * provider if settings are different than the ones already stored for this
+     * provider.
+     * Later on these will be used when the user switches a provider.
+     */
+    private void maybeSaveSettingsForVoicemailProvider(String key,
+            VoiceMailProviderSettings newSettings) {
+        if (mVoicemailProviders == null) {
+            return;
+        }
+        final VoiceMailProviderSettings curSettings = loadSettingsForVoiceMailProvider(key);
+        if (newSettings.equals(curSettings)) {
+            if (DBG) {
+                log("maybeSaveSettingsForVoicemailProvider:"
+                        + " Not saving setting for " + key + " since they have not changed");
+            }
+            return;
+        }
+        if (DBG) log("Saving settings for " + key + ": " + newSettings.toString());
+        Editor editor = mPerProviderSavedVMNumbers.edit();
+        editor.putString(key + VM_NUMBER_TAG, newSettings.voicemailNumber);
+        String fwdKey = key + FWD_SETTINGS_TAG;
+        CallForwardInfo[] s = newSettings.forwardingSettings;
+        if (s != FWD_SETTINGS_DONT_TOUCH) {
+            editor.putInt(fwdKey + FWD_SETTINGS_LENGTH_TAG, s.length);
+            for (int i = 0; i < s.length; i++) {
+                final String settingKey = fwdKey + FWD_SETTING_TAG + String.valueOf(i);
+                final CallForwardInfo fi = s[i];
+                editor.putInt(settingKey + FWD_SETTING_STATUS, fi.status);
+                editor.putInt(settingKey + FWD_SETTING_REASON, fi.reason);
+                editor.putString(settingKey + FWD_SETTING_NUMBER, fi.number);
+                editor.putInt(settingKey + FWD_SETTING_TIME, fi.timeSeconds);
+            }
+        } else {
+            editor.putInt(fwdKey + FWD_SETTINGS_LENGTH_TAG, 0);
+        }
+        editor.apply();
+    }
+
+    /**
+     * Returns settings previously stored for the currently selected
+     * voice mail provider. If none is stored returns null.
+     * If the user switches to a voice mail provider and we have settings
+     * stored for it we will automatically change the phone's voice mail number
+     * and forwarding number to the stored one. Otherwise we will bring up provider's configuration
+     * UI.
+     */
+    private VoiceMailProviderSettings loadSettingsForVoiceMailProvider(String key) {
+        final String vmNumberSetting = mPerProviderSavedVMNumbers.getString(key + VM_NUMBER_TAG,
+                null);
+        if (vmNumberSetting == null) {
+            Log.w(LOG_TAG, "VoiceMailProvider settings for the key \"" + key + "\""
+                    + " was not found. Returning null.");
+            return null;
+        }
+
+        CallForwardInfo[] cfi = FWD_SETTINGS_DONT_TOUCH;
+        String fwdKey = key + FWD_SETTINGS_TAG;
+        final int fwdLen = mPerProviderSavedVMNumbers.getInt(fwdKey + FWD_SETTINGS_LENGTH_TAG, 0);
+        if (fwdLen > 0) {
+            cfi = new CallForwardInfo[fwdLen];
+            for (int i = 0; i < cfi.length; i++) {
+                final String settingKey = fwdKey + FWD_SETTING_TAG + String.valueOf(i);
+                cfi[i] = new CallForwardInfo();
+                cfi[i].status = mPerProviderSavedVMNumbers.getInt(
+                        settingKey + FWD_SETTING_STATUS, 0);
+                cfi[i].reason = mPerProviderSavedVMNumbers.getInt(
+                        settingKey + FWD_SETTING_REASON,
+                        CommandsInterface.CF_REASON_ALL_CONDITIONAL);
+                cfi[i].serviceClass = CommandsInterface.SERVICE_CLASS_VOICE;
+                cfi[i].toa = PhoneNumberUtils.TOA_International;
+                cfi[i].number = mPerProviderSavedVMNumbers.getString(
+                        settingKey + FWD_SETTING_NUMBER, "");
+                cfi[i].timeSeconds = mPerProviderSavedVMNumbers.getInt(
+                        settingKey + FWD_SETTING_TIME, 20);
+            }
+        }
+
+        VoiceMailProviderSettings settings =  new VoiceMailProviderSettings(vmNumberSetting, cfi);
+        if (DBG) log("Loaded settings for " + key + ": " + settings.toString());
+        return settings;
+    }
+
+    /**
+     * Deletes settings for the specified provider.
+     */
+    private void deleteSettingsForVoicemailProvider(String key) {
+        if (DBG) log("Deleting settings for" + key);
+        if (mVoicemailProviders == null) {
+            return;
+        }
+        mPerProviderSavedVMNumbers.edit()
+            .putString(key + VM_NUMBER_TAG, null)
+            .putInt(key + FWD_SETTINGS_TAG + FWD_SETTINGS_LENGTH_TAG, 0)
+            .commit();
+    }
+
+    private String getCurrentVoicemailProviderKey() {
+        final String key = mVoicemailProviders.getValue();
+        return (key != null) ? key : DEFAULT_VM_PROVIDER_KEY;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        final int itemId = item.getItemId();
+        if (itemId == android.R.id.home) {  // See ActionBar#setDisplayHomeAsUpEnabled()
+            Intent intent = new Intent();
+            intent.setClassName(UP_ACTIVITY_PACKAGE, UP_ACTIVITY_CLASS);
+            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+            startActivity(intent);
+            finish();
+            return true;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    /**
+     * Finish current Activity and go up to the top level Settings ({@link CallFeaturesSetting}).
+     * This is useful for implementing "HomeAsUp" capability for second-level Settings.
+     */
+    public static void goUpToTopLevelSetting(Activity activity) {
+        Intent intent = new Intent(activity, CallFeaturesSetting.class);
+        intent.setAction(Intent.ACTION_MAIN);
+        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+        activity.startActivity(intent);
+        activity.finish();
+    }
+}
diff --git a/src/com/android/phone/CallForwardEditPreference.java b/src/com/android/phone/CallForwardEditPreference.java
new file mode 100644
index 0000000..f925022
--- /dev/null
+++ b/src/com/android/phone/CallForwardEditPreference.java
@@ -0,0 +1,265 @@
+package com.android.phone;
+
+import com.android.internal.telephony.CallForwardInfo;
+import com.android.internal.telephony.CommandException;
+import com.android.internal.telephony.CommandsInterface;
+import com.android.internal.telephony.Phone;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.res.TypedArray;
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.Message;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+
+import static com.android.phone.TimeConsumingPreferenceActivity.RESPONSE_ERROR;
+
+public class CallForwardEditPreference extends EditPhoneNumberPreference {
+    private static final String LOG_TAG = "CallForwardEditPreference";
+    private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
+
+    private static final String SRC_TAGS[]       = {"{0}"};
+    private CharSequence mSummaryOnTemplate;
+    /**
+     * Remembers which button was clicked by a user. If no button is clicked yet, this should have
+     * {@link DialogInterface#BUTTON_NEGATIVE}, meaning "cancel".
+     *
+     * TODO: consider removing this variable and having getButtonClicked() in
+     * EditPhoneNumberPreference instead.
+     */
+    private int mButtonClicked;
+    private int mServiceClass;
+    private MyHandler mHandler = new MyHandler();
+    int reason;
+    Phone phone;
+    CallForwardInfo callForwardInfo;
+    TimeConsumingPreferenceListener tcpListener;
+
+    public CallForwardEditPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        phone = PhoneGlobals.getPhone();
+        mSummaryOnTemplate = this.getSummaryOn();
+
+        TypedArray a = context.obtainStyledAttributes(attrs,
+                R.styleable.CallForwardEditPreference, 0, R.style.EditPhoneNumberPreference);
+        mServiceClass = a.getInt(R.styleable.CallForwardEditPreference_serviceClass,
+                CommandsInterface.SERVICE_CLASS_VOICE);
+        reason = a.getInt(R.styleable.CallForwardEditPreference_reason,
+                CommandsInterface.CF_REASON_UNCONDITIONAL);
+        a.recycle();
+
+        if (DBG) Log.d(LOG_TAG, "mServiceClass=" + mServiceClass + ", reason=" + reason);
+    }
+
+    public CallForwardEditPreference(Context context) {
+        this(context, null);
+    }
+
+    void init(TimeConsumingPreferenceListener listener, boolean skipReading) {
+        tcpListener = listener;
+        if (!skipReading) {
+            phone.getCallForwardingOption(reason,
+                    mHandler.obtainMessage(MyHandler.MESSAGE_GET_CF,
+                            // unused in this case
+                            CommandsInterface.CF_ACTION_DISABLE,
+                            MyHandler.MESSAGE_GET_CF, null));
+            if (tcpListener != null) {
+                tcpListener.onStarted(this, true);
+            }
+        }
+    }
+
+    @Override
+    protected void onBindDialogView(View view) {
+        // default the button clicked to be the cancel button.
+        mButtonClicked = DialogInterface.BUTTON_NEGATIVE;
+        super.onBindDialogView(view);
+    }
+
+    @Override
+    public void onClick(DialogInterface dialog, int which) {
+        super.onClick(dialog, which);
+        mButtonClicked = which;
+    }
+
+    @Override
+    protected void onDialogClosed(boolean positiveResult) {
+        super.onDialogClosed(positiveResult);
+
+        if (DBG) Log.d(LOG_TAG, "mButtonClicked=" + mButtonClicked
+                + ", positiveResult=" + positiveResult);
+        // Ignore this event if the user clicked the cancel button, or if the dialog is dismissed
+        // without any button being pressed (back button press or click event outside the dialog).
+        if (this.mButtonClicked != DialogInterface.BUTTON_NEGATIVE) {
+            int action = (isToggled() || (mButtonClicked == DialogInterface.BUTTON_POSITIVE)) ?
+                    CommandsInterface.CF_ACTION_REGISTRATION :
+                    CommandsInterface.CF_ACTION_DISABLE;
+            int time = (reason != CommandsInterface.CF_REASON_NO_REPLY) ? 0 : 20;
+            final String number = getPhoneNumber();
+
+            if (DBG) Log.d(LOG_TAG, "callForwardInfo=" + callForwardInfo);
+
+            if (action == CommandsInterface.CF_ACTION_REGISTRATION
+                    && callForwardInfo != null
+                    && callForwardInfo.status == 1
+                    && number.equals(callForwardInfo.number)) {
+                // no change, do nothing
+                if (DBG) Log.d(LOG_TAG, "no change, do nothing");
+            } else {
+                // set to network
+                if (DBG) Log.d(LOG_TAG, "reason=" + reason + ", action=" + action
+                        + ", number=" + number);
+
+                // Display no forwarding number while we're waiting for
+                // confirmation
+                setSummaryOn("");
+
+                // the interface of Phone.setCallForwardingOption has error:
+                // should be action, reason...
+                phone.setCallForwardingOption(action,
+                        reason,
+                        number,
+                        time,
+                        mHandler.obtainMessage(MyHandler.MESSAGE_SET_CF,
+                                action,
+                                MyHandler.MESSAGE_SET_CF));
+
+                if (tcpListener != null) {
+                    tcpListener.onStarted(this, false);
+                }
+            }
+        }
+    }
+
+    void handleCallForwardResult(CallForwardInfo cf) {
+        callForwardInfo = cf;
+        if (DBG) Log.d(LOG_TAG, "handleGetCFResponse done, callForwardInfo=" + callForwardInfo);
+
+        setToggled(callForwardInfo.status == 1);
+        setPhoneNumber(callForwardInfo.number);
+    }
+
+    private void updateSummaryText() {
+        if (isToggled()) {
+            CharSequence summaryOn;
+            final String number = getRawPhoneNumber();
+            if (number != null && number.length() > 0) {
+                String values[] = { number };
+                summaryOn = TextUtils.replace(mSummaryOnTemplate, SRC_TAGS, values);
+            } else {
+                summaryOn = getContext().getString(R.string.sum_cfu_enabled_no_number);
+            }
+            setSummaryOn(summaryOn);
+        }
+
+    }
+
+    // Message protocol:
+    // what: get vs. set
+    // arg1: action -- register vs. disable
+    // arg2: get vs. set for the preceding request
+    private class MyHandler extends Handler {
+        static final int MESSAGE_GET_CF = 0;
+        static final int MESSAGE_SET_CF = 1;
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MESSAGE_GET_CF:
+                    handleGetCFResponse(msg);
+                    break;
+                case MESSAGE_SET_CF:
+                    handleSetCFResponse(msg);
+                    break;
+            }
+        }
+
+        private void handleGetCFResponse(Message msg) {
+            if (DBG) Log.d(LOG_TAG, "handleGetCFResponse: done");
+
+            if (msg.arg2 == MESSAGE_SET_CF) {
+                tcpListener.onFinished(CallForwardEditPreference.this, false);
+            } else {
+                tcpListener.onFinished(CallForwardEditPreference.this, true);
+            }
+
+            AsyncResult ar = (AsyncResult) msg.obj;
+
+            callForwardInfo = null;
+            if (ar.exception != null) {
+                if (DBG) Log.d(LOG_TAG, "handleGetCFResponse: ar.exception=" + ar.exception);
+                tcpListener.onException(CallForwardEditPreference.this,
+                        (CommandException) ar.exception);
+            } else {
+                if (ar.userObj instanceof Throwable) {
+                    tcpListener.onError(CallForwardEditPreference.this, RESPONSE_ERROR);
+                }
+                CallForwardInfo cfInfoArray[] = (CallForwardInfo[]) ar.result;
+                if (cfInfoArray.length == 0) {
+                    if (DBG) Log.d(LOG_TAG, "handleGetCFResponse: cfInfoArray.length==0");
+                    setEnabled(false);
+                    tcpListener.onError(CallForwardEditPreference.this, RESPONSE_ERROR);
+                } else {
+                    for (int i = 0, length = cfInfoArray.length; i < length; i++) {
+                        if (DBG) Log.d(LOG_TAG, "handleGetCFResponse, cfInfoArray[" + i + "]="
+                                + cfInfoArray[i]);
+                        if ((mServiceClass & cfInfoArray[i].serviceClass) != 0) {
+                            // corresponding class
+                            CallForwardInfo info = cfInfoArray[i];
+                            handleCallForwardResult(info);
+
+                            // Show an alert if we got a success response but
+                            // with unexpected values.
+                            // Currently only handle the fail-to-disable case
+                            // since we haven't observed fail-to-enable.
+                            if (msg.arg2 == MESSAGE_SET_CF &&
+                                    msg.arg1 == CommandsInterface.CF_ACTION_DISABLE &&
+                                    info.status == 1) {
+                                CharSequence s;
+                                switch (reason) {
+                                    case CommandsInterface.CF_REASON_BUSY:
+                                        s = getContext().getText(R.string.disable_cfb_forbidden);
+                                        break;
+                                    case CommandsInterface.CF_REASON_NO_REPLY:
+                                        s = getContext().getText(R.string.disable_cfnry_forbidden);
+                                        break;
+                                    default: // not reachable
+                                        s = getContext().getText(R.string.disable_cfnrc_forbidden);
+                                }
+                                AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
+                                builder.setNeutralButton(R.string.close_dialog, null);
+                                builder.setTitle(getContext().getText(R.string.error_updating_title));
+                                builder.setMessage(s);
+                                builder.setCancelable(true);
+                                builder.create().show();
+                            }
+                        }
+                    }
+                }
+            }
+
+            // Now whether or not we got a new number, reset our enabled
+            // summary text since it may have been replaced by an empty
+            // placeholder.
+            updateSummaryText();
+        }
+
+        private void handleSetCFResponse(Message msg) {
+            AsyncResult ar = (AsyncResult) msg.obj;
+
+            if (ar.exception != null) {
+                if (DBG) Log.d(LOG_TAG, "handleSetCFResponse: ar.exception=" + ar.exception);
+                // setEnabled(false);
+            }
+            if (DBG) Log.d(LOG_TAG, "handleSetCFResponse: re get");
+            phone.getCallForwardingOption(reason,
+                    obtainMessage(MESSAGE_GET_CF, msg.arg1, MESSAGE_SET_CF, ar.exception));
+        }
+    }
+}
diff --git a/src/com/android/phone/CallLogger.java b/src/com/android/phone/CallLogger.java
new file mode 100644
index 0000000..644812f
--- /dev/null
+++ b/src/com/android/phone/CallLogger.java
@@ -0,0 +1,237 @@
+/*
+ * Copyright (C) 2013 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.internal.telephony.CallerInfo;
+import com.android.internal.telephony.Connection;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.TelephonyCapabilities;
+import com.android.phone.common.CallLogAsync;
+
+import android.net.Uri;
+import android.os.SystemProperties;
+import android.provider.CallLog.Calls;
+import android.telephony.PhoneNumberUtils;
+import android.text.TextUtils;
+import android.util.Log;
+
+/**
+ * Helper class for interacting with the call log.
+ */
+class CallLogger {
+    private static final String LOG_TAG = CallLogger.class.getSimpleName();
+    private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 1) &&
+        (SystemProperties.getInt("ro.debuggable", 0) == 1);
+    private static final boolean VDBG = (PhoneGlobals.DBG_LEVEL >= 2);
+
+    private PhoneGlobals mApplication;
+    private CallLogAsync mCallLog;
+
+    public CallLogger(PhoneGlobals application, CallLogAsync callLogAsync) {
+        mApplication = application;
+        mCallLog = callLogAsync;
+    }
+
+    /**
+     * Logs a call to the call log based on the connection object passed in.
+     *
+     * @param c The connection object for the call being logged.
+     * @param callLogType The type of call log entry.
+     */
+    public void logCall(Connection c, int callLogType) {
+        final String number = c.getAddress();
+        final long date = c.getCreateTime();
+        final long duration = c.getDurationMillis();
+        final Phone phone = c.getCall().getPhone();
+
+        final CallerInfo ci = getCallerInfoFromConnection(c);  // May be null.
+        final String logNumber = getLogNumber(c, ci);
+
+        if (DBG) {
+            log("- onDisconnect(): logNumber set to:" + PhoneUtils.toLogSafePhoneNumber(logNumber) +
+                ", number set to: " + PhoneUtils.toLogSafePhoneNumber(number));
+        }
+
+        // TODO: In getLogNumber we use the presentation from
+        // the connection for the CNAP. Should we use the one
+        // below instead? (comes from caller info)
+
+        // For international calls, 011 needs to be logged as +
+        final int presentation = getPresentation(c, ci);
+
+        final boolean isOtaspNumber = TelephonyCapabilities.supportsOtasp(phone)
+                && phone.isOtaSpNumber(number);
+
+        // Don't log OTASP calls.
+        if (!isOtaspNumber) {
+            logCall(ci, logNumber, presentation, callLogType, date, duration);
+        }
+    }
+
+    /**
+     * Came as logCall(Connection,int) but calculates the call type from the connection object.
+     */
+    public void logCall(Connection c) {
+        final Connection.DisconnectCause cause = c.getDisconnectCause();
+
+        // Set the "type" to be displayed in the call log (see constants in CallLog.Calls)
+        final int callLogType;
+
+        if (c.isIncoming()) {
+            callLogType = (cause == Connection.DisconnectCause.INCOMING_MISSED ?
+                           Calls.MISSED_TYPE : Calls.INCOMING_TYPE);
+        } else {
+            callLogType = Calls.OUTGOING_TYPE;
+        }
+        if (VDBG) log("- callLogType: " + callLogType + ", UserData: " + c.getUserData());
+
+        logCall(c, callLogType);
+    }
+
+    /**
+     * Logs a call to the call from the parameters passed in.
+     */
+    public void logCall(CallerInfo ci, String number, int presentation, int callType, long start,
+                        long duration) {
+        final boolean isEmergencyNumber = PhoneNumberUtils.isLocalEmergencyNumber(number,
+                mApplication);
+
+        // On some devices, to avoid accidental redialing of
+        // emergency numbers, we *never* log emergency calls to
+        // the Call Log.  (This behavior is set on a per-product
+        // basis, based on carrier requirements.)
+        final boolean okToLogEmergencyNumber =
+            mApplication.getResources().getBoolean(
+                        R.bool.allow_emergency_numbers_in_call_log);
+
+        // Don't log emergency numbers if the device doesn't allow it,
+        boolean isOkToLogThisCall = !isEmergencyNumber || okToLogEmergencyNumber;
+
+        if (isOkToLogThisCall) {
+            if (DBG) {
+                log("sending Calllog entry: " + ci + ", " + PhoneUtils.toLogSafePhoneNumber(number)
+                    + "," + presentation + ", " + callType + ", " + start + ", " + duration);
+            }
+
+            CallLogAsync.AddCallArgs args = new CallLogAsync.AddCallArgs(mApplication, ci, number,
+                    presentation, callType, start, duration);
+            mCallLog.addCall(args);
+        }
+    }
+
+    /**
+     * Get the caller info.
+     *
+     * @param conn The phone connection.
+     * @return The CallerInfo associated with the connection. Maybe null.
+     */
+    private CallerInfo getCallerInfoFromConnection(Connection conn) {
+        CallerInfo ci = null;
+        Object o = conn.getUserData();
+
+        if ((o == null) || (o instanceof CallerInfo)) {
+            ci = (CallerInfo) o;
+        } else if (o instanceof Uri) {
+            ci = CallerInfo.getCallerInfo(mApplication.getApplicationContext(), (Uri) o);
+        } else {
+            ci = ((PhoneUtils.CallerInfoToken) o).currentInfo;
+        }
+        return ci;
+    }
+
+    /**
+     * Retrieve the phone number from the caller info or the connection.
+     *
+     * For incoming call the number is in the Connection object. For
+     * outgoing call we use the CallerInfo phoneNumber field if
+     * present. All the processing should have been done already (CDMA vs GSM numbers).
+     *
+     * If CallerInfo is missing the phone number, get it from the connection.
+     * Apply the Call Name Presentation (CNAP) transform in the connection on the number.
+     *
+     * @param conn The phone connection.
+     * @param callerInfo The CallerInfo. Maybe null.
+     * @return the phone number.
+     */
+    private String getLogNumber(Connection conn, CallerInfo callerInfo) {
+        String number = null;
+
+        if (conn.isIncoming()) {
+            number = conn.getAddress();
+        } else {
+            // For emergency and voicemail calls,
+            // CallerInfo.phoneNumber does *not* contain a valid phone
+            // number.  Instead it contains an I18N'd string such as
+            // "Emergency Number" or "Voice Mail" so we get the number
+            // from the connection.
+            if (null == callerInfo || TextUtils.isEmpty(callerInfo.phoneNumber) ||
+                callerInfo.isEmergencyNumber() || callerInfo.isVoiceMailNumber()) {
+                if (conn.getCall().getPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
+                    // In cdma getAddress() is not always equals to getOrigDialString().
+                    number = conn.getOrigDialString();
+                } else {
+                    number = conn.getAddress();
+                }
+            } else {
+                number = callerInfo.phoneNumber;
+            }
+        }
+
+        if (null == number) {
+            return null;
+        } else {
+            int presentation = conn.getNumberPresentation();
+
+            // Do final CNAP modifications.
+            String newNumber = PhoneUtils.modifyForSpecialCnapCases(mApplication, callerInfo,
+                                                          number, presentation);
+
+            if (!PhoneNumberUtils.isUriNumber(number)) {
+                number = PhoneNumberUtils.stripSeparators(number);
+            }
+            if (VDBG) log("getLogNumber: " + number);
+            return number;
+        }
+    }
+
+    /**
+     * Get the presentation from the callerinfo if not null otherwise,
+     * get it from the connection.
+     *
+     * @param conn The phone connection.
+     * @param callerInfo The CallerInfo. Maybe null.
+     * @return The presentation to use in the logs.
+     */
+    private int getPresentation(Connection conn, CallerInfo callerInfo) {
+        int presentation;
+
+        if (null == callerInfo) {
+            presentation = conn.getNumberPresentation();
+        } else {
+            presentation = callerInfo.numberPresentation;
+            if (DBG) log("- getPresentation(): ignoring connection's presentation: " +
+                         conn.getNumberPresentation());
+        }
+        if (DBG) log("- getPresentation: presentation: " + presentation);
+        return presentation;
+    }
+
+    private void log(String msg) {
+        Log.d(LOG_TAG, msg);
+    }
+}
diff --git a/src/com/android/phone/CallNotifier.java b/src/com/android/phone/CallNotifier.java
new file mode 100644
index 0000000..39feb25
--- /dev/null
+++ b/src/com/android/phone/CallNotifier.java
@@ -0,0 +1,1907 @@
+/*
+ * 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 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 com.android.internal.telephony.PhoneBase;
+import com.android.internal.telephony.TelephonyCapabilities;
+import com.android.internal.telephony.cdma.CdmaCallWaitingNotification;
+import com.android.internal.telephony.cdma.CdmaInformationRecords.CdmaDisplayInfoRec;
+import com.android.internal.telephony.cdma.CdmaInformationRecords.CdmaSignalInfoRec;
+import com.android.internal.telephony.cdma.SignalToneUtil;
+
+import android.app.ActivityManagerNative;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothHeadset;
+import android.bluetooth.BluetoothProfile;
+import android.content.Context;
+import android.media.AudioManager;
+import android.media.ToneGenerator;
+import android.net.Uri;
+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;
+import android.provider.CallLog.Calls;
+import android.provider.Settings;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.PhoneStateListener;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.util.EventLog;
+import android.util.Log;
+
+/**
+ * Phone app module that listens for phone state changes and various other
+ * events from the telephony layer, and triggers any resulting UI behavior
+ * (like starting the Ringer and Incoming Call UI, playing in-call tones,
+ * updating notifications, writing call log entries, etc.)
+ */
+public class CallNotifier extends Handler
+        implements CallerInfoAsyncQuery.OnQueryCompleteListener {
+    private static final String LOG_TAG = "CallNotifier";
+    private static final boolean DBG =
+            (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
+    private static final boolean VDBG = (PhoneGlobals.DBG_LEVEL >= 2);
+
+    // Maximum time we allow the CallerInfo query to run,
+    // before giving up and falling back to the default ringtone.
+    private static final int RINGTONE_QUERY_WAIT_TIME = 500;  // msec
+
+    // Timers related to CDMA Call Waiting
+    // 1) For displaying Caller Info
+    // 2) For disabling "Add Call" menu option once User selects Ignore or CW Timeout occures
+    private static final int CALLWAITING_CALLERINFO_DISPLAY_TIME = 20000; // msec
+    private static final int CALLWAITING_ADDCALL_DISABLE_TIME = 30000; // msec
+
+    // Time to display the  DisplayInfo Record sent by CDMA network
+    private static final int DISPLAYINFO_NOTIFICATION_TIME = 2000; // msec
+
+    /** The singleton instance. */
+    private static CallNotifier sInstance;
+
+    // Boolean to keep track of whether or not a CDMA Call Waiting call timed out.
+    //
+    // This is CDMA-specific, because with CDMA we *don't* get explicit
+    // notification from the telephony layer that a call-waiting call has
+    // stopped ringing.  Instead, when a call-waiting call first comes in we
+    // start a 20-second timer (see CALLWAITING_CALLERINFO_DISPLAY_DONE), and
+    // if the timer expires we clean up the call and treat it as a missed call.
+    //
+    // If this field is true, that means that the current Call Waiting call
+    // "timed out" and should be logged in Call Log as a missed call.  If it's
+    // false when we reach onCdmaCallWaitingReject(), we can assume the user
+    // explicitly rejected this call-waiting call.
+    //
+    // This field is reset to false any time a call-waiting call first comes
+    // in, and after cleaning up a missed call-waiting call.  It's only ever
+    // set to true when the CALLWAITING_CALLERINFO_DISPLAY_DONE timer fires.
+    //
+    // TODO: do we really need a member variable for this?  Don't we always
+    // know at the moment we call onCdmaCallWaitingReject() whether this is an
+    // explicit rejection or not?
+    // (Specifically: when we call onCdmaCallWaitingReject() from
+    // PhoneUtils.hangupRingingCall() that means the user deliberately rejected
+    // the call, and if we call onCdmaCallWaitingReject() because of a
+    // CALLWAITING_CALLERINFO_DISPLAY_DONE event that means that it timed
+    // out...)
+    private boolean mCallWaitingTimeOut = false;
+
+    // values used to track the query state
+    private static final int CALLERINFO_QUERY_READY = 0;
+    private static final int CALLERINFO_QUERYING = -1;
+
+    // the state of the CallerInfo Query.
+    private int mCallerInfoQueryState;
+
+    // object used to synchronize access to mCallerInfoQueryState
+    private Object mCallerInfoQueryStateGuard = new Object();
+
+    // Event used to indicate a query timeout.
+    private static final int RINGER_CUSTOM_RINGTONE_QUERY_TIMEOUT = 100;
+
+    // Events generated internally:
+    private static final int PHONE_MWI_CHANGED = 21;
+    private static final int CALLWAITING_CALLERINFO_DISPLAY_DONE = 22;
+    private static final int CALLWAITING_ADDCALL_DISABLE_TIMEOUT = 23;
+    private static final int DISPLAYINFO_NOTIFICATION_DONE = 24;
+    private static final int CDMA_CALL_WAITING_REJECT = 26;
+    private static final int UPDATE_IN_CALL_NOTIFICATION = 27;
+
+    // Emergency call related defines:
+    private static final int EMERGENCY_TONE_OFF = 0;
+    private static final int EMERGENCY_TONE_ALERT = 1;
+    private static final int EMERGENCY_TONE_VIBRATE = 2;
+
+    private PhoneGlobals mApplication;
+    private CallManager mCM;
+    private CallStateMonitor mCallStateMonitor;
+    private Ringer mRinger;
+    private BluetoothHeadset mBluetoothHeadset;
+    private CallLogger mCallLogger;
+    private boolean mSilentRingerRequested;
+
+    // ToneGenerator instance for playing SignalInfo tones
+    private ToneGenerator mSignalInfoToneGenerator;
+
+    // The tone volume relative to other sounds in the stream SignalInfo
+    private static final int TONE_RELATIVE_VOLUME_SIGNALINFO = 80;
+
+    private Call.State mPreviousCdmaCallState;
+    private boolean mVoicePrivacyState = false;
+    private boolean mIsCdmaRedialCall = false;
+
+    // Emergency call tone and vibrate:
+    private int mIsEmergencyToneOn;
+    private int mCurrentEmergencyToneState = EMERGENCY_TONE_OFF;
+    private EmergencyTonePlayerVibrator mEmergencyTonePlayerVibrator;
+
+    // Ringback tone player
+    private InCallTonePlayer mInCallRingbackTonePlayer;
+
+    // Call waiting tone player
+    private InCallTonePlayer mCallWaitingTonePlayer;
+
+    // Cached AudioManager
+    private AudioManager mAudioManager;
+
+    /**
+     * Initialize the singleton CallNotifier instance.
+     * This is only done once, at startup, from PhoneApp.onCreate().
+     */
+    /* package */ static CallNotifier init(PhoneGlobals app, Phone phone, Ringer ringer,
+            CallLogger callLogger, CallStateMonitor callStateMonitor) {
+        synchronized (CallNotifier.class) {
+            if (sInstance == null) {
+                sInstance = new CallNotifier(app, phone, ringer, callLogger, callStateMonitor);
+            } else {
+                Log.wtf(LOG_TAG, "init() called multiple times!  sInstance = " + sInstance);
+            }
+            return sInstance;
+        }
+    }
+
+    /** Private constructor; @see init() */
+    private CallNotifier(PhoneGlobals app, Phone phone, Ringer ringer, CallLogger callLogger,
+            CallStateMonitor callStateMonitor) {
+        mApplication = app;
+        mCM = app.mCM;
+        mCallLogger = callLogger;
+        mCallStateMonitor = callStateMonitor;
+
+        mAudioManager = (AudioManager) mApplication.getSystemService(Context.AUDIO_SERVICE);
+
+        callStateMonitor.addListener(this);
+
+        createSignalInfoToneGenerator();
+
+        mRinger = ringer;
+        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+        if (adapter != null) {
+            adapter.getProfileProxy(mApplication.getApplicationContext(),
+                                    mBluetoothProfileServiceListener,
+                                    BluetoothProfile.HEADSET);
+        }
+
+        TelephonyManager telephonyManager = (TelephonyManager)app.getSystemService(
+                Context.TELEPHONY_SERVICE);
+        telephonyManager.listen(mPhoneStateListener,
+                PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR
+                | PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR);
+    }
+
+    private void createSignalInfoToneGenerator() {
+        // Instantiate the ToneGenerator for SignalInfo and CallWaiting
+        // TODO: We probably don't need the mSignalInfoToneGenerator instance
+        // around forever. Need to change it so as to create a ToneGenerator instance only
+        // when a tone is being played and releases it after its done playing.
+        if (mSignalInfoToneGenerator == null) {
+            try {
+                mSignalInfoToneGenerator = new ToneGenerator(AudioManager.STREAM_VOICE_CALL,
+                        TONE_RELATIVE_VOLUME_SIGNALINFO);
+                Log.d(LOG_TAG, "CallNotifier: mSignalInfoToneGenerator created when toneplay");
+            } catch (RuntimeException e) {
+                Log.w(LOG_TAG, "CallNotifier: Exception caught while creating " +
+                        "mSignalInfoToneGenerator: " + e);
+                mSignalInfoToneGenerator = null;
+            }
+        } else {
+            Log.d(LOG_TAG, "mSignalInfoToneGenerator created already, hence skipping");
+        }
+    }
+
+    @Override
+    public void handleMessage(Message msg) {
+        switch (msg.what) {
+            case CallStateMonitor.PHONE_NEW_RINGING_CONNECTION:
+                log("RINGING... (new)");
+                onNewRingingConnection((AsyncResult) msg.obj);
+                mSilentRingerRequested = false;
+                break;
+
+            case CallStateMonitor.PHONE_INCOMING_RING:
+                // repeat the ring when requested by the RIL, and when the user has NOT
+                // specifically requested silence.
+                if (msg.obj != null && ((AsyncResult) msg.obj).result != null) {
+                    PhoneBase pb =  (PhoneBase)((AsyncResult)msg.obj).result;
+
+                    if ((pb.getState() == PhoneConstants.State.RINGING)
+                            && (mSilentRingerRequested == false)) {
+                        if (DBG) log("RINGING... (PHONE_INCOMING_RING event)");
+                        mRinger.ring();
+                    } else {
+                        if (DBG) log("RING before NEW_RING, skipping");
+                    }
+                }
+                break;
+
+            case CallStateMonitor.PHONE_STATE_CHANGED:
+                onPhoneStateChanged((AsyncResult) msg.obj);
+                break;
+
+            case CallStateMonitor.PHONE_DISCONNECT:
+                if (DBG) log("DISCONNECT");
+                onDisconnect((AsyncResult) msg.obj);
+                break;
+
+            case CallStateMonitor.PHONE_UNKNOWN_CONNECTION_APPEARED:
+                onUnknownConnectionAppeared((AsyncResult) msg.obj);
+                break;
+
+            case RINGER_CUSTOM_RINGTONE_QUERY_TIMEOUT:
+                onCustomRingtoneQueryTimeout((String) msg.obj);
+                break;
+
+            case PHONE_MWI_CHANGED:
+                onMwiChanged(mApplication.phone.getMessageWaitingIndicator());
+                break;
+
+            case CallStateMonitor.PHONE_CDMA_CALL_WAITING:
+                if (DBG) log("Received PHONE_CDMA_CALL_WAITING event");
+                onCdmaCallWaiting((AsyncResult) msg.obj);
+                break;
+
+            case CDMA_CALL_WAITING_REJECT:
+                Log.i(LOG_TAG, "Received CDMA_CALL_WAITING_REJECT event");
+                onCdmaCallWaitingReject();
+                break;
+
+            case CALLWAITING_CALLERINFO_DISPLAY_DONE:
+                Log.i(LOG_TAG, "Received CALLWAITING_CALLERINFO_DISPLAY_DONE event");
+                mCallWaitingTimeOut = true;
+                onCdmaCallWaitingReject();
+                break;
+
+            case CALLWAITING_ADDCALL_DISABLE_TIMEOUT:
+                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:
+                if (DBG) log("Received PHONE_STATE_DISPLAYINFO event");
+                onDisplayInfo((AsyncResult) msg.obj);
+                break;
+
+            case CallStateMonitor.PHONE_STATE_SIGNALINFO:
+                if (DBG) log("Received PHONE_STATE_SIGNALINFO event");
+                onSignalInfo((AsyncResult) msg.obj);
+                break;
+
+            case DISPLAYINFO_NOTIFICATION_DONE:
+                if (DBG) log("Received Display Info notification done event ...");
+                CdmaDisplayInfo.dismissDisplayInfoRecord();
+                break;
+
+            case CallStateMonitor.EVENT_OTA_PROVISION_CHANGE:
+                if (DBG) log("EVENT_OTA_PROVISION_CHANGE...");
+                mApplication.handleOtaspEvent(msg);
+                break;
+
+            case CallStateMonitor.PHONE_ENHANCED_VP_ON:
+                if (DBG) log("PHONE_ENHANCED_VP_ON...");
+                if (!mVoicePrivacyState) {
+                    int toneToPlay = InCallTonePlayer.TONE_VOICE_PRIVACY;
+                    new InCallTonePlayer(toneToPlay).start();
+                    mVoicePrivacyState = true;
+                    // Update the VP icon:
+                    if (DBG) log("- updating notification for VP state...");
+                    mApplication.notificationMgr.updateInCallNotification();
+                }
+                break;
+
+            case CallStateMonitor.PHONE_ENHANCED_VP_OFF:
+                if (DBG) log("PHONE_ENHANCED_VP_OFF...");
+                if (mVoicePrivacyState) {
+                    int toneToPlay = InCallTonePlayer.TONE_VOICE_PRIVACY;
+                    new InCallTonePlayer(toneToPlay).start();
+                    mVoicePrivacyState = false;
+                    // Update the VP icon:
+                    if (DBG) log("- updating notification for VP state...");
+                    mApplication.notificationMgr.updateInCallNotification();
+                }
+                break;
+
+            case CallStateMonitor.PHONE_RINGBACK_TONE:
+                onRingbackTone((AsyncResult) msg.obj);
+                break;
+
+            case CallStateMonitor.PHONE_RESEND_MUTE:
+                onResendMute();
+                break;
+
+            case UPDATE_IN_CALL_NOTIFICATION:
+                mApplication.notificationMgr.updateInCallNotification();
+                break;
+
+            default:
+                // super.handleMessage(msg);
+        }
+    }
+
+    PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
+        @Override
+        public void onMessageWaitingIndicatorChanged(boolean mwi) {
+            onMwiChanged(mwi);
+        }
+
+        @Override
+        public void onCallForwardingIndicatorChanged(boolean cfi) {
+            onCfiChanged(cfi);
+        }
+    };
+
+    /**
+     * Handles a "new ringing connection" event from the telephony layer.
+     */
+    private void onNewRingingConnection(AsyncResult r) {
+        Connection c = (Connection) r.result;
+        log("onNewRingingConnection(): state = " + mCM.getState() + ", conn = { " + c + " }");
+        Call ringing = c.getCall();
+        Phone phone = ringing.getPhone();
+
+        // Check for a few cases where we totally ignore incoming calls.
+        if (ignoreAllIncomingCalls(phone)) {
+            // Immediately reject the call, without even indicating to the user
+            // that an incoming call occurred.  (This will generally send the
+            // caller straight to voicemail, just as if we *had* shown the
+            // incoming-call UI and the user had declined the call.)
+            PhoneUtils.hangupRingingCall(ringing);
+            return;
+        }
+
+        if (!c.isRinging()) {
+            Log.i(LOG_TAG, "CallNotifier.onNewRingingConnection(): connection not ringing!");
+            // This is a very strange case: an incoming call that stopped
+            // ringing almost instantly after the onNewRingingConnection()
+            // event.  There's nothing we can do here, so just bail out
+            // without doing anything.  (But presumably we'll log it in
+            // the call log when the disconnect event comes in...)
+            return;
+        }
+
+        // Stop any signalInfo tone being played on receiving a Call
+        stopSignalInfoTone();
+
+        Call.State state = c.getState();
+        // State will be either INCOMING or WAITING.
+        if (VDBG) log("- connection is ringing!  state = " + state);
+        // if (DBG) PhoneUtils.dumpCallState(mPhone);
+
+        // No need to do any service state checks here (like for
+        // "emergency mode"), since in those states the SIM won't let
+        // us get incoming connections in the first place.
+
+        // TODO: Consider sending out a serialized broadcast Intent here
+        // (maybe "ACTION_NEW_INCOMING_CALL"), *before* starting the
+        // ringer and going to the in-call UI.  The intent should contain
+        // the caller-id info for the current connection, and say whether
+        // it would be a "call waiting" call or a regular ringing call.
+        // If anybody consumed the broadcast, we'd bail out without
+        // ringing or bringing up the in-call UI.
+        //
+        // This would give 3rd party apps a chance to listen for (and
+        // intercept) new ringing connections.  An app could reject the
+        // incoming call by consuming the broadcast and doing nothing, or
+        // it could "pick up" the call (without any action by the user!)
+        // via some future TelephonyManager API.
+        //
+        // See bug 1312336 for more details.
+        // We'd need to protect this with a new "intercept incoming calls"
+        // system permission.
+
+        // Obtain a partial wake lock to make sure the CPU doesn't go to
+        // sleep before we finish bringing up the InCallScreen.
+        // (This will be upgraded soon to a full wake lock; see
+        // showIncomingCall().)
+        if (VDBG) log("Holding wake lock on new incoming connection.");
+        mApplication.requestWakeState(PhoneGlobals.WakeState.PARTIAL);
+
+        // - 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();
+            }
+            // in this case, just fall through like before, and call
+            // showIncomingCall().
+            if (DBG) log("- showing incoming call (this is a WAITING call)...");
+            showIncomingCall();
+        }
+
+        // Note we *don't* post a status bar notification here, since
+        // we're not necessarily ready to actually show the incoming call
+        // to the user.  (For calls in the INCOMING state, at least, we
+        // still need to run a caller-id query, and we may not even ring
+        // at all if the "send directly to voicemail" flag is set.)
+        //
+        // Instead, we update the notification (and potentially launch the
+        // InCallScreen) from the showIncomingCall() method, which runs
+        // when the caller-id query completes or times out.
+
+        if (VDBG) log("- onNewRingingConnection() done.");
+    }
+
+    /**
+     * Determines whether or not we're allowed to present incoming calls to the
+     * user, based on the capabilities and/or current state of the device.
+     *
+     * If this method returns true, that means we should immediately reject the
+     * current incoming call, without even indicating to the user that an
+     * incoming call occurred.
+     *
+     * (We only reject incoming calls in a few cases, like during an OTASP call
+     * when we can't interrupt the user, or if the device hasn't completed the
+     * SetupWizard yet.  We also don't allow incoming calls on non-voice-capable
+     * devices.  But note that we *always* allow incoming calls while in ECM.)
+     *
+     * @return true if we're *not* allowed to present an incoming call to
+     * the user.
+     */
+    private boolean ignoreAllIncomingCalls(Phone phone) {
+        // Incoming calls are totally ignored on non-voice-capable devices.
+        if (!PhoneGlobals.sVoiceCapable) {
+            // ...but still log a warning, since we shouldn't have gotten this
+            // event in the first place!  (Incoming calls *should* be blocked at
+            // the telephony layer on non-voice-capable capable devices.)
+            Log.w(LOG_TAG, "Got onNewRingingConnection() on non-voice-capable device! Ignoring...");
+            return true;
+        }
+
+        // In ECM (emergency callback mode), we ALWAYS allow incoming calls
+        // to get through to the user.  (Note that ECM is applicable only to
+        // voice-capable CDMA devices).
+        if (PhoneUtils.isPhoneInEcm(phone)) {
+            if (DBG) log("Incoming call while in ECM: always allow...");
+            return false;
+        }
+
+        // Incoming calls are totally ignored if the device isn't provisioned yet.
+        boolean provisioned = Settings.Global.getInt(mApplication.getContentResolver(),
+            Settings.Global.DEVICE_PROVISIONED, 0) != 0;
+        if (!provisioned) {
+            Log.i(LOG_TAG, "Ignoring incoming call: not provisioned");
+            return true;
+        }
+
+        // Incoming calls are totally ignored if an OTASP call is active.
+        if (TelephonyCapabilities.supportsOtasp(phone)) {
+            boolean activateState = (mApplication.cdmaOtaScreenState.otaScreenState
+                    == OtaUtils.CdmaOtaScreenState.OtaScreenState.OTA_STATUS_ACTIVATION);
+            boolean dialogState = (mApplication.cdmaOtaScreenState.otaScreenState
+                    == OtaUtils.CdmaOtaScreenState.OtaScreenState.OTA_STATUS_SUCCESS_FAILURE_DLG);
+            boolean spcState = mApplication.cdmaOtaProvisionData.inOtaSpcState;
+
+            if (spcState) {
+                Log.i(LOG_TAG, "Ignoring incoming call: OTA call is active");
+                return true;
+            } else if (activateState || dialogState) {
+                // We *are* allowed to receive incoming calls at this point.
+                // But clear out any residual OTASP UI first.
+                // TODO: It's an MVC violation to twiddle the OTA UI state here;
+                // we should instead provide a higher-level API via OtaUtils.
+                if (dialogState) mApplication.dismissOtaDialogs();
+                mApplication.clearOtaState();
+                mApplication.clearInCallScreenMode();
+                return false;
+            }
+        }
+
+        // Normal case: allow this call to be presented to the user.
+        return false;
+    }
+
+    /**
+     * Helper method to manage the start of incoming call queries
+     */
+    private void startIncomingCallQuery(Connection c) {
+        // TODO: cache the custom ringer object so that subsequent
+        // calls will not need to do this query work.  We can keep
+        // the MRU ringtones in memory.  We'll still need to hit
+        // the database to get the callerinfo to act as a key,
+        // but at least we can save the time required for the
+        // Media player setup.  The only issue with this is that
+        // we may need to keep an eye on the resources the Media
+        // player uses to keep these ringtones around.
+
+        // make sure we're in a state where we can be ready to
+        // query a ringtone uri.
+        boolean shouldStartQuery = false;
+        synchronized (mCallerInfoQueryStateGuard) {
+            if (mCallerInfoQueryState == CALLERINFO_QUERY_READY) {
+                mCallerInfoQueryState = CALLERINFO_QUERYING;
+                shouldStartQuery = true;
+            }
+        }
+        if (shouldStartQuery) {
+            // Reset the ringtone to the default first.
+            mRinger.setCustomRingtoneUri(Settings.System.DEFAULT_RINGTONE_URI);
+
+            // query the callerinfo to try to get the ringer.
+            PhoneUtils.CallerInfoToken cit = PhoneUtils.startGetCallerInfo(
+                    mApplication, c, this, this);
+
+            // if this has already been queried then just ring, otherwise
+            // we wait for the alloted time before ringing.
+            if (cit.isFinal) {
+                if (VDBG) log("- CallerInfo already up to date, using available data");
+                onQueryComplete(0, this, cit.currentInfo);
+            } else {
+                if (VDBG) log("- Starting query, posting timeout message.");
+
+                // Phone number (via getAddress()) is stored in the message to remember which
+                // number is actually used for the look up.
+                sendMessageDelayed(
+                        Message.obtain(this, RINGER_CUSTOM_RINGTONE_QUERY_TIMEOUT, c.getAddress()),
+                        RINGTONE_QUERY_WAIT_TIME);
+            }
+            // The call to showIncomingCall() will happen after the
+            // queries are complete (or time out).
+        } else {
+            // This should never happen; its the case where an incoming call
+            // arrives at the same time that the query is still being run,
+            // 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)...");
+            showIncomingCall();
+        }
+    }
+
+    /**
+     * Performs the final steps of the onNewRingingConnection sequence:
+     * starts the ringer, and brings up the "incoming call" UI.
+     *
+     * Normally, this is called when the CallerInfo query completes (see
+     * onQueryComplete()).  In this case, onQueryComplete() has already
+     * configured the Ringer object to use the custom ringtone (if there
+     * is one) for this caller.  So we just tell the Ringer to start, and
+     * proceed to the InCallScreen.
+     *
+     * But this method can *also* be called if the
+     * RINGTONE_QUERY_WAIT_TIME timeout expires, which means that the
+     * CallerInfo query is taking too long.  In that case, we log a
+     * warning but otherwise we behave the same as in the normal case.
+     * (We still tell the Ringer to start, but it's going to use the
+     * default ringtone.)
+     */
+    private void onCustomRingQueryComplete() {
+        boolean isQueryExecutionTimeExpired = false;
+        synchronized (mCallerInfoQueryStateGuard) {
+            if (mCallerInfoQueryState == CALLERINFO_QUERYING) {
+                mCallerInfoQueryState = CALLERINFO_QUERY_READY;
+                isQueryExecutionTimeExpired = true;
+            }
+        }
+        if (isQueryExecutionTimeExpired) {
+            // There may be a problem with the query here, since the
+            // default ringtone is playing instead of the custom one.
+            Log.w(LOG_TAG, "CallerInfo query took too long; falling back to default ringtone");
+            EventLog.writeEvent(EventLogTags.PHONE_UI_RINGER_QUERY_ELAPSED);
+        }
+
+        // Make sure we still have an incoming call!
+        //
+        // (It's possible for the incoming call to have been disconnected
+        // while we were running the query.  In that case we better not
+        // start the ringer here, since there won't be any future
+        // DISCONNECT event to stop it!)
+        //
+        // Note we don't have to worry about the incoming call going away
+        // *after* this check but before we call mRinger.ring() below,
+        // since in that case we *will* still get a DISCONNECT message sent
+        // to our handler.  (And we will correctly stop the ringer when we
+        // process that event.)
+        if (mCM.getState() != PhoneConstants.State.RINGING) {
+            Log.i(LOG_TAG, "onCustomRingQueryComplete: No incoming call! Bailing out...");
+            // Don't start the ringer *or* bring up the "incoming call" UI.
+            // Just bail out.
+            return;
+        }
+
+        // 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)...");
+        showIncomingCall();
+    }
+
+    private void onUnknownConnectionAppeared(AsyncResult r) {
+        PhoneConstants.State state = mCM.getState();
+
+        if (state == PhoneConstants.State.OFFHOOK) {
+            // basically do onPhoneStateChanged + display the incoming call UI
+            onPhoneStateChanged(r);
+            if (DBG) log("- showing incoming call (unknown connection appeared)...");
+            showIncomingCall();
+        }
+    }
+
+    /**
+     * Informs the user about a new incoming call.
+     *
+     * In most cases this means "bring up the full-screen incoming call
+     * UI".  However, if an immersive activity is running, the system
+     * NotificationManager will instead pop up a small notification window
+     * on top of the activity.
+     *
+     * Watch out: be sure to call this method only once per incoming call,
+     * or otherwise we may end up launching the InCallScreen multiple
+     * times (which can lead to slow responsiveness and/or visible
+     * glitches.)
+     *
+     * Note this method handles only the onscreen UI for incoming calls;
+     * the ringer and/or vibrator are started separately (see the various
+     * calls to Ringer.ring() in this class.)
+     *
+     * @see NotificationMgr#updateNotificationAndLaunchIncomingCallUi()
+     */
+    private void showIncomingCall() {
+        log("showIncomingCall()...  phone state = " + mCM.getState());
+
+        // Before bringing up the "incoming call" UI, force any system
+        // dialogs (like "recent tasks" or the power dialog) to close first.
+        try {
+            ActivityManagerNative.getDefault().closeSystemDialogs("call");
+        } catch (RemoteException e) {
+        }
+
+        // Go directly to the in-call screen.
+        // (No need to do anything special if we're already on the in-call
+        // screen; it'll notice the phone state change and update itself.)
+        mApplication.requestWakeState(PhoneGlobals.WakeState.FULL);
+
+        // Post the "incoming call" notification *and* include the
+        // fullScreenIntent that'll launch the incoming-call UI.
+        // (This will usually take us straight to the incoming call
+        // screen, but if an immersive activity is running it'll just
+        // appear as a notification.)
+        if (DBG) log("- updating notification from showIncomingCall()...");
+        mApplication.notificationMgr.updateNotificationAndLaunchIncomingCallUi();
+    }
+
+    /**
+     * Updates the phone UI in response to phone state changes.
+     *
+     * Watch out: certain state changes are actually handled by their own
+     * specific methods:
+     *   - see onNewRingingConnection() for new incoming calls
+     *   - see onDisconnect() for calls being hung up or disconnected
+     */
+    private void onPhoneStateChanged(AsyncResult r) {
+        PhoneConstants.State state = mCM.getState();
+        if (VDBG) log("onPhoneStateChanged: state = " + state);
+
+        // Turn status bar notifications on or off depending upon the state
+        // of the phone.  Notification Alerts (audible or vibrating) should
+        // be on if and only if the phone is IDLE.
+        mApplication.notificationMgr.statusBarHelper
+                .enableNotificationAlerts(state == PhoneConstants.State.IDLE);
+
+        Phone fgPhone = mCM.getFgPhone();
+        if (fgPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
+            if ((fgPhone.getForegroundCall().getState() == Call.State.ACTIVE)
+                    && ((mPreviousCdmaCallState == Call.State.DIALING)
+                    ||  (mPreviousCdmaCallState == Call.State.ALERTING))) {
+                if (mIsCdmaRedialCall) {
+                    int toneToPlay = InCallTonePlayer.TONE_REDIAL;
+                    new InCallTonePlayer(toneToPlay).start();
+                }
+                // Stop any signal info tone when call moves to ACTIVE state
+                stopSignalInfoTone();
+            }
+            mPreviousCdmaCallState = fgPhone.getForegroundCall().getState();
+        }
+
+        // Have the PhoneApp recompute its mShowBluetoothIndication
+        // flag based on the (new) telephony state.
+        // There's no need to force a UI update since we update the
+        // in-call notification ourselves (below), and the InCallScreen
+        // listens for phone state changes itself.
+        mApplication.updateBluetoothIndication(false);
+
+
+        // Update the phone state and other sensor/lock.
+        mApplication.updatePhoneState(state);
+
+        if (state == PhoneConstants.State.OFFHOOK) {
+            // stop call waiting tone if needed when answering
+            if (mCallWaitingTonePlayer != null) {
+                mCallWaitingTonePlayer.stopTone();
+                mCallWaitingTonePlayer = null;
+            }
+
+            if (VDBG) log("onPhoneStateChanged: OFF HOOK");
+            // 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
+            // PhoneUtils.answerCall(), before the call to phone.acceptCall().)
+            // TODO: Confirm that this call really *is* unnecessary, and if so,
+            // remove it!
+            if (DBG) log("stopRing()... (OFFHOOK state)");
+            mRinger.stopRing();
+
+            // Post a request to update the "in-call" status bar icon.
+            //
+            // We don't call NotificationMgr.updateInCallNotification()
+            // directly here, for two reasons:
+            // (1) a single phone state change might actually trigger multiple
+            //   onPhoneStateChanged() callbacks, so this prevents redundant
+            //   updates of the notification.
+            // (2) we suppress the status bar icon while the in-call UI is
+            //   visible (see updateInCallNotification()).  But when launching
+            //   an outgoing call the phone actually goes OFFHOOK slightly
+            //   *before* the InCallScreen comes up, so the delay here avoids a
+            //   brief flicker of the icon at that point.
+
+            if (DBG) log("- posting UPDATE_IN_CALL_NOTIFICATION request...");
+            // Remove any previous requests in the queue
+            removeMessages(UPDATE_IN_CALL_NOTIFICATION);
+            final int IN_CALL_NOTIFICATION_UPDATE_DELAY = 1000;  // msec
+            sendEmptyMessageDelayed(UPDATE_IN_CALL_NOTIFICATION,
+                                    IN_CALL_NOTIFICATION_UPDATE_DELAY);
+        }
+
+        if (fgPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
+            Connection c = fgPhone.getForegroundCall().getLatestConnection();
+            if ((c != null) && (PhoneNumberUtils.isLocalEmergencyNumber(c.getAddress(),
+                                                                        mApplication))) {
+                if (VDBG) log("onPhoneStateChanged: it is an emergency call.");
+                Call.State callState = fgPhone.getForegroundCall().getState();
+                if (mEmergencyTonePlayerVibrator == null) {
+                    mEmergencyTonePlayerVibrator = new EmergencyTonePlayerVibrator();
+                }
+
+                if (callState == Call.State.DIALING || callState == Call.State.ALERTING) {
+                    mIsEmergencyToneOn = Settings.Global.getInt(
+                            mApplication.getContentResolver(),
+                            Settings.Global.EMERGENCY_TONE, EMERGENCY_TONE_OFF);
+                    if (mIsEmergencyToneOn != EMERGENCY_TONE_OFF &&
+                        mCurrentEmergencyToneState == EMERGENCY_TONE_OFF) {
+                        if (mEmergencyTonePlayerVibrator != null) {
+                            mEmergencyTonePlayerVibrator.start();
+                        }
+                    }
+                } else if (callState == Call.State.ACTIVE) {
+                    if (mCurrentEmergencyToneState != EMERGENCY_TONE_OFF) {
+                        if (mEmergencyTonePlayerVibrator != null) {
+                            mEmergencyTonePlayerVibrator.stop();
+                        }
+                    }
+                }
+            }
+        }
+
+        if ((fgPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_GSM)
+                || (fgPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_SIP)) {
+            Call.State callState = mCM.getActiveFgCallState();
+            if (!callState.isDialing()) {
+                // If call get activated or disconnected before the ringback
+                // tone stops, we have to stop it to prevent disturbing.
+                if (mInCallRingbackTonePlayer != null) {
+                    mInCallRingbackTonePlayer.stopTone();
+                    mInCallRingbackTonePlayer = null;
+                }
+            }
+        }
+    }
+
+    void updateCallNotifierRegistrationsAfterRadioTechnologyChange() {
+        if (DBG) Log.d(LOG_TAG, "updateCallNotifierRegistrationsAfterRadioTechnologyChange...");
+
+        // Clear ringback tone player
+        mInCallRingbackTonePlayer = null;
+
+        // Clear call waiting tone player
+        mCallWaitingTonePlayer = null;
+
+        // Instantiate mSignalInfoToneGenerator
+        createSignalInfoToneGenerator();
+    }
+
+    /**
+     * Implemented for CallerInfoAsyncQuery.OnQueryCompleteListener interface.
+     * refreshes the CallCard data when it called.  If called with this
+     * class itself, it is assumed that we have been waiting for the ringtone
+     * and direct to voicemail settings to update.
+     */
+    @Override
+    public void onQueryComplete(int token, Object cookie, CallerInfo ci) {
+        if (cookie instanceof Long) {
+            if (VDBG) log("CallerInfo query complete, posting missed call notification");
+
+            mApplication.notificationMgr.notifyMissedCall(ci.name, ci.phoneNumber,
+                    ci.phoneLabel, ci.cachedPhoto, ci.cachedPhotoIcon,
+                    ((Long) cookie).longValue());
+        } else if (cookie instanceof CallNotifier) {
+            if (VDBG) log("CallerInfo query complete (for CallNotifier), "
+                    + "updating state for incoming call..");
+
+            // get rid of the timeout messages
+            removeMessages(RINGER_CUSTOM_RINGTONE_QUERY_TIMEOUT);
+
+            boolean isQueryExecutionTimeOK = false;
+            synchronized (mCallerInfoQueryStateGuard) {
+                if (mCallerInfoQueryState == CALLERINFO_QUERYING) {
+                    mCallerInfoQueryState = CALLERINFO_QUERY_READY;
+                    isQueryExecutionTimeOK = true;
+                }
+            }
+            //if we're in the right state
+            if (isQueryExecutionTimeOK) {
+
+                // send directly to voicemail.
+                if (ci.shouldSendToVoicemail) {
+                    if (DBG) log("send to voicemail flag detected. hanging up.");
+                    PhoneUtils.hangupRingingCall(mCM.getFirstActiveRingingCall());
+                    return;
+                }
+
+                // set the ringtone uri to prepare for the ring.
+                if (ci.contactRingtoneUri != null) {
+                    if (DBG) log("custom ringtone found, setting up ringer.");
+                    Ringer r = ((CallNotifier) cookie).mRinger;
+                    r.setCustomRingtoneUri(ci.contactRingtoneUri);
+                }
+                // ring, and other post-ring actions.
+                onCustomRingQueryComplete();
+            }
+        }
+    }
+
+    /**
+     * Called when asynchronous CallerInfo query is taking too long (more than
+     * {@link #RINGTONE_QUERY_WAIT_TIME} msec), but we cannot wait any more.
+     *
+     * This looks up in-memory fallback cache and use it when available. If not, it just calls
+     * {@link #onCustomRingQueryComplete()} with default ringtone ("Send to voicemail" flag will
+     * be just ignored).
+     *
+     * @param number The phone number used for the async query. This method will take care of
+     * formatting or normalization of the number.
+     */
+    private void onCustomRingtoneQueryTimeout(String number) {
+        // First of all, this case itself should be rare enough, though we cannot avoid it in
+        // some situations (e.g. IPC is slow due to system overload, database is in sync, etc.)
+        Log.w(LOG_TAG, "CallerInfo query took too long; look up local fallback cache.");
+
+        // This method is intentionally verbose for now to detect possible bad side-effect for it.
+        // TODO: Remove the verbose log when it looks stable and reliable enough.
+
+        final CallerInfoCache.CacheEntry entry =
+                mApplication.callerInfoCache.getCacheEntry(number);
+        if (entry != null) {
+            if (entry.sendToVoicemail) {
+                log("send to voicemail flag detected (in fallback cache). hanging up.");
+                PhoneUtils.hangupRingingCall(mCM.getFirstActiveRingingCall());
+                return;
+            }
+
+            if (entry.customRingtone != null) {
+                log("custom ringtone found (in fallback cache), setting up ringer: "
+                        + entry.customRingtone);
+                this.mRinger.setCustomRingtoneUri(Uri.parse(entry.customRingtone));
+            }
+        } else {
+            // In this case we call onCustomRingQueryComplete(), just
+            // like if the query had completed normally.  (But we're
+            // going to get the default ringtone, since we never got
+            // the chance to call Ringer.setCustomRingtoneUri()).
+            log("Failed to find fallback cache. Use default ringer tone.");
+        }
+
+        onCustomRingQueryComplete();
+    }
+
+    private void onDisconnect(AsyncResult r) {
+        if (VDBG) log("onDisconnect()...  CallManager state: " + mCM.getState());
+
+        mVoicePrivacyState = false;
+        Connection c = (Connection) r.result;
+        if (c != null) {
+            log("onDisconnect: cause = " + c.getDisconnectCause()
+                  + ", incoming = " + c.isIncoming()
+                  + ", date = " + c.getCreateTime());
+        } else {
+            Log.w(LOG_TAG, "onDisconnect: null connection");
+        }
+
+        int autoretrySetting = 0;
+        if ((c != null) && (c.getCall().getPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)) {
+            autoretrySetting = android.provider.Settings.Global.getInt(mApplication.
+                    getContentResolver(),android.provider.Settings.Global.CALL_AUTO_RETRY, 0);
+        }
+
+        // Stop any signalInfo tone being played when a call gets ended
+        stopSignalInfoTone();
+
+        if ((c != null) && (c.getCall().getPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)) {
+            // Resetting the CdmaPhoneCallState members
+            mApplication.cdmaPhoneCallState.resetCdmaPhoneCallState();
+
+            // Remove Call waiting timers
+            removeMessages(CALLWAITING_CALLERINFO_DISPLAY_DONE);
+            removeMessages(CALLWAITING_ADDCALL_DISABLE_TIMEOUT);
+        }
+
+        // Stop the ringer if it was ringing (for an incoming call that
+        // either disconnected by itself, or was rejected by the user.)
+        //
+        // TODO: We technically *shouldn't* stop the ringer if the
+        // foreground or background call disconnects while an incoming call
+        // is still ringing, but that's a really rare corner case.
+        // It's safest to just unconditionally stop the ringer here.
+
+        // CDMA: 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* be stopping the ringer being played for
+        // the Incoming Call
+        Call ringingCall = mCM.getFirstActiveRingingCall();
+        if (ringingCall.getPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
+            if (PhoneUtils.isRealIncomingCall(ringingCall.getState())) {
+                // Also we need to take off the "In Call" icon from the Notification
+                // area as the Out going Call never got connected
+                if (DBG) log("cancelCallInProgressNotifications()... (onDisconnect)");
+                mApplication.notificationMgr.cancelCallInProgressNotifications();
+            } else {
+                if (DBG) log("stopRing()... (onDisconnect)");
+                mRinger.stopRing();
+            }
+        } else { // GSM
+            if (DBG) log("stopRing()... (onDisconnect)");
+            mRinger.stopRing();
+        }
+
+        // stop call waiting tone if needed when disconnecting
+        if (mCallWaitingTonePlayer != null) {
+            mCallWaitingTonePlayer.stopTone();
+            mCallWaitingTonePlayer = null;
+        }
+
+        // If this is the end of an OTASP call, pass it on to the PhoneApp.
+        if (c != null && TelephonyCapabilities.supportsOtasp(c.getCall().getPhone())) {
+            final String number = c.getAddress();
+            if (c.getCall().getPhone().isOtaSpNumber(number)) {
+                if (DBG) log("onDisconnect: this was an OTASP call!");
+                mApplication.handleOtaspDisconnect();
+            }
+        }
+
+        // Check for the various tones we might need to play (thru the
+        // earpiece) after a call disconnects.
+        int toneToPlay = InCallTonePlayer.TONE_NONE;
+
+        // The "Busy" or "Congestion" tone is the highest priority:
+        if (c != null) {
+            Connection.DisconnectCause cause = c.getDisconnectCause();
+            if (cause == Connection.DisconnectCause.BUSY) {
+                if (DBG) log("- need to play BUSY tone!");
+                toneToPlay = InCallTonePlayer.TONE_BUSY;
+            } else if (cause == Connection.DisconnectCause.CONGESTION) {
+                if (DBG) log("- need to play CONGESTION tone!");
+                toneToPlay = InCallTonePlayer.TONE_CONGESTION;
+            } else if (((cause == Connection.DisconnectCause.NORMAL)
+                    || (cause == Connection.DisconnectCause.LOCAL))
+                    && (mApplication.isOtaCallInActiveState())) {
+                if (DBG) log("- need to play OTA_CALL_END tone!");
+                toneToPlay = InCallTonePlayer.TONE_OTA_CALL_END;
+            } else if (cause == Connection.DisconnectCause.CDMA_REORDER) {
+                if (DBG) log("- need to play CDMA_REORDER tone!");
+                toneToPlay = InCallTonePlayer.TONE_REORDER;
+            } else if (cause == Connection.DisconnectCause.CDMA_INTERCEPT) {
+                if (DBG) log("- need to play CDMA_INTERCEPT tone!");
+                toneToPlay = InCallTonePlayer.TONE_INTERCEPT;
+            } else if (cause == Connection.DisconnectCause.CDMA_DROP) {
+                if (DBG) log("- need to play CDMA_DROP tone!");
+                toneToPlay = InCallTonePlayer.TONE_CDMA_DROP;
+            } else if (cause == Connection.DisconnectCause.OUT_OF_SERVICE) {
+                if (DBG) log("- need to play OUT OF SERVICE tone!");
+                toneToPlay = InCallTonePlayer.TONE_OUT_OF_SERVICE;
+            } else if (cause == Connection.DisconnectCause.UNOBTAINABLE_NUMBER) {
+                if (DBG) log("- need to play TONE_UNOBTAINABLE_NUMBER tone!");
+                toneToPlay = InCallTonePlayer.TONE_UNOBTAINABLE_NUMBER;
+            } else if (cause == Connection.DisconnectCause.ERROR_UNSPECIFIED) {
+                if (DBG) log("- DisconnectCause is ERROR_UNSPECIFIED: play TONE_CALL_ENDED!");
+                toneToPlay = InCallTonePlayer.TONE_CALL_ENDED;
+            }
+        }
+
+        // If we don't need to play BUSY or CONGESTION, then play the
+        // "call ended" tone if this was a "regular disconnect" (i.e. a
+        // normal call where one end or the other hung up) *and* this
+        // disconnect event caused the phone to become idle.  (In other
+        // words, we *don't* play the sound if one call hangs up but
+        // there's still an active call on the other line.)
+        // TODO: We may eventually want to disable this via a preference.
+        if ((toneToPlay == InCallTonePlayer.TONE_NONE)
+            && (mCM.getState() == PhoneConstants.State.IDLE)
+            && (c != null)) {
+            Connection.DisconnectCause cause = c.getDisconnectCause();
+            if ((cause == Connection.DisconnectCause.NORMAL)  // remote hangup
+                || (cause == Connection.DisconnectCause.LOCAL)) {  // local hangup
+                if (VDBG) log("- need to play CALL_ENDED tone!");
+                toneToPlay = InCallTonePlayer.TONE_CALL_ENDED;
+                mIsCdmaRedialCall = false;
+            }
+        }
+
+        // All phone calls are disconnected.
+        if (mCM.getState() == PhoneConstants.State.IDLE) {
+            // Don't reset the audio mode or bluetooth/speakerphone state
+            // if we still need to let the user hear a tone through the earpiece.
+            if (toneToPlay == InCallTonePlayer.TONE_NONE) {
+                resetAudioStateAfterDisconnect();
+            }
+
+            mApplication.notificationMgr.cancelCallInProgressNotifications();
+        }
+
+        if (c != null) {
+            mCallLogger.logCall(c);
+
+            final String number = c.getAddress();
+            final Phone phone = c.getCall().getPhone();
+            final boolean isEmergencyNumber =
+                    PhoneNumberUtils.isLocalEmergencyNumber(number, mApplication);
+
+            if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
+                if ((isEmergencyNumber)
+                        && (mCurrentEmergencyToneState != EMERGENCY_TONE_OFF)) {
+                    if (mEmergencyTonePlayerVibrator != null) {
+                        mEmergencyTonePlayerVibrator.stop();
+                    }
+                }
+            }
+
+            final long date = c.getCreateTime();
+            final Connection.DisconnectCause cause = c.getDisconnectCause();
+            final boolean missedCall = c.isIncoming() &&
+                    (cause == Connection.DisconnectCause.INCOMING_MISSED);
+            if (missedCall) {
+                // Show the "Missed call" notification.
+                // (Note we *don't* do this if this was an incoming call that
+                // the user deliberately rejected.)
+                showMissedCallNotification(c, date);
+            }
+
+            // Possibly play a "post-disconnect tone" thru the earpiece.
+            // We do this here, rather than from the InCallScreen
+            // activity, since we need to do this even if you're not in
+            // the Phone UI at the moment the connection ends.
+            if (toneToPlay != InCallTonePlayer.TONE_NONE) {
+                if (VDBG) log("- starting post-disconnect tone (" + toneToPlay + ")...");
+                new InCallTonePlayer(toneToPlay).start();
+
+                // TODO: alternatively, we could start an InCallTonePlayer
+                // here with an "unlimited" tone length,
+                // and manually stop it later when this connection truly goes
+                // away.  (The real connection over the network was closed as soon
+                // as we got the BUSY message.  But our telephony layer keeps the
+                // connection open for a few extra seconds so we can show the
+                // "busy" indication to the user.  We could stop the busy tone
+                // when *that* connection's "disconnect" event comes in.)
+            }
+
+            if (((mPreviousCdmaCallState == Call.State.DIALING)
+                    || (mPreviousCdmaCallState == Call.State.ALERTING))
+                    && (!isEmergencyNumber)
+                    && (cause != Connection.DisconnectCause.INCOMING_MISSED )
+                    && (cause != Connection.DisconnectCause.NORMAL)
+                    && (cause != Connection.DisconnectCause.LOCAL)
+                    && (cause != Connection.DisconnectCause.INCOMING_REJECTED)) {
+                if (!mIsCdmaRedialCall) {
+                    if (autoretrySetting == InCallScreen.AUTO_RETRY_ON) {
+                        // TODO: (Moto): The contact reference data may need to be stored and use
+                        // here when redialing a call. For now, pass in NULL as the URI parameter.
+                        PhoneUtils.placeCall(mApplication, phone, number, null, false, null);
+                        mIsCdmaRedialCall = true;
+                    } else {
+                        mIsCdmaRedialCall = false;
+                    }
+                } else {
+                    mIsCdmaRedialCall = false;
+                }
+            }
+        }
+    }
+
+    /**
+     * Resets the audio mode and speaker state when a call ends.
+     */
+    private void resetAudioStateAfterDisconnect() {
+        if (VDBG) log("resetAudioStateAfterDisconnect()...");
+
+        if (mBluetoothHeadset != null) {
+            mBluetoothHeadset.disconnectAudio();
+        }
+
+        // call turnOnSpeaker() with state=false and store=true even if speaker
+        // is already off to reset user requested speaker state.
+        PhoneUtils.turnOnSpeaker(mApplication, false, true);
+
+        PhoneUtils.setAudioMode(mCM);
+    }
+
+    private void onMwiChanged(boolean visible) {
+        if (VDBG) log("onMwiChanged(): " + visible);
+
+        // "Voicemail" is meaningless on non-voice-capable devices,
+        // so ignore MWI events.
+        if (!PhoneGlobals.sVoiceCapable) {
+            // ...but still log a warning, since we shouldn't have gotten this
+            // event in the first place!
+            // (PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR events
+            // *should* be blocked at the telephony layer on non-voice-capable
+            // capable devices.)
+            Log.w(LOG_TAG, "Got onMwiChanged() on non-voice-capable device! Ignoring...");
+            return;
+        }
+
+        mApplication.notificationMgr.updateMwi(visible);
+    }
+
+    /**
+     * Posts a delayed PHONE_MWI_CHANGED event, to schedule a "retry" for a
+     * failed NotificationMgr.updateMwi() call.
+     */
+    /* package */ void sendMwiChangedDelayed(long delayMillis) {
+        Message message = Message.obtain(this, PHONE_MWI_CHANGED);
+        sendMessageDelayed(message, delayMillis);
+    }
+
+    private void onCfiChanged(boolean visible) {
+        if (VDBG) log("onCfiChanged(): " + visible);
+        mApplication.notificationMgr.updateCfi(visible);
+    }
+
+    /**
+     * Indicates whether or not this ringer is ringing.
+     */
+    boolean isRinging() {
+        return mRinger.isRinging();
+    }
+
+    /**
+     * Stops the current ring, and tells the notifier that future
+     * ring requests should be ignored.
+     */
+    void silenceRinger() {
+        mSilentRingerRequested = true;
+        if (DBG) log("stopRing()... (silenceRinger)");
+        mRinger.stopRing();
+    }
+
+    /**
+     * Restarts the ringer after having previously silenced it.
+     *
+     * (This is a no-op if the ringer is actually still ringing, or if the
+     * incoming ringing call no longer exists.)
+     */
+    /* package */ void restartRinger() {
+        if (DBG) log("restartRinger()...");
+        // Already ringing or Silent requested; no need to restart.
+        if (isRinging() || mSilentRingerRequested) return;
+
+        final Call ringingCall = mCM.getFirstActiveRingingCall();
+        // Don't check ringingCall.isRinging() here, since that'll be true
+        // for the WAITING state also.  We only allow the ringer for
+        // regular INCOMING calls.
+        if (DBG) log("- ringingCall state: " + ringingCall.getState());
+        if (ringingCall.getState() == Call.State.INCOMING) {
+            mRinger.ring();
+        }
+    }
+
+    /**
+     * Helper class to play tones through the earpiece (or speaker / BT)
+     * during a call, using the ToneGenerator.
+     *
+     * To use, just instantiate a new InCallTonePlayer
+     * (passing in the TONE_* constant for the tone you want)
+     * and start() it.
+     *
+     * When we're done playing the tone, if the phone is idle at that
+     * point, we'll reset the audio routing and speaker state.
+     * (That means that for tones that get played *after* a call
+     * disconnects, like "busy" or "congestion" or "call ended", you
+     * should NOT call resetAudioStateAfterDisconnect() yourself.
+     * Instead, just start the InCallTonePlayer, which will automatically
+     * defer the resetAudioStateAfterDisconnect() call until the tone
+     * finishes playing.)
+     */
+    private class InCallTonePlayer extends Thread {
+        private int mToneId;
+        private int mState;
+        // The possible tones we can play.
+        public static final int TONE_NONE = 0;
+        public static final int TONE_CALL_WAITING = 1;
+        public static final int TONE_BUSY = 2;
+        public static final int TONE_CONGESTION = 3;
+        public static final int TONE_CALL_ENDED = 4;
+        public static final int TONE_VOICE_PRIVACY = 5;
+        public static final int TONE_REORDER = 6;
+        public static final int TONE_INTERCEPT = 7;
+        public static final int TONE_CDMA_DROP = 8;
+        public static final int TONE_OUT_OF_SERVICE = 9;
+        public static final int TONE_REDIAL = 10;
+        public static final int TONE_OTA_CALL_END = 11;
+        public static final int TONE_RING_BACK = 12;
+        public static final int TONE_UNOBTAINABLE_NUMBER = 13;
+
+        // The tone volume relative to other sounds in the stream
+        static final int TONE_RELATIVE_VOLUME_EMERGENCY = 100;
+        static final int TONE_RELATIVE_VOLUME_HIPRI = 80;
+        static final int TONE_RELATIVE_VOLUME_LOPRI = 50;
+
+        // Buffer time (in msec) to add on to tone timeout value.
+        // Needed mainly when the timeout value for a tone is the
+        // exact duration of the tone itself.
+        static final int TONE_TIMEOUT_BUFFER = 20;
+
+        // The tone state
+        static final int TONE_OFF = 0;
+        static final int TONE_ON = 1;
+        static final int TONE_STOPPED = 2;
+
+        InCallTonePlayer(int toneId) {
+            super();
+            mToneId = toneId;
+            mState = TONE_OFF;
+        }
+
+        @Override
+        public void run() {
+            log("InCallTonePlayer.run(toneId = " + mToneId + ")...");
+
+            int toneType = 0;  // passed to ToneGenerator.startTone()
+            int toneVolume;  // passed to the ToneGenerator constructor
+            int toneLengthMillis;
+            int phoneType = mCM.getFgPhone().getPhoneType();
+
+            switch (mToneId) {
+                case TONE_CALL_WAITING:
+                    toneType = ToneGenerator.TONE_SUP_CALL_WAITING;
+                    toneVolume = TONE_RELATIVE_VOLUME_HIPRI;
+                    // Call waiting tone is stopped by stopTone() method
+                    toneLengthMillis = Integer.MAX_VALUE - TONE_TIMEOUT_BUFFER;
+                    break;
+                case TONE_BUSY:
+                    if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
+                        toneType = ToneGenerator.TONE_CDMA_NETWORK_BUSY_ONE_SHOT;
+                        toneVolume = TONE_RELATIVE_VOLUME_LOPRI;
+                        toneLengthMillis = 1000;
+                    } else if ((phoneType == PhoneConstants.PHONE_TYPE_GSM)
+                            || (phoneType == PhoneConstants.PHONE_TYPE_SIP)) {
+                        toneType = ToneGenerator.TONE_SUP_BUSY;
+                        toneVolume = TONE_RELATIVE_VOLUME_HIPRI;
+                        toneLengthMillis = 4000;
+                    } else {
+                        throw new IllegalStateException("Unexpected phone type: " + phoneType);
+                    }
+                    break;
+                case TONE_CONGESTION:
+                    toneType = ToneGenerator.TONE_SUP_CONGESTION;
+                    toneVolume = TONE_RELATIVE_VOLUME_HIPRI;
+                    toneLengthMillis = 4000;
+                    break;
+
+                case TONE_CALL_ENDED:
+                    toneType = ToneGenerator.TONE_PROP_PROMPT;
+                    toneVolume = TONE_RELATIVE_VOLUME_HIPRI;
+                    toneLengthMillis = 200;
+                    break;
+                 case TONE_OTA_CALL_END:
+                    if (mApplication.cdmaOtaConfigData.otaPlaySuccessFailureTone ==
+                            OtaUtils.OTA_PLAY_SUCCESS_FAILURE_TONE_ON) {
+                        toneType = ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD;
+                        toneVolume = TONE_RELATIVE_VOLUME_HIPRI;
+                        toneLengthMillis = 750;
+                    } else {
+                        toneType = ToneGenerator.TONE_PROP_PROMPT;
+                        toneVolume = TONE_RELATIVE_VOLUME_HIPRI;
+                        toneLengthMillis = 200;
+                    }
+                    break;
+                case TONE_VOICE_PRIVACY:
+                    toneType = ToneGenerator.TONE_CDMA_ALERT_NETWORK_LITE;
+                    toneVolume = TONE_RELATIVE_VOLUME_HIPRI;
+                    toneLengthMillis = 5000;
+                    break;
+                case TONE_REORDER:
+                    toneType = ToneGenerator.TONE_CDMA_REORDER;
+                    toneVolume = TONE_RELATIVE_VOLUME_HIPRI;
+                    toneLengthMillis = 4000;
+                    break;
+                case TONE_INTERCEPT:
+                    toneType = ToneGenerator.TONE_CDMA_ABBR_INTERCEPT;
+                    toneVolume = TONE_RELATIVE_VOLUME_LOPRI;
+                    toneLengthMillis = 500;
+                    break;
+                case TONE_CDMA_DROP:
+                case TONE_OUT_OF_SERVICE:
+                    toneType = ToneGenerator.TONE_CDMA_CALLDROP_LITE;
+                    toneVolume = TONE_RELATIVE_VOLUME_LOPRI;
+                    toneLengthMillis = 375;
+                    break;
+                case TONE_REDIAL:
+                    toneType = ToneGenerator.TONE_CDMA_ALERT_AUTOREDIAL_LITE;
+                    toneVolume = TONE_RELATIVE_VOLUME_LOPRI;
+                    toneLengthMillis = 5000;
+                    break;
+                case TONE_RING_BACK:
+                    toneType = ToneGenerator.TONE_SUP_RINGTONE;
+                    toneVolume = TONE_RELATIVE_VOLUME_HIPRI;
+                    // Call ring back tone is stopped by stopTone() method
+                    toneLengthMillis = Integer.MAX_VALUE - TONE_TIMEOUT_BUFFER;
+                    break;
+                case TONE_UNOBTAINABLE_NUMBER:
+                    toneType = ToneGenerator.TONE_SUP_ERROR;
+                    toneVolume = TONE_RELATIVE_VOLUME_HIPRI;
+                    toneLengthMillis = 4000;
+                    break;
+                default:
+                    throw new IllegalArgumentException("Bad toneId: " + mToneId);
+            }
+
+            // If the mToneGenerator creation fails, just continue without it.  It is
+            // a local audio signal, and is not as important.
+            ToneGenerator toneGenerator;
+            try {
+                int stream;
+                if (mBluetoothHeadset != null) {
+                    stream = mBluetoothHeadset.isAudioOn() ? AudioManager.STREAM_BLUETOOTH_SCO:
+                        AudioManager.STREAM_VOICE_CALL;
+                } else {
+                    stream = AudioManager.STREAM_VOICE_CALL;
+                }
+                toneGenerator = new ToneGenerator(stream, toneVolume);
+                // if (DBG) log("- created toneGenerator: " + toneGenerator);
+            } catch (RuntimeException e) {
+                Log.w(LOG_TAG,
+                      "InCallTonePlayer: Exception caught while creating ToneGenerator: " + e);
+                toneGenerator = null;
+            }
+
+            // Using the ToneGenerator (with the CALL_WAITING / BUSY /
+            // CONGESTION tones at least), the ToneGenerator itself knows
+            // the right pattern of tones to play; we do NOT need to
+            // manually start/stop each individual tone, or manually
+            // insert the correct delay between tones.  (We just start it
+            // and let it run for however long we want the tone pattern to
+            // continue.)
+            //
+            // TODO: When we stop the ToneGenerator in the middle of a
+            // "tone pattern", it sounds bad if we cut if off while the
+            // tone is actually playing.  Consider adding API to the
+            // ToneGenerator to say "stop at the next silent part of the
+            // pattern", or simply "play the pattern N times and then
+            // stop."
+            boolean needToStopTone = true;
+            boolean okToPlayTone = false;
+
+            if (toneGenerator != null) {
+                int ringerMode = mAudioManager.getRingerMode();
+                if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
+                    if (toneType == ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD) {
+                        if ((ringerMode != AudioManager.RINGER_MODE_SILENT) &&
+                                (ringerMode != AudioManager.RINGER_MODE_VIBRATE)) {
+                            if (DBG) log("- InCallTonePlayer: start playing call tone=" + toneType);
+                            okToPlayTone = true;
+                            needToStopTone = false;
+                        }
+                    } else if ((toneType == ToneGenerator.TONE_CDMA_NETWORK_BUSY_ONE_SHOT) ||
+                            (toneType == ToneGenerator.TONE_CDMA_REORDER) ||
+                            (toneType == ToneGenerator.TONE_CDMA_ABBR_REORDER) ||
+                            (toneType == ToneGenerator.TONE_CDMA_ABBR_INTERCEPT) ||
+                            (toneType == ToneGenerator.TONE_CDMA_CALLDROP_LITE)) {
+                        if (ringerMode != AudioManager.RINGER_MODE_SILENT) {
+                            if (DBG) log("InCallTonePlayer:playing call fail tone:" + toneType);
+                            okToPlayTone = true;
+                            needToStopTone = false;
+                        }
+                    } else if ((toneType == ToneGenerator.TONE_CDMA_ALERT_AUTOREDIAL_LITE) ||
+                               (toneType == ToneGenerator.TONE_CDMA_ALERT_NETWORK_LITE)) {
+                        if ((ringerMode != AudioManager.RINGER_MODE_SILENT) &&
+                                (ringerMode != AudioManager.RINGER_MODE_VIBRATE)) {
+                            if (DBG) log("InCallTonePlayer:playing tone for toneType=" + toneType);
+                            okToPlayTone = true;
+                            needToStopTone = false;
+                        }
+                    } else { // For the rest of the tones, always OK to play.
+                        okToPlayTone = true;
+                    }
+                } else {  // Not "CDMA"
+                    okToPlayTone = true;
+                }
+
+                synchronized (this) {
+                    if (okToPlayTone && mState != TONE_STOPPED) {
+                        mState = TONE_ON;
+                        toneGenerator.startTone(toneType);
+                        try {
+                            wait(toneLengthMillis + TONE_TIMEOUT_BUFFER);
+                        } catch  (InterruptedException e) {
+                            Log.w(LOG_TAG,
+                                  "InCallTonePlayer stopped: " + e);
+                        }
+                        if (needToStopTone) {
+                            toneGenerator.stopTone();
+                        }
+                    }
+                    // if (DBG) log("- InCallTonePlayer: done playing.");
+                    toneGenerator.release();
+                    mState = TONE_OFF;
+                }
+            }
+
+            // Finally, do the same cleanup we otherwise would have done
+            // in onDisconnect().
+            //
+            // (But watch out: do NOT do this if the phone is in use,
+            // since some of our tones get played *during* a call (like
+            // CALL_WAITING) and we definitely *don't*
+            // want to reset the audio mode / speaker / bluetooth after
+            // playing those!
+            // This call is really here for use with tones that get played
+            // *after* a call disconnects, like "busy" or "congestion" or
+            // "call ended", where the phone has already become idle but
+            // we need to defer the resetAudioStateAfterDisconnect() call
+            // till the tone finishes playing.)
+            if (mCM.getState() == PhoneConstants.State.IDLE) {
+                resetAudioStateAfterDisconnect();
+            }
+        }
+
+        public void stopTone() {
+            synchronized (this) {
+                if (mState == TONE_ON) {
+                    notify();
+                }
+                mState = TONE_STOPPED;
+            }
+        }
+    }
+
+    /**
+     * Displays a notification when the phone receives a DisplayInfo record.
+     */
+    private void onDisplayInfo(AsyncResult r) {
+        // Extract the DisplayInfo String from the message
+        CdmaDisplayInfoRec displayInfoRec = (CdmaDisplayInfoRec)(r.result);
+
+        if (displayInfoRec != null) {
+            String displayInfo = displayInfoRec.alpha;
+            if (DBG) log("onDisplayInfo: displayInfo=" + displayInfo);
+            CdmaDisplayInfo.displayInfoRecord(mApplication, displayInfo);
+
+            // start a 2 second timer
+            sendEmptyMessageDelayed(DISPLAYINFO_NOTIFICATION_DONE,
+                    DISPLAYINFO_NOTIFICATION_TIME);
+        }
+    }
+
+    /**
+     * Helper class to play SignalInfo tones using the ToneGenerator.
+     *
+     * To use, just instantiate a new SignalInfoTonePlayer
+     * (passing in the ToneID constant for the tone you want)
+     * and start() it.
+     */
+    private class SignalInfoTonePlayer extends Thread {
+        private int mToneId;
+
+        SignalInfoTonePlayer(int toneId) {
+            super();
+            mToneId = toneId;
+        }
+
+        @Override
+        public void run() {
+            log("SignalInfoTonePlayer.run(toneId = " + mToneId + ")...");
+
+            if (mSignalInfoToneGenerator != null) {
+                //First stop any ongoing SignalInfo tone
+                mSignalInfoToneGenerator.stopTone();
+
+                //Start playing the new tone if its a valid tone
+                mSignalInfoToneGenerator.startTone(mToneId);
+            }
+        }
+    }
+
+    /**
+     * Plays a tone when the phone receives a SignalInfo record.
+     */
+    private void onSignalInfo(AsyncResult r) {
+        // Signal Info are totally ignored on non-voice-capable devices.
+        if (!PhoneGlobals.sVoiceCapable) {
+            Log.w(LOG_TAG, "Got onSignalInfo() on non-voice-capable device! Ignoring...");
+            return;
+        }
+
+        if (PhoneUtils.isRealIncomingCall(mCM.getFirstActiveRingingCall().getState())) {
+            // Do not start any new SignalInfo tone when Call state is INCOMING
+            // and stop any previous SignalInfo tone which is being played
+            stopSignalInfoTone();
+        } else {
+            // Extract the SignalInfo String from the message
+            CdmaSignalInfoRec signalInfoRec = (CdmaSignalInfoRec)(r.result);
+            // Only proceed if a Signal info is present.
+            if (signalInfoRec != null) {
+                boolean isPresent = signalInfoRec.isPresent;
+                if (DBG) log("onSignalInfo: isPresent=" + isPresent);
+                if (isPresent) {// if tone is valid
+                    int uSignalType = signalInfoRec.signalType;
+                    int uAlertPitch = signalInfoRec.alertPitch;
+                    int uSignal = signalInfoRec.signal;
+
+                    if (DBG) log("onSignalInfo: uSignalType=" + uSignalType + ", uAlertPitch=" +
+                            uAlertPitch + ", uSignal=" + uSignal);
+                    //Map the Signal to a ToneGenerator ToneID only if Signal info is present
+                    int toneID = SignalToneUtil.getAudioToneFromSignalInfo
+                            (uSignalType, uAlertPitch, uSignal);
+
+                    //Create the SignalInfo tone player and pass the ToneID
+                    new SignalInfoTonePlayer(toneID).start();
+                }
+            }
+        }
+    }
+
+    /**
+     * Stops a SignalInfo tone in the following condition
+     * 1 - On receiving a New Ringing Call
+     * 2 - On disconnecting a call
+     * 3 - On answering a Call Waiting Call
+     */
+    /* package */ void stopSignalInfoTone() {
+        if (DBG) log("stopSignalInfoTone: Stopping SignalInfo tone player");
+        new SignalInfoTonePlayer(ToneGenerator.TONE_CDMA_SIGNAL_OFF).start();
+    }
+
+    /**
+     * Plays a Call waiting tone if it is present in the second incoming call.
+     */
+    private void onCdmaCallWaiting(AsyncResult r) {
+        // Remove any previous Call waiting timers in the queue
+        removeMessages(CALLWAITING_CALLERINFO_DISPLAY_DONE);
+        removeMessages(CALLWAITING_ADDCALL_DISABLE_TIMEOUT);
+
+        // Set the Phone Call State to SINGLE_ACTIVE as there is only one connection
+        // else we would not have received Call waiting
+        mApplication.cdmaPhoneCallState.setCurrentCallState(
+                CdmaPhoneCallState.PhoneCallState.SINGLE_ACTIVE);
+
+        // Display the incoming call to the user if the InCallScreen isn't
+        // already in the foreground.
+        if (!mApplication.isShowingCallScreen()) {
+            if (DBG) log("- showing incoming call (CDMA call waiting)...");
+            showIncomingCall();
+        }
+
+        // Start timer for CW display
+        mCallWaitingTimeOut = false;
+        sendEmptyMessageDelayed(CALLWAITING_CALLERINFO_DISPLAY_DONE,
+                CALLWAITING_CALLERINFO_DISPLAY_TIME);
+
+        // Set the mAddCallMenuStateAfterCW state to false
+        mApplication.cdmaPhoneCallState.setAddCallMenuStateAfterCallWaiting(false);
+
+        // Start the timer for disabling "Add Call" menu option
+        sendEmptyMessageDelayed(CALLWAITING_ADDCALL_DISABLE_TIMEOUT,
+                CALLWAITING_ADDCALL_DISABLE_TIME);
+
+        // Extract the Call waiting information
+        CdmaCallWaitingNotification infoCW = (CdmaCallWaitingNotification) r.result;
+        int isPresent = infoCW.isPresent;
+        if (DBG) log("onCdmaCallWaiting: isPresent=" + isPresent);
+        if (isPresent == 1 ) {//'1' if tone is valid
+            int uSignalType = infoCW.signalType;
+            int uAlertPitch = infoCW.alertPitch;
+            int uSignal = infoCW.signal;
+            if (DBG) log("onCdmaCallWaiting: uSignalType=" + uSignalType + ", uAlertPitch="
+                    + uAlertPitch + ", uSignal=" + uSignal);
+            //Map the Signal to a ToneGenerator ToneID only if Signal info is present
+            int toneID =
+                SignalToneUtil.getAudioToneFromSignalInfo(uSignalType, uAlertPitch, uSignal);
+
+            //Create the SignalInfo tone player and pass the ToneID
+            new SignalInfoTonePlayer(toneID).start();
+        }
+    }
+
+    /**
+     * Posts a event causing us to clean up after rejecting (or timing-out) a
+     * CDMA call-waiting call.
+     *
+     * This method is safe to call from any thread.
+     * @see #onCdmaCallWaitingReject()
+     */
+    /* package */ void sendCdmaCallWaitingReject() {
+        sendEmptyMessage(CDMA_CALL_WAITING_REJECT);
+    }
+
+    /**
+     * Performs Call logging based on Timeout or Ignore Call Waiting Call for CDMA,
+     * and finally calls Hangup on the Call Waiting connection.
+     *
+     * This method should be called only from the UI thread.
+     * @see #sendCdmaCallWaitingReject()
+     */
+    private void onCdmaCallWaitingReject() {
+        final Call ringingCall = mCM.getFirstActiveRingingCall();
+
+        // Call waiting timeout scenario
+        if (ringingCall.getState() == Call.State.WAITING) {
+            // Code for perform Call logging and missed call notification
+            Connection c = ringingCall.getLatestConnection();
+
+            if (c != null) {
+                final int callLogType = mCallWaitingTimeOut ?
+                        Calls.MISSED_TYPE : Calls.INCOMING_TYPE;
+
+                // TODO: This callLogType override is not ideal. Connection should be astracted away
+                // at a telephony-phone layer that can understand and edit the callTypes within
+                // the abstraction for CDMA devices.
+                mCallLogger.logCall(c, callLogType);
+
+                final long date = c.getCreateTime();
+                if (callLogType == Calls.MISSED_TYPE) {
+                    // Add missed call notification
+                    showMissedCallNotification(c, date);
+                } else {
+                    // Remove Call waiting 20 second display timer in the queue
+                    removeMessages(CALLWAITING_CALLERINFO_DISPLAY_DONE);
+                }
+
+                // Hangup the RingingCall connection for CW
+                PhoneUtils.hangup(c);
+            }
+
+            //Reset the mCallWaitingTimeOut boolean
+            mCallWaitingTimeOut = false;
+        }
+    }
+
+    /**
+     * Return the private variable mPreviousCdmaCallState.
+     */
+    /* package */ Call.State getPreviousCdmaCallState() {
+        return mPreviousCdmaCallState;
+    }
+
+    /**
+     * Return the private variable mVoicePrivacyState.
+     */
+    /* package */ boolean getVoicePrivacyState() {
+        return mVoicePrivacyState;
+    }
+
+    /**
+     * Return the private variable mIsCdmaRedialCall.
+     */
+    /* package */ boolean getIsCdmaRedialCall() {
+        return mIsCdmaRedialCall;
+    }
+
+    /**
+     * Helper function used to show a missed call notification.
+     */
+    private void showMissedCallNotification(Connection c, final long date) {
+        PhoneUtils.CallerInfoToken info =
+                PhoneUtils.startGetCallerInfo(mApplication, c, this, Long.valueOf(date));
+        if (info != null) {
+            // at this point, we've requested to start a query, but it makes no
+            // sense to log this missed call until the query comes back.
+            if (VDBG) log("showMissedCallNotification: Querying for CallerInfo on missed call...");
+            if (info.isFinal) {
+                // it seems that the query we have actually is up to date.
+                // send the notification then.
+                CallerInfo ci = info.currentInfo;
+
+                // Check number presentation value; if we have a non-allowed presentation,
+                // then display an appropriate presentation string instead as the missed
+                // call.
+                String name = ci.name;
+                String number = ci.phoneNumber;
+                if (ci.numberPresentation == PhoneConstants.PRESENTATION_RESTRICTED) {
+                    name = mApplication.getString(R.string.private_num);
+                } else if (ci.numberPresentation != PhoneConstants.PRESENTATION_ALLOWED) {
+                    name = mApplication.getString(R.string.unknown);
+                } else {
+                    number = PhoneUtils.modifyForSpecialCnapCases(mApplication,
+                            ci, number, ci.numberPresentation);
+                }
+                mApplication.notificationMgr.notifyMissedCall(name, number,
+                        ci.phoneLabel, ci.cachedPhoto, ci.cachedPhotoIcon, date);
+            }
+        } else {
+            // getCallerInfo() can return null in rare cases, like if we weren't
+            // able to get a valid phone number out of the specified Connection.
+            Log.w(LOG_TAG, "showMissedCallNotification: got null CallerInfo for Connection " + c);
+        }
+    }
+
+    /**
+     *  Inner class to handle emergency call tone and vibrator
+     */
+    private class EmergencyTonePlayerVibrator {
+        private final int EMG_VIBRATE_LENGTH = 1000;  // ms.
+        private final int EMG_VIBRATE_PAUSE  = 1000;  // ms.
+        private final long[] mVibratePattern =
+                new long[] { EMG_VIBRATE_LENGTH, EMG_VIBRATE_PAUSE };
+
+        private ToneGenerator mToneGenerator;
+        // We don't rely on getSystemService(Context.VIBRATOR_SERVICE) to make sure this vibrator
+        // object will be isolated from others.
+        private Vibrator mEmgVibrator = new SystemVibrator();
+        private int mInCallVolume;
+
+        /**
+         * constructor
+         */
+        public EmergencyTonePlayerVibrator() {
+        }
+
+        /**
+         * Start the emergency tone or vibrator.
+         */
+        private void start() {
+            if (VDBG) log("call startEmergencyToneOrVibrate.");
+            int ringerMode = mAudioManager.getRingerMode();
+
+            if ((mIsEmergencyToneOn == EMERGENCY_TONE_ALERT) &&
+                    (ringerMode == AudioManager.RINGER_MODE_NORMAL)) {
+                log("EmergencyTonePlayerVibrator.start(): emergency tone...");
+                mToneGenerator = new ToneGenerator (AudioManager.STREAM_VOICE_CALL,
+                        InCallTonePlayer.TONE_RELATIVE_VOLUME_EMERGENCY);
+                if (mToneGenerator != null) {
+                    mInCallVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL);
+                    mAudioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL,
+                            mAudioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL),
+                            0);
+                    mToneGenerator.startTone(ToneGenerator.TONE_CDMA_EMERGENCY_RINGBACK);
+                    mCurrentEmergencyToneState = EMERGENCY_TONE_ALERT;
+                }
+            } else if (mIsEmergencyToneOn == EMERGENCY_TONE_VIBRATE) {
+                log("EmergencyTonePlayerVibrator.start(): emergency vibrate...");
+                if (mEmgVibrator != null) {
+                    mEmgVibrator.vibrate(mVibratePattern, 0);
+                    mCurrentEmergencyToneState = EMERGENCY_TONE_VIBRATE;
+                }
+            }
+        }
+
+        /**
+         * If the emergency tone is active, stop the tone or vibrator accordingly.
+         */
+        private void stop() {
+            if (VDBG) log("call stopEmergencyToneOrVibrate.");
+
+            if ((mCurrentEmergencyToneState == EMERGENCY_TONE_ALERT)
+                    && (mToneGenerator != null)) {
+                mToneGenerator.stopTone();
+                mToneGenerator.release();
+                mAudioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL,
+                        mInCallVolume,
+                        0);
+            } else if ((mCurrentEmergencyToneState == EMERGENCY_TONE_VIBRATE)
+                    && (mEmgVibrator != null)) {
+                mEmgVibrator.cancel();
+            }
+            mCurrentEmergencyToneState = EMERGENCY_TONE_OFF;
+        }
+    }
+
+     private BluetoothProfile.ServiceListener mBluetoothProfileServiceListener =
+        new BluetoothProfile.ServiceListener() {
+        public void onServiceConnected(int profile, BluetoothProfile proxy) {
+            mBluetoothHeadset = (BluetoothHeadset) proxy;
+            if (VDBG) log("- Got BluetoothHeadset: " + mBluetoothHeadset);
+        }
+
+        public void onServiceDisconnected(int profile) {
+            mBluetoothHeadset = null;
+        }
+    };
+
+    private void onRingbackTone(AsyncResult r) {
+        boolean playTone = (Boolean)(r.result);
+
+        if (playTone == true) {
+            // Only play when foreground call is in DIALING or ALERTING.
+            // to prevent a late coming playtone after ALERTING.
+            // Don't play ringback tone if it is in play, otherwise it will cut
+            // the current tone and replay it
+            if (mCM.getActiveFgCallState().isDialing() &&
+                mInCallRingbackTonePlayer == null) {
+                mInCallRingbackTonePlayer = new InCallTonePlayer(InCallTonePlayer.TONE_RING_BACK);
+                mInCallRingbackTonePlayer.start();
+            }
+        } else {
+            if (mInCallRingbackTonePlayer != null) {
+                mInCallRingbackTonePlayer.stopTone();
+                mInCallRingbackTonePlayer = null;
+            }
+        }
+    }
+
+    /**
+     * Toggle mute and unmute requests while keeping the same mute state
+     */
+    private void onResendMute() {
+        boolean muteState = PhoneUtils.getMute();
+        PhoneUtils.setMute(!muteState);
+        PhoneUtils.setMute(muteState);
+    }
+
+    private void log(String msg) {
+        Log.d(LOG_TAG, msg);
+    }
+}
diff --git a/src/com/android/phone/CallStateMonitor.java b/src/com/android/phone/CallStateMonitor.java
new file mode 100644
index 0000000..6a03e22
--- /dev/null
+++ b/src/com/android/phone/CallStateMonitor.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2013 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.AsyncResult;
+import android.os.Handler;
+import android.os.Message;
+import android.os.SystemProperties;
+import android.util.Log;
+
+import com.android.internal.telephony.CallManager;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+
+/**
+ * Dedicated Call state monitoring class.  This class communicates directly with
+ * the call manager to listen for call state events and notifies registered
+ * handlers.
+ * It works as an inverse multiplexor for all classes wanted Call State updates
+ * so that there exists only one channel to the telephony layer.
+ *
+ * TODO: Add manual phone state checks (getState(), etc.).
+ */
+class CallStateMonitor extends Handler {
+    private static final String LOG_TAG = CallStateMonitor.class.getSimpleName();
+    private static final boolean DBG =
+            (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
+
+    // Events from the Phone object:
+    public static final int PHONE_STATE_CHANGED = 1;
+    public static final int PHONE_NEW_RINGING_CONNECTION = 2;
+    public static final int PHONE_DISCONNECT = 3;
+    public static final int PHONE_UNKNOWN_CONNECTION_APPEARED = 4;
+    public static final int PHONE_INCOMING_RING = 5;
+    public static final int PHONE_STATE_DISPLAYINFO = 6;
+    public static final int PHONE_STATE_SIGNALINFO = 7;
+    public static final int PHONE_CDMA_CALL_WAITING = 8;
+    public static final int PHONE_ENHANCED_VP_ON = 9;
+    public static final int PHONE_ENHANCED_VP_OFF = 10;
+    public static final int PHONE_RINGBACK_TONE = 11;
+    public static final int PHONE_RESEND_MUTE = 12;
+
+    // Other events from call manager
+    public static final int EVENT_OTA_PROVISION_CHANGE = 20;
+
+    private CallManager callManager;
+    private ArrayList<Handler> registeredHandlers;
+
+    // Events generated internally:
+    public CallStateMonitor(CallManager callManager) {
+        this.callManager = callManager;
+        registeredHandlers = new ArrayList<Handler>();
+
+        registerForNotifications();
+    }
+
+    /**
+     * Register for call state notifications with the CallManager.
+     */
+    private void registerForNotifications() {
+        callManager.registerForNewRingingConnection(this, PHONE_NEW_RINGING_CONNECTION, null);
+        callManager.registerForPreciseCallStateChanged(this, PHONE_STATE_CHANGED, null);
+        callManager.registerForDisconnect(this, PHONE_DISCONNECT, null);
+        callManager.registerForUnknownConnection(this, PHONE_UNKNOWN_CONNECTION_APPEARED, null);
+        callManager.registerForIncomingRing(this, PHONE_INCOMING_RING, null);
+        callManager.registerForCdmaOtaStatusChange(this, EVENT_OTA_PROVISION_CHANGE, null);
+        callManager.registerForCallWaiting(this, PHONE_CDMA_CALL_WAITING, null);
+        callManager.registerForDisplayInfo(this, PHONE_STATE_DISPLAYINFO, null);
+        callManager.registerForSignalInfo(this, PHONE_STATE_SIGNALINFO, null);
+        callManager.registerForInCallVoicePrivacyOn(this, PHONE_ENHANCED_VP_ON, null);
+        callManager.registerForInCallVoicePrivacyOff(this, PHONE_ENHANCED_VP_OFF, null);
+        callManager.registerForRingbackTone(this, PHONE_RINGBACK_TONE, null);
+        callManager.registerForResendIncallMute(this, PHONE_RESEND_MUTE, null);
+    }
+
+    public void addListener(Handler handler) {
+        if (handler != null && !registeredHandlers.contains(handler)) {
+            registeredHandlers.add(handler);
+        }
+    }
+
+    @Override
+    public void handleMessage(Message msg) {
+        if (DBG) {
+            Log.d(LOG_TAG, "handleMessage(" + msg.what + ")");
+        }
+
+        for (Handler handler : registeredHandlers) {
+            handler.handleMessage(msg);
+        }
+    }
+
+    /**
+     * When radio technology changes, we need to to reregister for all the events which are
+     * all tied to the old radio.
+     */
+    public void updateAfterRadioTechnologyChange() {
+        if (DBG) Log.d(LOG_TAG, "updateCallNotifierRegistrationsAfterRadioTechnologyChange...");
+
+        // Unregister all events from the old obsolete phone
+        callManager.unregisterForNewRingingConnection(this);
+        callManager.unregisterForPreciseCallStateChanged(this);
+        callManager.unregisterForDisconnect(this);
+        callManager.unregisterForUnknownConnection(this);
+        callManager.unregisterForIncomingRing(this);
+        callManager.unregisterForCallWaiting(this);
+        callManager.unregisterForDisplayInfo(this);
+        callManager.unregisterForSignalInfo(this);
+        callManager.unregisterForCdmaOtaStatusChange(this);
+        callManager.unregisterForRingbackTone(this);
+        callManager.unregisterForResendIncallMute(this);
+        callManager.unregisterForInCallVoicePrivacyOn(this);
+        callManager.unregisterForInCallVoicePrivacyOff(this);
+
+        registerForNotifications();
+    }
+
+}
diff --git a/src/com/android/phone/CallTime.java b/src/com/android/phone/CallTime.java
new file mode 100644
index 0000000..92c7972
--- /dev/null
+++ b/src/com/android/phone/CallTime.java
@@ -0,0 +1,231 @@
+/*
+ * 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.content.Context;
+import android.os.Debug;
+import android.os.Handler;
+import android.os.SystemClock;
+import com.android.internal.telephony.Call;
+import com.android.internal.telephony.Connection;
+import android.util.Log;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * Helper class used to keep track of various "elapsed time" indications
+ * in the Phone app, and also to start and stop tracing / profiling.
+ */
+public class CallTime extends Handler {
+    private static final String LOG_TAG = "PHONE/CallTime";
+    private static final boolean DBG = false;
+    /* package */ static final boolean PROFILE = true;
+
+    private static final int PROFILE_STATE_NONE = 0;
+    private static final int PROFILE_STATE_READY = 1;
+    private static final int PROFILE_STATE_RUNNING = 2;
+
+    private static int sProfileState = PROFILE_STATE_NONE;
+
+    private Call mCall;
+    private long mLastReportedTime;
+    private boolean mTimerRunning;
+    private long mInterval;
+    private PeriodicTimerCallback mTimerCallback;
+    private OnTickListener mListener;
+
+    interface OnTickListener {
+        void onTickForCallTimeElapsed(long timeElapsed);
+    }
+
+    public CallTime(OnTickListener listener) {
+        mListener = listener;
+        mTimerCallback = new PeriodicTimerCallback();
+    }
+
+    /**
+     * Sets the call timer to "active call" mode, where the timer will
+     * periodically update the UI to show how long the specified call
+     * has been active.
+     *
+     * After calling this you should also call reset() and
+     * periodicUpdateTimer() to get the timer started.
+     */
+    /* package */ void setActiveCallMode(Call call) {
+        if (DBG) log("setActiveCallMode(" + call + ")...");
+        mCall = call;
+
+        // How frequently should we update the UI?
+        mInterval = 1000;  // once per second
+    }
+
+    /* package */ void reset() {
+        if (DBG) log("reset()...");
+        mLastReportedTime = SystemClock.uptimeMillis() - mInterval;
+    }
+
+    /* package */ void periodicUpdateTimer() {
+        if (!mTimerRunning) {
+            mTimerRunning = true;
+
+            long now = SystemClock.uptimeMillis();
+            long nextReport = mLastReportedTime + mInterval;
+
+            while (now >= nextReport) {
+                nextReport += mInterval;
+            }
+
+            if (DBG) log("periodicUpdateTimer() @ " + nextReport);
+            postAtTime(mTimerCallback, nextReport);
+            mLastReportedTime = nextReport;
+
+            if (mCall != null) {
+                Call.State state = mCall.getState();
+
+                if (state == Call.State.ACTIVE) {
+                    updateElapsedTime(mCall);
+                }
+            }
+
+            if (PROFILE && isTraceReady()) {
+                startTrace();
+            }
+        } else {
+            if (DBG) log("periodicUpdateTimer: timer already running, bail");
+        }
+    }
+
+    /* package */ void cancelTimer() {
+        if (DBG) log("cancelTimer()...");
+        removeCallbacks(mTimerCallback);
+        mTimerRunning = false;
+    }
+
+    private void updateElapsedTime(Call call) {
+        if (mListener != null) {
+            long duration = getCallDuration(call);
+            mListener.onTickForCallTimeElapsed(duration / 1000);
+        }
+    }
+
+    /**
+     * Returns a "call duration" value for the specified Call, in msec,
+     * suitable for display in the UI.
+     */
+    /* package */ static long getCallDuration(Call call) {
+        long duration = 0;
+        List connections = call.getConnections();
+        int count = connections.size();
+        Connection c;
+
+        if (count == 1) {
+            c = (Connection) connections.get(0);
+            //duration = (state == Call.State.ACTIVE
+            //            ? c.getDurationMillis() : c.getHoldDurationMillis());
+            duration = c.getDurationMillis();
+        } else {
+            for (int i = 0; i < count; i++) {
+                c = (Connection) connections.get(i);
+                //long t = (state == Call.State.ACTIVE
+                //          ? c.getDurationMillis() : c.getHoldDurationMillis());
+                long t = c.getDurationMillis();
+                if (t > duration) {
+                    duration = t;
+                }
+            }
+        }
+
+        if (DBG) log("updateElapsedTime, count=" + count + ", duration=" + duration);
+        return duration;
+    }
+
+    private static void log(String msg) {
+        Log.d(LOG_TAG, "[CallTime] " + msg);
+    }
+
+    private class PeriodicTimerCallback implements Runnable {
+        PeriodicTimerCallback() {
+
+        }
+
+        public void run() {
+            if (PROFILE && isTraceRunning()) {
+                stopTrace();
+            }
+
+            mTimerRunning = false;
+            periodicUpdateTimer();
+        }
+    }
+
+    static void setTraceReady() {
+        if (sProfileState == PROFILE_STATE_NONE) {
+            sProfileState = PROFILE_STATE_READY;
+            log("trace ready...");
+        } else {
+            log("current trace state = " + sProfileState);
+        }
+    }
+
+    boolean isTraceReady() {
+        return sProfileState == PROFILE_STATE_READY;
+    }
+
+    boolean isTraceRunning() {
+        return sProfileState == PROFILE_STATE_RUNNING;
+    }
+
+    void startTrace() {
+        if (PROFILE & sProfileState == PROFILE_STATE_READY) {
+            // For now, we move away from temp directory in favor of
+            // the application's data directory to store the trace
+            // information (/data/data/com.android.phone).
+            File file = PhoneGlobals.getInstance().getDir ("phoneTrace", Context.MODE_PRIVATE);
+            if (file.exists() == false) {
+                file.mkdirs();
+            }
+            String baseName = file.getPath() + File.separator + "callstate";
+            String dataFile = baseName + ".data";
+            String keyFile = baseName + ".key";
+
+            file = new File(dataFile);
+            if (file.exists() == true) {
+                file.delete();
+            }
+
+            file = new File(keyFile);
+            if (file.exists() == true) {
+                file.delete();
+            }
+
+            sProfileState = PROFILE_STATE_RUNNING;
+            log("startTrace");
+            Debug.startMethodTracing(baseName, 8 * 1024 * 1024);
+        }
+    }
+
+    void stopTrace() {
+        if (PROFILE) {
+            if (sProfileState == PROFILE_STATE_RUNNING) {
+                sProfileState = PROFILE_STATE_NONE;
+                log("stopTrace");
+                Debug.stopMethodTracing();
+            }
+        }
+    }
+}
diff --git a/src/com/android/phone/CallWaitingCheckBoxPreference.java b/src/com/android/phone/CallWaitingCheckBoxPreference.java
new file mode 100644
index 0000000..a2f5c70
--- /dev/null
+++ b/src/com/android/phone/CallWaitingCheckBoxPreference.java
@@ -0,0 +1,134 @@
+package com.android.phone;
+
+import com.android.internal.telephony.CommandException;
+import com.android.internal.telephony.Phone;
+
+import static com.android.phone.TimeConsumingPreferenceActivity.RESPONSE_ERROR;
+
+import android.content.Context;
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.Message;
+import android.preference.CheckBoxPreference;
+import android.util.AttributeSet;
+import android.util.Log;
+
+import com.android.internal.telephony.Phone;
+
+public class CallWaitingCheckBoxPreference extends CheckBoxPreference {
+    private static final String LOG_TAG = "CallWaitingCheckBoxPreference";
+    private final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
+
+    private final MyHandler mHandler = new MyHandler();
+    private final Phone mPhone;
+    private TimeConsumingPreferenceListener mTcpListener;
+
+    public CallWaitingCheckBoxPreference(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+
+        mPhone = PhoneGlobals.getPhone();
+    }
+
+    public CallWaitingCheckBoxPreference(Context context, AttributeSet attrs) {
+        this(context, attrs, com.android.internal.R.attr.checkBoxPreferenceStyle);
+    }
+
+    public CallWaitingCheckBoxPreference(Context context) {
+        this(context, null);
+    }
+
+    /* package */ void init(TimeConsumingPreferenceListener listener, boolean skipReading) {
+        mTcpListener = listener;
+
+        if (!skipReading) {
+            mPhone.getCallWaiting(mHandler.obtainMessage(MyHandler.MESSAGE_GET_CALL_WAITING,
+                    MyHandler.MESSAGE_GET_CALL_WAITING, MyHandler.MESSAGE_GET_CALL_WAITING));
+            if (mTcpListener != null) {
+                mTcpListener.onStarted(this, true);
+            }
+        }
+    }
+
+    @Override
+    protected void onClick() {
+        super.onClick();
+
+        mPhone.setCallWaiting(isChecked(),
+                mHandler.obtainMessage(MyHandler.MESSAGE_SET_CALL_WAITING));
+        if (mTcpListener != null) {
+            mTcpListener.onStarted(this, false);
+        }
+    }
+
+    private class MyHandler extends Handler {
+        static final int MESSAGE_GET_CALL_WAITING = 0;
+        static final int MESSAGE_SET_CALL_WAITING = 1;
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MESSAGE_GET_CALL_WAITING:
+                    handleGetCallWaitingResponse(msg);
+                    break;
+                case MESSAGE_SET_CALL_WAITING:
+                    handleSetCallWaitingResponse(msg);
+                    break;
+            }
+        }
+
+        private void handleGetCallWaitingResponse(Message msg) {
+            AsyncResult ar = (AsyncResult) msg.obj;
+
+            if (mTcpListener != null) {
+                if (msg.arg2 == MESSAGE_SET_CALL_WAITING) {
+                    mTcpListener.onFinished(CallWaitingCheckBoxPreference.this, false);
+                } else {
+                    mTcpListener.onFinished(CallWaitingCheckBoxPreference.this, true);
+                }
+            }
+
+            if (ar.exception != null) {
+                if (DBG) {
+                    Log.d(LOG_TAG, "handleGetCallWaitingResponse: ar.exception=" + ar.exception);
+                }
+                if (mTcpListener != null) {
+                    mTcpListener.onException(CallWaitingCheckBoxPreference.this,
+                            (CommandException)ar.exception);
+                }
+            } else if (ar.userObj instanceof Throwable) {
+                if (mTcpListener != null) {
+                    mTcpListener.onError(CallWaitingCheckBoxPreference.this, RESPONSE_ERROR);
+                }
+            } else {
+                if (DBG) {
+                    Log.d(LOG_TAG, "handleGetCallWaitingResponse: CW state successfully queried.");
+                }
+                int[] cwArray = (int[])ar.result;
+                // If cwArray[0] is = 1, then cwArray[1] must follow,
+                // with the TS 27.007 service class bit vector of services
+                // for which call waiting is enabled.
+                try {
+                    setChecked(((cwArray[0] == 1) && ((cwArray[1] & 0x01) == 0x01)));
+                } catch (ArrayIndexOutOfBoundsException e) {
+                    Log.e(LOG_TAG, "handleGetCallWaitingResponse: improper result: err ="
+                            + e.getMessage());
+                }
+            }
+        }
+
+        private void handleSetCallWaitingResponse(Message msg) {
+            AsyncResult ar = (AsyncResult) msg.obj;
+
+            if (ar.exception != null) {
+                if (DBG) {
+                    Log.d(LOG_TAG, "handleSetCallWaitingResponse: ar.exception=" + ar.exception);
+                }
+                //setEnabled(false);
+            }
+            if (DBG) Log.d(LOG_TAG, "handleSetCallWaitingResponse: re get");
+
+            mPhone.getCallWaiting(obtainMessage(MESSAGE_GET_CALL_WAITING,
+                    MESSAGE_SET_CALL_WAITING, MESSAGE_SET_CALL_WAITING, ar.exception));
+        }
+    }
+}
diff --git a/src/com/android/phone/CallerInfoCache.java b/src/com/android/phone/CallerInfoCache.java
new file mode 100644
index 0000000..76f79af
--- /dev/null
+++ b/src/com/android/phone/CallerInfoCache.java
@@ -0,0 +1,337 @@
+/*
+ * 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.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.os.AsyncTask;
+import android.os.PowerManager;
+import android.os.SystemClock;
+import android.os.SystemProperties;
+import android.provider.ContactsContract.CommonDataKinds.Callable;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.Data;
+import android.telephony.PhoneNumberUtils;
+import android.util.Log;
+
+import java.util.HashMap;
+import java.util.Map.Entry;
+
+/**
+ * Holds "custom ringtone" and "send to voicemail" information for each contact as a fallback of
+ * contacts database. The cached information is refreshed periodically and used when database
+ * lookup (via ContentResolver) takes longer time than expected.
+ *
+ * The data inside this class shouldn't be treated as "primary"; they may not reflect the
+ * latest information stored in the original database.
+ */
+public class CallerInfoCache {
+    private static final String LOG_TAG = CallerInfoCache.class.getSimpleName();
+    private static final boolean DBG =
+            (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
+
+    /** This must not be set to true when submitting changes. */
+    private static final boolean VDBG = false;
+
+    /**
+     * Interval used with {@link AlarmManager#setInexactRepeating(int, long, long, PendingIntent)},
+     * which means the actually interval may not be very accurate.
+     */
+    private static final int CACHE_REFRESH_INTERVAL = 8 * 60 * 60 * 1000; // 8 hours in millis.
+
+    public static final int MESSAGE_UPDATE_CACHE = 0;
+
+    // Assuming DATA.DATA1 corresponds to Phone.NUMBER and SipAddress.ADDRESS, we just use
+    // Data columns as much as we can. One exception: because normalized numbers won't be used in
+    // SIP cases, Phone.NORMALIZED_NUMBER is used as is instead of using Data.
+    private static final String[] PROJECTION = new String[] {
+        Data.DATA1,                  // 0
+        Phone.NORMALIZED_NUMBER,     // 1
+        Data.CUSTOM_RINGTONE,        // 2
+        Data.SEND_TO_VOICEMAIL       // 3
+    };
+
+    private static final int INDEX_NUMBER            = 0;
+    private static final int INDEX_NORMALIZED_NUMBER = 1;
+    private static final int INDEX_CUSTOM_RINGTONE   = 2;
+    private static final int INDEX_SEND_TO_VOICEMAIL = 3;
+
+    private static final String SELECTION = "("
+            + "(" + Data.CUSTOM_RINGTONE + " IS NOT NULL OR " + Data.SEND_TO_VOICEMAIL + "=1)"
+            + " AND " + Data.DATA1 + " IS NOT NULL)";
+
+    public static class CacheEntry {
+        public final String customRingtone;
+        public final boolean sendToVoicemail;
+        public CacheEntry(String customRingtone, boolean shouldSendToVoicemail) {
+            this.customRingtone = customRingtone;
+            this.sendToVoicemail = shouldSendToVoicemail;
+        }
+
+        @Override
+        public String toString() {
+            return "ringtone: " + customRingtone + ", " + sendToVoicemail;
+        }
+    }
+
+    private class CacheAsyncTask extends AsyncTask<Void, Void, Void> {
+
+        private PowerManager.WakeLock mWakeLock;
+
+        /**
+         * Call {@link PowerManager.WakeLock#acquire} and call {@link AsyncTask#execute(Object...)},
+         * guaranteeing the lock is held during the asynchronous task.
+         */
+        public void acquireWakeLockAndExecute() {
+            // Prepare a separate partial WakeLock than what PhoneApp has so to avoid
+            // unnecessary conflict.
+            PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+            mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG);
+            mWakeLock.acquire();
+            execute();
+        }
+
+        @Override
+        protected Void doInBackground(Void... params) {
+            if (DBG) log("Start refreshing cache.");
+            refreshCacheEntry();
+            return null;
+        }
+
+        @Override
+        protected void onPostExecute(Void result) {
+            if (VDBG) log("CacheAsyncTask#onPostExecute()");
+            super.onPostExecute(result);
+            releaseWakeLock();
+        }
+
+        @Override
+        protected void onCancelled(Void result) {
+            if (VDBG) log("CacheAsyncTask#onCanceled()");
+            super.onCancelled(result);
+            releaseWakeLock();
+        }
+
+        private void releaseWakeLock() {
+            if (mWakeLock != null && mWakeLock.isHeld()) {
+                mWakeLock.release();
+            }
+        }
+    }
+
+    private final Context mContext;
+
+    /**
+     * The mapping from number to CacheEntry.
+     *
+     * The number will be:
+     * - last 7 digits of each "normalized phone number when it is for PSTN phone call, or
+     * - a full SIP address for SIP call
+     *
+     * When cache is being refreshed, this whole object will be replaced with a newer object,
+     * instead of updating elements inside the object.  "volatile" is used to make
+     * {@link #getCacheEntry(String)} access to the newer one every time when the object is
+     * being replaced.
+     */
+    private volatile HashMap<String, CacheEntry> mNumberToEntry;
+
+    /**
+     * Used to remember if the previous task is finished or not. Should be set to null when done.
+     */
+    private CacheAsyncTask mCacheAsyncTask;
+
+    public static CallerInfoCache init(Context context) {
+        if (DBG) log("init()");
+        CallerInfoCache cache = new CallerInfoCache(context);
+        // The first cache should be available ASAP.
+        cache.startAsyncCache();
+        cache.setRepeatingCacheUpdateAlarm();
+        return cache;
+    }
+
+    private CallerInfoCache(Context context) {
+        mContext = context;
+        mNumberToEntry = new HashMap<String, CacheEntry>();
+    }
+
+    /* package */ void startAsyncCache() {
+        if (DBG) log("startAsyncCache");
+
+        if (mCacheAsyncTask != null) {
+            Log.w(LOG_TAG, "Previous cache task is remaining.");
+            mCacheAsyncTask.cancel(true);
+        }
+        mCacheAsyncTask = new CacheAsyncTask();
+        mCacheAsyncTask.acquireWakeLockAndExecute();
+    }
+
+    /**
+     * Set up periodic alarm for cache update.
+     */
+    private void setRepeatingCacheUpdateAlarm() {
+        if (DBG) log("setRepeatingCacheUpdateAlarm");
+
+        Intent intent = new Intent(CallerInfoCacheUpdateReceiver.ACTION_UPDATE_CALLER_INFO_CACHE);
+        intent.setClass(mContext, CallerInfoCacheUpdateReceiver.class);
+        PendingIntent pendingIntent =
+                PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
+        AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
+        // We don't need precise timer while this should be power efficient.
+        alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME,
+                SystemClock.uptimeMillis() + CACHE_REFRESH_INTERVAL,
+                CACHE_REFRESH_INTERVAL, pendingIntent);
+    }
+
+    private void refreshCacheEntry() {
+        if (VDBG) log("refreshCacheEntry() started");
+
+        // There's no way to know which part of the database was updated. Also we don't want
+        // to block incoming calls asking for the cache. So this method just does full query
+        // and replaces the older cache with newer one. To refrain from blocking incoming calls,
+        // it keeps older one as much as it can, and replaces it with newer one inside a very small
+        // synchronized block.
+
+        Cursor cursor = null;
+        try {
+            cursor = mContext.getContentResolver().query(Callable.CONTENT_URI,
+                    PROJECTION, SELECTION, null, null);
+            if (cursor != null) {
+                // We don't want to block real in-coming call, so prepare a completely fresh
+                // cache here again, and replace it with older one.
+                final HashMap<String, CacheEntry> newNumberToEntry =
+                        new HashMap<String, CacheEntry>(cursor.getCount());
+
+                while (cursor.moveToNext()) {
+                    final String number = cursor.getString(INDEX_NUMBER);
+                    String normalizedNumber = cursor.getString(INDEX_NORMALIZED_NUMBER);
+                    if (normalizedNumber == null) {
+                        // There's no guarantee normalized numbers are available every time and
+                        // it may become null sometimes. Try formatting the original number.
+                        normalizedNumber = PhoneNumberUtils.normalizeNumber(number);
+                    }
+                    final String customRingtone = cursor.getString(INDEX_CUSTOM_RINGTONE);
+                    final boolean sendToVoicemail = cursor.getInt(INDEX_SEND_TO_VOICEMAIL) == 1;
+
+                    if (PhoneNumberUtils.isUriNumber(number)) {
+                        // SIP address case
+                        putNewEntryWhenAppropriate(
+                                newNumberToEntry, number, customRingtone, sendToVoicemail);
+                    } else {
+                        // PSTN number case
+                        // Each normalized number may or may not have full content of the number.
+                        // Contacts database may contain +15001234567 while a dialed number may be
+                        // just 5001234567. Also we may have inappropriate country
+                        // code in some cases (e.g. when the location of the device is inconsistent
+                        // with the device's place). So to avoid confusion we just rely on the last
+                        // 7 digits here. It may cause some kind of wrong behavior, which is
+                        // unavoidable anyway in very rare cases..
+                        final int length = normalizedNumber.length();
+                        final String key = length > 7
+                                ? normalizedNumber.substring(length - 7, length)
+                                        : normalizedNumber;
+                        putNewEntryWhenAppropriate(
+                                newNumberToEntry, key, customRingtone, sendToVoicemail);
+                    }
+                }
+
+                if (VDBG) {
+                    Log.d(LOG_TAG, "New cache size: " + newNumberToEntry.size());
+                    for (Entry<String, CacheEntry> entry : newNumberToEntry.entrySet()) {
+                        Log.d(LOG_TAG, "Number: " + entry.getKey() + " -> " + entry.getValue());
+                    }
+                }
+
+                mNumberToEntry = newNumberToEntry;
+
+                if (DBG) {
+                    log("Caching entries are done. Total: " + newNumberToEntry.size());
+                }
+            } else {
+                // Let's just wait for the next refresh..
+                //
+                // If the cursor became null at that exact moment, probably we don't want to
+                // drop old cache. Also the case is fairly rare in usual cases unless acore being
+                // killed, so we don't take care much of this case.
+                Log.w(LOG_TAG, "cursor is null");
+            }
+        } finally {
+            if (cursor != null) {
+                cursor.close();
+            }
+        }
+
+        if (VDBG) log("refreshCacheEntry() ended");
+    }
+
+    private void putNewEntryWhenAppropriate(HashMap<String, CacheEntry> newNumberToEntry,
+            String numberOrSipAddress, String customRingtone, boolean sendToVoicemail) {
+        if (newNumberToEntry.containsKey(numberOrSipAddress)) {
+            // There may be duplicate entries here and we should prioritize
+            // "send-to-voicemail" flag in any case.
+            final CacheEntry entry = newNumberToEntry.get(numberOrSipAddress);
+            if (!entry.sendToVoicemail && sendToVoicemail) {
+                newNumberToEntry.put(numberOrSipAddress,
+                        new CacheEntry(customRingtone, sendToVoicemail));
+            }
+        } else {
+            newNumberToEntry.put(numberOrSipAddress,
+                    new CacheEntry(customRingtone, sendToVoicemail));
+        }
+    }
+
+    /**
+     * Returns CacheEntry for the given number (PSTN number or SIP address).
+     *
+     * @param number OK to be unformatted.
+     * @return CacheEntry to be used. Maybe null if there's no cache here. Note that this may
+     * return null when the cache itself is not ready. BE CAREFUL. (or might be better to throw
+     * an exception)
+     */
+    public CacheEntry getCacheEntry(String number) {
+        if (mNumberToEntry == null) {
+            // Very unusual state. This implies the cache isn't ready during the request, while
+            // it should be prepared on the boot time (i.e. a way before even the first request).
+            Log.w(LOG_TAG, "Fallback cache isn't ready.");
+            return null;
+        }
+
+        CacheEntry entry;
+        if (PhoneNumberUtils.isUriNumber(number)) {
+            if (VDBG) log("Trying to lookup " + number);
+
+            entry = mNumberToEntry.get(number);
+        } else {
+            final String normalizedNumber = PhoneNumberUtils.normalizeNumber(number);
+            final int length = normalizedNumber.length();
+            final String key =
+                    (length > 7 ? normalizedNumber.substring(length - 7, length)
+                            : normalizedNumber);
+            if (VDBG) log("Trying to lookup " + key);
+
+            entry = mNumberToEntry.get(key);
+        }
+        if (VDBG) log("Obtained " + entry);
+        return entry;
+    }
+
+    private static void log(String msg) {
+        Log.d(LOG_TAG, msg);
+    }
+}
diff --git a/src/com/android/phone/CallerInfoCacheUpdateReceiver.java b/src/com/android/phone/CallerInfoCacheUpdateReceiver.java
new file mode 100644
index 0000000..c0a2d83
--- /dev/null
+++ b/src/com/android/phone/CallerInfoCacheUpdateReceiver.java
@@ -0,0 +1,48 @@
+/*
+ * 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.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.SystemProperties;
+import android.util.Log;
+
+/**
+ * BroadcastReceiver responsible for (periodic) update of {@link CallerInfoCache}.
+ *
+ * This broadcast can be sent from Contacts edit screen, implying relevant settings have changed
+ * and the cache may become obsolete.
+ */
+public class CallerInfoCacheUpdateReceiver extends BroadcastReceiver {
+    private static final String LOG_TAG = CallerInfoCacheUpdateReceiver.class.getSimpleName();
+    private static final boolean DBG =
+            (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
+
+    public static final String ACTION_UPDATE_CALLER_INFO_CACHE =
+            "com.android.phone.UPDATE_CALLER_INFO_CACHE";
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        if (DBG) log("CallerInfoCacheUpdateReceiver#onReceive(). Intent: " + intent);
+        PhoneGlobals.getInstance().callerInfoCache.startAsyncCache();
+    }
+
+    private static void log(String msg) {
+        Log.d(LOG_TAG, msg);
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/phone/CarrierLogo.java b/src/com/android/phone/CarrierLogo.java
new file mode 100644
index 0000000..5ee81b8
--- /dev/null
+++ b/src/com/android/phone/CarrierLogo.java
@@ -0,0 +1,55 @@
+/*
+ * 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 java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Utility class to look up carrier logo resource IDs.
+ */
+public class CarrierLogo {
+    /** This class is never instantiated. */
+    private CarrierLogo() {
+    }
+
+    private static Map<String, Integer> sLogoMap = null;
+
+    private static Map<String, Integer> getLogoMap() {
+        if (sLogoMap == null) {
+            sLogoMap = new HashMap<String, Integer>();
+
+            // TODO: Load up sLogoMap with known carriers, like:
+            // sLogoMap.put("CarrierName",
+            //    Integer.valueOf(R.drawable.mobile_logo_carriername));
+
+            // TODO: ideally, read the mapping from a config file
+            // rather than manually creating it here.
+        }
+
+        return sLogoMap;
+    }
+
+    public static int getLogo(String name) {
+        Integer res = getLogoMap().get(name);
+        if (res != null) {
+            return res.intValue();
+        }
+
+        return -1;
+    }
+}
diff --git a/src/com/android/phone/CdmaCallOptions.java b/src/com/android/phone/CdmaCallOptions.java
new file mode 100644
index 0000000..8eecd27
--- /dev/null
+++ b/src/com/android/phone/CdmaCallOptions.java
@@ -0,0 +1,62 @@
+/*
+ * 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 com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
+
+import android.content.DialogInterface;
+import android.os.AsyncResult;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.preference.CheckBoxPreference;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceScreen;
+import android.util.Log;
+
+public class CdmaCallOptions extends PreferenceActivity {
+    private static final String LOG_TAG = "CdmaCallOptions";
+    private final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
+
+    private static final String BUTTON_VP_KEY = "button_voice_privacy_key";
+    private CheckBoxPreference mButtonVoicePrivacy;
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        addPreferencesFromResource(R.xml.cdma_call_privacy);
+
+        mButtonVoicePrivacy = (CheckBoxPreference) findPreference(BUTTON_VP_KEY);
+        if (PhoneGlobals.getPhone().getPhoneType() != PhoneConstants.PHONE_TYPE_CDMA
+                || getResources().getBoolean(R.bool.config_voice_privacy_disable)) {
+            //disable the entire screen
+            getPreferenceScreen().setEnabled(false);
+        }
+    }
+
+    @Override
+    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
+        if (preference.getKey().equals(BUTTON_VP_KEY)) {
+            return true;
+        }
+        return false;
+    }
+
+}
diff --git a/src/com/android/phone/CdmaDisplayInfo.java b/src/com/android/phone/CdmaDisplayInfo.java
new file mode 100644
index 0000000..1a88333
--- /dev/null
+++ b/src/com/android/phone/CdmaDisplayInfo.java
@@ -0,0 +1,86 @@
+/*
+ * 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.app.AlertDialog;
+import android.content.Context;
+import android.os.SystemProperties;
+import android.util.Log;
+import android.view.WindowManager;
+
+/**
+ * Helper class for displaying the DisplayInfo sent by CDMA network.
+ */
+public class CdmaDisplayInfo {
+    private static final String LOG_TAG = "CdmaDisplayInfo";
+    private static final boolean DBG = (SystemProperties.getInt("ro.debuggable", 0) == 1);
+
+    /** CDMA DisplayInfo dialog */
+    private static AlertDialog sDisplayInfoDialog = null;
+
+    /**
+     * Handle the DisplayInfo record and display the alert dialog with
+     * the network message.
+     *
+     * @param context context to get strings.
+     * @param infoMsg Text message from Network.
+     */
+    public static void displayInfoRecord(Context context, String infoMsg) {
+
+        if (DBG) log("displayInfoRecord: infoMsg=" + infoMsg);
+
+        if (sDisplayInfoDialog != null) {
+            sDisplayInfoDialog.dismiss();
+        }
+
+        // displaying system alert dialog on the screen instead of
+        // using another activity to display the message.  This
+        // places the message at the forefront of the UI.
+        sDisplayInfoDialog = new AlertDialog.Builder(context)
+                .setIcon(android.R.drawable.ic_dialog_info)
+                .setTitle(context.getText(R.string.network_message))
+                .setMessage(infoMsg)
+                .setCancelable(true)
+                .create();
+
+        sDisplayInfoDialog.getWindow().setType(
+                WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
+        sDisplayInfoDialog.getWindow().addFlags(
+                WindowManager.LayoutParams.FLAG_DIM_BEHIND);
+
+        sDisplayInfoDialog.show();
+        PhoneGlobals.getInstance().wakeUpScreen();
+
+    }
+
+    /**
+     * Dismiss the DisplayInfo record
+     */
+    public static void dismissDisplayInfoRecord() {
+
+        if (DBG) log("Dissmissing Display Info Record...");
+
+        if (sDisplayInfoDialog != null) {
+            sDisplayInfoDialog.dismiss();
+            sDisplayInfoDialog = null;
+        }
+    }
+
+    private static void log(String msg) {
+        Log.d(LOG_TAG, "[CdmaDisplayInfo] " + msg);
+    }
+}
diff --git a/src/com/android/phone/CdmaOptions.java b/src/com/android/phone/CdmaOptions.java
new file mode 100644
index 0000000..3e3c8b5
--- /dev/null
+++ b/src/com/android/phone/CdmaOptions.java
@@ -0,0 +1,137 @@
+/*
+ * 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.content.Intent;
+import android.net.Uri;
+import android.os.SystemProperties;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceScreen;
+import android.provider.Settings;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.TelephonyProperties;
+
+/**
+ * List of Phone-specific settings screens.
+ */
+public class CdmaOptions {
+    private static final String LOG_TAG = "CdmaOptions";
+
+    private CdmaSystemSelectListPreference mButtonCdmaSystemSelect;
+    private CdmaSubscriptionListPreference mButtonCdmaSubscription;
+
+    private static final String BUTTON_CDMA_SYSTEM_SELECT_KEY = "cdma_system_select_key";
+    private static final String BUTTON_CDMA_SUBSCRIPTION_KEY = "cdma_subscription_key";
+    private static final String BUTTON_CDMA_ACTIVATE_DEVICE_KEY = "cdma_activate_device_key";
+
+    private PreferenceActivity mPrefActivity;
+    private PreferenceScreen mPrefScreen;
+    private Phone mPhone;
+
+    public CdmaOptions(PreferenceActivity prefActivity, PreferenceScreen prefScreen, Phone phone) {
+        mPrefActivity = prefActivity;
+        mPrefScreen = prefScreen;
+        mPhone = phone;
+        create();
+    }
+
+    protected void create() {
+        mPrefActivity.addPreferencesFromResource(R.xml.cdma_options);
+
+        mButtonCdmaSystemSelect = (CdmaSystemSelectListPreference)mPrefScreen
+                .findPreference(BUTTON_CDMA_SYSTEM_SELECT_KEY);
+
+        mButtonCdmaSubscription = (CdmaSubscriptionListPreference)mPrefScreen
+                .findPreference(BUTTON_CDMA_SUBSCRIPTION_KEY);
+
+        mButtonCdmaSystemSelect.setEnabled(true);
+        if(deviceSupportsNvAndRuim()) {
+            log("Both NV and Ruim supported, ENABLE subscription type selection");
+            mButtonCdmaSubscription.setEnabled(true);
+        } else {
+            log("Both NV and Ruim NOT supported, REMOVE subscription type selection");
+            mPrefScreen.removePreference(mPrefScreen
+                                .findPreference(BUTTON_CDMA_SUBSCRIPTION_KEY));
+        }
+
+        final boolean voiceCapable = mPrefActivity.getResources().getBoolean(
+                com.android.internal.R.bool.config_voice_capable);
+        final boolean isLTE = mPhone.getLteOnCdmaMode() == PhoneConstants.LTE_ON_CDMA_TRUE;
+        if (voiceCapable || isLTE) {
+            // This option should not be available on voice-capable devices (i.e. regular phones)
+            // and is replaced by the LTE data service item on LTE devices
+            mPrefScreen.removePreference(
+                    mPrefScreen.findPreference(BUTTON_CDMA_ACTIVATE_DEVICE_KEY));
+        }
+    }
+
+    private boolean deviceSupportsNvAndRuim() {
+        // retrieve the list of subscription types supported by device.
+        String subscriptionsSupported = SystemProperties.get("ril.subscription.types");
+        boolean nvSupported = false;
+        boolean ruimSupported = false;
+
+        log("deviceSupportsnvAnRum: prop=" + subscriptionsSupported);
+        if (!TextUtils.isEmpty(subscriptionsSupported)) {
+            // Searches through the comma-separated list for a match for "NV"
+            // and "RUIM" to update nvSupported and ruimSupported.
+            for (String subscriptionType : subscriptionsSupported.split(",")) {
+                subscriptionType = subscriptionType.trim();
+                if (subscriptionType.equalsIgnoreCase("NV")) {
+                    nvSupported = true;
+                }
+                if (subscriptionType.equalsIgnoreCase("RUIM")) {
+                    ruimSupported = true;
+                }
+            }
+        }
+
+        log("deviceSupportsnvAnRum: nvSupported=" + nvSupported +
+                " ruimSupported=" + ruimSupported);
+        return (nvSupported && ruimSupported);
+    }
+
+    public boolean preferenceTreeClick(Preference preference) {
+        if (preference.getKey().equals(BUTTON_CDMA_SYSTEM_SELECT_KEY)) {
+            log("preferenceTreeClick: return BUTTON_CDMA_ROAMING_KEY true");
+            return true;
+        }
+        if (preference.getKey().equals(BUTTON_CDMA_SUBSCRIPTION_KEY)) {
+            log("preferenceTreeClick: return CDMA_SUBSCRIPTION_KEY true");
+            return true;
+        }
+        return false;
+    }
+
+    public void showDialog(Preference preference) {
+        if (preference.getKey().equals(BUTTON_CDMA_SYSTEM_SELECT_KEY)) {
+            mButtonCdmaSystemSelect.showDialog(null);
+        } else if (preference.getKey().equals(BUTTON_CDMA_SUBSCRIPTION_KEY)) {
+            mButtonCdmaSubscription.showDialog(null);
+        }
+    }
+
+    protected void log(String s) {
+        android.util.Log.d(LOG_TAG, s);
+    }
+}
diff --git a/src/com/android/phone/CdmaPhoneCallState.java b/src/com/android/phone/CdmaPhoneCallState.java
new file mode 100644
index 0000000..30ab209
--- /dev/null
+++ b/src/com/android/phone/CdmaPhoneCallState.java
@@ -0,0 +1,155 @@
+/*
+ * 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;
+
+/**
+ * Class to internally keep track of Call states to maintain
+ * information for Call Waiting and 3Way for CDMA instance of Phone App.
+ *
+ * Explanation for PhoneApp's Call states and why it is required:
+ * IDLE - When no call is going on. This is just required as default state to reset the PhoneApp
+ *        call state to when the complete call gets disconnected
+ * SINGLE_ACTIVE - When only single call is active.
+ *        In normal case(on a single call) this state would be similar for FW's state of ACTIVE
+ *        call or phone state of OFFHOOK, but in more complex conditions e.g. when phone is already
+ *        in a CONF_CALL state and user rejects a CW, which basically tells the PhoneApp that the
+ *        Call is back to a single call, the FW's state still would remain ACTIVE or OFFHOOK and
+ *        isGeneric would still be true. At this condition PhoneApp does need to enable the
+ *        "Add Call" menu item and disable the "Swap" and "Merge" options
+ * THRWAY_ACTIVE - When user initiate an outgoing call when already on a call.
+ *        fgCall can have more than one connections from various scenarios (accepting the CW or
+ *        making a 3way call) but once we are in this state and one of the parties drops off,
+ *        when the user originates another call we need to remember this state to update the menu
+ *        items accordingly. FW currently does not differentiate this condition hence PhoneApp
+ *        needs to maintain it.
+ * CONF_CALL - When the user merges two calls or on accepting the Call waiting call.
+ *        This is required cause even though a call might be generic but that does not mean it is
+ *        in conference. We can take the same example mention in the SINGLE_ACTIVE state.
+ *
+ * TODO: Eventually this state information should be maintained by Telephony FW.
+ */
+   public class CdmaPhoneCallState {
+
+        /**
+         * Allowable values for the PhoneCallState.
+         *   IDLE - When no call is going on.
+         *   SINGLE_ACTIVE - When only single call is active
+         *   THRWAY_ACTIVE - When user initiate an outgoing call when already on a call
+         *   CONF_CALL - When the user merges two calls or on accepting the Call waiting call
+         */
+        public enum PhoneCallState {
+            IDLE,
+            SINGLE_ACTIVE,
+            THRWAY_ACTIVE,
+            CONF_CALL
+        }
+
+        // For storing current and previous PhoneCallState's
+        private PhoneCallState mPreviousCallState;
+        private PhoneCallState mCurrentCallState;
+
+        // Boolean to track 3Way display state
+        private boolean mThreeWayCallOrigStateDialing;
+
+        // Flag to indicate if the "Add Call" menu item in an InCallScreen is OK
+        // to be displayed after a Call Waiting call was ignored or timed out
+        private boolean mAddCallMenuStateAfterCW;
+
+        /**
+         * Initialize PhoneCallState related members - constructor
+         */
+        public void CdmaPhoneCallStateInit() {
+            mCurrentCallState = PhoneCallState.IDLE;
+            mPreviousCallState = PhoneCallState.IDLE;
+            mThreeWayCallOrigStateDialing = false;
+            mAddCallMenuStateAfterCW = true;
+        }
+
+        /**
+         * Returns the current call state
+         */
+        public PhoneCallState getCurrentCallState() {
+            return mCurrentCallState;
+        }
+
+        /**
+         * Set current and previous PhoneCallState's
+         */
+        public void setCurrentCallState(PhoneCallState newState) {
+            mPreviousCallState = mCurrentCallState;
+            mCurrentCallState = newState;
+
+            //Reset the 3Way display boolean
+            mThreeWayCallOrigStateDialing = false;
+
+            //Set mAddCallMenuStateAfterCW to true
+            //if the current state is being set to SINGLE_ACTIVE
+            //and previous state was IDLE as we could reach the SINGLE_ACTIVE
+            //from CW ignore too. For all other cases let the timer or
+            //specific calls to setAddCallMenuStateAfterCallWaiting set
+            //mAddCallMenuStateAfterCW.
+            if ((mCurrentCallState == PhoneCallState.SINGLE_ACTIVE)
+                && (mPreviousCallState == PhoneCallState.IDLE)) {
+                mAddCallMenuStateAfterCW = true;
+            }
+        }
+
+        /**
+         * Return 3Way display information
+         */
+        public boolean IsThreeWayCallOrigStateDialing() {
+            return mThreeWayCallOrigStateDialing;
+        }
+
+        /**
+         * Set 3Way display information
+         */
+        public void setThreeWayCallOrigState(boolean newState) {
+            mThreeWayCallOrigStateDialing = newState;
+        }
+
+        /**
+         * Return information for enabling/disabling "Add Call" menu item
+         */
+        public boolean getAddCallMenuStateAfterCallWaiting() {
+            return mAddCallMenuStateAfterCW;
+        }
+
+        /**
+         * Set mAddCallMenuStateAfterCW to enabling/disabling "Add Call" menu item
+         */
+        public void setAddCallMenuStateAfterCallWaiting(boolean newState) {
+            mAddCallMenuStateAfterCW = newState;
+        }
+
+        /**
+         * Return previous PhoneCallState's
+         */
+        public PhoneCallState getPreviousCallState() {
+            return mPreviousCallState;
+        }
+
+        /**
+         * Reset all PhoneCallState
+         */
+        public void resetCdmaPhoneCallState() {
+            mCurrentCallState = PhoneCallState.IDLE;
+            mPreviousCallState = PhoneCallState.IDLE;
+            mThreeWayCallOrigStateDialing = false;
+            mAddCallMenuStateAfterCW = true;
+        }
+   }
diff --git a/src/com/android/phone/CdmaSubscriptionListPreference.java b/src/com/android/phone/CdmaSubscriptionListPreference.java
new file mode 100644
index 0000000..9b96850
--- /dev/null
+++ b/src/com/android/phone/CdmaSubscriptionListPreference.java
@@ -0,0 +1,132 @@
+/*
+ * 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.content.Context;
+import android.os.AsyncResult;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.preference.ListPreference;
+import android.provider.Settings;
+import android.provider.Settings.Secure;
+import android.util.AttributeSet;
+import android.util.Log;
+
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
+
+public class CdmaSubscriptionListPreference extends ListPreference {
+
+    private static final String LOG_TAG = "CdmaSubscriptionListPreference";
+
+    // Used for CDMA subscription mode
+    private static final int CDMA_SUBSCRIPTION_RUIM_SIM = 0;
+    private static final int CDMA_SUBSCRIPTION_NV = 1;
+
+    //preferredSubscriptionMode  0 - RUIM/SIM, preferred
+    //                           1 - NV
+    static final int preferredSubscriptionMode = CDMA_SUBSCRIPTION_NV;
+
+    private Phone mPhone;
+    private CdmaSubscriptionButtonHandler mHandler;
+
+    public CdmaSubscriptionListPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        mPhone = PhoneFactory.getDefaultPhone();
+        mHandler = new CdmaSubscriptionButtonHandler();
+        setCurrentCdmaSubscriptionModeValue();
+    }
+
+    private void setCurrentCdmaSubscriptionModeValue() {
+        int cdmaSubscriptionMode = Settings.Global.getInt(mPhone.getContext().getContentResolver(),
+                Settings.Global.CDMA_SUBSCRIPTION_MODE, preferredSubscriptionMode);
+        setValue(Integer.toString(cdmaSubscriptionMode));
+    }
+
+    public CdmaSubscriptionListPreference(Context context) {
+        this(context, null);
+    }
+
+    @Override
+    protected void showDialog(Bundle state) {
+        setCurrentCdmaSubscriptionModeValue();
+
+        super.showDialog(state);
+    }
+
+    @Override
+    protected void onDialogClosed(boolean positiveResult) {
+        super.onDialogClosed(positiveResult);
+
+        if (!positiveResult) {
+            //The button was dismissed - no need to set new value
+            return;
+        }
+
+        int buttonCdmaSubscriptionMode = Integer.valueOf(getValue()).intValue();
+        Log.d(LOG_TAG, "Setting new value " + buttonCdmaSubscriptionMode);
+        int statusCdmaSubscriptionMode;
+        switch(buttonCdmaSubscriptionMode) {
+            case CDMA_SUBSCRIPTION_NV:
+                statusCdmaSubscriptionMode = Phone.CDMA_SUBSCRIPTION_NV;
+                break;
+            case CDMA_SUBSCRIPTION_RUIM_SIM:
+                statusCdmaSubscriptionMode = Phone.CDMA_SUBSCRIPTION_RUIM_SIM;
+                break;
+            default:
+                statusCdmaSubscriptionMode = Phone.PREFERRED_CDMA_SUBSCRIPTION;
+        }
+
+        // Set the CDMA subscription mode, when mode has been successfully changed
+        // handleSetCdmaSubscriptionMode will be invoked and the value saved.
+        mPhone.setCdmaSubscription(statusCdmaSubscriptionMode, mHandler
+                .obtainMessage(CdmaSubscriptionButtonHandler.MESSAGE_SET_CDMA_SUBSCRIPTION,
+                        getValue()));
+
+    }
+
+    private class CdmaSubscriptionButtonHandler extends Handler {
+
+        static final int MESSAGE_SET_CDMA_SUBSCRIPTION = 0;
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MESSAGE_SET_CDMA_SUBSCRIPTION:
+                    handleSetCdmaSubscriptionMode(msg);
+                    break;
+            }
+        }
+
+        private void handleSetCdmaSubscriptionMode(Message msg) {
+            mPhone = PhoneFactory.getDefaultPhone();
+            AsyncResult ar = (AsyncResult) msg.obj;
+
+            if (ar.exception == null) {
+                // Get the original string entered by the user
+                int cdmaSubscriptionMode = Integer.valueOf((String) ar.userObj).intValue();
+                Settings.Global.putInt(mPhone.getContext().getContentResolver(),
+                        Settings.Global.CDMA_SUBSCRIPTION_MODE,
+                        cdmaSubscriptionMode );
+            } else {
+                Log.e(LOG_TAG, "Setting Cdma subscription source failed");
+            }
+        }
+    }
+}
diff --git a/src/com/android/phone/CdmaSystemSelectListPreference.java b/src/com/android/phone/CdmaSystemSelectListPreference.java
new file mode 100644
index 0000000..d291fd7
--- /dev/null
+++ b/src/com/android/phone/CdmaSystemSelectListPreference.java
@@ -0,0 +1,172 @@
+/*
+ * 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.content.Context;
+import android.os.AsyncResult;
+import android.os.Bundle;
+import android.os.SystemProperties;
+import android.os.Handler;
+import android.os.Message;
+import android.preference.ListPreference;
+import android.provider.Settings;
+import android.provider.Settings.Secure;
+import android.util.AttributeSet;
+import android.util.Log;
+
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.TelephonyProperties;
+
+public class CdmaSystemSelectListPreference extends ListPreference {
+
+    private static final String LOG_TAG = "CdmaRoamingListPreference";
+    private static final boolean DBG = false;
+
+    private Phone mPhone;
+    private MyHandler mHandler = new MyHandler();
+
+    public CdmaSystemSelectListPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        mPhone = PhoneGlobals.getPhone();
+        mHandler = new MyHandler();
+        mPhone.queryCdmaRoamingPreference(
+                mHandler.obtainMessage(MyHandler.MESSAGE_GET_ROAMING_PREFERENCE));
+    }
+
+    public CdmaSystemSelectListPreference(Context context) {
+        this(context, null);
+    }
+
+    @Override
+    protected void showDialog(Bundle state) {
+        if (Boolean.parseBoolean(
+                    SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE))) {
+            // In ECM mode do not show selection options
+        } else {
+            super.showDialog(state);
+        }
+    }
+
+    @Override
+    protected void onDialogClosed(boolean positiveResult) {
+        super.onDialogClosed(positiveResult);
+
+        if (positiveResult && (getValue() != null)) {
+            int buttonCdmaRoamingMode = Integer.valueOf(getValue()).intValue();
+            int settingsCdmaRoamingMode =
+                    Settings.Global.getInt(mPhone.getContext().getContentResolver(),
+                    Settings.Global.CDMA_ROAMING_MODE, Phone.CDMA_RM_HOME);
+            if (buttonCdmaRoamingMode != settingsCdmaRoamingMode) {
+                int statusCdmaRoamingMode;
+                switch(buttonCdmaRoamingMode) {
+                    case Phone.CDMA_RM_ANY:
+                        statusCdmaRoamingMode = Phone.CDMA_RM_ANY;
+                        break;
+                    case Phone.CDMA_RM_HOME:
+                    default:
+                        statusCdmaRoamingMode = Phone.CDMA_RM_HOME;
+                }
+                //Set the Settings.Secure network mode
+                Settings.Global.putInt(mPhone.getContext().getContentResolver(),
+                        Settings.Global.CDMA_ROAMING_MODE,
+                        buttonCdmaRoamingMode );
+                //Set the roaming preference mode
+                mPhone.setCdmaRoamingPreference(statusCdmaRoamingMode, mHandler
+                        .obtainMessage(MyHandler.MESSAGE_SET_ROAMING_PREFERENCE));
+            }
+        } else {
+            Log.d(LOG_TAG, String.format("onDialogClosed: positiveResult=%b value=%s -- do nothing",
+                    positiveResult, getValue()));
+        }
+    }
+
+    private class MyHandler extends Handler {
+
+        static final int MESSAGE_GET_ROAMING_PREFERENCE = 0;
+        static final int MESSAGE_SET_ROAMING_PREFERENCE = 1;
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MESSAGE_GET_ROAMING_PREFERENCE:
+                    handleQueryCdmaRoamingPreference(msg);
+                    break;
+
+                case MESSAGE_SET_ROAMING_PREFERENCE:
+                    handleSetCdmaRoamingPreference(msg);
+                    break;
+            }
+        }
+
+        private void handleQueryCdmaRoamingPreference(Message msg) {
+            AsyncResult ar = (AsyncResult) msg.obj;
+
+            if (ar.exception == null) {
+                int statusCdmaRoamingMode = ((int[])ar.result)[0];
+                int settingsRoamingMode = Settings.Global.getInt(
+                        mPhone.getContext().getContentResolver(),
+                        Settings.Global.CDMA_ROAMING_MODE, Phone.CDMA_RM_HOME);
+                //check that statusCdmaRoamingMode is from an accepted value
+                if (statusCdmaRoamingMode == Phone.CDMA_RM_HOME ||
+                        statusCdmaRoamingMode == Phone.CDMA_RM_ANY ) {
+                    //check changes in statusCdmaRoamingMode and updates settingsRoamingMode
+                    if (statusCdmaRoamingMode != settingsRoamingMode) {
+                        settingsRoamingMode = statusCdmaRoamingMode;
+                        //changes the Settings.Secure accordingly to statusCdmaRoamingMode
+                        Settings.Global.putInt(
+                                mPhone.getContext().getContentResolver(),
+                                Settings.Global.CDMA_ROAMING_MODE,
+                                settingsRoamingMode );
+                    }
+                    //changes the mButtonPreferredNetworkMode accordingly to modemNetworkMode
+                    setValue(Integer.toString(statusCdmaRoamingMode));
+                }
+                else {
+                    if(DBG) Log.i(LOG_TAG, "reset cdma roaming mode to default" );
+                    resetCdmaRoamingModeToDefault();
+                }
+            }
+        }
+
+        private void handleSetCdmaRoamingPreference(Message msg) {
+            AsyncResult ar = (AsyncResult) msg.obj;
+
+            if ((ar.exception == null) && (getValue() != null)) {
+                int cdmaRoamingMode = Integer.valueOf(getValue()).intValue();
+                Settings.Global.putInt(mPhone.getContext().getContentResolver(),
+                        Settings.Global.CDMA_ROAMING_MODE,
+                        cdmaRoamingMode );
+            } else {
+                mPhone.queryCdmaRoamingPreference(obtainMessage(MESSAGE_GET_ROAMING_PREFERENCE));
+            }
+        }
+
+        private void resetCdmaRoamingModeToDefault() {
+            //set the mButtonCdmaRoam
+            setValue(Integer.toString(Phone.CDMA_RM_HOME));
+            //set the Settings.System
+            Settings.Global.putInt(mPhone.getContext().getContentResolver(),
+                        Settings.Global.CDMA_ROAMING_MODE,
+                        Phone.CDMA_RM_HOME );
+            //Set the Status
+            mPhone.setCdmaRoamingPreference(Phone.CDMA_RM_HOME,
+                    obtainMessage(MyHandler.MESSAGE_SET_ROAMING_PREFERENCE));
+        }
+    }
+
+}
diff --git a/src/com/android/phone/CdmaVoicePrivacyCheckBoxPreference.java b/src/com/android/phone/CdmaVoicePrivacyCheckBoxPreference.java
new file mode 100644
index 0000000..a5ff37e
--- /dev/null
+++ b/src/com/android/phone/CdmaVoicePrivacyCheckBoxPreference.java
@@ -0,0 +1,105 @@
+/*
+ * 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 com.android.internal.telephony.Phone;
+
+import android.content.Context;
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.Message;
+import android.preference.CheckBoxPreference;
+import android.util.AttributeSet;
+import android.util.Log;
+
+public class CdmaVoicePrivacyCheckBoxPreference extends CheckBoxPreference {
+    private static final String LOG_TAG = "CdmaVoicePrivacyCheckBoxPreference";
+    private final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
+
+    Phone phone;
+    private MyHandler mHandler = new MyHandler();
+
+    public CdmaVoicePrivacyCheckBoxPreference(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+
+        phone = PhoneGlobals.getPhone();
+        phone.getEnhancedVoicePrivacy(mHandler.obtainMessage(MyHandler.MESSAGE_GET_VP));
+    }
+
+    public CdmaVoicePrivacyCheckBoxPreference(Context context, AttributeSet attrs) {
+        this(context, attrs, com.android.internal.R.attr.checkBoxPreferenceStyle);
+    }
+
+    public CdmaVoicePrivacyCheckBoxPreference(Context context) {
+        this(context, null);
+    }
+
+
+    @Override
+    protected void onClick() {
+        super.onClick();
+
+        phone.enableEnhancedVoicePrivacy(isChecked(),
+                mHandler.obtainMessage(MyHandler.MESSAGE_SET_VP));
+    }
+
+
+
+    private class MyHandler extends Handler {
+        static final int MESSAGE_GET_VP = 0;
+        static final int MESSAGE_SET_VP = 1;
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MESSAGE_GET_VP:
+                    handleGetVPResponse(msg);
+                    break;
+                case MESSAGE_SET_VP:
+                    handleSetVPResponse(msg);
+                    break;
+            }
+        }
+
+        private void handleGetVPResponse(Message msg) {
+            AsyncResult ar = (AsyncResult) msg.obj;
+
+            if (ar.exception != null) {
+                if (DBG) Log.d(LOG_TAG, "handleGetVPResponse: ar.exception=" + ar.exception);
+                setEnabled(false);
+            } else {
+                if (DBG) Log.d(LOG_TAG, "handleGetVPResponse: VP state successfully queried.");
+                final int enable = ((int[]) ar.result)[0];
+                setChecked(enable != 0);
+
+                android.provider.Settings.Secure.putInt(getContext().getContentResolver(),
+                        android.provider.Settings.Secure.ENHANCED_VOICE_PRIVACY_ENABLED, enable);
+            }
+        }
+
+        private void handleSetVPResponse(Message msg) {
+            AsyncResult ar = (AsyncResult) msg.obj;
+
+            if (ar.exception != null) {
+                if (DBG) Log.d(LOG_TAG, "handleSetVPResponse: ar.exception=" + ar.exception);
+            }
+            if (DBG) Log.d(LOG_TAG, "handleSetVPResponse: re get");
+
+            phone.getEnhancedVoicePrivacy(obtainMessage(MESSAGE_GET_VP));
+        }
+    }
+}
diff --git a/src/com/android/phone/CellBroadcastSms.java b/src/com/android/phone/CellBroadcastSms.java
new file mode 100644
index 0000000..7428321
--- /dev/null
+++ b/src/com/android/phone/CellBroadcastSms.java
@@ -0,0 +1,669 @@
+/*
+ * 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.Bundle;
+import android.preference.CheckBoxPreference;
+import android.preference.ListPreference;
+import android.preference.Preference;
+import android.preference.PreferenceScreen;
+import android.preference.PreferenceActivity;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.RILConstants;
+
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+
+
+/**
+ * List of Phone-specific settings screens.
+ */
+public class CellBroadcastSms extends PreferenceActivity
+        implements Preference.OnPreferenceChangeListener{
+    // debug data
+    private static final String LOG_TAG = "CellBroadcastSms";
+    private static final boolean DBG = false;
+
+    //String keys for preference lookup
+    private static final String BUTTON_ENABLE_DISABLE_BC_SMS_KEY =
+        "button_enable_disable_cell_bc_sms";
+    private static final String LIST_LANGUAGE_KEY =
+        "list_language";
+    private static final String BUTTON_EMERGENCY_BROADCAST_KEY =
+        "button_emergency_broadcast";
+    private static final String BUTTON_ADMINISTRATIVE_KEY =
+        "button_administrative";
+    private static final String BUTTON_MAINTENANCE_KEY =
+        "button_maintenance";
+    private static final String BUTTON_LOCAL_WEATHER_KEY =
+        "button_local_weather";
+    private static final String BUTTON_ATR_KEY =
+        "button_atr";
+    private static final String BUTTON_LAFS_KEY =
+        "button_lafs";
+    private static final String BUTTON_RESTAURANTS_KEY =
+        "button_restaurants";
+    private static final String BUTTON_LODGINGS_KEY =
+        "button_lodgings";
+    private static final String BUTTON_RETAIL_DIRECTORY_KEY =
+        "button_retail_directory";
+    private static final String BUTTON_ADVERTISEMENTS_KEY =
+        "button_advertisements";
+    private static final String BUTTON_STOCK_QUOTES_KEY =
+        "button_stock_quotes";
+    private static final String BUTTON_EO_KEY =
+        "button_eo";
+    private static final String BUTTON_MHH_KEY =
+        "button_mhh";
+    private static final String BUTTON_TECHNOLOGY_NEWS_KEY =
+        "button_technology_news";
+    private static final String BUTTON_MULTI_CATEGORY_KEY =
+        "button_multi_category";
+
+    private static final String BUTTON_LOCAL_GENERAL_NEWS_KEY =
+        "button_local_general_news";
+    private static final String BUTTON_REGIONAL_GENERAL_NEWS_KEY =
+        "button_regional_general_news";
+    private static final String BUTTON_NATIONAL_GENERAL_NEWS_KEY =
+        "button_national_general_news";
+    private static final String BUTTON_INTERNATIONAL_GENERAL_NEWS_KEY =
+        "button_international_general_news";
+
+    private static final String BUTTON_LOCAL_BF_NEWS_KEY =
+        "button_local_bf_news";
+    private static final String BUTTON_REGIONAL_BF_NEWS_KEY =
+        "button_regional_bf_news";
+    private static final String BUTTON_NATIONAL_BF_NEWS_KEY =
+        "button_national_bf_news";
+    private static final String BUTTON_INTERNATIONAL_BF_NEWS_KEY =
+        "button_international_bf_news";
+
+    private static final String BUTTON_LOCAL_SPORTS_NEWS_KEY =
+        "button_local_sports_news";
+    private static final String BUTTON_REGIONAL_SPORTS_NEWS_KEY =
+        "button_regional_sports_news";
+    private static final String BUTTON_NATIONAL_SPORTS_NEWS_KEY =
+        "button_national_sports_news";
+    private static final String BUTTON_INTERNATIONAL_SPORTS_NEWS_KEY =
+        "button_international_sports_news";
+
+    private static final String BUTTON_LOCAL_ENTERTAINMENT_NEWS_KEY =
+        "button_local_entertainment_news";
+    private static final String BUTTON_REGIONAL_ENTERTAINMENT_NEWS_KEY =
+        "button_regional_entertainment_news";
+    private static final String BUTTON_NATIONAL_ENTERTAINMENT_NEWS_KEY =
+        "button_national_entertainment_news";
+    private static final String BUTTON_INTERNATIONAL_ENTERTAINMENT_NEWS_KEY =
+        "button_international_entertainment_news";
+
+    //Class constants
+    //These values are related to the C structs. See the comments in  method
+    //setCbSmsConfig for more information.
+    private static final int NO_OF_SERVICE_CATEGORIES = 31;
+    private static final int NO_OF_INTS_STRUCT_1 = 3;
+    private static final int MAX_LENGTH_RESULT = NO_OF_SERVICE_CATEGORIES * NO_OF_INTS_STRUCT_1 + 1;
+    //Handler keys
+    private static final int MESSAGE_ACTIVATE_CB_SMS = 1;
+    private static final int MESSAGE_GET_CB_SMS_CONFIG = 2;
+    private static final int MESSAGE_SET_CB_SMS_CONFIG = 3;
+
+    //UI objects
+    private CheckBoxPreference mButtonBcSms;
+
+    private ListPreference mListLanguage;
+
+    private CheckBoxPreference mButtonEmergencyBroadcast;
+    private CheckBoxPreference mButtonAdministrative;
+    private CheckBoxPreference mButtonMaintenance;
+    private CheckBoxPreference mButtonLocalWeather;
+    private CheckBoxPreference mButtonAtr;
+    private CheckBoxPreference mButtonLafs;
+    private CheckBoxPreference mButtonRestaurants;
+    private CheckBoxPreference mButtonLodgings;
+    private CheckBoxPreference mButtonRetailDirectory;
+    private CheckBoxPreference mButtonAdvertisements;
+    private CheckBoxPreference mButtonStockQuotes;
+    private CheckBoxPreference mButtonEo;
+    private CheckBoxPreference mButtonMhh;
+    private CheckBoxPreference mButtonTechnologyNews;
+    private CheckBoxPreference mButtonMultiCategory;
+
+    private CheckBoxPreference mButtonLocal1;
+    private CheckBoxPreference mButtonRegional1;
+    private CheckBoxPreference mButtonNational1;
+    private CheckBoxPreference mButtonInternational1;
+
+    private CheckBoxPreference mButtonLocal2;
+    private CheckBoxPreference mButtonRegional2;
+    private CheckBoxPreference mButtonNational2;
+    private CheckBoxPreference mButtonInternational2;
+
+    private CheckBoxPreference mButtonLocal3;
+    private CheckBoxPreference mButtonRegional3;
+    private CheckBoxPreference mButtonNational3;
+    private CheckBoxPreference mButtonInternational3;
+
+    private CheckBoxPreference mButtonLocal4;
+    private CheckBoxPreference mButtonRegional4;
+    private CheckBoxPreference mButtonNational4;
+    private CheckBoxPreference mButtonInternational4;
+
+
+    //Member variables
+    private Phone mPhone;
+    private MyHandler mHandler;
+
+    /**
+     * Invoked on each preference click in this hierarchy, overrides
+     * PreferenceActivity's implementation.  Used to make sure we track the
+     * preference click events.
+     */
+    @Override
+    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
+            Preference preference) {
+        if (preference == mButtonBcSms) {
+            if (DBG) Log.d(LOG_TAG, "onPreferenceTreeClick: preference == mButtonBcSms.");
+            if(mButtonBcSms.isChecked()) {
+                mPhone.activateCellBroadcastSms(RILConstants.CDMA_CELL_BROADCAST_SMS_ENABLED,
+                        Message.obtain(mHandler, MESSAGE_ACTIVATE_CB_SMS));
+                android.provider.Settings.Global.putInt(mPhone.getContext().getContentResolver(),
+                        android.provider.Settings.Global.CDMA_CELL_BROADCAST_SMS,
+                        RILConstants.CDMA_CELL_BROADCAST_SMS_ENABLED);
+                enableDisableAllCbConfigButtons(true);
+            } else {
+                mPhone.activateCellBroadcastSms(RILConstants.CDMA_CELL_BROADCAST_SMS_DISABLED,
+                        Message.obtain(mHandler, MESSAGE_ACTIVATE_CB_SMS));
+                android.provider.Settings.Global.putInt(mPhone.getContext().getContentResolver(),
+                        android.provider.Settings.Global.CDMA_CELL_BROADCAST_SMS,
+                        RILConstants.CDMA_CELL_BROADCAST_SMS_DISABLED);
+                enableDisableAllCbConfigButtons(false);
+            }
+        } else if (preference == mListLanguage) {
+            //Do nothing here, because this click will be handled in onPreferenceChange
+        } else if (preference == mButtonEmergencyBroadcast) {
+            CellBroadcastSmsConfig.setConfigDataCompleteBSelected(
+                    mButtonEmergencyBroadcast.isChecked(), 1);
+            CellBroadcastSmsConfig.setCbSmsBSelectedValue(
+                    mButtonEmergencyBroadcast.isChecked(), 1);
+        } else if (preference == mButtonAdministrative) {
+            CellBroadcastSmsConfig.setConfigDataCompleteBSelected(
+                    mButtonAdministrative.isChecked(), 2);
+            CellBroadcastSmsConfig.setCbSmsBSelectedValue(mButtonAdministrative.isChecked(), 2);
+        } else if (preference == mButtonMaintenance) {
+            CellBroadcastSmsConfig.setConfigDataCompleteBSelected(
+                    mButtonMaintenance.isChecked(), 3);
+            CellBroadcastSmsConfig.setCbSmsBSelectedValue(mButtonMaintenance.isChecked(), 3);
+        } else if (preference == mButtonLocalWeather) {
+            CellBroadcastSmsConfig.setConfigDataCompleteBSelected(
+                    mButtonLocalWeather.isChecked(), 20);
+            CellBroadcastSmsConfig.setCbSmsBSelectedValue(mButtonLocalWeather.isChecked(), 20);
+        } else if (preference == mButtonAtr) {
+            CellBroadcastSmsConfig.setConfigDataCompleteBSelected(mButtonAtr.isChecked(), 21);
+            CellBroadcastSmsConfig.setCbSmsBSelectedValue(mButtonAtr.isChecked(), 21);
+        } else if (preference == mButtonLafs) {
+            CellBroadcastSmsConfig.setConfigDataCompleteBSelected(mButtonLafs.isChecked(), 22);
+            CellBroadcastSmsConfig.setCbSmsBSelectedValue(mButtonLafs.isChecked(), 22);
+        } else if (preference == mButtonRestaurants) {
+            CellBroadcastSmsConfig.setConfigDataCompleteBSelected(
+                    mButtonRestaurants.isChecked(), 23);
+            CellBroadcastSmsConfig.setCbSmsBSelectedValue(mButtonRestaurants.isChecked(), 23);
+        } else if (preference == mButtonLodgings) {
+            CellBroadcastSmsConfig.setConfigDataCompleteBSelected(mButtonLodgings.isChecked(), 24);
+            CellBroadcastSmsConfig.setCbSmsBSelectedValue(mButtonLodgings.isChecked(), 24);
+        } else if (preference == mButtonRetailDirectory) {
+            CellBroadcastSmsConfig.setConfigDataCompleteBSelected(
+                    mButtonRetailDirectory.isChecked(), 25);
+            CellBroadcastSmsConfig.setCbSmsBSelectedValue(mButtonRetailDirectory.isChecked(), 25);
+        } else if (preference == mButtonAdvertisements) {
+            CellBroadcastSmsConfig.setConfigDataCompleteBSelected(
+                    mButtonAdvertisements.isChecked(), 26);
+            CellBroadcastSmsConfig.setCbSmsBSelectedValue(mButtonAdvertisements.isChecked(), 26);
+        } else if (preference == mButtonStockQuotes) {
+            CellBroadcastSmsConfig.setConfigDataCompleteBSelected(
+                    mButtonStockQuotes.isChecked(), 27);
+            CellBroadcastSmsConfig.setCbSmsBSelectedValue(mButtonStockQuotes.isChecked(), 27);
+        } else if (preference == mButtonEo) {
+            CellBroadcastSmsConfig.setConfigDataCompleteBSelected(mButtonEo.isChecked(), 28);
+            CellBroadcastSmsConfig.setCbSmsBSelectedValue(mButtonEo.isChecked(), 28);
+        } else if (preference == mButtonMhh) {
+            CellBroadcastSmsConfig.setConfigDataCompleteBSelected(mButtonMhh.isChecked(), 29);
+            CellBroadcastSmsConfig.setCbSmsBSelectedValue(mButtonMhh.isChecked(), 29);
+        } else if (preference == mButtonTechnologyNews) {
+            CellBroadcastSmsConfig.setConfigDataCompleteBSelected(
+                    mButtonTechnologyNews.isChecked(), 30);
+            CellBroadcastSmsConfig.setCbSmsBSelectedValue(mButtonTechnologyNews.isChecked(), 30);
+        } else if (preference == mButtonMultiCategory) {
+            CellBroadcastSmsConfig.setConfigDataCompleteBSelected(
+                    mButtonMultiCategory.isChecked(), 31);
+            CellBroadcastSmsConfig.setCbSmsBSelectedValue(mButtonMultiCategory.isChecked(), 31);
+        } else if (preference == mButtonLocal1) {
+            CellBroadcastSmsConfig.setConfigDataCompleteBSelected(mButtonLocal1.isChecked(), 4);
+            CellBroadcastSmsConfig.setCbSmsBSelectedValue(mButtonLocal1.isChecked(), 4);
+        } else if (preference == mButtonRegional1) {
+            CellBroadcastSmsConfig.setConfigDataCompleteBSelected(
+                    mButtonRegional1.isChecked(), 5);
+            CellBroadcastSmsConfig.setCbSmsBSelectedValue(mButtonRegional1.isChecked(), 5);
+        } else if (preference == mButtonNational1) {
+            CellBroadcastSmsConfig.setConfigDataCompleteBSelected(
+                    mButtonNational1.isChecked(), 6);
+            CellBroadcastSmsConfig.setCbSmsBSelectedValue(mButtonNational1.isChecked(), 6);
+        } else if (preference == mButtonInternational1) {
+            CellBroadcastSmsConfig.setConfigDataCompleteBSelected(
+                    mButtonInternational1.isChecked(), 7);
+            CellBroadcastSmsConfig.setCbSmsBSelectedValue(mButtonInternational1.isChecked(), 7);
+        } else if (preference == mButtonLocal2) {
+            CellBroadcastSmsConfig.setConfigDataCompleteBSelected(mButtonLocal2.isChecked(), 8);
+            CellBroadcastSmsConfig.setCbSmsBSelectedValue(mButtonLocal2.isChecked(), 8);
+        } else if (preference == mButtonRegional2) {
+            CellBroadcastSmsConfig.setConfigDataCompleteBSelected(
+                    mButtonRegional2.isChecked(), 9);
+            CellBroadcastSmsConfig.setCbSmsBSelectedValue(mButtonRegional2.isChecked(), 9);
+        } else if (preference == mButtonNational2) {
+            CellBroadcastSmsConfig.setConfigDataCompleteBSelected(
+                    mButtonNational2.isChecked(), 10);
+            CellBroadcastSmsConfig.setCbSmsBSelectedValue(mButtonNational2.isChecked(), 10);
+        } else if (preference == mButtonInternational2) {
+            CellBroadcastSmsConfig.setConfigDataCompleteBSelected(
+                    mButtonInternational2.isChecked(), 11);
+            CellBroadcastSmsConfig.setCbSmsBSelectedValue(mButtonInternational2.isChecked(), 11);
+        } else if (preference == mButtonLocal3) {
+            CellBroadcastSmsConfig.setConfigDataCompleteBSelected(mButtonLocal3.isChecked(), 12);
+            CellBroadcastSmsConfig.setCbSmsBSelectedValue(mButtonLocal3.isChecked(), 12);
+        } else if (preference == mButtonRegional3) {
+            CellBroadcastSmsConfig.setConfigDataCompleteBSelected(
+                    mButtonRegional3.isChecked(), 13);
+            CellBroadcastSmsConfig.setCbSmsBSelectedValue(mButtonRegional3.isChecked(), 13);
+        } else if (preference == mButtonNational3) {
+            CellBroadcastSmsConfig.setConfigDataCompleteBSelected(
+                    mButtonNational3.isChecked(), 14);
+            CellBroadcastSmsConfig.setCbSmsBSelectedValue(mButtonNational3.isChecked(), 14);
+        } else if (preference == mButtonInternational3) {
+            CellBroadcastSmsConfig.setConfigDataCompleteBSelected(
+                    mButtonInternational3.isChecked(), 15);
+            CellBroadcastSmsConfig.setCbSmsBSelectedValue(mButtonInternational3.isChecked(), 15);
+        } else if (preference == mButtonLocal4) {
+            CellBroadcastSmsConfig.setConfigDataCompleteBSelected(mButtonLocal4.isChecked(), 16);
+            CellBroadcastSmsConfig.setCbSmsBSelectedValue(mButtonLocal4.isChecked(), 16);
+        } else if (preference == mButtonRegional4) {
+            CellBroadcastSmsConfig.setConfigDataCompleteBSelected(
+                    mButtonRegional4.isChecked(), 17);
+            CellBroadcastSmsConfig.setCbSmsBSelectedValue(mButtonRegional4.isChecked(), 17);
+        } else if (preference == mButtonNational4) {
+            CellBroadcastSmsConfig.setConfigDataCompleteBSelected(
+                    mButtonNational4.isChecked(), 18);
+            CellBroadcastSmsConfig.setCbSmsBSelectedValue(mButtonNational4.isChecked(), 18);
+        } else if (preference == mButtonInternational4) {
+            CellBroadcastSmsConfig.setConfigDataCompleteBSelected(
+                    mButtonInternational4.isChecked(), 19);
+            CellBroadcastSmsConfig.setCbSmsBSelectedValue(mButtonInternational4.isChecked(), 19);
+        } else {
+            preferenceScreen.setEnabled(false);
+            return false;
+        }
+
+        return true;
+    }
+
+    public boolean onPreferenceChange(Preference preference, Object objValue) {
+        if (preference == mListLanguage) {
+            // set the new language to the array which will be transmitted later
+            CellBroadcastSmsConfig.setConfigDataCompleteLanguage(
+                    mListLanguage.findIndexOfValue((String) objValue) + 1);
+        }
+
+        // always let the preference setting proceed.
+        return true;
+    }
+
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        addPreferencesFromResource(R.xml.cell_broadcast_sms);
+
+        mPhone = PhoneGlobals.getPhone();
+        mHandler = new MyHandler();
+
+        PreferenceScreen prefSet = getPreferenceScreen();
+
+        mButtonBcSms = (CheckBoxPreference) prefSet.findPreference(
+                BUTTON_ENABLE_DISABLE_BC_SMS_KEY);
+        mListLanguage = (ListPreference) prefSet.findPreference(
+                LIST_LANGUAGE_KEY);
+        // set the listener for the language list preference
+        mListLanguage.setOnPreferenceChangeListener(this);
+        mButtonEmergencyBroadcast = (CheckBoxPreference) prefSet.findPreference(
+                BUTTON_EMERGENCY_BROADCAST_KEY);
+        mButtonAdministrative = (CheckBoxPreference) prefSet.findPreference(
+                BUTTON_ADMINISTRATIVE_KEY);
+        mButtonMaintenance = (CheckBoxPreference) prefSet.findPreference(
+                BUTTON_MAINTENANCE_KEY);
+        mButtonLocalWeather = (CheckBoxPreference) prefSet.findPreference(
+                BUTTON_LOCAL_WEATHER_KEY);
+        mButtonAtr = (CheckBoxPreference) prefSet.findPreference(
+                BUTTON_ATR_KEY);
+        mButtonLafs = (CheckBoxPreference) prefSet.findPreference(
+                BUTTON_LAFS_KEY);
+        mButtonRestaurants = (CheckBoxPreference) prefSet.findPreference(
+                BUTTON_RESTAURANTS_KEY);
+        mButtonLodgings = (CheckBoxPreference) prefSet.findPreference(
+                BUTTON_LODGINGS_KEY);
+        mButtonRetailDirectory = (CheckBoxPreference) prefSet.findPreference(
+                BUTTON_RETAIL_DIRECTORY_KEY);
+        mButtonAdvertisements = (CheckBoxPreference) prefSet.findPreference(
+                BUTTON_ADVERTISEMENTS_KEY);
+        mButtonStockQuotes = (CheckBoxPreference) prefSet.findPreference(
+                BUTTON_STOCK_QUOTES_KEY);
+        mButtonEo = (CheckBoxPreference) prefSet.findPreference(
+                BUTTON_EO_KEY);
+        mButtonMhh = (CheckBoxPreference) prefSet.findPreference(
+                BUTTON_MHH_KEY);
+        mButtonTechnologyNews = (CheckBoxPreference) prefSet.findPreference(
+                BUTTON_TECHNOLOGY_NEWS_KEY);
+        mButtonMultiCategory = (CheckBoxPreference) prefSet.findPreference(
+                BUTTON_MULTI_CATEGORY_KEY);
+
+        mButtonLocal1 = (CheckBoxPreference) prefSet.findPreference(
+                BUTTON_LOCAL_GENERAL_NEWS_KEY);
+        mButtonRegional1 = (CheckBoxPreference) prefSet.findPreference(
+                BUTTON_REGIONAL_GENERAL_NEWS_KEY);
+        mButtonNational1 = (CheckBoxPreference) prefSet.findPreference(
+                BUTTON_NATIONAL_GENERAL_NEWS_KEY);
+        mButtonInternational1 = (CheckBoxPreference) prefSet.findPreference(
+                BUTTON_INTERNATIONAL_GENERAL_NEWS_KEY);
+
+        mButtonLocal2 = (CheckBoxPreference) prefSet.findPreference(
+                BUTTON_LOCAL_BF_NEWS_KEY);
+        mButtonRegional2 = (CheckBoxPreference) prefSet.findPreference(
+                BUTTON_REGIONAL_BF_NEWS_KEY);
+        mButtonNational2 = (CheckBoxPreference) prefSet.findPreference(
+                BUTTON_NATIONAL_BF_NEWS_KEY);
+        mButtonInternational2 = (CheckBoxPreference) prefSet.findPreference(
+                BUTTON_INTERNATIONAL_BF_NEWS_KEY);
+
+        mButtonLocal3 = (CheckBoxPreference) prefSet.findPreference(
+                BUTTON_LOCAL_SPORTS_NEWS_KEY);
+        mButtonRegional3 = (CheckBoxPreference) prefSet.findPreference(
+                BUTTON_REGIONAL_SPORTS_NEWS_KEY);
+        mButtonNational3 = (CheckBoxPreference) prefSet.findPreference(
+                BUTTON_NATIONAL_SPORTS_NEWS_KEY);
+        mButtonInternational3 = (CheckBoxPreference) prefSet.findPreference(
+                BUTTON_INTERNATIONAL_SPORTS_NEWS_KEY);
+
+        mButtonLocal4 = (CheckBoxPreference) prefSet.findPreference(
+                BUTTON_LOCAL_ENTERTAINMENT_NEWS_KEY);
+        mButtonRegional4 = (CheckBoxPreference) prefSet.findPreference(
+                BUTTON_REGIONAL_ENTERTAINMENT_NEWS_KEY);
+        mButtonNational4 = (CheckBoxPreference) prefSet.findPreference(
+                BUTTON_NATIONAL_ENTERTAINMENT_NEWS_KEY);
+        mButtonInternational4 = (CheckBoxPreference) prefSet.findPreference(
+                BUTTON_INTERNATIONAL_ENTERTAINMENT_NEWS_KEY);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        getPreferenceScreen().setEnabled(true);
+
+        int settingCbSms = android.provider.Settings.Global.getInt(
+                mPhone.getContext().getContentResolver(),
+                android.provider.Settings.Global.CDMA_CELL_BROADCAST_SMS,
+                RILConstants.CDMA_CELL_BROADCAST_SMS_DISABLED);
+        mButtonBcSms.setChecked(settingCbSms == RILConstants.CDMA_CELL_BROADCAST_SMS_ENABLED);
+
+        if(mButtonBcSms.isChecked()) {
+            enableDisableAllCbConfigButtons(true);
+        } else {
+            enableDisableAllCbConfigButtons(false);
+        }
+
+        mPhone.getCellBroadcastSmsConfig(Message.obtain(mHandler, MESSAGE_GET_CB_SMS_CONFIG));
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+
+            CellBroadcastSmsConfig.setCbSmsNoOfStructs(NO_OF_SERVICE_CATEGORIES);
+
+            mPhone.setCellBroadcastSmsConfig(CellBroadcastSmsConfig.getCbSmsAllValues(),
+                    Message.obtain(mHandler, MESSAGE_SET_CB_SMS_CONFIG));
+        }
+
+    private void enableDisableAllCbConfigButtons(boolean enable) {
+        mButtonEmergencyBroadcast.setEnabled(enable);
+        mListLanguage.setEnabled(enable);
+        mButtonAdministrative.setEnabled(enable);
+        mButtonMaintenance.setEnabled(enable);
+        mButtonLocalWeather.setEnabled(enable);
+        mButtonAtr.setEnabled(enable);
+        mButtonLafs.setEnabled(enable);
+        mButtonRestaurants.setEnabled(enable);
+        mButtonLodgings.setEnabled(enable);
+        mButtonRetailDirectory.setEnabled(enable);
+        mButtonAdvertisements.setEnabled(enable);
+        mButtonStockQuotes.setEnabled(enable);
+        mButtonEo.setEnabled(enable);
+        mButtonMhh.setEnabled(enable);
+        mButtonTechnologyNews.setEnabled(enable);
+        mButtonMultiCategory.setEnabled(enable);
+
+        mButtonLocal1.setEnabled(enable);
+        mButtonRegional1.setEnabled(enable);
+        mButtonNational1.setEnabled(enable);
+        mButtonInternational1.setEnabled(enable);
+
+        mButtonLocal2.setEnabled(enable);
+        mButtonRegional2.setEnabled(enable);
+        mButtonNational2.setEnabled(enable);
+        mButtonInternational2.setEnabled(enable);
+
+        mButtonLocal3.setEnabled(enable);
+        mButtonRegional3.setEnabled(enable);
+        mButtonNational3.setEnabled(enable);
+        mButtonInternational3.setEnabled(enable);
+
+        mButtonLocal4.setEnabled(enable);
+        mButtonRegional4.setEnabled(enable);
+        mButtonNational4.setEnabled(enable);
+        mButtonInternational4.setEnabled(enable);
+    }
+
+    private void setAllCbConfigButtons(int[] configArray) {
+        //These buttons are in a well defined sequence. If you want to change it,
+        //be sure to map the buttons to their corresponding slot in the configArray !
+        mButtonEmergencyBroadcast.setChecked(configArray[1] != 0);
+        //subtract 1, because the values are handled in an array which starts with 0 and not with 1
+        mListLanguage.setValueIndex(CellBroadcastSmsConfig.getConfigDataLanguage() - 1);
+        mButtonAdministrative.setChecked(configArray[2] != 0);
+        mButtonMaintenance.setChecked(configArray[3] != 0);
+        mButtonLocalWeather.setChecked(configArray[20] != 0);
+        mButtonAtr.setChecked(configArray[21] != 0);
+        mButtonLafs.setChecked(configArray[22] != 0);
+        mButtonRestaurants.setChecked(configArray[23] != 0);
+        mButtonLodgings.setChecked(configArray[24] != 0);
+        mButtonRetailDirectory.setChecked(configArray[25] != 0);
+        mButtonAdvertisements.setChecked(configArray[26] != 0);
+        mButtonStockQuotes.setChecked(configArray[27] != 0);
+        mButtonEo.setChecked(configArray[28] != 0);
+        mButtonMhh.setChecked(configArray[29] != 0);
+        mButtonTechnologyNews.setChecked(configArray[30] != 0);
+        mButtonMultiCategory.setChecked(configArray[31] != 0);
+
+        mButtonLocal1.setChecked(configArray[4] != 0);
+        mButtonRegional1.setChecked(configArray[5] != 0);
+        mButtonNational1.setChecked(configArray[6] != 0);
+        mButtonInternational1.setChecked(configArray[7] != 0);
+
+        mButtonLocal2.setChecked(configArray[8] != 0);
+        mButtonRegional2.setChecked(configArray[9] != 0);
+        mButtonNational2.setChecked(configArray[10] != 0);
+        mButtonInternational2.setChecked(configArray[11] != 0);
+
+        mButtonLocal3.setChecked(configArray[12] != 0);
+        mButtonRegional3.setChecked(configArray[13] != 0);
+        mButtonNational3.setChecked(configArray[14] != 0);
+        mButtonInternational3.setChecked(configArray[15] != 0);
+
+        mButtonLocal4.setChecked(configArray[16] != 0);
+        mButtonRegional4.setChecked(configArray[17] != 0);
+        mButtonNational4.setChecked(configArray[18] != 0);
+        mButtonInternational4.setChecked(configArray[19] != 0);
+    }
+
+    private class MyHandler extends Handler {
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+            case MESSAGE_ACTIVATE_CB_SMS:
+                //Only a log message here, because the received response is always null
+                if (DBG) Log.d(LOG_TAG, "Cell Broadcast SMS enabled/disabled.");
+                break;
+            case MESSAGE_GET_CB_SMS_CONFIG:
+                int result[] = (int[])((AsyncResult)msg.obj).result;
+
+                // check if the actual service categoties table size on the NV is '0'
+                if (result[0] == 0) {
+                    result[0] = NO_OF_SERVICE_CATEGORIES;
+
+                    mButtonBcSms.setChecked(false);
+                    mPhone.activateCellBroadcastSms(RILConstants.CDMA_CELL_BROADCAST_SMS_DISABLED,
+                            Message.obtain(mHandler, MESSAGE_ACTIVATE_CB_SMS));
+                    android.provider.Settings.Global.putInt(mPhone.getContext().getContentResolver(),
+                            android.provider.Settings.Global.CDMA_CELL_BROADCAST_SMS,
+                            RILConstants.CDMA_CELL_BROADCAST_SMS_DISABLED);
+                    enableDisableAllCbConfigButtons(false);
+                }
+
+                CellBroadcastSmsConfig.setCbSmsConfig(result);
+                setAllCbConfigButtons(CellBroadcastSmsConfig.getCbSmsBselectedValues());
+
+                break;
+            case MESSAGE_SET_CB_SMS_CONFIG:
+                //Only a log message here, because the received response is always null
+                if (DBG) Log.d(LOG_TAG, "Set Cell Broadcast SMS values.");
+                break;
+            default:
+                Log.e(LOG_TAG, "Error! Unhandled message in CellBroadcastSms.java. Message: "
+                        + msg.what);
+            break;
+            }
+        }
+    }
+
+    private static final class CellBroadcastSmsConfig {
+
+        //The values in this array are stored in a particular order. This order
+        //is calculated in the setCbSmsConfig method of this class.
+        //For more information see comments below...
+        //NO_OF_SERVICE_CATEGORIES +1 is used, because we will leave the first array entry 0
+        private static int mBSelected[] = new int[NO_OF_SERVICE_CATEGORIES + 1];
+        private static int mConfigDataComplete[] = new int[MAX_LENGTH_RESULT];
+
+        private static void setCbSmsConfig(int[] configData) {
+            if(configData == null) {
+                Log.e(LOG_TAG, "Error! No cell broadcast service categories returned.");
+                return;
+            }
+
+            if(configData[0] > MAX_LENGTH_RESULT) {
+                Log.e(LOG_TAG, "Error! Wrong number of service categories returned from RIL");
+                return;
+            }
+
+            //The required config values for broadcast SMS are stored in a C struct:
+            //
+            //  typedef struct {
+            //      int size;
+            //      RIL_CDMA_BcServiceInfo *entries;
+            //  } RIL_CDMA_BcSMSConfig;
+            //
+            //  typedef struct {
+            //      int uServiceCategory;
+            //      int uLanguage;
+            //      unsigned char bSelected;
+            //  } RIL_CDMA_BcServiceInfo;
+            //
+            // This means, that we have to ignore the first value and check every
+            // 3rd value starting with the 2nd of all. This value indicates, where we
+            // will store the appropriate bSelected value, which is 2 values behind it.
+            for(int i = 1; i < configData.length; i += NO_OF_INTS_STRUCT_1) {
+                mBSelected[configData[i]] = configData[i +2];
+            }
+
+            //Store all values in an extra array
+            mConfigDataComplete = configData;
+        }
+
+        private static void setCbSmsBSelectedValue(boolean value, int pos) {
+            if(pos < mBSelected.length) {
+                mBSelected[pos] = (value == true ? 1 : 0);
+            } else {
+                Log.e(LOG_TAG,"Error! Invalid value position.");
+            }
+        }
+
+        private static int[] getCbSmsBselectedValues() {
+            return(mBSelected);
+        }
+
+        // TODO: Change the return value to a RIL_BroadcastSMSConfig
+        private static int[] getCbSmsAllValues() {
+            return(mConfigDataComplete);
+        }
+
+        private static void setCbSmsNoOfStructs(int value) {
+            //Sets the size parameter, which contains the number of structs
+            //that will be transmitted
+            mConfigDataComplete[0] = value;
+        }
+
+        private static void setConfigDataCompleteBSelected(boolean value, int serviceCategory) {
+            //Sets the bSelected value for a specific serviceCategory
+            for(int i = 1; i < mConfigDataComplete.length; i += NO_OF_INTS_STRUCT_1) {
+                if(mConfigDataComplete[i] == serviceCategory) {
+                    mConfigDataComplete[i + 2] = value == true ? 1 : 0;
+                    break;
+                }
+            }
+        }
+
+        private static void setConfigDataCompleteLanguage(int language) {
+            //It is only possible to set the same language for all entries
+            for(int i = 2; i < mConfigDataComplete.length; i += NO_OF_INTS_STRUCT_1) {
+                mConfigDataComplete[i] = language;
+            }
+        }
+
+        private static int getConfigDataLanguage() {
+            int language = mConfigDataComplete[2];
+            //2 is the language value of the first entry
+            //It is only possible to set the same language for all entries
+            if (language < 1 || language > 7) {
+                Log.e(LOG_TAG, "Error! Wrong language returned from RIL...defaulting to 1, english");
+                return 1;
+            }
+            else {
+                return language;
+            }
+        }
+    }
+}
diff --git a/src/com/android/phone/ChangeIccPinScreen.java b/src/com/android/phone/ChangeIccPinScreen.java
new file mode 100644
index 0000000..70bf431
--- /dev/null
+++ b/src/com/android/phone/ChangeIccPinScreen.java
@@ -0,0 +1,306 @@
+/*
+ * 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.app.Activity;
+import android.app.AlertDialog;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.os.AsyncResult;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.text.method.DigitsKeyListener;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.ScrollView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.android.internal.telephony.CommandException;
+import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.Phone;
+
+/**
+ * "Change ICC PIN" UI for the Phone app.
+ */
+public class ChangeIccPinScreen extends Activity {
+    private static final String LOG_TAG = PhoneGlobals.LOG_TAG;
+    private static final boolean DBG = false;
+
+    private static final int EVENT_PIN_CHANGED = 100;
+    
+    private enum EntryState {
+        ES_PIN,
+        ES_PUK
+    }
+    
+    private EntryState mState;
+
+    private static final int NO_ERROR = 0;
+    private static final int PIN_MISMATCH = 1;
+    private static final int PIN_INVALID_LENGTH = 2;
+
+    private static final int MIN_PIN_LENGTH = 4;
+    private static final int MAX_PIN_LENGTH = 8;
+
+    private Phone mPhone;
+    private boolean mChangePin2;
+    private TextView mBadPinError;
+    private TextView mMismatchError;
+    private EditText mOldPin;
+    private EditText mNewPin1;
+    private EditText mNewPin2;
+    private EditText mPUKCode;
+    private Button mButton;
+    private Button mPUKSubmit;
+    private ScrollView mScrollView;
+
+    private LinearLayout mIccPUKPanel;
+
+    private Handler mHandler = new Handler() {
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case EVENT_PIN_CHANGED:
+                    AsyncResult ar = (AsyncResult) msg.obj;
+                    handleResult(ar);
+                    break;
+            }
+
+            return;
+        }
+    };
+
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        mPhone = PhoneGlobals.getPhone();
+
+        resolveIntent();
+
+        setContentView(R.layout.change_sim_pin_screen);
+
+        mOldPin = (EditText) findViewById(R.id.old_pin);
+        mOldPin.setKeyListener(DigitsKeyListener.getInstance());
+        mOldPin.setMovementMethod(null);
+        mOldPin.setOnClickListener(mClicked);
+
+        mNewPin1 = (EditText) findViewById(R.id.new_pin1);
+        mNewPin1.setKeyListener(DigitsKeyListener.getInstance());
+        mNewPin1.setMovementMethod(null);
+        mNewPin1.setOnClickListener(mClicked);
+
+        mNewPin2 = (EditText) findViewById(R.id.new_pin2);
+        mNewPin2.setKeyListener(DigitsKeyListener.getInstance());
+        mNewPin2.setMovementMethod(null);
+        mNewPin2.setOnClickListener(mClicked);
+
+        mBadPinError = (TextView) findViewById(R.id.bad_pin);
+        mMismatchError = (TextView) findViewById(R.id.mismatch);
+
+        mButton = (Button) findViewById(R.id.button);
+        mButton.setOnClickListener(mClicked);
+
+        mScrollView = (ScrollView) findViewById(R.id.scroll);
+        
+        mPUKCode = (EditText) findViewById(R.id.puk_code);
+        mPUKCode.setKeyListener(DigitsKeyListener.getInstance());
+        mPUKCode.setMovementMethod(null);
+        mPUKCode.setOnClickListener(mClicked);
+        
+        mPUKSubmit = (Button) findViewById(R.id.puk_submit);
+        mPUKSubmit.setOnClickListener(mClicked);
+
+        mIccPUKPanel = (LinearLayout) findViewById(R.id.puk_panel);
+
+        int id = mChangePin2 ? R.string.change_pin2 : R.string.change_pin;
+        setTitle(getResources().getText(id));
+        
+        mState = EntryState.ES_PIN;
+    }
+
+    private void resolveIntent() {
+        Intent intent = getIntent();
+        mChangePin2 = intent.getBooleanExtra("pin2", mChangePin2);
+    }
+
+    private void reset() {
+        mScrollView.scrollTo(0, 0);
+        mBadPinError.setVisibility(View.GONE);
+        mMismatchError.setVisibility(View.GONE);
+    }
+
+    private int validateNewPin(String p1, String p2) {
+        if (p1 == null) {
+            return PIN_INVALID_LENGTH;
+        }
+
+        if (!p1.equals(p2)) {
+            return PIN_MISMATCH;
+        }
+
+        int len1 = p1.length();
+
+        if (len1 < MIN_PIN_LENGTH || len1 > MAX_PIN_LENGTH) {
+            return PIN_INVALID_LENGTH;
+        }
+
+        return NO_ERROR;
+    }
+
+    private View.OnClickListener mClicked = new View.OnClickListener() {
+        public void onClick(View v) {
+            if (v == mOldPin) {
+                mNewPin1.requestFocus();
+            } else if (v == mNewPin1) {
+                mNewPin2.requestFocus();
+            } else if (v == mNewPin2) {
+                mButton.requestFocus();
+            } else if (v == mButton) {
+                IccCard iccCardInterface = mPhone.getIccCard();
+                if (iccCardInterface != null) {
+                    String oldPin = mOldPin.getText().toString();
+                    String newPin1 = mNewPin1.getText().toString();
+                    String newPin2 = mNewPin2.getText().toString();
+
+                    int error = validateNewPin(newPin1, newPin2);
+
+                    switch (error) {
+                        case PIN_INVALID_LENGTH:
+                        case PIN_MISMATCH:
+                            mNewPin1.getText().clear();
+                            mNewPin2.getText().clear();
+                            mMismatchError.setVisibility(View.VISIBLE);
+
+                            Resources r = getResources();
+                            CharSequence text;
+
+                            if (error == PIN_MISMATCH) {
+                                text = r.getString(R.string.mismatchPin);
+                            } else {
+                                text = r.getString(R.string.invalidPin);
+                            }
+
+                            mMismatchError.setText(text);
+                            break;
+
+                        default:
+                            Message callBack = Message.obtain(mHandler,
+                                    EVENT_PIN_CHANGED);
+
+                            if (DBG) log("change pin attempt: old=" + oldPin +
+                                    ", newPin=" + newPin1);
+
+                            reset();
+
+                            if (mChangePin2) {
+                                iccCardInterface.changeIccFdnPassword(oldPin,
+                                        newPin1, callBack);
+                            } else {
+                                iccCardInterface.changeIccLockPassword(oldPin,
+                                        newPin1, callBack);
+                            }
+
+                            // TODO: show progress panel
+                    }
+                }
+            } else if (v == mPUKCode) {
+                mPUKSubmit.requestFocus();
+            } else if (v == mPUKSubmit) {
+                mPhone.getIccCard().supplyPuk2(mPUKCode.getText().toString(), 
+                        mNewPin1.getText().toString(), 
+                        Message.obtain(mHandler, EVENT_PIN_CHANGED));
+            }
+        }
+    };
+
+    private void handleResult(AsyncResult ar) {
+        if (ar.exception == null) {
+            if (DBG) log("handleResult: success!");
+
+            if (mState == EntryState.ES_PUK) {
+                mScrollView.setVisibility(View.VISIBLE);
+                mIccPUKPanel.setVisibility(View.GONE);
+            }            
+            // TODO: show success feedback
+            showConfirmation();
+
+            mHandler.postDelayed(new Runnable() {
+                public void run() {
+                    finish();
+                }
+            }, 3000);
+
+        } else if (ar.exception instanceof CommandException
+           /*  && ((CommandException)ar.exception).getCommandError() ==
+           CommandException.Error.PASSWORD_INCORRECT */ ) {
+            if (mState == EntryState.ES_PIN) {
+                if (DBG) log("handleResult: pin failed!");
+                mOldPin.getText().clear();
+                mBadPinError.setVisibility(View.VISIBLE);
+                CommandException ce = (CommandException) ar.exception;
+                if (ce.getCommandError() == CommandException.Error.SIM_PUK2) {
+                    if (DBG) log("handleResult: puk requested!");
+                    mState = EntryState.ES_PUK;
+                    displayPUKAlert();
+                    mScrollView.setVisibility(View.GONE);
+                    mIccPUKPanel.setVisibility(View.VISIBLE);
+                    mPUKCode.requestFocus();
+                }
+            } else if (mState == EntryState.ES_PUK) {
+                //should really check to see if the error is CommandException.PASSWORD_INCORRECT...
+                if (DBG) log("handleResult: puk2 failed!");
+                displayPUKAlert();
+                mPUKCode.getText().clear();
+                mPUKCode.requestFocus();
+            }
+        }
+    }
+    
+    private AlertDialog mPUKAlert;
+    private void displayPUKAlert () {
+        if (mPUKAlert == null) {
+            mPUKAlert = new AlertDialog.Builder(this)
+            .setMessage (R.string.puk_requested)
+            .setCancelable(false)
+            .show();
+        } else {
+            mPUKAlert.show();
+        }
+        //TODO: The 3 second delay here is somewhat arbitrary, reflecting the values
+        //used elsewhere for similar code.  This should get revisited with the framework
+        //crew to see if there is some standard we should adhere to.
+        mHandler.postDelayed(new Runnable() {
+            public void run() {
+                mPUKAlert.dismiss();
+            }
+        }, 3000);
+    }
+
+    private void showConfirmation() {
+        int id = mChangePin2 ? R.string.pin2_changed : R.string.pin_changed;
+        Toast.makeText(this, id, Toast.LENGTH_SHORT).show();
+    }
+
+    private void log(String msg) {
+        String prefix = mChangePin2 ? "[ChgPin2]" : "[ChgPin]";
+        Log.d(LOG_TAG, prefix + msg);
+    }
+}
diff --git a/src/com/android/phone/ClearMissedCallsService.java b/src/com/android/phone/ClearMissedCallsService.java
new file mode 100644
index 0000000..b882472
--- /dev/null
+++ b/src/com/android/phone/ClearMissedCallsService.java
@@ -0,0 +1,61 @@
+/*
+ * 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.app.IntentService;
+import android.content.ContentValues;
+import android.content.Intent;
+import android.provider.CallLog.Calls;
+
+/**
+ * Handles the intent to clear the missed calls that is triggered when a notification is dismissed.
+ */
+public class ClearMissedCallsService extends IntentService {
+    /** This action is used to clear missed calls. */
+    public static final String ACTION_CLEAR_MISSED_CALLS =
+            "com.android.phone.intent.CLEAR_MISSED_CALLS";
+
+    private PhoneGlobals mApp;
+
+    public ClearMissedCallsService() {
+        super(ClearMissedCallsService.class.getSimpleName());
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        mApp = PhoneGlobals.getInstance();
+    }
+
+    @Override
+    protected void onHandleIntent(Intent intent) {
+        if (ACTION_CLEAR_MISSED_CALLS.equals(intent.getAction())) {
+            // Clear the list of new missed calls.
+            ContentValues values = new ContentValues();
+            values.put(Calls.NEW, 0);
+            values.put(Calls.IS_READ, 1);
+            StringBuilder where = new StringBuilder();
+            where.append(Calls.NEW);
+            where.append(" = 1 AND ");
+            where.append(Calls.TYPE);
+            where.append(" = ?");
+            getContentResolver().update(Calls.CONTENT_URI, values, where.toString(),
+                    new String[]{ Integer.toString(Calls.MISSED_TYPE) });
+            mApp.notificationMgr.cancelMissedCallNotification();
+        }
+    }
+}
diff --git a/src/com/android/phone/Constants.java b/src/com/android/phone/Constants.java
new file mode 100644
index 0000000..3e10c3a
--- /dev/null
+++ b/src/com/android/phone/Constants.java
@@ -0,0 +1,146 @@
+/*
+ * 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;
+
+/**
+ * App-wide constants and enums for the phone app.
+ *
+ * Any constants that need to be shared between two or more classes within
+ * the com.android.phone package should be defined here.  (Constants that
+ * are private to only one class can go in that class's .java file.)
+ */
+public class Constants {
+
+    /**
+     * Complete list of error / diagnostic indications we might possibly
+     * need to present to the user.
+     *
+     * This enum is basically a high-level list of the kinds of failures
+     * or "exceptional conditions" that can occur when making a phone
+     * call.  When an error occurs, the CallController stashes away one of
+     * these codes in the InCallUiState.pendingCallStatusCode flag and
+     * launches the InCallScreen; the InCallScreen will then display some
+     * kind of message to the user (usually an error dialog) explaining
+     * what happened.
+     *
+     * The enum values here cover all possible result status / error
+     * conditions that can happen when attempting to place an outgoing
+     * call (see CallController.placeCall() and placeCallInternal()), as
+     * well as some other conditions (like CDMA_CALL_LOST and EXITED_ECM)
+     * that don't technically result from the placeCall() sequence but
+     * still need to be communicated to the user.
+     */
+    public enum CallStatusCode {
+        /**
+         * No error or exceptional condition occurred.
+         * The InCallScreen does not need to display any kind of alert to the user.
+         */
+        SUCCESS,
+
+        /**
+         * Radio is explictly powered off, presumably because the
+         * device is in airplane mode.
+         */
+        POWER_OFF,
+
+        /**
+         * Only emergency numbers are allowed, but we tried to dial
+         * a non-emergency number.
+         */
+        EMERGENCY_ONLY,
+
+        /**
+         * No network connection.
+         */
+        OUT_OF_SERVICE,
+
+        /**
+         * The supplied CALL Intent didn't contain a valid phone number.
+         */
+        NO_PHONE_NUMBER_SUPPLIED,
+
+        /**
+         * Our initial phone number was actually an MMI sequence.
+         */
+        DIALED_MMI,
+
+        /**
+         * We couldn't successfully place the call due to an
+         * unknown failure in the telephony layer.
+         */
+        CALL_FAILED,
+
+        /**
+         * We tried to call a voicemail: URI but the device has no
+         * voicemail number configured.
+         *
+         * When InCallUiState.pendingCallStatusCode is set to this
+         * value, the InCallScreen will bring up a UI explaining what
+         * happened, and allowing the user to go into Settings to fix the
+         * problem.
+         */
+        VOICEMAIL_NUMBER_MISSING,
+
+        /**
+         * 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: this is currently unused, since the "call lost" dialog
+         * needs to be triggered by a *disconnect* event, rather than when
+         * the InCallScreen first comes to the foreground.  For now we use
+         * the needToShowCallLostDialog field for this (see below.)
+         */
+        CDMA_CALL_LOST,
+
+        /**
+         * This status indicates that the call was placed successfully,
+         * but additionally, the InCallScreen needs to display the
+         * "Exiting ECM" dialog.
+         *
+         * (Details: "Emergency callback mode" is a CDMA-specific concept
+         * where the phone disallows data connections over the cell
+         * network for some period of time after you make an emergency
+         * call.  If the phone is in ECM and you dial a non-emergency
+         * number, that automatically *cancels* ECM, but we additionally
+         * need to warn the user that ECM has been canceled (see bug
+         * 4207607.))
+         */
+        EXITED_ECM
+    }
+
+    //
+    // URI schemes
+    //
+
+    public static final String SCHEME_SIP = "sip";
+    public static final String SCHEME_SMS = "sms";
+    public static final String SCHEME_SMSTO = "smsto";
+    public static final String SCHEME_TEL = "tel";
+    public static final String SCHEME_VOICEMAIL = "voicemail";
+
+    //
+    // TODO: Move all the various EXTRA_* and intent action constants here too.
+    // (Currently they're all over the place: InCallScreen,
+    // OutgoingCallBroadcaster, OtaUtils, etc.)
+    //
+
+    // Dtmf tone type setting value for CDMA phone
+    public static final int DTMF_TONE_TYPE_NORMAL = 0;
+    public static final int DTMF_TONE_TYPE_LONG   = 1;
+}
diff --git a/src/com/android/phone/ContactsAsyncHelper.java b/src/com/android/phone/ContactsAsyncHelper.java
new file mode 100644
index 0000000..10a6950
--- /dev/null
+++ b/src/com/android/phone/ContactsAsyncHelper.java
@@ -0,0 +1,358 @@
+/*
+ * 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.app.Notification;
+import android.content.ContentUris;
+import android.content.Context;
+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.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.provider.ContactsContract.Contacts;
+import android.util.Log;
+
+import com.android.internal.telephony.CallerInfo;
+import com.android.internal.telephony.Connection;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Helper class for loading contacts photo asynchronously.
+ */
+public class ContactsAsyncHelper {
+
+    private static final boolean DBG = false;
+    private static final String LOG_TAG = "ContactsAsyncHelper";
+
+    /**
+     * Interface for a WorkerHandler result return.
+     */
+    public interface OnImageLoadCompleteListener {
+        /**
+         * Called when the image load is complete.
+         *
+         * @param token Integer passed in {@link ContactsAsyncHelper#startObtainPhotoAsync(int,
+         * Context, Uri, OnImageLoadCompleteListener, Object)}.
+         * @param photo Drawable object obtained by the async load.
+         * @param photoIcon Bitmap object obtained by the async load.
+         * @param cookie Object passed in {@link ContactsAsyncHelper#startObtainPhotoAsync(int,
+         * Context, Uri, OnImageLoadCompleteListener, Object)}. Can be null iff. the original
+         * cookie is null.
+         */
+        public void onImageLoadComplete(int token, Drawable photo, Bitmap photoIcon,
+                Object cookie);
+    }
+
+    // constants
+    private static final int EVENT_LOAD_IMAGE = 1;
+
+    private final Handler mResultHandler = new Handler() {
+        /** Called when loading is done. */
+        @Override
+        public void handleMessage(Message msg) {
+            WorkerArgs args = (WorkerArgs) msg.obj;
+            switch (msg.arg1) {
+                case EVENT_LOAD_IMAGE:
+                    if (args.listener != null) {
+                        if (DBG) {
+                            Log.d(LOG_TAG, "Notifying listener: " + args.listener.toString() +
+                                    " image: " + args.uri + " completed");
+                        }
+                        args.listener.onImageLoadComplete(msg.what, args.photo, args.photoIcon,
+                                args.cookie);
+                    }
+                    break;
+                default:
+            }
+        }
+    };
+
+    /** Handler run on a worker thread to load photo asynchronously. */
+    private static Handler sThreadHandler;
+
+    /** For forcing the system to call its constructor */
+    @SuppressWarnings("unused")
+    private static ContactsAsyncHelper sInstance;
+
+    static {
+        sInstance = new ContactsAsyncHelper();
+    }
+
+    private static final class WorkerArgs {
+        public Context context;
+        public Uri uri;
+        public Drawable photo;
+        public Bitmap photoIcon;
+        public Object cookie;
+        public OnImageLoadCompleteListener listener;
+    }
+
+    /**
+     * public inner class to help out the ContactsAsyncHelper callers
+     * with tracking the state of the CallerInfo Queries and image
+     * loading.
+     *
+     * Logic contained herein is used to remove the race conditions
+     * that exist as the CallerInfo queries run and mix with the image
+     * loads, which then mix with the Phone state changes.
+     */
+    public static class ImageTracker {
+
+        // Image display states
+        public static final int DISPLAY_UNDEFINED = 0;
+        public static final int DISPLAY_IMAGE = -1;
+        public static final int DISPLAY_DEFAULT = -2;
+
+        // State of the image on the imageview.
+        private CallerInfo mCurrentCallerInfo;
+        private int displayMode;
+
+        public ImageTracker() {
+            mCurrentCallerInfo = null;
+            displayMode = DISPLAY_UNDEFINED;
+        }
+
+        /**
+         * Used to see if the requested call / connection has a
+         * different caller attached to it than the one we currently
+         * have in the CallCard.
+         */
+        public boolean isDifferentImageRequest(CallerInfo ci) {
+            // note, since the connections are around for the lifetime of the
+            // call, and the CallerInfo-related items as well, we can
+            // definitely use a simple != comparison.
+            return (mCurrentCallerInfo != ci);
+        }
+
+        public boolean isDifferentImageRequest(Connection connection) {
+            // if the connection does not exist, see if the
+            // mCurrentCallerInfo is also null to match.
+            if (connection == null) {
+                if (DBG) Log.d(LOG_TAG, "isDifferentImageRequest: connection is null");
+                return (mCurrentCallerInfo != null);
+            }
+            Object o = connection.getUserData();
+
+            // if the call does NOT have a callerInfo attached
+            // then it is ok to query.
+            boolean runQuery = true;
+            if (o instanceof CallerInfo) {
+                runQuery = isDifferentImageRequest((CallerInfo) o);
+            }
+            return runQuery;
+        }
+
+        /**
+         * Simple setter for the CallerInfo object.
+         */
+        public void setPhotoRequest(CallerInfo ci) {
+            mCurrentCallerInfo = ci;
+        }
+
+        /**
+         * Convenience method used to retrieve the URI
+         * representing the Photo file recorded in the attached
+         * CallerInfo Object.
+         */
+        public Uri getPhotoUri() {
+            if (mCurrentCallerInfo != null) {
+                return ContentUris.withAppendedId(Contacts.CONTENT_URI,
+                        mCurrentCallerInfo.person_id);
+            }
+            return null;
+        }
+
+        /**
+         * Simple setter for the Photo state.
+         */
+        public void setPhotoState(int state) {
+            displayMode = state;
+        }
+
+        /**
+         * Simple getter for the Photo state.
+         */
+        public int getPhotoState() {
+            return displayMode;
+        }
+    }
+
+    /**
+     * Thread worker class that handles the task of opening the stream and loading
+     * the images.
+     */
+    private class WorkerHandler extends Handler {
+        public WorkerHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            WorkerArgs args = (WorkerArgs) msg.obj;
+
+            switch (msg.arg1) {
+                case EVENT_LOAD_IMAGE:
+                    InputStream inputStream = null;
+                    try {
+                        try {
+                            inputStream = Contacts.openContactPhotoInputStream(
+                                    args.context.getContentResolver(), args.uri, true);
+                        } catch (Exception e) {
+                            Log.e(LOG_TAG, "Error opening photo input stream", e);
+                        }
+
+                        if (inputStream != null) {
+                            args.photo = Drawable.createFromStream(inputStream,
+                                    args.uri.toString());
+
+                            // This assumes Drawable coming from contact database is usually
+                            // BitmapDrawable and thus we can have (down)scaled version of it.
+                            args.photoIcon = getPhotoIconWhenAppropriate(args.context, args.photo);
+
+                            if (DBG) {
+                                Log.d(LOG_TAG, "Loading image: " + msg.arg1 +
+                                        " token: " + msg.what + " image URI: " + args.uri);
+                            }
+                        } else {
+                            args.photo = null;
+                            args.photoIcon = null;
+                            if (DBG) {
+                                Log.d(LOG_TAG, "Problem with image: " + msg.arg1 +
+                                        " token: " + msg.what + " image URI: " + args.uri +
+                                        ", using default image.");
+                            }
+                        }
+                    } finally {
+                        if (inputStream != null) {
+                            try {
+                                inputStream.close();
+                            } catch (IOException e) {
+                                Log.e(LOG_TAG, "Unable to close input stream.", e);
+                            }
+                        }
+                    }
+                    break;
+                default:
+            }
+
+            // send the reply to the enclosing class.
+            Message reply = ContactsAsyncHelper.this.mResultHandler.obtainMessage(msg.what);
+            reply.arg1 = msg.arg1;
+            reply.obj = msg.obj;
+            reply.sendToTarget();
+        }
+
+        /**
+         * Returns a Bitmap object suitable for {@link Notification}'s large icon. This might
+         * return null when the given Drawable isn't BitmapDrawable, or if the system fails to
+         * create a scaled Bitmap for the Drawable.
+         */
+        private Bitmap getPhotoIconWhenAppropriate(Context context, Drawable photo) {
+            if (!(photo instanceof BitmapDrawable)) {
+                return null;
+            }
+            int iconSize = context.getResources()
+                    .getDimensionPixelSize(R.dimen.notification_icon_size);
+            Bitmap orgBitmap = ((BitmapDrawable) photo).getBitmap();
+            int orgWidth = orgBitmap.getWidth();
+            int orgHeight = orgBitmap.getHeight();
+            int longerEdge = orgWidth > orgHeight ? orgWidth : orgHeight;
+            // We want downscaled one only when the original icon is too big.
+            if (longerEdge > iconSize) {
+                float ratio = ((float) longerEdge) / iconSize;
+                int newWidth = (int) (orgWidth / ratio);
+                int newHeight = (int) (orgHeight / ratio);
+                // If the longer edge is much longer than the shorter edge, the latter may
+                // become 0 which will cause a crash.
+                if (newWidth <= 0 || newHeight <= 0) {
+                    Log.w(LOG_TAG, "Photo icon's width or height become 0.");
+                    return null;
+                }
+
+                // It is sure ratio >= 1.0f in any case and thus the newly created Bitmap
+                // should be smaller than the original.
+                return Bitmap.createScaledBitmap(orgBitmap, newWidth, newHeight, true);
+            } else {
+                return orgBitmap;
+            }
+        }
+    }
+
+    /**
+     * Private constructor for static class
+     */
+    private ContactsAsyncHelper() {
+        HandlerThread thread = new HandlerThread("ContactsAsyncWorker");
+        thread.start();
+        sThreadHandler = new WorkerHandler(thread.getLooper());
+    }
+
+    /**
+     * Starts an asynchronous image load. After finishing the load,
+     * {@link OnImageLoadCompleteListener#onImageLoadComplete(int, Drawable, Bitmap, Object)}
+     * will be called.
+     *
+     * @param token Arbitrary integer which will be returned as the first argument of
+     * {@link OnImageLoadCompleteListener#onImageLoadComplete(int, Drawable, Bitmap, Object)}
+     * @param context Context object used to do the time-consuming operation.
+     * @param personUri Uri to be used to fetch the photo
+     * @param listener Callback object which will be used when the asynchronous load is done.
+     * Can be null, which means only the asynchronous load is done while there's no way to
+     * obtain the loaded photos.
+     * @param cookie Arbitrary object the caller wants to remember, which will become the
+     * fourth argument of {@link OnImageLoadCompleteListener#onImageLoadComplete(int, Drawable,
+     * Bitmap, Object)}. Can be null, at which the callback will also has null for the argument.
+     */
+    public static final void startObtainPhotoAsync(int token, Context context, Uri personUri,
+            OnImageLoadCompleteListener listener, Object cookie) {
+        // in case the source caller info is null, the URI will be null as well.
+        // just update using the placeholder image in this case.
+        if (personUri == null) {
+            Log.wtf(LOG_TAG, "Uri is missing");
+            return;
+        }
+
+        // Added additional Cookie field in the callee to handle arguments
+        // sent to the callback function.
+
+        // setup arguments
+        WorkerArgs args = new WorkerArgs();
+        args.cookie = cookie;
+        args.context = context;
+        args.uri = personUri;
+        args.listener = listener;
+
+        // setup message arguments
+        Message msg = sThreadHandler.obtainMessage(token);
+        msg.arg1 = EVENT_LOAD_IMAGE;
+        msg.obj = args;
+
+        if (DBG) Log.d(LOG_TAG, "Begin loading image: " + args.uri +
+                ", displaying default image for now.");
+
+        // notify the thread to begin working
+        sThreadHandler.sendMessage(msg);
+    }
+
+
+}
diff --git a/src/com/android/phone/DTMFTwelveKeyDialer.java b/src/com/android/phone/DTMFTwelveKeyDialer.java
new file mode 100644
index 0000000..4afac55
--- /dev/null
+++ b/src/com/android/phone/DTMFTwelveKeyDialer.java
@@ -0,0 +1,1119 @@
+/*
+ * 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.ViewConfiguration;
+import android.view.View.OnHoverListener;
+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 com.android.internal.telephony.TelephonyCapabilities;
+
+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
new file mode 100644
index 0000000..e0502b7
--- /dev/null
+++ b/src/com/android/phone/DTMFTwelveKeyDialerView.java
@@ -0,0 +1,87 @@
+/*
+ * 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/DefaultRingtonePreference.java b/src/com/android/phone/DefaultRingtonePreference.java
new file mode 100644
index 0000000..8205fd0
--- /dev/null
+++ b/src/com/android/phone/DefaultRingtonePreference.java
@@ -0,0 +1,56 @@
+/*
+ * 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.content.Context;
+import android.content.Intent;
+import android.media.RingtoneManager;
+import android.net.Uri;
+import android.preference.RingtonePreference;
+import android.util.AttributeSet;
+
+/**
+ * RingtonePreference which doesn't show default ringtone setting.
+ *
+ * @see com.android.settings.DefaultRingtonePreference
+ */
+public class DefaultRingtonePreference extends RingtonePreference {
+    public DefaultRingtonePreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    protected void onPrepareRingtonePickerIntent(Intent ringtonePickerIntent) {
+        super.onPrepareRingtonePickerIntent(ringtonePickerIntent);
+
+        /*
+         * Since this preference is for choosing the default ringtone, it
+         * doesn't make sense to show a 'Default' item.
+         */
+        ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, false);
+    }
+
+    @Override
+    protected void onSaveRingtone(Uri ringtoneUri) {
+        RingtoneManager.setActualDefaultRingtoneUri(getContext(), getRingtoneType(), ringtoneUri);
+    }
+
+    @Override
+    protected Uri onRestoreRingtone() {
+        return RingtoneManager.getActualDefaultRingtoneUri(getContext(), getRingtoneType());
+    }
+}
diff --git a/src/com/android/phone/DeleteFdnContactScreen.java b/src/com/android/phone/DeleteFdnContactScreen.java
new file mode 100644
index 0000000..074078c
--- /dev/null
+++ b/src/com/android/phone/DeleteFdnContactScreen.java
@@ -0,0 +1,189 @@
+/*
+ * 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.app.Activity;
+import android.content.AsyncQueryHandler;
+import android.content.ContentResolver;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.Window;
+import android.widget.Toast;
+
+import static android.view.Window.PROGRESS_VISIBILITY_OFF;
+import static android.view.Window.PROGRESS_VISIBILITY_ON;
+
+/**
+ * Activity to let the user delete an FDN contact.
+ */
+public class DeleteFdnContactScreen extends Activity {
+    private static final String LOG_TAG = PhoneGlobals.LOG_TAG;
+    private static final boolean DBG = false;
+
+    private static final String INTENT_EXTRA_NAME = "name";
+    private static final String INTENT_EXTRA_NUMBER = "number";
+
+    private static final int PIN2_REQUEST_CODE = 100;
+
+    private String mName;
+    private String mNumber;
+    private String mPin2;
+
+    protected QueryHandler mQueryHandler;
+
+    private Handler mHandler = new Handler();
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        resolveIntent();
+
+        authenticatePin2();
+
+        getWindow().requestFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
+        setContentView(R.layout.delete_fdn_contact_screen);
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
+        if (DBG) log("onActivityResult");
+
+        switch (requestCode) {
+            case PIN2_REQUEST_CODE:
+                Bundle extras = (intent != null) ? intent.getExtras() : null;
+                if (extras != null) {
+                    mPin2 = extras.getString("pin2");
+                    showStatus(getResources().getText(
+                            R.string.deleting_fdn_contact));
+                    deleteContact();
+                } else {
+                    // if they cancelled, then we just cancel too.
+                    if (DBG) log("onActivityResult: CANCELLED");
+                    displayProgress(false);
+                    finish();
+                }
+                break;
+        }
+    }
+
+    private void resolveIntent() {
+        Intent intent = getIntent();
+
+        mName =  intent.getStringExtra(INTENT_EXTRA_NAME);
+        mNumber =  intent.getStringExtra(INTENT_EXTRA_NUMBER);
+
+        if (TextUtils.isEmpty(mNumber)) {
+            finish();
+        }
+    }
+
+    private void deleteContact() {
+        StringBuilder buf = new StringBuilder();
+        if (TextUtils.isEmpty(mName)) {
+            buf.append("number='");
+        } else {
+            buf.append("tag='");
+            buf.append(mName);
+            buf.append("' AND number='");
+        }
+        buf.append(mNumber);
+        buf.append("' AND pin2='");
+        buf.append(mPin2);
+        buf.append("'");
+
+        Uri uri = Uri.parse("content://icc/fdn");
+
+        mQueryHandler = new QueryHandler(getContentResolver());
+        mQueryHandler.startDelete(0, null, uri, buf.toString(), null);
+        displayProgress(true);
+    }
+
+    private void authenticatePin2() {
+        Intent intent = new Intent();
+        intent.setClass(this, GetPin2Screen.class);
+        startActivityForResult(intent, PIN2_REQUEST_CODE);
+    }
+
+    private void displayProgress(boolean flag) {
+        getWindow().setFeatureInt(
+                Window.FEATURE_INDETERMINATE_PROGRESS,
+                flag ? PROGRESS_VISIBILITY_ON : PROGRESS_VISIBILITY_OFF);
+    }
+
+    // Replace the status field with a toast to make things appear similar
+    // to the rest of the settings.  Removed the useless status field.
+    private void showStatus(CharSequence statusMsg) {
+        if (statusMsg != null) {
+            Toast.makeText(this, statusMsg, Toast.LENGTH_SHORT)
+            .show();
+        }
+    }
+
+    private void handleResult(boolean success) {
+        if (success) {
+            if (DBG) log("handleResult: success!");
+            showStatus(getResources().getText(R.string.fdn_contact_deleted));
+        } else {
+            if (DBG) log("handleResult: failed!");
+            showStatus(getResources().getText(R.string.pin2_invalid));
+        }
+
+        mHandler.postDelayed(new Runnable() {
+            @Override
+            public void run() {
+                finish();
+            }
+        }, 2000);
+
+    }
+
+    private class QueryHandler extends AsyncQueryHandler {
+        public QueryHandler(ContentResolver cr) {
+            super(cr);
+        }
+
+        @Override
+        protected void onQueryComplete(int token, Object cookie, Cursor c) {
+        }
+
+        @Override
+        protected void onInsertComplete(int token, Object cookie, Uri uri) {
+        }
+
+        @Override
+        protected void onUpdateComplete(int token, Object cookie, int result) {
+        }
+
+        @Override
+        protected void onDeleteComplete(int token, Object cookie, int result) {
+            if (DBG) log("onDeleteComplete");
+            displayProgress(false);
+            handleResult(result > 0);
+        }
+
+    }
+
+    private void log(String msg) {
+        Log.d(LOG_TAG, "[DeleteFdnContact] " + msg);
+    }
+}
diff --git a/src/com/android/phone/EditFdnContactScreen.java b/src/com/android/phone/EditFdnContactScreen.java
new file mode 100644
index 0000000..2992b7d
--- /dev/null
+++ b/src/com/android/phone/EditFdnContactScreen.java
@@ -0,0 +1,458 @@
+/*
+ * 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 static android.view.Window.PROGRESS_VISIBILITY_OFF;
+import static android.view.Window.PROGRESS_VISIBILITY_ON;
+
+import android.app.Activity;
+import android.content.AsyncQueryHandler;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.provider.Contacts.PeopleColumns;
+import android.provider.Contacts.PhonesColumns;
+import android.telephony.PhoneNumberUtils;
+import android.text.Selection;
+import android.text.Spannable;
+import android.text.TextUtils;
+import android.text.method.DialerKeyListener;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.Window;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+
+/**
+ * Activity to let the user add or edit an FDN contact.
+ */
+public class EditFdnContactScreen extends Activity {
+    private static final String LOG_TAG = PhoneGlobals.LOG_TAG;
+    private static final boolean DBG = false;
+
+    // Menu item codes
+    private static final int MENU_IMPORT = 1;
+    private static final int MENU_DELETE = 2;
+
+    private static final String INTENT_EXTRA_NAME = "name";
+    private static final String INTENT_EXTRA_NUMBER = "number";
+
+    private static final int PIN2_REQUEST_CODE = 100;
+
+    private String mName;
+    private String mNumber;
+    private String mPin2;
+    private boolean mAddContact;
+    private QueryHandler mQueryHandler;
+
+    private EditText mNameField;
+    private EditText mNumberField;
+    private LinearLayout mPinFieldContainer;
+    private Button mButton;
+
+    private Handler mHandler = new Handler();
+
+    /**
+     * Constants used in importing from contacts
+     */
+    /** request code when invoking subactivity */
+    private static final int CONTACTS_PICKER_CODE = 200;
+    /** projection for phone number query */
+    private static final String NUM_PROJECTION[] = {PeopleColumns.DISPLAY_NAME,
+        PhonesColumns.NUMBER};
+    /** static intent to invoke phone number picker */
+    private static final Intent CONTACT_IMPORT_INTENT;
+    static {
+        CONTACT_IMPORT_INTENT = new Intent(Intent.ACTION_GET_CONTENT);
+        CONTACT_IMPORT_INTENT.setType(android.provider.Contacts.Phones.CONTENT_ITEM_TYPE);
+    }
+    /** flag to track saving state */
+    private boolean mDataBusy;
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        resolveIntent();
+
+        getWindow().requestFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
+        setContentView(R.layout.edit_fdn_contact_screen);
+        setupView();
+        setTitle(mAddContact ?
+                R.string.add_fdn_contact : R.string.edit_fdn_contact);
+
+        displayProgress(false);
+    }
+
+    /**
+     * We now want to bring up the pin request screen AFTER the
+     * contact information is displayed, to help with user
+     * experience.
+     *
+     * Also, process the results from the contact picker.
+     */
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
+        if (DBG) log("onActivityResult request:" + requestCode + " result:" + resultCode);
+
+        switch (requestCode) {
+            case PIN2_REQUEST_CODE:
+                Bundle extras = (intent != null) ? intent.getExtras() : null;
+                if (extras != null) {
+                    mPin2 = extras.getString("pin2");
+                    if (mAddContact) {
+                        addContact();
+                    } else {
+                        updateContact();
+                    }
+                } else if (resultCode != RESULT_OK) {
+                    // if they cancelled, then we just cancel too.
+                    if (DBG) log("onActivityResult: cancelled.");
+                    finish();
+                }
+                break;
+
+            // look for the data associated with this number, and update
+            // the display with it.
+            case CONTACTS_PICKER_CODE:
+                if (resultCode != RESULT_OK) {
+                    if (DBG) log("onActivityResult: cancelled.");
+                    return;
+                }
+                Cursor cursor = null;
+                try {
+                    cursor = getContentResolver().query(intent.getData(),
+                        NUM_PROJECTION, null, null, null);
+                    if ((cursor == null) || (!cursor.moveToFirst())) {
+                        Log.w(LOG_TAG,"onActivityResult: bad contact data, no results found.");
+                        return;
+                    }
+                    mNameField.setText(cursor.getString(0));
+                    mNumberField.setText(cursor.getString(1));
+                } finally {
+                    if (cursor != null) {
+                        cursor.close();
+                    }
+                }
+                break;
+        }
+    }
+
+    /**
+     * Overridden to display the import and delete commands.
+     */
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+
+        Resources r = getResources();
+
+        // Added the icons to the context menu
+        menu.add(0, MENU_IMPORT, 0, r.getString(R.string.importToFDNfromContacts))
+                .setIcon(R.drawable.ic_menu_contact);
+        menu.add(0, MENU_DELETE, 0, r.getString(R.string.menu_delete))
+                .setIcon(android.R.drawable.ic_menu_delete);
+        return true;
+    }
+
+    /**
+     * Allow the menu to be opened ONLY if we're not busy.
+     */
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        boolean result = super.onPrepareOptionsMenu(menu);
+        return mDataBusy ? false : result;
+    }
+
+    /**
+     * Overridden to allow for handling of delete and import.
+     */
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case MENU_IMPORT:
+                startActivityForResult(CONTACT_IMPORT_INTENT, CONTACTS_PICKER_CODE);
+                return true;
+
+            case MENU_DELETE:
+                deleteSelected();
+                return true;
+        }
+
+        return super.onOptionsItemSelected(item);
+    }
+
+    private void resolveIntent() {
+        Intent intent = getIntent();
+
+        mName =  intent.getStringExtra(INTENT_EXTRA_NAME);
+        mNumber =  intent.getStringExtra(INTENT_EXTRA_NUMBER);
+
+        mAddContact = TextUtils.isEmpty(mNumber);
+    }
+
+    /**
+     * We have multiple layouts, one to indicate that the user needs to
+     * open the keyboard to enter information (if the keybord is hidden).
+     * So, we need to make sure that the layout here matches that in the
+     * layout file.
+     */
+    private void setupView() {
+        mNameField = (EditText) findViewById(R.id.fdn_name);
+        if (mNameField != null) {
+            mNameField.setOnFocusChangeListener(mOnFocusChangeHandler);
+            mNameField.setOnClickListener(mClicked);
+        }
+
+        mNumberField = (EditText) findViewById(R.id.fdn_number);
+        if (mNumberField != null) {
+            mNumberField.setKeyListener(DialerKeyListener.getInstance());
+            mNumberField.setOnFocusChangeListener(mOnFocusChangeHandler);
+            mNumberField.setOnClickListener(mClicked);
+        }
+
+        if (!mAddContact) {
+            if (mNameField != null) {
+                mNameField.setText(mName);
+            }
+            if (mNumberField != null) {
+                mNumberField.setText(mNumber);
+            }
+        }
+
+        mButton = (Button) findViewById(R.id.button);
+        if (mButton != null) {
+            mButton.setOnClickListener(mClicked);
+        }
+
+        mPinFieldContainer = (LinearLayout) findViewById(R.id.pinc);
+
+    }
+
+    private String getNameFromTextField() {
+        return mNameField.getText().toString();
+    }
+
+    private String getNumberFromTextField() {
+        return mNumberField.getText().toString();
+    }
+
+    private Uri getContentURI() {
+        return Uri.parse("content://icc/fdn");
+    }
+
+    /**
+      * @param number is voice mail number
+      * @return true if number length is less than 20-digit limit
+      *
+      * TODO: Fix this logic.
+      */
+     private boolean isValidNumber(String number) {
+         return (number.length() <= 20);
+     }
+
+
+    private void addContact() {
+        if (DBG) log("addContact");
+
+        final String number = PhoneNumberUtils.convertAndStrip(getNumberFromTextField());
+
+        if (!isValidNumber(number)) {
+            handleResult(false, true);
+            return;
+        }
+
+        Uri uri = getContentURI();
+
+        ContentValues bundle = new ContentValues(3);
+        bundle.put("tag", getNameFromTextField());
+        bundle.put("number", number);
+        bundle.put("pin2", mPin2);
+
+        mQueryHandler = new QueryHandler(getContentResolver());
+        mQueryHandler.startInsert(0, null, uri, bundle);
+        displayProgress(true);
+        showStatus(getResources().getText(R.string.adding_fdn_contact));
+    }
+
+    private void updateContact() {
+        if (DBG) log("updateContact");
+
+        final String name = getNameFromTextField();
+        final String number = PhoneNumberUtils.convertAndStrip(getNumberFromTextField());
+
+        if (!isValidNumber(number)) {
+            handleResult(false, true);
+            return;
+        }
+        Uri uri = getContentURI();
+
+        ContentValues bundle = new ContentValues();
+        bundle.put("tag", mName);
+        bundle.put("number", mNumber);
+        bundle.put("newTag", name);
+        bundle.put("newNumber", number);
+        bundle.put("pin2", mPin2);
+
+        mQueryHandler = new QueryHandler(getContentResolver());
+        mQueryHandler.startUpdate(0, null, uri, bundle, null, null);
+        displayProgress(true);
+        showStatus(getResources().getText(R.string.updating_fdn_contact));
+    }
+
+    /**
+     * Handle the delete command, based upon the state of the Activity.
+     */
+    private void deleteSelected() {
+        // delete ONLY if this is NOT a new contact.
+        if (!mAddContact) {
+            Intent intent = new Intent();
+            intent.setClass(this, DeleteFdnContactScreen.class);
+            intent.putExtra(INTENT_EXTRA_NAME, mName);
+            intent.putExtra(INTENT_EXTRA_NUMBER, mNumber);
+            startActivity(intent);
+        }
+        finish();
+    }
+
+    private void authenticatePin2() {
+        Intent intent = new Intent();
+        intent.setClass(this, GetPin2Screen.class);
+        startActivityForResult(intent, PIN2_REQUEST_CODE);
+    }
+
+    private void displayProgress(boolean flag) {
+        // indicate we are busy.
+        mDataBusy = flag;
+        getWindow().setFeatureInt(
+                Window.FEATURE_INDETERMINATE_PROGRESS,
+                mDataBusy ? PROGRESS_VISIBILITY_ON : PROGRESS_VISIBILITY_OFF);
+        // make sure we don't allow calls to save when we're
+        // not ready for them.
+        mButton.setClickable(!mDataBusy);
+    }
+
+    /**
+     * Removed the status field, with preference to displaying a toast
+     * to match the rest of settings UI.
+     */
+    private void showStatus(CharSequence statusMsg) {
+        if (statusMsg != null) {
+            Toast.makeText(this, statusMsg, Toast.LENGTH_LONG)
+                    .show();
+        }
+    }
+
+    private void handleResult(boolean success, boolean invalidNumber) {
+        if (success) {
+            if (DBG) log("handleResult: success!");
+            showStatus(getResources().getText(mAddContact ?
+                    R.string.fdn_contact_added : R.string.fdn_contact_updated));
+        } else {
+            if (DBG) log("handleResult: failed!");
+            if (invalidNumber) {
+                showStatus(getResources().getText(R.string.fdn_invalid_number));
+            } else {
+                // There's no way to know whether the failure is due to incorrect PIN2 or
+                // an inappropriate phone number.
+                showStatus(getResources().getText(R.string.pin2_or_fdn_invalid));
+            }
+        }
+
+        mHandler.postDelayed(new Runnable() {
+            @Override
+            public void run() {
+                finish();
+            }
+        }, 2000);
+
+    }
+
+    private final View.OnClickListener mClicked = new View.OnClickListener() {
+        @Override
+        public void onClick(View v) {
+            if (mPinFieldContainer.getVisibility() != View.VISIBLE) {
+                return;
+            }
+
+            if (v == mNameField) {
+                mNumberField.requestFocus();
+            } else if (v == mNumberField) {
+                mButton.requestFocus();
+            } else if (v == mButton) {
+                // Authenticate the pin AFTER the contact information
+                // is entered, and if we're not busy.
+                if (!mDataBusy) {
+                    authenticatePin2();
+                }
+            }
+        }
+    };
+
+    private final View.OnFocusChangeListener mOnFocusChangeHandler =
+            new View.OnFocusChangeListener() {
+        @Override
+        public void onFocusChange(View v, boolean hasFocus) {
+            if (hasFocus) {
+                TextView textView = (TextView) v;
+                Selection.selectAll((Spannable) textView.getText());
+            }
+        }
+    };
+
+    private class QueryHandler extends AsyncQueryHandler {
+        public QueryHandler(ContentResolver cr) {
+            super(cr);
+        }
+
+        @Override
+        protected void onQueryComplete(int token, Object cookie, Cursor c) {
+        }
+
+        @Override
+        protected void onInsertComplete(int token, Object cookie, Uri uri) {
+            if (DBG) log("onInsertComplete");
+            displayProgress(false);
+            handleResult(uri != null, false);
+        }
+
+        @Override
+        protected void onUpdateComplete(int token, Object cookie, int result) {
+            if (DBG) log("onUpdateComplete");
+            displayProgress(false);
+            handleResult(result > 0, false);
+        }
+
+        @Override
+        protected void onDeleteComplete(int token, Object cookie, int result) {
+        }
+    }
+
+    private void log(String msg) {
+        Log.d(LOG_TAG, "[EditFdnContact] " + msg);
+    }
+}
diff --git a/src/com/android/phone/EditPhoneNumberPreference.java b/src/com/android/phone/EditPhoneNumberPreference.java
new file mode 100644
index 0000000..86671a8
--- /dev/null
+++ b/src/com/android/phone/EditPhoneNumberPreference.java
@@ -0,0 +1,499 @@
+/*
+ * 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.app.Activity;
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.res.TypedArray;
+import android.preference.EditTextPreference;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.telephony.PhoneNumberUtils;
+import android.text.TextUtils;
+import android.text.method.ArrowKeyMovementMethod;
+import android.text.method.DialerKeyListener;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.EditText;
+import android.widget.ImageButton;
+import android.widget.TextView;
+
+public class EditPhoneNumberPreference extends EditTextPreference {
+
+    //allowed modes for this preference.
+    /** simple confirmation (OK / CANCEL) */
+    private static final int CM_CONFIRM = 0;
+    /** toggle [(ENABLE / CANCEL) or (DISABLE / CANCEL)], use isToggled() to see requested state.*/
+    private static final int CM_ACTIVATION = 1;
+
+    private int mConfirmationMode;
+
+    //String constants used in storing the value of the preference
+    // The preference is backed by a string that holds the encoded value, which reads:
+    //  <VALUE_ON | VALUE_OFF><VALUE_SEPARATOR><mPhoneNumber>
+    // for example, an enabled preference with a number of 6502345678 would read:
+    //  "1:6502345678"
+    private static final String VALUE_SEPARATOR = ":";
+    private static final String VALUE_OFF = "0";
+    private static final String VALUE_ON = "1";
+
+    //UI layout
+    private ImageButton mContactPickButton;
+
+    //Listeners
+    /** Called when focus is changed between fields */
+    private View.OnFocusChangeListener mDialogFocusChangeListener;
+    /** Called when the Dialog is closed. */
+    private OnDialogClosedListener mDialogOnClosedListener;
+    /**
+     * Used to indicate that we are going to request for a
+     * default number. for the dialog.
+     */
+    private GetDefaultNumberListener mGetDefaultNumberListener;
+
+    //Activity values
+    private Activity mParentActivity;
+    private Intent mContactListIntent;
+    /** Arbitrary activity-assigned preference id value */
+    private int mPrefId;
+
+    //similar to toggle preference
+    private CharSequence mEnableText;
+    private CharSequence mDisableText;
+    private CharSequence mChangeNumberText;
+    private CharSequence mSummaryOn;
+    private CharSequence mSummaryOff;
+
+    // button that was clicked on dialog close.
+    private int mButtonClicked;
+
+    //relevant (parsed) value of the mText
+    private String mPhoneNumber;
+    private boolean mChecked;
+
+
+    /**
+     * Interface for the dialog closed listener, related to
+     * DialogPreference.onDialogClosed(), except we also pass in a buttonClicked
+     * value indicating which of the three possible buttons were pressed.
+     */
+    interface OnDialogClosedListener {
+        void onDialogClosed(EditPhoneNumberPreference preference, int buttonClicked);
+    }
+
+    /**
+     * Interface for the default number setting listener.  Handles requests for
+     * the default display number for the dialog.
+     */
+    interface GetDefaultNumberListener {
+        /**
+         * Notify that we are looking for a default display value.
+         * @return null if there is no contribution from this interface,
+         *  indicating that the orignal value of mPhoneNumber should be
+         *  displayed unchanged.
+         */
+        String onGetDefaultNumber(EditPhoneNumberPreference preference);
+    }
+
+    /*
+     * Constructors
+     */
+    public EditPhoneNumberPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        setDialogLayoutResource(R.layout.pref_dialog_editphonenumber);
+
+        //create intent to bring up contact list
+        mContactListIntent = new Intent(Intent.ACTION_GET_CONTENT);
+        mContactListIntent.setType(Phone.CONTENT_ITEM_TYPE);
+
+        //get the edit phone number default settings
+        TypedArray a = context.obtainStyledAttributes(attrs,
+                R.styleable.EditPhoneNumberPreference, 0, R.style.EditPhoneNumberPreference);
+        mEnableText = a.getString(R.styleable.EditPhoneNumberPreference_enableButtonText);
+        mDisableText = a.getString(R.styleable.EditPhoneNumberPreference_disableButtonText);
+        mChangeNumberText = a.getString(R.styleable.EditPhoneNumberPreference_changeNumButtonText);
+        mConfirmationMode = a.getInt(R.styleable.EditPhoneNumberPreference_confirmMode, 0);
+        a.recycle();
+
+        //get the summary settings, use CheckBoxPreference as the standard.
+        a = context.obtainStyledAttributes(attrs, android.R.styleable.CheckBoxPreference, 0, 0);
+        mSummaryOn = a.getString(android.R.styleable.CheckBoxPreference_summaryOn);
+        mSummaryOff = a.getString(android.R.styleable.CheckBoxPreference_summaryOff);
+        a.recycle();
+    }
+
+    public EditPhoneNumberPreference(Context context) {
+        this(context, null);
+    }
+
+
+    /*
+     * Methods called on UI bindings
+     */
+    @Override
+    //called when we're binding the view to the preference.
+    protected void onBindView(View view) {
+        super.onBindView(view);
+
+        // Sync the summary view
+        TextView summaryView = (TextView) view.findViewById(android.R.id.summary);
+        if (summaryView != null) {
+            CharSequence sum;
+            int vis;
+
+            //set summary depending upon mode
+            if (mConfirmationMode == CM_ACTIVATION) {
+                if (mChecked) {
+                    sum = (mSummaryOn == null) ? getSummary() : mSummaryOn;
+                } else {
+                    sum = (mSummaryOff == null) ? getSummary() : mSummaryOff;
+                }
+            } else {
+                sum = getSummary();
+            }
+
+            if (sum != null) {
+                summaryView.setText(sum);
+                vis = View.VISIBLE;
+            } else {
+                vis = View.GONE;
+            }
+
+            if (vis != summaryView.getVisibility()) {
+                summaryView.setVisibility(vis);
+            }
+        }
+    }
+
+    //called when we're binding the dialog to the preference's view.
+    @Override
+    protected void onBindDialogView(View view) {
+        // default the button clicked to be the cancel button.
+        mButtonClicked = DialogInterface.BUTTON_NEGATIVE;
+
+        super.onBindDialogView(view);
+
+        //get the edittext component within the number field
+        EditText editText = getEditText();
+        //get the contact pick button within the number field
+        mContactPickButton = (ImageButton) view.findViewById(R.id.select_contact);
+
+        //setup number entry
+        if (editText != null) {
+            // see if there is a means to get a default number,
+            // and set it accordingly.
+            if (mGetDefaultNumberListener != null) {
+                String defaultNumber = mGetDefaultNumberListener.onGetDefaultNumber(this);
+                if (defaultNumber != null) {
+                    mPhoneNumber = defaultNumber;
+                }
+            }
+            editText.setText(mPhoneNumber);
+            editText.setMovementMethod(ArrowKeyMovementMethod.getInstance());
+            editText.setKeyListener(DialerKeyListener.getInstance());
+            editText.setOnFocusChangeListener(mDialogFocusChangeListener);
+        }
+
+        //set contact picker
+        if (mContactPickButton != null) {
+            mContactPickButton.setOnClickListener(new View.OnClickListener() {
+                public void onClick(View v) {
+                    if (mParentActivity != null) {
+                        mParentActivity.startActivityForResult(mContactListIntent, mPrefId);
+                    }
+                }
+            });
+        }
+    }
+
+    /**
+     * Overriding EditTextPreference's onAddEditTextToDialogView.
+     *
+     * This method attaches the EditText to the container specific to this
+     * preference's dialog layout.
+     */
+    @Override
+    protected void onAddEditTextToDialogView(View dialogView, EditText editText) {
+
+        // look for the container object
+        ViewGroup container = (ViewGroup) dialogView
+                .findViewById(R.id.edit_container);
+
+        // add the edittext to the container.
+        if (container != null) {
+            container.addView(editText, ViewGroup.LayoutParams.MATCH_PARENT,
+                    ViewGroup.LayoutParams.WRAP_CONTENT);
+        }
+    }
+
+    //control the appearance of the dialog depending upon the mode.
+    @Override
+    protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
+        // modified so that we just worry about the buttons being
+        // displayed, since there is no need to hide the edittext
+        // field anymore.
+        if (mConfirmationMode == CM_ACTIVATION) {
+            if (mChecked) {
+                builder.setPositiveButton(mChangeNumberText, this);
+                builder.setNeutralButton(mDisableText, this);
+            } else {
+                builder.setPositiveButton(null, null);
+                builder.setNeutralButton(mEnableText, this);
+            }
+        }
+        // set the call icon on the title.
+        builder.setIcon(R.mipmap.ic_launcher_phone);
+    }
+
+
+    /*
+     * Listeners and other state setting methods
+     */
+    //set the on focus change listener to be assigned to the Dialog's edittext field.
+    public void setDialogOnFocusChangeListener(View.OnFocusChangeListener l) {
+        mDialogFocusChangeListener = l;
+    }
+
+    //set the listener to be called wht the dialog is closed.
+    public void setDialogOnClosedListener(OnDialogClosedListener l) {
+        mDialogOnClosedListener = l;
+    }
+
+    //set the link back to the parent activity, so that we may run the contact picker.
+    public void setParentActivity(Activity parent, int identifier) {
+        mParentActivity = parent;
+        mPrefId = identifier;
+        mGetDefaultNumberListener = null;
+    }
+
+    //set the link back to the parent activity, so that we may run the contact picker.
+    //also set the default number listener.
+    public void setParentActivity(Activity parent, int identifier, GetDefaultNumberListener l) {
+        mParentActivity = parent;
+        mPrefId = identifier;
+        mGetDefaultNumberListener = l;
+    }
+
+    /*
+     * Notification handlers
+     */
+    //Notify the preference that the pick activity is complete.
+    public void onPickActivityResult(String pickedValue) {
+        EditText editText = getEditText();
+        if (editText != null) {
+            editText.setText(pickedValue);
+        }
+    }
+
+    //called when the dialog is clicked.
+    @Override
+    public void onClick(DialogInterface dialog, int which) {
+        // The neutral button (button3) is always the toggle.
+        if ((mConfirmationMode == CM_ACTIVATION) && (which == DialogInterface.BUTTON_NEUTRAL)) {
+            //flip the toggle if we are in the correct mode.
+            setToggled(!isToggled());
+        }
+        // record the button that was clicked.
+        mButtonClicked = which;
+        super.onClick(dialog, which);
+    }
+
+    @Override
+    //When the dialog is closed, perform the relevant actions, including setting
+    // phone numbers and calling the close action listener.
+    protected void onDialogClosed(boolean positiveResult) {
+        // A positive result is technically either button1 or button3.
+        if ((mButtonClicked == DialogInterface.BUTTON_POSITIVE) ||
+                (mButtonClicked == DialogInterface.BUTTON_NEUTRAL)){
+            setPhoneNumber(getEditText().getText().toString());
+            super.onDialogClosed(positiveResult);
+            setText(getStringValue());
+        } else {
+            super.onDialogClosed(positiveResult);
+        }
+
+        // send the clicked button over to the listener.
+        if (mDialogOnClosedListener != null) {
+            mDialogOnClosedListener.onDialogClosed(this, mButtonClicked);
+        }
+    }
+
+
+    /*
+     * Toggle handling code.
+     */
+    //return the toggle value.
+    public boolean isToggled() {
+        return mChecked;
+    }
+
+    //set the toggle value.
+    // return the current preference to allow for chaining preferences.
+    public EditPhoneNumberPreference setToggled(boolean checked) {
+        mChecked = checked;
+        setText(getStringValue());
+        notifyChanged();
+
+        return this;
+    }
+
+
+    /**
+     * Phone number handling code
+     */
+    public String getPhoneNumber() {
+        // return the phone number, after it has been stripped of all
+        // irrelevant text.
+        return PhoneNumberUtils.stripSeparators(mPhoneNumber);
+    }
+
+    /** The phone number including any formatting characters */
+    protected String getRawPhoneNumber() {
+        return mPhoneNumber;
+    }
+
+    //set the phone number value.
+    // return the current preference to allow for chaining preferences.
+    public EditPhoneNumberPreference setPhoneNumber(String number) {
+        mPhoneNumber = number;
+        setText(getStringValue());
+        notifyChanged();
+
+        return this;
+    }
+
+
+    /*
+     * Other code relevant to preference framework
+     */
+    //when setting default / initial values, make sure we're setting things correctly.
+    @Override
+    protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
+        setValueFromString(restoreValue ? getPersistedString(getStringValue())
+                : (String) defaultValue);
+    }
+
+    /**
+     * Decides how to disable dependents.
+     */
+    @Override
+    public boolean shouldDisableDependents() {
+        // There is really only one case we care about, but for consistency
+        // we fill out the dependency tree for all of the cases.  If this
+        // is in activation mode (CF), we look for the encoded toggle value
+        // in the string.  If this in confirm mode (VM), then we just
+        // examine the number field.
+        // Note: The toggle value is stored in the string in an encoded
+        // manner (refer to setValueFromString and getStringValue below).
+        boolean shouldDisable = false;
+        if ((mConfirmationMode == CM_ACTIVATION) && (mEncodedText != null)) {
+            String[] inValues = mEncodedText.split(":", 2);
+            shouldDisable = inValues[0].equals(VALUE_ON);
+        } else {
+            shouldDisable = (TextUtils.isEmpty(mPhoneNumber) && (mConfirmationMode == CM_CONFIRM));
+        }
+        return shouldDisable;
+    }
+
+    /**
+     * Override persistString so that we can get a hold of the EditTextPreference's
+     * text field.
+     */
+    private String mEncodedText = null;
+    @Override
+    protected boolean persistString(String value) {
+        mEncodedText = value;
+        return super.persistString(value);
+    }
+
+
+    /*
+     * Summary On handling code
+     */
+    //set the Summary for the on state (relevant only in CM_ACTIVATION mode)
+    public EditPhoneNumberPreference setSummaryOn(CharSequence summary) {
+        mSummaryOn = summary;
+        if (isToggled()) {
+            notifyChanged();
+        }
+        return this;
+    }
+
+    //set the Summary for the on state, given a string resource id
+    // (relevant only in CM_ACTIVATION mode)
+    public EditPhoneNumberPreference setSummaryOn(int summaryResId) {
+        return setSummaryOn(getContext().getString(summaryResId));
+    }
+
+    //get the summary string for the on state
+    public CharSequence getSummaryOn() {
+        return mSummaryOn;
+    }
+
+
+    /*
+     * Summary Off handling code
+     */
+    //set the Summary for the off state (relevant only in CM_ACTIVATION mode)
+    public EditPhoneNumberPreference setSummaryOff(CharSequence summary) {
+        mSummaryOff = summary;
+        if (!isToggled()) {
+            notifyChanged();
+        }
+        return this;
+    }
+
+    //set the Summary for the off state, given a string resource id
+    // (relevant only in CM_ACTIVATION mode)
+    public EditPhoneNumberPreference setSummaryOff(int summaryResId) {
+        return setSummaryOff(getContext().getString(summaryResId));
+    }
+
+    //get the summary string for the off state
+    public CharSequence getSummaryOff() {
+        return mSummaryOff;
+    }
+
+
+    /*
+     * Methods to get and set from encoded strings.
+     */
+    //set the values given an encoded string.
+    protected void setValueFromString(String value) {
+        String[] inValues = value.split(":", 2);
+        setToggled(inValues[0].equals(VALUE_ON));
+        setPhoneNumber(inValues[1]);
+    }
+
+    //retrieve the state of this preference in the form of an encoded string
+    protected String getStringValue() {
+        return ((isToggled() ? VALUE_ON : VALUE_OFF) + VALUE_SEPARATOR + getPhoneNumber());
+    }
+
+    /**
+     * Externally visible method to bring up the dialog.
+     *
+     * Generally used when we are navigating the user to this preference.
+     */
+    public void showPhoneNumberDialog() {
+        showDialog(null);
+    }
+}
diff --git a/src/com/android/phone/EditPinPreference.java b/src/com/android/phone/EditPinPreference.java
new file mode 100644
index 0000000..af0040d
--- /dev/null
+++ b/src/com/android/phone/EditPinPreference.java
@@ -0,0 +1,110 @@
+/*
+ * 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.app.AlertDialog;
+import android.content.Context;
+import android.preference.EditTextPreference;
+import android.text.InputType;
+import android.text.method.DigitsKeyListener;
+import android.text.method.PasswordTransformationMethod;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.EditText;
+
+import java.util.Map;
+
+/**
+ * Class similar to the com.android.settings.EditPinPreference
+ * class, with a couple of modifications, including a different layout 
+ * for the dialog.
+ */
+public class EditPinPreference extends EditTextPreference {
+
+    private boolean shouldHideButtons;
+    
+    interface OnPinEnteredListener {
+        void onPinEntered(EditPinPreference preference, boolean positiveResult);
+    }
+    
+    private OnPinEnteredListener mPinListener;
+
+    public void setOnPinEnteredListener(OnPinEnteredListener listener) {
+        mPinListener = listener;
+    }
+    
+    public EditPinPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public EditPinPreference(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+    
+    /**
+     * Overridden to setup the correct dialog layout, as well as setting up 
+     * other properties for the pin / puk entry field.
+     */
+    @Override
+    protected View onCreateDialogView() {
+        // set the dialog layout
+        setDialogLayoutResource(R.layout.pref_dialog_editpin);
+        
+        View dialog = super.onCreateDialogView();
+
+        getEditText().setInputType(InputType.TYPE_CLASS_NUMBER |
+            InputType.TYPE_NUMBER_VARIATION_PASSWORD);
+
+        return dialog;
+    }
+    
+    @Override
+    protected void onBindDialogView(View view) {
+        super.onBindDialogView(view);
+        
+        // If the layout does not contain an edittext, hide the buttons.
+        shouldHideButtons = (view.findViewById(android.R.id.edit) == null);
+    }
+    
+    @Override
+    protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
+        super.onPrepareDialogBuilder(builder);
+        
+        // hide the buttons if we need to.
+        if (shouldHideButtons) {
+            builder.setPositiveButton(null, this);
+            builder.setNegativeButton(null, this);
+        }
+    }
+    
+    @Override
+    protected void onDialogClosed(boolean positiveResult) {
+        super.onDialogClosed(positiveResult);
+        if (mPinListener != null) {
+            mPinListener.onPinEntered(this, positiveResult);
+        }
+    }
+    
+    /**
+     * Externally visible method to bring up the dialog to 
+     * for multi-step / multi-dialog requests (like changing 
+     * the SIM pin). 
+     */
+    public void showPinDialog() {
+        showDialog(null);
+    }
+}
diff --git a/src/com/android/phone/EmergencyCallHelper.java b/src/com/android/phone/EmergencyCallHelper.java
new file mode 100644
index 0000000..7f5b0d2
--- /dev/null
+++ b/src/com/android/phone/EmergencyCallHelper.java
@@ -0,0 +1,545 @@
+/*
+ * 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.internal.telephony.CallManager;
+import com.android.internal.telephony.Connection;
+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;
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.Message;
+import android.os.PowerManager;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.telephony.ServiceState;
+import android.util.Log;
+
+
+/**
+ * Helper class for the {@link CallController} that implements special
+ * behavior related to emergency calls.  Specifically, this class handles
+ * the case of the user trying to dial an emergency number while the radio
+ * is off (i.e. the device is in airplane mode), by forcibly turning the
+ * radio back on, waiting for it to come up, and then retrying the
+ * emergency call.
+ *
+ * This class is instantiated lazily (the first time the user attempts to
+ * make an emergency call from airplane mode) by the the
+ * {@link CallController} singleton.
+ */
+public class EmergencyCallHelper extends Handler {
+    private static final String TAG = "EmergencyCallHelper";
+    private static final boolean DBG = false;
+
+    // Number of times to retry the call, and time between retry attempts.
+    public static final int MAX_NUM_RETRIES = 6;
+    public static final long TIME_BETWEEN_RETRIES = 5000;  // msec
+
+    // Timeout used with our wake lock (just as a safety valve to make
+    // sure we don't hold it forever).
+    public static final long WAKE_LOCK_TIMEOUT = 5 * 60 * 1000;  // 5 minutes in msec
+
+    // Handler message codes; see handleMessage()
+    private static final int START_SEQUENCE = 1;
+    private static final int SERVICE_STATE_CHANGED = 2;
+    private static final int DISCONNECT = 3;
+    private static final int RETRY_TIMEOUT = 4;
+
+    private CallController mCallController;
+    private PhoneGlobals mApp;
+    private CallManager mCM;
+    private Phone mPhone;
+    private String mNumber;  // The emergency number we're trying to dial
+    private int mNumRetriesSoFar;
+
+    // Wake lock we hold while running the whole sequence
+    private PowerManager.WakeLock mPartialWakeLock;
+
+    public EmergencyCallHelper(CallController callController) {
+        if (DBG) log("EmergencyCallHelper constructor...");
+        mCallController = callController;
+        mApp = PhoneGlobals.getInstance();
+        mCM =  mApp.mCM;
+    }
+
+    @Override
+    public void handleMessage(Message msg) {
+        switch (msg.what) {
+            case START_SEQUENCE:
+                startSequenceInternal(msg);
+                break;
+            case SERVICE_STATE_CHANGED:
+                onServiceStateChanged(msg);
+                break;
+            case DISCONNECT:
+                onDisconnect(msg);
+                break;
+            case RETRY_TIMEOUT:
+                onRetryTimeout();
+                break;
+            default:
+                Log.wtf(TAG, "handleMessage: unexpected message: " + msg);
+                break;
+        }
+    }
+
+    /**
+     * Starts the "emergency call from airplane mode" sequence.
+     *
+     * This is the (single) external API of the EmergencyCallHelper class.
+     * This method is called from the CallController placeCall() sequence
+     * if the user dials a valid emergency number, but the radio is
+     * powered-off (presumably due to airplane mode.)
+     *
+     * This method kicks off the following sequence:
+     * - Power on the radio
+     * - Listen for the service state change event telling us the radio has come up
+     * - Then launch the emergency call
+     * - Retry if the call fails with an OUT_OF_SERVICE error
+     * - Retry if we've gone 5 seconds without any response from the radio
+     * - Finally, clean up any leftover state (progress UI, wake locks, etc.)
+     *
+     * This method is safe to call from any thread, since it simply posts
+     * a message to the EmergencyCallHelper's handler (thus ensuring that
+     * the rest of the sequence is entirely serialized, and runs only on
+     * the handler thread.)
+     *
+     * This method does *not* force the in-call UI to come up; our caller
+     * is responsible for doing that (presumably by calling
+     * PhoneApp.displayCallScreen().)
+     */
+    public void startEmergencyCallFromAirplaneModeSequence(String number) {
+        if (DBG) log("startEmergencyCallFromAirplaneModeSequence('" + number + "')...");
+        Message msg = obtainMessage(START_SEQUENCE, number);
+        sendMessage(msg);
+    }
+
+    /**
+     * Actual implementation of startEmergencyCallFromAirplaneModeSequence(),
+     * guaranteed to run on the handler thread.
+     * @see startEmergencyCallFromAirplaneModeSequence()
+     */
+    private void startSequenceInternal(Message msg) {
+        if (DBG) log("startSequenceInternal(): msg = " + msg);
+
+        // First of all, clean up any state (including mPartialWakeLock!)
+        // left over from a prior emergency call sequence.
+        // This ensures that we'll behave sanely if another
+        // startEmergencyCallFromAirplaneModeSequence() comes in while
+        // we're already in the middle of the sequence.
+        cleanup();
+
+        mNumber = (String) msg.obj;
+        if (DBG) log("- startSequenceInternal: Got mNumber: '" + mNumber + "'");
+
+        mNumRetriesSoFar = 0;
+
+        // Reset mPhone to whatever the current default phone is right now.
+        mPhone = mApp.mCM.getDefaultPhone();
+
+        // Wake lock to make sure the processor doesn't go to sleep midway
+        // through the emergency call sequence.
+        PowerManager pm = (PowerManager) mApp.getSystemService(Context.POWER_SERVICE);
+        mPartialWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
+        // Acquire with a timeout, just to be sure we won't hold the wake
+        // lock forever even if a logic bug (in this class) causes us to
+        // somehow never call cleanup().
+        if (DBG) log("- startSequenceInternal: acquiring wake lock");
+        mPartialWakeLock.acquire(WAKE_LOCK_TIMEOUT);
+
+        // No need to check the current service state here, since the only
+        // reason the CallController would call this method in the first
+        // place is if the radio is powered-off.
+        //
+        // So just go ahead and turn the radio on.
+
+        powerOnRadio();  // We'll get an onServiceStateChanged() callback
+                         // when the radio successfully comes up.
+
+        // Next step: when the SERVICE_STATE_CHANGED event comes in,
+        // we'll retry the call; see placeEmergencyCall();
+        // But also, just in case, start a timer to make sure we'll retry
+        // the call even if the SERVICE_STATE_CHANGED event never comes in
+        // 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().)
+    }
+
+    /**
+     * Handles the SERVICE_STATE_CHANGED event.
+     *
+     * (Normally this event tells us that the radio has finally come
+     * up.  In that case, it's now safe to actually place the
+     * emergency call.)
+     */
+    private void onServiceStateChanged(Message msg) {
+        ServiceState state = (ServiceState) ((AsyncResult) msg.obj).result;
+        if (DBG) log("onServiceStateChanged()...  new state = " + state);
+
+        // Possible service states:
+        // - STATE_IN_SERVICE        // Normal operation
+        // - STATE_OUT_OF_SERVICE    // Still searching for an operator to register to,
+        //                           // or no radio signal
+        // - STATE_EMERGENCY_ONLY    // Phone is locked; only emergency numbers are allowed
+        // - STATE_POWER_OFF         // Radio is explicitly powered off (airplane mode)
+
+        // Once we reach either STATE_IN_SERVICE or STATE_EMERGENCY_ONLY,
+        // it's finally OK to place the emergency call.
+        boolean okToCall = (state.getState() == ServiceState.STATE_IN_SERVICE)
+                || (state.getState() == ServiceState.STATE_EMERGENCY_ONLY);
+
+        if (okToCall) {
+            // Woo hoo!  It's OK to actually place the call.
+            if (DBG) log("onServiceStateChanged: ok to call!");
+
+            // 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
+            // STATE_OUT_OF_SERVICE, which happens immediately after powering-on
+            // the radio.)
+            //
+            // So just keep waiting; we'll probably get to either
+            // STATE_IN_SERVICE or STATE_EMERGENCY_ONLY very shortly.
+            // (Or even if that doesn't happen, we'll at least do another retry
+            // when the RETRY_TIMEOUT event fires.)
+            if (DBG) log("onServiceStateChanged: not ready to call yet, keep waiting...");
+        }
+    }
+
+    /**
+     * Handles a DISCONNECT event from the telephony layer.
+     *
+     * Even after we successfully place an emergency call (after powering
+     * on the radio), it's still possible for the call to fail with the
+     * disconnect cause OUT_OF_SERVICE.  If so, schedule a retry.
+     */
+    private void onDisconnect(Message msg) {
+        Connection conn = (Connection) ((AsyncResult) msg.obj).result;
+        Connection.DisconnectCause cause = conn.getDisconnectCause();
+        if (DBG) log("onDisconnect: connection '" + conn
+                     + "', addr '" + conn.getAddress() + "', cause = " + cause);
+
+        if (cause == Connection.DisconnectCause.OUT_OF_SERVICE) {
+            // Wait a bit more and try again (or just bail out totally if
+            // we've had too many failures.)
+            if (DBG) log("- onDisconnect: OUT_OF_SERVICE, need to retry...");
+            scheduleRetryOrBailOut();
+        } else {
+            // Any other disconnect cause means we're done.
+            // Either the emergency call succeeded *and* ended normally,
+            // or else there was some error that we can't retry.  In either
+            // case, just clean up our internal state.)
+
+            if (DBG) log("==> Disconnect event; clean up...");
+            cleanup();
+
+            // Nothing else to do here.  If the InCallScreen was visible,
+            // it would have received this disconnect event too (so it'll
+            // show the "Call ended" state and finish itself without any
+            // help from us.)
+        }
+    }
+
+    /**
+     * Handles the retry timer expiring.
+     */
+    private void onRetryTimeout() {
+        PhoneConstants.State phoneState = mCM.getState();
+        int serviceState = mPhone.getServiceState().getState();
+        if (DBG) log("onRetryTimeout():  phone state " + phoneState
+                     + ", service state " + serviceState
+                     + ", mNumRetriesSoFar = " + mNumRetriesSoFar);
+
+        // - If we're actually in a call, we've succeeded.
+        //
+        // - Otherwise, if the radio is now on, that means we successfully got
+        //   out of airplane mode but somehow didn't get the service state
+        //   change event.  In that case, try to place the call.
+        //
+        // - If the radio is still powered off, try powering it on again.
+
+        if (phoneState == PhoneConstants.State.OFFHOOK) {
+            if (DBG) log("- onRetryTimeout: Call is active!  Cleaning up...");
+            cleanup();
+            return;
+        }
+
+        if (serviceState != ServiceState.STATE_POWER_OFF) {
+            // Woo hoo -- we successfully got out of airplane mode.
+
+            // Deregister for the service state change events; we don't need
+            // 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 {
+            // Uh oh; we've waited the full TIME_BETWEEN_RETRIES and the
+            // radio is still not powered-on.  Try again...
+
+            if (DBG) log("- Trying (again) to turn on the radio...");
+            powerOnRadio();  // Again, we'll (hopefully) get an onServiceStateChanged()
+                             // callback when the radio successfully comes up.
+
+            // ...and also set a fresh retry timer (or just bail out
+            // 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();
+    }
+
+    /**
+     * Attempt to power on the radio (i.e. take the device out
+     * of airplane mode.)
+     *
+     * Additionally, start listening for service state changes;
+     * we'll eventually get an onServiceStateChanged() callback
+     * when the radio successfully comes up.
+     */
+    private void powerOnRadio() {
+        if (DBG) log("- powerOnRadio()...");
+
+        // We're about to turn on the radio, so arrange to be notified
+        // when the sequence is complete.
+        registerForServiceStateChanged();
+
+        // If airplane mode is on, we turn it off the same way that the
+        // Settings activity turns it off.
+        if (Settings.Global.getInt(mApp.getContentResolver(),
+                                   Settings.Global.AIRPLANE_MODE_ON, 0) > 0) {
+            if (DBG) log("==> Turning off airplane mode...");
+
+            // Change the system setting
+            Settings.Global.putInt(mApp.getContentResolver(),
+                                   Settings.Global.AIRPLANE_MODE_ON, 0);
+
+            // Post the intent
+            Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
+            intent.putExtra("state", false);
+            mApp.sendBroadcastAsUser(intent, UserHandle.ALL);
+        } else {
+            // Otherwise, for some strange reason the radio is off
+            // (even though the Settings database doesn't think we're
+            // in airplane mode.)  In this case just turn the radio
+            // back on.
+            if (DBG) log("==> (Apparently) not in airplane mode; manually powering radio on...");
+            mPhone.setRadioPower(true);
+        }
+    }
+
+    /**
+     * Actually initiate the outgoing emergency call.
+     * (We do this once the radio has successfully been powered-up.)
+     *
+     * If the call succeeds, we're done.
+     * If the call fails, schedule a retry of the whole sequence.
+     */
+    private void placeEmergencyCall() {
+        if (DBG) log("placeEmergencyCall()...");
+
+        // Place an outgoing call to mNumber.
+        // Note we call PhoneUtils.placeCall() directly; we don't want any
+        // of the behavior from CallController.placeCallInternal() here.
+        // (Specifically, we don't want to start the "emergency call from
+        // airplane mode" sequence from the beginning again!)
+
+        registerForDisconnect();  // Get notified when this call disconnects
+
+        if (DBG) log("- placing call to '" + mNumber + "'...");
+        int callStatus = PhoneUtils.placeCall(mApp,
+                                              mPhone,
+                                              mNumber,
+                                              null,  // contactUri
+                                              true,  // isEmergencyCall
+                                              null);  // gatewayUri
+        if (DBG) log("- PhoneUtils.placeCall() returned status = " + callStatus);
+
+        boolean success;
+        // Note PhoneUtils.placeCall() returns one of the CALL_STATUS_*
+        // constants, not a CallStatusCode enum value.
+        switch (callStatus) {
+            case PhoneUtils.CALL_STATUS_DIALED:
+                success = true;
+                break;
+
+            case PhoneUtils.CALL_STATUS_DIALED_MMI:
+            case PhoneUtils.CALL_STATUS_FAILED:
+            default:
+                // Anything else is a failure, and we'll need to retry.
+                Log.w(TAG, "placeEmergencyCall(): placeCall() failed: callStatus = " + callStatus);
+                success = false;
+                break;
+        }
+
+        if (success) {
+            if (DBG) log("==> Success from PhoneUtils.placeCall()!");
+            // Ok, the emergency call is (hopefully) under way.
+
+            // We're not done yet, though, so don't call cleanup() here.
+            // (It's still possible that this call will fail, and disconnect
+            // with cause==OUT_OF_SERVICE.  If so, that will trigger a retry
+            // from the onDisconnect() method.)
+        } else {
+            if (DBG) log("==> Failure.");
+            // Wait a bit more and try again (or just bail out totally if
+            // we've had too many failures.)
+            scheduleRetryOrBailOut();
+        }
+    }
+
+    /**
+     * Schedules a retry in response to some failure (either the radio
+     * failing to power on, or a failure when trying to place the call.)
+     * Or, if we've hit the retry limit, bail out of this whole sequence
+     * and display a failure message to the user.
+     */
+    private void scheduleRetryOrBailOut() {
+        mNumRetriesSoFar++;
+        if (DBG) log("scheduleRetryOrBailOut()...  mNumRetriesSoFar is now " + mNumRetriesSoFar);
+
+        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);
+        }
+    }
+
+    /**
+     * Clean up when done with the whole sequence: either after
+     * successfully placing *and* ending the emergency call, or after
+     * bailing out because of too many failures.
+     *
+     * The exact cleanup steps are:
+     * - Take down any progress UI (and also ask the in-call UI to refresh itself,
+     *   if it's still visible)
+     * - Double-check that we're not still registered for any telephony events
+     * - Clean up any extraneous handler messages (like retry timeouts) still in the queue
+     * - Make sure we're not still holding any wake locks
+     *
+     * Basically this method guarantees that there will be no more
+     * activity from the EmergencyCallHelper until the CallController
+     * kicks off the whole sequence again with another call to
+     * startEmergencyCallFromAirplaneModeSequence().
+     *
+     * Note we don't call this method simply after a successful call to
+     * placeCall(), since it's still possible the call will disconnect
+     * very quickly with an OUT_OF_SERVICE error.
+     */
+    private void cleanup() {
+        if (DBG) log("cleanup()...");
+
+        // Take down the "Turning on radio..." indication.
+        mApp.inCallUiState.clearProgressIndication();
+
+        unregisterForServiceStateChanged();
+        unregisterForDisconnect();
+        cancelRetryTimer();
+
+        // Release / clean up the wake lock
+        if (mPartialWakeLock != null) {
+            if (mPartialWakeLock.isHeld()) {
+                if (DBG) log("- releasing wake lock");
+                mPartialWakeLock.release();
+            }
+            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() {
+        removeMessages(RETRY_TIMEOUT);
+        sendEmptyMessageDelayed(RETRY_TIMEOUT, TIME_BETWEEN_RETRIES);
+    }
+
+    private void cancelRetryTimer() {
+        removeMessages(RETRY_TIMEOUT);
+    }
+
+    private void registerForServiceStateChanged() {
+        // Unregister first, just to make sure we never register ourselves
+        // twice.  (We need this because Phone.registerForServiceStateChanged()
+        // does not prevent multiple registration of the same handler.)
+        mPhone.unregisterForServiceStateChanged(this);  // Safe even if not currently registered
+        mPhone.registerForServiceStateChanged(this, SERVICE_STATE_CHANGED, null);
+    }
+
+    private void unregisterForServiceStateChanged() {
+        // This method is safe to call even if we haven't set mPhone yet.
+        if (mPhone != null) {
+            mPhone.unregisterForServiceStateChanged(this);  // Safe even if unnecessary
+        }
+        removeMessages(SERVICE_STATE_CHANGED);  // Clean up any pending messages too
+    }
+
+    private void registerForDisconnect() {
+        // Note: no need to unregister first, since
+        // CallManager.registerForDisconnect() automatically prevents
+        // multiple registration of the same handler.
+        mCM.registerForDisconnect(this, DISCONNECT, null);
+    }
+
+    private void unregisterForDisconnect() {
+        mCM.unregisterForDisconnect(this);  // Safe even if not currently registered
+        removeMessages(DISCONNECT);  // Clean up any pending messages too
+    }
+
+
+    //
+    // Debugging
+    //
+
+    private static void log(String msg) {
+        Log.d(TAG, msg);
+    }
+}
diff --git a/src/com/android/phone/EmergencyCallbackModeExitDialog.java b/src/com/android/phone/EmergencyCallbackModeExitDialog.java
new file mode 100644
index 0000000..7758b23
--- /dev/null
+++ b/src/com/android/phone/EmergencyCallbackModeExitDialog.java
@@ -0,0 +1,347 @@
+/*
+ * 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.app.Activity;
+import android.app.Dialog;
+import android.app.ProgressDialog;
+import android.app.AlertDialog;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnDismissListener;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.ServiceConnection;
+import android.content.res.Resources;
+import android.os.AsyncResult;
+import android.os.Bundle;
+import android.os.CountDownTimer;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.SystemProperties;
+import android.util.Log;
+
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.telephony.TelephonyProperties;
+
+/**
+ * Displays dialog that enables users to exit Emergency Callback Mode
+ *
+ * @see EmergencyCallbackModeService
+ */
+public class EmergencyCallbackModeExitDialog extends Activity implements OnDismissListener {
+
+    /** Intent to trigger the Emergency Callback Mode exit dialog */
+    static final String ACTION_SHOW_ECM_EXIT_DIALOG =
+            "com.android.phone.action.ACTION_SHOW_ECM_EXIT_DIALOG";
+    /** Used to get the users choice from the return Intent's extra */
+    public static final String EXTRA_EXIT_ECM_RESULT = "exit_ecm_result";
+
+    public static final int EXIT_ECM_BLOCK_OTHERS = 1;
+    public static final int EXIT_ECM_DIALOG = 2;
+    public static final int EXIT_ECM_PROGRESS_DIALOG = 3;
+    public static final int EXIT_ECM_IN_EMERGENCY_CALL_DIALOG = 4;
+
+    AlertDialog mAlertDialog = null;
+    ProgressDialog mProgressDialog = null;
+    CountDownTimer mTimer = null;
+    EmergencyCallbackModeService mService = null;
+    Handler mHandler = null;
+    int mDialogType = 0;
+    long mEcmTimeout = 0;
+    private boolean mInEmergencyCall = false;
+    private static final int ECM_TIMER_RESET = 1;
+    private Phone mPhone = null;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Check if phone is in Emergency Callback Mode. If not, exit.
+        if (!Boolean.parseBoolean(
+                    SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE))) {
+            finish();
+        }
+
+        mHandler = new Handler();
+
+        // Start thread that will wait for the connection completion so that it can get
+        // timeout value from the service
+        Thread waitForConnectionCompleteThread = new Thread(null, mTask,
+                "EcmExitDialogWaitThread");
+        waitForConnectionCompleteThread.start();
+
+        // Register ECM timer reset notfication
+        mPhone = PhoneGlobals.getPhone();
+        mPhone.registerForEcmTimerReset(mTimerResetHandler, ECM_TIMER_RESET, null);
+
+        // Register receiver for intent closing the dialog
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
+        registerReceiver(mEcmExitReceiver, filter);
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        unregisterReceiver(mEcmExitReceiver);
+        // Unregister ECM timer reset notification
+        mPhone.unregisterForEcmTimerReset(mHandler);
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Bundle savedInstanceState) {
+        super.onRestoreInstanceState(savedInstanceState);
+        mDialogType = savedInstanceState.getInt("DIALOG_TYPE");
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putInt("DIALOG_TYPE", mDialogType);
+    }
+
+    /**
+     * Waits until bind to the service completes
+     */
+    private Runnable mTask = new Runnable() {
+        public void run() {
+            Looper.prepare();
+
+            // Bind to the remote service
+            bindService(new Intent(EmergencyCallbackModeExitDialog.this,
+                    EmergencyCallbackModeService.class), mConnection, Context.BIND_AUTO_CREATE);
+
+            // Wait for bind to finish
+            synchronized (EmergencyCallbackModeExitDialog.this) {
+                try {
+                    if (mService == null) {
+                        EmergencyCallbackModeExitDialog.this.wait();
+                    }
+                } catch (InterruptedException e) {
+                    Log.d("ECM", "EmergencyCallbackModeExitDialog InterruptedException: "
+                            + e.getMessage());
+                    e.printStackTrace();
+                }
+            }
+
+            // Get timeout value and call state from the service
+            if (mService != null) {
+                mEcmTimeout = mService.getEmergencyCallbackModeTimeout();
+                mInEmergencyCall = mService.getEmergencyCallbackModeCallState();
+            }
+
+            // Unbind from remote service
+            unbindService(mConnection);
+
+            // Show dialog
+            mHandler.post(new Runnable() {
+                public void run() {
+                    showEmergencyCallbackModeExitDialog();
+                }
+            });
+        }
+    };
+
+    /**
+     * Shows Emergency Callback Mode dialog and starts countdown timer
+     */
+    private void showEmergencyCallbackModeExitDialog() {
+
+        if(mInEmergencyCall) {
+            mDialogType = EXIT_ECM_IN_EMERGENCY_CALL_DIALOG;
+            showDialog(EXIT_ECM_IN_EMERGENCY_CALL_DIALOG);
+        } else {
+            if (getIntent().getAction().equals(
+                    TelephonyIntents.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS)) {
+                mDialogType = EXIT_ECM_BLOCK_OTHERS;
+                showDialog(EXIT_ECM_BLOCK_OTHERS);
+            } else if (getIntent().getAction().equals(ACTION_SHOW_ECM_EXIT_DIALOG)) {
+                mDialogType = EXIT_ECM_DIALOG;
+                showDialog(EXIT_ECM_DIALOG);
+            }
+
+            mTimer = new CountDownTimer(mEcmTimeout, 1000) {
+                @Override
+                public void onTick(long millisUntilFinished) {
+                    CharSequence text = getDialogText(millisUntilFinished);
+                    mAlertDialog.setMessage(text);
+                }
+
+                @Override
+                public void onFinish() {
+                    //Do nothing
+                }
+            }.start();
+        }
+    }
+
+    /**
+     * Creates dialog that enables users to exit Emergency Callback Mode
+     */
+    @Override
+    protected Dialog onCreateDialog(int id) {
+        switch (id) {
+        case EXIT_ECM_BLOCK_OTHERS:
+        case EXIT_ECM_DIALOG:
+            CharSequence text = getDialogText(mEcmTimeout);
+            mAlertDialog = new AlertDialog.Builder(EmergencyCallbackModeExitDialog.this)
+                    .setIcon(R.drawable.picture_emergency32x32)
+                    .setTitle(R.string.phone_in_ecm_notification_title)
+                    .setMessage(text)
+                    .setPositiveButton(R.string.alert_dialog_yes,
+                            new DialogInterface.OnClickListener() {
+                                public void onClick(DialogInterface dialog,int whichButton) {
+                                    // User clicked Yes. Exit Emergency Callback Mode.
+                                    mPhone.exitEmergencyCallbackMode();
+
+                                    // Show progress dialog
+                                    showDialog(EXIT_ECM_PROGRESS_DIALOG);
+                                    mTimer.cancel();
+                                }
+                            })
+                    .setNegativeButton(R.string.alert_dialog_no,
+                            new DialogInterface.OnClickListener() {
+                                public void onClick(DialogInterface dialog, int whichButton) {
+                                    // User clicked No
+                                    setResult(RESULT_OK, (new Intent()).putExtra(
+                                            EXTRA_EXIT_ECM_RESULT, false));
+                                    finish();
+                                }
+                            }).create();
+            mAlertDialog.setOnDismissListener(this);
+            return mAlertDialog;
+
+        case EXIT_ECM_IN_EMERGENCY_CALL_DIALOG:
+            mAlertDialog = new AlertDialog.Builder(EmergencyCallbackModeExitDialog.this)
+                    .setIcon(R.drawable.picture_emergency32x32)
+                    .setTitle(R.string.phone_in_ecm_notification_title)
+                    .setMessage(R.string.alert_dialog_in_ecm_call)
+                    .setNeutralButton(R.string.alert_dialog_dismiss,
+                            new DialogInterface.OnClickListener() {
+                                public void onClick(DialogInterface dialog, int whichButton) {
+                                    // User clicked Dismiss
+                                    setResult(RESULT_OK, (new Intent()).putExtra(
+                                            EXTRA_EXIT_ECM_RESULT, false));
+                                    finish();
+                                }
+                            }).create();
+            mAlertDialog.setOnDismissListener(this);
+            return mAlertDialog;
+
+        case EXIT_ECM_PROGRESS_DIALOG:
+            mProgressDialog = new ProgressDialog(EmergencyCallbackModeExitDialog.this);
+            mProgressDialog.setMessage(getText(R.string.progress_dialog_exiting_ecm));
+            mProgressDialog.setIndeterminate(true);
+            mProgressDialog.setCancelable(false);
+            return mProgressDialog;
+
+        default:
+            return null;
+        }
+    }
+
+    /**
+     * Returns dialog box text with updated timeout value
+     */
+    private CharSequence getDialogText(long millisUntilFinished) {
+        // Format time
+        int minutes = (int)(millisUntilFinished / 60000);
+        String time = String.format("%d:%02d", minutes,
+                (millisUntilFinished % 60000) / 1000);
+
+        switch (mDialogType) {
+        case EXIT_ECM_BLOCK_OTHERS:
+            return String.format(getResources().getQuantityText(
+                    R.plurals.alert_dialog_not_avaialble_in_ecm, minutes).toString(), time);
+        case EXIT_ECM_DIALOG:
+            return String.format(getResources().getQuantityText(R.plurals.alert_dialog_exit_ecm,
+                    minutes).toString(), time);
+        }
+        return null;
+    }
+
+    /**
+     * Closes activity when dialog is dismissed
+     */
+    public void onDismiss(DialogInterface dialog) {
+        EmergencyCallbackModeExitDialog.this.setResult(RESULT_OK, (new Intent())
+                .putExtra(EXTRA_EXIT_ECM_RESULT, false));
+        finish();
+    }
+
+    /**
+     * Listens for Emergency Callback Mode state change intents
+     */
+    private BroadcastReceiver mEcmExitReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            // Received exit Emergency Callback Mode notification close all dialogs
+            if (intent.getAction().equals(
+                    TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED)) {
+                if (intent.getBooleanExtra("phoneinECMState", false) == false) {
+                    if (mAlertDialog != null)
+                        mAlertDialog.dismiss();
+                    if (mProgressDialog != null)
+                        mProgressDialog.dismiss();
+                    EmergencyCallbackModeExitDialog.this.setResult(RESULT_OK, (new Intent())
+                            .putExtra(EXTRA_EXIT_ECM_RESULT, true));
+                    finish();
+                }
+            }
+        }
+    };
+
+    /**
+     * Class for interacting with the interface of the service
+     */
+    private ServiceConnection mConnection = new ServiceConnection() {
+        public void onServiceConnected(ComponentName className, IBinder service) {
+            mService = ((EmergencyCallbackModeService.LocalBinder)service).getService();
+            // Notify thread that connection is ready
+            synchronized (EmergencyCallbackModeExitDialog.this) {
+                EmergencyCallbackModeExitDialog.this.notify();
+            }
+        }
+
+        public void onServiceDisconnected(ComponentName className) {
+            mService = null;
+        }
+    };
+
+    /**
+     * Class for receiving framework timer reset notifications
+     */
+    private Handler mTimerResetHandler = new Handler () {
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case ECM_TIMER_RESET:
+                    if(!((Boolean)((AsyncResult) msg.obj).result).booleanValue()) {
+                        EmergencyCallbackModeExitDialog.this.setResult(RESULT_OK, (new Intent())
+                                .putExtra(EXTRA_EXIT_ECM_RESULT, false));
+                        finish();
+                    }
+                    break;
+            }
+        }
+    };
+}
diff --git a/src/com/android/phone/EmergencyCallbackModeService.java b/src/com/android/phone/EmergencyCallbackModeService.java
new file mode 100644
index 0000000..b506598
--- /dev/null
+++ b/src/com/android/phone/EmergencyCallbackModeService.java
@@ -0,0 +1,242 @@
+/*
+ * 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.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Resources;
+import android.os.AsyncResult;
+import android.os.Binder;
+import android.os.CountDownTimer;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.SystemProperties;
+import android.util.Log;
+
+import com.android.internal.telephony.cdma.CDMAPhone;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.telephony.TelephonyProperties;
+
+/**
+ * Application service that inserts/removes Emergency Callback Mode notification and
+ * updates Emergency Callback Mode countdown clock in the notification
+ *
+ * @see EmergencyCallbackModeExitDialog
+ */
+public class EmergencyCallbackModeService extends Service {
+
+    // Default Emergency Callback Mode timeout value
+    private static final int DEFAULT_ECM_EXIT_TIMER_VALUE = 300000;
+    private static final String LOG_TAG = "EmergencyCallbackModeService";
+
+    private NotificationManager mNotificationManager = null;
+    private CountDownTimer mTimer = null;
+    private long mTimeLeft = 0;
+    private Phone mPhone = null;
+    private boolean mInEmergencyCall = false;
+
+    private static final int ECM_TIMER_RESET = 1;
+
+    private Handler mHandler = new Handler () {
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case ECM_TIMER_RESET:
+                    resetEcmTimer((AsyncResult) msg.obj);
+                    break;
+            }
+        }
+    };
+
+    @Override
+    public void onCreate() {
+        // Check if it is CDMA phone
+        if (PhoneFactory.getDefaultPhone().getPhoneType() != PhoneConstants.PHONE_TYPE_CDMA) {
+            Log.e(LOG_TAG, "Error! Emergency Callback Mode not supported for " +
+                    PhoneFactory.getDefaultPhone().getPhoneName() + " phones");
+            stopSelf();
+        }
+
+        // Register receiver for intents
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
+        filter.addAction(TelephonyIntents.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS);
+        registerReceiver(mEcmReceiver, filter);
+
+        mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
+
+        // Register ECM timer reset notfication
+        mPhone = PhoneFactory.getDefaultPhone();
+        mPhone.registerForEcmTimerReset(mHandler, ECM_TIMER_RESET, null);
+
+        startTimerNotification();
+    }
+
+    @Override
+    public void onDestroy() {
+        // Unregister receiver
+        unregisterReceiver(mEcmReceiver);
+        // Unregister ECM timer reset notification
+        mPhone.unregisterForEcmTimerReset(mHandler);
+
+        // Cancel the notification and timer
+        mNotificationManager.cancel(R.string.phone_in_ecm_notification_title);
+        mTimer.cancel();
+    }
+
+    /**
+     * Listens for Emergency Callback Mode intents
+     */
+    private BroadcastReceiver mEcmReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            // Stop the service when phone exits Emergency Callback Mode
+            if (intent.getAction().equals(
+                    TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED)) {
+                if (intent.getBooleanExtra("phoneinECMState", false) == false) {
+                    stopSelf();
+                }
+            }
+            // Show dialog box
+            else if (intent.getAction().equals(
+                    TelephonyIntents.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS)) {
+                    context.startActivity(
+                            new Intent(TelephonyIntents.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS)
+                    .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
+            }
+        }
+    };
+
+    /**
+     * Start timer notification for Emergency Callback Mode
+     */
+    private void startTimerNotification() {
+        // Get Emergency Callback Mode timeout value
+        long ecmTimeout = SystemProperties.getLong(
+                    TelephonyProperties.PROPERTY_ECM_EXIT_TIMER, DEFAULT_ECM_EXIT_TIMER_VALUE);
+
+        // Show the notification
+        showNotification(ecmTimeout);
+
+        // Start countdown timer for the notification updates
+        mTimer = new CountDownTimer(ecmTimeout, 1000) {
+
+            @Override
+            public void onTick(long millisUntilFinished) {
+                mTimeLeft = millisUntilFinished;
+                EmergencyCallbackModeService.this.showNotification(millisUntilFinished);
+            }
+
+            @Override
+            public void onFinish() {
+                //Do nothing
+            }
+
+        }.start();
+    }
+
+    /**
+     * Shows notification for Emergency Callback Mode
+     */
+    private void showNotification(long millisUntilFinished) {
+
+        // Set the icon and text
+        Notification notification = new Notification(
+                R.drawable.picture_emergency25x25,
+                getText(R.string.phone_entered_ecm_text), 0);
+
+        // PendingIntent to launch Emergency Callback Mode Exit activity if the user selects
+        // this notification
+        PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
+                new Intent(EmergencyCallbackModeExitDialog.ACTION_SHOW_ECM_EXIT_DIALOG), 0);
+
+        // Format notification string
+        String text = null;
+        if(mInEmergencyCall) {
+            text = getText(R.string.phone_in_ecm_call_notification_text).toString();
+        } else {
+            int minutes = (int)(millisUntilFinished / 60000);
+            String time = String.format("%d:%02d", minutes, (millisUntilFinished % 60000) / 1000);
+            text = String.format(getResources().getQuantityText(
+                     R.plurals.phone_in_ecm_notification_time, minutes).toString(), time);
+        }
+        // Set the info in the notification
+        notification.setLatestEventInfo(this, getText(R.string.phone_in_ecm_notification_title),
+                text, contentIntent);
+
+        notification.flags = Notification.FLAG_ONGOING_EVENT;
+
+        // Show notification
+        mNotificationManager.notify(R.string.phone_in_ecm_notification_title, notification);
+    }
+
+    /**
+     * Handle ECM_TIMER_RESET notification
+     */
+    private void resetEcmTimer(AsyncResult r) {
+        boolean isTimerCanceled = ((Boolean)r.result).booleanValue();
+
+        if (isTimerCanceled) {
+            mInEmergencyCall = true;
+            mTimer.cancel();
+            showNotification(0);
+        } else {
+            mInEmergencyCall = false;
+            startTimerNotification();
+        }
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return mBinder;
+    }
+
+    // This is the object that receives interactions from clients.
+    private final IBinder mBinder = new LocalBinder();
+
+    /**
+     * Class for clients to access
+     */
+    public class LocalBinder extends Binder {
+        EmergencyCallbackModeService getService() {
+            return EmergencyCallbackModeService.this;
+        }
+    }
+
+    /**
+     * Returns Emergency Callback Mode timeout value
+     */
+    public long getEmergencyCallbackModeTimeout() {
+        return mTimeLeft;
+    }
+
+    /**
+     * Returns Emergency Callback Mode call state
+     */
+    public boolean getEmergencyCallbackModeCallState() {
+        return mInEmergencyCall;
+    }
+}
diff --git a/src/com/android/phone/EmergencyDialer.java b/src/com/android/phone/EmergencyDialer.java
new file mode 100644
index 0000000..6900183
--- /dev/null
+++ b/src/com/android/phone/EmergencyDialer.java
@@ -0,0 +1,639 @@
+/*
+ * 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.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.StatusBarManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Resources;
+import android.media.AudioManager;
+import android.media.ToneGenerator;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.telephony.PhoneNumberUtils;
+import android.text.Editable;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.text.method.DialerKeyListener;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.accessibility.AccessibilityManager;
+import android.widget.EditText;
+
+import com.android.phone.common.HapticFeedback;
+
+
+/**
+ * EmergencyDialer is a special dialer that is used ONLY for dialing emergency calls.
+ *
+ * It's a simplified version of the regular dialer (i.e. the TwelveKeyDialer
+ * activity from apps/Contacts) that:
+ *   1. Allows ONLY emergency calls to be dialed
+ *   2. Disallows voicemail functionality
+ *   3. Uses the FLAG_SHOW_WHEN_LOCKED window manager flag to allow this
+ *      activity to stay in front of the keyguard.
+ *
+ * TODO: Even though this is an ultra-simplified version of the normal
+ * dialer, there's still lots of code duplication between this class and
+ * the TwelveKeyDialer class from apps/Contacts.  Could the common code be
+ * moved into a shared base class that would live in the framework?
+ * Or could we figure out some way to move *this* class into apps/Contacts
+ * also?
+ */
+public class EmergencyDialer extends Activity implements View.OnClickListener,
+        View.OnLongClickListener, View.OnHoverListener, View.OnKeyListener, TextWatcher {
+    // Keys used with onSaveInstanceState().
+    private static final String LAST_NUMBER = "lastNumber";
+
+    // Intent action for this activity.
+    public static final String ACTION_DIAL = "com.android.phone.EmergencyDialer.DIAL";
+
+    // List of dialer button IDs.
+    private static final int[] DIALER_KEYS = new int[] {
+            R.id.one, R.id.two, R.id.three,
+            R.id.four, R.id.five, R.id.six,
+            R.id.seven, R.id.eight, R.id.nine,
+            R.id.star, R.id.zero, R.id.pound };
+
+    // Debug constants.
+    private static final boolean DBG = false;
+    private static final String LOG_TAG = "EmergencyDialer";
+
+    private PhoneGlobals mApp;
+    private StatusBarManager mStatusBarManager;
+    private AccessibilityManager mAccessibilityManager;
+
+    /** The length of DTMF tones in milliseconds */
+    private static final int TONE_LENGTH_MS = 150;
+
+    /** The DTMF tone volume relative to other sounds in the stream */
+    private static final int TONE_RELATIVE_VOLUME = 80;
+
+    /** Stream type used to play the DTMF tones off call, and mapped to the volume control keys */
+    private static final int DIAL_TONE_STREAM_TYPE = AudioManager.STREAM_DTMF;
+
+    private static final int BAD_EMERGENCY_NUMBER_DIALOG = 0;
+
+    private static final int USER_ACTIVITY_TIMEOUT_WHEN_NO_PROX_SENSOR = 15000; // millis
+
+    EditText mDigits;
+    private View mDialButton;
+    private View mDelete;
+
+    private ToneGenerator mToneGenerator;
+    private Object mToneGeneratorLock = new Object();
+
+    // determines if we want to playback local DTMF tones.
+    private boolean mDTMFToneEnabled;
+
+    // Haptic feedback (vibration) for dialer key presses.
+    private HapticFeedback mHaptic = new HapticFeedback();
+
+    // close activity when screen turns off
+    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) {
+                finish();
+            }
+        }
+    };
+
+    private String mLastNumber; // last number we tried to dial. Used to restore error dialog.
+
+    @Override
+    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+        // Do nothing
+    }
+
+    @Override
+    public void onTextChanged(CharSequence input, int start, int before, int changeCount) {
+        // Do nothing
+    }
+
+    @Override
+    public void afterTextChanged(Editable input) {
+        // Check for special sequences, in particular the "**04" or "**05"
+        // sequences that allow you to enter PIN or PUK-related codes.
+        //
+        // But note we *don't* allow most other special sequences here,
+        // like "secret codes" (*#*#<code>#*#*) or IMEI display ("*#06#"),
+        // since those shouldn't be available if the device is locked.
+        //
+        // So we call SpecialCharSequenceMgr.handleCharsForLockedDevice()
+        // here, not the regular handleChars() method.
+        if (SpecialCharSequenceMgr.handleCharsForLockedDevice(this, input.toString(), this)) {
+            // A special sequence was entered, clear the digits
+            mDigits.getText().clear();
+        }
+
+        updateDialAndDeleteButtonStateEnabledAttr();
+    }
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        mApp = PhoneGlobals.getInstance();
+        mStatusBarManager = (StatusBarManager) getSystemService(Context.STATUS_BAR_SERVICE);
+        mAccessibilityManager = (AccessibilityManager) getSystemService(ACCESSIBILITY_SERVICE);
+
+        // Allow this activity to be displayed in front of the keyguard / lockscreen.
+        WindowManager.LayoutParams lp = getWindow().getAttributes();
+        lp.flags |= WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
+        if (!mApp.proximitySensorModeEnabled()) {
+            // When no proximity sensor is available, use a shorter timeout.
+            lp.userActivityTimeout = USER_ACTIVITY_TIMEOUT_WHEN_NO_PROX_SENSOR;
+        }
+        getWindow().setAttributes(lp);
+
+        setContentView(R.layout.emergency_dialer);
+
+        mDigits = (EditText) findViewById(R.id.digits);
+        mDigits.setKeyListener(DialerKeyListener.getInstance());
+        mDigits.setOnClickListener(this);
+        mDigits.setOnKeyListener(this);
+        mDigits.setLongClickable(false);
+        if (mAccessibilityManager.isEnabled()) {
+            // The text view must be selected to send accessibility events.
+            mDigits.setSelected(true);
+        }
+        maybeAddNumberFormatting();
+
+        // Check for the presence of the keypad
+        View view = findViewById(R.id.one);
+        if (view != null) {
+            setupKeypad();
+        }
+
+        mDelete = findViewById(R.id.deleteButton);
+        mDelete.setOnClickListener(this);
+        mDelete.setOnLongClickListener(this);
+
+        mDialButton = findViewById(R.id.dialButton);
+
+        // Check whether we should show the onscreen "Dial" button and co.
+        Resources res = getResources();
+        if (res.getBoolean(R.bool.config_show_onscreen_dial_button)) {
+            mDialButton.setOnClickListener(this);
+        } else {
+            mDialButton.setVisibility(View.GONE);
+        }
+
+        if (icicle != null) {
+            super.onRestoreInstanceState(icicle);
+        }
+
+        // Extract phone number from intent
+        Uri data = getIntent().getData();
+        if (data != null && (Constants.SCHEME_TEL.equals(data.getScheme()))) {
+            String number = PhoneNumberUtils.getNumberFromIntent(getIntent(), this);
+            if (number != null) {
+                mDigits.setText(number);
+            }
+        }
+
+        // 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.
+        synchronized (mToneGeneratorLock) {
+            if (mToneGenerator == null) {
+                try {
+                    mToneGenerator = new ToneGenerator(DIAL_TONE_STREAM_TYPE, TONE_RELATIVE_VOLUME);
+                } catch (RuntimeException e) {
+                    Log.w(LOG_TAG, "Exception caught while creating local tone generator: " + e);
+                    mToneGenerator = null;
+                }
+            }
+        }
+
+        final IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
+        registerReceiver(mBroadcastReceiver, intentFilter);
+
+        try {
+            mHaptic.init(this, res.getBoolean(R.bool.config_enable_dialer_key_vibration));
+        } catch (Resources.NotFoundException nfe) {
+             Log.e(LOG_TAG, "Vibrate control bool missing.", nfe);
+        }
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        synchronized (mToneGeneratorLock) {
+            if (mToneGenerator != null) {
+                mToneGenerator.release();
+                mToneGenerator = null;
+            }
+        }
+        unregisterReceiver(mBroadcastReceiver);
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Bundle icicle) {
+        mLastNumber = icicle.getString(LAST_NUMBER);
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putString(LAST_NUMBER, mLastNumber);
+    }
+
+    /**
+     * Explicitly turn off number formatting, since it gets in the way of the emergency
+     * number detector
+     */
+    protected void maybeAddNumberFormatting() {
+        // Do nothing.
+    }
+
+    @Override
+    protected void onPostCreate(Bundle savedInstanceState) {
+        super.onPostCreate(savedInstanceState);
+
+        // This can't be done in onCreate(), since the auto-restoring of the digits
+        // will play DTMF tones for all the old digits if it is when onRestoreSavedInstanceState()
+        // is called. This method will be called every time the activity is created, and
+        // will always happen after onRestoreSavedInstanceState().
+        mDigits.addTextChangedListener(this);
+    }
+
+    private void setupKeypad() {
+        // Setup the listeners for the buttons
+        for (int id : DIALER_KEYS) {
+            final View key = findViewById(id);
+            key.setOnClickListener(this);
+            key.setOnHoverListener(this);
+        }
+
+        View view = findViewById(R.id.zero);
+        view.setOnLongClickListener(this);
+    }
+
+    /**
+     * handle key events
+     */
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        switch (keyCode) {
+            // Happen when there's a "Call" hard button.
+            case KeyEvent.KEYCODE_CALL: {
+                if (TextUtils.isEmpty(mDigits.getText().toString())) {
+                    // if we are adding a call from the InCallScreen and the phone
+                    // number entered is empty, we just close the dialer to expose
+                    // the InCallScreen under it.
+                    finish();
+                } else {
+                    // otherwise, we place the call.
+                    placeCall();
+                }
+                return true;
+            }
+        }
+        return super.onKeyDown(keyCode, event);
+    }
+
+    private void keyPressed(int keyCode) {
+        mHaptic.vibrate();
+        KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
+        mDigits.onKeyDown(keyCode, event);
+    }
+
+    @Override
+    public boolean onKey(View view, int keyCode, KeyEvent event) {
+        switch (view.getId()) {
+            case R.id.digits:
+                // Happen when "Done" button of the IME is pressed. This can happen when this
+                // Activity is forced into landscape mode due to a desk dock.
+                if (keyCode == KeyEvent.KEYCODE_ENTER
+                        && event.getAction() == KeyEvent.ACTION_UP) {
+                    placeCall();
+                    return true;
+                }
+                break;
+        }
+        return false;
+    }
+
+    @Override
+    public void onClick(View view) {
+        switch (view.getId()) {
+            case R.id.one: {
+                playTone(ToneGenerator.TONE_DTMF_1);
+                keyPressed(KeyEvent.KEYCODE_1);
+                return;
+            }
+            case R.id.two: {
+                playTone(ToneGenerator.TONE_DTMF_2);
+                keyPressed(KeyEvent.KEYCODE_2);
+                return;
+            }
+            case R.id.three: {
+                playTone(ToneGenerator.TONE_DTMF_3);
+                keyPressed(KeyEvent.KEYCODE_3);
+                return;
+            }
+            case R.id.four: {
+                playTone(ToneGenerator.TONE_DTMF_4);
+                keyPressed(KeyEvent.KEYCODE_4);
+                return;
+            }
+            case R.id.five: {
+                playTone(ToneGenerator.TONE_DTMF_5);
+                keyPressed(KeyEvent.KEYCODE_5);
+                return;
+            }
+            case R.id.six: {
+                playTone(ToneGenerator.TONE_DTMF_6);
+                keyPressed(KeyEvent.KEYCODE_6);
+                return;
+            }
+            case R.id.seven: {
+                playTone(ToneGenerator.TONE_DTMF_7);
+                keyPressed(KeyEvent.KEYCODE_7);
+                return;
+            }
+            case R.id.eight: {
+                playTone(ToneGenerator.TONE_DTMF_8);
+                keyPressed(KeyEvent.KEYCODE_8);
+                return;
+            }
+            case R.id.nine: {
+                playTone(ToneGenerator.TONE_DTMF_9);
+                keyPressed(KeyEvent.KEYCODE_9);
+                return;
+            }
+            case R.id.zero: {
+                playTone(ToneGenerator.TONE_DTMF_0);
+                keyPressed(KeyEvent.KEYCODE_0);
+                return;
+            }
+            case R.id.pound: {
+                playTone(ToneGenerator.TONE_DTMF_P);
+                keyPressed(KeyEvent.KEYCODE_POUND);
+                return;
+            }
+            case R.id.star: {
+                playTone(ToneGenerator.TONE_DTMF_S);
+                keyPressed(KeyEvent.KEYCODE_STAR);
+                return;
+            }
+            case R.id.deleteButton: {
+                keyPressed(KeyEvent.KEYCODE_DEL);
+                return;
+            }
+            case R.id.dialButton: {
+                mHaptic.vibrate();  // Vibrate here too, just like we do for the regular keys
+                placeCall();
+                return;
+            }
+            case R.id.digits: {
+                if (mDigits.length() != 0) {
+                    mDigits.setCursorVisible(true);
+                }
+                return;
+            }
+        }
+    }
+
+    /**
+     * 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()) {
+
+            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 left = v.getPaddingLeft();
+                    final int right = (v.getWidth() - v.getPaddingRight());
+                    final int top = v.getPaddingTop();
+                    final int bottom = (v.getHeight() - v.getPaddingBottom());
+                    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;
+    }
+
+    /**
+     * called for long touch events
+     */
+    @Override
+    public boolean onLongClick(View view) {
+        int id = view.getId();
+        switch (id) {
+            case R.id.deleteButton: {
+                mDigits.getText().clear();
+                // TODO: The framework forgets to clear the pressed
+                // status of disabled button. Until this is fixed,
+                // clear manually the pressed status. b/2133127
+                mDelete.setPressed(false);
+                return true;
+            }
+            case R.id.zero: {
+                keyPressed(KeyEvent.KEYCODE_PLUS);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        // retrieve the DTMF tone play back setting.
+        mDTMFToneEnabled = Settings.System.getInt(getContentResolver(),
+                Settings.System.DTMF_TONE_WHEN_DIALING, 1) == 1;
+
+        // Retrieve the haptic feedback setting.
+        mHaptic.checkSystemSetting();
+
+        // 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.
+        synchronized (mToneGeneratorLock) {
+            if (mToneGenerator == null) {
+                try {
+                    mToneGenerator = new ToneGenerator(AudioManager.STREAM_DTMF,
+                            TONE_RELATIVE_VOLUME);
+                } catch (RuntimeException e) {
+                    Log.w(LOG_TAG, "Exception caught while creating local tone generator: " + e);
+                    mToneGenerator = null;
+                }
+            }
+        }
+
+        // Disable the status bar and set the poke lock timeout to medium.
+        // There is no need to do anything with the wake lock.
+        if (DBG) Log.d(LOG_TAG, "disabling status bar, set to long timeout");
+        mStatusBarManager.disable(StatusBarManager.DISABLE_EXPAND);
+
+        updateDialAndDeleteButtonStateEnabledAttr();
+    }
+
+    @Override
+    public void onPause() {
+        // Reenable the status bar and set the poke lock timeout to default.
+        // There is no need to do anything with the wake lock.
+        if (DBG) Log.d(LOG_TAG, "reenabling status bar and closing the dialer");
+        mStatusBarManager.disable(StatusBarManager.DISABLE_NONE);
+
+        super.onPause();
+
+        synchronized (mToneGeneratorLock) {
+            if (mToneGenerator != null) {
+                mToneGenerator.release();
+                mToneGenerator = null;
+            }
+        }
+    }
+
+    /**
+     * place the call, but check to make sure it is a viable number.
+     */
+    private void placeCall() {
+        mLastNumber = mDigits.getText().toString();
+        if (PhoneNumberUtils.isLocalEmergencyNumber(mLastNumber, this)) {
+            if (DBG) Log.d(LOG_TAG, "placing call to " + mLastNumber);
+
+            // place the call if it is a valid number
+            if (mLastNumber == null || !TextUtils.isGraphic(mLastNumber)) {
+                // There is no number entered.
+                playTone(ToneGenerator.TONE_PROP_NACK);
+                return;
+            }
+            Intent intent = new Intent(Intent.ACTION_CALL_EMERGENCY);
+            intent.setData(Uri.fromParts(Constants.SCHEME_TEL, mLastNumber, null));
+            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            startActivity(intent);
+            finish();
+        } else {
+            if (DBG) Log.d(LOG_TAG, "rejecting bad requested number " + mLastNumber);
+
+            // erase the number and throw up an alert dialog.
+            mDigits.getText().delete(0, mDigits.getText().length());
+            showDialog(BAD_EMERGENCY_NUMBER_DIALOG);
+        }
+    }
+
+    /**
+     * Plays the specified tone for TONE_LENGTH_MS milliseconds.
+     *
+     * The tone is played locally, using the audio stream for phone calls.
+     * Tones are played only if the "Audible touch tones" user preference
+     * is checked, and are NOT played if the device is in silent mode.
+     *
+     * @param tone a tone code from {@link ToneGenerator}
+     */
+    void playTone(int tone) {
+        // if local tone playback is disabled, just return.
+        if (!mDTMFToneEnabled) {
+            return;
+        }
+
+        // Also do nothing if the phone is in silent mode.
+        // We need to re-check the ringer mode for *every* playTone()
+        // call, rather than keeping a local flag that's updated in
+        // onResume(), since it's possible to toggle silent mode without
+        // leaving the current activity (via the ENDCALL-longpress menu.)
+        AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+        int ringerMode = audioManager.getRingerMode();
+        if ((ringerMode == AudioManager.RINGER_MODE_SILENT)
+            || (ringerMode == AudioManager.RINGER_MODE_VIBRATE)) {
+            return;
+        }
+
+        synchronized (mToneGeneratorLock) {
+            if (mToneGenerator == null) {
+                Log.w(LOG_TAG, "playTone: mToneGenerator == null, tone: " + tone);
+                return;
+            }
+
+            // Start the new tone (will stop any playing tone)
+            mToneGenerator.startTone(tone, TONE_LENGTH_MS);
+        }
+    }
+
+    private CharSequence createErrorMessage(String number) {
+        if (!TextUtils.isEmpty(number)) {
+            return getString(R.string.dial_emergency_error, mLastNumber);
+        } else {
+            return getText(R.string.dial_emergency_empty_error).toString();
+        }
+    }
+
+    @Override
+    protected Dialog onCreateDialog(int id) {
+        AlertDialog dialog = null;
+        if (id == BAD_EMERGENCY_NUMBER_DIALOG) {
+            // construct dialog
+            dialog = new AlertDialog.Builder(this)
+                    .setTitle(getText(R.string.emergency_enable_radio_dialog_title))
+                    .setMessage(createErrorMessage(mLastNumber))
+                    .setPositiveButton(R.string.ok, null)
+                    .setCancelable(true).create();
+
+            // blur stuff behind the dialog
+            dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
+        }
+        return dialog;
+    }
+
+    @Override
+    protected void onPrepareDialog(int id, Dialog dialog) {
+        super.onPrepareDialog(id, dialog);
+        if (id == BAD_EMERGENCY_NUMBER_DIALOG) {
+            AlertDialog alert = (AlertDialog) dialog;
+            alert.setMessage(createErrorMessage(mLastNumber));
+        }
+    }
+
+    /**
+     * Update the enabledness of the "Dial" and "Backspace" buttons if applicable.
+     */
+    private void updateDialAndDeleteButtonStateEnabledAttr() {
+        final boolean notEmpty = mDigits.length() != 0;
+
+        mDialButton.setEnabled(notEmpty);
+        mDelete.setEnabled(notEmpty);
+    }
+}
diff --git a/src/com/android/phone/EnableFdnScreen.java b/src/com/android/phone/EnableFdnScreen.java
new file mode 100644
index 0000000..0db47c3
--- /dev/null
+++ b/src/com/android/phone/EnableFdnScreen.java
@@ -0,0 +1,150 @@
+/*
+ * 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.app.Activity;
+import android.os.AsyncResult;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.text.TextUtils;
+import android.text.method.DigitsKeyListener;
+import android.util.Log;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.internal.telephony.CommandException;
+import com.android.internal.telephony.Phone;
+
+/**
+ * UI to enable/disable FDN.
+ */
+public class EnableFdnScreen extends Activity {
+    private static final String LOG_TAG = PhoneGlobals.LOG_TAG;
+    private static final boolean DBG = false;
+
+    private static final int ENABLE_FDN_COMPLETE = 100;
+
+    private LinearLayout mPinFieldContainer;
+    private EditText mPin2Field;
+    private TextView mStatusField;
+    private boolean mEnable;
+    private Phone mPhone;
+
+    private Handler mHandler = new Handler() {
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case ENABLE_FDN_COMPLETE:
+                    AsyncResult ar = (AsyncResult) msg.obj;
+                    handleResult(ar);
+                    break;
+            }
+
+            return;
+        }
+    };
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        setContentView(R.layout.enable_fdn_screen);
+        setupView();
+
+        mPhone = PhoneGlobals.getPhone();
+        mEnable = !mPhone.getIccCard().getIccFdnEnabled();
+
+        int id = mEnable ? R.string.enable_fdn : R.string.disable_fdn;
+        setTitle(getResources().getText(id));
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        mPhone = PhoneGlobals.getPhone();
+    }
+
+    private void setupView() {
+        mPin2Field = (EditText) findViewById(R.id.pin);
+        mPin2Field.setKeyListener(DigitsKeyListener.getInstance());
+        mPin2Field.setMovementMethod(null);
+        mPin2Field.setOnClickListener(mClicked);
+
+        mPinFieldContainer = (LinearLayout) findViewById(R.id.pinc);
+        mStatusField = (TextView) findViewById(R.id.status);
+    }
+
+    private void showStatus(CharSequence statusMsg) {
+        if (statusMsg != null) {
+            mStatusField.setText(statusMsg);
+            mStatusField.setVisibility(View.VISIBLE);
+            mPinFieldContainer.setVisibility(View.GONE);
+        } else {
+            mPinFieldContainer.setVisibility(View.VISIBLE);
+            mStatusField.setVisibility(View.GONE);
+        }
+    }
+
+    private String getPin2() {
+        return mPin2Field.getText().toString();
+    }
+
+    private void enableFdn() {
+        Message callback = Message.obtain(mHandler, ENABLE_FDN_COMPLETE);
+        mPhone.getIccCard().setIccFdnEnabled(mEnable, getPin2(), callback);
+        if (DBG) log("enableFdn: please wait...");
+    }
+
+    private void handleResult(AsyncResult ar) {
+        if (ar.exception == null) {
+            if (DBG) log("handleResult: success!");
+            showStatus(getResources().getText(mEnable ?
+                            R.string.enable_fdn_ok : R.string.disable_fdn_ok));
+        } else if (ar.exception instanceof CommandException
+                /* && ((CommandException)ar.exception).getCommandError() ==
+                    CommandException.Error.GENERIC_FAILURE */ ) {
+            if (DBG) log("handleResult: failed!");
+            showStatus(getResources().getText(
+                    R.string.pin_failed));
+        }
+
+        mHandler.postDelayed(new Runnable() {
+            public void run() {
+                finish();
+            }
+        }, 3000);
+    }
+
+    private View.OnClickListener mClicked = new View.OnClickListener() {
+        public void onClick(View v) {
+            if (TextUtils.isEmpty(mPin2Field.getText())) {
+                return;
+            }
+
+            showStatus(getResources().getText(
+                    R.string.enable_in_progress));
+
+            enableFdn();
+        }
+    };
+
+    private void log(String msg) {
+        Log.d(LOG_TAG, "[EnableSimPin] " + msg);
+    }
+}
diff --git a/src/com/android/phone/EnableIccPinScreen.java b/src/com/android/phone/EnableIccPinScreen.java
new file mode 100644
index 0000000..160978f
--- /dev/null
+++ b/src/com/android/phone/EnableIccPinScreen.java
@@ -0,0 +1,145 @@
+/*
+ * 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.app.Activity;
+import android.os.AsyncResult;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.text.TextUtils;
+import android.text.method.DigitsKeyListener;
+import android.util.Log;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.internal.telephony.CommandException;
+import com.android.internal.telephony.Phone;
+
+/**
+ * UI to enable/disable the ICC PIN.
+ */
+public class EnableIccPinScreen extends Activity {
+    private static final String LOG_TAG = PhoneGlobals.LOG_TAG;
+
+    private static final int ENABLE_ICC_PIN_COMPLETE = 100;
+    private static final boolean DBG = false;
+
+    private LinearLayout mPinFieldContainer;
+    private EditText mPinField;
+    private TextView mStatusField;
+    private boolean mEnable;
+    private Phone mPhone;
+
+    private Handler mHandler = new Handler() {
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case ENABLE_ICC_PIN_COMPLETE:
+                    AsyncResult ar = (AsyncResult) msg.obj;
+                    handleResult(ar);
+                    break;
+            }
+
+            return;
+        }
+    };
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        setContentView(R.layout.enable_sim_pin_screen);
+        setupView();
+
+        mPhone = PhoneGlobals.getPhone();
+        mEnable = !mPhone.getIccCard().getIccLockEnabled();
+
+        int id = mEnable ? R.string.enable_sim_pin : R.string.disable_sim_pin;
+        setTitle(getResources().getText(id));
+    }
+
+    private void setupView() {
+        mPinField = (EditText) findViewById(R.id.pin);
+        mPinField.setKeyListener(DigitsKeyListener.getInstance());
+        mPinField.setMovementMethod(null);
+        mPinField.setOnClickListener(mClicked);
+
+        mPinFieldContainer = (LinearLayout) findViewById(R.id.pinc);
+        mStatusField = (TextView) findViewById(R.id.status);
+    }
+
+    private void showStatus(CharSequence statusMsg) {
+        if (statusMsg != null) {
+            mStatusField.setText(statusMsg);
+            mStatusField.setVisibility(View.VISIBLE);
+            mPinFieldContainer.setVisibility(View.GONE);
+        } else {
+            mPinFieldContainer.setVisibility(View.VISIBLE);
+            mStatusField.setVisibility(View.GONE);
+        }
+    }
+
+    private String getPin() {
+        return mPinField.getText().toString();
+    }
+
+    private void enableIccPin() {
+        Message callback = Message.obtain(mHandler, ENABLE_ICC_PIN_COMPLETE);
+        if (DBG) log("enableIccPin:");
+        mPhone.getIccCard().setIccLockEnabled(mEnable, getPin(), callback);
+        if (DBG) log("enableIccPin: please wait...");
+    }
+
+    private void handleResult(AsyncResult ar) {
+        if (ar.exception == null) {
+            if (DBG) log("handleResult: success!");
+            showStatus(getResources().getText(
+                    mEnable ? R.string.enable_pin_ok : R.string.disable_pin_ok));
+        } else if (ar.exception instanceof CommandException
+                /* && ((CommandException)ar.exception).getCommandError() ==
+                    CommandException.Error.GENERIC_FAILURE */ ) {
+            if (DBG) log("handleResult: failed!");
+            showStatus(getResources().getText(
+                    R.string.pin_failed));
+        }
+
+        mHandler.postDelayed(new Runnable() {
+            public void run() {
+                finish();
+            }
+        }, 3000);
+    }
+
+    private View.OnClickListener mClicked = new View.OnClickListener() {
+        public void onClick(View v) {
+            if (TextUtils.isEmpty(mPinField.getText())) {
+                return;
+            }
+
+            showStatus(getResources().getText(
+                    R.string.enable_in_progress));
+
+            enableIccPin();
+        }
+    };
+
+    private void log(String msg) {
+        Log.d(LOG_TAG, "[EnableIccPin] " + msg);
+    }
+}
diff --git a/src/com/android/phone/EventLogTags.logtags b/src/com/android/phone/EventLogTags.logtags
new file mode 100644
index 0000000..474a01c
--- /dev/null
+++ b/src/com/android/phone/EventLogTags.logtags
@@ -0,0 +1,9 @@
+# See system/core/logcat/event.logtags for a description of the format of this file.
+
+option java_package com.android.phone;
+
+70301 phone_ui_enter
+70302 phone_ui_exit
+70303 phone_ui_button_click (text|3)
+70304 phone_ui_ringer_query_elapsed
+70305 phone_ui_multiple_query
diff --git a/src/com/android/phone/FakePhoneActivity.java b/src/com/android/phone/FakePhoneActivity.java
new file mode 100644
index 0000000..686a766
--- /dev/null
+++ b/src/com/android/phone/FakePhoneActivity.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2007 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.app.Activity;
+import android.app.NotificationManager;
+import android.os.Bundle;
+import com.android.internal.telephony.test.SimulatedRadioControl;
+import android.util.Log;
+import android.view.View.OnClickListener;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.Toast;
+
+/**
+ * A simple activity that presents you with a UI for faking incoming phone operations.
+ */
+public class FakePhoneActivity extends Activity {
+    private static final String TAG = "FakePhoneActivity";
+
+    private Button mPlaceCall;
+    private EditText mPhoneNumber;
+    SimulatedRadioControl mRadioControl;
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        setContentView(R.layout.fake_phone_activity);
+
+        mPlaceCall = (Button) findViewById(R.id.placeCall);
+        mPlaceCall.setOnClickListener(new ButtonListener());
+
+        mPhoneNumber = (EditText) findViewById(R.id.phoneNumber);
+        mPhoneNumber.setOnClickListener(
+                new View.OnClickListener() {
+                    public void onClick(View v) {
+                        mPlaceCall.requestFocus();
+                    }
+                });
+
+        mRadioControl = PhoneGlobals.getPhone().getSimulatedRadioControl();
+
+        Log.i(TAG, "- PhoneApp.getInstance(): " + PhoneGlobals.getInstance());
+        Log.i(TAG, "- PhoneApp.getPhone(): " + PhoneGlobals.getPhone());
+        Log.i(TAG, "- mRadioControl: " + mRadioControl);
+    }
+
+    private class ButtonListener implements OnClickListener {
+        public void onClick(View v) {
+            if (mRadioControl == null) {
+                Log.e("Phone", "SimulatedRadioControl not available, abort!");
+                NotificationManager nm =
+                        (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
+                Toast.makeText(FakePhoneActivity.this, "null mRadioControl!",
+                        Toast.LENGTH_SHORT).show();
+                return;
+            }
+            
+            mRadioControl.triggerRing(mPhoneNumber.getText().toString());
+        }
+    }
+}
diff --git a/src/com/android/phone/FdnList.java b/src/com/android/phone/FdnList.java
new file mode 100644
index 0000000..bd9680c
--- /dev/null
+++ b/src/com/android/phone/FdnList.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2007 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.app.ActionBar;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.ListView;
+
+/**
+ * FDN List UI for the Phone app.
+ */
+public class FdnList extends ADNList {
+    private static final int MENU_ADD = 1;
+    private static final int MENU_EDIT = 2;
+    private static final int MENU_DELETE = 3;
+
+    private static final String INTENT_EXTRA_NAME = "name";
+    private static final String INTENT_EXTRA_NUMBER = "number";
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        ActionBar actionBar = getActionBar();
+        if (actionBar != null) {
+            // android.R.id.home will be triggered in onOptionsItemSelected()
+            actionBar.setDisplayHomeAsUpEnabled(true);
+        }
+    }
+
+    @Override
+    protected Uri resolveIntent() {
+        Intent intent = getIntent();
+        intent.setData(Uri.parse("content://icc/fdn"));
+        return intent.getData();
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+
+        Resources r = getResources();
+
+        // Added the icons to the context menu
+        menu.add(0, MENU_ADD, 0, r.getString(R.string.menu_add))
+                .setIcon(android.R.drawable.ic_menu_add);
+        menu.add(0, MENU_EDIT, 0, r.getString(R.string.menu_edit))
+                .setIcon(android.R.drawable.ic_menu_edit);
+        menu.add(0, MENU_DELETE, 0, r.getString(R.string.menu_delete))
+                .setIcon(android.R.drawable.ic_menu_delete);
+        return true;
+    }
+
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        super.onPrepareOptionsMenu(menu);
+        boolean hasSelection = (getSelectedItemPosition() >= 0);
+
+        menu.findItem(MENU_ADD).setVisible(true);
+        menu.findItem(MENU_EDIT).setVisible(hasSelection);
+        menu.findItem(MENU_DELETE).setVisible(hasSelection);
+
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case android.R.id.home:  // See ActionBar#setDisplayHomeAsUpEnabled()
+                Intent intent = new Intent(this, FdnSetting.class);
+                intent.setAction(Intent.ACTION_MAIN);
+                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+                startActivity(intent);
+                finish();
+                return true;
+
+            case MENU_ADD:
+                addContact();
+                return true;
+
+            case MENU_EDIT:
+                editSelected();
+                return true;
+
+            case MENU_DELETE:
+                deleteSelected();
+                return true;
+        }
+
+        return super.onOptionsItemSelected(item);
+    }
+
+    @Override
+    public void onListItemClick(ListView l, View v, int position, long id) {
+        // TODO: is this what we really want?
+        editSelected(position);
+    }
+
+    private void addContact() {
+        // if we don't put extras "name" when starting this activity, then
+        // EditFdnContactScreen treats it like add contact.
+        Intent intent = new Intent();
+        intent.setClass(this, EditFdnContactScreen.class);
+        startActivity(intent);
+    }
+
+    /**
+     * Overloaded to call editSelected with the current selection
+     * by default.  This method may have a problem with touch UI
+     * since touch UI does not really have a concept of "selected"
+     * items.
+     */
+    private void editSelected() {
+        editSelected(getSelectedItemPosition());
+    }
+
+    /**
+     * Edit the item at the selected position in the list.
+     */
+    private void editSelected(int position) {
+        if (mCursor.moveToPosition(position)) {
+            String name = mCursor.getString(NAME_COLUMN);
+            String number = mCursor.getString(NUMBER_COLUMN);
+
+            Intent intent = new Intent();
+            intent.setClass(this, EditFdnContactScreen.class);
+            intent.putExtra(INTENT_EXTRA_NAME, name);
+            intent.putExtra(INTENT_EXTRA_NUMBER, number);
+            startActivity(intent);
+        }
+    }
+
+    private void deleteSelected() {
+        if (mCursor.moveToPosition(getSelectedItemPosition())) {
+            String name = mCursor.getString(NAME_COLUMN);
+            String number = mCursor.getString(NUMBER_COLUMN);
+
+            Intent intent = new Intent();
+            intent.setClass(this, DeleteFdnContactScreen.class);
+            intent.putExtra(INTENT_EXTRA_NAME, name);
+            intent.putExtra(INTENT_EXTRA_NUMBER, number);
+            startActivity(intent);
+        }
+    }
+}
diff --git a/src/com/android/phone/FdnSetting.java b/src/com/android/phone/FdnSetting.java
new file mode 100644
index 0000000..283d612
--- /dev/null
+++ b/src/com/android/phone/FdnSetting.java
@@ -0,0 +1,493 @@
+/*
+ * 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.app.ActionBar;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.os.AsyncResult;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceScreen;
+import android.view.MenuItem;
+import android.view.WindowManager;
+import android.widget.Toast;
+
+import com.android.internal.telephony.CommandException;
+import com.android.internal.telephony.Phone;
+
+/**
+ * FDN settings UI for the Phone app.
+ * Rewritten to look and behave closer to the other preferences.
+ */
+public class FdnSetting extends PreferenceActivity
+        implements EditPinPreference.OnPinEnteredListener, DialogInterface.OnCancelListener {
+
+    private static final String LOG_TAG = PhoneGlobals.LOG_TAG;
+    private static final boolean DBG = false;
+
+    private Phone mPhone;
+
+    /**
+     * Events we handle.
+     * The first is used for toggling FDN enable, the second for the PIN change.
+     */
+    private static final int EVENT_PIN2_ENTRY_COMPLETE = 100;
+    private static final int EVENT_PIN2_CHANGE_COMPLETE = 200;
+
+    // String keys for preference lookup
+    // We only care about the pin preferences here, the manage FDN contacts
+    // Preference is handled solely in xml.
+    private static final String BUTTON_FDN_ENABLE_KEY = "button_fdn_enable_key";
+    private static final String BUTTON_CHANGE_PIN2_KEY = "button_change_pin2_key";
+
+    private EditPinPreference mButtonEnableFDN;
+    private EditPinPreference mButtonChangePin2;
+
+    // State variables
+    private String mOldPin;
+    private String mNewPin;
+    private String mPuk2;
+    private static final int PIN_CHANGE_OLD = 0;
+    private static final int PIN_CHANGE_NEW = 1;
+    private static final int PIN_CHANGE_REENTER = 2;
+    private static final int PIN_CHANGE_PUK = 3;
+    private static final int PIN_CHANGE_NEW_PIN_FOR_PUK = 4;
+    private static final int PIN_CHANGE_REENTER_PIN_FOR_PUK = 5;
+    private int mPinChangeState;
+    private boolean mIsPuk2Locked;    // Indicates we know that we are PUK2 blocked.
+
+    private static final String SKIP_OLD_PIN_KEY = "skip_old_pin_key";
+    private static final String PIN_CHANGE_STATE_KEY = "pin_change_state_key";
+    private static final String OLD_PIN_KEY = "old_pin_key";
+    private static final String NEW_PIN_KEY = "new_pin_key";
+    private static final String DIALOG_MESSAGE_KEY = "dialog_message_key";
+    private static final String DIALOG_PIN_ENTRY_KEY = "dialog_pin_entry_key";
+
+    // size limits for the pin.
+    private static final int MIN_PIN_LENGTH = 4;
+    private static final int MAX_PIN_LENGTH = 8;
+
+    /**
+     * Delegate to the respective handlers.
+     */
+    @Override
+    public void onPinEntered(EditPinPreference preference, boolean positiveResult) {
+        if (preference == mButtonEnableFDN) {
+            toggleFDNEnable(positiveResult);
+        } else if (preference == mButtonChangePin2){
+            updatePINChangeState(positiveResult);
+        }
+    }
+
+    /**
+     * Attempt to toggle FDN activation.
+     */
+    private void toggleFDNEnable(boolean positiveResult) {
+        if (!positiveResult) {
+            return;
+        }
+
+        // validate the pin first, before submitting it to the RIL for FDN enable.
+        String password = mButtonEnableFDN.getText();
+        if (validatePin (password, false)) {
+            // get the relevant data for the icc call
+            boolean isEnabled = mPhone.getIccCard().getIccFdnEnabled();
+            Message onComplete = mFDNHandler.obtainMessage(EVENT_PIN2_ENTRY_COMPLETE);
+
+            // make fdn request
+            mPhone.getIccCard().setIccFdnEnabled(!isEnabled, password, onComplete);
+        } else {
+            // throw up error if the pin is invalid.
+            displayMessage(R.string.invalidPin2);
+        }
+
+        mButtonEnableFDN.setText("");
+    }
+
+    /**
+     * Attempt to change the pin.
+     */
+    private void updatePINChangeState(boolean positiveResult) {
+        if (DBG) log("updatePINChangeState positive=" + positiveResult
+                + " mPinChangeState=" + mPinChangeState
+                + " mSkipOldPin=" + mIsPuk2Locked);
+
+        if (!positiveResult) {
+            // reset the state on cancel, either to expect PUK2 or PIN2
+            if (!mIsPuk2Locked) {
+                resetPinChangeState();
+            } else {
+                resetPinChangeStateForPUK2();
+            }
+            return;
+        }
+
+        // Progress through the dialog states, generally in this order:
+        //   1. Enter old pin
+        //   2. Enter new pin
+        //   3. Re-Enter new pin
+        // While handling any error conditions that may show up in between.
+        // Also handle the PUK2 entry, if it is requested.
+        //
+        // In general, if any invalid entries are made, the dialog re-
+        // appears with text to indicate what the issue is.
+        switch (mPinChangeState) {
+            case PIN_CHANGE_OLD:
+                mOldPin = mButtonChangePin2.getText();
+                mButtonChangePin2.setText("");
+                // if the pin is not valid, display a message and reset the state.
+                if (validatePin (mOldPin, false)) {
+                    mPinChangeState = PIN_CHANGE_NEW;
+                    displayPinChangeDialog();
+                } else {
+                    displayPinChangeDialog(R.string.invalidPin2, true);
+                }
+                break;
+            case PIN_CHANGE_NEW:
+                mNewPin = mButtonChangePin2.getText();
+                mButtonChangePin2.setText("");
+                // if the new pin is not valid, display a message and reset the state.
+                if (validatePin (mNewPin, false)) {
+                    mPinChangeState = PIN_CHANGE_REENTER;
+                    displayPinChangeDialog();
+                } else {
+                    displayPinChangeDialog(R.string.invalidPin2, true);
+                }
+                break;
+            case PIN_CHANGE_REENTER:
+                // if the re-entered pin is not valid, display a message and reset the state.
+                if (!mNewPin.equals(mButtonChangePin2.getText())) {
+                    mPinChangeState = PIN_CHANGE_NEW;
+                    mButtonChangePin2.setText("");
+                    displayPinChangeDialog(R.string.mismatchPin2, true);
+                } else {
+                    // If the PIN is valid, then we submit the change PIN request.
+                    mButtonChangePin2.setText("");
+                    Message onComplete = mFDNHandler.obtainMessage(
+                            EVENT_PIN2_CHANGE_COMPLETE);
+                    mPhone.getIccCard().changeIccFdnPassword(
+                            mOldPin, mNewPin, onComplete);
+                }
+                break;
+            case PIN_CHANGE_PUK: {
+                    // Doh! too many incorrect requests, PUK requested.
+                    mPuk2 = mButtonChangePin2.getText();
+                    mButtonChangePin2.setText("");
+                    // if the puk is not valid, display
+                    // a message and reset the state.
+                    if (validatePin (mPuk2, true)) {
+                        mPinChangeState = PIN_CHANGE_NEW_PIN_FOR_PUK;
+                        displayPinChangeDialog();
+                    } else {
+                        displayPinChangeDialog(R.string.invalidPuk2, true);
+                    }
+                }
+                break;
+            case PIN_CHANGE_NEW_PIN_FOR_PUK:
+                mNewPin = mButtonChangePin2.getText();
+                mButtonChangePin2.setText("");
+                // if the new pin is not valid, display
+                // a message and reset the state.
+                if (validatePin (mNewPin, false)) {
+                    mPinChangeState = PIN_CHANGE_REENTER_PIN_FOR_PUK;
+                    displayPinChangeDialog();
+                } else {
+                    displayPinChangeDialog(R.string.invalidPin2, true);
+                }
+                break;
+            case PIN_CHANGE_REENTER_PIN_FOR_PUK:
+                // if the re-entered pin is not valid, display
+                // a message and reset the state.
+                if (!mNewPin.equals(mButtonChangePin2.getText())) {
+                    mPinChangeState = PIN_CHANGE_NEW_PIN_FOR_PUK;
+                    mButtonChangePin2.setText("");
+                    displayPinChangeDialog(R.string.mismatchPin2, true);
+                } else {
+                    // Both puk2 and new pin2 are ready to submit
+                    mButtonChangePin2.setText("");
+                    Message onComplete = mFDNHandler.obtainMessage(
+                            EVENT_PIN2_CHANGE_COMPLETE);
+                    mPhone.getIccCard().supplyPuk2(mPuk2, mNewPin, onComplete);
+                }
+                break;
+        }
+    }
+
+    /**
+     * Handler for asynchronous replies from the sim.
+     */
+    private final Handler mFDNHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+
+                // when we are enabling FDN, either we are unsuccessful and display
+                // a toast, or just update the UI.
+                case EVENT_PIN2_ENTRY_COMPLETE: {
+                        AsyncResult ar = (AsyncResult) msg.obj;
+                        if (ar.exception != null) {
+                            // see if PUK2 is requested and alert the user accordingly.
+                            CommandException ce = (CommandException) ar.exception;
+                            if (ce.getCommandError() == CommandException.Error.SIM_PUK2) {
+                                // make sure we set the PUK2 state so that we can skip
+                                // some redundant behaviour.
+                                displayMessage(R.string.fdn_enable_puk2_requested);
+                                resetPinChangeStateForPUK2();
+                            } else {
+                                displayMessage(R.string.pin2_invalid);
+                            }
+                        }
+                        updateEnableFDN();
+                    }
+                    break;
+
+                // when changing the pin we need to pay attention to whether or not
+                // the error requests a PUK (usually after too many incorrect tries)
+                // Set the state accordingly.
+                case EVENT_PIN2_CHANGE_COMPLETE: {
+                        if (DBG)
+                            log("Handle EVENT_PIN2_CHANGE_COMPLETE");
+                        AsyncResult ar = (AsyncResult) msg.obj;
+                        if (ar.exception != null) {
+                            CommandException ce = (CommandException) ar.exception;
+                            if (ce.getCommandError() == CommandException.Error.SIM_PUK2) {
+                                // throw an alert dialog on the screen, displaying the
+                                // request for a PUK2.  set the cancel listener to
+                                // FdnSetting.onCancel().
+                                AlertDialog a = new AlertDialog.Builder(FdnSetting.this)
+                                    .setMessage(R.string.puk2_requested)
+                                    .setCancelable(true)
+                                    .setOnCancelListener(FdnSetting.this)
+                                    .create();
+                                a.getWindow().addFlags(
+                                        WindowManager.LayoutParams.FLAG_DIM_BEHIND);
+                                a.show();
+                            } else {
+                                // set the correct error message depending upon the state.
+                                // Reset the state depending upon or knowledge of the PUK state.
+                                if (!mIsPuk2Locked) {
+                                    displayMessage(R.string.badPin2);
+                                    resetPinChangeState();
+                                } else {
+                                    displayMessage(R.string.badPuk2);
+                                    resetPinChangeStateForPUK2();
+                                }
+                            }
+                        } else {
+                            // reset to normal behaviour on successful change.
+                            displayMessage(R.string.pin2_changed);
+                            resetPinChangeState();
+                        }
+                    }
+                    break;
+            }
+        }
+    };
+
+    /**
+     * Cancel listener for the PUK2 request alert dialog.
+     */
+    @Override
+    public void onCancel(DialogInterface dialog) {
+        // set the state of the preference and then display the dialog.
+        resetPinChangeStateForPUK2();
+        displayPinChangeDialog(0, true);
+    }
+
+    /**
+     * Display a toast for message, like the rest of the settings.
+     */
+    private final void displayMessage(int strId) {
+        Toast.makeText(this, getString(strId), Toast.LENGTH_SHORT)
+            .show();
+    }
+
+    /**
+     * The next two functions are for updating the message field on the dialog.
+     */
+    private final void displayPinChangeDialog() {
+        displayPinChangeDialog(0, true);
+    }
+
+    private final void displayPinChangeDialog(int strId, boolean shouldDisplay) {
+        int msgId;
+        switch (mPinChangeState) {
+            case PIN_CHANGE_OLD:
+                msgId = R.string.oldPin2Label;
+                break;
+            case PIN_CHANGE_NEW:
+            case PIN_CHANGE_NEW_PIN_FOR_PUK:
+                msgId = R.string.newPin2Label;
+                break;
+            case PIN_CHANGE_REENTER:
+            case PIN_CHANGE_REENTER_PIN_FOR_PUK:
+                msgId = R.string.confirmPin2Label;
+                break;
+            case PIN_CHANGE_PUK:
+            default:
+                msgId = R.string.label_puk2_code;
+                break;
+        }
+
+        // append the note / additional message, if needed.
+        if (strId != 0) {
+            mButtonChangePin2.setDialogMessage(getText(msgId) + "\n" + getText(strId));
+        } else {
+            mButtonChangePin2.setDialogMessage(msgId);
+        }
+
+        // only display if requested.
+        if (shouldDisplay) {
+            mButtonChangePin2.showPinDialog();
+        }
+    }
+
+    /**
+     * Reset the state of the pin change dialog.
+     */
+    private final void resetPinChangeState() {
+        if (DBG) log("resetPinChangeState");
+        mPinChangeState = PIN_CHANGE_OLD;
+        displayPinChangeDialog(0, false);
+        mOldPin = mNewPin = "";
+        mIsPuk2Locked = false;
+    }
+
+    /**
+     * Reset the state of the pin change dialog solely for PUK2 use.
+     */
+    private final void resetPinChangeStateForPUK2() {
+        if (DBG) log("resetPinChangeStateForPUK2");
+        mPinChangeState = PIN_CHANGE_PUK;
+        displayPinChangeDialog(0, false);
+        mOldPin = mNewPin = mPuk2 = "";
+        mIsPuk2Locked = true;
+    }
+
+    /**
+     * Validate the pin entry.
+     *
+     * @param pin This is the pin to validate
+     * @param isPuk Boolean indicating whether we are to treat
+     * the pin input as a puk.
+     */
+    private boolean validatePin(String pin, boolean isPuk) {
+
+        // for pin, we have 4-8 numbers, or puk, we use only 8.
+        int pinMinimum = isPuk ? MAX_PIN_LENGTH : MIN_PIN_LENGTH;
+
+        // check validity
+        if (pin == null || pin.length() < pinMinimum || pin.length() > MAX_PIN_LENGTH) {
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    /**
+     * Reflect the updated FDN state in the UI.
+     */
+    private void updateEnableFDN() {
+        if (mPhone.getIccCard().getIccFdnEnabled()) {
+            mButtonEnableFDN.setTitle(R.string.enable_fdn_ok);
+            mButtonEnableFDN.setSummary(R.string.fdn_enabled);
+            mButtonEnableFDN.setDialogTitle(R.string.disable_fdn);
+        } else {
+            mButtonEnableFDN.setTitle(R.string.disable_fdn_ok);
+            mButtonEnableFDN.setSummary(R.string.fdn_disabled);
+            mButtonEnableFDN.setDialogTitle(R.string.enable_fdn);
+        }
+    }
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        addPreferencesFromResource(R.xml.fdn_setting);
+
+        mPhone = PhoneGlobals.getPhone();
+
+        //get UI object references
+        PreferenceScreen prefSet = getPreferenceScreen();
+        mButtonEnableFDN = (EditPinPreference) prefSet.findPreference(BUTTON_FDN_ENABLE_KEY);
+        mButtonChangePin2 = (EditPinPreference) prefSet.findPreference(BUTTON_CHANGE_PIN2_KEY);
+
+        //assign click listener and update state
+        mButtonEnableFDN.setOnPinEnteredListener(this);
+        updateEnableFDN();
+
+        mButtonChangePin2.setOnPinEnteredListener(this);
+
+        // Only reset the pin change dialog if we're not in the middle of changing it.
+        if (icicle == null) {
+            resetPinChangeState();
+        } else {
+            mIsPuk2Locked = icicle.getBoolean(SKIP_OLD_PIN_KEY);
+            mPinChangeState = icicle.getInt(PIN_CHANGE_STATE_KEY);
+            mOldPin = icicle.getString(OLD_PIN_KEY);
+            mNewPin = icicle.getString(NEW_PIN_KEY);
+            mButtonChangePin2.setDialogMessage(icicle.getString(DIALOG_MESSAGE_KEY));
+            mButtonChangePin2.setText(icicle.getString(DIALOG_PIN_ENTRY_KEY));
+        }
+
+        ActionBar actionBar = getActionBar();
+        if (actionBar != null) {
+            // android.R.id.home will be triggered in onOptionsItemSelected()
+            actionBar.setDisplayHomeAsUpEnabled(true);
+        }
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        mPhone = PhoneGlobals.getPhone();
+        updateEnableFDN();
+    }
+
+    /**
+     * Save the state of the pin change.
+     */
+    @Override
+    protected void onSaveInstanceState(Bundle out) {
+        super.onSaveInstanceState(out);
+        out.putBoolean(SKIP_OLD_PIN_KEY, mIsPuk2Locked);
+        out.putInt(PIN_CHANGE_STATE_KEY, mPinChangeState);
+        out.putString(OLD_PIN_KEY, mOldPin);
+        out.putString(NEW_PIN_KEY, mNewPin);
+        out.putString(DIALOG_MESSAGE_KEY, mButtonChangePin2.getDialogMessage().toString());
+        out.putString(DIALOG_PIN_ENTRY_KEY, mButtonChangePin2.getText());
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        final int itemId = item.getItemId();
+        if (itemId == android.R.id.home) {  // See ActionBar#setDisplayHomeAsUpEnabled()
+            CallFeaturesSetting.goUpToTopLevelSetting(this);
+            return true;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    private void log(String msg) {
+        Log.d(LOG_TAG, "FdnSetting: " + msg);
+    }
+}
+
diff --git a/src/com/android/phone/GetPin2Screen.java b/src/com/android/phone/GetPin2Screen.java
new file mode 100644
index 0000000..a06b0cf
--- /dev/null
+++ b/src/com/android/phone/GetPin2Screen.java
@@ -0,0 +1,97 @@
+/*
+ * 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.app.Activity;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.text.method.DigitsKeyListener;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.inputmethod.EditorInfo;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.TextView;
+
+/**
+ * Pin2 entry screen.
+ */
+public class GetPin2Screen extends Activity implements TextView.OnEditorActionListener {
+    private static final String LOG_TAG = PhoneGlobals.LOG_TAG;
+
+    private EditText mPin2Field;
+    private Button mOkButton;
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        setContentView(R.layout.get_pin2_screen);
+
+        mPin2Field = (EditText) findViewById(R.id.pin);
+        mPin2Field.setKeyListener(DigitsKeyListener.getInstance());
+        mPin2Field.setMovementMethod(null);
+        mPin2Field.setOnEditorActionListener(this);
+
+        mOkButton = (Button) findViewById(R.id.ok);
+        mOkButton.setOnClickListener(mClicked);
+    }
+
+    private String getPin2() {
+        return mPin2Field.getText().toString();
+    }
+
+    private void returnResult() {
+        Bundle map = new Bundle();
+        map.putString("pin2", getPin2());
+
+        Intent intent = getIntent();
+        Uri uri = intent.getData();
+
+        Intent action = new Intent();
+        if (uri != null) action.setAction(uri.toString());
+        setResult(RESULT_OK, action.putExtras(map));
+        finish();
+    }
+
+    @Override
+    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+        if (actionId == EditorInfo.IME_ACTION_DONE) {
+            mOkButton.performClick();
+            return true;
+        }
+        return false;
+    }
+
+    private final View.OnClickListener mClicked = new View.OnClickListener() {
+        @Override
+        public void onClick(View v) {
+            if (TextUtils.isEmpty(mPin2Field.getText())) {
+                return;
+            }
+
+            returnResult();
+        }
+    };
+
+    private void log(String msg) {
+        Log.d(LOG_TAG, "[GetPin2] " + msg);
+    }
+}
diff --git a/src/com/android/phone/GsmUmtsAdditionalCallOptions.java b/src/com/android/phone/GsmUmtsAdditionalCallOptions.java
new file mode 100644
index 0000000..cd400f9
--- /dev/null
+++ b/src/com/android/phone/GsmUmtsAdditionalCallOptions.java
@@ -0,0 +1,95 @@
+package com.android.phone;
+
+import android.app.ActionBar;
+import android.content.Intent;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.PreferenceScreen;
+import android.util.Log;
+import android.view.MenuItem;
+
+import java.util.ArrayList;
+
+public class GsmUmtsAdditionalCallOptions extends
+        TimeConsumingPreferenceActivity {
+    private static final String LOG_TAG = "GsmUmtsAdditionalCallOptions";
+    private final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
+
+    private static final String BUTTON_CLIR_KEY  = "button_clir_key";
+    private static final String BUTTON_CW_KEY    = "button_cw_key";
+
+    private CLIRListPreference mCLIRButton;
+    private CallWaitingCheckBoxPreference mCWButton;
+
+    private final ArrayList<Preference> mPreferences = new ArrayList<Preference>();
+    private int mInitIndex= 0;
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        addPreferencesFromResource(R.xml.gsm_umts_additional_options);
+
+        PreferenceScreen prefSet = getPreferenceScreen();
+        mCLIRButton = (CLIRListPreference) prefSet.findPreference(BUTTON_CLIR_KEY);
+        mCWButton = (CallWaitingCheckBoxPreference) prefSet.findPreference(BUTTON_CW_KEY);
+
+        mPreferences.add(mCLIRButton);
+        mPreferences.add(mCWButton);
+
+        if (icicle == null) {
+            if (DBG) Log.d(LOG_TAG, "start to init ");
+            mCLIRButton.init(this, false);
+        } else {
+            if (DBG) Log.d(LOG_TAG, "restore stored states");
+            mInitIndex = mPreferences.size();
+            mCLIRButton.init(this, true);
+            mCWButton.init(this, true);
+            int[] clirArray = icicle.getIntArray(mCLIRButton.getKey());
+            if (clirArray != null) {
+                if (DBG) Log.d(LOG_TAG, "onCreate:  clirArray[0]="
+                        + clirArray[0] + ", clirArray[1]=" + clirArray[1]);
+                mCLIRButton.handleGetCLIRResult(clirArray);
+            } else {
+                mCLIRButton.init(this, false);
+            }
+        }
+
+        ActionBar actionBar = getActionBar();
+        if (actionBar != null) {
+            // android.R.id.home will be triggered in onOptionsItemSelected()
+            actionBar.setDisplayHomeAsUpEnabled(true);
+        }
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+
+        if (mCLIRButton.clirArray != null) {
+            outState.putIntArray(mCLIRButton.getKey(), mCLIRButton.clirArray);
+        }
+    }
+
+    @Override
+    public void onFinished(Preference preference, boolean reading) {
+        if (mInitIndex < mPreferences.size()-1 && !isFinishing()) {
+            mInitIndex++;
+            Preference pref = mPreferences.get(mInitIndex);
+            if (pref instanceof CallWaitingCheckBoxPreference) {
+                ((CallWaitingCheckBoxPreference) pref).init(this, false);
+            }
+        }
+        super.onFinished(preference, reading);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        final int itemId = item.getItemId();
+        if (itemId == android.R.id.home) {  // See ActionBar#setDisplayHomeAsUpEnabled()
+            CallFeaturesSetting.goUpToTopLevelSetting(this);
+            return true;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+}
diff --git a/src/com/android/phone/GsmUmtsCallForwardOptions.java b/src/com/android/phone/GsmUmtsCallForwardOptions.java
new file mode 100644
index 0000000..8ecb1bf
--- /dev/null
+++ b/src/com/android/phone/GsmUmtsCallForwardOptions.java
@@ -0,0 +1,181 @@
+package com.android.phone;
+
+import com.android.internal.telephony.CallForwardInfo;
+import com.android.internal.telephony.CommandsInterface;
+
+import android.app.ActionBar;
+import android.content.Intent;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.PreferenceScreen;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.util.Log;
+import android.view.MenuItem;
+
+import java.util.ArrayList;
+
+
+public class GsmUmtsCallForwardOptions extends TimeConsumingPreferenceActivity {
+    private static final String LOG_TAG = "GsmUmtsCallForwardOptions";
+    private final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
+
+    private static final String NUM_PROJECTION[] = {Phone.NUMBER};
+
+    private static final String BUTTON_CFU_KEY   = "button_cfu_key";
+    private static final String BUTTON_CFB_KEY   = "button_cfb_key";
+    private static final String BUTTON_CFNRY_KEY = "button_cfnry_key";
+    private static final String BUTTON_CFNRC_KEY = "button_cfnrc_key";
+
+    private static final String KEY_TOGGLE = "toggle";
+    private static final String KEY_STATUS = "status";
+    private static final String KEY_NUMBER = "number";
+
+    private CallForwardEditPreference mButtonCFU;
+    private CallForwardEditPreference mButtonCFB;
+    private CallForwardEditPreference mButtonCFNRy;
+    private CallForwardEditPreference mButtonCFNRc;
+
+    private final ArrayList<CallForwardEditPreference> mPreferences =
+            new ArrayList<CallForwardEditPreference> ();
+    private int mInitIndex= 0;
+
+    private boolean mFirstResume;
+    private Bundle mIcicle;
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        addPreferencesFromResource(R.xml.callforward_options);
+
+        PreferenceScreen prefSet = getPreferenceScreen();
+        mButtonCFU   = (CallForwardEditPreference) prefSet.findPreference(BUTTON_CFU_KEY);
+        mButtonCFB   = (CallForwardEditPreference) prefSet.findPreference(BUTTON_CFB_KEY);
+        mButtonCFNRy = (CallForwardEditPreference) prefSet.findPreference(BUTTON_CFNRY_KEY);
+        mButtonCFNRc = (CallForwardEditPreference) prefSet.findPreference(BUTTON_CFNRC_KEY);
+
+        mButtonCFU.setParentActivity(this, mButtonCFU.reason);
+        mButtonCFB.setParentActivity(this, mButtonCFB.reason);
+        mButtonCFNRy.setParentActivity(this, mButtonCFNRy.reason);
+        mButtonCFNRc.setParentActivity(this, mButtonCFNRc.reason);
+
+        mPreferences.add(mButtonCFU);
+        mPreferences.add(mButtonCFB);
+        mPreferences.add(mButtonCFNRy);
+        mPreferences.add(mButtonCFNRc);
+
+        // we wait to do the initialization until onResume so that the
+        // TimeConsumingPreferenceActivity dialog can display as it
+        // relies on onResume / onPause to maintain its foreground state.
+
+        mFirstResume = true;
+        mIcicle = icicle;
+
+        ActionBar actionBar = getActionBar();
+        if (actionBar != null) {
+            // android.R.id.home will be triggered in onOptionsItemSelected()
+            actionBar.setDisplayHomeAsUpEnabled(true);
+        }
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+
+        if (mFirstResume) {
+            if (mIcicle == null) {
+                if (DBG) Log.d(LOG_TAG, "start to init ");
+                mPreferences.get(mInitIndex).init(this, false);
+            } else {
+                mInitIndex = mPreferences.size();
+
+                for (CallForwardEditPreference pref : mPreferences) {
+                    Bundle bundle = mIcicle.getParcelable(pref.getKey());
+                    pref.setToggled(bundle.getBoolean(KEY_TOGGLE));
+                    CallForwardInfo cf = new CallForwardInfo();
+                    cf.number = bundle.getString(KEY_NUMBER);
+                    cf.status = bundle.getInt(KEY_STATUS);
+                    pref.handleCallForwardResult(cf);
+                    pref.init(this, true);
+                }
+            }
+            mFirstResume = false;
+            mIcicle=null;
+        }
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+
+        for (CallForwardEditPreference pref : mPreferences) {
+            Bundle bundle = new Bundle();
+            bundle.putBoolean(KEY_TOGGLE, pref.isToggled());
+            if (pref.callForwardInfo != null) {
+                bundle.putString(KEY_NUMBER, pref.callForwardInfo.number);
+                bundle.putInt(KEY_STATUS, pref.callForwardInfo.status);
+            }
+            outState.putParcelable(pref.getKey(), bundle);
+        }
+    }
+
+    @Override
+    public void onFinished(Preference preference, boolean reading) {
+        if (mInitIndex < mPreferences.size()-1 && !isFinishing()) {
+            mInitIndex++;
+            mPreferences.get(mInitIndex).init(this, false);
+        }
+
+        super.onFinished(preference, reading);
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (DBG) Log.d(LOG_TAG, "onActivityResult: done");
+        if (resultCode != RESULT_OK) {
+            if (DBG) Log.d(LOG_TAG, "onActivityResult: contact picker result not OK.");
+            return;
+        }
+        Cursor cursor = null;
+        try {
+            cursor = getContentResolver().query(data.getData(),
+                NUM_PROJECTION, null, null, null);
+            if ((cursor == null) || (!cursor.moveToFirst())) {
+                if (DBG) Log.d(LOG_TAG, "onActivityResult: bad contact data, no results found.");
+                return;
+            }
+
+            switch (requestCode) {
+                case CommandsInterface.CF_REASON_UNCONDITIONAL:
+                    mButtonCFU.onPickActivityResult(cursor.getString(0));
+                    break;
+                case CommandsInterface.CF_REASON_BUSY:
+                    mButtonCFB.onPickActivityResult(cursor.getString(0));
+                    break;
+                case CommandsInterface.CF_REASON_NO_REPLY:
+                    mButtonCFNRy.onPickActivityResult(cursor.getString(0));
+                    break;
+                case CommandsInterface.CF_REASON_NOT_REACHABLE:
+                    mButtonCFNRc.onPickActivityResult(cursor.getString(0));
+                    break;
+                default:
+                    // TODO: may need exception here.
+            }
+        } finally {
+            if (cursor != null) {
+                cursor.close();
+            }
+        }
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        final int itemId = item.getItemId();
+        if (itemId == android.R.id.home) {  // See ActionBar#setDisplayHomeAsUpEnabled()
+            CallFeaturesSetting.goUpToTopLevelSetting(this);
+            return true;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+}
diff --git a/src/com/android/phone/GsmUmtsCallOptions.java b/src/com/android/phone/GsmUmtsCallOptions.java
new file mode 100644
index 0000000..a9a1940
--- /dev/null
+++ b/src/com/android/phone/GsmUmtsCallOptions.java
@@ -0,0 +1,43 @@
+/*
+ * 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.os.Bundle;
+import android.preference.CheckBoxPreference;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceScreen;
+
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
+
+public class GsmUmtsCallOptions extends PreferenceActivity {
+    private static final String LOG_TAG = "GsmUmtsCallOptions";
+    private final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        addPreferencesFromResource(R.xml.gsm_umts_call_options);
+
+        if (PhoneGlobals.getPhone().getPhoneType() != PhoneConstants.PHONE_TYPE_GSM) {
+            //disable the entire screen
+            getPreferenceScreen().setEnabled(false);
+        }
+    }
+}
diff --git a/src/com/android/phone/GsmUmtsOptions.java b/src/com/android/phone/GsmUmtsOptions.java
new file mode 100644
index 0000000..1f1ac4a
--- /dev/null
+++ b/src/com/android/phone/GsmUmtsOptions.java
@@ -0,0 +1,106 @@
+/*
+ * 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.preference.CheckBoxPreference;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceScreen;
+import android.content.res.Resources;
+
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.PhoneFactory;
+
+/**
+ * List of Network-specific settings screens.
+ */
+public class GsmUmtsOptions {
+    private static final String LOG_TAG = "GsmUmtsOptions";
+
+    private PreferenceScreen mButtonAPNExpand;
+    private PreferenceScreen mButtonOperatorSelectionExpand;
+    private CheckBoxPreference mButtonPrefer2g;
+
+    private static final String BUTTON_APN_EXPAND_KEY = "button_apn_key";
+    private static final String BUTTON_OPERATOR_SELECTION_EXPAND_KEY = "button_carrier_sel_key";
+    private static final String BUTTON_PREFER_2G_KEY = "button_prefer_2g_key";
+    private PreferenceActivity mPrefActivity;
+    private PreferenceScreen mPrefScreen;
+
+    public GsmUmtsOptions(PreferenceActivity prefActivity, PreferenceScreen prefScreen) {
+        mPrefActivity = prefActivity;
+        mPrefScreen = prefScreen;
+        create();
+    }
+
+    protected void create() {
+        mPrefActivity.addPreferencesFromResource(R.xml.gsm_umts_options);
+        mButtonAPNExpand = (PreferenceScreen) mPrefScreen.findPreference(BUTTON_APN_EXPAND_KEY);
+        mButtonOperatorSelectionExpand =
+                (PreferenceScreen) mPrefScreen.findPreference(BUTTON_OPERATOR_SELECTION_EXPAND_KEY);
+        mButtonPrefer2g = (CheckBoxPreference) mPrefScreen.findPreference(BUTTON_PREFER_2G_KEY);
+        if (PhoneFactory.getDefaultPhone().getPhoneType() != PhoneConstants.PHONE_TYPE_GSM) {
+            log("Not a GSM phone");
+            mButtonAPNExpand.setEnabled(false);
+            mButtonOperatorSelectionExpand.setEnabled(false);
+            mButtonPrefer2g.setEnabled(false);
+        } else {
+            log("Not a CDMA phone");
+            Resources res = mPrefActivity.getResources();
+
+            // Determine which options to display, for GSM these are defaulted
+            // are defaulted to true in Phone/res/values/config.xml. But for
+            // some operators like verizon they maybe overriden in operator
+            // specific resources or device specifc overlays.
+            if (!res.getBoolean(R.bool.config_apn_expand)) {
+                mPrefScreen.removePreference(mPrefScreen.findPreference(BUTTON_APN_EXPAND_KEY));
+            }
+            if (!res.getBoolean(R.bool.config_operator_selection_expand)) {
+                mPrefScreen.removePreference(mPrefScreen
+                        .findPreference(BUTTON_OPERATOR_SELECTION_EXPAND_KEY));
+            }
+            if (!res.getBoolean(R.bool.config_prefer_2g)) {
+                mPrefScreen.removePreference(mPrefScreen.findPreference(BUTTON_PREFER_2G_KEY));
+            }
+
+            if (res.getBoolean(R.bool.csp_enabled)) {
+                if (PhoneFactory.getDefaultPhone().isCspPlmnEnabled()) {
+                    log("[CSP] Enabling Operator Selection menu.");
+                    mButtonOperatorSelectionExpand.setEnabled(true);
+                } else {
+                    log("[CSP] Disabling Operator Selection menu.");
+                    mPrefScreen.removePreference(mPrefScreen
+                          .findPreference(BUTTON_OPERATOR_SELECTION_EXPAND_KEY));
+                }
+            }
+        }
+    }
+
+    public boolean preferenceTreeClick(Preference preference) {
+        if (preference.getKey().equals(BUTTON_PREFER_2G_KEY)) {
+            log("preferenceTreeClick: return true");
+            return true;
+        }
+        log("preferenceTreeClick: return false");
+        return false;
+    }
+
+    protected void log(String s) {
+        android.util.Log.d(LOG_TAG, s);
+    }
+}
diff --git a/src/com/android/phone/INetworkQueryService.aidl b/src/com/android/phone/INetworkQueryService.aidl
new file mode 100644
index 0000000..749163c
--- /dev/null
+++ b/src/com/android/phone/INetworkQueryService.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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 com.android.phone.INetworkQueryServiceCallback;
+ 
+/**
+ * Service interface to handle queries for available networks.  The
+ * Phone application lets this service interface handle carrier 
+ * availability queries instead of making direct calls to the 
+ * GSMPhone layer.
+ */
+oneway interface INetworkQueryService {
+ 
+    /**
+     * Starts a network query if it has not been started yet, and
+     * request a callback through the INetworkQueryServiceCallback
+     * object on query completion.  If there is an existing request,
+     * then just add the callback to the list of notifications
+     * that will be sent upon query completion.
+     */
+    void startNetworkQuery(in INetworkQueryServiceCallback cb);
+ 
+    /**
+     * Tells the service that the requested query is to be ignored.
+     * This may not do anything for the Query request in the 
+     * underlying RIL, but it ensures that the callback is removed
+     * from the list of notifications.
+     */
+    void stopNetworkQuery(in INetworkQueryServiceCallback cb);
+}
diff --git a/src/com/android/phone/INetworkQueryServiceCallback.aidl b/src/com/android/phone/INetworkQueryServiceCallback.aidl
new file mode 100644
index 0000000..4c32883
--- /dev/null
+++ b/src/com/android/phone/INetworkQueryServiceCallback.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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 com.android.internal.telephony.OperatorInfo;
+
+/**
+ * Service interface to handle callbacks into the activity from the
+ * NetworkQueryService.  These objects are used to notify that a
+ * query is complete and that the results are ready to process.
+ */
+oneway interface INetworkQueryServiceCallback {
+
+    /**
+     * Called upon query completion, handing a status value and an
+     * array of OperatorInfo objects.
+     *
+     * @param networkInfoArray is the list of OperatorInfo. Can be
+     * null, indicating no results were found, or an error.
+     * @param status the status indicating if there were any
+     * problems with the request.
+     */
+    void onQueryComplete(in List<OperatorInfo> networkInfoArray, int status);
+
+}
diff --git a/src/com/android/phone/IccNetworkDepersonalizationPanel.java b/src/com/android/phone/IccNetworkDepersonalizationPanel.java
new file mode 100644
index 0000000..aa582a1
--- /dev/null
+++ b/src/com/android/phone/IccNetworkDepersonalizationPanel.java
@@ -0,0 +1,216 @@
+/*
+ * 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.os.AsyncResult;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.text.Editable;
+import android.text.Spannable;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.text.method.DialerKeyListener;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.internal.telephony.Phone;
+
+/**
+ * "SIM network unlock" PIN entry screen.
+ *
+ * @see PhoneGlobals.EVENT_SIM_NETWORK_LOCKED
+ *
+ * TODO: This UI should be part of the lock screen, not the
+ * phone app (see bug 1804111).
+ */
+public class IccNetworkDepersonalizationPanel extends IccPanel {
+
+    //debug constants
+    private static final boolean DBG = false;
+
+    //events
+    private static final int EVENT_ICC_NTWRK_DEPERSONALIZATION_RESULT = 100;
+
+    private Phone mPhone;
+
+    //UI elements
+    private EditText     mPinEntry;
+    private LinearLayout mEntryPanel;
+    private LinearLayout mStatusPanel;
+    private TextView     mStatusText;
+
+    private Button       mUnlockButton;
+    private Button       mDismissButton;
+
+    //private textwatcher to control text entry.
+    private TextWatcher mPinEntryWatcher = new TextWatcher() {
+        public void beforeTextChanged(CharSequence buffer, int start, int olen, int nlen) {
+        }
+
+        public void onTextChanged(CharSequence buffer, int start, int olen, int nlen) {
+        }
+
+        public void afterTextChanged(Editable buffer) {
+            if (SpecialCharSequenceMgr.handleChars(
+                    getContext(), buffer.toString())) {
+                mPinEntry.getText().clear();
+            }
+        }
+    };
+
+    //handler for unlock function results
+    private Handler mHandler = new Handler() {
+        public void handleMessage(Message msg) {
+            if (msg.what == EVENT_ICC_NTWRK_DEPERSONALIZATION_RESULT) {
+                AsyncResult res = (AsyncResult) msg.obj;
+                if (res.exception != null) {
+                    if (DBG) log("network depersonalization request failure.");
+                    indicateError();
+                    postDelayed(new Runnable() {
+                                    public void run() {
+                                        hideAlert();
+                                        mPinEntry.getText().clear();
+                                        mPinEntry.requestFocus();
+                                    }
+                                }, 3000);
+                } else {
+                    if (DBG) log("network depersonalization success.");
+                    indicateSuccess();
+                    postDelayed(new Runnable() {
+                                    public void run() {
+                                        dismiss();
+                                    }
+                                }, 3000);
+                }
+            }
+        }
+    };
+
+    //constructor
+    public IccNetworkDepersonalizationPanel(Context context) {
+        super(context);
+    }
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        setContentView(R.layout.sim_ndp);
+
+        // PIN entry text field
+        mPinEntry = (EditText) findViewById(R.id.pin_entry);
+        mPinEntry.setKeyListener(DialerKeyListener.getInstance());
+        mPinEntry.setOnClickListener(mUnlockListener);
+
+        // Attach the textwatcher
+        CharSequence text = mPinEntry.getText();
+        Spannable span = (Spannable) text;
+        span.setSpan(mPinEntryWatcher, 0, text.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
+
+        mEntryPanel = (LinearLayout) findViewById(R.id.entry_panel);
+
+        mUnlockButton = (Button) findViewById(R.id.ndp_unlock);
+        mUnlockButton.setOnClickListener(mUnlockListener);
+
+        // The "Dismiss" button is present in some (but not all) products,
+        // based on the "sim_network_unlock_allow_dismiss" resource.
+        mDismissButton = (Button) findViewById(R.id.ndp_dismiss);
+        if (getContext().getResources().getBoolean(R.bool.sim_network_unlock_allow_dismiss)) {
+            if (DBG) log("Enabling 'Dismiss' button...");
+            mDismissButton.setVisibility(View.VISIBLE);
+            mDismissButton.setOnClickListener(mDismissListener);
+        } else {
+            if (DBG) log("Removing 'Dismiss' button...");
+            mDismissButton.setVisibility(View.GONE);
+        }
+
+        //status panel is used since we're having problems with the alert dialog.
+        mStatusPanel = (LinearLayout) findViewById(R.id.status_panel);
+        mStatusText = (TextView) findViewById(R.id.status_text);
+
+        mPhone = PhoneGlobals.getPhone();
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+    }
+
+    //Mirrors IccPinUnlockPanel.onKeyDown().
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        if (keyCode == KeyEvent.KEYCODE_BACK) {
+            return true;
+        }
+
+        return super.onKeyDown(keyCode, event);
+    }
+
+    View.OnClickListener mUnlockListener = new View.OnClickListener() {
+        public void onClick(View v) {
+            String pin = mPinEntry.getText().toString();
+
+            if (TextUtils.isEmpty(pin)) {
+                return;
+            }
+
+            if (DBG) log("requesting network depersonalization with code " + pin);
+            mPhone.getIccCard().supplyNetworkDepersonalization(pin,
+                    Message.obtain(mHandler, EVENT_ICC_NTWRK_DEPERSONALIZATION_RESULT));
+            indicateBusy();
+        }
+    };
+
+    private void indicateBusy() {
+        mStatusText.setText(R.string.requesting_unlock);
+        mEntryPanel.setVisibility(View.GONE);
+        mStatusPanel.setVisibility(View.VISIBLE);
+    }
+
+    private void indicateError() {
+        mStatusText.setText(R.string.unlock_failed);
+        mEntryPanel.setVisibility(View.GONE);
+        mStatusPanel.setVisibility(View.VISIBLE);
+    }
+
+    private void indicateSuccess() {
+        mStatusText.setText(R.string.unlock_success);
+        mEntryPanel.setVisibility(View.GONE);
+        mStatusPanel.setVisibility(View.VISIBLE);
+    }
+
+    private void hideAlert() {
+        mEntryPanel.setVisibility(View.VISIBLE);
+        mStatusPanel.setVisibility(View.GONE);
+    }
+
+    View.OnClickListener mDismissListener = new View.OnClickListener() {
+            public void onClick(View v) {
+                if (DBG) log("mDismissListener: skipping depersonalization...");
+                dismiss();
+            }
+        };
+
+    private void log(String msg) {
+        Log.v(TAG, "[IccNetworkDepersonalizationPanel] " + msg);
+    }
+}
diff --git a/src/com/android/phone/IccPanel.java b/src/com/android/phone/IccPanel.java
new file mode 100644
index 0000000..e603a06
--- /dev/null
+++ b/src/com/android/phone/IccPanel.java
@@ -0,0 +1,93 @@
+/*
+ * 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.app.Dialog;
+import android.app.StatusBarManager;
+import android.content.Context;
+import android.view.Gravity;
+import android.view.KeyEvent;
+import android.view.WindowManager;
+import android.view.Window;
+import android.os.Bundle;
+
+/**
+ * Base class for ICC-related panels in the Phone UI.
+ */
+public class IccPanel extends Dialog {
+    protected static final String TAG = PhoneGlobals.LOG_TAG;
+
+    private StatusBarManager mStatusBarManager;
+
+    public IccPanel(Context context) {
+        super(context, R.style.IccPanel);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Window winP = getWindow();
+        winP.setType(WindowManager.LayoutParams.TYPE_PRIORITY_PHONE);
+        winP.setLayout(WindowManager.LayoutParams.MATCH_PARENT,
+                WindowManager.LayoutParams.MATCH_PARENT);
+        winP.setGravity(Gravity.CENTER);
+
+        // TODO: Ideally, we'd like this dialog to be visible in front of the
+        // keyguard, so the user will see it immediately after boot (without
+        // needing to enter the lock pattern or dismiss the keyguard first.)
+        //
+        // However that's not easy to do.  It's not just a matter of setting
+        // the FLAG_SHOW_WHEN_LOCKED and FLAG_DISMISS_KEYGUARD flags on our
+        // window, since we're a Dialog (not an Activity), and the framework
+        // won't ever let a dialog hide the keyguard (because there could
+        // possibly be stuff behind it that shouldn't be seen.)
+        //
+        // So for now, we'll live with the fact that the user has to enter the
+        // lock pattern (or dismiss the keyguard) *before* being able to type
+        // a SIM network unlock PIN.  That's not ideal, but still OK.
+        // (And eventually this will be a moot point once this UI moves
+        // from the phone app to the framework; see bug 1804111).
+
+        // TODO: we shouldn't need the mStatusBarManager calls here either,
+        // once this dialog gets moved into the framework and becomes a truly
+        // full-screen UI.
+        PhoneGlobals app = PhoneGlobals.getInstance();
+        mStatusBarManager = (StatusBarManager) app.getSystemService(Context.STATUS_BAR_SERVICE);
+
+        requestWindowFeature(Window.FEATURE_NO_TITLE);
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+        mStatusBarManager.disable(StatusBarManager.DISABLE_EXPAND);
+    }
+
+    @Override
+    public void onStop() {
+        super.onStop();
+        mStatusBarManager.disable(StatusBarManager.DISABLE_NONE);
+    }
+
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        if (keyCode == KeyEvent.KEYCODE_BACK) {
+            return true;
+        }
+
+        return super.onKeyDown(keyCode, event);
+    }
+}
diff --git a/src/com/android/phone/IccProvider.java b/src/com/android/phone/IccProvider.java
new file mode 100644
index 0000000..827d500
--- /dev/null
+++ b/src/com/android/phone/IccProvider.java
@@ -0,0 +1,26 @@
+/*
+ * 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;
+
+/**
+ * ICC address book content provider.
+ */
+public class IccProvider extends com.android.internal.telephony.IccProvider {
+    public IccProvider() {
+        super();
+    }
+}
diff --git a/src/com/android/phone/InCallControlState.java b/src/com/android/phone/InCallControlState.java
new file mode 100644
index 0000000..e5c7f20
--- /dev/null
+++ b/src/com/android/phone/InCallControlState.java
@@ -0,0 +1,233 @@
+/*
+ * 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.Phone;
+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 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) {
+        if (DBG) log("InCallControlState constructor...");
+        mInCallScreen = inCallScreen;
+        mCM = cm;
+    }
+
+    /**
+     * 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 (mInCallScreen.isBluetoothAvailable()) {
+            bluetoothEnabled = true;
+            bluetoothIndicatorOn = mInCallScreen.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
new file mode 100644
index 0000000..d5db689
--- /dev/null
+++ b/src/com/android/phone/InCallScreen.java
@@ -0,0 +1,4612 @@
+/*
+ * 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.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";
+
+    /**
+     * Intent extra to specify the package name of the gateway
+     * provider.  Used to get the name displayed in the in-call screen
+     * during the call setup. The value is a string.
+     */
+    // TODO: This extra is currently set by the gateway application as
+    // a temporary measure. Ultimately, the framework will securely
+    // set it.
+    /* package */ static final String EXTRA_GATEWAY_PROVIDER_PACKAGE =
+            "com.android.phone.extra.GATEWAY_PROVIDER_PACKAGE";
+
+    /**
+     * Intent extra to specify the URI of the provider to place the
+     * call. The value is a string. It holds the gateway address
+     * (phone gateway URL should start with the 'tel:' scheme) that
+     * will actually be contacted to call the number passed in the
+     * intent URL or in the EXTRA_PHONE_NUMBER extra.
+     */
+    // TODO: Should the value be a Uri (Parcelable)? Need to make sure
+    // MMI code '#' don't get confused as URI fragments.
+    /* package */ static final String EXTRA_GATEWAY_URI =
+            "com.android.phone.extra.GATEWAY_URI";
+
+    // 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
+
+    // These are values for the settings of the auto retry mode:
+    // 0 = disabled
+    // 1 = enabled
+    // TODO (Moto):These constants don't really belong here,
+    // 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 REQUEST_UPDATE_BLUETOOTH_INDICATION = 114;
+    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;
+
+    private BluetoothHeadset mBluetoothHeadset;
+    private BluetoothAdapter mBluetoothAdapter;
+    private boolean mBluetoothConnectionPending;
+    private long mBluetoothConnectionRequestTime;
+
+    /** 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 boolean mIsForegroundActivityForProximity = 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 REQUEST_UPDATE_BLUETOOTH_INDICATION:
+                    if (VDBG) log("REQUEST_UPDATE_BLUETOOTH_INDICATION...");
+                    // The bluetooth headset state changed, so some UI
+                    // elements may need to update.  (There's no need to
+                    // look up the current state here, since any UI
+                    // elements that care about the bluetooth state get it
+                    // directly from PhoneApp.showBluetoothIndication().)
+                    updateScreen();
+                    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:
+                    mApp.inCallUiState.providerInfoVisible = false;
+                    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;
+        if (!mApp.proximitySensorModeEnabled()) {
+            // If we don't have a proximity sensor, then the in-call screen explicitly
+            // controls user activity.  This is to prevent spurious touches from waking
+            // the display.
+            lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_DISABLE_USER_ACTIVITY;
+        }
+        getWindow().setAttributes(lp);
+
+        setPhone(mApp.phone);  // Sets mPhone
+
+        mCM =  mApp.mCM;
+        log("- onCreate: phone state = " + mCM.getState());
+
+        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+        if (mBluetoothAdapter != null) {
+            mBluetoothAdapter.getProfileProxy(getApplicationContext(), mBluetoothProfileServiceListener,
+                                    BluetoothProfile.HEADSET);
+        }
+
+        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");
+    }
+
+     private BluetoothProfile.ServiceListener mBluetoothProfileServiceListener =
+             new BluetoothProfile.ServiceListener() {
+         @Override
+         public void onServiceConnected(int profile, BluetoothProfile proxy) {
+             mBluetoothHeadset = (BluetoothHeadset) proxy;
+             if (VDBG) log("- Got BluetoothHeadset: " + mBluetoothHeadset);
+         }
+
+         @Override
+         public void onServiceDisconnected(int profile) {
+             mBluetoothHeadset = null;
+         }
+    };
+
+    /**
+     * 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;
+        mIsForegroundActivityForProximity = 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();
+
+        // ...and update the in-call notification too, since the status bar
+        // icon needs to be hidden while we're the foreground activity:
+        mApp.notificationMgr.updateInCallNotification();
+
+        // 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 = isBluetoothAudioConnected();
+
+        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();
+
+        if (mPowerManager.isScreenOn()) {
+            // Set to false when the screen went background *not* by screen turned off. Probably
+            // the user bailed out of the in-call screen (by pressing BACK, HOME, etc.)
+            mIsForegroundActivityForProximity = false;
+        }
+        mIsForegroundActivity = false;
+
+        // Force a clear of the provider info frame. Since the
+        // frame is removed using a timed message, it is
+        // possible we missed it if the prev call was interrupted.
+        mApp.inCallUiState.providerInfoVisible = 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;
+
+        // A safety measure to disable proximity sensor in case call failed
+        // and the telephony state did not change.
+        mApp.setBeginningCall(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 the in-call notification too:
+        mApp.notificationMgr.updateInCallNotification();
+        // ...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.
+
+        if (mBluetoothHeadset != null) {
+            mBluetoothAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset);
+            mBluetoothHeadset = null;
+        }
+
+        // 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;
+    }
+
+    /**
+     * Returns true when the Activity is in foreground (between onResume() and onPause()),
+     * or, is in background due to user's bailing out of the screen, not by screen turning off.
+     *
+     * @see #isForegroundActivity()
+     */
+    /* package */ boolean isForegroundActivityForProximity() {
+        return mIsForegroundActivityForProximity;
+    }
+
+    /* 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);
+
+        // 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.
+            //
+            // See also comments for isForegroundActivityForProximity()
+            //
+            // 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() && isForegroundActivityForProximity()) {
+                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);
+        if (VDBG) dumpBluetoothState();
+
+        // 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);
+
+        if (newSpeakerState && isBluetoothAvailable() && isBluetoothAudioConnected()) {
+            disconnectBluetoothAudio();
+        }
+        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);
+    }
+
+    /**
+     * Toggles whether or not to route in-call audio to the bluetooth
+     * headset, or do nothing (but log a warning) if no bluetooth device
+     * is actually connected.
+     *
+     * TODO: this method is currently unused, but the "audio mode" UI
+     * design is still in flux so let's keep it around for now.
+     * (But if we ultimately end up *not* providing any way for the UI to
+     * simply "toggle bluetooth", we can get rid of this method.)
+     */
+    public void toggleBluetooth() {
+        if (VDBG) log("toggleBluetooth()...");
+
+        if (isBluetoothAvailable()) {
+            // Toggle the bluetooth audio connection state:
+            if (isBluetoothAudioConnected()) {
+                disconnectBluetoothAudio();
+            } else {
+                // Manually turn the speaker phone off, instead of allowing the
+                // Bluetooth audio routing to handle it, since there's other
+                // important state-updating that needs to happen in the
+                // PhoneUtils.turnOnSpeaker() method.
+                // (Similarly, whenever the user turns *on* the speaker, we
+                // manually disconnect the active bluetooth headset;
+                // see toggleSpeaker() and/or switchInCallAudio().)
+                if (PhoneUtils.isSpeakerOn(this)) {
+                    PhoneUtils.turnOnSpeaker(this, false, true);
+                }
+
+                connectBluetoothAudio();
+            }
+        } else {
+            // Bluetooth isn't available; the onscreen UI shouldn't have
+            // allowed this request in the first place!
+            Log.w(LOG_TAG, "toggleBluetooth(): bluetooth is unavailable");
+        }
+
+        // And update the InCallTouchUi widget (since the "audio mode"
+        // button might need to change its appearance based on the new
+        // audio state.)
+        updateInCallTouchUi();
+    }
+
+    /**
+     * Switches the current routing of in-call audio between speaker,
+     * bluetooth, and the built-in earpiece (or wired headset.)
+     *
+     * This method is used on devices that provide a single 3-way switch
+     * for audio routing.  For devices that provide separate toggles for
+     * Speaker and Bluetooth, see toggleBluetooth() and toggleSpeaker().
+     *
+     * TODO: UI design is still in flux.  If we end up totally
+     * eliminating the concept of Speaker and Bluetooth toggle buttons,
+     * we can get rid of toggleBluetooth() and toggleSpeaker().
+     */
+    public void switchInCallAudio(InCallAudioMode newMode) {
+        log("switchInCallAudio: new mode = " + newMode);
+        switch (newMode) {
+            case SPEAKER:
+                if (!PhoneUtils.isSpeakerOn(this)) {
+                    // Switch away from Bluetooth, if it was active.
+                    if (isBluetoothAvailable() && isBluetoothAudioConnected()) {
+                        disconnectBluetoothAudio();
+                    }
+                    PhoneUtils.turnOnSpeaker(this, true, true);
+                }
+                break;
+
+            case BLUETOOTH:
+                // If already connected to BT, there's nothing to do here.
+                if (isBluetoothAvailable() && !isBluetoothAudioConnected()) {
+                    // Manually turn the speaker phone off, instead of allowing the
+                    // Bluetooth audio routing to handle it, since there's other
+                    // important state-updating that needs to happen in the
+                    // PhoneUtils.turnOnSpeaker() method.
+                    // (Similarly, whenever the user turns *on* the speaker, we
+                    // manually disconnect the active bluetooth headset;
+                    // see toggleSpeaker() and/or switchInCallAudio().)
+                    if (PhoneUtils.isSpeakerOn(this)) {
+                        PhoneUtils.turnOnSpeaker(this, false, true);
+                    }
+                    connectBluetoothAudio();
+                }
+                break;
+
+            case EARPIECE:
+                // Switch to either the handset earpiece, or the wired headset (if connected.)
+                // (Do this by simply making sure both speaker and bluetooth are off.)
+                if (isBluetoothAvailable() && isBluetoothAudioConnected()) {
+                    disconnectBluetoothAudio();
+                }
+                if (PhoneUtils.isSpeakerOn(this)) {
+                    PhoneUtils.turnOnSpeaker(this, false, true);
+                }
+                break;
+
+            default:
+                Log.wtf(LOG_TAG, "switchInCallAudio: unexpected mode " + newMode);
+                break;
+        }
+
+        // And finally, update the InCallTouchUi widget (since the "audio
+        // mode" button might need to change its appearance based on the
+        // new audio state.)
+        updateInCallTouchUi();
+    }
+
+    /**
+     * 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
+        }
+        mApp.updateProximitySensorMode(mCM.getState());
+    }
+
+    /** 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();
+
+        mRespondViaSmsManager.showRespondViaSmsPopup(ringingCall);
+
+        // 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();
+
+        // Swap the fg and bg calls.
+        // In the future we may provides some way for user to choose among
+        // multiple background calls, for now, always act on the first background calll.
+        PhoneUtils.switchHoldingAndActive(mCM.getFirstActiveBgCall());
+
+        // If we have a valid BluetoothPhoneService then since CDMA network or
+        // Telephony FW does not send us information on which caller got swapped
+        // we need to update the second call active state in BluetoothPhoneService internally
+        if (mCM.getBgPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
+            IBluetoothHeadsetPhone btPhone = mApp.getBluetoothPhoneService();
+            if (btPhone != null) {
+                try {
+                    btPhone.cdmaSwapSecondCallState();
+                } catch (RemoteException e) {
+                    Log.e(LOG_TAG, Log.getStackTraceString(new Throwable()));
+                }
+            }
+        }
+
+    }
+
+    /**
+     * 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()));
+    }
+
+
+    //
+    // Bluetooth helper methods.
+    //
+    // - BluetoothAdapter is the Bluetooth system service.  If
+    //   getDefaultAdapter() returns null
+    //   then the device is not BT capable.  Use BluetoothDevice.isEnabled()
+    //   to see if BT is enabled on the device.
+    //
+    // - BluetoothHeadset is the API for the control connection to a
+    //   Bluetooth Headset.  This lets you completely connect/disconnect a
+    //   headset (which we don't do from the Phone UI!) but also lets you
+    //   get the address of the currently active headset and see whether
+    //   it's currently connected.
+
+    /**
+     * @return true if the Bluetooth on/off switch in the UI should be
+     *         available to the user (i.e. if the device is BT-capable
+     *         and a headset is connected.)
+     */
+    /* package */ boolean isBluetoothAvailable() {
+        if (VDBG) log("isBluetoothAvailable()...");
+
+        // There's no need to ask the Bluetooth system service if BT is enabled:
+        //
+        //    BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+        //    if ((adapter == null) || !adapter.isEnabled()) {
+        //        if (DBG) log("  ==> FALSE (BT not enabled)");
+        //        return false;
+        //    }
+        //    if (DBG) log("  - BT enabled!  device name " + adapter.getName()
+        //                 + ", address " + adapter.getAddress());
+        //
+        // ...since we already have a BluetoothHeadset instance.  We can just
+        // call isConnected() on that, and assume it'll be false if BT isn't
+        // enabled at all.
+
+        // Check if there's a connected headset, using the BluetoothHeadset API.
+        boolean isConnected = false;
+        if (mBluetoothHeadset != null) {
+            List<BluetoothDevice> deviceList = mBluetoothHeadset.getConnectedDevices();
+
+            if (deviceList.size() > 0) {
+                BluetoothDevice device = deviceList.get(0);
+                isConnected = true;
+
+                if (VDBG) log("  - headset state = " +
+                              mBluetoothHeadset.getConnectionState(device));
+                if (VDBG) log("  - headset address: " + device);
+                if (VDBG) log("  - isConnected: " + isConnected);
+            }
+        }
+
+        if (VDBG) log("  ==> " + isConnected);
+        return isConnected;
+    }
+
+    /**
+     * @return true if a BT Headset is available, and its audio is currently connected.
+     */
+    /* package */ boolean isBluetoothAudioConnected() {
+        if (mBluetoothHeadset == null) {
+            if (VDBG) log("isBluetoothAudioConnected: ==> FALSE (null mBluetoothHeadset)");
+            return false;
+        }
+        List<BluetoothDevice> deviceList = mBluetoothHeadset.getConnectedDevices();
+
+        if (deviceList.isEmpty()) {
+            return false;
+        }
+        BluetoothDevice device = deviceList.get(0);
+        boolean isAudioOn = mBluetoothHeadset.isAudioConnected(device);
+        if (VDBG) log("isBluetoothAudioConnected: ==> isAudioOn = " + isAudioOn);
+        return isAudioOn;
+    }
+
+    /**
+     * Helper method used to control the onscreen "Bluetooth" indication;
+     * see InCallControlState.bluetoothIndicatorOn.
+     *
+     * @return true if a BT device is available and its audio is currently connected,
+     *              <b>or</b> if we issued a BluetoothHeadset.connectAudio()
+     *              call within the last 5 seconds (which presumably means
+     *              that the BT audio connection is currently being set
+     *              up, and will be connected soon.)
+     */
+    /* package */ boolean isBluetoothAudioConnectedOrPending() {
+        if (isBluetoothAudioConnected()) {
+            if (VDBG) log("isBluetoothAudioConnectedOrPending: ==> TRUE (really connected)");
+            return true;
+        }
+
+        // If we issued a connectAudio() call "recently enough", even
+        // if BT isn't actually connected yet, let's still pretend BT is
+        // on.  This makes the onscreen indication more responsive.
+        if (mBluetoothConnectionPending) {
+            long timeSinceRequest =
+                    SystemClock.elapsedRealtime() - mBluetoothConnectionRequestTime;
+            if (timeSinceRequest < 5000 /* 5 seconds */) {
+                if (VDBG) log("isBluetoothAudioConnectedOrPending: ==> TRUE (requested "
+                             + timeSinceRequest + " msec ago)");
+                return true;
+            } else {
+                if (VDBG) log("isBluetoothAudioConnectedOrPending: ==> FALSE (request too old: "
+                             + timeSinceRequest + " msec ago)");
+                mBluetoothConnectionPending = false;
+                return false;
+            }
+        }
+
+        if (VDBG) log("isBluetoothAudioConnectedOrPending: ==> FALSE");
+        return false;
+    }
+
+    /**
+     * Posts a message to our handler saying to update the onscreen UI
+     * based on a bluetooth headset state change.
+     */
+    /* package */ void requestUpdateBluetoothIndication() {
+        if (VDBG) log("requestUpdateBluetoothIndication()...");
+        // No need to look at the current state here; any UI elements that
+        // care about the bluetooth state (i.e. the CallCard) get
+        // the necessary state directly from PhoneApp.showBluetoothIndication().
+        mHandler.removeMessages(REQUEST_UPDATE_BLUETOOTH_INDICATION);
+        mHandler.sendEmptyMessage(REQUEST_UPDATE_BLUETOOTH_INDICATION);
+    }
+
+    private void dumpBluetoothState() {
+        log("============== dumpBluetoothState() =============");
+        log("= isBluetoothAvailable: " + isBluetoothAvailable());
+        log("= isBluetoothAudioConnected: " + isBluetoothAudioConnected());
+        log("= isBluetoothAudioConnectedOrPending: " + isBluetoothAudioConnectedOrPending());
+        log("= PhoneApp.showBluetoothIndication: "
+            + mApp.showBluetoothIndication());
+        log("=");
+        if (mBluetoothAdapter != null) {
+            if (mBluetoothHeadset != null) {
+                List<BluetoothDevice> deviceList = mBluetoothHeadset.getConnectedDevices();
+
+                if (deviceList.size() > 0) {
+                    BluetoothDevice device = deviceList.get(0);
+                    log("= BluetoothHeadset.getCurrentDevice: " + device);
+                    log("= BluetoothHeadset.State: "
+                        + mBluetoothHeadset.getConnectionState(device));
+                    log("= BluetoothHeadset audio connected: " +
+                        mBluetoothHeadset.isAudioConnected(device));
+                }
+            } else {
+                log("= mBluetoothHeadset is null");
+            }
+        } else {
+            log("= mBluetoothAdapter is null; device is not BT capable");
+        }
+    }
+
+    /* package */ void connectBluetoothAudio() {
+        if (VDBG) log("connectBluetoothAudio()...");
+        if (mBluetoothHeadset != null) {
+            // TODO(BT) check return
+            mBluetoothHeadset.connectAudio();
+        }
+
+        // Watch out: The bluetooth connection doesn't happen instantly;
+        // the connectAudio() call returns instantly but does its real
+        // work in another thread.  The mBluetoothConnectionPending flag
+        // is just a little trickery to ensure that the onscreen UI updates
+        // instantly. (See isBluetoothAudioConnectedOrPending() above.)
+        mBluetoothConnectionPending = true;
+        mBluetoothConnectionRequestTime = SystemClock.elapsedRealtime();
+    }
+
+    /* package */ void disconnectBluetoothAudio() {
+        if (VDBG) log("disconnectBluetoothAudio()...");
+        if (mBluetoothHeadset != null) {
+            mBluetoothHeadset.disconnectAudio();
+        }
+        mBluetoothConnectionPending = false;
+    }
+
+    /**
+     * 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) {
+            if (mApp.proximitySensorModeEnabled()) {
+                // We should not enable notification's expanded view on RINGING state.
+                mApp.notificationMgr.statusBarHelper.enableExpandedView(
+                        mCM.getState() != PhoneConstants.State.RINGING);
+            } else {
+                // If proximity sensor is unavailable on the device, disable it to avoid false
+                // touches toward notifications.
+                mApp.notificationMgr.statusBarHelper.enableExpandedView(false);
+            }
+        } 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/InCallScreenShowActivation.java b/src/com/android/phone/InCallScreenShowActivation.java
new file mode 100644
index 0000000..221b915
--- /dev/null
+++ b/src/com/android/phone/InCallScreenShowActivation.java
@@ -0,0 +1,138 @@
+/*
+ * 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.app.Activity;
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.SystemProperties;
+import android.util.Log;
+
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.TelephonyCapabilities;
+
+/**
+ * Invisible activity that handles the com.android.phone.PERFORM_CDMA_PROVISIONING intent.
+ * This activity is protected by the android.permission.PERFORM_CDMA_PROVISIONING permission.
+ *
+ * We handle the PERFORM_CDMA_PROVISIONING action by launching an OTASP
+ * call via one of the OtaUtils helper methods: startInteractiveOtasp() on
+ * regular phones, or startNonInteractiveOtasp() on data-only devices.
+ *
+ * TODO: The class name InCallScreenShowActivation is misleading, since
+ * this activity is totally unrelated to the InCallScreen (which
+ * implements the in-call UI.)  Let's eventually rename this to something
+ * like CdmaProvisioningLauncher or CdmaProvisioningHandler...
+ */
+public class InCallScreenShowActivation extends Activity {
+    private static final String LOG_TAG = "InCallScreenShowActivation";
+    private static final boolean DBG =
+            (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        Intent intent = getIntent();
+        if (DBG) Log.d(LOG_TAG, "onCreate: intent = " + intent);
+        Bundle extras = intent.getExtras();
+        if (DBG && (extras != null)) {
+            Log.d(LOG_TAG, "      - has extras: size = " + extras.size()); // forces an unparcel()
+            Log.d(LOG_TAG, "      - extras = " + extras);
+        }
+
+        PhoneGlobals app = PhoneGlobals.getInstance();
+        Phone phone = app.getPhone();
+        if (!TelephonyCapabilities.supportsOtasp(phone)) {
+            Log.w(LOG_TAG, "CDMA Provisioning not supported on this device");
+            setResult(RESULT_CANCELED);
+            finish();
+            return;
+        }
+
+        if (intent.getAction().equals(OtaUtils.ACTION_PERFORM_CDMA_PROVISIONING)) {
+
+            // On voice-capable devices, we perform CDMA provisioning in
+            // "interactive" mode by directly launching the InCallScreen.
+            boolean interactiveMode = PhoneGlobals.sVoiceCapable;
+            Log.d(LOG_TAG, "ACTION_PERFORM_CDMA_PROVISIONING (interactiveMode = "
+                  + interactiveMode + ")...");
+
+            // Testing: this intent extra allows test apps manually
+            // enable/disable "interactive mode", regardless of whether
+            // the current device is voice-capable.  This is allowed only
+            // in userdebug or eng builds.
+            if (intent.hasExtra(OtaUtils.EXTRA_OVERRIDE_INTERACTIVE_MODE)
+                    && (SystemProperties.getInt("ro.debuggable", 0) == 1)) {
+                interactiveMode =
+                        intent.getBooleanExtra(OtaUtils.EXTRA_OVERRIDE_INTERACTIVE_MODE, false);
+                Log.d(LOG_TAG, "===> MANUALLY OVERRIDING interactiveMode to " + interactiveMode);
+            }
+
+            // We allow the caller to pass a PendingIntent (as the
+            // EXTRA_NONINTERACTIVE_OTASP_RESULT_PENDING_INTENT extra)
+            // which we'll later use to notify them when the OTASP call
+            // fails or succeeds.
+            //
+            // Stash that away here, and we'll fire it off later in
+            // OtaUtils.sendOtaspResult().
+            app.cdmaOtaScreenState.otaspResultCodePendingIntent =
+                        (PendingIntent) intent.getParcelableExtra(
+                                OtaUtils.EXTRA_OTASP_RESULT_CODE_PENDING_INTENT);
+
+            if (interactiveMode) {
+                // On voice-capable devices, launch an OTASP call and arrange
+                // for the in-call UI to come up.  (The InCallScreen will
+                // notice that an OTASP call is active, and display the
+                // special OTASP UI instead of the usual in-call controls.)
+
+                if (DBG) Log.d(LOG_TAG, "==> Starting interactive CDMA provisioning...");
+                OtaUtils.startInteractiveOtasp(this);
+
+                // The result we set here is actually irrelevant, since the
+                // InCallScreen's "interactive" OTASP sequence never actually
+                // finish()es; it ends by directly launching the Home
+                // activity.  So our caller won't actually ever get an
+                // onActivityResult() call in this case.
+                setResult(OtaUtils.RESULT_INTERACTIVE_OTASP_STARTED);
+            } else {
+                // On data-only devices, manually launch the OTASP call
+                // *without* displaying any UI.  (Our caller, presumably
+                // SetupWizardActivity, is responsible for displaying some
+                // sort of progress UI.)
+
+                if (DBG) Log.d(LOG_TAG, "==> Starting non-interactive CDMA provisioning...");
+                int callStatus = OtaUtils.startNonInteractiveOtasp(this);
+
+                if (callStatus == PhoneUtils.CALL_STATUS_DIALED) {
+                    if (DBG) Log.d(LOG_TAG, "  ==> successful result from startNonInteractiveOtasp(): "
+                          + callStatus);
+                    setResult(OtaUtils.RESULT_NONINTERACTIVE_OTASP_STARTED);
+                } else {
+                    Log.w(LOG_TAG, "Failure code from startNonInteractiveOtasp(): " + callStatus);
+                    setResult(OtaUtils.RESULT_NONINTERACTIVE_OTASP_FAILED);
+                }
+            }
+        } else {
+            Log.e(LOG_TAG, "Unexpected intent action: " + intent);
+            setResult(RESULT_CANCELED);
+        }
+
+        finish();
+    }
+}
diff --git a/src/com/android/phone/InCallTouchUi.java b/src/com/android/phone/InCallTouchUi.java
new file mode 100644
index 0000000..a68d066
--- /dev/null
+++ b/src/com/android/phone/InCallTouchUi.java
@@ -0,0 +1,1382 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.phone;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.content.Context;
+import android.graphics.drawable.LayerDrawable;
+import android.os.Handler;
+import android.os.Message;
+import android.os.SystemClock;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewPropertyAnimator;
+import android.view.ViewStub;
+import android.view.animation.AlphaAnimation;
+import android.view.animation.Animation;
+import android.view.animation.Animation.AnimationListener;
+import android.widget.CompoundButton;
+import android.widget.FrameLayout;
+import android.widget.ImageButton;
+import android.widget.PopupMenu;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.android.internal.telephony.Call;
+import com.android.internal.telephony.CallManager;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.widget.multiwaveview.GlowPadView;
+import com.android.internal.widget.multiwaveview.GlowPadView.OnTriggerListener;
+import com.android.phone.InCallUiState.InCallScreenMode;
+
+/**
+ * In-call onscreen touch UI elements, used on some platforms.
+ *
+ * This widget is a fullscreen overlay, drawn on top of the
+ * non-touch-sensitive parts of the in-call UI (i.e. the call card).
+ */
+public class InCallTouchUi extends FrameLayout
+        implements View.OnClickListener, View.OnLongClickListener, OnTriggerListener,
+        PopupMenu.OnMenuItemClickListener, PopupMenu.OnDismissListener {
+    private static final String LOG_TAG = "InCallTouchUi";
+    private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
+
+    // Incoming call widget targets
+    private static final int ANSWER_CALL_ID = 0;  // drag right
+    private static final int SEND_SMS_ID = 1;  // drag up
+    private static final int DECLINE_CALL_ID = 2;  // drag left
+
+    /**
+     * Reference to the InCallScreen activity that owns us.  This may be
+     * null if we haven't been initialized yet *or* after the InCallScreen
+     * activity has been destroyed.
+     */
+    private InCallScreen mInCallScreen;
+
+    // Phone app instance
+    private PhoneGlobals mApp;
+
+    // UI containers / elements
+    private GlowPadView mIncomingCallWidget;  // UI used for an incoming call
+    private boolean mIncomingCallWidgetIsFadingOut;
+    private boolean mIncomingCallWidgetShouldBeReset = true;
+
+    /** UI elements while on a regular call (bottom buttons, DTMF dialpad) */
+    private View mInCallControls;
+    private boolean mShowInCallControlsDuringHidingAnimation;
+
+    //
+    private ImageButton mAddButton;
+    private ImageButton mMergeButton;
+    private ImageButton mEndButton;
+    private CompoundButton mDialpadButton;
+    private CompoundButton mMuteButton;
+    private CompoundButton mAudioButton;
+    private CompoundButton mHoldButton;
+    private ImageButton mSwapButton;
+    private View mHoldSwapSpacer;
+    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 = 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);
+
+        // Update the GlowPadView widget's targets based on the state of
+        // the ringing call.  (Specifically, we need to disable the
+        // "respond via SMS" option for certain types of calls, like SIP
+        // addresses or numbers with blocked caller-id.)
+        final boolean allowRespondViaSms =
+                RespondViaSmsManager.allowRespondViaSmsForCall(mInCallScreen, ringingCall);
+        final int targetResourceId = allowRespondViaSms
+                ? R.array.incoming_call_widget_3way_targets
+                : R.array.incoming_call_widget_2way_targets;
+        // The widget should be updated only when appropriate; if the previous choice can be reused
+        // for this incoming call, we'll just keep using it. Otherwise we'll see UI glitch
+        // everytime when this method is called during a single incoming call.
+        if (targetResourceId != mIncomingCallWidget.getTargetResourceId()) {
+            if (allowRespondViaSms) {
+                // The GlowPadView widget is allowed to have all 3 choices:
+                // Answer, Decline, and Respond via SMS.
+                mIncomingCallWidget.setTargetResources(targetResourceId);
+                mIncomingCallWidget.setTargetDescriptionsResourceId(
+                        R.array.incoming_call_widget_3way_target_descriptions);
+                mIncomingCallWidget.setDirectionDescriptionsResourceId(
+                        R.array.incoming_call_widget_3way_direction_descriptions);
+            } else {
+                // You only get two choices: Answer or Decline.
+                mIncomingCallWidget.setTargetResources(targetResourceId);
+                mIncomingCallWidget.setTargetDescriptionsResourceId(
+                        R.array.incoming_call_widget_2way_target_descriptions);
+                mIncomingCallWidget.setDirectionDescriptionsResourceId(
+                        R.array.incoming_call_widget_2way_direction_descriptions);
+            }
+
+            // This will be used right after this block.
+            mIncomingCallWidgetShouldBeReset = true;
+        }
+        if (mIncomingCallWidgetShouldBeReset) {
+            // Watch out: be sure to call reset() and setVisibility() *after*
+            // updating the target resources, since otherwise the GlowPadView
+            // widget will make the targets visible initially (even before you
+            // touch the widget.)
+            mIncomingCallWidget.reset(false);
+            mIncomingCallWidgetShouldBeReset = false;
+        }
+
+        // On an incoming call, if the layout is landscape, then align the "incoming call" text
+        // to the left, because the incomingCallWidget (black background with glowing ring)
+        // is aligned to the right and would cover the "incoming call" text.
+        // Note that callStateLabel is within CallCard, outside of the context of InCallTouchUi
+        if (PhoneUtils.isLandscape(this.getContext())) {
+            TextView callStateLabel = (TextView) mIncomingCallWidget
+                    .getRootView().findViewById(R.id.callStateLabel);
+            if (callStateLabel != null) callStateLabel.setGravity(Gravity.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
new file mode 100644
index 0000000..3b700d7
--- /dev/null
+++ b/src/com/android/phone/InCallUiState.java
@@ -0,0 +1,453 @@
+/*
+ * 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);
+    }
+
+
+    //
+    // (4) Optional info when a 3rd party "provider" is used.
+    //     @see InCallScreen#requestRemoveProviderInfoWithDelay()
+    //     @see CallCard#updateCallStateWidgets()
+    //
+
+    // TODO: maybe isolate all the provider-related stuff out to a
+    //       separate inner class?
+    boolean providerInfoVisible;
+    CharSequence providerLabel;
+    Drawable providerIcon;
+    Uri providerGatewayUri;
+    // The formatted address extracted from mProviderGatewayUri. User visible.
+    String providerAddress;
+
+    /**
+     * Set the fields related to the provider support
+     * based on the specified intent.
+     */
+    public void setProviderInfo(Intent intent) {
+        providerLabel = PhoneUtils.getProviderLabel(mContext, intent);
+        providerIcon = PhoneUtils.getProviderIcon(mContext, intent);
+        providerGatewayUri = PhoneUtils.getProviderGatewayUri(intent);
+        providerAddress = PhoneUtils.formatProviderUri(providerGatewayUri);
+        providerInfoVisible = true;
+
+        // ...but if any of the "required" fields are missing, completely
+        // disable the overlay.
+        if (TextUtils.isEmpty(providerLabel) || providerIcon == null ||
+            providerGatewayUri == null || TextUtils.isEmpty(providerAddress)) {
+            clearProviderInfo();
+        }
+    }
+
+    /**
+     * Clear all the fields related to the provider support.
+     */
+    public void clearProviderInfo() {
+        providerInfoVisible = false;
+        providerLabel = null;
+        providerIcon = null;
+        providerGatewayUri = null;
+        providerAddress = null;
+    }
+
+    /**
+     * "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);
+        if (providerInfoVisible) {
+            log("  - provider info VISIBLE: "
+                  + providerLabel + " / "
+                  + providerIcon  + " / "
+                  + providerGatewayUri + " / "
+                  + providerAddress);
+        } else {
+            log("  - provider info: none");
+        }
+        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
new file mode 100644
index 0000000..5821754
--- /dev/null
+++ b/src/com/android/phone/ManageConferenceUtils.java
@@ -0,0 +1,358 @@
+/*
+ * 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.Button;
+import android.widget.Chronometer;
+import android.widget.ImageButton;
+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/MobileNetworkSettings.java b/src/com/android/phone/MobileNetworkSettings.java
new file mode 100644
index 0000000..e4b4de6
--- /dev/null
+++ b/src/com/android/phone/MobileNetworkSettings.java
@@ -0,0 +1,590 @@
+/*
+ * 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 com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.telephony.TelephonyProperties;
+
+import android.app.ActionBar;
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.net.ConnectivityManager;
+import android.net.Uri;
+import android.os.AsyncResult;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.SystemProperties;
+import android.preference.CheckBoxPreference;
+import android.preference.ListPreference;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceScreen;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.MenuItem;
+
+/**
+ * "Mobile network settings" screen.  This preference screen lets you
+ * enable/disable mobile data, and control data roaming and other
+ * network-specific mobile data features.  It's used on non-voice-capable
+ * tablets as well as regular phone devices.
+ *
+ * Note that this PreferenceActivity is part of the phone app, even though
+ * you reach it from the "Wireless & Networks" section of the main
+ * Settings app.  It's not part of the "Call settings" hierarchy that's
+ * available from the Phone app (see CallFeaturesSetting for that.)
+ */
+public class MobileNetworkSettings extends PreferenceActivity
+        implements DialogInterface.OnClickListener,
+        DialogInterface.OnDismissListener, Preference.OnPreferenceChangeListener{
+
+    // debug data
+    private static final String LOG_TAG = "NetworkSettings";
+    private static final boolean DBG = false;
+    public static final int REQUEST_CODE_EXIT_ECM = 17;
+
+    //String keys for preference lookup
+    private static final String BUTTON_DATA_ENABLED_KEY = "button_data_enabled_key";
+    private static final String BUTTON_PREFERED_NETWORK_MODE = "preferred_network_mode_key";
+    private static final String BUTTON_ROAMING_KEY = "button_roaming_key";
+    private static final String BUTTON_CDMA_LTE_DATA_SERVICE_KEY = "cdma_lte_data_service_key";
+
+    static final int preferredNetworkMode = Phone.PREFERRED_NT_MODE;
+
+    //Information about logical "up" Activity
+    private static final String UP_ACTIVITY_PACKAGE = "com.android.settings";
+    private static final String UP_ACTIVITY_CLASS =
+            "com.android.settings.Settings$WirelessSettingsActivity";
+
+    //UI objects
+    private ListPreference mButtonPreferredNetworkMode;
+    private CheckBoxPreference mButtonDataRoam;
+    private CheckBoxPreference mButtonDataEnabled;
+    private Preference mLteDataServicePref;
+
+    private static final String iface = "rmnet0"; //TODO: this will go away
+
+    private Phone mPhone;
+    private MyHandler mHandler;
+    private boolean mOkClicked;
+
+    //GsmUmts options and Cdma options
+    GsmUmtsOptions mGsmUmtsOptions;
+    CdmaOptions mCdmaOptions;
+
+    private Preference mClickedPreference;
+
+
+    //This is a method implemented for DialogInterface.OnClickListener.
+    //  Used to dismiss the dialogs when they come up.
+    public void onClick(DialogInterface dialog, int which) {
+        if (which == DialogInterface.BUTTON_POSITIVE) {
+            mPhone.setDataRoamingEnabled(true);
+            mOkClicked = true;
+        } else {
+            // Reset the toggle
+            mButtonDataRoam.setChecked(false);
+        }
+    }
+
+    public void onDismiss(DialogInterface dialog) {
+        // Assuming that onClick gets called first
+        if (!mOkClicked) {
+            mButtonDataRoam.setChecked(false);
+        }
+    }
+
+    /**
+     * Invoked on each preference click in this hierarchy, overrides
+     * PreferenceActivity's implementation.  Used to make sure we track the
+     * preference click events.
+     */
+    @Override
+    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
+        /** TODO: Refactor and get rid of the if's using subclasses */
+        if (mGsmUmtsOptions != null &&
+                mGsmUmtsOptions.preferenceTreeClick(preference) == true) {
+            return true;
+        } else if (mCdmaOptions != null &&
+                   mCdmaOptions.preferenceTreeClick(preference) == true) {
+            if (Boolean.parseBoolean(
+                    SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE))) {
+
+                mClickedPreference = preference;
+
+                // In ECM mode launch ECM app dialog
+                startActivityForResult(
+                    new Intent(TelephonyIntents.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS, null),
+                    REQUEST_CODE_EXIT_ECM);
+            }
+            return true;
+        } else if (preference == mButtonPreferredNetworkMode) {
+            //displays the value taken from the Settings.System
+            int settingsNetworkMode = android.provider.Settings.Global.getInt(mPhone.getContext().
+                    getContentResolver(), android.provider.Settings.Global.PREFERRED_NETWORK_MODE,
+                    preferredNetworkMode);
+            mButtonPreferredNetworkMode.setValue(Integer.toString(settingsNetworkMode));
+            return true;
+        } else if (preference == mButtonDataRoam) {
+            if (DBG) log("onPreferenceTreeClick: preference == mButtonDataRoam.");
+
+            //normally called on the toggle click
+            if (mButtonDataRoam.isChecked()) {
+                // First confirm with a warning dialog about charges
+                mOkClicked = false;
+                new AlertDialog.Builder(this).setMessage(
+                        getResources().getString(R.string.roaming_warning))
+                        .setTitle(android.R.string.dialog_alert_title)
+                        .setIconAttribute(android.R.attr.alertDialogIcon)
+                        .setPositiveButton(android.R.string.yes, this)
+                        .setNegativeButton(android.R.string.no, this)
+                        .show()
+                        .setOnDismissListener(this);
+            } else {
+                mPhone.setDataRoamingEnabled(false);
+            }
+            return true;
+        } else if (preference == mButtonDataEnabled) {
+            if (DBG) log("onPreferenceTreeClick: preference == mButtonDataEnabled.");
+            ConnectivityManager cm =
+                    (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
+
+            cm.setMobileDataEnabled(mButtonDataEnabled.isChecked());
+            return true;
+        } else if (preference == mLteDataServicePref) {
+            String tmpl = android.provider.Settings.Global.getString(getContentResolver(),
+                        android.provider.Settings.Global.SETUP_PREPAID_DATA_SERVICE_URL);
+            if (!TextUtils.isEmpty(tmpl)) {
+                TelephonyManager tm = (TelephonyManager) getSystemService(
+                        Context.TELEPHONY_SERVICE);
+                String imsi = tm.getSubscriberId();
+                if (imsi == null) {
+                    imsi = "";
+                }
+                final String url = TextUtils.isEmpty(tmpl) ? null
+                        : TextUtils.expandTemplate(tmpl, imsi).toString();
+                Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
+                startActivity(intent);
+            } else {
+                android.util.Log.e(LOG_TAG, "Missing SETUP_PREPAID_DATA_SERVICE_URL");
+            }
+            return true;
+        } else {
+            // if the button is anything but the simple toggle preference,
+            // we'll need to disable all preferences to reject all click
+            // events until the sub-activity's UI comes up.
+            preferenceScreen.setEnabled(false);
+            // Let the intents be launched by the Preference manager
+            return false;
+        }
+    }
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        addPreferencesFromResource(R.xml.network_setting);
+
+        mPhone = PhoneGlobals.getPhone();
+        mHandler = new MyHandler();
+
+        //get UI object references
+        PreferenceScreen prefSet = getPreferenceScreen();
+
+        mButtonDataEnabled = (CheckBoxPreference) prefSet.findPreference(BUTTON_DATA_ENABLED_KEY);
+        mButtonDataRoam = (CheckBoxPreference) prefSet.findPreference(BUTTON_ROAMING_KEY);
+        mButtonPreferredNetworkMode = (ListPreference) prefSet.findPreference(
+                BUTTON_PREFERED_NETWORK_MODE);
+        mLteDataServicePref = prefSet.findPreference(BUTTON_CDMA_LTE_DATA_SERVICE_KEY);
+
+        boolean isLteOnCdma = mPhone.getLteOnCdmaMode() == PhoneConstants.LTE_ON_CDMA_TRUE;
+        if (getResources().getBoolean(R.bool.world_phone) == true) {
+            // set the listener for the mButtonPreferredNetworkMode list preference so we can issue
+            // change Preferred Network Mode.
+            mButtonPreferredNetworkMode.setOnPreferenceChangeListener(this);
+
+            //Get the networkMode from Settings.System and displays it
+            int settingsNetworkMode = android.provider.Settings.Global.getInt(mPhone.getContext().
+                    getContentResolver(),android.provider.Settings.Global.PREFERRED_NETWORK_MODE,
+                    preferredNetworkMode);
+            mButtonPreferredNetworkMode.setValue(Integer.toString(settingsNetworkMode));
+            mCdmaOptions = new CdmaOptions(this, prefSet, mPhone);
+            mGsmUmtsOptions = new GsmUmtsOptions(this, prefSet);
+        } else {
+            if (!isLteOnCdma) {
+                prefSet.removePreference(mButtonPreferredNetworkMode);
+            }
+            int phoneType = mPhone.getPhoneType();
+            if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
+                mCdmaOptions = new CdmaOptions(this, prefSet, mPhone);
+                if (isLteOnCdma) {
+                    mButtonPreferredNetworkMode.setOnPreferenceChangeListener(this);
+                    int settingsNetworkMode = android.provider.Settings.Global.getInt(
+                            mPhone.getContext().getContentResolver(),
+                            android.provider.Settings.Global.PREFERRED_NETWORK_MODE,
+                            preferredNetworkMode);
+                    mButtonPreferredNetworkMode.setValue(
+                            Integer.toString(settingsNetworkMode));
+                }
+
+            } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
+                mGsmUmtsOptions = new GsmUmtsOptions(this, prefSet);
+            } else {
+                throw new IllegalStateException("Unexpected phone type: " + phoneType);
+            }
+        }
+
+        final boolean missingDataServiceUrl = TextUtils.isEmpty(
+                android.provider.Settings.Global.getString(getContentResolver(),
+                        android.provider.Settings.Global.SETUP_PREPAID_DATA_SERVICE_URL));
+        if (!isLteOnCdma || missingDataServiceUrl) {
+            prefSet.removePreference(mLteDataServicePref);
+        } else {
+            android.util.Log.d(LOG_TAG, "keep ltePref");
+        }
+
+        ActionBar actionBar = getActionBar();
+        if (actionBar != null) {
+            // android.R.id.home will be triggered in onOptionsItemSelected()
+            actionBar.setDisplayHomeAsUpEnabled(true);
+        }
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        // upon resumption from the sub-activity, make sure we re-enable the
+        // preferences.
+        getPreferenceScreen().setEnabled(true);
+
+        ConnectivityManager cm =
+                (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
+        mButtonDataEnabled.setChecked(cm.getMobileDataEnabled());
+
+        // Set UI state in onResume because a user could go home, launch some
+        // app to change this setting's backend, and re-launch this settings app
+        // and the UI state would be inconsistent with actual state
+        mButtonDataRoam.setChecked(mPhone.getDataRoamingEnabled());
+
+        if (getPreferenceScreen().findPreference(BUTTON_PREFERED_NETWORK_MODE) != null)  {
+            mPhone.getPreferredNetworkType(mHandler.obtainMessage(
+                    MyHandler.MESSAGE_GET_PREFERRED_NETWORK_TYPE));
+        }
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+    }
+
+    /**
+     * Implemented to support onPreferenceChangeListener to look for preference
+     * changes specifically on CLIR.
+     *
+     * @param preference is the preference to be changed, should be mButtonCLIR.
+     * @param objValue should be the value of the selection, NOT its localized
+     * display value.
+     */
+    public boolean onPreferenceChange(Preference preference, Object objValue) {
+        if (preference == mButtonPreferredNetworkMode) {
+            //NOTE onPreferenceChange seems to be called even if there is no change
+            //Check if the button value is changed from the System.Setting
+            mButtonPreferredNetworkMode.setValue((String) objValue);
+            int buttonNetworkMode;
+            buttonNetworkMode = Integer.valueOf((String) objValue).intValue();
+            int settingsNetworkMode = android.provider.Settings.Global.getInt(
+                    mPhone.getContext().getContentResolver(),
+                    android.provider.Settings.Global.PREFERRED_NETWORK_MODE, preferredNetworkMode);
+            if (buttonNetworkMode != settingsNetworkMode) {
+                int modemNetworkMode;
+                // if new mode is invalid ignore it
+                switch (buttonNetworkMode) {
+                    case Phone.NT_MODE_WCDMA_PREF:
+                    case Phone.NT_MODE_GSM_ONLY:
+                    case Phone.NT_MODE_WCDMA_ONLY:
+                    case Phone.NT_MODE_GSM_UMTS:
+                    case Phone.NT_MODE_CDMA:
+                    case Phone.NT_MODE_CDMA_NO_EVDO:
+                    case Phone.NT_MODE_EVDO_NO_CDMA:
+                    case Phone.NT_MODE_GLOBAL:
+                    case Phone.NT_MODE_LTE_CDMA_AND_EVDO:
+                    case Phone.NT_MODE_LTE_GSM_WCDMA:
+                    case Phone.NT_MODE_LTE_CMDA_EVDO_GSM_WCDMA:
+                    case Phone.NT_MODE_LTE_ONLY:
+                    case Phone.NT_MODE_LTE_WCDMA:
+                        // This is one of the modes we recognize
+                        modemNetworkMode = buttonNetworkMode;
+                        break;
+                    default:
+                        loge("Invalid Network Mode (" + buttonNetworkMode + ") chosen. Ignore.");
+                        return true;
+                }
+
+                UpdatePreferredNetworkModeSummary(buttonNetworkMode);
+
+                android.provider.Settings.Global.putInt(mPhone.getContext().getContentResolver(),
+                        android.provider.Settings.Global.PREFERRED_NETWORK_MODE,
+                        buttonNetworkMode );
+                //Set the modem network mode
+                mPhone.setPreferredNetworkType(modemNetworkMode, mHandler
+                        .obtainMessage(MyHandler.MESSAGE_SET_PREFERRED_NETWORK_TYPE));
+            }
+        }
+
+        // always let the preference setting proceed.
+        return true;
+    }
+
+    private class MyHandler extends Handler {
+
+        static final int MESSAGE_GET_PREFERRED_NETWORK_TYPE = 0;
+        static final int MESSAGE_SET_PREFERRED_NETWORK_TYPE = 1;
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MESSAGE_GET_PREFERRED_NETWORK_TYPE:
+                    handleGetPreferredNetworkTypeResponse(msg);
+                    break;
+
+                case MESSAGE_SET_PREFERRED_NETWORK_TYPE:
+                    handleSetPreferredNetworkTypeResponse(msg);
+                    break;
+            }
+        }
+
+        private void handleGetPreferredNetworkTypeResponse(Message msg) {
+            AsyncResult ar = (AsyncResult) msg.obj;
+
+            if (ar.exception == null) {
+                int modemNetworkMode = ((int[])ar.result)[0];
+
+                if (DBG) {
+                    log ("handleGetPreferredNetworkTypeResponse: modemNetworkMode = " +
+                            modemNetworkMode);
+                }
+
+                int settingsNetworkMode = android.provider.Settings.Global.getInt(
+                        mPhone.getContext().getContentResolver(),
+                        android.provider.Settings.Global.PREFERRED_NETWORK_MODE,
+                        preferredNetworkMode);
+
+                if (DBG) {
+                    log("handleGetPreferredNetworkTypeReponse: settingsNetworkMode = " +
+                            settingsNetworkMode);
+                }
+
+                //check that modemNetworkMode is from an accepted value
+                if (modemNetworkMode == Phone.NT_MODE_WCDMA_PREF ||
+                        modemNetworkMode == Phone.NT_MODE_GSM_ONLY ||
+                        modemNetworkMode == Phone.NT_MODE_WCDMA_ONLY ||
+                        modemNetworkMode == Phone.NT_MODE_GSM_UMTS ||
+                        modemNetworkMode == Phone.NT_MODE_CDMA ||
+                        modemNetworkMode == Phone.NT_MODE_CDMA_NO_EVDO ||
+                        modemNetworkMode == Phone.NT_MODE_EVDO_NO_CDMA ||
+                        modemNetworkMode == Phone.NT_MODE_GLOBAL ||
+                        modemNetworkMode == Phone.NT_MODE_LTE_CDMA_AND_EVDO ||
+                        modemNetworkMode == Phone.NT_MODE_LTE_GSM_WCDMA ||
+                        modemNetworkMode == Phone.NT_MODE_LTE_CMDA_EVDO_GSM_WCDMA ||
+                        modemNetworkMode == Phone.NT_MODE_LTE_ONLY ||
+                        modemNetworkMode == Phone.NT_MODE_LTE_WCDMA) {
+                    if (DBG) {
+                        log("handleGetPreferredNetworkTypeResponse: if 1: modemNetworkMode = " +
+                                modemNetworkMode);
+                    }
+
+                    //check changes in modemNetworkMode and updates settingsNetworkMode
+                    if (modemNetworkMode != settingsNetworkMode) {
+                        if (DBG) {
+                            log("handleGetPreferredNetworkTypeResponse: if 2: " +
+                                    "modemNetworkMode != settingsNetworkMode");
+                        }
+
+                        settingsNetworkMode = modemNetworkMode;
+
+                        if (DBG) { log("handleGetPreferredNetworkTypeResponse: if 2: " +
+                                "settingsNetworkMode = " + settingsNetworkMode);
+                        }
+
+                        //changes the Settings.System accordingly to modemNetworkMode
+                        android.provider.Settings.Global.putInt(
+                                mPhone.getContext().getContentResolver(),
+                                android.provider.Settings.Global.PREFERRED_NETWORK_MODE,
+                                settingsNetworkMode );
+                    }
+
+                    UpdatePreferredNetworkModeSummary(modemNetworkMode);
+                    // changes the mButtonPreferredNetworkMode accordingly to modemNetworkMode
+                    mButtonPreferredNetworkMode.setValue(Integer.toString(modemNetworkMode));
+                } else {
+                    if (DBG) log("handleGetPreferredNetworkTypeResponse: else: reset to default");
+                    resetNetworkModeToDefault();
+                }
+            }
+        }
+
+        private void handleSetPreferredNetworkTypeResponse(Message msg) {
+            AsyncResult ar = (AsyncResult) msg.obj;
+
+            if (ar.exception == null) {
+                int networkMode = Integer.valueOf(
+                        mButtonPreferredNetworkMode.getValue()).intValue();
+                android.provider.Settings.Global.putInt(mPhone.getContext().getContentResolver(),
+                        android.provider.Settings.Global.PREFERRED_NETWORK_MODE,
+                        networkMode );
+            } else {
+                mPhone.getPreferredNetworkType(obtainMessage(MESSAGE_GET_PREFERRED_NETWORK_TYPE));
+            }
+        }
+
+        private void resetNetworkModeToDefault() {
+            //set the mButtonPreferredNetworkMode
+            mButtonPreferredNetworkMode.setValue(Integer.toString(preferredNetworkMode));
+            //set the Settings.System
+            android.provider.Settings.Global.putInt(mPhone.getContext().getContentResolver(),
+                        android.provider.Settings.Global.PREFERRED_NETWORK_MODE,
+                        preferredNetworkMode );
+            //Set the Modem
+            mPhone.setPreferredNetworkType(preferredNetworkMode,
+                    this.obtainMessage(MyHandler.MESSAGE_SET_PREFERRED_NETWORK_TYPE));
+        }
+    }
+
+    private void UpdatePreferredNetworkModeSummary(int NetworkMode) {
+        switch(NetworkMode) {
+            case Phone.NT_MODE_WCDMA_PREF:
+                mButtonPreferredNetworkMode.setSummary(
+                        R.string.preferred_network_mode_wcdma_perf_summary);
+                break;
+            case Phone.NT_MODE_GSM_ONLY:
+                mButtonPreferredNetworkMode.setSummary(
+                        R.string.preferred_network_mode_gsm_only_summary);
+                break;
+            case Phone.NT_MODE_WCDMA_ONLY:
+                mButtonPreferredNetworkMode.setSummary(
+                        R.string.preferred_network_mode_wcdma_only_summary);
+                break;
+            case Phone.NT_MODE_GSM_UMTS:
+                mButtonPreferredNetworkMode.setSummary(
+                        R.string.preferred_network_mode_gsm_wcdma_summary);
+                break;
+            case Phone.NT_MODE_CDMA:
+                switch (mPhone.getLteOnCdmaMode()) {
+                    case PhoneConstants.LTE_ON_CDMA_TRUE:
+                        mButtonPreferredNetworkMode.setSummary(
+                            R.string.preferred_network_mode_cdma_summary);
+                    break;
+                    case PhoneConstants.LTE_ON_CDMA_FALSE:
+                    default:
+                        mButtonPreferredNetworkMode.setSummary(
+                            R.string.preferred_network_mode_cdma_evdo_summary);
+                        break;
+                }
+                break;
+            case Phone.NT_MODE_CDMA_NO_EVDO:
+                mButtonPreferredNetworkMode.setSummary(
+                        R.string.preferred_network_mode_cdma_only_summary);
+                break;
+            case Phone.NT_MODE_EVDO_NO_CDMA:
+                mButtonPreferredNetworkMode.setSummary(
+                        R.string.preferred_network_mode_evdo_only_summary);
+                break;
+            case Phone.NT_MODE_LTE_ONLY:
+                mButtonPreferredNetworkMode.setSummary(
+                        R.string.preferred_network_mode_lte_summary);
+                break;
+            case Phone.NT_MODE_LTE_GSM_WCDMA:
+                mButtonPreferredNetworkMode.setSummary(
+                        R.string.preferred_network_mode_lte_gsm_wcdma_summary);
+                break;
+            case Phone.NT_MODE_LTE_CDMA_AND_EVDO:
+                mButtonPreferredNetworkMode.setSummary(
+                        R.string.preferred_network_mode_lte_cdma_evdo_summary);
+                break;
+            case Phone.NT_MODE_LTE_CMDA_EVDO_GSM_WCDMA:
+                mButtonPreferredNetworkMode.setSummary(
+                        R.string.preferred_network_mode_global_summary);
+                break;
+            case Phone.NT_MODE_GLOBAL:
+                mButtonPreferredNetworkMode.setSummary(
+                        R.string.preferred_network_mode_cdma_evdo_gsm_wcdma_summary);
+                break;
+            case Phone.NT_MODE_LTE_WCDMA:
+                mButtonPreferredNetworkMode.setSummary(
+                        R.string.preferred_network_mode_lte_wcdma_summary);
+                break;
+            default:
+                mButtonPreferredNetworkMode.setSummary(
+                        R.string.preferred_network_mode_global_summary);
+        }
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        switch(requestCode) {
+        case REQUEST_CODE_EXIT_ECM:
+            Boolean isChoiceYes =
+                data.getBooleanExtra(EmergencyCallbackModeExitDialog.EXTRA_EXIT_ECM_RESULT, false);
+            if (isChoiceYes) {
+                // If the phone exits from ECM mode, show the CDMA Options
+                mCdmaOptions.showDialog(mClickedPreference);
+            } else {
+                // do nothing
+            }
+            break;
+
+        default:
+            break;
+        }
+    }
+
+    private static void log(String msg) {
+        Log.d(LOG_TAG, msg);
+    }
+
+    private static void loge(String msg) {
+        Log.e(LOG_TAG, msg);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        final int itemId = item.getItemId();
+        if (itemId == android.R.id.home) {  // See ActionBar#setDisplayHomeAsUpEnabled()
+            // Commenting out "logical up" capability. This is a workaround for issue 5278083.
+            //
+            // Settings app may not launch this activity via UP_ACTIVITY_CLASS but the other
+            // Activity that looks exactly same as UP_ACTIVITY_CLASS ("SubSettings" Activity).
+            // At that moment, this Activity launches UP_ACTIVITY_CLASS on top of the Activity.
+            // which confuses users.
+            // TODO: introduce better mechanism for "up" capability here.
+            /*Intent intent = new Intent(Intent.ACTION_MAIN);
+            intent.setClassName(UP_ACTIVITY_PACKAGE, UP_ACTIVITY_CLASS);
+            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+            startActivity(intent);*/
+            finish();
+            return true;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+}
diff --git a/src/com/android/phone/MultiLineTitleEditTextPreference.java b/src/com/android/phone/MultiLineTitleEditTextPreference.java
new file mode 100644
index 0000000..58d79f8
--- /dev/null
+++ b/src/com/android/phone/MultiLineTitleEditTextPreference.java
@@ -0,0 +1,73 @@
+/*
+ * 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.content.Context;
+import android.preference.EditTextPreference;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.TextView;
+
+/**
+ * Ultra-simple subclass of EditTextPreference that allows the "title" to wrap
+ * onto multiple lines.
+ *
+ * (By default, the title of an EditTextPreference is singleLine="true"; see
+ * preference_holo.xml under frameworks/base.  But in the "Respond via SMS"
+ * settings UI we want titles to be multi-line, since the customized messages
+ * might be fairly long, and should be able to wrap.)
+ *
+ * TODO: This is pretty cumbersome; it would be nicer for the framework to
+ * either allow modifying the title's attributes in XML, or at least provide
+ * some way from Java (given an EditTextPreference) to reach inside and get a
+ * handle to the "title" TextView.
+ *
+ * TODO: Also, it would reduce clutter if this could be an inner class in
+ * RespondViaSmsManager.java, but then there would be no way to reference the
+ * class from XML.  That's because
+ *    <com.android.phone.RespondViaSmsManager$MultiLineTitleEditTextPreference ... />
+ * isn't valid XML syntax due to the "$" character.  And Preference
+ * elements don't have a "class" attribute, so you can't do something like
+ * <view class="com.android.phone.Foo$Bar"> as you can with regular views.
+ */
+public class MultiLineTitleEditTextPreference extends EditTextPreference {
+    public MultiLineTitleEditTextPreference(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    public MultiLineTitleEditTextPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public MultiLineTitleEditTextPreference(Context context) {
+        super(context);
+    }
+
+    // The "title" TextView inside an EditTextPreference defaults to
+    // singleLine="true" (see preference_holo.xml under frameworks/base.)
+    // We override onBindView() purely to look up that TextView and call
+    // setSingleLine(false) on it.
+    @Override
+    protected void onBindView(View view) {
+        super.onBindView(view);
+
+        TextView textView = (TextView) view.findViewById(com.android.internal.R.id.title);
+        if (textView != null) {
+            textView.setSingleLine(false);
+        }
+    }
+}
diff --git a/src/com/android/phone/NetworkQueryService.java b/src/com/android/phone/NetworkQueryService.java
new file mode 100644
index 0000000..be8c78e
--- /dev/null
+++ b/src/com/android/phone/NetworkQueryService.java
@@ -0,0 +1,220 @@
+/*
+ * 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.app.Service;
+import android.content.Intent;
+import com.android.internal.telephony.OperatorInfo;
+import android.os.AsyncResult;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.RemoteCallbackList;
+import android.os.RemoteException;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
+import android.util.Log;
+
+import java.util.ArrayList;
+
+/**
+ * Service code used to assist in querying the network for service
+ * availability.   
+ */
+public class NetworkQueryService extends Service {
+    // debug data
+    private static final String LOG_TAG = "NetworkQuery";
+    private static final boolean DBG = false;
+
+    // static events
+    private static final int EVENT_NETWORK_SCAN_COMPLETED = 100; 
+    
+    // static states indicating the query status of the service 
+    private static final int QUERY_READY = -1;
+    private static final int QUERY_IS_RUNNING = -2;
+    
+    // error statuses that will be retured in the callback.
+    public static final int QUERY_OK = 0;
+    public static final int QUERY_EXCEPTION = 1;
+    
+    /** state of the query service */
+    private int mState;
+    
+    /** local handle to the phone object */
+    private Phone mPhone;
+    
+    /**
+     * Class for clients to access.  Because we know this service always
+     * runs in the same process as its clients, we don't need to deal with
+     * IPC.
+     */
+    public class LocalBinder extends Binder {
+        INetworkQueryService getService() {
+            return mBinder;
+        }
+    }
+    private final IBinder mLocalBinder = new LocalBinder();
+
+    /**
+     * Local handler to receive the network query compete callback
+     * from the RIL.
+     */
+    Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                // if the scan is complete, broadcast the results.
+                // to all registerd callbacks.
+                case EVENT_NETWORK_SCAN_COMPLETED:
+                    if (DBG) log("scan completed, broadcasting results");
+                    broadcastQueryResults((AsyncResult) msg.obj);
+                    break;
+            }
+        }
+    };
+    
+    /** 
+     * List of callback objects, also used to synchronize access to 
+     * itself and to changes in state.
+     */
+    final RemoteCallbackList<INetworkQueryServiceCallback> mCallbacks =
+        new RemoteCallbackList<INetworkQueryServiceCallback> ();
+    
+    /**
+     * Implementation of the INetworkQueryService interface.
+     */
+    private final INetworkQueryService.Stub mBinder = new INetworkQueryService.Stub() {
+        
+        /**
+         * Starts a query with a INetworkQueryServiceCallback object if
+         * one has not been started yet.  Ignore the new query request
+         * if the query has been started already.  Either way, place the
+         * callback object in the queue to be notified upon request 
+         * completion.
+         */
+        public void startNetworkQuery(INetworkQueryServiceCallback cb) {
+            if (cb != null) {
+                // register the callback to the list of callbacks.
+                synchronized (mCallbacks) {
+                    mCallbacks.register(cb);
+                    if (DBG) log("registering callback " + cb.getClass().toString());
+                    
+                    switch (mState) {
+                        case QUERY_READY:
+                            // TODO: we may want to install a timeout here in case we
+                            // do not get a timely response from the RIL.
+                            mPhone.getAvailableNetworks(
+                                    mHandler.obtainMessage(EVENT_NETWORK_SCAN_COMPLETED));
+                            mState = QUERY_IS_RUNNING;
+                            if (DBG) log("starting new query");
+                            break;
+                            
+                        // do nothing if we're currently busy.
+                        case QUERY_IS_RUNNING:
+                            if (DBG) log("query already in progress");
+                            break;
+                        default:
+                    }
+                }
+            }
+        }
+        
+        /**
+         * Stops a query with a INetworkQueryServiceCallback object as
+         * a token.
+         */
+        public void stopNetworkQuery(INetworkQueryServiceCallback cb) {
+            // currently we just unregister the callback, since there is 
+            // no way to tell the RIL to terminate the query request.  
+            // This means that the RIL may still be busy after the stop 
+            // request was made, but the state tracking logic ensures 
+            // that the delay will only last for 1 request even with 
+            // repeated button presses in the NetworkSetting activity. 
+            if (cb != null) {
+                synchronized (mCallbacks) {
+                    if (DBG) log("unregistering callback " + cb.getClass().toString());
+                    mCallbacks.unregister(cb);
+                }
+            }            
+        }
+    };
+    
+    @Override
+    public void onCreate() {
+        mState = QUERY_READY;
+        mPhone = PhoneFactory.getDefaultPhone();
+    }
+    
+    /**
+     * Required for service implementation.
+     */
+    @Override
+    public void onStart(Intent intent, int startId) {
+    }
+    
+    /**
+     * Handle the bind request.
+     */
+    @Override
+    public IBinder onBind(Intent intent) {
+        // TODO: Currently, return only the LocalBinder instance.  If we
+        // end up requiring support for a remote binder, we will need to 
+        // return mBinder as well, depending upon the intent.
+        if (DBG) log("binding service implementation");
+        return mLocalBinder;
+    }
+
+    /**
+     * Broadcast the results from the query to all registered callback
+     * objects. 
+     */
+    private void broadcastQueryResults (AsyncResult ar) {
+        // reset the state.
+        synchronized (mCallbacks) {
+            mState = QUERY_READY;
+            
+            // see if we need to do any work.
+            if (ar == null) {
+                if (DBG) log("AsyncResult is null.");
+                return;
+            }
+    
+            // TODO: we may need greater accuracy here, but for now, just a
+            // simple status integer will suffice.
+            int exception = (ar.exception == null) ? QUERY_OK : QUERY_EXCEPTION;
+            if (DBG) log("AsyncResult has exception " + exception);
+            
+            // Make the calls to all the registered callbacks.
+            for (int i = (mCallbacks.beginBroadcast() - 1); i >= 0; i--) {
+                INetworkQueryServiceCallback cb = mCallbacks.getBroadcastItem(i); 
+                if (DBG) log("broadcasting results to " + cb.getClass().toString());
+                try {
+                    cb.onQueryComplete((ArrayList<OperatorInfo>) ar.result, exception);
+                } catch (RemoteException e) {
+                }
+            }
+            
+            // finish up.
+            mCallbacks.finishBroadcast();
+        }
+    }
+    
+    private static void log(String msg) {
+        Log.d(LOG_TAG, msg);
+    }    
+}
diff --git a/src/com/android/phone/NetworkSetting.java b/src/com/android/phone/NetworkSetting.java
new file mode 100644
index 0000000..5917795
--- /dev/null
+++ b/src/com/android/phone/NetworkSetting.java
@@ -0,0 +1,478 @@
+/*
+ * 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.app.Dialog;
+import android.app.ProgressDialog;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.AsyncResult;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.RemoteException;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceGroup;
+import android.preference.PreferenceScreen;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.internal.telephony.CommandException;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.OperatorInfo;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * "Networks" settings UI for the Phone app.
+ */
+public class NetworkSetting extends PreferenceActivity
+        implements DialogInterface.OnCancelListener {
+
+    private static final String LOG_TAG = "phone";
+    private static final boolean DBG = false;
+
+    private static final int EVENT_NETWORK_SCAN_COMPLETED = 100;
+    private static final int EVENT_NETWORK_SELECTION_DONE = 200;
+    private static final int EVENT_AUTO_SELECT_DONE = 300;
+
+    //dialog ids
+    private static final int DIALOG_NETWORK_SELECTION = 100;
+    private static final int DIALOG_NETWORK_LIST_LOAD = 200;
+    private static final int DIALOG_NETWORK_AUTO_SELECT = 300;
+
+    //String keys for preference lookup
+    private static final String LIST_NETWORKS_KEY = "list_networks_key";
+    private static final String BUTTON_SRCH_NETWRKS_KEY = "button_srch_netwrks_key";
+    private static final String BUTTON_AUTO_SELECT_KEY = "button_auto_select_key";
+
+    //map of network controls to the network data.
+    private HashMap<Preference, OperatorInfo> mNetworkMap;
+
+    Phone mPhone;
+    protected boolean mIsForeground = false;
+
+    /** message for network selection */
+    String mNetworkSelectMsg;
+
+    //preference objects
+    private PreferenceGroup mNetworkList;
+    private Preference mSearchButton;
+    private Preference mAutoSelect;
+
+    private final Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            AsyncResult ar;
+            switch (msg.what) {
+                case EVENT_NETWORK_SCAN_COMPLETED:
+                    networksListLoaded ((List<OperatorInfo>) msg.obj, msg.arg1);
+                    break;
+
+                case EVENT_NETWORK_SELECTION_DONE:
+                    if (DBG) log("hideProgressPanel");
+                    removeDialog(DIALOG_NETWORK_SELECTION);
+                    getPreferenceScreen().setEnabled(true);
+
+                    ar = (AsyncResult) msg.obj;
+                    if (ar.exception != null) {
+                        if (DBG) log("manual network selection: failed!");
+                        displayNetworkSelectionFailed(ar.exception);
+                    } else {
+                        if (DBG) log("manual network selection: succeeded!");
+                        displayNetworkSelectionSucceeded();
+                    }
+                    break;
+                case EVENT_AUTO_SELECT_DONE:
+                    if (DBG) log("hideProgressPanel");
+
+                    // Always try to dismiss the dialog because activity may
+                    // be moved to background after dialog is shown.
+                    try {
+                        dismissDialog(DIALOG_NETWORK_AUTO_SELECT);
+                    } catch (IllegalArgumentException e) {
+                        // "auto select" is always trigged in foreground, so "auto select" dialog
+                        //  should be shown when "auto select" is trigged. Should NOT get
+                        // this exception, and Log it.
+                        Log.w(LOG_TAG, "[NetworksList] Fail to dismiss auto select dialog", e);
+                    }
+                    getPreferenceScreen().setEnabled(true);
+
+                    ar = (AsyncResult) msg.obj;
+                    if (ar.exception != null) {
+                        if (DBG) log("automatic network selection: failed!");
+                        displayNetworkSelectionFailed(ar.exception);
+                    } else {
+                        if (DBG) log("automatic network selection: succeeded!");
+                        displayNetworkSelectionSucceeded();
+                    }
+                    break;
+            }
+
+            return;
+        }
+    };
+
+    /**
+     * Service connection code for the NetworkQueryService.
+     * Handles the work of binding to a local object so that we can make
+     * the appropriate service calls.
+     */
+
+    /** Local service interface */
+    private INetworkQueryService mNetworkQueryService = null;
+
+    /** Service connection */
+    private final ServiceConnection mNetworkQueryServiceConnection = new ServiceConnection() {
+
+        /** Handle the task of binding the local object to the service */
+        public void onServiceConnected(ComponentName className, IBinder service) {
+            if (DBG) log("connection created, binding local service.");
+            mNetworkQueryService = ((NetworkQueryService.LocalBinder) service).getService();
+            // as soon as it is bound, run a query.
+            loadNetworksList();
+        }
+
+        /** Handle the task of cleaning up the local binding */
+        public void onServiceDisconnected(ComponentName className) {
+            if (DBG) log("connection disconnected, cleaning local binding.");
+            mNetworkQueryService = null;
+        }
+    };
+
+    /**
+     * This implementation of INetworkQueryServiceCallback is used to receive
+     * callback notifications from the network query service.
+     */
+    private final INetworkQueryServiceCallback mCallback = new INetworkQueryServiceCallback.Stub() {
+
+        /** place the message on the looper queue upon query completion. */
+        public void onQueryComplete(List<OperatorInfo> networkInfoArray, int status) {
+            if (DBG) log("notifying message loop of query completion.");
+            Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_COMPLETED,
+                    status, 0, networkInfoArray);
+            msg.sendToTarget();
+        }
+    };
+
+    @Override
+    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
+        boolean handled = false;
+
+        if (preference == mSearchButton) {
+            loadNetworksList();
+            handled = true;
+        } else if (preference == mAutoSelect) {
+            selectNetworkAutomatic();
+            handled = true;
+        } else {
+            Preference selectedCarrier = preference;
+
+            String networkStr = selectedCarrier.getTitle().toString();
+            if (DBG) log("selected network: " + networkStr);
+
+            Message msg = mHandler.obtainMessage(EVENT_NETWORK_SELECTION_DONE);
+            mPhone.selectNetworkManually(mNetworkMap.get(selectedCarrier), msg);
+
+            displayNetworkSeletionInProgress(networkStr);
+
+            handled = true;
+        }
+
+        return handled;
+    }
+
+    //implemented for DialogInterface.OnCancelListener
+    public void onCancel(DialogInterface dialog) {
+        // request that the service stop the query with this callback object.
+        try {
+            mNetworkQueryService.stopNetworkQuery(mCallback);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+        finish();
+    }
+
+    public String getNormalizedCarrierName(OperatorInfo ni) {
+        if (ni != null) {
+            return ni.getOperatorAlphaLong() + " (" + ni.getOperatorNumeric() + ")";
+        }
+        return null;
+    }
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        addPreferencesFromResource(R.xml.carrier_select);
+
+        mPhone = PhoneGlobals.getPhone();
+
+        mNetworkList = (PreferenceGroup) getPreferenceScreen().findPreference(LIST_NETWORKS_KEY);
+        mNetworkMap = new HashMap<Preference, OperatorInfo>();
+
+        mSearchButton = getPreferenceScreen().findPreference(BUTTON_SRCH_NETWRKS_KEY);
+        mAutoSelect = getPreferenceScreen().findPreference(BUTTON_AUTO_SELECT_KEY);
+
+        // Start the Network Query service, and bind it.
+        // The OS knows to start he service only once and keep the instance around (so
+        // long as startService is called) until a stopservice request is made.  Since
+        // we want this service to just stay in the background until it is killed, we
+        // don't bother stopping it from our end.
+        startService (new Intent(this, NetworkQueryService.class));
+        bindService (new Intent(this, NetworkQueryService.class), mNetworkQueryServiceConnection,
+                Context.BIND_AUTO_CREATE);
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        mIsForeground = true;
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        mIsForeground = false;
+    }
+
+    /**
+     * Override onDestroy() to unbind the query service, avoiding service
+     * leak exceptions.
+     */
+    @Override
+    protected void onDestroy() {
+        // unbind the service.
+        unbindService(mNetworkQueryServiceConnection);
+
+        super.onDestroy();
+    }
+
+    @Override
+    protected Dialog onCreateDialog(int id) {
+
+        if ((id == DIALOG_NETWORK_SELECTION) || (id == DIALOG_NETWORK_LIST_LOAD) ||
+                (id == DIALOG_NETWORK_AUTO_SELECT)) {
+            ProgressDialog dialog = new ProgressDialog(this);
+            switch (id) {
+                case DIALOG_NETWORK_SELECTION:
+                    // It would be more efficient to reuse this dialog by moving
+                    // this setMessage() into onPreparedDialog() and NOT use
+                    // removeDialog().  However, this is not possible since the
+                    // message is rendered only 2 times in the ProgressDialog -
+                    // after show() and before onCreate.
+                    dialog.setMessage(mNetworkSelectMsg);
+                    dialog.setCancelable(false);
+                    dialog.setIndeterminate(true);
+                    break;
+                case DIALOG_NETWORK_AUTO_SELECT:
+                    dialog.setMessage(getResources().getString(R.string.register_automatically));
+                    dialog.setCancelable(false);
+                    dialog.setIndeterminate(true);
+                    break;
+                case DIALOG_NETWORK_LIST_LOAD:
+                default:
+                    // reinstate the cancelablity of the dialog.
+                    dialog.setMessage(getResources().getString(R.string.load_networks_progress));
+                    dialog.setCanceledOnTouchOutside(false);
+                    dialog.setOnCancelListener(this);
+                    break;
+            }
+            return dialog;
+        }
+        return null;
+    }
+
+    @Override
+    protected void onPrepareDialog(int id, Dialog dialog) {
+        if ((id == DIALOG_NETWORK_SELECTION) || (id == DIALOG_NETWORK_LIST_LOAD) ||
+                (id == DIALOG_NETWORK_AUTO_SELECT)) {
+            // when the dialogs come up, we'll need to indicate that
+            // we're in a busy state to dissallow further input.
+            getPreferenceScreen().setEnabled(false);
+        }
+    }
+
+    private void displayEmptyNetworkList(boolean flag) {
+        mNetworkList.setTitle(flag ? R.string.empty_networks_list : R.string.label_available);
+    }
+
+    private void displayNetworkSeletionInProgress(String networkStr) {
+        // TODO: use notification manager?
+        mNetworkSelectMsg = getResources().getString(R.string.register_on_network, networkStr);
+
+        if (mIsForeground) {
+            showDialog(DIALOG_NETWORK_SELECTION);
+        }
+    }
+
+    private void displayNetworkQueryFailed(int error) {
+        String status = getResources().getString(R.string.network_query_error);
+
+        final PhoneGlobals app = PhoneGlobals.getInstance();
+        app.notificationMgr.postTransientNotification(
+                NotificationMgr.NETWORK_SELECTION_NOTIFICATION, status);
+    }
+
+    private void displayNetworkSelectionFailed(Throwable ex) {
+        String status;
+
+        if ((ex != null && ex instanceof CommandException) &&
+                ((CommandException)ex).getCommandError()
+                  == CommandException.Error.ILLEGAL_SIM_OR_ME)
+        {
+            status = getResources().getString(R.string.not_allowed);
+        } else {
+            status = getResources().getString(R.string.connect_later);
+        }
+
+        final PhoneGlobals app = PhoneGlobals.getInstance();
+        app.notificationMgr.postTransientNotification(
+                NotificationMgr.NETWORK_SELECTION_NOTIFICATION, status);
+    }
+
+    private void displayNetworkSelectionSucceeded() {
+        String status = getResources().getString(R.string.registration_done);
+
+        final PhoneGlobals app = PhoneGlobals.getInstance();
+        app.notificationMgr.postTransientNotification(
+                NotificationMgr.NETWORK_SELECTION_NOTIFICATION, status);
+
+        mHandler.postDelayed(new Runnable() {
+            public void run() {
+                finish();
+            }
+        }, 3000);
+    }
+
+    private void loadNetworksList() {
+        if (DBG) log("load networks list...");
+
+        if (mIsForeground) {
+            showDialog(DIALOG_NETWORK_LIST_LOAD);
+        }
+
+        // delegate query request to the service.
+        try {
+            mNetworkQueryService.startNetworkQuery(mCallback);
+        } catch (RemoteException e) {
+        }
+
+        displayEmptyNetworkList(false);
+    }
+
+    /**
+     * networksListLoaded has been rewritten to take an array of
+     * OperatorInfo objects and a status field, instead of an
+     * AsyncResult.  Otherwise, the functionality which takes the
+     * OperatorInfo array and creates a list of preferences from it,
+     * remains unchanged.
+     */
+    private void networksListLoaded(List<OperatorInfo> result, int status) {
+        if (DBG) log("networks list loaded");
+
+        // update the state of the preferences.
+        if (DBG) log("hideProgressPanel");
+
+
+        // Always try to dismiss the dialog because activity may
+        // be moved to background after dialog is shown.
+        try {
+            dismissDialog(DIALOG_NETWORK_LIST_LOAD);
+        } catch (IllegalArgumentException e) {
+            // It's not a error in following scenario, we just ignore it.
+            // "Load list" dialog will not show, if NetworkQueryService is
+            // connected after this activity is moved to background.
+            if (DBG) log("Fail to dismiss network load list dialog");
+        }
+
+        getPreferenceScreen().setEnabled(true);
+        clearList();
+
+        if (status != NetworkQueryService.QUERY_OK) {
+            if (DBG) log("error while querying available networks");
+            displayNetworkQueryFailed(status);
+            displayEmptyNetworkList(true);
+        } else {
+            if (result != null){
+                displayEmptyNetworkList(false);
+
+                // create a preference for each item in the list.
+                // just use the operator name instead of the mildly
+                // confusing mcc/mnc.
+                for (OperatorInfo ni : result) {
+                    Preference carrier = new Preference(this, null);
+                    carrier.setTitle(getNetworkTitle(ni));
+                    carrier.setPersistent(false);
+                    mNetworkList.addPreference(carrier);
+                    mNetworkMap.put(carrier, ni);
+
+                    if (DBG) log("  " + ni);
+                }
+
+            } else {
+                displayEmptyNetworkList(true);
+            }
+        }
+    }
+
+    /**
+     * Returns the title of the network obtained in the manual search.
+     *
+     * @param OperatorInfo contains the information of the network.
+     *
+     * @return Long Name if not null/empty, otherwise Short Name if not null/empty,
+     * else MCCMNC string.
+     */
+
+    private String getNetworkTitle(OperatorInfo ni) {
+        if (!TextUtils.isEmpty(ni.getOperatorAlphaLong())) {
+            return ni.getOperatorAlphaLong();
+        } else if (!TextUtils.isEmpty(ni.getOperatorAlphaShort())) {
+            return ni.getOperatorAlphaShort();
+        } else {
+            return ni.getOperatorNumeric();
+        }
+    }
+
+    private void clearList() {
+        for (Preference p : mNetworkMap.keySet()) {
+            mNetworkList.removePreference(p);
+        }
+        mNetworkMap.clear();
+    }
+
+    private void selectNetworkAutomatic() {
+        if (DBG) log("select network automatically...");
+        if (mIsForeground) {
+            showDialog(DIALOG_NETWORK_AUTO_SELECT);
+        }
+
+        Message msg = mHandler.obtainMessage(EVENT_AUTO_SELECT_DONE);
+        mPhone.setNetworkSelectionModeAutomatic(msg);
+    }
+
+    private void log(String msg) {
+        Log.d(LOG_TAG, "[NetworksList] " + msg);
+    }
+}
diff --git a/src/com/android/phone/NotificationMgr.java b/src/com/android/phone/NotificationMgr.java
new file mode 100644
index 0000000..ab0ba0c
--- /dev/null
+++ b/src/com/android/phone/NotificationMgr.java
@@ -0,0 +1,1471 @@
+/*
+ * 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.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.StatusBarManager;
+import android.content.AsyncQueryHandler;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.media.AudioManager;
+import android.net.Uri;
+import android.os.PowerManager;
+import android.os.SystemProperties;
+import android.preference.PreferenceManager;
+import android.provider.CallLog.Calls;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.PhoneLookup;
+import android.provider.Settings;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.ServiceState;
+import android.text.TextUtils;
+import android.util.Log;
+import android.widget.ImageView;
+import android.widget.Toast;
+
+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.PhoneBase;
+import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.TelephonyCapabilities;
+
+/**
+ * NotificationManager-related utility code for the Phone app.
+ *
+ * This is a singleton object which acts as the interface to the
+ * framework's NotificationManager, and is used to display status bar
+ * icons and control other status bar-related behavior.
+ *
+ * @see PhoneGlobals.notificationMgr
+ */
+public class NotificationMgr implements CallerInfoAsyncQuery.OnQueryCompleteListener{
+    private static final String LOG_TAG = "NotificationMgr";
+    private static final boolean DBG =
+            (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
+    // 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[] CALL_LOG_PROJECTION = new String[] {
+        Calls._ID,
+        Calls.NUMBER,
+        Calls.NUMBER_PRESENTATION,
+        Calls.DATE,
+        Calls.DURATION,
+        Calls.TYPE,
+    };
+
+    // notification types
+    static final int MISSED_CALL_NOTIFICATION = 1;
+    static final int IN_CALL_NOTIFICATION = 2;
+    static final int MMI_NOTIFICATION = 3;
+    static final int NETWORK_SELECTION_NOTIFICATION = 4;
+    static final int VOICEMAIL_NOTIFICATION = 5;
+    static final int CALL_FORWARD_NOTIFICATION = 6;
+    static final int DATA_DISCONNECTED_ROAMING_NOTIFICATION = 7;
+    static final int SELECTED_OPERATOR_FAIL_NOTIFICATION = 8;
+
+    /** The singleton NotificationMgr instance. */
+    private static NotificationMgr sInstance;
+
+    private PhoneGlobals mApp;
+    private Phone mPhone;
+    private CallManager mCM;
+
+    private Context mContext;
+    private NotificationManager mNotificationManager;
+    private StatusBarManager mStatusBarManager;
+    private PowerManager mPowerManager;
+    private Toast mToast;
+    private boolean mShowingSpeakerphoneIcon;
+    private boolean mShowingMuteIcon;
+
+    public StatusBarHelper statusBarHelper;
+
+    // used to track the missed call counter, default to 0.
+    private int mNumberMissedCalls = 0;
+
+    // Currently-displayed resource IDs for some status bar icons (or zero
+    // if no notification is active):
+    private int mInCallResId;
+
+    // used to track the notification of selected network unavailable
+    private boolean mSelectedUnavailableNotify = false;
+
+    // Retry params for the getVoiceMailNumber() call; see updateMwi().
+    private static final int MAX_VM_NUMBER_RETRIES = 5;
+    private static final int VM_NUMBER_RETRY_DELAY_MILLIS = 10000;
+    private int mVmNumberRetriesRemaining = MAX_VM_NUMBER_RETRIES;
+
+    // Query used to look up caller-id info for the "call log" notification.
+    private QueryHandler mQueryHandler = null;
+    private static final int CALL_LOG_TOKEN = -1;
+    private static final int CONTACT_TOKEN = -2;
+
+    /**
+     * Private constructor (this is a singleton).
+     * @see init()
+     */
+    private NotificationMgr(PhoneGlobals app) {
+        mApp = app;
+        mContext = app;
+        mNotificationManager =
+                (NotificationManager) app.getSystemService(Context.NOTIFICATION_SERVICE);
+        mStatusBarManager =
+                (StatusBarManager) app.getSystemService(Context.STATUS_BAR_SERVICE);
+        mPowerManager =
+                (PowerManager) app.getSystemService(Context.POWER_SERVICE);
+        mPhone = app.phone;  // TODO: better style to use mCM.getDefaultPhone() everywhere instead
+        mCM = app.mCM;
+        statusBarHelper = new StatusBarHelper();
+    }
+
+    /**
+     * Initialize the singleton NotificationMgr instance.
+     *
+     * This is only done once, at startup, from PhoneApp.onCreate().
+     * From then on, the NotificationMgr instance is available via the
+     * PhoneApp's public "notificationMgr" field, which is why there's no
+     * getInstance() method here.
+     */
+    /* package */ static NotificationMgr init(PhoneGlobals app) {
+        synchronized (NotificationMgr.class) {
+            if (sInstance == null) {
+                sInstance = new NotificationMgr(app);
+                // Update the notifications that need to be touched at startup.
+                sInstance.updateNotificationsAtStartup();
+            } else {
+                Log.wtf(LOG_TAG, "init() called multiple times!  sInstance = " + sInstance);
+            }
+            return sInstance;
+        }
+    }
+
+    /**
+     * Helper class that's a wrapper around the framework's
+     * StatusBarManager.disable() API.
+     *
+     * This class is used to control features like:
+     *
+     *   - Disabling the status bar "notification windowshade"
+     *     while the in-call UI is up
+     *
+     *   - Disabling notification alerts (audible or vibrating)
+     *     while a phone call is active
+     *
+     *   - Disabling navigation via the system bar (the "soft buttons" at
+     *     the bottom of the screen on devices with no hard buttons)
+     *
+     * We control these features through a single point of control to make
+     * sure that the various StatusBarManager.disable() calls don't
+     * interfere with each other.
+     */
+    public class StatusBarHelper {
+        // Current desired state of status bar / system bar behavior
+        private boolean mIsNotificationEnabled = true;
+        private boolean mIsExpandedViewEnabled = true;
+        private boolean mIsSystemBarNavigationEnabled = true;
+
+        private StatusBarHelper () {
+        }
+
+        /**
+         * Enables or disables auditory / vibrational alerts.
+         *
+         * (We disable these any time a voice call is active, regardless
+         * of whether or not the in-call UI is visible.)
+         */
+        public void enableNotificationAlerts(boolean enable) {
+            if (mIsNotificationEnabled != enable) {
+                mIsNotificationEnabled = enable;
+                updateStatusBar();
+            }
+        }
+
+        /**
+         * Enables or disables the expanded view of the status bar
+         * (i.e. the ability to pull down the "notification windowshade").
+         *
+         * (This feature is disabled by the InCallScreen while the in-call
+         * UI is active.)
+         */
+        public void enableExpandedView(boolean enable) {
+            if (mIsExpandedViewEnabled != enable) {
+                mIsExpandedViewEnabled = enable;
+                updateStatusBar();
+            }
+        }
+
+        /**
+         * Enables or disables the navigation via the system bar (the
+         * "soft buttons" at the bottom of the screen)
+         *
+         * (This feature is disabled while an incoming call is ringing,
+         * because it's easy to accidentally touch the system bar while
+         * pulling the phone out of your pocket.)
+         */
+        public void enableSystemBarNavigation(boolean enable) {
+            if (mIsSystemBarNavigationEnabled != enable) {
+                mIsSystemBarNavigationEnabled = enable;
+                updateStatusBar();
+            }
+        }
+
+        /**
+         * Updates the status bar to reflect the current desired state.
+         */
+        private void updateStatusBar() {
+            int state = StatusBarManager.DISABLE_NONE;
+
+            if (!mIsExpandedViewEnabled) {
+                state |= StatusBarManager.DISABLE_EXPAND;
+            }
+            if (!mIsNotificationEnabled) {
+                state |= StatusBarManager.DISABLE_NOTIFICATION_ALERTS;
+            }
+            if (!mIsSystemBarNavigationEnabled) {
+                // Disable *all* possible navigation via the system bar.
+                state |= StatusBarManager.DISABLE_HOME;
+                state |= StatusBarManager.DISABLE_RECENT;
+                state |= StatusBarManager.DISABLE_BACK;
+            }
+
+            if (DBG) log("updateStatusBar: state = 0x" + Integer.toHexString(state));
+            mStatusBarManager.disable(state);
+        }
+    }
+
+    /**
+     * Makes sure phone-related notifications are up to date on a
+     * freshly-booted device.
+     */
+    private void updateNotificationsAtStartup() {
+        if (DBG) log("updateNotificationsAtStartup()...");
+
+        // instantiate query handler
+        mQueryHandler = new QueryHandler(mContext.getContentResolver());
+
+        // setup query spec, look for all Missed calls that are new.
+        StringBuilder where = new StringBuilder("type=");
+        where.append(Calls.MISSED_TYPE);
+        where.append(" AND new=1");
+
+        // start the query
+        if (DBG) log("- start call log query...");
+        mQueryHandler.startQuery(CALL_LOG_TOKEN, null, Calls.CONTENT_URI,  CALL_LOG_PROJECTION,
+                where.toString(), null, Calls.DEFAULT_SORT_ORDER);
+
+        // Update (or cancel) the in-call notification
+        if (DBG) log("- updating in-call notification at startup...");
+        updateInCallNotification();
+
+        // Depend on android.app.StatusBarManager to be set to
+        // disable(DISABLE_NONE) upon startup.  This will be the
+        // case even if the phone app crashes.
+    }
+
+    /** The projection to use when querying the phones table */
+    static final String[] PHONES_PROJECTION = new String[] {
+        PhoneLookup.NUMBER,
+        PhoneLookup.DISPLAY_NAME,
+        PhoneLookup._ID
+    };
+
+    /**
+     * Class used to run asynchronous queries to re-populate the notifications we care about.
+     * There are really 3 steps to this:
+     *  1. Find the list of missed calls
+     *  2. For each call, run a query to retrieve the caller's name.
+     *  3. For each caller, try obtaining photo.
+     */
+    private class QueryHandler extends AsyncQueryHandler
+            implements ContactsAsyncHelper.OnImageLoadCompleteListener {
+
+        /**
+         * Used to store relevant fields for the Missed Call
+         * notifications.
+         */
+        private class NotificationInfo {
+            public String name;
+            public String number;
+            public int presentation;
+            /**
+             * Type of the call. {@link android.provider.CallLog.Calls#INCOMING_TYPE}
+             * {@link android.provider.CallLog.Calls#OUTGOING_TYPE}, or
+             * {@link android.provider.CallLog.Calls#MISSED_TYPE}.
+             */
+            public String type;
+            public long date;
+        }
+
+        public QueryHandler(ContentResolver cr) {
+            super(cr);
+        }
+
+        /**
+         * Handles the query results.
+         */
+        @Override
+        protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
+            // TODO: it would be faster to use a join here, but for the purposes
+            // of this small record set, it should be ok.
+
+            // Note that CursorJoiner is not useable here because the number
+            // comparisons are not strictly equals; the comparisons happen in
+            // the SQL function PHONE_NUMBERS_EQUAL, which is not available for
+            // the CursorJoiner.
+
+            // Executing our own query is also feasible (with a join), but that
+            // will require some work (possibly destabilizing) in Contacts
+            // Provider.
+
+            // At this point, we will execute subqueries on each row just as
+            // CallLogActivity.java does.
+            switch (token) {
+                case CALL_LOG_TOKEN:
+                    if (DBG) log("call log query complete.");
+
+                    // initial call to retrieve the call list.
+                    if (cursor != null) {
+                        while (cursor.moveToNext()) {
+                            // for each call in the call log list, create
+                            // the notification object and query contacts
+                            NotificationInfo n = getNotificationInfo (cursor);
+
+                            if (DBG) log("query contacts for number: " + n.number);
+
+                            mQueryHandler.startQuery(CONTACT_TOKEN, n,
+                                    Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, n.number),
+                                    PHONES_PROJECTION, null, null, PhoneLookup.NUMBER);
+                        }
+
+                        if (DBG) log("closing call log cursor.");
+                        cursor.close();
+                    }
+                    break;
+                case CONTACT_TOKEN:
+                    if (DBG) log("contact query complete.");
+
+                    // subqueries to get the caller name.
+                    if ((cursor != null) && (cookie != null)){
+                        NotificationInfo n = (NotificationInfo) cookie;
+
+                        Uri personUri = null;
+                        if (cursor.moveToFirst()) {
+                            n.name = cursor.getString(
+                                    cursor.getColumnIndexOrThrow(PhoneLookup.DISPLAY_NAME));
+                            long person_id = cursor.getLong(
+                                    cursor.getColumnIndexOrThrow(PhoneLookup._ID));
+                            if (DBG) {
+                                log("contact :" + n.name + " found for phone: " + n.number
+                                        + ". id : " + person_id);
+                            }
+                            personUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, person_id);
+                        }
+
+                        if (personUri != null) {
+                            if (DBG) {
+                                log("Start obtaining picture for the missed call. Uri: "
+                                        + personUri);
+                            }
+                            // Now try to obtain a photo for this person.
+                            // ContactsAsyncHelper will do that and call onImageLoadComplete()
+                            // after that.
+                            ContactsAsyncHelper.startObtainPhotoAsync(
+                                    0, mContext, personUri, this, n);
+                        } else {
+                            if (DBG) {
+                                log("Failed to find Uri for obtaining photo."
+                                        + " Just send notification without it.");
+                            }
+                            // We couldn't find person Uri, so we're sure we cannot obtain a photo.
+                            // Call notifyMissedCall() right now.
+                            notifyMissedCall(n.name, n.number, n.type, null, null, n.date);
+                        }
+
+                        if (DBG) log("closing contact cursor.");
+                        cursor.close();
+                    }
+                    break;
+                default:
+            }
+        }
+
+        @Override
+        public void onImageLoadComplete(
+                int token, Drawable photo, Bitmap photoIcon, Object cookie) {
+            if (DBG) log("Finished loading image: " + photo);
+            NotificationInfo n = (NotificationInfo) cookie;
+            notifyMissedCall(n.name, n.number, n.type, photo, photoIcon, n.date);
+        }
+
+        /**
+         * Factory method to generate a NotificationInfo object given a
+         * cursor from the call log table.
+         */
+        private final NotificationInfo getNotificationInfo(Cursor cursor) {
+            NotificationInfo n = new NotificationInfo();
+            n.name = null;
+            n.number = cursor.getString(cursor.getColumnIndexOrThrow(Calls.NUMBER));
+            n.presentation = cursor.getInt(cursor.getColumnIndexOrThrow(Calls.NUMBER_PRESENTATION));
+            n.type = cursor.getString(cursor.getColumnIndexOrThrow(Calls.TYPE));
+            n.date = cursor.getLong(cursor.getColumnIndexOrThrow(Calls.DATE));
+
+            // make sure we update the number depending upon saved values in
+            // CallLog.addCall().  If either special values for unknown or
+            // private number are detected, we need to hand off the message
+            // to the missed call notification.
+            if (n.presentation != Calls.PRESENTATION_ALLOWED) {
+                n.number = null;
+            }
+
+            if (DBG) log("NotificationInfo constructed for number: " + n.number);
+
+            return n;
+        }
+    }
+
+    /**
+     * Configures a Notification to emit the blinky green message-waiting/
+     * missed-call signal.
+     */
+    private static void configureLedNotification(Notification note) {
+        note.flags |= Notification.FLAG_SHOW_LIGHTS;
+        note.defaults |= Notification.DEFAULT_LIGHTS;
+    }
+
+    /**
+     * Displays a notification about a missed call.
+     *
+     * @param name the contact name.
+     * @param number the phone number. Note that this may be a non-callable String like "Unknown",
+     * or "Private Number", which possibly come from methods like
+     * {@link PhoneUtils#modifyForSpecialCnapCases(Context, CallerInfo, String, int)}.
+     * @param type the type of the call. {@link android.provider.CallLog.Calls#INCOMING_TYPE}
+     * {@link android.provider.CallLog.Calls#OUTGOING_TYPE}, or
+     * {@link android.provider.CallLog.Calls#MISSED_TYPE}
+     * @param photo picture which may be used for the notification (when photoIcon is null).
+     * This also can be null when the picture itself isn't available. If photoIcon is available
+     * it should be prioritized (because this may be too huge for notification).
+     * See also {@link ContactsAsyncHelper}.
+     * @param photoIcon picture which should be used for the notification. Can be null. This is
+     * the most suitable for {@link android.app.Notification.Builder#setLargeIcon(Bitmap)}, this
+     * should be used when non-null.
+     * @param date the time when the missed call happened
+     */
+    /* package */ void notifyMissedCall(
+            String name, String number, String type, Drawable photo, Bitmap photoIcon, long date) {
+
+        // When the user clicks this notification, we go to the call log.
+        final Intent callLogIntent = PhoneGlobals.createCallLogIntent();
+
+        // Never display the missed call notification on non-voice-capable
+        // devices, even if the device does somehow manage to get an
+        // incoming call.
+        if (!PhoneGlobals.sVoiceCapable) {
+            if (DBG) log("notifyMissedCall: non-voice-capable device, not posting notification");
+            return;
+        }
+
+        if (VDBG) {
+            log("notifyMissedCall(). name: " + name + ", number: " + number
+                + ", label: " + type + ", photo: " + photo + ", photoIcon: " + photoIcon
+                + ", date: " + date);
+        }
+
+        // title resource id
+        int titleResId;
+        // the text in the notification's line 1 and 2.
+        String expandedText, callName;
+
+        // increment number of missed calls.
+        mNumberMissedCalls++;
+
+        // get the name for the ticker text
+        // i.e. "Missed call from <caller name or number>"
+        if (name != null && TextUtils.isGraphic(name)) {
+            callName = name;
+        } else if (!TextUtils.isEmpty(number)){
+            callName = number;
+        } else {
+            // use "unknown" if the caller is unidentifiable.
+            callName = mContext.getString(R.string.unknown);
+        }
+
+        // display the first line of the notification:
+        // 1 missed call: call name
+        // more than 1 missed call: <number of calls> + "missed calls"
+        if (mNumberMissedCalls == 1) {
+            titleResId = R.string.notification_missedCallTitle;
+            expandedText = callName;
+        } else {
+            titleResId = R.string.notification_missedCallsTitle;
+            expandedText = mContext.getString(R.string.notification_missedCallsMsg,
+                    mNumberMissedCalls);
+        }
+
+        Notification.Builder builder = new Notification.Builder(mContext);
+        builder.setSmallIcon(android.R.drawable.stat_notify_missed_call)
+                .setTicker(mContext.getString(R.string.notification_missedCallTicker, callName))
+                .setWhen(date)
+                .setContentTitle(mContext.getText(titleResId))
+                .setContentText(expandedText)
+                .setContentIntent(PendingIntent.getActivity(mContext, 0, callLogIntent, 0))
+                .setAutoCancel(true)
+                .setDeleteIntent(createClearMissedCallsIntent());
+
+        // Simple workaround for issue 6476275; refrain having actions when the given number seems
+        // not a real one but a non-number which was embedded by methods outside (like
+        // PhoneUtils#modifyForSpecialCnapCases()).
+        // TODO: consider removing equals() checks here, and modify callers of this method instead.
+        if (mNumberMissedCalls == 1
+                && !TextUtils.isEmpty(number)
+                && !TextUtils.equals(number, mContext.getString(R.string.private_num))
+                && !TextUtils.equals(number, mContext.getString(R.string.unknown))){
+            if (DBG) log("Add actions with the number " + number);
+
+            builder.addAction(R.drawable.stat_sys_phone_call,
+                    mContext.getString(R.string.notification_missedCall_call_back),
+                    PhoneGlobals.getCallBackPendingIntent(mContext, number));
+
+            builder.addAction(R.drawable.ic_text_holo_dark,
+                    mContext.getString(R.string.notification_missedCall_message),
+                    PhoneGlobals.getSendSmsFromNotificationPendingIntent(mContext, number));
+
+            if (photoIcon != null) {
+                builder.setLargeIcon(photoIcon);
+            } else if (photo instanceof BitmapDrawable) {
+                builder.setLargeIcon(((BitmapDrawable) photo).getBitmap());
+            }
+        } else {
+            if (DBG) {
+                log("Suppress actions. number: " + number + ", missedCalls: " + mNumberMissedCalls);
+            }
+        }
+
+        Notification notification = builder.getNotification();
+        configureLedNotification(notification);
+        mNotificationManager.notify(MISSED_CALL_NOTIFICATION, notification);
+    }
+
+    /** Returns an intent to be invoked when the missed call notification is cleared. */
+    private PendingIntent createClearMissedCallsIntent() {
+        Intent intent = new Intent(mContext, ClearMissedCallsService.class);
+        intent.setAction(ClearMissedCallsService.ACTION_CLEAR_MISSED_CALLS);
+        return PendingIntent.getService(mContext, 0, intent, 0);
+    }
+
+    /**
+     * Cancels the "missed call" notification.
+     *
+     * @see ITelephony.cancelMissedCallsNotification()
+     */
+    void cancelMissedCallNotification() {
+        // reset the number of missed calls to 0.
+        mNumberMissedCalls = 0;
+        mNotificationManager.cancel(MISSED_CALL_NOTIFICATION);
+    }
+
+    private void notifySpeakerphone() {
+        if (!mShowingSpeakerphoneIcon) {
+            mStatusBarManager.setIcon("speakerphone", android.R.drawable.stat_sys_speakerphone, 0,
+                    mContext.getString(R.string.accessibility_speakerphone_enabled));
+            mShowingSpeakerphoneIcon = true;
+        }
+    }
+
+    private void cancelSpeakerphone() {
+        if (mShowingSpeakerphoneIcon) {
+            mStatusBarManager.removeIcon("speakerphone");
+            mShowingSpeakerphoneIcon = false;
+        }
+    }
+
+    /**
+     * Shows or hides the "speakerphone" notification in the status bar,
+     * based on the actual current state of the speaker.
+     *
+     * If you already know the current speaker state (e.g. if you just
+     * called AudioManager.setSpeakerphoneOn() yourself) then you should
+     * directly call {@link #updateSpeakerNotification(boolean)} instead.
+     *
+     * (But note that the status bar icon is *never* shown while the in-call UI
+     * is active; it only appears if you bail out to some other activity.)
+     */
+    private void updateSpeakerNotification() {
+        AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+        boolean showNotification =
+                (mPhone.getState() == PhoneConstants.State.OFFHOOK) && audioManager.isSpeakerphoneOn();
+
+        if (DBG) log(showNotification
+                     ? "updateSpeakerNotification: speaker ON"
+                     : "updateSpeakerNotification: speaker OFF (or not offhook)");
+
+        updateSpeakerNotification(showNotification);
+    }
+
+    /**
+     * Shows or hides the "speakerphone" notification in the status bar.
+     *
+     * @param showNotification if true, call notifySpeakerphone();
+     *                         if false, call cancelSpeakerphone().
+     *
+     * Use {@link updateSpeakerNotification()} to update the status bar
+     * based on the actual current state of the speaker.
+     *
+     * (But note that the status bar icon is *never* shown while the in-call UI
+     * is active; it only appears if you bail out to some other activity.)
+     */
+    public void updateSpeakerNotification(boolean showNotification) {
+        if (DBG) log("updateSpeakerNotification(" + showNotification + ")...");
+
+        // Regardless of the value of the showNotification param, suppress
+        // the status bar icon if the the InCallScreen is the foreground
+        // 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();
+        } else {
+            cancelSpeakerphone();
+        }
+    }
+
+    private void notifyMute() {
+        if (!mShowingMuteIcon) {
+            mStatusBarManager.setIcon("mute", android.R.drawable.stat_notify_call_mute, 0,
+                    mContext.getString(R.string.accessibility_call_muted));
+            mShowingMuteIcon = true;
+        }
+    }
+
+    private void cancelMute() {
+        if (mShowingMuteIcon) {
+            mStatusBarManager.removeIcon("mute");
+            mShowingMuteIcon = false;
+        }
+    }
+
+    /**
+     * Shows or hides the "mute" notification in the status bar,
+     * based on the current mute state of the Phone.
+     *
+     * (But note that the status bar icon is *never* shown while the in-call UI
+     * is active; it only appears if you bail out to some other activity.)
+     */
+    void updateMuteNotification() {
+        // Suppress the status bar icon if the the InCallScreen is the
+        // 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");
+            notifyMute();
+        } else {
+            if (DBG) log("updateMuteNotification: not muted (or not offhook)");
+            cancelMute();
+        }
+    }
+
+    /**
+     * Updates the phone app's status bar notification based on the
+     * current telephony state, or cancels the notification if the phone
+     * is totally idle.
+     *
+     * This method will never actually launch the incoming-call UI.
+     * (Use updateNotificationAndLaunchIncomingCallUi() for that.)
+     */
+    public void updateInCallNotification() {
+        // allowFullScreenIntent=false means *don't* allow the incoming
+        // call UI to be launched.
+        updateInCallNotification(false);
+    }
+
+    /**
+     * Updates the phone app's status bar notification *and* launches the
+     * incoming call UI in response to a new incoming call.
+     *
+     * This is just like updateInCallNotification(), with one exception:
+     * If an incoming call is ringing (or call-waiting), the notification
+     * will also include a "fullScreenIntent" that will cause the
+     * InCallScreen to be launched immediately, unless the current
+     * foreground activity is marked as "immersive".
+     *
+     * (This is the mechanism that actually brings up the incoming call UI
+     * when we receive a "new ringing connection" event from the telephony
+     * layer.)
+     *
+     * Watch out: this method should ONLY be called directly from the code
+     * path in CallNotifier that handles the "new ringing connection"
+     * event from the telephony layer.  All other places that update the
+     * in-call notification (like for phone state changes) should call
+     * updateInCallNotification() instead.  (This ensures that we don't
+     * end up launching the InCallScreen multiple times for a single
+     * incoming call, which could cause slow responsiveness and/or visible
+     * glitches.)
+     *
+     * Also note that this method is safe to call even if the phone isn't
+     * actually ringing (or, more likely, if an incoming call *was*
+     * ringing briefly but then disconnected).  In that case, we'll simply
+     * update or cancel the in-call notification based on the current
+     * phone state.
+     *
+     * @see #updateInCallNotification(boolean)
+     */
+    public void updateNotificationAndLaunchIncomingCallUi() {
+        // Set allowFullScreenIntent=true to indicate that we *should*
+        // launch the incoming call UI if necessary.
+        updateInCallNotification(true);
+    }
+
+    /**
+     * Helper method for updateInCallNotification() and
+     * updateNotificationAndLaunchIncomingCallUi(): Update the phone app's
+     * status bar notification based on the current telephony state, or
+     * cancels the notification if the phone is totally idle.
+     *
+     * @param allowFullScreenIntent If true, *and* an incoming call is
+     *   ringing, the notification will include a "fullScreenIntent"
+     *   pointing at the InCallScreen (which will cause the InCallScreen
+     *   to be launched.)
+     *   Watch out: This should be set to true *only* when directly
+     *   handling the "new ringing connection" event from the telephony
+     *   layer (see updateNotificationAndLaunchIncomingCallUi().)
+     */
+    private void updateInCallNotification(boolean allowFullScreenIntent) {
+        int resId;
+        if (DBG) log("updateInCallNotification(allowFullScreenIntent = "
+                     + allowFullScreenIntent + ")...");
+
+        // Never display the "ongoing call" notification on
+        // non-voice-capable devices, even if the phone is actually
+        // offhook (like during a non-interactive OTASP call.)
+        if (!PhoneGlobals.sVoiceCapable) {
+            if (DBG) log("- non-voice-capable device; suppressing notification.");
+            return;
+        }
+
+        // If the phone is idle, completely clean up all call-related
+        // notifications.
+        if (mCM.getState() == PhoneConstants.State.IDLE) {
+            cancelInCall();
+            cancelMute();
+            cancelSpeakerphone();
+            return;
+        }
+
+        final boolean hasRingingCall = mCM.hasActiveRingingCall();
+        final boolean hasActiveCall = mCM.hasActiveFgCall();
+        final boolean hasHoldingCall = mCM.hasActiveBgCall();
+        if (DBG) {
+            log("  - hasRingingCall = " + hasRingingCall);
+            log("  - hasActiveCall = " + hasActiveCall);
+            log("  - hasHoldingCall = " + hasHoldingCall);
+        }
+
+        // Suppress the in-call notification if the InCallScreen is the
+        // foreground activity, since it's already obvious that you're on a
+        // call.  (The status bar icon is needed only if you navigate *away*
+        // from the in-call UI.)
+        boolean suppressNotification = mApp.isShowingCallScreen();
+        // if (DBG) log("- suppressNotification: initial value: " + suppressNotification);
+
+        // ...except for a couple of cases where we *never* suppress the
+        // notification:
+        //
+        //   - If there's an incoming ringing call: always show the
+        //     notification, since the in-call notification is what actually
+        //     launches the incoming call UI in the first place (see
+        //     notification.fullScreenIntent below.)  This makes sure that we'll
+        //     correctly handle the case where a new incoming call comes in but
+        //     the InCallScreen is already in the foreground.
+        if (hasRingingCall) suppressNotification = false;
+
+        //   - If "voice privacy" mode is active: always show the notification,
+        //     since that's the only "voice privacy" indication we have.
+        boolean enhancedVoicePrivacy = mApp.notifier.getVoicePrivacyState();
+        // if (DBG) log("updateInCallNotification: enhancedVoicePrivacy = " + enhancedVoicePrivacy);
+        if (enhancedVoicePrivacy) suppressNotification = false;
+
+        if (suppressNotification) {
+            if (DBG) log("- suppressNotification = true; reducing clutter in status bar...");
+            cancelInCall();
+            // Suppress the mute and speaker status bar icons too
+            // (also to reduce clutter in the status bar.)
+            cancelSpeakerphone();
+            cancelMute();
+            return;
+        }
+
+        // Display the appropriate icon in the status bar,
+        // based on the current phone and/or bluetooth state.
+
+        if (hasRingingCall) {
+            // There's an incoming ringing call.
+            resId = R.drawable.stat_sys_phone_call;
+        } else if (!hasActiveCall && hasHoldingCall) {
+            // There's only one call, and it's on hold.
+            if (enhancedVoicePrivacy) {
+                resId = R.drawable.stat_sys_vp_phone_call_on_hold;
+            } else {
+                resId = R.drawable.stat_sys_phone_call_on_hold;
+            }
+        } else {
+            if (enhancedVoicePrivacy) {
+                resId = R.drawable.stat_sys_vp_phone_call;
+            } else {
+                resId = R.drawable.stat_sys_phone_call;
+            }
+        }
+
+        // Note we can't just bail out now if (resId == mInCallResId),
+        // since even if the status icon hasn't changed, some *other*
+        // notification-related info may be different from the last time
+        // we were here (like the caller-id info of the foreground call,
+        // if the user swapped calls...)
+
+        if (DBG) log("- Updating status bar icon: resId = " + resId);
+        mInCallResId = resId;
+
+        // Even if both lines are in use, we only show a single item in
+        // the expanded Notifications UI.  It's labeled "Ongoing call"
+        // (or "On hold" if there's only one call, and it's on hold.)
+        // Also, we don't have room to display caller-id info from two
+        // different calls.  So if both lines are in use, display info
+        // from the foreground call.  And if there's a ringing call,
+        // display that regardless of the state of the other calls.
+
+        Call currentCall;
+        if (hasRingingCall) {
+            currentCall = mCM.getFirstActiveRingingCall();
+        } else if (hasActiveCall) {
+            currentCall = mCM.getActiveFgCall();
+        } else {
+            currentCall = mCM.getFirstActiveBgCall();
+        }
+        Connection currentConn = currentCall.getEarliestConnection();
+
+        final Notification.Builder builder = new Notification.Builder(mContext);
+        builder.setSmallIcon(mInCallResId).setOngoing(true);
+
+        // PendingIntent that can be used to launch the InCallScreen.  The
+        // system fires off this intent if the user pulls down the windowshade
+        // and clicks the notification's expanded view.  It's also used to
+        // launch the InCallScreen immediately when when there's an incoming
+        // call (see the "fullScreenIntent" field below).
+        PendingIntent inCallPendingIntent =
+                PendingIntent.getActivity(mContext, 0,
+                                          PhoneGlobals.createInCallIntent(), 0);
+        builder.setContentIntent(inCallPendingIntent);
+
+        // Update icon on the left of the notification.
+        // - If it is directly available from CallerInfo, we'll just use that.
+        // - If it is not, use the same icon as in the status bar.
+        CallerInfo callerInfo = null;
+        if (currentConn != null) {
+            Object o = currentConn.getUserData();
+            if (o instanceof CallerInfo) {
+                callerInfo = (CallerInfo) o;
+            } else if (o instanceof PhoneUtils.CallerInfoToken) {
+                callerInfo = ((PhoneUtils.CallerInfoToken) o).currentInfo;
+            } else {
+                Log.w(LOG_TAG, "CallerInfo isn't available while Call object is available.");
+            }
+        }
+        boolean largeIconWasSet = false;
+        if (callerInfo != null) {
+            // In most cases, the user will see the notification after CallerInfo is already
+            // available, so photo will be available from this block.
+            if (callerInfo.isCachedPhotoCurrent) {
+                // .. and in that case CallerInfo's cachedPhotoIcon should also be available.
+                // If it happens not, then try using cachedPhoto, assuming Drawable coming from
+                // ContactProvider will be BitmapDrawable.
+                if (callerInfo.cachedPhotoIcon != null) {
+                    builder.setLargeIcon(callerInfo.cachedPhotoIcon);
+                    largeIconWasSet = true;
+                } else if (callerInfo.cachedPhoto instanceof BitmapDrawable) {
+                    if (DBG) log("- BitmapDrawable found for large icon");
+                    Bitmap bitmap = ((BitmapDrawable) callerInfo.cachedPhoto).getBitmap();
+                    builder.setLargeIcon(bitmap);
+                    largeIconWasSet = true;
+                } else {
+                    if (DBG) {
+                        log("- Failed to fetch icon from CallerInfo's cached photo."
+                                + " (cachedPhotoIcon: " + callerInfo.cachedPhotoIcon
+                                + ", cachedPhoto: " + callerInfo.cachedPhoto + ")."
+                                + " Ignore it.");
+                    }
+                }
+            }
+
+            if (!largeIconWasSet && callerInfo.photoResource > 0) {
+                if (DBG) {
+                    log("- BitmapDrawable nor person Id not found for large icon."
+                            + " Use photoResource: " + callerInfo.photoResource);
+                }
+                Drawable drawable =
+                        mContext.getResources().getDrawable(callerInfo.photoResource);
+                if (drawable instanceof BitmapDrawable) {
+                    Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
+                    builder.setLargeIcon(bitmap);
+                    largeIconWasSet = true;
+                } else {
+                    if (DBG) {
+                        log("- PhotoResource was found but it didn't return BitmapDrawable."
+                                + " Ignore it");
+                    }
+                }
+            }
+        } else {
+            if (DBG) log("- CallerInfo not found. Use the same icon as in the status bar.");
+        }
+
+        // Failed to fetch Bitmap.
+        if (!largeIconWasSet && DBG) {
+            log("- No useful Bitmap was found for the photo."
+                    + " Use the same icon as in the status bar.");
+        }
+
+        // If the connection is valid, then build what we need for the
+        // content text of notification, and start the chronometer.
+        // Otherwise, don't bother and just stick with content title.
+        if (currentConn != null) {
+            if (DBG) log("- Updating context text and chronometer.");
+            if (hasRingingCall) {
+                // Incoming call is ringing.
+                builder.setContentText(mContext.getString(R.string.notification_incoming_call));
+                builder.setUsesChronometer(false);
+            } else if (hasHoldingCall && !hasActiveCall) {
+                // Only one call, and it's on hold.
+                builder.setContentText(mContext.getString(R.string.notification_on_hold));
+                builder.setUsesChronometer(false);
+            } else {
+                // We show the elapsed time of the current call using Chronometer.
+                builder.setUsesChronometer(true);
+
+                // Determine the "start time" of the current connection.
+                //   We can't use currentConn.getConnectTime(), because (1) that's
+                // in the currentTimeMillis() time base, and (2) it's zero when
+                // the phone first goes off hook, since the getConnectTime counter
+                // doesn't start until the DIALING -> ACTIVE transition.
+                //   Instead we start with the current connection's duration,
+                // and translate that into the elapsedRealtime() timebase.
+                long callDurationMsec = currentConn.getDurationMillis();
+                builder.setWhen(System.currentTimeMillis() - callDurationMsec);
+
+                int contextTextId = R.string.notification_ongoing_call;
+
+                Call call = mCM.getActiveFgCall();
+                if (TelephonyCapabilities.canDistinguishDialingAndConnected(
+                        call.getPhone().getPhoneType()) && call.isDialingOrAlerting()) {
+                  contextTextId = R.string.notification_dialing;
+                }
+
+                builder.setContentText(mContext.getString(contextTextId));
+            }
+        } else if (DBG) {
+            Log.w(LOG_TAG, "updateInCallNotification: null connection, can't set exp view line 1.");
+        }
+
+        // display conference call string if this call is a conference
+        // call, otherwise display the connection information.
+
+        // Line 2 of the expanded view (smaller text).  This is usually a
+        // contact name or phone number.
+        String expandedViewLine2 = "";
+        // TODO: it may not make sense for every point to make separate
+        // checks for isConferenceCall, so we need to think about
+        // possibly including this in startGetCallerInfo or some other
+        // common point.
+        if (PhoneUtils.isConferenceCall(currentCall)) {
+            // if this is a conference call, just use that as the caller name.
+            expandedViewLine2 = mContext.getString(R.string.card_title_conf_call);
+        } else {
+            // If necessary, start asynchronous query to do the caller-id lookup.
+            PhoneUtils.CallerInfoToken cit =
+                PhoneUtils.startGetCallerInfo(mContext, currentCall, this, this);
+            expandedViewLine2 = PhoneUtils.getCompactNameFromCallerInfo(cit.currentInfo, mContext);
+            // Note: For an incoming call, the very first time we get here we
+            // won't have a contact name yet, since we only just started the
+            // caller-id query.  So expandedViewLine2 will start off as a raw
+            // phone number, but we'll update it very quickly when the query
+            // completes (see onQueryComplete() below.)
+        }
+
+        if (DBG) log("- Updating expanded view: line 2 '" + /*expandedViewLine2*/ "xxxxxxx" + "'");
+        builder.setContentTitle(expandedViewLine2);
+
+        // TODO: We also need to *update* this notification in some cases,
+        // like when a call ends on one line but the other is still in use
+        // (ie. make sure the caller info here corresponds to the active
+        // line), and maybe even when the user swaps calls (ie. if we only
+        // show info here for the "current active call".)
+
+        // Activate a couple of special Notification features if an
+        // incoming call is ringing:
+        if (hasRingingCall) {
+            if (DBG) log("- Using hi-pri notification for ringing call!");
+
+            // This is a high-priority event that should be shown even if the
+            // status bar is hidden or if an immersive activity is running.
+            builder.setPriority(Notification.PRIORITY_HIGH);
+
+            // If an immersive activity is running, we have room for a single
+            // line of text in the small notification popup window.
+            // We use expandedViewLine2 for this (i.e. the name or number of
+            // the incoming caller), since that's more relevant than
+            // expandedViewLine1 (which is something generic like "Incoming
+            // call".)
+            builder.setTicker(expandedViewLine2);
+
+            if (allowFullScreenIntent) {
+                // Ok, we actually want to launch the incoming call
+                // UI at this point (in addition to simply posting a notification
+                // to the status bar).  Setting fullScreenIntent will cause
+                // the InCallScreen to be launched immediately *unless* the
+                // current foreground activity is marked as "immersive".
+                if (DBG) log("- Setting fullScreenIntent: " + inCallPendingIntent);
+                builder.setFullScreenIntent(inCallPendingIntent, true);
+
+                // Ugly hack alert:
+                //
+                // The NotificationManager has the (undocumented) behavior
+                // that it will *ignore* the fullScreenIntent field if you
+                // post a new Notification that matches the ID of one that's
+                // already active.  Unfortunately this is exactly what happens
+                // when you get an incoming call-waiting call:  the
+                // "ongoing call" notification is already visible, so the
+                // InCallScreen won't get launched in this case!
+                // (The result: if you bail out of the in-call UI while on a
+                // call and then get a call-waiting call, the incoming call UI
+                // won't come up automatically.)
+                //
+                // The workaround is to just notice this exact case (this is a
+                // call-waiting call *and* the InCallScreen is not in the
+                // foreground) and manually cancel the in-call notification
+                // before (re)posting it.
+                //
+                // TODO: there should be a cleaner way of avoiding this
+                // problem (see discussion in bug 3184149.)
+                Call ringingCall = mCM.getFirstActiveRingingCall();
+                if ((ringingCall.getState() == Call.State.WAITING) && !mApp.isShowingCallScreen()) {
+                    Log.i(LOG_TAG, "updateInCallNotification: call-waiting! force relaunch...");
+                    // Cancel the IN_CALL_NOTIFICATION immediately before
+                    // (re)posting it; this seems to force the
+                    // NotificationManager to launch the fullScreenIntent.
+                    mNotificationManager.cancel(IN_CALL_NOTIFICATION);
+                }
+            }
+        } else { // not ringing call
+            // Make the notification prioritized over the other normal notifications.
+            builder.setPriority(Notification.PRIORITY_HIGH);
+
+            // TODO: use "if (DBG)" for this comment.
+            log("Will show \"hang-up\" action in the ongoing active call Notification");
+            // TODO: use better asset.
+            builder.addAction(R.drawable.stat_sys_phone_call_end,
+                    mContext.getText(R.string.notification_action_end_call),
+                    PhoneGlobals.createHangUpOngoingCallPendingIntent(mContext));
+        }
+
+        Notification notification = builder.getNotification();
+        if (DBG) log("Notifying IN_CALL_NOTIFICATION: " + notification);
+        mNotificationManager.notify(IN_CALL_NOTIFICATION, notification);
+
+        // Finally, refresh the mute and speakerphone notifications (since
+        // some phone state changes can indirectly affect the mute and/or
+        // speaker state).
+        updateSpeakerNotification();
+        updateMuteNotification();
+    }
+
+    /**
+     * Implemented for CallerInfoAsyncQuery.OnQueryCompleteListener interface.
+     * refreshes the contentView when called.
+     */
+    @Override
+    public void onQueryComplete(int token, Object cookie, CallerInfo ci){
+        if (DBG) log("CallerInfo query complete (for NotificationMgr), "
+                     + "updating in-call notification..");
+        if (DBG) log("- cookie: " + cookie);
+        if (DBG) log("- ci: " + ci);
+
+        if (cookie == this) {
+            // Ok, this is the caller-id query we fired off in
+            // updateInCallNotification(), presumably when an incoming call
+            // first appeared.  If the caller-id info matched any contacts,
+            // compactName should now be a real person name rather than a raw
+            // phone number:
+            if (DBG) log("- compactName is now: "
+                         + PhoneUtils.getCompactNameFromCallerInfo(ci, mContext));
+
+            // Now that our CallerInfo object has been fully filled-in,
+            // refresh the in-call notification.
+            if (DBG) log("- updating notification after query complete...");
+            updateInCallNotification();
+        } else {
+            Log.w(LOG_TAG, "onQueryComplete: caller-id query from unknown source! "
+                  + "cookie = " + cookie);
+        }
+    }
+
+    /**
+     * Take down the in-call notification.
+     * @see updateInCallNotification()
+     */
+    private void cancelInCall() {
+        if (DBG) log("cancelInCall()...");
+        mNotificationManager.cancel(IN_CALL_NOTIFICATION);
+        mInCallResId = 0;
+    }
+
+    /**
+     * Completely take down the in-call notification *and* the mute/speaker
+     * notifications as well, to indicate that the phone is now idle.
+     */
+    /* package */ void cancelCallInProgressNotifications() {
+        if (DBG) log("cancelCallInProgressNotifications()...");
+        if (mInCallResId == 0) {
+            return;
+        }
+
+        if (DBG) log("cancelCallInProgressNotifications: " + mInCallResId);
+        cancelInCall();
+        cancelMute();
+        cancelSpeakerphone();
+    }
+
+    /**
+     * Updates the message waiting indicator (voicemail) notification.
+     *
+     * @param visible true if there are messages waiting
+     */
+    /* package */ void updateMwi(boolean visible) {
+        if (DBG) log("updateMwi(): " + visible);
+
+        if (visible) {
+            int resId = android.R.drawable.stat_notify_voicemail;
+
+            // This Notification can get a lot fancier once we have more
+            // information about the current voicemail messages.
+            // (For example, the current voicemail system can't tell
+            // us the caller-id or timestamp of a message, or tell us the
+            // message count.)
+
+            // But for now, the UI is ultra-simple: if the MWI indication
+            // is supposed to be visible, just show a single generic
+            // notification.
+
+            String notificationTitle = mContext.getString(R.string.notification_voicemail_title);
+            String vmNumber = mPhone.getVoiceMailNumber();
+            if (DBG) log("- got vm number: '" + vmNumber + "'");
+
+            // Watch out: vmNumber may be null, for two possible reasons:
+            //
+            //   (1) This phone really has no voicemail number
+            //
+            //   (2) This phone *does* have a voicemail number, but
+            //       the SIM isn't ready yet.
+            //
+            // Case (2) *does* happen in practice if you have voicemail
+            // messages when the device first boots: we get an MWI
+            // notification as soon as we register on the network, but the
+            // SIM hasn't finished loading yet.
+            //
+            // So handle case (2) by retrying the lookup after a short
+            // delay.
+
+            if ((vmNumber == null) && !mPhone.getIccRecordsLoaded()) {
+                if (DBG) log("- Null vm number: SIM records not loaded (yet)...");
+
+                // TODO: rather than retrying after an arbitrary delay, it
+                // would be cleaner to instead just wait for a
+                // SIM_RECORDS_LOADED notification.
+                // (Unfortunately right now there's no convenient way to
+                // get that notification in phone app code.  We'd first
+                // want to add a call like registerForSimRecordsLoaded()
+                // to Phone.java and GSMPhone.java, and *then* we could
+                // listen for that in the CallNotifier class.)
+
+                // Limit the number of retries (in case the SIM is broken
+                // or missing and can *never* load successfully.)
+                if (mVmNumberRetriesRemaining-- > 0) {
+                    if (DBG) log("  - Retrying in " + VM_NUMBER_RETRY_DELAY_MILLIS + " msec...");
+                    mApp.notifier.sendMwiChangedDelayed(VM_NUMBER_RETRY_DELAY_MILLIS);
+                    return;
+                } else {
+                    Log.w(LOG_TAG, "NotificationMgr.updateMwi: getVoiceMailNumber() failed after "
+                          + MAX_VM_NUMBER_RETRIES + " retries; giving up.");
+                    // ...and continue with vmNumber==null, just as if the
+                    // phone had no VM number set up in the first place.
+                }
+            }
+
+            if (TelephonyCapabilities.supportsVoiceMessageCount(mPhone)) {
+                int vmCount = mPhone.getVoiceMessageCount();
+                String titleFormat = mContext.getString(R.string.notification_voicemail_title_count);
+                notificationTitle = String.format(titleFormat, vmCount);
+            }
+
+            String notificationText;
+            if (TextUtils.isEmpty(vmNumber)) {
+                notificationText = mContext.getString(
+                        R.string.notification_voicemail_no_vm_number);
+            } else {
+                notificationText = String.format(
+                        mContext.getString(R.string.notification_voicemail_text_format),
+                        PhoneNumberUtils.formatNumber(vmNumber));
+            }
+
+            Intent intent = new Intent(Intent.ACTION_CALL,
+                    Uri.fromParts(Constants.SCHEME_VOICEMAIL, "", null));
+            PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, intent, 0);
+
+            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
+            Uri ringtoneUri;
+            String uriString = prefs.getString(
+                    CallFeaturesSetting.BUTTON_VOICEMAIL_NOTIFICATION_RINGTONE_KEY, null);
+            if (!TextUtils.isEmpty(uriString)) {
+                ringtoneUri = Uri.parse(uriString);
+            } else {
+                ringtoneUri = Settings.System.DEFAULT_NOTIFICATION_URI;
+            }
+
+            Notification.Builder builder = new Notification.Builder(mContext);
+            builder.setSmallIcon(resId)
+                    .setWhen(System.currentTimeMillis())
+                    .setContentTitle(notificationTitle)
+                    .setContentText(notificationText)
+                    .setContentIntent(pendingIntent)
+                    .setSound(ringtoneUri);
+            Notification notification = builder.getNotification();
+
+            CallFeaturesSetting.migrateVoicemailVibrationSettingsIfNeeded(prefs);
+            final boolean vibrate = prefs.getBoolean(
+                    CallFeaturesSetting.BUTTON_VOICEMAIL_NOTIFICATION_VIBRATE_KEY, false);
+            if (vibrate) {
+                notification.defaults |= Notification.DEFAULT_VIBRATE;
+            }
+            notification.flags |= Notification.FLAG_NO_CLEAR;
+            configureLedNotification(notification);
+            mNotificationManager.notify(VOICEMAIL_NOTIFICATION, notification);
+        } else {
+            mNotificationManager.cancel(VOICEMAIL_NOTIFICATION);
+        }
+    }
+
+    /**
+     * Updates the message call forwarding indicator notification.
+     *
+     * @param visible true if there are messages waiting
+     */
+    /* package */ void updateCfi(boolean visible) {
+        if (DBG) log("updateCfi(): " + visible);
+        if (visible) {
+            // If Unconditional Call Forwarding (forward all calls) for VOICE
+            // is enabled, just show a notification.  We'll default to expanded
+            // view for now, so the there is less confusion about the icon.  If
+            // it is deemed too weird to have CF indications as expanded views,
+            // then we'll flip the flag back.
+
+            // TODO: We may want to take a look to see if the notification can
+            // display the target to forward calls to.  This will require some
+            // effort though, since there are multiple layers of messages that
+            // will need to propagate that information.
+
+            Notification notification;
+            final boolean showExpandedNotification = true;
+            if (showExpandedNotification) {
+                Intent intent = new Intent(Intent.ACTION_MAIN);
+                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                intent.setClassName("com.android.phone",
+                        "com.android.phone.CallFeaturesSetting");
+
+                notification = new Notification(
+                        R.drawable.stat_sys_phone_call_forward,  // icon
+                        null, // tickerText
+                        0); // The "timestamp" of this notification is meaningless;
+                            // we only care about whether CFI is currently on or not.
+                notification.setLatestEventInfo(
+                        mContext, // context
+                        mContext.getString(R.string.labelCF), // expandedTitle
+                        mContext.getString(R.string.sum_cfu_enabled_indicator), // expandedText
+                        PendingIntent.getActivity(mContext, 0, intent, 0)); // contentIntent
+            } else {
+                notification = new Notification(
+                        R.drawable.stat_sys_phone_call_forward,  // icon
+                        null,  // tickerText
+                        System.currentTimeMillis()  // when
+                        );
+            }
+
+            notification.flags |= Notification.FLAG_ONGOING_EVENT;  // also implies FLAG_NO_CLEAR
+
+            mNotificationManager.notify(
+                    CALL_FORWARD_NOTIFICATION,
+                    notification);
+        } else {
+            mNotificationManager.cancel(CALL_FORWARD_NOTIFICATION);
+        }
+    }
+
+    /**
+     * Shows the "data disconnected due to roaming" notification, which
+     * appears when you lose data connectivity because you're roaming and
+     * you have the "data roaming" feature turned off.
+     */
+    /* package */ void showDataDisconnectedRoaming() {
+        if (DBG) log("showDataDisconnectedRoaming()...");
+
+        // "Mobile network settings" screen / dialog
+        Intent intent = new Intent(mContext, com.android.phone.MobileNetworkSettings.class);
+
+        final CharSequence contentText = mContext.getText(R.string.roaming_reenable_message);
+
+        final Notification.Builder builder = new Notification.Builder(mContext);
+        builder.setSmallIcon(android.R.drawable.stat_sys_warning);
+        builder.setContentTitle(mContext.getText(R.string.roaming));
+        builder.setContentText(contentText);
+        builder.setContentIntent(PendingIntent.getActivity(mContext, 0, intent, 0));
+
+        final Notification notif = new Notification.BigTextStyle(builder).bigText(contentText)
+                .build();
+
+        mNotificationManager.notify(DATA_DISCONNECTED_ROAMING_NOTIFICATION, notif);
+    }
+
+    /**
+     * Turns off the "data disconnected due to roaming" notification.
+     */
+    /* package */ void hideDataDisconnectedRoaming() {
+        if (DBG) log("hideDataDisconnectedRoaming()...");
+        mNotificationManager.cancel(DATA_DISCONNECTED_ROAMING_NOTIFICATION);
+    }
+
+    /**
+     * Display the network selection "no service" notification
+     * @param operator is the numeric operator number
+     */
+    private void showNetworkSelection(String operator) {
+        if (DBG) log("showNetworkSelection(" + operator + ")...");
+
+        String titleText = mContext.getString(
+                R.string.notification_network_selection_title);
+        String expandedText = mContext.getString(
+                R.string.notification_network_selection_text, operator);
+
+        Notification notification = new Notification();
+        notification.icon = android.R.drawable.stat_sys_warning;
+        notification.when = 0;
+        notification.flags = Notification.FLAG_ONGOING_EVENT;
+        notification.tickerText = null;
+
+        // create the target network operators settings intent
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
+                Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+        // Use NetworkSetting to handle the selection intent
+        intent.setComponent(new ComponentName("com.android.phone",
+                "com.android.phone.NetworkSetting"));
+        PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0);
+
+        notification.setLatestEventInfo(mContext, titleText, expandedText, pi);
+
+        mNotificationManager.notify(SELECTED_OPERATOR_FAIL_NOTIFICATION, notification);
+    }
+
+    /**
+     * Turn off the network selection "no service" notification
+     */
+    private void cancelNetworkSelection() {
+        if (DBG) log("cancelNetworkSelection()...");
+        mNotificationManager.cancel(SELECTED_OPERATOR_FAIL_NOTIFICATION);
+    }
+
+    /**
+     * Update notification about no service of user selected operator
+     *
+     * @param serviceState Phone service state
+     */
+    void updateNetworkSelection(int serviceState) {
+        if (TelephonyCapabilities.supportsNetworkSelection(mPhone)) {
+            // get the shared preference of network_selection.
+            // empty is auto mode, otherwise it is the operator alpha name
+            // in case there is no operator name, check the operator numeric
+            SharedPreferences sp =
+                    PreferenceManager.getDefaultSharedPreferences(mContext);
+            String networkSelection =
+                    sp.getString(PhoneBase.NETWORK_SELECTION_NAME_KEY, "");
+            if (TextUtils.isEmpty(networkSelection)) {
+                networkSelection =
+                        sp.getString(PhoneBase.NETWORK_SELECTION_KEY, "");
+            }
+
+            if (DBG) log("updateNetworkSelection()..." + "state = " +
+                    serviceState + " new network " + networkSelection);
+
+            if (serviceState == ServiceState.STATE_OUT_OF_SERVICE
+                    && !TextUtils.isEmpty(networkSelection)) {
+                if (!mSelectedUnavailableNotify) {
+                    showNetworkSelection(networkSelection);
+                    mSelectedUnavailableNotify = true;
+                }
+            } else {
+                if (mSelectedUnavailableNotify) {
+                    cancelNetworkSelection();
+                    mSelectedUnavailableNotify = false;
+                }
+            }
+        }
+    }
+
+    /* package */ void postTransientNotification(int notifyId, CharSequence msg) {
+        if (mToast != null) {
+            mToast.cancel();
+        }
+
+        mToast = Toast.makeText(mContext, msg, Toast.LENGTH_LONG);
+        mToast.show();
+    }
+
+    private void log(String msg) {
+        Log.d(LOG_TAG, msg);
+    }
+}
diff --git a/src/com/android/phone/OtaStartupReceiver.java b/src/com/android/phone/OtaStartupReceiver.java
new file mode 100644
index 0000000..594b63a
--- /dev/null
+++ b/src/com/android/phone/OtaStartupReceiver.java
@@ -0,0 +1,177 @@
+/*
+ * 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.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.Message;
+import android.os.SystemProperties;
+import android.provider.Settings;
+import android.telephony.PhoneStateListener;
+import android.telephony.ServiceState;
+import android.telephony.TelephonyManager;
+
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.TelephonyCapabilities;
+
+import android.util.Log;
+
+/*
+ * Handles OTA Start procedure at phone power up. At phone power up, if phone is not OTA
+ * provisioned (check MIN value of the Phone) and 'device_provisioned' is not set,
+ * OTA Activation screen is shown that helps user activate the phone
+ */
+public class OtaStartupReceiver extends BroadcastReceiver {
+    private static final String TAG = "OtaStartupReceiver";
+    private static final boolean DBG = false;
+    private static final int MIN_READY = 10;
+    private static final int SERVICE_STATE_CHANGED = 11;
+    private Context mContext;
+
+    /**
+     * For debug purposes we're listening for otaspChanged events as
+     * this may be be used in the future for deciding if OTASP is
+     * necessary.
+     */
+    private int mOtaspMode = -1;
+    private boolean mPhoneStateListenerRegistered = false;
+    private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
+        @Override
+        public void onOtaspChanged(int otaspMode) {
+            mOtaspMode = otaspMode;
+            Log.v(TAG, "onOtaspChanged: mOtaspMode=" + mOtaspMode);
+        }
+    };
+
+
+    private Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MIN_READY:
+                    Log.v(TAG, "Attempting OtaActivation from handler, mOtaspMode=" + mOtaspMode);
+                    OtaUtils.maybeDoOtaCall(mContext, mHandler, MIN_READY);
+                    break;
+                case SERVICE_STATE_CHANGED: {
+                    ServiceState state = (ServiceState) ((AsyncResult) msg.obj).result;
+                    if (DBG) Log.d(TAG, "onServiceStateChanged()...  new state = " + state);
+
+                    // Possible service states:
+                    // - STATE_IN_SERVICE        // Normal operation
+                    // - STATE_OUT_OF_SERVICE    // Still searching for an operator to register to,
+                    //                           // or no radio signal
+                    // - STATE_EMERGENCY_ONLY    // Phone is locked; only emergency numbers are allowed
+                    // - STATE_POWER_OFF         // Radio is explicitly powered off (airplane mode)
+
+                    // Once we reach STATE_IN_SERVICE
+                    // it's finally OK to start OTA provisioning
+                    if (state.getState() == ServiceState.STATE_IN_SERVICE) {
+                        if (DBG) Log.d(TAG, "call OtaUtils.maybeDoOtaCall after network is available");
+                        Phone phone = PhoneGlobals.getPhone();
+                        phone.unregisterForServiceStateChanged(this);
+                        OtaUtils.maybeDoOtaCall(mContext, mHandler, MIN_READY);
+                    }
+                    break;
+                }
+            }
+
+        }
+    };
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        mContext = context;
+        if (DBG) {
+            Log.v(TAG, "onReceive: intent action=" + intent.getAction() +
+                    "  mOtaspMode=" + mOtaspMode);
+        }
+
+        PhoneGlobals globals = PhoneGlobals.getInstanceIfPrimary();
+        if (globals == null) {
+            if (DBG) Log.d(TAG, "Not primary user, nothing to do.");
+            return;
+        }
+
+        if (!TelephonyCapabilities.supportsOtasp(PhoneGlobals.getPhone())) {
+            if (DBG) Log.d(TAG, "OTASP not supported, nothing to do.");
+            return;
+        }
+
+        if (mPhoneStateListenerRegistered == false) {
+            if (DBG) Log.d(TAG, "Register our PhoneStateListener");
+            TelephonyManager telephonyManager = (TelephonyManager)context.getSystemService(
+                    Context.TELEPHONY_SERVICE);
+            telephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_OTASP_CHANGED);
+            mPhoneStateListenerRegistered = true;
+        } else {
+            if (DBG) Log.d(TAG, "PhoneStateListener already registered");
+        }
+
+        if (shouldPostpone(context)) {
+            if (DBG) Log.d(TAG, "Postponing OTASP until wizard runs");
+            return;
+        }
+
+        // Delay OTA provisioning if network is not available yet
+        PhoneGlobals app = PhoneGlobals.getInstance();
+        Phone phone = PhoneGlobals.getPhone();
+        if (app.mCM.getServiceState() != ServiceState.STATE_IN_SERVICE) {
+            if (DBG) Log.w(TAG, "Network is not ready. Registering to receive notification.");
+            phone.registerForServiceStateChanged(mHandler, SERVICE_STATE_CHANGED, null);
+            return;
+        }
+
+        // The following depends on the phone process being persistent. Normally we can't
+        // expect a BroadcastReceiver to persist after returning from this function but it does
+        // because the phone activity is persistent.
+        if (DBG) Log.d(TAG, "call OtaUtils.maybeDoOtaCall");
+        OtaUtils.maybeDoOtaCall(mContext, mHandler, MIN_READY);
+    }
+
+    /**
+     * On devices that provide a phone initialization wizard (such as Google Setup Wizard), we
+     * allow delaying CDMA OTA setup so it can be done in a single wizard. The wizard is responsible
+     * for (1) disabling itself once it has been run and/or (2) setting the 'device_provisioned'
+     * flag to something non-zero and (3) calling the OTA Setup with the action below.
+     *
+     * NB: Typical phone initialization wizards will install themselves as the homescreen
+     * (category "android.intent.category.HOME") with a priority higher than the default.
+     * The wizard should set 'device_provisioned' when it completes, disable itself with the
+     * PackageManager.setComponentEnabledSetting() and then start home screen.
+     *
+     * @return true if setup will be handled by wizard, false if it should be done now.
+     */
+    private boolean shouldPostpone(Context context) {
+        Intent intent = new Intent("android.intent.action.DEVICE_INITIALIZATION_WIZARD");
+        ResolveInfo resolveInfo = context.getPackageManager().resolveActivity(intent,
+                PackageManager.MATCH_DEFAULT_ONLY);
+        boolean provisioned = Settings.Global.getInt(context.getContentResolver(),
+                Settings.Global.DEVICE_PROVISIONED, 0) != 0;
+        String mode = SystemProperties.get("ro.setupwizard.mode", "REQUIRED");
+        boolean runningSetupWizard = "REQUIRED".equals(mode) || "OPTIONAL".equals(mode);
+        if (DBG) {
+            Log.v(TAG, "resolvInfo = " + resolveInfo + ", provisioned = " + provisioned
+                    + ", runningSetupWizard = " + runningSetupWizard);
+        }
+        return resolveInfo != null && !provisioned && runningSetupWizard;
+    }
+}
diff --git a/src/com/android/phone/OtaUtils.java b/src/com/android/phone/OtaUtils.java
new file mode 100644
index 0000000..495df27
--- /dev/null
+++ b/src/com/android/phone/OtaUtils.java
@@ -0,0 +1,1645 @@
+/*
+ * 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 com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.TelephonyCapabilities;
+import com.android.internal.telephony.TelephonyProperties;
+import com.android.phone.OtaUtils.CdmaOtaInCallScreenUiState.State;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.AlertDialog;
+import android.app.PendingIntent;
+import android.app.PendingIntent.CanceledException;
+import android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.SystemClock;
+import android.os.SystemProperties;
+import android.os.UserHandle;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewStub;
+import android.view.WindowManager;
+import android.widget.Button;
+import android.widget.ProgressBar;
+import android.widget.ScrollView;
+import android.widget.TextView;
+import android.widget.ToggleButton;
+
+/**
+ * Handles all OTASP Call related logic and UI functionality.
+ * The InCallScreen interacts with this class to perform an OTASP Call.
+ *
+ * OTASP is a CDMA-specific feature:
+ *   OTA or OTASP == Over The Air service provisioning
+ *   SPC == Service Programming Code
+ *   TODO: Include pointer to more detailed documentation.
+ *
+ * TODO: This is Over The Air Service Provisioning (OTASP)
+ *       A better name would be OtaspUtils.java.
+ */
+public class OtaUtils {
+    private static final String LOG_TAG = "OtaUtils";
+    private static final boolean DBG = false;
+
+    public static final int OTA_SHOW_ACTIVATION_SCREEN_OFF = 0;
+    public static final int OTA_SHOW_ACTIVATION_SCREEN_ON = 1;
+    public static final int OTA_SHOW_LISTENING_SCREEN_OFF =0;
+    public static final int OTA_SHOW_LISTENING_SCREEN_ON =1;
+    public static final int OTA_SHOW_ACTIVATE_FAIL_COUNT_OFF = 0;
+    public static final int OTA_SHOW_ACTIVATE_FAIL_COUNT_THREE = 3;
+    public static final int OTA_PLAY_SUCCESS_FAILURE_TONE_OFF = 0;
+    public static final int OTA_PLAY_SUCCESS_FAILURE_TONE_ON = 1;
+
+    // SPC Timeout is 60 seconds
+    public final int OTA_SPC_TIMEOUT = 60;
+    public final int OTA_FAILURE_DIALOG_TIMEOUT = 2;
+
+    // Constants for OTASP-related Intents and intent extras.
+    // Watch out: these must agree with the corresponding constants in
+    // apps/SetupWizard!
+
+    // Intent action to launch an OTASP call.
+    public static final String ACTION_PERFORM_CDMA_PROVISIONING =
+           "com.android.phone.PERFORM_CDMA_PROVISIONING";
+
+    // Intent action to launch activation on a non-voice capable device
+    public static final String ACTION_PERFORM_VOICELESS_CDMA_PROVISIONING =
+            "com.android.phone.PERFORM_VOICELESS_CDMA_PROVISIONING";
+
+    // Intent action to display the InCallScreen in the OTASP "activation" state.
+    public static final String ACTION_DISPLAY_ACTIVATION_SCREEN =
+            "com.android.phone.DISPLAY_ACTIVATION_SCREEN";
+
+    // boolean voiceless provisioning extra that enables a "don't show this again" checkbox
+    // the user can check to never see the activity upon bootup again
+    public static final String EXTRA_VOICELESS_PROVISIONING_OFFER_DONTSHOW =
+            "com.android.phone.VOICELESS_PROVISIONING_OFFER_DONTSHOW";
+
+    // Activity result codes for the ACTION_PERFORM_CDMA_PROVISIONING intent
+    // (see the InCallScreenShowActivation activity.)
+    //
+    // Note: currently, our caller won't ever actually receive the
+    // RESULT_INTERACTIVE_OTASP_STARTED result code; see comments in
+    // InCallScreenShowActivation.onCreate() for details.
+
+    public static final int RESULT_INTERACTIVE_OTASP_STARTED = Activity.RESULT_FIRST_USER;
+    public static final int RESULT_NONINTERACTIVE_OTASP_STARTED = Activity.RESULT_FIRST_USER + 1;
+    public static final int RESULT_NONINTERACTIVE_OTASP_FAILED = Activity.RESULT_FIRST_USER + 2;
+
+    // Testing: Extra for the ACTION_PERFORM_CDMA_PROVISIONING intent that
+    // allows the caller to manually enable/disable "interactive mode" for
+    // the OTASP call.   Only available in userdebug or eng builds.
+    public static final String EXTRA_OVERRIDE_INTERACTIVE_MODE =
+            "ota_override_interactive_mode";
+
+    // Extra for the ACTION_PERFORM_CDMA_PROVISIONING intent, holding a
+    // PendingIntent which the phone app can use to send a result code
+    // back to the caller.
+    public static final String EXTRA_OTASP_RESULT_CODE_PENDING_INTENT =
+            "otasp_result_code_pending_intent";
+
+    // Extra attached to the above PendingIntent that indicates
+    // success or failure.
+    public static final String EXTRA_OTASP_RESULT_CODE =
+            "otasp_result_code";
+    public static final int OTASP_UNKNOWN = 0;
+    public static final int OTASP_USER_SKIPPED = 1;  // Only meaningful with interactive OTASP
+    public static final int OTASP_SUCCESS = 2;
+    public static final int OTASP_FAILURE = 3;
+    // failed due to CDMA_OTA_PROVISION_STATUS_SPC_RETRIES_EXCEEDED
+    public static final int OTASP_FAILURE_SPC_RETRIES = 4;
+    // TODO: Distinguish between interactive and non-interactive success
+    // and failure.  Then, have the PendingIntent be sent after
+    // interactive OTASP as well (so the caller can find out definitively
+    // when interactive OTASP completes.)
+
+    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;
+
+    // How many times do we retry maybeDoOtaCall() if the LTE state is not known yet,
+    // and how long do we wait between retries
+    private static final int OTA_CALL_LTE_RETRIES_MAX = 5;
+    private static final int OTA_CALL_LTE_RETRY_PERIOD = 3000;
+    private static int sOtaCallLteRetries = 0;
+
+    // In "interactive mode", the OtaUtils object is tied to an
+    // InCallScreen instance, where we display a bunch of UI specific to
+    // the OTASP call.  But on devices that are not "voice capable", the
+    // OTASP call runs in a non-interactive mode, and we don't have
+    // an InCallScreen or CallCard or any OTASP UI elements at all.
+    private boolean mInteractive = true;
+
+
+    /**
+     * OtaWidgetData class represent all OTA UI elements
+     *
+     * TODO(OTASP): It's really ugly for the OtaUtils object to reach into the
+     *     InCallScreen like this and directly manipulate its widgets.
+     *
+     *     Instead, the model/view separation should be more clear: OtaUtils
+     *     should only know about a higher-level abstraction of the
+     *     OTASP-specific UI state (just like how the CallController uses the
+     *     InCallUiState object), and the InCallScreen itself should translate
+     *     that higher-level abstraction into actual onscreen views and widgets.
+     */
+    private class OtaWidgetData {
+        public Button otaEndButton;
+        public Button otaActivateButton;
+        public Button otaSkipButton;
+        public Button otaNextButton;
+        public ToggleButton otaSpeakerButton;
+        public ViewGroup otaUpperWidgets;
+        public View callCardOtaButtonsFailSuccess;
+        public ProgressBar otaTextProgressBar;
+        public TextView otaTextSuccessFail;
+        public View callCardOtaButtonsActivate;
+        public View callCardOtaButtonsListenProgress;
+        public TextView otaTextActivate;
+        public TextView otaTextListenProgress;
+        public AlertDialog spcErrorDialog;
+        public AlertDialog otaFailureDialog;
+        public AlertDialog otaSkipConfirmationDialog;
+        public TextView otaTitle;
+        public DTMFTwelveKeyDialerView otaDtmfDialerView;
+        public Button otaTryAgainButton;
+    }
+
+    /**
+     * OtaUtils constructor.
+     *
+     * @param context the Context of the calling Activity or Application
+     * @param interactive if true, use the InCallScreen to display the progress
+     *                    and result of the OTASP call.  In practice this is
+     *                    true IFF the current device is a voice-capable phone.
+     *
+     * Note if interactive is true, you must also call updateUiWidgets() as soon
+     * as the InCallScreen instance is ready.
+     */
+    public OtaUtils(Context context, boolean interactive) {
+        if (DBG) log("OtaUtils constructor...");
+        mApplication = PhoneGlobals.getInstance();
+        mContext = context;
+        mInteractive = interactive;
+    }
+
+    /**
+     * 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.
+     *
+     * @param context
+     * @param handler
+     * @param request
+     * @return true if we were able to launch Ota activity or it's not required; false otherwise
+     */
+    public static boolean maybeDoOtaCall(Context context, Handler handler, int request) {
+        PhoneGlobals app = PhoneGlobals.getInstance();
+        Phone phone = app.phone;
+
+        if (ActivityManager.isRunningInTestHarness()) {
+            Log.i(LOG_TAG, "Don't run provisioning when in test harness");
+            return true;
+        }
+
+        if (!TelephonyCapabilities.supportsOtasp(phone)) {
+            // Presumably not a CDMA phone.
+            if (DBG) log("maybeDoOtaCall: OTASP not supported on this device");
+            return true;  // Nothing to do here.
+        }
+
+        if (!phone.isMinInfoReady()) {
+            if (DBG) log("MIN is not ready. Registering to receive notification.");
+            phone.registerForSubscriptionInfoReady(handler, request, null);
+            return false;
+        }
+        phone.unregisterForSubscriptionInfoReady(handler);
+
+        if (getLteOnCdmaMode(context) == PhoneConstants.LTE_ON_CDMA_UNKNOWN) {
+            if (sOtaCallLteRetries < OTA_CALL_LTE_RETRIES_MAX) {
+                if (DBG) log("maybeDoOtaCall: LTE state still unknown: retrying");
+                handler.sendEmptyMessageDelayed(request, OTA_CALL_LTE_RETRY_PERIOD);
+                sOtaCallLteRetries++;
+                return false;
+            } else {
+                Log.w(LOG_TAG, "maybeDoOtaCall: LTE state still unknown: giving up");
+                return true;
+            }
+        }
+
+        boolean phoneNeedsActivation = phone.needsOtaServiceProvisioning();
+        if (DBG) log("phoneNeedsActivation is set to " + phoneNeedsActivation);
+
+        int otaShowActivationScreen = context.getResources().getInteger(
+                R.integer.OtaShowActivationScreen);
+        if (DBG) log("otaShowActivationScreen: " + otaShowActivationScreen);
+
+        // Run the OTASP call in "interactive" mode only if
+        // this is a non-LTE "voice capable" device.
+        if (PhoneGlobals.sVoiceCapable && getLteOnCdmaMode(context) == PhoneConstants.LTE_ON_CDMA_FALSE) {
+            if (phoneNeedsActivation
+                    && (otaShowActivationScreen == OTA_SHOW_ACTIVATION_SCREEN_ON)) {
+                app.cdmaOtaProvisionData.isOtaCallIntentProcessed = false;
+                sIsWizardMode = false;
+
+                if (DBG) Log.d(LOG_TAG, "==> Starting interactive CDMA provisioning...");
+                OtaUtils.startInteractiveOtasp(context);
+
+                if (DBG) log("maybeDoOtaCall: voice capable; activation started.");
+            } else {
+                if (DBG) log("maybeDoOtaCall: voice capable; activation NOT started.");
+            }
+        } else {
+            if (phoneNeedsActivation) {
+                app.cdmaOtaProvisionData.isOtaCallIntentProcessed = false;
+                Intent newIntent = new Intent(ACTION_PERFORM_VOICELESS_CDMA_PROVISIONING);
+                newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                newIntent.putExtra(EXTRA_VOICELESS_PROVISIONING_OFFER_DONTSHOW, true);
+                try {
+                    context.startActivity(newIntent);
+                } catch (ActivityNotFoundException e) {
+                    loge("No activity Handling PERFORM_VOICELESS_CDMA_PROVISIONING!");
+                    return false;
+                }
+                if (DBG) log("maybeDoOtaCall: non-interactive; activation intent sent.");
+            } else {
+                if (DBG) log("maybeDoOtaCall: non-interactive, no need for OTASP.");
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Starts a normal "interactive" OTASP call (i.e. CDMA activation
+     * for regular voice-capable phone devices.)
+     *
+     * This method is called from the InCallScreenShowActivation activity when
+     * handling the ACTION_PERFORM_CDMA_PROVISIONING intent.
+     */
+    public static void startInteractiveOtasp(Context context) {
+        if (DBG) log("startInteractiveOtasp()...");
+        PhoneGlobals app = PhoneGlobals.getInstance();
+
+        // There are two ways to start OTASP on voice-capable devices:
+        //
+        // (1) via the PERFORM_CDMA_PROVISIONING intent
+        //     - this is triggered by the "Activate device" button in settings,
+        //       or can be launched automatically upon boot if the device
+        //       thinks it needs to be provisioned.
+        //     - the intent is handled by InCallScreenShowActivation.onCreate(),
+        //       which calls this method
+        //     - we prepare for OTASP by initializing the OtaUtils object
+        //     - we bring up the InCallScreen in the ready-to-activate state
+        //     - when the user presses the "Activate" button we launch the
+        //       call by calling CallController.placeCall() via the
+        //       otaPerformActivation() method.
+        //
+        // (2) by manually making an outgoing call to a special OTASP number
+        //     like "*228" or "*22899".
+        //     - That sequence does NOT involve this method (OtaUtils.startInteractiveOtasp()).
+        //       Instead, the outgoing call request goes straight to CallController.placeCall().
+        //     - CallController.placeCall() notices that it's an OTASP
+        //       call, and initializes the OtaUtils object.
+        //     - The InCallScreen is launched (as the last step of
+        //       CallController.placeCall()).  The InCallScreen notices that
+        //       OTASP is active and shows the correct UI.
+
+        // Here, we start sequence (1):
+        // Do NOT immediately start the call.  Instead, bring up the InCallScreen
+        // in the special "activate" state (see OtaUtils.otaShowActivateScreen()).
+        // We won't actually make the call until the user presses the "Activate"
+        // button.
+
+        Intent activationScreenIntent = new Intent().setClass(context, InCallScreen.class)
+                .setAction(ACTION_DISPLAY_ACTIVATION_SCREEN);
+
+        // Watch out: in the scenario where OTASP gets triggered from the
+        // BOOT_COMPLETED broadcast (see OtaStartupReceiver.java), we might be
+        // running in the PhoneApp's context right now.
+        // So the FLAG_ACTIVITY_NEW_TASK flag is required here.
+        activationScreenIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+        // We're about to start the OTASP sequence, so create and initialize the
+        // OtaUtils instance.  (This needs to happen before bringing up the
+        // InCallScreen.)
+        OtaUtils.setupOtaspCall(activationScreenIntent);
+
+        // And bring up the InCallScreen...
+        Log.i(LOG_TAG, "startInteractiveOtasp: launching InCallScreen in 'activate' state: "
+              + activationScreenIntent);
+        context.startActivity(activationScreenIntent);
+    }
+
+    /**
+     * Starts the OTASP call *without* involving the InCallScreen or
+     * displaying any UI.
+     *
+     * This is used on data-only devices, which don't support any kind of
+     * in-call phone UI.
+     *
+     * @return PhoneUtils.CALL_STATUS_DIALED if we successfully
+     *         dialed the OTASP number, or one of the other
+     *         CALL_STATUS_* constants if there was a failure.
+     */
+    public static int startNonInteractiveOtasp(Context context) {
+        if (DBG) log("startNonInteractiveOtasp()...");
+        PhoneGlobals app = PhoneGlobals.getInstance();
+
+        if (app.otaUtils != null) {
+            // An OtaUtils instance already exists, presumably from a previous OTASP call.
+            Log.i(LOG_TAG, "startNonInteractiveOtasp: "
+                  + "OtaUtils already exists; nuking the old one and starting again...");
+        }
+
+        // Create the OtaUtils instance.
+        app.otaUtils = new OtaUtils(context, false /* non-interactive mode */);
+        if (DBG) log("- created OtaUtils: " + app.otaUtils);
+
+        // ... and kick off the OTASP call.
+        // TODO(InCallScreen redesign): This should probably go through
+        // the CallController, rather than directly calling
+        // PhoneUtils.placeCall().
+        Phone phone = PhoneGlobals.getPhone();
+        String number = OTASP_NUMBER_NON_INTERACTIVE;
+        Log.i(LOG_TAG, "startNonInteractiveOtasp: placing call to '" + number + "'...");
+        int callStatus = PhoneUtils.placeCall(context,
+                                              phone,
+                                              number,
+                                              null,  // contactRef
+                                              false,  //isEmergencyCall
+                                              null);  // gatewayUri
+
+        if (callStatus == PhoneUtils.CALL_STATUS_DIALED) {
+            if (DBG) log("  ==> successful return from placeCall(): callStatus = " + callStatus);
+        } else {
+            Log.w(LOG_TAG, "Failure from placeCall() for OTA number '"
+                  + number + "': code " + callStatus);
+            return callStatus;
+        }
+
+        // TODO: Any other special work to do here?
+        // Such as:
+        //
+        // - manually kick off progress updates, either using TelephonyRegistry
+        //   or else by sending PendingIntents directly to our caller?
+        //
+        // - manually silence the in-call audio?  (Probably unnecessary
+        //   if Stingray truly has no audio path from phone baseband
+        //   to the device's speakers.)
+        //
+
+        return callStatus;
+    }
+
+    /**
+     * @return true if the specified Intent is a CALL action that's an attempt
+     * to initate an OTASP call.
+     *
+     * OTASP is a CDMA-specific concept, so this method will always return false
+     * on GSM phones.
+     *
+     * This code was originally part of the InCallScreen.checkIsOtaCall() method.
+     */
+    public static boolean isOtaspCallIntent(Intent intent) {
+        if (DBG) log("isOtaspCallIntent(" + intent + ")...");
+        PhoneGlobals app = PhoneGlobals.getInstance();
+        Phone phone = app.mCM.getDefaultPhone();
+
+        if (intent == null) {
+            return false;
+        }
+        if (!TelephonyCapabilities.supportsOtasp(phone)) {
+            return false;
+        }
+
+        String action = intent.getAction();
+        if (action == null) {
+            return false;
+        }
+        if (!action.equals(Intent.ACTION_CALL)) {
+            if (DBG) log("isOtaspCallIntent: not a CALL action: '" + action + "' ==> not OTASP");
+            return false;
+        }
+
+        if ((app.cdmaOtaScreenState == null) || (app.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("isOtaspCallIntent: "
+                                            + "app.cdmaOta* objects(s) not initialized");
+        }
+
+        // This is an OTASP call iff the number we're trying to dial is one of
+        // the magic OTASP numbers.
+        String number;
+        try {
+            number = PhoneUtils.getInitialNumber(intent);
+        } catch (PhoneUtils.VoiceMailNumberMissingException ex) {
+            // This was presumably a "voicemail:" intent, so it's
+            // obviously not an OTASP number.
+            if (DBG) log("isOtaspCallIntent: VoiceMailNumberMissingException => not OTASP");
+            return false;
+        }
+        if (phone.isOtaSpNumber(number)) {
+            if (DBG) log("isOtaSpNumber: ACTION_CALL to '" + number + "' ==> OTASP call!");
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Set up for an OTASP call.
+     *
+     * This method is called as part of the CallController placeCall() sequence
+     * before initiating an outgoing OTASP call.
+     *
+     * The purpose of this method is mainly to create and initialize the
+     * OtaUtils instance, along with some other misc pre-OTASP cleanup.
+     */
+    public static void setupOtaspCall(Intent intent) {
+        if (DBG) log("setupOtaspCall(): preparing for OTASP call to " + intent);
+        PhoneGlobals app = PhoneGlobals.getInstance();
+
+        if (app.otaUtils != null) {
+            // An OtaUtils instance already exists, presumably from a prior OTASP call.
+            // Nuke the old one and start this call with a fresh instance.
+            Log.i(LOG_TAG, "setupOtaspCall: "
+                  + "OtaUtils already exists; replacing with new instance...");
+        }
+
+        // Create the OtaUtils instance.
+        app.otaUtils = new OtaUtils(app.getApplicationContext(), true /* interactive */);
+        if (DBG) log("- created OtaUtils: " + app.otaUtils);
+
+        // NOTE we still need to call OtaUtils.updateUiWidgets() once the
+        // InCallScreen instance is ready; see InCallScreen.checkOtaspStateOnResume()
+
+        // Make sure the InCallScreen knows that it needs to switch into OTASP mode.
+        //
+        // NOTE in gingerbread and earlier, we used to do
+        //     setInCallScreenMode(InCallScreenMode.OTA_NORMAL);
+        // directly in the InCallScreen, back when this check happened inside the InCallScreen.
+        //
+        // But now, set the global CdmaOtaInCallScreenUiState object into
+        // NORMAL mode, which will then cause the InCallScreen (when it
+        // comes up) to realize that an OTA call is active.
+
+        app.otaUtils.setCdmaOtaInCallScreenUiState(
+            OtaUtils.CdmaOtaInCallScreenUiState.State.NORMAL);
+
+        // TODO(OTASP): note app.inCallUiState.inCallScreenMode and
+        // app.cdmaOtaInCallScreenUiState.state are mostly redundant.  Combine them.
+        app.inCallUiState.inCallScreenMode = InCallUiState.InCallScreenMode.OTA_NORMAL;
+
+        // TODO(OTASP / bug 5092031): we ideally should call
+        // otaShowListeningScreen() here to make sure that the DTMF dialpad
+        // becomes visible at the start of the "*228" call:
+        //
+        //  // ...and get the OTASP-specific UI into the right state.
+        //  app.otaUtils.otaShowListeningScreen();
+        //  if (app.otaUtils.mInCallScreen != null) {
+        //      app.otaUtils.mInCallScreen.requestUpdateScreen();
+        //  }
+        //
+        // But this doesn't actually work; the call to otaShowListeningScreen()
+        // *doesn't* actually bring up the listening screen, since the
+        // cdmaOtaConfigData.otaShowListeningScreen config parameter hasn't been
+        // initialized (we haven't run readXmlSettings() yet at this point!)
+
+        // Also, since the OTA call is now just starting, clear out
+        // the "committed" flag in app.cdmaOtaProvisionData.
+        if (app.cdmaOtaProvisionData != null) {
+            app.cdmaOtaProvisionData.isOtaCallCommitted = false;
+        }
+    }
+
+    private void setSpeaker(boolean state) {
+        if (DBG) log("setSpeaker : " + state );
+
+        if (!mInteractive) {
+            if (DBG) log("non-interactive mode, ignoring setSpeaker.");
+            return;
+        }
+
+        if (state == PhoneUtils.isSpeakerOn(mContext)) {
+            if (DBG) log("no change. returning");
+            return;
+        }
+
+        if (state && mInCallScreen.isBluetoothAvailable()
+                && mInCallScreen.isBluetoothAudioConnected()) {
+            mInCallScreen.disconnectBluetoothAudio();
+        }
+        PhoneUtils.turnOnSpeaker(mContext, state, true);
+    }
+
+    /**
+     * Handles OTA Provision events from the telephony layer.
+     * These events come in to this method whether or not
+     * the InCallScreen is visible.
+     *
+     * Possible events are:
+     * OTA Commit Event - OTA provisioning was successful
+     * SPC retries exceeded - SPC failure retries has exceeded, and Phone needs to
+     *    power down.
+     */
+    public void onOtaProvisionStatusChanged(AsyncResult r) {
+        int OtaStatus[] = (int[]) r.result;
+        if (DBG) log("Provision status event!");
+        if (DBG) log("onOtaProvisionStatusChanged(): status = "
+                     + OtaStatus[0] + " ==> " + otaProvisionStatusToString(OtaStatus[0]));
+
+        // In practice, in a normal successful OTASP call, events come in as follows:
+        //   - SPL_UNLOCKED within a couple of seconds after the call starts
+        //   - then a delay of around 45 seconds
+        //   - then PRL_DOWNLOADED and MDN_DOWNLOADED and COMMITTED within a span of 2 seconds
+
+        switch(OtaStatus[0]) {
+            case Phone.CDMA_OTA_PROVISION_STATUS_SPC_RETRIES_EXCEEDED:
+                if (DBG) log("onOtaProvisionStatusChanged(): RETRIES EXCEEDED");
+                updateOtaspProgress();
+                mApplication.cdmaOtaProvisionData.otaSpcUptime = SystemClock.elapsedRealtime();
+                if (mInteractive) {
+                    otaShowSpcErrorNotice(OTA_SPC_TIMEOUT);
+                } else {
+                    sendOtaspResult(OTASP_FAILURE_SPC_RETRIES);
+                }
+                // Power.shutdown();
+                break;
+
+            case Phone.CDMA_OTA_PROVISION_STATUS_COMMITTED:
+                if (DBG) {
+                    log("onOtaProvisionStatusChanged(): DONE, isOtaCallCommitted set to true");
+                }
+                mApplication.cdmaOtaProvisionData.isOtaCallCommitted = true;
+                if (mApplication.cdmaOtaScreenState.otaScreenState !=
+                    CdmaOtaScreenState.OtaScreenState.OTA_STATUS_UNDEFINED) {
+                    updateOtaspProgress();
+                }
+
+                break;
+
+            case Phone.CDMA_OTA_PROVISION_STATUS_SPL_UNLOCKED:
+            case Phone.CDMA_OTA_PROVISION_STATUS_A_KEY_EXCHANGED:
+            case Phone.CDMA_OTA_PROVISION_STATUS_SSD_UPDATED:
+            case Phone.CDMA_OTA_PROVISION_STATUS_NAM_DOWNLOADED:
+            case Phone.CDMA_OTA_PROVISION_STATUS_MDN_DOWNLOADED:
+            case Phone.CDMA_OTA_PROVISION_STATUS_IMSI_DOWNLOADED:
+            case Phone.CDMA_OTA_PROVISION_STATUS_PRL_DOWNLOADED:
+            case Phone.CDMA_OTA_PROVISION_STATUS_OTAPA_STARTED:
+            case Phone.CDMA_OTA_PROVISION_STATUS_OTAPA_STOPPED:
+            case Phone.CDMA_OTA_PROVISION_STATUS_OTAPA_ABORTED:
+                // Only update progress when OTA call is in normal state
+                if (getCdmaOtaInCallScreenUiState() == CdmaOtaInCallScreenUiState.State.NORMAL) {
+                    if (DBG) log("onOtaProvisionStatusChanged(): change to ProgressScreen");
+                    updateOtaspProgress();
+                }
+                break;
+
+            default:
+                if (DBG) log("onOtaProvisionStatusChanged(): Ignoring OtaStatus " + OtaStatus[0]);
+                break;
+        }
+    }
+
+    /**
+     * Handle a disconnect event from the OTASP call.
+     */
+    public void onOtaspDisconnect() {
+        if (DBG) log("onOtaspDisconnect()...");
+        // We only handle this event explicitly in non-interactive mode.
+        // (In interactive mode, the InCallScreen does any post-disconnect
+        // cleanup.)
+        if (!mInteractive) {
+            // Send a success or failure indication back to our caller.
+            updateNonInteractiveOtaSuccessFailure();
+        }
+    }
+
+    private void otaShowHome() {
+        if (DBG) log("otaShowHome()...");
+        mApplication.cdmaOtaScreenState.otaScreenState =
+                CdmaOtaScreenState.OtaScreenState.OTA_STATUS_UNDEFINED;
+        mInCallScreen.endInCallScreenSession();
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.addCategory (Intent.CATEGORY_HOME);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mContext.startActivityAsUser(intent, UserHandle.CURRENT);
+        return;
+    }
+
+    private void otaSkipActivation() {
+        if (DBG) log("otaSkipActivation()...");
+
+        sendOtaspResult(OTASP_USER_SKIPPED);
+
+        if (mInteractive) mInCallScreen.finish();
+        return;
+    }
+
+    /**
+     * Actually initiate the OTASP call.  This method is triggered by the
+     * onscreen "Activate" button, and is only used in interactive mode.
+     */
+    private void otaPerformActivation() {
+        if (DBG) log("otaPerformActivation()...");
+        if (!mInteractive) {
+            // We shouldn't ever get here in non-interactive mode!
+            Log.w(LOG_TAG, "otaPerformActivation: not interactive!");
+            return;
+        }
+
+        if (!mApplication.cdmaOtaProvisionData.inOtaSpcState) {
+            // Place an outgoing call to the special OTASP number:
+            Intent newIntent = new Intent(Intent.ACTION_CALL);
+            newIntent.setData(Uri.fromParts(Constants.SCHEME_TEL, OTASP_NUMBER, null));
+
+            // Initiate the outgoing call:
+            mApplication.callController.placeCall(newIntent);
+
+            // ...and get the OTASP-specific UI into the right state.
+            otaShowListeningScreen();
+            mInCallScreen.requestUpdateScreen();
+        }
+        return;
+    }
+
+    /**
+     * Show Activation Screen when phone powers up and OTA provision is
+     * required. Also shown when activation fails and user needs
+     * to re-attempt it. Contains ACTIVATE and SKIP buttons
+     * which allow user to start OTA activation or skip the activation process.
+     */
+    public void otaShowActivateScreen() {
+        if (DBG) log("otaShowActivateScreen()...");
+        if (mApplication.cdmaOtaConfigData.otaShowActivationScreen
+                == OTA_SHOW_ACTIVATION_SCREEN_ON) {
+            if (DBG) log("otaShowActivateScreen(): show activation screen");
+            if (!isDialerOpened()) {
+                otaScreenInitialize();
+                mOtaWidgetData.otaSkipButton.setVisibility(sIsWizardMode ?
+                        View.VISIBLE : View.INVISIBLE);
+                mOtaWidgetData.otaTextActivate.setVisibility(View.VISIBLE);
+                mOtaWidgetData.callCardOtaButtonsActivate.setVisibility(View.VISIBLE);
+            }
+            mApplication.cdmaOtaScreenState.otaScreenState =
+                    CdmaOtaScreenState.OtaScreenState.OTA_STATUS_ACTIVATION;
+        } else {
+            if (DBG) log("otaShowActivateScreen(): show home screen");
+            otaShowHome();
+        }
+     }
+
+    /**
+     * Show "Listen for Instruction" screen during OTA call. Shown when OTA Call
+     * is initiated and user needs to listen for network instructions and press
+     * appropriate DTMF digits to proceed to the "Programming in Progress" phase.
+     */
+    private void otaShowListeningScreen() {
+        if (DBG) log("otaShowListeningScreen()...");
+        if (!mInteractive) {
+            // We shouldn't ever get here in non-interactive mode!
+            Log.w(LOG_TAG, "otaShowListeningScreen: not interactive!");
+            return;
+        }
+
+        if (mApplication.cdmaOtaConfigData.otaShowListeningScreen
+                == OTA_SHOW_LISTENING_SCREEN_ON) {
+            if (DBG) log("otaShowListeningScreen(): show listening screen");
+            if (!isDialerOpened()) {
+                otaScreenInitialize();
+                mOtaWidgetData.otaTextListenProgress.setVisibility(View.VISIBLE);
+                mOtaWidgetData.otaTextListenProgress.setText(R.string.ota_listen);
+                mOtaWidgetData.otaDtmfDialerView.setVisibility(View.VISIBLE);
+                mOtaWidgetData.callCardOtaButtonsListenProgress.setVisibility(View.VISIBLE);
+                mOtaWidgetData.otaSpeakerButton.setVisibility(View.VISIBLE);
+                boolean speakerOn = PhoneUtils.isSpeakerOn(mContext);
+                mOtaWidgetData.otaSpeakerButton.setChecked(speakerOn);
+            }
+            mApplication.cdmaOtaScreenState.otaScreenState =
+                    CdmaOtaScreenState.OtaScreenState.OTA_STATUS_LISTENING;
+        } else {
+            if (DBG) log("otaShowListeningScreen(): show progress screen");
+            otaShowInProgressScreen();
+        }
+    }
+
+    /**
+     * Do any necessary updates (of onscreen UI, for example)
+     * based on the latest status of the OTASP call.
+     */
+    private void updateOtaspProgress() {
+        if (DBG) log("updateOtaspProgress()...  mInteractive = " + mInteractive);
+        if (mInteractive) {
+            // On regular phones we just call through to
+            // otaShowInProgressScreen(), which updates the
+            // InCallScreen's onscreen UI.
+            otaShowInProgressScreen();
+        } else {
+            // We're not using the InCallScreen to show OTA progress.
+
+            // For now, at least, there's nothing to do here.
+            // The overall "success" or "failure" indication we send back
+            // (to our caller) is triggered by the DISCONNECT event;
+            // see updateNonInteractiveOtaSuccessFailure().
+
+            // But if we ever need to send *intermediate* progress updates back
+            // to our caller, we'd do that here, possbily using the same
+            // PendingIntent that we already use to indicate success or failure.
+        }
+    }
+
+    /**
+     * When a non-interactive OTASP call completes, send a success or
+     * failure indication back to our caller.
+     *
+     * This is basically the non-interactive equivalent of
+     * otaShowSuccessFailure().
+     */
+    private void updateNonInteractiveOtaSuccessFailure() {
+        // This is basically the same logic as otaShowSuccessFailure(): we
+        // check the isOtaCallCommitted bit, and if that's true it means
+        // that activation was successful.
+
+        if (DBG) log("updateNonInteractiveOtaSuccessFailure(): isOtaCallCommitted = "
+                     + mApplication.cdmaOtaProvisionData.isOtaCallCommitted);
+        int resultCode =
+                mApplication.cdmaOtaProvisionData.isOtaCallCommitted
+                ? OTASP_SUCCESS : OTASP_FAILURE;
+        sendOtaspResult(resultCode);
+    }
+
+    /**
+     * Sends the specified OTASP result code back to our caller (presumably
+     * SetupWizard) via the PendingIntent that they originally sent along with
+     * the ACTION_PERFORM_CDMA_PROVISIONING intent.
+     */
+    private void sendOtaspResult(int resultCode) {
+        if (DBG) log("sendOtaspResult: resultCode = " + resultCode);
+
+        // Pass the success or failure indication back to our caller by
+        // adding an additional extra to the PendingIntent we already
+        // have.
+        // (NB: there's a PendingIntent send() method that takes a resultCode
+        // directly, but we can't use that here since that call is only
+        // meaningful for pending intents that are actually used as activity
+        // results.)
+
+        Intent extraStuff = new Intent();
+        extraStuff.putExtra(EXTRA_OTASP_RESULT_CODE, resultCode);
+        // When we call PendingIntent.send() below, the extras from this
+        // intent will get merged with any extras already present in
+        // cdmaOtaScreenState.otaspResultCodePendingIntent.
+
+        if (mApplication.cdmaOtaScreenState == null) {
+            Log.e(LOG_TAG, "updateNonInteractiveOtaSuccessFailure: no cdmaOtaScreenState object!");
+            return;
+        }
+        if (mApplication.cdmaOtaScreenState.otaspResultCodePendingIntent == null) {
+            Log.w(LOG_TAG, "updateNonInteractiveOtaSuccessFailure: "
+                  + "null otaspResultCodePendingIntent!");
+            return;
+        }
+
+        try {
+            if (DBG) log("- sendOtaspResult:  SENDING PENDING INTENT: " +
+                         mApplication.cdmaOtaScreenState.otaspResultCodePendingIntent);
+            mApplication.cdmaOtaScreenState.otaspResultCodePendingIntent.send(
+                    mContext,
+                    0, /* resultCode (unused) */
+                    extraStuff);
+        } catch (CanceledException e) {
+            // should never happen because no code cancels the pending intent right now,
+            Log.e(LOG_TAG, "PendingIntent send() failed: " + e);
+        }
+    }
+
+    /**
+     * Show "Programming In Progress" screen during OTA call. Shown when OTA
+     * provisioning is in progress after user has selected an option.
+     */
+    private void otaShowInProgressScreen() {
+        if (DBG) log("otaShowInProgressScreen()...");
+        if (!mInteractive) {
+            // We shouldn't ever get here in non-interactive mode!
+            Log.w(LOG_TAG, "otaShowInProgressScreen: not interactive!");
+            return;
+        }
+
+        mApplication.cdmaOtaScreenState.otaScreenState =
+            CdmaOtaScreenState.OtaScreenState.OTA_STATUS_PROGRESS;
+
+        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
+            // it to OTA_STATUS_PROGRESS.  But we still need to make sure that
+            // when the InCallScreen eventually comes to the foreground, it
+            // notices that state and does all the same UI updating we do below.
+            return;
+        }
+
+        if (!isDialerOpened()) {
+            otaScreenInitialize();
+            mOtaWidgetData.otaTextListenProgress.setVisibility(View.VISIBLE);
+            mOtaWidgetData.otaTextListenProgress.setText(R.string.ota_progress);
+            mOtaWidgetData.otaTextProgressBar.setVisibility(View.VISIBLE);
+            mOtaWidgetData.callCardOtaButtonsListenProgress.setVisibility(View.VISIBLE);
+            mOtaWidgetData.otaSpeakerButton.setVisibility(View.VISIBLE);
+            boolean speakerOn = PhoneUtils.isSpeakerOn(mContext);
+            mOtaWidgetData.otaSpeakerButton.setChecked(speakerOn);
+        }
+    }
+
+    /**
+     * Show programming failure dialog when OTA provisioning fails.
+     * If OTA provisioning attempts fail more than 3 times, then unsuccessful
+     * dialog is shown. Otherwise a two-second notice is shown with unsuccessful
+     * information. When notice expires, phone returns to activation screen.
+     */
+    private void otaShowProgramFailure(int length) {
+        if (DBG) log("otaShowProgramFailure()...");
+        mApplication.cdmaOtaProvisionData.activationCount++;
+        if ((mApplication.cdmaOtaProvisionData.activationCount <
+                mApplication.cdmaOtaConfigData.otaShowActivateFailTimes)
+                && (mApplication.cdmaOtaConfigData.otaShowActivationScreen ==
+                OTA_SHOW_ACTIVATION_SCREEN_ON)) {
+            if (DBG) log("otaShowProgramFailure(): activationCount"
+                    + mApplication.cdmaOtaProvisionData.activationCount);
+            if (DBG) log("otaShowProgramFailure(): show failure notice");
+            otaShowProgramFailureNotice(length);
+        } else {
+            if (DBG) log("otaShowProgramFailure(): show failure dialog");
+            otaShowProgramFailureDialog();
+        }
+    }
+
+    /**
+     * Show either programming success dialog when OTA provisioning succeeds, or
+     * programming failure dialog when it fails. See {@link #otaShowProgramFailure}
+     * for more details.
+     */
+    public void otaShowSuccessFailure() {
+        if (DBG) log("otaShowSuccessFailure()...");
+        if (!mInteractive) {
+            // We shouldn't ever get here in non-interactive mode!
+            Log.w(LOG_TAG, "otaShowSuccessFailure: not interactive!");
+            return;
+        }
+
+        otaScreenInitialize();
+        if (DBG) log("otaShowSuccessFailure(): isOtaCallCommitted"
+                + mApplication.cdmaOtaProvisionData.isOtaCallCommitted);
+        if (mApplication.cdmaOtaProvisionData.isOtaCallCommitted) {
+            if (DBG) log("otaShowSuccessFailure(), show success dialog");
+            otaShowProgramSuccessDialog();
+        } else {
+            if (DBG) log("otaShowSuccessFailure(), show failure dialog");
+            otaShowProgramFailure(OTA_FAILURE_DIALOG_TIMEOUT);
+        }
+        return;
+    }
+
+    /**
+     * Show programming failure dialog when OTA provisioning fails more than 3
+     * times.
+     */
+    private void otaShowProgramFailureDialog() {
+        if (DBG) log("otaShowProgramFailureDialog()...");
+        mApplication.cdmaOtaScreenState.otaScreenState =
+                CdmaOtaScreenState.OtaScreenState.OTA_STATUS_SUCCESS_FAILURE_DLG;
+        mOtaWidgetData.otaTitle.setText(R.string.ota_title_problem_with_activation);
+        mOtaWidgetData.otaTextSuccessFail.setVisibility(View.VISIBLE);
+        mOtaWidgetData.otaTextSuccessFail.setText(R.string.ota_unsuccessful);
+        mOtaWidgetData.callCardOtaButtonsFailSuccess.setVisibility(View.VISIBLE);
+        mOtaWidgetData.otaTryAgainButton.setVisibility(View.VISIBLE);
+        //close the dialer if open
+        if (isDialerOpened()) {
+            mOtaCallCardDtmfDialer.closeDialer(false);
+        }
+    }
+
+    /**
+     * Show programming success dialog when OTA provisioning succeeds.
+     */
+    private void otaShowProgramSuccessDialog() {
+        if (DBG) log("otaShowProgramSuccessDialog()...");
+        mApplication.cdmaOtaScreenState.otaScreenState =
+                CdmaOtaScreenState.OtaScreenState.OTA_STATUS_SUCCESS_FAILURE_DLG;
+        mOtaWidgetData.otaTitle.setText(R.string.ota_title_activate_success);
+        mOtaWidgetData.otaTextSuccessFail.setVisibility(View.VISIBLE);
+        mOtaWidgetData.otaTextSuccessFail.setText(R.string.ota_successful);
+        mOtaWidgetData.callCardOtaButtonsFailSuccess.setVisibility(View.VISIBLE);
+        mOtaWidgetData.otaNextButton.setVisibility(View.VISIBLE);
+        //close the dialer if open
+        if (isDialerOpened()) {
+            mOtaCallCardDtmfDialer.closeDialer(false);
+        }
+    }
+
+    /**
+     * Show SPC failure notice when SPC attempts exceed 15 times.
+     * During OTA provisioning, if SPC code is incorrect OTA provisioning will
+     * fail. When SPC attempts are over 15, it shows SPC failure notice for one minute and
+     * then phone will power down.
+     */
+    private void otaShowSpcErrorNotice(int length) {
+        if (DBG) log("otaShowSpcErrorNotice()...");
+        if (mOtaWidgetData.spcErrorDialog == null) {
+            mApplication.cdmaOtaProvisionData.inOtaSpcState = true;
+            DialogInterface.OnKeyListener keyListener;
+            keyListener = new DialogInterface.OnKeyListener() {
+                public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
+                    log("Ignoring key events...");
+                    return true;
+                }};
+            mOtaWidgetData.spcErrorDialog = new AlertDialog.Builder(mInCallScreen)
+                    .setMessage(R.string.ota_spc_failure)
+                    .setOnKeyListener(keyListener)
+                    .create();
+            mOtaWidgetData.spcErrorDialog.getWindow().addFlags(
+                    WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
+                    | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+            mOtaWidgetData.spcErrorDialog.show();
+            //close the dialer if open
+            if (isDialerOpened()) {
+                mOtaCallCardDtmfDialer.closeDialer(false);
+            }
+            long noticeTime = length*1000;
+            if (DBG) log("otaShowSpcErrorNotice(), remaining SPC noticeTime" + noticeTime);
+            mInCallScreen.requestCloseSpcErrorNotice(noticeTime);
+        }
+    }
+
+    /**
+     * When SPC notice times out, force phone to power down.
+     */
+    public void onOtaCloseSpcNotice() {
+        if (DBG) log("onOtaCloseSpcNotice(), send shutdown intent");
+        Intent shutdown = new Intent(Intent.ACTION_REQUEST_SHUTDOWN);
+        shutdown.putExtra(Intent.EXTRA_KEY_CONFIRM, false);
+        shutdown.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mContext.startActivity(shutdown);
+    }
+
+    /**
+     * Show two-second notice when OTA provisioning fails and number of failed attempts
+     * is less then 3.
+     */
+    private void otaShowProgramFailureNotice(int length) {
+        if (DBG) log("otaShowProgramFailureNotice()...");
+        if (mOtaWidgetData.otaFailureDialog == null) {
+            mOtaWidgetData.otaFailureDialog = new AlertDialog.Builder(mInCallScreen)
+                    .setMessage(R.string.ota_failure)
+                    .create();
+            mOtaWidgetData.otaFailureDialog.getWindow().addFlags(
+                    WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
+                    | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+            mOtaWidgetData.otaFailureDialog.show();
+
+            long noticeTime = length*1000;
+            mInCallScreen.requestCloseOtaFailureNotice(noticeTime);
+        }
+    }
+
+    /**
+     * Handle OTA unsuccessful notice expiry. Dismisses the
+     * two-second notice and shows the activation screen.
+     */
+    public void onOtaCloseFailureNotice() {
+        if (DBG) log("onOtaCloseFailureNotice()...");
+        if (mOtaWidgetData.otaFailureDialog != null) {
+            mOtaWidgetData.otaFailureDialog.dismiss();
+            mOtaWidgetData.otaFailureDialog = null;
+        }
+        otaShowActivateScreen();
+    }
+
+    /**
+     * Initialize all OTA UI elements to be gone. Also set inCallPanel,
+     * callCard and the dialpad handle to be gone. This is called before any OTA screen
+     * gets drawn.
+     */
+    private void otaScreenInitialize() {
+        if (DBG) log("otaScreenInitialize()...");
+
+        if (!mInteractive) {
+            // We should never be doing anything with UI elements in
+            // non-interactive mode.
+            Log.w(LOG_TAG, "otaScreenInitialize: not interactive!");
+            return;
+        }
+
+        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);
+        mOtaWidgetData.otaTextListenProgress.setVisibility(View.GONE);
+        mOtaWidgetData.otaTextProgressBar.setVisibility(View.GONE);
+        mOtaWidgetData.otaTextSuccessFail.setVisibility(View.GONE);
+        mOtaWidgetData.callCardOtaButtonsActivate.setVisibility(View.GONE);
+        mOtaWidgetData.callCardOtaButtonsListenProgress.setVisibility(View.GONE);
+        mOtaWidgetData.callCardOtaButtonsFailSuccess.setVisibility(View.GONE);
+        mOtaWidgetData.otaDtmfDialerView.setVisibility(View.GONE);
+        mOtaWidgetData.otaSpeakerButton.setVisibility(View.GONE);
+        mOtaWidgetData.otaTryAgainButton.setVisibility(View.GONE);
+        mOtaWidgetData.otaNextButton.setVisibility(View.GONE);
+        mOtaWidgetData.otaUpperWidgets.setVisibility(View.VISIBLE);
+        mOtaWidgetData.otaSkipButton.setVisibility(View.VISIBLE);
+    }
+
+    public void hideOtaScreen() {
+        if (DBG) log("hideOtaScreen()...");
+
+        mOtaWidgetData.callCardOtaButtonsActivate.setVisibility(View.GONE);
+        mOtaWidgetData.callCardOtaButtonsListenProgress.setVisibility(View.GONE);
+        mOtaWidgetData.callCardOtaButtonsFailSuccess.setVisibility(View.GONE);
+        mOtaWidgetData.otaUpperWidgets.setVisibility(View.GONE);
+    }
+
+    public boolean isDialerOpened() {
+        boolean retval = (mOtaCallCardDtmfDialer != null && mOtaCallCardDtmfDialer.isOpened());
+        if (DBG) log("- isDialerOpened() ==> " + retval);
+        return retval;
+    }
+
+    /**
+     * Show the appropriate OTA screen based on the current state of OTA call.
+     *
+     * This is called from the InCallScreen when the screen needs to be
+     * refreshed (and thus is only ever used in interactive mode.)
+     *
+     * Since this is called as part of the InCallScreen.updateScreen() sequence,
+     * this method does *not* post an mInCallScreen.requestUpdateScreen()
+     * request.
+     */
+    public void otaShowProperScreen() {
+        if (DBG) log("otaShowProperScreen()...");
+        if (!mInteractive) {
+            // We shouldn't ever get here in non-interactive mode!
+            Log.w(LOG_TAG, "otaShowProperScreen: not interactive!");
+            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 (mApplication.cdmaOtaProvisionData.inOtaSpcState) {
+                otaShowSpcErrorNotice(getOtaSpcDisplayTime());
+            }
+        }
+    }
+
+    /**
+     * Read configuration values for each OTA screen from config.xml.
+     * These configuration values control visibility of each screen.
+     */
+    private void readXmlSettings() {
+        if (DBG) log("readXmlSettings()...");
+        if (mApplication.cdmaOtaConfigData.configComplete) {
+            return;
+        }
+
+        mApplication.cdmaOtaConfigData.configComplete = true;
+        int tmpOtaShowActivationScreen =
+                mContext.getResources().getInteger(R.integer.OtaShowActivationScreen);
+        mApplication.cdmaOtaConfigData.otaShowActivationScreen = tmpOtaShowActivationScreen;
+        if (DBG) log("readXmlSettings(), otaShowActivationScreen = "
+                + mApplication.cdmaOtaConfigData.otaShowActivationScreen);
+
+        int tmpOtaShowListeningScreen =
+                mContext.getResources().getInteger(R.integer.OtaShowListeningScreen);
+        mApplication.cdmaOtaConfigData.otaShowListeningScreen = tmpOtaShowListeningScreen;
+        if (DBG) log("readXmlSettings(), otaShowListeningScreen = "
+                + mApplication.cdmaOtaConfigData.otaShowListeningScreen);
+
+        int tmpOtaShowActivateFailTimes =
+                mContext.getResources().getInteger(R.integer.OtaShowActivateFailTimes);
+        mApplication.cdmaOtaConfigData.otaShowActivateFailTimes = tmpOtaShowActivateFailTimes;
+        if (DBG) log("readXmlSettings(), otaShowActivateFailTimes = "
+                + mApplication.cdmaOtaConfigData.otaShowActivateFailTimes);
+
+        int tmpOtaPlaySuccessFailureTone =
+                mContext.getResources().getInteger(R.integer.OtaPlaySuccessFailureTone);
+        mApplication.cdmaOtaConfigData.otaPlaySuccessFailureTone = tmpOtaPlaySuccessFailureTone;
+        if (DBG) log("readXmlSettings(), otaPlaySuccessFailureTone = "
+                + mApplication.cdmaOtaConfigData.otaPlaySuccessFailureTone);
+    }
+
+    /**
+     * Handle the click events for OTA buttons.
+     */
+    public void onClickHandler(int id) {
+        switch (id) {
+            case R.id.otaEndButton:
+                onClickOtaEndButton();
+                break;
+
+            case R.id.otaSpeakerButton:
+                onClickOtaSpeakerButton();
+                break;
+
+            case R.id.otaActivateButton:
+                onClickOtaActivateButton();
+                break;
+
+            case R.id.otaSkipButton:
+                onClickOtaActivateSkipButton();
+                break;
+
+            case R.id.otaNextButton:
+                onClickOtaActivateNextButton();
+                break;
+
+            case R.id.otaTryAgainButton:
+                onClickOtaTryAgainButton();
+                break;
+
+            default:
+                if (DBG) log ("onClickHandler: received a click event for unrecognized id");
+                break;
+        }
+    }
+
+    private void onClickOtaTryAgainButton() {
+        if (DBG) log("Activation Try Again Clicked!");
+        if (!mApplication.cdmaOtaProvisionData.inOtaSpcState) {
+            otaShowActivateScreen();
+        }
+    }
+
+    private void onClickOtaEndButton() {
+        if (DBG) log("Activation End Call Button Clicked!");
+        if (!mApplication.cdmaOtaProvisionData.inOtaSpcState) {
+            if (PhoneUtils.hangup(mApplication.mCM) == false) {
+                // If something went wrong when placing the OTA call,
+                // the screen is not updated by the call disconnect
+                // handler and we have to do it here
+                setSpeaker(false);
+                mInCallScreen.handleOtaCallEnd();
+            }
+        }
+    }
+
+    private void onClickOtaSpeakerButton() {
+        if (DBG) log("OTA Speaker button Clicked!");
+        if (!mApplication.cdmaOtaProvisionData.inOtaSpcState) {
+            boolean isChecked = !PhoneUtils.isSpeakerOn(mContext);
+            setSpeaker(isChecked);
+        }
+    }
+
+    private void onClickOtaActivateButton() {
+        if (DBG) log("Call Activation Clicked!");
+        otaPerformActivation();
+    }
+
+    private void onClickOtaActivateSkipButton() {
+        if (DBG) log("Activation Skip Clicked!");
+        DialogInterface.OnKeyListener keyListener;
+        keyListener = new DialogInterface.OnKeyListener() {
+            public boolean onKey(DialogInterface dialog, int keyCode,
+                    KeyEvent event) {
+                if (DBG) log("Ignoring key events...");
+                return true;
+            }
+        };
+        mOtaWidgetData.otaSkipConfirmationDialog = new AlertDialog.Builder(mInCallScreen)
+                .setTitle(R.string.ota_skip_activation_dialog_title)
+                .setMessage(R.string.ota_skip_activation_dialog_message)
+                .setPositiveButton(
+                    android.R.string.ok,
+                    // "OK" means "skip activation".
+                    new AlertDialog.OnClickListener() {
+                        public void onClick(DialogInterface dialog, int which) {
+                            otaSkipActivation();
+                        }
+                    })
+                .setNegativeButton(
+                    android.R.string.cancel,
+                    // "Cancel" means just dismiss the dialog.
+                    // Don't actually start an activation call.
+                    null)
+                .setOnKeyListener(keyListener)
+                .create();
+        mOtaWidgetData.otaSkipConfirmationDialog.show();
+    }
+
+    private void onClickOtaActivateNextButton() {
+        if (DBG) log("Dialog Next Clicked!");
+        if (!mApplication.cdmaOtaProvisionData.inOtaSpcState) {
+            mApplication.cdmaOtaScreenState.otaScreenState =
+                    CdmaOtaScreenState.OtaScreenState.OTA_STATUS_UNDEFINED;
+            otaShowHome();
+        }
+    }
+
+    public void dismissAllOtaDialogs() {
+        if (mOtaWidgetData != null) {
+            if (mOtaWidgetData.spcErrorDialog != null) {
+                if (DBG) log("- DISMISSING mSpcErrorDialog.");
+                mOtaWidgetData.spcErrorDialog.dismiss();
+                mOtaWidgetData.spcErrorDialog = null;
+            }
+            if (mOtaWidgetData.otaFailureDialog != null) {
+                if (DBG) log("- DISMISSING mOtaFailureDialog.");
+                mOtaWidgetData.otaFailureDialog.dismiss();
+                mOtaWidgetData.otaFailureDialog = null;
+            }
+        }
+    }
+
+    private int getOtaSpcDisplayTime() {
+        if (DBG) log("getOtaSpcDisplayTime()...");
+        int tmpSpcTime = 1;
+        if (mApplication.cdmaOtaProvisionData.inOtaSpcState) {
+            long tmpOtaSpcRunningTime = 0;
+            long tmpOtaSpcLeftTime = 0;
+            tmpOtaSpcRunningTime = SystemClock.elapsedRealtime();
+            tmpOtaSpcLeftTime =
+                tmpOtaSpcRunningTime - mApplication.cdmaOtaProvisionData.otaSpcUptime;
+            if (tmpOtaSpcLeftTime >= OTA_SPC_TIMEOUT*1000) {
+                tmpSpcTime = 1;
+            } else {
+                tmpSpcTime = OTA_SPC_TIMEOUT - (int)tmpOtaSpcLeftTime/1000;
+            }
+        }
+        if (DBG) log("getOtaSpcDisplayTime(), time for SPC error notice: " + tmpSpcTime);
+        return tmpSpcTime;
+    }
+
+    /**
+     * Initialize the OTA widgets for all OTA screens.
+     */
+    private void initOtaInCallScreen() {
+        if (DBG) log("initOtaInCallScreen()...");
+        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.otaTextProgressBar.setIndeterminate(true);
+        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.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);
+        // Sanity-check: the otaDtmfDialerView widget should *always* be present.
+        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);
+
+        // Initialize the new DTMFTwelveKeyDialer instance.  This is
+        // needed to play local DTMF tones.
+        mOtaCallCardDtmfDialer.startDialerSession();
+
+        mOtaWidgetData.otaDtmfDialerView.setDialer(mOtaCallCardDtmfDialer);
+    }
+
+    /**
+     * Clear out all OTA UI widget elements. Needs to get called
+     * when OTA call ends or InCallScreen is destroyed.
+     * @param disableSpeaker parameter control whether Speaker should be turned off.
+     */
+    public void cleanOtaScreen(boolean disableSpeaker) {
+        if (DBG) log("OTA ends, cleanOtaScreen!");
+
+        mApplication.cdmaOtaScreenState.otaScreenState =
+                CdmaOtaScreenState.OtaScreenState.OTA_STATUS_UNDEFINED;
+        mApplication.cdmaOtaProvisionData.isOtaCallCommitted = false;
+        mApplication.cdmaOtaProvisionData.isOtaCallIntentProcessed = false;
+        mApplication.cdmaOtaProvisionData.inOtaSpcState = false;
+        mApplication.cdmaOtaProvisionData.activationCount = 0;
+        mApplication.cdmaOtaProvisionData.otaSpcUptime = 0;
+        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();
+            }
+
+            // Free resources from the DTMFTwelveKeyDialer instance we created
+            // in initOtaInCallScreen().
+            if (mOtaCallCardDtmfDialer != null) {
+                mOtaCallCardDtmfDialer.stopDialerSession();
+            }
+
+            mOtaWidgetData.otaTextActivate.setVisibility(View.GONE);
+            mOtaWidgetData.otaTextListenProgress.setVisibility(View.GONE);
+            mOtaWidgetData.otaTextProgressBar.setVisibility(View.GONE);
+            mOtaWidgetData.otaTextSuccessFail.setVisibility(View.GONE);
+            mOtaWidgetData.callCardOtaButtonsActivate.setVisibility(View.GONE);
+            mOtaWidgetData.callCardOtaButtonsListenProgress.setVisibility(View.GONE);
+            mOtaWidgetData.callCardOtaButtonsFailSuccess.setVisibility(View.GONE);
+            mOtaWidgetData.otaUpperWidgets.setVisibility(View.GONE);
+            mOtaWidgetData.otaDtmfDialerView.setVisibility(View.GONE);
+            mOtaWidgetData.otaNextButton.setVisibility(View.GONE);
+            mOtaWidgetData.otaTryAgainButton.setVisibility(View.GONE);
+        }
+
+        // turn off the speaker in case it was turned on
+        // but the OTA call could not be completed
+        if (disableSpeaker) {
+            setSpeaker(false);
+        }
+    }
+
+    /**
+     * Defines OTA information that needs to be maintained during
+     * an OTA call when display orientation changes.
+     */
+    public static class CdmaOtaProvisionData {
+        public boolean isOtaCallCommitted;
+        public boolean isOtaCallIntentProcessed;
+        public boolean inOtaSpcState;
+        public int activationCount;
+        public long otaSpcUptime;
+    }
+
+    /**
+     * Defines OTA screen configuration items read from config.xml
+     * and used to control OTA display.
+     */
+    public static class CdmaOtaConfigData {
+        public int otaShowActivationScreen;
+        public int otaShowListeningScreen;
+        public int otaShowActivateFailTimes;
+        public int otaPlaySuccessFailureTone;
+        public boolean configComplete;
+        public CdmaOtaConfigData() {
+            if (DBG) log("CdmaOtaConfigData constructor!");
+            otaShowActivationScreen = OTA_SHOW_ACTIVATION_SCREEN_OFF;
+            otaShowListeningScreen = OTA_SHOW_LISTENING_SCREEN_OFF;
+            otaShowActivateFailTimes = OTA_SHOW_ACTIVATE_FAIL_COUNT_OFF;
+            otaPlaySuccessFailureTone = OTA_PLAY_SUCCESS_FAILURE_TONE_OFF;
+        }
+    }
+
+    /**
+     * The state of the OTA InCallScreen UI.
+     */
+    public static class CdmaOtaInCallScreenUiState {
+        public enum State {
+            UNDEFINED,
+            NORMAL,
+            ENDED
+        }
+
+        public State state;
+
+        public CdmaOtaInCallScreenUiState() {
+            if (DBG) log("CdmaOtaInCallScreenState: constructor init to UNDEFINED");
+            state = CdmaOtaInCallScreenUiState.State.UNDEFINED;
+        }
+    }
+
+    /**
+     * Save the Ota InCallScreen UI state
+     */
+    public void setCdmaOtaInCallScreenUiState(CdmaOtaInCallScreenUiState.State state) {
+        if (DBG) log("setCdmaOtaInCallScreenState: " + state);
+        mApplication.cdmaOtaInCallScreenUiState.state = state;
+    }
+
+    /**
+     * Get the Ota InCallScreen UI state
+     */
+    public CdmaOtaInCallScreenUiState.State getCdmaOtaInCallScreenUiState() {
+        if (DBG) log("getCdmaOtaInCallScreenState: "
+                     + mApplication.cdmaOtaInCallScreenUiState.state);
+        return mApplication.cdmaOtaInCallScreenUiState.state;
+    }
+
+    /**
+     * The OTA screen state machine.
+     */
+    public static class CdmaOtaScreenState {
+        public enum OtaScreenState {
+            OTA_STATUS_UNDEFINED,
+            OTA_STATUS_ACTIVATION,
+            OTA_STATUS_LISTENING,
+            OTA_STATUS_PROGRESS,
+            OTA_STATUS_SUCCESS_FAILURE_DLG
+        }
+
+        public OtaScreenState otaScreenState;
+
+        public CdmaOtaScreenState() {
+            otaScreenState = OtaScreenState.OTA_STATUS_UNDEFINED;
+        }
+
+        /**
+         * {@link PendingIntent} used to report an OTASP result status code
+         * back to our caller. Can be null.
+         *
+         * Our caller (presumably SetupWizard) may create this PendingIntent,
+         * pointing back at itself, and passes it along as an extra with the
+         * ACTION_PERFORM_CDMA_PROVISIONING intent.  Then, when there's an
+         * OTASP result to report, we send that PendingIntent back, adding an
+         * extra called EXTRA_OTASP_RESULT_CODE to indicate the result.
+         *
+         * Possible result values are the OTASP_RESULT_* constants.
+         */
+        public PendingIntent otaspResultCodePendingIntent;
+    }
+
+    /** @see com.android.internal.telephony.Phone */
+    private static String otaProvisionStatusToString(int status) {
+        switch (status) {
+            case Phone.CDMA_OTA_PROVISION_STATUS_SPL_UNLOCKED:
+                return "SPL_UNLOCKED";
+            case Phone.CDMA_OTA_PROVISION_STATUS_SPC_RETRIES_EXCEEDED:
+                return "SPC_RETRIES_EXCEEDED";
+            case Phone.CDMA_OTA_PROVISION_STATUS_A_KEY_EXCHANGED:
+                return "A_KEY_EXCHANGED";
+            case Phone.CDMA_OTA_PROVISION_STATUS_SSD_UPDATED:
+                return "SSD_UPDATED";
+            case Phone.CDMA_OTA_PROVISION_STATUS_NAM_DOWNLOADED:
+                return "NAM_DOWNLOADED";
+            case Phone.CDMA_OTA_PROVISION_STATUS_MDN_DOWNLOADED:
+                return "MDN_DOWNLOADED";
+            case Phone.CDMA_OTA_PROVISION_STATUS_IMSI_DOWNLOADED:
+                return "IMSI_DOWNLOADED";
+            case Phone.CDMA_OTA_PROVISION_STATUS_PRL_DOWNLOADED:
+                return "PRL_DOWNLOADED";
+            case Phone.CDMA_OTA_PROVISION_STATUS_COMMITTED:
+                return "COMMITTED";
+            case Phone.CDMA_OTA_PROVISION_STATUS_OTAPA_STARTED:
+                return "OTAPA_STARTED";
+            case Phone.CDMA_OTA_PROVISION_STATUS_OTAPA_STOPPED:
+                return "OTAPA_STOPPED";
+            case Phone.CDMA_OTA_PROVISION_STATUS_OTAPA_ABORTED:
+                return "OTAPA_ABORTED";
+            default:
+                return "<unknown status" + status + ">";
+        }
+    }
+
+    private static int getLteOnCdmaMode(Context context) {
+        final TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(
+                Context.TELEPHONY_SERVICE);
+        // If the telephony manager is not available yet, or if it doesn't know the answer yet,
+        // try falling back on the system property that may or may not be there
+        if (telephonyManager == null
+                || telephonyManager.getLteOnCdmaMode() == PhoneConstants.LTE_ON_CDMA_UNKNOWN) {
+            return SystemProperties.getInt(TelephonyProperties.PROPERTY_LTE_ON_CDMA_DEVICE,
+                    PhoneConstants.LTE_ON_CDMA_UNKNOWN);
+        }
+        return telephonyManager.getLteOnCdmaMode();
+    }
+
+    private static void log(String msg) {
+        Log.d(LOG_TAG, msg);
+    }
+
+    private static void loge(String msg) {
+        Log.e(LOG_TAG, msg);
+    }
+}
diff --git a/src/com/android/phone/OutgoingCallBroadcaster.java b/src/com/android/phone/OutgoingCallBroadcaster.java
new file mode 100644
index 0000000..fbec3a9
--- /dev/null
+++ b/src/com/android/phone/OutgoingCallBroadcaster.java
@@ -0,0 +1,750 @@
+/*
+ * 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.app.Activity;
+import android.app.ActivityManagerNative;
+import android.app.AlertDialog;
+import android.app.AppOpsManager;
+import android.app.Dialog;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.SystemProperties;
+import android.os.UserHandle;
+import android.telephony.PhoneNumberUtils;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.View;
+import android.widget.ProgressBar;
+
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.TelephonyCapabilities;
+
+/**
+ * OutgoingCallBroadcaster receives CALL and CALL_PRIVILEGED Intents, and
+ * broadcasts the ACTION_NEW_OUTGOING_CALL intent which allows other
+ * applications to monitor, redirect, or prevent the outgoing call.
+
+ * After the other applications have had a chance to see the
+ * ACTION_NEW_OUTGOING_CALL intent, it finally reaches the
+ * {@link OutgoingCallReceiver}, which passes the (possibly modified)
+ * intent on to the {@link SipCallOptionHandler}, which will
+ * ultimately start the call using the CallController.placeCall() API.
+ *
+ * Emergency calls and calls where no number is present (like for a CDMA
+ * "empty flash" or a nonexistent voicemail number) are exempt from being
+ * broadcast.
+ */
+public class OutgoingCallBroadcaster extends Activity
+        implements DialogInterface.OnClickListener, DialogInterface.OnCancelListener {
+
+    private static final String PERMISSION = android.Manifest.permission.PROCESS_OUTGOING_CALLS;
+    private static final String TAG = "OutgoingCallBroadcaster";
+    private static final boolean DBG =
+            (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
+    // Do not check in with VDBG = true, since that may write PII to the system log.
+    private static final boolean VDBG = false;
+
+    public static final String ACTION_SIP_SELECT_PHONE = "com.android.phone.SIP_SELECT_PHONE";
+    public static final String EXTRA_ALREADY_CALLED = "android.phone.extra.ALREADY_CALLED";
+    public static final String EXTRA_ORIGINAL_URI = "android.phone.extra.ORIGINAL_URI";
+    public static final String EXTRA_NEW_CALL_INTENT = "android.phone.extra.NEW_CALL_INTENT";
+    public static final String EXTRA_SIP_PHONE_URI = "android.phone.extra.SIP_PHONE_URI";
+    public static final String EXTRA_ACTUAL_NUMBER_TO_DIAL =
+            "android.phone.extra.ACTUAL_NUMBER_TO_DIAL";
+
+    /**
+     * Identifier for intent extra for sending an empty Flash message for
+     * CDMA networks. This message is used by the network to simulate a
+     * press/depress of the "hookswitch" of a landline phone. Aka "empty flash".
+     *
+     * TODO: Receiving an intent extra to tell the phone to send this flash is a
+     * temporary measure. To be replaced with an external ITelephony call in the future.
+     * TODO: Keep in sync with the string defined in TwelveKeyDialer.java in Contacts app
+     * until this is replaced with the ITelephony API.
+     */
+    public static final String EXTRA_SEND_EMPTY_FLASH =
+            "com.android.phone.extra.SEND_EMPTY_FLASH";
+
+    // Dialog IDs
+    private static final int DIALOG_NOT_VOICE_CAPABLE = 1;
+
+    /** Note message codes < 100 are reserved for the PhoneApp. */
+    private static final int EVENT_OUTGOING_CALL_TIMEOUT = 101;
+    private static final int OUTGOING_CALL_TIMEOUT_THRESHOLD = 2000; // msec
+    /**
+     * ProgressBar object with "spinner" style, which will be shown if we take more than
+     * {@link #EVENT_OUTGOING_CALL_TIMEOUT} msec to handle the incoming Intent.
+     */
+    private ProgressBar mWaitingSpinner;
+    private final Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            if (msg.what == EVENT_OUTGOING_CALL_TIMEOUT) {
+                Log.i(TAG, "Outgoing call takes too long. Showing the spinner.");
+                mWaitingSpinner.setVisibility(View.VISIBLE);
+            } else {
+                Log.wtf(TAG, "Unknown message id: " + msg.what);
+            }
+        }
+    };
+
+    /**
+     * OutgoingCallReceiver finishes NEW_OUTGOING_CALL broadcasts, starting
+     * the InCallScreen if the broadcast has not been canceled, possibly with
+     * a modified phone number and optional provider info (uri + package name + remote views.)
+     */
+    public class OutgoingCallReceiver extends BroadcastReceiver {
+        private static final String TAG = "OutgoingCallReceiver";
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            mHandler.removeMessages(EVENT_OUTGOING_CALL_TIMEOUT);
+            doReceive(context, intent);
+            if (DBG) Log.v(TAG, "OutgoingCallReceiver is going to finish the Activity itself.");
+            finish();
+        }
+
+        public void doReceive(Context context, Intent intent) {
+            if (DBG) Log.v(TAG, "doReceive: " + intent);
+
+            boolean alreadyCalled;
+            String number;
+            String originalUri;
+
+            alreadyCalled = intent.getBooleanExtra(
+                    OutgoingCallBroadcaster.EXTRA_ALREADY_CALLED, false);
+            if (alreadyCalled) {
+                if (DBG) Log.v(TAG, "CALL already placed -- returning.");
+                return;
+            }
+
+            // Once the NEW_OUTGOING_CALL broadcast is finished, the resultData
+            // is used as the actual number to call. (If null, no call will be
+            // placed.)
+
+            number = getResultData();
+            if (VDBG) Log.v(TAG, "- got number from resultData: '" + number + "'");
+
+            final PhoneGlobals app = PhoneGlobals.getInstance();
+
+            // OTASP-specific checks.
+            // TODO: This should probably all happen in
+            // OutgoingCallBroadcaster.onCreate(), since there's no reason to
+            // even bother with the NEW_OUTGOING_CALL broadcast if we're going
+            // to disallow the outgoing call anyway...
+            if (TelephonyCapabilities.supportsOtasp(app.phone)) {
+                boolean activateState = (app.cdmaOtaScreenState.otaScreenState
+                        == OtaUtils.CdmaOtaScreenState.OtaScreenState.OTA_STATUS_ACTIVATION);
+                boolean dialogState = (app.cdmaOtaScreenState.otaScreenState
+                        == OtaUtils.CdmaOtaScreenState.OtaScreenState
+                        .OTA_STATUS_SUCCESS_FAILURE_DLG);
+                boolean isOtaCallActive = false;
+
+                // TODO: Need cleaner way to check if OTA is active.
+                // Also, this check seems to be broken in one obscure case: if
+                // you interrupt an OTASP call by pressing Back then Skip,
+                // otaScreenState somehow gets left in either PROGRESS or
+                // LISTENING.
+                if ((app.cdmaOtaScreenState.otaScreenState
+                        == OtaUtils.CdmaOtaScreenState.OtaScreenState.OTA_STATUS_PROGRESS)
+                        || (app.cdmaOtaScreenState.otaScreenState
+                        == OtaUtils.CdmaOtaScreenState.OtaScreenState.OTA_STATUS_LISTENING)) {
+                    isOtaCallActive = true;
+                }
+
+                if (activateState || dialogState) {
+                    // The OTASP sequence is active, but either (1) the call
+                    // hasn't started yet, or (2) the call has ended and we're
+                    // showing the success/failure screen.  In either of these
+                    // cases it's OK to make a new outgoing call, but we need
+                    // 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.
+                    Log.w(TAG, "OTASP call is active: disallowing a new outgoing call.");
+                    return;
+                }
+            }
+
+            if (number == null) {
+                if (DBG) Log.v(TAG, "CALL cancelled (null number), returning...");
+                return;
+            } else if (TelephonyCapabilities.supportsOtasp(app.phone)
+                    && (app.phone.getState() != PhoneConstants.State.IDLE)
+                    && (app.phone.isOtaSpNumber(number))) {
+                if (DBG) Log.v(TAG, "Call is active, a 2nd OTA call cancelled -- returning.");
+                return;
+            } else if (PhoneNumberUtils.isPotentialLocalEmergencyNumber(number, context)) {
+                // Just like 3rd-party apps aren't allowed to place emergency
+                // calls via the ACTION_CALL intent, we also don't allow 3rd
+                // party apps to use the NEW_OUTGOING_CALL broadcast to rewrite
+                // an outgoing call into an emergency number.
+                Log.w(TAG, "Cannot modify outgoing call to emergency number " + number + ".");
+                return;
+            }
+
+            originalUri = intent.getStringExtra(
+                    OutgoingCallBroadcaster.EXTRA_ORIGINAL_URI);
+            if (originalUri == null) {
+                Log.e(TAG, "Intent is missing EXTRA_ORIGINAL_URI -- returning.");
+                return;
+            }
+
+            Uri uri = Uri.parse(originalUri);
+
+            // We already called convertKeypadLettersToDigits() and
+            // stripSeparators() way back in onCreate(), before we sent out the
+            // NEW_OUTGOING_CALL broadcast.  But we need to do it again here
+            // too, since the number might have been modified/rewritten during
+            // the broadcast (and may now contain letters or separators again.)
+            number = PhoneNumberUtils.convertKeypadLettersToDigits(number);
+            number = PhoneNumberUtils.stripSeparators(number);
+
+            if (DBG) Log.v(TAG, "doReceive: proceeding with call...");
+            if (VDBG) Log.v(TAG, "- uri: " + uri);
+            if (VDBG) Log.v(TAG, "- actual number to dial: '" + number + "'");
+
+            startSipCallOptionHandler(context, intent, uri, number);
+        }
+    }
+
+    /**
+     * Launch the SipCallOptionHandler, which is the next step(*) in the
+     * outgoing-call sequence after the outgoing call broadcast is
+     * complete.
+     *
+     * (*) We now know exactly what phone number we need to dial, so the next
+     *     step is for the SipCallOptionHandler to decide which Phone type (SIP
+     *     or PSTN) should be used.  (Depending on the user's preferences, this
+     *     decision may also involve popping up a dialog to ask the user to
+     *     choose what type of call this should be.)
+     *
+     * @param context used for the startActivity() call
+     *
+     * @param intent the intent from the previous step of the outgoing-call
+     *   sequence.  Normally this will be the NEW_OUTGOING_CALL broadcast intent
+     *   that came in to the OutgoingCallReceiver, although it can also be the
+     *   original ACTION_CALL intent that started the whole sequence (in cases
+     *   where we don't do the NEW_OUTGOING_CALL broadcast at all, like for
+     *   emergency numbers or SIP addresses).
+     *
+     * @param uri the data URI from the original CALL intent, presumably either
+     *   a tel: or sip: URI.  For tel: URIs, note that the scheme-specific part
+     *   does *not* necessarily have separators and keypad letters stripped (so
+     *   we might see URIs like "tel:(650)%20555-1234" or "tel:1-800-GOOG-411"
+     *   here.)
+     *
+     * @param number the actual number (or SIP address) to dial.  This is
+     *   guaranteed to be either a PSTN phone number with separators stripped
+     *   out and keypad letters converted to digits (like "16505551234"), or a
+     *   raw SIP address (like "user@example.com").
+     */
+    private void startSipCallOptionHandler(Context context, Intent intent,
+            Uri uri, String number) {
+        if (VDBG) {
+            Log.i(TAG, "startSipCallOptionHandler...");
+            Log.i(TAG, "- intent: " + intent);
+            Log.i(TAG, "- uri: " + uri);
+            Log.i(TAG, "- number: " + number);
+        }
+
+        // Create a copy of the original CALL intent that started the whole
+        // outgoing-call sequence.  This intent will ultimately be passed to
+        // CallController.placeCall() after the SipCallOptionHandler step.
+
+        Intent newIntent = new Intent(Intent.ACTION_CALL, uri);
+        newIntent.putExtra(EXTRA_ACTUAL_NUMBER_TO_DIAL, number);
+        PhoneUtils.checkAndCopyPhoneProviderExtras(intent, newIntent);
+
+        // Finally, launch the SipCallOptionHandler, with the copy of the
+        // original CALL intent stashed away in the EXTRA_NEW_CALL_INTENT
+        // extra.
+
+        Intent selectPhoneIntent = new Intent(ACTION_SIP_SELECT_PHONE, uri);
+        selectPhoneIntent.setClass(context, SipCallOptionHandler.class);
+        selectPhoneIntent.putExtra(EXTRA_NEW_CALL_INTENT, newIntent);
+        selectPhoneIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        if (DBG) {
+            Log.v(TAG, "startSipCallOptionHandler(): " +
+                    "calling startActivity: " + selectPhoneIntent);
+        }
+        context.startActivity(selectPhoneIntent);
+        // ...and see SipCallOptionHandler.onCreate() for the next step of the sequence.
+    }
+
+    /**
+     * This method is the single point of entry for the CALL intent, which is used (by built-in
+     * apps like Contacts / Dialer, as well as 3rd-party apps) to initiate an outgoing voice call.
+     *
+     *
+     */
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        setContentView(R.layout.outgoing_call_broadcaster);
+        mWaitingSpinner = (ProgressBar) findViewById(R.id.spinner);
+
+        Intent intent = getIntent();
+        if (DBG) {
+            final Configuration configuration = getResources().getConfiguration();
+            Log.v(TAG, "onCreate: this = " + this + ", icicle = " + icicle);
+            Log.v(TAG, " - getIntent() = " + intent);
+            Log.v(TAG, " - configuration = " + configuration);
+        }
+
+        if (icicle != null) {
+            // A non-null icicle means that this activity is being
+            // re-initialized after previously being shut down.
+            //
+            // In practice this happens very rarely (because the lifetime
+            // of this activity is so short!), but it *can* happen if the
+            // framework detects a configuration change at exactly the
+            // right moment; see bug 2202413.
+            //
+            // In this case, do nothing.  Our onCreate() method has already
+            // run once (with icicle==null the first time), which means
+            // that the NEW_OUTGOING_CALL broadcast for this new call has
+            // already been sent.
+            Log.i(TAG, "onCreate: non-null icicle!  "
+                  + "Bailing out, not sending NEW_OUTGOING_CALL broadcast...");
+
+            // No need to finish() here, since the OutgoingCallReceiver from
+            // our original instance will do that.  (It'll actually call
+            // finish() on our original instance, which apparently works fine
+            // even though the ActivityManager has already shut that instance
+            // down.  And note that if we *do* call finish() here, that just
+            // results in an "ActivityManager: Duplicate finish request"
+            // warning when the OutgoingCallReceiver runs.)
+
+            return;
+        }
+
+        processIntent(intent);
+
+        // isFinishing() return false when 1. broadcast is still ongoing, or 2. dialog is being
+        // shown. Otherwise finish() is called inside processIntent(), is isFinishing() here will
+        // return true.
+        if (DBG) Log.v(TAG, "At the end of onCreate(). isFinishing(): " + isFinishing());
+    }
+
+    /**
+     * Interprets a given Intent and starts something relevant to the Intent.
+     *
+     * This method will handle three kinds of actions:
+     *
+     * - CALL (action for usual outgoing voice calls)
+     * - CALL_PRIVILEGED (can come from built-in apps like contacts / voice dialer / bluetooth)
+     * - CALL_EMERGENCY (from the EmergencyDialer that's reachable from the lockscreen.)
+     *
+     * The exact behavior depends on the intent's data:
+     *
+     * - The most typical is a tel: URI, which we handle by starting the
+     *   NEW_OUTGOING_CALL broadcast.  That broadcast eventually triggers
+     *   the sequence OutgoingCallReceiver -> SipCallOptionHandler ->
+     *   InCallScreen.
+     *
+     * - Or, with a sip: URI we skip the NEW_OUTGOING_CALL broadcast and
+     *   go directly to SipCallOptionHandler, which then leads to the
+     *   InCallScreen.
+     *
+     * - voicemail: URIs take the same path as regular tel: URIs.
+     *
+     * Other special cases:
+     *
+     * - Outgoing calls are totally disallowed on non-voice-capable
+     *   devices (see handleNonVoiceCapable()).
+     *
+     * - A CALL intent with the EXTRA_SEND_EMPTY_FLASH extra (and
+     *   presumably no data at all) means "send an empty flash" (which
+     *   is only meaningful on CDMA devices while a call is already
+     *   active.)
+     *
+     */
+    private void processIntent(Intent intent) {
+        if (DBG) {
+            Log.v(TAG, "processIntent() = " + intent + ", thread: " + Thread.currentThread());
+        }
+        final Configuration configuration = getResources().getConfiguration();
+
+        // Outgoing phone calls are only allowed on "voice-capable" devices.
+        if (!PhoneGlobals.sVoiceCapable) {
+            Log.i(TAG, "This device is detected as non-voice-capable device.");
+            handleNonVoiceCapable(intent);
+            return;
+        }
+
+        String action = intent.getAction();
+        String number = PhoneNumberUtils.getNumberFromIntent(intent, this);
+        // Check the number, don't convert for sip uri
+        // TODO put uriNumber under PhoneNumberUtils
+        if (number != null) {
+            if (!PhoneNumberUtils.isUriNumber(number)) {
+                number = PhoneNumberUtils.convertKeypadLettersToDigits(number);
+                number = PhoneNumberUtils.stripSeparators(number);
+            }
+        } else {
+            Log.w(TAG, "The number obtained from Intent is null.");
+        }
+
+        AppOpsManager appOps = (AppOpsManager)getSystemService(Context.APP_OPS_SERVICE);
+        int launchedFromUid;
+        String launchedFromPackage;
+        try {
+            launchedFromUid = ActivityManagerNative.getDefault().getLaunchedFromUid(
+                    getActivityToken());
+            launchedFromPackage = ActivityManagerNative.getDefault().getLaunchedFromPackage(
+                    getActivityToken());
+        } catch (RemoteException e) {
+            launchedFromUid = -1;
+            launchedFromPackage = null;
+        }
+        if (appOps.noteOp(AppOpsManager.OP_CALL_PHONE, launchedFromUid, launchedFromPackage)
+                != AppOpsManager.MODE_ALLOWED) {
+            Log.w(TAG, "Rejecting call from uid " + launchedFromUid + " package "
+                    + launchedFromPackage);
+            finish();
+            return;
+        }
+
+        // If true, this flag will indicate that the current call is a special kind
+        // of call (most likely an emergency number) that 3rd parties aren't allowed
+        // to intercept or affect in any way.  (In that case, we start the call
+        // immediately rather than going through the NEW_OUTGOING_CALL sequence.)
+        boolean callNow;
+
+        if (getClass().getName().equals(intent.getComponent().getClassName())) {
+            // If we were launched directly from the OutgoingCallBroadcaster,
+            // not one of its more privileged aliases, then make sure that
+            // only the non-privileged actions are allowed.
+            if (!Intent.ACTION_CALL.equals(intent.getAction())) {
+                Log.w(TAG, "Attempt to deliver non-CALL action; forcing to CALL");
+                intent.setAction(Intent.ACTION_CALL);
+            }
+        }
+
+        // Check whether or not this is an emergency number, in order to
+        // enforce the restriction that only the CALL_PRIVILEGED and
+        // CALL_EMERGENCY intents are allowed to make emergency calls.
+        //
+        // (Note that the ACTION_CALL check below depends on the result of
+        // isPotentialLocalEmergencyNumber() rather than just plain
+        // isLocalEmergencyNumber(), to be 100% certain that we *don't*
+        // allow 3rd party apps to make emergency calls by passing in an
+        // "invalid" number like "9111234" that isn't technically an
+        // emergency number but might still result in an emergency call
+        // with some networks.)
+        final boolean isExactEmergencyNumber =
+                (number != null) && PhoneNumberUtils.isLocalEmergencyNumber(number, this);
+        final boolean isPotentialEmergencyNumber =
+                (number != null) && PhoneNumberUtils.isPotentialLocalEmergencyNumber(number, this);
+        if (VDBG) {
+            Log.v(TAG, " - Checking restrictions for number '" + number + "':");
+            Log.v(TAG, "     isExactEmergencyNumber     = " + isExactEmergencyNumber);
+            Log.v(TAG, "     isPotentialEmergencyNumber = " + isPotentialEmergencyNumber);
+        }
+
+        /* Change CALL_PRIVILEGED into CALL or CALL_EMERGENCY as needed. */
+        // TODO: This code is redundant with some code in InCallScreen: refactor.
+        if (Intent.ACTION_CALL_PRIVILEGED.equals(action)) {
+            // We're handling a CALL_PRIVILEGED intent, so we know this request came
+            // from a trusted source (like the built-in dialer.)  So even a number
+            // that's *potentially* an emergency number can safely be promoted to
+            // CALL_EMERGENCY (since we *should* allow you to dial "91112345" from
+            // the dialer if you really want to.)
+            if (isPotentialEmergencyNumber) {
+                Log.i(TAG, "ACTION_CALL_PRIVILEGED is used while the number is a potential"
+                        + " emergency number. Use ACTION_CALL_EMERGENCY as an action instead.");
+                action = Intent.ACTION_CALL_EMERGENCY;
+            } else {
+                action = Intent.ACTION_CALL;
+            }
+            if (DBG) Log.v(TAG, " - updating action from CALL_PRIVILEGED to " + action);
+            intent.setAction(action);
+        }
+
+        if (Intent.ACTION_CALL.equals(action)) {
+            if (isPotentialEmergencyNumber) {
+                Log.w(TAG, "Cannot call potential emergency number '" + number
+                        + "' with CALL Intent " + intent + ".");
+                Log.i(TAG, "Launching default dialer instead...");
+
+                Intent invokeFrameworkDialer = new Intent();
+
+                // TwelveKeyDialer is in a tab so we really want
+                // DialtactsActivity.  Build the intent 'manually' to
+                // use the java resolver to find the dialer class (as
+                // opposed to a Context which look up known android
+                // packages only)
+                invokeFrameworkDialer.setClassName("com.android.dialer",
+                                                   "com.android.dialer.DialtactsActivity");
+                invokeFrameworkDialer.setAction(Intent.ACTION_DIAL);
+                invokeFrameworkDialer.setData(intent.getData());
+
+                if (DBG) Log.v(TAG, "onCreate(): calling startActivity for Dialer: "
+                               + invokeFrameworkDialer);
+                startActivity(invokeFrameworkDialer);
+                finish();
+                return;
+            }
+            callNow = false;
+        } else if (Intent.ACTION_CALL_EMERGENCY.equals(action)) {
+            // ACTION_CALL_EMERGENCY case: this is either a CALL_PRIVILEGED
+            // intent that we just turned into a CALL_EMERGENCY intent (see
+            // above), or else it really is an CALL_EMERGENCY intent that
+            // came directly from some other app (e.g. the EmergencyDialer
+            // activity built in to the Phone app.)
+            // Make sure it's at least *possible* that this is really an
+            // emergency number.
+            if (!isPotentialEmergencyNumber) {
+                Log.w(TAG, "Cannot call non-potential-emergency number " + number
+                        + " with EMERGENCY_CALL Intent " + intent + "."
+                        + " Finish the Activity immediately.");
+                finish();
+                return;
+            }
+            callNow = true;
+        } else {
+            Log.e(TAG, "Unhandled Intent " + intent + ". Finish the Activity immediately.");
+            finish();
+            return;
+        }
+
+        // Make sure the screen is turned on.  This is probably the right
+        // thing to do, and more importantly it works around an issue in the
+        // activity manager where we will not launch activities consistently
+        // when the screen is off (since it is trying to keep them paused
+        // and has...  issues).
+        //
+        // Also, this ensures the device stays awake while doing the following
+        // broadcast; technically we should be holding a wake lock here
+        // as well.
+        PhoneGlobals.getInstance().wakeUpScreen();
+
+        // If number is null, we're probably trying to call a non-existent voicemail number,
+        // send an empty flash or something else is fishy.  Whatever the problem, there's no
+        // number, so there's no point in allowing apps to modify the number.
+        if (TextUtils.isEmpty(number)) {
+            if (intent.getBooleanExtra(EXTRA_SEND_EMPTY_FLASH, false)) {
+                Log.i(TAG, "onCreate: SEND_EMPTY_FLASH...");
+                PhoneUtils.sendEmptyFlash(PhoneGlobals.getPhone());
+                finish();
+                return;
+            } else {
+                Log.i(TAG, "onCreate: null or empty number, setting callNow=true...");
+                callNow = true;
+            }
+        }
+
+        if (callNow) {
+            // This is a special kind of call (most likely an emergency number)
+            // that 3rd parties aren't allowed to intercept or affect in any way.
+            // So initiate the outgoing call immediately.
+
+            Log.i(TAG, "onCreate(): callNow case! Calling placeCall(): " + intent);
+
+            // Initiate the outgoing call, and simultaneously launch the
+            // InCallScreen to display the in-call UI:
+            PhoneGlobals.getInstance().callController.placeCall(intent);
+
+            // Note we do *not* "return" here, but instead continue and
+            // send the ACTION_NEW_OUTGOING_CALL broadcast like for any
+            // other outgoing call.  (But when the broadcast finally
+            // reaches the OutgoingCallReceiver, we'll know not to
+            // initiate the call again because of the presence of the
+            // 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.
+        //
+        // TODO: In the future, though, 3rd party apps *should* be allowed to
+        // intercept outgoing calls to SIP addresses as well.  To do this, we should
+        // (1) update the NEW_OUTGOING_CALL intent documentation to explain this
+        // case, and (2) pass the outgoing SIP address by *not* overloading the
+        // EXTRA_PHONE_NUMBER extra, but instead using a new separate extra to hold
+        // the outgoing SIP address.  (Be sure to document whether it's a URI or just
+        // a plain address, whether it could be a tel: URI, etc.)
+        Uri uri = intent.getData();
+        String scheme = uri.getScheme();
+        if (Constants.SCHEME_SIP.equals(scheme) || PhoneNumberUtils.isUriNumber(number)) {
+            Log.i(TAG, "The requested number was detected as SIP call.");
+            startSipCallOptionHandler(this, intent, uri, number);
+            finish();
+            return;
+
+            // TODO: if there's ever a way for SIP calls to trigger a
+            // "callNow=true" case (see above), we'll need to handle that
+            // case here too (most likely by just doing nothing at all.)
+        }
+
+        Intent broadcastIntent = new Intent(Intent.ACTION_NEW_OUTGOING_CALL);
+        if (number != null) {
+            broadcastIntent.putExtra(Intent.EXTRA_PHONE_NUMBER, number);
+        }
+        PhoneUtils.checkAndCopyPhoneProviderExtras(intent, broadcastIntent);
+        broadcastIntent.putExtra(EXTRA_ALREADY_CALLED, callNow);
+        broadcastIntent.putExtra(EXTRA_ORIGINAL_URI, uri.toString());
+        // Need to raise foreground in-call UI as soon as possible while allowing 3rd party app
+        // to intercept the outgoing call.
+        broadcastIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+        if (DBG) Log.v(TAG, " - Broadcasting intent: " + broadcastIntent + ".");
+
+        // Set a timer so that we can prepare for unexpected delay introduced by the broadcast.
+        // If it takes too much time, the timer will show "waiting" spinner.
+        // This message will be removed when OutgoingCallReceiver#onReceive() is called before the
+        // timeout.
+        mHandler.sendEmptyMessageDelayed(EVENT_OUTGOING_CALL_TIMEOUT,
+                OUTGOING_CALL_TIMEOUT_THRESHOLD);
+        sendOrderedBroadcastAsUser(broadcastIntent, UserHandle.OWNER,
+                PERMISSION, new OutgoingCallReceiver(),
+                null,  // scheduler
+                Activity.RESULT_OK,  // initialCode
+                number,  // initialData: initial value for the result data
+                null);  // initialExtras
+    }
+
+    @Override
+    protected void onStop() {
+        // Clean up (and dismiss if necessary) any managed dialogs.
+        //
+        // We don't do this in onPause() since we can be paused/resumed
+        // due to orientation changes (in which case we don't want to
+        // disturb the dialog), but we *do* need it here in onStop() to be
+        // sure we clean up if the user hits HOME while the dialog is up.
+        //
+        // Note it's safe to call removeDialog() even if there's no dialog
+        // associated with that ID.
+        removeDialog(DIALOG_NOT_VOICE_CAPABLE);
+
+        super.onStop();
+    }
+
+    /**
+     * Handle the specified CALL or CALL_* intent on a non-voice-capable
+     * device.
+     *
+     * This method may launch a different intent (if there's some useful
+     * alternative action to take), or otherwise display an error dialog,
+     * and in either case will finish() the current activity when done.
+     */
+    private void handleNonVoiceCapable(Intent intent) {
+        if (DBG) Log.v(TAG, "handleNonVoiceCapable: handling " + intent
+                       + " on non-voice-capable device...");
+        String action = intent.getAction();
+        Uri uri = intent.getData();
+        String scheme = uri.getScheme();
+
+        // Handle one special case: If this is a regular CALL to a tel: URI,
+        // bring up a UI letting you do something useful with the phone number
+        // (like "Add to contacts" if it isn't a contact yet.)
+        //
+        // This UI is provided by the contacts app in response to a DIAL
+        // intent, so we bring it up here by demoting this CALL to a DIAL and
+        // relaunching.
+        //
+        // TODO: it's strange and unintuitive to manually launch a DIAL intent
+        // to do this; it would be cleaner to have some shared UI component
+        // that we could bring up directly.  (But for now at least, since both
+        // Contacts and Phone are built-in apps, this implementation is fine.)
+
+        if (Intent.ACTION_CALL.equals(action) && (Constants.SCHEME_TEL.equals(scheme))) {
+            Intent newIntent = new Intent(Intent.ACTION_DIAL, uri);
+            if (DBG) Log.v(TAG, "- relaunching as a DIAL intent: " + newIntent);
+            startActivity(newIntent);
+            finish();
+            return;
+        }
+
+        // In all other cases, just show a generic "voice calling not
+        // supported" dialog.
+        showDialog(DIALOG_NOT_VOICE_CAPABLE);
+        // ...and we'll eventually finish() when the user dismisses
+        // or cancels the dialog.
+    }
+
+    @Override
+    protected Dialog onCreateDialog(int id) {
+        Dialog dialog;
+        switch(id) {
+            case DIALOG_NOT_VOICE_CAPABLE:
+                dialog = new AlertDialog.Builder(this)
+                        .setTitle(R.string.not_voice_capable)
+                        .setIconAttribute(android.R.attr.alertDialogIcon)
+                        .setPositiveButton(android.R.string.ok, this)
+                        .setOnCancelListener(this)
+                        .create();
+                break;
+            default:
+                Log.w(TAG, "onCreateDialog: unexpected ID " + id);
+                dialog = null;
+                break;
+        }
+        return dialog;
+    }
+
+    /** DialogInterface.OnClickListener implementation */
+    @Override
+    public void onClick(DialogInterface dialog, int id) {
+        // DIALOG_NOT_VOICE_CAPABLE is the only dialog we ever use (so far
+        // at least), and its only button is "OK".
+        finish();
+    }
+
+    /** DialogInterface.OnCancelListener implementation */
+    @Override
+    public void onCancel(DialogInterface dialog) {
+        // DIALOG_NOT_VOICE_CAPABLE is the only dialog we ever use (so far
+        // at least), and canceling it is just like hitting "OK".
+        finish();
+    }
+
+    /**
+     * Implement onConfigurationChanged() purely for debugging purposes,
+     * to make sure that the android:configChanges element in our manifest
+     * is working properly.
+     */
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        if (DBG) Log.v(TAG, "onConfigurationChanged: newConfig = " + newConfig);
+    }
+}
diff --git a/src/com/android/phone/PhoneApp.java b/src/com/android/phone/PhoneApp.java
new file mode 100644
index 0000000..e3d3fa9
--- /dev/null
+++ b/src/com/android/phone/PhoneApp.java
@@ -0,0 +1,49 @@
+/*
+ * 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.app.Application;
+import android.content.res.Configuration;
+import android.os.UserHandle;
+
+/**
+ * Top-level Application class for the Phone app.
+ */
+public class PhoneApp extends Application {
+    PhoneGlobals mPhoneGlobals;
+
+    public PhoneApp() {
+    }
+
+    @Override
+    public void onCreate() {
+        if (UserHandle.myUserId() == 0) {
+            // We are running as the primary user, so should bring up the
+            // global phone state.
+            mPhoneGlobals = new PhoneGlobals(this);
+            mPhoneGlobals.onCreate();
+        }
+    }
+
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        if (mPhoneGlobals != null) {
+            mPhoneGlobals.onConfigurationChanged(newConfig);
+        }
+        super.onConfigurationChanged(newConfig);
+    }
+}
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
new file mode 100644
index 0000000..019c74a
--- /dev/null
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -0,0 +1,1859 @@
+/*
+ * 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.app.Activity;
+import android.app.KeyguardManager;
+import android.app.PendingIntent;
+import android.app.ProgressDialog;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothHeadset;
+import android.bluetooth.BluetoothProfile;
+import android.bluetooth.IBluetoothHeadsetPhone;
+import android.content.ActivityNotFoundException;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.ServiceConnection;
+import android.content.res.Configuration;
+import android.media.AudioManager;
+import android.net.Uri;
+import android.os.AsyncResult;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.IPowerManager;
+import android.os.Message;
+import android.os.PowerManager;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.os.SystemProperties;
+import android.os.UpdateLock;
+import android.os.UserHandle;
+import android.preference.PreferenceManager;
+import android.provider.Settings.System;
+import android.telephony.ServiceState;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.Slog;
+import android.view.KeyEvent;
+
+import com.android.internal.telephony.Call;
+import com.android.internal.telephony.CallManager;
+import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.IccCardConstants;
+import com.android.internal.telephony.MmiCode;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.TelephonyCapabilities;
+import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.telephony.cdma.TtyIntent;
+import com.android.phone.common.CallLogAsync;
+import com.android.phone.OtaUtils.CdmaOtaScreenState;
+import com.android.server.sip.SipService;
+
+/**
+ * Global state for the telephony subsystem when running in the primary
+ * phone process.
+ */
+public class PhoneGlobals extends ContextWrapper
+        implements AccelerometerListener.OrientationListener {
+    /* package */ static final String LOG_TAG = "PhoneApp";
+
+    /**
+     * Phone app-wide debug level:
+     *   0 - no debug logging
+     *   1 - normal debug logging if ro.debuggable is set (which is true in
+     *       "eng" and "userdebug" builds but not "user" builds)
+     *   2 - ultra-verbose debug logging
+     *
+     * Most individual classes in the phone app have a local DBG constant,
+     * typically set to
+     *   (PhoneApp.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1)
+     * or else
+     *   (PhoneApp.DBG_LEVEL >= 2)
+     * depending on the desired verbosity.
+     *
+     * ***** DO NOT SUBMIT WITH DBG_LEVEL > 0 *************
+     */
+    /* package */ static final int DBG_LEVEL = 0;
+
+    private static final boolean DBG =
+            (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
+    private static final boolean VDBG = (PhoneGlobals.DBG_LEVEL >= 2);
+
+    // Message codes; see mHandler below.
+    private static final int EVENT_SIM_NETWORK_LOCKED = 3;
+    private static final int EVENT_WIRED_HEADSET_PLUG = 7;
+    private static final int EVENT_SIM_STATE_CHANGED = 8;
+    private static final int EVENT_UPDATE_INCALL_NOTIFICATION = 9;
+    private static final int EVENT_DATA_ROAMING_DISCONNECTED = 10;
+    private static final int EVENT_DATA_ROAMING_OK = 11;
+    private static final int EVENT_UNSOL_CDMA_INFO_RECORD = 12;
+    private static final int EVENT_DOCK_STATE_CHANGED = 13;
+    private static final int EVENT_TTY_PREFERRED_MODE_CHANGED = 14;
+    private static final int EVENT_TTY_MODE_GET = 15;
+    private static final int EVENT_TTY_MODE_SET = 16;
+    private static final int EVENT_START_SIP_SERVICE = 17;
+
+    // The MMI codes are also used by the InCallScreen.
+    public static final int MMI_INITIATE = 51;
+    public static final int MMI_COMPLETE = 52;
+    public static final int MMI_CANCEL = 53;
+    // Don't use message codes larger than 99 here; those are reserved for
+    // the individual Activities of the Phone UI.
+
+    /**
+     * Allowable values for the wake lock code.
+     *   SLEEP means the device can be put to sleep.
+     *   PARTIAL means wake the processor, but we display can be kept off.
+     *   FULL means wake both the processor and the display.
+     */
+    public enum WakeState {
+        SLEEP,
+        PARTIAL,
+        FULL
+    }
+
+    /**
+     * Intent Action used for hanging up the current call from Notification bar. This will
+     * choose first ringing call, first active call, or first background call (typically in
+     * HOLDING state).
+     */
+    public static final String ACTION_HANG_UP_ONGOING_CALL =
+            "com.android.phone.ACTION_HANG_UP_ONGOING_CALL";
+
+    /**
+     * Intent Action used for making a phone call from Notification bar.
+     * This is for missed call notifications.
+     */
+    public static final String ACTION_CALL_BACK_FROM_NOTIFICATION =
+            "com.android.phone.ACTION_CALL_BACK_FROM_NOTIFICATION";
+
+    /**
+     * Intent Action used for sending a SMS from notification bar.
+     * This is for missed call notifications.
+     */
+    public static final String ACTION_SEND_SMS_FROM_NOTIFICATION =
+            "com.android.phone.ACTION_SEND_SMS_FROM_NOTIFICATION";
+
+    private static PhoneGlobals sMe;
+
+    // A few important fields we expose to the rest of the package
+    // directly (rather than thru set/get methods) for efficiency.
+    Phone phone;
+    CallController callController;
+    InCallUiState inCallUiState;
+    CallerInfoCache callerInfoCache;
+    CallNotifier notifier;
+    NotificationMgr notificationMgr;
+    Ringer ringer;
+    IBluetoothHeadsetPhone mBluetoothPhone;
+    PhoneInterfaceManager phoneMgr;
+    CallManager mCM;
+    CallStateMonitor callStateMonitor;
+    int mBluetoothHeadsetState = BluetoothProfile.STATE_DISCONNECTED;
+    int mBluetoothHeadsetAudioState = BluetoothHeadset.STATE_AUDIO_DISCONNECTED;
+    boolean mShowBluetoothIndication = false;
+    static int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
+    static boolean sVoiceCapable = true;
+
+    // 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
+    // the foreground.
+    private Activity mPUKEntryActivity;
+    private ProgressDialog mPUKEntryProgressDialog;
+
+    private boolean mIsSimPinEnabled;
+    private String mCachedSimPin;
+
+    // True if a wired headset is currently plugged in, based on the state
+    // from the latest Intent.ACTION_HEADSET_PLUG broadcast we received in
+    // mReceiver.onReceive().
+    private boolean mIsHeadsetPlugged;
+
+    // True if the keyboard is currently *not* hidden
+    // Gets updated whenever there is a Configuration change
+    private boolean mIsHardKeyboardOpen;
+
+    // True if we are beginning a call, but the phone state has not changed yet
+    private boolean mBeginningCall;
+
+    // Last phone state seen by updatePhoneState()
+    private PhoneConstants.State mLastPhoneState = PhoneConstants.State.IDLE;
+
+    private WakeState mWakeState = WakeState.SLEEP;
+
+    private PowerManager mPowerManager;
+    private IPowerManager mPowerManagerService;
+    private PowerManager.WakeLock mWakeLock;
+    private PowerManager.WakeLock mPartialWakeLock;
+    private PowerManager.WakeLock mProximityWakeLock;
+    private KeyguardManager mKeyguardManager;
+    private AccelerometerListener mAccelerometerListener;
+    private int mOrientation = AccelerometerListener.ORIENTATION_UNKNOWN;
+
+    private UpdateLock mUpdateLock;
+
+    // Broadcast receiver for various intent broadcasts (see onCreate())
+    private final BroadcastReceiver mReceiver = new PhoneAppBroadcastReceiver();
+
+    // Broadcast receiver purely for ACTION_MEDIA_BUTTON broadcasts
+    private final BroadcastReceiver mMediaButtonReceiver = new MediaButtonBroadcastReceiver();
+
+    /** boolean indicating restoring mute state on InCallScreen.onResume() */
+    private boolean mShouldRestoreMuteOnInCallResume;
+
+    /**
+     * The singleton OtaUtils instance used for OTASP calls.
+     *
+     * The OtaUtils instance is created lazily the first time we need to
+     * make an OTASP call, regardless of whether it's an interactive or
+     * non-interactive OTASP call.
+     */
+    public OtaUtils otaUtils;
+
+    // Following are the CDMA OTA information Objects used during OTA Call.
+    // cdmaOtaProvisionData object store static OTA information that needs
+    // to be maintained even during Slider open/close scenarios.
+    // cdmaOtaConfigData object stores configuration info to control visiblity
+    // of each OTA Screens.
+    // cdmaOtaScreenState object store OTA Screen State information.
+    public OtaUtils.CdmaOtaProvisionData cdmaOtaProvisionData;
+    public OtaUtils.CdmaOtaConfigData cdmaOtaConfigData;
+    public OtaUtils.CdmaOtaScreenState cdmaOtaScreenState;
+    public OtaUtils.CdmaOtaInCallScreenUiState cdmaOtaInCallScreenUiState;
+
+    // TTY feature enabled on this platform
+    private boolean mTtyEnabled;
+    // Current TTY operating mode selected by user
+    private int mPreferredTtyMode = Phone.TTY_MODE_OFF;
+
+    /**
+     * Set the restore mute state flag. Used when we are setting the mute state
+     * OUTSIDE of user interaction {@link PhoneUtils#startNewCall(Phone)}
+     */
+    /*package*/void setRestoreMuteOnInCallResume (boolean mode) {
+        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) {
+            PhoneConstants.State phoneState;
+            switch (msg.what) {
+                // Starts the SIP service. It's a no-op if SIP API is not supported
+                // on the deivce.
+                // TODO: Having the phone process host the SIP service is only
+                // temporary. Will move it to a persistent communication process
+                // later.
+                case EVENT_START_SIP_SERVICE:
+                    SipService.start(getApplicationContext());
+                    break;
+
+                // TODO: This event should be handled by the lock screen, just
+                // like the "SIM missing" and "Sim locked" cases (bug 1804111).
+                case EVENT_SIM_NETWORK_LOCKED:
+                    if (getResources().getBoolean(R.bool.ignore_sim_network_locked_events)) {
+                        // Some products don't have the concept of a "SIM network lock"
+                        Log.i(LOG_TAG, "Ignoring EVENT_SIM_NETWORK_LOCKED event; "
+                              + "not showing 'SIM network unlock' PIN entry screen");
+                    } else {
+                        // Normal case: show the "SIM network unlock" PIN entry screen.
+                        // The user won't be able to do anything else until
+                        // they enter a valid SIM network PIN.
+                        Log.i(LOG_TAG, "show sim depersonal panel");
+                        IccNetworkDepersonalizationPanel ndpPanel =
+                                new IccNetworkDepersonalizationPanel(PhoneGlobals.getInstance());
+                        ndpPanel.show();
+                    }
+                    break;
+
+                case EVENT_UPDATE_INCALL_NOTIFICATION:
+                    // Tell the NotificationMgr to update the "ongoing
+                    // call" icon in the status bar, if necessary.
+                    // Currently, this is triggered by a bluetooth headset
+                    // state change (since the status bar icon needs to
+                    // turn blue when bluetooth is active.)
+                    if (DBG) Log.d (LOG_TAG, "- updating in-call notification from handler...");
+                    notificationMgr.updateInCallNotification();
+                    break;
+
+                case EVENT_DATA_ROAMING_DISCONNECTED:
+                    notificationMgr.showDataDisconnectedRoaming();
+                    break;
+
+                case EVENT_DATA_ROAMING_OK:
+                    notificationMgr.hideDataDisconnectedRoaming();
+                    break;
+
+                case MMI_COMPLETE:
+                    onMMIComplete((AsyncResult) msg.obj);
+                    break;
+
+                case MMI_CANCEL:
+                    PhoneUtils.cancelMmiCode(phone);
+                    break;
+
+                case EVENT_WIRED_HEADSET_PLUG:
+                    // Since the presence of a wired headset or bluetooth affects the
+                    // speakerphone, update the "speaker" state.  We ONLY want to do
+                    // this on the wired headset connect / disconnect events for now
+                    // though, so we're only triggering on EVENT_WIRED_HEADSET_PLUG.
+
+                    phoneState = mCM.getState();
+                    // Do not change speaker state if phone is not off hook
+                    if (phoneState == PhoneConstants.State.OFFHOOK && !isBluetoothHeadsetAudioOn()) {
+                        if (!isHeadsetPlugged()) {
+                            // if the state is "not connected", restore the speaker state.
+                            PhoneUtils.restoreSpeakerMode(getApplicationContext());
+                        } else {
+                            // if the state is "connected", force the speaker off without
+                            // storing the state.
+                            PhoneUtils.turnOnSpeaker(getApplicationContext(), false, false);
+                        }
+                    }
+                    // Update the Proximity sensor based on headset state
+                    updateProximitySensorMode(phoneState);
+
+                    // Force TTY state update according to new headset state
+                    if (mTtyEnabled) {
+                        sendMessage(obtainMessage(EVENT_TTY_PREFERRED_MODE_CHANGED, 0));
+                    }
+                    break;
+
+                case EVENT_SIM_STATE_CHANGED:
+                    // Marks the event where the SIM goes into ready state.
+                    // Right now, this is only used for the PUK-unlocking
+                    // process.
+                    if (msg.obj.equals(IccCardConstants.INTENT_VALUE_ICC_READY)) {
+                        // when the right event is triggered and there
+                        // are UI objects in the foreground, we close
+                        // them to display the lock panel.
+                        if (mPUKEntryActivity != null) {
+                            mPUKEntryActivity.finish();
+                            mPUKEntryActivity = null;
+                        }
+                        if (mPUKEntryProgressDialog != null) {
+                            mPUKEntryProgressDialog.dismiss();
+                            mPUKEntryProgressDialog = null;
+                        }
+                    }
+                    break;
+
+                case EVENT_UNSOL_CDMA_INFO_RECORD:
+                    //TODO: handle message here;
+                    break;
+
+                case EVENT_DOCK_STATE_CHANGED:
+                    // If the phone is docked/undocked during a call, and no wired or BT headset
+                    // is connected: turn on/off the speaker accordingly.
+                    boolean inDockMode = false;
+                    if (mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED) {
+                        inDockMode = true;
+                    }
+                    if (VDBG) Log.d(LOG_TAG, "received EVENT_DOCK_STATE_CHANGED. Phone inDock = "
+                            + inDockMode);
+
+                    phoneState = mCM.getState();
+                    if (phoneState == PhoneConstants.State.OFFHOOK &&
+                        !isHeadsetPlugged() && !isBluetoothHeadsetAudioOn()) {
+                        PhoneUtils.turnOnSpeaker(getApplicationContext(), inDockMode, true);
+                        updateInCallScreen();  // Has no effect if the InCallScreen isn't visible
+                    }
+                    break;
+
+                case EVENT_TTY_PREFERRED_MODE_CHANGED:
+                    // TTY mode is only applied if a headset is connected
+                    int ttyMode;
+                    if (isHeadsetPlugged()) {
+                        ttyMode = mPreferredTtyMode;
+                    } else {
+                        ttyMode = Phone.TTY_MODE_OFF;
+                    }
+                    phone.setTTYMode(ttyMode, mHandler.obtainMessage(EVENT_TTY_MODE_SET));
+                    break;
+
+                case EVENT_TTY_MODE_GET:
+                    handleQueryTTYModeResponse(msg);
+                    break;
+
+                case EVENT_TTY_MODE_SET:
+                    handleSetTTYModeResponse(msg);
+                    break;
+            }
+        }
+    };
+
+    public PhoneGlobals(Context context) {
+        super(context);
+        sMe = this;
+    }
+
+    public void onCreate() {
+        if (VDBG) Log.v(LOG_TAG, "onCreate()...");
+
+        ContentResolver resolver = getContentResolver();
+
+        // Cache the "voice capable" flag.
+        // This flag currently comes from a resource (which is
+        // overrideable on a per-product basis):
+        sVoiceCapable =
+                getResources().getBoolean(com.android.internal.R.bool.config_voice_capable);
+        // ...but this might eventually become a PackageManager "system
+        // feature" instead, in which case we'd do something like:
+        // sVoiceCapable =
+        //   getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY_VOICE_CALLS);
+
+        if (phone == null) {
+            // Initialize the telephony framework
+            PhoneFactory.makeDefaultPhones(this);
+
+            // Get the default phone
+            phone = PhoneFactory.getDefaultPhone();
+
+            // Start TelephonyDebugService After the default phone is created.
+            Intent intent = new Intent(this, TelephonyDebugService.class);
+            startService(intent);
+
+            mCM = CallManager.getInstance();
+            mCM.registerPhone(phone);
+
+            // Create the NotificationMgr singleton, which is used to display
+            // status bar icons and control other status bar behavior.
+            notificationMgr = NotificationMgr.init(this);
+
+            phoneMgr = PhoneInterfaceManager.init(this, phone);
+
+            mHandler.sendEmptyMessage(EVENT_START_SIP_SERVICE);
+
+            int phoneType = phone.getPhoneType();
+
+            if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
+                // Create an instance of CdmaPhoneCallState and initialize it to IDLE
+                cdmaPhoneCallState = new CdmaPhoneCallState();
+                cdmaPhoneCallState.CdmaPhoneCallStateInit();
+            }
+
+            if (BluetoothAdapter.getDefaultAdapter() != null) {
+                // Start BluetoothPhoneService even if device is not voice capable.
+                // The device can still support VOIP.
+                startService(new Intent(this, BluetoothPhoneService.class));
+                bindService(new Intent(this, BluetoothPhoneService.class),
+                            mBluetoothPhoneConnection, 0);
+            } else {
+                // Device is not bluetooth capable
+                mBluetoothPhone = null;
+            }
+
+            ringer = Ringer.init(this);
+
+            // before registering for phone state changes
+            mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
+            mWakeLock = mPowerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, LOG_TAG);
+            // lock used to keep the processor awake, when we don't care for the display.
+            mPartialWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK
+                    | PowerManager.ON_AFTER_RELEASE, LOG_TAG);
+            // Wake lock used to control proximity sensor behavior.
+            if (mPowerManager.isWakeLockLevelSupported(
+                    PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)) {
+                mProximityWakeLock = mPowerManager.newWakeLock(
+                        PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, LOG_TAG);
+            }
+            if (DBG) Log.d(LOG_TAG, "onCreate: mProximityWakeLock: " + mProximityWakeLock);
+
+            // create mAccelerometerListener only if we are using the proximity sensor
+            if (proximitySensorModeEnabled()) {
+                mAccelerometerListener = new AccelerometerListener(this, this);
+            }
+
+            mKeyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
+
+            // get a handle to the service so that we can use it later when we
+            // want to set the poke lock.
+            mPowerManagerService = IPowerManager.Stub.asInterface(
+                    ServiceManager.getService("power"));
+
+            // Get UpdateLock to suppress system-update related events (e.g. dialog show-up)
+            // during phone calls.
+            mUpdateLock = new UpdateLock("phone");
+
+            if (DBG) Log.d(LOG_TAG, "onCreate: mUpdateLock: " + mUpdateLock);
+
+            CallLogger callLogger = new CallLogger(this, new CallLogAsync());
+
+            // Create the CallController singleton, which is the interface
+            // to the telephony layer for user-initiated telephony functionality
+            // (like making outgoing calls.)
+            callController = CallController.init(this, callLogger);
+            // ...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.
+            //
+            // The asynchronous caching will start just after this call.
+            callerInfoCache = CallerInfoCache.init(this);
+
+            // Monitors call activity from the telephony layer
+            callStateMonitor = new CallStateMonitor(mCM);
+
+            // Create the CallNotifer singleton, which handles
+            // asynchronous events from the telephony layer (like
+            // launching the incoming-call UI when an incoming call comes
+            // in.)
+            notifier = CallNotifier.init(this, phone, ringer, callLogger, callStateMonitor);
+
+            // register for ICC status
+            IccCard sim = phone.getIccCard();
+            if (sim != null) {
+                if (VDBG) Log.v(LOG_TAG, "register for ICC status");
+                sim.registerForNetworkLocked(mHandler, EVENT_SIM_NETWORK_LOCKED, null);
+            }
+
+            // register for MMI/USSD
+            mCM.registerForMmiComplete(mHandler, MMI_COMPLETE, null);
+
+            // register connection tracking to PhoneUtils
+            PhoneUtils.initializeConnectionHandler(mCM);
+
+            // Read platform settings for TTY feature
+            mTtyEnabled = getResources().getBoolean(R.bool.tty_enabled);
+
+            // Register for misc other intent broadcasts.
+            IntentFilter intentFilter =
+                    new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED);
+            intentFilter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
+            intentFilter.addAction(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
+            intentFilter.addAction(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
+            intentFilter.addAction(Intent.ACTION_HEADSET_PLUG);
+            intentFilter.addAction(Intent.ACTION_DOCK_EVENT);
+            intentFilter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
+            intentFilter.addAction(TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED);
+            intentFilter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
+            intentFilter.addAction(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
+            if (mTtyEnabled) {
+                intentFilter.addAction(TtyIntent.TTY_PREFERRED_MODE_CHANGE_ACTION);
+            }
+            intentFilter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
+            registerReceiver(mReceiver, intentFilter);
+
+            // Use a separate receiver for ACTION_MEDIA_BUTTON broadcasts,
+            // since we need to manually adjust its priority (to make sure
+            // we get these intents *before* the media player.)
+            IntentFilter mediaButtonIntentFilter =
+                    new IntentFilter(Intent.ACTION_MEDIA_BUTTON);
+            // TODO verify the independent priority doesn't need to be handled thanks to the
+            //  private intent handler registration
+            // Make sure we're higher priority than the media player's
+            // MediaButtonIntentReceiver (which currently has the default
+            // priority of zero; see apps/Music/AndroidManifest.xml.)
+            mediaButtonIntentFilter.setPriority(1);
+            //
+            registerReceiver(mMediaButtonReceiver, mediaButtonIntentFilter);
+            // register the component so it gets priority for calls
+            AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+            am.registerMediaButtonEventReceiverForCalls(new ComponentName(this.getPackageName(),
+                    MediaButtonBroadcastReceiver.class.getName()));
+
+            //set the default values for the preferences in the phone.
+            PreferenceManager.setDefaultValues(this, R.xml.network_setting, false);
+
+            PreferenceManager.setDefaultValues(this, R.xml.call_feature_setting, false);
+
+            // Make sure the audio mode (along with some
+            // audio-mode-related state of our own) is initialized
+            // correctly, given the current state of the phone.
+            PhoneUtils.setAudioMode(mCM);
+        }
+
+        if (TelephonyCapabilities.supportsOtasp(phone)) {
+            cdmaOtaProvisionData = new OtaUtils.CdmaOtaProvisionData();
+            cdmaOtaConfigData = new OtaUtils.CdmaOtaConfigData();
+            cdmaOtaScreenState = new OtaUtils.CdmaOtaScreenState();
+            cdmaOtaInCallScreenUiState = new OtaUtils.CdmaOtaInCallScreenUiState();
+        }
+
+        // XXX pre-load the SimProvider so that it's ready
+        resolver.getType(Uri.parse("content://icc/adn"));
+
+        // start with the default value to set the mute state.
+        mShouldRestoreMuteOnInCallResume = false;
+
+        // TODO: Register for Cdma Information Records
+        // phone.registerCdmaInformationRecord(mHandler, EVENT_UNSOL_CDMA_INFO_RECORD, null);
+
+        // Read TTY settings and store it into BP NV.
+        // AP owns (i.e. stores) the TTY setting in AP settings database and pushes the setting
+        // to BP at power up (BP does not need to make the TTY setting persistent storage).
+        // This way, there is a single owner (i.e AP) for the TTY setting in the phone.
+        if (mTtyEnabled) {
+            mPreferredTtyMode = android.provider.Settings.Secure.getInt(
+                    phone.getContext().getContentResolver(),
+                    android.provider.Settings.Secure.PREFERRED_TTY_MODE,
+                    Phone.TTY_MODE_OFF);
+            mHandler.sendMessage(mHandler.obtainMessage(EVENT_TTY_PREFERRED_MODE_CHANGED, 0));
+        }
+        // Read HAC settings and configure audio hardware
+        if (getResources().getBoolean(R.bool.hac_enabled)) {
+            int hac = android.provider.Settings.System.getInt(phone.getContext().getContentResolver(),
+                                                              android.provider.Settings.System.HEARING_AID,
+                                                              0);
+            AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+            audioManager.setParameter(CallFeaturesSetting.HAC_KEY, hac != 0 ?
+                                      CallFeaturesSetting.HAC_VAL_ON :
+                                      CallFeaturesSetting.HAC_VAL_OFF);
+        }
+   }
+
+    public void onConfigurationChanged(Configuration newConfig) {
+        if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO) {
+            mIsHardKeyboardOpen = true;
+        } else {
+            mIsHardKeyboardOpen = false;
+        }
+
+        // Update the Proximity sensor based on keyboard state
+        updateProximitySensorMode(mCM.getState());
+    }
+
+    /**
+     * Returns the singleton instance of the PhoneApp.
+     */
+    static PhoneGlobals getInstance() {
+        if (sMe == null) {
+            throw new IllegalStateException("No PhoneGlobals here!");
+        }
+        return sMe;
+    }
+
+    /**
+     * Returns the singleton instance of the PhoneApp if running as the
+     * primary user, otherwise null.
+     */
+    static PhoneGlobals getInstanceIfPrimary() {
+        return sMe;
+    }
+
+    /**
+     * Returns the Phone associated with this instance
+     */
+    static Phone getPhone() {
+        return getInstance().phone;
+    }
+
+    Ringer getRinger() {
+        return ringer;
+    }
+
+    IBluetoothHeadsetPhone getBluetoothPhoneService() {
+        return mBluetoothPhone;
+    }
+
+    boolean isBluetoothHeadsetAudioOn() {
+        return (mBluetoothHeadsetAudioState != BluetoothHeadset.STATE_AUDIO_DISCONNECTED);
+    }
+
+    /**
+     * Returns an Intent that can be used to go to the "Call log"
+     * UI (aka CallLogActivity) in the Contacts app.
+     *
+     * Watch out: there's no guarantee that the system has any activity to
+     * handle this intent.  (In particular there may be no "Call log" at
+     * all on on non-voice-capable devices.)
+     */
+    /* package */ static Intent createCallLogIntent() {
+        Intent intent = new Intent(Intent.ACTION_VIEW, null);
+        intent.setType("vnd.android.cursor.dir/calls");
+        return intent;
+    }
+
+    /**
+     * 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.
+     */
+    /* package */ static PendingIntent createHangUpOngoingCallPendingIntent(Context context) {
+        Intent intent = new Intent(PhoneGlobals.ACTION_HANG_UP_ONGOING_CALL, null,
+                context, NotificationBroadcastReceiver.class);
+        return PendingIntent.getBroadcast(context, 0, intent, 0);
+    }
+
+    /* package */ static PendingIntent getCallBackPendingIntent(Context context, String number) {
+        Intent intent = new Intent(ACTION_CALL_BACK_FROM_NOTIFICATION,
+                Uri.fromParts(Constants.SCHEME_TEL, number, null),
+                context, NotificationBroadcastReceiver.class);
+        return PendingIntent.getBroadcast(context, 0, intent, 0);
+    }
+
+    /* package */ static PendingIntent getSendSmsFromNotificationPendingIntent(
+            Context context, String number) {
+        Intent intent = new Intent(ACTION_SEND_SMS_FROM_NOTIFICATION,
+                Uri.fromParts(Constants.SCHEME_SMSTO, number, null),
+                context, NotificationBroadcastReceiver.class);
+        return PendingIntent.getBroadcast(context, 0, intent, 0);
+    }
+
+    private static String getCallScreenClassName() {
+        return InCallScreen.class.getName();
+    }
+
+    /**
+     * 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;
+    }
+
+    boolean authenticateAgainstCachedSimPin(String pin) {
+        return (mCachedSimPin != null && mCachedSimPin.equals(pin));
+    }
+
+    void setCachedSimPin(String pin) {
+        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();
+    }
+
+    /**
+     * @return true if the in-call UI is running as the foreground activity, or,
+     * it went to background due to screen being turned off. This might be useful
+     * to determine if the in-call screen went to background because of other
+     * activities, or its proximity sensor state or manual power-button press.
+     *
+     * Here are some examples.
+     *
+     * - If you want to know if the activity is in foreground or screen is turned off
+     *   from the in-call UI (i.e. though it is not "foreground" anymore it will become
+     *   so after screen being turned on), check
+     *   {@link #isShowingCallScreenForProximity()} is true or not.
+     *   {@link #updateProximitySensorMode(com.android.internal.telephony.PhoneConstants.State)} is
+     *   doing this.
+     *
+     * - If you want to know if the activity is not in foreground just because screen
+     *   is turned off (not due to other activity's interference), check
+     *   {@link #isShowingCallScreen()} is false *and* {@link #isShowingCallScreenForProximity()}
+     *   is true. InCallScreen#onDisconnect() is doing this check.
+     *
+     * @see #isShowingCallScreen()
+     *
+     * TODO: come up with better naming..
+     */
+    boolean isShowingCallScreenForProximity() {
+        if (mInCallScreen == null) return false;
+        return mInCallScreen.isForegroundActivityForProximity();
+    }
+
+    /**
+     * 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.
+     *
+     * While an OTASP call is active, the CallNotifier forwards
+     * OTASP-related telephony events to this method.
+     */
+    void handleOtaspEvent(Message msg) {
+        if (DBG) Log.d(LOG_TAG, "handleOtaspEvent(message " + msg + ")...");
+
+        if (otaUtils == null) {
+            // We shouldn't be getting OTASP events without ever
+            // having started the OTASP call in the first place!
+            Log.w(LOG_TAG, "handleOtaEvents: got an event but otaUtils is null! "
+                  + "message = " + msg);
+            return;
+        }
+
+        otaUtils.onOtaProvisionStatusChanged((AsyncResult) msg.obj);
+    }
+
+    /**
+     * Similarly, handle the disconnect event of an OTASP call
+     * by forwarding it to the OtaUtils instance.
+     */
+    /* package */ void handleOtaspDisconnect() {
+        if (DBG) Log.d(LOG_TAG, "handleOtaspDisconnect()...");
+
+        if (otaUtils == null) {
+            // We shouldn't be getting OTASP events without ever
+            // having started the OTASP call in the first place!
+            Log.w(LOG_TAG, "handleOtaspDisconnect: otaUtils is null!");
+            return;
+        }
+
+        otaUtils.onOtaspDisconnect();
+    }
+
+    /**
+     * Sets the activity responsible for un-PUK-blocking the device
+     * so that we may close it when we receive a positive result.
+     * mPUKEntryActivity is also used to indicate to the device that
+     * we are trying to un-PUK-lock the phone. In other words, iff
+     * it is NOT null, then we are trying to unlock and waiting for
+     * the SIM to move to READY state.
+     *
+     * @param activity is the activity to close when PUK has
+     * finished unlocking. Can be set to null to indicate the unlock
+     * or SIM READYing process is over.
+     */
+    void setPukEntryActivity(Activity activity) {
+        mPUKEntryActivity = activity;
+    }
+
+    Activity getPUKEntryActivity() {
+        return mPUKEntryActivity;
+    }
+
+    /**
+     * Sets the dialog responsible for notifying the user of un-PUK-
+     * blocking - SIM READYing progress, so that we may dismiss it
+     * when we receive a positive result.
+     *
+     * @param dialog indicates the progress dialog informing the user
+     * of the state of the device.  Dismissed upon completion of
+     * READYing process
+     */
+    void setPukEntryProgressDialog(ProgressDialog dialog) {
+        mPUKEntryProgressDialog = dialog;
+    }
+
+    ProgressDialog getPUKEntryProgressDialog() {
+        return mPUKEntryProgressDialog;
+    }
+
+    /**
+     * Controls whether or not the screen is allowed to sleep.
+     *
+     * Once sleep is allowed (WakeState is SLEEP), it will rely on the
+     * settings for the poke lock to determine when to timeout and let
+     * the device sleep {@link PhoneGlobals#setScreenTimeout}.
+     *
+     * @param ws tells the device to how to wake.
+     */
+    /* package */ void requestWakeState(WakeState ws) {
+        if (VDBG) Log.d(LOG_TAG, "requestWakeState(" + ws + ")...");
+        synchronized (this) {
+            if (mWakeState != ws) {
+                switch (ws) {
+                    case PARTIAL:
+                        // acquire the processor wake lock, and release the FULL
+                        // lock if it is being held.
+                        mPartialWakeLock.acquire();
+                        if (mWakeLock.isHeld()) {
+                            mWakeLock.release();
+                        }
+                        break;
+                    case FULL:
+                        // acquire the full wake lock, and release the PARTIAL
+                        // lock if it is being held.
+                        mWakeLock.acquire();
+                        if (mPartialWakeLock.isHeld()) {
+                            mPartialWakeLock.release();
+                        }
+                        break;
+                    case SLEEP:
+                    default:
+                        // release both the PARTIAL and FULL locks.
+                        if (mWakeLock.isHeld()) {
+                            mWakeLock.release();
+                        }
+                        if (mPartialWakeLock.isHeld()) {
+                            mPartialWakeLock.release();
+                        }
+                        break;
+                }
+                mWakeState = ws;
+            }
+        }
+    }
+
+    /**
+     * If we are not currently keeping the screen on, then poke the power
+     * manager to wake up the screen for the user activity timeout duration.
+     */
+    /* package */ void wakeUpScreen() {
+        synchronized (this) {
+            if (mWakeState == WakeState.SLEEP) {
+                if (DBG) Log.d(LOG_TAG, "pulse screen lock");
+                mPowerManager.wakeUp(SystemClock.uptimeMillis());
+            }
+        }
+    }
+
+    /**
+     * Sets the wake state and screen timeout based on the current state
+     * of the phone, and the current state of the in-call UI.
+     *
+     * This method is a "UI Policy" wrapper around
+     * {@link PhoneGlobals#requestWakeState} and {@link PhoneGlobals#setScreenTimeout}.
+     *
+     * It's safe to call this method regardless of the state of the Phone
+     * (e.g. whether or not it's idle), and regardless of the state of the
+     * Phone UI (e.g. whether or not the InCallScreen is active.)
+     */
+    /* 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
+        // false touches, and thus don't need to turn the screen off so
+        // aggressively.)
+        // Note that we need to make a fresh call to this method any
+        // time the speaker state changes.  (That happens in
+        // PhoneUtils.turnOnSpeaker().)
+        boolean isSpeakerInUse = (state == PhoneConstants.State.OFFHOOK) && PhoneUtils.isSpeakerOn(this);
+
+        // TODO (bug 1440854): The screen timeout *might* also need to
+        // depend on the bluetooth state, but this isn't as clear-cut as
+        // the speaker state (since while using BT it's common for the
+        // 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,
+        // or if we're displaying the "Call ended" UI for a connection in
+        // the "disconnected" state.
+        // However, if the phone is disconnected while the user is in the
+        // middle of selecting a quick response message, we should not force
+        // the screen to be on.
+        //
+        boolean isRinging = (state == PhoneConstants.State.RINGING);
+        boolean isDialing = (phone.getForegroundCall().getState() == Call.State.DIALING);
+        boolean showingQuickResponseDialog = (mInCallScreen != null) &&
+                mInCallScreen.isQuickResponseDialogShowing();
+        boolean showingDisconnectedConnection =
+                PhoneUtils.hasDisconnectedConnections(phone) && isShowingCallScreen;
+        boolean keepScreenOn = isRinging || isDialing ||
+                (showingDisconnectedConnection && !showingQuickResponseDialog);
+        if (DBG) Log.d(LOG_TAG, "updateWakeState: keepScreenOn = " + keepScreenOn
+                       + " (isRinging " + isRinging
+                       + ", isDialing " + isDialing
+                       + ", showingQuickResponse " + showingQuickResponseDialog
+                       + ", showingDisc " + showingDisconnectedConnection + ")");
+        // keepScreenOn == true means we'll hold a full wake lock:
+        requestWakeState(keepScreenOn ? WakeState.FULL : WakeState.SLEEP);
+    }
+
+    /**
+     * Manually pokes the PowerManager's userActivity method.  Since we
+     * set the {@link WindowManager.LayoutParams#INPUT_FEATURE_DISABLE_USER_ACTIVITY}
+     * flag while the InCallScreen is active when there is no proximity sensor,
+     * we need to do this for touch events that really do count as user activity
+     * (like pressing any onscreen UI elements.)
+     */
+    /* package */ void pokeUserActivity() {
+        if (VDBG) Log.d(LOG_TAG, "pokeUserActivity()...");
+        mPowerManager.userActivity(SystemClock.uptimeMillis(), false);
+    }
+
+    /**
+     * Set when a new outgoing call is beginning, so we can update
+     * the proximity sensor state.
+     * Cleared when the InCallScreen is no longer in the foreground,
+     * in case the call fails without changing the telephony state.
+     */
+    /* package */ void setBeginningCall(boolean beginning) {
+        // Note that we are beginning a new call, for proximity sensor support
+        mBeginningCall = beginning;
+        // Update the Proximity sensor based on mBeginningCall state
+        updateProximitySensorMode(mCM.getState());
+    }
+
+    /**
+     * Updates the wake lock used to control proximity sensor behavior,
+     * based on the current state of the phone.  This method is called
+     * from the CallNotifier on any phone state change.
+     *
+     * On devices that have a proximity sensor, to avoid false touches
+     * during a call, we hold a PROXIMITY_SCREEN_OFF_WAKE_LOCK wake lock
+     * whenever the phone is off hook.  (When held, that wake lock causes
+     * the screen to turn off automatically when the sensor detects an
+     * object close to the screen.)
+     *
+     * This method is a no-op for devices that don't have a proximity
+     * sensor.
+     *
+     * Note this method doesn't care if the InCallScreen is the foreground
+     * activity or not.  That's because we want the proximity sensor to be
+     * enabled any time the phone is in use, to avoid false cheek events
+     * for whatever app you happen to be running.
+     *
+     * Proximity wake lock will *not* be held if any one of the
+     * conditions is true while on a call:
+     * 1) If the audio is routed via Bluetooth
+     * 2) If a wired headset is connected
+     * 3) if the speaker is ON
+     * 4) If the slider is open(i.e. the hardkeyboard is *not* hidden)
+     *
+     * @param state current state of the phone (see {@link Phone#State})
+     */
+    /* package */ void updateProximitySensorMode(PhoneConstants.State state) {
+        if (VDBG) Log.d(LOG_TAG, "updateProximitySensorMode: state = " + state);
+
+        if (proximitySensorModeEnabled()) {
+            synchronized (mProximityWakeLock) {
+                // turn proximity sensor off and turn screen on immediately if
+                // we are using a headset, the keyboard is open, or the device
+                // is being held in a horizontal position.
+                boolean screenOnImmediately = (isHeadsetPlugged()
+                                               || PhoneUtils.isSpeakerOn(this)
+                                               || isBluetoothHeadsetAudioOn()
+                                               || mIsHardKeyboardOpen);
+
+                // We do not keep the screen off when the user is outside in-call screen and we are
+                // horizontal, but we do not force it on when we become horizontal until the
+                // proximity sensor goes negative.
+                boolean horizontal =
+                        (mOrientation == AccelerometerListener.ORIENTATION_HORIZONTAL);
+                screenOnImmediately |= !isShowingCallScreenForProximity() && horizontal;
+
+                // We do not keep the screen off when dialpad is visible, we are horizontal, and
+                // the in-call screen is being shown.
+                // At that moment we're pretty sure users want to use it, instead of letting the
+                // proximity sensor turn off the screen by their hands.
+                boolean dialpadVisible = false;
+                if (mInCallScreen != null) {
+                    dialpadVisible =
+                            mInCallScreen.getUpdatedInCallControlState().dialpadEnabled
+                            && mInCallScreen.getUpdatedInCallControlState().dialpadVisible
+                            && isShowingCallScreen();
+                }
+                screenOnImmediately |= dialpadVisible && horizontal;
+
+                if (((state == PhoneConstants.State.OFFHOOK) || mBeginningCall) && !screenOnImmediately) {
+                    // Phone is in use!  Arrange for the screen to turn off
+                    // automatically when the sensor detects a close object.
+                    if (!mProximityWakeLock.isHeld()) {
+                        if (DBG) Log.d(LOG_TAG, "updateProximitySensorMode: acquiring...");
+                        mProximityWakeLock.acquire();
+                    } else {
+                        if (VDBG) Log.d(LOG_TAG, "updateProximitySensorMode: lock already held.");
+                    }
+                } else {
+                    // Phone is either idle, or ringing.  We don't want any
+                    // special proximity sensor behavior in either case.
+                    if (mProximityWakeLock.isHeld()) {
+                        if (DBG) Log.d(LOG_TAG, "updateProximitySensorMode: releasing...");
+                        // Wait until user has moved the phone away from his head if we are
+                        // releasing due to the phone call ending.
+                        // Qtherwise, turn screen on immediately
+                        int flags =
+                            (screenOnImmediately ? 0 : PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE);
+                        mProximityWakeLock.release(flags);
+                    } else {
+                        if (VDBG) {
+                            Log.d(LOG_TAG, "updateProximitySensorMode: lock already released.");
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    public void orientationChanged(int orientation) {
+        mOrientation = orientation;
+        updateProximitySensorMode(mCM.getState());
+    }
+
+    /**
+     * Notifies the phone app when the phone state changes.
+     *
+     * This method will updates various states inside Phone app (e.g. proximity sensor mode,
+     * accelerometer listener state, update-lock state, etc.)
+     */
+    /* package */ void updatePhoneState(PhoneConstants.State state) {
+        if (state != mLastPhoneState) {
+            mLastPhoneState = state;
+            updateProximitySensorMode(state);
+
+            // Try to acquire or release UpdateLock.
+            //
+            // Watch out: we don't release the lock here when the screen is still in foreground.
+            // At that time InCallScreen will release it on onPause().
+            if (state != PhoneConstants.State.IDLE) {
+                // UpdateLock is a recursive lock, while we may get "acquire" request twice and
+                // "release" request once for a single call (RINGING + OFFHOOK and IDLE).
+                // We need to manually ensure the lock is just acquired once for each (and this
+                // will prevent other possible buggy situations too).
+                if (!mUpdateLock.isHeld()) {
+                    mUpdateLock.acquire();
+                }
+            } else {
+                if (!isShowingCallScreen()) {
+                    if (!mUpdateLock.isHeld()) {
+                        mUpdateLock.release();
+                    }
+                } else {
+                    // For this case InCallScreen will take care of the release() call.
+                }
+            }
+
+            if (mAccelerometerListener != null) {
+                // use accelerometer to augment proximity sensor when in call
+                mOrientation = AccelerometerListener.ORIENTATION_UNKNOWN;
+                mAccelerometerListener.enable(state == PhoneConstants.State.OFFHOOK);
+            }
+            // clear our beginning call flag
+            mBeginningCall = false;
+            // 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);
+            }
+        }
+    }
+
+    /* package */ PhoneConstants.State getPhoneState() {
+        return mLastPhoneState;
+    }
+
+    /**
+     * Returns UpdateLock object.
+     */
+    /* package */ UpdateLock getUpdateLock() {
+        return mUpdateLock;
+    }
+
+    /**
+     * @return true if this device supports the "proximity sensor
+     * auto-lock" feature while in-call (see updateProximitySensorMode()).
+     */
+    /* package */ boolean proximitySensorModeEnabled() {
+        return (mProximityWakeLock != null);
+    }
+
+    KeyguardManager getKeyguardManager() {
+        return mKeyguardManager;
+    }
+
+    private void onMMIComplete(AsyncResult r) {
+        if (VDBG) Log.d(LOG_TAG, "onMMIComplete()...");
+        MmiCode mmiCode = (MmiCode) r.result;
+        PhoneUtils.displayMMIComplete(phone, getInstance(), mmiCode, null, null);
+    }
+
+    private void initForNewRadioTechnology() {
+        if (DBG) Log.d(LOG_TAG, "initForNewRadioTechnology...");
+
+         if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
+            // Create an instance of CdmaPhoneCallState and initialize it to IDLE
+            cdmaPhoneCallState = new CdmaPhoneCallState();
+            cdmaPhoneCallState.CdmaPhoneCallStateInit();
+        }
+        if (TelephonyCapabilities.supportsOtasp(phone)) {
+            //create instances of CDMA OTA data classes
+            if (cdmaOtaProvisionData == null) {
+                cdmaOtaProvisionData = new OtaUtils.CdmaOtaProvisionData();
+            }
+            if (cdmaOtaConfigData == null) {
+                cdmaOtaConfigData = new OtaUtils.CdmaOtaConfigData();
+            }
+            if (cdmaOtaScreenState == null) {
+                cdmaOtaScreenState = new OtaUtils.CdmaOtaScreenState();
+            }
+            if (cdmaOtaInCallScreenUiState == null) {
+                cdmaOtaInCallScreenUiState = new OtaUtils.CdmaOtaInCallScreenUiState();
+            }
+        } else {
+            //Clean up OTA data in GSM/UMTS. It is valid only for CDMA
+            clearOtaState();
+        }
+
+        ringer.updateRingerContextAfterRadioTechnologyChange(this.phone);
+        notifier.updateCallNotifierRegistrationsAfterRadioTechnologyChange();
+        callStateMonitor.updateAfterRadioTechnologyChange();
+
+        if (mBluetoothPhone != null) {
+            try {
+                mBluetoothPhone.updateBtHandsfreeAfterRadioTechnologyChange();
+            } catch (RemoteException e) {
+                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();
+        if (sim != null) {
+            if (DBG) Log.d(LOG_TAG, "Update registration for ICC status...");
+
+            //Register all events new to the new active phone
+            sim.registerForNetworkLocked(mHandler, EVENT_SIM_NETWORK_LOCKED, null);
+        }
+    }
+
+
+    /**
+     * @return true if a wired headset is currently plugged in.
+     *
+     * @see Intent.ACTION_HEADSET_PLUG (which we listen for in mReceiver.onReceive())
+     */
+    boolean isHeadsetPlugged() {
+        return mIsHeadsetPlugged;
+    }
+
+    /**
+     * @return true if the onscreen UI should currently be showing the
+     * special "bluetooth is active" indication in a couple of places (in
+     * which UI elements turn blue and/or show the bluetooth logo.)
+     *
+     * This depends on the BluetoothHeadset state *and* the current
+     * telephony state; see shouldShowBluetoothIndication().
+     *
+     * @see CallCard
+     * @see NotificationMgr.updateInCallNotification
+     */
+    /* package */ boolean showBluetoothIndication() {
+        return mShowBluetoothIndication;
+    }
+
+    /**
+     * Recomputes the mShowBluetoothIndication flag based on the current
+     * bluetooth state and current telephony state.
+     *
+     * This needs to be called any time the bluetooth headset state or the
+     * telephony state changes.
+     *
+     * @param forceUiUpdate if true, force the UI elements that care
+     *                      about this flag to update themselves.
+     */
+    /* package */ void updateBluetoothIndication(boolean forceUiUpdate) {
+        mShowBluetoothIndication = shouldShowBluetoothIndication(mBluetoothHeadsetState,
+                                                                 mBluetoothHeadsetAudioState,
+                                                                 mCM);
+        if (forceUiUpdate) {
+            // Post Handler messages to the various components that might
+            // need to be refreshed based on the new state.
+            if (isShowingCallScreen()) mInCallScreen.requestUpdateBluetoothIndication();
+            if (DBG) Log.d (LOG_TAG, "- updating in-call notification for BT state change...");
+            mHandler.sendEmptyMessage(EVENT_UPDATE_INCALL_NOTIFICATION);
+        }
+
+        // Update the Proximity sensor based on Bluetooth audio state
+        updateProximitySensorMode(mCM.getState());
+    }
+
+    /**
+     * UI policy helper function for the couple of places in the UI that
+     * have some way of indicating that "bluetooth is in use."
+     *
+     * @return true if the onscreen UI should indicate that "bluetooth is in use",
+     *         based on the specified bluetooth headset state, and the
+     *         current state of the phone.
+     * @see showBluetoothIndication()
+     */
+    private static boolean shouldShowBluetoothIndication(int bluetoothState,
+                                                         int bluetoothAudioState,
+                                                         CallManager cm) {
+        // We want the UI to indicate that "bluetooth is in use" in two
+        // slightly different cases:
+        //
+        // (a) The obvious case: if a bluetooth headset is currently in
+        //     use for an ongoing call.
+        //
+        // (b) The not-so-obvious case: if an incoming call is ringing,
+        //     and we expect that audio *will* be routed to a bluetooth
+        //     headset once the call is answered.
+
+        switch (cm.getState()) {
+            case OFFHOOK:
+                // This covers normal active calls, and also the case if
+                // the foreground call is DIALING or ALERTING.  In this
+                // case, bluetooth is considered "active" if a headset
+                // is connected *and* audio is being routed to it.
+                return ((bluetoothState == BluetoothHeadset.STATE_CONNECTED)
+                        && (bluetoothAudioState == BluetoothHeadset.STATE_AUDIO_CONNECTED));
+
+            case RINGING:
+                // If an incoming call is ringing, we're *not* yet routing
+                // audio to the headset (since there's no in-call audio
+                // yet!)  In this case, if a bluetooth headset is
+                // connected at all, we assume that it'll become active
+                // once the user answers the phone.
+                return (bluetoothState == BluetoothHeadset.STATE_CONNECTED);
+
+            default:  // Presumably IDLE
+                return false;
+        }
+    }
+
+
+    /**
+     * Receiver for misc intent broadcasts the Phone app cares about.
+     */
+    private class PhoneAppBroadcastReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (action.equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) {
+                boolean enabled = System.getInt(getContentResolver(),
+                        System.AIRPLANE_MODE_ON, 0) == 0;
+                phone.setRadioPower(enabled);
+            } else if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
+                mBluetoothHeadsetState = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE,
+                                                          BluetoothHeadset.STATE_DISCONNECTED);
+                if (VDBG) Log.d(LOG_TAG, "mReceiver: HEADSET_STATE_CHANGED_ACTION");
+                if (VDBG) Log.d(LOG_TAG, "==> new state: " + mBluetoothHeadsetState);
+                updateBluetoothIndication(true);  // Also update any visible UI if necessary
+            } else if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
+                mBluetoothHeadsetAudioState =
+                        intent.getIntExtra(BluetoothHeadset.EXTRA_STATE,
+                                           BluetoothHeadset.STATE_AUDIO_DISCONNECTED);
+                if (VDBG) Log.d(LOG_TAG, "mReceiver: HEADSET_AUDIO_STATE_CHANGED_ACTION");
+                if (VDBG) Log.d(LOG_TAG, "==> new state: " + mBluetoothHeadsetAudioState);
+                updateBluetoothIndication(true);  // Also update any visible UI if necessary
+            } else if (action.equals(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED)) {
+                if (VDBG) Log.d(LOG_TAG, "mReceiver: ACTION_ANY_DATA_CONNECTION_STATE_CHANGED");
+                if (VDBG) Log.d(LOG_TAG, "- state: " + intent.getStringExtra(PhoneConstants.STATE_KEY));
+                if (VDBG) Log.d(LOG_TAG, "- reason: "
+                                + intent.getStringExtra(PhoneConstants.STATE_CHANGE_REASON_KEY));
+
+                // The "data disconnected due to roaming" notification is shown
+                // if (a) you have the "data roaming" feature turned off, and
+                // (b) you just lost data connectivity because you're roaming.
+                boolean disconnectedDueToRoaming =
+                        !phone.getDataRoamingEnabled()
+                        && "DISCONNECTED".equals(intent.getStringExtra(PhoneConstants.STATE_KEY))
+                        && Phone.REASON_ROAMING_ON.equals(
+                            intent.getStringExtra(PhoneConstants.STATE_CHANGE_REASON_KEY));
+                mHandler.sendEmptyMessage(disconnectedDueToRoaming
+                                          ? EVENT_DATA_ROAMING_DISCONNECTED
+                                          : EVENT_DATA_ROAMING_OK);
+            } else if (action.equals(Intent.ACTION_HEADSET_PLUG)) {
+                if (VDBG) Log.d(LOG_TAG, "mReceiver: ACTION_HEADSET_PLUG");
+                if (VDBG) Log.d(LOG_TAG, "    state: " + intent.getIntExtra("state", 0));
+                if (VDBG) Log.d(LOG_TAG, "    name: " + intent.getStringExtra("name"));
+                mIsHeadsetPlugged = (intent.getIntExtra("state", 0) == 1);
+                mHandler.sendMessage(mHandler.obtainMessage(EVENT_WIRED_HEADSET_PLUG, 0));
+            } else if ((action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) &&
+                    (mPUKEntryActivity != null)) {
+                // if an attempt to un-PUK-lock the device was made, while we're
+                // receiving this state change notification, notify the handler.
+                // NOTE: This is ONLY triggered if an attempt to un-PUK-lock has
+                // been attempted.
+                mHandler.sendMessage(mHandler.obtainMessage(EVENT_SIM_STATE_CHANGED,
+                        intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE)));
+            } else if (action.equals(TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED)) {
+                String newPhone = intent.getStringExtra(PhoneConstants.PHONE_NAME_KEY);
+                Log.d(LOG_TAG, "Radio technology switched. Now " + newPhone + " is active.");
+                initForNewRadioTechnology();
+            } else if (action.equals(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED)) {
+                handleServiceStateChanged(intent);
+            } else if (action.equals(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED)) {
+                if (TelephonyCapabilities.supportsEcm(phone)) {
+                    Log.d(LOG_TAG, "Emergency Callback Mode arrived in PhoneApp.");
+                    // Start Emergency Callback Mode service
+                    if (intent.getBooleanExtra("phoneinECMState", false)) {
+                        context.startService(new Intent(context,
+                                EmergencyCallbackModeService.class));
+                    }
+                } else {
+                    // It doesn't make sense to get ACTION_EMERGENCY_CALLBACK_MODE_CHANGED
+                    // on a device that doesn't support ECM in the first place.
+                    Log.e(LOG_TAG, "Got ACTION_EMERGENCY_CALLBACK_MODE_CHANGED, "
+                          + "but ECM isn't supported for phone: " + phone.getPhoneName());
+                }
+            } else if (action.equals(Intent.ACTION_DOCK_EVENT)) {
+                mDockState = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
+                        Intent.EXTRA_DOCK_STATE_UNDOCKED);
+                if (VDBG) Log.d(LOG_TAG, "ACTION_DOCK_EVENT -> mDockState = " + mDockState);
+                mHandler.sendMessage(mHandler.obtainMessage(EVENT_DOCK_STATE_CHANGED, 0));
+            } else if (action.equals(TtyIntent.TTY_PREFERRED_MODE_CHANGE_ACTION)) {
+                mPreferredTtyMode = intent.getIntExtra(TtyIntent.TTY_PREFFERED_MODE,
+                                                       Phone.TTY_MODE_OFF);
+                if (VDBG) Log.d(LOG_TAG, "mReceiver: TTY_PREFERRED_MODE_CHANGE_ACTION");
+                if (VDBG) Log.d(LOG_TAG, "    mode: " + mPreferredTtyMode);
+                mHandler.sendMessage(mHandler.obtainMessage(EVENT_TTY_PREFERRED_MODE_CHANGED, 0));
+            } else if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) {
+                int ringerMode = intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE,
+                        AudioManager.RINGER_MODE_NORMAL);
+                if (ringerMode == AudioManager.RINGER_MODE_SILENT) {
+                    notifier.silenceRinger();
+                }
+            }
+        }
+    }
+
+    /**
+     * Broadcast receiver for the ACTION_MEDIA_BUTTON broadcast intent.
+     *
+     * This functionality isn't lumped in with the other intents in
+     * PhoneAppBroadcastReceiver because we instantiate this as a totally
+     * separate BroadcastReceiver instance, since we need to manually
+     * adjust its IntentFilter's priority (to make sure we get these
+     * intents *before* the media player.)
+     */
+    private class MediaButtonBroadcastReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            KeyEvent event = (KeyEvent) intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
+            if (VDBG) Log.d(LOG_TAG,
+                           "MediaButtonBroadcastReceiver.onReceive()...  event = " + event);
+            if ((event != null)
+                && (event.getKeyCode() == KeyEvent.KEYCODE_HEADSETHOOK)) {
+                if (VDBG) Log.d(LOG_TAG, "MediaButtonBroadcastReceiver: HEADSETHOOK");
+                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 {
+                if (mCM.getState() != PhoneConstants.State.IDLE) {
+                    // If the phone is anything other than completely idle,
+                    // then we consume and ignore any media key events,
+                    // Otherwise it is too easy to accidentally start
+                    // playing music while a phone call is in progress.
+                    if (VDBG) Log.d(LOG_TAG, "MediaButtonBroadcastReceiver: consumed");
+                    abortBroadcast();
+                }
+            }
+        }
+    }
+
+    /**
+     * Accepts broadcast Intents which will be prepared by {@link NotificationMgr} and thus
+     * sent from framework's notification mechanism (which is outside Phone context).
+     * This should be visible from outside, but shouldn't be in "exported" state.
+     *
+     * TODO: If possible merge this into PhoneAppBroadcastReceiver.
+     */
+    public static class NotificationBroadcastReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            // TODO: use "if (VDBG)" here.
+            Log.d(LOG_TAG, "Broadcast from Notification: " + action);
+
+            if (action.equals(ACTION_HANG_UP_ONGOING_CALL)) {
+                PhoneUtils.hangup(PhoneGlobals.getInstance().mCM);
+            } else if (action.equals(ACTION_CALL_BACK_FROM_NOTIFICATION)) {
+                // Collapse the expanded notification and the notification item itself.
+                closeSystemDialogs(context);
+                clearMissedCallNotification(context);
+
+                Intent callIntent = new Intent(Intent.ACTION_CALL_PRIVILEGED, intent.getData());
+                callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                        | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+                context.startActivity(callIntent);
+            } else if (action.equals(ACTION_SEND_SMS_FROM_NOTIFICATION)) {
+                // Collapse the expanded notification and the notification item itself.
+                closeSystemDialogs(context);
+                clearMissedCallNotification(context);
+
+                Intent smsIntent = new Intent(Intent.ACTION_SENDTO, intent.getData());
+                smsIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                context.startActivity(smsIntent);
+            } else {
+                Log.w(LOG_TAG, "Received hang-up request from notification,"
+                        + " but there's no call the system can hang up.");
+            }
+        }
+
+        private void closeSystemDialogs(Context context) {
+            Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
+            context.sendBroadcastAsUser(intent, UserHandle.ALL);
+        }
+
+        private void clearMissedCallNotification(Context context) {
+            Intent clearIntent = new Intent(context, ClearMissedCallsService.class);
+            clearIntent.setAction(ClearMissedCallsService.ACTION_CLEAR_MISSED_CALLS);
+            context.startService(clearIntent);
+        }
+    }
+
+    private void handleServiceStateChanged(Intent intent) {
+        /**
+         * This used to handle updating EriTextWidgetProvider this routine
+         * and and listening for ACTION_SERVICE_STATE_CHANGED intents could
+         * be removed. But leaving just in case it might be needed in the near
+         * future.
+         */
+
+        // If service just returned, start sending out the queued messages
+        ServiceState ss = ServiceState.newFromBundle(intent.getExtras());
+
+        if (ss != null) {
+            int state = ss.getState();
+            notificationMgr.updateNetworkSelection(state);
+        }
+    }
+
+    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;
+    }
+
+    // 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)) {
+            otaUtils.cleanOtaScreen(true);
+            if (DBG) Log.d(LOG_TAG, "  - clearOtaState clears OTA screen");
+        }
+    }
+
+    // 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)) {
+            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) {
+            if (DBG) Log.d(LOG_TAG, "handleQueryTTYModeResponse: Error getting TTY state.");
+        } else {
+            if (DBG) Log.d(LOG_TAG,
+                           "handleQueryTTYModeResponse: TTY enable state successfully queried.");
+
+            int ttymode = ((int[]) ar.result)[0];
+            if (DBG) Log.d(LOG_TAG, "handleQueryTTYModeResponse:ttymode=" + ttymode);
+
+            Intent ttyModeChanged = new Intent(TtyIntent.TTY_ENABLED_CHANGE_ACTION);
+            ttyModeChanged.putExtra("ttyEnabled", ttymode != Phone.TTY_MODE_OFF);
+            sendBroadcastAsUser(ttyModeChanged, UserHandle.ALL);
+
+            String audioTtyMode;
+            switch (ttymode) {
+            case Phone.TTY_MODE_FULL:
+                audioTtyMode = "tty_full";
+                break;
+            case Phone.TTY_MODE_VCO:
+                audioTtyMode = "tty_vco";
+                break;
+            case Phone.TTY_MODE_HCO:
+                audioTtyMode = "tty_hco";
+                break;
+            case Phone.TTY_MODE_OFF:
+            default:
+                audioTtyMode = "tty_off";
+                break;
+            }
+            AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+            audioManager.setParameters("tty_mode="+audioTtyMode);
+        }
+    }
+
+    private void handleSetTTYModeResponse(Message msg) {
+        AsyncResult ar = (AsyncResult) msg.obj;
+
+        if (ar.exception != null) {
+            if (DBG) Log.d (LOG_TAG,
+                    "handleSetTTYModeResponse: Error setting TTY mode, ar.exception"
+                    + ar.exception);
+        }
+        phone.queryTTYMode(mHandler.obtainMessage(EVENT_TTY_MODE_GET));
+    }
+
+    /**
+     * "Call origin" may be used by Contacts app to specify where the phone call comes from.
+     * Currently, the only permitted value for this extra is {@link #ALLOWED_EXTRA_CALL_ORIGIN}.
+     * Any other value will be ignored, to make sure that malicious apps can't trick the in-call
+     * UI into launching some random other app after a call ends.
+     *
+     * TODO: make this more generic. Note that we should let the "origin" specify its package
+     * while we are now assuming it is "com.android.contacts"
+     */
+    public static final String EXTRA_CALL_ORIGIN = "com.android.phone.CALL_ORIGIN";
+    private static final String DEFAULT_CALL_ORIGIN_PACKAGE = "com.android.dialer";
+    private static final String ALLOWED_EXTRA_CALL_ORIGIN =
+            "com.android.dialer.DialtactsActivity";
+    /**
+     * Used to determine if the preserved call origin is fresh enough.
+     */
+    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() {
+
+        /** Handle the task of binding the local object to the service */
+        public void onServiceConnected(ComponentName className, IBinder service) {
+            Log.i(LOG_TAG, "Headset phone created, binding local service.");
+            mBluetoothPhone = IBluetoothHeadsetPhone.Stub.asInterface(service);
+        }
+
+        /** Handle the task of cleaning up the local binding */
+        public void onServiceDisconnected(ComponentName className) {
+            Log.i(LOG_TAG, "Headset phone disconnected, cleaning local binding.");
+            mBluetoothPhone = null;
+        }
+    };
+}
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
new file mode 100644
index 0000000..6600ae5
--- /dev/null
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -0,0 +1,884 @@
+/*
+ * 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.app.ActivityManager;
+import android.app.AppOpsManager;
+import android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.Intent;
+import android.net.ConnectivityManager;
+import android.net.Uri;
+import android.os.AsyncResult;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Process;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.telephony.NeighboringCellInfo;
+import android.telephony.CellInfo;
+import android.telephony.ServiceState;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.internal.telephony.DefaultPhoneNotifier;
+import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.ITelephony;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.CallManager;
+import com.android.internal.telephony.PhoneConstants;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * Implementation of the ITelephony interface.
+ */
+public class PhoneInterfaceManager extends ITelephony.Stub {
+    private static final String LOG_TAG = "PhoneInterfaceManager";
+    private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
+    private static final boolean DBG_LOC = false;
+
+    // Message codes used with mMainThreadHandler
+    private static final int CMD_HANDLE_PIN_MMI = 1;
+    private static final int CMD_HANDLE_NEIGHBORING_CELL = 2;
+    private static final int EVENT_NEIGHBORING_CELL_DONE = 3;
+    private static final int CMD_ANSWER_RINGING_CALL = 4;
+    private static final int CMD_END_CALL = 5;  // not used yet
+    private static final int CMD_SILENCE_RINGER = 6;
+
+    /** The singleton instance. */
+    private static PhoneInterfaceManager sInstance;
+
+    PhoneGlobals mApp;
+    Phone mPhone;
+    CallManager mCM;
+    AppOpsManager mAppOps;
+    MainThreadHandler mMainThreadHandler;
+
+    /**
+     * A request object for use with {@link MainThreadHandler}. Requesters should wait() on the
+     * request after sending. The main thread will notify the request when it is complete.
+     */
+    private static final class MainThreadRequest {
+        /** The argument to use for the request */
+        public Object argument;
+        /** The result of the request that is run on the main thread */
+        public Object result;
+
+        public MainThreadRequest(Object argument) {
+            this.argument = argument;
+        }
+    }
+
+    /**
+     * A handler that processes messages on the main thread in the phone process. Since many
+     * of the Phone calls are not thread safe this is needed to shuttle the requests from the
+     * inbound binder threads to the main thread in the phone process.  The Binder thread
+     * may provide a {@link MainThreadRequest} object in the msg.obj field that they are waiting
+     * on, which will be notified when the operation completes and will contain the result of the
+     * request.
+     *
+     * <p>If a MainThreadRequest object is provided in the msg.obj field,
+     * note that request.result must be set to something non-null for the calling thread to
+     * unblock.
+     */
+    private final class MainThreadHandler extends Handler {
+        @Override
+        public void handleMessage(Message msg) {
+            MainThreadRequest request;
+            Message onCompleted;
+            AsyncResult ar;
+
+            switch (msg.what) {
+                case CMD_HANDLE_PIN_MMI:
+                    request = (MainThreadRequest) msg.obj;
+                    request.result = Boolean.valueOf(
+                            mPhone.handlePinMmi((String) request.argument));
+                    // Wake up the requesting thread
+                    synchronized (request) {
+                        request.notifyAll();
+                    }
+                    break;
+
+                case CMD_HANDLE_NEIGHBORING_CELL:
+                    request = (MainThreadRequest) msg.obj;
+                    onCompleted = obtainMessage(EVENT_NEIGHBORING_CELL_DONE,
+                            request);
+                    mPhone.getNeighboringCids(onCompleted);
+                    break;
+
+                case EVENT_NEIGHBORING_CELL_DONE:
+                    ar = (AsyncResult) msg.obj;
+                    request = (MainThreadRequest) ar.userObj;
+                    if (ar.exception == null && ar.result != null) {
+                        request.result = ar.result;
+                    } else {
+                        // create an empty list to notify the waiting thread
+                        request.result = new ArrayList<NeighboringCellInfo>();
+                    }
+                    // Wake up the requesting thread
+                    synchronized (request) {
+                        request.notifyAll();
+                    }
+                    break;
+
+                case CMD_ANSWER_RINGING_CALL:
+                    answerRingingCallInternal();
+                    break;
+
+                case CMD_SILENCE_RINGER:
+                    silenceRingerInternal();
+                    break;
+
+                case CMD_END_CALL:
+                    request = (MainThreadRequest) msg.obj;
+                    boolean hungUp = false;
+                    int phoneType = mPhone.getPhoneType();
+                    if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
+                        // CDMA: If the user presses the Power button we treat it as
+                        // ending the complete call session
+                        hungUp = PhoneUtils.hangupRingingAndActive(mPhone);
+                    } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
+                        // GSM: End the call as per the Phone state
+                        hungUp = PhoneUtils.hangup(mCM);
+                    } else {
+                        throw new IllegalStateException("Unexpected phone type: " + phoneType);
+                    }
+                    if (DBG) log("CMD_END_CALL: " + (hungUp ? "hung up!" : "no call to hang up"));
+                    request.result = hungUp;
+                    // Wake up the requesting thread
+                    synchronized (request) {
+                        request.notifyAll();
+                    }
+                    break;
+
+                default:
+                    Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Posts the specified command to be executed on the main thread,
+     * waits for the request to complete, and returns the result.
+     * @see #sendRequestAsync
+     */
+    private Object sendRequest(int command, Object argument) {
+        if (Looper.myLooper() == mMainThreadHandler.getLooper()) {
+            throw new RuntimeException("This method will deadlock if called from the main thread.");
+        }
+
+        MainThreadRequest request = new MainThreadRequest(argument);
+        Message msg = mMainThreadHandler.obtainMessage(command, request);
+        msg.sendToTarget();
+
+        // Wait for the request to complete
+        synchronized (request) {
+            while (request.result == null) {
+                try {
+                    request.wait();
+                } catch (InterruptedException e) {
+                    // Do nothing, go back and wait until the request is complete
+                }
+            }
+        }
+        return request.result;
+    }
+
+    /**
+     * Asynchronous ("fire and forget") version of sendRequest():
+     * Posts the specified command to be executed on the main thread, and
+     * returns immediately.
+     * @see #sendRequest
+     */
+    private void sendRequestAsync(int command) {
+        mMainThreadHandler.sendEmptyMessage(command);
+    }
+
+    /**
+     * Initialize the singleton PhoneInterfaceManager instance.
+     * This is only done once, at startup, from PhoneApp.onCreate().
+     */
+    /* package */ static PhoneInterfaceManager init(PhoneGlobals app, Phone phone) {
+        synchronized (PhoneInterfaceManager.class) {
+            if (sInstance == null) {
+                sInstance = new PhoneInterfaceManager(app, phone);
+            } else {
+                Log.wtf(LOG_TAG, "init() called multiple times!  sInstance = " + sInstance);
+            }
+            return sInstance;
+        }
+    }
+
+    /** Private constructor; @see init() */
+    private PhoneInterfaceManager(PhoneGlobals app, Phone phone) {
+        mApp = app;
+        mPhone = phone;
+        mCM = PhoneGlobals.getInstance().mCM;
+        mAppOps = (AppOpsManager)app.getSystemService(Context.APP_OPS_SERVICE);
+        mMainThreadHandler = new MainThreadHandler();
+        publish();
+    }
+
+    private void publish() {
+        if (DBG) log("publish: " + this);
+
+        ServiceManager.addService("phone", this);
+    }
+
+    //
+    // Implementation of the ITelephony interface.
+    //
+
+    public void dial(String number) {
+        if (DBG) log("dial: " + number);
+        // No permission check needed here: This is just a wrapper around the
+        // ACTION_DIAL intent, which is available to any app since it puts up
+        // the UI before it does anything.
+
+        String url = createTelUrl(number);
+        if (url == null) {
+            return;
+        }
+
+        // PENDING: should we just silently fail if phone is offhook or ringing?
+        PhoneConstants.State state = mCM.getState();
+        if (state != PhoneConstants.State.OFFHOOK && state != PhoneConstants.State.RINGING) {
+            Intent  intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
+            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            mApp.startActivity(intent);
+        }
+    }
+
+    public void call(String callingPackage, String number) {
+        if (DBG) log("call: " + number);
+
+        // This is just a wrapper around the ACTION_CALL intent, but we still
+        // need to do a permission check since we're calling startActivity()
+        // from the context of the phone app.
+        enforceCallPermission();
+
+        if (mAppOps.noteOp(AppOpsManager.OP_CALL_PHONE, Binder.getCallingUid(), callingPackage)
+                != AppOpsManager.MODE_ALLOWED) {
+            return;
+        }
+
+        String url = createTelUrl(number);
+        if (url == null) {
+            return;
+        }
+
+        Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(url));
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mApp.startActivity(intent);
+    }
+
+    private boolean showCallScreenInternal(boolean specifyInitialDialpadState,
+                                           boolean initialDialpadState) {
+        if (!PhoneGlobals.sVoiceCapable) {
+            // Never allow the InCallScreen to appear on data-only devices.
+            return false;
+        }
+        if (isIdle()) {
+            return false;
+        }
+        // If the phone isn't idle then go to the in-call screen
+        long callingId = Binder.clearCallingIdentity();
+        try {
+            Intent intent;
+            if (specifyInitialDialpadState) {
+                intent = PhoneGlobals.createInCallIntent(initialDialpadState);
+            } else {
+                intent = PhoneGlobals.createInCallIntent();
+            }
+            try {
+                mApp.startActivity(intent);
+            } catch (ActivityNotFoundException e) {
+                // It's possible that the in-call UI might not exist
+                // (like on non-voice-capable devices), although we
+                // shouldn't be trying to bring up the InCallScreen on
+                // devices like that in the first place!
+                Log.w(LOG_TAG, "showCallScreenInternal: "
+                      + "transition to InCallScreen failed; intent = " + intent);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(callingId);
+        }
+        return true;
+    }
+
+    // Show the in-call screen without specifying the initial dialpad state.
+    public boolean showCallScreen() {
+        return showCallScreenInternal(false, false);
+    }
+
+    // The variation of showCallScreen() that specifies the initial dialpad state.
+    // (Ideally this would be called showCallScreen() too, just with a different
+    // signature, but AIDL doesn't allow that.)
+    public boolean showCallScreenWithDialpad(boolean showDialpad) {
+        return showCallScreenInternal(true, showDialpad);
+    }
+
+    /**
+     * End a call based on call state
+     * @return true is a call was ended
+     */
+    public boolean endCall() {
+        enforceCallPermission();
+        return (Boolean) sendRequest(CMD_END_CALL, null);
+    }
+
+    public void answerRingingCall() {
+        if (DBG) log("answerRingingCall...");
+        // TODO: there should eventually be a separate "ANSWER_PHONE" permission,
+        // but that can probably wait till the big TelephonyManager API overhaul.
+        // For now, protect this call with the MODIFY_PHONE_STATE permission.
+        enforceModifyPermission();
+        sendRequestAsync(CMD_ANSWER_RINGING_CALL);
+    }
+
+    /**
+     * Make the actual telephony calls to implement answerRingingCall().
+     * This should only be called from the main thread of the Phone app.
+     * @see #answerRingingCall
+     *
+     * TODO: it would be nice to return true if we answered the call, or
+     * false if there wasn't actually a ringing incoming call, or some
+     * other error occurred.  (In other words, pass back the return value
+     * from PhoneUtils.answerCall() or PhoneUtils.answerAndEndActive().)
+     * But that would require calling this method via sendRequest() rather
+     * than sendRequestAsync(), and right now we don't actually *need* that
+     * return value, so let's just return void for now.
+     */
+    private void answerRingingCallInternal() {
+        final boolean hasRingingCall = !mPhone.getRingingCall().isIdle();
+        if (hasRingingCall) {
+            final boolean hasActiveCall = !mPhone.getForegroundCall().isIdle();
+            final boolean hasHoldingCall = !mPhone.getBackgroundCall().isIdle();
+            if (hasActiveCall && hasHoldingCall) {
+                // Both lines are in use!
+                // TODO: provide a flag to let the caller specify what
+                // policy to use if both lines are in use.  (The current
+                // behavior is hardwired to "answer incoming, end ongoing",
+                // which is how the CALL button is specced to behave.)
+                PhoneUtils.answerAndEndActive(mCM, mCM.getFirstActiveRingingCall());
+                return;
+            } else {
+                // answerCall() will automatically hold the current active
+                // call, if there is one.
+                PhoneUtils.answerCall(mCM.getFirstActiveRingingCall());
+                return;
+            }
+        } else {
+            // No call was ringing.
+            return;
+        }
+    }
+
+    public void silenceRinger() {
+        if (DBG) log("silenceRinger...");
+        // TODO: find a more appropriate permission to check here.
+        // (That can probably wait till the big TelephonyManager API overhaul.
+        // For now, protect this call with the MODIFY_PHONE_STATE permission.)
+        enforceModifyPermission();
+        sendRequestAsync(CMD_SILENCE_RINGER);
+    }
+
+    /**
+     * Internal implemenation of silenceRinger().
+     * This should only be called from the main thread of the Phone app.
+     * @see #silenceRinger
+     */
+    private void silenceRingerInternal() {
+        if ((mCM.getState() == PhoneConstants.State.RINGING)
+            && mApp.notifier.isRinging()) {
+            // Ringer is actually playing, so silence it.
+            if (DBG) log("silenceRingerInternal: silencing...");
+            mApp.notifier.silenceRinger();
+        }
+    }
+
+    public boolean isOffhook() {
+        return (mCM.getState() == PhoneConstants.State.OFFHOOK);
+    }
+
+    public boolean isRinging() {
+        return (mCM.getState() == PhoneConstants.State.RINGING);
+    }
+
+    public boolean isIdle() {
+        return (mCM.getState() == PhoneConstants.State.IDLE);
+    }
+
+    public boolean isSimPinEnabled() {
+        enforceReadPermission();
+        return (PhoneGlobals.getInstance().isSimPinEnabled());
+    }
+
+    public boolean supplyPin(String pin) {
+        enforceModifyPermission();
+        final UnlockSim checkSimPin = new UnlockSim(mPhone.getIccCard());
+        checkSimPin.start();
+        return checkSimPin.unlockSim(null, pin);
+    }
+
+    public boolean supplyPuk(String puk, String pin) {
+        enforceModifyPermission();
+        final UnlockSim checkSimPuk = new UnlockSim(mPhone.getIccCard());
+        checkSimPuk.start();
+        return checkSimPuk.unlockSim(puk, pin);
+    }
+
+    /**
+     * Helper thread to turn async call to {@link SimCard#supplyPin} into
+     * a synchronous one.
+     */
+    private static class UnlockSim extends Thread {
+
+        private final IccCard mSimCard;
+
+        private boolean mDone = false;
+        private boolean mResult = false;
+
+        // For replies from SimCard interface
+        private Handler mHandler;
+
+        // For async handler to identify request type
+        private static final int SUPPLY_PIN_COMPLETE = 100;
+
+        public UnlockSim(IccCard simCard) {
+            mSimCard = simCard;
+        }
+
+        @Override
+        public void run() {
+            Looper.prepare();
+            synchronized (UnlockSim.this) {
+                mHandler = new Handler() {
+                    @Override
+                    public void handleMessage(Message msg) {
+                        AsyncResult ar = (AsyncResult) msg.obj;
+                        switch (msg.what) {
+                            case SUPPLY_PIN_COMPLETE:
+                                Log.d(LOG_TAG, "SUPPLY_PIN_COMPLETE");
+                                synchronized (UnlockSim.this) {
+                                    mResult = (ar.exception == null);
+                                    mDone = true;
+                                    UnlockSim.this.notifyAll();
+                                }
+                                break;
+                        }
+                    }
+                };
+                UnlockSim.this.notifyAll();
+            }
+            Looper.loop();
+        }
+
+        /*
+         * Use PIN or PUK to unlock SIM card
+         *
+         * If PUK is null, unlock SIM card with PIN
+         *
+         * If PUK is not null, unlock SIM card with PUK and set PIN code
+         */
+        synchronized boolean unlockSim(String puk, String pin) {
+
+            while (mHandler == null) {
+                try {
+                    wait();
+                } catch (InterruptedException e) {
+                    Thread.currentThread().interrupt();
+                }
+            }
+            Message callback = Message.obtain(mHandler, SUPPLY_PIN_COMPLETE);
+
+            if (puk == null) {
+                mSimCard.supplyPin(pin, callback);
+            } else {
+                mSimCard.supplyPuk(puk, pin, callback);
+            }
+
+            while (!mDone) {
+                try {
+                    Log.d(LOG_TAG, "wait for done");
+                    wait();
+                } catch (InterruptedException e) {
+                    // Restore the interrupted status
+                    Thread.currentThread().interrupt();
+                }
+            }
+            Log.d(LOG_TAG, "done");
+            return mResult;
+        }
+    }
+
+    public void updateServiceLocation() {
+        // No permission check needed here: this call is harmless, and it's
+        // needed for the ServiceState.requestStateUpdate() call (which is
+        // already intentionally exposed to 3rd parties.)
+        mPhone.updateServiceLocation();
+    }
+
+    public boolean isRadioOn() {
+        return mPhone.getServiceState().getVoiceRegState() != ServiceState.STATE_POWER_OFF;
+    }
+
+    public void toggleRadioOnOff() {
+        enforceModifyPermission();
+        mPhone.setRadioPower(!isRadioOn());
+    }
+    public boolean setRadio(boolean turnOn) {
+        enforceModifyPermission();
+        if ((mPhone.getServiceState().getVoiceRegState() != ServiceState.STATE_POWER_OFF) != turnOn) {
+            toggleRadioOnOff();
+        }
+        return true;
+    }
+    public boolean setRadioPower(boolean turnOn) {
+        enforceModifyPermission();
+        mPhone.setRadioPower(turnOn);
+        return true;
+    }
+
+    public boolean enableDataConnectivity() {
+        enforceModifyPermission();
+        ConnectivityManager cm =
+                (ConnectivityManager)mApp.getSystemService(Context.CONNECTIVITY_SERVICE);
+        cm.setMobileDataEnabled(true);
+        return true;
+    }
+
+    public int enableApnType(String type) {
+        enforceModifyPermission();
+        return mPhone.enableApnType(type);
+    }
+
+    public int disableApnType(String type) {
+        enforceModifyPermission();
+        return mPhone.disableApnType(type);
+    }
+
+    public boolean disableDataConnectivity() {
+        enforceModifyPermission();
+        ConnectivityManager cm =
+                (ConnectivityManager)mApp.getSystemService(Context.CONNECTIVITY_SERVICE);
+        cm.setMobileDataEnabled(false);
+        return true;
+    }
+
+    public boolean isDataConnectivityPossible() {
+        return mPhone.isDataConnectivityPossible();
+    }
+
+    public boolean handlePinMmi(String dialString) {
+        enforceModifyPermission();
+        return (Boolean) sendRequest(CMD_HANDLE_PIN_MMI, dialString);
+    }
+
+    public void cancelMissedCallsNotification() {
+        enforceModifyPermission();
+        mApp.notificationMgr.cancelMissedCallNotification();
+    }
+
+    public int getCallState() {
+        return DefaultPhoneNotifier.convertCallState(mCM.getState());
+    }
+
+    public int getDataState() {
+        return DefaultPhoneNotifier.convertDataState(mPhone.getDataConnectionState());
+    }
+
+    public int getDataActivity() {
+        return DefaultPhoneNotifier.convertDataActivityState(mPhone.getDataActivityState());
+    }
+
+    @Override
+    public Bundle getCellLocation() {
+        try {
+            mApp.enforceCallingOrSelfPermission(
+                android.Manifest.permission.ACCESS_FINE_LOCATION, null);
+        } catch (SecurityException e) {
+            // If we have ACCESS_FINE_LOCATION permission, skip the check for ACCESS_COARSE_LOCATION
+            // A failure should throw the SecurityException from ACCESS_COARSE_LOCATION since this
+            // is the weaker precondition
+            mApp.enforceCallingOrSelfPermission(
+                android.Manifest.permission.ACCESS_COARSE_LOCATION, null);
+        }
+
+        if (checkIfCallerIsSelfOrForegoundUser()) {
+            if (DBG_LOC) log("getCellLocation: is active user");
+            Bundle data = new Bundle();
+            mPhone.getCellLocation().fillInNotifierBundle(data);
+            return data;
+        } else {
+            if (DBG_LOC) log("getCellLocation: suppress non-active user");
+            return null;
+        }
+    }
+
+    @Override
+    public void enableLocationUpdates() {
+        mApp.enforceCallingOrSelfPermission(
+                android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
+        mPhone.enableLocationUpdates();
+    }
+
+    @Override
+    public void disableLocationUpdates() {
+        mApp.enforceCallingOrSelfPermission(
+                android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
+        mPhone.disableLocationUpdates();
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public List<NeighboringCellInfo> getNeighboringCellInfo(String callingPackage) {
+        try {
+            mApp.enforceCallingOrSelfPermission(
+                    android.Manifest.permission.ACCESS_FINE_LOCATION, null);
+        } catch (SecurityException e) {
+            // If we have ACCESS_FINE_LOCATION permission, skip the check
+            // for ACCESS_COARSE_LOCATION
+            // A failure should throw the SecurityException from
+            // ACCESS_COARSE_LOCATION since this is the weaker precondition
+            mApp.enforceCallingOrSelfPermission(
+                    android.Manifest.permission.ACCESS_COARSE_LOCATION, null);
+        }
+
+        if (mAppOps.noteOp(AppOpsManager.OP_NEIGHBORING_CELLS, Binder.getCallingUid(),
+                callingPackage) != AppOpsManager.MODE_ALLOWED) {
+            return null;
+        }
+        if (checkIfCallerIsSelfOrForegoundUser()) {
+            if (DBG_LOC) log("getNeighboringCellInfo: is active user");
+
+            ArrayList<NeighboringCellInfo> cells = null;
+
+            try {
+                cells = (ArrayList<NeighboringCellInfo>) sendRequest(
+                        CMD_HANDLE_NEIGHBORING_CELL, null);
+            } catch (RuntimeException e) {
+                Log.e(LOG_TAG, "getNeighboringCellInfo " + e);
+            }
+            return cells;
+        } else {
+            if (DBG_LOC) log("getNeighboringCellInfo: suppress non-active user");
+            return null;
+        }
+    }
+
+
+    @Override
+    public List<CellInfo> getAllCellInfo() {
+        try {
+            mApp.enforceCallingOrSelfPermission(
+                android.Manifest.permission.ACCESS_FINE_LOCATION, null);
+        } catch (SecurityException e) {
+            // If we have ACCESS_FINE_LOCATION permission, skip the check for ACCESS_COARSE_LOCATION
+            // A failure should throw the SecurityException from ACCESS_COARSE_LOCATION since this
+            // is the weaker precondition
+            mApp.enforceCallingOrSelfPermission(
+                android.Manifest.permission.ACCESS_COARSE_LOCATION, null);
+        }
+
+        if (checkIfCallerIsSelfOrForegoundUser()) {
+            if (DBG_LOC) log("getAllCellInfo: is active user");
+            return mPhone.getAllCellInfo();
+        } else {
+            if (DBG_LOC) log("getAllCellInfo: suppress non-active user");
+            return null;
+        }
+    }
+
+    public void setCellInfoListRate(int rateInMillis) {
+        mPhone.setCellInfoListRate(rateInMillis);
+    }
+
+    //
+    // Internal helper methods.
+    //
+
+    private boolean checkIfCallerIsSelfOrForegoundUser() {
+        boolean ok;
+
+        boolean self = Binder.getCallingUid() == Process.myUid();
+        if (!self) {
+            // Get the caller's user id then clear the calling identity
+            // which will be restored in the finally clause.
+            int callingUser = UserHandle.getCallingUserId();
+            long ident = Binder.clearCallingIdentity();
+
+            try {
+                // With calling identity cleared the current user is the foreground user.
+                int foregroundUser = ActivityManager.getCurrentUser();
+                ok = (foregroundUser == callingUser);
+                if (DBG_LOC) {
+                    log("checkIfCallerIsSelfOrForegoundUser: foregroundUser=" + foregroundUser
+                            + " callingUser=" + callingUser + " ok=" + ok);
+                }
+            } catch (Exception ex) {
+                if (DBG_LOC) loge("checkIfCallerIsSelfOrForegoundUser: Exception ex=" + ex);
+                ok = false;
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        } else {
+            if (DBG_LOC) log("checkIfCallerIsSelfOrForegoundUser: is self");
+            ok = true;
+        }
+        if (DBG_LOC) log("checkIfCallerIsSelfOrForegoundUser: ret=" + ok);
+        return ok;
+    }
+
+    /**
+     * Make sure the caller has the READ_PHONE_STATE permission.
+     *
+     * @throws SecurityException if the caller does not have the required permission
+     */
+    private void enforceReadPermission() {
+        mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE, null);
+    }
+
+    /**
+     * Make sure the caller has the MODIFY_PHONE_STATE permission.
+     *
+     * @throws SecurityException if the caller does not have the required permission
+     */
+    private void enforceModifyPermission() {
+        mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null);
+    }
+
+    /**
+     * Make sure the caller has the CALL_PHONE permission.
+     *
+     * @throws SecurityException if the caller does not have the required permission
+     */
+    private void enforceCallPermission() {
+        mApp.enforceCallingOrSelfPermission(android.Manifest.permission.CALL_PHONE, null);
+    }
+
+
+    private String createTelUrl(String number) {
+        if (TextUtils.isEmpty(number)) {
+            return null;
+        }
+
+        StringBuilder buf = new StringBuilder("tel:");
+        buf.append(number);
+        return buf.toString();
+    }
+
+    private void log(String msg) {
+        Log.d(LOG_TAG, "[PhoneIntfMgr] " + msg);
+    }
+
+    private void loge(String msg) {
+        Log.e(LOG_TAG, "[PhoneIntfMgr] " + msg);
+    }
+
+    public int getActivePhoneType() {
+        return mPhone.getPhoneType();
+    }
+
+    /**
+     * Returns the CDMA ERI icon index to display
+     */
+    public int getCdmaEriIconIndex() {
+        return mPhone.getCdmaEriIconIndex();
+    }
+
+    /**
+     * Returns the CDMA ERI icon mode,
+     * 0 - ON
+     * 1 - FLASHING
+     */
+    public int getCdmaEriIconMode() {
+        return mPhone.getCdmaEriIconMode();
+    }
+
+    /**
+     * Returns the CDMA ERI text,
+     */
+    public String getCdmaEriText() {
+        return mPhone.getCdmaEriText();
+    }
+
+    /**
+     * Returns true if CDMA provisioning needs to run.
+     */
+    public boolean needsOtaServiceProvisioning() {
+        return mPhone.needsOtaServiceProvisioning();
+    }
+
+    /**
+     * Returns the unread count of voicemails
+     */
+    public int getVoiceMessageCount() {
+        return mPhone.getVoiceMessageCount();
+    }
+
+    /**
+     * Returns the data network type
+     *
+     * @Deprecated to be removed Q3 2013 use {@link #getDataNetworkType}.
+     */
+    @Override
+    public int getNetworkType() {
+        return mPhone.getServiceState().getDataNetworkType();
+    }
+
+    /**
+     * Returns the data network type
+     */
+    @Override
+    public int getDataNetworkType() {
+        return mPhone.getServiceState().getDataNetworkType();
+    }
+
+    /**
+     * Returns the data network type
+     */
+    @Override
+    public int getVoiceNetworkType() {
+        return mPhone.getServiceState().getVoiceNetworkType();
+    }
+
+    /**
+     * @return true if a ICC card is present
+     */
+    public boolean hasIccCard() {
+        return mPhone.getIccCard().hasIccCard();
+    }
+
+    /**
+     * Return if the current radio is LTE on CDMA. This
+     * is a tri-state return value as for a period of time
+     * the mode may be unknown.
+     *
+     * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
+     * or {@link PHone#LTE_ON_CDMA_TRUE}
+     */
+    public int getLteOnCdmaMode() {
+        return mPhone.getLteOnCdmaMode();
+    }
+}
diff --git a/src/com/android/phone/PhoneUtils.java b/src/com/android/phone/PhoneUtils.java
new file mode 100644
index 0000000..4334962
--- /dev/null
+++ b/src/com/android/phone/PhoneUtils.java
@@ -0,0 +1,2717 @@
+/*
+ * 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.app.AlertDialog;
+import android.app.Dialog;
+import android.app.ProgressDialog;
+import android.bluetooth.IBluetoothHeadsetPhone;
+import android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Configuration;
+import android.graphics.drawable.Drawable;
+import android.media.AudioManager;
+import android.net.Uri;
+import android.net.sip.SipManager;
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.SystemProperties;
+import android.provider.Settings;
+import android.telephony.PhoneNumberUtils;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.EditText;
+import android.widget.Toast;
+
+import com.android.internal.telephony.Call;
+import com.android.internal.telephony.CallManager;
+import com.android.internal.telephony.CallStateException;
+import com.android.internal.telephony.CallerInfo;
+import com.android.internal.telephony.CallerInfoAsyncQuery;
+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.internal.telephony.TelephonyProperties;
+import com.android.internal.telephony.cdma.CdmaConnection;
+import com.android.internal.telephony.sip.SipPhone;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Misc utilities for the Phone app.
+ */
+public class PhoneUtils {
+    private static final String LOG_TAG = "PhoneUtils";
+    private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
+
+    // Do not check in with VDBG = true, since that may write PII to the system log.
+    private static final boolean VDBG = false;
+
+    /** Control stack trace for Audio Mode settings */
+    private static final boolean DBG_SETAUDIOMODE_STACK = false;
+
+    /** Identifier for the "Add Call" intent extra. */
+    static final String ADD_CALL_MODE_KEY = "add_call_mode";
+
+    // Return codes from placeCall()
+    static final int CALL_STATUS_DIALED = 0;  // The number was successfully dialed
+    static final int CALL_STATUS_DIALED_MMI = 1;  // The specified number was an MMI code
+    static final int CALL_STATUS_FAILED = 2;  // The call failed
+
+    // State of the Phone's audio modes
+    // Each state can move to the other states, but within the state only certain
+    //  transitions for AudioManager.setMode() are allowed.
+    static final int AUDIO_IDLE = 0;  /** audio behaviour at phone idle */
+    static final int AUDIO_RINGING = 1;  /** audio behaviour while ringing */
+    static final int AUDIO_OFFHOOK = 2;  /** audio behaviour while in call. */
+
+    // USSD string length for MMI operations
+    static final int MIN_USSD_LEN = 1;
+    static final int MAX_USSD_LEN = 160;
+
+    /** Speaker state, persisting between wired headset connection events */
+    private static boolean sIsSpeakerEnabled = false;
+
+    /** Hash table to store mute (Boolean) values based upon the connection.*/
+    private static Hashtable<Connection, Boolean> sConnectionMuteTable =
+        new Hashtable<Connection, Boolean>();
+
+    /** Static handler for the connection/mute tracking */
+    private static ConnectionHandler mConnectionHandler;
+
+    /** Phone state changed event*/
+    private static final int PHONE_STATE_CHANGED = -1;
+
+    /** Define for not a special CNAP string */
+    private static final int CNAP_SPECIAL_CASE_NO = -1;
+
+    /** Noise suppression status as selected by user */
+    private static boolean sIsNoiseSuppressionEnabled = true;
+
+    /**
+     * Handler that tracks the connections and updates the value of the
+     * Mute settings for each connection as needed.
+     */
+    private static class ConnectionHandler extends Handler {
+        @Override
+        public void handleMessage(Message msg) {
+            AsyncResult ar = (AsyncResult) msg.obj;
+            switch (msg.what) {
+                case PHONE_STATE_CHANGED:
+                    if (DBG) log("ConnectionHandler: updating mute state for each connection");
+
+                    CallManager cm = (CallManager) ar.userObj;
+
+                    // update the foreground connections, if there are new connections.
+                    // Have to get all foreground calls instead of the active one
+                    // because there may two foreground calls co-exist in shore period
+                    // (a racing condition based on which phone changes firstly)
+                    // Otherwise the connection may get deleted.
+                    List<Connection> fgConnections = new ArrayList<Connection>();
+                    for (Call fgCall : cm.getForegroundCalls()) {
+                        if (!fgCall.isIdle()) {
+                            fgConnections.addAll(fgCall.getConnections());
+                        }
+                    }
+                    for (Connection cn : fgConnections) {
+                        if (sConnectionMuteTable.get(cn) == null) {
+                            sConnectionMuteTable.put(cn, Boolean.FALSE);
+                        }
+                    }
+
+                    // mute is connection based operation, we need loop over
+                    // all background calls instead of the first one to update
+                    // the background connections, if there are new connections.
+                    List<Connection> bgConnections = new ArrayList<Connection>();
+                    for (Call bgCall : cm.getBackgroundCalls()) {
+                        if (!bgCall.isIdle()) {
+                            bgConnections.addAll(bgCall.getConnections());
+                        }
+                    }
+                    for (Connection cn : bgConnections) {
+                        if (sConnectionMuteTable.get(cn) == null) {
+                          sConnectionMuteTable.put(cn, Boolean.FALSE);
+                        }
+                    }
+
+                    // Check to see if there are any lingering connections here
+                    // (disconnected connections), use old-school iterators to avoid
+                    // concurrent modification exceptions.
+                    Connection cn;
+                    for (Iterator<Connection> cnlist = sConnectionMuteTable.keySet().iterator();
+                            cnlist.hasNext();) {
+                        cn = cnlist.next();
+                        if (!fgConnections.contains(cn) && !bgConnections.contains(cn)) {
+                            if (DBG) log("connection '" + cn + "' not accounted for, removing.");
+                            cnlist.remove();
+                        }
+                    }
+
+                    // Restore the mute state of the foreground call if we're not IDLE,
+                    // otherwise just clear the mute state. This is really saying that
+                    // as long as there is one or more connections, we should update
+                    // the mute state with the earliest connection on the foreground
+                    // call, and that with no connections, we should be back to a
+                    // non-mute state.
+                    if (cm.getState() != PhoneConstants.State.IDLE) {
+                        restoreMuteState();
+                    } else {
+                        setMuteInternal(cm.getFgPhone(), false);
+                    }
+
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Register the ConnectionHandler with the phone, to receive connection events
+     */
+    public static void initializeConnectionHandler(CallManager cm) {
+        if (mConnectionHandler == null) {
+            mConnectionHandler = new ConnectionHandler();
+        }
+
+        // pass over cm as user.obj
+        cm.registerForPreciseCallStateChanged(mConnectionHandler, PHONE_STATE_CHANGED, cm);
+
+    }
+
+    /** This class is never instantiated. */
+    private PhoneUtils() {
+    }
+
+    /**
+     * Answer the currently-ringing call.
+     *
+     * @return true if we answered the call, or false if there wasn't
+     *         actually a ringing incoming call, or some other error occurred.
+     *
+     * @see #answerAndEndHolding(CallManager, Call)
+     * @see #answerAndEndActive(CallManager, Call)
+     */
+    /* package */ static boolean answerCall(Call ringingCall) {
+        log("answerCall(" + ringingCall + ")...");
+        final PhoneGlobals app = PhoneGlobals.getInstance();
+        final CallNotifier notifier = app.notifier;
+
+        // If the ringer is currently ringing and/or vibrating, stop it
+        // right now (before actually answering the call.)
+        notifier.silenceRinger();
+
+        final Phone phone = ringingCall.getPhone();
+        final boolean phoneIsCdma = (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA);
+        boolean answered = false;
+        IBluetoothHeadsetPhone btPhone = null;
+
+        if (phoneIsCdma) {
+            // Stop any signalInfo tone being played when a Call waiting gets answered
+            if (ringingCall.getState() == Call.State.WAITING) {
+                notifier.stopSignalInfoTone();
+            }
+        }
+
+        if (ringingCall != null && ringingCall.isRinging()) {
+            if (DBG) log("answerCall: call state = " + ringingCall.getState());
+            try {
+                if (phoneIsCdma) {
+                    if (app.cdmaPhoneCallState.getCurrentCallState()
+                            == CdmaPhoneCallState.PhoneCallState.IDLE) {
+                        // This is the FIRST incoming call being answered.
+                        // Set the Phone Call State to SINGLE_ACTIVE
+                        app.cdmaPhoneCallState.setCurrentCallState(
+                                CdmaPhoneCallState.PhoneCallState.SINGLE_ACTIVE);
+                    } else {
+                        // This is the CALL WAITING call being answered.
+                        // Set the Phone Call State to CONF_CALL
+                        app.cdmaPhoneCallState.setCurrentCallState(
+                                CdmaPhoneCallState.PhoneCallState.CONF_CALL);
+                        // Enable "Add Call" option after answering a Call Waiting as the user
+                        // should be allowed to add another call in case one of the parties
+                        // drops off
+                        app.cdmaPhoneCallState.setAddCallMenuStateAfterCallWaiting(true);
+
+                        // If a BluetoothPhoneService is valid we need to set the second call state
+                        // so that the Bluetooth client can update the Call state correctly when
+                        // a call waiting is answered from the Phone.
+                        btPhone = app.getBluetoothPhoneService();
+                        if (btPhone != null) {
+                            try {
+                                btPhone.cdmaSetSecondCallState(true);
+                            } catch (RemoteException e) {
+                                Log.e(LOG_TAG, Log.getStackTraceString(new Throwable()));
+                            }
+                        }
+                  }
+                }
+
+                final boolean isRealIncomingCall = isRealIncomingCall(ringingCall.getState());
+
+                //if (DBG) log("sPhone.acceptCall");
+                app.mCM.acceptCall(ringingCall);
+                answered = true;
+
+                // Always reset to "unmuted" for a freshly-answered call
+                setMute(false);
+
+                setAudioMode();
+
+                // Check is phone in any dock, and turn on speaker accordingly
+                final boolean speakerActivated = activateSpeakerIfDocked(phone);
+
+                // When answering a phone call, the user will move the phone near to her/his ear
+                // and start conversation, without checking its speaker status. If some other
+                // application turned on the speaker mode before the call and didn't turn it off,
+                // Phone app would need to be responsible for the speaker phone.
+                // Here, we turn off the speaker if
+                // - the phone call is the first in-coming call,
+                // - we did not activate speaker by ourselves during the process above, and
+                // - Bluetooth headset is not in use.
+                if (isRealIncomingCall && !speakerActivated && isSpeakerOn(app)
+                        && !app.isBluetoothHeadsetAudioOn()) {
+                    // This is not an error but might cause users' confusion. Add log just in case.
+                    Log.i(LOG_TAG, "Forcing speaker off due to new incoming call...");
+                    turnOnSpeaker(app, false, true);
+                }
+            } catch (CallStateException ex) {
+                Log.w(LOG_TAG, "answerCall: caught " + ex, ex);
+
+                if (phoneIsCdma) {
+                    // restore the cdmaPhoneCallState and btPhone.cdmaSetSecondCallState:
+                    app.cdmaPhoneCallState.setCurrentCallState(
+                            app.cdmaPhoneCallState.getPreviousCallState());
+                    if (btPhone != null) {
+                        try {
+                            btPhone.cdmaSetSecondCallState(false);
+                        } catch (RemoteException e) {
+                            Log.e(LOG_TAG, Log.getStackTraceString(new Throwable()));
+                        }
+                    }
+                }
+            }
+        }
+        return answered;
+    }
+
+    /**
+     * Smart "hang up" helper method which hangs up exactly one connection,
+     * based on the current Phone state, as follows:
+     * <ul>
+     * <li>If there's a ringing call, hang that up.
+     * <li>Else if there's a foreground call, hang that up.
+     * <li>Else if there's a background call, hang that up.
+     * <li>Otherwise do nothing.
+     * </ul>
+     * @return true if we successfully hung up, or false
+     *              if there were no active calls at all.
+     */
+    static boolean hangup(CallManager cm) {
+        boolean hungup = false;
+        Call ringing = cm.getFirstActiveRingingCall();
+        Call fg = cm.getActiveFgCall();
+        Call bg = cm.getFirstActiveBgCall();
+
+        if (!ringing.isIdle()) {
+            log("hangup(): hanging up ringing call");
+            hungup = hangupRingingCall(ringing);
+        } else if (!fg.isIdle()) {
+            log("hangup(): hanging up foreground call");
+            hungup = hangup(fg);
+        } else if (!bg.isIdle()) {
+            log("hangup(): hanging up background call");
+            hungup = hangup(bg);
+        } else {
+            // No call to hang up!  This is unlikely in normal usage,
+            // since the UI shouldn't be providing an "End call" button in
+            // the first place.  (But it *can* happen, rarely, if an
+            // active call happens to disconnect on its own right when the
+            // user is trying to hang up..)
+            log("hangup(): no active call to hang up");
+        }
+        if (DBG) log("==> hungup = " + hungup);
+
+        return hungup;
+    }
+
+    static boolean hangupRingingCall(Call ringing) {
+        if (DBG) log("hangup ringing call");
+        int phoneType = ringing.getPhone().getPhoneType();
+        Call.State state = ringing.getState();
+
+        if (state == Call.State.INCOMING) {
+            // Regular incoming call (with no other active calls)
+            log("hangupRingingCall(): regular incoming call: hangup()");
+            return hangup(ringing);
+        } else if (state == Call.State.WAITING) {
+            // Call-waiting: there's an incoming call, but another call is
+            // already active.
+            // TODO: It would be better for the telephony layer to provide
+            // a "hangupWaitingCall()" API that works on all devices,
+            // rather than us having to check the phone type here and do
+            // the notifier.sendCdmaCallWaitingReject() hack for CDMA phones.
+            if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
+                // CDMA: Ringing call and Call waiting hangup is handled differently.
+                // For Call waiting we DO NOT call the conventional hangup(call) function
+                // as in CDMA we just want to hangup the Call waiting connection.
+                log("hangupRingingCall(): CDMA-specific call-waiting hangup");
+                final CallNotifier notifier = PhoneGlobals.getInstance().notifier;
+                notifier.sendCdmaCallWaitingReject();
+                return true;
+            } else {
+                // Otherwise, the regular hangup() API works for
+                // call-waiting calls too.
+                log("hangupRingingCall(): call-waiting call: hangup()");
+                return hangup(ringing);
+            }
+        } else {
+            // Unexpected state: the ringing call isn't INCOMING or
+            // WAITING, so there's no reason to have called
+            // hangupRingingCall() in the first place.
+            // (Presumably the incoming call went away at the exact moment
+            // we got here, so just do nothing.)
+            Log.w(LOG_TAG, "hangupRingingCall: no INCOMING or WAITING call");
+            return false;
+        }
+    }
+
+    static boolean hangupActiveCall(Call foreground) {
+        if (DBG) log("hangup active call");
+        return hangup(foreground);
+    }
+
+    static boolean hangupHoldingCall(Call background) {
+        if (DBG) log("hangup holding call");
+        return hangup(background);
+    }
+
+    /**
+     * Used in CDMA phones to end the complete Call session
+     * @param phone the Phone object.
+     * @return true if *any* call was successfully hung up
+     */
+    static boolean hangupRingingAndActive(Phone phone) {
+        boolean hungUpRingingCall = false;
+        boolean hungUpFgCall = false;
+        Call ringingCall = phone.getRingingCall();
+        Call fgCall = phone.getForegroundCall();
+
+        // Hang up any Ringing Call
+        if (!ringingCall.isIdle()) {
+            log("hangupRingingAndActive: Hang up Ringing Call");
+            hungUpRingingCall = hangupRingingCall(ringingCall);
+        }
+
+        // Hang up any Active Call
+        if (!fgCall.isIdle()) {
+            log("hangupRingingAndActive: Hang up Foreground Call");
+            hungUpFgCall = hangupActiveCall(fgCall);
+        }
+
+        return hungUpRingingCall || hungUpFgCall;
+    }
+
+    /**
+     * Trivial wrapper around Call.hangup(), except that we return a
+     * boolean success code rather than throwing CallStateException on
+     * failure.
+     *
+     * @return true if the call was successfully hung up, or false
+     *         if the call wasn't actually active.
+     */
+    static boolean hangup(Call call) {
+        try {
+            CallManager cm = PhoneGlobals.getInstance().mCM;
+
+            if (call.getState() == Call.State.ACTIVE && cm.hasActiveBgCall()) {
+                // handle foreground call hangup while there is background call
+                log("- hangup(Call): hangupForegroundResumeBackground...");
+                cm.hangupForegroundResumeBackground(cm.getFirstActiveBgCall());
+            } else {
+                log("- hangup(Call): regular hangup()...");
+                call.hangup();
+            }
+            return true;
+        } catch (CallStateException ex) {
+            Log.e(LOG_TAG, "Call hangup: caught " + ex, ex);
+        }
+
+        return false;
+    }
+
+    /**
+     * Trivial wrapper around Connection.hangup(), except that we silently
+     * do nothing (rather than throwing CallStateException) if the
+     * connection wasn't actually active.
+     */
+    static void hangup(Connection c) {
+        try {
+            if (c != null) {
+                c.hangup();
+            }
+        } catch (CallStateException ex) {
+            Log.w(LOG_TAG, "Connection hangup: caught " + ex, ex);
+        }
+    }
+
+    static boolean answerAndEndHolding(CallManager cm, Call ringing) {
+        if (DBG) log("end holding & answer waiting: 1");
+        if (!hangupHoldingCall(cm.getFirstActiveBgCall())) {
+            Log.e(LOG_TAG, "end holding failed!");
+            return false;
+        }
+
+        if (DBG) log("end holding & answer waiting: 2");
+        return answerCall(ringing);
+
+    }
+
+    /**
+     * Answers the incoming call specified by "ringing", and ends the currently active phone call.
+     *
+     * This method is useful when's there's an incoming call which we cannot manage with the
+     * current call. e.g. when you are having a phone call with CDMA network and has received
+     * a SIP call, then we won't expect our telephony can manage those phone calls simultaneously.
+     * Note that some types of network may allow multiple phone calls at once; GSM allows to hold
+     * an ongoing phone call, so we don't need to end the active call. The caller of this method
+     * needs to check if the network allows multiple phone calls or not.
+     *
+     * @see #answerCall(Call)
+     * @see InCallScreen#internalAnswerCall()
+     */
+    /* package */ static boolean answerAndEndActive(CallManager cm, Call ringing) {
+        if (DBG) log("answerAndEndActive()...");
+
+        // Unlike the answerCall() method, we *don't* need to stop the
+        // ringer or change audio modes here since the user is already
+        // in-call, which means that the audio mode is already set
+        // correctly, and that we wouldn't have started the ringer in the
+        // first place.
+
+        // hanging up the active call also accepts the waiting call
+        // while active call and waiting call are from the same phone
+        // i.e. both from GSM phone
+        if (!hangupActiveCall(cm.getActiveFgCall())) {
+            Log.w(LOG_TAG, "end active call failed!");
+            return false;
+        }
+
+        // since hangupActiveCall() also accepts the ringing call
+        // check if the ringing call was already answered or not
+        // only answer it when the call still is ringing
+        if (ringing.isRinging()) {
+            return answerCall(ringing);
+        }
+
+        return true;
+    }
+
+    /**
+     * For a CDMA phone, advance the call state upon making a new
+     * outgoing call.
+     *
+     * <pre>
+     *   IDLE -> SINGLE_ACTIVE
+     * or
+     *   SINGLE_ACTIVE -> THRWAY_ACTIVE
+     * </pre>
+     * @param app The phone instance.
+     */
+    private static void updateCdmaCallStateOnNewOutgoingCall(PhoneGlobals app) {
+        if (app.cdmaPhoneCallState.getCurrentCallState() ==
+            CdmaPhoneCallState.PhoneCallState.IDLE) {
+            // This is the first outgoing call. Set the Phone Call State to ACTIVE
+            app.cdmaPhoneCallState.setCurrentCallState(
+                CdmaPhoneCallState.PhoneCallState.SINGLE_ACTIVE);
+        } else {
+            // This is the second outgoing call. Set the Phone Call State to 3WAY
+            app.cdmaPhoneCallState.setCurrentCallState(
+                CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE);
+        }
+    }
+
+    /**
+     * Dial the number using the phone passed in.
+     *
+     * If the connection is establised, this method issues a sync call
+     * that may block to query the caller info.
+     * TODO: Change the logic to use the async query.
+     *
+     * @param context To perform the CallerInfo query.
+     * @param phone the Phone object.
+     * @param number to be dialed as requested by the user. This is
+     * NOT the phone number to connect to. It is used only to build the
+     * call card and to update the call log. See above for restrictions.
+     * @param contactRef that triggered the call. Typically a 'tel:'
+     * uri but can also be a 'content://contacts' one.
+     * @param isEmergencyCall indicates that whether or not this is an
+     * emergency call
+     * @param gatewayUri Is the address used to setup the connection, null
+     * if not using a gateway
+     *
+     * @return either CALL_STATUS_DIALED or CALL_STATUS_FAILED
+     */
+    public static int placeCall(Context context, Phone phone,
+            String number, Uri contactRef, boolean isEmergencyCall,
+            Uri gatewayUri) {
+        if (VDBG) {
+            log("placeCall()... number: '" + number + "'"
+                    + ", GW:'" + gatewayUri + "'"
+                    + ", contactRef:" + contactRef
+                    + ", isEmergencyCall: " + isEmergencyCall);
+        } else {
+            log("placeCall()... number: " + toLogSafePhoneNumber(number)
+                    + ", GW: " + (gatewayUri != null ? "non-null" : "null")
+                    + ", emergency? " + isEmergencyCall);
+        }
+        final PhoneGlobals app = PhoneGlobals.getInstance();
+
+        boolean useGateway = false;
+        if (null != gatewayUri &&
+            !isEmergencyCall &&
+            PhoneUtils.isRoutableViaGateway(number)) {  // Filter out MMI, OTA and other codes.
+            useGateway = true;
+        }
+
+        int status = CALL_STATUS_DIALED;
+        Connection connection;
+        String numberToDial;
+        if (useGateway) {
+            // TODO: 'tel' should be a constant defined in framework base
+            // somewhere (it is in webkit.)
+            if (null == gatewayUri || !Constants.SCHEME_TEL.equals(gatewayUri.getScheme())) {
+                Log.e(LOG_TAG, "Unsupported URL:" + gatewayUri);
+                return CALL_STATUS_FAILED;
+            }
+
+            // We can use getSchemeSpecificPart because we don't allow #
+            // in the gateway numbers (treated a fragment delim.) However
+            // if we allow more complex gateway numbers sequence (with
+            // passwords or whatnot) that use #, this may break.
+            // TODO: Need to support MMI codes.
+            numberToDial = gatewayUri.getSchemeSpecificPart();
+        } else {
+            numberToDial = number;
+        }
+
+        // Remember if the phone state was in IDLE state before this call.
+        // After calling CallManager#dial(), getState() will return different state.
+        final boolean initiallyIdle = app.mCM.getState() == PhoneConstants.State.IDLE;
+
+        try {
+            connection = app.mCM.dial(phone, numberToDial);
+        } catch (CallStateException ex) {
+            // CallStateException means a new outgoing call is not currently
+            // possible: either no more call slots exist, or there's another
+            // call already in the process of dialing or ringing.
+            Log.w(LOG_TAG, "Exception from app.mCM.dial()", ex);
+            return CALL_STATUS_FAILED;
+
+            // Note that it's possible for CallManager.dial() to return
+            // null *without* throwing an exception; that indicates that
+            // we dialed an MMI (see below).
+        }
+
+        int phoneType = phone.getPhoneType();
+
+        // On GSM phones, null is returned for MMI codes
+        if (null == connection) {
+            if (phoneType == PhoneConstants.PHONE_TYPE_GSM && gatewayUri == null) {
+                if (DBG) log("dialed MMI code: " + number);
+                status = CALL_STATUS_DIALED_MMI;
+            } else {
+                status = CALL_STATUS_FAILED;
+            }
+        } else {
+            if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
+                updateCdmaCallStateOnNewOutgoingCall(app);
+            }
+
+            // Clean up the number to be displayed.
+            if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
+                number = CdmaConnection.formatDialString(number);
+            }
+            number = PhoneNumberUtils.extractNetworkPortion(number);
+            number = PhoneNumberUtils.convertKeypadLettersToDigits(number);
+            number = PhoneNumberUtils.formatNumber(number);
+
+            if (gatewayUri == null) {
+                // phone.dial() succeeded: we're now in a normal phone call.
+                // attach the URI to the CallerInfo Object if it is there,
+                // otherwise just attach the Uri Reference.
+                // if the uri does not have a "content" scheme, then we treat
+                // it as if it does NOT have a unique reference.
+                String content = context.getContentResolver().SCHEME_CONTENT;
+                if ((contactRef != null) && (contactRef.getScheme().equals(content))) {
+                    Object userDataObject = connection.getUserData();
+                    if (userDataObject == null) {
+                        connection.setUserData(contactRef);
+                    } else {
+                        // TODO: This branch is dead code, we have
+                        // just created the connection which has
+                        // no user data (null) by default.
+                        if (userDataObject instanceof CallerInfo) {
+                        ((CallerInfo) userDataObject).contactRefUri = contactRef;
+                        } else {
+                        ((CallerInfoToken) userDataObject).currentInfo.contactRefUri =
+                            contactRef;
+                        }
+                    }
+                }
+            } else {
+                // Get the caller info synchronously because we need the final
+                // CallerInfo object to update the dialed number with the one
+                // requested by the user (and not the provider's gateway number).
+                CallerInfo info = null;
+                String content = phone.getContext().getContentResolver().SCHEME_CONTENT;
+                if ((contactRef != null) && (contactRef.getScheme().equals(content))) {
+                    info = CallerInfo.getCallerInfo(context, contactRef);
+                }
+
+                // Fallback, lookup contact using the phone number if the
+                // contact's URI scheme was not content:// or if is was but
+                // the lookup failed.
+                if (null == info) {
+                    info = CallerInfo.getCallerInfo(context, number);
+                }
+                info.phoneNumber = number;
+                connection.setUserData(info);
+            }
+            setAudioMode();
+
+            if (DBG) log("about to activate speaker");
+            // Check is phone in any dock, and turn on speaker accordingly
+            final boolean speakerActivated = activateSpeakerIfDocked(phone);
+
+            // See also similar logic in answerCall().
+            if (initiallyIdle && !speakerActivated && isSpeakerOn(app)
+                    && !app.isBluetoothHeadsetAudioOn()) {
+                // This is not an error but might cause users' confusion. Add log just in case.
+                Log.i(LOG_TAG, "Forcing speaker off when initiating a new outgoing call...");
+                PhoneUtils.turnOnSpeaker(app, false, true);
+            }
+        }
+
+        return status;
+    }
+
+    /* package */ static String toLogSafePhoneNumber(String number) {
+        // For unknown number, log empty string.
+        if (number == null) {
+            return "";
+        }
+
+        if (VDBG) {
+            // When VDBG is true we emit PII.
+            return number;
+        }
+
+        // Do exactly same thing as Uri#toSafeString() does, which will enable us to compare
+        // sanitized phone numbers.
+        StringBuilder builder = new StringBuilder();
+        for (int i = 0; i < number.length(); i++) {
+            char c = number.charAt(i);
+            if (c == '-' || c == '@' || c == '.') {
+                builder.append(c);
+            } else {
+                builder.append('x');
+            }
+        }
+        return builder.toString();
+    }
+
+    /**
+     * Wrapper function to control when to send an empty Flash command to the network.
+     * Mainly needed for CDMA networks, such as scenarios when we need to send a blank flash
+     * to the network prior to placing a 3-way call for it to be successful.
+     */
+    static void sendEmptyFlash(Phone phone) {
+        if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
+            Call fgCall = phone.getForegroundCall();
+            if (fgCall.getState() == Call.State.ACTIVE) {
+                // Send the empty flash
+                if (DBG) Log.d(LOG_TAG, "onReceive: (CDMA) sending empty flash to network");
+                switchHoldingAndActive(phone.getBackgroundCall());
+            }
+        }
+    }
+
+    /**
+     * @param heldCall is the background call want to be swapped
+     */
+    static void switchHoldingAndActive(Call heldCall) {
+        log("switchHoldingAndActive()...");
+        try {
+            CallManager cm = PhoneGlobals.getInstance().mCM;
+            if (heldCall.isIdle()) {
+                // no heldCall, so it is to hold active call
+                cm.switchHoldingAndActive(cm.getFgPhone().getBackgroundCall());
+            } else {
+                // has particular heldCall, so to switch
+                cm.switchHoldingAndActive(heldCall);
+            }
+            setAudioMode(cm);
+        } catch (CallStateException ex) {
+            Log.w(LOG_TAG, "switchHoldingAndActive: caught " + ex, ex);
+        }
+    }
+
+    /**
+     * Restore the mute setting from the earliest connection of the
+     * foreground call.
+     */
+    static Boolean restoreMuteState() {
+        Phone phone = PhoneGlobals.getInstance().mCM.getFgPhone();
+
+        //get the earliest connection
+        Connection c = phone.getForegroundCall().getEarliestConnection();
+
+        // only do this if connection is not null.
+        if (c != null) {
+
+            int phoneType = phone.getPhoneType();
+
+            // retrieve the mute value.
+            Boolean shouldMute = null;
+
+            // In CDMA, mute is not maintained per Connection. Single mute apply for
+            // a call where  call can have multiple connections such as
+            // Three way and Call Waiting.  Therefore retrieving Mute state for
+            // latest connection can apply for all connection in that call
+            if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
+                shouldMute = sConnectionMuteTable.get(
+                        phone.getForegroundCall().getLatestConnection());
+            } else if ((phoneType == PhoneConstants.PHONE_TYPE_GSM)
+                    || (phoneType == PhoneConstants.PHONE_TYPE_SIP)) {
+                shouldMute = sConnectionMuteTable.get(c);
+            }
+            if (shouldMute == null) {
+                if (DBG) log("problem retrieving mute value for this connection.");
+                shouldMute = Boolean.FALSE;
+            }
+
+            // set the mute value and return the result.
+            setMute (shouldMute.booleanValue());
+            return shouldMute;
+        }
+        return Boolean.valueOf(getMute());
+    }
+
+    static void mergeCalls() {
+        mergeCalls(PhoneGlobals.getInstance().mCM);
+    }
+
+    static void mergeCalls(CallManager cm) {
+        int phoneType = cm.getFgPhone().getPhoneType();
+        if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
+            log("mergeCalls(): CDMA...");
+            PhoneGlobals app = PhoneGlobals.getInstance();
+            if (app.cdmaPhoneCallState.getCurrentCallState()
+                    == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
+                // Set the Phone Call State to conference
+                app.cdmaPhoneCallState.setCurrentCallState(
+                        CdmaPhoneCallState.PhoneCallState.CONF_CALL);
+
+                // Send flash cmd
+                // TODO: Need to change the call from switchHoldingAndActive to
+                // something meaningful as we are not actually trying to swap calls but
+                // instead are merging two calls by sending a Flash command.
+                log("- sending flash...");
+                switchHoldingAndActive(cm.getFirstActiveBgCall());
+            }
+        } else {
+            try {
+                log("mergeCalls(): calling cm.conference()...");
+                cm.conference(cm.getFirstActiveBgCall());
+            } catch (CallStateException ex) {
+                Log.w(LOG_TAG, "mergeCalls: caught " + ex, ex);
+            }
+        }
+    }
+
+    static void separateCall(Connection c) {
+        try {
+            if (DBG) log("separateCall: " + toLogSafePhoneNumber(c.getAddress()));
+            c.separate();
+        } catch (CallStateException ex) {
+            Log.w(LOG_TAG, "separateCall: caught " + ex, ex);
+        }
+    }
+
+    /**
+     * Handle the MMIInitiate message and put up an alert that lets
+     * the user cancel the operation, if applicable.
+     *
+     * @param context context to get strings.
+     * @param mmiCode the MmiCode object being started.
+     * @param buttonCallbackMessage message to post when button is clicked.
+     * @param previousAlert a previous alert used in this activity.
+     * @return the dialog handle
+     */
+    static Dialog displayMMIInitiate(Context context,
+                                          MmiCode mmiCode,
+                                          Message buttonCallbackMessage,
+                                          Dialog previousAlert) {
+        if (DBG) log("displayMMIInitiate: " + mmiCode);
+        if (previousAlert != null) {
+            previousAlert.dismiss();
+        }
+
+        // The UI paradigm we are using now requests that all dialogs have
+        // user interaction, and that any other messages to the user should
+        // be by way of Toasts.
+        //
+        // In adhering to this request, all MMI initiating "OK" dialogs
+        // (non-cancelable MMIs) that end up being closed when the MMI
+        // completes (thereby showing a completion dialog) are being
+        // replaced with Toasts.
+        //
+        // As a side effect, moving to Toasts for the non-cancelable MMIs
+        // also means that buttonCallbackMessage (which was tied into "OK")
+        // is no longer invokable for these dialogs.  This is not a problem
+        // since the only callback messages we supported were for cancelable
+        // MMIs anyway.
+        //
+        // A cancelable MMI is really just a USSD request. The term
+        // "cancelable" here means that we can cancel the request when the
+        // system prompts us for a response, NOT while the network is
+        // processing the MMI request.  Any request to cancel a USSD while
+        // the network is NOT ready for a response may be ignored.
+        //
+        // With this in mind, we replace the cancelable alert dialog with
+        // a progress dialog, displayed until we receive a request from
+        // the the network.  For more information, please see the comments
+        // in the displayMMIComplete() method below.
+        //
+        // Anything that is NOT a USSD request is a normal MMI request,
+        // which will bring up a toast (desribed above).
+
+        boolean isCancelable = (mmiCode != null) && mmiCode.isCancelable();
+
+        if (!isCancelable) {
+            if (DBG) log("not a USSD code, displaying status toast.");
+            CharSequence text = context.getText(R.string.mmiStarted);
+            Toast.makeText(context, text, Toast.LENGTH_SHORT)
+                .show();
+            return null;
+        } else {
+            if (DBG) log("running USSD code, displaying indeterminate progress.");
+
+            // create the indeterminate progress dialog and display it.
+            ProgressDialog pd = new ProgressDialog(context);
+            pd.setMessage(context.getText(R.string.ussdRunning));
+            pd.setCancelable(false);
+            pd.setIndeterminate(true);
+            pd.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
+
+            pd.show();
+
+            return pd;
+        }
+
+    }
+
+    /**
+     * Handle the MMIComplete message and fire off an intent to display
+     * the message.
+     *
+     * @param context context to get strings.
+     * @param mmiCode MMI result.
+     * @param previousAlert a previous alert used in this activity.
+     */
+    static void displayMMIComplete(final Phone phone, Context context, final MmiCode mmiCode,
+            Message dismissCallbackMessage,
+            AlertDialog previousAlert) {
+        final PhoneGlobals app = PhoneGlobals.getInstance();
+        CharSequence text;
+        int title = 0;  // title for the progress dialog, if needed.
+        MmiCode.State state = mmiCode.getState();
+
+        if (DBG) log("displayMMIComplete: state=" + state);
+
+        switch (state) {
+            case PENDING:
+                // USSD code asking for feedback from user.
+                text = mmiCode.getMessage();
+                if (DBG) log("- using text from PENDING MMI message: '" + text + "'");
+                break;
+            case CANCELLED:
+                text = null;
+                break;
+            case COMPLETE:
+                if (app.getPUKEntryActivity() != null) {
+                    // if an attempt to unPUK the device was made, we specify
+                    // the title and the message here.
+                    title = com.android.internal.R.string.PinMmi;
+                    text = context.getText(R.string.puk_unlocked);
+                    break;
+                }
+                // All other conditions for the COMPLETE mmi state will cause
+                // the case to fall through to message logic in common with
+                // the FAILED case.
+
+            case FAILED:
+                text = mmiCode.getMessage();
+                if (DBG) log("- using text from MMI message: '" + text + "'");
+                break;
+            default:
+                throw new IllegalStateException("Unexpected MmiCode state: " + state);
+        }
+
+        if (previousAlert != null) {
+            previousAlert.dismiss();
+        }
+
+        // Check to see if a UI exists for the PUK activation.  If it does
+        // exist, then it indicates that we're trying to unblock the PUK.
+        if ((app.getPUKEntryActivity() != null) && (state == MmiCode.State.COMPLETE)) {
+            if (DBG) log("displaying PUK unblocking progress dialog.");
+
+            // create the progress dialog, make sure the flags and type are
+            // set correctly.
+            ProgressDialog pd = new ProgressDialog(app);
+            pd.setTitle(title);
+            pd.setMessage(text);
+            pd.setCancelable(false);
+            pd.setIndeterminate(true);
+            pd.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
+            pd.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
+
+            // display the dialog
+            pd.show();
+
+            // indicate to the Phone app that the progress dialog has
+            // been assigned for the PUK unlock / SIM READY process.
+            app.setPukEntryProgressDialog(pd);
+
+        } else {
+            // In case of failure to unlock, we'll need to reset the
+            // PUK unlock activity, so that the user may try again.
+            if (app.getPUKEntryActivity() != null) {
+                app.setPukEntryActivity(null);
+            }
+
+            // A USSD in a pending state means that it is still
+            // interacting with the user.
+            if (state != MmiCode.State.PENDING) {
+                if (DBG) log("MMI code has finished running.");
+
+                if (DBG) log("Extended NW displayMMIInitiate (" + text + ")");
+                if (text == null || text.length() == 0)
+                    return;
+
+                // displaying system alert dialog on the screen instead of
+                // using another activity to display the message.  This
+                // places the message at the forefront of the UI.
+                AlertDialog newDialog = new AlertDialog.Builder(context)
+                        .setMessage(text)
+                        .setPositiveButton(R.string.ok, null)
+                        .setCancelable(true)
+                        .create();
+
+                newDialog.getWindow().setType(
+                        WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
+                newDialog.getWindow().addFlags(
+                        WindowManager.LayoutParams.FLAG_DIM_BEHIND);
+
+                newDialog.show();
+            } else {
+                if (DBG) log("USSD code has requested user input. Constructing input dialog.");
+
+                // USSD MMI code that is interacting with the user.  The
+                // basic set of steps is this:
+                //   1. User enters a USSD request
+                //   2. We recognize the request and displayMMIInitiate
+                //      (above) creates a progress dialog.
+                //   3. Request returns and we get a PENDING or COMPLETE
+                //      message.
+                //   4. These MMI messages are caught in the PhoneApp
+                //      (onMMIComplete) and the InCallScreen
+                //      (mHandler.handleMessage) which bring up this dialog
+                //      and closes the original progress dialog,
+                //      respectively.
+                //   5. If the message is anything other than PENDING,
+                //      we are done, and the alert dialog (directly above)
+                //      displays the outcome.
+                //   6. If the network is requesting more information from
+                //      the user, the MMI will be in a PENDING state, and
+                //      we display this dialog with the message.
+                //   7. User input, or cancel requests result in a return
+                //      to step 1.  Keep in mind that this is the only
+                //      time that a USSD should be canceled.
+
+                // inflate the layout with the scrolling text area for the dialog.
+                LayoutInflater inflater = (LayoutInflater) context.getSystemService(
+                        Context.LAYOUT_INFLATER_SERVICE);
+                View dialogView = inflater.inflate(R.layout.dialog_ussd_response, null);
+
+                // get the input field.
+                final EditText inputText = (EditText) dialogView.findViewById(R.id.input_field);
+
+                // specify the dialog's click listener, with SEND and CANCEL logic.
+                final DialogInterface.OnClickListener mUSSDDialogListener =
+                    new DialogInterface.OnClickListener() {
+                        public void onClick(DialogInterface dialog, int whichButton) {
+                            switch (whichButton) {
+                                case DialogInterface.BUTTON_POSITIVE:
+                                    // As per spec 24.080, valid length of ussd string
+                                    // is 1 - 160. If length is out of the range then
+                                    // display toast message & Cancel MMI operation.
+                                    if (inputText.length() < MIN_USSD_LEN
+                                            || inputText.length() > MAX_USSD_LEN) {
+                                        Toast.makeText(app,
+                                                app.getResources().getString(R.string.enter_input,
+                                                MIN_USSD_LEN, MAX_USSD_LEN),
+                                                Toast.LENGTH_LONG).show();
+                                        if (mmiCode.isCancelable()) {
+                                            mmiCode.cancel();
+                                        }
+                                    } else {
+                                        phone.sendUssdResponse(inputText.getText().toString());
+                                    }
+                                    break;
+                                case DialogInterface.BUTTON_NEGATIVE:
+                                    if (mmiCode.isCancelable()) {
+                                        mmiCode.cancel();
+                                    }
+                                    break;
+                            }
+                        }
+                    };
+
+                // build the dialog
+                final AlertDialog newDialog = new AlertDialog.Builder(context)
+                        .setMessage(text)
+                        .setView(dialogView)
+                        .setPositiveButton(R.string.send_button, mUSSDDialogListener)
+                        .setNegativeButton(R.string.cancel, mUSSDDialogListener)
+                        .setCancelable(false)
+                        .create();
+
+                // attach the key listener to the dialog's input field and make
+                // sure focus is set.
+                final View.OnKeyListener mUSSDDialogInputListener =
+                    new View.OnKeyListener() {
+                        public boolean onKey(View v, int keyCode, KeyEvent event) {
+                            switch (keyCode) {
+                                case KeyEvent.KEYCODE_CALL:
+                                case KeyEvent.KEYCODE_ENTER:
+                                    if(event.getAction() == KeyEvent.ACTION_DOWN) {
+                                        phone.sendUssdResponse(inputText.getText().toString());
+                                        newDialog.dismiss();
+                                    }
+                                    return true;
+                            }
+                            return false;
+                        }
+                    };
+                inputText.setOnKeyListener(mUSSDDialogInputListener);
+                inputText.requestFocus();
+
+                // set the window properties of the dialog
+                newDialog.getWindow().setType(
+                        WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
+                newDialog.getWindow().addFlags(
+                        WindowManager.LayoutParams.FLAG_DIM_BEHIND);
+
+                // now show the dialog!
+                newDialog.show();
+            }
+        }
+    }
+
+    /**
+     * Cancels the current pending MMI operation, if applicable.
+     * @return true if we canceled an MMI operation, or false
+     *         if the current pending MMI wasn't cancelable
+     *         or if there was no current pending MMI at all.
+     *
+     * @see displayMMIInitiate
+     */
+    static boolean cancelMmiCode(Phone phone) {
+        List<? extends MmiCode> pendingMmis = phone.getPendingMmiCodes();
+        int count = pendingMmis.size();
+        if (DBG) log("cancelMmiCode: num pending MMIs = " + count);
+
+        boolean canceled = false;
+        if (count > 0) {
+            // assume that we only have one pending MMI operation active at a time.
+            // I don't think it's possible to enter multiple MMI codes concurrently
+            // in the phone UI, because during the MMI operation, an Alert panel
+            // is displayed, which prevents more MMI code from being entered.
+            MmiCode mmiCode = pendingMmis.get(0);
+            if (mmiCode.isCancelable()) {
+                mmiCode.cancel();
+                canceled = true;
+            }
+        }
+        return canceled;
+    }
+
+    public static class VoiceMailNumberMissingException extends Exception {
+        VoiceMailNumberMissingException() {
+            super();
+        }
+
+        VoiceMailNumberMissingException(String msg) {
+            super(msg);
+        }
+    }
+
+    /**
+     * Given an Intent (which is presumably the ACTION_CALL intent that
+     * initiated this outgoing call), figure out the actual phone number we
+     * should dial.
+     *
+     * Note that the returned "number" may actually be a SIP address,
+     * if the specified intent contains a sip: URI.
+     *
+     * This method is basically a wrapper around PhoneUtils.getNumberFromIntent(),
+     * except it's also aware of the EXTRA_ACTUAL_NUMBER_TO_DIAL extra.
+     * (That extra, if present, tells us the exact string to pass down to the
+     * telephony layer.  It's guaranteed to be safe to dial: it's either a PSTN
+     * phone number with separators and keypad letters stripped out, or a raw
+     * unencoded SIP address.)
+     *
+     * @return the phone number corresponding to the specified Intent, or null
+     *   if the Intent has no action or if the intent's data is malformed or
+     *   missing.
+     *
+     * @throws VoiceMailNumberMissingException if the intent
+     *   contains a "voicemail" URI, but there's no voicemail
+     *   number configured on the device.
+     */
+    public static String getInitialNumber(Intent intent)
+            throws PhoneUtils.VoiceMailNumberMissingException {
+        if (DBG) log("getInitialNumber(): " + intent);
+
+        String action = intent.getAction();
+        if (TextUtils.isEmpty(action)) {
+            return null;
+        }
+
+        // If the EXTRA_ACTUAL_NUMBER_TO_DIAL extra is present, get the phone
+        // number from there.  (That extra takes precedence over the actual data
+        // included in the intent.)
+        if (intent.hasExtra(OutgoingCallBroadcaster.EXTRA_ACTUAL_NUMBER_TO_DIAL)) {
+            String actualNumberToDial =
+                    intent.getStringExtra(OutgoingCallBroadcaster.EXTRA_ACTUAL_NUMBER_TO_DIAL);
+            if (DBG) {
+                log("==> got EXTRA_ACTUAL_NUMBER_TO_DIAL; returning '"
+                        + toLogSafePhoneNumber(actualNumberToDial) + "'");
+            }
+            return actualNumberToDial;
+        }
+
+        return getNumberFromIntent(PhoneGlobals.getInstance(), intent);
+    }
+
+    /**
+     * Gets the phone number to be called from an intent.  Requires a Context
+     * to access the contacts database, and a Phone to access the voicemail
+     * number.
+     *
+     * <p>If <code>phone</code> is <code>null</code>, the function will return
+     * <code>null</code> for <code>voicemail:</code> URIs;
+     * if <code>context</code> is <code>null</code>, the function will return
+     * <code>null</code> for person/phone URIs.</p>
+     *
+     * <p>If the intent contains a <code>sip:</code> URI, the returned
+     * "number" is actually the SIP address.
+     *
+     * @param context a context to use (or
+     * @param intent the intent
+     *
+     * @throws VoiceMailNumberMissingException if <code>intent</code> contains
+     *         a <code>voicemail:</code> URI, but <code>phone</code> does not
+     *         have a voicemail number set.
+     *
+     * @return the phone number (or SIP address) that would be called by the intent,
+     *         or <code>null</code> if the number cannot be found.
+     */
+    private static String getNumberFromIntent(Context context, Intent intent)
+            throws VoiceMailNumberMissingException {
+        Uri uri = intent.getData();
+        String scheme = uri.getScheme();
+
+        // The sip: scheme is simple: just treat the rest of the URI as a
+        // SIP address.
+        if (Constants.SCHEME_SIP.equals(scheme)) {
+            return uri.getSchemeSpecificPart();
+        }
+
+        // Otherwise, let PhoneNumberUtils.getNumberFromIntent() handle
+        // the other cases (i.e. tel: and voicemail: and contact: URIs.)
+
+        final String number = PhoneNumberUtils.getNumberFromIntent(intent, context);
+
+        // Check for a voicemail-dialing request.  If the voicemail number is
+        // empty, throw a VoiceMailNumberMissingException.
+        if (Constants.SCHEME_VOICEMAIL.equals(scheme) &&
+                (number == null || TextUtils.isEmpty(number)))
+            throw new VoiceMailNumberMissingException();
+
+        return number;
+    }
+
+    /**
+     * Returns the caller-id info corresponding to the specified Connection.
+     * (This is just a simple wrapper around CallerInfo.getCallerInfo(): we
+     * extract a phone number from the specified Connection, and feed that
+     * number into CallerInfo.getCallerInfo().)
+     *
+     * The returned CallerInfo may be null in certain error cases, like if the
+     * specified Connection was null, or if we weren't able to get a valid
+     * phone number from the Connection.
+     *
+     * Finally, if the getCallerInfo() call did succeed, we save the resulting
+     * CallerInfo object in the "userData" field of the Connection.
+     *
+     * NOTE: This API should be avoided, with preference given to the
+     * asynchronous startGetCallerInfo API.
+     */
+    static CallerInfo getCallerInfo(Context context, Connection c) {
+        CallerInfo info = null;
+
+        if (c != null) {
+            //See if there is a URI attached.  If there is, this means
+            //that there is no CallerInfo queried yet, so we'll need to
+            //replace the URI with a full CallerInfo object.
+            Object userDataObject = c.getUserData();
+            if (userDataObject instanceof Uri) {
+                info = CallerInfo.getCallerInfo(context, (Uri) userDataObject);
+                if (info != null) {
+                    c.setUserData(info);
+                }
+            } else {
+                if (userDataObject instanceof CallerInfoToken) {
+                    //temporary result, while query is running
+                    info = ((CallerInfoToken) userDataObject).currentInfo;
+                } else {
+                    //final query result
+                    info = (CallerInfo) userDataObject;
+                }
+                if (info == null) {
+                    // No URI, or Existing CallerInfo, so we'll have to make do with
+                    // querying a new CallerInfo using the connection's phone number.
+                    String number = c.getAddress();
+
+                    if (DBG) log("getCallerInfo: number = " + toLogSafePhoneNumber(number));
+
+                    if (!TextUtils.isEmpty(number)) {
+                        info = CallerInfo.getCallerInfo(context, number);
+                        if (info != null) {
+                            c.setUserData(info);
+                        }
+                    }
+                }
+            }
+        }
+        return info;
+    }
+
+    /**
+     * Class returned by the startGetCallerInfo call to package a temporary
+     * CallerInfo Object, to be superceded by the CallerInfo Object passed
+     * into the listener when the query with token mAsyncQueryToken is complete.
+     */
+    public static class CallerInfoToken {
+        /**indicates that there will no longer be updates to this request.*/
+        public boolean isFinal;
+
+        public CallerInfo currentInfo;
+        public CallerInfoAsyncQuery asyncQuery;
+    }
+
+    /**
+     * Start a CallerInfo Query based on the earliest connection in the call.
+     */
+    static CallerInfoToken startGetCallerInfo(Context context, Call call,
+            CallerInfoAsyncQuery.OnQueryCompleteListener listener, Object 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);
+        }
+
+        return startGetCallerInfo(context, conn, listener, cookie);
+    }
+
+    /**
+     * place a temporary callerinfo object in the hands of the caller and notify
+     * caller when the actual query is done.
+     */
+    static CallerInfoToken startGetCallerInfo(Context context, Connection c,
+            CallerInfoAsyncQuery.OnQueryCompleteListener listener, Object cookie) {
+        CallerInfoToken cit;
+
+        if (c == null) {
+            //TODO: perhaps throw an exception here.
+            cit = new CallerInfoToken();
+            cit.asyncQuery = null;
+            return cit;
+        }
+
+        Object userDataObject = c.getUserData();
+
+        // There are now 3 states for the Connection's userData object:
+        //
+        //   (1) Uri - query has not been executed yet
+        //
+        //   (2) CallerInfoToken - query is executing, but has not completed.
+        //
+        //   (3) CallerInfo - query has executed.
+        //
+        // In each case we have slightly different behaviour:
+        //   1. If the query has not been executed yet (Uri or null), we start
+        //      query execution asynchronously, and note it by attaching a
+        //      CallerInfoToken as the userData.
+        //   2. If the query is executing (CallerInfoToken), we've essentially
+        //      reached a state where we've received multiple requests for the
+        //      same callerInfo.  That means that once the query is complete,
+        //      we'll need to execute the additional listener requested.
+        //   3. If the query has already been executed (CallerInfo), we just
+        //      return the CallerInfo object as expected.
+        //   4. Regarding isFinal - there are cases where the CallerInfo object
+        //      will not be attached, like when the number is empty (caller id
+        //      blocking).  This flag is used to indicate that the
+        //      CallerInfoToken object is going to be permanent since no
+        //      query results will be returned.  In the case where a query
+        //      has been completed, this flag is used to indicate to the caller
+        //      that the data will not be updated since it is valid.
+        //
+        //      Note: For the case where a number is NOT retrievable, we leave
+        //      the CallerInfo as null in the CallerInfoToken.  This is
+        //      something of a departure from the original code, since the old
+        //      code manufactured a CallerInfo object regardless of the query
+        //      outcome.  From now on, we will append an empty CallerInfo
+        //      object, to mirror previous behaviour, and to avoid Null Pointer
+        //      Exceptions.
+
+        if (userDataObject instanceof Uri) {
+            // State (1): query has not been executed yet
+
+            //create a dummy callerinfo, populate with what we know from URI.
+            cit = new CallerInfoToken();
+            cit.currentInfo = new CallerInfo();
+            cit.asyncQuery = CallerInfoAsyncQuery.startQuery(QUERY_TOKEN, context,
+                    (Uri) userDataObject, sCallerInfoQueryListener, c);
+            cit.asyncQuery.addQueryListener(QUERY_TOKEN, listener, cookie);
+            cit.isFinal = false;
+
+            c.setUserData(cit);
+
+            if (DBG) log("startGetCallerInfo: query based on Uri: " + userDataObject);
+
+        } else if (userDataObject == null) {
+            // No URI, or Existing CallerInfo, so we'll have to make do with
+            // querying a new CallerInfo using the connection's phone number.
+            String number = c.getAddress();
+
+            if (DBG) {
+                log("PhoneUtils.startGetCallerInfo: new query for phone number...");
+                log("- number (address): " + toLogSafePhoneNumber(number));
+                log("- c: " + c);
+                log("- phone: " + c.getCall().getPhone());
+                int phoneType = c.getCall().getPhone().getPhoneType();
+                log("- phoneType: " + phoneType);
+                switch (phoneType) {
+                    case PhoneConstants.PHONE_TYPE_NONE: log("  ==> PHONE_TYPE_NONE"); break;
+                    case PhoneConstants.PHONE_TYPE_GSM: log("  ==> PHONE_TYPE_GSM"); break;
+                    case PhoneConstants.PHONE_TYPE_CDMA: log("  ==> PHONE_TYPE_CDMA"); break;
+                    case PhoneConstants.PHONE_TYPE_SIP: log("  ==> PHONE_TYPE_SIP"); break;
+                    default: log("  ==> Unknown phone type"); break;
+                }
+            }
+
+            cit = new CallerInfoToken();
+            cit.currentInfo = new CallerInfo();
+
+            // Store CNAP information retrieved from the Connection (we want to do this
+            // here regardless of whether the number is empty or not).
+            cit.currentInfo.cnapName =  c.getCnapName();
+            cit.currentInfo.name = cit.currentInfo.cnapName; // This can still get overwritten
+                                                             // by ContactInfo later
+            cit.currentInfo.numberPresentation = c.getNumberPresentation();
+            cit.currentInfo.namePresentation = c.getCnapNamePresentation();
+
+            if (VDBG) {
+                log("startGetCallerInfo: number = " + number);
+                log("startGetCallerInfo: CNAP Info from FW(1): name="
+                    + cit.currentInfo.cnapName
+                    + ", Name/Number Pres=" + cit.currentInfo.numberPresentation);
+            }
+
+            // handling case where number is null (caller id hidden) as well.
+            if (!TextUtils.isEmpty(number)) {
+                // Check for special CNAP cases and modify the CallerInfo accordingly
+                // to be sure we keep the right information to display/log later
+                number = modifyForSpecialCnapCases(context, cit.currentInfo, number,
+                        cit.currentInfo.numberPresentation);
+
+                cit.currentInfo.phoneNumber = number;
+                // For scenarios where we may receive a valid number from the network but a
+                // restricted/unavailable presentation, we do not want to perform a contact query
+                // (see note on isFinal above). So we set isFinal to true here as well.
+                if (cit.currentInfo.numberPresentation != PhoneConstants.PRESENTATION_ALLOWED) {
+                    cit.isFinal = true;
+                } else {
+                    if (DBG) log("==> Actually starting CallerInfoAsyncQuery.startQuery()...");
+                    cit.asyncQuery = CallerInfoAsyncQuery.startQuery(QUERY_TOKEN, context,
+                            number, sCallerInfoQueryListener, c);
+                    cit.asyncQuery.addQueryListener(QUERY_TOKEN, listener, cookie);
+                    cit.isFinal = false;
+                }
+            } else {
+                // This is the case where we are querying on a number that
+                // is null or empty, like a caller whose caller id is
+                // blocked or empty (CLIR).  The previous behaviour was to
+                // throw a null CallerInfo object back to the user, but
+                // this departure is somewhat cleaner.
+                if (DBG) log("startGetCallerInfo: No query to start, send trivial reply.");
+                cit.isFinal = true; // please see note on isFinal, above.
+            }
+
+            c.setUserData(cit);
+
+            if (DBG) {
+                log("startGetCallerInfo: query based on number: " + toLogSafePhoneNumber(number));
+            }
+
+        } else if (userDataObject instanceof CallerInfoToken) {
+            // State (2): query is executing, but has not completed.
+
+            // just tack on this listener to the queue.
+            cit = (CallerInfoToken) userDataObject;
+
+            // handling case where number is null (caller id hidden) as well.
+            if (cit.asyncQuery != null) {
+                cit.asyncQuery.addQueryListener(QUERY_TOKEN, listener, cookie);
+
+                if (DBG) log("startGetCallerInfo: query already running, adding listener: " +
+                        listener.getClass().toString());
+            } else {
+                // handling case where number/name gets updated later on by the network
+                String updatedNumber = c.getAddress();
+                if (DBG) {
+                    log("startGetCallerInfo: updatedNumber initially = "
+                            + toLogSafePhoneNumber(updatedNumber));
+                }
+                if (!TextUtils.isEmpty(updatedNumber)) {
+                    // Store CNAP information retrieved from the Connection
+                    cit.currentInfo.cnapName =  c.getCnapName();
+                    // This can still get overwritten by ContactInfo
+                    cit.currentInfo.name = cit.currentInfo.cnapName;
+                    cit.currentInfo.numberPresentation = c.getNumberPresentation();
+                    cit.currentInfo.namePresentation = c.getCnapNamePresentation();
+
+                    updatedNumber = modifyForSpecialCnapCases(context, cit.currentInfo,
+                            updatedNumber, cit.currentInfo.numberPresentation);
+
+                    cit.currentInfo.phoneNumber = updatedNumber;
+                    if (DBG) {
+                        log("startGetCallerInfo: updatedNumber="
+                                + toLogSafePhoneNumber(updatedNumber));
+                    }
+                    if (VDBG) {
+                        log("startGetCallerInfo: CNAP Info from FW(2): name="
+                                + cit.currentInfo.cnapName
+                                + ", Name/Number Pres=" + cit.currentInfo.numberPresentation);
+                    } else if (DBG) {
+                        log("startGetCallerInfo: CNAP Info from FW(2)");
+                    }
+                    // For scenarios where we may receive a valid number from the network but a
+                    // restricted/unavailable presentation, we do not want to perform a contact query
+                    // (see note on isFinal above). So we set isFinal to true here as well.
+                    if (cit.currentInfo.numberPresentation != PhoneConstants.PRESENTATION_ALLOWED) {
+                        cit.isFinal = true;
+                    } else {
+                        cit.asyncQuery = CallerInfoAsyncQuery.startQuery(QUERY_TOKEN, context,
+                                updatedNumber, sCallerInfoQueryListener, c);
+                        cit.asyncQuery.addQueryListener(QUERY_TOKEN, listener, cookie);
+                        cit.isFinal = false;
+                    }
+                } else {
+                    if (DBG) log("startGetCallerInfo: No query to attach to, send trivial reply.");
+                    if (cit.currentInfo == null) {
+                        cit.currentInfo = new CallerInfo();
+                    }
+                    // Store CNAP information retrieved from the Connection
+                    cit.currentInfo.cnapName = c.getCnapName();  // This can still get
+                                                                 // overwritten by ContactInfo
+                    cit.currentInfo.name = cit.currentInfo.cnapName;
+                    cit.currentInfo.numberPresentation = c.getNumberPresentation();
+                    cit.currentInfo.namePresentation = c.getCnapNamePresentation();
+
+                    if (VDBG) {
+                        log("startGetCallerInfo: CNAP Info from FW(3): name="
+                                + cit.currentInfo.cnapName
+                                + ", Name/Number Pres=" + cit.currentInfo.numberPresentation);
+                    } else if (DBG) {
+                        log("startGetCallerInfo: CNAP Info from FW(3)");
+                    }
+                    cit.isFinal = true; // please see note on isFinal, above.
+                }
+            }
+        } else {
+            // State (3): query is complete.
+
+            // The connection's userDataObject is a full-fledged
+            // CallerInfo instance.  Wrap it in a CallerInfoToken and
+            // return it to the user.
+
+            cit = new CallerInfoToken();
+            cit.currentInfo = (CallerInfo) userDataObject;
+            cit.asyncQuery = null;
+            cit.isFinal = true;
+            // since the query is already done, call the listener.
+            if (DBG) log("startGetCallerInfo: query already done, returning CallerInfo");
+            if (DBG) log("==> cit.currentInfo = " + cit.currentInfo);
+        }
+        return cit;
+    }
+
+    /**
+     * Static CallerInfoAsyncQuery.OnQueryCompleteListener instance that
+     * we use with all our CallerInfoAsyncQuery.startQuery() requests.
+     */
+    private static final int QUERY_TOKEN = -1;
+    static CallerInfoAsyncQuery.OnQueryCompleteListener sCallerInfoQueryListener =
+        new CallerInfoAsyncQuery.OnQueryCompleteListener () {
+            /**
+             * When the query completes, we stash the resulting CallerInfo
+             * object away in the Connection's "userData" (where it will
+             * later be retrieved by the in-call UI.)
+             */
+            public void onQueryComplete(int token, Object cookie, CallerInfo ci) {
+                if (DBG) log("query complete, updating connection.userdata");
+                Connection conn = (Connection) cookie;
+
+                // Added a check if CallerInfo is coming from ContactInfo or from Connection.
+                // If no ContactInfo, then we want to use CNAP information coming from network
+                if (DBG) log("- onQueryComplete: CallerInfo:" + ci);
+                if (ci.contactExists || ci.isEmergencyNumber() || ci.isVoiceMailNumber()) {
+                    // If the number presentation has not been set by
+                    // the ContactInfo, use the one from the
+                    // connection.
+
+                    // TODO: Need a new util method to merge the info
+                    // from the Connection in a CallerInfo object.
+                    // Here 'ci' is a new CallerInfo instance read
+                    // from the DB. It has lost all the connection
+                    // info preset before the query (see PhoneUtils
+                    // line 1334). We should have a method to merge
+                    // back into this new instance the info from the
+                    // connection object not set by the DB. If the
+                    // Connection already has a CallerInfo instance in
+                    // userData, then we could use this instance to
+                    // fill 'ci' in. The same routine could be used in
+                    // PhoneUtils.
+                    if (0 == ci.numberPresentation) {
+                        ci.numberPresentation = conn.getNumberPresentation();
+                    }
+                } else {
+                    // No matching contact was found for this number.
+                    // Return a new CallerInfo based solely on the CNAP
+                    // information from the network.
+
+                    CallerInfo newCi = getCallerInfo(null, conn);
+
+                    // ...but copy over the (few) things we care about
+                    // from the original CallerInfo object:
+                    if (newCi != null) {
+                        newCi.phoneNumber = ci.phoneNumber; // To get formatted phone number
+                        newCi.geoDescription = ci.geoDescription; // To get geo description string
+                        ci = newCi;
+                    }
+                }
+
+                if (DBG) log("==> Stashing CallerInfo " + ci + " into the connection...");
+                conn.setUserData(ci);
+            }
+        };
+
+
+    /**
+     * Returns a single "name" for the specified given a CallerInfo object.
+     * If the name is null, return defaultString as the default value, usually
+     * context.getString(R.string.unknown).
+     */
+    static String getCompactNameFromCallerInfo(CallerInfo ci, Context context) {
+        if (DBG) log("getCompactNameFromCallerInfo: info = " + ci);
+
+        String compactName = null;
+        if (ci != null) {
+            if (TextUtils.isEmpty(ci.name)) {
+                // Perform any modifications for special CNAP cases to
+                // the phone number being displayed, if applicable.
+                compactName = modifyForSpecialCnapCases(context, ci, ci.phoneNumber,
+                                                        ci.numberPresentation);
+            } else {
+                // Don't call modifyForSpecialCnapCases on regular name. See b/2160795.
+                compactName = ci.name;
+            }
+        }
+
+        if ((compactName == null) || (TextUtils.isEmpty(compactName))) {
+            // If we're still null/empty here, then check if we have a presentation
+            // string that takes precedence that we could return, otherwise display
+            // "unknown" string.
+            if (ci != null && ci.numberPresentation == PhoneConstants.PRESENTATION_RESTRICTED) {
+                compactName = context.getString(R.string.private_num);
+            } else if (ci != null && ci.numberPresentation == PhoneConstants.PRESENTATION_PAYPHONE) {
+                compactName = context.getString(R.string.payphone);
+            } else {
+                compactName = context.getString(R.string.unknown);
+            }
+        }
+        if (VDBG) log("getCompactNameFromCallerInfo: compactName=" + compactName);
+        return compactName;
+    }
+
+    /**
+     * Returns true if the specified Call is a "conference call", meaning
+     * that it owns more than one Connection object.  This information is
+     * used to trigger certain UI changes that appear when a conference
+     * call is active (like displaying the label "Conference call", and
+     * enabling the "Manage conference" UI.)
+     *
+     * Watch out: This method simply checks the number of Connections,
+     * *not* their states.  So if a Call has (for example) one ACTIVE
+     * connection and one DISCONNECTED connection, this method will return
+     * true (which is unintuitive, since the Call isn't *really* a
+     * conference call any more.)
+     *
+     * @return true if the specified call has more than one connection (in any state.)
+     */
+    static boolean isConferenceCall(Call call) {
+        // CDMA phones don't have the same concept of "conference call" as
+        // GSM phones do; there's no special "conference call" state of
+        // the UI or a "manage conference" function.  (Instead, when
+        // you're in a 3-way call, all we can do is display the "generic"
+        // state of the UI.)  So as far as the in-call UI is concerned,
+        // Conference corresponds to generic display.
+        final PhoneGlobals app = PhoneGlobals.getInstance();
+        int phoneType = call.getPhone().getPhoneType();
+        if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
+            CdmaPhoneCallState.PhoneCallState state = app.cdmaPhoneCallState.getCurrentCallState();
+            if ((state == CdmaPhoneCallState.PhoneCallState.CONF_CALL)
+                    || ((state == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE)
+                    && !app.cdmaPhoneCallState.IsThreeWayCallOrigStateDialing())) {
+                return true;
+            }
+        } else {
+            List<Connection> connections = call.getConnections();
+            if (connections != null && connections.size() > 1) {
+                return true;
+            }
+        }
+        return false;
+
+        // TODO: We may still want to change the semantics of this method
+        // to say that a given call is only really a conference call if
+        // the number of ACTIVE connections, not the total number of
+        // connections, is greater than one.  (See warning comment in the
+        // javadoc above.)
+        // Here's an implementation of that:
+        //        if (connections == null) {
+        //            return false;
+        //        }
+        //        int numActiveConnections = 0;
+        //        for (Connection conn : connections) {
+        //            if (DBG) log("  - CONN: " + conn + ", state = " + conn.getState());
+        //            if (conn.getState() == Call.State.ACTIVE) numActiveConnections++;
+        //            if (numActiveConnections > 1) {
+        //                return true;
+        //            }
+        //        }
+        //        return false;
+    }
+
+    /**
+     * Launch the Dialer to start a new call.
+     * This is just a wrapper around the ACTION_DIAL intent.
+     */
+    /* package */ static boolean startNewCall(final CallManager cm) {
+        final PhoneGlobals app = PhoneGlobals.getInstance();
+
+        // Sanity-check that this is OK given the current state of the phone.
+        if (!okToAddCall(cm)) {
+            Log.w(LOG_TAG, "startNewCall: can't add a new call in the current state");
+            dumpCallManager();
+            return false;
+        }
+
+        // if applicable, mute the call while we're showing the add call UI.
+        if (cm.hasActiveFgCall()) {
+            setMuteInternal(cm.getActiveFgCall().getPhone(), true);
+            // Inform the phone app that this mute state was NOT done
+            // voluntarily by the User.
+            app.setRestoreMuteOnInCallResume(true);
+        }
+
+        Intent intent = new Intent(Intent.ACTION_DIAL);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+        // when we request the dialer come up, we also want to inform
+        // it that we're going through the "add call" option from the
+        // InCallScreen / PhoneUtils.
+        intent.putExtra(ADD_CALL_MODE_KEY, true);
+        try {
+            app.startActivity(intent);
+        } catch (ActivityNotFoundException e) {
+            // This is rather rare but possible.
+            // Note: this method is used even when the phone is encrypted. At that moment
+            // the system may not find any Activity which can accept this Intent.
+            Log.e(LOG_TAG, "Activity for adding calls isn't found.");
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Turns on/off speaker.
+     *
+     * @param context Context
+     * @param flag True when speaker should be on. False otherwise.
+     * @param store True when the settings should be stored in the device.
+     */
+    /* package */ static void turnOnSpeaker(Context context, boolean flag, boolean store) {
+        if (DBG) log("turnOnSpeaker(flag=" + flag + ", store=" + store + ")...");
+        final PhoneGlobals app = PhoneGlobals.getInstance();
+
+        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        audioManager.setSpeakerphoneOn(flag);
+
+        // record the speaker-enable value
+        if (store) {
+            sIsSpeakerEnabled = flag;
+        }
+
+        // Update the status bar icon
+        app.notificationMgr.updateSpeakerNotification(flag);
+
+        // We also need to make a fresh call to PhoneApp.updateWakeState()
+        // any time the speaker state changes, since the screen timeout is
+        // sometimes different depending on whether or not the speaker is
+        // in use.
+        app.updateWakeState();
+
+        // Update the Proximity sensor based on speaker state
+        app.updateProximitySensorMode(app.mCM.getState());
+
+        app.mCM.setEchoSuppressionEnabled(flag);
+    }
+
+    /**
+     * Restore the speaker mode, called after a wired headset disconnect
+     * event.
+     */
+    static void restoreSpeakerMode(Context context) {
+        if (DBG) log("restoreSpeakerMode, restoring to: " + sIsSpeakerEnabled);
+
+        // change the mode if needed.
+        if (isSpeakerOn(context) != sIsSpeakerEnabled) {
+            turnOnSpeaker(context, sIsSpeakerEnabled, false);
+        }
+    }
+
+    static boolean isSpeakerOn(Context context) {
+        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        return audioManager.isSpeakerphoneOn();
+    }
+
+
+    static void turnOnNoiseSuppression(Context context, boolean flag, boolean store) {
+        if (DBG) log("turnOnNoiseSuppression: " + flag);
+        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+
+        if (!context.getResources().getBoolean(R.bool.has_in_call_noise_suppression)) {
+            return;
+        }
+
+        if (flag) {
+            audioManager.setParameters("noise_suppression=auto");
+        } else {
+            audioManager.setParameters("noise_suppression=off");
+        }
+
+        // record the speaker-enable value
+        if (store) {
+            sIsNoiseSuppressionEnabled = flag;
+        }
+
+        // TODO: implement and manage ICON
+
+    }
+
+    static void restoreNoiseSuppression(Context context) {
+        if (DBG) log("restoreNoiseSuppression, restoring to: " + sIsNoiseSuppressionEnabled);
+
+        if (!context.getResources().getBoolean(R.bool.has_in_call_noise_suppression)) {
+            return;
+        }
+
+        // change the mode if needed.
+        if (isNoiseSuppressionOn(context) != sIsNoiseSuppressionEnabled) {
+            turnOnNoiseSuppression(context, sIsNoiseSuppressionEnabled, false);
+        }
+    }
+
+    static boolean isNoiseSuppressionOn(Context context) {
+
+        if (!context.getResources().getBoolean(R.bool.has_in_call_noise_suppression)) {
+            return false;
+        }
+
+        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        String noiseSuppression = audioManager.getParameters("noise_suppression");
+        if (DBG) log("isNoiseSuppressionOn: " + noiseSuppression);
+        if (noiseSuppression.contains("off")) {
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    /**
+     *
+     * Mute / umute the foreground phone, which has the current foreground call
+     *
+     * All muting / unmuting from the in-call UI should go through this
+     * wrapper.
+     *
+     * Wrapper around Phone.setMute() and setMicrophoneMute().
+     * It also updates the connectionMuteTable and mute icon in the status bar.
+     *
+     */
+    static void setMute(boolean muted) {
+        CallManager cm = PhoneGlobals.getInstance().mCM;
+
+        // make the call to mute the audio
+        setMuteInternal(cm.getFgPhone(), muted);
+
+        // update the foreground connections to match.  This includes
+        // all the connections on conference calls.
+        for (Connection cn : cm.getActiveFgCall().getConnections()) {
+            if (sConnectionMuteTable.get(cn) == null) {
+                if (DBG) log("problem retrieving mute value for this connection.");
+            }
+            sConnectionMuteTable.put(cn, Boolean.valueOf(muted));
+        }
+    }
+
+    /**
+     * Internally used muting function.
+     */
+    private static void setMuteInternal(Phone phone, boolean muted) {
+        final PhoneGlobals app = PhoneGlobals.getInstance();
+        Context context = phone.getContext();
+        boolean routeToAudioManager =
+            context.getResources().getBoolean(R.bool.send_mic_mute_to_AudioManager);
+        if (routeToAudioManager) {
+            AudioManager audioManager =
+                (AudioManager) phone.getContext().getSystemService(Context.AUDIO_SERVICE);
+            if (DBG) log("setMuteInternal: using setMicrophoneMute(" + muted + ")...");
+            audioManager.setMicrophoneMute(muted);
+        } else {
+            if (DBG) log("setMuteInternal: using phone.setMute(" + muted + ")...");
+            phone.setMute(muted);
+        }
+        app.notificationMgr.updateMuteNotification();
+    }
+
+    /**
+     * Get the mute state of foreground phone, which has the current
+     * foreground call
+     */
+    static boolean getMute() {
+        final PhoneGlobals app = PhoneGlobals.getInstance();
+
+        boolean routeToAudioManager =
+            app.getResources().getBoolean(R.bool.send_mic_mute_to_AudioManager);
+        if (routeToAudioManager) {
+            AudioManager audioManager =
+                (AudioManager) app.getSystemService(Context.AUDIO_SERVICE);
+            return audioManager.isMicrophoneMute();
+        } else {
+            return app.mCM.getMute();
+        }
+    }
+
+    /* package */ static void setAudioMode() {
+        setAudioMode(PhoneGlobals.getInstance().mCM);
+    }
+
+    /**
+     * Sets the audio mode per current phone state.
+     */
+    /* package */ static void setAudioMode(CallManager cm) {
+        if (DBG) Log.d(LOG_TAG, "setAudioMode()..." + cm.getState());
+
+        Context context = PhoneGlobals.getInstance();
+        AudioManager audioManager = (AudioManager)
+                context.getSystemService(Context.AUDIO_SERVICE);
+        int modeBefore = audioManager.getMode();
+        cm.setAudioMode();
+        int modeAfter = audioManager.getMode();
+
+        if (modeBefore != modeAfter) {
+            // Enable stack dump only when actively debugging ("new Throwable()" is expensive!)
+            if (DBG_SETAUDIOMODE_STACK) Log.d(LOG_TAG, "Stack:", new Throwable("stack dump"));
+        } else {
+            if (DBG) Log.d(LOG_TAG, "setAudioMode() no change: "
+                    + audioModeToString(modeBefore));
+        }
+    }
+    private static String audioModeToString(int mode) {
+        switch (mode) {
+            case AudioManager.MODE_INVALID: return "MODE_INVALID";
+            case AudioManager.MODE_CURRENT: return "MODE_CURRENT";
+            case AudioManager.MODE_NORMAL: return "MODE_NORMAL";
+            case AudioManager.MODE_RINGTONE: return "MODE_RINGTONE";
+            case AudioManager.MODE_IN_CALL: return "MODE_IN_CALL";
+            default: return String.valueOf(mode);
+        }
+    }
+
+    /**
+     * Handles the wired headset button while in-call.
+     *
+     * This is called from the PhoneApp, not from the InCallScreen,
+     * since the HEADSETHOOK button means "mute or unmute the current
+     * call" *any* time a call is active, even if the user isn't actually
+     * on the in-call screen.
+     *
+     * @return true if we consumed the event.
+     */
+    /* package */ static boolean handleHeadsetHook(Phone phone, KeyEvent event) {
+        if (DBG) log("handleHeadsetHook()..." + event.getAction() + " " + event.getRepeatCount());
+        final PhoneGlobals app = PhoneGlobals.getInstance();
+
+        // If the phone is totally idle, we ignore HEADSETHOOK events
+        // (and instead let them fall through to the media player.)
+        if (phone.getState() == PhoneConstants.State.IDLE) {
+            return false;
+        }
+
+        // Ok, the phone is in use.
+        // The headset button button means "Answer" if an incoming call is
+        // ringing.  If not, it toggles the mute / unmute state.
+        //
+        // And in any case we *always* consume this event; this means
+        // that the usual mediaplayer-related behavior of the headset
+        // button will NEVER happen while the user is on a call.
+
+        final boolean hasRingingCall = !phone.getRingingCall().isIdle();
+        final boolean hasActiveCall = !phone.getForegroundCall().isIdle();
+        final boolean hasHoldingCall = !phone.getBackgroundCall().isIdle();
+
+        if (hasRingingCall &&
+            event.getRepeatCount() == 0 &&
+            event.getAction() == KeyEvent.ACTION_UP) {
+            // If an incoming call is ringing, answer it (just like with the
+            // CALL button):
+            int phoneType = phone.getPhoneType();
+            if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
+                answerCall(phone.getRingingCall());
+            } else if ((phoneType == PhoneConstants.PHONE_TYPE_GSM)
+                    || (phoneType == PhoneConstants.PHONE_TYPE_SIP)) {
+                if (hasActiveCall && hasHoldingCall) {
+                    if (DBG) log("handleHeadsetHook: ringing (both lines in use) ==> answer!");
+                    answerAndEndActive(app.mCM, phone.getRingingCall());
+                } else {
+                    if (DBG) log("handleHeadsetHook: ringing ==> answer!");
+                    // answerCall() will automatically hold the current
+                    // active call, if there is one.
+                    answerCall(phone.getRingingCall());
+                }
+            } else {
+                throw new IllegalStateException("Unexpected phone type: " + phoneType);
+            }
+        } else {
+            // No incoming ringing call.
+            if (event.isLongPress()) {
+                if (DBG) log("handleHeadsetHook: longpress -> hangup");
+                hangup(app.mCM);
+            }
+            else if (event.getAction() == KeyEvent.ACTION_UP &&
+                     event.getRepeatCount() == 0) {
+                Connection c = phone.getForegroundCall().getLatestConnection();
+                // If it is NOT an emg #, toggle the mute state. Otherwise, ignore the hook.
+                if (c != null && !PhoneNumberUtils.isLocalEmergencyNumber(c.getAddress(),
+                                                                          PhoneGlobals.getInstance())) {
+                    if (getMute()) {
+                        if (DBG) log("handleHeadsetHook: UNmuting...");
+                        setMute(false);
+                    } else {
+                        if (DBG) log("handleHeadsetHook: muting...");
+                        setMute(true);
+                    }
+                }
+            }
+        }
+
+        // Even if the InCallScreen is the current activity, there's no
+        // need to force it to update, because (1) if we answered a
+        // ringing call, the InCallScreen will imminently get a phone
+        // state change event (causing an update), and (2) if we muted or
+        // unmuted, the setMute() call automagically updates the status
+        // bar, and there's no "mute" indication in the InCallScreen
+        // itself (other than the menu item, which only ever stays
+        // onscreen for a second anyway.)
+        // TODO: (2) isn't entirely true anymore. Once we return our result
+        // to the PhoneApp, we ask InCallScreen to update its control widgets
+        // in case we changed mute or speaker state and phones with touch-
+        // screen [toggle] buttons need to update themselves.
+
+        return true;
+    }
+
+    /**
+     * Look for ANY connections on the phone that qualify as being
+     * disconnected.
+     *
+     * @return true if we find a connection that is disconnected over
+     * all the phone's call objects.
+     */
+    /* package */ static boolean hasDisconnectedConnections(Phone phone) {
+        return hasDisconnectedConnections(phone.getForegroundCall()) ||
+                hasDisconnectedConnections(phone.getBackgroundCall()) ||
+                hasDisconnectedConnections(phone.getRingingCall());
+    }
+
+    /**
+     * Iterate over all connections in a call to see if there are any
+     * that are not alive (disconnected or idle).
+     *
+     * @return true if we find a connection that is disconnected, and
+     * pending removal via
+     * {@link com.android.internal.telephony.gsm.GsmCall#clearDisconnected()}.
+     */
+    private static final boolean hasDisconnectedConnections(Call call) {
+        // look through all connections for non-active ones.
+        for (Connection c : call.getConnections()) {
+            if (!c.isAlive()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    //
+    // Misc UI policy helper functions
+    //
+
+    /**
+     * @return true if we're allowed to swap calls, given the current
+     * state of the Phone.
+     */
+    /* package */ static boolean okToSwapCalls(CallManager cm) {
+        int phoneType = cm.getDefaultPhone().getPhoneType();
+        if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
+            // CDMA: "Swap" is enabled only when the phone reaches a *generic*.
+            // state by either accepting a Call Waiting or by merging two calls
+            PhoneGlobals app = PhoneGlobals.getInstance();
+            return (app.cdmaPhoneCallState.getCurrentCallState()
+                    == CdmaPhoneCallState.PhoneCallState.CONF_CALL);
+        } else if ((phoneType == PhoneConstants.PHONE_TYPE_GSM)
+                || (phoneType == PhoneConstants.PHONE_TYPE_SIP)) {
+            // GSM: "Swap" is available if both lines are in use and there's no
+            // incoming call.  (Actually we need to verify that the active
+            // call really is in the ACTIVE state and the holding call really
+            // is in the HOLDING state, since you *can't* actually swap calls
+            // when the foreground call is DIALING or ALERTING.)
+            return !cm.hasActiveRingingCall()
+                    && (cm.getActiveFgCall().getState() == Call.State.ACTIVE)
+                    && (cm.getFirstActiveBgCall().getState() == Call.State.HOLDING);
+        } else {
+            throw new IllegalStateException("Unexpected phone type: " + phoneType);
+        }
+    }
+
+    /**
+     * @return true if we're allowed to merge calls, given the current
+     * state of the Phone.
+     */
+    /* package */ static boolean okToMergeCalls(CallManager cm) {
+        int phoneType = cm.getFgPhone().getPhoneType();
+        if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
+            // CDMA: "Merge" is enabled only when the user is in a 3Way call.
+            PhoneGlobals app = PhoneGlobals.getInstance();
+            return ((app.cdmaPhoneCallState.getCurrentCallState()
+                    == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE)
+                    && !app.cdmaPhoneCallState.IsThreeWayCallOrigStateDialing());
+        } else {
+            // GSM: "Merge" is available if both lines are in use and there's no
+            // incoming call, *and* the current conference isn't already
+            // "full".
+            // TODO: shall move all okToMerge logic to CallManager
+            return !cm.hasActiveRingingCall() && cm.hasActiveFgCall()
+                    && cm.hasActiveBgCall()
+                    && cm.canConference(cm.getFirstActiveBgCall());
+        }
+    }
+
+    /**
+     * @return true if the UI should let you add a new call, given the current
+     * state of the Phone.
+     */
+    /* package */ static boolean okToAddCall(CallManager cm) {
+        Phone phone = cm.getActiveFgCall().getPhone();
+
+        // "Add call" is never allowed in emergency callback mode (ECM).
+        if (isPhoneInEcm(phone)) {
+            return false;
+        }
+
+        int phoneType = phone.getPhoneType();
+        final Call.State fgCallState = cm.getActiveFgCall().getState();
+        if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
+           // CDMA: "Add call" button is only enabled when:
+           // - ForegroundCall is in ACTIVE state
+           // - After 30 seconds of user Ignoring/Missing a Call Waiting call.
+            PhoneGlobals app = PhoneGlobals.getInstance();
+            return ((fgCallState == Call.State.ACTIVE)
+                    && (app.cdmaPhoneCallState.getAddCallMenuStateAfterCallWaiting()));
+        } else if ((phoneType == PhoneConstants.PHONE_TYPE_GSM)
+                || (phoneType == PhoneConstants.PHONE_TYPE_SIP)) {
+            // GSM: "Add call" is available only if ALL of the following are true:
+            // - There's no incoming ringing call
+            // - There's < 2 lines in use
+            // - The foreground call is ACTIVE or IDLE or DISCONNECTED.
+            //   (We mainly need to make sure it *isn't* DIALING or ALERTING.)
+            final boolean hasRingingCall = cm.hasActiveRingingCall();
+            final boolean hasActiveCall = cm.hasActiveFgCall();
+            final boolean hasHoldingCall = cm.hasActiveBgCall();
+            final boolean allLinesTaken = hasActiveCall && hasHoldingCall;
+
+            return !hasRingingCall
+                    && !allLinesTaken
+                    && ((fgCallState == Call.State.ACTIVE)
+                        || (fgCallState == Call.State.IDLE)
+                        || (fgCallState == Call.State.DISCONNECTED));
+        } else {
+            throw new IllegalStateException("Unexpected phone type: " + phoneType);
+        }
+    }
+
+    /**
+     * Based on the input CNAP number string,
+     * @return _RESTRICTED or _UNKNOWN for all the special CNAP strings.
+     * Otherwise, return CNAP_SPECIAL_CASE_NO.
+     */
+    private static int checkCnapSpecialCases(String n) {
+        if (n.equals("PRIVATE") ||
+                n.equals("P") ||
+                n.equals("RES")) {
+            if (DBG) log("checkCnapSpecialCases, PRIVATE string: " + n);
+            return PhoneConstants.PRESENTATION_RESTRICTED;
+        } else if (n.equals("UNAVAILABLE") ||
+                n.equals("UNKNOWN") ||
+                n.equals("UNA") ||
+                n.equals("U")) {
+            if (DBG) log("checkCnapSpecialCases, UNKNOWN string: " + n);
+            return PhoneConstants.PRESENTATION_UNKNOWN;
+        } else {
+            if (DBG) log("checkCnapSpecialCases, normal str. number: " + n);
+            return CNAP_SPECIAL_CASE_NO;
+        }
+    }
+
+    /**
+     * Handles certain "corner cases" for CNAP. When we receive weird phone numbers
+     * from the network to indicate different number presentations, convert them to
+     * expected number and presentation values within the CallerInfo object.
+     * @param number number we use to verify if we are in a corner case
+     * @param presentation presentation value used to verify if we are in a corner case
+     * @return the new String that should be used for the phone number
+     */
+    /* package */ static String modifyForSpecialCnapCases(Context context, CallerInfo ci,
+            String number, int presentation) {
+        // Obviously we return number if ci == null, but still return number if
+        // number == null, because in these cases the correct string will still be
+        // displayed/logged after this function returns based on the presentation value.
+        if (ci == null || number == null) return number;
+
+        if (DBG) {
+            log("modifyForSpecialCnapCases: initially, number="
+                    + toLogSafePhoneNumber(number)
+                    + ", presentation=" + presentation + " ci " + ci);
+        }
+
+        // "ABSENT NUMBER" is a possible value we could get from the network as the
+        // phone number, so if this happens, change it to "Unknown" in the CallerInfo
+        // and fix the presentation to be the same.
+        final String[] absentNumberValues =
+                context.getResources().getStringArray(R.array.absent_num);
+        if (Arrays.asList(absentNumberValues).contains(number)
+                && presentation == PhoneConstants.PRESENTATION_ALLOWED) {
+            number = context.getString(R.string.unknown);
+            ci.numberPresentation = PhoneConstants.PRESENTATION_UNKNOWN;
+        }
+
+        // Check for other special "corner cases" for CNAP and fix them similarly. Corner
+        // cases only apply if we received an allowed presentation from the network, so check
+        // if we think we have an allowed presentation, or if the CallerInfo presentation doesn't
+        // match the presentation passed in for verification (meaning we changed it previously
+        // because it's a corner case and we're being called from a different entry point).
+        if (ci.numberPresentation == PhoneConstants.PRESENTATION_ALLOWED
+                || (ci.numberPresentation != presentation
+                        && presentation == PhoneConstants.PRESENTATION_ALLOWED)) {
+            int cnapSpecialCase = checkCnapSpecialCases(number);
+            if (cnapSpecialCase != CNAP_SPECIAL_CASE_NO) {
+                // For all special strings, change number & numberPresentation.
+                if (cnapSpecialCase == PhoneConstants.PRESENTATION_RESTRICTED) {
+                    number = context.getString(R.string.private_num);
+                } else if (cnapSpecialCase == PhoneConstants.PRESENTATION_UNKNOWN) {
+                    number = context.getString(R.string.unknown);
+                }
+                if (DBG) {
+                    log("SpecialCnap: number=" + toLogSafePhoneNumber(number)
+                            + "; presentation now=" + cnapSpecialCase);
+                }
+                ci.numberPresentation = cnapSpecialCase;
+            }
+        }
+        if (DBG) {
+            log("modifyForSpecialCnapCases: returning number string="
+                    + toLogSafePhoneNumber(number));
+        }
+        return number;
+    }
+
+    //
+    // Support for 3rd party phone service providers.
+    //
+
+    /**
+     * Check if all the provider's info is present in the intent.
+     * @param intent Expected to have the provider's extra.
+     * @return true if the intent has all the extras to build the
+     * in-call screen's provider info overlay.
+     */
+    /* package */ static boolean hasPhoneProviderExtras(Intent intent) {
+        if (null == intent) {
+            return false;
+        }
+        final String name = intent.getStringExtra(InCallScreen.EXTRA_GATEWAY_PROVIDER_PACKAGE);
+        final String gatewayUri = intent.getStringExtra(InCallScreen.EXTRA_GATEWAY_URI);
+
+        return !TextUtils.isEmpty(name) && !TextUtils.isEmpty(gatewayUri);
+    }
+
+    /**
+     * Copy all the expected extras set when a 3rd party provider is
+     * used from the source intent to the destination one.  Checks all
+     * the required extras are present, if any is missing, none will
+     * be copied.
+     * @param src Intent which may contain the provider's extras.
+     * @param dst Intent where a copy of the extras will be added if applicable.
+     */
+    /* package */ static void checkAndCopyPhoneProviderExtras(Intent src, Intent dst) {
+        if (!hasPhoneProviderExtras(src)) {
+            Log.d(LOG_TAG, "checkAndCopyPhoneProviderExtras: some or all extras are missing.");
+            return;
+        }
+
+        dst.putExtra(InCallScreen.EXTRA_GATEWAY_PROVIDER_PACKAGE,
+                     src.getStringExtra(InCallScreen.EXTRA_GATEWAY_PROVIDER_PACKAGE));
+        dst.putExtra(InCallScreen.EXTRA_GATEWAY_URI,
+                     src.getStringExtra(InCallScreen.EXTRA_GATEWAY_URI));
+    }
+
+    /**
+     * Get the provider's label from the intent.
+     * @param context to lookup the provider's package name.
+     * @param intent with an extra set to the provider's package name.
+     * @return The provider's application label. null if an error
+     * occurred during the lookup of the package name or the label.
+     */
+    /* package */ static CharSequence getProviderLabel(Context context, Intent intent) {
+        String packageName = intent.getStringExtra(InCallScreen.EXTRA_GATEWAY_PROVIDER_PACKAGE);
+        PackageManager pm = context.getPackageManager();
+
+        try {
+            ApplicationInfo info = pm.getApplicationInfo(packageName, 0);
+
+            return pm.getApplicationLabel(info);
+        } catch (PackageManager.NameNotFoundException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Get the provider's icon.
+     * @param context to lookup the provider's icon.
+     * @param intent with an extra set to the provider's package name.
+     * @return The provider's application icon. null if an error occured during the icon lookup.
+     */
+    /* package */ static Drawable getProviderIcon(Context context, Intent intent) {
+        String packageName = intent.getStringExtra(InCallScreen.EXTRA_GATEWAY_PROVIDER_PACKAGE);
+        PackageManager pm = context.getPackageManager();
+
+        try {
+            return pm.getApplicationIcon(packageName);
+        } catch (PackageManager.NameNotFoundException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Return the gateway uri from the intent.
+     * @param intent With the gateway uri extra.
+     * @return The gateway URI or null if not found.
+     */
+    /* package */ static Uri getProviderGatewayUri(Intent intent) {
+        String uri = intent.getStringExtra(InCallScreen.EXTRA_GATEWAY_URI);
+        return TextUtils.isEmpty(uri) ? null : Uri.parse(uri);
+    }
+
+    /**
+     * Return a formatted version of the uri's scheme specific
+     * part. E.g for 'tel:12345678', return '1-234-5678'.
+     * @param uri A 'tel:' URI with the gateway phone number.
+     * @return the provider's address (from the gateway uri) formatted
+     * for user display. null if uri was null or its scheme was not 'tel:'.
+     */
+    /* package */ static String formatProviderUri(Uri uri) {
+        if (null != uri) {
+            if (Constants.SCHEME_TEL.equals(uri.getScheme())) {
+                return PhoneNumberUtils.formatNumber(uri.getSchemeSpecificPart());
+            } else {
+                return uri.toString();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Check if a phone number can be route through a 3rd party
+     * gateway. The number must be a global phone number in numerical
+     * form (1-800-666-SEXY won't work).
+     *
+     * MMI codes and the like cannot be used as a dial number for the
+     * gateway either.
+     *
+     * @param number To be dialed via a 3rd party gateway.
+     * @return true If the number can be routed through the 3rd party network.
+     */
+    /* package */ static boolean isRoutableViaGateway(String number) {
+        if (TextUtils.isEmpty(number)) {
+            return false;
+        }
+        number = PhoneNumberUtils.stripSeparators(number);
+        if (!number.equals(PhoneNumberUtils.convertKeypadLettersToDigits(number))) {
+            return false;
+        }
+        number = PhoneNumberUtils.extractNetworkPortion(number);
+        return PhoneNumberUtils.isGlobalPhoneNumber(number);
+    }
+
+   /**
+    * This function is called when phone answers or places a call.
+    * Check if the phone is in a car dock or desk dock.
+    * If yes, turn on the speaker, when no wired or BT headsets are connected.
+    * Otherwise do nothing.
+    * @return true if activated
+    */
+    private static boolean activateSpeakerIfDocked(Phone phone) {
+        if (DBG) log("activateSpeakerIfDocked()...");
+
+        boolean activated = false;
+        if (PhoneGlobals.mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED) {
+            if (DBG) log("activateSpeakerIfDocked(): In a dock -> may need to turn on speaker.");
+            PhoneGlobals app = PhoneGlobals.getInstance();
+
+            if (!app.isHeadsetPlugged() && !app.isBluetoothHeadsetAudioOn()) {
+                turnOnSpeaker(phone.getContext(), true, true);
+                activated = true;
+            }
+        }
+        return activated;
+    }
+
+
+    /**
+     * Returns whether the phone is in ECM ("Emergency Callback Mode") or not.
+     */
+    /* package */ static boolean isPhoneInEcm(Phone phone) {
+        if ((phone != null) && TelephonyCapabilities.supportsEcm(phone)) {
+            // For phones that support ECM, return true iff PROPERTY_INECM_MODE == "true".
+            // TODO: There ought to be a better API for this than just
+            // exposing a system property all the way up to the app layer,
+            // probably a method like "inEcm()" provided by the telephony
+            // layer.
+            String ecmMode =
+                    SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE);
+            if (ecmMode != null) {
+                return ecmMode.equals("true");
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns the most appropriate Phone object to handle a call
+     * to the specified number.
+     *
+     * @param cm the CallManager.
+     * @param scheme the scheme from the data URI that the number originally came from.
+     * @param number the phone number, or SIP address.
+     */
+    public static Phone pickPhoneBasedOnNumber(CallManager cm,
+            String scheme, String number, String primarySipUri) {
+        if (DBG) {
+            log("pickPhoneBasedOnNumber: scheme " + scheme
+                    + ", number " + toLogSafePhoneNumber(number)
+                    + ", sipUri "
+                    + (primarySipUri != null ? Uri.parse(primarySipUri).toSafeString() : "null"));
+        }
+
+        if (primarySipUri != null) {
+            Phone phone = getSipPhoneFromUri(cm, primarySipUri);
+            if (phone != null) return phone;
+        }
+        return cm.getDefaultPhone();
+    }
+
+    public static Phone getSipPhoneFromUri(CallManager cm, String target) {
+        for (Phone phone : cm.getAllPhones()) {
+            if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_SIP) {
+                String sipUri = ((SipPhone) phone).getSipUri();
+                if (target.equals(sipUri)) {
+                    if (DBG) log("- pickPhoneBasedOnNumber:" +
+                            "found SipPhone! obj = " + phone + ", "
+                            + phone.getClass());
+                    return phone;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns true when the given call is in INCOMING state and there's no foreground phone call,
+     * meaning the call is the first real incoming call the phone is having.
+     */
+    public static boolean isRealIncomingCall(Call.State state) {
+        return (state == Call.State.INCOMING && !PhoneGlobals.getInstance().mCM.hasActiveFgCall());
+    }
+
+    private static boolean sVoipSupported = false;
+    static {
+        PhoneGlobals app = PhoneGlobals.getInstance();
+        sVoipSupported = SipManager.isVoipSupported(app)
+                && app.getResources().getBoolean(com.android.internal.R.bool.config_built_in_sip_phone)
+                && app.getResources().getBoolean(com.android.internal.R.bool.config_voice_capable);
+    }
+
+    /**
+     * @return true if this device supports voice calls using the built-in SIP stack.
+     */
+    static boolean isVoipSupported() {
+        return sVoipSupported;
+    }
+
+    public static String getPresentationString(Context context, int presentation) {
+        String name = context.getString(R.string.unknown);
+        if (presentation == PhoneConstants.PRESENTATION_RESTRICTED) {
+            name = context.getString(R.string.private_num);
+        } else if (presentation == PhoneConstants.PRESENTATION_PAYPHONE) {
+            name = context.getString(R.string.payphone);
+        }
+        return name;
+    }
+
+    public static void sendViewNotificationAsync(Context context, Uri contactUri) {
+        if (DBG) Log.d(LOG_TAG, "Send view notification to Contacts (uri: " + contactUri + ")");
+        Intent intent = new Intent("com.android.contacts.VIEW_NOTIFICATION", contactUri);
+        intent.setClassName("com.android.contacts",
+                "com.android.contacts.ViewNotificationService");
+        context.startService(intent);
+    }
+
+    //
+    // General phone and call state debugging/testing code
+    //
+
+    /* package */ static void dumpCallState(Phone phone) {
+        PhoneGlobals app = PhoneGlobals.getInstance();
+        Log.d(LOG_TAG, "dumpCallState():");
+        Log.d(LOG_TAG, "- Phone: " + phone + ", name = " + phone.getPhoneName()
+              + ", state = " + phone.getState());
+
+        StringBuilder b = new StringBuilder(128);
+
+        Call call = phone.getForegroundCall();
+        b.setLength(0);
+        b.append("  - FG call: ").append(call.getState());
+        b.append(" isAlive ").append(call.getState().isAlive());
+        b.append(" isRinging ").append(call.getState().isRinging());
+        b.append(" isDialing ").append(call.getState().isDialing());
+        b.append(" isIdle ").append(call.isIdle());
+        b.append(" hasConnections ").append(call.hasConnections());
+        Log.d(LOG_TAG, b.toString());
+
+        call = phone.getBackgroundCall();
+        b.setLength(0);
+        b.append("  - BG call: ").append(call.getState());
+        b.append(" isAlive ").append(call.getState().isAlive());
+        b.append(" isRinging ").append(call.getState().isRinging());
+        b.append(" isDialing ").append(call.getState().isDialing());
+        b.append(" isIdle ").append(call.isIdle());
+        b.append(" hasConnections ").append(call.hasConnections());
+        Log.d(LOG_TAG, b.toString());
+
+        call = phone.getRingingCall();
+        b.setLength(0);
+        b.append("  - RINGING call: ").append(call.getState());
+        b.append(" isAlive ").append(call.getState().isAlive());
+        b.append(" isRinging ").append(call.getState().isRinging());
+        b.append(" isDialing ").append(call.getState().isDialing());
+        b.append(" isIdle ").append(call.isIdle());
+        b.append(" hasConnections ").append(call.hasConnections());
+        Log.d(LOG_TAG, b.toString());
+
+
+        final boolean hasRingingCall = !phone.getRingingCall().isIdle();
+        final boolean hasActiveCall = !phone.getForegroundCall().isIdle();
+        final boolean hasHoldingCall = !phone.getBackgroundCall().isIdle();
+        final boolean allLinesTaken = hasActiveCall && hasHoldingCall;
+        b.setLength(0);
+        b.append("  - hasRingingCall ").append(hasRingingCall);
+        b.append(" hasActiveCall ").append(hasActiveCall);
+        b.append(" hasHoldingCall ").append(hasHoldingCall);
+        b.append(" allLinesTaken ").append(allLinesTaken);
+        Log.d(LOG_TAG, b.toString());
+
+        // On CDMA phones, dump out the CdmaPhoneCallState too:
+        if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
+            if (app.cdmaPhoneCallState != null) {
+                Log.d(LOG_TAG, "  - CDMA call state: "
+                      + app.cdmaPhoneCallState.getCurrentCallState());
+            } else {
+                Log.d(LOG_TAG, "  - CDMA device, but null cdmaPhoneCallState!");
+            }
+        }
+
+        // Watch out: the isRinging() call below does NOT tell us anything
+        // about the state of the telephony layer; it merely tells us whether
+        // the Ringer manager is currently playing the ringtone.
+        boolean ringing = app.getRinger().isRinging();
+        Log.d(LOG_TAG, "  - Ringer state: " + ringing);
+    }
+
+    private static void log(String msg) {
+        Log.d(LOG_TAG, msg);
+    }
+
+    static void dumpCallManager() {
+        Call call;
+        CallManager cm = PhoneGlobals.getInstance().mCM;
+        StringBuilder b = new StringBuilder(128);
+
+
+
+        Log.d(LOG_TAG, "############### dumpCallManager() ##############");
+        // TODO: Don't log "cm" itself, since CallManager.toString()
+        // already spews out almost all this same information.
+        // We should fix CallManager.toString() to be more minimal, and
+        // use an explicit dumpState() method for the verbose dump.
+        // Log.d(LOG_TAG, "CallManager: " + cm
+        //         + ", state = " + cm.getState());
+        Log.d(LOG_TAG, "CallManager: state = " + cm.getState());
+        b.setLength(0);
+        call = cm.getActiveFgCall();
+        b.append(" - FG call: ").append(cm.hasActiveFgCall()? "YES ": "NO ");
+        b.append(call);
+        b.append( "  State: ").append(cm.getActiveFgCallState());
+        b.append( "  Conn: ").append(cm.getFgCallConnections());
+        Log.d(LOG_TAG, b.toString());
+        b.setLength(0);
+        call = cm.getFirstActiveBgCall();
+        b.append(" - BG call: ").append(cm.hasActiveBgCall()? "YES ": "NO ");
+        b.append(call);
+        b.append( "  State: ").append(cm.getFirstActiveBgCall().getState());
+        b.append( "  Conn: ").append(cm.getBgCallConnections());
+        Log.d(LOG_TAG, b.toString());
+        b.setLength(0);
+        call = cm.getFirstActiveRingingCall();
+        b.append(" - RINGING call: ").append(cm.hasActiveRingingCall()? "YES ": "NO ");
+        b.append(call);
+        b.append( "  State: ").append(cm.getFirstActiveRingingCall().getState());
+        Log.d(LOG_TAG, b.toString());
+
+
+
+        for (Phone phone : CallManager.getInstance().getAllPhones()) {
+            if (phone != null) {
+                Log.d(LOG_TAG, "Phone: " + phone + ", name = " + phone.getPhoneName()
+                        + ", state = " + phone.getState());
+                b.setLength(0);
+                call = phone.getForegroundCall();
+                b.append(" - FG call: ").append(call);
+                b.append( "  State: ").append(call.getState());
+                b.append( "  Conn: ").append(call.hasConnections());
+                Log.d(LOG_TAG, b.toString());
+                b.setLength(0);
+                call = phone.getBackgroundCall();
+                b.append(" - BG call: ").append(call);
+                b.append( "  State: ").append(call.getState());
+                b.append( "  Conn: ").append(call.hasConnections());
+                Log.d(LOG_TAG, b.toString());b.setLength(0);
+                call = phone.getRingingCall();
+                b.append(" - RINGING call: ").append(call);
+                b.append( "  State: ").append(call.getState());
+                b.append( "  Conn: ").append(call.hasConnections());
+                Log.d(LOG_TAG, b.toString());
+            }
+        }
+
+        Log.d(LOG_TAG, "############## END dumpCallManager() ###############");
+    }
+
+    /**
+     * @return if the context is in landscape orientation.
+     */
+    public static boolean isLandscape(Context context) {
+        return context.getResources().getConfiguration().orientation
+                == Configuration.ORIENTATION_LANDSCAPE;
+    }
+}
diff --git a/src/com/android/phone/ProcessOutgoingCallTest.java b/src/com/android/phone/ProcessOutgoingCallTest.java
new file mode 100644
index 0000000..c76fb43
--- /dev/null
+++ b/src/com/android/phone/ProcessOutgoingCallTest.java
@@ -0,0 +1,79 @@
+/*
+ * 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.app.SearchManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.util.Log;
+
+/**
+ * ProcessOutgoingCallTest tests {@link OutgoingCallBroadcaster} by performing
+ * a couple of simple modifications to outgoing calls, and by printing log
+ * messages for each call.
+ */
+public class ProcessOutgoingCallTest extends BroadcastReceiver {
+    private static final String TAG = "ProcessOutgoingCallTest";
+    private static final String AREACODE = "617";
+
+    private static final boolean LOGV = false;
+
+    private static final boolean REDIRECT_411_TO_GOOG411 = true;
+    private static final boolean SEVEN_DIGIT_DIALING = true;
+    private static final boolean POUND_POUND_SEARCH = true;
+    private static final boolean BLOCK_555 = true;
+
+    public void onReceive(Context context, Intent intent) {
+        if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) {
+            String number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
+            if (LOGV) Log.v(TAG, "Received intent " + intent + " (number = " + number + ".");
+            /* Example of how to redirect calls from one number to another. */
+            if (REDIRECT_411_TO_GOOG411 && number.equals("411")) {
+                setResultData("18004664411");
+            }
+
+            /* Example of how to modify the phone number in flight. */
+            if (SEVEN_DIGIT_DIALING && number.length() == 7) {
+                setResultData(AREACODE + number);
+            }
+
+            /* Example of how to route a call to another Application. */
+            if (POUND_POUND_SEARCH && number.startsWith("##")) {
+                Intent newIntent = new Intent(Intent.ACTION_SEARCH);
+                newIntent.putExtra(SearchManager.QUERY, number.substring(2));
+                newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                context.startActivity(newIntent);
+                setResultData(null);
+            }
+
+            /* Example of how to deny calls to a particular number.
+             * Note that no UI is displayed to the user -- the call simply 
+             * does not happen.  It is the application's responaibility to
+             * explain this to the user. */
+            int length = number.length();
+            if (BLOCK_555 && length >= 7) {
+                String exchange = number.substring(length - 7, length - 4);
+                Log.v(TAG, "exchange = " + exchange);
+                if (exchange.equals("555")) {
+                    setResultData(null);
+                }
+            }
+        }
+    }
+}
diff --git a/src/com/android/phone/Profiler.java b/src/com/android/phone/Profiler.java
new file mode 100644
index 0000000..234073c
--- /dev/null
+++ b/src/com/android/phone/Profiler.java
@@ -0,0 +1,126 @@
+/*
+ * 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.os.SystemClock;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewParent;
+import android.view.Window;
+
+/**
+ * Profiling utilities for the Phone app.
+ */
+public class Profiler {
+    private static final String LOG_TAG = PhoneGlobals.LOG_TAG;
+
+    // Let the compiler optimize all this code out unless we're actively
+    // doing profiling runs.
+    // TODO: Instead of doing all these "if (PROFILE)" checks here, every
+    // place that *calls* any of these methods should check the value of
+    // Profiler.PROFILE first, so the method calls will get optimized out
+    // too.
+    private static final boolean PROFILE = false;
+
+    static long sTimeCallScreenRequested;
+    static long sTimeCallScreenOnCreate;
+    static long sTimeCallScreenCreated;
+
+    // TODO: Clean up any usage of these times.  (There's no "incoming call
+    // panel" in the Phone UI any more; incoming calls just go straight to the
+    // regular in-call UI.)
+    static long sTimeIncomingCallPanelRequested;
+    static long sTimeIncomingCallPanelOnCreate;
+    static long sTimeIncomingCallPanelCreated;
+
+    /** This class is never instantiated. */
+    private Profiler() {
+    }
+
+    static void profileViewCreate(Window win, String tag) {
+        if (false) {
+            ViewParent p = (ViewParent) win.getDecorView();
+            while (p instanceof View) {
+                p = ((View) p).getParent();
+            }
+            //((ViewRoot)p).profile();
+            //((ViewRoot)p).setProfileTag(tag);
+        }
+    }
+
+    static void callScreenRequested() {
+        if (PROFILE) {
+            sTimeCallScreenRequested = SystemClock.uptimeMillis();
+        }
+    }
+
+    static void callScreenOnCreate() {
+        if (PROFILE) {
+            sTimeCallScreenOnCreate = SystemClock.uptimeMillis();
+        }
+    }
+
+    static void callScreenCreated() {
+        if (PROFILE) {
+            sTimeCallScreenCreated = SystemClock.uptimeMillis();
+            dumpCallScreenStat();
+        }
+    }
+
+    private static void dumpCallScreenStat() {
+        if (PROFILE) {
+            log(">>> call screen perf stats <<<");
+            log(">>> request -> onCreate = " +
+                    (sTimeCallScreenOnCreate - sTimeCallScreenRequested));
+            log(">>> onCreate -> created = " +
+                    (sTimeCallScreenCreated - sTimeCallScreenOnCreate));
+        }
+    }
+
+    static void incomingCallPanelRequested() {
+        if (PROFILE) {
+            sTimeIncomingCallPanelRequested = SystemClock.uptimeMillis();
+        }
+    }
+
+    static void incomingCallPanelOnCreate() {
+        if (PROFILE) {
+            sTimeIncomingCallPanelOnCreate = SystemClock.uptimeMillis();
+        }
+    }
+
+    static void incomingCallPanelCreated() {
+        if (PROFILE) {
+            sTimeIncomingCallPanelCreated = SystemClock.uptimeMillis();
+            dumpIncomingCallPanelStat();
+        }
+    }
+
+    private static void dumpIncomingCallPanelStat() {
+        if (PROFILE) {
+            log(">>> incoming call panel perf stats <<<");
+            log(">>> request -> onCreate = " +
+                    (sTimeIncomingCallPanelOnCreate - sTimeIncomingCallPanelRequested));
+            log(">>> onCreate -> created = " +
+                    (sTimeIncomingCallPanelCreated - sTimeIncomingCallPanelOnCreate));
+        }
+    }
+
+    private static void log(String msg) {
+        Log.d(LOG_TAG, "[Profiler] " + msg);
+    }
+}
diff --git a/src/com/android/phone/RespondViaSmsManager.java b/src/com/android/phone/RespondViaSmsManager.java
new file mode 100644
index 0000000..c851471
--- /dev/null
+++ b/src/com/android/phone/RespondViaSmsManager.java
@@ -0,0 +1,874 @@
+/*
+ * 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.app.ActivityManager;
+import android.app.ActionBar;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.SystemProperties;
+import android.preference.EditTextPreference;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.BaseAdapter;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.android.internal.telephony.Call;
+import com.android.internal.telephony.Connection;
+import com.android.internal.telephony.PhoneConstants;
+import com.google.android.collect.Lists;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Helper class to manage the "Respond via Message" feature for incoming calls.
+ *
+ * @see InCallScreen.internalRespondViaSms()
+ */
+public class RespondViaSmsManager {
+    private static final String TAG = "RespondViaSmsManager";
+    private static final boolean DBG =
+            (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
+    // 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";
+
+    // Preference keys for the 4 "canned responses"; see RespondViaSmsManager$Settings.
+    // Since (for now at least) the number of messages is fixed at 4, and since
+    // SharedPreferences can't deal with arrays anyway, just store the messages
+    // as 4 separate strings.
+    private static final int NUM_CANNED_RESPONSES = 4;
+    private static final String KEY_CANNED_RESPONSE_PREF_1 = "canned_response_pref_1";
+    private static final String KEY_CANNED_RESPONSE_PREF_2 = "canned_response_pref_2";
+    private static final String KEY_CANNED_RESPONSE_PREF_3 = "canned_response_pref_3";
+    private static final String KEY_CANNED_RESPONSE_PREF_4 = "canned_response_pref_4";
+    private static final String KEY_PREFERRED_PACKAGE = "preferred_package_pref";
+    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
+     */
+    public static class Settings extends PreferenceActivity
+            implements Preference.OnPreferenceChangeListener {
+        @Override
+        protected void onCreate(Bundle icicle) {
+            super.onCreate(icicle);
+            if (DBG) log("Settings: onCreate()...");
+
+            getPreferenceManager().setSharedPreferencesName(SHARED_PREFERENCES_NAME);
+
+            // This preference screen is ultra-simple; it's just 4 plain
+            // <EditTextPreference>s, one for each of the 4 "canned responses".
+            //
+            // The only nontrivial thing we do here is copy the text value of
+            // each of those EditTextPreferences and use it as the preference's
+            // "title" as well, so that the user will immediately see all 4
+            // strings when they arrive here.
+            //
+            // Also, listen for change events (since we'll need to update the
+            // title any time the user edits one of the strings.)
+
+            addPreferencesFromResource(R.xml.respond_via_sms_settings);
+
+            EditTextPreference pref;
+            pref = (EditTextPreference) findPreference(KEY_CANNED_RESPONSE_PREF_1);
+            pref.setTitle(pref.getText());
+            pref.setOnPreferenceChangeListener(this);
+
+            pref = (EditTextPreference) findPreference(KEY_CANNED_RESPONSE_PREF_2);
+            pref.setTitle(pref.getText());
+            pref.setOnPreferenceChangeListener(this);
+
+            pref = (EditTextPreference) findPreference(KEY_CANNED_RESPONSE_PREF_3);
+            pref.setTitle(pref.getText());
+            pref.setOnPreferenceChangeListener(this);
+
+            pref = (EditTextPreference) findPreference(KEY_CANNED_RESPONSE_PREF_4);
+            pref.setTitle(pref.getText());
+            pref.setOnPreferenceChangeListener(this);
+
+            ActionBar actionBar = getActionBar();
+            if (actionBar != null) {
+                // android.R.id.home will be triggered in onOptionsItemSelected()
+                actionBar.setDisplayHomeAsUpEnabled(true);
+            }
+        }
+
+        // Preference.OnPreferenceChangeListener implementation
+        @Override
+        public boolean onPreferenceChange(Preference preference, Object newValue) {
+            if (DBG) log("onPreferenceChange: key = " + preference.getKey());
+            if (VDBG) log("  preference = '" + preference + "'");
+            if (VDBG) log("  newValue = '" + newValue + "'");
+
+            EditTextPreference pref = (EditTextPreference) preference;
+
+            // Copy the new text over to the title, just like in onCreate().
+            // (Watch out: onPreferenceChange() is called *before* the
+            // Preference itself gets updated, so we need to use newValue here
+            // rather than pref.getText().)
+            pref.setTitle((String) newValue);
+
+            return true;  // means it's OK to update the state of the Preference with the new value
+        }
+
+        @Override
+        public boolean onOptionsItemSelected(MenuItem item) {
+            final int itemId = item.getItemId();
+            switch (itemId) {
+                case android.R.id.home:
+                    // See ActionBar#setDisplayHomeAsUpEnabled()
+                    CallFeaturesSetting.goUpToTopLevelSetting(this);
+                    return true;
+                case R.id.respond_via_message_reset:
+                    // Reset the preferences settings
+                    SharedPreferences prefs = getSharedPreferences(
+                            SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
+                    SharedPreferences.Editor editor = prefs.edit();
+                    editor.remove(KEY_INSTANT_TEXT_DEFAULT_COMPONENT);
+                    editor.apply();
+
+                    return true;
+                default:
+            }
+            return super.onOptionsItemSelected(item);
+        }
+
+        @Override
+        public boolean onCreateOptionsMenu(Menu menu) {
+            getMenuInflater().inflate(R.menu.respond_via_message_settings_menu, menu);
+            return super.onCreateOptionsMenu(menu);
+        }
+    }
+
+    /**
+     * 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;
+    }
+
+    /**
+     * @return true if the "Respond via SMS" feature should be enabled
+     * for the specified incoming call.
+     *
+     * The general rule is that we *do* allow "Respond via SMS" except for
+     * the few (relatively rare) cases where we know for sure it won't
+     * work, namely:
+     *   - a bogus or blank incoming number
+     *   - a call from a SIP address
+     *   - a "call presentation" that doesn't allow the number to be revealed
+     *
+     * In all other cases, we allow the user to respond via SMS.
+     *
+     * Note that this behavior isn't perfect; for example we have no way
+     * to detect whether the incoming call is from a landline (with most
+     * networks at least), so we still enable this feature even though
+     * SMSes to that number will silently fail.
+     */
+    public static boolean allowRespondViaSmsForCall(Context context, Call ringingCall) {
+        if (DBG) log("allowRespondViaSmsForCall(" + ringingCall + ")...");
+
+        // First some basic sanity checks:
+        if (ringingCall == null) {
+            Log.w(TAG, "allowRespondViaSmsForCall: null ringingCall!");
+            return false;
+        }
+        if (!ringingCall.isRinging()) {
+            // The call is in some state other than INCOMING or WAITING!
+            // (This should almost never happen, but it *could*
+            // conceivably happen if the ringing call got disconnected by
+            // the network just *after* we got it from the CallManager.)
+            Log.w(TAG, "allowRespondViaSmsForCall: ringingCall not ringing! state = "
+                  + ringingCall.getState());
+            return false;
+        }
+        Connection conn = ringingCall.getLatestConnection();
+        if (conn == null) {
+            // The call doesn't have any connections!  (Again, this can
+            // happen if the ringing call disconnects at the exact right
+            // moment, but should almost never happen in practice.)
+            Log.w(TAG, "allowRespondViaSmsForCall: null Connection!");
+            return false;
+        }
+
+        // Check the incoming number:
+        final String number = conn.getAddress();
+        if (DBG) log("- number: '" + number + "'");
+        if (TextUtils.isEmpty(number)) {
+            Log.w(TAG, "allowRespondViaSmsForCall: no incoming number!");
+            return false;
+        }
+        if (PhoneNumberUtils.isUriNumber(number)) {
+            // The incoming number is actually a URI (i.e. a SIP address),
+            // not a regular PSTN phone number, and we can't send SMSes to
+            // SIP addresses.
+            // (TODO: That might still be possible eventually, though.  Is
+            // there some SIP-specific equivalent to sending a text message?)
+            Log.i(TAG, "allowRespondViaSmsForCall: incoming 'number' is a SIP address.");
+            return false;
+        }
+
+        // Finally, check the "call presentation":
+        int presentation = conn.getNumberPresentation();
+        if (DBG) log("- presentation: " + presentation);
+        if (presentation == PhoneConstants.PRESENTATION_RESTRICTED) {
+            // PRESENTATION_RESTRICTED means "caller-id blocked".
+            // The user isn't allowed to see the number in the first
+            // place, so obviously we can't let you send an SMS to it.
+            Log.i(TAG, "allowRespondViaSmsForCall: PRESENTATION_RESTRICTED.");
+            return false;
+        }
+
+        // Allow the feature only when there's a destination for it.
+        if (context.getPackageManager().resolveService(getInstantTextIntent(number, null, null) , 0)
+                == null) {
+            return false;
+        }
+
+        // TODO: with some carriers (in certain countries) you *can* actually
+        // tell whether a given number is a mobile phone or not.  So in that
+        // case we could potentially return false here if the incoming call is
+        // from a land line.
+
+        // If none of the above special cases apply, it's OK to enable the
+        // "Respond via SMS" feature.
+        return true;
+    }
+
+    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);
+    }
+}
diff --git a/src/com/android/phone/Ringer.java b/src/com/android/phone/Ringer.java
new file mode 100644
index 0000000..a882490
--- /dev/null
+++ b/src/com/android/phone/Ringer.java
@@ -0,0 +1,354 @@
+/*
+ * 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.content.Context;
+import android.media.AudioManager;
+import android.media.Ringtone;
+import android.media.RingtoneManager;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.IPowerManager;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.os.SystemProperties;
+import android.os.SystemVibrator;
+import android.os.Vibrator;
+import android.provider.Settings;
+import android.util.Log;
+
+import com.android.internal.telephony.Phone;
+/**
+ * Ringer manager for the Phone app.
+ */
+public class Ringer {
+    private static final String LOG_TAG = "Ringer";
+    private static final boolean DBG =
+            (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
+
+    private static final int PLAY_RING_ONCE = 1;
+    private static final int STOP_RING = 3;
+
+    private static final int VIBRATE_LENGTH = 1000; // ms
+    private static final int PAUSE_LENGTH = 1000; // ms
+
+    /** The singleton instance. */
+    private static Ringer sInstance;
+
+    // Uri for the ringtone.
+    Uri mCustomRingtoneUri = Settings.System.DEFAULT_RINGTONE_URI;
+
+    Ringtone mRingtone;
+    Vibrator mVibrator;
+    IPowerManager mPowerManager;
+    volatile boolean mContinueVibrating;
+    VibratorThread mVibratorThread;
+    Context mContext;
+    private Worker mRingThread;
+    private Handler mRingHandler;
+    private long mFirstRingEventTime = -1;
+    private long mFirstRingStartTime = -1;
+
+    /**
+     * Initialize the singleton Ringer instance.
+     * This is only done once, at startup, from PhoneApp.onCreate().
+     */
+    /* package */ static Ringer init(Context context) {
+        synchronized (Ringer.class) {
+            if (sInstance == null) {
+                sInstance = new Ringer(context);
+            } else {
+                Log.wtf(LOG_TAG, "init() called multiple times!  sInstance = " + sInstance);
+            }
+            return sInstance;
+        }
+    }
+
+    /** Private constructor; @see init() */
+    private Ringer(Context context) {
+        mContext = context;
+        mPowerManager = IPowerManager.Stub.asInterface(ServiceManager.getService(Context.POWER_SERVICE));
+        // We don't rely on getSystemService(Context.VIBRATOR_SERVICE) to make sure this
+        // vibrator object will be isolated from others.
+        mVibrator = new SystemVibrator(context);
+    }
+
+    /**
+     * After a radio technology change, e.g. from CDMA to GSM or vice versa,
+     * the Context of the Ringer has to be updated. This is done by that function.
+     *
+     * @parameter Phone, the new active phone for the appropriate radio
+     * technology
+     */
+    void updateRingerContextAfterRadioTechnologyChange(Phone phone) {
+        if(DBG) Log.d(LOG_TAG, "updateRingerContextAfterRadioTechnologyChange...");
+        mContext = phone.getContext();
+    }
+
+    /**
+     * @return true if we're playing a ringtone and/or vibrating
+     *     to indicate that there's an incoming call.
+     *     ("Ringing" here is used in the general sense.  If you literally
+     *     need to know if we're playing a ringtone or vibrating, use
+     *     isRingtonePlaying() or isVibrating() instead.)
+     *
+     * @see isVibrating
+     * @see isRingtonePlaying
+     */
+    boolean isRinging() {
+        synchronized (this) {
+            return (isRingtonePlaying() || isVibrating());
+        }
+    }
+
+    /**
+     * @return true if the ringtone is playing
+     * @see isVibrating
+     * @see isRinging
+     */
+    private boolean isRingtonePlaying() {
+        synchronized (this) {
+            return (mRingtone != null && mRingtone.isPlaying()) ||
+                    (mRingHandler != null && mRingHandler.hasMessages(PLAY_RING_ONCE));
+        }
+    }
+
+    /**
+     * @return true if we're vibrating in response to an incoming call
+     * @see isVibrating
+     * @see isRinging
+     */
+    private boolean isVibrating() {
+        synchronized (this) {
+            return (mVibratorThread != null);
+        }
+    }
+
+    /**
+     * Starts the ringtone and/or vibrator
+     */
+    void ring() {
+        if (DBG) log("ring()...");
+
+        synchronized (this) {
+            try {
+                if (PhoneGlobals.getInstance().showBluetoothIndication()) {
+                    mPowerManager.setAttentionLight(true, 0x000000ff);
+                } else {
+                    mPowerManager.setAttentionLight(true, 0x00ffffff);
+                }
+            } catch (RemoteException ex) {
+                // the other end of this binder call is in the system process.
+            }
+
+            if (shouldVibrate() && mVibratorThread == null) {
+                mContinueVibrating = true;
+                mVibratorThread = new VibratorThread();
+                if (DBG) log("- starting vibrator...");
+                mVibratorThread.start();
+            }
+            AudioManager audioManager =
+                    (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+
+            if (audioManager.getStreamVolume(AudioManager.STREAM_RING) == 0) {
+                if (DBG) log("skipping ring because volume is zero");
+                return;
+            }
+
+            makeLooper();
+            if (mFirstRingEventTime < 0) {
+                mFirstRingEventTime = SystemClock.elapsedRealtime();
+                mRingHandler.sendEmptyMessage(PLAY_RING_ONCE);
+            } else {
+                // For repeat rings, figure out by how much to delay
+                // the ring so that it happens the correct amount of
+                // time after the previous ring
+                if (mFirstRingStartTime > 0) {
+                    // Delay subsequent rings by the delta between event
+                    // and play time of the first ring
+                    if (DBG) {
+                        log("delaying ring by " + (mFirstRingStartTime - mFirstRingEventTime));
+                    }
+                    mRingHandler.sendEmptyMessageDelayed(PLAY_RING_ONCE,
+                            mFirstRingStartTime - mFirstRingEventTime);
+                } else {
+                    // We've gotten two ring events so far, but the ring
+                    // still hasn't started. Reset the event time to the
+                    // time of this event to maintain correct spacing.
+                    mFirstRingEventTime = SystemClock.elapsedRealtime();
+                }
+            }
+        }
+    }
+
+    boolean shouldVibrate() {
+        AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+        int ringerMode = audioManager.getRingerMode();
+        if (CallFeaturesSetting.getVibrateWhenRinging(mContext)) {
+            return ringerMode != AudioManager.RINGER_MODE_SILENT;
+        } else {
+            return ringerMode == AudioManager.RINGER_MODE_VIBRATE;
+        }
+    }
+
+    /**
+     * Stops the ringtone and/or vibrator if any of these are actually
+     * ringing/vibrating.
+     */
+    void stopRing() {
+        synchronized (this) {
+            if (DBG) log("stopRing()...");
+
+            try {
+                mPowerManager.setAttentionLight(false, 0x00000000);
+            } catch (RemoteException ex) {
+                // the other end of this binder call is in the system process.
+            }
+
+            if (mRingHandler != null) {
+                mRingHandler.removeCallbacksAndMessages(null);
+                Message msg = mRingHandler.obtainMessage(STOP_RING);
+                msg.obj = mRingtone;
+                mRingHandler.sendMessage(msg);
+                PhoneUtils.setAudioMode();
+                mRingThread = null;
+                mRingHandler = null;
+                mRingtone = null;
+                mFirstRingEventTime = -1;
+                mFirstRingStartTime = -1;
+            } else {
+                if (DBG) log("- stopRing: null mRingHandler!");
+            }
+
+            if (mVibratorThread != null) {
+                if (DBG) log("- stopRing: cleaning up vibrator thread...");
+                mContinueVibrating = false;
+                mVibratorThread = null;
+            }
+            // Also immediately cancel any vibration in progress.
+            mVibrator.cancel();
+        }
+    }
+
+    private class VibratorThread extends Thread {
+        public void run() {
+            while (mContinueVibrating) {
+                mVibrator.vibrate(VIBRATE_LENGTH);
+                SystemClock.sleep(VIBRATE_LENGTH + PAUSE_LENGTH);
+            }
+        }
+    }
+    private class Worker implements Runnable {
+        private final Object mLock = new Object();
+        private Looper mLooper;
+
+        Worker(String name) {
+            Thread t = new Thread(null, this, name);
+            t.start();
+            synchronized (mLock) {
+                while (mLooper == null) {
+                    try {
+                        mLock.wait();
+                    } catch (InterruptedException ex) {
+                    }
+                }
+            }
+        }
+
+        public Looper getLooper() {
+            return mLooper;
+        }
+
+        public void run() {
+            synchronized (mLock) {
+                Looper.prepare();
+                mLooper = Looper.myLooper();
+                mLock.notifyAll();
+            }
+            Looper.loop();
+        }
+
+        public void quit() {
+            mLooper.quit();
+        }
+    }
+
+    /**
+     * Sets the ringtone uri in preparation for ringtone creation
+     * in makeLooper().  This uri is defaulted to the phone-wide
+     * default ringtone.
+     */
+    void setCustomRingtoneUri (Uri uri) {
+        if (uri != null) {
+            mCustomRingtoneUri = uri;
+        }
+    }
+
+    private void makeLooper() {
+        if (mRingThread == null) {
+            mRingThread = new Worker("ringer");
+            mRingHandler = new Handler(mRingThread.getLooper()) {
+                @Override
+                public void handleMessage(Message msg) {
+                    Ringtone r = null;
+                    switch (msg.what) {
+                        case PLAY_RING_ONCE:
+                            if (DBG) log("mRingHandler: PLAY_RING_ONCE...");
+                            if (mRingtone == null && !hasMessages(STOP_RING)) {
+                                // create the ringtone with the uri
+                                if (DBG) log("creating ringtone: " + mCustomRingtoneUri);
+                                r = RingtoneManager.getRingtone(mContext, mCustomRingtoneUri);
+                                synchronized (Ringer.this) {
+                                    if (!hasMessages(STOP_RING)) {
+                                        mRingtone = r;
+                                    }
+                                }
+                            }
+                            r = mRingtone;
+                            if (r != null && !hasMessages(STOP_RING) && !r.isPlaying()) {
+                                PhoneUtils.setAudioMode();
+                                r.play();
+                                synchronized (Ringer.this) {
+                                    if (mFirstRingStartTime < 0) {
+                                        mFirstRingStartTime = SystemClock.elapsedRealtime();
+                                    }
+                                }
+                            }
+                            break;
+                        case STOP_RING:
+                            if (DBG) log("mRingHandler: STOP_RING...");
+                            r = (Ringtone) msg.obj;
+                            if (r != null) {
+                                r.stop();
+                            } else {
+                                if (DBG) log("- STOP_RING with null ringtone!  msg = " + msg);
+                            }
+                            getLooper().quit();
+                            break;
+                    }
+                }
+            };
+        }
+    }
+
+    private static void log(String msg) {
+        Log.d(LOG_TAG, msg);
+    }
+}
diff --git a/src/com/android/phone/SimContacts.java b/src/com/android/phone/SimContacts.java
new file mode 100644
index 0000000..ebfc775
--- /dev/null
+++ b/src/com/android/phone/SimContacts.java
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2007 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.accounts.Account;
+import android.app.ActionBar;
+import android.app.ProgressDialog;
+import android.content.ContentProviderOperation;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnCancelListener;
+import android.content.DialogInterface.OnClickListener;
+import android.content.Intent;
+import android.content.OperationApplicationException;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.StructuredName;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.RawContacts;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.ContextMenu;
+import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.CursorAdapter;
+import android.widget.ListView;
+import android.widget.SimpleCursorAdapter;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+
+/**
+ * SIM Address Book UI for the Phone app.
+ */
+public class SimContacts extends ADNList {
+    private static final String LOG_TAG = "SimContacts";
+
+    private static final String UP_ACTIVITY_PACKAGE = "com.android.contacts";
+    private static final String UP_ACTIVITY_CLASS =
+            "com.android.contacts.activities.PeopleActivity";
+
+    static final ContentValues sEmptyContentValues = new ContentValues();
+
+    private static final int MENU_IMPORT_ONE = 1;
+    private static final int MENU_IMPORT_ALL = 2;
+    private ProgressDialog mProgressDialog;
+
+    private Account mAccount;
+
+    private static class NamePhoneTypePair {
+        final String name;
+        final int phoneType;
+        public NamePhoneTypePair(String nameWithPhoneType) {
+            // Look for /W /H /M or /O at the end of the name signifying the type
+            int nameLen = nameWithPhoneType.length();
+            if (nameLen - 2 >= 0 && nameWithPhoneType.charAt(nameLen - 2) == '/') {
+                char c = Character.toUpperCase(nameWithPhoneType.charAt(nameLen - 1));
+                if (c == 'W') {
+                    phoneType = Phone.TYPE_WORK;
+                } else if (c == 'M' || c == 'O') {
+                    phoneType = Phone.TYPE_MOBILE;
+                } else if (c == 'H') {
+                    phoneType = Phone.TYPE_HOME;
+                } else {
+                    phoneType = Phone.TYPE_OTHER;
+                }
+                name = nameWithPhoneType.substring(0, nameLen - 2);
+            } else {
+                phoneType = Phone.TYPE_OTHER;
+                name = nameWithPhoneType;
+            }
+        }
+    }
+
+    private class ImportAllSimContactsThread extends Thread
+            implements OnCancelListener, OnClickListener {
+
+        boolean mCanceled = false;
+
+        public ImportAllSimContactsThread() {
+            super("ImportAllSimContactsThread");
+        }
+
+        @Override
+        public void run() {
+            final ContentValues emptyContentValues = new ContentValues();
+            final ContentResolver resolver = getContentResolver();
+
+            mCursor.moveToPosition(-1);
+            while (!mCanceled && mCursor.moveToNext()) {
+                actuallyImportOneSimContact(mCursor, resolver, mAccount);
+                mProgressDialog.incrementProgressBy(1);
+            }
+
+            mProgressDialog.dismiss();
+            finish();
+        }
+
+        public void onCancel(DialogInterface dialog) {
+            mCanceled = true;
+        }
+
+        public void onClick(DialogInterface dialog, int which) {
+            if (which == DialogInterface.BUTTON_NEGATIVE) {
+                mCanceled = true;
+                mProgressDialog.dismiss();
+            } else {
+                Log.e(LOG_TAG, "Unknown button event has come: " + dialog.toString());
+            }
+        }
+    }
+
+    private static void actuallyImportOneSimContact(
+            final Cursor cursor, final ContentResolver resolver, Account account) {
+        final NamePhoneTypePair namePhoneTypePair =
+            new NamePhoneTypePair(cursor.getString(NAME_COLUMN));
+        final String name = namePhoneTypePair.name;
+        final int phoneType = namePhoneTypePair.phoneType;
+        final String phoneNumber = cursor.getString(NUMBER_COLUMN);
+        final String emailAddresses = cursor.getString(EMAILS_COLUMN);
+        final String[] emailAddressArray;
+        if (!TextUtils.isEmpty(emailAddresses)) {
+            emailAddressArray = emailAddresses.split(",");
+        } else {
+            emailAddressArray = null;
+        }
+
+        final ArrayList<ContentProviderOperation> operationList =
+            new ArrayList<ContentProviderOperation>();
+        ContentProviderOperation.Builder builder =
+            ContentProviderOperation.newInsert(RawContacts.CONTENT_URI);
+        String myGroupsId = null;
+        if (account != null) {
+            builder.withValue(RawContacts.ACCOUNT_NAME, account.name);
+            builder.withValue(RawContacts.ACCOUNT_TYPE, account.type);
+        } else {
+            builder.withValues(sEmptyContentValues);
+        }
+        operationList.add(builder.build());
+
+        builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
+        builder.withValueBackReference(StructuredName.RAW_CONTACT_ID, 0);
+        builder.withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
+        builder.withValue(StructuredName.DISPLAY_NAME, name);
+        operationList.add(builder.build());
+
+        builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
+        builder.withValueBackReference(Phone.RAW_CONTACT_ID, 0);
+        builder.withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
+        builder.withValue(Phone.TYPE, phoneType);
+        builder.withValue(Phone.NUMBER, phoneNumber);
+        builder.withValue(Data.IS_PRIMARY, 1);
+        operationList.add(builder.build());
+
+        if (emailAddresses != null) {
+            for (String emailAddress : emailAddressArray) {
+                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
+                builder.withValueBackReference(Email.RAW_CONTACT_ID, 0);
+                builder.withValue(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
+                builder.withValue(Email.TYPE, Email.TYPE_MOBILE);
+                builder.withValue(Email.DATA, emailAddress);
+                operationList.add(builder.build());
+            }
+        }
+
+        if (myGroupsId != null) {
+            builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
+            builder.withValueBackReference(GroupMembership.RAW_CONTACT_ID, 0);
+            builder.withValue(Data.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE);
+            builder.withValue(GroupMembership.GROUP_SOURCE_ID, myGroupsId);
+            operationList.add(builder.build());
+        }
+
+        try {
+            resolver.applyBatch(ContactsContract.AUTHORITY, operationList);
+        } catch (RemoteException e) {
+            Log.e(LOG_TAG, String.format("%s: %s", e.toString(), e.getMessage()));
+        } catch (OperationApplicationException e) {
+            Log.e(LOG_TAG, String.format("%s: %s", e.toString(), e.getMessage()));
+        }
+    }
+
+    private void importOneSimContact(int position) {
+        final ContentResolver resolver = getContentResolver();
+        if (mCursor.moveToPosition(position)) {
+            actuallyImportOneSimContact(mCursor, resolver, mAccount);
+        } else {
+            Log.e(LOG_TAG, "Failed to move the cursor to the position \"" + position + "\"");
+        }
+    }
+
+    /* Followings are overridden methods */
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        Intent intent = getIntent();
+        if (intent != null) {
+            final String accountName = intent.getStringExtra("account_name");
+            final String accountType = intent.getStringExtra("account_type");
+            if (!TextUtils.isEmpty(accountName) && !TextUtils.isEmpty(accountType)) {
+                mAccount = new Account(accountName, accountType);
+            }
+        }
+
+        registerForContextMenu(getListView());
+
+        ActionBar actionBar = getActionBar();
+        if (actionBar != null) {
+            // android.R.id.home will be triggered in onOptionsItemSelected()
+            actionBar.setDisplayHomeAsUpEnabled(true);
+        }
+    }
+
+    @Override
+    protected CursorAdapter newAdapter() {
+        return new SimpleCursorAdapter(this, R.layout.sim_import_list_entry, mCursor,
+                new String[] { "name" }, new int[] { android.R.id.text1 });
+    }
+
+    @Override
+    protected Uri resolveIntent() {
+        Intent intent = getIntent();
+        intent.setData(Uri.parse("content://icc/adn"));
+        if (Intent.ACTION_PICK.equals(intent.getAction())) {
+            // "index" is 1-based
+            mInitialSelection = intent.getIntExtra("index", 0) - 1;
+        }
+        return intent.getData();
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+        menu.add(0, MENU_IMPORT_ALL, 0, R.string.importAllSimEntries);
+        return true;
+    }
+
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        MenuItem item = menu.findItem(MENU_IMPORT_ALL);
+        if (item != null) {
+            item.setVisible(mCursor != null && mCursor.getCount() > 0);
+        }
+        return super.onPrepareOptionsMenu(menu);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case android.R.id.home:
+                Intent intent = new Intent();
+                intent.setClassName(UP_ACTIVITY_PACKAGE, UP_ACTIVITY_CLASS);
+                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+                startActivity(intent);
+                finish();
+                return true;
+            case MENU_IMPORT_ALL:
+                CharSequence title = getString(R.string.importAllSimEntries);
+                CharSequence message = getString(R.string.importingSimContacts);
+
+                ImportAllSimContactsThread thread = new ImportAllSimContactsThread();
+
+                // TODO: need to show some error dialog.
+                if (mCursor == null) {
+                    Log.e(LOG_TAG, "cursor is null. Ignore silently.");
+                    break;
+                }
+                mProgressDialog = new ProgressDialog(this);
+                mProgressDialog.setTitle(title);
+                mProgressDialog.setMessage(message);
+                mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
+                mProgressDialog.setButton(DialogInterface.BUTTON_NEGATIVE,
+                        getString(R.string.cancel), thread);
+                mProgressDialog.setProgress(0);
+                mProgressDialog.setMax(mCursor.getCount());
+                mProgressDialog.show();
+
+                thread.start();
+
+                return true;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    @Override
+    public boolean onContextItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case MENU_IMPORT_ONE:
+                ContextMenu.ContextMenuInfo menuInfo = item.getMenuInfo();
+                if (menuInfo instanceof AdapterView.AdapterContextMenuInfo) {
+                    int position = ((AdapterView.AdapterContextMenuInfo)menuInfo).position;
+                    importOneSimContact(position);
+                    return true;
+                }
+        }
+        return super.onContextItemSelected(item);
+    }
+
+    @Override
+    public void onCreateContextMenu(ContextMenu menu, View v,
+            ContextMenu.ContextMenuInfo menuInfo) {
+        if (menuInfo instanceof AdapterView.AdapterContextMenuInfo) {
+            AdapterView.AdapterContextMenuInfo itemInfo =
+                    (AdapterView.AdapterContextMenuInfo) menuInfo;
+            TextView textView = (TextView) itemInfo.targetView.findViewById(android.R.id.text1);
+            if (textView != null) {
+                menu.setHeaderTitle(textView.getText());
+            }
+            menu.add(0, MENU_IMPORT_ONE, 0, R.string.importSimEntry);
+        }
+    }
+
+    @Override
+    public void onListItemClick(ListView l, View v, int position, long id) {
+        importOneSimContact(position);
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        switch (keyCode) {
+            case KeyEvent.KEYCODE_CALL: {
+                if (mCursor != null && mCursor.moveToPosition(getSelectedItemPosition())) {
+                    String phoneNumber = mCursor.getString(NUMBER_COLUMN);
+                    if (phoneNumber == null || !TextUtils.isGraphic(phoneNumber)) {
+                        // There is no number entered.
+                        //TODO play error sound or something...
+                        return true;
+                    }
+                    Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED,
+                            Uri.fromParts(Constants.SCHEME_TEL, phoneNumber, null));
+                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                                          | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+                    startActivity(intent);
+                    finish();
+                    return true;
+                }
+            }
+        }
+        return super.onKeyDown(keyCode, event);
+    }
+}
diff --git a/src/com/android/phone/SipBroadcastReceiver.java b/src/com/android/phone/SipBroadcastReceiver.java
new file mode 100644
index 0000000..8fdc7f7
--- /dev/null
+++ b/src/com/android/phone/SipBroadcastReceiver.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2010 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.internal.telephony.CallManager;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.sip.SipPhone;
+import com.android.phone.sip.SipProfileDb;
+import com.android.phone.sip.SipSharedPreferences;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.sip.SipAudioCall;
+import android.net.sip.SipException;
+import android.net.sip.SipManager;
+import android.net.sip.SipProfile;
+import android.telephony.Rlog;
+import java.util.List;
+
+/**
+ * Broadcast receiver that handles SIP-related intents.
+ */
+public class SipBroadcastReceiver extends BroadcastReceiver {
+    private static final String TAG = SipBroadcastReceiver.class.getSimpleName();
+    private static final boolean DBG = true;
+    private SipSharedPreferences mSipSharedPreferences;
+
+    @Override
+    public void onReceive(Context context, final Intent intent) {
+        String action = intent.getAction();
+
+        if (!PhoneUtils.isVoipSupported()) {
+            if (DBG) log("SIP VOIP not supported: " + action);
+            return;
+        }
+        mSipSharedPreferences = new SipSharedPreferences(context);
+
+        if (action.equals(SipManager.ACTION_SIP_INCOMING_CALL)) {
+            takeCall(intent);
+        } else if (action.equals(SipManager.ACTION_SIP_ADD_PHONE)) {
+            String localSipUri = intent.getStringExtra(SipManager.EXTRA_LOCAL_URI);
+            SipPhone phone = PhoneFactory.makeSipPhone(localSipUri);
+            if (phone != null) {
+                CallManager.getInstance().registerPhone(phone);
+            }
+            if (DBG) log("onReceive: add phone" + localSipUri + " #phones="
+                    + CallManager.getInstance().getAllPhones().size());
+        } else if (action.equals(SipManager.ACTION_SIP_REMOVE_PHONE)) {
+            String localSipUri = intent.getStringExtra(SipManager.EXTRA_LOCAL_URI);
+            removeSipPhone(localSipUri);
+            if (DBG) log("onReceive: remove phone: " + localSipUri + " #phones="
+                    + CallManager.getInstance().getAllPhones().size());
+        } else if (action.equals(SipManager.ACTION_SIP_SERVICE_UP)) {
+            if (DBG) log("onReceive: start auto registration");
+            registerAllProfiles();
+        } else {
+            if (DBG) log("onReceive: action not processed: " + action);
+            return;
+        }
+    }
+
+    private void removeSipPhone(String sipUri) {
+        for (Phone phone : CallManager.getInstance().getAllPhones()) {
+            if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_SIP) {
+                if (((SipPhone) phone).getSipUri().equals(sipUri)) {
+                    CallManager.getInstance().unregisterPhone(phone);
+                    return;
+                }
+            }
+        }
+        if (DBG) log("RemoveSipPhone: failed:cannot find phone with uri " + sipUri);
+    }
+
+    private void takeCall(Intent intent) {
+        Context phoneContext = PhoneGlobals.getInstance();
+        try {
+            SipAudioCall sipAudioCall = SipManager.newInstance(phoneContext)
+                    .takeAudioCall(intent, null);
+            for (Phone phone : CallManager.getInstance().getAllPhones()) {
+                if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_SIP) {
+                   if (((SipPhone) phone).canTake(sipAudioCall)) {
+                       if (DBG) log("takeCall: SIP call: " + intent);
+                       return;
+                   }
+                }
+            }
+            if (DBG) log("takeCall: not taken, drop SIP call: " + intent);
+        } catch (SipException e) {
+            loge("takeCall: error incoming SIP call", e);
+        }
+    }
+
+    private void registerAllProfiles() {
+        final Context context = PhoneGlobals.getInstance();
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+                SipManager sipManager = SipManager.newInstance(context);
+                SipProfileDb profileDb = new SipProfileDb(context);
+                List<SipProfile> sipProfileList =
+                        profileDb.retrieveSipProfileList();
+                for (SipProfile profile : sipProfileList) {
+                    try {
+                        if (!profile.getAutoRegistration() &&
+                                !profile.getUriString().equals(
+                                mSipSharedPreferences.getPrimaryAccount())) {
+                            continue;
+                        }
+                        sipManager.open(profile,
+                                SipUtil.createIncomingCallPendingIntent(),
+                                null);
+                        if (DBG) log("registerAllProfiles: profile=" + profile);
+                    } catch (SipException e) {
+                        loge("registerAllProfiles: failed" + profile.getProfileName(), e);
+                    }
+                }
+            }}
+        ).start();
+    }
+
+    private void log(String s) {
+        Rlog.d(TAG, s);
+    }
+
+    private void loge(String s, Throwable t) {
+        Rlog.e(TAG, s, t);
+    }
+}
diff --git a/src/com/android/phone/SipCallOptionHandler.java b/src/com/android/phone/SipCallOptionHandler.java
new file mode 100644
index 0000000..500f322
--- /dev/null
+++ b/src/com/android/phone/SipCallOptionHandler.java
@@ -0,0 +1,448 @@
+/**
+ * Copyright (C) 2010 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.internal.telephony.CallManager;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
+import com.android.phone.sip.SipProfileDb;
+import com.android.phone.sip.SipSettings;
+import com.android.phone.sip.SipSharedPreferences;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.net.Uri;
+import android.net.sip.SipException;
+import android.net.sip.SipManager;
+import android.net.sip.SipProfile;
+import android.os.Bundle;
+import android.os.SystemProperties;
+import android.provider.Settings;
+import android.telephony.PhoneNumberUtils;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.TextView;
+
+import java.util.List;
+
+/**
+ * Activity that selects the proper phone type for an outgoing call.
+ *
+ * This activity determines which Phone type (SIP or PSTN) should be used
+ * for an outgoing phone call, depending on the outgoing "number" (which
+ * may be either a PSTN number or a SIP address) as well as the user's SIP
+ * preferences.  In some cases this activity has no interaction with the
+ * user, but in other cases it may (by bringing up a dialog if the user's
+ * preference is "Ask for each call".)
+ */
+public class SipCallOptionHandler extends Activity implements
+        DialogInterface.OnClickListener, DialogInterface.OnCancelListener,
+        CompoundButton.OnCheckedChangeListener {
+    static final String TAG = "SipCallOptionHandler";
+    private static final boolean DBG =
+            (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
+
+    static final int DIALOG_SELECT_PHONE_TYPE = 0;
+    static final int DIALOG_SELECT_OUTGOING_SIP_PHONE = 1;
+    static final int DIALOG_START_SIP_SETTINGS = 2;
+    static final int DIALOG_NO_INTERNET_ERROR = 3;
+    static final int DIALOG_NO_VOIP = 4;
+    static final int DIALOG_SIZE = 5;
+
+    private Intent mIntent;
+    private List<SipProfile> mProfileList;
+    private String mCallOption;
+    private String mNumber;
+    private SipSharedPreferences mSipSharedPreferences;
+    private SipProfileDb mSipProfileDb;
+    private Dialog[] mDialogs = new Dialog[DIALOG_SIZE];
+    private SipProfile mOutgoingSipProfile;
+    private TextView mUnsetPriamryHint;
+    private boolean mUseSipPhone = false;
+    private boolean mMakePrimary = false;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        Intent intent = getIntent();
+        String action = intent.getAction();
+
+        // This activity is only ever launched with the
+        // ACTION_SIP_SELECT_PHONE action.
+        if (!OutgoingCallBroadcaster.ACTION_SIP_SELECT_PHONE.equals(action)) {
+            Log.wtf(TAG, "onCreate: got intent action '" + action + "', expected "
+                    + OutgoingCallBroadcaster.ACTION_SIP_SELECT_PHONE);
+            finish();
+            return;
+        }
+
+        // mIntent is a copy of the original CALL intent that started the
+        // whole outgoing-call sequence.  This intent will ultimately be
+        // passed to CallController.placeCall() after displaying the SIP
+        // call options dialog (if necessary).
+        mIntent = (Intent) intent.getParcelableExtra(OutgoingCallBroadcaster.EXTRA_NEW_CALL_INTENT);
+        if (mIntent == null) {
+            finish();
+            return;
+        }
+
+        // Allow this activity to be visible in front of the keyguard.
+        // (This is only necessary for obscure scenarios like the user
+        // initiating a call and then immediately pressing the Power
+        // button.)
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
+
+        // If we're trying to make a SIP call, return a SipPhone if one is
+        // available.
+        //
+        // - If it's a sip: URI, this is definitely a SIP call, regardless
+        //   of whether the data is a SIP address or a regular phone
+        //   number.
+        //
+        // - If this is a tel: URI but the data contains an "@" character
+        //   (see PhoneNumberUtils.isUriNumber()) we consider that to be a
+        //   SIP number too.
+        //
+        // TODO: Eventually we may want to disallow that latter case
+        //       (e.g. "tel:foo@example.com").
+        //
+        // TODO: We should also consider moving this logic into the
+        //       CallManager, where it could be made more generic.
+        //       (For example, each "telephony provider" could be allowed
+        //       to register the URI scheme(s) that it can handle, and the
+        //       CallManager would then find the best match for every
+        //       outgoing call.)
+
+        boolean voipSupported = PhoneUtils.isVoipSupported();
+        if (DBG) Log.v(TAG, "voipSupported: " + voipSupported);
+        mSipProfileDb = new SipProfileDb(this);
+        mSipSharedPreferences = new SipSharedPreferences(this);
+        mCallOption = mSipSharedPreferences.getSipCallOption();
+        if (DBG) Log.v(TAG, "Call option: " + mCallOption);
+        Uri uri = mIntent.getData();
+        String scheme = uri.getScheme();
+        mNumber = PhoneNumberUtils.getNumberFromIntent(mIntent, this);
+        boolean isInCellNetwork = PhoneGlobals.getInstance().phoneMgr.isRadioOn();
+        boolean isKnownCallScheme = Constants.SCHEME_TEL.equals(scheme)
+                || Constants.SCHEME_SIP.equals(scheme);
+        boolean isRegularCall = Constants.SCHEME_TEL.equals(scheme)
+                && !PhoneNumberUtils.isUriNumber(mNumber);
+
+        // Bypass the handler if the call scheme is not sip or tel.
+        if (!isKnownCallScheme) {
+            setResultAndFinish();
+            return;
+        }
+
+        // Check if VoIP feature is supported.
+        if (!voipSupported) {
+            if (!isRegularCall) {
+                showDialog(DIALOG_NO_VOIP);
+            } else {
+                setResultAndFinish();
+            }
+            return;
+        }
+
+        // Since we are not sure if anyone has touched the number during
+        // the NEW_OUTGOING_CALL broadcast, we just check if the provider
+        // put their gateway information in the intent. If so, it means
+        // someone has changed the destination number. We then make the
+        // call via the default pstn network. However, if one just alters
+        // the destination directly, then we still let it go through the
+        // Internet call option process.
+        if (!PhoneUtils.hasPhoneProviderExtras(mIntent)) {
+            if (!isNetworkConnected()) {
+                if (!isRegularCall) {
+                    showDialog(DIALOG_NO_INTERNET_ERROR);
+                    return;
+                }
+            } else {
+                if (mCallOption.equals(Settings.System.SIP_ASK_ME_EACH_TIME)
+                        && isRegularCall && isInCellNetwork) {
+                    showDialog(DIALOG_SELECT_PHONE_TYPE);
+                    return;
+                }
+                if (!mCallOption.equals(Settings.System.SIP_ADDRESS_ONLY)
+                        || !isRegularCall) {
+                    mUseSipPhone = true;
+                }
+            }
+        }
+
+        if (mUseSipPhone) {
+            // If there is no sip profile and it is a regular call, then we
+            // should use pstn network instead.
+            if ((mSipProfileDb.getProfilesCount() > 0) || !isRegularCall) {
+                startGetPrimarySipPhoneThread();
+                return;
+            } else {
+                mUseSipPhone = false;
+            }
+        }
+        setResultAndFinish();
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        if (isFinishing()) return;
+        for (Dialog dialog : mDialogs) {
+            if (dialog != null) dialog.dismiss();
+        }
+        finish();
+    }
+
+    protected Dialog onCreateDialog(int id) {
+        Dialog dialog;
+        switch(id) {
+        case DIALOG_SELECT_PHONE_TYPE:
+            dialog = new AlertDialog.Builder(this)
+                    .setTitle(R.string.pick_outgoing_call_phone_type)
+                    .setIconAttribute(android.R.attr.alertDialogIcon)
+                    .setSingleChoiceItems(R.array.phone_type_values, -1, this)
+                    .setNegativeButton(android.R.string.cancel, this)
+                    .setOnCancelListener(this)
+                    .create();
+            break;
+        case DIALOG_SELECT_OUTGOING_SIP_PHONE:
+            dialog = new AlertDialog.Builder(this)
+                    .setTitle(R.string.pick_outgoing_sip_phone)
+                    .setIconAttribute(android.R.attr.alertDialogIcon)
+                    .setSingleChoiceItems(getProfileNameArray(), -1, this)
+                    .setNegativeButton(android.R.string.cancel, this)
+                    .setOnCancelListener(this)
+                    .create();
+            addMakeDefaultCheckBox(dialog);
+            break;
+        case DIALOG_START_SIP_SETTINGS:
+            dialog = new AlertDialog.Builder(this)
+                    .setTitle(R.string.no_sip_account_found_title)
+                    .setMessage(R.string.no_sip_account_found)
+                    .setIconAttribute(android.R.attr.alertDialogIcon)
+                    .setPositiveButton(R.string.sip_menu_add, this)
+                    .setNegativeButton(android.R.string.cancel, this)
+                    .setOnCancelListener(this)
+                    .create();
+            break;
+        case DIALOG_NO_INTERNET_ERROR:
+            boolean wifiOnly = SipManager.isSipWifiOnly(this);
+            dialog = new AlertDialog.Builder(this)
+                    .setTitle(wifiOnly ? R.string.no_wifi_available_title
+                                       : R.string.no_internet_available_title)
+                    .setMessage(wifiOnly ? R.string.no_wifi_available
+                                         : R.string.no_internet_available)
+                    .setIconAttribute(android.R.attr.alertDialogIcon)
+                    .setPositiveButton(android.R.string.ok, this)
+                    .setOnCancelListener(this)
+                    .create();
+            break;
+        case DIALOG_NO_VOIP:
+            dialog = new AlertDialog.Builder(this)
+                    .setTitle(R.string.no_voip)
+                    .setIconAttribute(android.R.attr.alertDialogIcon)
+                    .setPositiveButton(android.R.string.ok, this)
+                    .setOnCancelListener(this)
+                    .create();
+            break;
+        default:
+            dialog = null;
+        }
+        if (dialog != null) {
+            mDialogs[id] = dialog;
+        }
+        return dialog;
+    }
+
+    private void addMakeDefaultCheckBox(Dialog dialog) {
+        LayoutInflater inflater = (LayoutInflater) getSystemService(
+                Context.LAYOUT_INFLATER_SERVICE);
+        View view = inflater.inflate(
+                com.android.internal.R.layout.always_use_checkbox, null);
+        CheckBox makePrimaryCheckBox =
+                (CheckBox)view.findViewById(com.android.internal.R.id.alwaysUse);
+        makePrimaryCheckBox.setText(R.string.remember_my_choice);
+        makePrimaryCheckBox.setOnCheckedChangeListener(this);
+        mUnsetPriamryHint = (TextView)view.findViewById(
+                com.android.internal.R.id.clearDefaultHint);
+        mUnsetPriamryHint.setText(R.string.reset_my_choice_hint);
+        mUnsetPriamryHint.setVisibility(View.GONE);
+        ((AlertDialog)dialog).setView(view);
+    }
+
+    private CharSequence[] getProfileNameArray() {
+        CharSequence[] entries = new CharSequence[mProfileList.size()];
+        int i = 0;
+        for (SipProfile p : mProfileList) {
+            entries[i++] = p.getProfileName();
+        }
+        return entries;
+    }
+
+    public void onClick(DialogInterface dialog, int id) {
+        if (id == DialogInterface.BUTTON_NEGATIVE) {
+            // button negative is cancel
+            finish();
+            return;
+        } else if(dialog == mDialogs[DIALOG_SELECT_PHONE_TYPE]) {
+            String selection = getResources().getStringArray(
+                    R.array.phone_type_values)[id];
+            if (DBG) Log.v(TAG, "User pick phone " + selection);
+            if (selection.equals(getString(R.string.internet_phone))) {
+                mUseSipPhone = true;
+                startGetPrimarySipPhoneThread();
+                return;
+            }
+        } else if (dialog == mDialogs[DIALOG_SELECT_OUTGOING_SIP_PHONE]) {
+            mOutgoingSipProfile = mProfileList.get(id);
+        } else if ((dialog == mDialogs[DIALOG_NO_INTERNET_ERROR])
+                || (dialog == mDialogs[DIALOG_NO_VOIP])) {
+            finish();
+            return;
+        } else {
+            if (id == DialogInterface.BUTTON_POSITIVE) {
+                // Redirect to sip settings and drop the call.
+                Intent newIntent = new Intent(this, SipSettings.class);
+                newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                startActivity(newIntent);
+            }
+            finish();
+            return;
+        }
+        setResultAndFinish();
+    }
+
+    public void onCancel(DialogInterface dialog) {
+        finish();
+    }
+
+    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+        mMakePrimary = isChecked;
+        if (isChecked) {
+            mUnsetPriamryHint.setVisibility(View.VISIBLE);
+        } else {
+            mUnsetPriamryHint.setVisibility(View.INVISIBLE);
+        }
+    }
+
+    private void createSipPhoneIfNeeded(SipProfile p) {
+        CallManager cm = PhoneGlobals.getInstance().mCM;
+        if (PhoneUtils.getSipPhoneFromUri(cm, p.getUriString()) != null) return;
+
+        // Create the phone since we can not find it in CallManager
+        try {
+            SipManager.newInstance(this).open(p);
+            Phone phone = PhoneFactory.makeSipPhone(p.getUriString());
+            if (phone != null) {
+                cm.registerPhone(phone);
+            } else {
+                Log.e(TAG, "cannot make sipphone profile" + p);
+            }
+        } catch (SipException e) {
+            Log.e(TAG, "cannot open sip profile" + p, e);
+        }
+    }
+
+    private void setResultAndFinish() {
+        runOnUiThread(new Runnable() {
+            public void run() {
+                if (mOutgoingSipProfile != null) {
+                    if (!isNetworkConnected()) {
+                        showDialog(DIALOG_NO_INTERNET_ERROR);
+                        return;
+                    }
+                    if (DBG) Log.v(TAG, "primary SIP URI is " +
+                            mOutgoingSipProfile.getUriString());
+                    createSipPhoneIfNeeded(mOutgoingSipProfile);
+                    mIntent.putExtra(OutgoingCallBroadcaster.EXTRA_SIP_PHONE_URI,
+                            mOutgoingSipProfile.getUriString());
+                    if (mMakePrimary) {
+                        mSipSharedPreferences.setPrimaryAccount(
+                                mOutgoingSipProfile.getUriString());
+                    }
+                }
+
+                if (mUseSipPhone && mOutgoingSipProfile == null) {
+                    showDialog(DIALOG_START_SIP_SETTINGS);
+                    return;
+                } else {
+                    // Woo hoo -- it's finally OK to initiate the outgoing call!
+                    PhoneGlobals.getInstance().callController.placeCall(mIntent);
+                }
+                finish();
+            }
+        });
+    }
+
+    private boolean isNetworkConnected() {
+        ConnectivityManager cm = (ConnectivityManager) getSystemService(
+                Context.CONNECTIVITY_SERVICE);
+        if (cm != null) {
+            NetworkInfo ni = cm.getActiveNetworkInfo();
+            if ((ni == null) || !ni.isConnected()) return false;
+
+            return ((ni.getType() == ConnectivityManager.TYPE_WIFI)
+                    || !SipManager.isSipWifiOnly(this));
+        }
+        return false;
+    }
+
+    private void startGetPrimarySipPhoneThread() {
+        new Thread(new Runnable() {
+            public void run() {
+                getPrimarySipPhone();
+            }
+        }).start();
+    }
+
+    private void getPrimarySipPhone() {
+        String primarySipUri = mSipSharedPreferences.getPrimaryAccount();
+
+        mOutgoingSipProfile = getPrimaryFromExistingProfiles(primarySipUri);
+        if (mOutgoingSipProfile == null) {
+            if ((mProfileList != null) && (mProfileList.size() > 0)) {
+                runOnUiThread(new Runnable() {
+                    public void run() {
+                        showDialog(DIALOG_SELECT_OUTGOING_SIP_PHONE);
+                    }
+                });
+                return;
+            }
+        }
+        setResultAndFinish();
+    }
+
+    private SipProfile getPrimaryFromExistingProfiles(String primarySipUri) {
+        mProfileList = mSipProfileDb.retrieveSipProfileList();
+        if (mProfileList == null) return null;
+        for (SipProfile p : mProfileList) {
+            if (p.getUriString().equals(primarySipUri)) return p;
+        }
+        return null;
+    }
+}
diff --git a/src/com/android/phone/SipUtil.java b/src/com/android/phone/SipUtil.java
new file mode 100644
index 0000000..a901d58
--- /dev/null
+++ b/src/com/android/phone/SipUtil.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2010 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.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.net.sip.SipManager;
+
+public class SipUtil {
+    private SipUtil() {
+    }
+
+    public static PendingIntent createIncomingCallPendingIntent() {
+        Context phoneContext = PhoneGlobals.getInstance();
+        Intent intent = new Intent(phoneContext, SipBroadcastReceiver.class);
+        intent.setAction(SipManager.ACTION_SIP_INCOMING_CALL);
+        return PendingIntent.getBroadcast(phoneContext, 0, intent,
+                PendingIntent.FLAG_UPDATE_CURRENT);
+    }
+}
diff --git a/src/com/android/phone/SmallerHitTargetTouchListener.java b/src/com/android/phone/SmallerHitTargetTouchListener.java
new file mode 100644
index 0000000..8e1bf16
--- /dev/null
+++ b/src/com/android/phone/SmallerHitTargetTouchListener.java
@@ -0,0 +1,115 @@
+/*
+ * 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.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+
+/**
+ * OnTouchListener used to shrink the "hit target" of some onscreen buttons.
+ *
+ * We do this for a few specific buttons which are vulnerable to
+ * "false touches" because either (1) they're near the edge of the
+ * screen and might be unintentionally touched while holding the
+ * device in your hand, (2) they're in the upper corners and might
+ * be touched by the user's ear before the prox sensor has a chance to
+ * kick in, or (3) they are close to other buttons.
+ */
+public class SmallerHitTargetTouchListener implements View.OnTouchListener {
+    private static final String TAG = "SmallerHitTargetTouchListener";
+
+    /**
+     * Edge dimensions where a touch does not register an action (in DIP).
+     */
+    private static final int HIT_TARGET_EDGE_IGNORE_DP_X = 30;
+    private static final int HIT_TARGET_EDGE_IGNORE_DP_Y = 10;
+    private static final int HIT_TARGET_MIN_SIZE_DP_X = HIT_TARGET_EDGE_IGNORE_DP_X * 3;
+    private static final int HIT_TARGET_MIN_SIZE_DP_Y = HIT_TARGET_EDGE_IGNORE_DP_Y * 3;
+
+    // True if the most recent DOWN event was a "hit".
+    boolean mDownEventHit;
+
+    /**
+     * Called when a touch event is dispatched to a view. This allows listeners to
+     * get a chance to respond before the target view.
+     *
+     * @return True if the listener has consumed the event, false otherwise.
+     *         (In other words, we return true when the touch is *outside*
+     *         the "smaller hit target", which will prevent the actual
+     *         button from handling these events.)
+     */
+    @Override
+    public boolean onTouch(View v, MotionEvent event) {
+        // if (DBG) log("SmallerHitTargetTouchListener: " + v + ", event " + event);
+
+        if (event.getAction() == MotionEvent.ACTION_DOWN) {
+            // Note that event.getX() and event.getY() are already
+            // translated into the View's coordinates.  (In other words,
+            // "0,0" is a touch on the upper-left-most corner of the view.)
+            final int touchX = (int) event.getX();
+            final int touchY = (int) event.getY();
+
+            final int viewWidth = v.getWidth();
+            final int viewHeight = v.getHeight();
+
+            final float pixelDensity = v.getResources().getDisplayMetrics().density;
+            final int targetMinSizeX = (int) (HIT_TARGET_MIN_SIZE_DP_X * pixelDensity);
+            final int targetMinSizeY = (int) (HIT_TARGET_MIN_SIZE_DP_Y * pixelDensity);
+
+            int edgeIgnoreX = (int) (HIT_TARGET_EDGE_IGNORE_DP_X * pixelDensity);
+            int edgeIgnoreY = (int) (HIT_TARGET_EDGE_IGNORE_DP_Y * pixelDensity);
+
+            // If we are dealing with smaller buttons where the dead zone defined by
+            // HIT_TARGET_EDGE_IGNORE_DP_[X|Y] is too large.
+            if (viewWidth < targetMinSizeX || viewHeight < targetMinSizeY) {
+                // This really should not happen given our two use cases (as of this writing)
+                // in the call edge button and secondary calling card. However, we leave
+                // this is as a precautionary measure.
+                Log.w(TAG, "onTouch: view is too small for SmallerHitTargetTouchListener");
+                edgeIgnoreX = 0;
+                edgeIgnoreY = 0;
+            }
+
+            final int minTouchX = edgeIgnoreX;
+            final int maxTouchX = viewWidth - edgeIgnoreX;
+            final int minTouchY = edgeIgnoreY;
+            final int maxTouchY = viewHeight - edgeIgnoreY;
+
+            if (touchX < minTouchX || touchX > maxTouchX ||
+                    touchY < minTouchY || touchY > maxTouchY) {
+                // Missed!
+                // if (DBG) log("  -> MISSED!");
+                mDownEventHit = false;
+                return true;  // Consume this event; don't let the button see it
+            } else {
+                // Hit!
+                // if (DBG) log("  -> HIT!");
+                mDownEventHit = true;
+                return false;  // Let this event through to the actual button
+            }
+        } else {
+            // This is a MOVE, UP or CANCEL event.
+            //
+            // We only do the "smaller hit target" check on DOWN events.
+            // For the subsequent MOVE/UP/CANCEL events, we let them
+            // through to the actual button IFF the previous DOWN event
+            // got through to the actual button (i.e. it was a "hit".)
+            return !mDownEventHit;
+        }
+    }
+}
diff --git a/src/com/android/phone/SpecialCharSequenceMgr.java b/src/com/android/phone/SpecialCharSequenceMgr.java
new file mode 100644
index 0000000..9b5373c
--- /dev/null
+++ b/src/com/android/phone/SpecialCharSequenceMgr.java
@@ -0,0 +1,263 @@
+/*
+ * 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.app.Activity;
+import android.app.AlertDialog;
+import android.content.ActivityNotFoundException;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.telephony.Phone;
+import android.telephony.PhoneNumberUtils;
+import android.util.Log;
+import android.view.WindowManager;
+
+import com.android.internal.telephony.TelephonyCapabilities;
+
+/**
+ * Helper class to listen for some magic dialpad character sequences
+ * that are handled specially by the Phone app.
+ *
+ * Note the Contacts app also handles these sequences too, so there's a
+ * separate version of this class under apps/Contacts.
+ *
+ * In fact, the most common use case for these special sequences is typing
+ * them from the regular "Dialer" used for outgoing calls, which is part
+ * of the contacts app; see DialtactsActivity and DialpadFragment.
+ * *This* version of SpecialCharSequenceMgr is used for only a few
+ * relatively obscure places in the UI:
+ * - The "SIM network unlock" PIN entry screen (see
+ *   IccNetworkDepersonalizationPanel.java)
+ * - The emergency dialer (see EmergencyDialer.java).
+ *
+ * TODO: there's lots of duplicated code between this class and the
+ * corresponding class under apps/Contacts.  Let's figure out a way to
+ * unify these two classes (in the framework? in a common shared library?)
+ */
+public class SpecialCharSequenceMgr {
+    private static final String TAG = PhoneGlobals.LOG_TAG;
+    private static final boolean DBG = false;
+
+    private static final String MMI_IMEI_DISPLAY = "*#06#";
+    private static final String MMI_REGULATORY_INFO_DISPLAY = "*#07#";
+
+    /** This class is never instantiated. */
+    private SpecialCharSequenceMgr() {
+    }
+
+    /**
+     * Check for special strings of digits from an input
+     * string.
+     * @param context input Context for the events we handle.
+     * @param input the dial string to be examined.
+     */
+    static boolean handleChars(Context context, String input) {
+        return handleChars(context, input, null);
+    }
+
+    /**
+     * Generally used for the Personal Unblocking Key (PUK) unlocking
+     * case, where we want to be able to maintain a handle to the
+     * calling activity so that we can close it or otherwise display
+     * indication if the PUK code is recognized.
+     *
+     * NOTE: The counterpart to this file in Contacts does
+     * NOT contain the special PUK handling code, since it
+     * does NOT need it.  When the device gets into PUK-
+     * locked state, the keyguard comes up and the only way
+     * to unlock the device is through the Emergency dialer,
+     * which is still in the Phone App.
+     *
+     * @param context input Context for the events we handle.
+     * @param input the dial string to be examined.
+     * @param pukInputActivity activity that originated this
+     * PUK call, tracked so that we can close it or otherwise
+     * indicate that special character sequence is
+     * successfully processed. Can be null.
+     * @return true if the input was a special string which has been
+     * handled.
+     */
+    static boolean handleChars(Context context,
+                               String input,
+                               Activity pukInputActivity) {
+
+        //get rid of the separators so that the string gets parsed correctly
+        String dialString = PhoneNumberUtils.stripSeparators(input);
+
+        if (handleIMEIDisplay(context, dialString)
+            || handleRegulatoryInfoDisplay(context, dialString)
+            || handlePinEntry(context, dialString, pukInputActivity)
+            || handleAdnEntry(context, dialString)
+            || handleSecretCode(context, dialString)) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Variant of handleChars() that looks for the subset of "special
+     * sequences" that are available even if the device is locked.
+     *
+     * (Specifically, these are the sequences that you're allowed to type
+     * in the Emergency Dialer, which is accessible *without* unlocking
+     * the device.)
+     */
+    static boolean handleCharsForLockedDevice(Context context,
+                                              String input,
+                                              Activity pukInputActivity) {
+        // Get rid of the separators so that the string gets parsed correctly
+        String dialString = PhoneNumberUtils.stripSeparators(input);
+
+        // The only sequences available on a locked device are the "**04"
+        // or "**05" sequences that allow you to enter PIN or PUK-related
+        // codes.  (e.g. for the case where you're currently locked out of
+        // your phone, and need to change the PIN!  The only way to do
+        // that is via the Emergency Dialer.)
+
+        if (handlePinEntry(context, dialString, pukInputActivity)) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Handles secret codes to launch arbitrary activities in the form of *#*#<code>#*#*.
+     * If a secret code is encountered an Intent is started with the android_secret_code://<code>
+     * URI.
+     *
+     * @param context the context to use
+     * @param input the text to check for a secret code in
+     * @return true if a secret code was encountered
+     */
+    static private boolean handleSecretCode(Context context, String input) {
+        // Secret codes are in the form *#*#<code>#*#*
+        int len = input.length();
+        if (len > 8 && input.startsWith("*#*#") && input.endsWith("#*#*")) {
+            Intent intent = new Intent(TelephonyIntents.SECRET_CODE_ACTION,
+                    Uri.parse("android_secret_code://" + input.substring(4, len - 4)));
+            context.sendBroadcast(intent);
+            return true;
+        }
+
+        return false;
+    }
+
+    static private boolean handleAdnEntry(Context context, String input) {
+        /* ADN entries are of the form "N(N)(N)#" */
+
+        // if the phone is keyguard-restricted, then just ignore this
+        // input.  We want to make sure that sim card contacts are NOT
+        // exposed unless the phone is unlocked, and this code can be
+        // accessed from the emergency dialer.
+        if (PhoneGlobals.getInstance().getKeyguardManager().inKeyguardRestrictedInputMode()) {
+            return false;
+        }
+
+        int len = input.length();
+        if ((len > 1) && (len < 5) && (input.endsWith("#"))) {
+            try {
+                int index = Integer.parseInt(input.substring(0, len-1));
+                Intent intent = new Intent(Intent.ACTION_PICK);
+
+                intent.setClassName("com.android.phone",
+                                    "com.android.phone.SimContacts");
+                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                intent.putExtra("index", index);
+                PhoneGlobals.getInstance().startActivity(intent);
+
+                return true;
+            } catch (NumberFormatException ex) {}
+        }
+        return false;
+    }
+
+    static private boolean handlePinEntry(Context context, String input,
+                                          Activity pukInputActivity) {
+        // TODO: The string constants here should be removed in favor
+        // of some call to a static the MmiCode class that determines
+        // if a dialstring is an MMI code.
+        if ((input.startsWith("**04") || input.startsWith("**05"))
+                && input.endsWith("#")) {
+            PhoneGlobals app = PhoneGlobals.getInstance();
+            boolean isMMIHandled = app.phone.handlePinMmi(input);
+
+            // if the PUK code is recognized then indicate to the
+            // phone app that an attempt to unPUK the device was
+            // made with this activity.  The PUK code may still
+            // fail though, but we won't know until the MMI code
+            // returns a result.
+            if (isMMIHandled && input.startsWith("**05")) {
+                app.setPukEntryActivity(pukInputActivity);
+            }
+            return isMMIHandled;
+        }
+        return false;
+    }
+
+    static private boolean handleIMEIDisplay(Context context,
+                                             String input) {
+        if (input.equals(MMI_IMEI_DISPLAY)) {
+            showDeviceIdPanel(context);
+            return true;
+        }
+
+        return false;
+    }
+
+    static private void showDeviceIdPanel(Context context) {
+        if (DBG) log("showDeviceIdPanel()...");
+
+        Phone phone = PhoneGlobals.getPhone();
+        int labelId = TelephonyCapabilities.getDeviceIdLabel(phone);
+        String deviceId = phone.getDeviceId();
+
+        AlertDialog alert = new AlertDialog.Builder(context)
+                .setTitle(labelId)
+                .setMessage(deviceId)
+                .setPositiveButton(R.string.ok, null)
+                .setCancelable(false)
+                .create();
+        alert.getWindow().setType(WindowManager.LayoutParams.TYPE_PRIORITY_PHONE);
+        alert.show();
+    }
+
+    private static boolean handleRegulatoryInfoDisplay(Context context, String input) {
+        if (input.equals(MMI_REGULATORY_INFO_DISPLAY)) {
+            log("handleRegulatoryInfoDisplay() sending intent to settings app");
+            ComponentName regInfoDisplayActivity = new ComponentName(
+                    "com.android.settings", "com.android.settings.RegulatoryInfoDisplayActivity");
+            Intent showRegInfoIntent = new Intent("android.settings.SHOW_REGULATORY_INFO");
+            showRegInfoIntent.setComponent(regInfoDisplayActivity);
+            try {
+                context.startActivity(showRegInfoIntent);
+            } catch (ActivityNotFoundException e) {
+                Log.e(TAG, "startActivity() failed: " + e);
+            }
+            return true;
+        }
+        return false;
+    }
+
+    private static void log(String msg) {
+        Log.d(TAG, "[SpecialCharSequenceMgr] " + msg);
+    }
+}
diff --git a/src/com/android/phone/TelephonyDebugService.java b/src/com/android/phone/TelephonyDebugService.java
new file mode 100644
index 0000000..fdfe8f5
--- /dev/null
+++ b/src/com/android/phone/TelephonyDebugService.java
@@ -0,0 +1,53 @@
+/*
+ * 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 com.android.internal.telephony.DebugService;
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+import android.util.Log;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+/**
+ * A debug service for telephony.
+ */
+public class TelephonyDebugService extends Service {
+    private static String TAG = "TelephonyDebugService";
+    private DebugService mDebugService = new DebugService();
+
+    /** Constructor */
+    public TelephonyDebugService() {
+        Log.d(TAG, "TelephonyDebugService()");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public IBinder onBind(Intent intent) {
+        return null;
+    }
+
+    @Override
+    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        mDebugService.dump(fd, pw, args);
+    }
+}
+
diff --git a/src/com/android/phone/TimeConsumingPreferenceActivity.java b/src/com/android/phone/TimeConsumingPreferenceActivity.java
new file mode 100644
index 0000000..19c4dda
--- /dev/null
+++ b/src/com/android/phone/TimeConsumingPreferenceActivity.java
@@ -0,0 +1,211 @@
+package com.android.phone;
+
+import com.android.internal.telephony.CommandException;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.ProgressDialog;
+import android.content.DialogInterface;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.util.Log;
+import android.view.WindowManager;
+
+import java.util.ArrayList;
+
+interface  TimeConsumingPreferenceListener {
+    public void onStarted(Preference preference, boolean reading);
+    public void onFinished(Preference preference, boolean reading);
+    public void onError(Preference preference, int error);
+    public void onException(Preference preference, CommandException exception);
+}
+
+public class TimeConsumingPreferenceActivity extends PreferenceActivity
+                        implements TimeConsumingPreferenceListener,
+                        DialogInterface.OnCancelListener {
+    private static final String LOG_TAG = "TimeConsumingPreferenceActivity";
+    private final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
+
+    private class DismissOnClickListener implements DialogInterface.OnClickListener {
+        @Override
+        public void onClick(DialogInterface dialog, int which) {
+            dialog.dismiss();
+        }
+    }
+    private class DismissAndFinishOnClickListener implements DialogInterface.OnClickListener {
+        @Override
+        public void onClick(DialogInterface dialog, int which) {
+            dialog.dismiss();
+            finish();
+        }
+    }
+    private final DialogInterface.OnClickListener mDismiss = new DismissOnClickListener();
+    private final DialogInterface.OnClickListener mDismissAndFinish
+            = new DismissAndFinishOnClickListener();
+
+    private static final int BUSY_READING_DIALOG = 100;
+    private static final int BUSY_SAVING_DIALOG = 200;
+
+    static final int EXCEPTION_ERROR = 300;
+    static final int RESPONSE_ERROR = 400;
+    static final int RADIO_OFF_ERROR = 500;
+    static final int FDN_CHECK_FAILURE = 600;
+
+    private final ArrayList<String> mBusyList = new ArrayList<String>();
+
+    protected boolean mIsForeground = false;
+
+    @Override
+    protected Dialog onCreateDialog(int id) {
+        if (id == BUSY_READING_DIALOG || id == BUSY_SAVING_DIALOG) {
+            ProgressDialog dialog = new ProgressDialog(this);
+            dialog.setTitle(getText(R.string.updating_title));
+            dialog.setIndeterminate(true);
+
+            switch(id) {
+                case BUSY_READING_DIALOG:
+                    dialog.setCancelable(true);
+                    dialog.setOnCancelListener(this);
+                    dialog.setMessage(getText(R.string.reading_settings));
+                    return dialog;
+                case BUSY_SAVING_DIALOG:
+                    dialog.setCancelable(false);
+                    dialog.setMessage(getText(R.string.updating_settings));
+                    return dialog;
+            }
+            return null;
+        }
+
+        if (id == RESPONSE_ERROR || id == RADIO_OFF_ERROR || id == EXCEPTION_ERROR
+                || id == FDN_CHECK_FAILURE) {
+            AlertDialog.Builder builder = new AlertDialog.Builder(this);
+
+            int msgId;
+            int titleId = R.string.error_updating_title;
+
+            switch (id) {
+                case RESPONSE_ERROR:
+                    msgId = R.string.response_error;
+                    builder.setPositiveButton(R.string.close_dialog, mDismiss);
+                    break;
+                case RADIO_OFF_ERROR:
+                    msgId = R.string.radio_off_error;
+                    // The error is not recoverable on dialog exit.
+                    builder.setPositiveButton(R.string.close_dialog, mDismissAndFinish);
+                    break;
+                case FDN_CHECK_FAILURE:
+                    msgId = R.string.fdn_check_failure;
+                    builder.setPositiveButton(R.string.close_dialog, mDismiss);
+                    break;
+                case EXCEPTION_ERROR:
+                default:
+                    msgId = R.string.exception_error;
+                    // The error is not recoverable on dialog exit.
+                    builder.setPositiveButton(R.string.close_dialog, mDismissAndFinish);
+                    break;
+            }
+
+            builder.setTitle(getText(titleId));
+            builder.setMessage(getText(msgId));
+            builder.setCancelable(false);
+            AlertDialog dialog = builder.create();
+
+            // make the dialog more obvious by blurring the background.
+            dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
+
+            return dialog;
+        }
+        return null;
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        mIsForeground = true;
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        mIsForeground = false;
+    }
+
+    @Override
+    public void onStarted(Preference preference, boolean reading) {
+        if (DBG) dumpState();
+        if (DBG) Log.d(LOG_TAG, "onStarted, preference=" + preference.getKey()
+                + ", reading=" + reading);
+        mBusyList.add(preference.getKey());
+
+        if (mIsForeground) {
+              if (reading) {
+                  showDialog(BUSY_READING_DIALOG);
+              } else {
+                  showDialog(BUSY_SAVING_DIALOG);
+              }
+        }
+
+    }
+
+    @Override
+    public void onFinished(Preference preference, boolean reading) {
+        if (DBG) dumpState();
+        if (DBG) Log.d(LOG_TAG, "onFinished, preference=" + preference.getKey()
+                + ", reading=" + reading);
+        mBusyList.remove(preference.getKey());
+
+        if (mBusyList.isEmpty()) {
+            if (reading) {
+                dismissDialogSafely(BUSY_READING_DIALOG);
+            } else {
+                dismissDialogSafely(BUSY_SAVING_DIALOG);
+            }
+        }
+        preference.setEnabled(true);
+    }
+
+    @Override
+    public void onError(Preference preference, int error) {
+        if (DBG) dumpState();
+        if (DBG) Log.d(LOG_TAG, "onError, preference=" + preference.getKey() + ", error=" + error);
+
+        if (mIsForeground) {
+            showDialog(error);
+        }
+        preference.setEnabled(false);
+    }
+
+    @Override
+    public void onException(Preference preference, CommandException exception) {
+        if (exception.getCommandError() == CommandException.Error.FDN_CHECK_FAILURE) {
+            onError(preference, FDN_CHECK_FAILURE);
+        } else {
+            preference.setEnabled(false);
+            onError(preference, EXCEPTION_ERROR);
+        }
+    }
+
+    @Override
+    public void onCancel(DialogInterface dialog) {
+        if (DBG) dumpState();
+        finish();
+    }
+
+    private void dismissDialogSafely(int id) {
+        try {
+            dismissDialog(id);
+        } catch (IllegalArgumentException e) {
+            // This is expected in the case where we were in the background
+            // at the time we would normally have shown the dialog, so we didn't
+            // show it.
+        }
+    }
+
+    /* package */ void dumpState() {
+        Log.d(LOG_TAG, "dumpState begin");
+        for (String key : mBusyList) {
+            Log.d(LOG_TAG, "mBusyList: key=" + key);
+        }
+        Log.d(LOG_TAG, "dumpState end");
+    }
+}
diff --git a/src/com/android/phone/Use2GOnlyCheckBoxPreference.java b/src/com/android/phone/Use2GOnlyCheckBoxPreference.java
new file mode 100644
index 0000000..a5a7a67
--- /dev/null
+++ b/src/com/android/phone/Use2GOnlyCheckBoxPreference.java
@@ -0,0 +1,123 @@
+/*
+ * 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.content.Context;
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.Message;
+import android.os.SystemProperties;
+import android.preference.CheckBoxPreference;
+import android.util.AttributeSet;
+import android.util.Log;
+
+import com.android.internal.telephony.Phone;
+
+public class Use2GOnlyCheckBoxPreference extends CheckBoxPreference {
+    private static final String LOG_TAG = "Use2GOnlyCheckBoxPreference";
+
+    private Phone mPhone;
+    private MyHandler mHandler;
+
+    public Use2GOnlyCheckBoxPreference(Context context) {
+        this(context, null);
+    }
+
+    public Use2GOnlyCheckBoxPreference(Context context, AttributeSet attrs) {
+        this(context, attrs,com.android.internal.R.attr.checkBoxPreferenceStyle);
+    }
+
+    public Use2GOnlyCheckBoxPreference(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        mPhone = PhoneGlobals.getPhone();
+        mHandler = new MyHandler();
+        mPhone.getPreferredNetworkType(
+                mHandler.obtainMessage(MyHandler.MESSAGE_GET_PREFERRED_NETWORK_TYPE));
+    }
+
+    private int getDefaultNetworkMode() {
+        int mode = SystemProperties.getInt("ro.telephony.default_network",
+                Phone.PREFERRED_NT_MODE);
+        Log.i(LOG_TAG, "getDefaultNetworkMode: mode=" + mode);
+        return mode;
+    }
+
+    @Override
+    protected void  onClick() {
+        super.onClick();
+
+        int networkType = isChecked() ? Phone.NT_MODE_GSM_ONLY : getDefaultNetworkMode();
+        Log.i(LOG_TAG, "set preferred network type="+networkType);
+        android.provider.Settings.Global.putInt(mPhone.getContext().getContentResolver(),
+                android.provider.Settings.Global.PREFERRED_NETWORK_MODE, networkType);
+        mPhone.setPreferredNetworkType(networkType, mHandler
+                .obtainMessage(MyHandler.MESSAGE_SET_PREFERRED_NETWORK_TYPE));
+   }
+
+    private class MyHandler extends Handler {
+
+        static final int MESSAGE_GET_PREFERRED_NETWORK_TYPE = 0;
+        static final int MESSAGE_SET_PREFERRED_NETWORK_TYPE = 1;
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MESSAGE_GET_PREFERRED_NETWORK_TYPE:
+                    handleGetPreferredNetworkTypeResponse(msg);
+                    break;
+
+                case MESSAGE_SET_PREFERRED_NETWORK_TYPE:
+                    handleSetPreferredNetworkTypeResponse(msg);
+                    break;
+            }
+        }
+
+        private void handleGetPreferredNetworkTypeResponse(Message msg) {
+            AsyncResult ar = (AsyncResult) msg.obj;
+
+            if (ar.exception == null) {
+                int type = ((int[])ar.result)[0];
+                if (type != Phone.NT_MODE_GSM_ONLY) {
+                    // Back to default
+                    type = getDefaultNetworkMode();
+                }
+                Log.i(LOG_TAG, "get preferred network type="+type);
+                setChecked(type == Phone.NT_MODE_GSM_ONLY);
+                android.provider.Settings.Global.putInt(mPhone.getContext().getContentResolver(),
+                        android.provider.Settings.Global.PREFERRED_NETWORK_MODE, type);
+            } else {
+                // Weird state, disable the setting
+                Log.i(LOG_TAG, "get preferred network type, exception="+ar.exception);
+                setEnabled(false);
+            }
+        }
+
+        private void handleSetPreferredNetworkTypeResponse(Message msg) {
+            AsyncResult ar = (AsyncResult) msg.obj;
+
+            if (ar.exception != null) {
+                // Yikes, error, disable the setting
+                setEnabled(false);
+                // Set UI to current state
+                Log.i(LOG_TAG, "set preferred network type, exception=" + ar.exception);
+                mPhone.getPreferredNetworkType(obtainMessage(MESSAGE_GET_PREFERRED_NETWORK_TYPE));
+            } else {
+                Log.i(LOG_TAG, "set preferred network type done");
+            }
+        }
+    }
+}
diff --git a/src/com/android/phone/sip/SipEditor.java b/src/com/android/phone/sip/SipEditor.java
new file mode 100644
index 0000000..8145c94
--- /dev/null
+++ b/src/com/android/phone/sip/SipEditor.java
@@ -0,0 +1,657 @@
+/*
+ * Copyright (C) 2010 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.sip;
+
+import com.android.internal.telephony.CallManager;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
+import com.android.phone.R;
+import com.android.phone.SipUtil;
+
+import android.app.ActionBar;
+import android.app.AlertDialog;
+import android.content.Intent;
+import android.net.sip.SipManager;
+import android.net.sip.SipProfile;
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.preference.CheckBoxPreference;
+import android.preference.EditTextPreference;
+import android.preference.ListPreference;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceGroup;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.Button;
+import android.widget.Toast;
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+
+/**
+ * The activity class for editing a new or existing SIP profile.
+ */
+public class SipEditor extends PreferenceActivity
+        implements Preference.OnPreferenceChangeListener {
+    private static final int MENU_SAVE = Menu.FIRST;
+    private static final int MENU_DISCARD = Menu.FIRST + 1;
+    private static final int MENU_REMOVE = Menu.FIRST + 2;
+
+    private static final String TAG = SipEditor.class.getSimpleName();
+    private static final String KEY_PROFILE = "profile";
+    private static final String GET_METHOD_PREFIX = "get";
+    private static final char SCRAMBLED = '*';
+    private static final int NA = 0;
+
+    private PrimaryAccountSelector mPrimaryAccountSelector;
+    private AdvancedSettings mAdvancedSettings;
+    private SipSharedPreferences mSharedPreferences;
+    private boolean mDisplayNameSet;
+    private boolean mHomeButtonClicked;
+    private boolean mUpdateRequired;
+    private boolean mUpdatedFieldIsEmpty;
+
+    private SipManager mSipManager;
+    private SipProfileDb mProfileDb;
+    private SipProfile mOldProfile;
+    private CallManager mCallManager;
+    private Button mRemoveButton;
+
+    enum PreferenceKey {
+        Username(R.string.username, 0, R.string.default_preference_summary),
+        Password(R.string.password, 0, R.string.default_preference_summary),
+        DomainAddress(R.string.domain_address, 0, R.string.default_preference_summary),
+        DisplayName(R.string.display_name, 0, R.string.display_name_summary),
+        ProxyAddress(R.string.proxy_address, 0, R.string.optional_summary),
+        Port(R.string.port, R.string.default_port, R.string.default_port),
+        Transport(R.string.transport, R.string.default_transport, NA),
+        SendKeepAlive(R.string.send_keepalive, R.string.sip_system_decide, NA),
+        AuthUserName(R.string.auth_username, 0, R.string.optional_summary);
+
+        final int text;
+        final int initValue;
+        final int defaultSummary;
+        Preference preference;
+
+        /**
+         * @param key The key name of the preference.
+         * @param initValue The initial value of the preference.
+         * @param defaultSummary The default summary value of the preference
+         *        when the preference value is empty.
+         */
+        PreferenceKey(int text, int initValue, int defaultSummary) {
+            this.text = text;
+            this.initValue = initValue;
+            this.defaultSummary = defaultSummary;
+        }
+
+        String getValue() {
+            if (preference instanceof EditTextPreference) {
+                return ((EditTextPreference) preference).getText();
+            } else if (preference instanceof ListPreference) {
+                return ((ListPreference) preference).getValue();
+            }
+            throw new RuntimeException("getValue() for the preference " + this);
+        }
+
+        void setValue(String value) {
+            if (preference instanceof EditTextPreference) {
+                String oldValue = getValue();
+                ((EditTextPreference) preference).setText(value);
+                if (this != Password) {
+                    Log.v(TAG, this + ": setValue() " + value + ": " + oldValue
+                            + " --> " + getValue());
+                }
+            } else if (preference instanceof ListPreference) {
+                ((ListPreference) preference).setValue(value);
+            }
+
+            if (TextUtils.isEmpty(value)) {
+                preference.setSummary(defaultSummary);
+            } else if (this == Password) {
+                preference.setSummary(scramble(value));
+            } else if ((this == DisplayName)
+                    && value.equals(getDefaultDisplayName())) {
+                preference.setSummary(defaultSummary);
+            } else {
+                preference.setSummary(value);
+            }
+        }
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        mHomeButtonClicked = false;
+        if (mCallManager.getState() != PhoneConstants.State.IDLE) {
+            mAdvancedSettings.show();
+            getPreferenceScreen().setEnabled(false);
+            if (mRemoveButton != null) mRemoveButton.setEnabled(false);
+        } else {
+            getPreferenceScreen().setEnabled(true);
+            if (mRemoveButton != null) mRemoveButton.setEnabled(true);
+        }
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        Log.v(TAG, "start profile editor");
+        super.onCreate(savedInstanceState);
+
+        mSipManager = SipManager.newInstance(this);
+        mSharedPreferences = new SipSharedPreferences(this);
+        mProfileDb = new SipProfileDb(this);
+        mCallManager = CallManager.getInstance();
+
+        setContentView(R.layout.sip_settings_ui);
+        addPreferencesFromResource(R.xml.sip_edit);
+
+        SipProfile p = mOldProfile = (SipProfile) ((savedInstanceState == null)
+                ? getIntent().getParcelableExtra(SipSettings.KEY_SIP_PROFILE)
+                : savedInstanceState.getParcelable(KEY_PROFILE));
+
+        PreferenceGroup screen = (PreferenceGroup) getPreferenceScreen();
+        for (int i = 0, n = screen.getPreferenceCount(); i < n; i++) {
+            setupPreference(screen.getPreference(i));
+        }
+
+        if (p == null) {
+            screen.setTitle(R.string.sip_edit_new_title);
+        }
+
+        mAdvancedSettings = new AdvancedSettings();
+        mPrimaryAccountSelector = new PrimaryAccountSelector(p);
+
+        loadPreferencesFromProfile(p);
+    }
+
+    @Override
+    public void onPause() {
+        Log.v(TAG, "SipEditor onPause(): finishing? " + isFinishing());
+        if (!isFinishing()) {
+            mHomeButtonClicked = true;
+            validateAndSetResult();
+        }
+        super.onPause();
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+        menu.add(0, MENU_DISCARD, 0, R.string.sip_menu_discard)
+                .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+        menu.add(0, MENU_SAVE, 0, R.string.sip_menu_save)
+                .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+        menu.add(0, MENU_REMOVE, 0, R.string.remove_sip_account)
+                .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
+        return true;
+    }
+
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        MenuItem removeMenu = menu.findItem(MENU_REMOVE);
+        removeMenu.setVisible(mOldProfile != null);
+        menu.findItem(MENU_SAVE).setEnabled(mUpdateRequired);
+        return super.onPrepareOptionsMenu(menu);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case MENU_SAVE:
+                validateAndSetResult();
+                return true;
+
+            case MENU_DISCARD:
+                finish();
+                return true;
+
+            case MENU_REMOVE: {
+                setRemovedProfileAndFinish();
+                return true;
+            }
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        switch (keyCode) {
+            case KeyEvent.KEYCODE_BACK:
+                validateAndSetResult();
+                return true;
+        }
+        return super.onKeyDown(keyCode, event);
+    }
+
+    private void saveAndRegisterProfile(SipProfile p) throws IOException {
+        if (p == null) return;
+        mProfileDb.saveProfile(p);
+        if (p.getAutoRegistration()
+                || mSharedPreferences.isPrimaryAccount(p.getUriString())) {
+            try {
+                mSipManager.open(p, SipUtil.createIncomingCallPendingIntent(),
+                        null);
+            } catch (Exception e) {
+                Log.e(TAG, "register failed: " + p.getUriString(), e);
+            }
+        }
+    }
+
+    private void deleteAndUnregisterProfile(SipProfile p) {
+        if (p == null) return;
+        mProfileDb.deleteProfile(p);
+        unregisterProfile(p.getUriString());
+    }
+
+    private void unregisterProfile(String uri) {
+        try {
+            mSipManager.close(uri);
+        } catch (Exception e) {
+            Log.e(TAG, "unregister failed: " + uri, e);
+        }
+    }
+
+    private void setRemovedProfileAndFinish() {
+        Intent intent = new Intent(this, SipSettings.class);
+        setResult(RESULT_FIRST_USER, intent);
+        Toast.makeText(this, R.string.removing_account, Toast.LENGTH_SHORT)
+                .show();
+        replaceProfile(mOldProfile, null);
+        // do finish() in replaceProfile() in a background thread
+    }
+
+    private void showAlert(Throwable e) {
+        String msg = e.getMessage();
+        if (TextUtils.isEmpty(msg)) msg = e.toString();
+        showAlert(msg);
+    }
+
+    private void showAlert(final String message) {
+        if (mHomeButtonClicked) {
+            Log.v(TAG, "Home button clicked, don't show dialog: " + message);
+            return;
+        }
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                new AlertDialog.Builder(SipEditor.this)
+                        .setTitle(android.R.string.dialog_alert_title)
+                        .setIconAttribute(android.R.attr.alertDialogIcon)
+                        .setMessage(message)
+                        .setPositiveButton(R.string.alert_dialog_ok, null)
+                        .show();
+            }
+        });
+    }
+
+    private boolean isEditTextEmpty(PreferenceKey key) {
+        EditTextPreference pref = (EditTextPreference) key.preference;
+        return TextUtils.isEmpty(pref.getText())
+                || pref.getSummary().equals(getString(key.defaultSummary));
+    }
+
+    private void validateAndSetResult() {
+        boolean allEmpty = true;
+        CharSequence firstEmptyFieldTitle = null;
+        for (PreferenceKey key : PreferenceKey.values()) {
+            Preference p = key.preference;
+            if (p instanceof EditTextPreference) {
+                EditTextPreference pref = (EditTextPreference) p;
+                boolean fieldEmpty = isEditTextEmpty(key);
+                if (allEmpty && !fieldEmpty) allEmpty = false;
+
+                // use default value if display name is empty
+                if (fieldEmpty) {
+                    switch (key) {
+                        case DisplayName:
+                            pref.setText(getDefaultDisplayName());
+                            break;
+                        case AuthUserName:
+                        case ProxyAddress:
+                            // optional; do nothing
+                            break;
+                        case Port:
+                            pref.setText(getString(R.string.default_port));
+                            break;
+                        default:
+                            if (firstEmptyFieldTitle == null) {
+                                firstEmptyFieldTitle = pref.getTitle();
+                            }
+                    }
+                } else if (key == PreferenceKey.Port) {
+                    int port = Integer.parseInt(PreferenceKey.Port.getValue());
+                    if ((port < 1000) || (port > 65534)) {
+                        showAlert(getString(R.string.not_a_valid_port));
+                        return;
+                    }
+                }
+            }
+        }
+
+        if (allEmpty || !mUpdateRequired) {
+            finish();
+            return;
+        } else if (firstEmptyFieldTitle != null) {
+            showAlert(getString(R.string.empty_alert, firstEmptyFieldTitle));
+            return;
+        }
+        try {
+            SipProfile profile = createSipProfile();
+            Intent intent = new Intent(this, SipSettings.class);
+            intent.putExtra(SipSettings.KEY_SIP_PROFILE, (Parcelable) profile);
+            setResult(RESULT_OK, intent);
+            Toast.makeText(this, R.string.saving_account, Toast.LENGTH_SHORT)
+                    .show();
+
+            replaceProfile(mOldProfile, profile);
+            // do finish() in replaceProfile() in a background thread
+        } catch (Exception e) {
+            Log.w(TAG, "Can not create new SipProfile", e);
+            showAlert(e);
+        }
+    }
+
+    private void unregisterOldPrimaryAccount() {
+        String primaryAccountUri = mSharedPreferences.getPrimaryAccount();
+        Log.v(TAG, "old primary: " + primaryAccountUri);
+        if ((primaryAccountUri != null)
+                && !mSharedPreferences.isReceivingCallsEnabled()) {
+            Log.v(TAG, "unregister old primary: " + primaryAccountUri);
+            unregisterProfile(primaryAccountUri);
+        }
+    }
+
+    private void replaceProfile(final SipProfile oldProfile,
+            final SipProfile newProfile) {
+        // Replace profile in a background thread as it takes time to access the
+        // storage; do finish() once everything goes fine.
+        // newProfile may be null if the old profile is to be deleted rather
+        // than being modified.
+        new Thread(new Runnable() {
+            public void run() {
+                try {
+                    // if new profile is primary, unregister the old primary account
+                    if ((newProfile != null) && mPrimaryAccountSelector.isSelected()) {
+                        unregisterOldPrimaryAccount();
+                    }
+
+                    mPrimaryAccountSelector.commit(newProfile);
+                    deleteAndUnregisterProfile(oldProfile);
+                    saveAndRegisterProfile(newProfile);
+                    finish();
+                } catch (Exception e) {
+                    Log.e(TAG, "Can not save/register new SipProfile", e);
+                    showAlert(e);
+                }
+            }
+        }, "SipEditor").start();
+    }
+
+    private String getProfileName() {
+        return PreferenceKey.Username.getValue() + "@"
+                + PreferenceKey.DomainAddress.getValue();
+    }
+
+    private SipProfile createSipProfile() throws Exception {
+            return new SipProfile.Builder(
+                    PreferenceKey.Username.getValue(),
+                    PreferenceKey.DomainAddress.getValue())
+                    .setProfileName(getProfileName())
+                    .setPassword(PreferenceKey.Password.getValue())
+                    .setOutboundProxy(PreferenceKey.ProxyAddress.getValue())
+                    .setProtocol(PreferenceKey.Transport.getValue())
+                    .setDisplayName(PreferenceKey.DisplayName.getValue())
+                    .setPort(Integer.parseInt(PreferenceKey.Port.getValue()))
+                    .setSendKeepAlive(isAlwaysSendKeepAlive())
+                    .setAutoRegistration(
+                            mSharedPreferences.isReceivingCallsEnabled())
+                    .setAuthUserName(PreferenceKey.AuthUserName.getValue())
+                    .build();
+    }
+
+    public boolean onPreferenceChange(Preference pref, Object newValue) {
+        if (!mUpdateRequired) {
+            mUpdateRequired = true;
+            if (mOldProfile != null) {
+                unregisterProfile(mOldProfile.getUriString());
+            }
+        }
+        if (pref instanceof CheckBoxPreference) {
+            invalidateOptionsMenu();
+            return true;
+        }
+        String value = (newValue == null) ? "" : newValue.toString();
+        if (TextUtils.isEmpty(value)) {
+            pref.setSummary(getPreferenceKey(pref).defaultSummary);
+        } else if (pref == PreferenceKey.Password.preference) {
+            pref.setSummary(scramble(value));
+        } else {
+            pref.setSummary(value);
+        }
+
+        if (pref == PreferenceKey.DisplayName.preference) {
+            ((EditTextPreference) pref).setText(value);
+            checkIfDisplayNameSet();
+        }
+
+        // SAVE menu should be enabled once the user modified some preference.
+        invalidateOptionsMenu();
+        return true;
+    }
+
+    private PreferenceKey getPreferenceKey(Preference pref) {
+        for (PreferenceKey key : PreferenceKey.values()) {
+            if (key.preference == pref) return key;
+        }
+        throw new RuntimeException("not possible to reach here");
+    }
+
+    private void loadPreferencesFromProfile(SipProfile p) {
+        if (p != null) {
+            Log.v(TAG, "Edit the existing profile : " + p.getProfileName());
+            try {
+                Class profileClass = SipProfile.class;
+                for (PreferenceKey key : PreferenceKey.values()) {
+                    Method meth = profileClass.getMethod(GET_METHOD_PREFIX
+                            + getString(key.text), (Class[])null);
+                    if (key == PreferenceKey.SendKeepAlive) {
+                        boolean value = ((Boolean)
+                                meth.invoke(p, (Object[]) null)).booleanValue();
+                        key.setValue(getString(value
+                                ? R.string.sip_always_send_keepalive
+                                : R.string.sip_system_decide));
+                    } else {
+                        Object value = meth.invoke(p, (Object[])null);
+                        key.setValue((value == null) ? "" : value.toString());
+                    }
+                }
+                checkIfDisplayNameSet();
+            } catch (Exception e) {
+                Log.e(TAG, "Can not load pref from profile", e);
+            }
+        } else {
+            Log.v(TAG, "Edit a new profile");
+            for (PreferenceKey key : PreferenceKey.values()) {
+                key.preference.setOnPreferenceChangeListener(this);
+
+                // FIXME: android:defaultValue in preference xml file doesn't
+                // work. Even if we setValue() for each preference in the case
+                // of (p != null), the dialog still shows android:defaultValue,
+                // not the value set by setValue(). This happens if
+                // android:defaultValue is not empty. Is it a bug?
+                if (key.initValue != 0) {
+                    key.setValue(getString(key.initValue));
+                }
+            }
+            mDisplayNameSet = false;
+        }
+    }
+
+    private boolean isAlwaysSendKeepAlive() {
+        ListPreference pref = (ListPreference)
+                PreferenceKey.SendKeepAlive.preference;
+        return getString(R.string.sip_always_send_keepalive).equals(
+                pref.getValue());
+    }
+
+    private void setCheckBox(PreferenceKey key, boolean checked) {
+        CheckBoxPreference pref = (CheckBoxPreference) key.preference;
+        pref.setChecked(checked);
+    }
+
+    private void setupPreference(Preference pref) {
+        pref.setOnPreferenceChangeListener(this);
+        for (PreferenceKey key : PreferenceKey.values()) {
+            String name = getString(key.text);
+            if (name.equals(pref.getKey())) {
+                key.preference = pref;
+                return;
+            }
+        }
+    }
+
+    private void checkIfDisplayNameSet() {
+        String displayName = PreferenceKey.DisplayName.getValue();
+        mDisplayNameSet = !TextUtils.isEmpty(displayName)
+                && !displayName.equals(getDefaultDisplayName());
+        Log.d(TAG, "displayName set? " + mDisplayNameSet);
+        if (mDisplayNameSet) {
+            PreferenceKey.DisplayName.preference.setSummary(displayName);
+        } else {
+            PreferenceKey.DisplayName.setValue("");
+        }
+    }
+
+    private static String getDefaultDisplayName() {
+        return PreferenceKey.Username.getValue();
+    }
+
+    private static String scramble(String s) {
+        char[] cc = new char[s.length()];
+        Arrays.fill(cc, SCRAMBLED);
+        return new String(cc);
+    }
+
+    // only takes care of the primary account setting in SipSharedSettings
+    private class PrimaryAccountSelector {
+        private CheckBoxPreference mCheckbox;
+        private final boolean mWasPrimaryAccount;
+
+        // @param profile profile to be edited; null if adding new profile
+        PrimaryAccountSelector(SipProfile profile) {
+            mCheckbox = (CheckBoxPreference) getPreferenceScreen()
+                    .findPreference(getString(R.string.set_primary));
+            boolean noPrimaryAccountSet =
+                    !mSharedPreferences.hasPrimaryAccount();
+            boolean editNewProfile = (profile == null);
+            mWasPrimaryAccount = !editNewProfile
+                    && mSharedPreferences.isPrimaryAccount(
+                            profile.getUriString());
+
+            Log.v(TAG, " noPrimaryAccountSet: " + noPrimaryAccountSet);
+            Log.v(TAG, " editNewProfile: " + editNewProfile);
+            Log.v(TAG, " mWasPrimaryAccount: " + mWasPrimaryAccount);
+
+            mCheckbox.setChecked(mWasPrimaryAccount
+                    || (editNewProfile && noPrimaryAccountSet));
+        }
+
+        boolean isSelected() {
+            return mCheckbox.isChecked();
+        }
+
+        // profile is null if the user removes it
+        void commit(SipProfile profile) {
+            if ((profile != null) && mCheckbox.isChecked()) {
+                mSharedPreferences.setPrimaryAccount(profile.getUriString());
+            } else if (mWasPrimaryAccount) {
+                mSharedPreferences.unsetPrimaryAccount();
+            }
+            Log.d(TAG, " primary account changed to : "
+                    + mSharedPreferences.getPrimaryAccount());
+        }
+    }
+
+    private class AdvancedSettings
+            implements Preference.OnPreferenceClickListener {
+        private Preference mAdvancedSettingsTrigger;
+        private Preference[] mPreferences;
+        private boolean mShowing = false;
+
+        AdvancedSettings() {
+            mAdvancedSettingsTrigger = getPreferenceScreen().findPreference(
+                    getString(R.string.advanced_settings));
+            mAdvancedSettingsTrigger.setOnPreferenceClickListener(this);
+
+            loadAdvancedPreferences();
+        }
+
+        private void loadAdvancedPreferences() {
+            PreferenceGroup screen = (PreferenceGroup) getPreferenceScreen();
+
+            addPreferencesFromResource(R.xml.sip_advanced_edit);
+            PreferenceGroup group = (PreferenceGroup) screen.findPreference(
+                    getString(R.string.advanced_settings_container));
+            screen.removePreference(group);
+
+            mPreferences = new Preference[group.getPreferenceCount()];
+            int order = screen.getPreferenceCount();
+            for (int i = 0, n = mPreferences.length; i < n; i++) {
+                Preference pref = group.getPreference(i);
+                pref.setOrder(order++);
+                setupPreference(pref);
+                mPreferences[i] = pref;
+            }
+        }
+
+        void show() {
+            mShowing = true;
+            mAdvancedSettingsTrigger.setSummary(R.string.advanced_settings_hide);
+            PreferenceGroup screen = (PreferenceGroup) getPreferenceScreen();
+            for (Preference pref : mPreferences) {
+                screen.addPreference(pref);
+                Log.v(TAG, "add pref " + pref.getKey() + ": order=" + pref.getOrder());
+            }
+        }
+
+        private void hide() {
+            mShowing = false;
+            mAdvancedSettingsTrigger.setSummary(R.string.advanced_settings_show);
+            PreferenceGroup screen = (PreferenceGroup) getPreferenceScreen();
+            for (Preference pref : mPreferences) {
+                screen.removePreference(pref);
+            }
+        }
+
+        public boolean onPreferenceClick(Preference preference) {
+            Log.v(TAG, "optional settings clicked");
+            if (!mShowing) {
+                show();
+            } else {
+                hide();
+            }
+            return true;
+        }
+    }
+}
diff --git a/src/com/android/phone/sip/SipProfileDb.java b/src/com/android/phone/sip/SipProfileDb.java
new file mode 100644
index 0000000..a51dfb9
--- /dev/null
+++ b/src/com/android/phone/sip/SipProfileDb.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2010 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.sip;
+
+import com.android.internal.os.AtomicFile;
+
+import android.content.Context;
+import android.net.sip.SipProfile;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Utility class that helps perform operations on the SipProfile database.
+ */
+public class SipProfileDb {
+    private static final String TAG = SipProfileDb.class.getSimpleName();
+
+    private static final String PROFILES_DIR = "/profiles/";
+    private static final String PROFILE_OBJ_FILE = ".pobj";
+
+    private String mProfilesDirectory;
+    private SipSharedPreferences mSipSharedPreferences;
+    private int mProfilesCount = -1;
+
+    public SipProfileDb(Context context) {
+        mProfilesDirectory = context.getFilesDir().getAbsolutePath()
+                + PROFILES_DIR;
+        mSipSharedPreferences = new SipSharedPreferences(context);
+    }
+
+    public void deleteProfile(SipProfile p) {
+        synchronized(SipProfileDb.class) {
+            deleteProfile(new File(mProfilesDirectory + p.getProfileName()));
+            if (mProfilesCount < 0) retrieveSipProfileListInternal();
+            mSipSharedPreferences.setProfilesCount(--mProfilesCount);
+        }
+    }
+
+    private void deleteProfile(File file) {
+        if (file.isDirectory()) {
+            for (File child : file.listFiles()) deleteProfile(child);
+        }
+        file.delete();
+    }
+
+    public void saveProfile(SipProfile p) throws IOException {
+        synchronized(SipProfileDb.class) {
+            if (mProfilesCount < 0) retrieveSipProfileListInternal();
+            File f = new File(mProfilesDirectory + p.getProfileName());
+            if (!f.exists()) f.mkdirs();
+            AtomicFile atomicFile =
+                    new AtomicFile(new File(f, PROFILE_OBJ_FILE));
+            FileOutputStream fos = null;
+            ObjectOutputStream oos = null;
+            try {
+                fos = atomicFile.startWrite();
+                oos = new ObjectOutputStream(fos);
+                oos.writeObject(p);
+                oos.flush();
+                mSipSharedPreferences.setProfilesCount(++mProfilesCount);
+                atomicFile.finishWrite(fos);
+            } catch (IOException e) {
+                atomicFile.failWrite(fos);
+                throw e;
+            } finally {
+                if (oos != null) oos.close();
+            }
+        }
+    }
+
+    public int getProfilesCount() {
+        return (mProfilesCount < 0) ?
+                mSipSharedPreferences.getProfilesCount() : mProfilesCount;
+    }
+
+    public List<SipProfile> retrieveSipProfileList() {
+        synchronized(SipProfileDb.class) {
+            return retrieveSipProfileListInternal();
+        }
+    }
+
+    private List<SipProfile> retrieveSipProfileListInternal() {
+        List<SipProfile> sipProfileList = Collections.synchronizedList(
+                new ArrayList<SipProfile>());
+
+        File root = new File(mProfilesDirectory);
+        String[] dirs = root.list();
+        if (dirs == null) return sipProfileList;
+        for (String dir : dirs) {
+            File f = new File(new File(root, dir), PROFILE_OBJ_FILE);
+            if (!f.exists()) continue;
+            try {
+                SipProfile p = deserialize(f);
+                if (p == null) continue;
+                if (!dir.equals(p.getProfileName())) continue;
+
+                sipProfileList.add(p);
+            } catch (IOException e) {
+                Log.e(TAG, "retrieveProfileListFromStorage()", e);
+            }
+        }
+        mProfilesCount = sipProfileList.size();
+        mSipSharedPreferences.setProfilesCount(mProfilesCount);
+        return sipProfileList;
+    }
+
+    private SipProfile deserialize(File profileObjectFile) throws IOException {
+        AtomicFile atomicFile = new AtomicFile(profileObjectFile);
+        ObjectInputStream ois = null;
+        try {
+            ois = new ObjectInputStream(atomicFile.openRead());
+            SipProfile p = (SipProfile) ois.readObject();
+            return p;
+        } catch (ClassNotFoundException e) {
+            Log.w(TAG, "deserialize a profile: " + e);
+        } finally {
+            if (ois!= null) ois.close();
+        }
+        return null;
+    }
+}
diff --git a/src/com/android/phone/sip/SipSettings.java b/src/com/android/phone/sip/SipSettings.java
new file mode 100644
index 0000000..d58386c
--- /dev/null
+++ b/src/com/android/phone/sip/SipSettings.java
@@ -0,0 +1,514 @@
+/*
+ * Copyright (C) 2010 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.sip;
+
+import com.android.internal.telephony.CallManager;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
+import com.android.phone.CallFeaturesSetting;
+import com.android.phone.R;
+import com.android.phone.SipUtil;
+
+import android.app.ActionBar;
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.net.sip.SipErrorCode;
+import android.net.sip.SipException;
+import android.net.sip.SipManager;
+import android.net.sip.SipProfile;
+import android.net.sip.SipRegistrationListener;
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.os.Process;
+import android.preference.CheckBoxPreference;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceClickListener;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceCategory;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * The PreferenceActivity class for managing sip profile preferences.
+ */
+public class SipSettings extends PreferenceActivity {
+    public static final String SIP_SHARED_PREFERENCES = "SIP_PREFERENCES";
+
+    private static final int MENU_ADD_ACCOUNT = Menu.FIRST;
+
+    static final String KEY_SIP_PROFILE = "sip_profile";
+
+    private static final String BUTTON_SIP_RECEIVE_CALLS =
+            "sip_receive_calls_key";
+    private static final String PREF_SIP_LIST = "sip_account_list";
+    private static final String TAG = "SipSettings";
+
+    private static final int REQUEST_ADD_OR_EDIT_SIP_PROFILE = 1;
+
+    private PackageManager mPackageManager;
+    private SipManager mSipManager;
+    private CallManager mCallManager;
+    private SipProfileDb mProfileDb;
+
+    private SipProfile mProfile; // profile that's being edited
+
+    private CheckBoxPreference mButtonSipReceiveCalls;
+    private PreferenceCategory mSipListContainer;
+    private Map<String, SipPreference> mSipPreferenceMap;
+    private List<SipProfile> mSipProfileList;
+    private SipSharedPreferences mSipSharedPreferences;
+    private int mUid = Process.myUid();
+
+    private class SipPreference extends Preference {
+        SipProfile mProfile;
+        SipPreference(Context c, SipProfile p) {
+            super(c);
+            setProfile(p);
+        }
+
+        SipProfile getProfile() {
+            return mProfile;
+        }
+
+        void setProfile(SipProfile p) {
+            mProfile = p;
+            setTitle(getProfileName(p));
+            updateSummary(mSipSharedPreferences.isReceivingCallsEnabled()
+                    ? getString(R.string.registration_status_checking_status)
+                    : getString(R.string.registration_status_not_receiving));
+        }
+
+        void updateSummary(String registrationStatus) {
+            int profileUid = mProfile.getCallingUid();
+            boolean isPrimary = mProfile.getUriString().equals(
+                    mSipSharedPreferences.getPrimaryAccount());
+            Log.v(TAG, "profile uid is " + profileUid + " isPrimary:"
+                    + isPrimary + " registration:" + registrationStatus
+                    + " Primary:" + mSipSharedPreferences.getPrimaryAccount()
+                    + " status:" + registrationStatus);
+            String summary = "";
+            if ((profileUid > 0) && (profileUid != mUid)) {
+                // from third party apps
+                summary = getString(R.string.third_party_account_summary,
+                        getPackageNameFromUid(profileUid));
+            } else if (isPrimary) {
+                summary = getString(R.string.primary_account_summary_with,
+                        registrationStatus);
+            } else {
+                summary = registrationStatus;
+            }
+            setSummary(summary);
+        }
+    }
+
+    private String getPackageNameFromUid(int uid) {
+        try {
+            String[] pkgs = mPackageManager.getPackagesForUid(uid);
+            ApplicationInfo ai =
+                    mPackageManager.getApplicationInfo(pkgs[0], 0);
+            return ai.loadLabel(mPackageManager).toString();
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.e(TAG, "cannot find name of uid " + uid, e);
+        }
+        return "uid:" + uid;
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        mSipManager = SipManager.newInstance(this);
+        mSipSharedPreferences = new SipSharedPreferences(this);
+        mProfileDb = new SipProfileDb(this);
+
+        mPackageManager = getPackageManager();
+        setContentView(R.layout.sip_settings_ui);
+        addPreferencesFromResource(R.xml.sip_setting);
+        mSipListContainer = (PreferenceCategory) findPreference(PREF_SIP_LIST);
+        registerForReceiveCallsCheckBox();
+        mCallManager = CallManager.getInstance();
+
+        updateProfilesStatus();
+
+        ActionBar actionBar = getActionBar();
+        if (actionBar != null) {
+            // android.R.id.home will be triggered in onOptionsItemSelected()
+            actionBar.setDisplayHomeAsUpEnabled(true);
+        }
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+
+        if (mCallManager.getState() != PhoneConstants.State.IDLE) {
+            mButtonSipReceiveCalls.setEnabled(false);
+        } else {
+            mButtonSipReceiveCalls.setEnabled(true);
+        }
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        unregisterForContextMenu(getListView());
+    }
+
+    @Override
+    protected void onActivityResult(final int requestCode, final int resultCode,
+            final Intent intent) {
+        if (resultCode != RESULT_OK && resultCode != RESULT_FIRST_USER) return;
+        new Thread() {
+            @Override
+            public void run() {
+                try {
+                    if (mProfile != null) {
+                        Log.v(TAG, "Removed Profile:" + mProfile.getProfileName());
+                        deleteProfile(mProfile);
+                    }
+
+                    SipProfile profile = intent.getParcelableExtra(KEY_SIP_PROFILE);
+                    if (resultCode == RESULT_OK) {
+                        Log.v(TAG, "New Profile Name:" + profile.getProfileName());
+                        addProfile(profile);
+                    }
+                    updateProfilesStatus();
+                } catch (IOException e) {
+                    Log.v(TAG, "Can not handle the profile : " + e.getMessage());
+                }
+            }
+        }.start();
+    }
+
+    private void registerForReceiveCallsCheckBox() {
+        mButtonSipReceiveCalls = (CheckBoxPreference) findPreference
+                (BUTTON_SIP_RECEIVE_CALLS);
+        mButtonSipReceiveCalls.setChecked(
+                mSipSharedPreferences.isReceivingCallsEnabled());
+        mButtonSipReceiveCalls.setOnPreferenceClickListener(
+                new OnPreferenceClickListener() {
+                    public boolean onPreferenceClick(Preference preference) {
+                        final boolean enabled =
+                                ((CheckBoxPreference) preference).isChecked();
+                        new Thread(new Runnable() {
+                                public void run() {
+                                    handleSipReceiveCallsOption(enabled);
+                                }
+                        }).start();
+                        return true;
+                    }
+                });
+    }
+
+    private synchronized void handleSipReceiveCallsOption(boolean enabled) {
+        mSipSharedPreferences.setReceivingCallsEnabled(enabled);
+        List<SipProfile> sipProfileList = mProfileDb.retrieveSipProfileList();
+        for (SipProfile p : sipProfileList) {
+            String sipUri = p.getUriString();
+            p = updateAutoRegistrationFlag(p, enabled);
+            try {
+                if (enabled) {
+                    mSipManager.open(p,
+                            SipUtil.createIncomingCallPendingIntent(), null);
+                } else {
+                    mSipManager.close(sipUri);
+                    if (mSipSharedPreferences.isPrimaryAccount(sipUri)) {
+                        // re-open in order to make calls
+                        mSipManager.open(p);
+                    }
+                }
+            } catch (Exception e) {
+                Log.e(TAG, "register failed", e);
+            }
+        }
+        updateProfilesStatus();
+    }
+
+    private SipProfile updateAutoRegistrationFlag(
+            SipProfile p, boolean enabled) {
+        SipProfile newProfile = new SipProfile.Builder(p)
+                .setAutoRegistration(enabled)
+                .build();
+        try {
+            mProfileDb.deleteProfile(p);
+            mProfileDb.saveProfile(newProfile);
+        } catch (Exception e) {
+            Log.e(TAG, "updateAutoRegistrationFlag error", e);
+        }
+        return newProfile;
+    }
+
+    private void updateProfilesStatus() {
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    retrieveSipLists();
+                } catch (Exception e) {
+                    Log.e(TAG, "isRegistered", e);
+                }
+            }
+        }).start();
+    }
+
+    private String getProfileName(SipProfile profile) {
+        String profileName = profile.getProfileName();
+        if (TextUtils.isEmpty(profileName)) {
+            profileName = profile.getUserName() + "@" + profile.getSipDomain();
+        }
+        return profileName;
+    }
+
+    private void retrieveSipLists() {
+        mSipPreferenceMap = new LinkedHashMap<String, SipPreference>();
+        mSipProfileList = mProfileDb.retrieveSipProfileList();
+        processActiveProfilesFromSipService();
+        Collections.sort(mSipProfileList, new Comparator<SipProfile>() {
+            @Override
+            public int compare(SipProfile p1, SipProfile p2) {
+                return getProfileName(p1).compareTo(getProfileName(p2));
+            }
+
+            public boolean equals(SipProfile p) {
+                // not used
+                return false;
+            }
+        });
+        mSipListContainer.removeAll();
+        for (SipProfile p : mSipProfileList) {
+            addPreferenceFor(p);
+        }
+
+        if (!mSipSharedPreferences.isReceivingCallsEnabled()) return;
+        for (SipProfile p : mSipProfileList) {
+            if (mUid == p.getCallingUid()) {
+                try {
+                    mSipManager.setRegistrationListener(
+                            p.getUriString(), createRegistrationListener());
+                } catch (SipException e) {
+                    Log.e(TAG, "cannot set registration listener", e);
+                }
+            }
+        }
+    }
+
+    private void processActiveProfilesFromSipService() {
+        SipProfile[] activeList = mSipManager.getListOfProfiles();
+        for (SipProfile activeProfile : activeList) {
+            SipProfile profile = getProfileFromList(activeProfile);
+            if (profile == null) {
+                mSipProfileList.add(activeProfile);
+            } else {
+                profile.setCallingUid(activeProfile.getCallingUid());
+            }
+        }
+    }
+
+    private SipProfile getProfileFromList(SipProfile activeProfile) {
+        for (SipProfile p : mSipProfileList) {
+            if (p.getUriString().equals(activeProfile.getUriString())) {
+                return p;
+            }
+        }
+        return null;
+    }
+
+    private void addPreferenceFor(SipProfile p) {
+        String status;
+        Log.v(TAG, "addPreferenceFor profile uri" + p.getUri());
+        SipPreference pref = new SipPreference(this, p);
+        mSipPreferenceMap.put(p.getUriString(), pref);
+        mSipListContainer.addPreference(pref);
+
+        pref.setOnPreferenceClickListener(
+                new Preference.OnPreferenceClickListener() {
+                    @Override
+                    public boolean onPreferenceClick(Preference pref) {
+                        handleProfileClick(((SipPreference) pref).mProfile);
+                        return true;
+                    }
+                });
+    }
+
+    private void handleProfileClick(final SipProfile profile) {
+        int uid = profile.getCallingUid();
+        if (uid == mUid || uid == 0) {
+            startSipEditor(profile);
+            return;
+        }
+        new AlertDialog.Builder(this)
+                .setTitle(R.string.alert_dialog_close)
+                .setIconAttribute(android.R.attr.alertDialogIcon)
+                .setPositiveButton(R.string.close_profile,
+                        new DialogInterface.OnClickListener() {
+                            @Override
+                            public void onClick(DialogInterface dialog, int w) {
+                                deleteProfile(profile);
+                                unregisterProfile(profile);
+                            }
+                        })
+                .setNegativeButton(android.R.string.cancel, null)
+                .show();
+    }
+
+    private void unregisterProfile(final SipProfile p) {
+        // run it on background thread for better UI response
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    mSipManager.close(p.getUriString());
+                } catch (Exception e) {
+                    Log.e(TAG, "unregister failed, SipService died?", e);
+                }
+            }
+        }, "unregisterProfile").start();
+    }
+
+    void deleteProfile(SipProfile p) {
+        mSipProfileList.remove(p);
+        SipPreference pref = mSipPreferenceMap.remove(p.getUriString());
+        mSipListContainer.removePreference(pref);
+    }
+
+    private void addProfile(SipProfile p) throws IOException {
+        try {
+            mSipManager.setRegistrationListener(p.getUriString(),
+                    createRegistrationListener());
+        } catch (Exception e) {
+            Log.e(TAG, "cannot set registration listener", e);
+        }
+        mSipProfileList.add(p);
+        addPreferenceFor(p);
+    }
+
+    private void startSipEditor(final SipProfile profile) {
+        mProfile = profile;
+        Intent intent = new Intent(this, SipEditor.class);
+        intent.putExtra(KEY_SIP_PROFILE, (Parcelable) profile);
+        startActivityForResult(intent, REQUEST_ADD_OR_EDIT_SIP_PROFILE);
+    }
+
+    private void showRegistrationMessage(final String profileUri,
+            final String message) {
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                SipPreference pref = mSipPreferenceMap.get(profileUri);
+                if (pref != null) {
+                    pref.updateSummary(message);
+                }
+            }
+        });
+    }
+
+    private SipRegistrationListener createRegistrationListener() {
+        return new SipRegistrationListener() {
+            @Override
+            public void onRegistrationDone(String profileUri, long expiryTime) {
+                showRegistrationMessage(profileUri, getString(
+                        R.string.registration_status_done));
+            }
+
+            @Override
+            public void onRegistering(String profileUri) {
+                showRegistrationMessage(profileUri, getString(
+                        R.string.registration_status_registering));
+            }
+
+            @Override
+            public void onRegistrationFailed(String profileUri, int errorCode,
+                    String message) {
+                switch (errorCode) {
+                    case SipErrorCode.IN_PROGRESS:
+                        showRegistrationMessage(profileUri, getString(
+                                R.string.registration_status_still_trying));
+                        break;
+                    case SipErrorCode.INVALID_CREDENTIALS:
+                        showRegistrationMessage(profileUri, getString(
+                                R.string.registration_status_invalid_credentials));
+                        break;
+                    case SipErrorCode.SERVER_UNREACHABLE:
+                        showRegistrationMessage(profileUri, getString(
+                                R.string.registration_status_server_unreachable));
+                        break;
+                    case SipErrorCode.DATA_CONNECTION_LOST:
+                        if (SipManager.isSipWifiOnly(getApplicationContext())){
+                            showRegistrationMessage(profileUri, getString(
+                                    R.string.registration_status_no_wifi_data));
+                        } else {
+                            showRegistrationMessage(profileUri, getString(
+                                    R.string.registration_status_no_data));
+                        }
+                        break;
+                    case SipErrorCode.CLIENT_ERROR:
+                        showRegistrationMessage(profileUri, getString(
+                                R.string.registration_status_not_running));
+                        break;
+                    default:
+                        showRegistrationMessage(profileUri, getString(
+                                R.string.registration_status_failed_try_later,
+                                message));
+                }
+            }
+        };
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+        menu.add(0, MENU_ADD_ACCOUNT, 0, R.string.add_sip_account)
+                .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+        return true;
+    }
+
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        menu.findItem(MENU_ADD_ACCOUNT).setEnabled(
+                mCallManager.getState() == PhoneConstants.State.IDLE);
+        return super.onPrepareOptionsMenu(menu);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        final int itemId = item.getItemId();
+        switch (itemId) {
+            case android.R.id.home: {
+                CallFeaturesSetting.goUpToTopLevelSetting(this);
+                return true;
+            }
+            case MENU_ADD_ACCOUNT: {
+                startSipEditor(null);
+                return true;
+            }
+        }
+        return super.onOptionsItemSelected(item);
+    }
+}
diff --git a/src/com/android/phone/sip/SipSharedPreferences.java b/src/com/android/phone/sip/SipSharedPreferences.java
new file mode 100644
index 0000000..e15db64
--- /dev/null
+++ b/src/com/android/phone/sip/SipSharedPreferences.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2010 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.sip;
+
+import com.android.phone.R;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.provider.Settings;
+import android.provider.Settings.SettingNotFoundException;
+import android.text.TextUtils;
+import android.util.Log;
+
+/**
+ * Wrapper for SIP's shared preferences.
+ */
+public class SipSharedPreferences {
+    private static final String SIP_SHARED_PREFERENCES = "SIP_PREFERENCES";
+    private static final String KEY_PRIMARY_ACCOUNT = "primary";
+    private static final String KEY_NUMBER_OF_PROFILES = "profiles";
+
+    private SharedPreferences mPreferences;
+    private Context mContext;
+
+    public SipSharedPreferences(Context context) {
+        mPreferences = context.getSharedPreferences(
+                SIP_SHARED_PREFERENCES, Context.MODE_WORLD_READABLE);
+        mContext = context;
+    }
+
+    public void setPrimaryAccount(String accountUri) {
+        SharedPreferences.Editor editor = mPreferences.edit();
+        editor.putString(KEY_PRIMARY_ACCOUNT, accountUri);
+        editor.apply();
+    }
+
+    public void unsetPrimaryAccount() {
+        setPrimaryAccount(null);
+    }
+
+    /** Returns the primary account URI or null if it does not exist. */
+    public String getPrimaryAccount() {
+        return mPreferences.getString(KEY_PRIMARY_ACCOUNT, null);
+    }
+
+    public boolean isPrimaryAccount(String accountUri) {
+        return accountUri.equals(
+                mPreferences.getString(KEY_PRIMARY_ACCOUNT, null));
+    }
+
+    public boolean hasPrimaryAccount() {
+        return !TextUtils.isEmpty(
+                mPreferences.getString(KEY_PRIMARY_ACCOUNT, null));
+    }
+
+    public void setProfilesCount(int number) {
+        SharedPreferences.Editor editor = mPreferences.edit();
+        editor.putInt(KEY_NUMBER_OF_PROFILES, number);
+        editor.apply();
+    }
+
+    public int getProfilesCount() {
+        return mPreferences.getInt(KEY_NUMBER_OF_PROFILES, 0);
+    }
+
+    public void setSipCallOption(String option) {
+        Settings.System.putString(mContext.getContentResolver(),
+                Settings.System.SIP_CALL_OPTIONS, option);
+    }
+
+    public String getSipCallOption() {
+        String option = Settings.System.getString(mContext.getContentResolver(),
+                Settings.System.SIP_CALL_OPTIONS);
+        return (option != null) ? option
+                                : mContext.getString(R.string.sip_address_only);
+    }
+
+    public void setReceivingCallsEnabled(boolean enabled) {
+        Settings.System.putInt(mContext.getContentResolver(),
+                Settings.System.SIP_RECEIVE_CALLS, (enabled ? 1 : 0));
+    }
+
+    public boolean isReceivingCallsEnabled() {
+        try {
+            return (Settings.System.getInt(mContext.getContentResolver(),
+                    Settings.System.SIP_RECEIVE_CALLS) != 0);
+        } catch (SettingNotFoundException e) {
+            Log.d("SIP", "ReceiveCall option is not set; use default value");
+            return false;
+        }
+    }
+
+    // TODO: back up to Android Backup
+}
