blob: 19c4dda2f5e5d88f658ffd894c061ad6b44b4d81 [file] [log] [blame]
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001package com.android.phone;
2
3import com.android.internal.telephony.CommandException;
4
5import android.app.AlertDialog;
6import android.app.Dialog;
7import android.app.ProgressDialog;
8import android.content.DialogInterface;
9import android.preference.Preference;
10import android.preference.PreferenceActivity;
11import android.util.Log;
12import android.view.WindowManager;
13
14import java.util.ArrayList;
15
16interface 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
23public 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, mDismissAndFinish);
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}