[MediaController] Add new APIs for event, capabilities and search. (#468)
authorhsgwon <haesu.gwon@samsung.com>
Wed, 19 Sep 2018 08:18:25 +0000 (17:18 +0900)
committerGitHub <noreply@github.com>
Wed, 19 Sep 2018 08:18:25 +0000 (17:18 +0900)
* [MediaController] Add new APIs for event, capabilities and search.

21 files changed:
src/Tizen.Multimedia.Remoting/Interop/Interop.Libraries.cs
src/Tizen.Multimedia.Remoting/Interop/Interop.MediaControllerClient.cs
src/Tizen.Multimedia.Remoting/Interop/Interop.MediaControllerPlaylist.cs
src/Tizen.Multimedia.Remoting/Interop/Interop.MediaControllerServer.cs
src/Tizen.Multimedia.Remoting/MediaController/CommandCompletedEventArgs.cs
src/Tizen.Multimedia.Remoting/MediaController/CustomCommandReceivedEventArgs.cs
src/Tizen.Multimedia.Remoting/MediaController/MediaControlCommand.cs
src/Tizen.Multimedia.Remoting/MediaController/MediaControlEnums.cs [moved from src/Tizen.Multimedia.Remoting/MediaController/EnumExtensions.cs with 57% similarity]
src/Tizen.Multimedia.Remoting/MediaController/MediaControlPlaybackCommand.cs [deleted file]
src/Tizen.Multimedia.Remoting/MediaController/MediaControlPlaylist.cs
src/Tizen.Multimedia.Remoting/MediaController/MediaControlSearchCondition.cs [new file with mode: 0644]
src/Tizen.Multimedia.Remoting/MediaController/MediaControlServer.Events.cs
src/Tizen.Multimedia.Remoting/MediaController/MediaControlServer.cs
src/Tizen.Multimedia.Remoting/MediaController/MediaController.Events.cs
src/Tizen.Multimedia.Remoting/MediaController/MediaController.cs
src/Tizen.Multimedia.Remoting/MediaController/MediaControllerManager.Events.cs
src/Tizen.Multimedia.Remoting/MediaController/PlaybackCapabilityUpdatedEventArgs.cs [new file with mode: 0644]
src/Tizen.Multimedia.Remoting/MediaController/PlaylistUpdatedEventArgs.cs
src/Tizen.Multimedia.Remoting/MediaController/RepeatModeCapabilityUpdatedEventArgs.cs [moved from src/Tizen.Multimedia.Remoting/MediaController/MediaControlPlaybackState.cs with 53% similarity]
src/Tizen.Multimedia.Remoting/MediaController/SearchCommandReceivedEventArgs.cs [moved from src/Tizen.Multimedia.Remoting/MediaController/MediaControllerPlaylistMode.cs with 57% similarity]
src/Tizen.Multimedia.Remoting/MediaController/ShuffleModeCapabilityUpdatedEventArgs.cs [moved from src/Tizen.Multimedia.Remoting/MediaController/MediaControllerRepeatMode.cs with 51% similarity]

index d479daa..35c3f8d 100644 (file)
@@ -22,4 +22,3 @@ internal static partial class Interop
         public const string MediaController = "libcapi-media-controller.so.0";
     }
 }
-
index becaf42..73e70de 100644 (file)
@@ -44,6 +44,9 @@ internal static partial class Interop
         internal delegate void CommandCompletedCallback(string serverName, string requestId, MediaControllerError result,
             IntPtr bundleHandle, IntPtr userData);
 
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void CustomCommandReceivedCallback(string serverName, string requestId, string customEvent, IntPtr bundleHandle, IntPtr userData);
+
 
         [DllImport(Libraries.MediaController, EntryPoint = "mc_client_create")]
         internal static extern MediaControllerError Create(out MediaControllerClientHandle handle);
