• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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