[Multimedia] Deprecate constructors related to ElmSharp (#4540)
[platform/core/csapi/tizenfx.git] / src / Tizen.Multimedia.Remoting / WebRTC / MediaStreamTrack.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.Diagnostics;
19 using static Interop;
20
21 namespace Tizen.Multimedia.Remoting
22 {
23     /// <summary>
24     /// Provides the ability to control audio/video track.
25     /// </summary>
26     /// <since_tizen> 9 </since_tizen>
27     public sealed class MediaStreamTrack : IDisplayable<WebRTCErrorCode>
28     {
29         private WebRTC _webRtc;
30         private uint _trackId;
31         private Display _display;
32
33         internal MediaStreamTrack(WebRTC webRtc, MediaType type, uint trackId)
34         {
35             _webRtc = webRtc;
36             _trackId = trackId;
37             Type = type;
38         }
39
40         /// <summary>
41         /// Gets the the of media stream track.
42         /// </summary>
43         /// <value><see cref="MediaType"/></value>
44         /// <since_tizen> 9 </since_tizen>
45         public MediaType Type { get; }
46
47         private WebRTCErrorCode SetDisplay(Display display)
48             => display.ApplyTo(this);
49
50         private void ReplaceDisplay(Display newDisplay)
51         {
52             _display?.SetOwner(null);
53             _display = newDisplay;
54             _display?.SetOwner(this);
55         }
56
57         /// <summary>
58         /// Gets or sets the display to show remote video.
59         /// </summary>
60         /// <value>A <see cref="Multimedia.Display"/> that specifies the display.</value>
61         /// <remarks>
62         /// If user set video source with <see cref="TransceiverDirection.SendRecv"/>, <see cref="Display"/> must be set.<br/>
63         /// If not, the received video will fill entire screen.<br/>
64         /// If remote track, <see cref="Display"/> must be set in <see cref="WebRTC.TrackAdded"/> event.<br/>
65         /// The display is created with <see cref="MediaView"/>.
66         /// </remarks>
67         /// <exception cref="ObjectDisposedException">The WebRTC has already been disposed of.</exception>
68         /// <exception cref="ArgumentException">The value has already been assigned to another WebRTC.</exception>
69         /// <exception cref="InvalidOperationException">
70         /// The WebRTC is not called in <see cref="WebRTC.TrackAdded"/> event.
71         /// -or-<br/>
72         /// This MediaStreamTrack is not Video.
73         /// </exception>
74         /// <since_tizen> 9 </since_tizen>
75         public Display Display
76         {
77             get => _display;
78             set
79             {
80                 if (Type != MediaType.Video)
81                 {
82                     throw new InvalidOperationException("This property is only for video.");
83                 }
84
85                 if (value == null)
86                 {
87                     throw new ArgumentNullException(nameof(value), "Display cannot be null.");
88                 }
89
90                 if (value?.Owner != null)
91                 {
92                     if (ReferenceEquals(this, value.Owner))
93                     {
94                         throw new ArgumentException("The display has already been assigned to another.");
95                     }
96                 }
97                 else
98                 {
99                     SetDisplay(value).ThrowIfFailed("Failed to configure display of the MediaStreamTrack");
100                     ReplaceDisplay(value);
101                 }
102             }
103         }
104
105         WebRTCErrorCode IDisplayable<WebRTCErrorCode>.ApplyEvasDisplay(DisplayType type, ElmSharp.EvasObject evasObject)
106         {
107             Debug.Assert(Enum.IsDefined(typeof(DisplayType), type));
108             Debug.Assert(type != DisplayType.None);
109
110             return NativeWebRTC.SetDisplay(_webRtc.Handle, _trackId,
111                 type == DisplayType.Overlay ? WebRTCDisplayType.Overlay : WebRTCDisplayType.Evas, evasObject);
112         }
113
114         WebRTCErrorCode IDisplayable<WebRTCErrorCode>.ApplyEcoreWindow(IntPtr windowHandle)
115         {
116             return NativeWebRTC.SetEcoreDisplay(_webRtc.Handle, _trackId, windowHandle);
117         }
118
119         /// <summary>
120         /// Gets or sets the display mode.
121         /// </summary>
122         /// <remarks>
123         /// This property is meaningful only in overlay or EVAS surface display type.
124         /// </remarks>
125         /// <value>A <see cref="WebRTCDisplayMode"/> that specifies the display mode.</value>
126         /// <exception cref="ArgumentException">Display mode type is incorrect.</exception>
127         /// <exception cref="InvalidOperationException"><see cref="Display"/> is not set.</exception>
128         /// <since_tizen> 9 </since_tizen>
129         public WebRTCDisplayMode DisplayMode
130         {
131             get
132             {
133                 if (Type != MediaType.Video)
134                 {
135                     throw new InvalidOperationException("This property is only for video.");
136                 }
137
138                 NativeWebRTC.GetDisplayMode(_webRtc.Handle, _trackId, out var val).
139                     ThrowIfFailed("Failed to get WebRTC display mode");
140
141                 return val;
142             }
143             set
144             {
145                 if (Type != MediaType.Video)
146                 {
147                     throw new InvalidOperationException("This property is only for video.");
148                 }
149
150                 ValidationUtil.ValidateEnum(typeof(WebRTCDisplayMode), value, nameof(value));
151
152                 NativeWebRTC.SetDisplayMode(_webRtc.Handle, _trackId, value).
153                     ThrowIfFailed("Failed to set WebRTC display mode.");
154             }
155         }
156
157         /// <summary>
158         /// Gets or sets the display visibility.
159         /// </summary>
160         /// <value>true if WebRTC display is visible, otherwise false.</value>
161         /// <remarks>
162         /// This property is meaningful only in overlay or EVAS surface display type.
163         /// </remarks>
164         /// <exception cref="InvalidOperationException"><see cref="Display"/> is not set.</exception>
165         /// <since_tizen> 9 </since_tizen>
166         public bool DisplayVisible
167         {
168             get
169             {
170                 if (Type != MediaType.Video)
171                 {
172                     throw new InvalidOperationException("This property is only for video.");
173                 }
174
175                 NativeWebRTC.GetDisplayVisible(_webRtc.Handle, _trackId, out bool val).
176                     ThrowIfFailed("Failed to get visible status");
177
178                 return val;
179             }
180             set
181             {
182                 if (Type != MediaType.Video)
183                 {
184                     throw new InvalidOperationException("This property is only for video.");
185                 }
186
187                 NativeWebRTC.SetDisplayVisible(_webRtc.Handle, _trackId, value).
188                     ThrowIfFailed("Failed to set display status.");
189             }
190         }
191
192         /// <summary>
193         /// Applies the audio stream policy to remote track.
194         /// </summary>
195         /// <param name="policy">The <see cref="AudioStreamPolicy"/> to apply.</param>
196         /// <remarks>
197         /// This must be called in <see cref="WebRTC.TrackAdded"/> event.<br/>
198         /// <br/>
199         /// <see cref="WebRTC"/> does not support all <see cref="AudioStreamType"/>.<br/>
200         /// Supported types are <see cref="AudioStreamType.Media"/>, <see cref="AudioStreamType.Voip"/>,
201         /// <see cref="AudioStreamType.MediaExternalOnly"/>.
202         /// </remarks>
203         /// <exception cref="ArgumentNullException"><paramref name="policy"/> is null.</exception>
204         /// <exception cref="InvalidOperationException">
205         /// <see cref="WebRTC.AudioFrameEncoded"/> was set.<br/>
206         /// -or-<br/>
207         /// This method was not called in <see cref="WebRTC.TrackAdded"/> event.
208         /// -or-<br/>
209         /// This MediaStreamTrack is not Audio.
210         /// </exception>
211         /// <exception cref="NotSupportedException">
212         ///     <see cref="AudioStreamType"/> of <paramref name="policy"/> is not supported on the current platform.
213         /// </exception>
214         /// <exception cref="ObjectDisposedException">
215         ///     The WebRTC has already been disposed.<br/>
216         ///     -or-<br/>
217         ///     <paramref name="policy"/> has already been disposed.
218         /// </exception>
219         /// <seealso cref="AudioStreamPolicy"/>
220         /// <seealso cref="WebRTC.TrackAdded"/>
221         /// <since_tizen> 9 </since_tizen>
222         public void ApplyAudioStreamPolicy(AudioStreamPolicy policy)
223         {
224             if (policy == null)
225             {
226                 throw new ArgumentNullException(nameof(policy));
227             }
228
229             if (Type != MediaType.Audio)
230             {
231                 throw new InvalidOperationException("Should be applied in Audio");
232             }
233
234             var ret = NativeWebRTC.SetAudioStreamPolicy(_webRtc.Handle, _trackId, policy.Handle);
235
236             if (ret == WebRTCErrorCode.InvalidArgument)
237             {
238                 throw new NotSupportedException("The specified policy is not supported on the current system.");
239             }
240
241             ret.ThrowIfFailed("Failed to set the audio stream policy to the WebRTC");
242         }
243     }
244 }