diff --git a/src/com/android/phone/CallController.java b/src/com/android/phone/CallController.java
index 5b08662..a5d340c 100644
--- a/src/com/android/phone/CallController.java
+++ b/src/com/android/phone/CallController.java
@@ -19,7 +19,6 @@
 import com.android.internal.telephony.CallManager;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.TelephonyCapabilities;
 import com.android.phone.CallGatewayManager.RawGatewayInfo;
 import com.android.phone.Constants.CallStatusCode;
 
@@ -226,14 +225,6 @@
             throw new IllegalArgumentException("Unexpected action: " + action);
         }
 
-        // Check to see if this is an OTASP call (the "activation" call
-        // used to provision CDMA devices), and if so, do some
-        // OTASP-specific setup.
-        Phone phone = mApp.mCM.getDefaultPhone();
-        if (TelephonyCapabilities.supportsOtasp(phone)) {
-            checkForOtaspCall(intent);
-        }
-
         CallStatusCode status = placeCallInternal(intent);
 
         switch (status) {
@@ -670,28 +661,6 @@
         mApp.startActivity(intent);
     }
 
-    /**
-     * Checks the current outgoing call to see if it's an OTASP call (the
-     * "activation" call used to provision CDMA devices).  If so, do any
-     * necessary OTASP-specific setup before actually placing the call.
-     */
-    private void checkForOtaspCall(Intent intent) {
-        if (OtaUtils.isOtaspCallIntent(intent)) {
-            Log.i(TAG, "checkForOtaspCall: handling OTASP intent! " + intent);
-
-            // ("OTASP-specific setup" basically means creating and initializing
-            // the OtaUtils instance.  Note that this setup needs to be here in
-            // the CallController.placeCall() sequence, *not* in
-            // OtaUtils.startInteractiveOtasp(), since it's also possible to
-            // start an OTASP call by manually dialing "*228" (in which case
-            // OtaUtils.startInteractiveOtasp() never gets run at all.)
-            OtaUtils.setupOtaspCall(intent);
-        } else {
-            if (DBG) log("checkForOtaspCall: not an OTASP call.");
-        }
-    }
-
-
     //
     // Debugging
     //
diff --git a/src/com/android/phone/CallNotifier.java b/src/com/android/phone/CallNotifier.java
index 7836248..b3d8ade 100644
--- a/src/com/android/phone/CallNotifier.java
+++ b/src/com/android/phone/CallNotifier.java
@@ -16,12 +16,10 @@
 
 package com.android.phone;
 
-import com.android.internal.telephony.Call;
 import com.android.internal.telephony.CallManager;
-import com.android.internal.telephony.Connection;
+
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.TelephonyCapabilities;
 import com.android.internal.telephony.cdma.CdmaInformationRecords.CdmaDisplayInfoRec;
 import com.android.internal.telephony.cdma.CdmaInformationRecords.CdmaSignalInfoRec;
 import com.android.internal.telephony.cdma.SignalToneUtil;
@@ -30,17 +28,14 @@
 import android.bluetooth.BluetoothHeadset;
 import android.bluetooth.BluetoothProfile;
 import android.content.Context;
-import android.media.AudioAttributes;
 import android.media.AudioManager;
 import android.media.ToneGenerator;
 import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.Message;
 import android.os.SystemProperties;
-import android.provider.Settings;
 import android.telecom.TelecomManager;
-import android.telephony.DisconnectCause;
-import android.telephony.PhoneNumberUtils;
+
 import android.telephony.PhoneStateListener;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
@@ -103,8 +98,6 @@
     // We should store all the possible event type values in one place to make sure that
     // they don't step on each others' toes.
     public static final int INTERNAL_SHOW_MESSAGE_NOTIFICATION_DONE = 22;
