Setting since_tizen 3/4 on Tizen.NET API
[platform/core/csapi/tizenfx.git] / src / Tizen.Multimedia.Remoting / MediaController / MediaController.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
17 using System;
18 using System.Diagnostics;
19 using Native = Interop.MediaControllerClient;
20
21 namespace Tizen.Multimedia.Remoting
22 {
23     /// <summary>
24     /// Provides a means to to send commands to and handle events from media control server.
25     /// </summary>
26     /// <since_tizen> 4 </since_tizen>
27     public class MediaController
28     {
29         internal MediaController(MediaControllerManager manager, string serverAppId)
30         {
31             Debug.Assert(manager != null);
32             Debug.Assert(serverAppId != null);
33
34             Manager = manager;
35             ServerAppId = serverAppId;
36         }
37
38         private MediaControllerManager Manager { get; }
39
40         /// <summary>
41         /// Gets the application id of the server.
42         /// </summary>
43         /// <value>The server application id.</value>
44         /// <since_tizen> 4 </since_tizen>
45         public string ServerAppId { get; }
46
47         /// <summary>
48         /// Gets a value indicating whether the sever has been stopped.
49         /// </summary>
50         /// <value>true if the server has been stopped; otherwise, false.</value>
51         /// <since_tizen> 4 </since_tizen>
52         public bool IsStopped
53         {
54             get;
55             private set;
56         }
57
58         private void ThrowIfStopped()
59         {
60             if (IsStopped)
61             {
62                 throw new InvalidOperationException("The server has already been stopped.");
63             }
64         }
65
66         /// <summary>
67         /// Occurs when the server is stopped.
68         /// </summary>
69         /// <since_tizen> 4 </since_tizen>
70         public event EventHandler ServerStopped;
71
72         internal void RaiseStoppedEvent()
73         {
74             IsStopped = true;
75             ServerStopped?.Invoke(this, EventArgs.Empty);
76         }
77
78         /// <summary>
79         /// Occurs when the playback state is updated.
80         /// </summary>
81         /// <since_tizen> 4 </since_tizen>
82         public event EventHandler<PlaybackStateUpdatedEventArgs> PlaybackStateUpdated;
83
84         private PlaybackStateUpdatedEventArgs CreatePlaybackUpdatedEventArgs(IntPtr playbackHandle)
85         {
86             try
87             {
88                 Native.GetPlaybackState(playbackHandle, out var playbackCode).ThrowIfError("Failed to get state.");
89
90                 Native.GetPlaybackPosition(playbackHandle, out var position).ThrowIfError("Failed to get position.");
91
92                 return new PlaybackStateUpdatedEventArgs(playbackCode.ToState(), (long)position);
93             }
94             catch (Exception e)
95             {
96                 Log.Error(GetType().FullName, e.ToString());
97             }
98             return null;
99         }
100
101         internal void RaisePlaybackUpdatedEvent(IntPtr playbackHandle)
102         {
103             var eventHandler = PlaybackStateUpdated;
104
105             if (eventHandler == null)
106             {
107                 return;
108             }
109
110             var args = CreatePlaybackUpdatedEventArgs(playbackHandle);
111
112             if (args != null)
113             {
114                 eventHandler.Invoke(this, args);
115             }
116         }
117
118         /// <summary>
119         /// Occurs when the metadata is updated.
120         /// </summary>
121         /// <since_tizen> 4 </since_tizen>
122         public event EventHandler<MetadataUpdatedEventArgs> MetadataUpdated;
123
124         private MetadataUpdatedEventArgs CreateMetadataUpdatedEventArgs(IntPtr metadataHandle)
125         {
126             try
127             {
128                 return new MetadataUpdatedEventArgs(new MediaControlMetadata(metadataHandle));
129             }
130             catch (Exception e)
131             {
132                 Log.Error(GetType().FullName, e.ToString());
133             }
134             return null;
135         }
136
137         internal void RaiseMetadataUpdatedEvent(IntPtr metadataHandle)
138         {
139             var eventHandler = MetadataUpdated;
140
141             if (eventHandler == null)
142             {
143                 return;
144             }
145
146             var args = CreateMetadataUpdatedEventArgs(metadataHandle);
147
148             if (args != null)
149             {
150                 eventHandler.Invoke(this, args);
151             }
152         }
153
154         /// <summary>
155         /// Occurs when the shuffle mode is updated.
156         /// </summary>
157         /// <since_tizen> 4 </since_tizen>
158         public event EventHandler<ShuffleModeUpdatedEventArgs> ShuffleModeUpdated;
159
160         internal void RaiseShuffleModeUpdatedEvent(MediaControllerShuffleMode mode)
161         {
162             ShuffleModeUpdated?.Invoke(this, new ShuffleModeUpdatedEventArgs(mode == MediaControllerShuffleMode.On));
163         }
164
165         /// <summary>
166         /// Occurs when the repeat mode is updated.
167         /// </summary>
168         /// <since_tizen> 4 </since_tizen>
169         public event EventHandler<RepeatModeUpdatedEventArgs> RepeatModeUpdated;
170
171         internal void RaiseRepeatModeUpdatedEvent(MediaControlRepeatMode mode)
172         {
173             RepeatModeUpdated?.Invoke(this, new RepeatModeUpdatedEventArgs(mode));
174         }
175
176         /// <summary>
177         /// Returns the playback state set by the server.
178         /// </summary>
179         /// <returns>The playback state.</returns>
180         /// <exception cref="InvalidOperationException">
181         ///     The server has already been stopped.<br/>
182         ///     -or-<br/>
183         ///     An internal error occurs.
184         /// </exception>
185         /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed of.</exception>
186         /// <seealso cref="MediaControlServer.SetPlaybackState(MediaControlPlaybackState, long)"/>
187         /// <since_tizen> 4 </since_tizen>
188         public MediaControlPlaybackState GetPlaybackState()
189         {
190             ThrowIfStopped();
191
192             IntPtr playbackHandle = IntPtr.Zero;
193
194             try
195             {
196                 Native.GetServerPlayback(Manager.Handle, ServerAppId, out playbackHandle).ThrowIfError("Failed to get playback.");
197
198                 Native.GetPlaybackState(playbackHandle, out var playbackCode).ThrowIfError("Failed to get state.");
199
200                 return playbackCode.ToState();
201             }
202             finally
203             {
204                 if (playbackHandle != IntPtr.Zero)
205                 {
206                     Native.DestroyPlayback(playbackHandle);
207                 }
208             }
209         }
210
211         /// <summary>
212         /// Returns the playback position set by the server.
213         /// </summary>
214         /// <returns>The playback position in milliseconds.</returns>
215         /// <exception cref="InvalidOperationException">
216         ///     The server has already been stopped.<br/>
217         ///     -or-<br/>
218         ///     An internal error occurs.
219         /// </exception>
220         /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed of.</exception>
221         /// <seealso cref="MediaControlServer.SetPlaybackState(MediaControlPlaybackState, long)"/>
222         /// <since_tizen> 4 </since_tizen>
223         public long GetPlaybackPosition()
224         {
225             ThrowIfStopped();
226
227             IntPtr playbackHandle = IntPtr.Zero;
228
229             try
230             {
231                 Native.GetServerPlayback(Manager.Handle, ServerAppId, out playbackHandle).ThrowIfError("Failed to get playback.");
232
233                 Native.GetPlaybackPosition(playbackHandle, out var position).ThrowIfError("Failed to get position.");
234
235                 return (long)position;
236             }
237             finally
238             {
239                 if (playbackHandle != IntPtr.Zero)
240                 {
241                     Native.DestroyPlayback(playbackHandle);
242                 }
243             }
244         }
245
246         /// <summary>
247         /// Returns the metadata set by the server.
248         /// </summary>
249         /// <returns>The metadata.</returns>
250         /// <exception cref="InvalidOperationException">
251         ///     The server has already been stopped.<br/>
252         ///     -or-<br/>
253         ///     An internal error occurs.
254         /// </exception>
255         /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed of.</exception>
256         /// <seealso cref="MediaControlServer.SetMetadata(MediaControlMetadata)"/>
257         /// <since_tizen> 4 </since_tizen>
258         public MediaControlMetadata GetMetadata()
259         {
260             ThrowIfStopped();
261
262             IntPtr metadataHandle = IntPtr.Zero;
263
264             try
265             {
266                 Native.GetServerMetadata(Manager.Handle, ServerAppId, out metadataHandle).
267                     ThrowIfError("Failed to get metadata.");
268
269                 return new MediaControlMetadata(metadataHandle);
270             }
271             finally
272             {
273                 if (metadataHandle != IntPtr.Zero)
274                 {
275                     Native.DestroyMetadata(metadataHandle);
276                 }
277             }
278         }
279
280         /// <summary>
281         /// Returns whether the shuffle mode is enabled.
282         /// </summary>
283         /// <returns>A value indicating whether the shuffle mode is enabled.</returns>
284         /// <exception cref="InvalidOperationException">
285         ///     The server has already been stopped.<br/>
286         ///     -or-<br/>
287         ///     An internal error occurs.
288         /// </exception>
289         /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed of.</exception>
290         /// <seealso cref="MediaControlServer.SetShuffleModeEnabled(bool)"/>
291         /// <since_tizen> 4 </since_tizen>
292         public bool IsShuffleModeEnabled()
293         {
294             ThrowIfStopped();
295
296             Native.GetServerShuffleMode(Manager.Handle, ServerAppId, out var shuffleMode).
297                 ThrowIfError("Failed to get shuffle mode state.");
298
299             return shuffleMode == MediaControllerShuffleMode.On;
300         }
301
302         /// <summary>
303         /// Returns the repeat mode.
304         /// </summary>
305         /// <returns>A <see cref="MediaControlRepeatMode"/> set by the server.</returns>
306         /// <exception cref="InvalidOperationException">
307         ///     The server has already been stopped.<br/>
308         ///     -or-<br/>
309         ///     An internal error occurs.
310         /// </exception>
311         /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed of.</exception>
312         /// <seealso cref="MediaControlServer.SetRepeatMode(MediaControlRepeatMode)"/>
313         /// <since_tizen> 4 </since_tizen>
314         public MediaControlRepeatMode GetRepeatMode()
315         {
316             ThrowIfStopped();
317
318             Native.GetServerRepeatMode(Manager.Handle, ServerAppId, out var repeatMode).
319                 ThrowIfError("Failed to get repeat mode state.");
320
321             return repeatMode.ToPublic();
322         }
323
324         /// <summary>
325         /// Sends playback command to the server.</summary>
326         /// <param name="command">A playback command.</param>
327         /// <exception cref="InvalidOperationException">
328         ///     The server has already been stopped.<br/>
329         ///     -or-<br/>
330         ///     An internal error occurs.
331         /// </exception>
332         /// <exception cref="ArgumentException"><paramref name="command"/> is not valid.</exception>
333         /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed of.</exception>
334         /// <seealso cref="MediaControlServer.PlaybackCommandReceived"/>
335         /// <since_tizen> 4 </since_tizen>
336         public void SendPlaybackCommand(MediaControlPlaybackCommand command)
337         {
338             ThrowIfStopped();
339
340             ValidationUtil.ValidateEnum(typeof(MediaControlPlaybackCommand), command, nameof(command));
341
342             Native.SendPlaybackStateCommand(Manager.Handle, ServerAppId, command.ToCode()).
343                 ThrowIfError("Failed to send command.");
344         }
345     }
346 }