Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(293)

Unified Diff: components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/SessionDependencyFactory.java

Issue 537253003: Implementing RTC debugging session objects (client and server parts). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@tunnel
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/SessionDependencyFactory.java
diff --git a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/SessionDependencyFactory.java b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/SessionDependencyFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..c39de43774dfb84edf75dc5cf07a7bcbd3a650c3
--- /dev/null
+++ b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/SessionDependencyFactory.java
@@ -0,0 +1,370 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.components.devtools_bridge;
+
+import org.webrtc.DataChannel;
+import org.webrtc.IceCandidate;
+import org.webrtc.MediaConstraints;
+import org.webrtc.MediaStream;
+import org.webrtc.PeerConnection;
+import org.webrtc.PeerConnectionFactory;
+import org.webrtc.SdpObserver;
+import org.webrtc.SessionDescription;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Implements AbstractDataChannel and AbstractPeerConnection on top of org.webrtc.* API.
+ * Isolation is needed because some configuration of DevTools bridge may not be based on
+ * Java API. Native implementation of SessionDependencyFactory will be added for this case.
+ * In addition abstraction layer isolates SessionBase from complexity of underlying API
+ * beside used features.
+ */
+public class SessionDependencyFactory {
+ private final PeerConnectionFactory mFactory = new PeerConnectionFactory();
+
+ public AbstractPeerConnection createPeerConnection(
+ RTCConfiguration config, AbstractPeerConnection.Observer observer) {
+ MediaConstraints constraints = new MediaConstraints();
+ constraints.mandatory.add(
+ new MediaConstraints.KeyValuePair("DtlsSrtpKeyAgreement", "true"));
+ return new PeerConnectionAdapter(
+ mFactory.createPeerConnection(convert(config), constraints,
+ new PeerConnnectionObserverAdapter(observer)), observer);
+ }
+
+ public void dispose() {
+ mFactory.dispose();
+ }
+
+ private static AbstractPeerConnection.SessionDescriptionType convertType(
+ SessionDescription.Type type) {
+ switch (type) {
+ case OFFER:
+ return AbstractPeerConnection.SessionDescriptionType.OFFER;
+ case ANSWER:
+ return AbstractPeerConnection.SessionDescriptionType.ANSWER;
+ default:
+ throw new IllegalArgumentException(type.toString());
+ }
+ }
+
+ private static SessionDescription.Type convertType(
+ AbstractPeerConnection.SessionDescriptionType type) {
+ switch (type) {
+ case OFFER:
+ return SessionDescription.Type.OFFER;
+ case ANSWER:
+ return SessionDescription.Type.ANSWER;
+ default:
+ throw new IllegalArgumentException(type.toString());
+ }
+ }
+
+ private static AbstractPeerConnection.IceCandidate convert(IceCandidate candidate) {
+ return new AbstractPeerConnection.IceCandidate(
+ candidate.sdpMid, candidate.sdpMLineIndex, candidate.sdp);
+ }
+
+ private static IceCandidate convert(AbstractPeerConnection.IceCandidate candidate) {
+ return new IceCandidate(candidate.sdpMid, candidate.sdpMLineIndex, candidate.sdp);
+ }
+
+ private static List<PeerConnection.IceServer> convert(RTCConfiguration config) {
+ List<PeerConnection.IceServer> result = new ArrayList<PeerConnection.IceServer>();
+ for (RTCConfiguration.IceServer server : config.iceServers) {
+ result.add(new PeerConnection.IceServer(
+ server.uri, server.username, server.credential));
+ }
+ return result;
+ }
+
+ public static DataChannelAdapter createDataChannel(PeerConnection connection, int channelId) {
+ DataChannel.Init init = new DataChannel.Init();
+ init.ordered = true;
+ init.negotiated = true;
+ init.id = channelId;
+ return new DataChannelAdapter(connection.createDataChannel("", init));
+ }
+
+ private static final class DataChannelAdapter extends AbstractDataChannel {
+ private final DataChannel mAdaptee;
+
+ public DataChannelAdapter(DataChannel adaptee) {
+ mAdaptee = adaptee;
+ }
+
+ @Override
+ public void dispose() {
+ mAdaptee.dispose();
+ }
+
+ @Override
+ public void close() {
+ mAdaptee.close();
+ }
+
+ @Override
+ public void send(ByteBuffer message, AbstractDataChannel.MessageType type) {
+ assert message.remaining() > 0;
+ mAdaptee.send(new DataChannel.Buffer(
+ message, type == AbstractDataChannel.MessageType.BINARY));
+ }
+
+ @Override
+ public void registerObserver(Observer observer) {
+ mAdaptee.registerObserver(new DataChannelObserverAdapter(observer, mAdaptee));
+ }
+
+ @Override
+ public void unregisterObserver() {
+ mAdaptee.unregisterObserver();
+ }
+ }
+
+ private static final class DataChannelObserverAdapter implements DataChannel.Observer {
+ private final AbstractDataChannel.Observer mAdaptee;
+ private final DataChannel mDataChannel;
+ private AbstractDataChannel.State mState = AbstractDataChannel.State.CLOSED;
+
+ public DataChannelObserverAdapter(
+ AbstractDataChannel.Observer adaptee, DataChannel dataChannel) {
+ mAdaptee = adaptee;
+ mDataChannel = dataChannel;
+ }
+
+ @Override
+ public void onStateChange() {
+ AbstractDataChannel.State state = mDataChannel.state() == DataChannel.State.OPEN ?
+ AbstractDataChannel.State.OPEN : AbstractDataChannel.State.CLOSED;
+ if (mState != state) {
+ mState = state;
+ mAdaptee.onStateChange(state);
+ }
+ }
+
+ @Override
+ public void onMessage(DataChannel.Buffer buffer) {
+ assert buffer.data.remaining() > 0;
+ mAdaptee.onMessage(buffer.data);
+ }
+ }
+
+ private abstract static class SetHandler implements SdpObserver {
+ @Override
+ public final void onCreateSuccess(SessionDescription description) {
+ assert false;
+ }
+
+ @Override
+ public final void onCreateFailure(String error) {
+ assert false;
+ }
+ }
+
+ private abstract static class CreateHandler implements SdpObserver {
+ @Override
+ public final void onSetSuccess() {
+ assert false;
+ }
+
+ @Override
+ public final void onSetFailure(String error) {
+ assert false;
+ }
+ }
+
+ private static final class CreateAndSetHandler extends CreateHandler {
+ private final PeerConnectionAdapter mConnection;
+ private final AbstractPeerConnection.Observer mObserver;
+
+ public CreateAndSetHandler(PeerConnectionAdapter connection,
+ AbstractPeerConnection.Observer observer) {
+ mConnection = connection;
+ mObserver = observer;
+ }
+
+ @Override
+ public void onCreateSuccess(final SessionDescription localDescription) {
+ mConnection.setLocalDescriptionOnSignalingThread(localDescription);
+ }
+
+ @Override
+ public void onCreateFailure(String description) {
+ mObserver.onFailure(description);
+ }
+ }
+
+ private static final class LocalSetHandler extends SetHandler {
+ private final SessionDescription mLocalDescription;
+ private final AbstractPeerConnection.Observer mObserver;
+
+ public LocalSetHandler(SessionDescription localDescription,
+ AbstractPeerConnection.Observer observer) {
+ mLocalDescription = localDescription;
+ mObserver = observer;
+ }
+
+ @Override
+ public void onSetSuccess() {
+ mObserver.onLocalDescriptionCreatedAndSet(
+ convertType(mLocalDescription.type), mLocalDescription.description);
+ }
+
+ @Override
+ public void onSetFailure(String description) {
+ mObserver.onFailure(description);
+ }
+ }
+
+ private static final class SetRemoteDescriptionHandler extends SetHandler {
+ private final AbstractPeerConnection.Observer mObserver;
+
+ public SetRemoteDescriptionHandler(AbstractPeerConnection.Observer observer) {
+ mObserver = observer;
+ }
+
+ @Override
+ public void onSetSuccess() {
+ mObserver.onRemoteDescriptionSet();
+ }
+
+ @Override
+ public void onSetFailure(String description) {
+ mObserver.onFailure(description);
+ }
+ }
+
+ private static final class PeerConnectionAdapter extends AbstractPeerConnection {
+ private PeerConnection mAdaptee;
+ private final Observer mObserver;
+
+ // Only access from signaling thread and disposing need synchronization.
+ private final Object mDisposeLock = new Object();
+
+ public PeerConnectionAdapter(PeerConnection adaptee, Observer observer) {
+ mAdaptee = adaptee;
+ mObserver = observer;
+ }
+
+ public void setLocalDescriptionOnSignalingThread(SessionDescription description) {
+ synchronized (mDisposeLock) {
+ if (mAdaptee == null)
+ return;
+
+ mAdaptee.setLocalDescription(
+ new LocalSetHandler(description, mObserver), description);
+ }
+ }
+
+ @Override
+ public void createAndSetLocalDescription(SessionDescriptionType type) {
+ CreateAndSetHandler handler = new CreateAndSetHandler(this, mObserver);
+ switch (type) {
+ case OFFER:
+ mAdaptee.createOffer(handler, new MediaConstraints());
+ break;
+
+ case ANSWER:
+ mAdaptee.createAnswer(handler, new MediaConstraints());
+ break;
+
+ default:
+ assert false;
+ }
+ }
+
+ @Override
+ public void setRemoteDescription(SessionDescriptionType type, String description) {
+ mAdaptee.setRemoteDescription(new SetRemoteDescriptionHandler(mObserver),
+ new SessionDescription(convertType(type), description));
+ }
+
+ @Override
+ public void addIceCandidate(String candidate) {
+ mAdaptee.addIceCandidate(convert(
+ AbstractPeerConnection.IceCandidate.fromString(candidate)));
+ }
+
+ @Override
+ public void dispose() {
+ synchronized (mDisposeLock) {
+ mAdaptee.dispose();
+ mAdaptee = null;
+ }
+ }
+
+ @Override
+ public AbstractDataChannel createDataChannel(int channelId) {
+ DataChannel.Init init = new DataChannel.Init();
+ init.ordered = true;
+ init.negotiated = true;
+ init.id = channelId;
+ return new DataChannelAdapter(mAdaptee.createDataChannel("", init));
+ }
+ }
+
+ private static final class PeerConnnectionObserverAdapter implements PeerConnection.Observer {
+ private final AbstractPeerConnection.Observer mAdaptee;
+ private boolean mConnected = false;
+
+ public PeerConnnectionObserverAdapter(AbstractPeerConnection.Observer adaptee) {
+ mAdaptee = adaptee;
+ }
+
+ @Override
+ public void onIceCandidate(IceCandidate candidate) {
+ mAdaptee.onIceCandidate(convert(candidate).toString());
+ }
+
+ @Override
+ public void onSignalingChange(PeerConnection.SignalingState newState) {}
+
+ @Override
+ public void onIceConnectionChange(PeerConnection.IceConnectionState newState) {
+ boolean connected = isConnected(newState);
+ if (mConnected != connected) {
+ mConnected = connected;
+ mAdaptee.onIceConnectionChange(connected);
+ }
+ }
+
+ private static boolean isConnected(PeerConnection.IceConnectionState newState) {
+ switch (newState) {
+ case CONNECTED:
+ case COMPLETED:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ @Override
+ public void onIceGatheringChange(PeerConnection.IceGatheringState newState) {}
+
+ @Override
+ public void onDataChannel(DataChannel dataChannel) {
+ // Remote peer added non-prenegotiated data channel. It's not supported.
+ dataChannel.dispose();
+ }
+
+ @Override
+ public void onAddStream(MediaStream stream) {}
+
+ @Override
+ public void onRemoveStream(MediaStream stream) {}
+
+ @Override
+ public void onRenegotiationNeeded() {
+ }
+
+ @Override
+ public void onError() {
+ assert false; // TODO(serya): add meaningful handling strategy.
+ }
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698