blob: 921b7f780203a3395e2f4744551b4ceac646cb34 [file] [log] [blame]
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.phone;
18
19import android.app.Activity;
20import android.app.Dialog;
21import android.app.ProgressDialog;
22import android.app.AlertDialog;
23import android.content.BroadcastReceiver;
24import android.content.ComponentName;
25import android.content.Context;
26import android.content.DialogInterface;
27import android.content.DialogInterface.OnDismissListener;
28import android.content.Intent;
29import android.content.IntentFilter;
30import android.content.ServiceConnection;
31import android.content.res.Resources;
32import android.os.AsyncResult;
33import android.os.Bundle;
34import android.os.CountDownTimer;
35import android.os.Handler;
36import android.os.IBinder;
37import android.os.Looper;
38import android.os.Message;
39import android.os.SystemProperties;
40import android.util.Log;
41
42import com.android.internal.telephony.Phone;
43import com.android.internal.telephony.TelephonyIntents;
44import com.android.internal.telephony.TelephonyProperties;
45
46/**
47 * Displays dialog that enables users to exit Emergency Callback Mode
48 *
49 * @see EmergencyCallbackModeService
50 */
51public class EmergencyCallbackModeExitDialog extends Activity implements OnDismissListener {
52
53 /** Intent to trigger the Emergency Callback Mode exit dialog */
54 static final String ACTION_SHOW_ECM_EXIT_DIALOG =
55 "com.android.phone.action.ACTION_SHOW_ECM_EXIT_DIALOG";
56 /** Used to get the users choice from the return Intent's extra */
57 public static final String EXTRA_EXIT_ECM_RESULT = "exit_ecm_result";
58
59 public static final int EXIT_ECM_BLOCK_OTHERS = 1;
60 public static final int EXIT_ECM_DIALOG = 2;
61 public static final int EXIT_ECM_PROGRESS_DIALOG = 3;
62 public static final int EXIT_ECM_IN_EMERGENCY_CALL_DIALOG = 4;
63
64 AlertDialog mAlertDialog = null;
65 ProgressDialog mProgressDialog = null;
66 CountDownTimer mTimer = null;
67 EmergencyCallbackModeService mService = null;
68 Handler mHandler = null;
69 int mDialogType = 0;
70 long mEcmTimeout = 0;
71 private boolean mInEmergencyCall = false;
72 private static final int ECM_TIMER_RESET = 1;
73 private Phone mPhone = null;
74
75 @Override
76 public void onCreate(Bundle savedInstanceState) {
77 super.onCreate(savedInstanceState);
78
79 // Check if phone is in Emergency Callback Mode. If not, exit.
80 if (!Boolean.parseBoolean(
81 SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE))) {
82 finish();
83 }
84
85 mHandler = new Handler();
86
87 // Start thread that will wait for the connection completion so that it can get
88 // timeout value from the service
89 Thread waitForConnectionCompleteThread = new Thread(null, mTask,
90 "EcmExitDialogWaitThread");
91 waitForConnectionCompleteThread.start();
92
93 // Register ECM timer reset notfication
94 mPhone = PhoneGlobals.getPhone();
95 mPhone.registerForEcmTimerReset(mTimerResetHandler, ECM_TIMER_RESET, null);
96
97 // Register receiver for intent closing the dialog
98 IntentFilter filter = new IntentFilter();
99 filter.addAction(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
100 registerReceiver(mEcmExitReceiver, filter);
101 }
102
103 @Override
104 public void onDestroy() {
105 super.onDestroy();
106 unregisterReceiver(mEcmExitReceiver);
107 // Unregister ECM timer reset notification
108 mPhone.unregisterForEcmTimerReset(mHandler);
109 }
110
111 @Override
112 protected void onRestoreInstanceState(Bundle savedInstanceState) {
113 super.onRestoreInstanceState(savedInstanceState);
114 mDialogType = savedInstanceState.getInt("DIALOG_TYPE");
115 }
116
117 @Override
118 protected void onSaveInstanceState(Bundle outState) {
119 super.onSaveInstanceState(outState);
120 outState.putInt("DIALOG_TYPE", mDialogType);
121 }
122
123 /**
124 * Waits until bind to the service completes
125 */
126 private Runnable mTask = new Runnable() {
127 public void run() {
128 Looper.prepare();
129
130 // Bind to the remote service
131 bindService(new Intent(EmergencyCallbackModeExitDialog.this,
132 EmergencyCallbackModeService.class), mConnection, Context.BIND_AUTO_CREATE);
133
134 // Wait for bind to finish
135 synchronized (EmergencyCallbackModeExitDialog.this) {
136 try {
137 if (mService == null) {
138 EmergencyCallbackModeExitDialog.this.wait();
139 }
140 } catch (InterruptedException e) {
141 Log.d("ECM", "EmergencyCallbackModeExitDialog InterruptedException: "
142 + e.getMessage());
143 e.printStackTrace();
144 }
145 }
146
147 // Get timeout value and call state from the service
148 if (mService != null) {
149 mEcmTimeout = mService.getEmergencyCallbackModeTimeout();
150 mInEmergencyCall = mService.getEmergencyCallbackModeCallState();
151 }
152
153 // Unbind from remote service
154 unbindService(mConnection);
155
156 // Show dialog
157 mHandler.post(new Runnable() {
158 public void run() {
159 showEmergencyCallbackModeExitDialog();
160 }
161 });
162 }
163 };
164
165 /**
166 * Shows Emergency Callback Mode dialog and starts countdown timer
167 */
168 private void showEmergencyCallbackModeExitDialog() {
169
170 if(mInEmergencyCall) {
171 mDialogType = EXIT_ECM_IN_EMERGENCY_CALL_DIALOG;
172 showDialog(EXIT_ECM_IN_EMERGENCY_CALL_DIALOG);
173 } else {
174 if (getIntent().getAction().equals(
175 TelephonyIntents.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS)) {
176 mDialogType = EXIT_ECM_BLOCK_OTHERS;
177 showDialog(EXIT_ECM_BLOCK_OTHERS);
178 } else if (getIntent().getAction().equals(ACTION_SHOW_ECM_EXIT_DIALOG)) {
179 mDialogType = EXIT_ECM_DIALOG;
180 showDialog(EXIT_ECM_DIALOG);
181 }
182
183 mTimer = new CountDownTimer(mEcmTimeout, 1000) {
184 @Override
185 public void onTick(long millisUntilFinished) {
186 CharSequence text = getDialogText(millisUntilFinished);
187 mAlertDialog.setMessage(text);
188 }
189
190 @Override
191 public void onFinish() {
192 //Do nothing
193 }
194 }.start();
195 }
196 }
197
198 /**
199 * Creates dialog that enables users to exit Emergency Callback Mode
200 */
201 @Override
202 protected Dialog onCreateDialog(int id) {
203 switch (id) {
204 case EXIT_ECM_BLOCK_OTHERS:
205 case EXIT_ECM_DIALOG:
206 CharSequence text = getDialogText(mEcmTimeout);
207 mAlertDialog = new AlertDialog.Builder(EmergencyCallbackModeExitDialog.this)
Tyler Gunn625eb0b2014-08-27 20:37:32 -0700208 .setIcon(R.drawable.ic_emergency_callback_mode)
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700209 .setTitle(R.string.phone_in_ecm_notification_title)
210 .setMessage(text)
211 .setPositiveButton(R.string.alert_dialog_yes,
212 new DialogInterface.OnClickListener() {
213 public void onClick(DialogInterface dialog,int whichButton) {
214 // User clicked Yes. Exit Emergency Callback Mode.
215 mPhone.exitEmergencyCallbackMode();
216
217 // Show progress dialog
218 showDialog(EXIT_ECM_PROGRESS_DIALOG);
219 mTimer.cancel();
220 }
221 })
222 .setNegativeButton(R.string.alert_dialog_no,
223 new DialogInterface.OnClickListener() {
224 public void onClick(DialogInterface dialog, int whichButton) {
225 // User clicked No
226 setResult(RESULT_OK, (new Intent()).putExtra(
227 EXTRA_EXIT_ECM_RESULT, false));
228 finish();
229 }
230 }).create();
231 mAlertDialog.setOnDismissListener(this);
232 return mAlertDialog;
233
234 case EXIT_ECM_IN_EMERGENCY_CALL_DIALOG:
235 mAlertDialog = new AlertDialog.Builder(EmergencyCallbackModeExitDialog.this)
Tyler Gunn625eb0b2014-08-27 20:37:32 -0700236 .setIcon(R.drawable.ic_emergency_callback_mode)
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700237 .setTitle(R.string.phone_in_ecm_notification_title)
238 .setMessage(R.string.alert_dialog_in_ecm_call)
239 .setNeutralButton(R.string.alert_dialog_dismiss,
240 new DialogInterface.OnClickListener() {
241 public void onClick(DialogInterface dialog, int whichButton) {
242 // User clicked Dismiss
243 setResult(RESULT_OK, (new Intent()).putExtra(
244 EXTRA_EXIT_ECM_RESULT, false));
245 finish();
246 }
247 }).create();
248 mAlertDialog.setOnDismissListener(this);
249 return mAlertDialog;
250
251 case EXIT_ECM_PROGRESS_DIALOG:
252 mProgressDialog = new ProgressDialog(EmergencyCallbackModeExitDialog.this);
253 mProgressDialog.setMessage(getText(R.string.progress_dialog_exiting_ecm));
254 mProgressDialog.setIndeterminate(true);
255 mProgressDialog.setCancelable(false);
256 return mProgressDialog;
257
258 default:
259 return null;
260 }
261 }
262
263 /**
264 * Returns dialog box text with updated timeout value
265 */
266 private CharSequence getDialogText(long millisUntilFinished) {
267 // Format time
268 int minutes = (int)(millisUntilFinished / 60000);
269 String time = String.format("%d:%02d", minutes,
270 (millisUntilFinished % 60000) / 1000);
271
272 switch (mDialogType) {
273 case EXIT_ECM_BLOCK_OTHERS:
274 return String.format(getResources().getQuantityText(
275 R.plurals.alert_dialog_not_avaialble_in_ecm, minutes).toString(), time);
276 case EXIT_ECM_DIALOG:
277 return String.format(getResources().getQuantityText(R.plurals.alert_dialog_exit_ecm,
278 minutes).toString(), time);
279 }
280 return null;
281 }
282
283 /**
284 * Closes activity when dialog is dismissed
285 */
286 public void onDismiss(DialogInterface dialog) {
287 EmergencyCallbackModeExitDialog.this.setResult(RESULT_OK, (new Intent())
288 .putExtra(EXTRA_EXIT_ECM_RESULT, false));
289 finish();
290 }
291
292 /**
293 * Listens for Emergency Callback Mode state change intents
294 */
295 private BroadcastReceiver mEcmExitReceiver = new BroadcastReceiver() {
296 @Override
297 public void onReceive(Context context, Intent intent) {
298 // Received exit Emergency Callback Mode notification close all dialogs
299 if (intent.getAction().equals(
300 TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED)) {
301 if (intent.getBooleanExtra("phoneinECMState", false) == false) {
302 if (mAlertDialog != null)
303 mAlertDialog.dismiss();
304 if (mProgressDialog != null)
305 mProgressDialog.dismiss();
306 EmergencyCallbackModeExitDialog.this.setResult(RESULT_OK, (new Intent())
307 .putExtra(EXTRA_EXIT_ECM_RESULT, true));
308 finish();
309 }
310 }
311 }
312 };
313
314 /**
315 * Class for interacting with the interface of the service
316 */
317 private ServiceConnection mConnection = new ServiceConnection() {
318 public void onServiceConnected(ComponentName className, IBinder service) {
319 mService = ((EmergencyCallbackModeService.LocalBinder)service).getService();
320 // Notify thread that connection is ready
321 synchronized (EmergencyCallbackModeExitDialog.this) {
322 EmergencyCallbackModeExitDialog.this.notify();
323 }
324 }
325
326 public void onServiceDisconnected(ComponentName className) {
327 mService = null;
328 }
329 };
330
331 /**
332 * Class for receiving framework timer reset notifications
333 */
334 private Handler mTimerResetHandler = new Handler () {
335 public void handleMessage(Message msg) {
336 switch (msg.what) {
337 case ECM_TIMER_RESET:
338 if(!((Boolean)((AsyncResult) msg.obj).result).booleanValue()) {
339 EmergencyCallbackModeExitDialog.this.setResult(RESULT_OK, (new Intent())
340 .putExtra(EXTRA_EXIT_ECM_RESULT, false));
341 finish();
342 }
343 break;
344 }
345 }
346 };
347}