@@ -86,6 +89,13 @@ internal static partial class Interop
         [DllImport(Libraries.MediaController, EntryPoint = "mc_client_unset_cmd_reply_received_cb")]
         internal static extern MediaControllerError UnsetCommandCompletedCb(MediaControllerClientHandle handle);
 
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_set_custom_event_received_cb")]
+        internal static extern MediaControllerError SetCustomEventCb(MediaControllerClientHandle handle,
+            CustomCommandReceivedCallback callback, IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_unset_custom_event_received_cb")]
+        internal static extern MediaControllerError UnsetCustomEventCb(MediaControllerClientHandle handle);
+
         [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_playback_state")]
         internal static extern MediaControllerError GetPlaybackState(IntPtr playback, out MediaControllerNativePlaybackState state);
 
@@ -144,9 +154,106 @@ internal static partial class Interop
             string serverName, string playlistName, string index, MediaControllerNativePlaybackAction mode,
             ulong position, out string requestId);
 
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_send_search_cmd")]
+        internal static extern MediaControllerError SendSearchCommand(MediaControllerClientHandle handle,
+            string serverName, IntPtr searchHandle, out string requestId);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_send_event_reply")]
+        internal static extern MediaControllerError SendCustomEventReply(MediaControllerClientHandle handle,
+            string serverName, string requestId, int result, IntPtr bundleHandle);
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_send_event_reply")]
+        internal static extern MediaControllerError SendCustomEventReplyBundle(MediaControllerClientHandle handle,
+            string serverName, string requestId, int result, SafeBundleHandle bundleHandle);
+
+
         [DllImport(Libraries.MediaController, EntryPoint = "mc_client_foreach_server")]
         internal static extern MediaControllerError ForeachActivatedServer(MediaControllerClientHandle handle,
             ActivatedServerCallback callback, IntPtr userData);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_age_rating")]
+        internal static extern MediaControllerError GetAgeRating(IntPtr playbackHandle, out int rating);
+
+        #region Capability
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void PlaybackCapabilityUpdatedCallback(string serverName, IntPtr capaHandle,
+            IntPtr userData = default(IntPtr));
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void ShuffleCapabilityUpdatedCallback(string serverName, MediaControlCapabilitySupport support,
+            IntPtr userData = default(IntPtr));
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void RepeatCapabilityUpdatedCallback(string serverName, MediaControlCapabilitySupport support,
+            IntPtr userData = default(IntPtr));
+
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_playback_content_type")]
+        internal static extern MediaControllerError GetPlaybackContentType(IntPtr playbackHandle,
+            out MediaControlContentType type);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_server_icon")]
+        internal static extern MediaControllerError GetServerIcon(MediaControllerClientHandle clientHandle,
+            string serverName, out string uri);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_server_playback_ability")]
+        internal static extern MediaControllerError GetPlaybackCapabilityHandle(MediaControllerClientHandle clientHandle,
+            string serverName, out IntPtr capaHandle);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_server_shuffle_ability_support")]
+        internal static extern MediaControllerError GetShuffleCapability(MediaControllerClientHandle clientHandle,
+            string serverName, out MediaControlCapabilitySupport type);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_server_repeat_ability_support")]
+        internal static extern MediaControllerError GetRepeatCapability(MediaControllerClientHandle clientHandle,
+            string serverName, out MediaControlCapabilitySupport type);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_set_playback_ability_updated_cb")]
+        internal static extern MediaControllerError SetPlaybackCapabilityUpdatedCb(MediaControllerClientHandle clientHandle,
+            PlaybackCapabilityUpdatedCallback callback, IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_unset_playback_ability_updated_cb")]
+        internal static extern MediaControllerError UnsetPlaybackCapabilityUpdatedCb(MediaControllerClientHandle clientHandle);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_set_shuffle_ability_updated_cb")]
+        internal static extern MediaControllerError SetShuffleCapabilityUpdatedCb(MediaControllerClientHandle clientHandle,
+            ShuffleCapabilityUpdatedCallback callback, IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_unset_shuffle_ability_updated_cb")]
+        internal static extern MediaControllerError UnsetShuffleCapabilityUpdatedCb(MediaControllerClientHandle clientHandle);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_set_repeat_ability_updated_cb")]
+        internal static extern MediaControllerError SetRepeatCapabilityUpdatedCb(MediaControllerClientHandle clientHandle,
+            RepeatCapabilityUpdatedCallback callback, IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_unset_repeat_ability_updated_cb")]
+        internal static extern MediaControllerError UnsetRepeatCapabilityUpdatedCb(MediaControllerClientHandle clientHandle);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_playback_ability_clone")]
+        internal static extern MediaControllerError CloneCapability(IntPtr capaSrcHandle, out IntPtr capaDstHandle);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_playback_ability_destroy")]
+        internal static extern MediaControllerError DestroyCapability(IntPtr capaHandle);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_playback_action_is_supported")]
+        internal static extern MediaControllerError IsCapabilitySupported(IntPtr capaHandle,
+            MediaControllerNativePlaybackAction action, out MediaControlCapabilitySupport support);
+        #endregion Capability
+
+        #region Search
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_search_create")]
+        internal static extern MediaControllerError CreateSearchHandle(out IntPtr searchHandle);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_search_set_condition")]
+        internal static extern MediaControllerError SetSearchCondition(IntPtr searchHandle,
+            MediaControlContentType type, MediaControlSearchCategory category, string keyword, IntPtr bundle);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_search_set_condition")]
+        internal static extern MediaControllerError SetSearchConditionBundle(IntPtr searchHandle,
+            MediaControlContentType type, MediaControlSearchCategory category, string keyword, SafeBundleHandle bundle);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_search_destroy")]
+        internal static extern MediaControllerError DestroySearchHandle(IntPtr searchHandle);
+        #endregion Search
     }
 
     internal class MediaControllerClientHandle : SafeHandle
index 1d37ca5..8877da3 100644 (file)
@@ -99,15 +99,15 @@ internal static partial class Interop
             string serverName, PlaylistCallback callback, IntPtr userData);
 
         [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_playlist_item_index")]
-        private static extern MediaControllerError GetPlaylistIndex(IntPtr handle, out IntPtr index);
+        private static extern MediaControllerError GetPlaylistIndex(IntPtr playbackHandle, out IntPtr index);
 
-        internal static string GetPlaylistIndex(IntPtr handle)
+        internal static string GetPlaylistIndex(IntPtr playbackHandle)
         {
             IntPtr valuePtr = IntPtr.Zero;
 
             try
             {
-                GetPlaylistIndex(handle, out valuePtr).ThrowIfError($"Failed to get playlist.");
+                GetPlaylistIndex(playbackHandle, out valuePtr).ThrowIfError($"Failed to get playlist.");
                 return Marshal.PtrToStringAnsi(valuePtr);
             }
             finally
@@ -116,6 +116,26 @@ internal static partial class Interop
             }
         }
 
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_playlist_item_info")]
+        internal static extern MediaControllerError GetPlaylistInfo(IntPtr playbackHandle, out IntPtr playlistName, out IntPtr index);
+
+        internal static string GetPlaylistInfo(IntPtr playbackHandle)
+        {
+            IntPtr playlistName = IntPtr.Zero;
+            IntPtr index = IntPtr.Zero;
+
+            try
+            {
+                GetPlaylistInfo(playbackHandle, out playlistName, out index).ThrowIfError($"Failed to get playlist info.");
+                return Marshal.PtrToStringAnsi(playlistName);
+            }
+            finally
+            {
+                Tizen.Multimedia.LibcSupport.Free(playlistName);
+                Tizen.Multimedia.LibcSupport.Free(index);
+            }
+        }
+
         [DllImport(Libraries.MediaController, EntryPoint = "mc_playlist_get_name")]
         private static extern MediaControllerError GetPlaylistName(IntPtr handle, out IntPtr name);
 
index ce0fe1c..ee4a97b 100644 (file)
@@ -53,7 +53,22 @@ internal static partial class Interop
             string requestId, string customCommand, IntPtr bundleHandle, IntPtr userData);
 
         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate void PlaylistCallback(IntPtr handle, IntPtr userData);
+        internal delegate bool PlaylistCallback(IntPtr handle, IntPtr userData);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate bool ActivatedClientCallback(string clientName, IntPtr userData);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void CommandCompletedCallback(string clientName, string requestId, MediaControllerError result, IntPtr bundleHandle,
+            IntPtr userData = default(IntPtr));
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void SearchCommandReceivedCallback(string clientName, string requestId, IntPtr searchHandle,
+            IntPtr userData = default(IntPtr));
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate bool SearchItemCallback(MediaControlContentType type, MediaControlSearchCategory category,
+            string keyword, IntPtr bundleHandle, IntPtr userData = default(IntPtr));
 
 
         [DllImport(Libraries.MediaController, EntryPoint = "mc_server_create")]
@@ -135,6 +150,13 @@ internal static partial class Interop
         [DllImport(Libraries.MediaController, EntryPoint = "mc_server_unset_custom_cmd_received_cb")]
         internal static extern MediaControllerError UnsetCustomCommandReceivedCb(IntPtr handle);
 
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_set_search_cmd_received_cb")]
+        internal static extern MediaControllerError SetSearchCommandReceivedCb(IntPtr handle,
+            SearchCommandReceivedCallback callback, IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_unset_search_cmd_received_cb")]
+        internal static extern MediaControllerError UnsetSearchCommandReceivedCb(IntPtr handle);
+
         [DllImport(Libraries.MediaController, EntryPoint = "mc_server_send_cmd_reply")]
         internal static extern MediaControllerError SendCommandReplyBundle(IntPtr handle,
             string appId, string requestID, int result, SafeBundleHandle bundleHandle);
@@ -174,5 +196,65 @@ internal static partial class Interop
         // Playlist API. but this need to server handle so have to be here.
         [DllImport(Libraries.MediaController, EntryPoint = "mc_server_get_playlist")]
         internal static extern MediaControllerError GetPlaylistHandle(IntPtr handle, string name, out IntPtr playbackHandle);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_foreach_client")]
+        internal static extern MediaControllerError ForeachActivatedClient(IntPtr handle, ActivatedClientCallback callback,
+            IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_send_custom_event")]
+        internal static extern MediaControllerError SendCustomEvent(IntPtr handle, string appId, string customEvent,
+            IntPtr bundle, out string requestId);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_send_custom_event")]
+        internal static extern MediaControllerError SendCustomEventBundle(IntPtr handle, string appId, string customEvent,
+            SafeBundleHandle bundle, out string requestId);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_set_event_reply_received_cb")]
+        internal static extern MediaControllerError SetEventReceivedCb(IntPtr handle, CommandCompletedCallback callback,
+            IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_unset_event_reply_received_cb")]
+        internal static extern MediaControllerError UnsetEventReceivedCb(IntPtr handle);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_set_content_age_rating")]
+        internal static extern MediaControllerError SetAgeRating(IntPtr handle, int rating);
+
+
+        #region Capability
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_set_playback_content_type")]
+        internal static extern MediaControllerError SetPlaybackContentType(IntPtr serverHandle,
+            MediaControlContentType type);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_set_icon")]
+        internal static extern MediaControllerError SetIconPath(IntPtr serverHandle, string uri);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_set_playback_ability")]
+        internal static extern MediaControllerError SetPlaybackCapability(IntPtr serverHandle,
+            MediaControllerNativePlaybackAction action, MediaControlCapabilitySupport support);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_update_playback_ability")]
+        internal static extern MediaControllerError SaveAndNotifyPlaybackCapabilityUpdated(IntPtr serverHandle);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_set_shuffle_ability")]
+        internal static extern MediaControllerError SetShuffleModeCapability(IntPtr serverHandle,
+            MediaControlCapabilitySupport support);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_set_repeat_ability")]
+        internal static extern MediaControllerError SetRepeatModeCapability(IntPtr serverHandle,
+            MediaControlCapabilitySupport support);
+        #endregion Capability
+
+        #region Search
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_search_foreach")]
+        internal static extern MediaControllerError ForeachSearchCondition(IntPtr serverHandle,
+            SearchItemCallback callback, IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_search_clone")]
+        internal static extern MediaControllerError CloneSearchHandle(IntPtr srcHandle, out IntPtr dstHandle);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_search_destroy")]
+        internal static extern MediaControllerError DestroySearchHandle(IntPtr searchHandle);
+
+        #endregion Search
     }
 }
index a78351d..0741fd0 100644 (file)
@@ -20,7 +20,8 @@ using Tizen.Applications;
 namespace Tizen.Multimedia.Remoting
 {
     /// <summary>
-    /// Provides data for the <see cref="MediaController.CommandCompleted"/> event.
+    /// Provides data for the <see cref="MediaController.CommandCompleted"/> or
+    /// <see cref="MediaControlServer.CommandCompleted"/>event.
     /// </summary>
     /// <since_tizen> 5 </since_tizen>
     internal class CommandCompletedEventArgs : EventArgs
index 9c65aba..e18594f 100644 (file)
  */
 
 using System;
-using Tizen.Applications;
 
 namespace Tizen.Multimedia.Remoting
 {
     /// <summary>
-    /// Provides data for the <see cref="MediaControlServer.CustomCommandReceived"/> event.
+    /// Provides data for the <see cref="MediaControlServer.CustomCommandReceived"/> or
+    /// <see cref="MediaController.CustomCommandReceived"/> event.
     /// </summary>
     /// <since_tizen> 5 </since_tizen>
     public class CustomCommandReceivedEventArgs : EventArgs
index 769d00b..9f7d88d 100644 (file)
@@ -16,6 +16,7 @@
 
 using Tizen.Applications;
 using System;
+using System.Collections.Generic;
 using NativeClient = Interop.MediaControllerClient;
 using NativeServer = Interop.MediaControllerServer;
 using NativeClientHandle = Interop.MediaControllerClientHandle;
@@ -30,58 +31,110 @@ namespace Tizen.Multimedia.Remoting
     {
         private string _requestId;
 
-        internal NativeClientHandle _clientHandle;
-
-        private string _clientId;
-
         /// <summary>
-        /// The server id.
+        /// The id for command receiver.
         /// </summary>
         /// <since_tizen> 5 </since_tizen>
-        protected string _serverId;
+        protected string ReceiverId { get; private set; }
 
         /// <summary>
         /// Initializes a <see cref="Command"/> base class.
         /// </summary>
+        /// <since_tizen> 5 </since_tizen>
         protected Command() { }
 
-        internal abstract string Request();
-
-        internal void Response(IntPtr handle, int result, Bundle bundle)
-        {
-            if (bundle != null)
-            {
-                NativeServer.SendCommandReplyBundle(handle, _clientId, _requestId, result, bundle.SafeBundleHandle)
-                    .ThrowIfError("Failed to response command.");
-            }
-            else
-            {
-                NativeServer.SendCommandReply(handle, _clientId, _requestId, result, IntPtr.Zero)
-                    .ThrowIfError("Failed to response command.");
-            }
-        }
-
         /// <summary>
         /// Sets the server information.
         /// </summary>
-        /// <param name="clientrHandle">The client handle.</param>
-        /// <param name="serverId">The server Id that receives command.</param>
-        internal void SetServerInfo(NativeClientHandle clientrHandle, string serverId)
+        /// <param name="receiverId">The receiver Id that receives command.</param>
+        internal void SetRequestInformation(string receiverId)
         {
-            _serverId = serverId;
-            _clientHandle = clientrHandle;
+            ReceiverId = receiverId;
         }
 
         /// <summary>
         /// Sets the client information.
         /// </summary>
-        /// <param name="clientId">The client Id that will be received response.</param>
+        /// <param name="receiverId">The receiver Id that receives response for command.</param>
         /// <param name="requestId">The request Id for each command.</param>
-        internal void SetClientInfo(string clientId, string requestId)
+        internal void SetResponseInformation(string receiverId, string requestId)
         {
-            _clientId = clientId;
+            ReceiverId = receiverId;
             _requestId = requestId;
         }
+
+        /// <summary>
+        /// Requests command to server.
+        /// </summary>
+        /// <returns>The request id for each command.</returns>
+        internal abstract string Request(NativeClientHandle clientHandle);
+
+        /// <summary>
+        /// Requests command to client.
+        /// </summary>
+        /// <param name="serverHandle"></param>
+        /// <returns>The request id for each command.</returns>
+        internal virtual string Request(IntPtr serverHandle) => throw new NotImplementedException();
+
+        /// <summary>
+        /// Represents a method that is called when an response command completes.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        protected virtual void OnResponseCompleted() { }
+
+        /// <summary>
+        /// Responses command to the client.
+        /// </summary>
+        /// <param name="serverHandle">The server handle.</param>
+        /// <param name="result">The result of each command.</param>
+        /// <param name="bundle">The extra data.</param>
+        internal void Response(IntPtr serverHandle, int result, Bundle bundle)
+        {
+            try
+            {
+                if (bundle != null)
+                {
+                    NativeServer.SendCommandReplyBundle(serverHandle, ReceiverId, _requestId, result, bundle.SafeBundleHandle)
+                        .ThrowIfError("Failed to response command.");
+                }
+                else
+                {
+                    NativeServer.SendCommandReply(serverHandle, ReceiverId, _requestId, result, IntPtr.Zero)
+                        .ThrowIfError("Failed to response command.");
+                }
+            }
+            finally
+            {
+                OnResponseCompleted();
+            }
+        }
+
+        /// <summary>
+        /// Responses command to the server.
+        /// </summary>
+        /// <param name="clientHandle">The client handle.</param>
+        /// <param name="result">The result of each command.</param>
+        /// <param name="bundle">The extra data.</param>
+        internal void Response(NativeClientHandle clientHandle, int result, Bundle bundle)
+        {
+            try
+            {
+                if (bundle != null)
+                {
+                    NativeClient.SendCustomEventReplyBundle(clientHandle, ReceiverId, _requestId, result, bundle.SafeBundleHandle)
+                        .ThrowIfError("Failed to response event.");
+                }
+                else
+                {
+                    NativeClient.SendCustomEventReply(clientHandle, ReceiverId, _requestId, result, IntPtr.Zero)
+                        .ThrowIfError("Failed to repose event.");
+                }
+            }
+            finally
+            {
+                OnResponseCompleted();
+            }
+        }
     }
 
 
@@ -106,11 +159,11 @@ namespace Tizen.Multimedia.Remoting
         /// <since_tizen> 5 </since_tizen>
         public MediaControlPlaybackCommand Action { get; }
 
-        internal override string Request()
+        internal override string Request(NativeClientHandle clientHandle)
         {
             ValidationUtil.ValidateEnum(typeof(MediaControlPlaybackCommand), Action, nameof(MediaControlPlaybackCommand));
 
-            NativeClient.SendPlaybackActionCommand(_clientHandle, _serverId, Action.ToNative(), out string requestId)
+            NativeClient.SendPlaybackActionCommand(clientHandle, ReceiverId, Action.ToNative(), out string requestId)
                 .ThrowIfError("Failed to send playback command.");
 
             return requestId;
@@ -138,9 +191,9 @@ namespace Tizen.Multimedia.Remoting
         /// <since_tizen> 5 </since_tizen>
         public ulong Position { get; }
 
-        internal override string Request()
+        internal override string Request(NativeClientHandle clientHandle)
         {
-            NativeClient.SendPlaybackPositionCommand(_clientHandle, _serverId, Position, out string requestId)
+            NativeClient.SendPlaybackPositionCommand(clientHandle, ReceiverId, Position, out string requestId)
                 .ThrowIfError("Failed to send playback position command.");
 
             return requestId;
@@ -167,8 +220,8 @@ namespace Tizen.Multimedia.Remoting
         public PlaylistCommand(MediaControlPlaybackCommand action, string playlistName, string index, ulong position)
         {
             Action = action;
-            Index = index ?? throw new ArgumentNullException("Playlist index is not set.");
-            Name = playlistName ?? throw new ArgumentNullException("Playlist name is not set.");
+            Index = index ?? throw new ArgumentNullException(nameof(index));
+            Name = playlistName ?? throw new ArgumentNullException(nameof(playlistName));
             Position = position;
         }
 
@@ -180,7 +233,7 @@ namespace Tizen.Multimedia.Remoting
         /// <param name="index">The index of the media in the playlist.</param>
         /// <exception cref="ArgumentException"><paramref name="index"/> cannot be converted to number.</exception>
         /// <exception cref="ArgumentNullException">
-        /// <paramref name="playlistName"/> or <paramref name="index"/> is not set.
+        /// <paramref name="playlistName"/> or <paramref name="index"/> is null.
         /// </exception>
         /// <since_tizen> 5 </since_tizen>
         public PlaylistCommand(MediaControlPlaybackCommand action, string playlistName, string index)
@@ -212,11 +265,11 @@ namespace Tizen.Multimedia.Remoting
         /// <since_tizen> 5 </since_tizen>
         public string Name { get; }
 
-        internal override string Request()
+        internal override string Request(NativeClientHandle clientHandle)
         {
             ValidationUtil.ValidateEnum(typeof(MediaControlPlaybackCommand), Action, nameof(MediaControlPlaybackCommand));
 
-            NativeClient.SendPlaylistCommand(_clientHandle, _serverId, Name, Index, Action.ToNative(),
+            NativeClient.SendPlaylistCommand(clientHandle, ReceiverId, Name, Index, Action.ToNative(),
                 Position, out string requestId).ThrowIfError("Failed to send playlist command.");
 
             return requestId;
@@ -244,11 +297,11 @@ namespace Tizen.Multimedia.Remoting
         /// </summary>
         public bool Enabled { get; }
 
-        internal override string Request()
+        internal override string Request(NativeClientHandle clientHandle)
         {
             var mode = Enabled ? MediaControllerNativeShuffleMode.On : MediaControllerNativeShuffleMode.Off;
 
-            NativeClient.SendShuffleModeCommand(_clientHandle, _serverId, mode, out string requestId).
+            NativeClient.SendShuffleModeCommand(clientHandle, ReceiverId, mode, out string requestId).
                 ThrowIfError("Failed to send playback shuffle command.");
 
             return requestId;
@@ -277,11 +330,11 @@ namespace Tizen.Multimedia.Remoting
         /// <since_tizen> 5 </since_tizen>
         public MediaControlRepeatMode Mode { get; }
 
-        internal override string Request()
+        internal override string Request(NativeClientHandle clientHandle)
         {
             ValidationUtil.ValidateEnum(typeof(MediaControlRepeatMode), Mode, nameof(MediaControlRepeatMode));
 
-            NativeClient.SendRepeatModeCommand(_clientHandle, _serverId, Mode.ToNative(), out string requestId).
+            NativeClient.SendRepeatModeCommand(clientHandle, ReceiverId, Mode.ToNative(), out string requestId).
                 ThrowIfError("Failed to send playback repeat command.");
 
             return requestId;
@@ -291,6 +344,7 @@ namespace Tizen.Multimedia.Remoting
     /// <summary>
     /// Provides a means to to send custom commands.
     /// </summary>
+    /// <remarks>This command can be used by both client and server to send predefined command or data.</remarks>
     /// <since_tizen> 5 </since_tizen>
     public sealed class CustomCommand : Command
     {
@@ -301,7 +355,7 @@ namespace Tizen.Multimedia.Remoting
         /// <since_tizen> 5 </since_tizen>
         public CustomCommand(string action)
         {
-            Action = action ?? throw new ArgumentNullException("Custom command is not set.");
+            Action = action ?? throw new ArgumentNullException(nameof(action));
         }
 
         /// <summary>
@@ -328,22 +382,199 @@ namespace Tizen.Multimedia.Remoting
         /// <since_tizen> 5 </since_tizen>
         public Bundle Bundle { get; }
 
-        internal override string Request()
+        internal override string Request(NativeClientHandle clientHandle)
         {
             string requestId = null;
 
             if (Bundle != null)
             {
-                NativeClient.SendCustomCommandBundle(_clientHandle, _serverId, Action, Bundle.SafeBundleHandle, out requestId).
+                NativeClient.SendCustomCommandBundle(clientHandle, ReceiverId, Action, Bundle.SafeBundleHandle, out requestId).
                     ThrowIfError("Failed to send custom command.");
             }
             else
             {
-                NativeClient.SendCustomCommand(_clientHandle, _serverId, Action, IntPtr.Zero, out requestId).
+                NativeClient.SendCustomCommand(clientHandle, ReceiverId, Action, IntPtr.Zero, out requestId).
                     ThrowIfError("Failed to send custom command.");
             }
 
             return requestId;
         }
+
+        internal override string Request(IntPtr serverHandle)
+        {
+            string requestId = null;
+
+            if (Bundle != null)
+            {
+                NativeServer.SendCustomEventBundle(serverHandle, ReceiverId, Action, Bundle.SafeBundleHandle, out requestId)
+                    .ThrowIfError("Failed to send costom event.");
+            }
+            else
+            {
+                NativeServer.SendCustomEvent(serverHandle, ReceiverId, Action, IntPtr.Zero, out requestId)
+                    .ThrowIfError("Failed to send costom event.");
+            }
+
+            return requestId;
+        }
+    }
+
+    /// <summary>
+    /// Provides a means to to send search commands.
+    /// </summary>
+    /// <since_tizen> 5 </since_tizen>
+    public sealed class SearchCommand : Command
+    {
+        private readonly IntPtr _searchHandle;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="SearchCommand"/> class.
+        /// </summary>
+        /// <remarks>User can search maximum 20 items once.</remarks>
+        /// <exception cref="ArgumentNullException"><paramref name="conditions"/> is not set.</exception>
+        /// <exception cref="ArgumentException">
+        ///     <paramref name="conditions.Count"/> is greater than maximum value(20).<br/>
+        ///     -or-<br/>
+        ///     <paramref name="conditions.Count"/> is less than 1.
+        /// </exception>
+        /// <exception cref="InvalidOperationException">An internal error occurs.</exception>
+        /// <param name="conditions">The set of <see cref="MediaControlSearchCondition"/>.</param>
+        /// <since_tizen> 5 </since_tizen>
+        public SearchCommand(List<MediaControlSearchCondition> conditions)
+        {
+            if (conditions == null)
+            {
+                throw new ArgumentNullException(nameof(conditions));
+            }
+            if (conditions.Count <= 0 || conditions.Count > 20)
+            {
+                var errMessage = $"Invalid number of search conditions. : {conditions.Count}. " +
+                    $"Valid range is 1 ~ 20.";
+                throw new ArgumentException(errMessage);
+            }
+
+            NativeClient.CreateSearchHandle(out _searchHandle).ThrowIfError("Failed to create search handle.");
+
+            try
+            {
+                foreach (var condition in conditions)
+                {
+                    if (condition.Bundle != null)
+                    {
+                        NativeClient.SetSearchConditionBundle(_searchHandle, condition.ContentType, condition.Category,
+                            condition.Keyword, condition.Bundle.SafeBundleHandle).
+                            ThrowIfError("Failed to set search condition.");
+                    }
+                    else
+                    {
+                        NativeClient.SetSearchCondition(_searchHandle, condition.ContentType, condition.Category,
+                            condition.Keyword, IntPtr.Zero).
+                            ThrowIfError("Failed to set search condition.");
+                    }
+                }
+            }
+            catch
+            {
+                if (_searchHandle != IntPtr.Zero)
+                {
+                    NativeClient.DestroySearchHandle(_searchHandle).ThrowIfError("Failed to destroy search handle");
+                }
+                throw;
+            }
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="SearchCommand"/> class.
+        /// </summary>
+        /// <exception cref="InvalidOperationException">An internal error occurs.</exception>
+        /// <param name="condition">The set of <see cref="MediaControlSearchCondition"/>.</param>
+        /// <since_tizen> 5 </since_tizen>
+        public SearchCommand(MediaControlSearchCondition condition)
+        {
+            NativeClient.CreateSearchHandle(out _searchHandle).ThrowIfError("Failed to create search handle.");
+
+            try
+            {   
+                if (condition.Bundle != null)
+                {
+                    NativeClient.SetSearchConditionBundle(_searchHandle, condition.ContentType, condition.Category,
+                        condition.Keyword, condition.Bundle.SafeBundleHandle).
+                        ThrowIfError("Failed to set search condition.");
+                }
+                else
+                {
+                    NativeClient.SetSearchCondition(_searchHandle, condition.ContentType, condition.Category,
+                        condition.Keyword, IntPtr.Zero).
+                        ThrowIfError("Failed to set search condition.");
+                }
+            }
+            catch
+            {
+                if (_searchHandle != IntPtr.Zero)
+                {
+                    NativeClient.DestroySearchHandle(_searchHandle).ThrowIfError("Failed to destroy search handle");
+                }
+                throw;
+            }
+        }
+
+        internal SearchCommand(List<MediaControlSearchCondition> conditions, IntPtr searchHandle)
+        {
+            _searchHandle = searchHandle;
+
+            try
+            {
+                foreach (var condition in conditions)
+                {
+                    if (condition.Bundle != null)
+                    {
+                        NativeClient.SetSearchConditionBundle(_searchHandle, condition.ContentType, condition.Category,
+                            condition.Keyword, condition.Bundle.SafeBundleHandle).
+                            ThrowIfError("Failed to set search condition.");
+                    }
+                    else
+                    {
+                        NativeClient.SetSearchCondition(_searchHandle, condition.ContentType, condition.Category,
+                            condition.Keyword, IntPtr.Zero).
+                            ThrowIfError("Failed to set search condition.");
+                    }
+                }
+            }
+            catch
+            {
+                if (_searchHandle != IntPtr.Zero)
+                {
+                    NativeClient.DestroySearchHandle(_searchHandle).ThrowIfError("Failed to destroy search handle");
+                }
+                throw;
+            }
+        }
+
+        internal override string Request(NativeClientHandle clientHandle)
+        {
+            NativeClient.SendSearchCommand(clientHandle, ReceiverId, _searchHandle, out string requestId).
+                ThrowIfError("Failed to send search command.");
+
+            if (_searchHandle != IntPtr.Zero)
+            {
+                NativeClient.DestroySearchHandle(_searchHandle).ThrowIfError("Failed to destroy search handle");
+            }
+
+            return requestId;
+        }
+
+        /// <summary>
+        /// Represents a method that is called when an response command completes.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        protected override void OnResponseCompleted()
+        {
+            base.OnResponseCompleted();
+
+            if (_searchHandle != IntPtr.Zero)
+            {
+                NativeClient.DestroySearchHandle(_searchHandle).ThrowIfError("Failed to destroy search handle");
+            }
+        }
     }
 }
\ No newline at end of file
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
  *
  * Licensed under the Apache License, Version 2.0 (the License);
  * you may not use this file except in compliance with the License.
@@ -19,6 +19,234 @@ using System.Diagnostics;
 
 namespace Tizen.Multimedia.Remoting
 {
+    /// <summary>
+    /// Specifies the playlist mode.
+    /// </summary>
+    /// <since_tizen> 5 </since_tizen>
+    public enum MediaControlPlaylistMode
+    {
+        /// <summary>
+        /// Playlist is created or update.
+        /// </summary>
+        Updated,
+
+        /// <summary>
+        /// Playlist is removed.
+        /// </summary>
+        Removed,
+    }
+
+    /// <summary>
+    /// Specifies the repeat mode.
+    /// </summary>
+    /// <since_tizen> 4 </since_tizen>
+    public enum MediaControlRepeatMode
+    {
+        /// <summary>
+        /// Off.
+        /// </summary>
+        Off,
+
+        /// <summary>
+        /// On.
+        /// </summary>
+        On,
+
+        /// <summary>
+        /// One media.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        OneMedia
+    }
+
+    /// <summary>
+    /// Specifies playback commands.
+    /// </summary>
+    /// <since_tizen> 4 </since_tizen>
+    public enum MediaControlPlaybackCommand
+    {
+        /// <summary>
+        /// Play.
+        /// </summary>
+        Play,
+
+        /// <summary>
+        /// Pause.
+        /// </summary>
+        Pause,
+
+        /// <summary>
+        /// Stop.
+        /// </summary>
+        Stop,
+
+        /// <summary>
+        /// Skip to next.
+        /// </summary>
+        Next,
+
+        /// <summary>
+        /// Skip to previous.
+        /// </summary>
+        Previous,
+
+        /// <summary>
+        /// Fast forward.
+        /// </summary>
+        FastForward,
+
+        /// <summary>
+        /// Rewind.
+        /// </summary>
+        Rewind,
+
+        /// <summary>
+        /// Toggle play/pause.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        Toggle,
+    }
+
+    /// <summary>
+    /// Specifies playback states.
+    /// </summary>
+    /// <since_tizen> 4 </since_tizen>
+    public enum MediaControlPlaybackState
+    {
+        /// <summary>
+        /// Unknown; no state is set.
+        /// </summary>
+        None,
+
+        /// <summary>
+        /// Playing.
+        /// </summary>
+        Playing,
+
+        /// <summary>
+        /// Paused.
+        /// </summary>
+        Paused,
+
+        /// <summary>
+        /// Stopped.
+        /// </summary>
+        Stopped,
+
+        /// <summary>
+        /// Fast forwarding.
+        /// </summary>
+        FastForwarding,
+
+        /// <summary>
+        /// Rewinding.
+        /// </summary>
+        Rewinding,
+
+        /// <summary>
+        /// Skipping to the next item.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        MovingToNext,
+
+        /// <summary>
+        /// Skipping to the previous item.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        MovingToPrevious,
+    }
+
+    /// <summary>
+    /// Specifies the support type of media control capability.
+    /// </summary>
+    /// <since_tizen> 5 </since_tizen>
+    public enum MediaControlCapabilitySupport
+    {
+        /// <summary>
+        /// Supported.
+        /// </summary>
+        Supported,
+
+        /// <summary>
+        /// Not supported.
+        /// </summary>
+        NotSupported,
+
+        /// <summary>
+        /// There's no support info in server.
+        /// </summary>
+        NotDecided
+    }
+
+    /// <summary>
+    /// Specifies the content type.
+    /// </summary>
+    /// <since_tizen> 5 </since_tizen>
+    public enum MediaControlContentType
+    {
+        /// <summary>
+        /// Image type.
+        /// </summary>
+        Image,
+
+        /// <summary>
+        /// Video type.
+        /// </summary>
+        Video,
+
+        /// <summary>
+        /// Music type.
+        /// </summary>
+        Music,
+
+        /// <summary>
+        /// Other type.
+        /// </summary>
+        Other,
+
+        /// <summary>
+        /// There's no content type info in server.
+        /// </summary>
+        NotDecided
+    }
+
+    /// <summary>
+    /// Specifies the search category.
+    /// </summary>
+    /// <since_tizen> 5 </since_tizen>
+    public enum MediaControlSearchCategory
+    {
+        /// <summary>
+        /// Search by all category.
+        /// </summary>
+        All,
+
+        /// <summary>
+        /// Search by content title.
+        /// </summary>
+        Title,
+
+        /// <summary>
+        /// Search by content artist.
+        /// </summary>
+        Artist,
+
+        /// <summary>
+        /// Search by content album.
+        /// </summary>
+        Album,
+
+        /// <summary>
+        /// Search by content genre.
+        /// </summary>
+        Genre,
+
+        /// <summary>
+        /// Search by TPO(Time Place Occasion).
+        /// </summary>
+        Tpo
+    }
+
     internal static class EnumExtensions
     {
         internal static MediaControlPlaybackState ToPublic(this MediaControllerNativePlaybackState nativeState)
@@ -92,14 +320,6 @@ namespace Tizen.Multimedia.Remoting
             return MediaControllerNativePlaybackAction.Play;
         }
 
-        internal static MediaControllerNativeRepeatMode ToNative(this MediaControlRepeatMode mode)
-        {
-            Debug.Assert(Enum.IsDefined(typeof(MediaControlRepeatMode), mode));
-
-            return mode == MediaControlRepeatMode.Off ? MediaControllerNativeRepeatMode.On :
-                (mode == MediaControlRepeatMode.On ? MediaControllerNativeRepeatMode.Off : MediaControllerNativeRepeatMode.OneMedia);
-        }
-
         internal static MediaControlRepeatMode ToPublic(this MediaControllerNativeRepeatMode mode)
         {
             Debug.Assert(Enum.IsDefined(typeof(MediaControllerNativeRepeatMode), mode));
@@ -107,5 +327,13 @@ namespace Tizen.Multimedia.Remoting
             return mode == MediaControllerNativeRepeatMode.Off ? MediaControlRepeatMode.On :
                 (mode == MediaControllerNativeRepeatMode.On ? MediaControlRepeatMode.Off : MediaControlRepeatMode.OneMedia);
         }
+
+        internal static MediaControllerNativeRepeatMode ToNative(this MediaControlRepeatMode mode)
+        {
+            Debug.Assert(Enum.IsDefined(typeof(MediaControlRepeatMode), mode));
+
+            return mode == MediaControlRepeatMode.Off ? MediaControllerNativeRepeatMode.On :
+                (mode == MediaControlRepeatMode.On ? MediaControllerNativeRepeatMode.Off : MediaControllerNativeRepeatMode.OneMedia);
+        }
     }
 }
\ No newline at end of file
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/MediaControlPlaybackCommand.cs b/src/Tizen.Multimedia.Remoting/MediaController/MediaControlPlaybackCommand.cs
deleted file mode 100644 (file)
index 1a924d4..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-namespace Tizen.Multimedia.Remoting
-{
-    /// <summary>
-    /// Specifies playback commands.
-    /// </summary>
-    /// <since_tizen> 4 </since_tizen>
-    public enum MediaControlPlaybackCommand
-    {
-        /// <summary>
-        /// Play.
-        /// </summary>
-        Play,
-
-        /// <summary>
-        /// Pause.
-        /// </summary>
-        Pause,
-
-        /// <summary>
-        /// Stop.
-        /// </summary>
-        Stop,
-
-        /// <summary>
-        /// Skip to next.
-        /// </summary>
-        Next,
-
-        /// <summary>
-        /// Skip to previous.
-        /// </summary>
-        Previous,
-
-        /// <summary>
-        /// Fast forward.
-        /// </summary>
-        FastForward,
-
-        /// <summary>
-        /// Rewind.
-        /// </summary>
-        Rewind,
-
-        /// <summary>
-        /// Toggle play/pause.
-        /// </summary>
-        /// <since_tizen> 5 </since_tizen>
-        Toggle,
-    }
-}
\ No newline at end of file
index 163a249..5cc1af6 100644 (file)
@@ -29,7 +29,7 @@ namespace Tizen.Multimedia.Remoting
     public class MediaControlPlaylist : IDisposable
     {
         private IntPtr _handle;
-        private Dictionary<string, MediaControlMetadata> _metadata = null;
+        private Dictionary<string, MediaControlMetadata> _metadata = new Dictionary<string, MediaControlMetadata>();
 
         /// <summary>
         /// Initializes a new instance of the <see cref="MediaControlPlaylist"/> class by server side.
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/MediaControlSearchCondition.cs b/src/Tizen.Multimedia.Remoting/MediaController/MediaControlSearchCondition.cs
new file mode 100644 (file)
index 0000000..4ed37ba
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using Tizen.Applications;
+using NativeClient = Interop.MediaControllerClient;
+using NativeServer = Interop.MediaControllerServer;
+using NativePlaylist = Interop.MediaControllerPlaylist;
+
+namespace Tizen.Multimedia.Remoting
+{
+    /// <summary>
+    /// Represents the search conditions.
+    /// </summary>
+    /// <since_tizen> 5 </since_tizen>
+    public class MediaControlSearchCondition
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="MediaControlSearchCondition"/> class.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        public MediaControlSearchCondition(MediaControlContentType type, MediaControlSearchCategory category,
+            string keyword, Bundle bundle)
+            : this (type, keyword, bundle)
+        {
+            ValidationUtil.ValidateEnum(typeof(MediaControlSearchCategory), category, nameof(category));
+
+            Category = category;
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="MediaControlSearchCondition"/> class.
+        /// </summary>
+        /// <remarks>The <see cref="MediaControlSearchCategory"/> will be set internally by <see cref="MediaControlSearchCategory.All"/>.</remarks>
+        /// <since_tizen> 5 </since_tizen>
+        public MediaControlSearchCondition(MediaControlContentType type, string keyword, Bundle bundle)
+        {
+            ValidationUtil.ValidateEnum(typeof(MediaControlContentType), type, nameof(type));
+
+            Category = MediaControlSearchCategory.All;
+            ContentType = type;
+            Keyword = keyword ?? throw new ArgumentNullException(nameof(keyword));
+            Bundle = bundle;
+        }
+
+        /// <summary>
+        /// Gets the search content type.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        public MediaControlContentType ContentType { get; }
+
+        /// <summary>
+        /// Gets the search category.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        public MediaControlSearchCategory Category { get; }
+
+        /// <summary>
+        /// Gets the search keyword.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        public string Keyword { get; }
+
+        /// <summary>
+        /// Gets the extra data.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        public Bundle Bundle { get; }
+    }
+}
\ No newline at end of file
index 951ad77..8b8b689 100644 (file)
@@ -16,6 +16,7 @@
 
 using Tizen.Applications;
 using System;
+using System.Collections.Generic;
 using Native = Interop.MediaControllerServer;
 
 namespace Tizen.Multimedia.Remoting
@@ -29,6 +30,8 @@ namespace Tizen.Multimedia.Remoting
         private static Native.ShuffleModeCommandReceivedCallback _shuffleModeCommandCallback;
         private static Native.RepeatModeCommandReceivedCallback _repeatModeCommandCallback;
         private static Native.CustomCommandReceivedCallback _customCommandCallback;
+        private static Native.SearchCommandReceivedCallback _searchCommandCallback;
+        private static Native.CommandCompletedCallback _commandCompletedCallback;
 
         /// <summary>
         /// Occurs when a client sends playback command.
@@ -73,6 +76,18 @@ namespace Tizen.Multimedia.Remoting
         /// <since_tizen> 5 </since_tizen>
         public static event EventHandler<CustomCommandReceivedEventArgs> CustomCommandReceived;
 
+        /// <summary>
+        /// Occurs when a client sends search command.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        public static event EventHandler<SearchCommandReceivedEventArgs> SearchCommandReceived;
+
+        /// <summary>
+        /// Occurs when a client sends custom command.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        internal static event EventHandler<CommandCompletedEventArgs> CommandCompleted;
+
         private static void RegisterPlaybackCommandReceivedEvent()
         {
             _playbackCommandCallback = (clientName, playbackCode, _) =>
@@ -88,7 +103,7 @@ namespace Tizen.Multimedia.Remoting
             _playbackActionCommandCallback = (clientName, requestId, playbackCommand, _) =>
             {
                 var command = new PlaybackCommand(playbackCommand.ToPublic());
-                command.SetClientInfo(clientName, requestId);
+                command.SetResponseInformation(clientName, requestId);
 
                 PlaybackActionCommandReceived?.Invoke(null, new PlaybackActionCommandReceivedEventArgs(command));
             };
@@ -101,7 +116,7 @@ namespace Tizen.Multimedia.Remoting
             _playbackPositionCommandCallback = (clientName, requestId, playbackPosition, _) =>
             {
                 var command = new PlaybackPositionCommand(playbackPosition);
-                command.SetClientInfo(clientName, requestId);
+                command.SetResponseInformation(clientName, requestId);
 
                 PlaybackPositionCommandReceived?.Invoke(null, new PlaybackPositionCommandReceivedEventArgs(command));
             };
@@ -114,7 +129,7 @@ namespace Tizen.Multimedia.Remoting
             _playlistCommandCallback = (clientName, requestId, playlistName, index, playbackCommand, playbackPosition, _) =>
             {
                 var command = new PlaylistCommand(playbackCommand.ToPublic(), playlistName, index, playbackPosition);
-                command.SetClientInfo(clientName, requestId);
+                command.SetResponseInformation(clientName, requestId);
 
                 PlaylistCommandReceived?.Invoke(null, new PlaylistCommandReceivedEventArgs(command));
             };
@@ -127,7 +142,7 @@ namespace Tizen.Multimedia.Remoting
             _shuffleModeCommandCallback = (clientName, requestId, mode, _) =>
             {
                 var command = new ShuffleModeCommand(mode == MediaControllerNativeShuffleMode.On ? true : false);
-                command.SetClientInfo(clientName, requestId);
+                command.SetResponseInformation(clientName, requestId);
 
                 ShuffleModeCommandReceived?.Invoke(null, new ShuffleModeCommandReceivedEventArgs(command));
             };
@@ -140,7 +155,7 @@ namespace Tizen.Multimedia.Remoting
             _repeatModeCommandCallback = (clientName, requestId, mode, _) =>
             {
                 var command = new RepeatModeCommand(mode.ToPublic());
-                command.SetClientInfo(clientName, requestId);
+                command.SetResponseInformation(clientName, requestId);
 
                 RepeatModeCommandReceived?.Invoke(null, new RepeatModeCommandReceivedEventArgs(command));
             };
@@ -162,12 +177,65 @@ namespace Tizen.Multimedia.Remoting
                     command = new CustomCommand(customCommand);
                 }
 
-                command.SetClientInfo(clientName, requestId);
+                command.SetResponseInformation(clientName, requestId);
 
                 CustomCommandReceived?.Invoke(null, new CustomCommandReceivedEventArgs(command));
             };
             Native.SetCustomCommandReceivedCb(Handle, _customCommandCallback).
                 ThrowIfError("Failed to init CustomCommandReceived event.");
         }
+        
+        private static SearchCommand CreateSearchCommandReceivedEventArgs(IntPtr searchHandle)
+        {
+            var searchConditions = new List<MediaControlSearchCondition>();
+
+            Native.SearchItemCallback searchItemCallback = (type, category, keyword, bundleHandle, _) =>
+            {
+                Bundle bundle = null;
+                if (bundleHandle != IntPtr.Zero)
+                {
+                    bundle = new Bundle(new SafeBundleHandle(bundleHandle, true));
+                }
+
+                searchConditions.Add(new MediaControlSearchCondition(type, category, keyword, bundle));
+
+                return true;
+            };
+            Native.ForeachSearchCondition(searchHandle, searchItemCallback).
+                ThrowIfError("Failed to get search items.");
+
+            return new SearchCommand(searchConditions, searchHandle);
+        }
+
+        private static void RegisterSearchCommandReceivedEvent()
+        {
+            _searchCommandCallback = (clientName, requestId, searchHandle, _) =>
+            {
+                var command = CreateSearchCommandReceivedEventArgs(searchHandle);
+
+                command.SetResponseInformation(clientName, requestId);
+
+                SearchCommandReceived?.Invoke(null, new SearchCommandReceivedEventArgs(command));
+            };
+            Native.SetSearchCommandReceivedCb(Handle, _searchCommandCallback).
+                ThrowIfError("Failed to init SearchCommandReceived event.");
+        }
+
+        private static void RegisterCommandCompletedEvent()
+        {
+            _commandCompletedCallback = (clientName, requestId, result, bundleHandle, _) =>
+            {
+                if (bundleHandle != IntPtr.Zero)
+                {
+                    CommandCompleted?.Invoke(null, new CommandCompletedEventArgs(requestId, result, new Bundle(new SafeBundleHandle(bundleHandle, true))));
+                }
+                else
+                {
+                    CommandCompleted?.Invoke(null, new CommandCompletedEventArgs(requestId, result));
+                }
+            };
+            Native.SetEventReceivedCb(Handle, _commandCompletedCallback).
+                ThrowIfError("Failed to init RegisterEventCompletedEvent.");
+        }
     }
 }
\ No newline at end of file
index bdf5a14..3c14975 100644 (file)
@@ -16,6 +16,7 @@
 
 using System;
 using System.Collections.Generic;
+using System.Threading.Tasks;
 using Tizen.Applications;
 using Native = Interop.MediaControllerServer;
 
@@ -111,6 +112,8 @@ namespace Tizen.Multimedia.Remoting
                 RegisterShuffleModeCommandReceivedEvent();
                 RegisterRepeatModeCommandReceivedEvent();
                 RegisterCustomCommandReceivedEvent();
+                RegisterCommandCompletedEvent();
+                RegisterSearchCommandReceivedEvent();
 
                 _isRunning = true;
             }
@@ -312,6 +315,77 @@ namespace Tizen.Multimedia.Remoting
         }
 
         /// <summary>
+        /// Gets the active clients.
+        /// </summary>
+        /// <exception cref="InvalidOperationException">
+        ///     The server is not running .<br/>
+        ///     -or-<br/>
+        ///     An internal error occurs.
+        /// </exception>
+        /// <returns>the activated client ids.</returns>
+        /// <since_tizen> 5 </since_tizen>
+        public static IEnumerable<string> GetActivatedClients()
+        {
+            var clientIds = new List<string>();
+
+            Native.ActivatedClientCallback activatedClientCallback = (name, _) =>
+            {
+                clientIds.Add(name);
+                return true;
+            };
+
+            Native.ForeachActivatedClient(Handle, activatedClientCallback).
+                ThrowIfError("Failed to get activated client.");
+
+            return clientIds.AsReadOnly();
+        }
+
+        /// <summary>
+        /// Requests commands to the client.
+        /// </summary>
+        /// <remarks>
+        /// The client can request the command to execute <see cref="Command"/>, <br/>
+        /// and then, the server receive the result of each request(command).
+        /// </remarks>
+        /// <param name="command">A <see cref="Command"/> class.</param>
+        /// <param name="clientId">The client Id to send command.</param>
+        /// <returns>A task that represents the asynchronous operation.</returns>
+        /// <exception cref="InvalidOperationException">
+        ///     The server has already been stopped.<br/>
+        ///     -or-<br/>
+        ///     An internal error occurs.
+        /// </exception>
+        /// <since_tizen> 5 </since_tizen>
+        public static async Task RequestAsync(Command command, string clientId)
+        {
+            command.SetRequestInformation(clientId);
+
+            var tcs = new TaskCompletionSource<MediaControllerError>();
+            string reqeustId = null;
+
+            EventHandler<CommandCompletedEventArgs> eventHandler = (s, e) =>
+            {
+                if (e.RequestId == reqeustId)
+                {
+                    tcs.TrySetResult(e.Result);
+                }
+            };
+
+            try
+            {
+                CommandCompleted += eventHandler;
+
+                reqeustId = command.Request(Handle);
+
+                (await tcs.Task).ThrowIfError("Failed to request event.");
+            }
+            finally
+            {
+                CommandCompleted -= eventHandler;
+            }
+        }
+
+        /// <summary>
         /// Sends the result of each command.
         /// </summary>
         /// <param name="command">The command that return to client.</param>
@@ -343,5 +417,130 @@ namespace Tizen.Multimedia.Remoting
         {
             command.Response(Handle, result, null);
         }
+
+        #region Capabilities
+        /// <summary>
+        /// Sets the content type of latest played media.
+        /// </summary>
+        /// <param name="type">A value indicating the content type of the latest played media.</param>
+        /// <exception cref="InvalidOperationException">
+        ///     The server is not running .<br/>
+        ///     -or-<br/>
+        ///     An internal error occurs.
+        /// </exception>
+        /// <exception cref="ArgumentException"><paramref name="type"/> is invalid.</exception>
+        /// <since_tizen> 5 </since_tizen>
+        public static void SetPlaybackContentType(MediaControlContentType type)
+        {
+            ValidationUtil.ValidateEnum(typeof(MediaControlContentType), type, nameof(type));
+
+            Native.SetPlaybackContentType(Handle, type).ThrowIfError("Failed to set playback content type.");
+        }
+
+        /// <summary>
+        /// Sets the path of icon.
+        /// </summary>
+        /// <param name="path">The path of icon.</param>
+        /// <exception cref="InvalidOperationException">
+        ///     The server is not running .<br/>
+        ///     -or-<br/>
+        ///     An internal error occurs.
+        /// </exception>
+        /// <exception cref="ArgumentNullException"><paramref name="path"/> is invalid.</exception>
+        /// <since_tizen> 5 </since_tizen>
+        public static void SetIconPath(string path)
+        {
+            if (path == null)
+            {
+                throw new ArgumentNullException(nameof(path));
+            }
+
+            Native.SetIconPath(Handle, path).ThrowIfError("Failed to set uri path.");
+        }
+
+        /// <summary>
+        /// Sets the capabilities by <see cref="MediaControlPlaybackCommand"/>.
+        /// </summary>
+        /// <param name="capabilities">The set of <see cref="MediaControlPlaybackCommand"/> and <see cref="MediaControlCapabilitySupport"/>.</param>
+        /// <exception cref="InvalidOperationException">
+        ///     The server is not running .<br/>
+        ///     -or-<br/>
+        ///     An internal error occurs.
+        /// </exception>
+        /// <exception cref="ArgumentException"><paramref name="capabilities"/> is invalid.</exception>
+        /// <since_tizen> 5 </since_tizen>
+        public static void SetPlaybackCapability(Dictionary<MediaControlPlaybackCommand, MediaControlCapabilitySupport> capabilities)
+        {
+            foreach (var pair in capabilities)
+            {
+                ValidationUtil.ValidateEnum(typeof(MediaControlPlaybackCommand), pair.Key, nameof(pair.Key));
+                ValidationUtil.ValidateEnum(typeof(MediaControlCapabilitySupport), pair.Value, nameof(pair.Value));
+
+                SetPlaybackCapability(pair.Key, pair.Value);
+                Native.SetPlaybackCapability(Handle, pair.Key.ToNative(), pair.Value).
+                    ThrowIfError("Failed to set playback capability.");
+            }
+
+            Native.SaveAndNotifyPlaybackCapabilityUpdated(Handle).ThrowIfError("Failed to update playback capability.");
+        }
+
+        /// <summary>
+        /// Sets the capabilities by <see cref="MediaControlPlaybackCommand"/>.
+        /// </summary>
+        /// <param name="action">A playback command.</param>
+        /// <param name="support">A value indicating whether the <paramref name="action"/> is supported or not.</param>
+        /// <exception cref="InvalidOperationException">
+        ///     The server is not running .<br/>
+        ///     -or-<br/>
+        ///     An internal error occurs.
+        /// </exception>
+        /// <exception cref="ArgumentException"><paramref name="action"/> or <paramref name="support"/> is invalid.</exception>
+        /// <since_tizen> 5 </since_tizen>
+        public static void SetPlaybackCapability(MediaControlPlaybackCommand action, MediaControlCapabilitySupport support)
+        {
+            ValidationUtil.ValidateEnum(typeof(MediaControlPlaybackCommand), action, nameof(action));
+            ValidationUtil.ValidateEnum(typeof(MediaControlCapabilitySupport), support, nameof(support));
+
+            Native.SetPlaybackCapability(Handle, action.ToNative(), support).ThrowIfError("Failed to set playback capability.");
+
+            Native.SaveAndNotifyPlaybackCapabilityUpdated(Handle).ThrowIfError("Failed to update playback capability.");
+        }
+
+        /// <summary>
+        /// Sets the <see cref="MediaControlCapabilitySupport"/> indicating shuffle mode is supported or not.
+        /// </summary>
+        /// <param name="support">A value indicating whether the shuffle mode is supported or not.</param>
+        /// <exception cref="InvalidOperationException">
+        ///     The server is not running .<br/>
+        ///     -or-<br/>
+        ///     An internal error occurs.
+        /// </exception>
+        /// <exception cref="ArgumentException"><paramref name="support"/> is invalid.</exception>
+        /// <since_tizen> 5 </since_tizen>
+        public static void SetShuffleModeCapability(MediaControlCapabilitySupport support)
+        {
+            ValidationUtil.ValidateEnum(typeof(MediaControlCapabilitySupport), support, nameof(support));
+
+            Native.SetShuffleModeCapability(Handle, support).ThrowIfError("Failed to set shuffle mode capability.");
+        }
+
+        /// <summary>
+        /// Sets the content type of latest played media.
+        /// </summary>
+        /// <param name="support">A value indicating whether the <see cref="MediaControlRepeatMode"/> is supported or not.</param>
+        /// <exception cref="InvalidOperationException">
+        ///     The server is not running .<br/>
+        ///     -or-<br/>
+        ///     An internal error occurs.
+        /// </exception>
+        /// <exception cref="ArgumentException"><paramref name="support"/> is invalid.</exception>
+        /// <since_tizen> 5 </since_tizen>
+        public static void SetRepeatModeCapability(MediaControlCapabilitySupport support)
+        {
+            ValidationUtil.ValidateEnum(typeof(MediaControlCapabilitySupport), support, nameof(support));
+
+            Native.SetRepeatModeCapability(Handle, support).ThrowIfError("Failed to set shuffle mode capability.");
+        }
+        #endregion Capabilities
     }
 }
\ No newline at end of file
index 08b7b47..109818c 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 using System;
+using System.Collections.Generic;
 using Tizen.Applications;
 using Native = Interop.MediaControllerClient;
 
@@ -142,9 +143,9 @@ namespace Tizen.Multimedia.Remoting
         /// <since_tizen> 5 </since_tizen>
         public event EventHandler<PlaylistUpdatedEventArgs> PlaylistUpdated;
 
-        internal void RaisePlaylistUpdatedEvent(MediaControlPlaylistMode mode, string name)
+        internal void RaisePlaylistUpdatedEvent(MediaControlPlaylistMode mode, string name, IntPtr playlistHandle)
         {
-            PlaylistUpdated?.Invoke(this, new PlaylistUpdatedEventArgs(mode, name));
+            PlaylistUpdated?.Invoke(this, new PlaylistUpdatedEventArgs(mode, name, new MediaControlPlaylist(playlistHandle)));
         }
 
         /// <summary>
@@ -167,5 +168,81 @@ namespace Tizen.Multimedia.Remoting
                 CommandCompleted?.Invoke(this, new CommandCompletedEventArgs(requestId, result));
             }
         }
+
+        /// <summary>
+        /// Occurs when the playback capabilities are updated.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        public event EventHandler<PlaybackCapabilityUpdatedEventArgs> PlaybackCapabilityUpdated;
+
+        private PlaybackCapabilityUpdatedEventArgs CreatePlaybackCapabilityUpdatedEventArgs(IntPtr playbackCapaHandle)
+        {
+            var capabilities = new Dictionary<MediaControlPlaybackCommand, MediaControlCapabilitySupport>();
+            try
+            {
+                foreach (MediaControllerNativePlaybackAction action in Enum.GetValues(typeof(MediaControllerNativePlaybackAction)))
+                {
+                    Native.IsCapabilitySupported(playbackCapaHandle, action, out MediaControlCapabilitySupport support);
+                    capabilities.Add(action.ToPublic(), support);
+                }
+
+                return new PlaybackCapabilityUpdatedEventArgs(capabilities);
+            }
+            catch (Exception e)
+            {
+                Log.Error(GetType().FullName, e.ToString());
+            }
+            return null;
+        }
+
+        internal void RaisePlaybackCapabilityUpdatedEvent(IntPtr playbackCapaHandle)
+        {
+            var eventHandler = PlaybackCapabilityUpdated;
+
+            if (eventHandler == null)
+            {
+                return;
+            }
+
+            var args = CreatePlaybackCapabilityUpdatedEventArgs(playbackCapaHandle);
+
+            if (args != null)
+            {
+                eventHandler.Invoke(this, args);
+            }
+        }
+
+        /// <summary>
+        /// Occurs when the repeat mode capabilities are updated.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        public event EventHandler<RepeatModeCapabilityUpdatedEventArgs> RepeatModeCapabilityUpdated;
+
+        internal void RaiseRepeatModeCapabilityUpdatedEvent(MediaControlCapabilitySupport support)
+        {
+            RepeatModeCapabilityUpdated?.Invoke(this, new RepeatModeCapabilityUpdatedEventArgs(support));
+        }
+
+        /// <summary>
+        /// Occurs when the shuffle mode capabilities are updated.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        public event EventHandler<ShuffleModeCapabilityUpdatedEventArgs> ShuffleModeCapabilityUpdated;
+
+        internal void RaiseShuffleModeCapabilityUpdatedEvent(MediaControlCapabilitySupport support)
+        {
+            ShuffleModeCapabilityUpdated?.Invoke(this, new ShuffleModeCapabilityUpdatedEventArgs(support));
+        }
+
+        /// <summary>
+        /// Occurs when a server sends custom event.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        public event EventHandler<CustomCommandReceivedEventArgs> CustomCommandReceived;
+
+        internal void RaiseCustomCommandReceivedEvent(CustomCommand command)
+        {
+            CustomCommandReceived?.Invoke(this, new CustomCommandReceivedEventArgs(command));
+        }
     }
 }
