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 { onStarted(Preference preference, boolean reading)17 public void onStarted(Preference preference, boolean reading); onFinished(Preference preference, boolean reading)18 public void onFinished(Preference preference, boolean reading); onError(Preference preference, int error)19 public void onError(Preference preference, int error); onException(Preference preference, CommandException exception)20 public void onException(Preference preference, CommandException exception); 21 } 22 23 public class TimeConsumingPreferenceActivity extends PreferenceActivity 24 implements TimeConsumingPreferenceListener, DialogInterface.OnClickListener, 25 DialogInterface.OnCancelListener { 26 private static final String LOG_TAG = "TimeConsumingPreferenceActivity"; 27 private final boolean DBG = (PhoneApp.DBG_LEVEL >= 2); 28 29 private static final int BUSY_READING_DIALOG = 100; 30 private static final int BUSY_SAVING_DIALOG = 200; 31 32 static final int EXCEPTION_ERROR = 300; 33 static final int RESPONSE_ERROR = 400; 34 static final int RADIO_OFF_ERROR = 500; 35 static final int FDN_CHECK_FAILURE = 600; 36 37 private final ArrayList<String> mBusyList=new ArrayList<String> (); 38 39 protected boolean mIsForeground = false; 40 41 @Override onCreateDialog(int id)42 protected Dialog onCreateDialog(int id) { 43 if (id == BUSY_READING_DIALOG || id == BUSY_SAVING_DIALOG) { 44 ProgressDialog dialog = new ProgressDialog(this); 45 dialog.setTitle(getText(R.string.updating_title)); 46 dialog.setIndeterminate(true); 47 48 switch(id) { 49 case BUSY_READING_DIALOG: 50 dialog.setCancelable(true); 51 dialog.setOnCancelListener(this); 52 dialog.setMessage(getText(R.string.reading_settings)); 53 return dialog; 54 case BUSY_SAVING_DIALOG: 55 dialog.setCancelable(false); 56 dialog.setMessage(getText(R.string.updating_settings)); 57 return dialog; 58 } 59 return null; 60 } 61 62 if (id == RESPONSE_ERROR || id == RADIO_OFF_ERROR || id == EXCEPTION_ERROR 63 || id == FDN_CHECK_FAILURE) { 64 AlertDialog.Builder b = new AlertDialog.Builder(this); 65 66 int msgId; 67 int titleId = R.string.error_updating_title; 68 69 switch (id) { 70 case RESPONSE_ERROR: 71 msgId = R.string.response_error; 72 // Set Button 2, tells the activity that the error is 73 // recoverable on dialog exit. 74 b.setNegativeButton(R.string.close_dialog, this); 75 break; 76 case RADIO_OFF_ERROR: 77 msgId = R.string.radio_off_error; 78 // Set Button 3 79 b.setNeutralButton(R.string.close_dialog, this); 80 break; 81 case FDN_CHECK_FAILURE: 82 msgId = R.string.fdn_only_error; 83 // Set Button 2 84 b.setNegativeButton(R.string.close_dialog, this); 85 break; 86 case EXCEPTION_ERROR: 87 default: 88 msgId = R.string.exception_error; 89 // Set Button 3, tells the activity that the error is 90 // not recoverable on dialog exit. 91 b.setNeutralButton(R.string.close_dialog, this); 92 break; 93 } 94 95 b.setTitle(getText(titleId)); 96 b.setMessage(getText(msgId)); 97 b.setCancelable(false); 98 AlertDialog dialog = b.create(); 99 100 // make the dialog more obvious by blurring the background. 101 dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND); 102 103 return dialog; 104 } 105 return null; 106 } 107 108 @Override onResume()109 public void onResume() { 110 super.onResume(); 111 mIsForeground = true; 112 } 113 114 @Override onPause()115 public void onPause() { 116 super.onPause(); 117 mIsForeground = false; 118 } 119 onClick(DialogInterface dialog, int which)120 public void onClick(DialogInterface dialog, int which) { 121 dialog.dismiss(); 122 } 123 onStarted(Preference preference, boolean reading)124 public void onStarted(Preference preference, boolean reading) { 125 if (DBG) dumpState(); 126 if (DBG) Log.d(LOG_TAG, "onStarted, preference=" + preference.getKey() 127 + ", reading=" + reading); 128 mBusyList.add(preference.getKey()); 129 130 if (mIsForeground) { 131 if (reading) { 132 showDialog(BUSY_READING_DIALOG); 133 } else { 134 showDialog(BUSY_SAVING_DIALOG); 135 } 136 } 137 138 } 139 onFinished(Preference preference, boolean reading)140 public void onFinished(Preference preference, boolean reading) { 141 if (DBG) dumpState(); 142 if (DBG) Log.d(LOG_TAG, "onFinished, preference=" + preference.getKey() 143 + ", reading=" + reading); 144 mBusyList.remove(preference.getKey()); 145 146 if (mBusyList.isEmpty()) { 147 if (reading) { 148 dismissDialogSafely(BUSY_READING_DIALOG); 149 } else { 150 dismissDialogSafely(BUSY_SAVING_DIALOG); 151 } 152 } 153 } 154 onError(Preference preference, int error)155 public void onError(Preference preference, int error) { 156 if (DBG) dumpState(); 157 if (DBG) Log.d(LOG_TAG, "onError, preference=" + preference.getKey() + ", error=" + error); 158 159 if (mIsForeground) { 160 showDialog(error); 161 } 162 } 163 onException(Preference preference, CommandException exception)164 public void onException(Preference preference, CommandException exception) { 165 if (exception.getCommandError() == CommandException.Error.FDN_CHECK_FAILURE) { 166 onError(preference, FDN_CHECK_FAILURE); 167 } else { 168 preference.setEnabled(false); 169 onError(preference, EXCEPTION_ERROR); 170 } 171 } onCancel(DialogInterface dialog)172 public void onCancel(DialogInterface dialog) { 173 if (DBG) dumpState(); 174 finish(); 175 } 176 dismissDialogSafely(int id)177 private void dismissDialogSafely(int id) { 178 try { 179 dismissDialog(id); 180 } catch (IllegalArgumentException e) { 181 // This is expected in the case where we were in the background 182 // at the time we would normally have shown the dialog, so we didn't 183 // show it. 184 } 185 } 186 dumpState()187 void dumpState() { 188 Log.d(LOG_TAG, "dumpState begin"); 189 for (String key : mBusyList) { 190 Log.d(LOG_TAG, "mBusyList: key=" + key); 191 } 192 Log.d(LOG_TAG, "dumpState end"); 193 } 194 } 195