2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 using System.Collections.Generic;
19 using Tizen.Applications;
20 using Native = Interop.MediaControllerServer;
22 namespace Tizen.Multimedia.Remoting
25 /// Provides a means to set playback information and metadata and receive commands from clients.
27 /// <seealso cref="MediaControllerManager"/>
28 /// <seealso cref="MediaController"/>
29 /// <since_tizen> 4 </since_tizen>
30 public static partial class MediaControlServer
32 private static IntPtr _handle = IntPtr.Zero;
33 private static bool? _isRunning;
36 /// Gets a value indicating whether the server is running.
38 /// <value>true if the server has started; otherwise, false.</value>
39 /// <seealso cref="Start"/>
40 /// <seealso cref="Stop"/>
41 /// <since_tizen> 4 </since_tizen>
42 public static bool IsRunning
46 if (_isRunning.HasValue == false)
48 _isRunning = GetRunningState();
51 return _isRunning.Value;
55 private static bool GetRunningState()
57 IntPtr handle = IntPtr.Zero;
60 Native.ConnectDb(out handle).ThrowIfError("Failed to retrieve the running state.");
62 Native.CheckServerExist(handle, Applications.Application.Current.ApplicationInfo.ApplicationId,
63 out var value).ThrowIfError("Failed to retrieve the running state.");
69 if (handle != IntPtr.Zero)
71 Native.DisconnectDb(handle);
76 private static void EnsureInitializedIfRunning()
78 if (_handle != IntPtr.Zero)
83 if (IsRunning == false)
85 throw new InvalidOperationException("The server is not running.");
91 private static IntPtr Handle
95 EnsureInitializedIfRunning();
101 private static void Initialize()
103 Native.Create(out _handle).ThrowIfError("Failed to create media controller server.");
107 RegisterPlaybackCommandReceivedEvent();
108 RegisterPlaybackActionCommandReceivedEvent();
109 RegisterPlaybackPositionCommandReceivedEvent();
110 RegisterPlaylistCommandReceivedEvent();
111 RegisterShuffleModeCommandReceivedEvent();
112 RegisterRepeatModeCommandReceivedEvent();
113 RegisterCustomCommandReceivedEvent();
119 Native.Destroy(_handle);
120 _playbackCommandCallback = null;
121 _handle = IntPtr.Zero;
127 /// Starts the media control server.
130 /// When the server starts, <see cref="MediaControllerManager.ServerStarted"/> will be raised.
132 /// <privilege>http://tizen.org/privilege/mediacontroller.server</privilege>
133 /// <exception cref="InvalidOperationException">An internal error occurs.</exception>
134 /// <exception cref="UnauthorizedAccessException">Caller does not have required privilege.</exception>
135 /// <seealso cref="MediaControllerManager.ServerStarted"/>
136 /// <since_tizen> 4 </since_tizen>
137 public static void Start()
143 /// Stops the media control server.
146 /// When the server stops, <see cref="MediaControllerManager.ServerStopped"/> will be raised.
148 /// <exception cref="InvalidOperationException">
149 /// The server is not running .<br/>
151 /// An internal error occurs.
153 /// <seealso cref="MediaControllerManager.ServerStopped"/>
154 /// <since_tizen> 4 </since_tizen>
155 public static void Stop()
157 EnsureInitializedIfRunning();
159 Native.Destroy(_handle).ThrowIfError("Failed to stop the server.");
161 _handle = IntPtr.Zero;
162 _playbackCommandCallback = null;
167 /// Updates playback state and playback position.</summary>
168 /// <param name="state">The playback state.</param>
169 /// <param name="position">The playback position in milliseconds.</param>
170 /// <exception cref="ArgumentException"><paramref name="state"/> is not valid.</exception>
171 /// <exception cref="ArgumentOutOfRangeException"><paramref name="position"/> is less than zero.</exception>
172 /// <exception cref="InvalidOperationException">
173 /// The server is not running .<br/>
175 /// An internal error occurs.
177 /// <since_tizen> 4 </since_tizen>
178 public static void SetPlaybackState(MediaControlPlaybackState state, long position)
180 ValidationUtil.ValidateEnum(typeof(MediaControlPlaybackState), state, nameof(state));
184 throw new ArgumentOutOfRangeException(nameof(position), position, "position can't be less than zero.");
187 Native.SetPlaybackState(Handle, state.ToNative()).ThrowIfError("Failed to set playback state.");
189 Native.SetPlaybackPosition(Handle, (ulong)position).ThrowIfError("Failed to set playback position.");
191 Native.UpdatePlayback(Handle).ThrowIfError("Failed to set playback.");
194 private static void SetMetadata(MediaControllerNativeAttribute attribute, string value)
196 Native.SetMetadata(Handle, attribute, value).ThrowIfError($"Failed to set metadata({attribute}).");
200 /// Updates metadata information.
202 /// <param name="metadata">The metadata to update.</param>
203 /// <exception cref="ArgumentNullException"><paramref name="metadata"/> is null.</exception>
204 /// <exception cref="InvalidOperationException">
205 /// The server is not running .<br/>
207 /// An internal error occurs.
209 /// <since_tizen> 4 </since_tizen>
210 public static void SetMetadata(MediaControlMetadata metadata)
212 if (metadata == null)
214 throw new ArgumentNullException(nameof(metadata));
217 SetMetadata(MediaControllerNativeAttribute.Title, metadata.Title);
218 SetMetadata(MediaControllerNativeAttribute.Artist, metadata.Artist);
219 SetMetadata(MediaControllerNativeAttribute.Album, metadata.Album);
220 SetMetadata(MediaControllerNativeAttribute.Author, metadata.Author);
221 SetMetadata(MediaControllerNativeAttribute.Genre, metadata.Genre);
222 SetMetadata(MediaControllerNativeAttribute.Duration, metadata.Duration);
223 SetMetadata(MediaControllerNativeAttribute.Date, metadata.Date);
224 SetMetadata(MediaControllerNativeAttribute.Copyright, metadata.Copyright);
225 SetMetadata(MediaControllerNativeAttribute.Description, metadata.Description);
226 SetMetadata(MediaControllerNativeAttribute.TrackNumber, metadata.TrackNumber);
227 SetMetadata(MediaControllerNativeAttribute.Picture, metadata.AlbumArtPath);
229 Native.UpdateMetadata(Handle).ThrowIfError("Failed to set metadata.");
233 /// Updates the shuffle mode.
235 /// <param name="enabled">A value indicating whether the shuffle mode is enabled.</param>
236 /// <exception cref="InvalidOperationException">
237 /// The server is not running .<br/>
239 /// An internal error occurs.
241 /// <since_tizen> 4 </since_tizen>
242 public static void SetShuffleModeEnabled(bool enabled)
244 Native.UpdateShuffleMode(Handle, enabled ? MediaControllerNativeShuffleMode.On : MediaControllerNativeShuffleMode.Off).
245 ThrowIfError("Failed to set shuffle mode.");
249 /// Updates the repeat mode.
251 /// <param name="mode">A value indicating the repeat mode.</param>
252 /// <exception cref="InvalidOperationException">
253 /// The server is not running .<br/>
255 /// An internal error occurs.
257 /// <exception cref="ArgumentException"><paramref name="mode"/> is invalid.</exception>
258 /// <since_tizen> 4 </since_tizen>
259 public static void SetRepeatMode(MediaControlRepeatMode mode)
261 ValidationUtil.ValidateEnum(typeof(MediaControlRepeatMode), mode, nameof(mode));
263 Native.UpdateRepeatMode(Handle, mode.ToNative()).ThrowIfError("Failed to set repeat mode.");
267 /// Sets the index of current playing media.
269 /// <param name="index">The index of current playing media.</param>
270 /// <exception cref="ArgumentNullException"><paramref name="index"/> is null.</exception>
271 /// <exception cref="InvalidOperationException">
272 /// The server is not running .<br/>
274 /// An internal error occurs.
276 /// <since_tizen> 5 </since_tizen>
277 public static void SetIndexOfCurrentPlayingMedia(string index)
279 Native.SetIndexOfCurrentPlayingMedia(Handle, index)
280 .ThrowIfError("Failed to set the index of current playing media");
286 /// <param name="playlist">The name of playlist.</param>
287 /// <exception cref="InvalidOperationException">
288 /// The server is not running .<br/>
290 /// An internal error occurs.
292 /// <since_tizen> 5 </since_tizen>
293 public static void RemovePlaylist(MediaControlPlaylist playlist)
295 Native.DeletePlaylist(Handle, playlist.Handle);
299 // Saves the playlist to the persistent storage.
300 internal static void SavePlaylist(IntPtr playlistHandle)
302 Native.SavePlaylist(Handle, playlistHandle).ThrowIfError("Failed to save playlist");
305 // Gets the playlist handle by name.
306 internal static IntPtr GetPlaylistHandle(string name)
308 Native.GetPlaylistHandle(Handle, name, out IntPtr playlistHandle)
309 .ThrowIfError("Failed to get playlist handle by name");
311 return playlistHandle;
315 /// Sends the result of each command.
317 /// <param name="command">The command that return to client.</param>
318 /// <param name="result">The result of <paramref name="command"/>.</param>
319 /// <param name="bundle">The extra data.</param>
320 /// <exception cref="InvalidOperationException">
321 /// The server is not running .<br/>
323 /// An internal error occurs.
325 /// <since_tizen> 5 </since_tizen>
326 public static void Response(Command command, int result, Bundle bundle)
328 command.Response(Handle, result, bundle);
332 /// Sends the result of each command.
334 /// <param name="command">The command that return to client.</param>
335 /// <param name="result">The result of <paramref name="command"/>.</param>
336 /// <exception cref="InvalidOperationException">
337 /// The server is not running .<br/>
339 /// An internal error occurs.
341 /// <since_tizen> 5 </since_tizen>
342 public static void Response(Command command, int result)
344 command.Response(Handle, result, null);