• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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.ims.stub;
18 
19 import android.annotation.NonNull;
20 import android.annotation.SystemApi;
21 import android.os.Message;
22 import android.os.RemoteException;
23 import android.telephony.ims.ImsCallProfile;
24 import android.telephony.ims.ImsCallSession;
25 import android.telephony.ims.ImsCallSessionListener;
26 import android.telephony.ims.ImsReasonInfo;
27 import android.telephony.ims.ImsStreamMediaProfile;
28 import android.telephony.ims.ImsVideoCallProvider;
29 import android.telephony.ims.RtpHeaderExtension;
30 import android.telephony.ims.RtpHeaderExtensionType;
31 import android.telephony.ims.aidl.IImsCallSessionListener;
32 import android.util.ArraySet;
33 import android.util.Log;
34 
35 import com.android.ims.internal.IImsCallSession;
36 import com.android.ims.internal.IImsVideoCallProvider;
37 import com.android.internal.telephony.util.TelephonyUtils;
38 
39 import java.util.List;
40 import java.util.Set;
41 import java.util.concurrent.CancellationException;
42 import java.util.concurrent.CompletableFuture;
43 import java.util.concurrent.CompletionException;
44 import java.util.concurrent.ExecutionException;
45 import java.util.concurrent.Executor;
46 import java.util.function.Supplier;
47 
48 /**
49  * Base implementation of IImsCallSession, which implements stub versions of the methods available.
50  *
51  * Override the methods that your implementation of ImsCallSession supports.
52  *
53  * @hide
54  */
55 @SystemApi
56 // DO NOT remove or change the existing APIs, only add new ones to this Base implementation or you
57 // will break other implementations of ImsCallSession maintained by other ImsServices.
58 public class ImsCallSessionImplBase implements AutoCloseable {
59 
60     private static final String LOG_TAG = "ImsCallSessionImplBase";
61     /**
62      * Notify USSD Mode.
63      */
64     public static final int USSD_MODE_NOTIFY = 0;
65     /**
66      * Request USSD Mode
67      */
68     public static final int USSD_MODE_REQUEST = 1;
69 
70     /**
71      * Defines IMS call session state.
72      */
73     public static class State {
74         public static final int IDLE = 0;
75         public static final int INITIATED = 1;
76         public static final int NEGOTIATING = 2;
77         public static final int ESTABLISHING = 3;
78         public static final int ESTABLISHED = 4;
79 
80         public static final int RENEGOTIATING = 5;
81         public static final int REESTABLISHING = 6;
82 
83         public static final int TERMINATING = 7;
84         public static final int TERMINATED = 8;
85 
86         public static final int INVALID = (-1);
87 
88         /**
89          * Converts the state to string.
90          */
toString(int state)91         public static String toString(int state) {
92             switch (state) {
93                 case IDLE:
94                     return "IDLE";
95                 case INITIATED:
96                     return "INITIATED";
97                 case NEGOTIATING:
98                     return "NEGOTIATING";
99                 case ESTABLISHING:
100                     return "ESTABLISHING";
101                 case ESTABLISHED:
102                     return "ESTABLISHED";
103                 case RENEGOTIATING:
104                     return "RENEGOTIATING";
105                 case REESTABLISHING:
106                     return "REESTABLISHING";
107                 case TERMINATING:
108                     return "TERMINATING";
109                 case TERMINATED:
110                     return "TERMINATED";
111                 default:
112                     return "UNKNOWN";
113             }
114         }
115 
116         /**
117          * @hide
118          */
State()119         private State() {
120         }
121     }
122 
123     private Executor mExecutor = Runnable::run;
124 
125     // Non-final for injection by tests
126     private IImsCallSession mServiceImpl = new IImsCallSession.Stub() {
127         @Override
128         public void close() {
129             executeMethodAsync(() -> ImsCallSessionImplBase.this.close(), "close");
130         }
131 
132         @Override
133         public String getCallId() {
134             return executeMethodAsyncForResult(() -> ImsCallSessionImplBase.this.getCallId(),
135                     "getCallId");
136         }
137 
138         @Override
139         public ImsCallProfile getCallProfile() {
140             return executeMethodAsyncForResult(() -> ImsCallSessionImplBase.this.getCallProfile(),
141                     "getCallProfile");
142         }
143 
144         @Override
145         public ImsCallProfile getLocalCallProfile() {
146             return executeMethodAsyncForResult(() -> ImsCallSessionImplBase.this
147                     .getLocalCallProfile(), "getLocalCallProfile");
148         }
149 
150         @Override
151         public ImsCallProfile getRemoteCallProfile() {
152             return executeMethodAsyncForResult(() -> ImsCallSessionImplBase.this
153                     .getRemoteCallProfile(), "getRemoteCallProfile");
154         }
155 
156         @Override
157         public String getProperty(String name) {
158             return executeMethodAsyncForResult(() -> ImsCallSessionImplBase.this.getProperty(name),
159                     "getProperty");
160         }
161 
162         @Override
163         public int getState() {
164             return executeMethodAsyncForResult(() -> ImsCallSessionImplBase.this.getState(),
165                     "getState");
166         }
167 
168         @Override
169         public boolean isInCall() {
170             return executeMethodAsyncForResult(() -> ImsCallSessionImplBase.this.isInCall(),
171                     "isInCall");
172         }
173 
174         @Override
175         public void setListener(IImsCallSessionListener listener) {
176             executeMethodAsync(() -> ImsCallSessionImplBase.this.setListener(
177                     new ImsCallSessionListener(listener)), "setListener");
178         }
179 
180         @Override
181         public void setMute(boolean muted) {
182             executeMethodAsync(() -> ImsCallSessionImplBase.this.setMute(muted), "setMute");
183         }
184 
185         @Override
186         public void start(String callee, ImsCallProfile profile) {
187             executeMethodAsync(() -> ImsCallSessionImplBase.this.start(callee, profile), "start");
188         }
189 
190         @Override
191         public void startConference(String[] participants, ImsCallProfile profile) throws
192                 RemoteException {
193             executeMethodAsync(() -> ImsCallSessionImplBase.this.startConference(participants,
194                     profile), "startConference");
195         }
196 
197         @Override
198         public void accept(int callType, ImsStreamMediaProfile profile) {
199             executeMethodAsync(() -> ImsCallSessionImplBase.this.accept(callType, profile),
200                     "accept");
201         }
202 
203         @Override
204         public void deflect(String deflectNumber) {
205             executeMethodAsync(() -> ImsCallSessionImplBase.this.deflect(deflectNumber),
206                     "deflect");
207         }
208 
209         @Override
210         public void reject(int reason) {
211             executeMethodAsync(() -> ImsCallSessionImplBase.this.reject(reason), "reject");
212         }
213 
214         @Override
215         public void transfer(@NonNull String number, boolean isConfirmationRequired) {
216             executeMethodAsync(() -> ImsCallSessionImplBase.this.transfer(number,
217                     isConfirmationRequired), "transfer");
218         }
219 
220         @Override
221         public void consultativeTransfer(@NonNull IImsCallSession transferToSession) {
222             executeMethodAsync(() -> {
223                 ImsCallSessionImplBase otherSession = new ImsCallSessionImplBase();
224                 otherSession.setServiceImpl(transferToSession);
225                 ImsCallSessionImplBase.this.transfer(otherSession);
226             }, "consultativeTransfer");
227         }
228 
229         @Override
230         public void terminate(int reason) {
231             executeMethodAsync(() -> ImsCallSessionImplBase.this.terminate(reason), "terminate");
232         }
233 
234         @Override
235         public void hold(ImsStreamMediaProfile profile) {
236             executeMethodAsync(() -> ImsCallSessionImplBase.this.hold(profile), "hold");
237         }
238 
239         @Override
240         public void resume(ImsStreamMediaProfile profile) {
241             executeMethodAsync(() -> ImsCallSessionImplBase.this.resume(profile), "resume");
242         }
243 
244         @Override
245         public void merge() {
246             executeMethodAsync(() -> ImsCallSessionImplBase.this.merge(), "merge");
247         }
248 
249         @Override
250         public void update(int callType, ImsStreamMediaProfile profile) {
251             executeMethodAsync(() -> ImsCallSessionImplBase.this.update(callType, profile),
252                     "update");
253         }
254 
255         @Override
256         public void extendToConference(String[] participants) {
257             executeMethodAsync(() -> ImsCallSessionImplBase.this.extendToConference(participants),
258                     "extendToConference");
259         }
260 
261         @Override
262         public void inviteParticipants(String[] participants) {
263             executeMethodAsync(() -> ImsCallSessionImplBase.this.inviteParticipants(participants),
264                     "inviteParticipants");
265         }
266 
267         @Override
268         public void removeParticipants(String[] participants) {
269             executeMethodAsync(() -> ImsCallSessionImplBase.this.removeParticipants(participants),
270                     "removeParticipants");
271         }
272 
273         @Override
274         public void sendDtmf(char c, Message result) {
275             executeMethodAsync(() -> ImsCallSessionImplBase.this.sendDtmf(c, result), "sendDtmf");
276         }
277 
278         @Override
279         public void startDtmf(char c) {
280             executeMethodAsync(() -> ImsCallSessionImplBase.this.startDtmf(c), "startDtmf");
281         }
282 
283         @Override
284         public void stopDtmf() {
285             executeMethodAsync(() -> ImsCallSessionImplBase.this.stopDtmf(), "stopDtmf");
286         }
287 
288         @Override
289         public void sendUssd(String ussdMessage) {
290             executeMethodAsync(() -> ImsCallSessionImplBase.this.sendUssd(ussdMessage), "sendUssd");
291         }
292 
293         @Override
294         public IImsVideoCallProvider getVideoCallProvider() {
295             return executeMethodAsyncForResult(() -> ImsCallSessionImplBase.this
296                     .getVideoCallProvider(), "getVideoCallProvider");
297         }
298 
299         @Override
300         public boolean isMultiparty() {
301             return executeMethodAsyncForResult(() -> ImsCallSessionImplBase.this.isMultiparty(),
302                     "isMultiparty");
303         }
304 
305         @Override
306         public void sendRttModifyRequest(ImsCallProfile toProfile) {
307             executeMethodAsync(() -> ImsCallSessionImplBase.this.sendRttModifyRequest(toProfile),
308                     "sendRttModifyRequest");
309         }
310 
311         @Override
312         public void sendRttModifyResponse(boolean status) {
313             executeMethodAsync(() -> ImsCallSessionImplBase.this.sendRttModifyResponse(status),
314                     "sendRttModifyResponse");
315         }
316 
317         @Override
318         public void sendRttMessage(String rttMessage) {
319             executeMethodAsync(() -> ImsCallSessionImplBase.this.sendRttMessage(rttMessage),
320                     "sendRttMessage");
321         }
322 
323         @Override
324         public void sendRtpHeaderExtensions(@NonNull List<RtpHeaderExtension> extensions) {
325             executeMethodAsync(() -> ImsCallSessionImplBase.this.sendRtpHeaderExtensions(
326                     new ArraySet<RtpHeaderExtension>(extensions)), "sendRtpHeaderExtensions");
327         }
328 
329         // Call the methods with a clean calling identity on the executor and wait indefinitely for
330         // the future to return.
331         private void executeMethodAsync(Runnable r, String errorLogName) {
332             try {
333                 CompletableFuture.runAsync(
334                         () -> TelephonyUtils.runWithCleanCallingIdentity(r), mExecutor).join();
335             } catch (CancellationException | CompletionException e) {
336                 Log.w(LOG_TAG, "ImsCallSessionImplBase Binder - " + errorLogName + " exception: "
337                         + e.getMessage());
338             }
339         }
340 
341         private <T> T executeMethodAsyncForResult(Supplier<T> r,
342                 String errorLogName) {
343             CompletableFuture<T> future = CompletableFuture.supplyAsync(
344                     () -> TelephonyUtils.runWithCleanCallingIdentity(r), mExecutor);
345             try {
346                 return future.get();
347             } catch (ExecutionException | InterruptedException e) {
348                 Log.w(LOG_TAG, "ImsCallSessionImplBase Binder - " + errorLogName + " exception: "
349                         + e.getMessage());
350                 return null;
351             }
352         }
353     };
354 
355     /**
356      * @hide
357      */
setListener(IImsCallSessionListener listener)358     public final void setListener(IImsCallSessionListener listener) throws RemoteException {
359         setListener(new ImsCallSessionListener(listener));
360     }
361 
362     /**
363      * Sets the listener to listen to the session events. An {@link ImsCallSession}
364      * can only hold one listener at a time. Subsequent calls to this method
365      * override the previous listener.
366      *
367      * @param listener {@link ImsCallSessionListener} used to notify the framework of updates
368      * to the ImsCallSession
369      */
setListener(ImsCallSessionListener listener)370     public void setListener(ImsCallSessionListener listener) {
371     }
372 
373     /**
374      * Closes the object. This {@link ImsCallSessionImplBase} is not usable after being closed.
375      */
376     @Override
close()377     public void close() {
378 
379     }
380 
381     /**
382      * @return A String containing the unique call ID of this {@link ImsCallSessionImplBase}.
383      */
getCallId()384     public String getCallId() {
385         return null;
386     }
387 
388     /**
389      * @return The {@link ImsCallProfile} that this {@link ImsCallSessionImplBase} is associated
390      * with.
391      */
getCallProfile()392     public ImsCallProfile getCallProfile() {
393         return null;
394     }
395 
396     /**
397      * @return The local {@link ImsCallProfile} that this {@link ImsCallSessionImplBase} is
398      * associated with.
399      */
getLocalCallProfile()400     public ImsCallProfile getLocalCallProfile() {
401         return null;
402     }
403 
404     /**
405      * @return The remote {@link ImsCallProfile} that this {@link ImsCallSessionImplBase} is
406      * associated with.
407      */
getRemoteCallProfile()408     public ImsCallProfile getRemoteCallProfile() {
409         return null;
410     }
411 
412     /**
413      * @param name The String extra key.
414      * @return The string extra value associated with the specified property.
415      */
getProperty(String name)416     public String getProperty(String name) {
417         return null;
418     }
419 
420     /**
421      * @return The {@link ImsCallSessionImplBase} state, defined in
422      * {@link ImsCallSessionImplBase.State}.
423      */
getState()424     public int getState() {
425         return ImsCallSessionImplBase.State.INVALID;
426     }
427 
428     /**
429      * @return true if the {@link ImsCallSessionImplBase} is in a call, false otherwise.
430      */
isInCall()431     public boolean isInCall() {
432         return false;
433     }
434 
435     /**
436      * Mutes or unmutes the mic for the active call.
437      *
438      * @param muted true if the call should be muted, false otherwise.
439      */
setMute(boolean muted)440     public void setMute(boolean muted) {
441     }
442 
443     /**
444      * Initiates an IMS call with the specified number and call profile.
445      * The session listener set in {@link #setListener(ImsCallSessionListener)} is called back upon
446      * defined session events.
447      * Only valid to call when the session state is in
448      * {@link ImsCallSession.State#IDLE}.
449      *
450      * @param callee dialed string to make the call to
451      * @param profile call profile to make the call with the specified service type,
452      *      call type and media information
453      * @see {@link ImsCallSession.Listener#callSessionStarted},
454      * {@link ImsCallSession.Listener#callSessionStartFailed}
455      */
start(String callee, ImsCallProfile profile)456     public void start(String callee, ImsCallProfile profile) {
457     }
458 
459     /**
460      * Initiates an IMS call with the specified participants and call profile.
461      * The session listener set in {@link #setListener(ImsCallSessionListener)} is called back upon
462      * defined session events.
463      * The method is only valid to call when the session state is in
464      * {@link ImsCallSession.State#IDLE}.
465      *
466      * @param participants participant list to initiate an IMS conference call
467      * @param profile call profile to make the call with the specified service type,
468      *      call type and media information
469      * @see {@link ImsCallSession.Listener#callSessionStarted},
470      * {@link ImsCallSession.Listener#callSessionStartFailed}
471      */
startConference(String[] participants, ImsCallProfile profile)472     public void startConference(String[] participants, ImsCallProfile profile) {
473     }
474 
475     /**
476      * Accepts an incoming call or session update.
477      *
478      * @param callType call type specified in {@link ImsCallProfile} to be answered
479      * @param profile stream media profile {@link ImsStreamMediaProfile} to be answered
480      * @see {@link ImsCallSession.Listener#callSessionStarted}
481      */
accept(int callType, ImsStreamMediaProfile profile)482     public void accept(int callType, ImsStreamMediaProfile profile) {
483     }
484 
485     /**
486      * Deflects an incoming call.
487      *
488      * @param deflectNumber number to deflect the call
489      */
deflect(String deflectNumber)490     public void deflect(String deflectNumber) {
491     }
492 
493     /**
494      * Rejects an incoming call or session update.
495      *
496      * @param reason reason code to reject an incoming call, defined in {@link ImsReasonInfo}.
497      *               The {@link android.telecom.InCallService} (dialer app) can use the
498      *               {@link android.telecom.Call#reject(int)} API to reject a call while specifying
499      *               a user-indicated reason for rejecting the call.
500      *               Normal call declines ({@link android.telecom.Call#REJECT_REASON_DECLINED}) will
501      *               map to {@link ImsReasonInfo#CODE_USER_DECLINE}.
502      *               Unwanted calls ({@link android.telecom.Call#REJECT_REASON_UNWANTED}) will map
503      *               to {@link ImsReasonInfo#CODE_SIP_USER_MARKED_UNWANTED}.
504      * {@link ImsCallSession.Listener#callSessionStartFailed}
505      */
reject(int reason)506     public void reject(int reason) {
507     }
508 
509     /**
510      * Transfer an established call to given number
511      *
512      * @param number number to transfer the call
513      * @param isConfirmationRequired if {@code True}, indicates a confirmed transfer,
514      * if {@code False} it indicates an unconfirmed transfer.
515      * @hide
516      */
transfer(@onNull String number, boolean isConfirmationRequired)517     public void transfer(@NonNull String number, boolean isConfirmationRequired) {
518     }
519 
520     /**
521      * Transfer an established call to another call session
522      *
523      * @param otherSession The other ImsCallSession to transfer the ongoing session to.
524      * @hide
525      */
transfer(@onNull ImsCallSessionImplBase otherSession)526     public void transfer(@NonNull ImsCallSessionImplBase otherSession) {
527     }
528 
529     /**
530      * Terminates a call.
531      *
532      * @param reason reason code to terminate a call, defined in {@link ImsReasonInfo}.
533      *
534      * @see {@link ImsCallSession.Listener#callSessionTerminated}
535      */
terminate(int reason)536     public void terminate(int reason) {
537     }
538 
539     /**
540      * Puts a call on hold. When it succeeds, {@link ImsCallSession.Listener#callSessionHeld} is
541      * called.
542      *
543      * @param profile stream media profile {@link ImsStreamMediaProfile} to hold the call
544      * @see {@link ImsCallSession.Listener#callSessionHeld},
545      * {@link ImsCallSession.Listener#callSessionHoldFailed}
546      */
hold(ImsStreamMediaProfile profile)547     public void hold(ImsStreamMediaProfile profile) {
548     }
549 
550     /**
551      * Continues a call that's on hold. When it succeeds,
552      * {@link ImsCallSession.Listener#callSessionResumed} is called.
553      *
554      * @param profile stream media profile with {@link ImsStreamMediaProfile} to resume the call
555      * @see {@link ImsCallSession.Listener#callSessionResumed},
556      * {@link ImsCallSession.Listener#callSessionResumeFailed}
557      */
resume(ImsStreamMediaProfile profile)558     public void resume(ImsStreamMediaProfile profile) {
559     }
560 
561     /**
562      * Merges the active and held call. When the merge starts,
563      * {@link ImsCallSession.Listener#callSessionMergeStarted} is called.
564      * {@link ImsCallSession.Listener#callSessionMergeComplete} is called if the merge is
565      * successful, and {@link ImsCallSession.Listener#callSessionMergeFailed} is called if the merge
566      * fails.
567      *
568      * @see {@link ImsCallSession.Listener#callSessionMergeStarted},
569      * {@link ImsCallSession.Listener#callSessionMergeComplete},
570      *      {@link ImsCallSession.Listener#callSessionMergeFailed}
571      */
merge()572     public void merge() {
573     }
574 
575     /**
576      * Updates the current call's properties (ex. call mode change: video upgrade / downgrade).
577      *
578      * @param callType call type specified in {@link ImsCallProfile} to be updated
579      * @param profile stream media profile {@link ImsStreamMediaProfile} to be updated
580      * @see {@link ImsCallSession.Listener#callSessionUpdated},
581      * {@link ImsCallSession.Listener#callSessionUpdateFailed}
582      */
update(int callType, ImsStreamMediaProfile profile)583     public void update(int callType, ImsStreamMediaProfile profile) {
584     }
585 
586     /**
587      * Extends this call to the conference call with the specified recipients.
588      *
589      * @param participants participant list to be invited to the conference call after extending the
590      * call
591      * @see {@link ImsCallSession.Listener#callSessionConferenceExtended},
592      * {@link ImsCallSession.Listener#callSessionConferenceExtendFailed}
593      */
extendToConference(String[] participants)594     public void extendToConference(String[] participants) {
595     }
596 
597     /**
598      * Requests the conference server to invite an additional participants to the conference.
599      *
600      * @param participants participant list to be invited to the conference call
601      * @see {@link ImsCallSession.Listener#callSessionInviteParticipantsRequestDelivered},
602      *      {@link ImsCallSession.Listener#callSessionInviteParticipantsRequestFailed}
603      */
inviteParticipants(String[] participants)604     public void inviteParticipants(String[] participants) {
605     }
606 
607     /**
608      * Requests the conference server to remove the specified participants from the conference.
609      *
610      * @param participants participant list to be removed from the conference call
611      * @see {@link ImsCallSession.Listener#callSessionRemoveParticipantsRequestDelivered},
612      *      {@link ImsCallSession.Listener#callSessionRemoveParticipantsRequestFailed}
613      */
removeParticipants(String[] participants)614     public void removeParticipants(String[] participants) {
615     }
616 
617     /**
618      * Sends a DTMF code. According to <a href="http://tools.ietf.org/html/rfc2833">RFC 2833</a>,
619      * event 0 ~ 9 maps to decimal value 0 ~ 9, '*' to 10, '#' to 11, event 'A' ~ 'D' to 12 ~ 15,
620      * and event flash to 16. Currently, event flash is not supported.
621      *
622      * @param c the DTMF to send. '0' ~ '9', 'A' ~ 'D', '*', '#' are valid inputs.
623      * @param result If non-null, the {@link Message} to send when the operation is complete. This
624      *         is done by using the associated {@link android.os.Messenger} in
625      *         {@link Message#replyTo}. For example:
626      * {@code
627      *     // Send DTMF and other operations...
628      *     try {
629      *         // Notify framework that the DTMF was sent.
630      *         Messenger dtmfMessenger = result.replyTo;
631      *         if (dtmfMessenger != null) {
632      *             dtmfMessenger.send(result);
633      *         }
634      *     } catch (RemoteException e) {
635      *         // Remote side is dead
636      *     }
637      * }
638      */
sendDtmf(char c, Message result)639     public void sendDtmf(char c, Message result) {
640     }
641 
642     /**
643      * Start a DTMF code. According to <a href="http://tools.ietf.org/html/rfc2833">RFC 2833</a>,
644      * event 0 ~ 9 maps to decimal value 0 ~ 9, '*' to 10, '#' to 11, event 'A' ~ 'D' to 12 ~ 15,
645      * and event flash to 16. Currently, event flash is not supported.
646      *
647      * @param c the DTMF to send. '0' ~ '9', 'A' ~ 'D', '*', '#' are valid inputs.
648      */
startDtmf(char c)649     public void startDtmf(char c) {
650     }
651 
652     /**
653      * Stop a DTMF code.
654      */
stopDtmf()655     public void stopDtmf() {
656     }
657 
658     /**
659      * Sends an USSD message.
660      *
661      * @param ussdMessage USSD message to send
662      */
sendUssd(String ussdMessage)663     public void sendUssd(String ussdMessage) {
664     }
665 
666     /**
667      * See {@link #getImsVideoCallProvider()}, used directly in older ImsService implementations.
668      * @hide
669      */
getVideoCallProvider()670     public IImsVideoCallProvider getVideoCallProvider() {
671         ImsVideoCallProvider provider = getImsVideoCallProvider();
672         return provider != null ? provider.getInterface() : null;
673     }
674 
675     /**
676      * @return The {@link ImsVideoCallProvider} implementation contained within the IMS service
677      * process.
678      */
getImsVideoCallProvider()679     public ImsVideoCallProvider getImsVideoCallProvider() {
680         return null;
681     }
682 
683     /**
684      * Determines if the current session is multiparty.
685      * @return {@code True} if the session is multiparty.
686      */
isMultiparty()687     public boolean isMultiparty() {
688         return false;
689     }
690 
691     /**
692      * Device issues RTT modify request
693      * @param toProfile The profile with requested changes made
694      */
sendRttModifyRequest(ImsCallProfile toProfile)695     public void sendRttModifyRequest(ImsCallProfile toProfile) {
696     }
697 
698     /**
699      * Device responds to Remote RTT modify request
700      * @param status true if the the request was accepted or false of the request is defined.
701      */
sendRttModifyResponse(boolean status)702     public void sendRttModifyResponse(boolean status) {
703     }
704 
705     /**
706      * Device sends RTT message
707      * @param rttMessage RTT message to be sent
708      */
sendRttMessage(String rttMessage)709     public void sendRttMessage(String rttMessage) {
710     }
711 
712     /**
713      * Device requests that {@code rtpHeaderExtensions} are sent as a header extension with the next
714      * RTP packet sent by the IMS stack.
715      * <p>
716      * The {@link RtpHeaderExtensionType}s negotiated during SDP (Session Description Protocol)
717      * signalling determine the {@link RtpHeaderExtension}s which can be sent using this method.
718      * See RFC8285 for more information.
719      * <p>
720      * By specification, the RTP header extension is an unacknowledged transmission and there is no
721      * guarantee that the header extension will be delivered by the network to the other end of the
722      * call.
723      * @param rtpHeaderExtensions The RTP header extensions to be included in the next RTP header.
724      */
sendRtpHeaderExtensions(@onNull Set<RtpHeaderExtension> rtpHeaderExtensions)725     public void sendRtpHeaderExtensions(@NonNull Set<RtpHeaderExtension> rtpHeaderExtensions) {
726     }
727 
728     /** @hide */
getServiceImpl()729     public IImsCallSession getServiceImpl() {
730         return mServiceImpl;
731     }
732 
733     /** @hide */
setServiceImpl(IImsCallSession serviceImpl)734     public void setServiceImpl(IImsCallSession serviceImpl) {
735         mServiceImpl = serviceImpl;
736     }
737 
738     /**
739      * Set default Executor from MmTelFeature.
740      * @param executor The default executor for the framework to use when executing the methods
741      * overridden by the implementation of ImsCallSession.
742      * @hide
743      */
setDefaultExecutor(@onNull Executor executor)744     public final void setDefaultExecutor(@NonNull Executor executor) {
745         mExecutor = executor;
746     }
747 }
748