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 Native = Interop.MediaControllerServer;
20 namespace Tizen.Multimedia.Remoting
23 /// Provides a means to set playback information and metadata and receive commands from clients.
25 /// <seealso cref="MediaControllerManager"/>
26 /// <seealso cref="MediaController"/>
27 public static class MediaControlServer
29 private static IntPtr _handle = IntPtr.Zero;
30 private static bool? _isRunning;
33 /// Gets a value indicating whether the server is running.
35 /// <value>true if the server has started; otherwise, false.</value>
36 /// <seealso cref="Start"/>
37 /// <seealso cref="Stop"/>
38 public static bool IsRunning
42 if (_isRunning.HasValue == false)
44 _isRunning = GetRunningState();
47 return _isRunning.Value;
51 private static bool GetRunningState()
53 IntPtr handle = IntPtr.Zero;
56 Native.ConnectDb(out handle).ThrowIfError("Failed to retrieve the running state.");
58 Native.CheckServerExist(handle, Applications.Application.Current.ApplicationInfo.ApplicationId,
59 out var value).ThrowIfError("Failed to retrieve the running state.");
65 if (handle != IntPtr.Zero)
67 Native.DisconnectDb(handle);
72 private static void EnsureInitializedIfRunning()
74 if (_handle != IntPtr.Zero)
79 if (IsRunning == false)
81 throw new InvalidOperationException("The server is not running.");
87 private static IntPtr Handle
91 EnsureInitializedIfRunning();
97 private static void Initialize()
99 Native.Create(out _handle).ThrowIfError("Failed to create media controller server.");
103 RegisterPlaybackCommandReceivedEvent();
108 Native.Destroy(_handle);
109 _playbackCommandCallback = null;
110 _handle = IntPtr.Zero;
116 /// Starts the media control server.
119 /// When the server starts, <see cref="MediaControllerManager.ServerStarted"/> will be raised.
121 /// <privilege>http://tizen.org/privilege/mediacontroller.server</privilege>
122 /// <exception cref="InvalidOperationException">An internal error occurs.</exception>
123 /// <exception cref="UnauthorizedAccessException">Caller does not have required privilege.</exception>
124 /// <seealso cref="MediaControllerManager.ServerStarted"/>
125 public static void Start()
131 /// Stops the media control server.
134 /// When the server stops, <see cref="MediaControllerManager.ServerStopped"/> will be raised.
136 /// <exception cref="InvalidOperationException">
137 /// The server is not running .<br/>
139 /// An internal error occurs.
141 /// <seealso cref="MediaControllerManager.ServerStopped"/>
142 public static void Stop()
144 EnsureInitializedIfRunning();
146 Native.Destroy(_handle).ThrowIfError("Failed to stop the server.");
148 _handle = IntPtr.Zero;
149 _playbackCommandCallback = null;
154 /// Updates playback state and playback position.</summary>
155 /// <param name="state">The playback state.</param>
156 /// <param name="position">The playback position in milliseconds.</param>
157 /// <exception cref="ArgumentException"><paramref name="state"/> is not valid.</exception>
158 /// <exception cref="ArgumentOutOfRangeException"><paramref name="position"/> is less than zero.</exception>
159 /// <exception cref="InvalidOperationException">
160 /// The server is not running .<br/>
162 /// An internal error occurs.
164 public static void SetPlaybackState(MediaControlPlaybackState state, long position)
166 ValidationUtil.ValidateEnum(typeof(MediaControlPlaybackState), state, nameof(state));
170 throw new ArgumentOutOfRangeException(nameof(position), position, "position can't be less than zero.");
173 Native.SetPlaybackState(Handle, state.ToCode()).ThrowIfError("Failed to set playback state.");
175 Native.SetPlaybackPosition(Handle, (ulong)position).ThrowIfError("Failed to set playback position.");
177 Native.UpdatePlayback(Handle).ThrowIfError("Failed to set playback.");
180 private static void SetMetadata(MediaControllerAttribute attribute, string value)
182 Native.SetMetadata(Handle, attribute, value).ThrowIfError($"Failed to set metadata({attribute}).");
186 /// Updates metadata information.
188 /// <param name="metadata">The metadata to update.</param>
189 /// <exception cref="ArgumentNullException"><paramref name="metadata"/> is null.</exception>
190 /// <exception cref="InvalidOperationException">
191 /// The server is not running .<br/>
193 /// An internal error occurs.
195 public static void SetMetadata(MediaControlMetadata metadata)
197 if (metadata == null)
199 throw new ArgumentNullException(nameof(metadata));
202 SetMetadata(MediaControllerAttribute.Title, metadata.Title);
203 SetMetadata(MediaControllerAttribute.Artist, metadata.Artist);
204 SetMetadata(MediaControllerAttribute.Album, metadata.Album);
205 SetMetadata(MediaControllerAttribute.Author, metadata.Author);
206 SetMetadata(MediaControllerAttribute.Genre, metadata.Genre);
207 SetMetadata(MediaControllerAttribute.Duration, metadata.Duration);
208 SetMetadata(MediaControllerAttribute.Date, metadata.Date);
209 SetMetadata(MediaControllerAttribute.Copyright, metadata.Copyright);
210 SetMetadata(MediaControllerAttribute.Description, metadata.Description);
211 SetMetadata(MediaControllerAttribute.TrackNumber, metadata.TrackNumber);
212 SetMetadata(MediaControllerAttribute.Picture, metadata.AlbumArtPath);
214 Native.UpdateMetadata(Handle).ThrowIfError("Failed to set metadata.");
218 /// Updates the shuffle mode.
220 /// <param name="enabled">A value indicating whether the shuffle mode is enabled.</param>
221 /// <exception cref="InvalidOperationException">
222 /// The server is not running .<br/>
224 /// An internal error occurs.
226 public static void SetShuffleModeEnabled(bool enabled)
228 Native.UpdateShuffleMode(Handle, enabled ? MediaControllerShuffleMode.On : MediaControllerShuffleMode.Off).
229 ThrowIfError("Failed to set shuffle mode.");
233 /// Updates the repeat mode.
235 /// <param name="mode">A value indicating the repeat mode.</param>
236 /// <exception cref="InvalidOperationException">
237 /// The server is not running .<br/>
239 /// An internal error occurs.
241 /// <exception cref="ArgumentException"><paramref name="mode"/> is invalid.</exception>
242 public static void SetRepeatMode(MediaControlRepeatMode mode)
244 ValidationUtil.ValidateEnum(typeof(MediaControlRepeatMode), mode, nameof(mode));
246 Native.UpdateRepeatMode(Handle, mode.ToNative()).ThrowIfError("Failed to set repeat mode.");
250 /// Occurs when a client sends playback command.
252 public static event EventHandler<PlaybackCommandReceivedEventArgs> PlaybackCommandReceived;
254 private static Native.PlaybackStateCommandReceivedCallback _playbackCommandCallback;
256 private static void RegisterPlaybackCommandReceivedEvent()
258 _playbackCommandCallback = (clientName, playbackCode, _) =>
260 PlaybackCommandReceived?.Invoke(null, new PlaybackCommandReceivedEventArgs(clientName, playbackCode.ToCommand()));
262 Native.SetPlaybackStateCmdRecvCb(Handle, _playbackCommandCallback).
263 ThrowIfError("Failed to init PlaybackStateCommandReceived event."); ;