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.content.res.AssetManager; 20 import android.os.Parcel; 21 import android.os.Process; 22 import android.util.ArrayMap; 23 import android.view.Surface; 24 25 import androidx.annotation.VisibleForTesting; 26 27 import com.android.telephony.imsmedia.util.Log; 28 29 /** JNI interface class to send message to libimsmediajni */ 30 public class JNIImsMediaService { 31 private static final String TAG = "JNIImsMediaService"; 32 private static final int THREAD_PRIORITY_REALTIME = -20; 33 public static JNIImsMediaService sService = null; 34 private final Object mLock = new Object(); 35 36 /** for media service based on type ex. audio, video, rtt */ 37 private static ArrayMap<Integer, JNIImsMediaListener> sListeners = 38 new ArrayMap<Integer, JNIImsMediaListener>(); 39 40 /** 41 * Gets instance object of BaseManager with the corresponding media type 42 * 43 * @param mediatype Audio/Video/Text type 44 * @return the native instance of BaseManager 45 */ getInterface(int mediatype)46 public static native long getInterface(int mediatype); 47 48 /** 49 * Send message to libimsmediajni to libimsmedia library to operate with corresponding 50 * arguments 51 * 52 * @param nativeObject An unique object identifier of BaseManager to operate 53 * @param sessionId An unique session identifier 54 * @param baData A parameter to operate session 55 */ sendMessage(long nativeObject, int sessionId, byte[] baData)56 public static native void sendMessage(long nativeObject, int sessionId, byte[] baData); 57 58 /** 59 * Set preview surface to libimsmediajni and it delivers libimsmedia 60 * 61 * @param nativeObject An unique object identifier of BaseManager to operate 62 * @param sessionId An unique session identifier 63 * @param surface A preview surface 64 */ setPreviewSurface(long nativeObject, int sessionId, Surface surface)65 public static native void setPreviewSurface(long nativeObject, int sessionId, Surface surface); 66 67 /** 68 * Set display surface to libimsmediajni and it delivers libimsmedia 69 * 70 * @param nativeObject An unique object identifier of BaseManager to operate 71 * @param sessionId An unique session identifier 72 * @param surface A display surface 73 */ setDisplaySurface(long nativeObject, int sessionId, Surface surface)74 public static native void setDisplaySurface(long nativeObject, int sessionId, Surface surface); 75 76 /** 77 * Generates SPROP list for the given set of video configurations. 78 * 79 * @param videoConfig video configuration for which sprop should be generated. 80 * @return returns the generated sprop value. 81 */ generateSprop(byte[] videoConfig)82 public static native String generateSprop(byte[] videoConfig); 83 84 /** 85 * Passes the application's asset manager reference to native which will be used to access 86 * pause images assets during video call multitasking scenarios. 87 * 88 * @param assetManager Application's asset manager reference. 89 */ setAssetManager(AssetManager assetManager)90 public static native void setAssetManager(AssetManager assetManager); 91 92 /** 93 * Set the libimsmedia library logging level and mode for debug 94 * 95 * @param logMode The log mode 96 * @param debugLogMode The debug log mode 97 */ setLogMode(int logMode, int debugLogMode)98 public static native void setLogMode(int logMode, int debugLogMode); 99 100 /** 101 * Gets intance of JNIImsMediaService for jni interface 102 * 103 * @return instance of JNIImsMediaService 104 */ getInstance()105 public static JNIImsMediaService getInstance() { 106 if (sService == null) { 107 sService = new JNIImsMediaService(); 108 } 109 return sService; 110 } 111 112 /** 113 * Sets listener to get callback from libimsmediajni 114 * 115 * @param sessionId An unique object identifier the session to use as a key to acquire a paired 116 * listener 117 * @param listener A listener to set for getting messages 118 */ setListener(final int sessionId, final JNIImsMediaListener listener)119 public static void setListener(final int sessionId, final JNIImsMediaListener listener) { 120 Log.d(TAG, "setListener() - sessionId=" + sessionId); 121 if (listener == null) { 122 Log.e(TAG, "setListener() - null listener"); 123 return; 124 } 125 synchronized (sListeners) { 126 sListeners.put(sessionId, listener); 127 } 128 } 129 130 /** 131 * Gets a listener with the key to match 132 * 133 * @param sessionId An unique key identifier to get the paired listener 134 * @return A JNIImsMediaListener listener 135 */ getListener(final int sessionId)136 public static JNIImsMediaListener getListener(final int sessionId) { 137 JNIImsMediaListener listener = null; 138 synchronized (sListeners) { 139 listener = sListeners.get(sessionId); 140 } 141 142 return listener; 143 } 144 145 /** 146 * Clears listener container 147 */ clearListener()148 public static void clearListener() { 149 synchronized (sListeners) { 150 sListeners.clear(); 151 } 152 } 153 154 @VisibleForTesting getListenerSize()155 public static int getListenerSize() { 156 return sListeners.size(); 157 } 158 159 /** 160 * Sends callback parcel message from libimsmediajni to java 161 * 162 * @param sessionId An unique key idenfier to find corresponding listener object to send message 163 * @param baData byte array form of data to send 164 * @return 1 if it is success to send data, -1 when it fails 165 */ sendData2Java(final int sessionId, final byte[] baData)166 public static int sendData2Java(final int sessionId, final byte[] baData) { 167 Log.dc(TAG, "sendData2Java() - sessionId=" + sessionId); 168 JNIImsMediaListener listener = getListener(sessionId); 169 if (listener == null) { 170 Log.e(TAG, "No listener :: sessionId=" + sessionId); 171 return -1; 172 } 173 if (baData == null) { 174 return -1; 175 } 176 // retrieve parcel object from pool 177 Parcel parcel = Parcel.obtain(); 178 parcel.unmarshall(baData, 0, baData.length); 179 parcel.setDataPosition(0); 180 listener.onMessage(parcel); 181 parcel.recycle(); 182 183 return 1; 184 } 185 186 /** Elevates the priority of audio thread to THREAD_PRIORITY_REALTIME. Increase in thead 187 * priority will ensure AOC and JitterBuffer calls are made consistent every 20msecs. 188 * 189 * @param threadId is the id of the thread whose priority should to be increased. 190 */ setAudioThreadPriority(int threadId)191 public static void setAudioThreadPriority(int threadId) { 192 Log.d(TAG, "setAudioThreadPriority. tid:" + threadId); 193 Process.setThreadPriority(threadId, THREAD_PRIORITY_REALTIME); 194 } 195 196 /** local shared libimsmediajni library */ 197 static { 198 try { Log.d(TAG, "libimsmedia :: loading")199 Log.d(TAG, "libimsmedia :: loading"); 200 System.loadLibrary("imsmedia"); Log.d(TAG, "libimsmedia :: load completed")201 Log.d(TAG, "libimsmedia :: load completed"); 202 } catch (UnsatisfiedLinkError e) { 203 Log.e(TAG, "Loading fail : libimsmedia.so"); 204 } 205 } 206 } 207