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
17package android.telephony.ims.stub;
18
19import android.annotation.SystemApi;
20import android.os.Message;
21import android.os.RemoteException;
22import android.telephony.ims.ImsCallSessionListener;
23import android.telephony.ims.aidl.IImsCallSessionListener;
24
25import android.telephony.ims.ImsCallProfile;
26import android.telephony.ims.ImsReasonInfo;
27import android.telephony.ims.ImsStreamMediaProfile;
28import android.telephony.ims.ImsCallSession;
29import com.android.ims.internal.IImsCallSession;
30import com.android.ims.internal.IImsVideoCallProvider;
31import 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.
43public 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         */
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         */
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     */
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     */
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
292    public void close() {
293
294    }
295
296    /**
297     * @return A String containing the unique call ID of this {@link ImsCallSessionImplBase}.
298     */
299    public String getCallId() {
300        return null;
301    }
302
303    /**
304     * @return The {@link ImsCallProfile} that this {@link ImsCallSessionImplBase} is associated
305     * with.
306     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
537    public void startDtmf(char c) {
538    }
539
540    /**
541     * Stop a DTMF code.
542     */
543    public void stopDtmf() {
544    }
545
546    /**
547     * Sends an USSD message.
548     *
549     * @param ussdMessage USSD message to send
550     */
551    public void sendUssd(String ussdMessage) {
552    }
553
554    /**
555     * See {@link #getImsVideoCallProvider()}, used directly in older ImsService implementations.
556     * @hide
557     */
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     */
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     */
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     */
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     */
590    public void sendRttModifyResponse(boolean status) {
591    }
592
593    /**
594     * Device sends RTT message
595     * @param rttMessage RTT message to be sent
596     */
597    public void sendRttMessage(String rttMessage) {
598    }
599
600    /** @hide */
601    public IImsCallSession getServiceImpl() {
602        return mServiceImpl;
603    }
604
605    /** @hide */
606    public void setServiceImpl(IImsCallSession serviceImpl) {
607        mServiceImpl = serviceImpl;
608    }
609}
610