-    // Other events from call manager
-    public static final int EVENT_OTA_PROVISION_CHANGE = 20;
 
     /**
      * Initialize the singleton CallNotifier instance.
@@ -177,7 +170,6 @@
      */
     private void registerForNotifications() {
         mCM.registerForDisconnect(this, PHONE_DISCONNECT, null);
-        mCM.registerForCdmaOtaStatusChange(this, EVENT_OTA_PROVISION_CHANGE, null);
         mCM.registerForDisplayInfo(this, PHONE_STATE_DISPLAYINFO, null);
         mCM.registerForSignalInfo(this, PHONE_STATE_SIGNALINFO, null);
         mCM.registerForInCallVoicePrivacyOn(this, PHONE_ENHANCED_VP_ON, null);
@@ -214,11 +206,6 @@
                 PhoneDisplayMessage.dismissMessage();
                 break;
 
-            case EVENT_OTA_PROVISION_CHANGE:
-                if (DBG) log("EVENT_OTA_PROVISION_CHANGE...");
-                mApplication.handleOtaspEvent(msg);
-                break;
-
             case PHONE_ENHANCED_VP_ON:
                 if (DBG) log("PHONE_ENHANCED_VP_ON...");
                 if (!mVoicePrivacyState) {
@@ -375,18 +362,6 @@
                     toneVolume = TONE_RELATIVE_VOLUME_HIPRI;
                     toneLengthMillis = 200;
                     break;
-                 case TONE_OTA_CALL_END:
-                    if (mApplication.cdmaOtaConfigData.otaPlaySuccessFailureTone ==
-                            OtaUtils.OTA_PLAY_SUCCESS_FAILURE_TONE_ON) {
-                        toneType = ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD;
-                        toneVolume = TONE_RELATIVE_VOLUME_HIPRI;
-                        toneLengthMillis = 750;
-                    } else {
-                        toneType = ToneGenerator.TONE_PROP_PROMPT;
-                        toneVolume = TONE_RELATIVE_VOLUME_HIPRI;
-                        toneLengthMillis = 200;
-                    }
-                    break;
                 case TONE_VOICE_PRIVACY:
                     toneType = ToneGenerator.TONE_CDMA_ALERT_NETWORK_LITE;
                     toneVolume = TONE_RELATIVE_VOLUME_HIPRI;
diff --git a/src/com/android/phone/InCallScreenShowActivation.java b/src/com/android/phone/InCallScreenShowActivation.java
deleted file mode 100644
index 78cc20b..0000000
--- a/src/com/android/phone/InCallScreenShowActivation.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.phone;
-
-import android.app.Activity;
-import android.app.PendingIntent;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.PersistableBundle;
-import android.os.SystemProperties;
-import android.telephony.CarrierConfigManager;
-import android.util.Log;
-
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.TelephonyCapabilities;
-
-/**
- * Invisible activity that handles the com.android.phone.PERFORM_CDMA_PROVISIONING intent.
- * This activity is protected by the android.permission.PERFORM_CDMA_PROVISIONING permission.
- *
- * We handle the PERFORM_CDMA_PROVISIONING action by launching an OTASP
- * call via one of the OtaUtils helper methods: startInteractiveOtasp() on
- * regular phones, or startNonInteractiveOtasp() on data-only devices.
- *
- * TODO: The class name InCallScreenShowActivation is misleading, since
- * this activity is totally unrelated to the InCallScreen (which
- * implements the in-call UI.)  Let's eventually rename this to something
- * like CdmaProvisioningLauncher or CdmaProvisioningHandler...
- */
-public class InCallScreenShowActivation extends Activity {
-    private static final String LOG_TAG = "InCallScreenShowActivation";
-    private static final boolean DBG =
-            (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
-
-    @Override
-    protected void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-
-        Intent intent = getIntent();
-        if (DBG) Log.d(LOG_TAG, "onCreate: intent = " + intent);
-        Bundle extras = intent.getExtras();
-        if (DBG && (extras != null)) {
-            Log.d(LOG_TAG, "      - has extras: size = " + extras.size()); // forces an unparcel()
-            Log.d(LOG_TAG, "      - extras = " + extras);
-        }
-
-        PhoneGlobals app = PhoneGlobals.getInstanceIfPrimary();
-        if (app == null) {
-            // TODO: All CDMA provisioning code should move into a BroadcastReceiver that runs
-            // exclusively in the primary user's context.  This is because the majority of the
-            // telephony logic -- and all of the important bits -- runs only as primary so we don't
-            // have access to the things we need. We still need to maintain an Activity to support
-            // legacy code which starts this using startActivity() but that Activity should be a
-            // simple intent-trampoline for the new BroadcastReceiver.
-            //
-            // Though this conditional protects this code from NPEs on a secondary user due to an
-            // uninitialized PhoneGlobals, there's not a good reason at the time of this writing as
-            // to why a secondary user context shouldn't trigger a CDMA provisioning, or at least
-            // nobody has expressed concern.
-            Log.i(LOG_TAG, "Being asked to provision CDMA SIM from secondary user, skipping.");
-            setResult(RESULT_CANCELED);
-            finish();
-            return;
-        }
-
-        Phone phone = app.getPhone();
-        if (!TelephonyCapabilities.supportsOtasp(phone)) {
-            Log.w(LOG_TAG, "CDMA Provisioning not supported on this device");
-            setResult(RESULT_CANCELED);
-            finish();
-            return;
-        }
-
-        if (intent.getAction().equals(OtaUtils.ACTION_PERFORM_CDMA_PROVISIONING)) {
-
-            PersistableBundle carrierConfig = app.getCarrierConfig();
-
-            boolean usesOtasp = carrierConfig.getBoolean(
-                    CarrierConfigManager.KEY_USE_OTASP_FOR_PROVISIONING_BOOL);
-            if (usesOtasp) {
-                // On voice-capable devices, we perform CDMA provisioning in
-                // "interactive" mode by directly launching the InCallScreen.
-                // boolean interactiveMode = PhoneGlobals.sVoiceCapable;
-                // TODO: Renable interactive mode for device provisioning.
-                boolean interactiveMode = false;
-                Log.i(LOG_TAG, "ACTION_PERFORM_CDMA_PROVISIONING (interactiveMode = "
-                      + interactiveMode + ")...");
-
-                // Testing: this intent extra allows test apps manually
-                // enable/disable "interactive mode", regardless of whether
-                // the current device is voice-capable.  This is allowed only
-                // in userdebug or eng builds.
-                if (intent.hasExtra(OtaUtils.EXTRA_OVERRIDE_INTERACTIVE_MODE)
-                        && (SystemProperties.getInt("ro.debuggable", 0) == 1)) {
-                    interactiveMode =
-                            intent.getBooleanExtra(OtaUtils.EXTRA_OVERRIDE_INTERACTIVE_MODE, false);
-                    Log.d(LOG_TAG, "==> MANUALLY OVERRIDING interactiveMode to " + interactiveMode);
-                }
-
-                // We allow the caller to pass a PendingIntent (as the
-                // EXTRA_NONINTERACTIVE_OTASP_RESULT_PENDING_INTENT extra)
-                // which we'll later use to notify them when the OTASP call
-                // fails or succeeds.
-                //
-                // Stash that away here, and we'll fire it off later in
-                // OtaUtils.sendOtaspResult().
-                app.cdmaOtaScreenState.otaspResultCodePendingIntent =
-                            (PendingIntent) intent.getParcelableExtra(
-                                    OtaUtils.EXTRA_OTASP_RESULT_CODE_PENDING_INTENT);
-
-                if (interactiveMode) {
-                    // On voice-capable devices, launch an OTASP call and arrange
-                    // for the in-call UI to come up.  (The InCallScreen will
-                    // notice that an OTASP call is active, and display the
-                    // special OTASP UI instead of the usual in-call controls.)
-
-                    if (DBG) Log.d(LOG_TAG, "==> Starting interactive CDMA provisioning...");
-                    OtaUtils.startInteractiveOtasp(this);
-
-                    // The result we set here is actually irrelevant, since the
-                    // InCallScreen's "interactive" OTASP sequence never actually
-                    // finish()es; it ends by directly launching the Home
-                    // activity.  So our caller won't actually ever get an
-                    // onActivityResult() call in this case.
-                    setResult(OtaUtils.RESULT_INTERACTIVE_OTASP_STARTED);
-                } else {
-                    // On data-only devices, manually launch the OTASP call
-                    // *without* displaying any UI.  (Our caller, presumably
-                    // SetupWizardActivity, is responsible for displaying some
-                    // sort of progress UI.)
-
-                    if (DBG) Log.d(LOG_TAG, "==> Starting non-interactive CDMA provisioning...");
-                    int callStatus = OtaUtils.startNonInteractiveOtasp(this);
-
-                    if (callStatus == PhoneUtils.CALL_STATUS_DIALED) {
-                        if (DBG) Log.d(LOG_TAG,
-                                "  ==> successful result from startNonInteractiveOtasp(): " +
-                                callStatus);
-                        setResult(OtaUtils.RESULT_NONINTERACTIVE_OTASP_STARTED);
-                    } else {
-                        Log.w(LOG_TAG, "Failure code from startNonInteractiveOtasp(): " +
-                                callStatus);
-                        setResult(OtaUtils.RESULT_NONINTERACTIVE_OTASP_FAILED);
-                    }
-                }
-            } else {
-                Log.i(LOG_TAG, "Skipping activation.");
-            }
-        } else {
-            Log.e(LOG_TAG, "Unexpected intent action: " + intent);
-            setResult(RESULT_CANCELED);
-        }
-
-        finish();
-    }
-}
diff --git a/src/com/android/phone/OtaStartupReceiver.java b/src/com/android/phone/OtaStartupReceiver.java
deleted file mode 100644
index 09cb185..0000000
--- a/src/com/android/phone/OtaStartupReceiver.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.phone;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.SystemProperties;
-import android.provider.Settings;
-import android.telephony.PhoneStateListener;
-import android.telephony.ServiceState;
-import android.telephony.TelephonyManager;
-
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.ServiceStateTracker;
-import com.android.internal.telephony.TelephonyCapabilities;
-
-import android.util.Log;
-
-/*
- * Handles OTA Start procedure at phone power up. At phone power up, if phone is not OTA
- * provisioned (check MIN value of the Phone) and 'device_provisioned' is not set,
- * OTA Activation screen is shown that helps user activate the phone
- */
-public class OtaStartupReceiver extends BroadcastReceiver {
-    private static final String TAG = "OtaStartupReceiver";
-    private static final boolean DBG = false;
-    private static final int MIN_READY = 10;
-    private static final int SERVICE_STATE_CHANGED = 11;
-    private Context mContext;
-
-    private int mOtaspMode = -1;
-    private boolean mPhoneStateListenerRegistered = false;
-    private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
-        @Override
-        public void onOtaspChanged(int otaspMode) {
-            if (mOtaspMode == otaspMode) {
-                return;
-            }
-            mOtaspMode = otaspMode;
-            Log.v(TAG, "onOtaspChanged: mOtaspMode=" + mOtaspMode);
-
-            if (otaspMode == ServiceStateTracker.OTASP_NEEDED) {
-                Log.i(TAG, "OTASP is needed - performing CDMA provisioning");
-                final Intent intent = new Intent(OtaUtils.ACTION_PERFORM_CDMA_PROVISIONING);
-                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                mContext.startActivity(intent);
-            }
-        }
-    };
-
-
-    private Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MIN_READY:
-                    Log.v(TAG, "Attempting OtaActivation from handler, mOtaspMode=" + mOtaspMode);
-                    OtaUtils.maybeDoOtaCall(mContext, mHandler, MIN_READY);
-                    break;
-                case SERVICE_STATE_CHANGED: {
-                    ServiceState state = (ServiceState) ((AsyncResult) msg.obj).result;
-                    if (DBG) Log.d(TAG, "onServiceStateChanged()...  new state = " + state);
-
-                    // Possible service states:
-                    // - STATE_IN_SERVICE        // Normal operation
-                    // - STATE_OUT_OF_SERVICE    // Still searching for an operator to register to,
-                    //                           // or no radio signal
-                    // - STATE_EMERGENCY_ONLY    // Phone is locked; only emergency numbers are allowed
-                    // - STATE_POWER_OFF         // Radio is explicitly powered off (airplane mode)
-
-                    // Once we reach STATE_IN_SERVICE
-                    // it's finally OK to start OTA provisioning
-                    if (state.getState() == ServiceState.STATE_IN_SERVICE) {
-                        if (DBG) Log.d(TAG, "call OtaUtils.maybeDoOtaCall after network is available");
-                        Phone phone = PhoneGlobals.getPhone();
-                        phone.unregisterForServiceStateChanged(this);
-                        OtaUtils.maybeDoOtaCall(mContext, mHandler, MIN_READY);
-                    }
-                    break;
-                }
-            }
-
-        }
-    };
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        mContext = context;
-        if (DBG) {
-            Log.v(TAG, "onReceive: intent action=" + intent.getAction() +
-                    "  mOtaspMode=" + mOtaspMode);
-        }
-
-        PhoneGlobals globals = PhoneGlobals.getInstanceIfPrimary();
-        if (globals == null) {
-            if (DBG) Log.d(TAG, "Not primary user, nothing to do.");
-            return;
-        }
-
-        if (mPhoneStateListenerRegistered == false) {
-            if (DBG) Log.d(TAG, "Register our PhoneStateListener");
-            TelephonyManager telephonyManager = (TelephonyManager)context.getSystemService(
-                    Context.TELEPHONY_SERVICE);
-            telephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_OTASP_CHANGED);
-            mPhoneStateListenerRegistered = true;
-        } else {
-            if (DBG) Log.d(TAG, "PhoneStateListener already registered");
-        }
-
-        if (!TelephonyCapabilities.supportsOtasp(PhoneGlobals.getPhone())) {
-            if (DBG) Log.d(TAG, "OTASP not supported, nothing to do.");
-            return;
-        }
-
-        if (shouldPostpone(context)) {
-            if (DBG) Log.d(TAG, "Postponing OTASP until wizard runs");
-            return;
-        }
-
-        // Delay OTA provisioning if network is not available yet
-        PhoneGlobals app = PhoneGlobals.getInstance();
-        Phone phone = PhoneGlobals.getPhone();
-        if (app.mCM.getServiceState() != ServiceState.STATE_IN_SERVICE) {
-            if (DBG) Log.w(TAG, "Network is not ready. Registering to receive notification.");
-            phone.registerForServiceStateChanged(mHandler, SERVICE_STATE_CHANGED, null);
-            return;
-        }
-
-        // The following depends on the phone process being persistent. Normally we can't
-        // expect a BroadcastReceiver to persist after returning from this function but it does
-        // because the phone activity is persistent.
-        if (DBG) Log.d(TAG, "call OtaUtils.maybeDoOtaCall");
-        OtaUtils.maybeDoOtaCall(mContext, mHandler, MIN_READY);
-    }
-
-    /**
-     * On devices that provide a phone initialization wizard (such as Google Setup Wizard), we
-     * allow delaying CDMA OTA setup so it can be done in a single wizard. The wizard is responsible
-     * for (1) disabling itself once it has been run and/or (2) setting the 'device_provisioned'
-     * flag to something non-zero and (3) calling the OTA Setup with the action below.
-     *
-     * NB: Typical phone initialization wizards will install themselves as the homescreen
-     * (category "android.intent.category.HOME") with a priority higher than the default.
-     * The wizard should set 'device_provisioned' when it completes, disable itself with the
-     * PackageManager.setComponentEnabledSetting() and then start home screen.
-     *
-     * @return true if setup will be handled by wizard, false if it should be done now.
-     */
-    private boolean shouldPostpone(Context context) {
-        Intent intent = new Intent("android.intent.action.DEVICE_INITIALIZATION_WIZARD");
-        ResolveInfo resolveInfo = context.getPackageManager().resolveActivity(intent,
-                PackageManager.MATCH_DEFAULT_ONLY);
-        boolean provisioned = Settings.Global.getInt(context.getContentResolver(),
-                Settings.Global.DEVICE_PROVISIONED, 0) != 0;
-        String mode = SystemProperties.get("ro.setupwizard.mode", "REQUIRED");
-        boolean runningSetupWizard = "REQUIRED".equals(mode) || "OPTIONAL".equals(mode);
-        if (DBG) {
-            Log.v(TAG, "resolvInfo = " + resolveInfo + ", provisioned = " + provisioned
-                    + ", runningSetupWizard = " + runningSetupWizard);
-        }
-        return resolveInfo != null && !provisioned && runningSetupWizard;
-    }
-}
diff --git a/src/com/android/phone/OtaUtils.java b/src/com/android/phone/OtaUtils.java
deleted file mode 100644
index b1b0049..0000000
--- a/src/com/android/phone/OtaUtils.java
+++ /dev/null
@@ -1,1585 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.phone;
-
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.TelephonyCapabilities;
-import com.android.internal.telephony.TelephonyProperties;
-import com.android.phone.OtaUtils.CdmaOtaInCallScreenUiState.State;
-
-import android.app.Activity;
-import android.app.ActivityManager;
-import android.app.AlertDialog;
-import android.app.PendingIntent;
-import android.app.PendingIntent.CanceledException;
-import android.content.ActivityNotFoundException;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.os.UserHandle;
-import android.telecom.PhoneAccount;
-import android.telephony.TelephonyManager;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.widget.Button;
-import android.widget.ProgressBar;
-import android.widget.TextView;
-import android.widget.ToggleButton;
-
-/**
- * Handles all OTASP Call related logic and UI functionality.
- * The InCallScreen interacts with this class to perform an OTASP Call.
- *
- * OTASP is a CDMA-specific feature:
- *   OTA or OTASP == Over The Air service provisioning
- *   SPC == Service Programming Code
- *   TODO: Include pointer to more detailed documentation.
- *
- * TODO: This is Over The Air Service Provisioning (OTASP)
- *       A better name would be OtaspUtils.java.
- */
-public class OtaUtils {
-    private static final String LOG_TAG = "OtaUtils";
-    private static final boolean DBG = false;
-
-    public static final int OTA_SHOW_ACTIVATION_SCREEN_OFF = 0;
-    public static final int OTA_SHOW_ACTIVATION_SCREEN_ON = 1;
-    public static final int OTA_SHOW_LISTENING_SCREEN_OFF =0;
-    public static final int OTA_SHOW_LISTENING_SCREEN_ON =1;
-    public static final int OTA_SHOW_ACTIVATE_FAIL_COUNT_OFF = 0;
-    public static final int OTA_SHOW_ACTIVATE_FAIL_COUNT_THREE = 3;
-    public static final int OTA_PLAY_SUCCESS_FAILURE_TONE_OFF = 0;
-    public static final int OTA_PLAY_SUCCESS_FAILURE_TONE_ON = 1;
-
-    // SPC Timeout is 60 seconds
-    public final int OTA_SPC_TIMEOUT = 60;
-    public final int OTA_FAILURE_DIALOG_TIMEOUT = 2;
-
-    // Constants for OTASP-related Intents and intent extras.
-    // Watch out: these must agree with the corresponding constants in
-    // apps/SetupWizard!
-
-    // Intent action to launch an OTASP call.
-    public static final String ACTION_PERFORM_CDMA_PROVISIONING =
-           "com.android.phone.PERFORM_CDMA_PROVISIONING";
-
-    // Intent action to launch activation on a non-voice capable device
-    /**
-     * @deprecated platform no longer supports voiceless cdma provisioning,
-     * only hands free activation.
-     */
-    public static final String ACTION_PERFORM_VOICELESS_CDMA_PROVISIONING =
-            "com.android.phone.PERFORM_VOICELESS_CDMA_PROVISIONING";
-
-    // Intent action to display the InCallScreen in the OTASP "activation" state.
-    public static final String ACTION_DISPLAY_ACTIVATION_SCREEN =
-            "com.android.phone.DISPLAY_ACTIVATION_SCREEN";
-
-    // boolean voiceless provisioning extra that enables a "don't show this again" checkbox
-    // the user can check to never see the activity upon bootup again
-    public static final String EXTRA_VOICELESS_PROVISIONING_OFFER_DONTSHOW =
-            "com.android.phone.VOICELESS_PROVISIONING_OFFER_DONTSHOW";
-
-    // Activity result codes for the ACTION_PERFORM_CDMA_PROVISIONING intent
-    // (see the InCallScreenShowActivation activity.)
-    //
-    // Note: currently, our caller won't ever actually receive the
-    // RESULT_INTERACTIVE_OTASP_STARTED result code; see comments in
-    // InCallScreenShowActivation.onCreate() for details.
-
-    public static final int RESULT_INTERACTIVE_OTASP_STARTED = Activity.RESULT_FIRST_USER;
-    public static final int RESULT_NONINTERACTIVE_OTASP_STARTED = Activity.RESULT_FIRST_USER + 1;
-    public static final int RESULT_NONINTERACTIVE_OTASP_FAILED = Activity.RESULT_FIRST_USER + 2;
-
-    // Testing: Extra for the ACTION_PERFORM_CDMA_PROVISIONING intent that
-    // allows the caller to manually enable/disable "interactive mode" for
-    // the OTASP call.   Only available in userdebug or eng builds.
-    public static final String EXTRA_OVERRIDE_INTERACTIVE_MODE =
-            "ota_override_interactive_mode";
-
-    // Extra for the ACTION_PERFORM_CDMA_PROVISIONING intent, holding a
-    // PendingIntent which the phone app can use to send a result code
-    // back to the caller.
-    public static final String EXTRA_OTASP_RESULT_CODE_PENDING_INTENT =
-            "otasp_result_code_pending_intent";
-
-    // Extra attached to the above PendingIntent that indicates
-    // success or failure.
-    public static final String EXTRA_OTASP_RESULT_CODE = "otasp_result_code";
-
-    // Extra attached to the above PendingIntent that contains an error code.
-    public static final String EXTRA_OTASP_ERROR_CODE = "otasp_error_code";
-
-    public static final int OTASP_UNKNOWN = 0;
-    public static final int OTASP_USER_SKIPPED = 1;  // Only meaningful with interactive OTASP
-    public static final int OTASP_SUCCESS = 2;
-    public static final int OTASP_FAILURE = 3;
-    // failed due to CDMA_OTA_PROVISION_STATUS_SPC_RETRIES_EXCEEDED
-    public static final int OTASP_FAILURE_SPC_RETRIES = 4;
-    // TODO: Distinguish between interactive and non-interactive success
-    // and failure.  Then, have the PendingIntent be sent after
-    // interactive OTASP as well (so the caller can find out definitively
-    // when interactive OTASP completes.)
-
-    private static final String OTASP_NUMBER = "*228";
-    private static final String OTASP_NUMBER_NON_INTERACTIVE = "*22899";
-
-    private Context mContext;
-    private PhoneGlobals mApplication;
-    private OtaWidgetData mOtaWidgetData;
-
-    private static boolean sIsWizardMode = true;
-
-    // How many times do we retry maybeDoOtaCall() if the LTE state is not known yet,
-    // and how long do we wait between retries
-    private static final int OTA_CALL_LTE_RETRIES_MAX = 5;
-    private static final int OTA_CALL_LTE_RETRY_PERIOD = 3000;
-    private static int sOtaCallLteRetries = 0;
-
-    // In "interactive mode", the OtaUtils object is tied to an
-    // InCallScreen instance, where we display a bunch of UI specific to
-    // the OTASP call.  But on devices that are not "voice capable", the
-    // OTASP call runs in a non-interactive mode, and we don't have
-    // an InCallScreen or CallCard or any OTASP UI elements at all.
-    private boolean mInteractive = true;
-
-    /**
-     * OtaWidgetData class represent all OTA UI elements
-     *
-     * TODO(OTASP): It's really ugly for the OtaUtils object to reach into the
-     *     InCallScreen like this and directly manipulate its widgets.
-     *
-     *     Instead, the model/view separation should be more clear: OtaUtils
-     *     should only know about a higher-level abstraction of the
-     *     OTASP-specific UI state (just like how the CallController uses the
-     *     InCallUiState object), and the InCallScreen itself should translate
-     *     that higher-level abstraction into actual onscreen views and widgets.
-     */
-    private class OtaWidgetData {
-        public Button otaEndButton;
-        public Button otaActivateButton;
-        public Button otaSkipButton;
-        public Button otaNextButton;
-        public ToggleButton otaSpeakerButton;
-        public ViewGroup otaUpperWidgets;
-        public View callCardOtaButtonsFailSuccess;
-        public ProgressBar otaTextProgressBar;
-        public TextView otaTextSuccessFail;
-        public View callCardOtaButtonsActivate;
-        public View callCardOtaButtonsListenProgress;
-        public TextView otaTextActivate;
-        public TextView otaTextListenProgress;
-        public AlertDialog spcErrorDialog;
-        public AlertDialog otaFailureDialog;
-        public AlertDialog otaSkipConfirmationDialog;
-        public TextView otaTitle;
-        public Button otaTryAgainButton;
-    }
-
-    /**
-     * OtaUtils constructor.
-     *
-     * @param context the Context of the calling Activity or Application
-     * @param interactive if true, use the InCallScreen to display the progress
-     *                    and result of the OTASP call.  In practice this is
-     *                    true IFF the current device is a voice-capable phone.
-     *
-     * Note if interactive is true, you must also call updateUiWidgets() as soon
-     * as the InCallScreen instance is ready.
-     */
-    public OtaUtils(Context context, boolean interactive) {
-        if (DBG) log("OtaUtils constructor...");
-        mApplication = PhoneGlobals.getInstance();
-        mContext = context;
-        mInteractive = interactive;
-    }
-
-    /**
-     * Starts the OTA provisioning call.  If the MIN isn't available yet, it returns false and adds
-     * an event to return the request to the calling app when it becomes available.
-     *
-     * @param context
-     * @param handler
-     * @param request
-     * @return true if we were able to launch Ota activity or it's not required; false otherwise
-     */
-    public static boolean maybeDoOtaCall(Context context, Handler handler, int request) {
-        PhoneGlobals app = PhoneGlobals.getInstance();
-        Phone phone = PhoneGlobals.getPhone();
-
-        if (ActivityManager.isRunningInTestHarness()) {
-            Log.i(LOG_TAG, "Don't run provisioning when in test harness");
-            return true;
-        }
-
-        if (!TelephonyCapabilities.supportsOtasp(phone)) {
-            // Presumably not a CDMA phone.
-            if (DBG) log("maybeDoOtaCall: OTASP not supported on this device");
-            return true;  // Nothing to do here.
-        }
-
-        if (!phone.isMinInfoReady()) {
-            if (DBG) log("MIN is not ready. Registering to receive notification.");
-            phone.registerForSubscriptionInfoReady(handler, request, null);
-            return false;
-        }
-        phone.unregisterForSubscriptionInfoReady(handler);
-
-        if (getLteOnCdmaMode(context) == PhoneConstants.LTE_ON_CDMA_UNKNOWN) {
-            if (sOtaCallLteRetries < OTA_CALL_LTE_RETRIES_MAX) {
-                if (DBG) log("maybeDoOtaCall: LTE state still unknown: retrying");
-                handler.sendEmptyMessageDelayed(request, OTA_CALL_LTE_RETRY_PERIOD);
-                sOtaCallLteRetries++;
-                return false;
-            } else {
-                Log.w(LOG_TAG, "maybeDoOtaCall: LTE state still unknown: giving up");
-                return true;
-            }
-        }
-
-        boolean phoneNeedsActivation = phone.needsOtaServiceProvisioning();
-        if (DBG) log("phoneNeedsActivation is set to " + phoneNeedsActivation);
-
-        int otaShowActivationScreen = context.getResources().getInteger(
-                R.integer.OtaShowActivationScreen);
-        if (DBG) log("otaShowActivationScreen: " + otaShowActivationScreen);
-
-        // Run the OTASP call in "interactive" mode only if
-        // this is a non-LTE "voice capable" device.
-        if (PhoneGlobals.sVoiceCapable && getLteOnCdmaMode(context) == PhoneConstants.LTE_ON_CDMA_FALSE) {
-            if (phoneNeedsActivation
-                    && (otaShowActivationScreen == OTA_SHOW_ACTIVATION_SCREEN_ON)) {
-                app.cdmaOtaProvisionData.isOtaCallIntentProcessed = false;
-                sIsWizardMode = false;
-
-                if (DBG) Log.d(LOG_TAG, "==> Starting interactive CDMA provisioning...");
-                OtaUtils.startInteractiveOtasp(context);
-
-                if (DBG) log("maybeDoOtaCall: voice capable; activation started.");
-            } else {
-                if (DBG) log("maybeDoOtaCall: voice capable; activation NOT started.");
-            }
-        } else {
-            if (phoneNeedsActivation) {
-                app.cdmaOtaProvisionData.isOtaCallIntentProcessed = false;
-                Intent newIntent = new Intent(ACTION_PERFORM_VOICELESS_CDMA_PROVISIONING);
-                newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                newIntent.putExtra(EXTRA_VOICELESS_PROVISIONING_OFFER_DONTSHOW, true);
-                try {
-                    context.startActivity(newIntent);
-                } catch (ActivityNotFoundException e) {
-                    loge("No activity Handling PERFORM_VOICELESS_CDMA_PROVISIONING!");
-                    return false;
-                }
-                if (DBG) log("maybeDoOtaCall: non-interactive; activation intent sent.");
-            } else {
-                if (DBG) log("maybeDoOtaCall: non-interactive, no need for OTASP.");
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Starts a normal "interactive" OTASP call (i.e. CDMA activation
-     * for regular voice-capable phone devices.)
-     *
-     * This method is called from the InCallScreenShowActivation activity when
-     * handling the ACTION_PERFORM_CDMA_PROVISIONING intent.
-     */
-    public static void startInteractiveOtasp(Context context) {
-        if (DBG) log("startInteractiveOtasp()...");
-        PhoneGlobals app = PhoneGlobals.getInstance();
-
-        // There are two ways to start OTASP on voice-capable devices:
-        //
-        // (1) via the PERFORM_CDMA_PROVISIONING intent
-        //     - this is triggered by the "Activate device" button in settings,
-        //       or can be launched automatically upon boot if the device
-        //       thinks it needs to be provisioned.
-        //     - the intent is handled by InCallScreenShowActivation.onCreate(),
-        //       which calls this method
-        //     - we prepare for OTASP by initializing the OtaUtils object
-        //     - we bring up the InCallScreen in the ready-to-activate state
-        //     - when the user presses the "Activate" button we launch the
-        //       call by calling CallController.placeCall() via the
-        //       otaPerformActivation() method.
-        //
-        // (2) by manually making an outgoing call to a special OTASP number
-        //     like "*228" or "*22899".
-        //     - That sequence does NOT involve this method (OtaUtils.startInteractiveOtasp()).
-        //       Instead, the outgoing call request goes straight to CallController.placeCall().
-        //     - CallController.placeCall() notices that it's an OTASP
-        //       call, and initializes the OtaUtils object.
-        //     - The InCallScreen is launched (as the last step of
-        //       CallController.placeCall()).  The InCallScreen notices that
-        //       OTASP is active and shows the correct UI.
-
-        // Here, we start sequence (1):
-        // Do NOT immediately start the call.  Instead, bring up the InCallScreen
-        // in the special "activate" state (see OtaUtils.otaShowActivateScreen()).
-        // We won't actually make the call until the user presses the "Activate"
-        // button.
-
-        Intent activationScreenIntent = new Intent().setClass(context, InCallScreen.class)
-                .setAction(ACTION_DISPLAY_ACTIVATION_SCREEN);
-
-        // Watch out: in the scenario where OTASP gets triggered from the
-        // BOOT_COMPLETED broadcast (see OtaStartupReceiver.java), we might be
-        // running in the PhoneApp's context right now.
-        // So the FLAG_ACTIVITY_NEW_TASK flag is required here.
-        activationScreenIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
-        // We're about to start the OTASP sequence, so create and initialize the
-        // OtaUtils instance.  (This needs to happen before bringing up the
-        // InCallScreen.)
-        OtaUtils.setupOtaspCall(activationScreenIntent);
-
-        // And bring up the InCallScreen...
-        Log.i(LOG_TAG, "startInteractiveOtasp: launching InCallScreen in 'activate' state: "
-              + activationScreenIntent);
-        context.startActivity(activationScreenIntent);
-    }
-
-    /**
-     * Starts the OTASP call *without* involving the InCallScreen or
-     * displaying any UI.
-     *
-     * This is used on data-only devices, which don't support any kind of
-     * in-call phone UI.
-     *
-     * @return PhoneUtils.CALL_STATUS_DIALED if we successfully
-     *         dialed the OTASP number, or one of the other
-     *         CALL_STATUS_* constants if there was a failure.
-     */
-    public static int startNonInteractiveOtasp(Context context) {
-        if (DBG) log("startNonInteractiveOtasp()...");
-        PhoneGlobals app = PhoneGlobals.getInstance();
-
-        if (app.otaUtils != null) {
-            // An OtaUtils instance already exists, presumably from a previous OTASP call.
-            Log.i(LOG_TAG, "startNonInteractiveOtasp: "
-                  + "OtaUtils already exists; nuking the old one and starting again...");
-        }
-
-        // Create the OtaUtils instance.
-        app.otaUtils = new OtaUtils(context, false /* non-interactive mode */);
-        if (DBG) log("- created OtaUtils: " + app.otaUtils);
-
-        // ... and kick off the OTASP call.
-        // TODO(InCallScreen redesign): This should probably go through
-        // the CallController, rather than directly calling
-        // PhoneUtils.placeCall().
-        Phone phone = PhoneGlobals.getPhone();
-        String number = OTASP_NUMBER_NON_INTERACTIVE;
-        Log.i(LOG_TAG, "startNonInteractiveOtasp: placing call to '" + number + "'...");
-        int callStatus = PhoneUtils.placeCall(context,
-                                              phone,
-                                              number,
-                                              null,   // contactRef
-                                              false); //isEmergencyCall
-
-        if (callStatus == PhoneUtils.CALL_STATUS_DIALED) {
-            if (DBG) log("  ==> successful return from placeCall(): callStatus = " + callStatus);
-        } else {
-            Log.w(LOG_TAG, "Failure from placeCall() for OTA number '"
-                  + number + "': code " + callStatus);
-            return callStatus;
-        }
-
-        // TODO: Any other special work to do here?
-        // Such as:
-        //
-        // - manually kick off progress updates, either using TelephonyRegistry
-        //   or else by sending PendingIntents directly to our caller?
-        //
-        // - manually silence the in-call audio?  (Probably unnecessary
-        //   if Stingray truly has no audio path from phone baseband
-        //   to the device's speakers.)
-        //
-
-        return callStatus;
-    }
-
-    /**
-     * @return true if the specified Intent is a CALL action that's an attempt
-     * to initate an OTASP call.
-     *
-     * OTASP is a CDMA-specific concept, so this method will always return false
-     * on GSM phones.
-     *
-     * This code was originally part of the InCallScreen.checkIsOtaCall() method.
-     */
-    public static boolean isOtaspCallIntent(Intent intent) {
-        if (DBG) log("isOtaspCallIntent(" + intent + ")...");
-        PhoneGlobals app = PhoneGlobals.getInstance();
-        Phone phone = app.mCM.getDefaultPhone();
-
-        if (intent == null) {
-            return false;
-        }
-        if (!TelephonyCapabilities.supportsOtasp(phone)) {
-            return false;
-        }
-
-        String action = intent.getAction();
-        if (action == null) {
-            return false;
-        }
-        if (!action.equals(Intent.ACTION_CALL)) {
-            if (DBG) log("isOtaspCallIntent: not a CALL action: '" + action + "' ==> not OTASP");
-            return false;
-        }
-
-        if ((app.cdmaOtaScreenState == null) || (app.cdmaOtaProvisionData == null)) {
-            // Uh oh -- something wrong with our internal OTASP state.
-            // (Since this is an OTASP-capable device, these objects
-            // *should* have already been created by PhoneApp.onCreate().)
-            throw new IllegalStateException("isOtaspCallIntent: "
-                                            + "app.cdmaOta* objects(s) not initialized");
-        }
-
-        // This is an OTASP call iff the number we're trying to dial is one of
-        // the magic OTASP numbers.
-        String number;
-        try {
-            number = PhoneUtils.getInitialNumber(intent);
-        } catch (PhoneUtils.VoiceMailNumberMissingException ex) {
-            // This was presumably a "voicemail:" intent, so it's
-            // obviously not an OTASP number.
-            if (DBG) log("isOtaspCallIntent: VoiceMailNumberMissingException => not OTASP");
-            return false;
-        }
-        if (phone.isOtaSpNumber(number)) {
-            if (DBG) log("isOtaSpNumber: ACTION_CALL to '" + number + "' ==> OTASP call!");
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Set up for an OTASP call.
-     *
-     * This method is called as part of the CallController placeCall() sequence
-     * before initiating an outgoing OTASP call.
-     *
-     * The purpose of this method is mainly to create and initialize the
-     * OtaUtils instance, along with some other misc pre-OTASP cleanup.
-     */
-    public static void setupOtaspCall(Intent intent) {
-        if (DBG) log("setupOtaspCall(): preparing for OTASP call to " + intent);
-        PhoneGlobals app = PhoneGlobals.getInstance();
-
-        if (app.otaUtils != null) {
-            // An OtaUtils instance already exists, presumably from a prior OTASP call.
-            // Nuke the old one and start this call with a fresh instance.
-            Log.i(LOG_TAG, "setupOtaspCall: "
-                  + "OtaUtils already exists; replacing with new instance...");
-        }
-
-        // Create the OtaUtils instance.
-        app.otaUtils = new OtaUtils(app.getApplicationContext(), true /* interactive */);
-        if (DBG) log("- created OtaUtils: " + app.otaUtils);
-
-        // NOTE we still need to call OtaUtils.updateUiWidgets() once the
-        // InCallScreen instance is ready; see InCallScreen.checkOtaspStateOnResume()
-
-        // Make sure the InCallScreen knows that it needs to switch into OTASP mode.
-        //
-        // NOTE in gingerbread and earlier, we used to do
-        //     setInCallScreenMode(InCallScreenMode.OTA_NORMAL);
-        // directly in the InCallScreen, back when this check happened inside the InCallScreen.
-        //
-        // But now, set the global CdmaOtaInCallScreenUiState object into
-        // NORMAL mode, which will then cause the InCallScreen (when it
-        // comes up) to realize that an OTA call is active.
-
-        app.otaUtils.setCdmaOtaInCallScreenUiState(
-            OtaUtils.CdmaOtaInCallScreenUiState.State.NORMAL);
-
-        // TODO(OTASP): note app.inCallUiState.inCallScreenMode and
-        // app.cdmaOtaInCallScreenUiState.state are mostly redundant.  Combine them.
-        // app.inCallUiState.inCallScreenMode = InCallUiState.InCallScreenMode.OTA_NORMAL;
-
-        // TODO(OTASP / bug 5092031): we ideally should call
-        // otaShowListeningScreen() here to make sure that the DTMF dialpad
-        // becomes visible at the start of the "*228" call:
-        //
-        //  // ...and get the OTASP-specific UI into the right state.
-        //  app.otaUtils.otaShowListeningScreen();
-        //  if (app.otaUtils.mInCallScreen != null) {
-        //      app.otaUtils.mInCallScreen.requestUpdateScreen();
-        //  }
-        //
-        // But this doesn't actually work; the call to otaShowListeningScreen()
-        // *doesn't* actually bring up the listening screen, since the
-        // cdmaOtaConfigData.otaShowListeningScreen config parameter hasn't been
-        // initialized (we haven't run readXmlSettings() yet at this point!)
-
-        // Also, since the OTA call is now just starting, clear out
-        // the "committed" flag in app.cdmaOtaProvisionData.
-        if (app.cdmaOtaProvisionData != null) {
-            app.cdmaOtaProvisionData.isOtaCallCommitted = false;
-        }
-    }
-
-    private void setSpeaker(boolean state) {
-        if (DBG) log("setSpeaker : " + state );
-
-        if (!mInteractive) {
-            if (DBG) log("non-interactive mode, ignoring setSpeaker.");
-            return;
-        }
-
-        if (state == PhoneUtils.isSpeakerOn(mContext)) {
-            if (DBG) log("no change. returning");
-            return;
-        }
-
-        PhoneUtils.turnOnSpeaker(mContext, state, true);
-    }
-
-    /**
-     * Handles OTA Provision events from the telephony layer.
-     * These events come in to this method whether or not
-     * the InCallScreen is visible.
-     *
-     * Possible events are:
-     * OTA Commit Event - OTA provisioning was successful
-     * SPC retries exceeded - SPC failure retries has exceeded, and Phone needs to
-     *    power down.
-     */
-    public void onOtaProvisionStatusChanged(AsyncResult r) {
-        int OtaStatus[] = (int[]) r.result;
-        if (DBG) log("Provision status event!");
-        if (DBG) log("onOtaProvisionStatusChanged(): status = "
-                     + OtaStatus[0] + " ==> " + otaProvisionStatusToString(OtaStatus[0]));
-
-        // In practice, in a normal successful OTASP call, events come in as follows:
-        //   - SPL_UNLOCKED within a couple of seconds after the call starts
-        //   - then a delay of around 45 seconds
-        //   - then PRL_DOWNLOADED and MDN_DOWNLOADED and COMMITTED within a span of 2 seconds
-
-        switch(OtaStatus[0]) {
-            case Phone.CDMA_OTA_PROVISION_STATUS_SPC_RETRIES_EXCEEDED:
-                if (DBG) log("onOtaProvisionStatusChanged(): RETRIES EXCEEDED");
-                updateOtaspProgress();
-                mApplication.cdmaOtaProvisionData.otaSpcUptime = SystemClock.elapsedRealtime();
-                if (mInteractive) {
-                    otaShowSpcErrorNotice(OTA_SPC_TIMEOUT);
-                } else {
-                    sendOtaspResult(OTASP_FAILURE_SPC_RETRIES);
-                }
-                // Power.shutdown();
-                break;
-
-            case Phone.CDMA_OTA_PROVISION_STATUS_COMMITTED:
-                if (DBG) {
-                    log("onOtaProvisionStatusChanged(): DONE, isOtaCallCommitted set to true");
-                }
-                mApplication.cdmaOtaProvisionData.isOtaCallCommitted = true;
-                if (mApplication.cdmaOtaScreenState.otaScreenState !=
-                    CdmaOtaScreenState.OtaScreenState.OTA_STATUS_UNDEFINED) {
-                    updateOtaspProgress();
-                }
-
-                break;
-
-            case Phone.CDMA_OTA_PROVISION_STATUS_SPL_UNLOCKED:
-            case Phone.CDMA_OTA_PROVISION_STATUS_A_KEY_EXCHANGED:
-            case Phone.CDMA_OTA_PROVISION_STATUS_SSD_UPDATED:
-            case Phone.CDMA_OTA_PROVISION_STATUS_NAM_DOWNLOADED:
-            case Phone.CDMA_OTA_PROVISION_STATUS_MDN_DOWNLOADED:
-            case Phone.CDMA_OTA_PROVISION_STATUS_IMSI_DOWNLOADED:
-            case Phone.CDMA_OTA_PROVISION_STATUS_PRL_DOWNLOADED:
-            case Phone.CDMA_OTA_PROVISION_STATUS_OTAPA_STARTED:
-            case Phone.CDMA_OTA_PROVISION_STATUS_OTAPA_STOPPED:
-            case Phone.CDMA_OTA_PROVISION_STATUS_OTAPA_ABORTED:
-                // Only update progress when OTA call is in normal state
-                if (getCdmaOtaInCallScreenUiState() == CdmaOtaInCallScreenUiState.State.NORMAL) {
-                    if (DBG) log("onOtaProvisionStatusChanged(): change to ProgressScreen");
-                    updateOtaspProgress();
-                }
-                break;
-
-            default:
-                if (DBG) log("onOtaProvisionStatusChanged(): Ignoring OtaStatus " + OtaStatus[0]);
-                break;
-        }
-    }
-
-    /**
-     * Handle a disconnect event from the OTASP call.
-     */
-    public void onOtaspDisconnect() {
-        if (DBG) log("onOtaspDisconnect()...");
-        // We only handle this event explicitly in non-interactive mode.
-        // (In interactive mode, the InCallScreen does any post-disconnect
-        // cleanup.)
-        if (!mInteractive) {
-            // Send a success or failure indication back to our caller.
-            updateNonInteractiveOtaSuccessFailure();
-        }
-        cleanOtaScreen(true);
-    }
-
-    private void otaShowHome() {
-        if (DBG) log("otaShowHome()...");
-        mApplication.cdmaOtaScreenState.otaScreenState =
-                CdmaOtaScreenState.OtaScreenState.OTA_STATUS_UNDEFINED;
-        // mInCallScreen.endInCallScreenSession();
-        Intent intent = new Intent(Intent.ACTION_MAIN);
-        intent.addCategory (Intent.CATEGORY_HOME);
-        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        mContext.startActivityAsUser(intent, UserHandle.CURRENT);
-        return;
-    }
-
-    private void otaSkipActivation() {
-        if (DBG) log("otaSkipActivation()...");
-
-        sendOtaspResult(OTASP_USER_SKIPPED);
-
-        // if (mInteractive) mInCallScreen.finish();
-        return;
-    }
-
-    /**
-     * Actually initiate the OTASP call.  This method is triggered by the
-     * onscreen "Activate" button, and is only used in interactive mode.
-     */
-    private void otaPerformActivation() {
-        if (DBG) log("otaPerformActivation()...");
-        if (!mInteractive) {
-            // We shouldn't ever get here in non-interactive mode!
-            Log.w(LOG_TAG, "otaPerformActivation: not interactive!");
-            return;
-        }
-
-        if (!mApplication.cdmaOtaProvisionData.inOtaSpcState) {
-            // Place an outgoing call to the special OTASP number:
-            Intent newIntent = new Intent(Intent.ACTION_CALL);
-            newIntent.setData(Uri.fromParts(PhoneAccount.SCHEME_TEL, OTASP_NUMBER, null));
-
-            // Initiate the outgoing call:
-            mApplication.callController.placeCall(newIntent);
-
-            // ...and get the OTASP-specific UI into the right state.
-            otaShowListeningScreen();
-            // mInCallScreen.requestUpdateScreen();
-        }
-        return;
-    }
-
-    /**
-     * Show Activation Screen when phone powers up and OTA provision is
-     * required. Also shown when activation fails and user needs
-     * to re-attempt it. Contains ACTIVATE and SKIP buttons
-     * which allow user to start OTA activation or skip the activation process.
-     */
-    public void otaShowActivateScreen() {
-        if (DBG) log("otaShowActivateScreen()...");
-        if (mApplication.cdmaOtaConfigData.otaShowActivationScreen
-                == OTA_SHOW_ACTIVATION_SCREEN_ON) {
-            if (DBG) log("otaShowActivateScreen(): show activation screen");
-            if (!isDialerOpened()) {
-                otaScreenInitialize();
-                mOtaWidgetData.otaSkipButton.setVisibility(sIsWizardMode ?
-                        View.VISIBLE : View.INVISIBLE);
-                mOtaWidgetData.otaTextActivate.setVisibility(View.VISIBLE);
-                mOtaWidgetData.callCardOtaButtonsActivate.setVisibility(View.VISIBLE);
-            }
-            mApplication.cdmaOtaScreenState.otaScreenState =
-                    CdmaOtaScreenState.OtaScreenState.OTA_STATUS_ACTIVATION;
-        } else {
-            if (DBG) log("otaShowActivateScreen(): show home screen");
-            otaShowHome();
-        }
-     }
-
-    /**
-     * Show "Listen for Instruction" screen during OTA call. Shown when OTA Call
-     * is initiated and user needs to listen for network instructions and press
-     * appropriate DTMF digits to proceed to the "Programming in Progress" phase.
-     */
-    private void otaShowListeningScreen() {
-        if (DBG) log("otaShowListeningScreen()...");
-        if (!mInteractive) {
-            // We shouldn't ever get here in non-interactive mode!
-            Log.w(LOG_TAG, "otaShowListeningScreen: not interactive!");
-            return;
-        }
-
-        if (mApplication.cdmaOtaConfigData.otaShowListeningScreen
-                == OTA_SHOW_LISTENING_SCREEN_ON) {
-            if (DBG) log("otaShowListeningScreen(): show listening screen");
-            if (!isDialerOpened()) {
-                otaScreenInitialize();
-                mOtaWidgetData.otaTextListenProgress.setVisibility(View.VISIBLE);
-                mOtaWidgetData.otaTextListenProgress.setText(R.string.ota_listen);
-                // mOtaWidgetData.otaDtmfDialerView.setVisibility(View.VISIBLE);
-                mOtaWidgetData.callCardOtaButtonsListenProgress.setVisibility(View.VISIBLE);
-                mOtaWidgetData.otaSpeakerButton.setVisibility(View.VISIBLE);
-                boolean speakerOn = PhoneUtils.isSpeakerOn(mContext);
-                mOtaWidgetData.otaSpeakerButton.setChecked(speakerOn);
-            }
-            mApplication.cdmaOtaScreenState.otaScreenState =
-                    CdmaOtaScreenState.OtaScreenState.OTA_STATUS_LISTENING;
-        } else {
-            if (DBG) log("otaShowListeningScreen(): show progress screen");
-            otaShowInProgressScreen();
-        }
-    }
-
-    /**
-     * Do any necessary updates (of onscreen UI, for example)
-     * based on the latest status of the OTASP call.
-     */
-    private void updateOtaspProgress() {
-        if (DBG) log("updateOtaspProgress()...  mInteractive = " + mInteractive);
-        if (mInteractive) {
-            // On regular phones we just call through to
-            // otaShowInProgressScreen(), which updates the
-            // InCallScreen's onscreen UI.
-            otaShowInProgressScreen();
-        } else {
-            // We're not using the InCallScreen to show OTA progress.
-
-            // For now, at least, there's nothing to do here.
-            // The overall "success" or "failure" indication we send back
-            // (to our caller) is triggered by the DISCONNECT event;
-            // see updateNonInteractiveOtaSuccessFailure().
-
-            // But if we ever need to send *intermediate* progress updates back
-            // to our caller, we'd do that here, possbily using the same
-            // PendingIntent that we already use to indicate success or failure.
-        }
-    }
-
-    /**
-     * When a non-interactive OTASP call completes, send a success or
-     * failure indication back to our caller.
-     *
-     * This is basically the non-interactive equivalent of
-     * otaShowSuccessFailure().
-     */
-    private void updateNonInteractiveOtaSuccessFailure() {
-        // This is basically the same logic as otaShowSuccessFailure(): we
-        // check the isOtaCallCommitted bit, and if that's true it means
-        // that activation was successful.
-
-        if (DBG) log("updateNonInteractiveOtaSuccessFailure(): isOtaCallCommitted = "
-                     + mApplication.cdmaOtaProvisionData.isOtaCallCommitted);
-        int resultCode =
-                mApplication.cdmaOtaProvisionData.isOtaCallCommitted
-                ? OTASP_SUCCESS : OTASP_FAILURE;
-        sendOtaspResult(resultCode);
-    }
-
-    /**
-     * Sends the specified OTASP result code back to our caller (presumably
-     * SetupWizard) via the PendingIntent that they originally sent along with
-     * the ACTION_PERFORM_CDMA_PROVISIONING intent.
-     */
-    private void sendOtaspResult(int resultCode) {
-        if (DBG) log("sendOtaspResult: resultCode = " + resultCode);
-
-        // Pass the success or failure indication back to our caller by
-        // adding an additional extra to the PendingIntent we already
-        // have.
-        // (NB: there's a PendingIntent send() method that takes a resultCode
-        // directly, but we can't use that here since that call is only
-        // meaningful for pending intents that are actually used as activity
-        // results.)
-
-        Intent extraStuff = new Intent();
-        extraStuff.putExtra(EXTRA_OTASP_RESULT_CODE, resultCode);
-        // When we call PendingIntent.send() below, the extras from this
-        // intent will get merged with any extras already present in
-        // cdmaOtaScreenState.otaspResultCodePendingIntent.
-
-        if (mApplication.cdmaOtaScreenState == null) {
-            Log.e(LOG_TAG, "updateNonInteractiveOtaSuccessFailure: no cdmaOtaScreenState object!");
-            return;
-        }
-        if (mApplication.cdmaOtaScreenState.otaspResultCodePendingIntent == null) {
-            Log.w(LOG_TAG, "updateNonInteractiveOtaSuccessFailure: "
-                  + "null otaspResultCodePendingIntent!");
-            return;
-        }
-
-        try {
-            if (DBG) log("- sendOtaspResult:  SENDING PENDING INTENT: " +
-                         mApplication.cdmaOtaScreenState.otaspResultCodePendingIntent);
-            mApplication.cdmaOtaScreenState.otaspResultCodePendingIntent.send(
-                    mContext,
-                    0, /* resultCode (unused) */
-                    extraStuff);
-        } catch (CanceledException e) {
-            // should never happen because no code cancels the pending intent right now,
-            Log.e(LOG_TAG, "PendingIntent send() failed: " + e);
-        }
-    }
-
-    /**
-     * Show "Programming In Progress" screen during OTA call. Shown when OTA
-     * provisioning is in progress after user has selected an option.
-     */
-    private void otaShowInProgressScreen() {
-        if (DBG) log("otaShowInProgressScreen()...");
-        if (!mInteractive) {
-            // We shouldn't ever get here in non-interactive mode!
-            Log.w(LOG_TAG, "otaShowInProgressScreen: not interactive!");
-            return;
-        }
-
-        mApplication.cdmaOtaScreenState.otaScreenState =
-            CdmaOtaScreenState.OtaScreenState.OTA_STATUS_PROGRESS;
-
-        if ((mOtaWidgetData == null) /* || (mInCallScreen == null) */) {
-            Log.w(LOG_TAG, "otaShowInProgressScreen: UI widgets not set up yet!");
-
-            // TODO(OTASP): our CdmaOtaScreenState is now correct; we just set
-            // it to OTA_STATUS_PROGRESS.  But we still need to make sure that
-            // when the InCallScreen eventually comes to the foreground, it
-            // notices that state and does all the same UI updating we do below.
-            return;
-        }
-
-        if (!isDialerOpened()) {
-            otaScreenInitialize();
-            mOtaWidgetData.otaTextListenProgress.setVisibility(View.VISIBLE);
-            mOtaWidgetData.otaTextListenProgress.setText(R.string.ota_progress);
-            mOtaWidgetData.otaTextProgressBar.setVisibility(View.VISIBLE);
-            mOtaWidgetData.callCardOtaButtonsListenProgress.setVisibility(View.VISIBLE);
-            mOtaWidgetData.otaSpeakerButton.setVisibility(View.VISIBLE);
-            boolean speakerOn = PhoneUtils.isSpeakerOn(mContext);
-            mOtaWidgetData.otaSpeakerButton.setChecked(speakerOn);
-        }
-    }
-
-    /**
-     * Show programming failure dialog when OTA provisioning fails.
-     * If OTA provisioning attempts fail more than 3 times, then unsuccessful
-     * dialog is shown. Otherwise a two-second notice is shown with unsuccessful
-     * information. When notice expires, phone returns to activation screen.
-     */
-    private void otaShowProgramFailure(int length) {
-        if (DBG) log("otaShowProgramFailure()...");
-        mApplication.cdmaOtaProvisionData.activationCount++;
-        if ((mApplication.cdmaOtaProvisionData.activationCount <
-                mApplication.cdmaOtaConfigData.otaShowActivateFailTimes)
-                && (mApplication.cdmaOtaConfigData.otaShowActivationScreen ==
-                OTA_SHOW_ACTIVATION_SCREEN_ON)) {
-            if (DBG) log("otaShowProgramFailure(): activationCount"
-                    + mApplication.cdmaOtaProvisionData.activationCount);
-            if (DBG) log("otaShowProgramFailure(): show failure notice");
-            otaShowProgramFailureNotice(length);
-        } else {
-            if (DBG) log("otaShowProgramFailure(): show failure dialog");
-            otaShowProgramFailureDialog();
-        }
-    }
-
-    /**
-     * Show either programming success dialog when OTA provisioning succeeds, or
-     * programming failure dialog when it fails. See {@link #otaShowProgramFailure}
-     * for more details.
-     */
-    public void otaShowSuccessFailure() {
-        if (DBG) log("otaShowSuccessFailure()...");
-        if (!mInteractive) {
-            // We shouldn't ever get here in non-interactive mode!
-            Log.w(LOG_TAG, "otaShowSuccessFailure: not interactive!");
-            return;
-        }
-
-        otaScreenInitialize();
-        if (DBG) log("otaShowSuccessFailure(): isOtaCallCommitted"
-                + mApplication.cdmaOtaProvisionData.isOtaCallCommitted);
-        if (mApplication.cdmaOtaProvisionData.isOtaCallCommitted) {
-            if (DBG) log("otaShowSuccessFailure(), show success dialog");
-            otaShowProgramSuccessDialog();
-        } else {
-            if (DBG) log("otaShowSuccessFailure(), show failure dialog");
-            otaShowProgramFailure(OTA_FAILURE_DIALOG_TIMEOUT);
-        }
-        return;
-    }
-
-    /**
-     * Show programming failure dialog when OTA provisioning fails more than 3
-     * times.
-     */
-    private void otaShowProgramFailureDialog() {
-        if (DBG) log("otaShowProgramFailureDialog()...");
-        mApplication.cdmaOtaScreenState.otaScreenState =
-                CdmaOtaScreenState.OtaScreenState.OTA_STATUS_SUCCESS_FAILURE_DLG;
-        mOtaWidgetData.otaTitle.setText(R.string.ota_title_problem_with_activation);
-        mOtaWidgetData.otaTextSuccessFail.setVisibility(View.VISIBLE);
-        mOtaWidgetData.otaTextSuccessFail.setText(R.string.ota_unsuccessful);
-        mOtaWidgetData.callCardOtaButtonsFailSuccess.setVisibility(View.VISIBLE);
-        mOtaWidgetData.otaTryAgainButton.setVisibility(View.VISIBLE);
-        //close the dialer if open
-        // if (isDialerOpened()) {
-        //     mOtaCallCardDtmfDialer.closeDialer(false);
-        // }
-    }
-
-    /**
-     * Show programming success dialog when OTA provisioning succeeds.
-     */
-    private void otaShowProgramSuccessDialog() {
-        if (DBG) log("otaShowProgramSuccessDialog()...");
-        mApplication.cdmaOtaScreenState.otaScreenState =
-                CdmaOtaScreenState.OtaScreenState.OTA_STATUS_SUCCESS_FAILURE_DLG;
-        mOtaWidgetData.otaTitle.setText(R.string.ota_title_activate_success);
-        mOtaWidgetData.otaTextSuccessFail.setVisibility(View.VISIBLE);
-        mOtaWidgetData.otaTextSuccessFail.setText(R.string.ota_successful);
-        mOtaWidgetData.callCardOtaButtonsFailSuccess.setVisibility(View.VISIBLE);
-        mOtaWidgetData.otaNextButton.setVisibility(View.VISIBLE);
-        //close the dialer if open
-        // if (isDialerOpened()) {
-        //     mOtaCallCardDtmfDialer.closeDialer(false);
-        // }
-    }
-
-    /**
-     * Show SPC failure notice when SPC attempts exceed 15 times.
-     * During OTA provisioning, if SPC code is incorrect OTA provisioning will
-     * fail. When SPC attempts are over 15, it shows SPC failure notice for one minute and
-     * then phone will power down.
-     */
-    private void otaShowSpcErrorNotice(int length) {
-        if (DBG) log("otaShowSpcErrorNotice()...");
-        if (mOtaWidgetData.spcErrorDialog == null) {
-            mApplication.cdmaOtaProvisionData.inOtaSpcState = true;
-            DialogInterface.OnKeyListener keyListener;
-            keyListener = new DialogInterface.OnKeyListener() {
-                public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
-                    log("Ignoring key events...");
-                    return true;
-                }};
-            mOtaWidgetData.spcErrorDialog = new AlertDialog.Builder(null /* mInCallScreen */)
-                    .setMessage(R.string.ota_spc_failure)
-                    .setOnKeyListener(keyListener)
-                    .create();
-            mOtaWidgetData.spcErrorDialog.getWindow().addFlags(
-                    WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
-                    | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
-            mOtaWidgetData.spcErrorDialog.show();
-            //close the dialer if open
-            // if (isDialerOpened()) {
-            //     mOtaCallCardDtmfDialer.closeDialer(false);
-            // }
-            long noticeTime = length*1000;
-            if (DBG) log("otaShowSpcErrorNotice(), remaining SPC noticeTime" + noticeTime);
-            // mInCallScreen.requestCloseSpcErrorNotice(noticeTime);
-        }
-    }
-
-    /**
-     * When SPC notice times out, force phone to power down.
-     */
-    public void onOtaCloseSpcNotice() {
-        if (DBG) log("onOtaCloseSpcNotice(), send shutdown intent");
-        Intent shutdown = new Intent(Intent.ACTION_REQUEST_SHUTDOWN);
-        shutdown.putExtra(Intent.EXTRA_KEY_CONFIRM, false);
-        shutdown.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        mContext.startActivity(shutdown);
-    }
-
-    /**
-     * Show two-second notice when OTA provisioning fails and number of failed attempts
-     * is less then 3.
-     */
-    private void otaShowProgramFailureNotice(int length) {
-        if (DBG) log("otaShowProgramFailureNotice()...");
-        if (mOtaWidgetData.otaFailureDialog == null) {
-            mOtaWidgetData.otaFailureDialog = new AlertDialog.Builder(null /* mInCallScreen */)
-                    .setMessage(R.string.ota_failure)
-                    .create();
-            mOtaWidgetData.otaFailureDialog.getWindow().addFlags(
-                    WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
-                    | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
-            mOtaWidgetData.otaFailureDialog.show();
-
-            long noticeTime = length*1000;
-            // mInCallScreen.requestCloseOtaFailureNotice(noticeTime);
-        }
-    }
-
-    /**
-     * Handle OTA unsuccessful notice expiry. Dismisses the
-     * two-second notice and shows the activation screen.
-     */
-    public void onOtaCloseFailureNotice() {
-        if (DBG) log("onOtaCloseFailureNotice()...");
-        if (mOtaWidgetData.otaFailureDialog != null) {
-            mOtaWidgetData.otaFailureDialog.dismiss();
-            mOtaWidgetData.otaFailureDialog = null;
-        }
-        otaShowActivateScreen();
-    }
-
-    /**
-     * Initialize all OTA UI elements to be gone. Also set inCallPanel,
-     * callCard and the dialpad handle to be gone. This is called before any OTA screen
-     * gets drawn.
-     */
-    private void otaScreenInitialize() {
-        if (DBG) log("otaScreenInitialize()...");
-
-        if (!mInteractive) {
-            // We should never be doing anything with UI elements in
-            // non-interactive mode.
-            Log.w(LOG_TAG, "otaScreenInitialize: not interactive!");
-            return;
-        }
-
-        // if (mInCallTouchUi != null) mInCallTouchUi.setVisibility(View.GONE);
-        // if (mCallCard != null) {
-        //     mCallCard.setVisibility(View.GONE);
-        //     // TODO: try removing this.
-        //     mCallCard.hideCallCardElements();
-        // }
-
-        mOtaWidgetData.otaTitle.setText(R.string.ota_title_activate);
-        mOtaWidgetData.otaTextActivate.setVisibility(View.GONE);
-        mOtaWidgetData.otaTextListenProgress.setVisibility(View.GONE);
-        mOtaWidgetData.otaTextProgressBar.setVisibility(View.GONE);
-        mOtaWidgetData.otaTextSuccessFail.setVisibility(View.GONE);
-        mOtaWidgetData.callCardOtaButtonsActivate.setVisibility(View.GONE);
-        mOtaWidgetData.callCardOtaButtonsListenProgress.setVisibility(View.GONE);
-        mOtaWidgetData.callCardOtaButtonsFailSuccess.setVisibility(View.GONE);
-        // mOtaWidgetData.otaDtmfDialerView.setVisibility(View.GONE);
-        mOtaWidgetData.otaSpeakerButton.setVisibility(View.GONE);
-        mOtaWidgetData.otaTryAgainButton.setVisibility(View.GONE);
-        mOtaWidgetData.otaNextButton.setVisibility(View.GONE);
-        mOtaWidgetData.otaUpperWidgets.setVisibility(View.VISIBLE);
-        mOtaWidgetData.otaSkipButton.setVisibility(View.VISIBLE);
-    }
-
-    public void hideOtaScreen() {
-        if (DBG) log("hideOtaScreen()...");
-
-        mOtaWidgetData.callCardOtaButtonsActivate.setVisibility(View.GONE);
-        mOtaWidgetData.callCardOtaButtonsListenProgress.setVisibility(View.GONE);
-        mOtaWidgetData.callCardOtaButtonsFailSuccess.setVisibility(View.GONE);
-        mOtaWidgetData.otaUpperWidgets.setVisibility(View.GONE);
-    }
-
-    public boolean isDialerOpened() {
-        // boolean retval = (mOtaCallCardDtmfDialer != null && mOtaCallCardDtmfDialer.isOpened());
-        boolean retval = false;
-        if (DBG) log("- isDialerOpened() ==> " + retval);
-        return retval;
-    }
-
-    /**
-     * Show the appropriate OTA screen based on the current state of OTA call.
-     *
-     * This is called from the InCallScreen when the screen needs to be
-     * refreshed (and thus is only ever used in interactive mode.)
-     *
-     * Since this is called as part of the InCallScreen.updateScreen() sequence,
-     * this method does *not* post an mInCallScreen.requestUpdateScreen()
-     * request.
-     */
-    public void otaShowProperScreen() {
-        if (DBG) log("otaShowProperScreen()...");
-        if (!mInteractive) {
-            // We shouldn't ever get here in non-interactive mode!
-            Log.w(LOG_TAG, "otaShowProperScreen: not interactive!");
-            return;
-        }
-
-        // if ((mInCallScreen != null) && mInCallScreen.isForegroundActivity()) {
-        //     if (DBG) log("otaShowProperScreen(): InCallScreen in foreground, currentstate = "
-        //             + mApplication.cdmaOtaScreenState.otaScreenState);
-        //     if (mInCallTouchUi != null) {
-        //         mInCallTouchUi.setVisibility(View.GONE);
-        //     }
-        //     if (mCallCard != null) {
-        //         mCallCard.setVisibility(View.GONE);
-        //     }
-        //     if (mApplication.cdmaOtaScreenState.otaScreenState
-        //             == CdmaOtaScreenState.OtaScreenState.OTA_STATUS_ACTIVATION) {
-        //         otaShowActivateScreen();
-        //     } else if (mApplication.cdmaOtaScreenState.otaScreenState
-        //             == CdmaOtaScreenState.OtaScreenState.OTA_STATUS_LISTENING) {
-        //         otaShowListeningScreen();
-        //     } else if (mApplication.cdmaOtaScreenState.otaScreenState
-        //             == CdmaOtaScreenState.OtaScreenState.OTA_STATUS_PROGRESS) {
-        //         otaShowInProgressScreen();
-        //     }
-
-        //     if (mApplication.cdmaOtaProvisionData.inOtaSpcState) {
-        //         otaShowSpcErrorNotice(getOtaSpcDisplayTime());
-        //     }
-        // }
-    }
-
-    /**
-     * Read configuration values for each OTA screen from config.xml.
-     * These configuration values control visibility of each screen.
-     */
-    private void readXmlSettings() {
-        if (DBG) log("readXmlSettings()...");
-        if (mApplication.cdmaOtaConfigData.configComplete) {
-            return;
-        }
-
-        mApplication.cdmaOtaConfigData.configComplete = true;
-        int tmpOtaShowActivationScreen =
-                mContext.getResources().getInteger(R.integer.OtaShowActivationScreen);
-        mApplication.cdmaOtaConfigData.otaShowActivationScreen = tmpOtaShowActivationScreen;
-        if (DBG) log("readXmlSettings(), otaShowActivationScreen = "
-                + mApplication.cdmaOtaConfigData.otaShowActivationScreen);
-
-        int tmpOtaShowListeningScreen =
-                mContext.getResources().getInteger(R.integer.OtaShowListeningScreen);
-        mApplication.cdmaOtaConfigData.otaShowListeningScreen = tmpOtaShowListeningScreen;
-        if (DBG) log("readXmlSettings(), otaShowListeningScreen = "
-                + mApplication.cdmaOtaConfigData.otaShowListeningScreen);
-
-        int tmpOtaShowActivateFailTimes =
-                mContext.getResources().getInteger(R.integer.OtaShowActivateFailTimes);
-        mApplication.cdmaOtaConfigData.otaShowActivateFailTimes = tmpOtaShowActivateFailTimes;
-        if (DBG) log("readXmlSettings(), otaShowActivateFailTimes = "
-                + mApplication.cdmaOtaConfigData.otaShowActivateFailTimes);
-
-        int tmpOtaPlaySuccessFailureTone =
-                mContext.getResources().getInteger(R.integer.OtaPlaySuccessFailureTone);
-        mApplication.cdmaOtaConfigData.otaPlaySuccessFailureTone = tmpOtaPlaySuccessFailureTone;
-        if (DBG) log("readXmlSettings(), otaPlaySuccessFailureTone = "
-                + mApplication.cdmaOtaConfigData.otaPlaySuccessFailureTone);
-    }
-
-    /**
-     * Handle the click events for OTA buttons.
-     */
-    public void onClickHandler(int id) {
-        switch (id) {
-            case R.id.otaEndButton:
-                onClickOtaEndButton();
-                break;
-
-            case R.id.otaSpeakerButton:
-                onClickOtaSpeakerButton();
-                break;
-
-            case R.id.otaActivateButton:
-                onClickOtaActivateButton();
-                break;
-
-            case R.id.otaSkipButton:
-                onClickOtaActivateSkipButton();
-                break;
-
-            case R.id.otaNextButton:
-                onClickOtaActivateNextButton();
-                break;
-
-            case R.id.otaTryAgainButton:
-                onClickOtaTryAgainButton();
-                break;
-
-            default:
-                if (DBG) log ("onClickHandler: received a click event for unrecognized id");
-                break;
-        }
-    }
-
-    private void onClickOtaTryAgainButton() {
-        if (DBG) log("Activation Try Again Clicked!");
-        if (!mApplication.cdmaOtaProvisionData.inOtaSpcState) {
-            otaShowActivateScreen();
-        }
-    }
-
-    private void onClickOtaEndButton() {
-        if (DBG) log("Activation End Call Button Clicked!");
-        if (!mApplication.cdmaOtaProvisionData.inOtaSpcState) {
-            if (PhoneUtils.hangup(mApplication.mCM) == false) {
-                // If something went wrong when placing the OTA call,
-                // the screen is not updated by the call disconnect
-                // handler and we have to do it here
-                setSpeaker(false);
-                // mInCallScreen.handleOtaCallEnd();
-            }
-        }
-    }
-
-    private void onClickOtaSpeakerButton() {
-        if (DBG) log("OTA Speaker button Clicked!");
-        if (!mApplication.cdmaOtaProvisionData.inOtaSpcState) {
-            boolean isChecked = !PhoneUtils.isSpeakerOn(mContext);
-            setSpeaker(isChecked);
-        }
-    }
-
-    private void onClickOtaActivateButton() {
-        if (DBG) log("Call Activation Clicked!");
-        otaPerformActivation();
-    }
-
-    private void onClickOtaActivateSkipButton() {
-        if (DBG) log("Activation Skip Clicked!");
-        DialogInterface.OnKeyListener keyListener;
-        keyListener = new DialogInterface.OnKeyListener() {
-            public boolean onKey(DialogInterface dialog, int keyCode,
-                    KeyEvent event) {
-                if (DBG) log("Ignoring key events...");
-                return true;
-            }
-        };
-        mOtaWidgetData.otaSkipConfirmationDialog = new AlertDialog.Builder(null /* mInCallScreen */)
-                .setTitle(R.string.ota_skip_activation_dialog_title)
-                .setMessage(R.string.ota_skip_activation_dialog_message)
-                .setPositiveButton(
-                    android.R.string.ok,
-                    // "OK" means "skip activation".
-                    new AlertDialog.OnClickListener() {
-                        public void onClick(DialogInterface dialog, int which) {
-                            otaSkipActivation();
-                        }
-                    })
-                .setNegativeButton(
-                    android.R.string.cancel,
-                    // "Cancel" means just dismiss the dialog.
-                    // Don't actually start an activation call.
-                    null)
-                .setOnKeyListener(keyListener)
-                .create();
-        mOtaWidgetData.otaSkipConfirmationDialog.show();
-    }
-
-    private void onClickOtaActivateNextButton() {
-        if (DBG) log("Dialog Next Clicked!");
-        if (!mApplication.cdmaOtaProvisionData.inOtaSpcState) {
-            mApplication.cdmaOtaScreenState.otaScreenState =
-                    CdmaOtaScreenState.OtaScreenState.OTA_STATUS_UNDEFINED;
-            otaShowHome();
-        }
-    }
-
-    public void dismissAllOtaDialogs() {
-        if (mOtaWidgetData != null) {
-            if (mOtaWidgetData.spcErrorDialog != null) {
-                if (DBG) log("- DISMISSING mSpcErrorDialog.");
-                mOtaWidgetData.spcErrorDialog.dismiss();
-                mOtaWidgetData.spcErrorDialog = null;
-            }
-            if (mOtaWidgetData.otaFailureDialog != null) {
-                if (DBG) log("- DISMISSING mOtaFailureDialog.");
-                mOtaWidgetData.otaFailureDialog.dismiss();
-                mOtaWidgetData.otaFailureDialog = null;
-            }
-        }
-    }
-
-    private int getOtaSpcDisplayTime() {
-        if (DBG) log("getOtaSpcDisplayTime()...");
-        int tmpSpcTime = 1;
-        if (mApplication.cdmaOtaProvisionData.inOtaSpcState) {
-            long tmpOtaSpcRunningTime = 0;
-            long tmpOtaSpcLeftTime = 0;
-            tmpOtaSpcRunningTime = SystemClock.elapsedRealtime();
-            tmpOtaSpcLeftTime =
-                tmpOtaSpcRunningTime - mApplication.cdmaOtaProvisionData.otaSpcUptime;
-            if (tmpOtaSpcLeftTime >= OTA_SPC_TIMEOUT*1000) {
-                tmpSpcTime = 1;
-            } else {
-                tmpSpcTime = OTA_SPC_TIMEOUT - (int)tmpOtaSpcLeftTime/1000;
-            }
-        }
-        if (DBG) log("getOtaSpcDisplayTime(), time for SPC error notice: " + tmpSpcTime);
-        return tmpSpcTime;
-    }
-
-    /**
-     * Initialize the OTA widgets for all OTA screens.
-     */
-    private void initOtaInCallScreen() {
-        if (DBG) log("initOtaInCallScreen()...");
-        // mOtaWidgetData.otaTitle = (TextView) mInCallScreen.findViewById(R.id.otaTitle);
-        // mOtaWidgetData.otaTextActivate = (TextView) mInCallScreen.findViewById(R.id.otaActivate);
-        mOtaWidgetData.otaTextActivate.setVisibility(View.GONE);
-        // mOtaWidgetData.otaTextListenProgress =
-        //         (TextView) mInCallScreen.findViewById(R.id.otaListenProgress);
-        // mOtaWidgetData.otaTextProgressBar =
-        //         (ProgressBar) mInCallScreen.findViewById(R.id.progress_large);
-        mOtaWidgetData.otaTextProgressBar.setIndeterminate(true);
-        // mOtaWidgetData.otaTextSuccessFail =
-        //         (TextView) mInCallScreen.findViewById(R.id.otaSuccessFailStatus);
-
-        // mOtaWidgetData.otaUpperWidgets =
-        //         (ViewGroup) mInCallScreen.findViewById(R.id.otaUpperWidgets);
-        // mOtaWidgetData.callCardOtaButtonsListenProgress =
-        //         (View) mInCallScreen.findViewById(R.id.callCardOtaListenProgress);
-        // mOtaWidgetData.callCardOtaButtonsActivate =
-        //         (View) mInCallScreen.findViewById(R.id.callCardOtaActivate);
-        // mOtaWidgetData.callCardOtaButtonsFailSuccess =
-        //         (View) mInCallScreen.findViewById(R.id.callCardOtaFailOrSuccessful);
-
-        // mOtaWidgetData.otaEndButton = (Button) mInCallScreen.findViewById(R.id.otaEndButton);
-        // mOtaWidgetData.otaEndButton.setOnClickListener(mInCallScreen);
-        // mOtaWidgetData.otaSpeakerButton =
-        //         (ToggleButton) mInCallScreen.findViewById(R.id.otaSpeakerButton);
-        // mOtaWidgetData.otaSpeakerButton.setOnClickListener(mInCallScreen);
-        // mOtaWidgetData.otaActivateButton =
-        //         (Button) mInCallScreen.findViewById(R.id.otaActivateButton);
-        // mOtaWidgetData.otaActivateButton.setOnClickListener(mInCallScreen);
-        // mOtaWidgetData.otaSkipButton = (Button) mInCallScreen.findViewById(R.id.otaSkipButton);
-        // mOtaWidgetData.otaSkipButton.setOnClickListener(mInCallScreen);
-        // mOtaWidgetData.otaNextButton = (Button) mInCallScreen.findViewById(R.id.otaNextButton);
-        // mOtaWidgetData.otaNextButton.setOnClickListener(mInCallScreen);
-        // mOtaWidgetData.otaTryAgainButton =
-        //         (Button) mInCallScreen.findViewById(R.id.otaTryAgainButton);
-        // mOtaWidgetData.otaTryAgainButton.setOnClickListener(mInCallScreen);
-
-        // mOtaWidgetData.otaDtmfDialerView =
-        //         (DTMFTwelveKeyDialerView) mInCallScreen.findViewById(R.id.otaDtmfDialerView);
-        // Sanity-check: the otaDtmfDialerView widget should *always* be present.
-        // if (mOtaWidgetData.otaDtmfDialerView == null) {
-        //     throw new IllegalStateException("initOtaInCallScreen: couldn't find otaDtmfDialerView");
-        // }
-
-        // Create a new DTMFTwelveKeyDialer instance purely for use by the
-        // DTMFTwelveKeyDialerView ("otaDtmfDialerView") that comes from
-        // otacall_card.xml.
-        // mOtaCallCardDtmfDialer = new DTMFTwelveKeyDialer(mInCallScreen,
-        //                                                  mOtaWidgetData.otaDtmfDialerView);
-
-        // Initialize the new DTMFTwelveKeyDialer instance.  This is
-        // needed to play local DTMF tones.
-        // mOtaCallCardDtmfDialer.startDialerSession();
-
-        // mOtaWidgetData.otaDtmfDialerView.setDialer(mOtaCallCardDtmfDialer);
-    }
-
-    /**
-     * Clear out all OTA UI widget elements. Needs to get called
-     * when OTA call ends or InCallScreen is destroyed.
-     * @param disableSpeaker parameter control whether Speaker should be turned off.
-     */
-    public void cleanOtaScreen(boolean disableSpeaker) {
-        if (DBG) log("OTA ends, cleanOtaScreen!");
-
-        mApplication.cdmaOtaScreenState.otaScreenState =
-                CdmaOtaScreenState.OtaScreenState.OTA_STATUS_UNDEFINED;
-        mApplication.cdmaOtaProvisionData.isOtaCallCommitted = false;
-        mApplication.cdmaOtaProvisionData.isOtaCallIntentProcessed = false;
-        mApplication.cdmaOtaProvisionData.inOtaSpcState = false;
-        mApplication.cdmaOtaProvisionData.activationCount = 0;
-        mApplication.cdmaOtaProvisionData.otaSpcUptime = 0;
-        mApplication.cdmaOtaInCallScreenUiState.state = State.UNDEFINED;
-
-        if (mInteractive && (mOtaWidgetData != null)) {
-            // if (mInCallTouchUi != null) mInCallTouchUi.setVisibility(View.VISIBLE);
-            // if (mCallCard != null) {
-            //     mCallCard.setVisibility(View.VISIBLE);
-            //     mCallCard.hideCallCardElements();
-            // }
-
-            // Free resources from the DTMFTwelveKeyDialer instance we created
-            // in initOtaInCallScreen().
-            // if (mOtaCallCardDtmfDialer != null) {
-            //     mOtaCallCardDtmfDialer.stopDialerSession();
-            // }
-
-            mOtaWidgetData.otaTextActivate.setVisibility(View.GONE);
-            mOtaWidgetData.otaTextListenProgress.setVisibility(View.GONE);
-            mOtaWidgetData.otaTextProgressBar.setVisibility(View.GONE);
-            mOtaWidgetData.otaTextSuccessFail.setVisibility(View.GONE);
-            mOtaWidgetData.callCardOtaButtonsActivate.setVisibility(View.GONE);
-            mOtaWidgetData.callCardOtaButtonsListenProgress.setVisibility(View.GONE);
-            mOtaWidgetData.callCardOtaButtonsFailSuccess.setVisibility(View.GONE);
-            mOtaWidgetData.otaUpperWidgets.setVisibility(View.GONE);
-            // mOtaWidgetData.otaDtmfDialerView.setVisibility(View.GONE);
-            mOtaWidgetData.otaNextButton.setVisibility(View.GONE);
-            mOtaWidgetData.otaTryAgainButton.setVisibility(View.GONE);
-        }
-
-        // turn off the speaker in case it was turned on
-        // but the OTA call could not be completed
-        if (disableSpeaker) {
-            setSpeaker(false);
-        }
-    }
-
-    /**
-     * Defines OTA information that needs to be maintained during
-     * an OTA call when display orientation changes.
-     */
-    public static class CdmaOtaProvisionData {
-        public boolean isOtaCallCommitted;
-        public boolean isOtaCallIntentProcessed;
-        public boolean inOtaSpcState;
-        public int activationCount;
-        public long otaSpcUptime;
-    }
-
-    /**
-     * Defines OTA screen configuration items read from config.xml
-     * and used to control OTA display.
-     */
-    public static class CdmaOtaConfigData {
-        public int otaShowActivationScreen;
-        public int otaShowListeningScreen;
-        public int otaShowActivateFailTimes;
-        public int otaPlaySuccessFailureTone;
-        public boolean configComplete;
-        public CdmaOtaConfigData() {
-            if (DBG) log("CdmaOtaConfigData constructor!");
-            otaShowActivationScreen = OTA_SHOW_ACTIVATION_SCREEN_OFF;
-            otaShowListeningScreen = OTA_SHOW_LISTENING_SCREEN_OFF;
-            otaShowActivateFailTimes = OTA_SHOW_ACTIVATE_FAIL_COUNT_OFF;
-            otaPlaySuccessFailureTone = OTA_PLAY_SUCCESS_FAILURE_TONE_OFF;
-        }
-    }
-
-    /**
-     * The state of the OTA InCallScreen UI.
-     */
-    public static class CdmaOtaInCallScreenUiState {
-        public enum State {
-            UNDEFINED,
-            NORMAL,
-            ENDED
-        }
-
-        public State state;
-
-        public CdmaOtaInCallScreenUiState() {
-            if (DBG) log("CdmaOtaInCallScreenState: constructor init to UNDEFINED");
-            state = CdmaOtaInCallScreenUiState.State.UNDEFINED;
-        }
-    }
-
-    /**
-     * Save the Ota InCallScreen UI state
-     */
-    public void setCdmaOtaInCallScreenUiState(CdmaOtaInCallScreenUiState.State state) {
-        if (DBG) log("setCdmaOtaInCallScreenState: " + state);
-        mApplication.cdmaOtaInCallScreenUiState.state = state;
-    }
-
-    /**
-     * Get the Ota InCallScreen UI state
-     */
-    public CdmaOtaInCallScreenUiState.State getCdmaOtaInCallScreenUiState() {
-        if (DBG) log("getCdmaOtaInCallScreenState: "
-                     + mApplication.cdmaOtaInCallScreenUiState.state);
-        return mApplication.cdmaOtaInCallScreenUiState.state;
-    }
-
-    /**
-     * The OTA screen state machine.
-     */
-    public static class CdmaOtaScreenState {
-        public enum OtaScreenState {
-            OTA_STATUS_UNDEFINED,
-            OTA_STATUS_ACTIVATION,
-            OTA_STATUS_LISTENING,
-            OTA_STATUS_PROGRESS,
-            OTA_STATUS_SUCCESS_FAILURE_DLG
-        }
-
-        public OtaScreenState otaScreenState;
-
-        public CdmaOtaScreenState() {
-            otaScreenState = OtaScreenState.OTA_STATUS_UNDEFINED;
-        }
-
-        /**
-         * {@link PendingIntent} used to report an OTASP result status code
-         * back to our caller. Can be null.
-         *
-         * Our caller (presumably SetupWizard) may create this PendingIntent,
-         * pointing back at itself, and passes it along as an extra with the
-         * ACTION_PERFORM_CDMA_PROVISIONING intent.  Then, when there's an
-         * OTASP result to report, we send that PendingIntent back, adding an
-         * extra called EXTRA_OTASP_RESULT_CODE to indicate the result.
-         *
-         * Possible result values are the OTASP_RESULT_* constants.
-         */
-        public PendingIntent otaspResultCodePendingIntent;
-    }
-
-    /** @see com.android.internal.telephony.Phone */
-    private static String otaProvisionStatusToString(int status) {
-        switch (status) {
-            case Phone.CDMA_OTA_PROVISION_STATUS_SPL_UNLOCKED:
-                return "SPL_UNLOCKED";
-            case Phone.CDMA_OTA_PROVISION_STATUS_SPC_RETRIES_EXCEEDED:
-                return "SPC_RETRIES_EXCEEDED";
-            case Phone.CDMA_OTA_PROVISION_STATUS_A_KEY_EXCHANGED:
-                return "A_KEY_EXCHANGED";
-            case Phone.CDMA_OTA_PROVISION_STATUS_SSD_UPDATED:
-                return "SSD_UPDATED";
-            case Phone.CDMA_OTA_PROVISION_STATUS_NAM_DOWNLOADED:
-                return "NAM_DOWNLOADED";
-            case Phone.CDMA_OTA_PROVISION_STATUS_MDN_DOWNLOADED:
-                return "MDN_DOWNLOADED";
-            case Phone.CDMA_OTA_PROVISION_STATUS_IMSI_DOWNLOADED:
-                return "IMSI_DOWNLOADED";
-            case Phone.CDMA_OTA_PROVISION_STATUS_PRL_DOWNLOADED:
-                return "PRL_DOWNLOADED";
-            case Phone.CDMA_OTA_PROVISION_STATUS_COMMITTED:
-                return "COMMITTED";
-            case Phone.CDMA_OTA_PROVISION_STATUS_OTAPA_STARTED:
-                return "OTAPA_STARTED";
-            case Phone.CDMA_OTA_PROVISION_STATUS_OTAPA_STOPPED:
-                return "OTAPA_STOPPED";
-            case Phone.CDMA_OTA_PROVISION_STATUS_OTAPA_ABORTED:
-                return "OTAPA_ABORTED";
-            default:
-                return "<unknown status" + status + ">";
-        }
-    }
-
-    private static int getLteOnCdmaMode(Context context) {
-        final TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(
-                Context.TELEPHONY_SERVICE);
-        // If the telephony manager is not available yet, or if it doesn't know the answer yet,
-        // try falling back on the system property that may or may not be there
-        if (telephonyManager == null
-                || telephonyManager.getLteOnCdmaMode() == PhoneConstants.LTE_ON_CDMA_UNKNOWN) {
-            return SystemProperties.getInt(TelephonyProperties.PROPERTY_LTE_ON_CDMA_DEVICE,
-                    PhoneConstants.LTE_ON_CDMA_UNKNOWN);
-        }
-        return telephonyManager.getLteOnCdmaMode();
-    }
-
-    private static void log(String msg) {
-        Log.d(LOG_TAG, msg);
-    }
-
-    private static void loge(String msg) {
-        Log.e(LOG_TAG, msg);
-    }
-}
diff --git a/src/com/android/phone/OutgoingCallBroadcaster.java b/src/com/android/phone/OutgoingCallBroadcaster.java
index cfe6f32..dab2077 100644
--- a/src/com/android/phone/OutgoingCallBroadcaster.java
+++ b/src/com/android/phone/OutgoingCallBroadcaster.java
@@ -190,47 +190,6 @@
             final PhoneGlobals app = PhoneGlobals.getInstance();
             final Phone phone = PhoneGlobals.getPhone();
 
-            // OTASP-specific checks.
-            // TODO: This should probably all happen in
-            // OutgoingCallBroadcaster.onCreate(), since there's no reason to
-            // even bother with the NEW_OUTGOING_CALL broadcast if we're going
-            // to disallow the outgoing call anyway...
-            if (TelephonyCapabilities.supportsOtasp(phone)) {
-                boolean activateState = (app.cdmaOtaScreenState.otaScreenState
-                        == OtaUtils.CdmaOtaScreenState.OtaScreenState.OTA_STATUS_ACTIVATION);
-                boolean dialogState = (app.cdmaOtaScreenState.otaScreenState
-                        == OtaUtils.CdmaOtaScreenState.OtaScreenState
-                        .OTA_STATUS_SUCCESS_FAILURE_DLG);
-                boolean isOtaCallActive = false;
-
-                // TODO: Need cleaner way to check if OTA is active.
-                // Also, this check seems to be broken in one obscure case: if
-                // you interrupt an OTASP call by pressing Back then Skip,
-                // otaScreenState somehow gets left in either PROGRESS or
-                // LISTENING.
-                if ((app.cdmaOtaScreenState.otaScreenState
-                        == OtaUtils.CdmaOtaScreenState.OtaScreenState.OTA_STATUS_PROGRESS)
-                        || (app.cdmaOtaScreenState.otaScreenState
-                        == OtaUtils.CdmaOtaScreenState.OtaScreenState.OTA_STATUS_LISTENING)) {
-                    isOtaCallActive = true;
-                }
-
-                if (activateState || dialogState) {
-                    // The OTASP sequence is active, but either (1) the call
-                    // hasn't started yet, or (2) the call has ended and we're
-                    // showing the success/failure screen.  In either of these
-                    // cases it's OK to make a new outgoing call, but we need
-                    // to take down any OTASP-related UI first.
-                    if (dialogState) app.dismissOtaDialogs();
-                    app.clearOtaState();
-                } else if (isOtaCallActive) {
-                    // The actual OTASP call is active.  Don't allow new
-                    // outgoing calls at all from this state.
-                    Log.w(TAG, "OTASP call is active: disallowing a new outgoing call.");
-                    return false;
-                }
-            }
-
             if (number == null) {
                 if (DBG) Log.v(TAG, "CALL cancelled (null number), returning...");
                 return false;
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index cec5a76..842eb06 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -159,26 +159,6 @@
     // Broadcast receiver for various intent broadcasts (see onCreate())
     private final BroadcastReceiver mReceiver = new PhoneAppBroadcastReceiver();
 
-    /**
-     * The singleton OtaUtils instance used for OTASP calls.
-     *
-     * The OtaUtils instance is created lazily the first time we need to
-     * make an OTASP call, regardless of whether it's an interactive or
-     * non-interactive OTASP call.
-     */
-    public OtaUtils otaUtils;
-
-    // Following are the CDMA OTA information Objects used during OTA Call.
-    // cdmaOtaProvisionData object store static OTA information that needs
-    // to be maintained even during Slider open/close scenarios.
-    // cdmaOtaConfigData object stores configuration info to control visiblity
-    // of each OTA Screens.
-    // cdmaOtaScreenState object store OTA Screen State information.
-    public OtaUtils.CdmaOtaProvisionData cdmaOtaProvisionData;
-    public OtaUtils.CdmaOtaConfigData cdmaOtaConfigData;
-    public OtaUtils.CdmaOtaScreenState cdmaOtaScreenState;
-    public OtaUtils.CdmaOtaInCallScreenUiState cdmaOtaInCallScreenUiState;
-
     Handler mHandler = new Handler() {
         @Override
         public void handleMessage(Message msg) {
@@ -366,11 +346,6 @@
             PhoneUtils.setAudioMode(mCM);
         }
 
-        cdmaOtaProvisionData = new OtaUtils.CdmaOtaProvisionData();
-        cdmaOtaConfigData = new OtaUtils.CdmaOtaConfigData();
-        cdmaOtaScreenState = new OtaUtils.CdmaOtaScreenState();
-        cdmaOtaInCallScreenUiState = new OtaUtils.CdmaOtaInCallScreenUiState();
-
         // XXX pre-load the SimProvider so that it's ready
         resolver.getType(Uri.parse("content://icc/adn"));
 
@@ -434,43 +409,6 @@
     }
 
     /**
-     * Handles OTASP-related events from the telephony layer.
-     *
-     * While an OTASP call is active, the CallNotifier forwards
-     * OTASP-related telephony events to this method.
-     */
-    void handleOtaspEvent(Message msg) {
-        if (DBG) Log.d(LOG_TAG, "handleOtaspEvent(message " + msg + ")...");
-
-        if (otaUtils == null) {
-            // We shouldn't be getting OTASP events without ever
-            // having started the OTASP call in the first place!
-            Log.w(LOG_TAG, "handleOtaEvents: got an event but otaUtils is null! "
-                  + "message = " + msg);
-            return;
-        }
-
-        otaUtils.onOtaProvisionStatusChanged((AsyncResult) msg.obj);
-    }
-
-    /**
-     * Similarly, handle the disconnect event of an OTASP call
-     * by forwarding it to the OtaUtils instance.
-     */
-    /* package */ void handleOtaspDisconnect() {
-        if (DBG) Log.d(LOG_TAG, "handleOtaspDisconnect()...");
-
-        if (otaUtils == null) {
-            // We shouldn't be getting OTASP events without ever
-            // having started the OTASP call in the first place!
-            Log.w(LOG_TAG, "handleOtaspDisconnect: otaUtils is null!");
-            return;
-        }
-
-        otaUtils.onOtaspDisconnect();
-    }
-
-    /**
      * Sets the activity responsible for un-PUK-blocking the device
      * so that we may close it when we receive a positive result.
      * mPUKEntryActivity is also used to indicate to the device that
@@ -618,15 +556,8 @@
         PhoneUtils.displayMMIComplete(mmiCode.getPhone(), getInstance(), mmiCode, null, null);
     }
 
-    private void initForNewRadioTechnology(int phoneId) {
+    private void initForNewRadioTechnology() {
         if (DBG) Log.d(LOG_TAG, "initForNewRadioTechnology...");
-
-        final Phone phone = PhoneFactory.getPhone(phoneId);
-        if (phone == null || !TelephonyCapabilities.supportsOtasp(phone)) {
-            // Clean up OTA for non-CDMA since it is only valid for CDMA.
-            clearOtaState();
-        }
-
         notifier.updateCallNotifierRegistrationsAfterRadioTechnologyChange();
     }
 
@@ -758,11 +689,8 @@
                         intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE)));
             } else if (action.equals(TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED)) {
                 String newPhone = intent.getStringExtra(PhoneConstants.PHONE_NAME_KEY);
-                int phoneId = intent.getIntExtra(PhoneConstants.PHONE_KEY,
-                        SubscriptionManager.INVALID_PHONE_INDEX);
-                Log.d(LOG_TAG, "Radio technology switched. Now " + newPhone + " (" + phoneId
-                        + ") is active.");
-                initForNewRadioTechnology(phoneId);
+                Log.d(LOG_TAG, "Radio technology switched. Now " + newPhone + " is active.");
+                initForNewRadioTechnology();
             } else if (action.equals(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED)) {
                 handleServiceStateChanged(intent);
             } else if (action.equals(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED)) {
@@ -812,24 +740,6 @@
         }
     }
 
-    // it is safe to call clearOtaState() even if the InCallScreen isn't active
-    public void clearOtaState() {
-        if (DBG) Log.d(LOG_TAG, "- clearOtaState ...");
-        if (otaUtils != null) {
-            otaUtils.cleanOtaScreen(true);
-            if (DBG) Log.d(LOG_TAG, "  - clearOtaState clears OTA screen");
-        }
-    }
-
-    // it is safe to call dismissOtaDialogs() even if the InCallScreen isn't active
-    public void dismissOtaDialogs() {
-        if (DBG) Log.d(LOG_TAG, "- dismissOtaDialogs ...");
-        if (otaUtils != null) {
-            otaUtils.dismissAllOtaDialogs();
-            if (DBG) Log.d(LOG_TAG, "  - dismissOtaDialogs clears OTA dialogs");
-        }
-    }
-
     public Phone getPhoneInEcm() {
         return phoneInEcm;
     }
