Home | History | Annotate | Download | only in phone
      1 package com.android.phone;
      2 
      3 import android.app.AlertDialog;
      4 import android.app.Dialog;
      5 import android.app.ProgressDialog;
      6 import android.content.DialogInterface;
      7 import android.preference.Preference;
      8 import android.preference.PreferenceActivity;
      9 import android.util.Log;
     10 import android.view.WindowManager;
     11 
     12 import com.android.internal.telephony.CommandException;
     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 = "TimeConsumingPrefActivity";
     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     static final int STK_CC_SS_TO_DIAL_VIDEO_ERROR = 1000;
     57 
     58     private final ArrayList<String> mBusyList = new ArrayList<String>();
     59 
     60     protected boolean mIsForeground = false;
     61 
     62     @Override
     63     protected Dialog onCreateDialog(int id) {
     64         if (id == BUSY_READING_DIALOG || id == BUSY_SAVING_DIALOG) {
     65             ProgressDialog dialog = new ProgressDialog(this);
     66             dialog.setTitle(getText(R.string.updating_title));
     67             dialog.setIndeterminate(true);
     68 
     69             switch(id) {
     70                 case BUSY_READING_DIALOG:
     71                     dialog.setCancelable(true);
     72                     dialog.setOnCancelListener(this);
     73                     dialog.setMessage(getText(R.string.reading_settings));
     74                     return dialog;
     75                 case BUSY_SAVING_DIALOG:
     76                     dialog.setCancelable(false);
     77                     dialog.setMessage(getText(R.string.updating_settings));
     78                     return dialog;
     79             }
     80             return null;
     81         }
     82 
     83         if (id == RESPONSE_ERROR || id == RADIO_OFF_ERROR || id == EXCEPTION_ERROR
     84                 || id == FDN_CHECK_FAILURE || id == STK_CC_SS_TO_DIAL_ERROR
     85                 || id == STK_CC_SS_TO_USSD_ERROR || id == STK_CC_SS_TO_SS_ERROR
     86                 || id == STK_CC_SS_TO_DIAL_VIDEO_ERROR) {
     87             AlertDialog.Builder builder = new AlertDialog.Builder(this);
     88 
     89             int msgId;
     90             int titleId = R.string.error_updating_title;
     91 
     92             switch (id) {
     93                 case RESPONSE_ERROR:
     94                     msgId = R.string.response_error;
     95                     builder.setPositiveButton(R.string.close_dialog, mDismiss);
     96                     break;
     97                 case RADIO_OFF_ERROR:
     98                     msgId = R.string.radio_off_error;
     99                     // The error is not recoverable on dialog exit.
    100                     builder.setPositiveButton(R.string.close_dialog, mDismissAndFinish);
    101                     break;
    102                 case FDN_CHECK_FAILURE:
    103                     msgId = R.string.fdn_check_failure;
    104                     builder.setPositiveButton(R.string.close_dialog, mDismiss);
    105                     break;
    106                 case STK_CC_SS_TO_DIAL_ERROR:
    107                     msgId = R.string.stk_cc_ss_to_dial_error;
    108                     builder.setPositiveButton(R.string.close_dialog, mDismiss);
    109                     break;
    110                 case STK_CC_SS_TO_USSD_ERROR:
    111                     msgId = R.string.stk_cc_ss_to_ussd_error;
    112                     builder.setPositiveButton(R.string.close_dialog, mDismiss);
    113                     break;
    114                 case STK_CC_SS_TO_SS_ERROR:
    115                     msgId = R.string.stk_cc_ss_to_ss_error;
    116                     builder.setPositiveButton(R.string.close_dialog, mDismiss);
    117                     break;
    118                 case STK_CC_SS_TO_DIAL_VIDEO_ERROR:
    119                     msgId = R.string.stk_cc_ss_to_dial_video_error;
    120                     builder.setPositiveButton(R.string.close_dialog, mDismiss);
    121                     break;
    122                 case EXCEPTION_ERROR:
    123                 default:
    124                     msgId = R.string.exception_error;
    125                     // The error is not recoverable on dialog exit.
    126                     builder.setPositiveButton(R.string.close_dialog, mDismiss);
    127                     break;
    128             }
    129 
    130             builder.setTitle(getText(titleId));
    131             builder.setMessage(getText(msgId));
    132             builder.setCancelable(false);
    133             AlertDialog dialog = builder.create();
    134 
    135             // make the dialog more obvious by blurring the background.
    136             dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
    137 
    138             return dialog;
    139         }
    140         return null;
    141     }
    142 
    143     @Override
    144     public void onResume() {
    145         super.onResume();
    146         mIsForeground = true;
    147     }
    148 
    149     @Override
    150     public void onPause() {
    151         super.onPause();
    152         mIsForeground = false;
    153     }
    154 
    155     @Override
    156     public void onStarted(Preference preference, boolean reading) {
    157         if (DBG) dumpState();
    158         Log.i(LOG_TAG, "onStarted, preference=" + preference.getKey() + ", reading=" + reading);
    159         mBusyList.add(preference.getKey());
    160 
    161         if (mIsForeground) {
    162               if (reading) {
    163                   showDialog(BUSY_READING_DIALOG);
    164               } else {
    165                   showDialog(BUSY_SAVING_DIALOG);
    166               }
    167         }
    168 
    169     }
    170 
    171     @Override
    172     public void onFinished(Preference preference, boolean reading) {
    173         if (DBG) dumpState();
    174         Log.i(LOG_TAG, "onFinished, preference=" + preference.getKey() + ", reading=" + reading);
    175         mBusyList.remove(preference.getKey());
    176 
    177         if (mBusyList.isEmpty()) {
    178             if (reading) {
    179                 dismissDialogSafely(BUSY_READING_DIALOG);
    180             } else {
    181                 dismissDialogSafely(BUSY_SAVING_DIALOG);
    182             }
    183         }
    184         preference.setEnabled(true);
    185     }
    186 
    187     @Override
    188     public void onError(Preference preference, int error) {
    189         if (DBG) dumpState();
    190         Log.i(LOG_TAG, "onError, preference=" + preference.getKey() + ", error=" + error);
    191 
    192         if (mIsForeground) {
    193             showDialog(error);
    194         }
    195         preference.setEnabled(false);
    196     }
    197 
    198     @Override
    199     public void onException(Preference preference, CommandException exception) {
    200         if (exception.getCommandError() == CommandException.Error.FDN_CHECK_FAILURE) {
    201             onError(preference, FDN_CHECK_FAILURE);
    202         } else if (exception.getCommandError() == CommandException.Error.RADIO_NOT_AVAILABLE) {
    203             onError(preference, RADIO_OFF_ERROR);
    204         } else if (exception.getCommandError() == CommandException.Error.SS_MODIFIED_TO_DIAL) {
    205             onError(preference, STK_CC_SS_TO_DIAL_ERROR);
    206         } else if (exception.getCommandError() == CommandException.Error
    207                 .SS_MODIFIED_TO_DIAL_VIDEO) {
    208             onError(preference, STK_CC_SS_TO_DIAL_VIDEO_ERROR);
    209         } else if (exception.getCommandError() == CommandException.Error.SS_MODIFIED_TO_USSD) {
    210             onError(preference, STK_CC_SS_TO_USSD_ERROR);
    211         } else if (exception.getCommandError() == CommandException.Error.SS_MODIFIED_TO_SS) {
    212             onError(preference, STK_CC_SS_TO_SS_ERROR);
    213         } else {
    214             preference.setEnabled(false);
    215             onError(preference, EXCEPTION_ERROR);
    216         }
    217     }
    218 
    219     @Override
    220     public void onCancel(DialogInterface dialog) {
    221         if (DBG) dumpState();
    222         finish();
    223     }
    224 
    225     private void dismissDialogSafely(int id) {
    226         try {
    227             dismissDialog(id);
    228         } catch (IllegalArgumentException e) {
    229             // This is expected in the case where we were in the background
    230             // at the time we would normally have shown the dialog, so we didn't
    231             // show it.
    232         }
    233     }
    234 
    235     /* package */ void dumpState() {
    236         Log.d(LOG_TAG, "dumpState begin");
    237         for (String key : mBusyList) {
    238             Log.d(LOG_TAG, "mBusyList: key=" + key);
    239         }
    240         Log.d(LOG_TAG, "dumpState end");
    241     }
    242 }
    243