[WebRTC] Add initial code (#2977)
[platform/core/csapi/tizenfx.git] / src / Tizen.Multimedia.Remoting / WebRTC / WebRTCDataChannel.cs
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 using System;
18 using System.ComponentModel;
19 using System.Diagnostics;
20 using Tizen.Applications;
21 using static Interop;
22
23 namespace Tizen.Multimedia.Remoting
24 {
25     /// <summary>
26     /// Provides the ability to control WebRTC data channel.
27     /// </summary>
28     /// <since_tizen> 9 </since_tizen>
29     public partial class WebRTCDataChannel : IDisposable
30     {
31         private readonly IntPtr _handle;
32
33         /// <summary>
34         /// Initializes a new instance of the <see cref="WebRTCDataChannel"/> class.
35         /// </summary>
36         /// <param name="webRtc">The owner of this WebRTCDataChannel.</param>
37         /// <param name="label">The name of this data channel.</param>
38         /// <exception cref="ArgumentNullException">The webRtc or label is null.</exception>
39         /// <since_tizen> 9 </since_tizen>
40         public WebRTCDataChannel(WebRTC webRtc, string label)
41             : this(webRtc, label, null)
42         {
43         }
44
45         /// <summary>
46         /// Initializes a new instance of the <see cref="WebRTCDataChannel"/> class.
47         /// </summary>
48         /// <remarks>
49         /// The bundle is similar format as the RTCDataChannelInit members outlined https://www.w3.org/TR/webrtc/#dom-rtcdatachannelinit.<br/>
50         /// The following attributes can be set to options by using <see cref="Bundle"/> API:<br/>
51         /// 'ordered' of type bool            : Whether the channel will send data with guaranteed ordering. The default value is true.<br/>
52         /// 'max-packet-lifetime' of type int : The time in milliseconds to attempt transmitting unacknowledged data. -1 for unset. The default value is -1.<br/>
53         /// 'max-retransmits' of type int     : The number of times data will be attempted to be transmitted without acknowledgement before dropping. The default value is -1.<br/>
54         /// 'protocol' of type string         : The subprotocol used by this channel. The default value is NULL.<br/>
55         /// 'id' of type int                  : Override the default identifier selection of this channel. The default value is -1.<br/>
56         /// 'priority' of type int            : The priority to use for this channel(1:very low, 2:low, 3:medium, 4:high). The default value is 2.<br/>
57         /// </remarks>
58         /// <param name="webRtc">The owner of this WebRTCDataChannel.</param>
59         /// <param name="label">The name of this data channel.</param>
60         /// <param name="bundle">The data channel option.</param>
61         /// <exception cref="ArgumentNullException">The webRtc or label is null.</exception>
62         /// <since_tizen> 9 </since_tizen>
63         public WebRTCDataChannel(WebRTC webRtc, string label, Bundle bundle)
64         {
65             if (webRtc == null)
66             {
67                 throw new ArgumentNullException(nameof(webRtc), "WebRTC is not created successfully.");
68             }
69
70             if (string.IsNullOrEmpty(label))
71             {
72                 throw new ArgumentNullException(nameof(label), "label is null.");
73             }
74
75             var bundle_ = bundle?.SafeBundleHandle ?? new SafeBundleHandle();
76             NativeDataChannel.Create(webRtc.Handle, label, bundle_, out _handle).
77                 ThrowIfFailed("Failed to create webrtc data channel");
78
79             Debug.Assert(_handle != null);
80
81             Label = label;
82
83             RegisterEvents();
84         }
85
86         internal WebRTCDataChannel(IntPtr dataChannelHandle)
87         {
88             if (dataChannelHandle == IntPtr.Zero)
89             {
90                 throw new ArgumentNullException(nameof(dataChannelHandle),
91                     "WebRTC is not created successfully in native");
92             }
93
94             _handle = dataChannelHandle;
95
96             NativeDataChannel.GetLabel(_handle, out string label).
97                 ThrowIfFailed("Failed to get label");
98
99             Label = label;
100
101             Log.Info(WebRTCLog.Tag, "Register event");
102             RegisterEvents();
103         }
104
105         private IntPtr Handle
106         {
107             get
108             {
109                 ValidateNotDisposed();
110                 return _handle;
111             }
112         }
113
114         /// <summary>
115         /// Gets the label of this data channel.
116         /// </summary>
117         /// <value>The label.</value>
118         /// <since_tizen> 9 </since_tizen>
119         public string Label { get; }
120
121         /// <summary>
122         /// Sends a string data across the data channel to the remote peer.
123         /// </summary>
124         /// <param name="data">The string data to send</param>
125         /// <since_tizen> 9 </since_tizen>
126         public void Send(string data)
127         {
128             ValidateNotDisposed();
129
130             NativeDataChannel.SendString(Handle, data).
131                 ThrowIfFailed("Failed to send string data");
132         }
133
134         /// <summary>
135         /// Sends byte data across the data channel to the remote peer.
136         /// </summary>
137         /// <param name="data">The byte data to send</param>
138         /// <since_tizen> 9 </since_tizen>
139         public void Send(byte[] data)
140         {
141             ValidateNotDisposed();
142
143             if (data == null)
144             {
145                 throw new ArgumentNullException(nameof(data), "data is null");
146             }
147
148             NativeDataChannel.SendBytes(Handle, data, (uint)data.Length).
149                 ThrowIfFailed("Failed to send bytes data");
150         }
151
152         #region Dispose support
153         private bool _disposed;
154
155         /// <summary>
156         /// Releases all resources used by the current instance.
157         /// </summary>
158         /// <exception cref="ObjectDisposedException">The WebRTC has already been disposed.</exception>
159         /// <since_tizen> 9 </since_tizen>
160         public void Dispose()
161         {
162             Dispose(true);
163             GC.SuppressFinalize(this);
164         }
165
166         /// <summary>
167         /// Releases the unmanaged resources used by the <see cref="WebRTCDataChannel"/>.
168         /// </summary>
169         /// <param name="disposing">
170         /// true to release both managed and unmanaged resources;
171         /// false to release only unmanaged resources.
172         /// </param>
173         [EditorBrowsable(EditorBrowsableState.Never)]
174         protected virtual void Dispose(bool disposing)
175         {
176             if (_disposed || !disposing)
177             {
178                 return;
179             }
180
181             if (true)
182             {
183                 NativeDataChannel.Destroy(_handle);
184                 _disposed = true;
185             }
186         }
187
188         private void ValidateNotDisposed()
189         {
190             if (_disposed)
191             {
192                 Log.Warn(WebRTCLog.Tag, "WebRTCDataChannel was disposed");
193                 throw new ObjectDisposedException(nameof(WebRTCDataChannel));
194             }
195         }
196         #endregion Dispose support
197     }
198 }