2 * Copyright (c) 2018 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 System.Threading.Tasks;
20 using Tizen.Applications;
21 using Native = Interop.MediaControllerServer;
22 using NativePlaylist = Interop.MediaControllerPlaylist;
24 namespace Tizen.Multimedia.Remoting
27 /// Provides a means to set playback information and metadata and receive commands from clients.
29 /// <seealso cref="MediaControllerManager"/>
30 /// <seealso cref="MediaController"/>
31 /// <since_tizen> 4 </since_tizen>
32 public static partial class MediaControlServer
34 private static IntPtr _handle;
35 private static bool? _isRunning;
36 private static string _serverName;
39 /// Gets a value indicating whether the server is running.
41 /// <value>true if the server has started; otherwise, false.</value>
42 /// <seealso cref="Start"/>
43 /// <seealso cref="Stop"/>
44 /// <since_tizen> 4 </since_tizen>
45 public static bool IsRunning
49 if (_isRunning.HasValue == false)
51 _isRunning = GetRunningState();
54 return _isRunning.Value;
58 private static bool GetRunningState()
60 IntPtr handle = IntPtr.Zero;
63 Native.ConnectDb(out handle).ThrowIfError("Failed to retrieve the running state.");
65 Native.CheckServerExist(handle, Applications.Application.Current.ApplicationInfo.ApplicationId,
66 out var value).ThrowIfError("Failed to retrieve the running state.");
72 if (handle != IntPtr.Zero)
74 Native.DisconnectDb(handle);
79 private static void EnsureInitializedIfRunning()
81 if (_handle != IntPtr.Zero)
86 if (IsRunning == false)
88 throw new InvalidOperationException("The server is not running.");
94 private static IntPtr Handle
98 EnsureInitializedIfRunning();
104 private static void Initialize()
106 Native.Create(out _handle).ThrowIfError("Failed to create media controller server.");
110 RegisterPlaybackActionCommandReceivedEvent();
111 RegisterPlaybackPositionCommandReceivedEvent();
112 RegisterPlaylistCommandReceivedEvent();
113 RegisterShuffleModeCommandReceivedEvent();
114 RegisterRepeatModeCommandReceivedEvent();
115 RegisterSubtitleModeCommandReceivedEvent();
116 RegisterMode360CommandReceivedEvent();
117 RegisterDisplayModeCommandReceivedEvent();
118 RegisterDisplayRotationCommandReceivedEvent();
119 RegisterCustomCommandReceivedEvent();
120 RegisterCommandCompletedEvent();
121 RegisterSearchCommandReceivedEvent();
123 _serverName = Application.Current.ApplicationInfo.ApplicationId;
128 Native.Destroy(_handle);
129 _playbackCommandCallback = null;
130 _handle = IntPtr.Zero;
137 /// Starts the media control server.
140 /// When the server starts, <see cref="MediaControllerManager.ServerStarted"/> will be raised.
142 /// <privilege>http://tizen.org/privilege/mediacontroller.server</privilege>
143 /// <exception cref="InvalidOperationException">An internal error occurs.</exception>
144 /// <exception cref="UnauthorizedAccessException">Caller does not have required privilege.</exception>
145 /// <seealso cref="MediaControllerManager.ServerStarted"/>
146 /// <since_tizen> 4 </since_tizen>
147 public static void Start()
153 /// Stops the media control server.
156 /// When the server stops, <see cref="MediaControllerManager.ServerStopped"/> will be raised.
158 /// <exception cref="InvalidOperationException">
159 /// The server is not running .<br/>
161 /// An internal error occurs.
163 /// <seealso cref="MediaControllerManager.ServerStopped"/>
164 /// <since_tizen> 4 </since_tizen>
165 public static void Stop()
167 EnsureInitializedIfRunning();
169 Native.Destroy(_handle).ThrowIfError("Failed to stop the server.");
171 _handle = IntPtr.Zero;
172 _playbackCommandCallback = null;
177 /// Gets the active clients.
179 /// <exception cref="InvalidOperationException">
180 /// The server is not running .<br/>
182 /// An internal error occurs.
184 /// <returns>the activated client ids.</returns>
185 /// <since_tizen> 5 </since_tizen>
186 public static IEnumerable<string> GetActivatedClients()
188 var clientIds = new List<string>();
190 Native.ActivatedClientCallback activatedClientCallback = (name, _) =>
196 Native.ForeachActivatedClient(Handle, activatedClientCallback).
197 ThrowIfError("Failed to get activated client.");
199 return clientIds.AsReadOnly();
203 #region Set information
205 /// Updates playback state and playback position.</summary>
206 /// <param name="state">The playback state.</param>
207 /// <param name="position">The playback position in milliseconds.</param>
208 /// <exception cref="ArgumentException"><paramref name="state"/> is not valid.</exception>
209 /// <exception cref="ArgumentOutOfRangeException"><paramref name="position"/> is less than zero.</exception>
210 /// <exception cref="InvalidOperationException">
211 /// The server is not running .<br/>
213 /// An internal error occurs.
215 /// <since_tizen> 4 </since_tizen>
216 public static void SetPlaybackState(MediaControlPlaybackState state, long position)
218 ValidationUtil.ValidateEnum(typeof(MediaControlPlaybackState), state, nameof(state));
222 throw new ArgumentOutOfRangeException(nameof(position), position, "position can't be less than zero.");
225 Native.SetPlaybackState(Handle, state.ToNative()).ThrowIfError("Failed to set playback state.");
227 Native.SetPlaybackPosition(Handle, (ulong)position).ThrowIfError("Failed to set playback position.");
229 Native.UpdatePlayback(Handle).ThrowIfError("Failed to set playback.");
232 private static void SetMetadata(MediaControllerNativeAttribute attribute, string value)
236 Native.SetMetadata(Handle, attribute, value).ThrowIfError($"Failed to set metadata({attribute}).");
241 /// Updates metadata information.
243 /// <param name="metadata">The metadata to update.</param>
244 /// <exception cref="ArgumentNullException"><paramref name="metadata"/> is null.</exception>
245 /// <exception cref="InvalidOperationException">
246 /// The server is not running .<br/>
248 /// An internal error occurs.
250 /// <since_tizen> 4 </since_tizen>
251 public static void SetMetadata(MediaControlMetadata metadata)
253 if (metadata == null)
255 throw new ArgumentNullException(nameof(metadata));
258 SetMetadata(MediaControllerNativeAttribute.Title, metadata.Title);
259 SetMetadata(MediaControllerNativeAttribute.Artist, metadata.Artist);
260 SetMetadata(MediaControllerNativeAttribute.Album, metadata.Album);
261 SetMetadata(MediaControllerNativeAttribute.Author, metadata.Author);
262 SetMetadata(MediaControllerNativeAttribute.Genre, metadata.Genre);
263 SetMetadata(MediaControllerNativeAttribute.Duration, metadata.Duration);
264 SetMetadata(MediaControllerNativeAttribute.Date, metadata.Date);
265 SetMetadata(MediaControllerNativeAttribute.Copyright, metadata.Copyright);
266 SetMetadata(MediaControllerNativeAttribute.Description, metadata.Description);
267 SetMetadata(MediaControllerNativeAttribute.TrackNumber, metadata.TrackNumber);
268 SetMetadata(MediaControllerNativeAttribute.Picture, metadata.AlbumArtPath);
269 SetMetadata(MediaControllerNativeAttribute.Season, metadata.EncodedSeason);
270 SetMetadata(MediaControllerNativeAttribute.Episode, metadata.EncodedEpisode);
271 SetMetadata(MediaControllerNativeAttribute.Resolution, metadata.EncodedResolution);
273 Native.UpdateMetadata(Handle).ThrowIfError("Failed to set metadata.");
277 /// Updates the shuffle mode.
279 /// <param name="enabled">A value indicating whether the shuffle mode is enabled.</param>
280 /// <exception cref="InvalidOperationException">
281 /// The server is not running .<br/>
283 /// An internal error occurs.
285 /// <since_tizen> 4 </since_tizen>
286 public static void SetShuffleModeEnabled(bool enabled)
288 Native.UpdateShuffleMode(Handle, enabled ? MediaControllerNativeShuffleMode.On : MediaControllerNativeShuffleMode.Off).
289 ThrowIfError("Failed to set shuffle mode.");
293 /// Updates the repeat mode.
295 /// <param name="mode">A value indicating the repeat mode.</param>
296 /// <exception cref="InvalidOperationException">
297 /// The server is not running .<br/>
299 /// An internal error occurs.
301 /// <exception cref="ArgumentException"><paramref name="mode"/> is invalid.</exception>
302 /// <since_tizen> 4 </since_tizen>
303 public static void SetRepeatMode(MediaControlRepeatMode mode)
305 ValidationUtil.ValidateEnum(typeof(MediaControlRepeatMode), mode, nameof(mode));
307 Native.UpdateRepeatMode(Handle, mode.ToNative()).ThrowIfError("Failed to set repeat mode.");
311 /// Sets the playlist name and index of current playing media.
313 /// <param name="playlistName">The playlist name of current playing media.</param>
314 /// <param name="index">The index of current playing media.</param>
315 /// <exception cref="ArgumentNullException">
316 /// <paramref name="playlistName"/> or <paramref name="index"/> is null.
318 /// <exception cref="InvalidOperationException">
319 /// The server is not running .<br/>
321 /// An internal error occurs.
323 /// <since_tizen> 5 </since_tizen>
324 public static void SetInfoOfCurrentPlayingMedia(string playlistName, string index)
326 if (playlistName == null)
328 throw new ArgumentNullException(nameof(playlistName));
332 throw new ArgumentNullException(nameof(index));
335 Native.SetInfoOfCurrentPlayingMedia(Handle, playlistName, index)
336 .ThrowIfError("Failed to set the playlist name and index of current playing media");
338 Native.UpdatePlayback(Handle).ThrowIfError("Failed to set playback.");
342 /// Sets the age rating of latest played media.
344 /// <param name="ageRating">
345 /// The Age rating of latest played media. The valid range is 0 to 19, inclusive.
346 /// Especially, 0 means that media is suitable for all ages.
348 /// <exception cref="ArgumentOutOfRangeException">The specified <paramref name="ageRating"/> is not valid.</exception>
349 /// <exception cref="InvalidOperationException">
350 /// The server is not running .<br/>
352 /// An internal error occurs.
354 /// <since_tizen> 5 </since_tizen>
355 public static void SetAgeRating(int ageRating)
357 if (ageRating < 0 || ageRating > 19)
359 throw new ArgumentOutOfRangeException(nameof(ageRating));
362 Native.SetAgeRating(Handle, ageRating).ThrowIfError("Failed to set age rating.");
364 Native.UpdatePlayback(Handle).ThrowIfError("Failed to set playback.");
368 /// Sets the subtitle mode.
370 /// <param name="isEnabled">A value indicating whether the subtitle mode is enabled.</param>
371 /// <exception cref="InvalidOperationException">
372 /// The server is not running .<br/>
374 /// An internal error occurs.
376 /// <since_tizen> 6 </since_tizen>
377 public static void SetSubtitleMode(bool isEnabled)
379 Native.UpdateSubtitleMode(Handle, isEnabled).ThrowIfError("Failed to set subtitle mode.");
383 /// Sets the 360 mode.
385 /// <param name="isEnabled">A value indicating whether the 360 mode is enabled.</param>
386 /// <exception cref="InvalidOperationException">
387 /// The server is not running .<br/>
389 /// An internal error occurs.
391 /// <since_tizen> 6 </since_tizen>
392 public static void SetMode360(bool isEnabled)
394 Native.UpdateMode360(Handle, isEnabled).ThrowIfError("Failed to set 360 mode.");
398 /// Sets the display mode.
400 /// <param name="mode">A value indicating the <see cref="MediaControlDisplayMode"/>.</param>
401 /// <exception cref="InvalidOperationException">
402 /// The server is not running .<br/>
404 /// An internal error occurs.
406 /// <since_tizen> 6 </since_tizen>
407 public static void SetDisplayMode(MediaControlDisplayMode mode)
409 Native.UpdateDisplayMode(Handle, mode.ToNative()).ThrowIfError("Failed to set display mode.");
413 /// Sets the display rotation.
415 /// <param name="rotation">A value indicating the <see cref="Rotation"/>.</param>
416 /// <exception cref="InvalidOperationException">
417 /// The server is not running .<br/>
419 /// An internal error occurs.
421 /// <since_tizen> 6 </since_tizen>
422 public static void SetDisplayRotation(Rotation rotation)
424 Native.UpdateDisplayRotaton(Handle, rotation.ToNative()).ThrowIfError("Failed to set display rotation.");
428 /// Sets the index of current playing media.
430 /// <param name="index">The index of current playing media.</param>
431 /// <exception cref="ArgumentNullException"><paramref name="index"/> is null.</exception>
432 /// <exception cref="InvalidOperationException">
433 /// The server is not running .<br/>
435 /// An internal error occurs.
437 /// <since_tizen> 5 </since_tizen>
438 [Obsolete("Please do not use! This will be deprecated. Please use SetInfoOfCurrentPlayingMedia instead.")]
439 public static void SetIndexOfCurrentPlayingMedia(string index)
443 throw new ArgumentNullException(nameof(index));
446 Native.SetIndexOfCurrentPlayingMedia(Handle, index)
447 .ThrowIfError("Failed to set the index of current playing media");
449 Native.UpdatePlayback(Handle).ThrowIfError("Failed to set playback.");
451 #endregion Set information
458 /// <remarks>Currently, only server can remove the playlist.</remarks>
459 /// <param name="playlist">The name of playlist.</param>
460 /// <exception cref="ArgumentNullException"><paramref name="playlist"/> is null.</exception>
461 /// <exception cref="InvalidOperationException">
462 /// The server is not running .<br/>
464 /// An internal error occurs.
466 /// <since_tizen> 5 </since_tizen>
467 public static void RemovePlaylist(MediaControlPlaylist playlist)
469 if (playlist == null)
471 throw new ArgumentNullException(nameof(playlist));
474 Native.DeletePlaylist(Handle, playlist.Handle);
478 // Saves the playlist to the persistent storage.
479 internal static void SavePlaylist(IntPtr playlistHandle)
481 Native.SavePlaylist(Handle, playlistHandle).ThrowIfError("Failed to save playlist");
484 // Gets the playlist handle by name.
485 internal static IntPtr GetPlaylistHandle(string name)
487 NativePlaylist.GetPlaylistHandle(_serverName, name, out IntPtr playlistHandle).
488 ThrowIfError("Failed to get playlist handle by name");
490 return playlistHandle;
497 /// Sets the content type of latest played media.
499 /// <param name="type">A value indicating the content type of the latest played media.</param>
500 /// <exception cref="InvalidOperationException">
501 /// The server is not running .<br/>
503 /// An internal error occurs.
505 /// <exception cref="ArgumentException"><paramref name="type"/> is invalid.</exception>
506 /// <since_tizen> 5 </since_tizen>
507 public static void SetPlaybackContentType(MediaControlContentType type)
509 ValidationUtil.ValidateEnum(typeof(MediaControlContentType), type, nameof(type));
511 Native.SetPlaybackContentType(Handle, type).ThrowIfError("Failed to set playback content type.");
513 Native.UpdatePlayback(Handle).ThrowIfError("Failed to set playback.");
517 /// Sets the path of icon.
519 /// <param name="path">The path of icon.</param>
520 /// <exception cref="InvalidOperationException">
521 /// The server is not running .<br/>
523 /// An internal error occurs.
525 /// <exception cref="ArgumentNullException"><paramref name="path"/> is invalid.</exception>
526 /// <since_tizen> 5 </since_tizen>
527 public static void SetIconPath(string path)
531 throw new ArgumentNullException(nameof(path));
534 Native.SetIconPath(Handle, path).ThrowIfError("Failed to set uri path.");
538 /// Sets the capabilities by <see cref="MediaControlPlaybackCommand"/>.
540 /// <param name="capabilities">The set of <see cref="MediaControlPlaybackCommand"/> and <see cref="MediaControlCapabilitySupport"/>.</param>
541 /// <exception cref="InvalidOperationException">
542 /// The server is not running .<br/>
544 /// An internal error occurs.
546 /// <exception cref="ArgumentException"><paramref name="capabilities"/> is invalid.</exception>
547 /// <since_tizen> 5 </since_tizen>
548 public static void SetPlaybackCapabilities(Dictionary<MediaControlPlaybackCommand, MediaControlCapabilitySupport> capabilities)
550 foreach (var pair in capabilities)
552 ValidationUtil.ValidateEnum(typeof(MediaControlPlaybackCommand), pair.Key, nameof(pair.Key));
553 ValidationUtil.ValidateEnum(typeof(MediaControlCapabilitySupport), pair.Value, nameof(pair.Value));
555 SetPlaybackCapability(pair.Key, pair.Value);
556 Native.SetPlaybackCapability(Handle, pair.Key.ToNative(), pair.Value).
557 ThrowIfError("Failed to set playback capability.");
560 Native.SaveAndNotifyPlaybackCapabilityUpdated(Handle).ThrowIfError("Failed to update playback capability.");
564 /// Sets the capabilities by <see cref="MediaControlPlaybackCommand"/>.
566 /// <param name="action">A playback command.</param>
567 /// <param name="support">A value indicating whether the <paramref name="action"/> is supported or not.</param>
568 /// <exception cref="InvalidOperationException">
569 /// The server is not running .<br/>
571 /// An internal error occurs.
573 /// <exception cref="ArgumentException"><paramref name="action"/> or <paramref name="support"/> is invalid.</exception>
574 /// <since_tizen> 5 </since_tizen>
575 public static void SetPlaybackCapability(MediaControlPlaybackCommand action, MediaControlCapabilitySupport support)
577 ValidationUtil.ValidateEnum(typeof(MediaControlPlaybackCommand), action, nameof(action));
578 ValidationUtil.ValidateEnum(typeof(MediaControlCapabilitySupport), support, nameof(support));
580 Native.SetPlaybackCapability(Handle, action.ToNative(), support).ThrowIfError("Failed to set playback capability.");
582 Native.SaveAndNotifyPlaybackCapabilityUpdated(Handle).ThrowIfError("Failed to update playback capability.");
586 /// Sets the <see cref="MediaControlCapabilitySupport"/> indicating shuffle mode is supported or not.
588 /// <param name="support">A value indicating whether the shuffle mode is supported or not.</param>
589 /// <exception cref="InvalidOperationException">
590 /// The server is not running .<br/>
592 /// An internal error occurs.
594 /// <exception cref="ArgumentException"><paramref name="support"/> is invalid.</exception>
595 /// <since_tizen> 5 </since_tizen>
596 public static void SetShuffleModeCapability(MediaControlCapabilitySupport support)
598 ValidationUtil.ValidateEnum(typeof(MediaControlCapabilitySupport), support, nameof(support));
600 Native.SetSimpleCapability(Handle, MediaControlNativeCapabilityCategory.Shuffle, support).
601 ThrowIfError("Failed to set shuffle mode capability.");
605 /// Sets the <see cref="MediaControlCapabilitySupport"/> indicating repeat mode is supported or not.
607 /// <param name="support">A value indicating whether the <see cref="MediaControlRepeatMode"/> is supported or not.</param>
608 /// <exception cref="InvalidOperationException">
609 /// The server is not running .<br/>
611 /// An internal error occurs.
613 /// <exception cref="ArgumentException"><paramref name="support"/> is invalid.</exception>
614 /// <since_tizen> 5 </since_tizen>
615 public static void SetRepeatModeCapability(MediaControlCapabilitySupport support)
617 ValidationUtil.ValidateEnum(typeof(MediaControlCapabilitySupport), support, nameof(support));
619 Native.SetSimpleCapability(Handle, MediaControlNativeCapabilityCategory.Repeat, support).
620 ThrowIfError("Failed to set repeat mode capability.");
624 /// Sets the supported list of <see cref="MediaControlDisplayMode"/>.
627 /// <see cref="MediaControlCapabilitySupport.NotDecided"/> is not allowed in display mode capability.
628 /// The default value of each <see cref="MediaControlDisplayMode"/> is not supported.
630 /// <param name="capabilities">The supported list of <see cref="MediaControlDisplayMode"/>.</param>
631 /// <exception cref="InvalidOperationException">
632 /// The server is not running .<br/>
634 /// An internal error occurs.
636 /// <exception cref="ArgumentException"><paramref name="capabilities"/> is invalid.</exception>
637 /// <since_tizen> 6 </since_tizen>
638 public static void SetDisplayModeCapabilities(IDictionary<MediaControlDisplayMode, MediaControlCapabilitySupport> capabilities)
640 foreach (var pair in capabilities)
642 SetDisplayModeCapability(pair.Key, pair.Value);
647 /// Sets the <paramref name="mode"/> is supported or not.
650 /// <see cref="MediaControlCapabilitySupport.NotDecided"/> is not allowed in display mode capability.<br/>
651 /// The default value of each <see cref="MediaControlDisplayMode"/> is not supported.
653 /// <param name="mode">The <see cref="MediaControlDisplayMode"/>.</param>
654 /// <param name="support">A value indicating whether the <paramref name="mode"/> is supported or not.</param>
655 /// <exception cref="InvalidOperationException">
656 /// The server is not running .<br/>
658 /// An internal error occurs.
660 /// <exception cref="ArgumentException"><paramref name="mode"/> or <paramref name="support"/> is invalid.</exception>
661 /// <since_tizen> 6 </since_tizen>
662 public static void SetDisplayModeCapability(MediaControlDisplayMode mode, MediaControlCapabilitySupport support)
664 ValidationUtil.ValidateEnum(typeof(MediaControlDisplayMode), mode, nameof(mode));
665 ValidationUtil.ValidateEnum(typeof(MediaControlCapabilitySupport), support, nameof(support));
667 if (support == MediaControlCapabilitySupport.NotDecided)
669 throw new ArgumentException($"NotDecided is not allowed in {mode} capability.");
672 Native.SetDisplayModeCapability(Handle, (uint)mode.ToNative(), support).
673 ThrowIfError("Failed to set display mode capability.");
677 /// Sets the supported list of <see cref="Rotation"/>.
680 /// <see cref="MediaControlCapabilitySupport.NotDecided"/> is not allowed in display rotation capability.<br/>
681 /// The default value of each <see cref="Rotation"/> is not supported.
683 /// <param name="capabilities">The supported list of <see cref="Rotation"/>.</param>
684 /// <exception cref="InvalidOperationException">
685 /// The server is not running .<br/>
687 /// An internal error occurs.
689 /// <exception cref="ArgumentException"><paramref name="capabilities"/> is invalid.</exception>
690 /// <since_tizen> 6 </since_tizen>
691 public static void SetDisplayRotationCapabilities(IDictionary<Rotation, MediaControlCapabilitySupport> capabilities)
693 foreach (var pair in capabilities)
695 SetDisplayRotationCapability(pair.Key, pair.Value);
700 /// Sets the <paramref name="rotation"/> is supported or not.
703 /// <see cref="MediaControlCapabilitySupport.NotDecided"/> is not allowed in display rotation capability.<br/>
704 /// The default value of each <see cref="Rotation"/> is not supported.
706 /// <param name="rotation">The <see cref="Rotation"/>.</param>
707 /// <param name="support">A value indicating whether the <paramref name="rotation"/> is supported or not..</param>
708 /// <exception cref="InvalidOperationException">
709 /// The server is not running .<br/>
711 /// An internal error occurs.
713 /// <exception cref="ArgumentException"><paramref name="rotation"/> or <paramref name="support"/> is invalid.</exception>
714 /// <since_tizen> 6 </since_tizen>
715 public static void SetDisplayRotationCapability(Rotation rotation, MediaControlCapabilitySupport support)
717 ValidationUtil.ValidateEnum(typeof(Rotation), rotation, nameof(rotation));
718 ValidationUtil.ValidateEnum(typeof(MediaControlCapabilitySupport), support, nameof(support));
720 if (support == MediaControlCapabilitySupport.NotDecided)
722 throw new ArgumentException($"NotDecided is not allowed in {rotation} capability.");
725 Native.SetDisplayRotationCapability(Handle, (uint)rotation.ToNative(), support).
726 ThrowIfError("Failed to set display rotation capability.");
728 #endregion Capability
733 /// Requests commands to the client.
736 /// The client can request the command to execute <see cref="Command"/>, <br/>
737 /// and then, the server receive the result of each request(command).
739 /// <param name="command">A <see cref="Command"/> class.</param>
740 /// <param name="clientId">The client Id to send command.</param>
741 /// <returns><see cref="Bundle"/> represents the extra data from client and it can be null.</returns>
742 /// <exception cref="ArgumentNullException">
743 /// <paramref name="command"/> or <paramref name="clientId"/> is null.
745 /// <exception cref="InvalidOperationException">
746 /// The server has already been stopped.<br/>
748 /// An internal error occurs.
750 /// <since_tizen> 5 </since_tizen>
751 public static async Task<Bundle> RequestAsync(Command command, string clientId)
755 throw new ArgumentNullException(nameof(command));
757 if (clientId == null)
759 throw new ArgumentNullException(nameof(clientId));
762 command.SetRequestInformation(clientId);
764 var tcs = new TaskCompletionSource<MediaControllerError>();
765 string reqeustId = null;
766 Bundle bundle = null;
768 EventHandler<CommandCompletedEventArgs> eventHandler = (s, e) =>
770 if (e.RequestId == reqeustId)
773 tcs.TrySetResult(e.Result);
779 CommandCompleted += eventHandler;
781 reqeustId = command.Request(Handle);
783 (await tcs.Task).ThrowIfError("Failed to request event.");
789 CommandCompleted -= eventHandler;
794 /// Sends the result of each command.
796 /// <param name="command">The command that return to client.</param>
797 /// <param name="result">The result of <paramref name="command"/>.</param>
798 /// <param name="bundle">The extra data.</param>
799 /// <exception cref="ArgumentNullException"><paramref name="command"/> is null.</exception>
800 /// <exception cref="InvalidOperationException">
801 /// The server is not running .<br/>
803 /// An internal error occurs.
805 /// <since_tizen> 5 </since_tizen>
806 public static void Response(Command command, int result, Bundle bundle)
810 throw new ArgumentNullException(nameof(command));
813 command.Response(Handle, result, bundle);
817 /// Sends the result of each command.
819 /// <param name="command">The command that return to client.</param>
820 /// <param name="result">The result of <paramref name="command"/>.</param>
821 /// <exception cref="ArgumentNullException"><paramref name="command"/> is null.</exception>
822 /// <exception cref="InvalidOperationException">
823 /// The server is not running .<br/>
825 /// An internal error occurs.
827 /// <since_tizen> 5 </since_tizen>
828 public static void Response(Command command, int result)
832 throw new ArgumentNullException(nameof(command));
835 command.Response(Handle, result, null);