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