Port some fixes in AppRTCDemo.

- Make PeerConnectionClient a singleton.
- Fix crash in CpuMonitor.
- Remove reading constraints from room response.
- Catch and report camera errors.

R=wzh@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/43059004

Cr-Commit-Position: refs/heads/master@{#8930}
This commit is contained in:
Alex Glaznev 2015-04-06 14:02:19 -07:00
parent be508a1d36
commit e095148869
8 changed files with 125 additions and 164 deletions

View File

@ -28,7 +28,6 @@
package org.appspot.apprtc; package org.appspot.apprtc;
import org.webrtc.IceCandidate; import org.webrtc.IceCandidate;
import org.webrtc.MediaConstraints;
import org.webrtc.PeerConnection; import org.webrtc.PeerConnection;
import org.webrtc.SessionDescription; import org.webrtc.SessionDescription;
@ -87,9 +86,6 @@ public interface AppRTCClient {
public static class SignalingParameters { public static class SignalingParameters {
public final List<PeerConnection.IceServer> iceServers; public final List<PeerConnection.IceServer> iceServers;
public final boolean initiator; public final boolean initiator;
public final MediaConstraints pcConstraints;
public final MediaConstraints videoConstraints;
public final MediaConstraints audioConstraints;
public final String clientId; public final String clientId;
public final String wssUrl; public final String wssUrl;
public final String wssPostUrl; public final String wssPostUrl;
@ -98,15 +94,11 @@ public interface AppRTCClient {
public SignalingParameters( public SignalingParameters(
List<PeerConnection.IceServer> iceServers, List<PeerConnection.IceServer> iceServers,
boolean initiator, MediaConstraints pcConstraints, boolean initiator, String clientId,
MediaConstraints videoConstraints, MediaConstraints audioConstraints, String wssUrl, String wssPostUrl,
String clientId, String wssUrl, String wssPostUrl,
SessionDescription offerSdp, List<IceCandidate> iceCandidates) { SessionDescription offerSdp, List<IceCandidate> iceCandidates) {
this.iceServers = iceServers; this.iceServers = iceServers;
this.initiator = initiator; this.initiator = initiator;
this.pcConstraints = pcConstraints;
this.videoConstraints = videoConstraints;
this.audioConstraints = audioConstraints;
this.clientId = clientId; this.clientId = clientId;
this.wssUrl = wssUrl; this.wssUrl = wssUrl;
this.wssPostUrl = wssPostUrl; this.wssPostUrl = wssPostUrl;

View File

@ -383,7 +383,7 @@ public class CallActivity extends Activity
if (peerConnectionClient == null) { if (peerConnectionClient == null) {
final long delta = System.currentTimeMillis() - callStartedTimeMs; final long delta = System.currentTimeMillis() - callStartedTimeMs;
Log.d(TAG, "Creating peer connection factory, delay=" + delta + "ms"); Log.d(TAG, "Creating peer connection factory, delay=" + delta + "ms");
peerConnectionClient = new PeerConnectionClient(); peerConnectionClient = PeerConnectionClient.getInstance();
peerConnectionClient.createPeerConnectionFactory(CallActivity.this, peerConnectionClient.createPeerConnectionFactory(CallActivity.this,
VideoRendererGui.getEGLContext(), peerConnectionParameters, VideoRendererGui.getEGLContext(), peerConnectionParameters,
CallActivity.this); CallActivity.this);

View File

@ -113,7 +113,8 @@ class CpuMonitor {
Scanner scanner = new Scanner(rdr).useDelimiter("[-\n]"); Scanner scanner = new Scanner(rdr).useDelimiter("[-\n]");
scanner.nextInt(); // Skip leading number 0. scanner.nextInt(); // Skip leading number 0.
cpusPresent = 1 + scanner.nextInt(); cpusPresent = 1 + scanner.nextInt();
} catch (InputMismatchException e) { scanner.close();
} catch (Exception e) {
Log.e(TAG, "Cannot do CPU stats due to /sys/devices/system/cpu/present parsing problem"); Log.e(TAG, "Cannot do CPU stats due to /sys/devices/system/cpu/present parsing problem");
} finally { } finally {
fin.close(); fin.close();
@ -264,7 +265,8 @@ class CpuMonitor {
BufferedReader rdr = new BufferedReader(fin); BufferedReader rdr = new BufferedReader(fin);
Scanner scannerC = new Scanner(rdr); Scanner scannerC = new Scanner(rdr);
number = scannerC.nextLong(); number = scannerC.nextLong();
} catch (InputMismatchException e) { scannerC.close();
} catch (Exception e) {
// CPU presumably got offline just after we opened file. // CPU presumably got offline just after we opened file.
} finally { } finally {
fin.close(); fin.close();
@ -295,7 +297,8 @@ class CpuMonitor {
long sys = scanner.nextLong(); long sys = scanner.nextLong();
runTime = user + nice + sys; runTime = user + nice + sys;
idleTime = scanner.nextLong(); idleTime = scanner.nextLong();
} catch (InputMismatchException e) { scanner.close();
} catch (Exception e) {
Log.e(TAG, "Problems parsing /proc/stat"); Log.e(TAG, "Problems parsing /proc/stat");
return null; return null;
} finally { } finally {

View File

@ -35,6 +35,7 @@ import org.appspot.apprtc.AppRTCClient.SignalingParameters;
import org.appspot.apprtc.util.LooperExecutor; import org.appspot.apprtc.util.LooperExecutor;
import org.webrtc.DataChannel; import org.webrtc.DataChannel;
import org.webrtc.IceCandidate; import org.webrtc.IceCandidate;
import org.webrtc.Logging;
import org.webrtc.MediaCodecVideoEncoder; import org.webrtc.MediaCodecVideoEncoder;
import org.webrtc.MediaConstraints; import org.webrtc.MediaConstraints;
import org.webrtc.MediaConstraints.KeyValuePair; import org.webrtc.MediaConstraints.KeyValuePair;
@ -51,6 +52,7 @@ import org.webrtc.VideoRenderer;
import org.webrtc.VideoSource; import org.webrtc.VideoSource;
import org.webrtc.VideoTrack; import org.webrtc.VideoTrack;
import java.util.EnumSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.Timer; import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
@ -62,6 +64,7 @@ import java.util.regex.Pattern;
* *
* <p>All public methods are routed to local looper thread. * <p>All public methods are routed to local looper thread.
* All PeerConnectionEvents callbacks are invoked from the same looper thread. * All PeerConnectionEvents callbacks are invoked from the same looper thread.
* This class is a singleton.
*/ */
public class PeerConnectionClient { public class PeerConnectionClient {
public static final String VIDEO_TRACK_ID = "ARDAMSv0"; public static final String VIDEO_TRACK_ID = "ARDAMSv0";
@ -89,18 +92,21 @@ public class PeerConnectionClient {
private static final int MAX_VIDEO_HEIGHT = 1280; private static final int MAX_VIDEO_HEIGHT = 1280;
private static final int MAX_VIDEO_FPS = 30; private static final int MAX_VIDEO_FPS = 30;
private final LooperExecutor executor; private static final PeerConnectionClient instance = new PeerConnectionClient();
private PeerConnectionFactory factory = null;
private PeerConnection peerConnection = null;
private VideoSource videoSource;
private boolean videoCallEnabled = true;
private boolean preferIsac = false;
private boolean preferH264 = false;
private boolean videoSourceStopped = false;
private boolean isError = false;
private final Timer statsTimer = new Timer();
private final PCObserver pcObserver = new PCObserver(); private final PCObserver pcObserver = new PCObserver();
private final SDPObserver sdpObserver = new SDPObserver(); private final SDPObserver sdpObserver = new SDPObserver();
private final LooperExecutor executor;
private PeerConnectionFactory factory;
private PeerConnection peerConnection;
PeerConnectionFactory.Options options = null;
private VideoSource videoSource;
private boolean videoCallEnabled;
private boolean preferIsac;
private boolean preferH264;
private boolean videoSourceStopped;
private boolean isError;
private Timer statsTimer;
private VideoRenderer.Callbacks localRender; private VideoRenderer.Callbacks localRender;
private VideoRenderer.Callbacks remoteRender; private VideoRenderer.Callbacks remoteRender;
private SignalingParameters signalingParameters; private SignalingParameters signalingParameters;
@ -112,17 +118,17 @@ public class PeerConnectionClient {
// Queued remote ICE candidates are consumed only after both local and // Queued remote ICE candidates are consumed only after both local and
// remote descriptions are set. Similarly local ICE candidates are sent to // remote descriptions are set. Similarly local ICE candidates are sent to
// remote peer after both local and remote description are set. // remote peer after both local and remote description are set.
private LinkedList<IceCandidate> queuedRemoteCandidates = null; private LinkedList<IceCandidate> queuedRemoteCandidates;
private PeerConnectionEvents events; private PeerConnectionEvents events;
private boolean isInitiator; private boolean isInitiator;
private SessionDescription localSdp = null; // either offer or answer SDP private SessionDescription localSdp; // either offer or answer SDP
private MediaStream mediaStream = null; private MediaStream mediaStream;
private int numberOfCameras; private int numberOfCameras;
private VideoCapturerAndroid videoCapturer = null; private VideoCapturerAndroid videoCapturer;
// enableVideo is set to true if video should be rendered and sent. // enableVideo is set to true if video should be rendered and sent.
private boolean renderVideo = true; private boolean renderVideo;
private VideoTrack localVideoTrack = null; private VideoTrack localVideoTrack;
private VideoTrack remoteVideoTrack = null; private VideoTrack remoteVideoTrack;
/** /**
* Peer connection parameters. * Peer connection parameters.
@ -202,8 +208,20 @@ public class PeerConnectionClient {
public void onPeerConnectionError(final String description); public void onPeerConnectionError(final String description);
} }
public PeerConnectionClient() { private PeerConnectionClient() {
executor = new LooperExecutor(); executor = new LooperExecutor();
// Looper thread is started once in private ctor and is used for all
// peer connection API calls to ensure new peer connection factory is
// created on the same thread as previously destroyed factory.
executor.requestStart();
}
public static PeerConnectionClient getInstance() {
return instance;
}
public void setPeerConnectionFactoryOptions(PeerConnectionFactory.Options options) {
this.options = options;
} }
public void createPeerConnectionFactory( public void createPeerConnectionFactory(
@ -214,7 +232,22 @@ public class PeerConnectionClient {
this.peerConnectionParameters = peerConnectionParameters; this.peerConnectionParameters = peerConnectionParameters;
this.events = events; this.events = events;
videoCallEnabled = peerConnectionParameters.videoCallEnabled; videoCallEnabled = peerConnectionParameters.videoCallEnabled;
executor.requestStart(); // Reset variables to initial states.
factory = null;
peerConnection = null;
preferIsac = false;
preferH264 = false;
videoSourceStopped = false;
isError = false;
queuedRemoteCandidates = null;
localSdp = null; // either offer or answer SDP
mediaStream = null;
videoCapturer = null;
renderVideo = true;
localVideoTrack = null;
remoteVideoTrack = null;
statsTimer = new Timer();
executor.execute(new Runnable() { executor.execute(new Runnable() {
@Override @Override
public void run() { public void run() {
@ -250,7 +283,10 @@ public class PeerConnectionClient {
closeInternal(); closeInternal();
} }
}); });
executor.requestStop(); }
public boolean isVideoCallEnabled() {
return videoCallEnabled;
} }
private void createPeerConnectionFactoryInternal( private void createPeerConnectionFactoryInternal(
@ -284,16 +320,13 @@ public class PeerConnectionClient {
events.onPeerConnectionError("Failed to initializeAndroidGlobals"); events.onPeerConnectionError("Failed to initializeAndroidGlobals");
} }
factory = new PeerConnectionFactory(); factory = new PeerConnectionFactory();
configureFactory(factory); if (options != null) {
Log.d(TAG, "Factory networkIgnoreMask option: " + options.networkIgnoreMask);
factory.setOptions(options);
}
Log.d(TAG, "Peer connection factory created."); Log.d(TAG, "Peer connection factory created.");
} }
/**
* Hook where tests can provide additional configuration for the factory.
*/
protected void configureFactory(PeerConnectionFactory factory) {
}
private void createMediaConstraintsInternal() { private void createMediaConstraintsInternal() {
// Create peer connection constraints. // Create peer connection constraints.
pcConstraints = new MediaConstraints(); pcConstraints = new MediaConstraints();
@ -384,12 +417,12 @@ public class PeerConnectionClient {
signalingParameters.iceServers, pcConstraints, pcObserver); signalingParameters.iceServers, pcConstraints, pcObserver);
isInitiator = false; isInitiator = false;
// Uncomment to get ALL WebRTC tracing and SENSITIVE libjingle logging. // Set default WebRTC tracing and INFO libjingle logging.
// NOTE: this _must_ happen while |factory| is alive! // NOTE: this _must_ happen while |factory| is alive!
// Logging.enableTracing( Logging.enableTracing(
// "logcat:", "logcat:",
// EnumSet.of(Logging.TraceLevel.TRACE_ALL), EnumSet.of(Logging.TraceLevel.TRACE_DEFAULT),
// Logging.Severity.LS_SENSITIVE); Logging.Severity.LS_INFO);
mediaStream = factory.createLocalMediaStream("ARDAMS"); mediaStream = factory.createLocalMediaStream("ARDAMS");
if (videoCallEnabled) { if (videoCallEnabled) {
@ -401,6 +434,10 @@ public class PeerConnectionClient {
} }
Log.d(TAG, "Opening camera: " + cameraDeviceName); Log.d(TAG, "Opening camera: " + cameraDeviceName);
videoCapturer = VideoCapturerAndroid.create(cameraDeviceName); videoCapturer = VideoCapturerAndroid.create(cameraDeviceName);
if (videoCapturer == null) {
reportError("Failed to open camera");
return;
}
mediaStream.addTrack(createVideoTrack(videoCapturer)); mediaStream.addTrack(createVideoTrack(videoCapturer));
} }
@ -419,6 +456,7 @@ public class PeerConnectionClient {
peerConnection.dispose(); peerConnection.dispose();
peerConnection = null; peerConnection = null;
} }
Log.d(TAG, "Closing video source.");
if (videoSource != null) { if (videoSource != null) {
videoSource.dispose(); videoSource.dispose();
videoSource = null; videoSource = null;
@ -428,6 +466,7 @@ public class PeerConnectionClient {
factory.dispose(); factory.dispose();
factory = null; factory = null;
} }
options = null;
Log.d(TAG, "Closing peer connection done."); Log.d(TAG, "Closing peer connection done.");
events.onPeerConnectionClosed(); events.onPeerConnectionClosed();
} }
@ -477,17 +516,21 @@ public class PeerConnectionClient {
public void enableStatsEvents(boolean enable, int periodMs) { public void enableStatsEvents(boolean enable, int periodMs) {
if (enable) { if (enable) {
statsTimer.schedule(new TimerTask() { try {
@Override statsTimer.schedule(new TimerTask() {
public void run() { @Override
executor.execute(new Runnable() { public void run() {
@Override executor.execute(new Runnable() {
public void run() { @Override
getStats(); public void run() {
} getStats();
}); }
} });
}, 0, periodMs); }
}, 0, periodMs);
} catch (Exception e) {
Log.e(TAG, "Can not schedule statistics timer", e);
}
} else { } else {
statsTimer.cancel(); statsTimer.cancel();
} }
@ -769,8 +812,10 @@ public class PeerConnectionClient {
} }
private void switchCameraInternal() { private void switchCameraInternal() {
if (!videoCallEnabled || numberOfCameras < 2) { if (!videoCallEnabled || numberOfCameras < 2 || isError || videoCapturer == null) {
return; // No video is sent or only one camera is available. Log.e(TAG, "Failed to switch camera. Video: " + videoCallEnabled + ". Error : "
+ isError + ". Number of cameras: " + numberOfCameras);
return; // No video is sent or only one camera is available or error happened.
} }
Log.d(TAG, "Switch camera"); Log.d(TAG, "Switch camera");
videoCapturer.switchCamera(); videoCapturer.switchCamera();
@ -780,9 +825,7 @@ public class PeerConnectionClient {
executor.execute(new Runnable() { executor.execute(new Runnable() {
@Override @Override
public void run() { public void run() {
if (peerConnection != null && !isError) { switchCameraInternal();
switchCameraInternal();
}
} }
}); });
} }

View File

@ -37,7 +37,6 @@ import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.webrtc.IceCandidate; import org.webrtc.IceCandidate;
import org.webrtc.MediaConstraints;
import org.webrtc.PeerConnection; import org.webrtc.PeerConnection;
import org.webrtc.SessionDescription; import org.webrtc.SessionDescription;
@ -170,18 +169,8 @@ public class RoomParametersFetcher {
} }
} }
MediaConstraints pcConstraints = constraintsFromJSON(roomJson.getString("pc_constraints"));
Log.d(TAG, "pcConstraints: " + pcConstraints);
MediaConstraints videoConstraints = constraintsFromJSON(
getAVConstraints("video", roomJson.getString("media_constraints")));
Log.d(TAG, "videoConstraints: " + videoConstraints);
MediaConstraints audioConstraints = constraintsFromJSON(
getAVConstraints("audio", roomJson.getString("media_constraints")));
Log.d(TAG, "audioConstraints: " + audioConstraints);
SignalingParameters params = new SignalingParameters( SignalingParameters params = new SignalingParameters(
iceServers, initiator, iceServers, initiator,
pcConstraints, videoConstraints, audioConstraints,
clientId, wssUrl, wssPostUrl, clientId, wssUrl, wssPostUrl,
offerSdp, iceCandidates); offerSdp, iceCandidates);
events.onSignalingParametersReady(params); events.onSignalingParametersReady(params);
@ -193,59 +182,6 @@ public class RoomParametersFetcher {
} }
} }
// Return the constraints specified for |type| of "audio" or "video" in
// |mediaConstraintsString|.
private String getAVConstraints (
String type, String mediaConstraintsString) throws JSONException {
JSONObject json = new JSONObject(mediaConstraintsString);
// Tricky handling of values that are allowed to be (boolean or
// MediaTrackConstraints) by the getUserMedia() spec. There are three
// cases below.
if (!json.has(type) || !json.optBoolean(type, true)) {
// Case 1: "audio"/"video" is not present, or is an explicit "false"
// boolean.
return null;
}
if (json.optBoolean(type, false)) {
// Case 2: "audio"/"video" is an explicit "true" boolean.
return "{\"mandatory\": {}, \"optional\": []}";
}
// Case 3: "audio"/"video" is an object.
return json.getJSONObject(type).toString();
}
private MediaConstraints constraintsFromJSON(String jsonString)
throws JSONException {
if (jsonString == null) {
return null;
}
MediaConstraints constraints = new MediaConstraints();
JSONObject json = new JSONObject(jsonString);
JSONObject mandatoryJSON = json.optJSONObject("mandatory");
if (mandatoryJSON != null) {
JSONArray mandatoryKeys = mandatoryJSON.names();
if (mandatoryKeys != null) {
for (int i = 0; i < mandatoryKeys.length(); ++i) {
String key = mandatoryKeys.getString(i);
String value = mandatoryJSON.getString(key);
constraints.mandatory.add(
new MediaConstraints.KeyValuePair(key, value));
}
}
}
JSONArray optionalJSON = json.optJSONArray("optional");
if (optionalJSON != null) {
for (int i = 0; i < optionalJSON.length(); ++i) {
JSONObject keyValueDict = optionalJSON.getJSONObject(i);
String key = keyValueDict.names().getString(0);
String value = keyValueDict.getString(key);
constraints.optional.add(
new MediaConstraints.KeyValuePair(key, value));
}
}
return constraints;
}
// Requests & returns a TURN ICE Server based on a request URL. Must be run // Requests & returns a TURN ICE Server based on a request URL. Must be run
// off the main thread! // off the main thread!
private LinkedList<PeerConnection.IceServer> requestTurnServers(String url) private LinkedList<PeerConnection.IceServer> requestTurnServers(String url)

View File

@ -127,7 +127,7 @@ public class WebSocketChannelClient {
this.roomID = roomID; this.roomID = roomID;
this.clientID = clientID; this.clientID = clientID;
if (state != WebSocketConnectionState.CONNECTED) { if (state != WebSocketConnectionState.CONNECTED) {
Log.d(TAG, "WebSocket register() in state " + state); Log.w(TAG, "WebSocket register() in state " + state);
return; return;
} }
Log.d(TAG, "Registering WebSocket for room " + roomID + ". CLientID: " + clientID); Log.d(TAG, "Registering WebSocket for room " + roomID + ". CLientID: " + clientID);
@ -190,17 +190,16 @@ public class WebSocketChannelClient {
checkIfCalledOnValidThread(); checkIfCalledOnValidThread();
Log.d(TAG, "Disonnect WebSocket. State: " + state); Log.d(TAG, "Disonnect WebSocket. State: " + state);
if (state == WebSocketConnectionState.REGISTERED) { if (state == WebSocketConnectionState.REGISTERED) {
// Send "bye" to WebSocket server.
send("{\"type\": \"bye\"}"); send("{\"type\": \"bye\"}");
state = WebSocketConnectionState.CONNECTED; state = WebSocketConnectionState.CONNECTED;
// Send http DELETE to http WebSocket server.
sendWSSMessage("DELETE", "");
} }
// Close WebSocket in CONNECTED or ERROR states only. // Close WebSocket in CONNECTED or ERROR states only.
if (state == WebSocketConnectionState.CONNECTED if (state == WebSocketConnectionState.CONNECTED
|| state == WebSocketConnectionState.ERROR) { || state == WebSocketConnectionState.ERROR) {
ws.disconnect(); ws.disconnect();
// Send DELETE to http WebSocket server.
sendWSSMessage("DELETE", "");
state = WebSocketConnectionState.CLOSED; state = WebSocketConnectionState.CLOSED;
// Wait for websocket close event to prevent websocket library from // Wait for websocket close event to prevent websocket library from

View File

@ -45,6 +45,7 @@ public class AsyncHttpURLConnection {
private final String url; private final String url;
private final String message; private final String message;
private final AsyncHttpEvents events; private final AsyncHttpEvents events;
private String contentType;
/** /**
* Http requests callbacks. * Http requests callbacks.
@ -62,6 +63,10 @@ public class AsyncHttpURLConnection {
this.events = events; this.events = events;
} }
public void setContentType(String contentType) {
this.contentType = contentType;
}
public void send() { public void send() {
Runnable runHttp = new Runnable() { Runnable runHttp = new Runnable() {
public void run() { public void run() {
@ -92,8 +97,11 @@ public class AsyncHttpURLConnection {
connection.setDoOutput(true); connection.setDoOutput(true);
connection.setFixedLengthStreamingMode(postData.length); connection.setFixedLengthStreamingMode(postData.length);
} }
connection.setRequestProperty( if (contentType == null) {
"content-type", "text/plain; charset=utf-8"); connection.setRequestProperty("Content-Type", "text/plain; charset=utf-8");
} else {
connection.setRequestProperty("Content-Type", contentType);
}
// Send POST request. // Send POST request.
if (doOutput && postData.length > 0) { if (doOutput && postData.length > 0) {
@ -105,9 +113,9 @@ public class AsyncHttpURLConnection {
// Get response. // Get response.
int responseCode = connection.getResponseCode(); int responseCode = connection.getResponseCode();
if (responseCode != 200) { if (responseCode != 200) {
connection.disconnect();
events.onHttpError("Non-200 response to " + method + " to URL: " events.onHttpError("Non-200 response to " + method + " to URL: "
+ url + " : " + connection.getHeaderField(null)); + url + " : " + connection.getHeaderField(null));
connection.disconnect();
return; return;
} }
InputStream responseStream = connection.getInputStream(); InputStream responseStream = connection.getInputStream();

View File

@ -61,7 +61,6 @@ public class PeerConnectionClientTest extends InstrumentationTestCase
private static final String VIDEO_CODEC_VP9 = "VP9"; private static final String VIDEO_CODEC_VP9 = "VP9";
private static final String VIDEO_CODEC_H264 = "H264"; private static final String VIDEO_CODEC_H264 = "H264";
private static final int AUDIO_RUN_TIMEOUT = 1000; private static final int AUDIO_RUN_TIMEOUT = 1000;
private static final String DTLS_SRTP_KEY_AGREEMENT_CONSTRAINT = "DtlsSrtpKeyAgreement";
private static final String LOCAL_RENDERER_NAME = "Local renderer"; private static final String LOCAL_RENDERER_NAME = "Local renderer";
private static final String REMOTE_RENDERER_NAME = "Remote renderer"; private static final String REMOTE_RENDERER_NAME = "Remote renderer";
@ -130,17 +129,6 @@ public class PeerConnectionClientTest extends InstrumentationTestCase
} }
} }
// Test instance of the PeerConnectionClient class that overrides the options
// for the factory so we can run the test without an Internet connection.
class TestPeerConnectionClient extends PeerConnectionClient {
protected void configureFactory(PeerConnectionFactory factory) {
PeerConnectionFactory.Options options =
new PeerConnectionFactory.Options();
options.networkIgnoreMask = 0;
factory.setOptions(options);
}
}
// Peer connection events implementation. // Peer connection events implementation.
@Override @Override
public void onLocalDescription(SessionDescription sdp) { public void onLocalDescription(SessionDescription sdp) {
@ -251,33 +239,25 @@ public class PeerConnectionClientTest extends InstrumentationTestCase
} }
} }
private SignalingParameters getTestSignalingParameters() {
List<PeerConnection.IceServer> iceServers =
new LinkedList<PeerConnection.IceServer>();
MediaConstraints pcConstraints = new MediaConstraints();
pcConstraints.optional.add(
new MediaConstraints.KeyValuePair(DTLS_SRTP_KEY_AGREEMENT_CONSTRAINT, "false"));
MediaConstraints videoConstraints = new MediaConstraints();
MediaConstraints audioConstraints = new MediaConstraints();
SignalingParameters signalingParameters = new SignalingParameters(
iceServers, true,
pcConstraints, videoConstraints, audioConstraints,
null, null, null,
null, null);
return signalingParameters;
}
PeerConnectionClient createPeerConnectionClient( PeerConnectionClient createPeerConnectionClient(
MockRenderer localRenderer, MockRenderer remoteRenderer, MockRenderer localRenderer, MockRenderer remoteRenderer,
boolean enableVideo, String videoCodec) { boolean enableVideo, String videoCodec) {
SignalingParameters signalingParameters = getTestSignalingParameters(); List<PeerConnection.IceServer> iceServers =
new LinkedList<PeerConnection.IceServer>();
SignalingParameters signalingParameters = new SignalingParameters(
iceServers, true, // iceServers, initiator.
null, null, null, // clientId, wssUrl, wssPostUrl.
null, null); // offerSdp, iceCandidates.
PeerConnectionParameters peerConnectionParameters = PeerConnectionParameters peerConnectionParameters =
new PeerConnectionParameters( new PeerConnectionParameters(
enableVideo, true, // videoCallEnabled, loopback. enableVideo, true, // videoCallEnabled, loopback.
0, 0, 0, 0, videoCodec, true, // video codec parameters. 0, 0, 0, 0, videoCodec, true, // video codec parameters.
0, "OPUS", true); // audio codec parameters. 0, "OPUS", true); // audio codec parameters.
PeerConnectionClient client = new TestPeerConnectionClient(); PeerConnectionClient client = PeerConnectionClient.getInstance();
PeerConnectionFactory.Options options = new PeerConnectionFactory.Options();
options.networkIgnoreMask = 0;
client.setPeerConnectionFactoryOptions(options);
client.createPeerConnectionFactory( client.createPeerConnectionFactory(
getInstrumentation().getContext(), null, getInstrumentation().getContext(), null,
peerConnectionParameters, this); peerConnectionParameters, this);