Blanket copy of PhoneApp to services/Telephony.
First phase of splitting out InCallUI from PhoneApp.
Change-Id: I237341c4ff00e96c677caa4580b251ef3432931b
diff --git a/src/com/android/phone/TimeConsumingPreferenceActivity.java b/src/com/android/phone/TimeConsumingPreferenceActivity.java
new file mode 100644
index 0000000..19c4dda
--- /dev/null
+++ b/src/com/android/phone/TimeConsumingPreferenceActivity.java
@@ -0,0 +1,211 @@
+package com.android.phone;
+
+import com.android.internal.telephony.CommandException;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.ProgressDialog;
+import android.content.DialogInterface;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.util.Log;
+import android.view.WindowManager;
+
+import java.util.ArrayList;
+
+interface TimeConsumingPreferenceListener {
+ public void onStarted(Preference preference, boolean reading);
+ public void onFinished(Preference preference, boolean reading);
+ public void onError(Preference preference, int error);
+ public void onException(Preference preference, CommandException exception);
+}
+
+public class TimeConsumingPreferenceActivity extends PreferenceActivity
+ implements TimeConsumingPreferenceListener,
+ DialogInterface.OnCancelListener {
+ private static final String LOG_TAG = "TimeConsumingPreferenceActivity";
+ private final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
+
+ private class DismissOnClickListener implements DialogInterface.OnClickListener {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.dismiss();
+ }
+ }
+ private class DismissAndFinishOnClickListener implements DialogInterface.OnClickListener {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.dismiss();
+ finish();
+ }
+ }
+ private final DialogInterface.OnClickListener mDismiss = new DismissOnClickListener();
+ private final DialogInterface.OnClickListener mDismissAndFinish
+ = new DismissAndFinishOnClickListener();
+
+ private static final int BUSY_READING_DIALOG = 100;
+ private static final int BUSY_SAVING_DIALOG = 200;
+
+ static final int EXCEPTION_ERROR = 300;
+ static final int RESPONSE_ERROR = 400;
+ static final int RADIO_OFF_ERROR = 500;
+ static final int FDN_CHECK_FAILURE = 600;
+
+ private final ArrayList<String> mBusyList = new ArrayList<String>();
+
+ protected boolean mIsForeground = false;
+
+ @Override
+ protected Dialog onCreateDialog(int id) {
+ if (id == BUSY_READING_DIALOG || id == BUSY_SAVING_DIALOG) {
+ ProgressDialog dialog = new ProgressDialog(this);
+ dialog.setTitle(getText(R.string.updating_title));
+ dialog.setIndeterminate(true);
+
+ switch(id) {
+ case BUSY_READING_DIALOG:
+ dialog.setCancelable(true);
+ dialog.setOnCancelListener(this);
+ dialog.setMessage(getText(R.string.reading_settings));
+ return dialog;
+ case BUSY_SAVING_DIALOG:
+ dialog.setCancelable(false);
+ dialog.setMessage(getText(R.string.updating_settings));
+ return dialog;
+ }
+ return null;
+ }
+
+ if (id == RESPONSE_ERROR || id == RADIO_OFF_ERROR || id == EXCEPTION_ERROR
+ || id == FDN_CHECK_FAILURE) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+
+ int msgId;
+ int titleId = R.string.error_updating_title;
+
+ switch (id) {
+ case RESPONSE_ERROR:
+ msgId = R.string.response_error;
+ builder.setPositiveButton(R.string.close_dialog, mDismiss);
+ break;
+ case RADIO_OFF_ERROR:
+ msgId = R.string.radio_off_error;
+ // The error is not recoverable on dialog exit.
+ builder.setPositiveButton(R.string.close_dialog, mDismissAndFinish);
+ break;
+ case FDN_CHECK_FAILURE:
+ msgId = R.string.fdn_check_failure;
+ builder.setPositiveButton(R.string.close_dialog, mDismiss);
+ break;
+ case EXCEPTION_ERROR:
+ default:
+ msgId = R.string.exception_error;
+ // The error is not recoverable on dialog exit.
+ builder.setPositiveButton(R.string.close_dialog, mDismissAndFinish);
+ break;
+ }
+
+ builder.setTitle(getText(titleId));
+ builder.setMessage(getText(msgId));
+ builder.setCancelable(false);
+ AlertDialog dialog = builder.create();
+
+ // make the dialog more obvious by blurring the background.
+ dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
+
+ return dialog;
+ }
+ return null;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ mIsForeground = true;
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ mIsForeground = false;
+ }
+
+ @Override
+ public void onStarted(Preference preference, boolean reading) {
+ if (DBG) dumpState();
+ if (DBG) Log.d(LOG_TAG, "onStarted, preference=" + preference.getKey()
+ + ", reading=" + reading);
+ mBusyList.add(preference.getKey());
+
+ if (mIsForeground) {
+ if (reading) {
+ showDialog(BUSY_READING_DIALOG);
+ } else {
+ showDialog(BUSY_SAVING_DIALOG);
+ }
+ }
+
+ }
+
+ @Override
+ public void onFinished(Preference preference, boolean reading) {
+ if (DBG) dumpState();
+ if (DBG) Log.d(LOG_TAG, "onFinished, preference=" + preference.getKey()
+ + ", reading=" + reading);
+ mBusyList.remove(preference.getKey());
+
+ if (mBusyList.isEmpty()) {
+ if (reading) {
+ dismissDialogSafely(BUSY_READING_DIALOG);
+ } else {
+ dismissDialogSafely(BUSY_SAVING_DIALOG);
+ }
+ }
+ preference.setEnabled(true);
+ }
+
+ @Override
+ public void onError(Preference preference, int error) {
+ if (DBG) dumpState();
+ if (DBG) Log.d(LOG_TAG, "onError, preference=" + preference.getKey() + ", error=" + error);
+
+ if (mIsForeground) {
+ showDialog(error);
+ }
+ preference.setEnabled(false);
+ }
+
+ @Override
+ public void onException(Preference preference, CommandException exception) {
+ if (exception.getCommandError() == CommandException.Error.FDN_CHECK_FAILURE) {
+ onError(preference, FDN_CHECK_FAILURE);
+ } else {
+ preference.setEnabled(false);
+ onError(preference, EXCEPTION_ERROR);
+ }
+ }
+
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ if (DBG) dumpState();
+ finish();
+ }
+
+ private void dismissDialogSafely(int id) {
+ try {
+ dismissDialog(id);
+ } catch (IllegalArgumentException e) {
+ // This is expected in the case where we were in the background
+ // at the time we would normally have shown the dialog, so we didn't
+ // show it.
+ }
+ }
+
+ /* package */ void dumpState() {
+ Log.d(LOG_TAG, "dumpState begin");
+ for (String key : mBusyList) {
+ Log.d(LOG_TAG, "mBusyList: key=" + key);
+ }
+ Log.d(LOG_TAG, "dumpState end");
+ }
+}