1/* 2 * Copyright (C) 2014 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.omadm.service; 18 19import android.app.Activity; 20import android.app.AlertDialog; 21import android.app.KeyguardManager; 22import android.app.ProgressDialog; 23import android.content.BroadcastReceiver; 24import android.content.Context; 25import android.content.DialogInterface; 26import android.content.Intent; 27import android.content.IntentFilter; 28import android.os.Bundle; 29import android.os.Handler; 30import android.os.PowerManager; 31import android.text.InputFilter; 32import android.text.InputType; 33import android.util.Log; 34import android.view.KeyEvent; 35import android.view.LayoutInflater; 36import android.view.View; 37import android.widget.EditText; 38 39import java.util.Arrays; 40 41public class DMAlertActivity extends Activity { 42 private static final String TAG = "DMAlertActivity"; 43 private static final boolean DBG = DMClientService.DBG; 44 45 private static final int DISPLAY_ALERT_DIALOG = 1; 46 47 private static final int CONFIRM_ALERT_DIALOG = 2; 48 49 private static final int TEXTINPUT_ALERT_DIALOG = 3; 50 51 private static final int SINGLECHOICE_ALERT_DIALOG = 4; 52 53 private static final int MULTICHOICE_ALERT_DIALOG = 5; 54 55 private static final int SHOW_PROGRESS_ALERT_DIALOG = 6; 56 57 private static final int HIDE_PROGRESS_ALERT_DIALOG = 7; 58 59 private static final int CANCEL_ALERT_DIALOG = 8; 60 61 private static AlertDialog mDialog; 62 63 private Runnable mDialogTimeout; 64 65 private KeyReceiver mKeyReceiver; 66 67 private static PowerManager.WakeLock wl; 68 69 private KeyguardManager.KeyguardLock mKeyguardLock; 70 71 private int mType; 72 73 private String mMessage; 74 75 private String mTitle; 76 77 private int mIcon; 78 79 private int mTimeout; 80 81 private int mMaxLength; 82 83 private EditText mInputBox; 84 85 private int mInputType; 86 87 private String[] mChoices; 88 89 private int mCheckedItem; 90 91 private boolean[] mCheckedItems; 92 93 private int mResultCode; // == DMAlert.DM_SERVICE_ALERT_RESP_SUCCESS (0) 94 95 private String mResultData; 96 97 private Handler mHandler; 98 99 @Override 100 public void onCreate(Bundle savedInstanceState) { 101 super.onCreate(savedInstanceState); 102 if (DBG) { 103 logd("onCreate"); 104 } 105 106 final Intent intent = getIntent(); 107 mMessage = intent.getStringExtra("Message"); 108 mTitle = intent.getStringExtra("Title"); 109 mIcon = intent.getIntExtra("Icon", -1); 110 mTimeout = intent.getIntExtra("Timeout", 0); 111 if (DBG) { 112 logd("mMessage: " + mMessage); 113 } 114 if (DBG) { 115 logd("mTitle: " + mTitle); 116 } 117 if (DBG) { 118 logd("mIcon: " + mIcon); 119 } 120 if (DBG) { 121 logd("mTimeout: " + mTimeout); 122 } 123 124 String action = intent.getAction(); 125 if (action.equals(DMIntent.SHOW_DISPLAY_ALERT_DLG)) { 126 mType = DISPLAY_ALERT_DIALOG; 127 } else if (action.equals(DMIntent.SHOW_CONFIRM_ALERT_DLG)) { 128 mType = CONFIRM_ALERT_DIALOG; 129 } else if (action.equals(DMIntent.SHOW_TEXTINPUT_ALERT_DLG)) { 130 mType = TEXTINPUT_ALERT_DIALOG; 131 mMaxLength = intent.getIntExtra("MaxLength", 80); 132 if (DBG) { 133 logd("mMaxLength: " + mMaxLength); 134 } 135 mInputType = intent.getIntExtra("InputType", InputType.TYPE_CLASS_TEXT); 136 if (DBG) { 137 logd("mInputType: " + mInputType); 138 } 139 mResultData = intent.getStringExtra("DefaultText"); 140 if (DBG) { 141 logd("mResultData: " + mResultData); 142 } 143 } else if (action.equals(DMIntent.SHOW_SINGLECHOICE_ALERT_DLG)) { 144 mType = SINGLECHOICE_ALERT_DIALOG; 145 mChoices = intent.getStringArrayExtra("Choices"); 146 mCheckedItem = intent.getIntExtra("CheckedItem", -1); 147 for (int i = 0; i < mChoices.length; i++) { 148 if (DMClientService.DBG) { 149 logd("mChoices: " + i + ": " + mChoices[i]); 150 } 151 } 152 if (DMClientService.DBG) { 153 logd("mCheckedItem: " + mCheckedItem); 154 } 155 } else if (action.equals(DMIntent.SHOW_MULTICHOICE_ALERT_DLG)) { 156 mType = MULTICHOICE_ALERT_DIALOG; 157 mChoices = intent.getStringArrayExtra("Choices"); 158 for (int i = 0; i < mChoices.length; i++) { 159 if (DMClientService.DBG) { 160 logd("mChoices " + i + ": " + mChoices[i]); 161 } 162 } 163 mCheckedItems = intent.getBooleanArrayExtra("CheckedItems"); 164 for (int i = 0; i < mCheckedItems.length; i++) { 165 if (DMClientService.DBG) { 166 logd("CheckedItems " + i + ": " + mCheckedItems[i]); 167 } 168 } 169 } else if (action.equals(DMIntent.SHOW_PROGRESS_ALERT_DLG)) { 170 mType = SHOW_PROGRESS_ALERT_DIALOG; 171 } else if (action.equals(DMIntent.HIDE_PROGRESS_ALERT_DLG)) { 172 mType = HIDE_PROGRESS_ALERT_DIALOG; 173 onFinish(); 174 if (DMClientService.DBG) { 175 logd("HIDE_PROGRESS_ALERT_DLG"); 176 } 177 return; 178 } else if (action.equals(DMIntent.CANCEL_ALERT_DLG)) { 179 mType = CANCEL_ALERT_DIALOG; 180 onFinish(); 181 if (DMClientService.DBG) { 182 logd("CANCEL_ALERT_DIALOG"); 183 } 184 return; 185 } else { 186 if (DMClientService.DBG) { 187 logd("TODO: new dialog type support!"); 188 } 189 return; 190 } 191 192 if (null != mDialog) { 193 if (DMClientService.DBG) { 194 logd("Cancel previous dialog!"); 195 } 196 mDialog.dismiss(); 197 mDialog = null; 198 } 199 200 setVisible(false); 201 202 showDialog(mType); 203 204 mKeyReceiver = new KeyReceiver(); 205 IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 206 IntentFilter searchkeyFilter = new IntentFilter(Intent.ACTION_SEARCH); 207 IntentFilter searchkeyFilterLongPress = new IntentFilter(Intent.ACTION_SEARCH_LONG_PRESS); 208 registerReceiver(mKeyReceiver, searchkeyFilter); 209 registerReceiver(mKeyReceiver, searchkeyFilterLongPress); 210 registerReceiver(mKeyReceiver, filter); 211 212 if (mTimeout <= 0 || mTimeout > 300) { 213 if (DMClientService.DBG) { 214 logd("Forcing the default and max Timeout to 5mins"); 215 } 216 mTimeout = 300; //forcing the default and max timeout to 5mins 217 //return; 218 } 219 220 mHandler = new Handler(); 221 mDialogTimeout = new Runnable() { 222 @Override 223 public void run() { 224 mResultCode = DMAlert.DM_SERVICE_ALERT_RESP_TIMEOUT; 225 onFinish(); 226 if (DMClientService.DBG) { 227 logd("DMAlert.DM_SERVICE_ALERT_RESP_TIMEOUT"); 228 } 229 } 230 }; 231 mHandler.postDelayed(mDialogTimeout, mTimeout * 1000); 232 } 233 234 private final class KeyReceiver extends BroadcastReceiver { 235 236 KeyReceiver() { 237 } 238 239 @Override 240 public void onReceive(Context arg0, Intent arg1) { 241 Log.i(TAG, "receive the broadcast " + arg1.getAction()); 242 mResultCode = DMAlert.DM_SERVICE_ALERT_RESP_CANCEL; 243 onFinish(); 244 } 245 } 246 247 @Override 248 protected AlertDialog onCreateDialog(int id) { 249 if (DMClientService.DBG) { 250 logd("Dialog Type: " + id); 251 } 252 getKeyGuardAndWakeLock(); 253 254 switch (id) { 255 case DISPLAY_ALERT_DIALOG: 256 mDialog = new AlertDialog.Builder(this) 257 .setTitle(mTitle) 258 .setMessage(mMessage) 259 .setCancelable(true) 260 .setView(null) 261 .create(); 262 break; 263 case CONFIRM_ALERT_DIALOG: 264 mDialog = new AlertDialog.Builder(this) 265 .setTitle(mTitle) 266 .setMessage(mMessage) 267 .setPositiveButton( 268 getResources().getString(R.string.DM_SERVICE_ALERT_BUTTON_YES), 269 mKeyYesClickListener) 270 .setNegativeButton( 271 getResources().getString(R.string.DM_SERVICE_ALERT_BUTTON_NO), 272 mKeyNoClickListener) 273 .setCancelable(true) 274 .create(); 275 break; 276 case TEXTINPUT_ALERT_DIALOG: 277 View view = LayoutInflater.from(this).inflate(R.layout.textinput_dialog, null); 278 mInputBox = (EditText) view.findViewById(R.id.textinput_content); 279 mInputBox.requestFocus(); 280 mInputBox.setText(mResultData); 281 mInputBox.setInputType(mInputType); 282 InputFilter[] f = new InputFilter[1]; 283 f[0] = new InputFilter.LengthFilter(mMaxLength); 284 mInputBox.setFilters(f); 285 286 mDialog = new AlertDialog.Builder(this) 287 .setTitle(mTitle) 288 .setMessage(mMessage) 289 .setView(view) 290 .setPositiveButton( 291 getResources().getString(R.string.DM_SERVICE_ALERT_BUTTON_YES), 292 mKeyYesClickListener) 293 .setNegativeButton( 294 getResources().getString(R.string.DM_SERVICE_ALERT_BUTTON_NO), 295 mKeyNoClickListener) 296 .create(); 297 break; 298 case SINGLECHOICE_ALERT_DIALOG: 299 mDialog = new AlertDialog.Builder(this) 300 .setTitle(mMessage) 301 .setSingleChoiceItems(mChoices, mCheckedItem, mSingleChoiceClickListener) 302 .setPositiveButton( 303 getResources().getString(R.string.DM_SERVICE_ALERT_BUTTON_YES), 304 mKeyYesClickListener) 305 .setNegativeButton( 306 getResources().getString(R.string.DM_SERVICE_ALERT_BUTTON_NO), 307 mKeyNoClickListener) 308 .setCancelable(true) 309 .create(); 310 break; 311 case MULTICHOICE_ALERT_DIALOG: 312 mDialog = new AlertDialog.Builder(this) 313 .setTitle(mMessage) 314 .setMultiChoiceItems(mChoices, mCheckedItems, mMultiChoiceClickListener) 315 .setPositiveButton( 316 getResources().getString(R.string.DM_SERVICE_ALERT_BUTTON_YES), 317 mKeyYesClickListener) 318 .setNegativeButton( 319 getResources().getString(R.string.DM_SERVICE_ALERT_BUTTON_NO), 320 mKeyNoClickListener) 321 .setCancelable(true) 322 .create(); 323 break; 324 325 case SHOW_PROGRESS_ALERT_DIALOG: 326 mDialog = new ProgressDialog(this); 327 mDialog.setTitle(mTitle); 328 mDialog.setMessage(mMessage); 329 mDialog.setCancelable(true); 330 if (DMClientService.DBG) { 331 logd("SHOW_PROGRESS_ALERT_DIALOG"); 332 } 333 break; 334 335 default: 336 Log.i(TAG, "Unknown dialog type: " + id); 337 return null; 338 } 339 340 if (-1 != mIcon) { 341 mDialog.setIcon(mIcon); 342 } 343 344 mDialog.setOnCancelListener(mOnCancelListener); 345 return mDialog; 346 } 347 348 private void getKeyGuardAndWakeLock() { 349 logd("Inside getKeyGuardAndWakeLock"); 350 PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); 351 wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | 352 PowerManager.ACQUIRE_CAUSES_WAKEUP | 353 PowerManager.ON_AFTER_RELEASE, TAG); 354 logd("Acquiring the wakelock"); 355 wl.acquire(); 356 357 KeyguardManager keyguardManager = (KeyguardManager) getSystemService( 358 Context.KEYGUARD_SERVICE); 359 mKeyguardLock = keyguardManager.newKeyguardLock(TAG); 360 logd("Disabling the KeyGuard"); 361 mKeyguardLock.disableKeyguard(); 362 } 363 364 @Override 365 public boolean onKeyDown(int keyCode, KeyEvent event) { 366 if (DMClientService.DBG) { 367 logd("onKeyDown - keyCode: " + keyCode + " DialogType: " + mType); 368 } 369 if (keyCode == KeyEvent.KEYCODE_BACK) { 370 onFinish(); 371 return true; 372 } 373 return false; 374 } 375 376 @Override 377 public void onDestroy() { 378 if (DMClientService.DBG) { 379 logd("onDestroy - DialogType: " + mType); 380 } 381 if (mKeyReceiver != null) { 382 unregisterReceiver(mKeyReceiver); 383 } 384 releaseKeyGuardAndWakeLock(); 385 super.onDestroy(); 386 } 387 388 private void onFinish() { 389 if (DMClientService.DBG) { 390 logd("OnFinish: Dialog - " + mType); 391 } 392 393 if (mTimeout > 0) { 394 mHandler.removeCallbacks(mDialogTimeout); 395 } 396 397 if (null != mDialog) { 398 mDialog.dismiss(); 399 } 400 401 mDialog = null; 402 403 if (mType == DISPLAY_ALERT_DIALOG || 404 mType == SHOW_PROGRESS_ALERT_DIALOG || 405 mType == HIDE_PROGRESS_ALERT_DIALOG || 406 mType == CANCEL_ALERT_DIALOG) { 407 finish(); 408 return; 409 } 410 411 Intent i = new Intent(DMIntent.DM_ALERT_DLG_CLOSED); 412 413 i.putExtra("ResultCode", mResultCode); 414 if (DMClientService.DBG) { 415 logd("onFinish - ResultCode: " + mResultCode); 416 } 417 418 if (mType == TEXTINPUT_ALERT_DIALOG) { 419 i.putExtra("ResultData", mResultData); 420 if (DMClientService.DBG) { 421 logd("onFinish - ResultData: " + mResultData); 422 } 423 } else if (mType == SINGLECHOICE_ALERT_DIALOG) { 424 i.putExtra("ResultCheckedItem", mCheckedItem); 425 if (DMClientService.DBG) { 426 logd("onFinish - ResultCheckedItem: " + mCheckedItem); 427 } 428 } else if (mType == MULTICHOICE_ALERT_DIALOG) { 429 i.putExtra("ResultCheckedItems", mCheckedItems); 430 if (DMClientService.DBG) { 431 logd("onFinish - ResultCheckedItems: " 432 + Arrays.toString(mCheckedItems)); 433 } 434 } 435 436 sendBroadcast(i); 437 438 finish(); 439 } 440 441 private void releaseKeyGuardAndWakeLock() { 442 logd("Inside releaseKeyGuardAndWakeLock"); 443 if (wl != null) { 444 logd("Releasing the wakelock"); 445 wl.release(); 446 wl = null; 447 } 448 449 if (mKeyguardLock != null) { 450 logd("Reenable the KeyGuard"); 451 mKeyguardLock.reenableKeyguard(); 452 mKeyguardLock = null; 453 } 454 } 455 456 private final DialogInterface.OnClickListener mKeyYesClickListener 457 = new DialogInterface.OnClickListener() { 458 @Override 459 public void onClick(DialogInterface dialog, int which) { 460 if (mTimeout > 0) { 461 mHandler.removeCallbacks(mDialogTimeout); 462 } 463 464 if (mType == TEXTINPUT_ALERT_DIALOG) { 465 mResultData = mInputBox.getText().toString(); 466 } 467 468 mResultCode = DMAlert.DM_SERVICE_ALERT_RESP_YES; 469 onFinish(); 470 if (DMClientService.DBG) { 471 logd("DMAlert.DM_SERVICE_ALERT_RESP_YES"); 472 } 473 } 474 }; 475 476 private final DialogInterface.OnClickListener mKeyNoClickListener 477 = new DialogInterface.OnClickListener() { 478 @Override 479 public void onClick(DialogInterface dialog, int which) { 480 if (mTimeout > 0) { 481 mHandler.removeCallbacks(mDialogTimeout); 482 } 483 484 mResultCode = DMAlert.DM_SERVICE_ALERT_RESP_NO; 485 onFinish(); 486 if (DMClientService.DBG) { 487 logd("DMAlert.DM_SERVICE_ALERT_RESP_NO"); 488 } 489 } 490 }; 491 492 private final DialogInterface.OnCancelListener mOnCancelListener 493 = new DialogInterface.OnCancelListener() { 494 @Override 495 public void onCancel(DialogInterface dialog) { 496 if (DMClientService.DBG) { 497 logd("OnCancel: Dialog - " + mType); 498 } 499 mResultCode = DMAlert.DM_SERVICE_ALERT_RESP_CANCEL; 500 if (DMClientService.DBG) { 501 logd("DMAlert.DM_SERVICE_ALERT_RESP_CANCEL"); 502 } 503 onFinish(); 504 } 505 }; 506 507 private final DialogInterface.OnClickListener mSingleChoiceClickListener 508 = new DialogInterface.OnClickListener() { 509 @Override 510 public void onClick(DialogInterface dialog, int which) { 511 mCheckedItem = which; 512 } 513 }; 514 515 private final DialogInterface.OnMultiChoiceClickListener mMultiChoiceClickListener 516 = new DialogInterface.OnMultiChoiceClickListener() { 517 @Override 518 public void onClick(DialogInterface dialog, int which, boolean isChecked) { 519 mCheckedItems[which] = isChecked; 520 } 521 }; 522 523 private static void logd(String msg) { 524 Log.d(TAG, msg); 525 } 526} 527 528