[Multimedia] Fix VD SVACE issues (#5445)
[platform/core/csapi/tizenfx.git] / src / Tizen.Multimedia.Remoting / WebRTC / WebRTCSignalingServer.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 System.Threading.Tasks;
21 using static Interop;
22
23 namespace Tizen.Multimedia.Remoting
24 {
25     /// <summary>
26     /// Provides the ability to control WebRTCSignalingServer.
27     /// </summary>
28     [EditorBrowsable(EditorBrowsableState.Never)]
29     public class WebRTCSignalingServer : IDisposable
30     {
31         private readonly IntPtr _handle;
32         private bool _disposed;
33
34         /// <summary>
35         /// Initializes a new instance of the <see cref="WebRTCSignalingServer"/> class.
36         /// </summary>
37         /// <param name="port">The server port.</param>
38         [EditorBrowsable(EditorBrowsableState.Never)]
39         public WebRTCSignalingServer(int port)
40         {
41             SignalingServer.Create(port, out _handle).
42                 ThrowIfFailed("Failed to create signaling");
43
44             Debug.Assert(true);
45         }
46
47         /// <summary>
48         /// Starts the signaling server.
49         /// </summary>
50         [EditorBrowsable(EditorBrowsableState.Never)]
51         public void Start()
52         {
53             ValidateNotDisposed();
54
55             SignalingServer.Start(_handle).
56                 ThrowIfFailed("Failed to start signaling server");
57         }
58
59         /// <summary>
60         /// Stops the signaling server.
61         /// </summary>
62         [EditorBrowsable(EditorBrowsableState.Never)]
63         public void Stop()
64         {
65             ValidateNotDisposed();
66
67             SignalingServer.Stop(_handle).
68                 ThrowIfFailed("Failed to stop signaling server");
69         }
70
71         #region dispose support
72         internal bool IsDisposed => _disposed;
73         /// <summary>
74         /// Releases all resources used by the current instance.
75         /// </summary>
76         /// <exception cref="ObjectDisposedException">The WebRTCSignalingServer has already been disposed.</exception>
77         public void Dispose()
78         {
79             Dispose(true);
80             GC.SuppressFinalize((object)this);
81         }
82
83         /// <summary>
84         /// Releases the unmanaged resources used by the <see cref="WebRTCSignalingServer"/>.
85         /// </summary>
86         /// <param name="disposing">
87         /// true to release both managed and unmanaged resources;
88         /// false to release only unmanaged resources.
89         /// </param>
90         [EditorBrowsable(EditorBrowsableState.Never)]
91         protected virtual void Dispose(bool disposing)
92         {
93             if (_disposed || !disposing)
94             {
95                 return;
96             }
97
98             if (_handle != IntPtr.Zero)
99             {
100                 SignalingServer.Destroy(_handle);
101                 _disposed = true;
102             }
103         }
104
105         private void ValidateNotDisposed()
106         {
107             if (_disposed)
108             {
109                 Log.Error(WebRTCLog.Tag, "WebRTCSignalingServer was disposed");
110                 throw new ObjectDisposedException(nameof(WebRTCSignalingServer));
111             }
112         }
113         #endregion dispose support
114     }
115
116
117     /// <summary>
118     /// Provides the ability to control WebRTCSignalingClient.
119     /// </summary>
120     [EditorBrowsable(EditorBrowsableState.Never)]
121     public class WebRTCSignalingClient : IDisposable
122     {
123         private IntPtr _handle;
124         private bool _isConnected;
125         private (string serverIp, int port) _serverInfo;
126         private SignalingClient.SignalingMessageCallback _signalingMessageCallback;
127         private bool _disposed;
128
129         /// <summary>
130         /// Initializes a new instance of the <see cref="WebRTCSignalingClient"/> class.
131         /// </summary>
132         /// <param name="serverIp">The server IP.</param>
133         /// <param name="port">The server port.</param>
134         /// <seealso cref="Connect"/>
135         [EditorBrowsable(EditorBrowsableState.Never)]
136         public WebRTCSignalingClient(string serverIp, int port)
137         {
138             ValidationUtil.ValidateIsNullOrEmpty(serverIp, nameof(serverIp));
139
140             if (port < 0)
141             {
142                 throw new ArgumentException("port should be greater than zero.");
143             }
144
145             _serverInfo.serverIp = serverIp;
146             _serverInfo.port = port;
147         }
148
149         /// <summary>
150         /// Occurs when a message to be handled is sent from the remote peer or the signaling server.
151         /// </summary>
152         [EditorBrowsable(EditorBrowsableState.Never)]
153         public event EventHandler<WebRTCSignalingEventArgs> SignalingMessage;
154
155         /// <summary>
156         /// Connect to signaling server and return client id.
157         /// </summary>
158         /// <returns>The signaling client ID.</returns>
159         /// <exception cref="ObjectDisposedException">The WebRTCSignalingClient has already been disposed.</exception>
160         [EditorBrowsable(EditorBrowsableState.Never)]
161         public async Task<int> Connect()
162         {
163             ValidateNotDisposed();
164
165             var tcsConnected = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
166
167             _signalingMessageCallback = (type, message, _) =>
168             {
169                 Log.Info(WebRTCLog.Tag, $"type:{type}, message:{message}");
170
171                 if (!_isConnected && type == SignalingMessageType.Connected)
172                 {
173                     _isConnected = true;
174
175                     SignalingClient.GetID(_handle, out int id).ThrowIfFailed("Failed to get signaling client ID");
176                     Log.Info(WebRTCLog.Tag, $"Client ID[{id}]");
177
178                     tcsConnected.TrySetResult(id);
179                 }
180
181                 SignalingMessage?.Invoke(this, new WebRTCSignalingEventArgs(type, message));
182             };
183
184             SignalingClient.Connect(_serverInfo.serverIp, _serverInfo.port, _signalingMessageCallback, IntPtr.Zero, out _handle).
185                 ThrowIfFailed("Failed to connect to server");
186
187             return await tcsConnected.Task;
188         }
189
190         /// <summary>
191         /// Requests session with peer ID.
192         /// </summary>
193         /// <param name="peerId">The ID of remote peer.</param>
194         /// <exception cref="ObjectDisposedException">The WebRTCSignalingClient has already been disposed.</exception>
195         /// <see cref="SignalingMessageType.SessionEstablished"/>
196         [EditorBrowsable(EditorBrowsableState.Never)]
197         public void RequestSession(int peerId)
198         {
199             ValidateNotDisposed();
200
201             SignalingClient.RequestSession(_handle, peerId).
202                 ThrowIfFailed("Failed to request session to peer");
203         }
204
205         /// <summary>
206         /// Sends the signaling message to remote peer.
207         /// </summary>
208         /// <param name="message"></param>
209         /// <exception cref="ObjectDisposedException">The WebRTCSignalingClient has already been disposed.</exception>
210         [EditorBrowsable(EditorBrowsableState.Never)]
211         public void SendMessage(string message)
212         {
213             ValidateNotDisposed();
214
215             SignalingClient.SendMessage(_handle, message).
216                 ThrowIfFailed("Failed to send message to peer");
217         }
218
219         #region dispose support
220         internal bool IsDisposed => _disposed;
221         /// <summary>
222         /// Releases all resources used by the current instance.
223         /// </summary>
224         /// <exception cref="ObjectDisposedException">The WebRTCSignalingClient has already been disposed.</exception>
225         public void Dispose()
226         {
227             Dispose(true);
228             GC.SuppressFinalize((object)this);
229         }
230
231         /// <summary>
232         /// Releases the unmanaged resources used by the <see cref="WebRTCSignalingClient"/>.
233         /// </summary>
234         /// <param name="disposing">
235         /// true to release both managed and unmanaged resources;
236         /// false to release only unmanaged resources.
237         /// </param>
238         [EditorBrowsable(EditorBrowsableState.Never)]
239         protected virtual void Dispose(bool disposing)
240         {
241             if (_disposed || !disposing)
242             {
243                 return;
244             }
245
246             if (_handle != IntPtr.Zero)
247             {
248                 SignalingClient.Disconnect(_handle);
249
250                 _isConnected = false;
251                 _disposed = true;
252             }
253         }
254
255         private void ValidateNotDisposed()
256         {
257             if (_disposed)
258             {
259                 Log.Error(WebRTCLog.Tag, "WebRTCSignalingClient was disposed");
260                 throw new ObjectDisposedException(nameof(WebRTCSignalingClient));
261             }
262         }
263         #endregion dispose support
264     }
265 }