\ No newline at end of file
index 22f3de0..dd61ccf 100644 (file)
  */
 
 using System;
+using System.Linq;
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Threading.Tasks;
+using Tizen.Applications;
 using Native = Interop.MediaControllerClient;
 using NativePlaylist = Interop.MediaControllerPlaylist;
 
@@ -173,7 +175,7 @@ namespace Tizen.Multimedia.Remoting
         /// <summary>
         /// Returns the all playlists.
         /// </summary>
-        /// <returns><see cref="MediaControlPlaylist"/></returns>
+        /// <returns>The set of <see cref="MediaControlPlaylist"/>.</returns>
         /// <exception cref="InvalidOperationException">
         ///     The server has already been stopped.<br/>
         ///     -or-<br/>
@@ -185,7 +187,7 @@ namespace Tizen.Multimedia.Remoting
         {
             ThrowIfStopped();
 
-            List<MediaControlPlaylist> playlists = null;
+            var playlists = new List<MediaControlPlaylist>();
 
             NativePlaylist.PlaylistCallback playlistCallback = (handle, _) =>
             {
@@ -194,7 +196,43 @@ namespace Tizen.Multimedia.Remoting
             NativePlaylist.ForeachServerPlaylist(Manager.Handle, ServerAppId, playlistCallback, IntPtr.Zero)
                 .ThrowIfError("Failed to get playlist.");
 
-            return playlists;
+            return playlists.AsReadOnly();
+        }
+
+        /// <summary>
+        /// Returns the playlist name of current playing media.
+        /// </summary>
+        /// <returns>The playlist name.</returns>
+        /// <exception cref="InvalidOperationException">
+        ///     The server has already been stopped.<br/>
+        ///     -or-<br/>
+        ///     An internal error occurs.
+        /// </exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed of.</exception>
+        /// <since_tizen> 5 </since_tizen>
+        public MediaControlPlaylist GetPlaylistOfCurrentPlayingMedia()
+        {
+            ThrowIfStopped();
+
+            IntPtr playbackHandle = IntPtr.Zero;
+            string name = null;
+
+            // Get the playlist name of current playing media.
+            try
+            {
+                Native.GetServerPlayback(Manager.Handle, ServerAppId, out playbackHandle).ThrowIfError("Failed to get playback.");
+
+                name = NativePlaylist.GetPlaylistIndex(playbackHandle);
+            }
+            finally
+            {
+                if (playbackHandle != IntPtr.Zero)
+                {
+                    Native.DestroyPlayback(playbackHandle).ThrowIfError("Failed to destroy playback handle.");
+                }
+            }
+
+            return GetPlaylists().FirstOrDefault(playlist => playlist.Name == name);
         }
 
         /// <summary>
@@ -224,7 +262,7 @@ namespace Tizen.Multimedia.Remoting
             {
                 if (playbackHandle != IntPtr.Zero)
                 {
-                    Native.DestroyPlayback(playbackHandle);
+                    Native.DestroyPlayback(playbackHandle).ThrowIfError("Failed to destroy playback handle.");
                 }
             }
         }
