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 com.android.internal.telephony; 18 19 import android.os.RemoteException; 20 import android.telephony.PhoneNumberUtils; 21 import android.telephony.Rlog; 22 import android.telephony.emergency.EmergencyNumber; 23 24 import com.android.internal.telephony.flags.Flags; 25 26 import java.util.ArrayList; 27 28 /** 29 * A holder for IRadioVoice. 30 * Use getAidl to get IRadioVoice and call the AIDL implementations of the HAL APIs. 31 */ 32 public class RadioVoiceProxy extends RadioServiceProxy { 33 private static final String TAG = "RadioVoiceProxy"; 34 private volatile android.hardware.radio.voice.IRadioVoice mVoiceProxy = null; 35 36 /** 37 * Set IRadioVoice as the AIDL implementation for RadioServiceProxy 38 * @param halVersion Radio HAL version 39 * @param voice IRadioVoice implementation 40 * 41 * @return updated HAL version 42 */ setAidl(HalVersion halVersion, android.hardware.radio.voice.IRadioVoice voice)43 public HalVersion setAidl(HalVersion halVersion, 44 android.hardware.radio.voice.IRadioVoice voice) { 45 HalVersion version = halVersion; 46 try { 47 version = RIL.getServiceHalVersion(voice.getInterfaceVersion()); 48 } catch (RemoteException e) { 49 Rlog.e(TAG, "setAidl: " + e); 50 } 51 mHalVersion = version; 52 mVoiceProxy = voice; 53 mIsAidl = true; 54 55 Rlog.d(TAG, "AIDL initialized mHalVersion=" + mHalVersion); 56 return mHalVersion; 57 } 58 59 /** 60 * Get the AIDL implementation of RadioVoiceProxy 61 * @return IRadioVoice implementation 62 */ getAidl()63 public android.hardware.radio.voice.IRadioVoice getAidl() { 64 return mVoiceProxy; 65 } 66 67 /** 68 * Reset RadioVoiceProxy 69 */ 70 @Override clear()71 public void clear() { 72 super.clear(); 73 mVoiceProxy = null; 74 } 75 76 /** 77 * Check whether a RadioVoice implementation exists 78 * @return true if there is neither a HIDL nor AIDL implementation 79 */ 80 @Override isEmpty()81 public boolean isEmpty() { 82 return mRadioProxy == null && mVoiceProxy == null; 83 } 84 85 /** 86 * Call IRadioVoice#acceptCall 87 * @param serial Serial number of request 88 * @throws RemoteException 89 */ acceptCall(int serial)90 public void acceptCall(int serial) throws RemoteException { 91 if (isEmpty()) return; 92 if (isAidl()) { 93 mVoiceProxy.acceptCall(serial); 94 } else { 95 mRadioProxy.acceptCall(serial); 96 } 97 } 98 99 /** 100 * Call IRadioVoice#cancelPendingUssd 101 * @param serial Serial number of request 102 * @throws RemoteException 103 */ cancelPendingUssd(int serial)104 public void cancelPendingUssd(int serial) throws RemoteException { 105 if (isEmpty()) return; 106 if (isAidl()) { 107 mVoiceProxy.cancelPendingUssd(serial); 108 } else { 109 mRadioProxy.cancelPendingUssd(serial); 110 } 111 } 112 113 /** 114 * Call IRadioVoice#conference 115 * @param serial Serial number of request 116 * @throws RemoteException 117 */ conference(int serial)118 public void conference(int serial) throws RemoteException { 119 if (isEmpty()) return; 120 if (isAidl()) { 121 mVoiceProxy.conference(serial); 122 } else { 123 mRadioProxy.conference(serial); 124 } 125 } 126 127 /** 128 * Call IRadioVoice#dial 129 * @param serial Serial number of request 130 * @param address Address 131 * @param clirMode CLIR mode 132 * @param uusInfo UUS info 133 * @throws RemoteException 134 */ dial(int serial, String address, int clirMode, UUSInfo uusInfo)135 public void dial(int serial, String address, int clirMode, UUSInfo uusInfo) 136 throws RemoteException { 137 if (isEmpty()) return; 138 if (isAidl()) { 139 mVoiceProxy.dial(serial, RILUtils.convertToHalDialAidl(address, clirMode, uusInfo)); 140 } else { 141 mRadioProxy.dial(serial, RILUtils.convertToHalDial(address, clirMode, uusInfo)); 142 } 143 } 144 145 /** 146 * Call IRadioVoice#emergencyDial 147 * @param serial Serial number of request 148 * @param address Address 149 * @param emergencyNumberInfo Emergency number information 150 * @param hasKnownUserIntentEmergency Whether or not the request has known user intent emergency 151 * @param clirMode CLIR mode 152 * @param uusInfo UUS info 153 * @throws RemoteException 154 */ emergencyDial(int serial, String address, EmergencyNumber emergencyNumberInfo, boolean hasKnownUserIntentEmergency, int clirMode, UUSInfo uusInfo)155 public void emergencyDial(int serial, String address, EmergencyNumber emergencyNumberInfo, 156 boolean hasKnownUserIntentEmergency, int clirMode, UUSInfo uusInfo) 157 throws RemoteException { 158 if (isEmpty()) return; 159 if (isAidl()) { 160 mVoiceProxy.emergencyDial(serial, 161 RILUtils.convertToHalDialAidl(address, clirMode, uusInfo), 162 emergencyNumberInfo.getEmergencyServiceCategoryBitmaskInternalDial(), 163 emergencyNumberInfo.getEmergencyUrns() != null 164 ? emergencyNumberInfo.getEmergencyUrns().stream().toArray(String[]::new) 165 : new String[0], 166 emergencyNumberInfo.getEmergencyCallRouting(), 167 hasKnownUserIntentEmergency, 168 emergencyNumberInfo.getEmergencyNumberSourceBitmask() 169 == EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST); 170 } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6)) { 171 ((android.hardware.radio.V1_6.IRadio) mRadioProxy).emergencyDial_1_6(serial, 172 RILUtils.convertToHalDial(address, clirMode, uusInfo), 173 emergencyNumberInfo.getEmergencyServiceCategoryBitmaskInternalDial(), 174 emergencyNumberInfo.getEmergencyUrns() != null 175 ? new ArrayList(emergencyNumberInfo.getEmergencyUrns()) 176 : new ArrayList<>(), 177 emergencyNumberInfo.getEmergencyCallRouting(), 178 hasKnownUserIntentEmergency, 179 emergencyNumberInfo.getEmergencyNumberSourceBitmask() 180 == EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST); 181 } else { 182 mRadioProxy.emergencyDial(serial, 183 RILUtils.convertToHalDial(address, clirMode, uusInfo), 184 emergencyNumberInfo.getEmergencyServiceCategoryBitmaskInternalDial(), 185 emergencyNumberInfo.getEmergencyUrns() != null 186 ? new ArrayList(emergencyNumberInfo.getEmergencyUrns()) 187 : new ArrayList<>(), 188 emergencyNumberInfo.getEmergencyCallRouting(), 189 hasKnownUserIntentEmergency, 190 emergencyNumberInfo.getEmergencyNumberSourceBitmask() 191 == EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST); 192 } 193 } 194 195 /** 196 * Call IRadioVoice#exitEmergencyCallbackMode 197 * @param serial Serial number of request 198 * @throws RemoteException 199 */ exitEmergencyCallbackMode(int serial)200 public void exitEmergencyCallbackMode(int serial) throws RemoteException { 201 if (isEmpty()) return; 202 if (isAidl()) { 203 mVoiceProxy.exitEmergencyCallbackMode(serial); 204 } else { 205 mRadioProxy.exitEmergencyCallbackMode(serial); 206 } 207 } 208 209 /** 210 * Call IRadioVoice#explicitCallTransfer 211 * @param serial Serial number of request 212 * @throws RemoteException 213 */ explicitCallTransfer(int serial)214 public void explicitCallTransfer(int serial) throws RemoteException { 215 if (isEmpty()) return; 216 if (isAidl()) { 217 mVoiceProxy.explicitCallTransfer(serial); 218 } else { 219 mRadioProxy.explicitCallTransfer(serial); 220 } 221 } 222 223 /** 224 * Call IRadioVoice#getCallForwardStatus 225 * @param serial Serial number of request 226 * @param cfReason One of CF_REASON_* 227 * @param serviceClass Sum of SERVICE_CLASS_* 228 * @param number Number 229 * @throws RemoteException 230 */ getCallForwardStatus(int serial, int cfReason, int serviceClass, String number)231 public void getCallForwardStatus(int serial, int cfReason, int serviceClass, String number) 232 throws RemoteException { 233 if (isEmpty()) return; 234 if (isAidl()) { 235 android.hardware.radio.voice.CallForwardInfo cfInfo = 236 new android.hardware.radio.voice.CallForwardInfo(); 237 cfInfo.reason = cfReason; 238 cfInfo.serviceClass = serviceClass; 239 cfInfo.toa = PhoneNumberUtils.toaFromString(number); 240 cfInfo.number = RILUtils.convertNullToEmptyString(number); 241 cfInfo.timeSeconds = 0; 242 mVoiceProxy.getCallForwardStatus(serial, cfInfo); 243 } else { 244 android.hardware.radio.V1_0.CallForwardInfo cfInfo = 245 new android.hardware.radio.V1_0.CallForwardInfo(); 246 cfInfo.reason = cfReason; 247 cfInfo.serviceClass = serviceClass; 248 cfInfo.toa = PhoneNumberUtils.toaFromString(number); 249 cfInfo.number = RILUtils.convertNullToEmptyString(number); 250 cfInfo.timeSeconds = 0; 251 mRadioProxy.getCallForwardStatus(serial, cfInfo); 252 } 253 } 254 255 /** 256 * Call IRadioVoice#getCallWaiting 257 * @param serial Serial number of request 258 * @param serviceClass Sum of SERVICE_CLASS_* 259 * @throws RemoteException 260 */ getCallWaiting(int serial, int serviceClass)261 public void getCallWaiting(int serial, int serviceClass) throws RemoteException { 262 if (isEmpty()) return; 263 if (isAidl()) { 264 mVoiceProxy.getCallWaiting(serial, serviceClass); 265 } else { 266 mRadioProxy.getCallWaiting(serial, serviceClass); 267 } 268 } 269 270 /** 271 * Call IRadioVoice#getClip 272 * @param serial Serial number of request 273 * @throws RemoteException 274 */ getClip(int serial)275 public void getClip(int serial) throws RemoteException { 276 if (isEmpty()) return; 277 if (isAidl()) { 278 mVoiceProxy.getClip(serial); 279 } else { 280 mRadioProxy.getClip(serial); 281 } 282 } 283 284 /** 285 * Call IRadioVoice#getClir 286 * @param serial Serial number of request 287 * @throws RemoteException 288 */ getClir(int serial)289 public void getClir(int serial) throws RemoteException { 290 if (isEmpty()) return; 291 if (isAidl()) { 292 mVoiceProxy.getClir(serial); 293 } else { 294 mRadioProxy.getClir(serial); 295 } 296 } 297 298 /** 299 * Call IRadioVoice#getCurrentCalls 300 * @param serial Serial number of request 301 * @throws RemoteException 302 */ getCurrentCalls(int serial)303 public void getCurrentCalls(int serial) throws RemoteException { 304 if (isEmpty()) return; 305 if (isAidl()) { 306 mVoiceProxy.getCurrentCalls(serial); 307 } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6)) { 308 ((android.hardware.radio.V1_6.IRadio) mRadioProxy).getCurrentCalls_1_6(serial); 309 } else { 310 mRadioProxy.getCurrentCalls(serial); 311 } 312 } 313 314 /** 315 * Call IRadioVoice#getLastCallFailCause 316 * @param serial Serial number of request 317 * @throws RemoteException 318 */ getLastCallFailCause(int serial)319 public void getLastCallFailCause(int serial) throws RemoteException { 320 if (isEmpty()) return; 321 if (isAidl()) { 322 mVoiceProxy.getLastCallFailCause(serial); 323 } else { 324 mRadioProxy.getLastCallFailCause(serial); 325 } 326 } 327 328 /** 329 * Call IRadioVoice#getMute 330 * @param serial Serial number of request 331 * @throws RemoteException 332 */ getMute(int serial)333 public void getMute(int serial) throws RemoteException { 334 if (isEmpty()) return; 335 if (isAidl()) { 336 mVoiceProxy.getMute(serial); 337 } else { 338 mRadioProxy.getMute(serial); 339 } 340 } 341 342 /** 343 * Call IRadioVoice#getPreferredVoicePrivacy 344 * @param serial Serial number of request 345 * @throws RemoteException 346 */ getPreferredVoicePrivacy(int serial)347 public void getPreferredVoicePrivacy(int serial) throws RemoteException { 348 if (isEmpty()) return; 349 if (isAidl()) { 350 mVoiceProxy.getPreferredVoicePrivacy(serial); 351 } else { 352 mRadioProxy.getPreferredVoicePrivacy(serial); 353 } 354 } 355 356 /** 357 * Call IRadioVoice#getTtyMode 358 * @param serial Serial number of request 359 * @throws RemoteException 360 */ getTtyMode(int serial)361 public void getTtyMode(int serial) throws RemoteException { 362 if (isEmpty()) return; 363 if (isAidl()) { 364 mVoiceProxy.getTtyMode(serial); 365 } else { 366 mRadioProxy.getTTYMode(serial); 367 } 368 } 369 370 /** 371 * Call IRadioVoice#handleStkCallSetupRequestFromSim 372 * @param serial Serial number of request 373 * @param accept Whether or not the call is to be accepted 374 * @throws RemoteException 375 */ handleStkCallSetupRequestFromSim(int serial, boolean accept)376 public void handleStkCallSetupRequestFromSim(int serial, boolean accept) 377 throws RemoteException { 378 if (isEmpty()) return; 379 if (isAidl()) { 380 mVoiceProxy.handleStkCallSetupRequestFromSim(serial, accept); 381 } else { 382 mRadioProxy.handleStkCallSetupRequestFromSim(serial, accept); 383 } 384 } 385 386 /** 387 * Call IRadioVoice#hangup 388 * @param serial Serial number of request 389 * @param gsmIndex Connection index 390 * @throws RemoteException 391 */ hangup(int serial, int gsmIndex)392 public void hangup(int serial, int gsmIndex) throws RemoteException { 393 if (isEmpty()) return; 394 if (isAidl()) { 395 mVoiceProxy.hangup(serial, gsmIndex); 396 } else { 397 mRadioProxy.hangup(serial, gsmIndex); 398 } 399 } 400 401 /** 402 * Call IRadioVoice#hangupForegroundResumeBackground 403 * @param serial Serial number of request 404 * @throws RemoteException 405 */ hangupForegroundResumeBackground(int serial)406 public void hangupForegroundResumeBackground(int serial) throws RemoteException { 407 if (isEmpty()) return; 408 if (isAidl()) { 409 mVoiceProxy.hangupForegroundResumeBackground(serial); 410 } else { 411 mRadioProxy.hangupForegroundResumeBackground(serial); 412 } 413 } 414 415 /** 416 * Call IRadioVoice#hangupWaitingOrBackground 417 * @param serial Serial number of request 418 * @throws RemoteException 419 */ hangupWaitingOrBackground(int serial)420 public void hangupWaitingOrBackground(int serial) throws RemoteException { 421 if (isEmpty()) return; 422 if (isAidl()) { 423 mVoiceProxy.hangupWaitingOrBackground(serial); 424 } else { 425 mRadioProxy.hangupWaitingOrBackground(serial); 426 } 427 } 428 429 /** 430 * Call IRadioVoice#isVoNrEnabled 431 * @param serial Serial number of request 432 * @throws RemoteException 433 */ isVoNrEnabled(int serial)434 public void isVoNrEnabled(int serial) throws RemoteException { 435 if (isEmpty()) return; 436 if (isAidl()) { 437 mVoiceProxy.isVoNrEnabled(serial); 438 } 439 } 440 441 /** 442 * Call IRadioVoice#rejectCall 443 * @param serial Serial number of request 444 * @throws RemoteException 445 */ rejectCall(int serial)446 public void rejectCall(int serial) throws RemoteException { 447 if (isEmpty()) return; 448 if (isAidl()) { 449 mVoiceProxy.rejectCall(serial); 450 } else { 451 mRadioProxy.rejectCall(serial); 452 } 453 } 454 455 /** 456 * Call IRadioVoice#responseAcknowledgement 457 * @throws RemoteException 458 */ 459 @Override responseAcknowledgement()460 public void responseAcknowledgement() throws RemoteException { 461 if (isEmpty()) return; 462 if (isAidl()) { 463 mVoiceProxy.responseAcknowledgement(); 464 } else { 465 mRadioProxy.responseAcknowledgement(); 466 } 467 } 468 469 /** 470 * Call IRadioVoice#sendBurstDtmf 471 * @param serial Serial number of request 472 * @param dtmf DTMF string 473 * @param on DTMF ON length in milliseconds, or 0 to use default 474 * @param off DTMF OFF length in milliseconds, or 0 to use default 475 * @throws RemoteException 476 */ sendBurstDtmf(int serial, String dtmf, int on, int off)477 public void sendBurstDtmf(int serial, String dtmf, int on, int off) throws RemoteException { 478 if (isEmpty()) return; 479 if (isAidl()) { 480 mVoiceProxy.sendBurstDtmf(serial, dtmf, on, off); 481 } else { 482 mRadioProxy.sendBurstDtmf(serial, dtmf, on, off); 483 } 484 } 485 486 /** 487 * Call IRadioVoice#sendCdmaFeatureCode 488 * @param serial Serial number of request 489 * @param featureCode String associated with FLASH command 490 * @throws RemoteException 491 */ sendCdmaFeatureCode(int serial, String featureCode)492 public void sendCdmaFeatureCode(int serial, String featureCode) throws RemoteException { 493 if (Flags.cleanupCdma()) return; 494 if (isEmpty()) return; 495 if (isAidl()) { 496 mVoiceProxy.sendCdmaFeatureCode(serial, featureCode); 497 } else { 498 mRadioProxy.sendCDMAFeatureCode(serial, featureCode); 499 } 500 } 501 502 /** 503 * Call IRadioVoice#sendDtmf 504 * @param serial Serial number of request 505 * @param s String with single char having one of 12 values: 0-0, *, # 506 * @throws RemoteException 507 */ sendDtmf(int serial, String s)508 public void sendDtmf(int serial, String s) throws RemoteException { 509 if (isEmpty()) return; 510 if (isAidl()) { 511 mVoiceProxy.sendDtmf(serial, s); 512 } else { 513 mRadioProxy.sendDtmf(serial, s); 514 } 515 } 516 517 /** 518 * Call IRadioVoice#sendUssd 519 * @param serial Serial number of request 520 * @param ussd String containing the USSD request in UTF-8 format 521 * @throws RemoteException 522 */ sendUssd(int serial, String ussd)523 public void sendUssd(int serial, String ussd) throws RemoteException { 524 if (isEmpty()) return; 525 if (isAidl()) { 526 mVoiceProxy.sendUssd(serial, ussd); 527 } else { 528 mRadioProxy.sendUssd(serial, ussd); 529 } 530 } 531 532 /** 533 * Call IRadioVoice#separateConnection 534 * @param serial Serial number of request 535 * @param gsmIndex Connection index 536 * @throws RemoteException 537 */ separateConnection(int serial, int gsmIndex)538 public void separateConnection(int serial, int gsmIndex) throws RemoteException { 539 if (isEmpty()) return; 540 if (isAidl()) { 541 mVoiceProxy.separateConnection(serial, gsmIndex); 542 } else { 543 mRadioProxy.separateConnection(serial, gsmIndex); 544 } 545 } 546 547 /** 548 * Call IRadioVoice#setCallForward 549 * @param serial Serial number of request 550 * @param action One of CF_ACTION_* 551 * @param cfReason One of CF_REASON_* 552 * @param serviceClass Sum of SERVICE_CLASSS_* 553 * @param number Number 554 * @param timeSeconds Time in seconds 555 * @throws RemoteException 556 */ setCallForward(int serial, int action, int cfReason, int serviceClass, String number, int timeSeconds)557 public void setCallForward(int serial, int action, int cfReason, int serviceClass, 558 String number, int timeSeconds) throws RemoteException { 559 if (isEmpty()) return; 560 if (isAidl()) { 561 android.hardware.radio.voice.CallForwardInfo cfInfo = 562 new android.hardware.radio.voice.CallForwardInfo(); 563 cfInfo.status = action; 564 cfInfo.reason = cfReason; 565 cfInfo.serviceClass = serviceClass; 566 cfInfo.toa = PhoneNumberUtils.toaFromString(number); 567 cfInfo.number = RILUtils.convertNullToEmptyString(number); 568 cfInfo.timeSeconds = timeSeconds; 569 mVoiceProxy.setCallForward(serial, cfInfo); 570 } else { 571 android.hardware.radio.V1_0.CallForwardInfo cfInfo = 572 new android.hardware.radio.V1_0.CallForwardInfo(); 573 cfInfo.status = action; 574 cfInfo.reason = cfReason; 575 cfInfo.serviceClass = serviceClass; 576 cfInfo.toa = PhoneNumberUtils.toaFromString(number); 577 cfInfo.number = RILUtils.convertNullToEmptyString(number); 578 cfInfo.timeSeconds = timeSeconds; 579 mRadioProxy.setCallForward(serial, cfInfo); 580 } 581 } 582 583 /** 584 * Call IRadioVoice#setCallWaiting 585 * @param serial Serial number of request 586 * @param enable True to enable, false to disable 587 * @param serviceClass Sum of SERVICE_CLASS_* 588 * @throws RemoteException 589 */ setCallWaiting(int serial, boolean enable, int serviceClass)590 public void setCallWaiting(int serial, boolean enable, int serviceClass) 591 throws RemoteException { 592 if (isEmpty()) return; 593 if (isAidl()) { 594 mVoiceProxy.setCallWaiting(serial, enable, serviceClass); 595 } else { 596 mRadioProxy.setCallWaiting(serial, enable, serviceClass); 597 } 598 } 599 600 /** 601 * Call IRadioVoice#setClir 602 * @param serial Serial number of request 603 * @param status One of CLIR_* 604 * @throws RemoteException 605 */ setClir(int serial, int status)606 public void setClir(int serial, int status) throws RemoteException { 607 if (isEmpty()) return; 608 if (isAidl()) { 609 mVoiceProxy.setClir(serial, status); 610 } else { 611 mRadioProxy.setClir(serial, status); 612 } 613 } 614 615 /** 616 * Call IRadioVoice#setMute 617 * @param serial Serial number of request 618 * @param enable True to enable, false to disable 619 * @throws RemoteException 620 */ setMute(int serial, boolean enable)621 public void setMute(int serial, boolean enable) throws RemoteException { 622 if (isEmpty()) return; 623 if (isAidl()) { 624 mVoiceProxy.setMute(serial, enable); 625 } else { 626 mRadioProxy.setMute(serial, enable); 627 } 628 } 629 630 /** 631 * Call IRadioVoice#setPreferredVoicePrivacy 632 * @param serial Serial number of request 633 * @param enable True is enhanced, false is normal voice privacy 634 * @throws RemoteException 635 */ setPreferredVoicePrivacy(int serial, boolean enable)636 public void setPreferredVoicePrivacy(int serial, boolean enable) throws RemoteException { 637 if (isEmpty()) return; 638 if (isAidl()) { 639 mVoiceProxy.setPreferredVoicePrivacy(serial, enable); 640 } else { 641 mRadioProxy.setPreferredVoicePrivacy(serial, enable); 642 } 643 } 644 645 /** 646 * Call IRadioVoice#setTtyMode 647 * @param serial Serial number of request 648 * @param mode One of TTY_MODE_* 649 * @throws RemoteException 650 */ setTtyMode(int serial, int mode)651 public void setTtyMode(int serial, int mode) throws RemoteException { 652 if (isEmpty()) return; 653 if (isAidl()) { 654 mVoiceProxy.setTtyMode(serial, mode); 655 } else { 656 mRadioProxy.setTTYMode(serial, mode); 657 } 658 } 659 660 /** 661 * Call IRadioVoice#setVoNrEnabled 662 * @param serial Serial number of request 663 * @param enable True to enable, false to disable 664 * @throws RemoteException 665 */ setVoNrEnabled(int serial, boolean enable)666 public void setVoNrEnabled(int serial, boolean enable) throws RemoteException { 667 if (isEmpty()) return; 668 if (isAidl()) { 669 mVoiceProxy.setVoNrEnabled(serial, enable); 670 } 671 } 672 673 /** 674 * Call IRadioVoice#startDtmf 675 * @param serial Serial number of request 676 * @param s String having a single character with one of 12 values: 0-9, *, # 677 * @throws RemoteException 678 */ startDtmf(int serial, String s)679 public void startDtmf(int serial, String s) throws RemoteException { 680 if (isEmpty()) return; 681 if (isAidl()) { 682 mVoiceProxy.startDtmf(serial, s); 683 } else { 684 mRadioProxy.startDtmf(serial, s); 685 } 686 } 687 688 /** 689 * Call IRadioVoice#stopDtmf 690 * @param serial Serial number of request 691 * @throws RemoteException 692 */ stopDtmf(int serial)693 public void stopDtmf(int serial) throws RemoteException { 694 if (isEmpty()) return; 695 if (isAidl()) { 696 mVoiceProxy.stopDtmf(serial); 697 } else { 698 mRadioProxy.stopDtmf(serial); 699 } 700 } 701 702 /** 703 * Call IRadioVoice#switchWaitingOrHoldingAndActive 704 * @param serial Serial number of request 705 * @throws RemoteException 706 */ switchWaitingOrHoldingAndActive(int serial)707 public void switchWaitingOrHoldingAndActive(int serial) throws RemoteException { 708 if (isEmpty()) return; 709 if (isAidl()) { 710 mVoiceProxy.switchWaitingOrHoldingAndActive(serial); 711 } else { 712 mRadioProxy.switchWaitingOrHoldingAndActive(serial); 713 } 714 } 715 } 716