diff --git a/src/com/android/phone/CallController.java b/src/com/android/phone/CallController.java
deleted file mode 100644
index a5d340c..0000000
--- a/src/com/android/phone/CallController.java
+++ /dev/null
@@ -1,671 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.phone;
-
-import com.android.internal.telephony.CallManager;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConstants;
-import com.android.phone.CallGatewayManager.RawGatewayInfo;
-import com.android.phone.Constants.CallStatusCode;
-
-import android.content.ComponentName;
-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.telecom.PhoneAccount;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.ServiceState;
-import android.util.Log;
-
-/**
- * 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;
-
-    final private PhoneGlobals mApp;
-    final private CallManager mCM;
-    final private CallLogger mCallLogger;
-    final private CallGatewayManager mCallGatewayManager;
-
-    /** 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,
-            CallGatewayManager callGatewayManager) {
-        synchronized (CallController.class) {
-            if (sInstance == null) {
-                sInstance = new CallController(app, callLogger, callGatewayManager);
-            } 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,
-            CallGatewayManager callGatewayManager) {
-        if (DBG) log("CallController constructor: app = " + app);
-        mApp = app;
-        mCM = app.mCM;
-        mCallLogger = callLogger;
-        mCallGatewayManager = callGatewayManager;
-    }
-
-    @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);
-
-                    // TODO: Remove this code.
-                    //mApp.getCallModeler().setCdmaOutgoing3WayCall(null);
-                }
-                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());
-
-        // 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);
-        }
-
-        CallStatusCode status = placeCallInternal(intent);
-
-        switch (status) {
-            // Call was placed successfully:
-            case SUCCESS:
-            case EXITED_ECM:
-                if (DBG) log("==> placeCall(): success from placeCallInternal(): " + status);
-                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.)
-    }
-
-    /**
-     * 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 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);
-            ComponentName thirdPartyCallComponent = (ComponentName) intent.getParcelableExtra(
-                    OutgoingCallBroadcaster.EXTRA_THIRD_PARTY_CALL_COMPONENT);
-            phone = PhoneUtils.pickPhoneBasedOnNumber(mCM, scheme, number, sipPhoneUri,
-                    thirdPartyCallComponent);
-            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(mApp, number);
-        boolean isPotentialEmergencyNumber =
-                PhoneNumberUtils.isPotentialLocalEmergencyNumber(mApp, number);
-        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: 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;
-            }
-        }
-
-        // 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();
-
-        // If a gateway is used, extract the data here and pass that into placeCall.
-        final RawGatewayInfo rawGatewayInfo = mCallGatewayManager.getRawGatewayInfo(intent, number);
-
-        // 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),
-                                              rawGatewayInfo,
-                                              mCallGatewayManager);
-
-        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.
-
-                boolean voicemailUriSpecified = scheme != null &&
-                    scheme.equals(PhoneAccount.SCHEME_VOICEMAIL);
-                // 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) {
-
-                        // 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.
-     *
-     * @param status one of the CallStatusCode error codes.
-     */
-    private void handleOutgoingCallError(CallStatusCode status) {
-        if (DBG) log("handleOutgoingCallError(): status = " + status);
-        final Intent intent = new Intent(mApp, ErrorDialogActivity.class);
-        int errorMessageId = -1;
-        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 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.
-                errorMessageId = R.string.incall_error_call_failed;
-                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.)
-                errorMessageId = R.string.incall_error_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.)
-                errorMessageId = R.string.incall_error_emergency_only;
-                break;
-            case OUT_OF_SERVICE:
-                // No network connection.
-                errorMessageId = R.string.incall_error_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.
-                errorMessageId = R.string.incall_error_no_phone_number_supplied;
-                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.
-                intent.putExtra(ErrorDialogActivity.SHOW_MISSING_VOICEMAIL_NO_DIALOG_EXTRA, true);
-                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...
-                final Intent mmiIntent = new Intent(mApp, MMIDialogActivity.class);
-                mmiIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
-                        Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
-                mApp.startActivity(mmiIntent);
-                return;
-            default:
-                Log.wtf(TAG, "handleOutgoingCallError: unexpected status code " + status);
-                // Show a generic "call failed" error.
-                errorMessageId = R.string.incall_error_call_failed;
-                break;
-        }
-        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
-        if (errorMessageId != -1) {
-            intent.putExtra(ErrorDialogActivity.ERROR_MESSAGE_ID_EXTRA, errorMessageId);
-        }
-        mApp.startActivity(intent);
-    }
-
-    //
-    // Debugging
-    //
-
-    private static void log(String msg) {
-        Log.d(TAG, msg);
-    }
-}
diff --git a/src/com/android/phone/EmergencyCallHelper.java b/src/com/android/phone/EmergencyCallHelper.java
deleted file mode 100644
index 74ce088..0000000
--- a/src/com/android/phone/EmergencyCallHelper.java
+++ /dev/null
@@ -1,513 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.phone;
-
-import com.android.internal.telephony.CallManager;
-import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConstants;
-
-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.DisconnectCause;
-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 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;
-
-        // 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();
-
-        // (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();
-
-            placeEmergencyCall();
-        } 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;
-        int cause = conn.getDisconnectCause();
-        if (DBG) log("onDisconnect: connection '" + conn
-                     + "', addr '" + conn.getAddress()
-                     + "', cause = " + DisconnectCause.toString(cause));
-
-        if (cause == 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 = mCM.getDefaultPhone().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();
-
-            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();
-        }
-    }
-
-    /**
-     * 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...");
-            mCM.getDefaultPhone().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,
-                                              mCM.getDefaultPhone(),
-                                              mNumber,
-                                              null,  // contactUri
-                                              true); // isEmergencyCall
-        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();
-        } else {
-            if (DBG) log("- Scheduling another retry...");
-            startRetryTimer();
-        }
-    }
-
-    /**
-     * 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()...");
-
-        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;
-        }
-    }
-
-    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.)
-        Phone phone = mCM.getDefaultPhone();
-        phone.unregisterForServiceStateChanged(this);  // Safe even if not currently registered
-        phone.registerForServiceStateChanged(this, SERVICE_STATE_CHANGED, null);
-    }
-
-    private void unregisterForServiceStateChanged() {
-        // This method is safe to call even if we haven't set mPhone yet.
-        Phone phone = mCM.getDefaultPhone();
-        if (phone != null) {
-            phone.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
index 765c52d..9d43d60 100644
--- a/src/com/android/phone/EmergencyCallbackModeExitDialog.java
+++ b/src/com/android/phone/EmergencyCallbackModeExitDialog.java
@@ -17,9 +17,9 @@
 package com.android.phone;
 
 import android.app.Activity;
+import android.app.AlertDialog;
 import android.app.Dialog;
 import android.app.ProgressDialog;
-import android.app.AlertDialog;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
@@ -28,7 +28,6 @@
 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;
@@ -36,12 +35,10 @@
 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
@@ -80,12 +77,12 @@
 
         mPhone = PhoneGlobals.getInstance().getPhoneInEcm();
         // Check if phone is in Emergency Callback Mode. If not, exit.
-        final boolean isInEcm = mPhone.isInEcm();
-        Log.i(TAG, "ECMModeExitDialog launched - isInEcm: " + isInEcm + " phone:" + mPhone);
-        if (mPhone == null || !isInEcm) {
+        if (mPhone == null || !mPhone.isInEcm()) {
+            Log.i(TAG, "ECMModeExitDialog launched - isInEcm: false" + " phone:" + mPhone);
             finish();
             return;
         }
+        Log.i(TAG, "ECMModeExitDialog launched - isInEcm: true" + " phone:" + mPhone);
 
         mHandler = new Handler();
 
diff --git a/src/com/android/phone/ErrorDialogActivity.java b/src/com/android/phone/ErrorDialogActivity.java
deleted file mode 100644
index bf09376..0000000
--- a/src/com/android/phone/ErrorDialogActivity.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * 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.app.Activity;
-import android.app.AlertDialog;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.os.Bundle;
-import android.util.Log;
-
-import com.android.phone.settings.VoicemailSettingsActivity;
-
-/**
- * Used to display an error dialog from within the Telephony service when an outgoing call fails
- */
-public class ErrorDialogActivity extends Activity {
-    private static final String TAG = ErrorDialogActivity.class.getSimpleName();
-
-    public static final String SHOW_MISSING_VOICEMAIL_NO_DIALOG_EXTRA = "show_missing_voicemail";
-    public static final String ERROR_MESSAGE_ID_EXTRA = "error_message_id";
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        final boolean showVoicemailDialog = getIntent().getBooleanExtra(
-                SHOW_MISSING_VOICEMAIL_NO_DIALOG_EXTRA, false);
-
-        if (showVoicemailDialog) {
-            showMissingVoicemailErrorDialog();
-        } else {
-            final int error = getIntent().getIntExtra(ERROR_MESSAGE_ID_EXTRA, -1);
-            if (error == -1) {
-                Log.e(TAG, "ErrorDialogActivity called with no error type extra.");
-                finish();
-            }
-            showGenericErrorDialog(error);
-        }
-    }
-
-    private void showGenericErrorDialog(int resid) {
-        final CharSequence msg = getResources().getText(resid);
-
-        final DialogInterface.OnClickListener clickListener;
-
-        final DialogInterface.OnCancelListener cancelListener;
-        clickListener = new DialogInterface.OnClickListener() {
-            @Override
-            public void onClick(DialogInterface dialog, int which) {
-                finish();
-            }
-        };
-        cancelListener = new DialogInterface.OnCancelListener() {
-            @Override
-            public void onCancel(DialogInterface dialog) {
-                finish();
-            }
-        };
-
-        final AlertDialog errorDialog = new AlertDialog.Builder(this)
-                .setMessage(msg).setPositiveButton(R.string.ok, clickListener)
-                        .setOnCancelListener(cancelListener).create();
-
-        errorDialog.show();
-    }
-
-    private void showMissingVoicemailErrorDialog() {
-        final AlertDialog missingVoicemailDialog = new AlertDialog.Builder(this)
-        .setTitle(R.string.no_vm_number)
-        .setMessage(R.string.no_vm_number_msg)
-        .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
-                @Override
-                public void onClick(DialogInterface dialog, int which) {
-                    dontAddVoiceMailNumber();
-                }})
-        .setNegativeButton(R.string.add_vm_number_str, new DialogInterface.OnClickListener() {
-                @Override
-                public void onClick(DialogInterface dialog, int which) {
-                    addVoiceMailNumberPanel(dialog);
-                }})
-        .setOnCancelListener(new DialogInterface.OnCancelListener() {
-                @Override
-                public void onCancel(DialogInterface dialog) {
-                    dontAddVoiceMailNumber();
-                }}).show();
-    }
-
-
-    private void addVoiceMailNumberPanel(DialogInterface dialog) {
-        if (dialog != null) {
-            dialog.dismiss();
-        }
-
-        // navigate to the Voicemail setting in the Call Settings activity.
-        Intent intent = new Intent(VoicemailSettingsActivity.ACTION_ADD_VOICEMAIL);
-        intent.setClass(this, VoicemailSettingsActivity.class);
-        startActivity(intent);
-        finish();
-    }
-
-    private void dontAddVoiceMailNumber() {
-        finish();
-    }
-}
diff --git a/src/com/android/phone/MMIDialogActivity.java b/src/com/android/phone/MMIDialogActivity.java
index 4afa6be..c9be2ac 100644
--- a/src/com/android/phone/MMIDialogActivity.java
+++ b/src/com/android/phone/MMIDialogActivity.java
@@ -25,7 +25,6 @@
 import android.os.Message;
 import android.telephony.SubscriptionManager;
 import android.util.Log;