@@ -282,6 +320,7 @@ namespace Tizen.Multimedia.Remoting
         /// and then, the client receive the result of each request(command).
         /// </remarks>
         /// <param name="command">A <see cref="Command"/> class.</param>
+        /// <returns>A task that represents the asynchronous operation.</returns>
         /// <exception cref="InvalidOperationException">
         ///     The server has already been stopped.<br/>
         ///     -or-<br/>
@@ -293,7 +332,7 @@ namespace Tizen.Multimedia.Remoting
         {
             ThrowIfStopped();
 
-            command.SetServerInfo(Manager.Handle, ServerAppId);
+            command.SetRequestInformation(ServerAppId);
 
             var tcs = new TaskCompletionSource<MediaControllerError>();
             string reqeustId = null;
@@ -310,7 +349,7 @@ namespace Tizen.Multimedia.Remoting
             {
                 CommandCompleted += eventHandler;
 
-                reqeustId = command.Request();
+                reqeustId = command.Request(Manager.Handle);
 
                 (await tcs.Task).ThrowIfError("Failed to request command");
             }
@@ -321,6 +360,39 @@ namespace Tizen.Multimedia.Remoting
         }
 
         /// <summary>
+        /// Sends the result of each command.
+        /// </summary>
+        /// <param name="command">The command that return to client.</param>
+        /// <param name="result">The result of <paramref name="command"/>.</param>
+        /// <param name="bundle">The extra data.</param>
+        /// <exception cref="InvalidOperationException">
+        ///     The server is not running .<br/>
+        ///     -or-<br/>
+        ///     An internal error occurs.
+        /// </exception>
+        /// <since_tizen> 5 </since_tizen>
+        public void Response(Command command, int result, Bundle bundle)
+        {
+            command.Response(Manager.Handle, result, bundle);
+        }
+
+        /// <summary>
+        /// Sends the result of each command.
+        /// </summary>
+        /// <param name="command">The command that return to client.</param>
+        /// <param name="result">The result of <paramref name="command"/>.</param>
+        /// <exception cref="InvalidOperationException">
+        ///     The server is not running .<br/>
+        ///     -or-<br/>
+        ///     An internal error occurs.
+        /// </exception>
+        /// <since_tizen> 5 </since_tizen>
+        public void Response(Command command, int result)
+        {
+            command.Response(Manager.Handle, result, null);
+        }
+
+        /// <summary>
         /// Sends playback command to the server.
         /// </summary>
         /// <param name="command">A playback command.</param>
