1 /**
2  * Copyright (C) 2022 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.imsmedia;
18 
19 import android.os.IBinder;
20 import android.os.RemoteException;
21 import android.telephony.ims.RtpHeaderExtension;
22 import android.util.Log;
23 
24 import java.util.List;
25 
26 /**
27  * API to manage the audio session
28  *
29  * @hide
30  */
31 public class ImsAudioSession implements ImsMediaSession {
32     private static final String TAG = "ImsAudioSession";
33     private final IImsAudioSession miSession;
34 
35     /** @hide */
ImsAudioSession(final IImsAudioSession session)36     public ImsAudioSession(final IImsAudioSession session) {
37         miSession = session;
38     }
39 
40     /** @hide */
41     @Override
getBinder()42     public IBinder getBinder() {
43         return miSession.asBinder();
44     }
45 
46     /** {@inheritDoc} */
getSessionId()47     public int getSessionId() {
48         try {
49             return miSession.getSessionId();
50         } catch (RemoteException e) {
51             Log.e(TAG, "Failed to get session ID: " + e);
52         }
53 
54         return -1;
55     }
56 
57     /**
58      * {@inheritDoc}
59      */
modifySession(final RtpConfig config)60     public void modifySession(final RtpConfig config) {
61         try {
62             miSession.modifySession((AudioConfig)config);
63         } catch (RemoteException e) {
64             Log.e(TAG, "Failed to modify session: " + e);
65         }
66     }
67 
68     /**
69      * {@inheritDoc}
70      */
setMediaQualityThreshold(final MediaQualityThreshold threshold)71     public void setMediaQualityThreshold(final MediaQualityThreshold threshold) {
72         try {
73             miSession.setMediaQualityThreshold(threshold);
74         } catch (RemoteException e) {
75             Log.e(TAG, "Failed to modify session: " + e);
76         }
77     }
78 
79     /**
80      * Adds a new remote configuration to a RTP session during early media
81      * scenarios where the IMS network could add more than one remote endpoint.
82      *
83      * @param config provides remote end point info and codec details
84      */
addConfig(final AudioConfig config)85     public void addConfig(final AudioConfig config) {
86         try {
87             miSession.addConfig(config);
88         } catch (RemoteException e) {
89             Log.e(TAG, "Failed to add config: " + e);
90         }
91     }
92 
93     /**
94      * Deletes a remote configuration from a RTP session during early media
95      * scenarios. A session shall have at least one config so this API shall
96      * not delete the last config.
97      *
98      * @param config remote config to be deleted
99      */
deleteConfig(final AudioConfig config)100     public void deleteConfig(final AudioConfig config) {
101         try {
102             miSession.deleteConfig(config);
103         } catch (RemoteException e) {
104             Log.e(TAG, "Failed to delete config: " + e);
105         }
106     }
107 
108     /**
109      * Confirms a remote configuration for a Rtp session for early media scenarios
110      * when there are more than one remote configs. All other early remote configs
111      * (potentially including the config created as part of openSession) are auto
112      * deleted when one config is confirmed.
113      * Confirming a remote configuration is necessary only if additional
114      * configurations were created.
115      * New remote configurations cannot be added after a remote configuration is
116      * confirmed.
117      *
118      * @param config remote config to be confirmed
119      */
confirmConfig(final AudioConfig config)120     public void confirmConfig(final AudioConfig config) {
121         try {
122             miSession.confirmConfig(config);
123         } catch (RemoteException e) {
124             Log.e(TAG, "Failed to confirm config: " + e);
125         }
126     }
127 
128     /**
129      * Send DTMF digit until the duration expires.
130      *
131      * @param dtmfDigit single char having one of 12 values: 0-9, *, #
132      * @param duration of the key press in milliseconds.
133      */
sendDtmf(final char dtmfDigit, final int duration)134     public void sendDtmf(final char dtmfDigit, final int duration) {
135         try {
136             miSession.sendDtmf(dtmfDigit, duration);
137         } catch (RemoteException e) {
138             Log.e(TAG, "Failed to send DTMF: " + e);
139         }
140     }
141 
142     /**
143      * Start sending DTMF digit until the stopDtmf() API is received.
144      * If the implementation is currently sending a DTMF tone for which
145      * stopDtmf() is not received yet, then that digit must be stopped first
146      *
147      * @param dtmfDigit single char having one of 12 values: 0-9, *, #
148      */
startDtmf(final char dtmfDigit)149     public void startDtmf(final char dtmfDigit) {
150         try {
151             miSession.startDtmf(dtmfDigit);
152         } catch (RemoteException e) {
153             Log.e(TAG, "Failed to start DTMF: " + e);
154         }
155     }
156 
157     /**
158      * Stop sending the last DTMF digit started by startDtmf().
159      * stopDtmf() without preceding startDtmf() must be ignored.
160      */
stopDtmf()161     public void stopDtmf() {
162         try {
163             miSession.stopDtmf();
164         } catch (RemoteException e) {
165             Log.e(TAG, "Failed to stop DTMF: " + e);
166         }
167     }
168 
169     /**
170      * Send RTP header extension to the other party in the next RTP packet.
171      *
172      * @param extensions List of RTP header extensions to be transmitted
173      */
sendHeaderExtension(final List<RtpHeaderExtension> extensions)174     public void sendHeaderExtension(final List<RtpHeaderExtension> extensions) {
175         try {
176             miSession.sendHeaderExtension(extensions);
177         } catch (RemoteException e) {
178             Log.e(TAG, "Failed to send RTP header extension: " + e);
179         }
180     }
181 
182     /**
183      * Request the current rtp reception statistics parameters for checking the current status of
184      * the rtp stream. It will trigger the notifyRtpReceptionStats() with the RtpReceptionStats.
185      *
186      * @param intervalMs The interval of the time in milliseconds of the rtp reception notification
187      */
requestRtpReceptionStats(int intervalMs)188     public void requestRtpReceptionStats(int intervalMs) {
189         try {
190             miSession.requestRtpReceptionStats(intervalMs);
191         } catch (RemoteException e) {
192             Log.e(TAG, "Failed to query rtp reception statistics: " + e);
193         }
194     }
195 
196     /**
197      * Adjust the delay in the jitter buffer to synchronize the audio with the time of video frames
198      *
199      * @param delayMs The delay to adjust the additional delay to the jitter buffer. The value is
200      * always positive.
201      */
adjustDelay(int delayMs)202     public void adjustDelay(int delayMs) {
203         try {
204             miSession.adjustDelay(delayMs);
205         } catch (RemoteException e) {
206             Log.e(TAG, "Failed to apply delay to the session de-jitter buffer: " + e);
207         }
208     }
209 }
210