Home | History | Annotate | Download | only in phone
      1 package com.android.phone;
      2 
      3 import com.android.internal.telephony.CommandException;
      4 
      5 import android.app.AlertDialog;
      6 import android.app.Dialog;
      7 import android.app.ProgressDialog;
      8 import android.content.DialogInterface;
      9 import android.preference.Preference;
     10 import android.preference.PreferenceActivity;
     11 import android.util.Log;
     12 import android.view.WindowManager;
     13 
     14 import java.util.ArrayList;
     15 
     16 interface  TimeConsumingPreferenceListener {
     17     public void onStarted(Preference preference, boolean reading);
     18     public void onFinished(Preference preference, boolean reading);
     19     public void onError(Preference preference, int error);
     20     public void onException(Preference preference, CommandException exception);
     21 }
     22 
     23 public class TimeConsumingPreferenceActivity extends PreferenceActivity
     24                         implements TimeConsumingPreferenceListener,
     25                         DialogInterface.OnCancelListener {
     26     private static final String LOG_TAG = "TimeConsumingPreferenceActivity";
     27     private final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
     28 
     29     private class DismissOnClickListener implements DialogInterface.OnClickListener {
     30         @Override
     31         public void onClick(DialogInterface dialog, int which) {
     32             dialog.dismiss();
     33         }
     34     }
     35     private class DismissAndFinishOnClickListener implements DialogInterface.OnClickListener {
     36         @Override
     37         public void onClick(DialogInterface dialog, int which) {
     38             dialog.dismiss();
     39             finish();
     40         }
     41     }
     42     private final DialogInterface.OnClickListener mDismiss = new DismissOnClickListener();
     43     private final DialogInterface.OnClickListener mDismissAndFinish
     44             = new DismissAndFinishOnClickListener();
     45 
     46     private static final int BUSY_READING_DIALOG = 100;
     47     private static final int BUSY_SAVING_DIALOG = 200;
     48 
     49     static final int EXCEPTION_ERROR = 300;
     50     static final int RESPONSE_ERROR = 400;
     51     static final int RADIO_OFF_ERROR = 500;
     52     static final int FDN_CHECK_FAILURE = 600;
     53     static final int STK_CC_SS_TO_DIAL_ERROR = 700;
     54     static final int STK_CC_SS_TO_USSD_ERROR = 800;
     55     static final int STK_CC_SS_TO_SS_ERROR = 900;
     56 
     57     private final ArrayList<String> mBusyList = new ArrayList<String>();
     58 
     59     protected boolean mIsForeground = false;
     60 
     61     @Override
     62     protected Dialog onCreateDialog(int id) {
     63         if (id == BUSY_READING_DIALOG || id == BUSY_SAVING_DIALOG) {
     64             ProgressDialog dialog = new ProgressDialog(this);
     65             dialog.setTitle(getText(R.string.updating_title));
     66             dialog.setIndeterminate(true);
     67 
     68             switch(id) {
     69                 case BUSY_READING_DIALOG:
     70                     dialog.setCancelable(true);
     71                     dialog.setOnCancelListener(this);
     72                     dialog.setMessage(getText(R.string.reading_settings));
     73                     return dialog;
     74                 case BUSY_SAVING_DIALOG:
     75                     dialog.setCancelable(false);
     76                     dialog.setMessage(getText(R.string.updating_settings));
     77                     return dialog;
     78             }
     79             return null;
     80         }
     81 
     82         if (id == RESPONSE_ERROR || id == RADIO_OFF_ERROR || id == EXCEPTION_ERROR
     83                 || id == FDN_CHECK_FAILURE || id == STK_CC_SS_TO_DIAL_ERROR
     84                 || id == STK_CC_SS_TO_USSD_ERROR || id == STK_CC_SS_TO_SS_ERROR) {
     85             AlertDialog.Builder builder = new AlertDialog.Builder(this);
     86 
     87             int msgId;
     88             int titleId = R.string.error_updating_title;
     89 
     90             switch (id) {
     91                 case RESPONSE_ERROR:
     92                     msgId = R.string.response_error;
     93                     builder.setPositiveButton(R.string.close_dialog, mDismiss);
     94                     break;
     95                 case RADIO_OFF_ERROR:
     96                     msgId = R.string.radio_off_error;
     97                     // The error is not recoverable on dialog exit.
     98                     builder.setPositiveButton(R.string.close_dialog, mDismissAndFinish);
     99                     break;
    100                 case FDN_CHECK_FAILURE:
    101                     msgId = R.string.fdn_check_failure;
    102                     builder.setPositiveButton(R.string.close_dialog, mDismiss);
    103                     break;
    104                 case STK_CC_SS_TO_DIAL_ERROR:
    105                     msgId = R.string.stk_cc_ss_to_dial_error;
    106                     builder.setPositiveButton(R.string.close_dialog, mDismiss);
    107                     break;
    108                 case STK_CC_SS_TO_USSD_ERROR:
    109                     msgId = R.string.stk_cc_ss_to_ussd_error;
    110                     builder.setPositiveButton(R.string.close_dialog, mDismiss);
    111                     break;
    112                 case STK_CC_SS_TO_SS_ERROR:
    113                     msgId = R.string.stk_cc_ss_to_ss_error;
    114                     builder.setPositiveButton(R.string.close_dialog, mDismiss);
    115                     break;
    116                 case EXCEPTION_ERROR:
    117                 default:
    118                     msgId = R.string.exception_error;
    119                     // The error is not recoverable on dialog exit.
    120                     builder.setPositiveButton(R.string.close_dialog, mDismiss);
    121                     break;
    122             }
    123 
    124             builder.setTitle(getText(titleId));
    125             builder.setMessage(getText(msgId));
    126             builder.setCancelable(false);
    127             AlertDialog dialog = builder.create();
    128 
    129             // make the dialog more obvious by blurring the background.
    130             dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
    131 
    132             return dialog;
    133         }
    134         return null;
    135     }
    136 
    137     @Override
    138     public void onResume() {
    139         super.onResume();
    140         mIsForeground = true;
    141     }
    142 
    143     @Override
    144     public void onPause() {
    145         super.onPause();
    146         mIsForeground = false;
    147     }
    148 
    149     @Override
    150     public void onStarted(Preference preference, boolean reading) {
    151         if (DBG) dumpState();
    152         if (DBG) Log.d(LOG_TAG, "onStarted, preference=" + preference.getKey()
    153                 + ", reading=" + reading);
    154         mBusyList.add(preference.getKey());
    155 
    156         if (mIsForeground) {
    157               if (reading) {
    158                   showDialog(BUSY_READING_DIALOG);
    159               } else {
    160                   showDialog(BUSY_SAVING_DIALOG);
    161               }
    162         }
    163 
    164     }
    165 
    166     @Override
    167     public void onFinished(Preference preference, boolean reading) {
    168         if (DBG) dumpState();
    169         if (DBG) Log.d(LOG_TAG, "onFinished, preference=" + preference.getKey()
    170                 + ", reading=" + reading);
    171         mBusyList.remove(preference.getKey());
    172 
    173         if (mBusyList.isEmpty()) {
    174             if (reading) {
    175                 dismissDialogSafely(BUSY_READING_DIALOG);
    176             } else {
    177                 dismissDialogSafely(BUSY_SAVING_DIALOG);
    178             }
    179         }
    180         preference.setEnabled(true);
    181     }
    182 
    183     @Override
    184     public void onError(Preference preference, int error) {
    185         if (DBG) dumpState();
    186         if (DBG) Log.d(LOG_TAG, "onError, preference=" + preference.getKey() + ", error=" + error);
    187 
    188         if (mIsForeground) {
    189             showDialog(error);
    190         }
    191         preference.setEnabled(false);
    192     }
    193 
    194     @Override
    195     public void onException(Preference preference, CommandException exception) {
    196         if (exception.getCommandError() == CommandException.Error.FDN_CHECK_FAILURE) {
    197             onError(preference, FDN_CHECK_FAILURE);
    198         } else if (exception.getCommandError() == CommandException.Error.RADIO_NOT_AVAILABLE) {
    199             onError(preference, RADIO_OFF_ERROR);
    200         } else {
    201             preference.setEnabled(false);
    202             onError(preference, EXCEPTION_ERROR);
    203         }
    204     }
    205 
    206     @Override
    207     public void onCancel(DialogInterface dialog) {
    208         if (DBG) dumpState();
    209         finish();
    210     }
    211 
    212     private void dismissDialogSafely(int id) {
    213         try {
    214             dismissDialog(id);
    215         } catch (IllegalArgumentException e) {
    216             // This is expected in the case where we were in the background
    217             // at the time we would normally have shown the dialog, so we didn't
    218             // show it.
    219         }
    220     }
    221 
    222     /* package */ void dumpState() {
    223         Log.d(LOG_TAG, "dumpState begin");
    224         for (String key : mBusyList) {
    225             Log.d(LOG_TAG, "mBusyList: key=" + key);
    226         }
    227         Log.d(LOG_TAG, "dumpState end");
    228     }
    229 }
    230