@@ -343,5 +415,246 @@ namespace Tizen.Multimedia.Remoting
             Native.SendPlaybackStateCommand(Manager.Handle, ServerAppId, command.ToNative()).
                 ThrowIfError("Failed to send command.");
         }
+
+        #region Capabilities
+        /// <summary>
+        /// Gets the content type of current playing media.
+        /// </summary>
+        /// <returns>The <see cref="MediaControlContentType"/>.</returns>
+        /// <exception cref="InvalidOperationException">
+        ///     The server has already been stopped.<br/>
+        ///     -or-<br/>
+        ///     An internal error occurs.
+        /// </exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed of.</exception>
+        /// <since_tizen> 5 </since_tizen>
+        public MediaControlContentType GetContentTypeOfCurrentPlayingMedia()
+        {
+            ThrowIfStopped();
+
+            IntPtr playbackHandle = IntPtr.Zero;
+
+            try
+            {
+                Native.GetServerPlayback(Manager.Handle, ServerAppId, out playbackHandle).ThrowIfError("Failed to get playback.");
+
+                Native.GetPlaybackContentType(playbackHandle, out MediaControlContentType type).
+                    ThrowIfError("Failed to get playback content type");
+
+                return type;
+            }
+            finally
+            {
+                if (playbackHandle != IntPtr.Zero)
+                {
+                    Native.DestroyPlayback(playbackHandle);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Gets the icon path.
+        /// </summary>
+        /// <returns>The icon path.</returns>
+        /// <exception cref="InvalidOperationException">
+        ///     The server has already been stopped.<br/>
+        ///     -or-<br/>
+        ///     An internal error occurs.
+        /// </exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed of.</exception>
+        /// <since_tizen> 5 </since_tizen>
+        public string GetIconPath()
+        {
+            ThrowIfStopped();
+
+            Native.GetServerIcon(Manager.Handle, ServerAppId, out string uri).
+                ThrowIfError("Failed to get icon path.");
+
+            return uri;
+        }
+
+        /// <summary>
+        /// Gets the age rating of current playing media.
+        /// </summary>
+        /// <returns>The Age rating of current playing media. The range is 0 to 19, inclusive.</returns>
+        /// <exception cref="InvalidOperationException">
+        ///     The server has already been stopped.<br/>
+        ///     -or-<br/>
+        ///     An internal error occurs.
+        /// </exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed of.</exception>
+        /// <since_tizen> 5 </since_tizen>
+        public int GetAgeRatingOfCurrentPlayingMedia()
+        {
+            ThrowIfStopped();
+
+            IntPtr playbackHandle = IntPtr.Zero;
+
+            try
+            {
+                Native.GetServerPlayback(Manager.Handle, ServerAppId, out playbackHandle).ThrowIfError("Failed to get playback.");
+
+                Native.GetAgeRating(playbackHandle, out int ageRating).ThrowIfError("Failed to get age rating.");
+
+                return ageRating;
+            }
+            finally
+            {
+                if (playbackHandle != IntPtr.Zero)
+                {
+                    Native.DestroyPlayback(playbackHandle);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Gets the value whether <see cref="MediaControlPlaybackCommand"/> is supported or not.
+        /// </summary>
+        /// <returns>
+        /// the set of <see cref="MediaControlPlaybackCommand"/> and <see cref="MediaControlCapabilitySupport"/>.
+        /// </returns>
+        /// <exception cref="InvalidOperationException">
+        ///     The server has already been stopped.<br/>
+        ///     -or-<br/>
+        ///     An internal error occurs.
+        /// </exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed of.</exception>
+        /// <since_tizen> 5 </since_tizen>
+        public Dictionary<MediaControlPlaybackCommand, MediaControlCapabilitySupport> GetPlaybackCapabilities()
+        {
+            ThrowIfStopped();
+
+            IntPtr playbackCapaHandle = IntPtr.Zero;
+
+            var playbackCapabilities = new Dictionary<MediaControlPlaybackCommand, MediaControlCapabilitySupport>();
+
+            try
+            {
+                Native.GetPlaybackCapabilityHandle(Manager.Handle, ServerAppId, out playbackCapaHandle).
+                    ThrowIfError("Failed to get playback capability handle.");
+
+                foreach (MediaControllerNativePlaybackAction action in Enum.GetValues(typeof(MediaControllerNativePlaybackAction)))
+                {
+                    Native.IsCapabilitySupported(playbackCapaHandle, action, out MediaControlCapabilitySupport support);
+                    playbackCapabilities.Add(action.ToPublic(), support);
+                }
+
+                return playbackCapabilities;
+            }
+            finally
+            {
+                if (playbackCapaHandle != IntPtr.Zero)
+                {
+                    Native.DestroyCapability(playbackCapaHandle);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Gets the value whether <paramref name="action"/> is supported or not.
+        /// </summary>
+        /// <param name="action">A playback command.</param>
+        /// <returns>A <see cref="MediaControlCapabilitySupport"/>.</returns>
+        /// <exception cref="InvalidOperationException">
+        ///     The server has already been stopped.<br/>
+        ///     -or-<br/>
+        ///     An internal error occurs.
+        /// </exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed of.</exception>
+        /// <since_tizen> 5 </since_tizen>
+        public MediaControlCapabilitySupport GetPlaybackCapabilities(MediaControlPlaybackCommand action)
+        {
+            ThrowIfStopped();
+
+            IntPtr playbackCapaHandle = IntPtr.Zero;
+
+            try
+            {
+                Native.GetPlaybackCapabilityHandle(Manager.Handle, ServerAppId, out playbackCapaHandle).
+                    ThrowIfError("Failed to get playback capability handle.");
+
+                Native.IsCapabilitySupported(playbackCapaHandle, action.ToNative(), out MediaControlCapabilitySupport support);
+
+                return support;
+            }
+            finally
+            {
+                if (playbackCapaHandle != IntPtr.Zero)
+                {
+                    Native.DestroyCapability(playbackCapaHandle);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Gets the value whether the shuffle mode is supported or not.
+        /// </summary>
+        /// <returns>A <see cref="MediaControlCapabilitySupport"/>.</returns>
+        /// <exception cref="InvalidOperationException">
+        ///     The server has already been stopped.<br/>
+        ///     -or-<br/>
+        ///     An internal error occurs.
+        /// </exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed of.</exception>
+        /// <since_tizen> 5 </since_tizen>
+        public MediaControlCapabilitySupport GetShuffleModeCapability()
+        {
+            ThrowIfStopped();
+
+            IntPtr playbackCapaHandle = IntPtr.Zero;
+
+            try
+            {
+                Native.GetPlaybackCapabilityHandle(Manager.Handle, ServerAppId, out playbackCapaHandle).
+                    ThrowIfError("Failed to get playback capability handle.");
+
+                Native.GetShuffleCapability(Manager.Handle, ServerAppId, out MediaControlCapabilitySupport support);
+
+                return support;
+            }
+            finally
+            {
+                if (playbackCapaHandle != IntPtr.Zero)
+                {
+                    Native.DestroyCapability(playbackCapaHandle);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Gets the value whether the repeat mode is supported or not.
+        /// </summary>
+        /// <returns>A <see cref="MediaControlCapabilitySupport"/>.</returns>
+        /// <exception cref="InvalidOperationException">
+        ///     The server has already been stopped.<br/>
+        ///     -or-<br/>
+        ///     An internal error occurs.
+        /// </exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed of.</exception>
+        /// <since_tizen> 5 </since_tizen>
+        public MediaControlCapabilitySupport GetRepeatModeCapability()
+        {
+            ThrowIfStopped();
+
+            IntPtr playbackCapaHandle = IntPtr.Zero;
+
+            try
+            {
+                Native.GetPlaybackCapabilityHandle(Manager.Handle, ServerAppId, out playbackCapaHandle).
+                    ThrowIfError("Failed to get playback capability handle.");
+
+                Native.GetRepeatCapability(Manager.Handle, ServerAppId, out MediaControlCapabilitySupport support);
+
+                return support;
+            }
+            finally
+            {
+                if (playbackCapaHandle != IntPtr.Zero)
+                {
+                    Native.DestroyCapability(playbackCapaHandle);
+                }
+            }
+        }
+        #endregion Capabilities
     }
 }
\ No newline at end of file
index bd4079d..23166bf 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 using System;
+using Tizen.Applications;
 using Native = Interop.MediaControllerClient;
 using NativePlaylist = Interop.MediaControllerPlaylist;
 
@@ -29,6 +30,10 @@ namespace Tizen.Multimedia.Remoting
         private Native.CommandCompletedCallback _commandCompletedCallback;
         private NativePlaylist.MetadataUpdatedCallback _metadataUpdatedCallback;
         private NativePlaylist.PlaylistUpdatedCallback _playlistUpdatedCallback;
+        private Native.PlaybackCapabilityUpdatedCallback _playbackCapabilityUpdatedCallback;
+        private Native.ShuffleCapabilityUpdatedCallback _shuffleModeCapabilityUpdatedCallback;
+        private Native.RepeatCapabilityUpdatedCallback _repeatModeCapabilityUpdatedCallback;
+        private Native.CustomCommandReceivedCallback _customCommandReceivedCallback;
 
         /// <summary>
         /// Occurs when a server is started.
@@ -50,6 +55,10 @@ namespace Tizen.Multimedia.Remoting
             RegisterShuffleModeUpdatedEvent();
             RegisterRepeatModeUpdatedEvent();
             RegisterCommandCompletedEvent();
+            RegisterPlaybackCapabilitiesEvent();
+            RegisterRepeatModeCapabilitiesEvent();
+            RegisterShuffleModeCapabilitiesEvent();
+            RegisterCustomCommandReceivedEvent();
         }
 
         private void RaiseServerChangedEvent(MediaControllerNativeServerState state, MediaController controller)
@@ -82,9 +91,9 @@ namespace Tizen.Multimedia.Remoting
 
         private void RegisterPlaybackUpdatedEvent()
         {
-            _playbackUpdatedCallback = (serverName, playback, _) =>
+            _playbackUpdatedCallback = (serverName, playbackHandle, _) =>
             {
-                GetController(serverName)?.RaisePlaybackUpdatedEvent(playback);
+                GetController(serverName)?.RaisePlaybackUpdatedEvent(playbackHandle);
             };
 
             Native.SetPlaybackUpdatedCb(Handle, _playbackUpdatedCallback).ThrowIfError("Failed to init PlaybackUpdated event.");
@@ -125,9 +134,9 @@ namespace Tizen.Multimedia.Remoting
 
         private void RegisterPlaylistUpdatedEvent()
         {
-            _playlistUpdatedCallback = (serverName, playlistMode, name, handle, _) =>
+            _playlistUpdatedCallback = (serverName, playlistMode, name, playlistHandle, _) =>
             {
-                GetController(serverName)?.RaisePlaylistUpdatedEvent(playlistMode, name);
+                GetController(serverName)?.RaisePlaylistUpdatedEvent(playlistMode, name, playlistHandle);
             };
 
             NativePlaylist.SetPlaylistModeUpdatedCb(Handle, _playlistUpdatedCallback).
@@ -146,5 +155,61 @@ namespace Tizen.Multimedia.Remoting
             Native.SetCommandCompletedCb(Handle, _commandCompletedCallback).
                 ThrowIfError("Failed to init CommandCompleted event.");
         }
+
+        private void RegisterPlaybackCapabilitiesEvent()
+        {
+            _playbackCapabilityUpdatedCallback = (serverName, playbackCapaHandle, _) =>
+            {
+                GetController(serverName)?.RaisePlaybackCapabilityUpdatedEvent(playbackCapaHandle);
+            };
+
+            Native.SetPlaybackCapabilityUpdatedCb(Handle, _playbackCapabilityUpdatedCallback).
+                ThrowIfError("Failed to init PlaylistUpdated event.");
+        }
+
+        private void RegisterRepeatModeCapabilitiesEvent()
+        {
+            _repeatModeCapabilityUpdatedCallback = (serverName, support, _) =>
+            {
+                GetController(serverName)?.RaiseRepeatModeCapabilityUpdatedEvent(support);
+            };
+
+            Native.SetRepeatCapabilityUpdatedCb(Handle, _repeatModeCapabilityUpdatedCallback).
+                ThrowIfError("Failed to init RepeatModeCapabilityUpdated event.");
+        }
+
+        private void RegisterShuffleModeCapabilitiesEvent()
+        {
+            _shuffleModeCapabilityUpdatedCallback = (serverName, support, _) =>
+            {
+                GetController(serverName)?.RaiseShuffleModeCapabilityUpdatedEvent(support);
+            };
+
+            Native.SetShuffleCapabilityUpdatedCb(Handle, _shuffleModeCapabilityUpdatedCallback).
+                ThrowIfError("Failed to init ShuffleModeCapabilityUpdated event.");
+        }
+
+        private void RegisterCustomCommandReceivedEvent()
+        {
+            _customCommandReceivedCallback = (serverName, requestId, customEvent, bundleHandle, _) =>
+            {
+                CustomCommand command = null;
+                if (bundleHandle != IntPtr.Zero)
+                {
+                    command = new CustomCommand(customEvent, new Bundle(new SafeBundleHandle(bundleHandle, true)));
+                }
+                else
+                {
+                    command = new CustomCommand(customEvent);
+                }
+
+                command.SetResponseInformation(serverName, requestId);
+
+                GetController(serverName)?.RaiseCustomCommandReceivedEvent(command);
+            };
+
+            Native.SetCustomEventCb(Handle, _customCommandReceivedCallback).
+                ThrowIfError("Failed to init CustomCommandReceived event.");
+        }
     }
 }
\ No newline at end of file
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/PlaybackCapabilityUpdatedEventArgs.cs b/src/Tizen.Multimedia.Remoting/MediaController/PlaybackCapabilityUpdatedEventArgs.cs
new file mode 100644 (file)
index 0000000..3fdf658
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using Native = Interop.MediaControllerClient;
+
+namespace Tizen.Multimedia.Remoting
+{
+    /// <summary>
+    /// Provides data for the <see cref="MediaController.PlaybackCapabilityUpdated"/> event.
+    /// </summary>
+    /// <since_tizen> 5 </since_tizen>
+    public class PlaybackCapabilityUpdatedEventArgs : EventArgs
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PlaybackCapabilityUpdatedEventArgs"/> class.
+        /// </summary>
+        /// <param name="support">The set of playback capabilities.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="support"/> is invalid.</exception>
+        /// <since_tizen> 5 </since_tizen>
+        public PlaybackCapabilityUpdatedEventArgs(Dictionary<MediaControlPlaybackCommand, MediaControlCapabilitySupport> support)
+        {
+            Support = support ?? throw new ArgumentNullException(nameof(support));
+        }
+
+        /// <summary>
+        /// Gets the value whether the playback action is supported or not.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        public Dictionary<MediaControlPlaybackCommand, MediaControlCapabilitySupport> Support { get; }
+    }
+}
\ No newline at end of file
index 54cf2c5..eb11df8 100644 (file)
@@ -29,14 +29,16 @@ namespace Tizen.Multimedia.Remoting
         /// </summary>
         /// <param name="mode">A value indicating the updated repeat mode.</param>
         /// <param name="name">A value indicating the playlist name.</param>
+        /// <param name="playlist">A value indicating the playlist.</param>
         /// <exception cref="ArgumentException"><paramref name="mode"/> is invalid.</exception>
         /// <since_tizen> 5 </since_tizen>
-        public PlaylistUpdatedEventArgs(MediaControlPlaylistMode mode, string name)
+        public PlaylistUpdatedEventArgs(MediaControlPlaylistMode mode, string name, MediaControlPlaylist playlist)
         {
             ValidationUtil.ValidateEnum(typeof(MediaControlPlaylistMode), mode, nameof(mode));
 
             Mode = mode;
             Name = name;
+            Playlist = playlist;
         }
 
         /// <summary>
@@ -55,5 +57,11 @@ namespace Tizen.Multimedia.Remoting
         /// </summary>
         /// <since_tizen> 5 </since_tizen>
         public string Name { get; }
+
+        /// <summary>
+        /// Gets the updated playlist.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        public MediaControlPlaylist Playlist { get; }
     }
 }
  * limitations under the License.
  */
 
+using System;
+using System.Collections.Generic;
+using Native = Interop.MediaControllerClient;
+
 namespace Tizen.Multimedia.Remoting
 {
     /// <summary>
-    /// Specifies playback states.
+    /// Provides data for the <see cref="MediaController.RepeatModeCapabilityUpdated"/> event.
     /// </summary>
-    /// <since_tizen> 4 </since_tizen>
-    public enum MediaControlPlaybackState
+    /// <since_tizen> 5 </since_tizen>
+    public class RepeatModeCapabilityUpdatedEventArgs : EventArgs
     {
         /// <summary>
-        /// Unknown; no state is set.
-        /// </summary>
-        None,
-
-        /// <summary>
-        /// Playing.
-        /// </summary>
-        Playing,
-
-        /// <summary>
-        /// Paused.
-        /// </summary>
-        Paused,
-
-        /// <summary>
-        /// Stopped.
-        /// </summary>
-        Stopped,
-
-        /// <summary>
-        /// Fast forwarding.
-        /// </summary>
-        FastForwarding,
-
-        /// <summary>
-        /// Rewinding.
-        /// </summary>
-        Rewinding,
-
-        /// <summary>
-        /// Skipping to the next item.
+        /// Initializes a new instance of the <see cref="RepeatModeCapabilityUpdatedEventArgs"/> class.
         /// </summary>
+        /// <param name="support">The repeat mode capabilities.</param>
         /// <since_tizen> 5 </since_tizen>
-        MovingToNext,
+        public RepeatModeCapabilityUpdatedEventArgs(MediaControlCapabilitySupport support)
+        {
+            Support = support;
+        }
 
         /// <summary>
-        /// Skipping to the previous item.
+        /// Gets the value whether the repeat mode is supported or not.
         /// </summary>
         /// <since_tizen> 5 </since_tizen>
-        MovingToPrevious,
+        public MediaControlCapabilitySupport Support { get; }
     }
 }
\ No newline at end of file
  * limitations under the License.
  */
 
+using System;
+
 namespace Tizen.Multimedia.Remoting
 {
     /// <summary>
-    /// Specifies the playlist mode.
+    /// Provides data for the <see cref="SearchCommandReceivedEventArgs"/> event.
     /// </summary>
     /// <since_tizen> 5 </since_tizen>
-    public enum MediaControlPlaylistMode
+    public class SearchCommandReceivedEventArgs : EventArgs
     {
         /// <summary>
-        /// Playlist is created or update.
+        /// Initializes a new instance of the <see cref="SearchCommandReceivedEventArgs"/> class.
         /// </summary>
-        Updated,
+        /// <param name="command">The search command.</param>
+        /// <since_tizen> 5 </since_tizen>
+        public SearchCommandReceivedEventArgs(SearchCommand command)
+        {
+            Command = command;
+        }
 
         /// <summary>
-        /// Playlist is removed.
+        /// Gets the <see cref="SearchCommand"/>.
         /// </summary>
-        Removed,
+        /// <since_tizen> 5 </since_tizen>
+        public SearchCommand Command { get; }
     }
 }
\ No newline at end of file
  * limitations under the License.
  */
 
+using System;
+using System.Collections.Generic;
+using Native = Interop.MediaControllerClient;
+
 namespace Tizen.Multimedia.Remoting
 {
     /// <summary>
-    /// Specifies the repeat mode.
+    /// Provides data for the <see cref="MediaController.ShuffleModeCapabilityUpdated"/> event.
     /// </summary>
-    /// <since_tizen> 4 </since_tizen>
-    public enum MediaControlRepeatMode
+    /// <since_tizen> 5 </since_tizen>
+    public class ShuffleModeCapabilityUpdatedEventArgs : EventArgs
     {
         /// <summary>
-        /// Off.
+        /// Initializes a new instance of the <see cref="ShuffleModeCapabilityUpdatedEventArgs"/> class.
         /// </summary>
-        Off,
-
-        /// <summary>
-        /// On.
-        /// </summary>
-        On,
+        /// <param name="support">The shuffle mode capabilities.</param>
+        /// <since_tizen> 5 </since_tizen>
+        public ShuffleModeCapabilityUpdatedEventArgs(MediaControlCapabilitySupport support)
+        {
+            Support = support;
+        }
 
         /// <summary>
-        /// One media.
+        /// Gets the value whether the shuffle mode is supported or not.
         /// </summary>
         /// <since_tizen> 5 </since_tizen>
-        OneMedia
+        public MediaControlCapabilitySupport Support { get; }
     }
 }
\ No newline at end of file