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