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 com.android.telephony.imsmedia; 18 19 import android.os.Parcel; 20 import android.os.ParcelFileDescriptor; 21 import android.telephony.imsmedia.ImsMediaSession; 22 23 import com.android.telephony.imsmedia.Utils.OpenSessionParams; 24 import com.android.telephony.imsmedia.util.Log; 25 26 /** 27 * Audio service for internal AP based RTP stack. This interacts with native library 28 * to open/close {@link AudioLocalSession} 29 */ 30 public class AudioService { 31 private static final String LOG_TAG = "AudioService"; 32 private long mNativeObject = 0; 33 private AudioListener mListener = null; 34 AudioService()35 AudioService() { 36 mNativeObject = JNIImsMediaService.getInterface(ImsMediaSession.SESSION_TYPE_AUDIO); 37 } 38 39 /** Returns the native instance identifier of AudioManager in libimsmedia*/ getNativeObject()40 public long getNativeObject() { 41 return mNativeObject; 42 } 43 44 /** Sets JNI listener to get JNI callback from libimsmediajni library*/ setListener(final AudioListener listener)45 public void setListener(final AudioListener listener) { 46 mListener = listener; 47 } 48 49 /** 50 * Sends request message with the corresponding arguments to libimsmediajni library to operate 51 * 52 * @param sessionId : session identifier 53 * @param parcel : parcel argument to send to JNI 54 */ sendRequest(final int sessionId, Parcel parcel)55 public void sendRequest(final int sessionId, Parcel parcel) { 56 if (mNativeObject != 0) { 57 byte[] data = parcel.marshall(); 58 parcel.recycle(); 59 parcel = null; 60 JNIImsMediaService.sendMessage(mNativeObject, sessionId, data); 61 } 62 } 63 64 /** 65 * Opens a RTP session based on local the local sockets with the associated 66 * initial remote configuration if there is a valid RtpConfig passed. 67 * It starts the media flow if the media direction in the RtpConfig is set 68 * to any value other than NO_MEDIA_FLOW. If the open session is 69 * successful then a new AudioLocalSession object will be created using 70 * the JNIImsMediaListener#onMessage() API. If the open 71 * session is failed then a error code will be returned using 72 * JNIImsMediaListener#onMessage(int) API. 73 * 74 * @param sessionId A unique RTP session identifier 75 * @param sessionParams Paratmers including rtp, rtcp socket to send and receive incoming 76 * RTP packets and RtpConfig to create session. 77 * 78 * @return RESULT_INVALID_PARAM - input params are not valid and 79 * RESULT_SUCCESS - open session request is accepted. 80 */ openSession(final int sessionId, final OpenSessionParams sessionParams)81 public int openSession(final int sessionId, final OpenSessionParams sessionParams) { 82 if (mNativeObject == 0 || sessionParams == null) { 83 return ImsMediaSession.RESULT_INVALID_PARAM; 84 } 85 86 ParcelFileDescriptor rtpSockFd = sessionParams.getRtpFd(); 87 ParcelFileDescriptor rtcpSockFd = sessionParams.getRtcpFd(); 88 if (rtpSockFd == null || rtcpSockFd == null) { 89 Log.e(LOG_TAG, "Rtp/Rtcp socket fds are null"); 90 return ImsMediaSession.RESULT_INVALID_PARAM; 91 } 92 93 JNIImsMediaService.setListener(sessionId, mListener); 94 95 final int socketFdRtp = rtpSockFd.detachFd(); 96 final int socketFdRtcp = rtcpSockFd.detachFd(); 97 98 Parcel parcel = Parcel.obtain(); 99 parcel.writeInt(AudioSession.CMD_OPEN_SESSION); 100 parcel.writeInt(socketFdRtp); 101 parcel.writeInt(socketFdRtcp); 102 103 if (sessionParams.getRtpConfig() != null) { 104 sessionParams.getRtpConfig().writeToParcel(parcel, ImsMediaSession.SESSION_TYPE_AUDIO); 105 } 106 sendRequest(sessionId, parcel); 107 return ImsMediaSession.RESULT_SUCCESS; 108 } 109 110 /** 111 * Closes the RTP session including cleanup of all the resources 112 * associated with the session. This will also close the session object 113 * and associated callback. 114 * 115 * @param sessionId RTP session to be closed. 116 */ closeSession(final int sessionId)117 public void closeSession(final int sessionId) { 118 Log.dc(LOG_TAG, "closeSession"); 119 Parcel parcel = Parcel.obtain(); 120 parcel.writeInt(AudioSession.CMD_CLOSE_SESSION); 121 sendRequest(sessionId, parcel); 122 } 123 } 124