OtaUtils.java revision 425b8e3c9846d5e0e76466604b35cad8856d79de
1/* 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 com.android.internal.telephony.Phone; 20 21import android.app.AlertDialog; 22import android.content.Context; 23import android.content.DialogInterface; 24import android.content.Intent; 25import android.content.pm.ResolveInfo; 26import android.os.AsyncResult; 27import android.os.Handler; 28import android.os.Message; 29import android.os.SystemClock; 30import android.os.SystemProperties; 31import android.provider.Settings; 32 33import android.util.Log; 34import android.view.KeyEvent; 35import android.view.View; 36import android.view.ViewGroup; 37import android.view.ViewStub; 38import android.view.WindowManager; 39 40import android.widget.Button; 41import android.widget.ToggleButton; 42import android.widget.ProgressBar; 43import android.widget.SlidingDrawer; 44import android.widget.TextView; 45 46/** 47 * Handles all OTA Call related logic and UI functionality. 48 * InCallScreen interacts with this class to perform OTA Call 49 */ 50 51public class OtaUtils { 52 private static final String LOG_TAG = "OtaUtils"; 53 private static final String UNACTIVATED_MIN2_VALUE = "000000"; 54 private static final String UNACTIVATED_MIN_VALUE = "1111110111"; 55 private static final boolean DBG = (PhoneApp.DBG_LEVEL >= 2); 56 57 public static final int OTA_SHOW_ACTIVATION_SCREEN_OFF = 0; 58 public static final int OTA_SHOW_ACTIVATION_SCREEN_ON = 1; 59 public static final int OTA_SHOW_LISTENING_SCREEN_OFF =0; 60 public static final int OTA_SHOW_LISTENING_SCREEN_ON =1; 61 public static final int OTA_SHOW_ACTIVATE_FAIL_COUNT_OFF = 0; 62 public static final int OTA_SHOW_ACTIVATE_FAIL_COUNT_THREE = 3; 63 public static final int OTA_PLAY_SUCCESS_FAILURE_TONE_OFF = 0; 64 public static final int OTA_PLAY_SUCCESS_FAILURE_TONE_ON = 1; 65 66 // SPC Timeout is 60 seconds 67 public final int OTA_SPC_TIMEOUT = 60; 68 public final int OTA_FAILURE_DIALOG_TIMEOUT = 2; 69 70 private InCallScreen mInCallScreen; 71 private Context mContext; 72 private PhoneApp mApplication; 73 private OtaWidgetData mOtaWidgetData; 74 private ViewGroup mInCallPanel; 75 private CallCard mCallCard; 76 private DTMFTwelveKeyDialer mDialer; 77 private SlidingDrawer mDialerDrawer; 78 79 /** 80 * OtaWidgetData class represent all OTA UI elements 81 */ 82 private class OtaWidgetData { 83 public Button otaEndButton; 84 public Button otaActivateButton; 85 public Button otaCancelButton; 86 public Button otaDialogOKButton; 87 public Button otaKeypadButton; 88 public ToggleButton otaSpeakerButton; 89 public View otaCallCardBase; 90 public View callCardOtaButtonsFailSuccess; 91 public ProgressBar otaTextProgressBar; 92 public TextView otaTextSuccessFail; 93 public View callCardOtaButtonsActivate; 94 public View callCardOtaButtonsListenProgress; 95 public TextView otaTextActivate; 96 public TextView otaTextListenProgress; 97 public AlertDialog spcErrorDialog; 98 public AlertDialog otaFailureDialog; 99 } 100 101 public OtaUtils(Context context, 102 InCallScreen inCallScreen, 103 ViewGroup inCallPanel, 104 CallCard callCard, 105 DTMFTwelveKeyDialer dialer, 106 SlidingDrawer dialerDrawer) { 107 108 if (DBG) log("Enter OtaUtil constructor"); 109 110 mInCallScreen = inCallScreen; 111 mContext = context; 112 mInCallPanel = inCallPanel; 113 mCallCard = callCard; 114 mDialer = dialer; 115 mDialerDrawer = dialerDrawer; 116 mApplication = PhoneApp.getInstance(); 117 mOtaWidgetData = new OtaWidgetData(); 118 119 // inflate OTA Call card and footers 120 ViewStub otaCallCardStub = (ViewStub) mInCallScreen.findViewById(R.id.otaCallCardStub); 121 otaCallCardStub.inflate(); 122 readXmlSettings(); 123 initOtaInCallScreen(); 124 } 125 126 /** 127 * Returns true if the phone needs activation. 128 * 129 * @param minString the phone's MIN configuration string 130 * @return true if phone needs activation 131 * @throws OtaConfigurationException if the string is invalid 132 */ 133 public static boolean needsActivation(String minString) throws IllegalArgumentException { 134 if (minString == null || (minString.length() < 6)) { 135 throw new IllegalArgumentException(); 136 } 137 return (minString.equals(UNACTIVATED_MIN_VALUE) 138 || minString.substring(0,6).equals(UNACTIVATED_MIN2_VALUE)) 139 || SystemProperties.getBoolean("test_cdma_setup", false); 140 } 141 142 /** 143 * Starts the OTA provisioning call. If the MIN isn't available yet, it returns false and adds 144 * an event to return the request to the calling app when it becomes available. 145 * 146 * @param context 147 * @param handler 148 * @param request 149 * @return true if we were able to launch Ota activity or it's not required; false otherwise 150 */ 151 public static boolean maybeDoOtaCall(Context context, Handler handler, int request) { 152 PhoneApp app = PhoneApp.getInstance(); 153 Phone phone = app.phone; 154 155 if (!isCdmaPhone()) { 156 if (DBG) Log.v("OtaUtils", "Can't run provisioning on a non-CDMA phone"); 157 return true; // sanity check - a non-cdma phone doesn't need to run this 158 } 159 160 if (!phone.isMinInfoReady()) { 161 if (DBG) log("MIN is not ready. Registering to receive notification."); 162 phone.registerForSubscriptionInfoReady(handler, request, null); 163 return false; 164 } 165 166 phone.unregisterForSubscriptionInfoReady(handler); 167 String min = phone.getCdmaMin(); 168 169 if (DBG) log("min_string: " + min); 170 171 boolean phoneNeedsActivation = false; 172 try { 173 phoneNeedsActivation = needsActivation(min); 174 } catch (IllegalArgumentException e) { 175 if (DBG) log("invalid MIN string, exit"); 176 return true; // If the MIN string is wrong, there's nothing else we can do. 177 } 178 179 if (DBG) log("phoneNeedsActivation is set to " + phoneNeedsActivation); 180 181 int otaShowActivationScreen = context.getResources().getInteger( 182 R.integer.OtaShowActivationScreen); 183 184 if (DBG) log("otaShowActivationScreen: " + otaShowActivationScreen); 185 186 if (phoneNeedsActivation && (otaShowActivationScreen == OTA_SHOW_ACTIVATION_SCREEN_ON)) { 187 app.cdmaOtaProvisionData.isOtaCallIntentProcessed = false; 188 Intent newIntent = new Intent(InCallScreen.ACTION_SHOW_ACTIVATION); 189 newIntent.setClass(context, InCallScreen.class); 190 newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 191 context.startActivity(newIntent); 192 if (DBG) log("activation intent sent."); 193 } else { 194 if (DBG) log("activation intent NOT sent."); 195 } 196 return true; 197 } 198 199 private void setSpeaker(boolean state) { 200 if (DBG) log("setSpeaker : " + state ); 201 if (state == PhoneUtils.isSpeakerOn(mContext)) { 202 if (DBG) log("no change. returning"); 203 return; 204 } 205 206 if (state && mInCallScreen.isBluetoothAvailable() 207 && mInCallScreen.isBluetoothAudioConnected()) { 208 mInCallScreen.disconnectBluetoothAudio(); 209 } 210 PhoneUtils.turnOnSpeaker(mContext, state, true); 211 } 212 213 /** 214 * Handle OTA Provision events from Framework. Possible events are: 215 * OTA Commit Event - OTA provisioning was successful 216 * SPC retries exceeded - SPC failure retries has exceeded, and Phone needs to 217 * power down. 218 */ 219 public void onOtaProvisionStatusChanged(AsyncResult r) { 220 int OtaStatus[] = (int[]) r.result; 221 if (DBG) log("onOtaProvisionStatusChanged(): OtaStatus[0]" + OtaStatus[0]); 222 223 otaShowInProgressScreen(); 224 switch(OtaStatus[0]) { 225 case Phone.CDMA_OTA_PROVISION_STATUS_SPC_RETRIES_EXCEEDED: 226 mApplication.cdmaOtaProvisionData.otaSpcUptime = SystemClock.elapsedRealtime(); 227 otaShowSpcErrorNotice(OTA_SPC_TIMEOUT); 228 // Power.shutdown(); 229 break; 230 case Phone.CDMA_OTA_PROVISION_STATUS_COMMITTED: 231 mApplication.cdmaOtaProvisionData.isOtaCallCommitted = true; 232 if (DBG) log("onOtaProvisionStatusChanged(): isOtaCallCommitted set to true"); 233 break; 234 } 235 } 236 237 private void otaShowHome() { 238 if (DBG) log("OtaShowHome()..."); 239 mApplication.cdmaOtaScreenState.otaScreenState = 240 CdmaOtaScreenState.OtaScreenState.OTA_STATUS_UNDEFINED; 241 cleanOtaScreen(); 242 Intent intent = new Intent(Intent.ACTION_MAIN); 243 intent.addCategory (Intent.CATEGORY_HOME); 244 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 245 mContext.startActivity(intent); 246 mInCallScreen.finish(); 247 return; 248 } 249 250 /** 251 * Show Activation Screen when phone powers up and OTA provision is 252 * required. Also shown when activation fails and user needs 253 * to re-attempt it. Contains ACTIVE and CANCEL buttons 254 * which allow user to start OTA activation or cancel the activation process. 255 */ 256 public void otaShowActivateScreen() { 257 if (DBG) log("OtaShowActivationScreen()..."); 258 if (mApplication.cdmaOtaConfigData.otaShowActivationScreen 259 == OTA_SHOW_ACTIVATION_SCREEN_ON) { 260 if (DBG) log("OtaShowActivationScreen(): show activation screen"); 261 if (!isDialerOpened()) { 262 otaScreenInitialize(); 263 mOtaWidgetData.otaTextActivate.setVisibility(View.VISIBLE); 264 mOtaWidgetData.callCardOtaButtonsActivate.setVisibility(View.VISIBLE); 265 } else { 266 if (mDialerDrawer != null) mDialerDrawer.setVisibility(View.VISIBLE); 267 } 268 mApplication.cdmaOtaScreenState.otaScreenState = 269 CdmaOtaScreenState.OtaScreenState.OTA_STATUS_ACTIVATION; 270 } else { 271 if (DBG) log("OtaShowActivationScreen(): show home screen"); 272 otaShowHome(); 273 } 274 } 275 276 /** 277 * Show "Listen for Instruction" screen during OTA call. Shown when OTA Call 278 * is initiated and user needs to listen for network instructions and press 279 * appropriate DTMF digits to proceed to the "Programming in Progress" phase. 280 */ 281 private void otaShowListeningScreen() { 282 if (DBG) log("OtaShowListeningScreen()..."); 283 if (mApplication.cdmaOtaConfigData.otaShowListeningScreen 284 == OTA_SHOW_LISTENING_SCREEN_ON) { 285 if (DBG) log("OtaShowListeningScreen(): show listening screen"); 286 if (!isDialerOpened()) { 287 otaScreenInitialize(); 288 mOtaWidgetData.otaTextListenProgress.setVisibility(View.VISIBLE); 289 mOtaWidgetData.otaTextListenProgress.setText(R.string.ota_listen); 290 mOtaWidgetData.callCardOtaButtonsListenProgress.setVisibility(View.VISIBLE); 291 } else { 292 if (mDialerDrawer != null) mDialerDrawer.setVisibility(View.VISIBLE); 293 } 294 mApplication.cdmaOtaScreenState.otaScreenState = 295 CdmaOtaScreenState.OtaScreenState.OTA_STATUS_LISTENING; 296 297 // Update the state of the in-call menu items. 298 mInCallScreen.updateMenuItems(); 299 } else { 300 if (DBG) log("OtaShowListeningScreen(): show progress screen"); 301 otaShowInProgressScreen(); 302 } 303 } 304 305 /** 306 * Show "Programming In Progress" screen during OTA call. Shown when OTA 307 * provisioning is in progress after user has selected an option. 308 */ 309 private void otaShowInProgressScreen() { 310 if (DBG) log("OtaShowInProgressScreen()..."); 311 if (!isDialerOpened()) { 312 otaScreenInitialize(); 313 mOtaWidgetData.otaTextListenProgress.setVisibility(View.VISIBLE); 314 mOtaWidgetData.otaTextListenProgress.setText(R.string.ota_progress); 315 mOtaWidgetData.otaTextProgressBar.setVisibility(View.VISIBLE); 316 mOtaWidgetData.callCardOtaButtonsListenProgress.setVisibility(View.VISIBLE); 317 } else { 318 if (mDialerDrawer != null) mDialerDrawer.setVisibility(View.VISIBLE); 319 } 320 mApplication.cdmaOtaScreenState.otaScreenState = 321 CdmaOtaScreenState.OtaScreenState.OTA_STATUS_PROGRESS; 322 323 // Update the state of the in-call menu items. 324 mInCallScreen.updateMenuItems(); 325 } 326 327 /** 328 * Show programming failure dialog when OTA provisioning fails. 329 * If OTA provisioning attempts fail more than 3 times, then unsuccessful 330 * dialog is shown. Otherwise a two-second notice is shown with unsuccessful 331 * information. When notice expires, phone returns to activation screen. 332 */ 333 private void otaShowProgramFailure( int length) { 334 if (DBG) log("OtaShowProgramFailure()..."); 335 mApplication.cdmaOtaProvisionData.activationCount++; 336 if ((mApplication.cdmaOtaProvisionData.activationCount < 337 mApplication.cdmaOtaConfigData.otaShowActivateFailTimes) 338 && (mApplication.cdmaOtaConfigData.otaShowActivationScreen == 339 OTA_SHOW_ACTIVATION_SCREEN_ON)) { 340 if (DBG) log("OtaShowProgramFailure(): activationCount" 341 + mApplication.cdmaOtaProvisionData.activationCount); 342 if (DBG) log("OtaShowProgramFailure(): show failure notice"); 343 otaShowProgramFailureNotice(length); 344 } else { 345 if (DBG) log("OtaShowProgramFailure(): show failure dialog"); 346 otaShowProgramFailureDialog(); 347 } 348 } 349 350 /** 351 * Show either programming success dialog when OTA provisioning succeeds, or 352 * programming failure dialog when it fails. See {@link otaShowProgramFailure} 353 * for more details. 354 */ 355 public void otaShowSuccessFailure() { 356 if (DBG) log("OtaShowSuccessFailure()..."); 357 otaScreenInitialize(); 358 if (DBG) log("OtaShowSuccessFailure(): isOtaCallCommitted" 359 + mApplication.cdmaOtaProvisionData.isOtaCallCommitted); 360 if (mApplication.cdmaOtaProvisionData.isOtaCallCommitted) { 361 if (DBG) log("OtaShowSuccessFailure(), show success dialog"); 362 otaShowProgramSuccessDialog(); 363 } else { 364 if (DBG) log("OtaShowSuccessFailure(), show failure dialog"); 365 otaShowProgramFailure(OTA_FAILURE_DIALOG_TIMEOUT); 366 } 367 return; 368 } 369 370 /** 371 * Show programming failure dialog when OTA provisioning fails more than 3 372 * times. 373 */ 374 private void otaShowProgramFailureDialog() { 375 if (DBG) log("OtaShowProgramFailureDialog()..."); 376 mApplication.cdmaOtaScreenState.otaScreenState = 377 CdmaOtaScreenState.OtaScreenState.OTA_STATUS_SUCCESS_FAILURE_DLG; 378 mOtaWidgetData.otaTextSuccessFail.setVisibility(View.VISIBLE); 379 mOtaWidgetData.otaTextSuccessFail.setText(R.string.ota_unsuccessful); 380 mOtaWidgetData.callCardOtaButtonsFailSuccess.setVisibility(View.VISIBLE); 381 //close the dialer if open 382 if (isDialerOpened()) { 383 mDialer.closeDialer(false); 384 } 385 } 386 387 /** 388 * Show programming success dialog when OTA provisioning succeeds. 389 */ 390 private void otaShowProgramSuccessDialog() { 391 if (DBG) log("OtaShowProgramSuccessDialog()..."); 392 mApplication.cdmaOtaScreenState.otaScreenState = 393 CdmaOtaScreenState.OtaScreenState.OTA_STATUS_SUCCESS_FAILURE_DLG; 394 mOtaWidgetData.otaTextSuccessFail.setVisibility(View.VISIBLE); 395 mOtaWidgetData.otaTextSuccessFail.setText(R.string.ota_successful); 396 mOtaWidgetData.callCardOtaButtonsFailSuccess.setVisibility(View.VISIBLE); 397 //close the dialer if open 398 if (isDialerOpened()) { 399 mDialer.closeDialer(false); 400 } 401 } 402 403 /** 404 * Show SPC failure notice when SPC attempts exceed 15 times. 405 * During OTA provisioning, if SPC code is incorrect OTA provisioning will 406 * fail. When SPC attempts are over 15, it shows SPC failure notice for one minute and 407 * then phone will power down. 408 */ 409 private void otaShowSpcErrorNotice(int length) { 410 if (DBG) log("OtaShowSpcErrorNotice()..."); 411 if (mOtaWidgetData.spcErrorDialog == null) { 412 mApplication.cdmaOtaProvisionData.inOtaSpcState = true; 413 DialogInterface.OnKeyListener keyListener; 414 keyListener = new DialogInterface.OnKeyListener() { 415 public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { 416 log("Ignoring key events..."); 417 return true; 418 }}; 419 mOtaWidgetData.spcErrorDialog = new AlertDialog.Builder(mInCallScreen) 420 .setMessage(R.string.ota_spc_failure) 421 .setOnKeyListener(keyListener) 422 .create(); 423 mOtaWidgetData.spcErrorDialog.getWindow().addFlags( 424 WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE 425 | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 426 mOtaWidgetData.spcErrorDialog.show(); 427 //close the dialer if open 428 if (isDialerOpened()) { 429 mDialer.closeDialer(false); 430 } 431 long noticeTime = length*1000; 432 if (DBG) log("OtaShowSpcErrorNotice(), remaining SPC noticeTime"+noticeTime); 433 mInCallScreen.postNewMessageDelay(InCallScreen.CLOSE_SPC_ERROR_NOTICE,noticeTime); 434 } 435 } 436 437 /** 438 * When SPC notice times out, force phone to power down. 439 */ 440 public void onOtaCloseSpcNotice() { 441 if (DBG) log("onOtaCloseSpcNotice(), send shutdown intent"); 442 Intent shutdown = new Intent(Intent.ACTION_REQUEST_SHUTDOWN); 443 shutdown.putExtra(Intent.EXTRA_KEY_CONFIRM, false); 444 shutdown.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 445 mContext.startActivity(shutdown); 446 } 447 448 /** 449 * Show two-second notice when OTA provisioning fails and number of failed attempts 450 * is less then 3. 451 */ 452 private void otaShowProgramFailureNotice(int length) { 453 if (DBG) log("OtaShowProgramFailureNotice()..."); 454 if (mOtaWidgetData.otaFailureDialog == null) { 455 mOtaWidgetData.otaFailureDialog = new AlertDialog.Builder(mInCallScreen) 456 .setMessage(R.string.ota_failure) 457 .create(); 458 mOtaWidgetData.otaFailureDialog.getWindow().addFlags( 459 WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE 460 | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 461 mOtaWidgetData.otaFailureDialog.show(); 462 463 long noticeTime = length*1000; 464 mInCallScreen.postNewMessageDelay(InCallScreen.CLOSE_OTA_FAILURE_NOTICE, noticeTime); 465 } 466 } 467 468 /** 469 * Handle OTA unsuccessful notice expiry. Dismisses the 470 * two-second notice and shows the activation screen. 471 */ 472 public void onOtaCloseFailureNotice() { 473 if (DBG) log("onOtaCloseFailureNotice()..."); 474 if (mOtaWidgetData.otaFailureDialog != null) { 475 mOtaWidgetData.otaFailureDialog.dismiss(); 476 mOtaWidgetData.otaFailureDialog = null; 477 } 478 otaShowActivateScreen(); 479 } 480 481 /** 482 * Initialize all OTA UI elements to be gone. Also set inCallPanel, 483 * callCard and dialerDrawer to be gone. This is called before any OTA screen 484 * gets drawn. 485 */ 486 private void otaScreenInitialize() { 487 if (DBG) log("OtaScreenInitialize()..."); 488 489 if (mInCallPanel != null) mInCallPanel.setVisibility(View.GONE); 490 if (mCallCard != null) mCallCard.hideCallCardElements(); 491 if (mDialerDrawer != null) mDialerDrawer.setVisibility(View.GONE); 492 493 mOtaWidgetData.otaTextActivate.setVisibility(View.GONE); 494 mOtaWidgetData.otaTextListenProgress.setVisibility(View.GONE); 495 mOtaWidgetData.otaTextProgressBar.setVisibility(View.GONE); 496 mOtaWidgetData.otaTextSuccessFail.setVisibility(View.GONE); 497 mOtaWidgetData.callCardOtaButtonsActivate.setVisibility(View.GONE); 498 mOtaWidgetData.callCardOtaButtonsListenProgress.setVisibility(View.GONE); 499 mOtaWidgetData.callCardOtaButtonsFailSuccess.setVisibility(View.GONE); 500 mOtaWidgetData.otaCallCardBase.setVisibility(View.VISIBLE); 501 } 502 503 public void hideOtaScreen() { 504 if (DBG) log("hideOtaScreen()..."); 505 506 mOtaWidgetData.callCardOtaButtonsActivate.setVisibility(View.GONE); 507 mOtaWidgetData.callCardOtaButtonsListenProgress.setVisibility(View.GONE); 508 mOtaWidgetData.callCardOtaButtonsFailSuccess.setVisibility(View.GONE); 509 mOtaWidgetData.otaCallCardBase.setVisibility(View.GONE); 510 } 511 512 public boolean isDialerOpened() { 513 return (mDialer != null && mDialer.isOpened()); 514 } 515 516 /** 517 * Show the appropriate OTA screen based on the current state of OTA call. 518 * Shown whenever calling screen is resumed. 519 */ 520 public void otaShowProperScreen() { 521 if (DBG) log("otaShowProperScreen()..."); 522 if (mInCallScreen.isForegroundActivity()) { 523 if (DBG) log("otaShowProperScreen(), OTA is foreground activity, currentstate =" 524 + mApplication.cdmaOtaScreenState.otaScreenState); 525 if (mInCallPanel != null) { 526 mInCallPanel.setVisibility(View.GONE); 527 } 528 if (mApplication.cdmaOtaScreenState.otaScreenState 529 == CdmaOtaScreenState.OtaScreenState.OTA_STATUS_ACTIVATION) { 530 otaShowActivateScreen(); 531 } else if (mApplication.cdmaOtaScreenState.otaScreenState 532 == CdmaOtaScreenState.OtaScreenState.OTA_STATUS_LISTENING) { 533 otaShowListeningScreen(); 534 } else if (mApplication.cdmaOtaScreenState.otaScreenState 535 == CdmaOtaScreenState.OtaScreenState.OTA_STATUS_PROGRESS) { 536 otaShowInProgressScreen(); 537 } 538 539 if (mApplication.cdmaOtaProvisionData.inOtaSpcState) { 540 otaShowSpcErrorNotice(getOtaSpcDisplayTime()); 541 } 542 } 543 } 544 545 /** 546 * Read configuration values for each OTA screen from config.xml. 547 * These configuration values control visibility of each screen. 548 */ 549 private void readXmlSettings() { 550 if (DBG) log("readXmlSettings()..."); 551 if (mApplication.cdmaOtaConfigData.configComplete) { 552 return; 553 } 554 555 mApplication.cdmaOtaConfigData.configComplete = true; 556 int tmpOtaShowActivationScreen = 557 mContext.getResources().getInteger(R.integer.OtaShowActivationScreen); 558 mApplication.cdmaOtaConfigData.otaShowActivationScreen = tmpOtaShowActivationScreen; 559 if (DBG) log("readXmlSettings(), otaShowActivationScreen" 560 + mApplication.cdmaOtaConfigData.otaShowActivationScreen); 561 562 int tmpOtaShowListeningScreen = 563 mContext.getResources().getInteger(R.integer.OtaShowListeningScreen); 564 mApplication.cdmaOtaConfigData.otaShowListeningScreen = tmpOtaShowListeningScreen; 565 if (DBG) log("readXmlSettings(), otaShowListeningScreen" 566 + mApplication.cdmaOtaConfigData.otaShowListeningScreen); 567 568 int tmpOtaShowActivateFailTimes = 569 mContext.getResources().getInteger(R.integer.OtaShowActivateFailTimes); 570 mApplication.cdmaOtaConfigData.otaShowActivateFailTimes = tmpOtaShowActivateFailTimes; 571 if (DBG) log("readXmlSettings(), otaShowActivateFailTimes" 572 + mApplication.cdmaOtaConfigData.otaShowActivateFailTimes); 573 574 int tmpOtaPlaySuccessFailureTone = 575 mContext.getResources().getInteger(R.integer.OtaPlaySuccessFailureTone); 576 mApplication.cdmaOtaConfigData.otaPlaySuccessFailureTone = tmpOtaPlaySuccessFailureTone; 577 if (DBG) log("readXmlSettings(), otaPlaySuccessFailureTone" 578 + mApplication.cdmaOtaConfigData.otaPlaySuccessFailureTone); 579 } 580 581 /** 582 * Handle the click events for OTA buttons. 583 */ 584 public void onClickHandler(int id) { 585 switch (id) { 586 case R.id.otaEndButton: 587 onClickOtaEndButton(); 588 break; 589 590 case R.id.otaSpeakerButton: 591 onClickOtaSpeakerButton(); 592 break; 593 594 case R.id.otaActivateButton: 595 onClickOtaActivateButton(); 596 break; 597 598 case R.id.otaCancelButton: 599 onClickOtaActivateCancelButton(); 600 break; 601 602 case R.id.otaOkButton: 603 onClickOtaActivateDialogOkButton(); 604 break; 605 606 case R.id.otaDialButton: 607 onClickOtaKeypadButton(); 608 break; 609 610 default: 611 if (DBG) log ("onClickHandler: received a click event for unrecognized id"); 612 break; 613 } 614 } 615 616 private void onClickOtaEndButton() { 617 if (DBG) log("Activation Cancel Clicked!"); 618 if (!mApplication.cdmaOtaProvisionData.inOtaSpcState) { 619 PhoneUtils.hangup(mApplication.phone); 620 } 621 } 622 623 private void onClickOtaSpeakerButton() { 624 if (DBG) log("OTA Speaker button Clicked!"); 625 if (!mApplication.cdmaOtaProvisionData.inOtaSpcState) { 626 boolean isChecked = !PhoneUtils.isSpeakerOn(mContext); 627 setSpeaker(isChecked); 628 } 629 } 630 631 private void onClickOtaActivateButton() { 632 if (DBG) log("Call Activation Clicked!"); 633 if (!mApplication.cdmaOtaProvisionData.inOtaSpcState) { 634 Intent newIntent = new Intent(Intent.ACTION_CALL); 635 newIntent.putExtra(Intent.EXTRA_PHONE_NUMBER, InCallScreen.OTA_NUMBER); 636 mInCallScreen.internalResolveIntent(newIntent); 637 otaShowListeningScreen(); 638 } 639 } 640 641 private void onClickOtaActivateCancelButton() { 642 if (DBG) log("Activation Cancel Clicked!"); 643 if (!mApplication.cdmaOtaProvisionData.inOtaSpcState) { 644 otaShowHome(); 645 } 646 } 647 648 private void onClickOtaActivateDialogOkButton() { 649 if (DBG) log("Dialog OK Clicked!"); 650 if (!mApplication.cdmaOtaProvisionData.inOtaSpcState) { 651 mApplication.cdmaOtaScreenState.otaScreenState = 652 CdmaOtaScreenState.OtaScreenState.OTA_STATUS_UNDEFINED; 653 otaShowHome(); 654 mInCallScreen.finish(); 655 } 656 } 657 658 private void onClickOtaKeypadButton() { 659 if (DBG) log("DTMF Keypad Button Clicked!"); 660 if ((!InCallScreen.ConfigurationHelper.isLandscape()) 661 && (!mApplication.cdmaOtaProvisionData.inOtaSpcState)) { 662 if (mDialer != null) { 663 mDialer.openDialer(true); 664 } 665 if (mDialerDrawer != null) { 666 mDialerDrawer.setVisibility(View.VISIBLE); 667 } 668 } 669 } 670 671 public void dismissAllOtaDialogs() { 672 if (mOtaWidgetData.spcErrorDialog != null) { 673 if (DBG) log("- DISMISSING mSpcErrorDialog."); 674 mOtaWidgetData.spcErrorDialog.dismiss(); 675 mOtaWidgetData.spcErrorDialog = null; 676 } 677 if (mOtaWidgetData.otaFailureDialog != null) { 678 if (DBG) log("- DISMISSING mOtaFailureDialog."); 679 mOtaWidgetData.otaFailureDialog.dismiss(); 680 mOtaWidgetData.otaFailureDialog = null; 681 } 682 } 683 684 private int getOtaSpcDisplayTime() { 685 if (DBG) log("getOtaSpcDisplayTime()..."); 686 int tmpSpcTime = 1; 687 if (mApplication.cdmaOtaProvisionData.inOtaSpcState) { 688 long tmpOtaSpcRunningTime = 0; 689 long tmpOtaSpcLeftTime = 0; 690 tmpOtaSpcRunningTime = SystemClock.elapsedRealtime(); 691 tmpOtaSpcLeftTime = 692 tmpOtaSpcRunningTime - mApplication.cdmaOtaProvisionData.otaSpcUptime; 693 if (tmpOtaSpcLeftTime >= OTA_SPC_TIMEOUT*1000) { 694 tmpSpcTime = 1; 695 } else { 696 tmpSpcTime = OTA_SPC_TIMEOUT - (int)tmpOtaSpcLeftTime/1000; 697 } 698 } 699 if (DBG) log("getOtaSpcDisplayTime(), time for SPC error notice: " + tmpSpcTime); 700 return tmpSpcTime; 701 } 702 703 /** 704 * Initialize the OTA widgets for all OTA screens. 705 */ 706 private void initOtaInCallScreen() { 707 if (DBG) log("initOtaInCallScreen()..."); 708 mOtaWidgetData.otaTextActivate = (TextView) mInCallScreen.findViewById(R.id.otaActivate); 709 mOtaWidgetData.otaTextActivate.setVisibility(View.GONE); 710 mOtaWidgetData.otaTextListenProgress = 711 (TextView) mInCallScreen.findViewById(R.id.otaListenProgress); 712 mOtaWidgetData.otaTextProgressBar = 713 (ProgressBar) mInCallScreen.findViewById(R.id.progress_large); 714 mOtaWidgetData.otaTextProgressBar.setIndeterminate(true); 715 mOtaWidgetData.otaTextSuccessFail = 716 (TextView) mInCallScreen.findViewById(R.id.otaSuccessFailStatus); 717 718 mOtaWidgetData.otaCallCardBase = (View) mInCallScreen.findViewById(R.id.otaBase); 719 mOtaWidgetData.callCardOtaButtonsListenProgress = 720 (View) mInCallScreen.findViewById(R.id.callCardOtaListenProgress); 721 mOtaWidgetData.callCardOtaButtonsActivate = 722 (View) mInCallScreen.findViewById(R.id.callCardOtaActivate); 723 mOtaWidgetData.callCardOtaButtonsFailSuccess = 724 (View) mInCallScreen.findViewById(R.id.callCardOtaFailOrSuccessful); 725 726 mOtaWidgetData.otaEndButton = (Button) mInCallScreen.findViewById(R.id.otaEndButton); 727 mOtaWidgetData.otaEndButton.setOnClickListener(mInCallScreen); 728 mOtaWidgetData.otaSpeakerButton = 729 (ToggleButton) mInCallScreen.findViewById(R.id.otaSpeakerButton); 730 mOtaWidgetData.otaSpeakerButton.setOnClickListener(mInCallScreen); 731 mOtaWidgetData.otaActivateButton = 732 (Button) mInCallScreen.findViewById(R.id.otaActivateButton); 733 mOtaWidgetData.otaActivateButton.setOnClickListener(mInCallScreen); 734 mOtaWidgetData.otaCancelButton = 735 (Button) mInCallScreen.findViewById(R.id.otaCancelButton); 736 mOtaWidgetData.otaCancelButton.setOnClickListener(mInCallScreen); 737 mOtaWidgetData.otaDialogOKButton = 738 (Button) mInCallScreen.findViewById(R.id.otaOkButton); 739 mOtaWidgetData.otaDialogOKButton.setOnClickListener(mInCallScreen); 740 741 if (!InCallScreen.ConfigurationHelper.isLandscape()) { 742 mOtaWidgetData.otaKeypadButton = 743 (Button) mInCallScreen.findViewById(R.id.otaDialButton); 744 mOtaWidgetData.otaKeypadButton.setOnClickListener(mInCallScreen); 745 } 746 } 747 748 /** 749 * Clear out all OTA UI widget elements. Needs to get called 750 * when OTA call ends or InCallScreen is destroyed. 751 */ 752 public void cleanOtaScreen() { 753 if (DBG) log("OTA ends, cleanOtaScreen!"); 754 mApplication.cdmaOtaScreenState.otaScreenState = 755 CdmaOtaScreenState.OtaScreenState.OTA_STATUS_UNDEFINED; 756 mApplication.cdmaOtaProvisionData.isOtaCallCommitted = false; 757 mApplication.cdmaOtaProvisionData.isOtaCallIntentProcessed = false; 758 mApplication.cdmaOtaProvisionData.inOtaSpcState = false; 759 mApplication.cdmaOtaProvisionData.activationCount = 0; 760 mApplication.cdmaOtaProvisionData.otaSpcUptime = 0; 761 762 if (mInCallPanel != null) mInCallPanel.setVisibility(View.VISIBLE); 763 if (mCallCard != null) mCallCard.hideCallCardElements(); 764 if (mDialerDrawer != null) mDialerDrawer.setVisibility(View.VISIBLE); 765 766 mOtaWidgetData.otaTextActivate.setVisibility(View.GONE); 767 mOtaWidgetData.otaTextListenProgress.setVisibility(View.GONE); 768 mOtaWidgetData.otaTextProgressBar.setVisibility(View.GONE); 769 mOtaWidgetData.otaTextSuccessFail.setVisibility(View.GONE); 770 mOtaWidgetData.callCardOtaButtonsActivate.setVisibility(View.GONE); 771 mOtaWidgetData.callCardOtaButtonsListenProgress.setVisibility(View.GONE); 772 mOtaWidgetData.callCardOtaButtonsFailSuccess.setVisibility(View.GONE); 773 mOtaWidgetData.otaCallCardBase.setVisibility(View.GONE); 774 } 775 776 /** 777 * Defines OTA information that needs to be maintained during 778 * an OTA call when display orientation changes. 779 */ 780 public static class CdmaOtaProvisionData { 781 public boolean isOtaCallCommitted; 782 public boolean isOtaCallIntentProcessed; 783 public boolean inOtaSpcState; 784 public int activationCount; 785 public long otaSpcUptime; 786 } 787 788 /** 789 * Defines OTA screen configuration items read from config.xml 790 * and used to control OTA display. 791 */ 792 public static class CdmaOtaConfigData { 793 public int otaShowActivationScreen; 794 public int otaShowListeningScreen; 795 public int otaShowActivateFailTimes; 796 public int otaPlaySuccessFailureTone; 797 public boolean configComplete; 798 public CdmaOtaConfigData() { 799 if (DBG) log("CdmaOtaConfigData constructor!"); 800 otaShowActivationScreen = OTA_SHOW_ACTIVATION_SCREEN_OFF; 801 otaShowListeningScreen = OTA_SHOW_LISTENING_SCREEN_OFF; 802 otaShowActivateFailTimes = OTA_SHOW_ACTIVATE_FAIL_COUNT_OFF; 803 otaPlaySuccessFailureTone = OTA_PLAY_SUCCESS_FAILURE_TONE_OFF; 804 } 805 } 806 807 /** 808 * The OTA screen state machine. 809 */ 810 public static class CdmaOtaScreenState { 811 public enum OtaScreenState { 812 OTA_STATUS_UNDEFINED, 813 OTA_STATUS_ACTIVATION, 814 OTA_STATUS_LISTENING, 815 OTA_STATUS_PROGRESS, 816 OTA_STATUS_SUCCESS_FAILURE_DLG 817 } 818 819 public OtaScreenState otaScreenState; 820 821 public CdmaOtaScreenState() { 822 otaScreenState = OtaScreenState.OTA_STATUS_UNDEFINED; 823 } 824 } 825 826 private static void log(String msg) { 827 Log.d(LOG_TAG, msg); 828 } 829 830 public static boolean isCdmaPhone() { 831 return PhoneApp.getInstance().phone.getPhoneName().equals("CDMA"); 832 } 833} 834