Add RtcEventLog to AppRTCMobile with preference setting.

Enable diagnostic packet and event recording as in the "webrtc-internal"
setting in Chromium.

Bug: webrtc:8859
Change-Id: I1d4a19e0dd60133cdd0d4e18a55780623b65653c
Reviewed-on: https://webrtc-review.googlesource.com/49541
Commit-Queue: Qingsi Wang <qingsi@google.com>
Reviewed-by: Sami Kalliomäki <sakal@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#21987}
This commit is contained in:
Qingsi Wang
2018-02-12 10:34:18 -08:00
committed by Commit Bot
parent f7f8cb979b
commit a4e72b7914
9 changed files with 158 additions and 20 deletions

View File

@ -13,16 +13,21 @@ package org.appspot.apprtc;
import android.content.Context;
import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.preference.PreferenceManager;
import android.util.Log;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
@ -105,6 +110,7 @@ public class PeerConnectionClient {
private static final int HD_VIDEO_WIDTH = 1280;
private static final int HD_VIDEO_HEIGHT = 720;
private static final int BPS_IN_KBPS = 1000;
private static final String RTCEVENTLOG_OUTPUT_DIR_NAME = "rtc_event_log";
// Executor thread is started once in private ctor and is used for all
// peer connection API calls to ensure new peer connection factory is
@ -115,6 +121,7 @@ public class PeerConnectionClient {
private final SDPObserver sdpObserver = new SDPObserver();
private final EglBase rootEglBase;
private final Context appContext;
private PeerConnectionFactory factory;
private PeerConnection peerConnection;
PeerConnectionFactory.Options options = null;
@ -154,6 +161,8 @@ public class PeerConnectionClient {
private AudioTrack localAudioTrack;
private DataChannel dataChannel;
private boolean dataChannelEnabled;
// Enable RtcEventLog.
private RtcEventLog rtcEventLog;
/**
* Peer connection parameters.
@ -201,6 +210,7 @@ public class PeerConnectionClient {
public final boolean disableBuiltInNS;
public final boolean enableLevelControl;
public final boolean disableWebRtcAGCAndHPF;
public final boolean enableRtcEventLog;
private final DataChannelParameters dataChannelParameters;
public PeerConnectionParameters(boolean videoCallEnabled, boolean loopback, boolean tracing,
@ -208,11 +218,11 @@ public class PeerConnectionClient {
boolean videoCodecHwAcceleration, boolean videoFlexfecEnabled, int audioStartBitrate,
String audioCodec, boolean noAudioProcessing, boolean aecDump, boolean useOpenSLES,
boolean disableBuiltInAEC, boolean disableBuiltInAGC, boolean disableBuiltInNS,
boolean enableLevelControl, boolean disableWebRtcAGCAndHPF) {
boolean enableLevelControl, boolean disableWebRtcAGCAndHPF, boolean enableRtcEventLog) {
this(videoCallEnabled, loopback, tracing, videoWidth, videoHeight, videoFps, videoMaxBitrate,
videoCodec, videoCodecHwAcceleration, videoFlexfecEnabled, audioStartBitrate, audioCodec,
noAudioProcessing, aecDump, useOpenSLES, disableBuiltInAEC, disableBuiltInAGC,
disableBuiltInNS, enableLevelControl, disableWebRtcAGCAndHPF, null);
disableBuiltInNS, enableLevelControl, disableWebRtcAGCAndHPF, enableRtcEventLog, null);
}
public PeerConnectionParameters(boolean videoCallEnabled, boolean loopback, boolean tracing,
@ -220,7 +230,7 @@ public class PeerConnectionClient {
boolean videoCodecHwAcceleration, boolean videoFlexfecEnabled, int audioStartBitrate,
String audioCodec, boolean noAudioProcessing, boolean aecDump, boolean useOpenSLES,
boolean disableBuiltInAEC, boolean disableBuiltInAGC, boolean disableBuiltInNS,
boolean enableLevelControl, boolean disableWebRtcAGCAndHPF,
boolean enableLevelControl, boolean disableWebRtcAGCAndHPF, boolean enableRtcEventLog,
DataChannelParameters dataChannelParameters) {
this.videoCallEnabled = videoCallEnabled;
this.loopback = loopback;
@ -242,6 +252,7 @@ public class PeerConnectionClient {
this.disableBuiltInNS = disableBuiltInNS;
this.enableLevelControl = enableLevelControl;
this.disableWebRtcAGCAndHPF = disableWebRtcAGCAndHPF;
this.enableRtcEventLog = enableRtcEventLog;
this.dataChannelParameters = dataChannelParameters;
}
}
@ -293,15 +304,19 @@ public class PeerConnectionClient {
void onPeerConnectionError(final String description);
}
public PeerConnectionClient() {
public PeerConnectionClient(Context appContext) {
if (appContext == null) {
throw new NullPointerException("The application context is null");
}
rootEglBase = EglBase.create();
this.appContext = appContext;
}
public void setPeerConnectionFactoryOptions(PeerConnectionFactory.Options options) {
this.options = options;
}
public void createPeerConnectionFactory(final Context context,
public void createPeerConnectionFactory(
final PeerConnectionParameters peerConnectionParameters, final PeerConnectionEvents events) {
this.peerConnectionParameters = peerConnectionParameters;
this.events = events;
@ -328,7 +343,7 @@ public class PeerConnectionClient {
executor.execute(new Runnable() {
@Override
public void run() {
createPeerConnectionFactoryInternal(context);
createPeerConnectionFactoryInternal();
}
});
}
@ -357,6 +372,7 @@ public class PeerConnectionClient {
try {
createMediaConstraintsInternal();
createPeerConnectionInternal();
maybeCreateAndStartRtcEventLog();
} catch (Exception e) {
reportError("Failed to create peer connection: " + e.getMessage());
throw e;
@ -378,7 +394,7 @@ public class PeerConnectionClient {
return videoCallEnabled;
}
private void createPeerConnectionFactoryInternal(Context context) {
private void createPeerConnectionFactoryInternal() {
isError = false;
// Initialize field trials.
@ -422,7 +438,7 @@ public class PeerConnectionClient {
"Initialize WebRTC. Field trials: " + fieldTrials + " Enable video HW acceleration: "
+ peerConnectionParameters.videoCodecHwAcceleration);
PeerConnectionFactory.initialize(
PeerConnectionFactory.InitializationOptions.builder(context)
PeerConnectionFactory.InitializationOptions.builder(appContext)
.setFieldTrials(fieldTrials)
.setEnableVideoHwAcceleration(peerConnectionParameters.videoCodecHwAcceleration)
.setEnableInternalTracer(true)
@ -664,6 +680,26 @@ public class PeerConnectionClient {
Log.d(TAG, "Peer connection created.");
}
private File createRtcEventLogOutputFile() {
DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_hhmm_ss", Locale.getDefault());
Date date = new Date();
final String outputFileName = "event_log_" + dateFormat.format(date) + ".log";
return new File(
appContext.getDir(RTCEVENTLOG_OUTPUT_DIR_NAME, Context.MODE_PRIVATE), outputFileName);
}
private void maybeCreateAndStartRtcEventLog() {
if (appContext == null || peerConnection == null) {
return;
}
if (!peerConnectionParameters.enableRtcEventLog) {
Log.d(TAG, "RtcEventLog is disabled.");
return;
}
rtcEventLog = new RtcEventLog(peerConnection);
rtcEventLog.start(createRtcEventLogOutputFile());
}
private void closeInternal() {
if (factory != null && peerConnectionParameters.aecDump) {
factory.stopAecDump();
@ -674,6 +710,11 @@ public class PeerConnectionClient {
dataChannel.dispose();
dataChannel = null;
}
if (rtcEventLog != null) {
// RtcEventLog should stop before the peer connection is disposed.
rtcEventLog.stop();
rtcEventLog = null;
}
if (peerConnection != null) {
peerConnection.dispose();
peerConnection = null;