-import android.widget.Toast;
 
 import com.android.internal.telephony.CallManager;
 import com.android.internal.telephony.MmiCode;
@@ -56,6 +55,11 @@
         int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
                 SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
         mPhone = PhoneGlobals.getPhone(subId);
+        if (mPhone == null) {
+            Log.w(TAG, "onCreate: invalid subscription id (" + subId + ") lead to null"
+                    + " Phone.");
+            finish();
+        }
         mHandler = new Handler() {
                 @Override
                 public void handleMessage(Message msg) {
diff --git a/src/com/android/phone/OutgoingCallBroadcaster.java b/src/com/android/phone/OutgoingCallBroadcaster.java
deleted file mode 100644
index 6bb1388..0000000
--- a/src/com/android/phone/OutgoingCallBroadcaster.java
+++ /dev/null
@@ -1,687 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.phone;
-
-import android.Manifest;
-import android.app.Activity;
-import android.app.ActivityManager;
-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.content.res.Resources;
-import android.net.Uri;
-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.telecom.PhoneAccount;
-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. ACTION_NEW_OUTGOING_CALL is an ordered broadcast intent which
- * contains the phone number being dialed. Applications can use this intent to (1) see which numbers
- * are being dialed, (2) redirect a call (change the number being dialed), or (3) prevent a call
- * from being placed.
- *
- * 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.
- *
- * Calls where no number is present (like for a CDMA "empty flash" or a nonexistent voicemail
- * number) are exempt from being broadcast.
- * Calls to emergency numbers are still broadcast for informative purposes. The call is placed
- * prior to sending ACTION_NEW_OUTGOING_CALL and cannot be redirected nor prevented.
- */
-public class OutgoingCallBroadcaster extends Activity
-        implements DialogInterface.OnClickListener, DialogInterface.OnCancelListener {
-
-    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";
-    public static final String EXTRA_THIRD_PARTY_CALL_COMPONENT =
-            "android.phone.extra.THIRD_PARTY_CALL_COMPONENT";
-
-    /**
-     * 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 EVENT_DELAYED_FINISH = 102;
-
-    private static final int OUTGOING_CALL_TIMEOUT_THRESHOLD = 2000; // msec
-    private static final int DELAYED_FINISH_TIME = 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 if (msg.what == EVENT_DELAYED_FINISH) {
-                finish();
-            } else {
-                Log.wtf(TAG, "Unknown message id: " + msg.what);
-            }
-        }
-    };
-
-    /**
-     * Starts the delayed finish() of OutgoingCallBroadcaster in order to give the UI
-     * some time to start up.
-     */
-    private void startDelayedFinish() {
-        mHandler.sendEmptyMessageDelayed(EVENT_DELAYED_FINISH, DELAYED_FINISH_TIME);
-    }
-
-    /**
-     * 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);
-            final boolean isAttemptingCall = doReceive(context, intent);
-            if (DBG) Log.v(TAG, "OutgoingCallReceiver is going to finish the Activity itself.");
-
-            // We cannot finish the activity immediately here because it would cause the temporary
-            // black screen of OutgoingBroadcaster to go away and we need it to stay up until the
-            // UI (in a different process) has time to come up.
-            // However, if we know we are not attemping a call, we need to finish the activity
-            // immediately so that subsequent CALL intents will retrigger a new
-            // OutgoingCallReceiver. see b/10857203
-            if (isAttemptingCall) {
-                startDelayedFinish();
-            } else {
-                finish();
-            }
-        }
-
-
-        /**
-         * Handes receipt of ordered new_outgoing_call intent. Verifies that the return from the
-         * ordered intent is valid.
-         * @return true if the call is being attempted; false if we are canceling the call.
-         */
-        public boolean 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 false;
-            }
-
-            // 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();
-            final Phone phone = PhoneGlobals.getPhone();
-
-            if (number == null) {
-                if (DBG) Log.v(TAG, "CALL cancelled (null number), returning...");
-                return false;
-            } else if (TelephonyCapabilities.supportsOtasp(phone)
-                    && (phone.getState() != PhoneConstants.State.IDLE)
-                    && (phone.isOtaSpNumber(number))) {
-                if (DBG) Log.v(TAG, "Call is active, a 2nd OTA call cancelled -- returning.");
-                return false;
-            } else if (PhoneNumberUtils.isPotentialLocalEmergencyNumber(context, number)) {
-                // 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 false;
-            }
-
-            originalUri = intent.getStringExtra(
-                    OutgoingCallBroadcaster.EXTRA_ORIGINAL_URI);
-            if (originalUri == null) {
-                Log.e(TAG, "Intent is missing EXTRA_ORIGINAL_URI -- returning.");
-                return false;
-            }
-
-            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);
-
-            return true;
-        }
-    }
-
-    /**
-     * 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) {
-        // TODO: Remove this code.
-    }
-
-    /**
-     * 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 = ActivityManager.getService().getLaunchedFromUid(
-                    getActivityToken());
-            launchedFromPackage = ActivityManager.getService().getLaunchedFromPackage(
-                    getActivityToken());
-        } catch (RemoteException e) {
-            launchedFromUid = -1;
-            launchedFromPackage = null;
-        }
-        if (appOps.noteOpNoThrow(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(this, number);
-        final boolean isPotentialEmergencyNumber =
-                (number != null) && PhoneNumberUtils.isPotentialLocalEmergencyNumber(this, number);
-        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)
-                final Resources resources = getResources();
-                invokeFrameworkDialer.setClassName(
-                        resources.getString(R.string.ui_default_package),
-                        resources.getString(R.string.dialer_default_class));
-                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.)
-        }
-
-        // 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 (PhoneAccount.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);
-        }
-        CallGatewayManager.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.SYSTEM,
-                android.Manifest.permission.PROCESS_OUTGOING_CALLS,
-                AppOpsManager.OP_PROCESS_OUTGOING_CALLS,
-                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...");
-
-        // 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/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index 98b94cc..2d0b99d 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -134,9 +134,6 @@
 
     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.
-    CallController callController;
     CallManager mCM;
     CallNotifier notifier;
     CallerInfoCache callerInfoCache;
@@ -326,11 +323,6 @@
 
             callGatewayManager = CallGatewayManager.getInstance();
 
-            // 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, callGatewayManager);
-
             // Create the CallerInfoCache singleton, which remembers custom ring tone and
             // send-to-voicemail settings.
             //
diff --git a/src/com/android/phone/PhoneUtils.java b/src/com/android/phone/PhoneUtils.java
index 50e7f0a..a153cf7 100644
--- a/src/com/android/phone/PhoneUtils.java
+++ b/src/com/android/phone/PhoneUtils.java
@@ -32,7 +32,6 @@
 import android.os.Message;
 import android.os.PersistableBundle;
 import android.os.RemoteException;
-import android.os.SystemProperties;
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.VideoProfile;
@@ -61,7 +60,6 @@
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.PhoneFactory;
 import com.android.internal.telephony.TelephonyCapabilities;
-import com.android.internal.telephony.TelephonyProperties;
 import com.android.internal.telephony.sip.SipPhone;
 import com.android.phone.CallGatewayManager.RawGatewayInfo;
 
@@ -1117,54 +1115,6 @@
     }
 
     /**
-     * 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.
diff --git a/src/com/android/phone/ProcessOutgoingCallTest.java b/src/com/android/phone/ProcessOutgoingCallTest.java
deleted file mode 100644
index c76fb43..0000000
--- a/src/com/android/phone/ProcessOutgoingCallTest.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.phone;
-
-import android.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);
-                }
-            }
-        }
-    }
-}
