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 _handle = IntPtr.Zero;
136 /// Starts the media control server.
139 /// When the server starts, <see cref="MediaControllerManager.ServerStarted"/> will be raised.
141 /// <privilege>http://tizen.org/privilege/mediacontroller.server</privilege>
142 /// <exception cref="InvalidOperationException">An internal error occurs.</exception>
143 /// <exception cref="UnauthorizedAccessException">Caller does not have required privilege.</exception>
144 /// <seealso cref="MediaControllerManager.ServerStarted"/>
145 /// <since_tizen> 4 </since_tizen>
146 public static void Start()
152 /// Stops the media control server.
155 /// When the server stops, <see cref="MediaControllerManager.ServerStopped"/> will be raised.
157 /// <exception cref="InvalidOperationException">
158 /// The server is not running .<br/>
160 /// An internal error occurs.
162 /// <seealso cref="MediaControllerManager.ServerStopped"/>
163 /// <since_tizen> 4 </since_tizen>
164 public static void Stop()
166 EnsureInitializedIfRunning();
168 Native.Destroy(_handle).ThrowIfError("Failed to stop the server.");
170 _handle = IntPtr.Zero;
175 /// Gets the active clients.
177 /// <exception cref="InvalidOperationException">
178 /// The server is not running .<br/>
180 /// An internal error occurs.
182 /// <returns>the activated client ids.</returns>
183 /// <since_tizen> 5 </since_tizen>
184 public static IEnumerable<string> GetActivatedClients()
186 var clientIds = new List<string>();
188 Native.ActivatedClientCallback activatedClientCallback = (name, _) =>
194 Native.ForeachActivatedClient(Handle, activatedClientCallback).
195 ThrowIfError("Failed to get activated client.");
197 return clientIds.AsReadOnly();
201 #region Set information
203 /// Updates playback state and playback position.</summary>
204 /// <param name="state">The playback state.</param>
205 /// <param name="position">The playback position in milliseconds.</param>
206 /// <exception cref="ArgumentException"><paramref name="state"/> is not valid.</exception>
207 /// <exception cref="ArgumentOutOfRangeException"><paramref name="position"/> is less than zero.</exception>
208 /// <exception cref="InvalidOperationException">
209 /// The server is not running .<br/>
211 /// An internal error occurs.
213 /// <since_tizen> 4 </since_tizen>
214 public static void SetPlaybackState(MediaControlPlaybackState state, long position)
216 ValidationUtil.ValidateEnum(typeof(MediaControlPlaybackState), state, nameof(state));
220 throw new ArgumentOutOfRangeException(nameof(position), position, "position can't be less than zero.");
223 Native.SetPlaybackState(Handle, state.ToNative()).ThrowIfError("Failed to set playback state.");
225 Native.SetPlaybackPosition(Handle, (ulong)position).ThrowIfError("Failed to set playback position.");
227 Native.UpdatePlayback(Handle).ThrowIfError("Failed to set playback.");
230 private static void SetMetadata(MediaControllerNativeAttribute attribute, string value)
234 Native.SetMetadata(Handle, attribute, value).ThrowIfError($"Failed to set metadata({attribute}).");
239 /// Updates metadata information.
241 /// <param name="metadata">The metadata to update.</param>
242 /// <exception cref="ArgumentNullException"><paramref name="metadata"/> is null.</exception>
243 /// <exception cref="InvalidOperationException">
244 /// The server is not running .<br/>
246 /// An internal error occurs.
248 /// <since_tizen> 4 </since_tizen>
249 public static void SetMetadata(MediaControlMetadata metadata)
251 if (metadata == null)
253 throw new ArgumentNullException(nameof(metadata));
256 SetMetadata(MediaControllerNativeAttribute.Title, metadata.Title);
257 SetMetadata(MediaControllerNativeAttribute.Artist, metadata.Artist);
258 SetMetadata(MediaControllerNativeAttribute.Album, metadata.Album);
259 SetMetadata(MediaControllerNativeAttribute.Author, metadata.Author);
260 SetMetadata(MediaControllerNativeAttribute.Genre, metadata.Genre);
261 SetMetadata(MediaControllerNativeAttribute.Duration, metadata.Duration);
262 SetMetadata(MediaControllerNativeAttribute.Date, metadata.Date);
263 SetMetadata(MediaControllerNativeAttribute.Copyright, metadata.Copyright);
264 SetMetadata(MediaControllerNativeAttribute.Description, metadata.Description);
265 SetMetadata(MediaControllerNativeAttribute.TrackNumber, metadata.TrackNumber);
266 SetMetadata(MediaControllerNativeAttribute.Picture, metadata.AlbumArtPath);
267 SetMetadata(MediaControllerNativeAttribute.Season, metadata.EncodedSeason);
268 SetMetadata(MediaControllerNativeAttribute.Episode, metadata.EncodedEpisode);
269 SetMetadata(MediaControllerNativeAttribute.Resolution, metadata.EncodedResolution);
271 Native.UpdateMetadata(Handle).ThrowIfError("Failed to set metadata.");
275 /// Updates the shuffle mode.
277 /// <param name="enabled">A value indicating whether the shuffle mode is enabled.</param>
278 /// <exception cref="InvalidOperationException">
279 /// The server is not running .<br/>
281 /// An internal error occurs.
283 /// <since_tizen> 4 </since_tizen>
284 public static void SetShuffleModeEnabled(bool enabled)
286 Native.UpdateShuffleMode(Handle, enabled ? MediaControllerNativeShuffleMode.On : MediaControllerNativeShuffleMode.Off).
287 ThrowIfError("Failed to set shuffle mode.");
291 /// Updates the repeat mode.
293 /// <param name="mode">A value indicating the repeat mode.</param>
294 /// <exception cref="InvalidOperationException">
295 /// The server is not running .<br/>
297 /// An internal error occurs.
299 /// <exception cref="ArgumentException"><paramref name="mode"/> is invalid.</exception>
300 /// <since_tizen> 4 </since_tizen>
301 public static void SetRepeatMode(MediaControlRepeatMode mode)
303 ValidationUtil.ValidateEnum(typeof(MediaControlRepeatMode), mode, nameof(mode));
305 Native.UpdateRepeatMode(Handle, mode.ToNative()).ThrowIfError("Failed to set repeat mode.");
309 /// Sets the playlist name and index of current playing media.
311 /// <param name="playlistName">The playlist name of current playing media.</param>
312 /// <param name="index">The index of current playing media.</param>
313 /// <exception cref="ArgumentNullException">
314 /// <paramref name="playlistName"/> or <paramref name="index"/> is null.
316 /// <exception cref="InvalidOperationException">
317 /// The server is not running .<br/>
319 /// An internal error occurs.
321 /// <since_tizen> 5 </since_tizen>
322 public static void SetInfoOfCurrentPlayingMedia(string playlistName, string index)
324 if (playlistName == null)
326 throw new ArgumentNullException(nameof(playlistName));
330 throw new ArgumentNullException(nameof(index));
333 Native.SetInfoOfCurrentPlayingMedia(Handle, playlistName, index)
334 .ThrowIfError("Failed to set the playlist name and index of current playing media");
336 Native.UpdatePlayback(Handle).ThrowIfError("Failed to set playback.");
340 /// Sets the age rating of latest played media.
342 /// <param name="ageRating">
343 /// The Age rating of latest played media. The valid range is 0 to 19, inclusive.
344 /// Especially, 0 means that media is suitable for all ages.
346 /// <exception cref="ArgumentOutOfRangeException">The specified <paramref name="ageRating"/> is not valid.</exception>
347 /// <exception cref="InvalidOperationException">
348 /// The server is not running .<br/>
350 /// An internal error occurs.
352 /// <since_tizen> 5 </since_tizen>
353 public static void SetAgeRating(int ageRating)
355 if (ageRating < 0 || ageRating > 19)
357 throw new ArgumentOutOfRangeException(nameof(ageRating));
360 Native.SetAgeRating(Handle, ageRating).ThrowIfError("Failed to set age rating.");
362 Native.UpdatePlayback(Handle).ThrowIfError("Failed to set playback.");
366 /// Sets the subtitle mode.
368 /// <param name="isEnabled">A value indicating whether the subtitle mode is enabled.</param>
369 /// <exception cref="InvalidOperationException">
370 /// The server is not running .<br/>
372 /// An internal error occurs.
374 /// <since_tizen> 6 </since_tizen>
375 public static void SetSubtitleMode(bool isEnabled)
377 Native.UpdateSubtitleMode(Handle, isEnabled).ThrowIfError("Failed to set subtitle mode.");
381 /// Sets the 360 mode.
383 /// <param name="isEnabled">A value indicating whether the 360 mode is enabled.</param>
384 /// <exception cref="InvalidOperationException">
385 /// The server is not running .<br/>
387 /// An internal error occurs.
389 /// <since_tizen> 6 </since_tizen>
390 public static void SetMode360(bool isEnabled)
392 Native.UpdateMode360(Handle, isEnabled).ThrowIfError("Failed to set 360 mode.");
396 /// Sets the display mode.
398 /// <param name="mode">A value indicating the <see cref="MediaControlDisplayMode"/>.</param>
399 /// <exception cref="InvalidOperationException">
400 /// The server is not running .<br/>
402 /// An internal error occurs.
404 /// <since_tizen> 6 </since_tizen>
405 public static void SetDisplayMode(MediaControlDisplayMode mode)
407 Native.UpdateDisplayMode(Handle, mode.ToNative()).ThrowIfError("Failed to set display mode.");
411 /// Sets the display rotation.
413 /// <param name="rotation">A value indicating the <see cref="Rotation"/>.</param>
414 /// <exception cref="InvalidOperationException">
415 /// The server is not running .<br/>
417 /// An internal error occurs.
419 /// <since_tizen> 6 </since_tizen>
420 public static void SetDisplayRotation(Rotation rotation)
422 Native.UpdateDisplayRotaton(Handle, rotation.ToNative()).ThrowIfError("Failed to set display rotation.");
426 /// Sets the index of current playing media.
428 /// <param name="index">The index of current playing media.</param>
429 /// <exception cref="ArgumentNullException"><paramref name="index"/> is null.</exception>
430 /// <exception cref="InvalidOperationException">
431 /// The server is not running .<br/>
433 /// An internal error occurs.
435 /// <since_tizen> 5 </since_tizen>
436 [Obsolete("Please do not use! This will be deprecated. Please use SetInfoOfCurrentPlayingMedia instead.")]
437 public static void SetIndexOfCurrentPlayingMedia(string index)
441 throw new ArgumentNullException(nameof(index));
444 Native.SetIndexOfCurrentPlayingMedia(Handle, index)
445 .ThrowIfError("Failed to set the index of current playing media");
447 Native.UpdatePlayback(Handle).ThrowIfError("Failed to set playback.");
449 #endregion Set information
456 /// <remarks>Currently, only server can remove the playlist.</remarks>
457 /// <param name="playlist">The name of playlist.</param>
458 /// <exception cref="ArgumentNullException"><paramref name="playlist"/> is null.</exception>
459 /// <exception cref="InvalidOperationException">
460 /// The server is not running .<br/>
462 /// An internal error occurs.
464 /// <since_tizen> 5 </since_tizen>
465 public static void RemovePlaylist(MediaControlPlaylist playlist)
467 if (playlist == null)
469 throw new ArgumentNullException(nameof(playlist));
472 Native.DeletePlaylist(Handle, playlist.Handle);
476 // Saves the playlist to the persistent storage.
477 internal static void SavePlaylist(IntPtr playlistHandle)
479 Native.SavePlaylist(Handle, playlistHandle).ThrowIfError("Failed to save playlist");
482 // Gets the playlist handle by name.
483 internal static IntPtr GetPlaylistHandle(string name)
485 NativePlaylist.GetPlaylistHandle(_serverName, name, out IntPtr playlistHandle).
486 ThrowIfError("Failed to get playlist handle by name");
488 return playlistHandle;
495 /// Sets the content type of latest played media.
497 /// <param name="type">A value indicating the content type of the latest played media.</param>
498 /// <exception cref="InvalidOperationException">
499 /// The server is not running .<br/>
501 /// An internal error occurs.
503 /// <exception cref="ArgumentException"><paramref name="type"/> is invalid.</exception>
504 /// <since_tizen> 5 </since_tizen>
505 public static void SetPlaybackContentType(MediaControlContentType type)
507 ValidationUtil.ValidateEnum(typeof(MediaControlContentType), type, nameof(type));
509 Native.SetPlaybackContentType(Handle, type).ThrowIfError("Failed to set playback content type.");
511 Native.UpdatePlayback(Handle).ThrowIfError("Failed to set playback.");
515 /// Sets the path of icon.
517 /// <param name="path">The path of icon.</param>
518 /// <exception cref="InvalidOperationException">
519 /// The server is not running .<br/>
521 /// An internal error occurs.
523 /// <exception cref="ArgumentNullException"><paramref name="path"/> is invalid.</exception>
524 /// <since_tizen> 5 </since_tizen>
525 public static void SetIconPath(string path)
529 throw new ArgumentNullException(nameof(path));
532 Native.SetIconPath(Handle, path).ThrowIfError("Failed to set uri path.");
536 /// Sets the capabilities by <see cref="MediaControlPlaybackCommand"/>.
538 /// <param name="capabilities">The set of <see cref="MediaControlPlaybackCommand"/> and <see cref="MediaControlCapabilitySupport"/>.</param>
539 /// <exception cref="InvalidOperationException">
540 /// The server is not running .<br/>
542 /// An internal error occurs.
544 /// <exception cref="ArgumentException"><paramref name="capabilities"/> is invalid.</exception>
545 /// <since_tizen> 5 </since_tizen>
546 public static void SetPlaybackCapabilities(Dictionary<MediaControlPlaybackCommand, MediaControlCapabilitySupport> capabilities)
548 foreach (var pair in capabilities)
550 ValidationUtil.ValidateEnum(typeof(MediaControlPlaybackCommand), pair.Key, nameof(pair.Key));
551 ValidationUtil.ValidateEnum(typeof(MediaControlCapabilitySupport), pair.Value, nameof(pair.Value));
553 SetPlaybackCapability(pair.Key, pair.Value);
554 Native.SetPlaybackCapability(Handle, pair.Key.ToNative(), pair.Value).
555 ThrowIfError("Failed to set playback capability.");
558 Native.SaveAndNotifyPlaybackCapabilityUpdated(Handle).ThrowIfError("Failed to update playback capability.");
562 /// Sets the capabilities by <see cref="MediaControlPlaybackCommand"/>.
564 /// <param name="action">A playback command.</param>
565 /// <param name="support">A value indicating whether the <paramref name="action"/> is supported or not.</param>
566 /// <exception cref="InvalidOperationException">
567 /// The server is not running .<br/>
569 /// An internal error occurs.
571 /// <exception cref="ArgumentException"><paramref name="action"/> or <paramref name="support"/> is invalid.</exception>
572 /// <since_tizen> 5 </since_tizen>
573 public static void SetPlaybackCapability(MediaControlPlaybackCommand action, MediaControlCapabilitySupport support)
575 ValidationUtil.ValidateEnum(typeof(MediaControlPlaybackCommand), action, nameof(action));
576 ValidationUtil.ValidateEnum(typeof(MediaControlCapabilitySupport), support, nameof(support));
578 Native.SetPlaybackCapability(Handle, action.ToNative(), support).ThrowIfError("Failed to set playback capability.");
580 Native.SaveAndNotifyPlaybackCapabilityUpdated(Handle).ThrowIfError("Failed to update playback capability.");
584 /// Sets the <see cref="MediaControlCapabilitySupport"/> indicating shuffle mode is supported or not.
586 /// <param name="support">A value indicating whether the shuffle mode is supported or not.</param>
587 /// <exception cref="InvalidOperationException">
588 /// The server is not running .<br/>
590 /// An internal error occurs.
592 /// <exception cref="ArgumentException"><paramref name="support"/> is invalid.</exception>
593 /// <since_tizen> 5 </since_tizen>
594 public static void SetShuffleModeCapability(MediaControlCapabilitySupport support)
596 ValidationUtil.ValidateEnum(typeof(MediaControlCapabilitySupport), support, nameof(support));
598 Native.SetSimpleCapability(Handle, MediaControlNativeCapabilityCategory.Shuffle, support).
599 ThrowIfError("Failed to set shuffle mode capability.");
603 /// Sets the <see cref="MediaControlCapabilitySupport"/> indicating repeat mode is supported or not.
605 /// <param name="support">A value indicating whether the <see cref="MediaControlRepeatMode"/> is supported or not.</param>
606 /// <exception cref="InvalidOperationException">
607 /// The server is not running .<br/>
609 /// An internal error occurs.
611 /// <exception cref="ArgumentException"><paramref name="support"/> is invalid.</exception>
612 /// <since_tizen> 5 </since_tizen>
613 public static void SetRepeatModeCapability(MediaControlCapabilitySupport support)
615 ValidationUtil.ValidateEnum(typeof(MediaControlCapabilitySupport), support, nameof(support));
617 Native.SetSimpleCapability(Handle, MediaControlNativeCapabilityCategory.Repeat, support).
618 ThrowIfError("Failed to set repeat mode capability.");
622 /// Sets the <see cref="MediaControlCapabilitySupport"/> indicating whether 360 mode is supported or not.
624 /// <param name="support">A value indicating whether the 360 mode is supported or not.</param>
625 /// <exception cref="InvalidOperationException">
626 /// The server is not running .<br/>
628 /// An internal error occurs.
630 /// <exception cref="ArgumentException"><paramref name="support"/> is invalid.</exception>
631 /// <since_tizen> 6 </since_tizen>
632 public static void SetMode360Capability(MediaControlCapabilitySupport support)
634 ValidationUtil.ValidateEnum(typeof(MediaControlCapabilitySupport), support, nameof(support));
636 Native.SetSimpleCapability(Handle, MediaControlNativeCapabilityCategory.Mode360, support).
637 ThrowIfError("Failed to set 360 mode capability.");
641 /// Sets the <see cref="MediaControlCapabilitySupport"/> indicating whether subtitle mode is supported or not.
643 /// <param name="support">A value indicating whether the subtitle mode is supported or not.</param>
644 /// <exception cref="InvalidOperationException">
645 /// The server is not running .<br/>
647 /// An internal error occurs.
649 /// <exception cref="ArgumentException"><paramref name="support"/> is invalid.</exception>
650 /// <since_tizen> 6 </since_tizen>
651 public static void SetSubtitleModeCapability(MediaControlCapabilitySupport support)
653 ValidationUtil.ValidateEnum(typeof(MediaControlCapabilitySupport), support, nameof(support));
655 Native.SetSimpleCapability(Handle, MediaControlNativeCapabilityCategory.Subtitle, support).
656 ThrowIfError("Failed to set subtitle mode capability.");
660 /// Sets the supported list of <see cref="MediaControlDisplayMode"/>.
663 /// <see cref="MediaControlCapabilitySupport.NotDecided"/> is not allowed in display mode capability.
664 /// The default value of each <see cref="MediaControlDisplayMode"/> is not supported.
666 /// <param name="capabilities">The supported list of <see cref="MediaControlDisplayMode"/>.</param>
667 /// <exception cref="InvalidOperationException">
668 /// The server is not running .<br/>
670 /// An internal error occurs.
672 /// <exception cref="ArgumentException"><paramref name="capabilities"/> is invalid.</exception>
673 /// <since_tizen> 6 </since_tizen>
674 public static void SetDisplayModeCapabilities(IDictionary<MediaControlDisplayMode, MediaControlCapabilitySupport> capabilities)
676 foreach (var pair in capabilities)
678 SetDisplayModeCapability(pair.Key, pair.Value);
683 /// Sets the <paramref name="mode"/> is supported or not.
686 /// <see cref="MediaControlCapabilitySupport.NotDecided"/> is not allowed in display mode capability.<br/>
687 /// The default value of each <see cref="MediaControlDisplayMode"/> is not supported.
689 /// <param name="mode">The <see cref="MediaControlDisplayMode"/>.</param>
690 /// <param name="support">A value indicating whether the <paramref name="mode"/> is supported or not.</param>
691 /// <exception cref="InvalidOperationException">
692 /// The server is not running .<br/>
694 /// An internal error occurs.
696 /// <exception cref="ArgumentException"><paramref name="mode"/> or <paramref name="support"/> is invalid.</exception>
697 /// <since_tizen> 6 </since_tizen>
698 public static void SetDisplayModeCapability(MediaControlDisplayMode mode, MediaControlCapabilitySupport support)
700 ValidationUtil.ValidateEnum(typeof(MediaControlDisplayMode), mode, nameof(mode));
701 ValidationUtil.ValidateEnum(typeof(MediaControlCapabilitySupport), support, nameof(support));
703 if (support == MediaControlCapabilitySupport.NotDecided)
705 throw new ArgumentException($"NotDecided is not allowed in {mode} capability.");
708 Native.SetDisplayModeCapability(Handle, (uint)mode.ToNative(), support).
709 ThrowIfError("Failed to set display mode capability.");
713 /// Sets the supported list of <see cref="Rotation"/>.
716 /// <see cref="MediaControlCapabilitySupport.NotDecided"/> is not allowed in display rotation capability.<br/>
717 /// The default value of each <see cref="Rotation"/> is not supported.
719 /// <param name="capabilities">The supported list of <see cref="Rotation"/>.</param>
720 /// <exception cref="InvalidOperationException">
721 /// The server is not running .<br/>
723 /// An internal error occurs.
725 /// <exception cref="ArgumentException"><paramref name="capabilities"/> is invalid.</exception>
726 /// <since_tizen> 6 </since_tizen>
727 public static void SetDisplayRotationCapabilities(IDictionary<Rotation, MediaControlCapabilitySupport> capabilities)
729 foreach (var pair in capabilities)
731 SetDisplayRotationCapability(pair.Key, pair.Value);
736 /// Sets the <paramref name="rotation"/> is supported or not.
739 /// <see cref="MediaControlCapabilitySupport.NotDecided"/> is not allowed in display rotation capability.<br/>
740 /// The default value of each <see cref="Rotation"/> is not supported.
742 /// <param name="rotation">The <see cref="Rotation"/>.</param>
743 /// <param name="support">A value indicating whether the <paramref name="rotation"/> is supported or not..</param>
744 /// <exception cref="InvalidOperationException">
745 /// The server is not running .<br/>
747 /// An internal error occurs.
749 /// <exception cref="ArgumentException"><paramref name="rotation"/> or <paramref name="support"/> is invalid.</exception>
750 /// <since_tizen> 6 </since_tizen>
751 public static void SetDisplayRotationCapability(Rotation rotation, MediaControlCapabilitySupport support)
753 ValidationUtil.ValidateEnum(typeof(Rotation), rotation, nameof(rotation));
754 ValidationUtil.ValidateEnum(typeof(MediaControlCapabilitySupport), support, nameof(support));
756 if (support == MediaControlCapabilitySupport.NotDecided)
758 throw new ArgumentException($"NotDecided is not allowed in {rotation} capability.");
761 Native.SetDisplayRotationCapability(Handle, (uint)rotation.ToNative(), support).
762 ThrowIfError("Failed to set display rotation capability.");
764 #endregion Capability
769 /// Requests commands to the client.
772 /// The client can request the command to execute <see cref="Command"/>, <br/>
773 /// and then, the server receive the result of each request(command).
775 /// <param name="command">A <see cref="Command"/> class.</param>
776 /// <param name="clientId">The client Id to send command.</param>
777 /// <returns><see cref="Bundle"/> represents the extra data from client and it can be null.</returns>
778 /// <exception cref="ArgumentNullException">
779 /// <paramref name="command"/> or <paramref name="clientId"/> is null.
781 /// <exception cref="InvalidOperationException">
782 /// The server has already been stopped.<br/>
784 /// An internal error occurs.
786 /// <since_tizen> 5 </since_tizen>
787 public static async Task<Bundle> RequestAsync(Command command, string clientId)
791 throw new ArgumentNullException(nameof(command));
793 if (clientId == null)
795 throw new ArgumentNullException(nameof(clientId));
798 command.SetRequestInformation(clientId);
800 var tcs = new TaskCompletionSource<MediaControllerError>();
801 string reqeustId = null;
802 Bundle bundle = null;
804 EventHandler<CommandCompletedEventArgs> eventHandler = (s, e) =>
806 if (e.RequestId == reqeustId)
809 tcs.TrySetResult(e.Result);
815 CommandCompleted += eventHandler;
817 reqeustId = command.Request(Handle);
819 (await tcs.Task).ThrowIfError("Failed to request event.");
825 CommandCompleted -= eventHandler;
830 /// Sends the result of each command.
832 /// <param name="command">The command that return to client.</param>
833 /// <param name="result">The result of <paramref name="command"/>.</param>
834 /// <param name="bundle">The extra data.</param>
835 /// <exception cref="ArgumentNullException"><paramref name="command"/> is null.</exception>
836 /// <exception cref="InvalidOperationException">
837 /// The server is not running .<br/>
839 /// An internal error occurs.
841 /// <since_tizen> 5 </since_tizen>
842 public static void Response(Command command, int result, Bundle bundle)
846 throw new ArgumentNullException(nameof(command));
849 command.Response(Handle, result, bundle);
853 /// Sends the result of each command.
855 /// <param name="command">The command that return to client.</param>
856 /// <param name="result">The result of <paramref name="command"/>.</param>
857 /// <exception cref="ArgumentNullException"><paramref name="command"/> is null.</exception>
858 /// <exception cref="InvalidOperationException">
859 /// The server is not running .<br/>
861 /// An internal error occurs.
863 /// <since_tizen> 5 </since_tizen>
864 public static void Response(Command command, int result)
866 Response(command, result, null);
870 /// Sends the result of each command.
872 /// <param name="command">The command that return to client.</param>
873 /// <param name="result">The <see cref="MediaControlResult"/> of <paramref name="command"/>.</param>
874 /// <param name="bundle">The extra data.</param>
875 /// <exception cref="ArgumentNullException"><paramref name="command"/> is null.</exception>
876 /// <exception cref="InvalidOperationException">
877 /// The server is not running .<br/>
879 /// An internal error occurs.
881 /// <since_tizen> 8 </since_tizen>
882 public static void Response(Command command, MediaControlResult result, Bundle bundle)
884 Response(command, (int)result, bundle);
888 /// Sends the result of each command.
890 /// <param name="command">The command that return to client.</param>
891 /// <param name="result">The <see cref="MediaControlResult"/> of <paramref name="command"/>.</param>
892 /// <exception cref="ArgumentNullException"><paramref name="command"/> is null.</exception>
893 /// <exception cref="InvalidOperationException">
894 /// The server is not running .<br/>
896 /// An internal error occurs.
898 /// <since_tizen> 8 </since_tizen>
899 public static void Response(Command command, MediaControlResult result)
901 Response(command, (int)result, null);