1 /* 2 * Copyright (C) 2021 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 17 package android.telephony.mockmodem; 18 19 import android.hardware.radio.RadioError; 20 import android.hardware.radio.RadioIndicationType; 21 import android.hardware.radio.RadioResponseInfo; 22 import android.hardware.radio.voice.EmergencyNumber; 23 import android.hardware.radio.voice.IRadioVoice; 24 import android.hardware.radio.voice.IRadioVoiceIndication; 25 import android.hardware.radio.voice.IRadioVoiceResponse; 26 import android.hardware.radio.voice.LastCallFailCauseInfo; 27 import android.os.AsyncResult; 28 import android.os.Handler; 29 import android.os.HandlerThread; 30 import android.os.Looper; 31 import android.os.Message; 32 import android.os.RemoteException; 33 import android.telephony.mockmodem.MockVoiceService.MockCallInfo; 34 import android.util.Log; 35 36 import java.util.ArrayList; 37 import java.util.concurrent.CountDownLatch; 38 import java.util.concurrent.TimeUnit; 39 40 public class IRadioVoiceImpl extends IRadioVoice.Stub { 41 private static final String TAG = "MRVOICE"; 42 43 public static final int LATCH_EMERGENCY_DIAL = 0; 44 public static final int LATCH_GET_LAST_CALL_FAIL_CAUSE = 1; 45 private static final int LATCH_MAX = 2; 46 47 private final CountDownLatch[] mLatches = new CountDownLatch[LATCH_MAX]; 48 49 private final MockModemService mService; 50 private IRadioVoiceResponse mRadioVoiceResponse; 51 private IRadioVoiceIndication mRadioVoiceIndication; 52 private MockModemConfigInterface mMockModemConfigInterface; 53 private final Object mCacheUpdateMutex; 54 private final HandlerThread mHandlerThread; 55 private final Handler mHandler; 56 private int mSubId; 57 private String mTag; 58 59 // ***** Events 60 static final int EVENT_CALL_STATE_CHANGED = 1; 61 static final int EVENT_CURRENT_CALLS_RESPONSE = 2; 62 static final int EVENT_CALL_INCOMING = 3; 63 static final int EVENT_RINGBACK_TONE = 4; 64 65 // ***** Cache of modem attributes/status 66 private ArrayList<MockCallInfo> mCallList; 67 private ArrayList<Integer> mGetCurrentCallReqList; 68 IRadioVoiceImpl( MockModemService service, MockModemConfigInterface configInterface, int instanceId)69 public IRadioVoiceImpl( 70 MockModemService service, MockModemConfigInterface configInterface, int instanceId) { 71 mTag = TAG + "-" + instanceId; 72 Log.d(mTag, "Instantiated"); 73 74 this.mService = service; 75 mMockModemConfigInterface = configInterface; 76 mSubId = instanceId; 77 mCacheUpdateMutex = new Object(); 78 mHandlerThread = new HandlerThread(mTag); 79 mHandlerThread.start(); 80 mHandler = new IRadioVoiceHandler(mHandlerThread.getLooper()); 81 mGetCurrentCallReqList = new ArrayList<Integer>(); 82 83 // Register events 84 mMockModemConfigInterface.registerForCallStateChanged( 85 mSubId, mHandler, EVENT_CALL_STATE_CHANGED, null); 86 mMockModemConfigInterface.registerForCurrentCallsResponse( 87 mSubId, mHandler, EVENT_CURRENT_CALLS_RESPONSE, null); 88 mMockModemConfigInterface.registerForCallIncoming( 89 mSubId, mHandler, EVENT_CALL_INCOMING, null); 90 mMockModemConfigInterface.registerRingbackTone(mSubId, mHandler, EVENT_RINGBACK_TONE, null); 91 92 for (int i = 0; i < LATCH_MAX; i++) { 93 mLatches[i] = new CountDownLatch(1); 94 } 95 } 96 97 /** Handler class to handle callbacks */ 98 private final class IRadioVoiceHandler extends Handler { IRadioVoiceHandler(Looper looper)99 IRadioVoiceHandler(Looper looper) { 100 super(looper); 101 } 102 103 @Override handleMessage(Message msg)104 public void handleMessage(Message msg) { 105 AsyncResult ar; 106 synchronized (mCacheUpdateMutex) { 107 switch (msg.what) { 108 case EVENT_CALL_STATE_CHANGED: 109 Log.d(mTag, "Received EVENT_CALL_STATE_CHANGED"); 110 ar = (AsyncResult) msg.obj; 111 if (ar != null && ar.exception == null) { 112 mCallList = (ArrayList<MockCallInfo>) ar.result; 113 Log.i(mTag, "num of calls: " + mCallList.size()); 114 callStateChanged(); 115 } else { 116 Log.e(mTag, msg.what + " failure. Exception: " + ar.exception); 117 } 118 break; 119 case EVENT_CURRENT_CALLS_RESPONSE: 120 Log.d(mTag, "Received EVENT_CURRENT_CALLS_RESPONSE"); 121 ar = (AsyncResult) msg.obj; 122 if (ar != null && ar.exception == null) { 123 final ArrayList<MockCallInfo> callList = 124 (ArrayList<MockCallInfo>) ar.result; 125 synchronized (callList) { 126 mCallList = callList; 127 Log.i( 128 mTag, 129 "num of calls: " 130 + mCallList.size() 131 + ", num of getCurrentCalls requests: " 132 + mGetCurrentCallReqList.size()); 133 for (int i = 0; i < mGetCurrentCallReqList.size(); i++) { 134 getCurrentCallsRespnose( 135 mGetCurrentCallReqList.get(i).intValue()); 136 } 137 mGetCurrentCallReqList.clear(); 138 } 139 } else { 140 Log.e(mTag, msg.what + " failure. Exception: " + ar.exception); 141 } 142 break; 143 case EVENT_CALL_INCOMING: 144 Log.d(mTag, "Received EVENT_CALL_INCOMING"); 145 ar = (AsyncResult) msg.obj; 146 if (ar != null && ar.exception == null) { 147 MockCallInfo callInfo = (MockCallInfo) ar.result; 148 Log.i(mTag, "Incoming call id = " + callInfo.getCallId()); 149 boolean hasCdmaSignalInfoRecord = 150 (callInfo.getCdmaSignalInfoRecord() != null) ? true : false; 151 callRing(!hasCdmaSignalInfoRecord, callInfo.getCdmaSignalInfoRecord()); 152 } else { 153 Log.e(mTag, msg.what + " failure. Exception: " + ar.exception); 154 } 155 break; 156 case EVENT_RINGBACK_TONE: 157 Log.d(mTag, "Received EVENT_RINGBACK_TONE"); 158 ar = (AsyncResult) msg.obj; 159 if (ar != null && ar.exception == null) { 160 boolean ringbackToneState = (boolean) ar.result; 161 Log.i(mTag, "ringbackToneState = " + ringbackToneState); 162 indicateRingbackTone(ringbackToneState); 163 } else { 164 Log.e(mTag, msg.what + " failure. Exception: " + ar.exception); 165 } 166 break; 167 } 168 } 169 } 170 } 171 convertCallState(int callstate)172 private int convertCallState(int callstate) { 173 int state = -1; 174 175 switch (callstate) { 176 case MockCallInfo.CALL_STATE_ACTIVE: 177 state = android.hardware.radio.voice.Call.STATE_ACTIVE; 178 break; 179 180 case MockCallInfo.CALL_STATE_HOLDING: 181 state = android.hardware.radio.voice.Call.STATE_HOLDING; 182 break; 183 184 case MockCallInfo.CALL_STATE_DIALING: 185 state = android.hardware.radio.voice.Call.STATE_DIALING; 186 break; 187 188 case MockCallInfo.CALL_STATE_ALERTING: 189 state = android.hardware.radio.voice.Call.STATE_ALERTING; 190 break; 191 192 case MockCallInfo.CALL_STATE_INCOMING: 193 state = android.hardware.radio.voice.Call.STATE_INCOMING; 194 break; 195 196 case MockCallInfo.CALL_STATE_WAITING: 197 state = android.hardware.radio.voice.Call.STATE_WAITING; 198 break; 199 200 default: 201 Log.e(mTag, "Unknown call state = " + callstate); 202 break; 203 } 204 205 return state; 206 } 207 fillUpCurrentCallsRespnose()208 private android.hardware.radio.voice.Call[] fillUpCurrentCallsRespnose() { 209 int numOfCalls = 0; 210 android.hardware.radio.voice.Call[] calls = null; 211 212 if (mCallList != null) { 213 numOfCalls = mCallList.size(); 214 } 215 216 if (mMockModemConfigInterface != null 217 && mMockModemConfigInterface.getNumberOfCalls(mSubId, mTag) == numOfCalls) { 218 calls = new android.hardware.radio.voice.Call[numOfCalls]; 219 220 if (calls != null) { 221 for (int i = 0; i < numOfCalls; i++) { 222 calls[i] = new android.hardware.radio.voice.Call(); 223 if (calls[i] != null) { 224 calls[i].state = convertCallState(mCallList.get(i).getCallState()); 225 calls[i].index = mCallList.get(i).getCallId(); 226 calls[i].toa = mCallList.get(i).getCallToa(); 227 calls[i].isMpty = mCallList.get(i).isMpty(); 228 calls[i].isMT = mCallList.get(i).isMT(); 229 calls[i].als = mCallList.get(i).getCallAls(); 230 calls[i].isVoice = mCallList.get(i).isVoice(); 231 calls[i].isVoicePrivacy = mCallList.get(i).isVoicePrivacy(); 232 calls[i].number = mCallList.get(i).getNumber(); 233 calls[i].numberPresentation = mCallList.get(i).getNumberPresentation(); 234 calls[i].uusInfo = mCallList.get(i).getUusInfo(); 235 calls[i].audioQuality = mCallList.get(i).getAudioQuality(); 236 calls[i].forwardedNumber = mCallList.get(i).getForwardedNumber(); 237 } else { 238 Log.e( 239 mTag, 240 "Failed to allocate memory for call " + i + "/" + numOfCalls + "."); 241 break; 242 } 243 } 244 } else { 245 Log.e(mTag, "Failed to allocate memory for calls."); 246 } 247 } else { 248 Log.e(mTag, "mMockModemConfigInterface != null or num of calls isn't matched."); 249 } 250 251 return calls; 252 } 253 getCurrentCallsRespnose(int serial)254 private void getCurrentCallsRespnose(int serial) { 255 int responseError = RadioError.NONE; 256 android.hardware.radio.voice.Call[] calls = fillUpCurrentCallsRespnose(); 257 258 if (calls == null) { 259 responseError = RadioError.INTERNAL_ERR; 260 Log.e(mTag, "calls == null!!"); 261 } 262 263 RadioResponseInfo rsp = mService.makeSolRsp(serial, responseError); 264 try { 265 mRadioVoiceResponse.getCurrentCallsResponse(rsp, calls); 266 } catch (RemoteException ex) { 267 Log.e(mTag, "Failed to getCurrentCalls from AIDL. Exception" + ex); 268 } 269 } 270 271 // Implementation of IRadioVoice functions 272 @Override setResponseFunctions( IRadioVoiceResponse radioVoiceResponse, IRadioVoiceIndication radioVoiceIndication)273 public void setResponseFunctions( 274 IRadioVoiceResponse radioVoiceResponse, IRadioVoiceIndication radioVoiceIndication) { 275 Log.d(mTag, "setResponseFunctions"); 276 mRadioVoiceResponse = radioVoiceResponse; 277 mRadioVoiceIndication = radioVoiceIndication; 278 mService.countDownLatch(MockModemService.LATCH_RADIO_INTERFACES_READY); 279 } 280 281 @Override acceptCall(int serial)282 public void acceptCall(int serial) { 283 Log.d(mTag, "acceptCall"); 284 int responseError = RadioError.NONE; 285 286 if (mMockModemConfigInterface != null) { 287 boolean ret = mMockModemConfigInterface.acceptVoiceCall(mSubId, mTag); 288 289 if (!ret) { 290 Log.e(mTag, "Failed: accept request failed"); 291 responseError = RadioError.INTERNAL_ERR; 292 } 293 } else { 294 Log.e(mTag, "Failed: mMockModemConfigInterface == null"); 295 responseError = RadioError.INTERNAL_ERR; 296 } 297 298 RadioResponseInfo rsp = mService.makeSolRsp(serial, responseError); 299 try { 300 mRadioVoiceResponse.acceptCallResponse(rsp); 301 } catch (RemoteException ex) { 302 Log.e(mTag, "Failed to acceptCall from AIDL. Exception" + ex); 303 } 304 } 305 306 @Override cancelPendingUssd(int serial)307 public void cancelPendingUssd(int serial) { 308 Log.d(mTag, "cancelPendingUssd"); 309 310 RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); 311 try { 312 mRadioVoiceResponse.cancelPendingUssdResponse(rsp); 313 } catch (RemoteException ex) { 314 Log.e(mTag, "Failed to cancelPendingUssd from AIDL. Exception" + ex); 315 } 316 } 317 318 @Override conference(int serial)319 public void conference(int serial) { 320 Log.d(mTag, "conference"); 321 322 RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); 323 try { 324 mRadioVoiceResponse.conferenceResponse(rsp); 325 } catch (RemoteException ex) { 326 Log.e(mTag, "Failed to conference from AIDL. Exception" + ex); 327 } 328 } 329 330 @Override dial(int serial, android.hardware.radio.voice.Dial dialInfo)331 public void dial(int serial, android.hardware.radio.voice.Dial dialInfo) { 332 Log.d(mTag, "dial"); 333 int responseError = RadioError.NONE; 334 335 if (mMockModemConfigInterface != null) { 336 boolean ret = 337 mMockModemConfigInterface.dialVoiceCall( 338 mSubId, dialInfo.address, dialInfo.clir, dialInfo.uusInfo, mTag); 339 340 if (!ret) { 341 Log.e(mTag, "Failed: dial request failed"); 342 responseError = RadioError.INTERNAL_ERR; 343 } 344 } else { 345 Log.e(mTag, "Failed: mMockModemConfigInterface == null"); 346 responseError = RadioError.INTERNAL_ERR; 347 } 348 349 RadioResponseInfo rsp = mService.makeSolRsp(serial, responseError); 350 try { 351 mRadioVoiceResponse.dialResponse(rsp); 352 } catch (RemoteException ex) { 353 Log.e(mTag, "Failed to dial from AIDL. Exception" + ex); 354 } 355 } 356 357 @Override emergencyDial( int serial, android.hardware.radio.voice.Dial dialInfo, int categories, String[] urns, int routing, boolean hasKnownUserIntentEmergency, boolean isTesting)358 public void emergencyDial( 359 int serial, 360 android.hardware.radio.voice.Dial dialInfo, 361 int categories, 362 String[] urns, 363 int routing, 364 boolean hasKnownUserIntentEmergency, 365 boolean isTesting) { 366 Log.d(mTag, "emergencyDial"); 367 int responseError = RadioError.NONE; 368 369 if (mMockModemConfigInterface != null) { 370 boolean ret = 371 mMockModemConfigInterface.dialEccVoiceCall( 372 mSubId, dialInfo.address, categories, urns, routing, mTag); 373 374 if (!ret) { 375 Log.e(mTag, "Failed: dial request failed"); 376 responseError = RadioError.INTERNAL_ERR; 377 } 378 } else { 379 Log.e(mTag, "Failed: mMockModemConfigInterface == null"); 380 responseError = RadioError.INTERNAL_ERR; 381 } 382 383 RadioResponseInfo rsp = mService.makeSolRsp(serial, responseError); 384 try { 385 mRadioVoiceResponse.emergencyDialResponse(rsp); 386 } catch (RemoteException ex) { 387 Log.e(mTag, "Failed to emergencyDial from AIDL. Exception" + ex); 388 } 389 390 countDownLatch(LATCH_EMERGENCY_DIAL); 391 resetLatch(LATCH_GET_LAST_CALL_FAIL_CAUSE); 392 } 393 394 @Override exitEmergencyCallbackMode(int serial)395 public void exitEmergencyCallbackMode(int serial) { 396 Log.d(mTag, "exitEmergencyCallbackMode"); 397 398 RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); 399 try { 400 mRadioVoiceResponse.exitEmergencyCallbackModeResponse(rsp); 401 } catch (RemoteException ex) { 402 Log.e(mTag, "Failed to exitEmergencyCallbackMode from AIDL. Exception" + ex); 403 } 404 } 405 406 @Override explicitCallTransfer(int serial)407 public void explicitCallTransfer(int serial) { 408 Log.d(mTag, "explicitCallTransfer"); 409 410 RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); 411 try { 412 mRadioVoiceResponse.explicitCallTransferResponse(rsp); 413 } catch (RemoteException ex) { 414 Log.e(mTag, "Failed to explicitCallTransfer from AIDL. Exception" + ex); 415 } 416 } 417 418 @Override getCallForwardStatus( int serial, android.hardware.radio.voice.CallForwardInfo callInfo)419 public void getCallForwardStatus( 420 int serial, android.hardware.radio.voice.CallForwardInfo callInfo) { 421 Log.d(mTag, "getCallForwardStatus"); 422 423 android.hardware.radio.voice.CallForwardInfo[] callForwardInfos = 424 new android.hardware.radio.voice.CallForwardInfo[0]; 425 RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); 426 try { 427 mRadioVoiceResponse.getCallForwardStatusResponse(rsp, callForwardInfos); 428 } catch (RemoteException ex) { 429 Log.e(mTag, "Failed to getCallForwardStatus from AIDL. Exception" + ex); 430 } 431 } 432 433 @Override getCallWaiting(int serial, int serviceClass)434 public void getCallWaiting(int serial, int serviceClass) { 435 Log.d(mTag, "getCallWaiting"); 436 437 boolean enable = false; 438 int rspServiceClass = 0; 439 RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); 440 try { 441 mRadioVoiceResponse.getCallWaitingResponse(rsp, enable, rspServiceClass); 442 } catch (RemoteException ex) { 443 Log.e(mTag, "Failed to getCallWaiting from AIDL. Exception" + ex); 444 } 445 } 446 447 @Override getClip(int serial)448 public void getClip(int serial) { 449 Log.d(mTag, "getClip"); 450 451 int status = 0; 452 RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); 453 try { 454 mRadioVoiceResponse.getClipResponse(rsp, status); 455 } catch (RemoteException ex) { 456 Log.e(mTag, "Failed to getClip from AIDL. Exception" + ex); 457 } 458 } 459 460 @Override getClir(int serial)461 public void getClir(int serial) { 462 Log.d(mTag, "getClir"); 463 464 int n = 0; 465 int m = 0; 466 RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); 467 try { 468 mRadioVoiceResponse.getClirResponse(rsp, n, m); 469 } catch (RemoteException ex) { 470 Log.e(mTag, "Failed to getClir from AIDL. Exception" + ex); 471 } 472 } 473 474 @Override getCurrentCalls(int serial)475 public void getCurrentCalls(int serial) { 476 Log.d(mTag, "getCurrentCalls"); 477 478 int responseError = RadioError.NONE; 479 480 if (mMockModemConfigInterface != null) { 481 Integer request = Integer.valueOf(serial); 482 483 synchronized (mCacheUpdateMutex) { 484 if (mGetCurrentCallReqList != null && request != null) { 485 mGetCurrentCallReqList.add(request); 486 Log.d(mTag, "Add GetCurrentCallReq"); 487 } else { 488 Log.e(mTag, "Failed: mGetCurrentCallReqList == null or request == null"); 489 responseError = RadioError.INTERNAL_ERR; 490 } 491 } 492 493 if (responseError == RadioError.NONE) { 494 boolean ret = mMockModemConfigInterface.getCurrentCalls(mSubId, mTag); 495 496 if (!ret) { 497 Log.e(mTag, "Failed: getCurrentCalls request failed"); 498 responseError = RadioError.INTERNAL_ERR; 499 } 500 } 501 } else { 502 Log.e(mTag, "Failed: mMockModemConfigInterface == null"); 503 responseError = RadioError.INTERNAL_ERR; 504 } 505 506 if (responseError != RadioError.NONE) { 507 android.hardware.radio.voice.Call[] calls = new android.hardware.radio.voice.Call[0]; 508 RadioResponseInfo rsp = mService.makeSolRsp(serial, responseError); 509 try { 510 mRadioVoiceResponse.getCurrentCallsResponse(rsp, calls); 511 } catch (RemoteException ex) { 512 Log.e(mTag, "Failed to getCurrentCalls from AIDL. Exception" + ex); 513 } 514 } 515 } 516 517 @Override getLastCallFailCause(int serial)518 public void getLastCallFailCause(int serial) { 519 Log.d(mTag, "getLastCallFailCause"); 520 LastCallFailCauseInfo failCauseInfo = null; 521 int responseError = RadioError.NONE; 522 523 if (mMockModemConfigInterface != null) { 524 failCauseInfo = mMockModemConfigInterface.getLastCallFailCause(mSubId, mTag); 525 526 if (failCauseInfo == null) { 527 Log.e(mTag, "Failed: get last call fail cause request failed"); 528 responseError = RadioError.INTERNAL_ERR; 529 } 530 } else { 531 Log.e(mTag, "Failed: mMockModemConfigInterface == null"); 532 responseError = RadioError.INTERNAL_ERR; 533 } 534 535 RadioResponseInfo rsp = mService.makeSolRsp(serial, responseError); 536 try { 537 mRadioVoiceResponse.getLastCallFailCauseResponse(rsp, failCauseInfo); 538 } catch (RemoteException ex) { 539 Log.e(mTag, "Failed to getLastCallFailCause from AIDL. Exception" + ex); 540 } 541 countDownLatch(LATCH_GET_LAST_CALL_FAIL_CAUSE); 542 } 543 544 @Override getMute(int serial)545 public void getMute(int serial) { 546 Log.d(mTag, "getMute"); 547 int responseError = RadioError.NONE; 548 boolean muteMode = false; 549 550 if (mMockModemConfigInterface != null) { 551 muteMode = mMockModemConfigInterface.getVoiceMuteMode(mSubId, mTag); 552 } else { 553 Log.e(mTag, "Failed: mMockModemConfigInterface == null"); 554 responseError = RadioError.INTERNAL_ERR; 555 } 556 557 RadioResponseInfo rsp = mService.makeSolRsp(serial, responseError); 558 try { 559 mRadioVoiceResponse.getMuteResponse(rsp, muteMode); 560 } catch (RemoteException ex) { 561 Log.e(mTag, "Failed to getMute from AIDL. Exception" + ex); 562 } 563 } 564 565 @Override getPreferredVoicePrivacy(int serial)566 public void getPreferredVoicePrivacy(int serial) { 567 Log.d(mTag, "getPreferredVoicePrivacy"); 568 569 boolean enable = false; 570 RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); 571 try { 572 mRadioVoiceResponse.getPreferredVoicePrivacyResponse(rsp, enable); 573 } catch (RemoteException ex) { 574 Log.e(mTag, "Failed to getPreferredVoicePrivacy from AIDL. Exception" + ex); 575 } 576 } 577 578 @Override getTtyMode(int serial)579 public void getTtyMode(int serial) { 580 Log.d(mTag, "getTtyMode"); 581 582 int mode = 0; 583 RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); 584 try { 585 mRadioVoiceResponse.getTtyModeResponse(rsp, mode); 586 } catch (RemoteException ex) { 587 Log.e(mTag, "Failed to getTtyMode from AIDL. Exception" + ex); 588 } 589 } 590 591 @Override handleStkCallSetupRequestFromSim(int serial, boolean accept)592 public void handleStkCallSetupRequestFromSim(int serial, boolean accept) { 593 Log.d(mTag, "handleStkCallSetupRequestFromSim"); 594 595 RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); 596 try { 597 mRadioVoiceResponse.handleStkCallSetupRequestFromSimResponse(rsp); 598 } catch (RemoteException ex) { 599 Log.e(mTag, "Failed to handleStkCallSetupRequestFromSim from AIDL. Exception" + ex); 600 } 601 } 602 603 @Override hangup(int serial, int gsmIndex)604 public void hangup(int serial, int gsmIndex) { 605 Log.d(mTag, "hangup"); 606 int responseError = RadioError.NONE; 607 608 if (mMockModemConfigInterface != null) { 609 boolean ret = mMockModemConfigInterface.hangupVoiceCall(mSubId, gsmIndex, mTag); 610 611 if (!ret) { 612 Log.e(mTag, "Failed: hangup request failed"); 613 responseError = RadioError.INTERNAL_ERR; 614 } 615 } else { 616 Log.e(mTag, "Failed: mMockModemConfigInterface == null"); 617 responseError = RadioError.INTERNAL_ERR; 618 } 619 620 RadioResponseInfo rsp = mService.makeSolRsp(serial, responseError); 621 try { 622 mRadioVoiceResponse.hangupConnectionResponse(rsp); 623 } catch (RemoteException ex) { 624 Log.e(mTag, "Failed to hangup from AIDL. Exception" + ex); 625 } 626 } 627 628 @Override hangupForegroundResumeBackground(int serial)629 public void hangupForegroundResumeBackground(int serial) { 630 Log.d(mTag, "hangupForegroundResumeBackground"); 631 632 RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); 633 try { 634 mRadioVoiceResponse.hangupForegroundResumeBackgroundResponse(rsp); 635 } catch (RemoteException ex) { 636 Log.e(mTag, "Failed to hangupForegroundResumeBackground from AIDL. Exception" + ex); 637 } 638 } 639 640 @Override hangupWaitingOrBackground(int serial)641 public void hangupWaitingOrBackground(int serial) { 642 Log.d(mTag, "hangupWaitingOrBackground"); 643 644 RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); 645 try { 646 mRadioVoiceResponse.hangupWaitingOrBackgroundResponse(rsp); 647 } catch (RemoteException ex) { 648 Log.e(mTag, "Failed to hangupWaitingOrBackground from AIDL. Exception" + ex); 649 } 650 } 651 652 @Override isVoNrEnabled(int serial)653 public void isVoNrEnabled(int serial) { 654 Log.d(mTag, "isVoNrEnabled"); 655 656 boolean enable = false; 657 RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); 658 try { 659 mRadioVoiceResponse.isVoNrEnabledResponse(rsp, enable); 660 } catch (RemoteException ex) { 661 Log.e(mTag, "Failed to isVoNrEnabled from AIDL. Exception" + ex); 662 } 663 } 664 665 @Override rejectCall(int serial)666 public void rejectCall(int serial) { 667 Log.d(mTag, "rejectCall"); 668 int responseError = RadioError.NONE; 669 670 if (mMockModemConfigInterface != null) { 671 boolean ret = mMockModemConfigInterface.rejectVoiceCall(mSubId, mTag); 672 673 if (!ret) { 674 Log.e(mTag, "Failed: reject request failed"); 675 responseError = RadioError.INTERNAL_ERR; 676 } 677 } else { 678 Log.e(mTag, "Failed: mMockModemConfigInterface == null"); 679 responseError = RadioError.INTERNAL_ERR; 680 } 681 682 RadioResponseInfo rsp = mService.makeSolRsp(serial, responseError); 683 try { 684 mRadioVoiceResponse.rejectCallResponse(rsp); 685 } catch (RemoteException ex) { 686 Log.e(mTag, "Failed to rejectCall from AIDL. Exception" + ex); 687 } 688 } 689 690 @Override responseAcknowledgement()691 public void responseAcknowledgement() { 692 Log.d(mTag, "responseAcknowledgement"); 693 // TODO 694 } 695 696 @Override sendBurstDtmf(int serial, String dtmf, int on, int off)697 public void sendBurstDtmf(int serial, String dtmf, int on, int off) { 698 Log.d(mTag, "sendBurstDtmf"); 699 700 RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); 701 try { 702 mRadioVoiceResponse.sendBurstDtmfResponse(rsp); 703 } catch (RemoteException ex) { 704 Log.e(mTag, "Failed to sendBurstDtmf from AIDL. Exception" + ex); 705 } 706 } 707 708 @Override sendCdmaFeatureCode(int serial, String featureCode)709 public void sendCdmaFeatureCode(int serial, String featureCode) { 710 Log.d(mTag, "sendCdmaFeatureCode"); 711 712 RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); 713 try { 714 mRadioVoiceResponse.sendCdmaFeatureCodeResponse(rsp); 715 } catch (RemoteException ex) { 716 Log.e(mTag, "Failed to sendCdmaFeatureCode from AIDL. Exception" + ex); 717 } 718 } 719 720 @Override sendDtmf(int serial, String s)721 public void sendDtmf(int serial, String s) { 722 Log.d(mTag, "sendDtmf"); 723 724 RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); 725 try { 726 mRadioVoiceResponse.sendDtmfResponse(rsp); 727 } catch (RemoteException ex) { 728 Log.e(mTag, "Failed to sendDtmf from AIDL. Exception" + ex); 729 } 730 } 731 732 @Override sendUssd(int serial, String ussd)733 public void sendUssd(int serial, String ussd) { 734 Log.d(mTag, "sendUssd"); 735 736 RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); 737 try { 738 mRadioVoiceResponse.sendUssdResponse(rsp); 739 } catch (RemoteException ex) { 740 Log.e(mTag, "Failed to sendUssd from AIDL. Exception" + ex); 741 } 742 } 743 744 @Override separateConnection(int serial, int gsmIndex)745 public void separateConnection(int serial, int gsmIndex) { 746 Log.d(mTag, "separateConnection"); 747 748 RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); 749 try { 750 mRadioVoiceResponse.separateConnectionResponse(rsp); 751 } catch (RemoteException ex) { 752 Log.e(mTag, "Failed to separateConnection from AIDL. Exception" + ex); 753 } 754 } 755 756 @Override setCallForward(int serial, android.hardware.radio.voice.CallForwardInfo callInfo)757 public void setCallForward(int serial, android.hardware.radio.voice.CallForwardInfo callInfo) { 758 Log.d(mTag, "setCallForward"); 759 760 RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); 761 try { 762 mRadioVoiceResponse.setCallForwardResponse(rsp); 763 } catch (RemoteException ex) { 764 Log.e(mTag, "Failed to setCallForward from AIDL. Exception" + ex); 765 } 766 } 767 768 @Override setCallWaiting(int serial, boolean enable, int serviceClass)769 public void setCallWaiting(int serial, boolean enable, int serviceClass) { 770 Log.d(mTag, "setCallWaiting"); 771 772 RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); 773 try { 774 mRadioVoiceResponse.setCallWaitingResponse(rsp); 775 } catch (RemoteException ex) { 776 Log.e(mTag, "Failed to setCallWaiting from AIDL. Exception" + ex); 777 } 778 } 779 780 @Override setClir(int serial, int status)781 public void setClir(int serial, int status) { 782 Log.d(mTag, "setClir"); 783 784 RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); 785 try { 786 mRadioVoiceResponse.setClirResponse(rsp); 787 } catch (RemoteException ex) { 788 Log.e(mTag, "Failed to setClir from AIDL. Exception" + ex); 789 } 790 } 791 792 @Override setMute(int serial, boolean enable)793 public void setMute(int serial, boolean enable) { 794 Log.d(mTag, "setMute"); 795 int responseError = RadioError.NONE; 796 797 if (mMockModemConfigInterface != null) { 798 boolean ret = mMockModemConfigInterface.setVoiceMuteMode(mSubId, enable, mTag); 799 800 if (!ret) { 801 Log.e(mTag, "Failed: setMute request failed"); 802 responseError = RadioError.INTERNAL_ERR; 803 } 804 } else { 805 Log.e(mTag, "Failed: mMockModemConfigInterface == null"); 806 responseError = RadioError.INTERNAL_ERR; 807 } 808 809 RadioResponseInfo rsp = mService.makeSolRsp(serial, responseError); 810 try { 811 mRadioVoiceResponse.setMuteResponse(rsp); 812 } catch (RemoteException ex) { 813 Log.e(mTag, "Failed to setMute from AIDL. Exception" + ex); 814 } 815 } 816 817 @Override setPreferredVoicePrivacy(int serial, boolean enable)818 public void setPreferredVoicePrivacy(int serial, boolean enable) { 819 Log.d(mTag, "setPreferredVoicePrivacy"); 820 821 RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); 822 try { 823 mRadioVoiceResponse.setPreferredVoicePrivacyResponse(rsp); 824 } catch (RemoteException ex) { 825 Log.e(mTag, "Failed to setPreferredVoicePrivacy from AIDL. Exception" + ex); 826 } 827 } 828 829 @Override setTtyMode(int serial, int mode)830 public void setTtyMode(int serial, int mode) { 831 Log.d(mTag, "setTtyMode"); 832 833 RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); 834 try { 835 mRadioVoiceResponse.setTtyModeResponse(rsp); 836 } catch (RemoteException ex) { 837 Log.e(mTag, "Failed to setTtyMode from AIDL. Exception" + ex); 838 } 839 } 840 841 @Override setVoNrEnabled(int serial, boolean enable)842 public void setVoNrEnabled(int serial, boolean enable) { 843 Log.d(mTag, "setVoNrEnabled"); 844 845 RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); 846 try { 847 mRadioVoiceResponse.setVoNrEnabledResponse(rsp); 848 } catch (RemoteException ex) { 849 Log.e(mTag, "Failed to setVoNrEnabled from AIDL. Exception" + ex); 850 } 851 } 852 853 @Override startDtmf(int serial, String s)854 public void startDtmf(int serial, String s) { 855 Log.d(mTag, "startDtmf"); 856 857 RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); 858 try { 859 mRadioVoiceResponse.startDtmfResponse(rsp); 860 } catch (RemoteException ex) { 861 Log.e(mTag, "Failed to startDtmf from AIDL. Exception" + ex); 862 } 863 } 864 865 @Override stopDtmf(int serial)866 public void stopDtmf(int serial) { 867 Log.d(mTag, "stopDtmf"); 868 869 RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); 870 try { 871 mRadioVoiceResponse.stopDtmfResponse(rsp); 872 } catch (RemoteException ex) { 873 Log.e(mTag, "Failed to stopDtmf from AIDL. Exception" + ex); 874 } 875 } 876 877 @Override switchWaitingOrHoldingAndActive(int serial)878 public void switchWaitingOrHoldingAndActive(int serial) { 879 Log.d(mTag, "switchWaitingOrHoldingAndActive"); 880 881 RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED); 882 try { 883 mRadioVoiceResponse.switchWaitingOrHoldingAndActiveResponse(rsp); 884 } catch (RemoteException ex) { 885 Log.e(mTag, "Failed to switchWaitingOrHoldingAndActive from AIDL. Exception" + ex); 886 } 887 } 888 callRing(boolean isGsm, android.hardware.radio.voice.CdmaSignalInfoRecord record)889 public void callRing(boolean isGsm, android.hardware.radio.voice.CdmaSignalInfoRecord record) { 890 Log.d(mTag, "callRing"); 891 892 if (mRadioVoiceIndication != null) { 893 try { 894 mRadioVoiceIndication.callRing(RadioIndicationType.UNSOLICITED, isGsm, record); 895 } catch (RemoteException ex) { 896 Log.e(mTag, "Failed to callRing indication from AIDL. Exception" + ex); 897 } 898 } else { 899 Log.e(mTag, "null mRadioVoiceIndication"); 900 } 901 } 902 callStateChanged()903 public void callStateChanged() { 904 Log.d(mTag, "callStateChanged"); 905 906 if (mRadioVoiceIndication != null) { 907 try { 908 mRadioVoiceIndication.callStateChanged(RadioIndicationType.UNSOLICITED); 909 } catch (RemoteException ex) { 910 Log.e(mTag, "Failed to callStateChanged indication from AIDL. Exception" + ex); 911 } 912 } else { 913 Log.e(mTag, "null mRadioVoiceIndication"); 914 } 915 } 916 cdmaCallWaiting(android.hardware.radio.voice.CdmaCallWaiting callWaitingRecord)917 public void cdmaCallWaiting(android.hardware.radio.voice.CdmaCallWaiting callWaitingRecord) { 918 Log.d(mTag, "cdmaCallWaiting"); 919 920 if (mRadioVoiceIndication != null) { 921 try { 922 mRadioVoiceIndication.cdmaCallWaiting( 923 RadioIndicationType.UNSOLICITED, callWaitingRecord); 924 } catch (RemoteException ex) { 925 Log.e(mTag, "Failed to cdmaCallWaiting indication from AIDL. Exception" + ex); 926 } 927 } else { 928 Log.e(mTag, "null mRadioVoiceIndication"); 929 } 930 } 931 cdmaInfoRec(android.hardware.radio.voice.CdmaInformationRecord[] records)932 public void cdmaInfoRec(android.hardware.radio.voice.CdmaInformationRecord[] records) { 933 Log.d(mTag, "cdmaInfoRec"); 934 935 if (mRadioVoiceIndication != null) { 936 try { 937 mRadioVoiceIndication.cdmaInfoRec(RadioIndicationType.UNSOLICITED, records); 938 } catch (RemoteException ex) { 939 Log.e(mTag, "Failed to cdmaInfoRec indication from AIDL. Exception" + ex); 940 } 941 } else { 942 Log.e(mTag, "null mRadioVoiceIndication"); 943 } 944 } 945 cdmaOtaProvisionStatus(int status)946 public void cdmaOtaProvisionStatus(int status) { 947 Log.d(mTag, "cdmaOtaProvisionStatus"); 948 949 if (mRadioVoiceIndication != null) { 950 try { 951 mRadioVoiceIndication.cdmaOtaProvisionStatus( 952 RadioIndicationType.UNSOLICITED, status); 953 } catch (RemoteException ex) { 954 Log.e( 955 mTag, 956 "Failed to cdmaOtaProvisionStatus indication from AIDL. Exception" + ex); 957 } 958 } else { 959 Log.e(mTag, "null mRadioVoiceIndication"); 960 } 961 } 962 currentEmergencyNumberList( android.hardware.radio.voice.EmergencyNumber[] emergencyNumberList)963 public void currentEmergencyNumberList( 964 android.hardware.radio.voice.EmergencyNumber[] emergencyNumberList) { 965 Log.d(mTag, "currentEmergencyNumberList"); 966 967 if (mRadioVoiceIndication != null) { 968 try { 969 mRadioVoiceIndication.currentEmergencyNumberList( 970 RadioIndicationType.UNSOLICITED, emergencyNumberList); 971 } catch (RemoteException ex) { 972 Log.e( 973 mTag, 974 "Failed to currentEmergencyNumberList indication from AIDL. Exception" 975 + ex); 976 } 977 } else { 978 Log.e(mTag, "null mRadioVoiceIndication"); 979 } 980 } 981 enterEmergencyCallbackMode()982 public void enterEmergencyCallbackMode() { 983 Log.d(mTag, "enterEmergencyCallbackMode"); 984 985 if (mRadioVoiceIndication != null) { 986 try { 987 mRadioVoiceIndication.enterEmergencyCallbackMode(RadioIndicationType.UNSOLICITED); 988 } catch (RemoteException ex) { 989 Log.e( 990 mTag, 991 "Failed to enterEmergencyCallbackMode indication from AIDL. Exception" 992 + ex); 993 } 994 } else { 995 Log.e(mTag, "null mRadioVoiceIndication"); 996 } 997 } 998 exitEmergencyCallbackMode()999 public void exitEmergencyCallbackMode() { 1000 Log.d(mTag, "exitEmergencyCallbackMode"); 1001 1002 if (mRadioVoiceIndication != null) { 1003 try { 1004 mRadioVoiceIndication.exitEmergencyCallbackMode(RadioIndicationType.UNSOLICITED); 1005 } catch (RemoteException ex) { 1006 Log.e( 1007 mTag, 1008 "Failed to exitEmergencyCallbackMode indication from AIDL. Exception" + ex); 1009 } 1010 } else { 1011 Log.e(mTag, "null mRadioVoiceIndication"); 1012 } 1013 } 1014 indicateRingbackTone(boolean start)1015 public void indicateRingbackTone(boolean start) { 1016 Log.d(mTag, "indicateRingbackTone"); 1017 1018 if (mRadioVoiceIndication != null) { 1019 try { 1020 mRadioVoiceIndication.indicateRingbackTone(RadioIndicationType.UNSOLICITED, start); 1021 } catch (RemoteException ex) { 1022 Log.e(mTag, "Failed to indicateRingbackTone indication from AIDL. Exception" + ex); 1023 } 1024 } else { 1025 Log.e(mTag, "null mRadioVoiceIndication"); 1026 } 1027 } 1028 onSupplementaryServiceIndication( android.hardware.radio.voice.StkCcUnsolSsResult ss)1029 public void onSupplementaryServiceIndication( 1030 android.hardware.radio.voice.StkCcUnsolSsResult ss) { 1031 Log.d(mTag, "onSupplementaryServiceIndication"); 1032 1033 if (mRadioVoiceIndication != null) { 1034 try { 1035 mRadioVoiceIndication.onSupplementaryServiceIndication( 1036 RadioIndicationType.UNSOLICITED, ss); 1037 } catch (RemoteException ex) { 1038 Log.e( 1039 mTag, 1040 "Failed to onSupplementaryServiceIndication indication from AIDL. Exception" 1041 + ex); 1042 } 1043 } else { 1044 Log.e(mTag, "null mRadioVoiceIndication"); 1045 } 1046 } 1047 onUssd(int modeType, String msg)1048 public void onUssd(int modeType, String msg) { 1049 Log.d(mTag, "onUssd"); 1050 1051 if (mRadioVoiceIndication != null) { 1052 try { 1053 mRadioVoiceIndication.onUssd(RadioIndicationType.UNSOLICITED, modeType, msg); 1054 } catch (RemoteException ex) { 1055 Log.e(mTag, "Failed to onUssd indication from AIDL. Exception" + ex); 1056 } 1057 } else { 1058 Log.e(mTag, "null mRadioVoiceIndication"); 1059 } 1060 } 1061 resendIncallMute()1062 public void resendIncallMute() { 1063 Log.d(mTag, "resendIncallMute"); 1064 1065 if (mRadioVoiceIndication != null) { 1066 try { 1067 mRadioVoiceIndication.resendIncallMute(RadioIndicationType.UNSOLICITED); 1068 } catch (RemoteException ex) { 1069 Log.e(mTag, "Failed to resendIncallMute indication from AIDL. Exception" + ex); 1070 } 1071 } else { 1072 Log.e(mTag, "null mRadioVoiceIndication"); 1073 } 1074 } 1075 srvccStateNotify(int state)1076 public void srvccStateNotify(int state) { 1077 Log.d(mTag, "srvccStateNotify"); 1078 1079 if (mRadioVoiceIndication != null) { 1080 try { 1081 mRadioVoiceIndication.srvccStateNotify(RadioIndicationType.UNSOLICITED, state); 1082 } catch (RemoteException ex) { 1083 Log.e(mTag, "Failed to srvccStateNotify indication from AIDL. Exception" + ex); 1084 } 1085 } else { 1086 Log.e(mTag, "null mRadioVoiceIndication"); 1087 } 1088 } 1089 stkCallControlAlphaNotify(String alpha)1090 public void stkCallControlAlphaNotify(String alpha) { 1091 Log.d(mTag, "stkCallControlAlphaNotify"); 1092 1093 if (mRadioVoiceIndication != null) { 1094 try { 1095 mRadioVoiceIndication.stkCallControlAlphaNotify( 1096 RadioIndicationType.UNSOLICITED, alpha); 1097 } catch (RemoteException ex) { 1098 Log.e( 1099 mTag, 1100 "Failed to stkCallControlAlphaNotify indication from AIDL. Exception" + ex); 1101 } 1102 } else { 1103 Log.e(mTag, "null mRadioVoiceIndication"); 1104 } 1105 } 1106 stkCallSetup(long timeout)1107 public void stkCallSetup(long timeout) { 1108 Log.d(mTag, "stkCallSetup"); 1109 1110 if (mRadioVoiceIndication != null) { 1111 try { 1112 mRadioVoiceIndication.stkCallSetup(RadioIndicationType.UNSOLICITED, timeout); 1113 } catch (RemoteException ex) { 1114 Log.e(mTag, "Failed to stkCallSetup indication from AIDL. Exception" + ex); 1115 } 1116 } else { 1117 Log.e(mTag, "null mRadioVoiceIndication"); 1118 } 1119 } 1120 notifyEmergencyNumberList(String[] numbers)1121 public void notifyEmergencyNumberList(String[] numbers) { 1122 if (numbers == null || numbers.length == 0) return; 1123 1124 EmergencyNumber[] emergencyNumberList = new EmergencyNumber[numbers.length]; 1125 1126 for (int i = 0; i < numbers.length; i++) { 1127 EmergencyNumber number = new EmergencyNumber(); 1128 number.number = numbers[i]; 1129 number.mcc = "310"; 1130 number.mnc = ""; 1131 String urn = "sip:" + numbers[i] + "@test.3gpp.com"; 1132 number.urns = new String[] { urn }; 1133 number.sources = EmergencyNumber.SOURCE_MODEM_CONFIG; 1134 emergencyNumberList[i] = number; 1135 } 1136 1137 currentEmergencyNumberList(emergencyNumberList); 1138 } 1139 1140 countDownLatch(int latchIndex)1141 private void countDownLatch(int latchIndex) { 1142 synchronized (mLatches) { 1143 mLatches[latchIndex].countDown(); 1144 } 1145 } 1146 resetLatch(int latchIndex)1147 private void resetLatch(int latchIndex) { 1148 synchronized (mLatches) { 1149 mLatches[latchIndex] = new CountDownLatch(1); 1150 } 1151 } 1152 1153 /** 1154 * Waits for the event of voice service. 1155 * 1156 * @param latchIndex The index of the event. 1157 * @param waitMs The timeout in milliseconds. 1158 * @return {@code true} if the event happens. 1159 */ waitForLatchCountdown(int latchIndex, long waitMs)1160 public boolean waitForLatchCountdown(int latchIndex, long waitMs) { 1161 boolean complete = false; 1162 try { 1163 CountDownLatch latch; 1164 synchronized (mLatches) { 1165 latch = mLatches[latchIndex]; 1166 } 1167 long startTime = System.currentTimeMillis(); 1168 complete = latch.await(waitMs, TimeUnit.MILLISECONDS); 1169 Log.i(TAG, "Latch " + latchIndex + " took " 1170 + (System.currentTimeMillis() - startTime) + " ms to count down."); 1171 } catch (InterruptedException e) { 1172 Log.e(TAG, "Waiting latch " + latchIndex + " interrupted, e=" + e); 1173 } 1174 synchronized (mLatches) { 1175 mLatches[latchIndex] = new CountDownLatch(1); 1176 } 1177 return complete; 1178 } 1179 1180 /** 1181 * Resets the CountDownLatches. 1182 */ resetAllLatchCountdown()1183 public void resetAllLatchCountdown() { 1184 synchronized (mLatches) { 1185 for (int i = 0; i < LATCH_MAX; i++) { 1186 mLatches[i] = new CountDownLatch(1); 1187 } 1188 } 1189 } 1190 1191 @Override getInterfaceHash()1192 public String getInterfaceHash() { 1193 return IRadioVoice.HASH; 1194 } 1195 1196 @Override getInterfaceVersion()1197 public int getInterfaceVersion() { 1198 return IRadioVoice.VERSION; 1199 } 1200 } 1201