blob: 7758b23be9e117c41d01be224352c98e26ff9e96 [file] [log] [blame]
/*
* 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;
}
}
};
}