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