Add Datachannel support to Android AppRTCMobile
BUG=webrtc:6647 Review-Url: https://codereview.webrtc.org/2464243002 Cr-Commit-Position: refs/heads/master@{#15145}
This commit is contained in:
@ -36,6 +36,7 @@ import java.util.List;
|
||||
import org.appspot.apprtc.AppRTCClient.RoomConnectionParameters;
|
||||
import org.appspot.apprtc.AppRTCClient.SignalingParameters;
|
||||
import org.appspot.apprtc.PeerConnectionClient.PeerConnectionParameters;
|
||||
import org.appspot.apprtc.PeerConnectionClient.DataChannelParameters;
|
||||
import org.webrtc.Camera1Enumerator;
|
||||
import org.webrtc.Camera2Enumerator;
|
||||
import org.webrtc.CameraEnumerator;
|
||||
@ -97,6 +98,14 @@ public class CallActivity extends Activity implements AppRTCClient.SignalingEven
|
||||
"org.appspot.apprtc.SAVE_REMOTE_VIDEO_TO_FILE_HEIGHT";
|
||||
public static final String EXTRA_USE_VALUES_FROM_INTENT =
|
||||
"org.appspot.apprtc.USE_VALUES_FROM_INTENT";
|
||||
public static final String EXTRA_DATA_CHANNEL_ENABLED = "org.appspot.apprtc.DATA_CHANNEL_ENABLED";
|
||||
public static final String EXTRA_ORDERED = "org.appspot.apprtc.ORDERED";
|
||||
public static final String EXTRA_MAX_RETRANSMITS_MS = "org.appspot.apprtc.MAX_RETRANSMITS_MS";
|
||||
public static final String EXTRA_MAX_RETRANSMITS = "org.appspot.apprtc.MAX_RETRANSMITS";
|
||||
public static final String EXTRA_PROTOCOL = "org.appspot.apprtc.PROTOCOL";
|
||||
public static final String EXTRA_NEGOTIATED = "org.appspot.apprtc.NEGOTIATED";
|
||||
public static final String EXTRA_ID = "org.appspot.apprtc.ID";
|
||||
|
||||
private static final String TAG = "CallRTCClient";
|
||||
private static final int CAPTURE_PERMISSION_REQUEST_CODE = 1;
|
||||
|
||||
@ -264,7 +273,13 @@ public class CallActivity extends Activity implements AppRTCClient.SignalingEven
|
||||
videoWidth = displayMetrics.widthPixels;
|
||||
videoHeight = displayMetrics.heightPixels;
|
||||
}
|
||||
|
||||
DataChannelParameters dataChannelParameters = null;
|
||||
if (intent.getBooleanExtra(EXTRA_DATA_CHANNEL_ENABLED, true)) {
|
||||
dataChannelParameters = new DataChannelParameters(intent.getBooleanExtra(EXTRA_ORDERED, true),
|
||||
intent.getIntExtra(EXTRA_MAX_RETRANSMITS_MS, -1),
|
||||
intent.getIntExtra(EXTRA_MAX_RETRANSMITS, -1), intent.getStringExtra(EXTRA_PROTOCOL),
|
||||
intent.getBooleanExtra(EXTRA_NEGOTIATED, false), intent.getIntExtra(EXTRA_ID, -1));
|
||||
}
|
||||
peerConnectionParameters =
|
||||
new PeerConnectionParameters(intent.getBooleanExtra(EXTRA_VIDEO_CALL, true), loopback,
|
||||
tracing, videoWidth, videoHeight, intent.getIntExtra(EXTRA_VIDEO_FPS, 0),
|
||||
@ -277,7 +292,7 @@ public class CallActivity extends Activity implements AppRTCClient.SignalingEven
|
||||
intent.getBooleanExtra(EXTRA_DISABLE_BUILT_IN_AEC, false),
|
||||
intent.getBooleanExtra(EXTRA_DISABLE_BUILT_IN_AGC, false),
|
||||
intent.getBooleanExtra(EXTRA_DISABLE_BUILT_IN_NS, false),
|
||||
intent.getBooleanExtra(EXTRA_ENABLE_LEVEL_CONTROL, false));
|
||||
intent.getBooleanExtra(EXTRA_ENABLE_LEVEL_CONTROL, false), dataChannelParameters);
|
||||
commandLineRun = intent.getBooleanExtra(EXTRA_CMDLINE, false);
|
||||
runTimeMs = intent.getIntExtra(EXTRA_RUNTIME, 0);
|
||||
|
||||
|
||||
@ -80,6 +80,13 @@ public class ConnectActivity extends Activity {
|
||||
private String keyprefRoomList;
|
||||
private ArrayList<String> roomList;
|
||||
private ArrayAdapter<String> adapter;
|
||||
private String keyprefEnableDataChannel;
|
||||
private String keyprefOrdered;
|
||||
private String keyprefMaxRetransmitTimeMs;
|
||||
private String keyprefMaxRetransmits;
|
||||
private String keyprefDataProtocol;
|
||||
private String keyprefNegotiated;
|
||||
private String keyprefDataId;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
@ -114,6 +121,13 @@ public class ConnectActivity extends Activity {
|
||||
keyprefRoomServerUrl = getString(R.string.pref_room_server_url_key);
|
||||
keyprefRoom = getString(R.string.pref_room_key);
|
||||
keyprefRoomList = getString(R.string.pref_room_list_key);
|
||||
keyprefEnableDataChannel = getString(R.string.pref_enable_datachannel_key);
|
||||
keyprefOrdered = getString(R.string.pref_ordered_key);
|
||||
keyprefMaxRetransmitTimeMs = getString(R.string.pref_max_retransmit_time_ms_key);
|
||||
keyprefMaxRetransmits = getString(R.string.pref_max_retransmits_key);
|
||||
keyprefDataProtocol = getString(R.string.pref_data_protocol_key);
|
||||
keyprefNegotiated = getString(R.string.pref_negotiated_key);
|
||||
keyprefDataId = getString(R.string.pref_data_id_key);
|
||||
|
||||
setContentView(R.layout.activity_connect);
|
||||
|
||||
@ -279,6 +293,28 @@ public class ConnectActivity extends Activity {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a value from the shared preference or from the intent, if it does not
|
||||
* exist the default is used.
|
||||
*/
|
||||
private int sharedPrefGetInteger(
|
||||
int attributeId, String intentName, int defaultId, boolean useFromIntent) {
|
||||
String defaultString = getString(defaultId);
|
||||
int defaultValue = Integer.parseInt(defaultString);
|
||||
if (useFromIntent) {
|
||||
return getIntent().getIntExtra(intentName, defaultValue);
|
||||
} else {
|
||||
String attributeName = getString(attributeId);
|
||||
String value = sharedPref.getString(attributeName, defaultString);
|
||||
try {
|
||||
return Integer.parseInt(value);
|
||||
} catch (NumberFormatException e) {
|
||||
Log.e(TAG, "Wrong setting for: " + attributeName + ":" + value);
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void connectToRoom(String roomId, boolean commandLineRun, boolean loopback,
|
||||
boolean useValuesFromIntent, int runTimeMs) {
|
||||
this.commandLineRun = commandLineRun;
|
||||
@ -433,6 +469,25 @@ public class ConnectActivity extends Activity {
|
||||
boolean tracing = sharedPrefGetBoolean(R.string.pref_tracing_key, CallActivity.EXTRA_TRACING,
|
||||
R.string.pref_tracing_default, useValuesFromIntent);
|
||||
|
||||
// Get datachannel options
|
||||
boolean dataChannelEnabled = sharedPrefGetBoolean(R.string.pref_enable_datachannel_key,
|
||||
CallActivity.EXTRA_DATA_CHANNEL_ENABLED, R.string.pref_enable_datachannel_default,
|
||||
useValuesFromIntent);
|
||||
boolean ordered = sharedPrefGetBoolean(R.string.pref_ordered_key, CallActivity.EXTRA_ORDERED,
|
||||
R.string.pref_ordered_default, useValuesFromIntent);
|
||||
boolean negotiated = sharedPrefGetBoolean(R.string.pref_negotiated_key,
|
||||
CallActivity.EXTRA_NEGOTIATED, R.string.pref_negotiated_default, useValuesFromIntent);
|
||||
int maxRetrMs = sharedPrefGetInteger(R.string.pref_max_retransmit_time_ms_key,
|
||||
CallActivity.EXTRA_MAX_RETRANSMITS_MS, R.string.pref_max_retransmit_time_ms_default,
|
||||
useValuesFromIntent);
|
||||
int maxRetr =
|
||||
sharedPrefGetInteger(R.string.pref_max_retransmits_key, CallActivity.EXTRA_MAX_RETRANSMITS,
|
||||
R.string.pref_max_retransmits_default, useValuesFromIntent);
|
||||
int id = sharedPrefGetInteger(R.string.pref_data_id_key, CallActivity.EXTRA_ID,
|
||||
R.string.pref_data_id_default, useValuesFromIntent);
|
||||
String protocol = sharedPrefGetString(R.string.pref_data_protocol_key,
|
||||
CallActivity.EXTRA_PROTOCOL, R.string.pref_data_protocol_default, useValuesFromIntent);
|
||||
|
||||
// Start AppRTCMobile activity.
|
||||
Log.d(TAG, "Connecting to room " + roomId + " at URL " + roomUrl);
|
||||
if (validateUrl(roomUrl)) {
|
||||
@ -466,6 +521,17 @@ public class ConnectActivity extends Activity {
|
||||
intent.putExtra(CallActivity.EXTRA_CMDLINE, commandLineRun);
|
||||
intent.putExtra(CallActivity.EXTRA_RUNTIME, runTimeMs);
|
||||
|
||||
intent.putExtra(CallActivity.EXTRA_DATA_CHANNEL_ENABLED, dataChannelEnabled);
|
||||
|
||||
if (dataChannelEnabled) {
|
||||
intent.putExtra(CallActivity.EXTRA_ORDERED, ordered);
|
||||
intent.putExtra(CallActivity.EXTRA_MAX_RETRANSMITS_MS, maxRetrMs);
|
||||
intent.putExtra(CallActivity.EXTRA_MAX_RETRANSMITS, maxRetr);
|
||||
intent.putExtra(CallActivity.EXTRA_PROTOCOL, protocol);
|
||||
intent.putExtra(CallActivity.EXTRA_NEGOTIATED, negotiated);
|
||||
intent.putExtra(CallActivity.EXTRA_ID, id);
|
||||
}
|
||||
|
||||
if (useValuesFromIntent) {
|
||||
if (getIntent().hasExtra(CallActivity.EXTRA_VIDEO_FILE_AS_CAMERA)) {
|
||||
String videoFileAsCamera =
|
||||
|
||||
@ -16,6 +16,7 @@ import android.os.ParcelFileDescriptor;
|
||||
import android.util.Log;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.LinkedList;
|
||||
@ -126,6 +127,30 @@ public class PeerConnectionClient {
|
||||
// enableAudio is set to true if audio should be sent.
|
||||
private boolean enableAudio;
|
||||
private AudioTrack localAudioTrack;
|
||||
private DataChannel dataChannel;
|
||||
private boolean dataChannelEnabled;
|
||||
|
||||
/**
|
||||
* Peer connection parameters.
|
||||
*/
|
||||
public static class DataChannelParameters {
|
||||
public final boolean ordered;
|
||||
public final int maxRetransmitTimeMs;
|
||||
public final int maxRetransmits;
|
||||
public final String protocol;
|
||||
public final boolean negotiated;
|
||||
public final int id;
|
||||
|
||||
public DataChannelParameters(boolean ordered, int maxRetransmitTimeMs, int maxRetransmits,
|
||||
String protocol, boolean negotiated, int id) {
|
||||
this.ordered = ordered;
|
||||
this.maxRetransmitTimeMs = maxRetransmitTimeMs;
|
||||
this.maxRetransmits = maxRetransmits;
|
||||
this.protocol = protocol;
|
||||
this.negotiated = negotiated;
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Peer connection parameters.
|
||||
@ -149,12 +174,25 @@ public class PeerConnectionClient {
|
||||
public final boolean disableBuiltInAGC;
|
||||
public final boolean disableBuiltInNS;
|
||||
public final boolean enableLevelControl;
|
||||
private final DataChannelParameters dataChannelParameters;
|
||||
|
||||
public PeerConnectionParameters(boolean videoCallEnabled, boolean loopback, boolean tracing,
|
||||
int videoWidth, int videoHeight, int videoFps, int videoMaxBitrate, String videoCodec,
|
||||
boolean videoCodecHwAcceleration, int audioStartBitrate, String audioCodec,
|
||||
boolean noAudioProcessing, boolean aecDump, boolean useOpenSLES, boolean disableBuiltInAEC,
|
||||
boolean disableBuiltInAGC, boolean disableBuiltInNS, boolean enableLevelControl) {
|
||||
this(videoCallEnabled, loopback, tracing, videoWidth, videoHeight, videoFps, videoMaxBitrate,
|
||||
videoCodec, videoCodecHwAcceleration, audioStartBitrate, audioCodec, noAudioProcessing,
|
||||
aecDump, useOpenSLES, disableBuiltInAEC, disableBuiltInAGC, disableBuiltInNS,
|
||||
enableLevelControl, null);
|
||||
}
|
||||
|
||||
public PeerConnectionParameters(boolean videoCallEnabled, boolean loopback, boolean tracing,
|
||||
int videoWidth, int videoHeight, int videoFps, int videoMaxBitrate, String videoCodec,
|
||||
boolean videoCodecHwAcceleration, int audioStartBitrate, String audioCodec,
|
||||
boolean noAudioProcessing, boolean aecDump, boolean useOpenSLES, boolean disableBuiltInAEC,
|
||||
boolean disableBuiltInAGC, boolean disableBuiltInNS, boolean enableLevelControl,
|
||||
DataChannelParameters dataChannelParameters) {
|
||||
this.videoCallEnabled = videoCallEnabled;
|
||||
this.loopback = loopback;
|
||||
this.tracing = tracing;
|
||||
@ -173,6 +211,7 @@ public class PeerConnectionClient {
|
||||
this.disableBuiltInAGC = disableBuiltInAGC;
|
||||
this.disableBuiltInNS = disableBuiltInNS;
|
||||
this.enableLevelControl = enableLevelControl;
|
||||
this.dataChannelParameters = dataChannelParameters;
|
||||
}
|
||||
}
|
||||
|
||||
@ -243,6 +282,7 @@ public class PeerConnectionClient {
|
||||
this.peerConnectionParameters = peerConnectionParameters;
|
||||
this.events = events;
|
||||
videoCallEnabled = peerConnectionParameters.videoCallEnabled;
|
||||
dataChannelEnabled = peerConnectionParameters.dataChannelParameters != null;
|
||||
// Reset variables to initial states.
|
||||
this.context = null;
|
||||
factory = null;
|
||||
@ -484,6 +524,17 @@ public class PeerConnectionClient {
|
||||
rtcConfig.keyType = PeerConnection.KeyType.ECDSA;
|
||||
|
||||
peerConnection = factory.createPeerConnection(rtcConfig, pcConstraints, pcObserver);
|
||||
|
||||
if (dataChannelEnabled) {
|
||||
DataChannel.Init init = new DataChannel.Init();
|
||||
init.ordered = peerConnectionParameters.dataChannelParameters.ordered;
|
||||
init.negotiated = peerConnectionParameters.dataChannelParameters.negotiated;
|
||||
init.maxRetransmits = peerConnectionParameters.dataChannelParameters.maxRetransmits;
|
||||
init.maxRetransmitTimeMs = peerConnectionParameters.dataChannelParameters.maxRetransmitTimeMs;
|
||||
init.id = peerConnectionParameters.dataChannelParameters.id;
|
||||
init.protocol = peerConnectionParameters.dataChannelParameters.protocol;
|
||||
dataChannel = peerConnection.createDataChannel("ApprtcDemo data", init);
|
||||
}
|
||||
isInitiator = false;
|
||||
|
||||
// Set default WebRTC tracing and INFO libjingle logging.
|
||||
@ -524,6 +575,10 @@ public class PeerConnectionClient {
|
||||
}
|
||||
Log.d(TAG, "Closing peer connection.");
|
||||
statsTimer.cancel();
|
||||
if (dataChannel != null) {
|
||||
dataChannel.dispose();
|
||||
dataChannel = null;
|
||||
}
|
||||
if (peerConnection != null) {
|
||||
peerConnection.dispose();
|
||||
peerConnection = null;
|
||||
@ -1076,7 +1131,34 @@ public class PeerConnectionClient {
|
||||
|
||||
@Override
|
||||
public void onDataChannel(final DataChannel dc) {
|
||||
reportError("AppRTC doesn't use data channels, but got: " + dc.label() + " anyway!");
|
||||
Log.d(TAG, "New Data channel " + dc.label());
|
||||
|
||||
if (!dataChannelEnabled)
|
||||
return;
|
||||
|
||||
dc.registerObserver(new DataChannel.Observer() {
|
||||
public void onBufferedAmountChange(long previousAmount) {
|
||||
Log.d(TAG, "Data channel buffered amount changed: " + dc.label() + ": " + dc.state());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateChange() {
|
||||
Log.d(TAG, "Data channel state changed: " + dc.label() + ": " + dc.state());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessage(final DataChannel.Buffer buffer) {
|
||||
if (buffer.binary) {
|
||||
Log.d(TAG, "Received binary msg over " + dc);
|
||||
return;
|
||||
}
|
||||
ByteBuffer data = buffer.data;
|
||||
final byte[] bytes = new byte[data.capacity()];
|
||||
data.get(bytes);
|
||||
String strData = new String(bytes);
|
||||
Log.d(TAG, "Got msg: " + strData + " over " + dc);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -52,6 +52,14 @@ public class SettingsActivity extends Activity implements OnSharedPreferenceChan
|
||||
private String keyPrefDisplayHud;
|
||||
private String keyPrefTracing;
|
||||
|
||||
private String keyprefEnableDataChannel;
|
||||
private String keyprefOrdered;
|
||||
private String keyprefMaxRetransmitTimeMs;
|
||||
private String keyprefMaxRetransmits;
|
||||
private String keyprefDataProtocol;
|
||||
private String keyprefNegotiated;
|
||||
private String keyprefDataId;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@ -79,6 +87,14 @@ public class SettingsActivity extends Activity implements OnSharedPreferenceChan
|
||||
keyprefEnableLevelControl = getString(R.string.pref_enable_level_control_key);
|
||||
keyprefSpeakerphone = getString(R.string.pref_speakerphone_key);
|
||||
|
||||
keyprefEnableDataChannel = getString(R.string.pref_enable_datachannel_key);
|
||||
keyprefOrdered = getString(R.string.pref_ordered_key);
|
||||
keyprefMaxRetransmitTimeMs = getString(R.string.pref_max_retransmit_time_ms_key);
|
||||
keyprefMaxRetransmits = getString(R.string.pref_max_retransmits_key);
|
||||
keyprefDataProtocol = getString(R.string.pref_data_protocol_key);
|
||||
keyprefNegotiated = getString(R.string.pref_negotiated_key);
|
||||
keyprefDataId = getString(R.string.pref_data_id_key);
|
||||
|
||||
keyPrefRoomServerUrl = getString(R.string.pref_room_server_url_key);
|
||||
keyPrefDisplayHud = getString(R.string.pref_displayhud_key);
|
||||
keyPrefTracing = getString(R.string.pref_tracing_key);
|
||||
@ -124,6 +140,15 @@ public class SettingsActivity extends Activity implements OnSharedPreferenceChan
|
||||
updateSummaryB(sharedPreferences, keyprefEnableLevelControl);
|
||||
updateSummaryList(sharedPreferences, keyprefSpeakerphone);
|
||||
|
||||
updateSummaryB(sharedPreferences, keyprefEnableDataChannel);
|
||||
updateSummaryB(sharedPreferences, keyprefOrdered);
|
||||
updateSummary(sharedPreferences, keyprefMaxRetransmitTimeMs);
|
||||
updateSummary(sharedPreferences, keyprefMaxRetransmits);
|
||||
updateSummary(sharedPreferences, keyprefDataProtocol);
|
||||
updateSummaryB(sharedPreferences, keyprefNegotiated);
|
||||
updateSummary(sharedPreferences, keyprefDataId);
|
||||
setDataChannelEnable(sharedPreferences);
|
||||
|
||||
updateSummary(sharedPreferences, keyPrefRoomServerUrl);
|
||||
updateSummaryB(sharedPreferences, keyPrefDisplayHud);
|
||||
updateSummaryB(sharedPreferences, keyPrefTracing);
|
||||
@ -182,7 +207,11 @@ public class SettingsActivity extends Activity implements OnSharedPreferenceChan
|
||||
|| key.equals(keyPrefVideoCodec)
|
||||
|| key.equals(keyprefStartAudioBitrateType)
|
||||
|| key.equals(keyPrefAudioCodec)
|
||||
|| key.equals(keyPrefRoomServerUrl)) {
|
||||
|| key.equals(keyPrefRoomServerUrl)
|
||||
|| key.equals(keyprefMaxRetransmitTimeMs)
|
||||
|| key.equals(keyprefMaxRetransmits)
|
||||
|| key.equals(keyprefDataProtocol)
|
||||
|| key.equals(keyprefDataId)) {
|
||||
updateSummary(sharedPreferences, key);
|
||||
} else if (key.equals(keyprefMaxVideoBitrateValue)
|
||||
|| key.equals(keyprefStartAudioBitrateValue)) {
|
||||
@ -201,7 +230,10 @@ public class SettingsActivity extends Activity implements OnSharedPreferenceChan
|
||||
|| key.equals(keyprefDisableBuiltInAGC)
|
||||
|| key.equals(keyprefDisableBuiltInNS)
|
||||
|| key.equals(keyprefEnableLevelControl)
|
||||
|| key.equals(keyPrefDisplayHud)) {
|
||||
|| key.equals(keyPrefDisplayHud)
|
||||
|| key.equals(keyprefEnableDataChannel)
|
||||
|| key.equals(keyprefOrdered)
|
||||
|| key.equals(keyprefNegotiated)) {
|
||||
updateSummaryB(sharedPreferences, key);
|
||||
} else if (key.equals(keyprefSpeakerphone)) {
|
||||
updateSummaryList(sharedPreferences, key);
|
||||
@ -213,6 +245,9 @@ public class SettingsActivity extends Activity implements OnSharedPreferenceChan
|
||||
if (key.equals(keyprefStartAudioBitrateType)) {
|
||||
setAudioBitrateEnable(sharedPreferences);
|
||||
}
|
||||
if (key.equals(keyprefEnableDataChannel)) {
|
||||
setDataChannelEnable(sharedPreferences);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateSummary(SharedPreferences sharedPreferences, String key) {
|
||||
@ -263,4 +298,14 @@ public class SettingsActivity extends Activity implements OnSharedPreferenceChan
|
||||
bitratePreferenceValue.setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void setDataChannelEnable(SharedPreferences sharedPreferences) {
|
||||
boolean enabled = sharedPreferences.getBoolean(keyprefEnableDataChannel, true);
|
||||
settingsFragment.findPreference(keyprefOrdered).setEnabled(enabled);
|
||||
settingsFragment.findPreference(keyprefMaxRetransmitTimeMs).setEnabled(enabled);
|
||||
settingsFragment.findPreference(keyprefMaxRetransmits).setEnabled(enabled);
|
||||
settingsFragment.findPreference(keyprefDataProtocol).setEnabled(enabled);
|
||||
settingsFragment.findPreference(keyprefNegotiated).setEnabled(enabled);
|
||||
settingsFragment.findPreference(keyprefDataId).setEnabled(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user