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.Binder; 20 import android.os.IBinder; 21 import android.telephony.ims.RtpHeaderExtension; 22 23 import java.util.List; 24 import java.util.concurrent.Executor; 25 26 /** 27 * Video session callback APIs 28 * 29 * @hide 30 */ 31 public class VideoSessionCallback extends ImsMediaManager.SessionCallback { 32 33 private final CallbackBinder mCallbackBinder = new CallbackBinder(this); 34 35 /** @hide */ 36 @Override getBinder()37 public IBinder getBinder() { 38 return mCallbackBinder; 39 } 40 41 /** @hide */ 42 @Override setExecutor(final Executor executor)43 public void setExecutor(final Executor executor) { 44 mCallbackBinder.setExecutor(executor); 45 } 46 47 private static class CallbackBinder extends IImsVideoSessionCallback.Stub { 48 private final VideoSessionCallback mLocalCallback; 49 private Executor mExecutor; 50 CallbackBinder(final VideoSessionCallback localCallback)51 CallbackBinder(final VideoSessionCallback localCallback) { 52 mLocalCallback = localCallback; 53 } 54 55 @Override onOpenSessionSuccess(final IImsVideoSession session)56 public void onOpenSessionSuccess(final IImsVideoSession session) { 57 if (mLocalCallback == null) return; 58 59 final long callingIdentity = Binder.clearCallingIdentity(); 60 try { 61 mExecutor.execute(() 62 -> mLocalCallback.onOpenSessionSuccess(new ImsVideoSession(session))); 63 } finally { 64 restoreCallingIdentity(callingIdentity); 65 } 66 } 67 68 @Override onOpenSessionFailure(final int error)69 public void onOpenSessionFailure(final int error) { 70 if (mLocalCallback == null) return; 71 72 final long callingIdentity = Binder.clearCallingIdentity(); 73 try { 74 mExecutor.execute(() -> mLocalCallback.onOpenSessionFailure(error)); 75 } finally { 76 restoreCallingIdentity(callingIdentity); 77 } 78 } 79 80 @Override onSessionClosed()81 public void onSessionClosed() { 82 if (mLocalCallback == null) return; 83 84 final long callingIdentity = Binder.clearCallingIdentity(); 85 try { 86 mExecutor.execute(() -> mLocalCallback.onSessionClosed()); 87 } finally { 88 restoreCallingIdentity(callingIdentity); 89 } 90 } 91 92 @Override onModifySessionResponse(final VideoConfig config, final @ImsMediaSession.SessionOperationResult int result)93 public void onModifySessionResponse(final VideoConfig config, 94 final @ImsMediaSession.SessionOperationResult int result) { 95 if (mLocalCallback == null) return; 96 97 final long callingIdentity = Binder.clearCallingIdentity(); 98 try { 99 mExecutor.execute(() -> mLocalCallback.onModifySessionResponse(config, result)); 100 } finally { 101 restoreCallingIdentity(callingIdentity); 102 } 103 } 104 105 @Override onFirstMediaPacketReceived(final VideoConfig config)106 public void onFirstMediaPacketReceived(final VideoConfig config) { 107 if (mLocalCallback == null) return; 108 109 final long callingIdentity = Binder.clearCallingIdentity(); 110 try { 111 mExecutor.execute(() -> mLocalCallback.onFirstMediaPacketReceived(config)); 112 } finally { 113 restoreCallingIdentity(callingIdentity); 114 } 115 } 116 117 @Override onPeerDimensionChanged(final int width, final int height)118 public void onPeerDimensionChanged(final int width, final int height) { 119 if (mLocalCallback == null) return; 120 121 final long callingIdentity = Binder.clearCallingIdentity(); 122 try { 123 mExecutor.execute(() -> mLocalCallback.onPeerDimensionChanged(width, height)); 124 } finally { 125 restoreCallingIdentity(callingIdentity); 126 } 127 } 128 129 @Override onHeaderExtensionReceived(final List<RtpHeaderExtension> extensions)130 public void onHeaderExtensionReceived(final List<RtpHeaderExtension> extensions) { 131 if (mLocalCallback == null) return; 132 133 final long callingIdentity = Binder.clearCallingIdentity(); 134 try { 135 mExecutor.execute(() -> mLocalCallback.onHeaderExtensionReceived(extensions)); 136 } finally { 137 restoreCallingIdentity(callingIdentity); 138 } 139 } 140 141 @Override notifyMediaInactivity(final int packetType)142 public void notifyMediaInactivity(final int packetType) { 143 if (mLocalCallback == null) return; 144 145 final long callingIdentity = Binder.clearCallingIdentity(); 146 try { 147 mExecutor.execute(() -> mLocalCallback.notifyMediaInactivity(packetType)); 148 } finally { 149 restoreCallingIdentity(callingIdentity); 150 } 151 } 152 153 @Override notifyBitrate(final int bitrate)154 public void notifyBitrate(final int bitrate) { 155 if (mLocalCallback == null) return; 156 157 final long callingIdentity = Binder.clearCallingIdentity(); 158 try { 159 mExecutor.execute(() -> mLocalCallback.notifyBitrate(bitrate)); 160 } finally { 161 restoreCallingIdentity(callingIdentity); 162 } 163 } 164 165 @Override notifyVideoDataUsage(final long bytes)166 public void notifyVideoDataUsage(final long bytes) { 167 if (mLocalCallback == null) return; 168 169 final long callingIdentity = Binder.clearCallingIdentity(); 170 try { 171 mExecutor.execute(() -> mLocalCallback.notifyVideoDataUsage(bytes)); 172 } finally { 173 restoreCallingIdentity(callingIdentity); 174 } 175 } 176 setExecutor(final Executor executor)177 private void setExecutor(final Executor executor) { 178 mExecutor = executor; 179 } 180 } 181 182 /** 183 * Called when ImsMediaSession#modifySession() API is handled 184 * 185 * @param config The VideoConfig passed in ImsMediaSession#modifySession() 186 * @param result The result of modify session 187 */ onModifySessionResponse(final VideoConfig config, final @ImsMediaSession.SessionOperationResult int result)188 public void onModifySessionResponse(final VideoConfig config, 189 final @ImsMediaSession.SessionOperationResult int result) { 190 // Base Implementation 191 } 192 193 /** 194 * Indicates when the first Rtp media packet is received by the UE 195 * during ring back, call hold or early media scenarios. This is 196 * sent only if the packet is received on the active remote 197 * configuration. 198 * 199 * In case of early media scenarios, the implementation shall play 200 * the RTP packets from the most recently added config. 201 * 202 * @param config the remote config where media packet is received 203 */ onFirstMediaPacketReceived(final VideoConfig config)204 public void onFirstMediaPacketReceived(final VideoConfig config) { 205 // Base Implementation 206 } 207 208 /** 209 * Notify when the received video frame resolution is different with the current resolution. 210 * @param width width of resolution changed. 211 * @param height height of resolution changed. 212 */ onPeerDimensionChanged(final int width, final int height)213 public void onPeerDimensionChanged(final int width, final int height) { 214 // Base Implementation 215 } 216 217 /** 218 * RTP header extension received from the other party 219 * 220 * @param extensions List of received RTP header extensions 221 */ onHeaderExtensionReceived(final List<RtpHeaderExtension> extensions)222 public void onHeaderExtensionReceived(final List<RtpHeaderExtension> extensions){ 223 // Base Implementation 224 } 225 226 /** 227 * Notifies media inactivity observed as per thresholds set by 228 * setMediaQualityThreshold() API 229 * 230 * @param packetType either RTP or RTCP 231 */ notifyMediaInactivity(final int packetType)232 public void notifyMediaInactivity(final int packetType) { 233 // Base Implementation 234 } 235 236 /** 237 * Notifies when the video bitrate decreased below the threshold set by 238 * setMediaQualityThreshold() API 239 * 240 * @param bitrate The bitrate of sending video packets in bps unit 241 */ notifyBitrate(final int bitrate)242 public void notifyBitrate(final int bitrate) { 243 // Base Implementation 244 } 245 246 /** 247 * Notify accumulated video data usage in the current session. 248 * @param bytes bytes of send and received rtp data. 249 */ notifyVideoDataUsage(final long bytes)250 public void notifyVideoDataUsage(final long bytes) { 251 // Base Implementation 252 } 253 } 254