Merge "[Contacts]fix Validator issues"
[platform/core/csapi/tizenfx.git] / src / Tizen.Multimedia.MediaPlayer / Player / Player.Properties.cs
1 /*
2  * Copyright (c) 2016 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 using System;
17 using System.Threading.Tasks;
18 using System.Runtime.InteropServices;
19 using System.Diagnostics;
20 using System.IO;
21 using System.Threading;
22 using static Interop;
23
24 namespace Tizen.Multimedia
25 {
26     public partial class Player
27     {
28         private void RetrieveProperties()
29         {
30             NativePlayer.GetAudioLatencyMode(Handle, out _audioLatencyMode).
31                 ThrowIfFailed("Failed to initialize the player");
32
33             NativePlayer.IsLooping(Handle, out _isLooping).ThrowIfFailed("Failed to initialize the player");
34         }
35
36         /// <summary>
37         /// Gets the native handle of the player.
38         /// </summary>
39         /// <value>An IntPtr that contains the native handle of the player.</value>
40         /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
41         public IntPtr Handle
42         {
43             get
44             {
45                 ValidateNotDisposed();
46                 return _handle.DangerousGetHandle();
47             }
48         }
49
50         #region Network configuration
51         private string _cookie = "";
52         private string _userAgent = "";
53
54         /// <summary>
55         /// Gets or Sets the cookie for streaming playback.
56         /// </summary>
57         /// <remarks>To set, the player must be in the <see cref="PlayerState.Idle"/> state.</remarks>
58         /// <exception cref="InvalidOperationException">The player is not in the valid state.</exception>
59         /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
60         /// <exception cref="ArgumentNullException">The value to set is null.</exception>
61         public string Cookie
62         {
63             get
64             {
65                 Log.Info(PlayerLog.Tag, "get cookie : " + _cookie);
66                 return _cookie;
67             }
68             set
69             {
70                 ValidatePlayerState(PlayerState.Idle);
71
72                 if (value == null)
73                 {
74                     throw new ArgumentNullException(nameof(value), "Cookie can't be null.");
75                 }
76
77                 NativePlayer.SetStreamingCookie(Handle, value, value.Length).
78                     ThrowIfFailed("Failed to set the cookie to the player");
79
80                 _cookie = value;
81             }
82         }
83
84         /// <summary>
85         /// Gets or Sets the user agent for streaming playback.
86         /// </summary>
87         /// <remarks>To set, the player must be in the <see cref="PlayerState.Idle"/> state.</remarks>
88         /// <exception cref="InvalidOperationException">The player is not in the valid state.</exception>
89         /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
90         /// <exception cref="ArgumentNullException">The value to set is null.</exception>
91         public string UserAgent
92         {
93             get
94             {
95                 Log.Info(PlayerLog.Tag, "get useragent : " + _userAgent);
96                 return _userAgent;
97             }
98             set
99             {
100                 ValidatePlayerState(PlayerState.Idle);
101
102                 if (value == null)
103                 {
104                     throw new ArgumentNullException(nameof(value), "UserAgent can't be null.");
105                 }
106
107                 NativePlayer.SetStreamingUserAgent(Handle, value, value.Length).
108                     ThrowIfFailed("Failed to set the user agent to the player");
109
110                 _userAgent = value;
111             }
112         }
113         #endregion
114
115         /// <summary>
116         /// Gets the state of the player.
117         /// </summary>
118         /// <value>The current state of the player.</value>
119         /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
120         public PlayerState State
121         {
122             get
123             {
124                 ValidateNotDisposed();
125
126                 if (IsPreparing())
127                 {
128                     return PlayerState.Preparing;
129                 }
130
131                 NativePlayer.GetState(Handle, out var state).ThrowIfFailed("Failed to retrieve the state of the player");
132
133                 Debug.Assert(Enum.IsDefined(typeof(PlayerState), state));
134
135                 return (PlayerState)state;
136             }
137         }
138
139         private AudioLatencyMode _audioLatencyMode;
140
141         /// <summary>
142         /// Gets or sets the audio latency mode.
143         /// </summary>
144         /// <value>A <see cref="AudioLatencyMode"/> that specifies the mode. The default is <see cref="AudioLatencyMode.Mid"/>.</value>
145         /// <remarks>
146         /// If the mode is <see cref="AudioLatencyMode.High"/>,
147         /// audio output interval can be increased so, it can keep more audio data to play.
148         /// But, state transition like pause or resume can be more slower than default(<see cref="AudioLatencyMode.Mid"/>).
149         /// </remarks>
150         /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
151         /// <exception cref="ArgumentException">The value is not valid.</exception>
152         public AudioLatencyMode AudioLatencyMode
153         {
154             get
155             {
156                 Log.Info(PlayerLog.Tag, "get audio latency mode : " + _audioLatencyMode);
157                 return _audioLatencyMode;
158             }
159             set
160             {
161                 ValidateNotDisposed();
162
163                 if (_audioLatencyMode == value)
164                 {
165                     return;
166                 }
167                 ValidationUtil.ValidateEnum(typeof(AudioLatencyMode), value);
168
169                 NativePlayer.SetAudioLatencyMode(Handle, value).
170                     ThrowIfFailed("Failed to set the audio latency mode of the player");
171
172                 _audioLatencyMode = value;
173             }
174         }
175
176         private bool _isLooping;
177
178         /// <summary>
179         /// Gets or sets the looping state.
180         /// </summary>
181         /// <value>true if the playback is looping; otherwise, false. The default value is false.</value>
182         /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
183         public bool IsLooping
184         {
185             get
186             {
187                 Log.Info(PlayerLog.Tag, "get looping : " + _isLooping);
188                 return _isLooping;
189             }
190             set
191             {
192                 ValidateNotDisposed();
193
194                 if (_isLooping == value)
195                 {
196                     return;
197                 }
198
199                 NativePlayer.SetLooping(Handle, value).ThrowIfFailed("Failed to set the looping state of the player");
200
201                 _isLooping = value;
202             }
203         }
204
205         #region Display methods
206         /// <summary>
207         /// Gets the display settings.
208         /// </summary>
209         /// <value>A <see cref="PlayerDisplaySettings"/> that specifies the display settings.</value>
210         public PlayerDisplaySettings DisplaySettings { get; }
211
212         private Display _display;
213
214         private PlayerErrorCode SetDisplay(Display display)
215         {
216             if (display == null)
217             {
218                 Log.Info(PlayerLog.Tag, "set display to none");
219                 return NativePlayer.SetDisplay(Handle, DisplayType.None, IntPtr.Zero);
220             }
221
222             return display.ApplyTo(this);
223         }
224
225         private void ReplaceDisplay(Display newDisplay)
226         {
227             _display?.SetOwner(null);
228             _display = newDisplay;
229             _display?.SetOwner(this);
230         }
231
232         /// <summary>
233         /// Gets or sets the display.
234         /// </summary>
235         /// <value>A <see cref="Multimedia.Display"/> that specifies the display.</value>
236         /// <remarks>The player must be in the <see cref="PlayerState.Idle"/> state.</remarks>
237         /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
238         /// <exception cref="ArgumentException">The value has already been assigned to another player.</exception>
239         /// <exception cref="InvalidOperationException">The player is not in the valid state.</exception>
240         public Display Display
241         {
242             get
243             {
244                 return _display;
245             }
246             set
247             {
248                 ValidatePlayerState(PlayerState.Idle);
249
250                 if (value?.Owner != null)
251                 {
252                     if (ReferenceEquals(this, value.Owner))
253                     {
254                         return;
255                     }
256
257                     throw new ArgumentException("The display has already been assigned to another.");
258                 }
259                 SetDisplay(value).ThrowIfFailed("Failed to set the display to the player");
260
261                 ReplaceDisplay(value);
262             }
263         }
264
265         PlayerErrorCode IDisplayable<PlayerErrorCode>.ApplyEvasDisplay(DisplayType type, ElmSharp.EvasObject evasObject)
266         {
267             Debug.Assert(IsDisposed == false);
268
269             Debug.Assert(Enum.IsDefined(typeof(DisplayType), type));
270
271             return NativePlayer.SetDisplay(Handle, type, evasObject);
272         }
273         #endregion
274
275         private PlayerTrackInfo _audioTrack;
276
277         /// <summary>
278         /// Gets the track info for audio.
279         /// </summary>
280         /// <value>A <see cref="PlayerTrackInfo"/> for audio.</value>
281         public PlayerTrackInfo AudioTrackInfo
282         {
283             get
284             {
285                 if (_audioTrack == null)
286                 {
287                     _audioTrack = new PlayerTrackInfo(this, StreamType.Audio);
288                 }
289                 return _audioTrack;
290             }
291         }
292
293         private PlayerTrackInfo _subtitleTrackInfo;
294
295         /// <summary>
296         /// Gets the track info for subtitle.
297         /// </summary>
298         /// <value>A <see cref="PlayerTrackInfo"/> for subtitle.</value>
299         public PlayerTrackInfo SubtitleTrackInfo
300         {
301             get
302             {
303                 if (_subtitleTrackInfo == null)
304                 {
305                     _subtitleTrackInfo = new PlayerTrackInfo(this, StreamType.Text);
306                 }
307                 return _subtitleTrackInfo;
308             }
309         }
310
311         private StreamInfo _streamInfo;
312
313         /// <summary>
314         /// Gets the stream information.
315         /// </summary>
316         /// <value>A <see cref="StreamInfo"/> for this player.</value>
317         public StreamInfo StreamInfo
318         {
319             get
320             {
321                 if (_streamInfo == null)
322                 {
323                     _streamInfo = new StreamInfo(this);
324                 }
325                 return _streamInfo;
326             }
327         }
328
329         private readonly AudioEffect _audioEffect;
330
331         /// <summary>
332         /// Gets the audio effect.
333         /// </summary>
334         /// <feature>http://tizen.org/feature/multimedia.custom_audio_effect</feature>
335         /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
336         public AudioEffect AudioEffect
337         {
338             get
339             {
340                 if (_audioEffect == null)
341                 {
342                     throw new NotSupportedException($"The feature({Features.AudioEffect}) is not supported.");
343                 }
344
345                 return _audioEffect;
346             }
347         }
348
349         /// <summary>
350         /// Gets or sets the mute state.
351         /// </summary>
352         /// <value>true if the player is muted; otherwise, false.</value>
353         /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
354         public bool Muted
355         {
356             get
357             {
358                 bool value = false;
359                 NativePlayer.IsMuted(Handle, out value).ThrowIfFailed("Failed to get the mute state of the player");
360
361                 Log.Info(PlayerLog.Tag, "get mute : " + value);
362
363                 return value;
364             }
365             set
366             {
367                 NativePlayer.SetMute(Handle, value).ThrowIfFailed("Failed to set the mute state of the player");
368             }
369         }
370
371         /// <summary>
372         /// Gets or sets the current volume.
373         /// </summary>
374         /// <remarks>Valid volume range is from 0 to 1.0, inclusive.</remarks>
375         /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
376         /// <exception cref="ArgumentOutOfRangeException">
377         ///     <paramref name="value"/> is less than zero.\n
378         ///     -or-\n
379         ///     <paramref name="value"/> is greater than 1.0.
380         /// </exception>
381         public float Volume
382         {
383             get
384             {
385                 float value = 0.0F;
386                 NativePlayer.GetVolume(Handle, out value, out value).
387                     ThrowIfFailed("Failed to get the volume of the player");
388                 return value;
389             }
390             set
391             {
392                 if (value < 0F || 1.0F < value)
393                 {
394                     throw new ArgumentOutOfRangeException(nameof(value), value,
395                         $"Valid volume range is 0 <= value <= 1.0, but got { value }.");
396                 }
397
398                 NativePlayer.SetVolume(Handle, value, value).
399                     ThrowIfFailed("Failed to set the volume of the player");
400             }
401         }
402     }
403 }