1 /* 2 * libjingle 3 * Copyright 2013 Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 29 package org.webrtc; 30 31 import java.util.List; 32 33 /** 34 * Java wrapper for a C++ PeerConnectionFactoryInterface. Main entry point to 35 * the PeerConnection API for clients. 36 */ 37 public class PeerConnectionFactory { 38 static { 39 System.loadLibrary("jingle_peerconnection_so"); 40 } 41 42 private static final String TAG = "PeerConnectionFactory"; 43 private final long nativeFactory; 44 private static Thread workerThread; 45 private static Thread signalingThread; 46 47 public static class Options { 48 // Keep in sync with webrtc/base/network.h! 49 static final int ADAPTER_TYPE_UNKNOWN = 0; 50 static final int ADAPTER_TYPE_ETHERNET = 1 << 0; 51 static final int ADAPTER_TYPE_WIFI = 1 << 1; 52 static final int ADAPTER_TYPE_CELLULAR = 1 << 2; 53 static final int ADAPTER_TYPE_VPN = 1 << 3; 54 static final int ADAPTER_TYPE_LOOPBACK = 1 << 4; 55 56 public int networkIgnoreMask; 57 public boolean disableEncryption; 58 public boolean disableNetworkMonitor; 59 } 60 61 // |context| is an android.content.Context object, but we keep it untyped here 62 // to allow building on non-Android platforms. 63 // Callers may specify either |initializeAudio| or |initializeVideo| as false 64 // to skip initializing the respective engine (and avoid the need for the 65 // respective permissions). 66 // |renderEGLContext| can be provided to suport HW video decoding to 67 // texture and will be used to create a shared EGL context on video 68 // decoding thread. initializeAndroidGlobals( Object context, boolean initializeAudio, boolean initializeVideo, boolean videoHwAcceleration)69 public static native boolean initializeAndroidGlobals( 70 Object context, boolean initializeAudio, boolean initializeVideo, 71 boolean videoHwAcceleration); 72 73 // Field trial initialization. Must be called before PeerConnectionFactory 74 // is created. initializeFieldTrials(String fieldTrialsInitString)75 public static native void initializeFieldTrials(String fieldTrialsInitString); 76 // Internal tracing initialization. Must be called before PeerConnectionFactory is created to 77 // prevent racing with tracing code. initializeInternalTracer()78 public static native void initializeInternalTracer(); 79 // Internal tracing shutdown, called to prevent resource leaks. Must be called after 80 // PeerConnectionFactory is gone to prevent races with code performing tracing. shutdownInternalTracer()81 public static native void shutdownInternalTracer(); 82 // Start/stop internal capturing of internal tracing. startInternalTracingCapture(String tracing_filename)83 public static native boolean startInternalTracingCapture(String tracing_filename); stopInternalTracingCapture()84 public static native void stopInternalTracingCapture(); 85 PeerConnectionFactory()86 public PeerConnectionFactory() { 87 nativeFactory = nativeCreatePeerConnectionFactory(); 88 if (nativeFactory == 0) { 89 throw new RuntimeException("Failed to initialize PeerConnectionFactory!"); 90 } 91 } 92 createPeerConnection( PeerConnection.RTCConfiguration rtcConfig, MediaConstraints constraints, PeerConnection.Observer observer)93 public PeerConnection createPeerConnection( 94 PeerConnection.RTCConfiguration rtcConfig, 95 MediaConstraints constraints, 96 PeerConnection.Observer observer) { 97 long nativeObserver = nativeCreateObserver(observer); 98 if (nativeObserver == 0) { 99 return null; 100 } 101 long nativePeerConnection = nativeCreatePeerConnection( 102 nativeFactory, rtcConfig, constraints, nativeObserver); 103 if (nativePeerConnection == 0) { 104 return null; 105 } 106 return new PeerConnection(nativePeerConnection, nativeObserver); 107 } 108 createPeerConnection( List<PeerConnection.IceServer> iceServers, MediaConstraints constraints, PeerConnection.Observer observer)109 public PeerConnection createPeerConnection( 110 List<PeerConnection.IceServer> iceServers, 111 MediaConstraints constraints, 112 PeerConnection.Observer observer) { 113 PeerConnection.RTCConfiguration rtcConfig = 114 new PeerConnection.RTCConfiguration(iceServers); 115 return createPeerConnection(rtcConfig, constraints, observer); 116 } 117 createLocalMediaStream(String label)118 public MediaStream createLocalMediaStream(String label) { 119 return new MediaStream( 120 nativeCreateLocalMediaStream(nativeFactory, label)); 121 } 122 createVideoSource( VideoCapturer capturer, MediaConstraints constraints)123 public VideoSource createVideoSource( 124 VideoCapturer capturer, MediaConstraints constraints) { 125 return new VideoSource(nativeCreateVideoSource( 126 nativeFactory, capturer.takeNativeVideoCapturer(), constraints)); 127 } 128 createVideoTrack(String id, VideoSource source)129 public VideoTrack createVideoTrack(String id, VideoSource source) { 130 return new VideoTrack(nativeCreateVideoTrack( 131 nativeFactory, id, source.nativeSource)); 132 } 133 createAudioSource(MediaConstraints constraints)134 public AudioSource createAudioSource(MediaConstraints constraints) { 135 return new AudioSource(nativeCreateAudioSource(nativeFactory, constraints)); 136 } 137 createAudioTrack(String id, AudioSource source)138 public AudioTrack createAudioTrack(String id, AudioSource source) { 139 return new AudioTrack(nativeCreateAudioTrack( 140 nativeFactory, id, source.nativeSource)); 141 } 142 143 // Starts recording an AEC dump. Ownership of the file is transfered to the 144 // native code. If an AEC dump is already in progress, it will be stopped and 145 // a new one will start using the provided file. startAecDump(int file_descriptor)146 public boolean startAecDump(int file_descriptor) { 147 return nativeStartAecDump(nativeFactory, file_descriptor); 148 } 149 150 // Stops recording an AEC dump. If no AEC dump is currently being recorded, 151 // this call will have no effect. stopAecDump()152 public void stopAecDump() { 153 nativeStopAecDump(nativeFactory); 154 } 155 156 // Starts recording an RTC event log. Ownership of the file is transfered to 157 // the native code. If an RTC event log is already being recorded, it will be 158 // stopped and a new one will start using the provided file. startRtcEventLog(int file_descriptor)159 public boolean startRtcEventLog(int file_descriptor) { 160 return nativeStartRtcEventLog(nativeFactory, file_descriptor); 161 } 162 163 // Stops recording an RTC event log. If no RTC event log is currently being 164 // recorded, this call will have no effect. StopRtcEventLog()165 public void StopRtcEventLog() { 166 nativeStopRtcEventLog(nativeFactory); 167 } 168 setOptions(Options options)169 public void setOptions(Options options) { 170 nativeSetOptions(nativeFactory, options); 171 } 172 173 @Deprecated setVideoHwAccelerationOptions(Object renderEGLContext)174 public void setVideoHwAccelerationOptions(Object renderEGLContext) { 175 nativeSetVideoHwAccelerationOptions(nativeFactory, renderEGLContext, renderEGLContext); 176 } 177 178 /** Set the EGL context used by HW Video encoding and decoding. 179 * 180 * 181 * @param localEGLContext An instance of javax.microedition.khronos.egl.EGLContext. 182 * Must be the same as used by VideoCapturerAndroid and any local 183 * video renderer. 184 * @param remoteEGLContext An instance of javax.microedition.khronos.egl.EGLContext. 185 * Must be the same as used by any remote video renderer. 186 */ setVideoHwAccelerationOptions(Object localEGLContext, Object remoteEGLContext)187 public void setVideoHwAccelerationOptions(Object localEGLContext, Object remoteEGLContext) { 188 nativeSetVideoHwAccelerationOptions(nativeFactory, localEGLContext, remoteEGLContext); 189 } 190 dispose()191 public void dispose() { 192 nativeFreeFactory(nativeFactory); 193 signalingThread = null; 194 workerThread = null; 195 } 196 threadsCallbacks()197 public void threadsCallbacks() { 198 nativeThreadsCallbacks(nativeFactory); 199 } 200 printStackTrace(Thread thread, String threadName)201 private static void printStackTrace(Thread thread, String threadName) { 202 if (thread != null) { 203 StackTraceElement[] stackTraces = thread.getStackTrace(); 204 if (stackTraces.length > 0) { 205 Logging.d(TAG, threadName + " stacks trace:"); 206 for (StackTraceElement stackTrace : stackTraces) { 207 Logging.d(TAG, stackTrace.toString()); 208 } 209 } 210 } 211 } 212 printStackTraces()213 public static void printStackTraces() { 214 printStackTrace(workerThread, "Worker thread"); 215 printStackTrace(signalingThread, "Signaling thread"); 216 } 217 onWorkerThreadReady()218 private static void onWorkerThreadReady() { 219 workerThread = Thread.currentThread(); 220 Logging.d(TAG, "onWorkerThreadReady"); 221 } 222 onSignalingThreadReady()223 private static void onSignalingThreadReady() { 224 signalingThread = Thread.currentThread(); 225 Logging.d(TAG, "onSignalingThreadReady"); 226 } 227 nativeCreatePeerConnectionFactory()228 private static native long nativeCreatePeerConnectionFactory(); 229 nativeCreateObserver( PeerConnection.Observer observer)230 private static native long nativeCreateObserver( 231 PeerConnection.Observer observer); 232 nativeCreatePeerConnection( long nativeFactory, PeerConnection.RTCConfiguration rtcConfig, MediaConstraints constraints, long nativeObserver)233 private static native long nativeCreatePeerConnection( 234 long nativeFactory, PeerConnection.RTCConfiguration rtcConfig, 235 MediaConstraints constraints, long nativeObserver); 236 nativeCreateLocalMediaStream( long nativeFactory, String label)237 private static native long nativeCreateLocalMediaStream( 238 long nativeFactory, String label); 239 nativeCreateVideoSource( long nativeFactory, long nativeVideoCapturer, MediaConstraints constraints)240 private static native long nativeCreateVideoSource( 241 long nativeFactory, long nativeVideoCapturer, 242 MediaConstraints constraints); 243 nativeCreateVideoTrack( long nativeFactory, String id, long nativeVideoSource)244 private static native long nativeCreateVideoTrack( 245 long nativeFactory, String id, long nativeVideoSource); 246 nativeCreateAudioSource( long nativeFactory, MediaConstraints constraints)247 private static native long nativeCreateAudioSource( 248 long nativeFactory, MediaConstraints constraints); 249 nativeCreateAudioTrack( long nativeFactory, String id, long nativeSource)250 private static native long nativeCreateAudioTrack( 251 long nativeFactory, String id, long nativeSource); 252 nativeStartAecDump(long nativeFactory, int file_descriptor)253 private static native boolean nativeStartAecDump(long nativeFactory, int file_descriptor); 254 nativeStopAecDump(long nativeFactory)255 private static native void nativeStopAecDump(long nativeFactory); 256 nativeStartRtcEventLog(long nativeFactory, int file_descriptor)257 private static native boolean nativeStartRtcEventLog(long nativeFactory, int file_descriptor); 258 nativeStopRtcEventLog(long nativeFactory)259 private static native void nativeStopRtcEventLog(long nativeFactory); 260 nativeSetOptions(long nativeFactory, Options options)261 public native void nativeSetOptions(long nativeFactory, Options options); 262 nativeSetVideoHwAccelerationOptions( long nativeFactory, Object localEGLContext, Object remoteEGLContext)263 private static native void nativeSetVideoHwAccelerationOptions( 264 long nativeFactory, Object localEGLContext, Object remoteEGLContext); 265 nativeThreadsCallbacks(long nativeFactory)266 private static native void nativeThreadsCallbacks(long nativeFactory); 267 nativeFreeFactory(long nativeFactory)268 private static native void nativeFreeFactory(long nativeFactory); 269 } 270