1 /* 2 * Copyright 2013 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 package org.webrtc; 12 13 import java.nio.ByteBuffer; 14 15 /** Java wrapper for a C++ DataChannelInterface. */ 16 public class DataChannel { 17 /** Java wrapper for WebIDL RTCDataChannel. */ 18 public static class Init { 19 public boolean ordered = true; 20 // Optional unsigned short in WebIDL, -1 means unspecified. 21 public int maxRetransmitTimeMs = -1; 22 // Optional unsigned short in WebIDL, -1 means unspecified. 23 public int maxRetransmits = -1; 24 public String protocol = ""; 25 public boolean negotiated; 26 // Optional unsigned short in WebIDL, -1 means unspecified. 27 public int id = -1; 28 29 @CalledByNative("Init") getOrdered()30 boolean getOrdered() { 31 return ordered; 32 } 33 34 @CalledByNative("Init") getMaxRetransmitTimeMs()35 int getMaxRetransmitTimeMs() { 36 return maxRetransmitTimeMs; 37 } 38 39 @CalledByNative("Init") getMaxRetransmits()40 int getMaxRetransmits() { 41 return maxRetransmits; 42 } 43 44 @CalledByNative("Init") getProtocol()45 String getProtocol() { 46 return protocol; 47 } 48 49 @CalledByNative("Init") getNegotiated()50 boolean getNegotiated() { 51 return negotiated; 52 } 53 54 @CalledByNative("Init") getId()55 int getId() { 56 return id; 57 } 58 } 59 60 /** Java version of C++ DataBuffer. The atom of data in a DataChannel. */ 61 public static class Buffer { 62 /** The underlying data. */ 63 public final ByteBuffer data; 64 65 /** 66 * Indicates whether |data| contains UTF-8 text or "binary data" 67 * (i.e. anything else). 68 */ 69 public final boolean binary; 70 71 @CalledByNative("Buffer") Buffer(ByteBuffer data, boolean binary)72 public Buffer(ByteBuffer data, boolean binary) { 73 this.data = data; 74 this.binary = binary; 75 } 76 } 77 78 /** Java version of C++ DataChannelObserver. */ 79 public interface Observer { 80 /** The data channel's bufferedAmount has changed. */ onBufferedAmountChange(long previousAmount)81 @CalledByNative("Observer") public void onBufferedAmountChange(long previousAmount); 82 /** The data channel state has changed. */ onStateChange()83 @CalledByNative("Observer") public void onStateChange(); 84 /** 85 * A data buffer was successfully received. NOTE: |buffer.data| will be 86 * freed once this function returns so callers who want to use the data 87 * asynchronously must make sure to copy it first. 88 */ onMessage(Buffer buffer)89 @CalledByNative("Observer") public void onMessage(Buffer buffer); 90 } 91 92 /** Keep in sync with DataChannelInterface::DataState. */ 93 public enum State { 94 CONNECTING, 95 OPEN, 96 CLOSING, 97 CLOSED; 98 99 @CalledByNative("State") fromNativeIndex(int nativeIndex)100 static State fromNativeIndex(int nativeIndex) { 101 return values()[nativeIndex]; 102 } 103 } 104 105 private long nativeDataChannel; 106 private long nativeObserver; 107 108 @CalledByNative DataChannel(long nativeDataChannel)109 public DataChannel(long nativeDataChannel) { 110 this.nativeDataChannel = nativeDataChannel; 111 } 112 113 /** Register |observer|, replacing any previously-registered observer. */ registerObserver(Observer observer)114 public void registerObserver(Observer observer) { 115 checkDataChannelExists(); 116 if (nativeObserver != 0) { 117 nativeUnregisterObserver(nativeObserver); 118 } 119 nativeObserver = nativeRegisterObserver(observer); 120 } 121 122 /** Unregister the (only) observer. */ unregisterObserver()123 public void unregisterObserver() { 124 checkDataChannelExists(); 125 nativeUnregisterObserver(nativeObserver); 126 } 127 label()128 public String label() { 129 checkDataChannelExists(); 130 return nativeLabel(); 131 } 132 id()133 public int id() { 134 checkDataChannelExists(); 135 return nativeId(); 136 } 137 state()138 public State state() { 139 checkDataChannelExists(); 140 return nativeState(); 141 } 142 143 /** 144 * Return the number of bytes of application data (UTF-8 text and binary data) 145 * that have been queued using SendBuffer but have not yet been transmitted 146 * to the network. 147 */ bufferedAmount()148 public long bufferedAmount() { 149 checkDataChannelExists(); 150 return nativeBufferedAmount(); 151 } 152 153 /** Close the channel. */ close()154 public void close() { 155 checkDataChannelExists(); 156 nativeClose(); 157 } 158 159 /** Send |data| to the remote peer; return success. */ send(Buffer buffer)160 public boolean send(Buffer buffer) { 161 checkDataChannelExists(); 162 // TODO(fischman): this could be cleverer about avoiding copies if the 163 // ByteBuffer is direct and/or is backed by an array. 164 byte[] data = new byte[buffer.data.remaining()]; 165 buffer.data.get(data); 166 return nativeSend(data, buffer.binary); 167 } 168 169 /** Dispose of native resources attached to this channel. */ dispose()170 public void dispose() { 171 checkDataChannelExists(); 172 JniCommon.nativeReleaseRef(nativeDataChannel); 173 nativeDataChannel = 0; 174 } 175 176 @CalledByNative getNativeDataChannel()177 long getNativeDataChannel() { 178 return nativeDataChannel; 179 } 180 checkDataChannelExists()181 private void checkDataChannelExists() { 182 if (nativeDataChannel == 0) { 183 throw new IllegalStateException("DataChannel has been disposed."); 184 } 185 } 186 nativeRegisterObserver(Observer observer)187 private native long nativeRegisterObserver(Observer observer); nativeUnregisterObserver(long observer)188 private native void nativeUnregisterObserver(long observer); nativeLabel()189 private native String nativeLabel(); nativeId()190 private native int nativeId(); nativeState()191 private native State nativeState(); nativeBufferedAmount()192 private native long nativeBufferedAmount(); nativeClose()193 private native void nativeClose(); nativeSend(byte[] data, boolean binary)194 private native boolean nativeSend(byte[] data, boolean binary); 195 }; 196