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