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