diff options
Diffstat (limited to 'src/com/android/phone/EmergencyCallbackModeExitDialog.java')
-rw-r--r-- | src/com/android/phone/EmergencyCallbackModeExitDialog.java | 347 |
1 files changed, 347 insertions, 0 deletions
diff --git a/src/com/android/phone/EmergencyCallbackModeExitDialog.java b/src/com/android/phone/EmergencyCallbackModeExitDialog.java new file mode 100644 index 00000000..7758b23b --- /dev/null +++ b/src/com/android/phone/EmergencyCallbackModeExitDialog.java @@ -0,0 +1,347 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.phone; + +import android.app.Activity; +import android.app.Dialog; +import android.app.ProgressDialog; +import android.app.AlertDialog; +import android.content.BroadcastReceiver; +import android.content.ComponentName; +import android.content.Context; +import android.content.DialogInterface; +import android.content.DialogInterface.OnDismissListener; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.ServiceConnection; +import android.content.res.Resources; +import android.os.AsyncResult; +import android.os.Bundle; +import android.os.CountDownTimer; +import android.os.Handler; +import android.os.IBinder; +import android.os.Looper; +import android.os.Message; +import android.os.SystemProperties; +import android.util.Log; + +import com.android.internal.telephony.Phone; +import com.android.internal.telephony.TelephonyIntents; +import com.android.internal.telephony.TelephonyProperties; + +/** + * Displays dialog that enables users to exit Emergency Callback Mode + * + * @see EmergencyCallbackModeService + */ +public class EmergencyCallbackModeExitDialog extends Activity implements OnDismissListener { + + /** Intent to trigger the Emergency Callback Mode exit dialog */ + static final String ACTION_SHOW_ECM_EXIT_DIALOG = + "com.android.phone.action.ACTION_SHOW_ECM_EXIT_DIALOG"; + /** Used to get the users choice from the return Intent's extra */ + public static final String EXTRA_EXIT_ECM_RESULT = "exit_ecm_result"; + + public static final int EXIT_ECM_BLOCK_OTHERS = 1; + public static final int EXIT_ECM_DIALOG = 2; + public static final int EXIT_ECM_PROGRESS_DIALOG = 3; + public static final int EXIT_ECM_IN_EMERGENCY_CALL_DIALOG = 4; + + AlertDialog mAlertDialog = null; + ProgressDialog mProgressDialog = null; + CountDownTimer mTimer = null; + EmergencyCallbackModeService mService = null; + Handler mHandler = null; + int mDialogType = 0; + long mEcmTimeout = 0; + private boolean mInEmergencyCall = false; + private static final int ECM_TIMER_RESET = 1; + private Phone mPhone = null; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Check if phone is in Emergency Callback Mode. If not, exit. + if (!Boolean.parseBoolean( + SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE))) { + finish(); + } + + mHandler = new Handler(); + + // Start thread that will wait for the connection completion so that it can get + // timeout value from the service + Thread waitForConnectionCompleteThread = new Thread(null, mTask, + "EcmExitDialogWaitThread"); + waitForConnectionCompleteThread.start(); + + // Register ECM timer reset notfication + mPhone = PhoneGlobals.getPhone(); + mPhone.registerForEcmTimerReset(mTimerResetHandler, ECM_TIMER_RESET, null); + + // Register receiver for intent closing the dialog + IntentFilter filter = new IntentFilter(); + filter.addAction(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED); + registerReceiver(mEcmExitReceiver, filter); + } + + @Override + public void onDestroy() { + super.onDestroy(); + unregisterReceiver(mEcmExitReceiver); + // Unregister ECM timer reset notification + mPhone.unregisterForEcmTimerReset(mHandler); + } + + @Override + protected void onRestoreInstanceState(Bundle savedInstanceState) { + super.onRestoreInstanceState(savedInstanceState); + mDialogType = savedInstanceState.getInt("DIALOG_TYPE"); + } + + @Override + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + outState.putInt("DIALOG_TYPE", mDialogType); + } + + /** + * Waits until bind to the service completes + */ + private Runnable mTask = new Runnable() { + public void run() { + Looper.prepare(); + + // Bind to the remote service + bindService(new Intent(EmergencyCallbackModeExitDialog.this, + EmergencyCallbackModeService.class), mConnection, Context.BIND_AUTO_CREATE); + + // Wait for bind to finish + synchronized (EmergencyCallbackModeExitDialog.this) { + try { + if (mService == null) { + EmergencyCallbackModeExitDialog.this.wait(); + } + } catch (InterruptedException e) { + Log.d("ECM", "EmergencyCallbackModeExitDialog InterruptedException: " + + e.getMessage()); + e.printStackTrace(); + } + } + + // Get timeout value and call state from the service + if (mService != null) { + mEcmTimeout = mService.getEmergencyCallbackModeTimeout(); + mInEmergencyCall = mService.getEmergencyCallbackModeCallState(); + } + + // Unbind from remote service + unbindService(mConnection); + + // Show dialog + mHandler.post(new Runnable() { + public void run() { + showEmergencyCallbackModeExitDialog(); + } + }); + } + }; + + /** + * Shows Emergency Callback Mode dialog and starts countdown timer + */ + private void showEmergencyCallbackModeExitDialog() { + + if(mInEmergencyCall) { + mDialogType = EXIT_ECM_IN_EMERGENCY_CALL_DIALOG; + showDialog(EXIT_ECM_IN_EMERGENCY_CALL_DIALOG); + } else { + if (getIntent().getAction().equals( + TelephonyIntents.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS)) { + mDialogType = EXIT_ECM_BLOCK_OTHERS; + showDialog(EXIT_ECM_BLOCK_OTHERS); + } else if (getIntent().getAction().equals(ACTION_SHOW_ECM_EXIT_DIALOG)) { + mDialogType = EXIT_ECM_DIALOG; + showDialog(EXIT_ECM_DIALOG); + } + + mTimer = new CountDownTimer(mEcmTimeout, 1000) { + @Override + public void onTick(long millisUntilFinished) { + CharSequence text = getDialogText(millisUntilFinished); + mAlertDialog.setMessage(text); + } + + @Override + public void onFinish() { + //Do nothing + } + }.start(); + } + } + + /** + * Creates dialog that enables users to exit Emergency Callback Mode + */ + @Override + protected Dialog onCreateDialog(int id) { + switch (id) { + case EXIT_ECM_BLOCK_OTHERS: + case EXIT_ECM_DIALOG: + CharSequence text = getDialogText(mEcmTimeout); + mAlertDialog = new AlertDialog.Builder(EmergencyCallbackModeExitDialog.this) + .setIcon(R.drawable.picture_emergency32x32) + .setTitle(R.string.phone_in_ecm_notification_title) + .setMessage(text) + .setPositiveButton(R.string.alert_dialog_yes, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog,int whichButton) { + // User clicked Yes. Exit Emergency Callback Mode. + mPhone.exitEmergencyCallbackMode(); + + // Show progress dialog + showDialog(EXIT_ECM_PROGRESS_DIALOG); + mTimer.cancel(); + } + }) + .setNegativeButton(R.string.alert_dialog_no, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + // User clicked No + setResult(RESULT_OK, (new Intent()).putExtra( + EXTRA_EXIT_ECM_RESULT, false)); + finish(); + } + }).create(); + mAlertDialog.setOnDismissListener(this); + return mAlertDialog; + + case EXIT_ECM_IN_EMERGENCY_CALL_DIALOG: + mAlertDialog = new AlertDialog.Builder(EmergencyCallbackModeExitDialog.this) + .setIcon(R.drawable.picture_emergency32x32) + .setTitle(R.string.phone_in_ecm_notification_title) + .setMessage(R.string.alert_dialog_in_ecm_call) + .setNeutralButton(R.string.alert_dialog_dismiss, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + // User clicked Dismiss + setResult(RESULT_OK, (new Intent()).putExtra( + EXTRA_EXIT_ECM_RESULT, false)); + finish(); + } + }).create(); + mAlertDialog.setOnDismissListener(this); + return mAlertDialog; + + case EXIT_ECM_PROGRESS_DIALOG: + mProgressDialog = new ProgressDialog(EmergencyCallbackModeExitDialog.this); + mProgressDialog.setMessage(getText(R.string.progress_dialog_exiting_ecm)); + mProgressDialog.setIndeterminate(true); + mProgressDialog.setCancelable(false); + return mProgressDialog; + + default: + return null; + } + } + + /** + * Returns dialog box text with updated timeout value + */ + private CharSequence getDialogText(long millisUntilFinished) { + // Format time + int minutes = (int)(millisUntilFinished / 60000); + String time = String.format("%d:%02d", minutes, + (millisUntilFinished % 60000) / 1000); + + switch (mDialogType) { + case EXIT_ECM_BLOCK_OTHERS: + return String.format(getResources().getQuantityText( + R.plurals.alert_dialog_not_avaialble_in_ecm, minutes).toString(), time); + case EXIT_ECM_DIALOG: + return String.format(getResources().getQuantityText(R.plurals.alert_dialog_exit_ecm, + minutes).toString(), time); + } + return null; + } + + /** + * Closes activity when dialog is dismissed + */ + public void onDismiss(DialogInterface dialog) { + EmergencyCallbackModeExitDialog.this.setResult(RESULT_OK, (new Intent()) + .putExtra(EXTRA_EXIT_ECM_RESULT, false)); + finish(); + } + + /** + * Listens for Emergency Callback Mode state change intents + */ + private BroadcastReceiver mEcmExitReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + // Received exit Emergency Callback Mode notification close all dialogs + if (intent.getAction().equals( + TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED)) { + if (intent.getBooleanExtra("phoneinECMState", false) == false) { + if (mAlertDialog != null) + mAlertDialog.dismiss(); + if (mProgressDialog != null) + mProgressDialog.dismiss(); + EmergencyCallbackModeExitDialog.this.setResult(RESULT_OK, (new Intent()) + .putExtra(EXTRA_EXIT_ECM_RESULT, true)); + finish(); + } + } + } + }; + + /** + * Class for interacting with the interface of the service + */ + private ServiceConnection mConnection = new ServiceConnection() { + public void onServiceConnected(ComponentName className, IBinder service) { + mService = ((EmergencyCallbackModeService.LocalBinder)service).getService(); + // Notify thread that connection is ready + synchronized (EmergencyCallbackModeExitDialog.this) { + EmergencyCallbackModeExitDialog.this.notify(); + } + } + + public void onServiceDisconnected(ComponentName className) { + mService = null; + } + }; + + /** + * Class for receiving framework timer reset notifications + */ + private Handler mTimerResetHandler = new Handler () { + public void handleMessage(Message msg) { + switch (msg.what) { + case ECM_TIMER_RESET: + if(!((Boolean)((AsyncResult) msg.obj).result).booleanValue()) { + EmergencyCallbackModeExitDialog.this.setResult(RESULT_OK, (new Intent()) + .putExtra(EXTRA_EXIT_ECM_RESULT, false)); + finish(); + } + break; + } + } + }; +} |