Home | History | Annotate | Download | only in phone
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.phone;
     18 
     19 import com.android.internal.telephony.Phone;
     20 import com.android.phone.OtaUtils.CdmaOtaInCallScreenUiState.State;
     21 
     22 import android.app.AlertDialog;
     23 import android.app.PendingIntent;
     24 import android.app.PendingIntent.CanceledException;
     25 import android.content.ActivityNotFoundException;
     26 import android.content.Context;
     27 import android.content.DialogInterface;
     28 import android.content.Intent;
     29 import android.content.pm.ResolveInfo;
     30 import android.os.AsyncResult;
     31 import android.os.Handler;
     32 import android.os.Message;
     33 import android.os.SystemClock;
     34 import android.os.SystemProperties;
     35 import android.provider.Settings;
     36 
     37 import android.util.Log;
     38 import android.view.KeyEvent;
     39 import android.view.View;
     40 import android.view.ViewGroup;
     41 import android.view.ViewStub;
     42 import android.view.WindowManager;
     43 
     44 import android.widget.Button;
     45 import android.widget.ScrollView;
     46 import android.widget.ToggleButton;
     47 import android.widget.ProgressBar;
     48 import android.widget.TextView;
     49 
     50 /**
     51  * Handles all OTA Call related logic and UI functionality.
     52  * The InCallScreen interacts with this class to perform an OTA Call.
     53  *
     54  * OTA is a CDMA-specific feature:
     55  *   OTA or OTASP == Over The Air service provisioning
     56  *   SPC == Service Programming Code
     57  *   TODO: Include pointer to more detailed documentation.
     58  */
     59 public class OtaUtils {
     60     private static final String LOG_TAG = "OtaUtils";
     61     private static final String UNACTIVATED_MIN2_VALUE = "000000";
     62     private static final String UNACTIVATED_MIN_VALUE = "1111110111";
     63     private static final boolean DBG = (PhoneApp.DBG_LEVEL >= 1);
     64 
     65     public static final int OTA_SHOW_ACTIVATION_SCREEN_OFF = 0;
     66     public static final int OTA_SHOW_ACTIVATION_SCREEN_ON = 1;
     67     public static final int OTA_SHOW_LISTENING_SCREEN_OFF =0;
     68     public static final int OTA_SHOW_LISTENING_SCREEN_ON =1;
     69     public static final int OTA_SHOW_ACTIVATE_FAIL_COUNT_OFF = 0;
     70     public static final int OTA_SHOW_ACTIVATE_FAIL_COUNT_THREE = 3;
     71     public static final int OTA_PLAY_SUCCESS_FAILURE_TONE_OFF = 0;
     72     public static final int OTA_PLAY_SUCCESS_FAILURE_TONE_ON = 1;
     73 
     74     // SPC Timeout is 60 seconds
     75     public final int OTA_SPC_TIMEOUT = 60;
     76     public final int OTA_FAILURE_DIALOG_TIMEOUT = 2;
     77 
     78     private InCallScreen mInCallScreen;
     79     private Context mContext;
     80     private PhoneApp mApplication;
     81     private OtaWidgetData mOtaWidgetData;
     82     private ViewGroup mInCallPanel;
     83     private CallCard mCallCard;
     84 
     85     // The DTMFTwelveKeyDialer instance owned by the InCallScreen, which
     86     // the InCallScreen passes in to our constructor.
     87     private DTMFTwelveKeyDialer mDialer;
     88     //
     89     // The DTMFTwelveKeyDialer instance that we create ourselves in
     90     // initOtaInCallScreen(), and attach to the DTMFTwelveKeyDialerView
     91     // ("otaDtmfDialerView") that comes from otacall_card.xml.
     92     private DTMFTwelveKeyDialer mOtaCallCardDtmfDialer;
     93     // TODO: we ought to share a single DTMFTwelveKeyDialer instance for
     94     // both these uses, but see bug 2432289 for related issues.
     95 
     96     private static boolean mIsWizardMode = true;
     97 
     98     /**
     99      * OtaWidgetData class represent all OTA UI elements
    100      */
    101     private class OtaWidgetData {
    102         public Button otaEndButton;
    103         public Button otaActivateButton;
    104         public Button otaSkipButton;
    105         public Button otaNextButton;
    106         public ToggleButton otaSpeakerButton;
    107         public View otaCallCardBase;
    108         public View callCardOtaButtonsFailSuccess;
    109         public ProgressBar otaTextProgressBar;
    110         public TextView otaTextSuccessFail;
    111         public View callCardOtaButtonsActivate;
    112         public View callCardOtaButtonsListenProgress;
    113         public TextView otaTextActivate;
    114         public TextView otaTextListenProgress;
    115         public ScrollView otaTextListenProgressContainer;
    116         public AlertDialog spcErrorDialog;
    117         public AlertDialog otaFailureDialog;
    118         public AlertDialog otaSkipConfirmationDialog;
    119         public TextView otaTitle;
    120         public DTMFTwelveKeyDialerView otaDtmfDialerView;
    121         public Button otaTryAgainButton;
    122     }
    123 
    124     public OtaUtils(Context context,
    125                     InCallScreen inCallScreen,
    126                     ViewGroup inCallPanel,
    127                     CallCard callCard,
    128                     DTMFTwelveKeyDialer dialer) {
    129 
    130         if (DBG) log("Enter OtaUtil constructor");
    131 
    132         mInCallScreen = inCallScreen;
    133         mContext = context;
    134         mInCallPanel = inCallPanel;
    135         mCallCard = callCard;
    136         mDialer = dialer;
    137         mApplication = PhoneApp.getInstance();
    138         mOtaWidgetData = new OtaWidgetData();
    139 
    140         // inflate OTA Call card and footers
    141         ViewStub otaCallCardStub = (ViewStub) mInCallScreen.findViewById(R.id.otaCallCardStub);
    142         otaCallCardStub.inflate();
    143         readXmlSettings();
    144         initOtaInCallScreen();
    145     }
    146 
    147     /**
    148      * Returns true if the phone needs activation.
    149      *
    150      * @param minString the phone's MIN configuration string
    151      * @return true if phone needs activation
    152      * @throws OtaConfigurationException if the string is invalid
    153      */
    154     public static boolean needsActivation(String minString) throws IllegalArgumentException {
    155         if (minString == null || (minString.length() < 6)) {
    156             throw new IllegalArgumentException();
    157         }
    158         return (minString.equals(UNACTIVATED_MIN_VALUE)
    159                 || minString.substring(0,6).equals(UNACTIVATED_MIN2_VALUE))
    160                 || SystemProperties.getBoolean("test_cdma_setup", false);
    161     }
    162 
    163     /**
    164      * Starts the OTA provisioning call.  If the MIN isn't available yet, it returns false and adds
    165      * an event to return the request to the calling app when it becomes available.
    166      *
    167      * @param context
    168      * @param handler
    169      * @param request
    170      * @return true if we were able to launch Ota activity or it's not required; false otherwise
    171      */
    172     public static boolean maybeDoOtaCall(Context context, Handler handler, int request) {
    173 
    174         PhoneApp app = PhoneApp.getInstance();
    175         Phone phone = app.phone;
    176 
    177         if (!isCdmaPhone()) {
    178             if (DBG) Log.v("OtaUtils", "Can't run provisioning on a non-CDMA phone");
    179             return true; // sanity check - a non-cdma phone doesn't need to run this
    180         }
    181 
    182         if (!phone.isMinInfoReady()) {
    183             if (DBG) log("MIN is not ready. Registering to receive notification.");
    184             phone.registerForSubscriptionInfoReady(handler, request, null);
    185             return false;
    186         }
    187 
    188         phone.unregisterForSubscriptionInfoReady(handler);
    189         String min = phone.getCdmaMin();
    190 
    191         if (DBG) log("min_string: " + min);
    192 
    193         boolean phoneNeedsActivation = false;
    194         try {
    195             phoneNeedsActivation = needsActivation(min);
    196         } catch (IllegalArgumentException e) {
    197             if (DBG) log("invalid MIN string, exit");
    198             return true; // If the MIN string is wrong, there's nothing else we can do.
    199         }
    200 
    201         if (DBG) log("phoneNeedsActivation is set to " + phoneNeedsActivation);
    202 
    203         int otaShowActivationScreen = context.getResources().getInteger(
    204                 R.integer.OtaShowActivationScreen);
    205 
    206         if (DBG) log("otaShowActivationScreen: " + otaShowActivationScreen);
    207 
    208         if (phoneNeedsActivation && (otaShowActivationScreen == OTA_SHOW_ACTIVATION_SCREEN_ON)) {
    209             app.cdmaOtaProvisionData.isOtaCallIntentProcessed = false;
    210             Intent newIntent = new Intent(InCallScreen.ACTION_SHOW_ACTIVATION);
    211             newIntent.setClass(context, InCallScreen.class);
    212             newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    213             mIsWizardMode = false;
    214             context.startActivity(newIntent);
    215             if (DBG) log("activation intent sent.");
    216         } else {
    217             if (DBG) log("activation intent NOT sent.");
    218         }
    219         return true;
    220     }
    221 
    222     private void setSpeaker(boolean state) {
    223         if (DBG) log("setSpeaker : " + state );
    224         if (state == PhoneUtils.isSpeakerOn(mContext)) {
    225             if (DBG) log("no change. returning");
    226             return;
    227         }
    228 
    229         if (state && mInCallScreen.isBluetoothAvailable()
    230                 && mInCallScreen.isBluetoothAudioConnected()) {
    231             mInCallScreen.disconnectBluetoothAudio();
    232         }
    233         PhoneUtils.turnOnSpeaker(mContext, state, true);
    234     }
    235 
    236     /**
    237      * Handle OTA Provision events from Framework. Possible events are:
    238      * OTA Commit Event - OTA provisioning was successful
    239      * SPC retries exceeded - SPC failure retries has exceeded, and Phone needs to
    240      *    power down.
    241      */
    242     public void onOtaProvisionStatusChanged(AsyncResult r) {
    243         int OtaStatus[] = (int[]) r.result;
    244         if (DBG) log("onOtaProvisionStatusChanged(): OtaStatus[0]" + OtaStatus[0]);
    245 
    246         switch(OtaStatus[0]) {
    247             case Phone.CDMA_OTA_PROVISION_STATUS_SPC_RETRIES_EXCEEDED:
    248                 otaShowInProgressScreen();
    249                 mApplication.cdmaOtaProvisionData.otaSpcUptime = SystemClock.elapsedRealtime();
    250                 otaShowSpcErrorNotice(OTA_SPC_TIMEOUT);
    251                 if (DBG) log("onOtaProvisionStatusChanged(): RETRIES EXCEEDED");
    252                 // Power.shutdown();
    253                 break;
    254 
    255             case Phone.CDMA_OTA_PROVISION_STATUS_COMMITTED:
    256                 otaShowInProgressScreen();
    257                 mApplication.cdmaOtaProvisionData.isOtaCallCommitted = true;
    258                 if (DBG) log("onOtaProvisionStatusChanged(): DONE, isOtaCallCommitted set to true");
    259                 break;
    260 
    261             case Phone.CDMA_OTA_PROVISION_STATUS_SPL_UNLOCKED:
    262             case Phone.CDMA_OTA_PROVISION_STATUS_A_KEY_EXCHANGED:
    263             case Phone.CDMA_OTA_PROVISION_STATUS_SSD_UPDATED:
    264             case Phone.CDMA_OTA_PROVISION_STATUS_NAM_DOWNLOADED:
    265             case Phone.CDMA_OTA_PROVISION_STATUS_MDN_DOWNLOADED:
    266             case Phone.CDMA_OTA_PROVISION_STATUS_IMSI_DOWNLOADED:
    267             case Phone.CDMA_OTA_PROVISION_STATUS_PRL_DOWNLOADED:
    268             case Phone.CDMA_OTA_PROVISION_STATUS_OTAPA_STARTED:
    269             case Phone.CDMA_OTA_PROVISION_STATUS_OTAPA_STOPPED:
    270             case Phone.CDMA_OTA_PROVISION_STATUS_OTAPA_ABORTED:
    271                 if (DBG) log("onOtaProvisionStatusChanged(): change to ProgressScreen");
    272                 otaShowInProgressScreen();
    273                 break;
    274 
    275             default:
    276                 if (DBG) log("onOtaProvisionStatusChanged(): Ignoring OtaStatus " + OtaStatus[0]);
    277                 break;
    278         }
    279     }
    280 
    281     private void otaShowHome() {
    282         if (DBG) log("OtaShowHome()...");
    283         mApplication.cdmaOtaScreenState.otaScreenState =
    284                 CdmaOtaScreenState.OtaScreenState.OTA_STATUS_UNDEFINED;
    285         mInCallScreen.endInCallScreenSession();
    286         Intent intent = new Intent(Intent.ACTION_MAIN);
    287         intent.addCategory (Intent.CATEGORY_HOME);
    288         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    289         mContext.startActivity(intent);
    290         return;
    291     }
    292 
    293     private void otaSkipActivation() {
    294         if (DBG) log("otaSkipActivation()...");
    295 
    296         PhoneApp app = PhoneApp.getInstance();
    297         if (app != null && app.cdmaOtaInCallScreenUiState.reportSkipPendingIntent != null) {
    298             try {
    299                 app.cdmaOtaInCallScreenUiState.reportSkipPendingIntent.send();
    300             } catch (CanceledException e) {
    301                 // should never happen because no code cancels the pending intent right now,
    302                 // but if it does, the user will simply be returned to the initial setup screen
    303             }
    304         }
    305 
    306         mInCallScreen.finish();
    307         return;
    308     }
    309 
    310     private void otaPerformActivation() {
    311         if (DBG) log("otaPerformActivation()...");
    312         if (!mApplication.cdmaOtaProvisionData.inOtaSpcState) {
    313             Intent newIntent = new Intent(Intent.ACTION_CALL);
    314             newIntent.putExtra(Intent.EXTRA_PHONE_NUMBER, InCallScreen.OTA_NUMBER);
    315             mInCallScreen.internalResolveIntent(newIntent);
    316             otaShowListeningScreen();
    317         }
    318         return;
    319     }
    320 
    321     /**
    322      * Show Activation Screen when phone powers up and OTA provision is
    323      * required. Also shown when activation fails and user needs
    324      * to re-attempt it. Contains ACTIVATE and SKIP buttons
    325      * which allow user to start OTA activation or skip the activation process.
    326      */
    327     public void otaShowActivateScreen() {
    328         if (DBG) log("OtaShowActivationScreen()...");
    329         if (mApplication.cdmaOtaConfigData.otaShowActivationScreen
    330                 == OTA_SHOW_ACTIVATION_SCREEN_ON) {
    331             if (DBG) log("OtaShowActivationScreen(): show activation screen");
    332             if (!isDialerOpened()) {
    333                 otaScreenInitialize();
    334                 mOtaWidgetData.otaSkipButton.setVisibility(mIsWizardMode ?
    335                         View.VISIBLE : View.INVISIBLE);
    336                 mOtaWidgetData.otaTextActivate.setVisibility(View.VISIBLE);
    337                 mOtaWidgetData.callCardOtaButtonsActivate.setVisibility(View.VISIBLE);
    338             } else {
    339                 mDialer.setHandleVisible(true);
    340             }
    341             mApplication.cdmaOtaScreenState.otaScreenState =
    342                     CdmaOtaScreenState.OtaScreenState.OTA_STATUS_ACTIVATION;
    343         } else {
    344             if (DBG) log("OtaShowActivationScreen(): show home screen");
    345             otaShowHome();
    346         }
    347      }
    348 
    349     /**
    350      * Show "Listen for Instruction" screen during OTA call. Shown when OTA Call
    351      * is initiated and user needs to listen for network instructions and press
    352      * appropriate DTMF digits to proceed to the "Programming in Progress" phase.
    353      */
    354     private void otaShowListeningScreen() {
    355         if (DBG) log("OtaShowListeningScreen()...");
    356         if (mApplication.cdmaOtaConfigData.otaShowListeningScreen
    357                 == OTA_SHOW_LISTENING_SCREEN_ON) {
    358             if (DBG) log("OtaShowListeningScreen(): show listening screen");
    359             if (!isDialerOpened()) {
    360                 otaScreenInitialize();
    361                 mOtaWidgetData.otaTextListenProgressContainer.setVisibility(View.VISIBLE);
    362                 mOtaWidgetData.otaTextListenProgress.setText(R.string.ota_listen);
    363                 mOtaWidgetData.otaDtmfDialerView.setVisibility(View.VISIBLE);
    364                 mOtaWidgetData.callCardOtaButtonsListenProgress.setVisibility(View.VISIBLE);
    365                 mOtaWidgetData.otaSpeakerButton.setVisibility(View.VISIBLE);
    366                 boolean speakerOn = PhoneUtils.isSpeakerOn(mContext);
    367                 mOtaWidgetData.otaSpeakerButton.setChecked(speakerOn);
    368             } else {
    369                 mDialer.setHandleVisible(true);
    370             }
    371             mApplication.cdmaOtaScreenState.otaScreenState =
    372                     CdmaOtaScreenState.OtaScreenState.OTA_STATUS_LISTENING;
    373 
    374             // Update the state of the in-call menu items.
    375             mInCallScreen.updateMenuItems();
    376         } else {
    377             if (DBG) log("OtaShowListeningScreen(): show progress screen");
    378             otaShowInProgressScreen();
    379         }
    380     }
    381 
    382     /**
    383      * Show "Programming In Progress" screen during OTA call. Shown when OTA
    384      * provisioning is in progress after user has selected an option.
    385      */
    386     private void otaShowInProgressScreen() {
    387         if (DBG) log("OtaShowInProgressScreen()...");
    388         if (!isDialerOpened()) {
    389             otaScreenInitialize();
    390             mOtaWidgetData.otaTextListenProgressContainer.setVisibility(View.VISIBLE);
    391             mOtaWidgetData.otaTextListenProgress.setText(R.string.ota_progress);
    392             mOtaWidgetData.otaTextProgressBar.setVisibility(View.VISIBLE);
    393             mOtaWidgetData.callCardOtaButtonsListenProgress.setVisibility(View.VISIBLE);
    394             mOtaWidgetData.otaSpeakerButton.setVisibility(View.VISIBLE);
    395             boolean speakerOn = PhoneUtils.isSpeakerOn(mContext);
    396             mOtaWidgetData.otaSpeakerButton.setChecked(speakerOn);
    397         } else {
    398             mDialer.setHandleVisible(true);
    399         }
    400         mApplication.cdmaOtaScreenState.otaScreenState =
    401             CdmaOtaScreenState.OtaScreenState.OTA_STATUS_PROGRESS;
    402 
    403         // Update the state of the in-call menu items.
    404         mInCallScreen.updateMenuItems();
    405     }
    406 
    407     /**
    408      * Show programming failure dialog when OTA provisioning fails.
    409      * If OTA provisioning attempts fail more than 3 times, then unsuccessful
    410      * dialog is shown. Otherwise a two-second notice is shown with unsuccessful
    411      * information. When notice expires, phone returns to activation screen.
    412      */
    413     private void otaShowProgramFailure(int length) {
    414         if (DBG) log("OtaShowProgramFailure()...");
    415         mApplication.cdmaOtaProvisionData.activationCount++;
    416         if ((mApplication.cdmaOtaProvisionData.activationCount <
    417                 mApplication.cdmaOtaConfigData.otaShowActivateFailTimes)
    418                 && (mApplication.cdmaOtaConfigData.otaShowActivationScreen ==
    419                 OTA_SHOW_ACTIVATION_SCREEN_ON)) {
    420             if (DBG) log("OtaShowProgramFailure(): activationCount"
    421                     + mApplication.cdmaOtaProvisionData.activationCount);
    422             if (DBG) log("OtaShowProgramFailure(): show failure notice");
    423             otaShowProgramFailureNotice(length);
    424         } else {
    425             if (DBG) log("OtaShowProgramFailure(): show failure dialog");
    426             otaShowProgramFailureDialog();
    427         }
    428     }
    429 
    430     /**
    431      * Show either programming success dialog when OTA provisioning succeeds, or
    432      * programming failure dialog when it fails. See {@link otaShowProgramFailure}
    433      * for more details.
    434      */
    435     public void otaShowSuccessFailure() {
    436         if (DBG) log("OtaShowSuccessFailure()...");
    437         otaScreenInitialize();
    438         if (DBG) log("OtaShowSuccessFailure(): isOtaCallCommitted"
    439                 + mApplication.cdmaOtaProvisionData.isOtaCallCommitted);
    440         if (mApplication.cdmaOtaProvisionData.isOtaCallCommitted) {
    441             if (DBG) log("OtaShowSuccessFailure(), show success dialog");
    442             otaShowProgramSuccessDialog();
    443         } else {
    444             if (DBG) log("OtaShowSuccessFailure(), show failure dialog");
    445             otaShowProgramFailure(OTA_FAILURE_DIALOG_TIMEOUT);
    446         }
    447         return;
    448     }
    449 
    450     /**
    451      * Show programming failure dialog when OTA provisioning fails more than 3
    452      * times.
    453      */
    454     private void otaShowProgramFailureDialog() {
    455         if (DBG) log("OtaShowProgramFailureDialog()...");
    456         mApplication.cdmaOtaScreenState.otaScreenState =
    457                 CdmaOtaScreenState.OtaScreenState.OTA_STATUS_SUCCESS_FAILURE_DLG;
    458         mOtaWidgetData.otaTitle.setText(R.string.ota_title_problem_with_activation);
    459         mOtaWidgetData.otaTextSuccessFail.setVisibility(View.VISIBLE);
    460         mOtaWidgetData.otaTextSuccessFail.setText(R.string.ota_unsuccessful);
    461         mOtaWidgetData.callCardOtaButtonsFailSuccess.setVisibility(View.VISIBLE);
    462         mOtaWidgetData.otaTryAgainButton.setVisibility(View.VISIBLE);
    463         //close the dialer if open
    464         if (isDialerOpened()) {
    465             mDialer.closeDialer(false);
    466         }
    467     }
    468 
    469     /**
    470      * Show programming success dialog when OTA provisioning succeeds.
    471      */
    472     private void otaShowProgramSuccessDialog() {
    473         if (DBG) log("OtaShowProgramSuccessDialog()...");
    474         mApplication.cdmaOtaScreenState.otaScreenState =
    475                 CdmaOtaScreenState.OtaScreenState.OTA_STATUS_SUCCESS_FAILURE_DLG;
    476         mOtaWidgetData.otaTitle.setText(R.string.ota_title_activate_success);
    477         mOtaWidgetData.otaTextSuccessFail.setVisibility(View.VISIBLE);
    478         mOtaWidgetData.otaTextSuccessFail.setText(R.string.ota_successful);
    479         mOtaWidgetData.callCardOtaButtonsFailSuccess.setVisibility(View.VISIBLE);
    480         mOtaWidgetData.otaNextButton.setVisibility(View.VISIBLE);
    481         //close the dialer if open
    482         if (isDialerOpened()) {
    483             mDialer.closeDialer(false);
    484         }
    485     }
    486 
    487     /**
    488      * Show SPC failure notice when SPC attempts exceed 15 times.
    489      * During OTA provisioning, if SPC code is incorrect OTA provisioning will
    490      * fail. When SPC attempts are over 15, it shows SPC failure notice for one minute and
    491      * then phone will power down.
    492      */
    493     private void otaShowSpcErrorNotice(int length) {
    494         if (DBG) log("OtaShowSpcErrorNotice()...");
    495         if (mOtaWidgetData.spcErrorDialog == null) {
    496             mApplication.cdmaOtaProvisionData.inOtaSpcState = true;
    497             DialogInterface.OnKeyListener keyListener;
    498             keyListener = new DialogInterface.OnKeyListener() {
    499                 public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
    500                     log("Ignoring key events...");
    501                     return true;
    502                 }};
    503             mOtaWidgetData.spcErrorDialog = new AlertDialog.Builder(mInCallScreen)
    504                     .setMessage(R.string.ota_spc_failure)
    505                     .setOnKeyListener(keyListener)
    506                     .create();
    507             mOtaWidgetData.spcErrorDialog.getWindow().addFlags(
    508                     WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
    509                     | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    510             mOtaWidgetData.spcErrorDialog.show();
    511             //close the dialer if open
    512             if (isDialerOpened()) {
    513                 mDialer.closeDialer(false);
    514             }
    515             long noticeTime = length*1000;
    516             if (DBG) log("OtaShowSpcErrorNotice(), remaining SPC noticeTime" + noticeTime);
    517             mInCallScreen.requestCloseSpcErrorNotice(noticeTime);
    518         }
    519     }
    520 
    521     /**
    522      * When SPC notice times out, force phone to power down.
    523      */
    524     public void onOtaCloseSpcNotice() {
    525         if (DBG) log("onOtaCloseSpcNotice(), send shutdown intent");
    526         Intent shutdown = new Intent(Intent.ACTION_REQUEST_SHUTDOWN);
    527         shutdown.putExtra(Intent.EXTRA_KEY_CONFIRM, false);
    528         shutdown.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    529         mContext.startActivity(shutdown);
    530     }
    531 
    532     /**
    533      * Show two-second notice when OTA provisioning fails and number of failed attempts
    534      * is less then 3.
    535      */
    536     private void otaShowProgramFailureNotice(int length) {
    537         if (DBG) log("OtaShowProgramFailureNotice()...");
    538         if (mOtaWidgetData.otaFailureDialog == null) {
    539             mOtaWidgetData.otaFailureDialog = new AlertDialog.Builder(mInCallScreen)
    540                     .setMessage(R.string.ota_failure)
    541                     .create();
    542             mOtaWidgetData.otaFailureDialog.getWindow().addFlags(
    543                     WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
    544                     | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    545             mOtaWidgetData.otaFailureDialog.show();
    546 
    547             long noticeTime = length*1000;
    548             mInCallScreen.requestCloseOtaFailureNotice(noticeTime);
    549         }
    550     }
    551 
    552     /**
    553      * Handle OTA unsuccessful notice expiry. Dismisses the
    554      * two-second notice and shows the activation screen.
    555      */
    556     public void onOtaCloseFailureNotice() {
    557         if (DBG) log("onOtaCloseFailureNotice()...");
    558         if (mOtaWidgetData.otaFailureDialog != null) {
    559             mOtaWidgetData.otaFailureDialog.dismiss();
    560             mOtaWidgetData.otaFailureDialog = null;
    561         }
    562         otaShowActivateScreen();
    563     }
    564 
    565     /**
    566      * Initialize all OTA UI elements to be gone. Also set inCallPanel,
    567      * callCard and the dialpad handle to be gone. This is called before any OTA screen
    568      * gets drawn.
    569      */
    570     private void otaScreenInitialize() {
    571         if (DBG) log("OtaScreenInitialize()...");
    572 
    573         if (mInCallPanel != null) mInCallPanel.setVisibility(View.GONE);
    574         if (mCallCard != null) mCallCard.hideCallCardElements();
    575         mDialer.setHandleVisible(false);
    576 
    577         mOtaWidgetData.otaTitle.setText(R.string.ota_title_activate);
    578         mOtaWidgetData.otaTextActivate.setVisibility(View.GONE);
    579         mOtaWidgetData.otaTextListenProgressContainer.setVisibility(View.GONE);
    580         mOtaWidgetData.otaTextProgressBar.setVisibility(View.GONE);
    581         mOtaWidgetData.otaTextSuccessFail.setVisibility(View.GONE);
    582         mOtaWidgetData.callCardOtaButtonsActivate.setVisibility(View.GONE);
    583         mOtaWidgetData.callCardOtaButtonsListenProgress.setVisibility(View.GONE);
    584         mOtaWidgetData.callCardOtaButtonsFailSuccess.setVisibility(View.GONE);
    585         mOtaWidgetData.otaDtmfDialerView.setVisibility(View.GONE);
    586         mOtaWidgetData.otaSpeakerButton.setVisibility(View.GONE);
    587         mOtaWidgetData.otaTryAgainButton.setVisibility(View.GONE);
    588         mOtaWidgetData.otaNextButton.setVisibility(View.GONE);
    589         mOtaWidgetData.otaCallCardBase.setVisibility(View.VISIBLE);
    590         mOtaWidgetData.otaSkipButton.setVisibility(View.VISIBLE);
    591     }
    592 
    593     public void hideOtaScreen() {
    594         if (DBG) log("hideOtaScreen()...");
    595 
    596         mOtaWidgetData.callCardOtaButtonsActivate.setVisibility(View.GONE);
    597         mOtaWidgetData.callCardOtaButtonsListenProgress.setVisibility(View.GONE);
    598         mOtaWidgetData.callCardOtaButtonsFailSuccess.setVisibility(View.GONE);
    599         mOtaWidgetData.otaCallCardBase.setVisibility(View.GONE);
    600     }
    601 
    602     public boolean isDialerOpened() {
    603         return (mDialer != null && mDialer.isOpened());
    604     }
    605 
    606     /**
    607      * Show the appropriate OTA screen based on the current state of OTA call.
    608      * Shown whenever calling screen is resumed.
    609      */
    610     public void otaShowProperScreen() {
    611         if (DBG) log("otaShowProperScreen()...");
    612         if (mInCallScreen.isForegroundActivity()) {
    613             if (DBG) log("otaShowProperScreen(), OTA is foreground activity, currentstate ="
    614                     + mApplication.cdmaOtaScreenState.otaScreenState);
    615             if (mInCallPanel != null) {
    616                 mInCallPanel.setVisibility(View.GONE);
    617             }
    618             if (mApplication.cdmaOtaScreenState.otaScreenState
    619                     == CdmaOtaScreenState.OtaScreenState.OTA_STATUS_ACTIVATION) {
    620                 otaShowActivateScreen();
    621             } else if (mApplication.cdmaOtaScreenState.otaScreenState
    622                     == CdmaOtaScreenState.OtaScreenState.OTA_STATUS_LISTENING) {
    623                 otaShowListeningScreen();
    624             } else if (mApplication.cdmaOtaScreenState.otaScreenState
    625                     == CdmaOtaScreenState.OtaScreenState.OTA_STATUS_PROGRESS) {
    626                 otaShowInProgressScreen();
    627             }
    628 
    629             if (mApplication.cdmaOtaProvisionData.inOtaSpcState) {
    630                 otaShowSpcErrorNotice(getOtaSpcDisplayTime());
    631             }
    632         }
    633     }
    634 
    635     /**
    636      * Read configuration values for each OTA screen from config.xml.
    637      * These configuration values control visibility of each screen.
    638      */
    639     private void readXmlSettings() {
    640         if (DBG) log("readXmlSettings()...");
    641         if (mApplication.cdmaOtaConfigData.configComplete) {
    642             return;
    643         }
    644 
    645         mApplication.cdmaOtaConfigData.configComplete = true;
    646         int tmpOtaShowActivationScreen =
    647                 mContext.getResources().getInteger(R.integer.OtaShowActivationScreen);
    648         mApplication.cdmaOtaConfigData.otaShowActivationScreen = tmpOtaShowActivationScreen;
    649         if (DBG) log("readXmlSettings(), otaShowActivationScreen"
    650                 + mApplication.cdmaOtaConfigData.otaShowActivationScreen);
    651 
    652         int tmpOtaShowListeningScreen =
    653                 mContext.getResources().getInteger(R.integer.OtaShowListeningScreen);
    654         mApplication.cdmaOtaConfigData.otaShowListeningScreen = tmpOtaShowListeningScreen;
    655         if (DBG) log("readXmlSettings(), otaShowListeningScreen"
    656                 + mApplication.cdmaOtaConfigData.otaShowListeningScreen);
    657 
    658         int tmpOtaShowActivateFailTimes =
    659                 mContext.getResources().getInteger(R.integer.OtaShowActivateFailTimes);
    660         mApplication.cdmaOtaConfigData.otaShowActivateFailTimes = tmpOtaShowActivateFailTimes;
    661         if (DBG) log("readXmlSettings(), otaShowActivateFailTimes"
    662                 + mApplication.cdmaOtaConfigData.otaShowActivateFailTimes);
    663 
    664         int tmpOtaPlaySuccessFailureTone =
    665                 mContext.getResources().getInteger(R.integer.OtaPlaySuccessFailureTone);
    666         mApplication.cdmaOtaConfigData.otaPlaySuccessFailureTone = tmpOtaPlaySuccessFailureTone;
    667         if (DBG) log("readXmlSettings(), otaPlaySuccessFailureTone"
    668                 + mApplication.cdmaOtaConfigData.otaPlaySuccessFailureTone);
    669     }
    670 
    671     /**
    672      * Handle the click events for OTA buttons.
    673      */
    674     public void onClickHandler(int id) {
    675         switch (id) {
    676             case R.id.otaEndButton:
    677                 onClickOtaEndButton();
    678                 break;
    679 
    680             case R.id.otaSpeakerButton:
    681                 onClickOtaSpeakerButton();
    682                 break;
    683 
    684             case R.id.otaActivateButton:
    685                 onClickOtaActivateButton();
    686                 break;
    687 
    688             case R.id.otaSkipButton:
    689                 onClickOtaActivateSkipButton();
    690                 break;
    691 
    692             case R.id.otaNextButton:
    693                 onClickOtaActivateNextButton();
    694                 break;
    695 
    696             case R.id.otaTryAgainButton:
    697                 onClickOtaTryAgainButton();
    698                 break;
    699 
    700             default:
    701                 if (DBG) log ("onClickHandler: received a click event for unrecognized id");
    702                 break;
    703         }
    704     }
    705 
    706     private void onClickOtaTryAgainButton() {
    707         if (DBG) log("Activation Try Again Clicked!");
    708         if (!mApplication.cdmaOtaProvisionData.inOtaSpcState) {
    709             otaShowActivateScreen();
    710         }
    711     }
    712 
    713     private void onClickOtaEndButton() {
    714         if (DBG) log("Activation End Call Button Clicked!");
    715         if (!mApplication.cdmaOtaProvisionData.inOtaSpcState) {
    716             if (PhoneUtils.hangup(mApplication.phone) == false) {
    717                 // If something went wrong when placing the OTA call,
    718                 // the screen is not updated by the call disconnect
    719                 // handler and we have to do it here
    720                 setSpeaker(false);
    721                 mInCallScreen.handleOtaCallEnd();
    722             }
    723         }
    724     }
    725 
    726     private void onClickOtaSpeakerButton() {
    727         if (DBG) log("OTA Speaker button Clicked!");
    728         if (!mApplication.cdmaOtaProvisionData.inOtaSpcState) {
    729             boolean isChecked = !PhoneUtils.isSpeakerOn(mContext);
    730             setSpeaker(isChecked);
    731         }
    732     }
    733 
    734     private void onClickOtaActivateButton() {
    735         if (DBG) log("Call Activation Clicked!");
    736         otaPerformActivation();
    737     }
    738 
    739     private void onClickOtaActivateSkipButton() {
    740         if (DBG) log("Activation Skip Clicked!");
    741         DialogInterface.OnKeyListener keyListener;
    742         keyListener = new DialogInterface.OnKeyListener() {
    743             public boolean onKey(DialogInterface dialog, int keyCode,
    744                     KeyEvent event) {
    745                 if (DBG) log("Ignoring key events...");
    746                 return true;
    747             }
    748         };
    749         mOtaWidgetData.otaSkipConfirmationDialog = new AlertDialog.Builder(mInCallScreen)
    750                 .setTitle(R.string.ota_skip_activation_dialog_title)
    751                 .setMessage(R.string.ota_skip_activation_dialog_message)
    752                 .setPositiveButton(
    753                     R.string.ota_skip_activation_dialog_skip_label,
    754                     new AlertDialog.OnClickListener() {
    755                         public void onClick(DialogInterface dialog, int which) {
    756                             otaSkipActivation();
    757                         }
    758                     })
    759                 .setNegativeButton(
    760                     R.string.ota_skip_activation_dialog_continue_label,
    761                     new AlertDialog.OnClickListener() {
    762                         public void onClick(DialogInterface dialog, int which) {
    763                             otaPerformActivation();
    764                         }
    765                     })
    766                 .setOnKeyListener(keyListener)
    767                 .create();
    768         mOtaWidgetData.otaSkipConfirmationDialog.show();
    769     }
    770 
    771     private void onClickOtaActivateNextButton() {
    772         if (DBG) log("Dialog Next Clicked!");
    773         if (!mApplication.cdmaOtaProvisionData.inOtaSpcState) {
    774             mApplication.cdmaOtaScreenState.otaScreenState =
    775                     CdmaOtaScreenState.OtaScreenState.OTA_STATUS_UNDEFINED;
    776             otaShowHome();
    777         }
    778     }
    779 
    780     public void dismissAllOtaDialogs() {
    781         if (mOtaWidgetData.spcErrorDialog != null) {
    782             if (DBG) log("- DISMISSING mSpcErrorDialog.");
    783             mOtaWidgetData.spcErrorDialog.dismiss();
    784             mOtaWidgetData.spcErrorDialog = null;
    785         }
    786         if (mOtaWidgetData.otaFailureDialog != null) {
    787             if (DBG) log("- DISMISSING mOtaFailureDialog.");
    788             mOtaWidgetData.otaFailureDialog.dismiss();
    789             mOtaWidgetData.otaFailureDialog = null;
    790         }
    791     }
    792 
    793     private int getOtaSpcDisplayTime() {
    794         if (DBG) log("getOtaSpcDisplayTime()...");
    795         int tmpSpcTime = 1;
    796         if (mApplication.cdmaOtaProvisionData.inOtaSpcState) {
    797             long tmpOtaSpcRunningTime = 0;
    798             long tmpOtaSpcLeftTime = 0;
    799             tmpOtaSpcRunningTime = SystemClock.elapsedRealtime();
    800             tmpOtaSpcLeftTime =
    801                 tmpOtaSpcRunningTime - mApplication.cdmaOtaProvisionData.otaSpcUptime;
    802             if (tmpOtaSpcLeftTime >= OTA_SPC_TIMEOUT*1000) {
    803                 tmpSpcTime = 1;
    804             } else {
    805                 tmpSpcTime = OTA_SPC_TIMEOUT - (int)tmpOtaSpcLeftTime/1000;
    806             }
    807         }
    808         if (DBG) log("getOtaSpcDisplayTime(), time for SPC error notice: " + tmpSpcTime);
    809         return tmpSpcTime;
    810     }
    811 
    812     /**
    813      * Initialize the OTA widgets for all OTA screens.
    814      */
    815     private void initOtaInCallScreen() {
    816         if (DBG) log("initOtaInCallScreen()...");
    817         mOtaWidgetData.otaTitle = (TextView) mInCallScreen.findViewById(R.id.otaTitle);
    818         mOtaWidgetData.otaTextActivate = (TextView) mInCallScreen.findViewById(R.id.otaActivate);
    819         mOtaWidgetData.otaTextActivate.setVisibility(View.GONE);
    820         mOtaWidgetData.otaTextListenProgressContainer =
    821                 (ScrollView) mInCallScreen.findViewById(R.id.otaListenProgressContainer);
    822         mOtaWidgetData.otaTextListenProgress =
    823                 (TextView) mInCallScreen.findViewById(R.id.otaListenProgress);
    824         mOtaWidgetData.otaTextProgressBar =
    825                 (ProgressBar) mInCallScreen.findViewById(R.id.progress_large);
    826         mOtaWidgetData.otaTextProgressBar.setIndeterminate(true);
    827         mOtaWidgetData.otaTextSuccessFail =
    828                 (TextView) mInCallScreen.findViewById(R.id.otaSuccessFailStatus);
    829 
    830         mOtaWidgetData.otaCallCardBase = (View) mInCallScreen.findViewById(R.id.otaBase);
    831         mOtaWidgetData.callCardOtaButtonsListenProgress =
    832                 (View) mInCallScreen.findViewById(R.id.callCardOtaListenProgress);
    833         mOtaWidgetData.callCardOtaButtonsActivate =
    834                 (View) mInCallScreen.findViewById(R.id.callCardOtaActivate);
    835         mOtaWidgetData.callCardOtaButtonsFailSuccess =
    836                 (View) mInCallScreen.findViewById(R.id.callCardOtaFailOrSuccessful);
    837 
    838         mOtaWidgetData.otaEndButton = (Button) mInCallScreen.findViewById(R.id.otaEndButton);
    839         mOtaWidgetData.otaEndButton.setOnClickListener(mInCallScreen);
    840         mOtaWidgetData.otaSpeakerButton =
    841                 (ToggleButton) mInCallScreen.findViewById(R.id.otaSpeakerButton);
    842         mOtaWidgetData.otaSpeakerButton.setOnClickListener(mInCallScreen);
    843         mOtaWidgetData.otaActivateButton =
    844                 (Button) mInCallScreen.findViewById(R.id.otaActivateButton);
    845         mOtaWidgetData.otaActivateButton.setOnClickListener(mInCallScreen);
    846         mOtaWidgetData.otaSkipButton = (Button) mInCallScreen.findViewById(R.id.otaSkipButton);
    847         mOtaWidgetData.otaSkipButton.setOnClickListener(mInCallScreen);
    848         mOtaWidgetData.otaNextButton = (Button) mInCallScreen.findViewById(R.id.otaNextButton);
    849         mOtaWidgetData.otaNextButton.setOnClickListener(mInCallScreen);
    850         mOtaWidgetData.otaTryAgainButton =
    851                 (Button) mInCallScreen.findViewById(R.id.otaTryAgainButton);
    852         mOtaWidgetData.otaTryAgainButton.setOnClickListener(mInCallScreen);
    853 
    854         mOtaWidgetData.otaDtmfDialerView =
    855                 (DTMFTwelveKeyDialerView) mInCallScreen.findViewById(R.id.otaDtmfDialer);
    856         // Sanity-check: the otaDtmfDialer widget should *always* be present.
    857         if (mOtaWidgetData.otaDtmfDialerView == null) {
    858             Log.e(LOG_TAG, "onCreate: couldn't find otaDtmfDialer", new IllegalStateException());
    859         }
    860 
    861 
    862         // Create a new DTMFTwelveKeyDialer instance purely for use by the
    863         // DTMFTwelveKeyDialerView ("otaDtmfDialerView") that comes from
    864         // otacall_card.xml.
    865         // (But note that mDialer is a separate DTMFTwelveKeyDialer
    866         // instance, that belongs to the InCallScreen.  This is confusing;
    867         // see the TODO comment above.)
    868         mOtaCallCardDtmfDialer = new DTMFTwelveKeyDialer(mInCallScreen,
    869                                                          mOtaWidgetData.otaDtmfDialerView,
    870                                                          null /* no SlidingDrawer used here */);
    871 
    872         // Initialize the new DTMFTwelveKeyDialer instance.  This is
    873         // needed to play local DTMF tones.
    874         mOtaCallCardDtmfDialer.startDialerSession();
    875 
    876         mOtaWidgetData.otaDtmfDialerView.setDialer(mOtaCallCardDtmfDialer);
    877     }
    878 
    879     /**
    880      * Clear out all OTA UI widget elements. Needs to get called
    881      * when OTA call ends or InCallScreen is destroyed.
    882      * @param disableSpeaker parameter control whether Speaker should be turned off.
    883      */
    884     public void cleanOtaScreen(boolean disableSpeaker) {
    885         if (DBG) log("OTA ends, cleanOtaScreen!");
    886 
    887         mApplication.cdmaOtaScreenState.otaScreenState =
    888                 CdmaOtaScreenState.OtaScreenState.OTA_STATUS_UNDEFINED;
    889         mApplication.cdmaOtaProvisionData.isOtaCallCommitted = false;
    890         mApplication.cdmaOtaProvisionData.isOtaCallIntentProcessed = false;
    891         mApplication.cdmaOtaProvisionData.inOtaSpcState = false;
    892         mApplication.cdmaOtaProvisionData.activationCount = 0;
    893         mApplication.cdmaOtaProvisionData.otaSpcUptime = 0;
    894         mApplication.cdmaOtaInCallScreenUiState.state = State.UNDEFINED;
    895 
    896         if (mInCallPanel != null) mInCallPanel.setVisibility(View.VISIBLE);
    897         if (mCallCard != null) mCallCard.hideCallCardElements();
    898         mDialer.setHandleVisible(true);
    899 
    900         // Free resources from the DTMFTwelveKeyDialer instance we created
    901         // in initOtaInCallScreen().
    902         if (mOtaCallCardDtmfDialer != null) {
    903             mOtaCallCardDtmfDialer.stopDialerSession();
    904         }
    905 
    906         mOtaWidgetData.otaTextActivate.setVisibility(View.GONE);
    907         mOtaWidgetData.otaTextListenProgressContainer.setVisibility(View.GONE);
    908         mOtaWidgetData.otaTextProgressBar.setVisibility(View.GONE);
    909         mOtaWidgetData.otaTextSuccessFail.setVisibility(View.GONE);
    910         mOtaWidgetData.callCardOtaButtonsActivate.setVisibility(View.GONE);
    911         mOtaWidgetData.callCardOtaButtonsListenProgress.setVisibility(View.GONE);
    912         mOtaWidgetData.callCardOtaButtonsFailSuccess.setVisibility(View.GONE);
    913         mOtaWidgetData.otaCallCardBase.setVisibility(View.GONE);
    914         mOtaWidgetData.otaDtmfDialerView.setVisibility(View.GONE);
    915         mOtaWidgetData.otaNextButton.setVisibility(View.GONE);
    916         mOtaWidgetData.otaTryAgainButton.setVisibility(View.GONE);
    917 
    918         // turn off the speaker in case it was turned on
    919         // but the OTA call could not be completed
    920         if (disableSpeaker) {
    921             setSpeaker(false);
    922         }
    923     }
    924 
    925     /**
    926      * Defines OTA information that needs to be maintained during
    927      * an OTA call when display orientation changes.
    928      */
    929     public static class CdmaOtaProvisionData {
    930         public boolean isOtaCallCommitted;
    931         public boolean isOtaCallIntentProcessed;
    932         public boolean inOtaSpcState;
    933         public int activationCount;
    934         public long otaSpcUptime;
    935     }
    936 
    937     /**
    938      * Defines OTA screen configuration items read from config.xml
    939      * and used to control OTA display.
    940      */
    941     public static class CdmaOtaConfigData {
    942         public int otaShowActivationScreen;
    943         public int otaShowListeningScreen;
    944         public int otaShowActivateFailTimes;
    945         public int otaPlaySuccessFailureTone;
    946         public boolean configComplete;
    947         public CdmaOtaConfigData() {
    948             if (DBG) log("CdmaOtaConfigData constructor!");
    949             otaShowActivationScreen = OTA_SHOW_ACTIVATION_SCREEN_OFF;
    950             otaShowListeningScreen = OTA_SHOW_LISTENING_SCREEN_OFF;
    951             otaShowActivateFailTimes = OTA_SHOW_ACTIVATE_FAIL_COUNT_OFF;
    952             otaPlaySuccessFailureTone = OTA_PLAY_SUCCESS_FAILURE_TONE_OFF;
    953         }
    954     }
    955 
    956     /**
    957      * The state of the OTA InCallScreen UI.
    958      */
    959     public static class CdmaOtaInCallScreenUiState {
    960         public enum State {
    961             UNDEFINED,
    962             NORMAL,
    963             ENDED
    964         }
    965 
    966         public State state;
    967 
    968         public CdmaOtaInCallScreenUiState() {
    969             if (DBG) log("CdmaOtaInCallScreenState: constructor init to UNDEFINED");
    970             state = CdmaOtaInCallScreenUiState.State.UNDEFINED;
    971         }
    972 
    973         // the pending intent used to report when the user skips ota provisioning
    974         public PendingIntent reportSkipPendingIntent;
    975     }
    976 
    977     /**
    978      * Save the Ota InCallScreen UI state
    979      */
    980     public void setCdmaOtaInCallScreenUiState(CdmaOtaInCallScreenUiState.State state) {
    981         if (DBG) log("setCdmaOtaInCallScreenState: " + state);
    982         mApplication.cdmaOtaInCallScreenUiState.state = state;
    983     }
    984 
    985     /**
    986      * Get the Ota InCallScreen UI state
    987      */
    988     public CdmaOtaInCallScreenUiState.State getCdmaOtaInCallScreenUiState() {
    989         if (DBG) log("getCdmaOtaInCallScreenState: " + mApplication.cdmaOtaInCallScreenUiState.state);
    990         return mApplication.cdmaOtaInCallScreenUiState.state;
    991     }
    992 
    993     /**
    994      * The OTA screen state machine.
    995      */
    996     public static class CdmaOtaScreenState {
    997         public enum OtaScreenState {
    998             OTA_STATUS_UNDEFINED,
    999             OTA_STATUS_ACTIVATION,
   1000             OTA_STATUS_LISTENING,
   1001             OTA_STATUS_PROGRESS,
   1002             OTA_STATUS_SUCCESS_FAILURE_DLG
   1003         }
   1004 
   1005         public OtaScreenState otaScreenState;
   1006 
   1007         public CdmaOtaScreenState() {
   1008             otaScreenState = OtaScreenState.OTA_STATUS_UNDEFINED;
   1009         }
   1010     }
   1011 
   1012     private static void log(String msg) {
   1013         Log.d(LOG_TAG, msg);
   1014     }
   1015 
   1016     public static boolean isCdmaPhone() {
   1017         return (PhoneApp.getInstance().phone.getPhoneType() == Phone.PHONE_TYPE_CDMA);
   1018     }
   1019 }
   1020