[MediaController] Add new APIs for sending command and its callback (#396)
authorhsgwon <haesu.gwon@samsung.com>
Fri, 14 Sep 2018 05:41:57 +0000 (14:41 +0900)
committerGitHub <noreply@github.com>
Fri, 14 Sep 2018 05:41:57 +0000 (14:41 +0900)
[MediaController] Add new APIs for sending command and its callback

28 files changed:
src/Tizen.Multimedia.Remoting/Interop/Interop.MediaControllerClient.cs
src/Tizen.Multimedia.Remoting/Interop/Interop.MediaControllerPlaylist.cs [new file with mode: 0644]
src/Tizen.Multimedia.Remoting/Interop/Interop.MediaControllerServer.cs
src/Tizen.Multimedia.Remoting/MediaController/CommandCompletedEventArgs.cs [new file with mode: 0644]
src/Tizen.Multimedia.Remoting/MediaController/CustomCommandReceivedEventArgs.cs [new file with mode: 0644]
src/Tizen.Multimedia.Remoting/MediaController/EnumExtensions.cs
src/Tizen.Multimedia.Remoting/MediaController/InternalEnums.cs
src/Tizen.Multimedia.Remoting/MediaController/MediaControlCommand.cs [new file with mode: 0644]
src/Tizen.Multimedia.Remoting/MediaController/MediaControlMetadata.cs
src/Tizen.Multimedia.Remoting/MediaController/MediaControlPlaybackCommand.cs
src/Tizen.Multimedia.Remoting/MediaController/MediaControlPlaybackState.cs
src/Tizen.Multimedia.Remoting/MediaController/MediaControlPlaylist.cs [new file with mode: 0644]
src/Tizen.Multimedia.Remoting/MediaController/MediaControlServer.Events.cs [new file with mode: 0644]
src/Tizen.Multimedia.Remoting/MediaController/MediaControlServer.cs
src/Tizen.Multimedia.Remoting/MediaController/MediaController.Events.cs [new file with mode: 0644]
src/Tizen.Multimedia.Remoting/MediaController/MediaController.cs
src/Tizen.Multimedia.Remoting/MediaController/MediaControllerError.cs
src/Tizen.Multimedia.Remoting/MediaController/MediaControllerManager.Events.cs
src/Tizen.Multimedia.Remoting/MediaController/MediaControllerManager.cs
src/Tizen.Multimedia.Remoting/MediaController/MediaControllerPlaylistMode.cs [new file with mode: 0644]
src/Tizen.Multimedia.Remoting/MediaController/MediaControllerRepeatMode.cs
src/Tizen.Multimedia.Remoting/MediaController/PlaybackActionCommandReceivedEventArgs.cs [new file with mode: 0644]
src/Tizen.Multimedia.Remoting/MediaController/PlaybackCommandReceivedEventArgs.cs
src/Tizen.Multimedia.Remoting/MediaController/PlaybackPositionCommandReceivedEventArgs.cs [new file with mode: 0644]
src/Tizen.Multimedia.Remoting/MediaController/PlaylistCommandReceivedEventArgs.cs [new file with mode: 0644]
src/Tizen.Multimedia.Remoting/MediaController/PlaylistUpdatedEventArgs.cs [new file with mode: 0644]
src/Tizen.Multimedia.Remoting/MediaController/RepeatModeCommandReceivedEventArgs.cs [new file with mode: 0644]
src/Tizen.Multimedia.Remoting/MediaController/ShuffleModeCommandReceivedEventArgs.cs [new file with mode: 0644]

index 2029564..becaf42 100644 (file)
@@ -1,4 +1,4 @@
-/*
+/*
  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
  *
  * Licensed under the Apache License, Version 2.0 (the License);
@@ -16,6 +16,7 @@
 
 using System;
 using System.Runtime.InteropServices;
+using Tizen.Applications;
 using Tizen.Multimedia.Remoting;
 
 internal static partial class Interop
@@ -23,68 +24,70 @@ internal static partial class Interop
     internal static partial class MediaControllerClient
     {
         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate void ServerUpdatedCallback(string serverName, MediaControllerServerState serverState,
+        internal delegate void ServerUpdatedCallback(string serverName, MediaControllerNativeServerState serverState,
             IntPtr userData);
 
         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
         internal delegate void PlaybackUpdatedCallback(string serverName, IntPtr playback, IntPtr userData);
 
         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate void MetadataUpdatedCallback(string serverName, IntPtr metadata, IntPtr userData);
-
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate void ShuffleModeUpdatedCallback(string serverName, MediaControllerShuffleMode shuffleMode,
+        internal delegate void ShuffleModeUpdatedCallback(string serverName, MediaControllerNativeShuffleMode shuffleMode,
             IntPtr userData);
 
         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate void RepeatModeUpdatedCallback(string serverName, NativeRepeatMode repeatMode, IntPtr userData);
+        internal delegate void RepeatModeUpdatedCallback(string serverName, MediaControllerNativeRepeatMode repeatMode, IntPtr userData);
 
         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
         internal delegate bool ActivatedServerCallback(string serverName, IntPtr userData);
 
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void CommandCompletedCallback(string serverName, string requestId, MediaControllerError result,
+            IntPtr bundleHandle, IntPtr userData);
+
+
         [DllImport(Libraries.MediaController, EntryPoint = "mc_client_create")]
         internal static extern MediaControllerError Create(out MediaControllerClientHandle handle);
 
         [DllImport(Libraries.MediaController, EntryPoint = "mc_client_destroy")]
         internal static extern MediaControllerError Destroy(IntPtr handle);
 
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_set_server_update_cb")]
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_set_server_updated_cb")]
         internal static extern MediaControllerError SetServerUpdatedCb(MediaControllerClientHandle handle,
             ServerUpdatedCallback callback, IntPtr userData = default(IntPtr));
 
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_unset_server_update_cb")]
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_unset_server_updated_cb")]
         internal static extern MediaControllerError UnsetServerUpdatedCb(MediaControllerClientHandle handle);
 
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_set_playback_update_cb")]
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_set_playback_updated_cb")]
         internal static extern MediaControllerError SetPlaybackUpdatedCb(MediaControllerClientHandle handle,
             PlaybackUpdatedCallback callback, IntPtr userData = default(IntPtr));
 
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_unset_playback_update_cb")]
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_unset_playback_updated_cb")]
         internal static extern MediaControllerError UnsetPlaybackUpdatedCb(MediaControllerClientHandle handle);
 
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_set_metadata_update_cb")]
-        internal static extern MediaControllerError SetMetadataUpdatedCb(MediaControllerClientHandle handle,
-            MetadataUpdatedCallback callback, IntPtr userData = default(IntPtr));
-
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_unset_metadata_update_cb")]
-        internal static extern MediaControllerError UnsetMetadataUpdatedCb(MediaControllerClientHandle handle);
-
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_set_shuffle_mode_update_cb")]
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_set_shuffle_mode_updated_cb")]
         internal static extern MediaControllerError SetShuffleModeUpdatedCb(MediaControllerClientHandle handle,
             ShuffleModeUpdatedCallback callback, IntPtr userData = default(IntPtr));
 
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_unset_shuffle_mode_update_cb")]
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_unset_shuffle_mode_updated_cb")]
         internal static extern MediaControllerError UnsetShuffleModeUpdatedCb(MediaControllerClientHandle handle);
 
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_set_repeat_mode_update_cb")]
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_set_repeat_mode_updated_cb")]
         internal static extern MediaControllerError SetRepeatModeUpdatedCb(MediaControllerClientHandle handle,
             RepeatModeUpdatedCallback callback, IntPtr userData = default(IntPtr));
 
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_unset_repeat_mode_update_cb")]
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_unset_repeat_mode_updated_cb")]
         internal static extern MediaControllerError UnsetRepeatModeUpdatedCb(MediaControllerClientHandle handle);
 
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_set_cmd_reply_received_cb")]
+        internal static extern MediaControllerError SetCommandCompletedCb(MediaControllerClientHandle handle,
+            CommandCompletedCallback callback, IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_unset_cmd_reply_received_cb")]
+        internal static extern MediaControllerError UnsetCommandCompletedCb(MediaControllerClientHandle handle);
+
         [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_playback_state")]
-        internal static extern MediaControllerError GetPlaybackState(IntPtr playback, out MediaControllerPlaybackCode state);
+        internal static extern MediaControllerError GetPlaybackState(IntPtr playback, out MediaControllerNativePlaybackState state);
 
         [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_playback_position")]
         internal static extern MediaControllerError GetPlaybackPosition(IntPtr playback, out ulong position);
@@ -92,51 +95,54 @@ internal static partial class Interop
         [DllImport(Libraries.MediaController, EntryPoint = "mc_client_destroy_playback")]
         internal static extern MediaControllerError DestroyPlayback(IntPtr playback);
 
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_metadata")]
-        private static extern MediaControllerError GetMetadata(IntPtr metadata, MediaControllerAttribute attribute,
-            out IntPtr value);
-
-        internal static string GetMetadata(IntPtr handle, MediaControllerAttribute attr)
-        {
-            IntPtr valuePtr = IntPtr.Zero;
-
-            try
-            {
-                GetMetadata(handle, attr, out valuePtr).ThrowIfError($"Failed to get value for {attr}.");
-                return Marshal.PtrToStringAnsi(valuePtr);
-            }
-            finally
-            {
-                Tizen.Multimedia.LibcSupport.Free(valuePtr);
-            }
-        }
-
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_destroy_metadata")]
-        internal static extern MediaControllerError DestroyMetadata(IntPtr metadata);
-
         [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_latest_server_info")]
         internal static extern MediaControllerError GetLatestServer(MediaControllerClientHandle handle,
-            out IntPtr serverName, out MediaControllerServerState serverState);
+            out IntPtr serverName, out MediaControllerNativeServerState serverState);
 
         [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_server_playback_info")]
         internal static extern MediaControllerError GetServerPlayback(MediaControllerClientHandle handle,
             string serverName, out IntPtr playback);
 
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_server_metadata")]
-        internal static extern MediaControllerError GetServerMetadata(MediaControllerClientHandle handle,
-            string serverName, out IntPtr metadata);
-
         [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_server_shuffle_mode")]
         internal static extern MediaControllerError GetServerShuffleMode(MediaControllerClientHandle handle,
-            string serverName, out MediaControllerShuffleMode mode);
+            string serverName, out MediaControllerNativeShuffleMode mode);
 
         [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_server_repeat_mode")]
         internal static extern MediaControllerError GetServerRepeatMode(MediaControllerClientHandle handle,
-            string serverName, out NativeRepeatMode mode);
+            string serverName, out MediaControllerNativeRepeatMode mode);
 
         [DllImport(Libraries.MediaController, EntryPoint = "mc_client_send_playback_state_command")]
         internal static extern MediaControllerError SendPlaybackStateCommand(MediaControllerClientHandle handle,
-            string serverName, MediaControllerPlaybackCode command);
+            string serverName, MediaControllerNativePlaybackAction command);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_send_custom_cmd")]
+        internal static extern MediaControllerError SendCustomCommandBundle(MediaControllerClientHandle handle,
+            string serverName, string command, SafeBundleHandle bundleHandle, out string requestId);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_send_custom_cmd")]
+        internal static extern MediaControllerError SendCustomCommand(MediaControllerClientHandle handle,
+            string serverName, string command, IntPtr bundleHandle, out string requestId);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_send_playback_action_cmd")]
+        internal static extern MediaControllerError SendPlaybackActionCommand(MediaControllerClientHandle handle,
+            string serverName, MediaControllerNativePlaybackAction action, out string requestId);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_send_playback_position_cmd")]
+        internal static extern MediaControllerError SendPlaybackPositionCommand(MediaControllerClientHandle handle,
+            string serverName, ulong playbackPosition, out string requestId);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_send_shuffle_mode_cmd")]
+        internal static extern MediaControllerError SendShuffleModeCommand(MediaControllerClientHandle handle,
+            string serverName, MediaControllerNativeShuffleMode mode, out string requestId);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_send_repeat_mode_cmd")]
+        internal static extern MediaControllerError SendRepeatModeCommand(MediaControllerClientHandle handle,
+            string serverName, MediaControllerNativeRepeatMode mode, out string requestId);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_send_playlist_cmd")]
+        internal static extern MediaControllerError SendPlaylistCommand(MediaControllerClientHandle handle,
+            string serverName, string playlistName, string index, MediaControllerNativePlaybackAction mode,
+            ulong position, out string requestId);
 
         [DllImport(Libraries.MediaController, EntryPoint = "mc_client_foreach_server")]
         internal static extern MediaControllerError ForeachActivatedServer(MediaControllerClientHandle handle,
diff --git a/src/Tizen.Multimedia.Remoting/Interop/Interop.MediaControllerPlaylist.cs b/src/Tizen.Multimedia.Remoting/Interop/Interop.MediaControllerPlaylist.cs
new file mode 100644 (file)
index 0000000..1d37ca5
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * 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.Runtime.InteropServices;
+using Tizen.Applications;
+using Tizen.Multimedia.Remoting;
+
+internal static partial class Interop
+{
+    internal static partial class MediaControllerPlaylist
+    {
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void MetadataUpdatedCallback(string serverName, IntPtr metadata, IntPtr userData);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void PlaylistUpdatedCallback(string serverName, MediaControlPlaylistMode repeatMode, string playlist,
+            IntPtr handle, IntPtr userData);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void PlaylistCallback(IntPtr handle, IntPtr userData);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate bool PlaylistItemCallback(string index, IntPtr handle, IntPtr userData);
+
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_set_metadata_updated_cb")]
+        internal static extern MediaControllerError SetMetadataUpdatedCb(MediaControllerClientHandle handle,
+            MetadataUpdatedCallback callback, IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_unset_metadata_updated_cb")]
+        internal static extern MediaControllerError UnsetMetadataUpdatedCb(MediaControllerClientHandle handle);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_set_playlist_updated_cb")]
+        internal static extern MediaControllerError SetPlaylistModeUpdatedCb(MediaControllerClientHandle handle,
+            PlaylistUpdatedCallback callback, IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_unset_playlist_updated_cb")]
+        internal static extern MediaControllerError UnsetPlaylistModeUpdatedCb(MediaControllerClientHandle handle);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_metadata_get")]
+        private static extern MediaControllerError GetMetadata(IntPtr metadata, MediaControllerNativeAttribute attribute,
+            out IntPtr value);
+
+        internal static string GetMetadata(IntPtr handle, MediaControllerNativeAttribute attr)
+        {
+            IntPtr valuePtr = IntPtr.Zero;
+
+            try
+            {
+                GetMetadata(handle, attr, out valuePtr).ThrowIfError($"Failed to get value for {attr}.");
+                return Marshal.PtrToStringAnsi(valuePtr);
+            }
+            finally
+            {
+                Tizen.Multimedia.LibcSupport.Free(valuePtr);
+            }
+        }
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_metadata_clone")]
+        internal static extern MediaControllerError CloneMetadata();
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_metadata_destroy")]
+        internal static extern MediaControllerError DestroyMetadata(IntPtr metadata);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_server_metadata")]
+        internal static extern MediaControllerError GetServerMetadata(MediaControllerClientHandle handle,
+            string serverName, out IntPtr metadata);
+
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_playlist_create")]
+        internal static extern MediaControllerError CreatePlaylist(string name, out IntPtr handle);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_playlist_destroy")]
+        internal static extern MediaControllerError DestroyPlaylist(IntPtr handle);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_playlist_clone")]
+        internal static extern MediaControllerError ClonePlaylist(IntPtr source, IntPtr destination);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_playlist_update_item")]
+        internal static extern MediaControllerError UpdatePlaylist(IntPtr handle, string index,
+            MediaControllerNativeAttribute attribute, string value);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_foreach_server_playlist")]
+        internal static extern MediaControllerError ForeachServerPlaylist(MediaControllerClientHandle handle,
+            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);
+
+        internal static string GetPlaylistIndex(IntPtr handle)
+        {
+            IntPtr valuePtr = IntPtr.Zero;
+
+            try
+            {
+                GetPlaylistIndex(handle, out valuePtr).ThrowIfError($"Failed to get playlist.");
+                return Marshal.PtrToStringAnsi(valuePtr);
+            }
+            finally
+            {
+                Tizen.Multimedia.LibcSupport.Free(valuePtr);
+            }
+        }
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_playlist_get_name")]
+        private static extern MediaControllerError GetPlaylistName(IntPtr handle, out IntPtr name);
+
+        // It will be added next commit. Native Fw is not ready yet.
+        //[DllImport(Libraries.MediaController, EntryPoint = "mc_playlist_set_name")]
+        //internal static extern MediaControllerError SetPlaylistName(IntPtr handle, string name);
+
+        internal static string GetPlaylistName(IntPtr handle)
+        {
+            IntPtr valuePtr = IntPtr.Zero;
+
+            try
+            {
+                GetPlaylistName(handle, out valuePtr).ThrowIfError($"Failed to get playlist name.");
+                return Marshal.PtrToStringAnsi(valuePtr);
+            }
+            finally
+            {
+                Tizen.Multimedia.LibcSupport.Free(valuePtr);
+            }
+        }
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_playlist_foreach_item")]
+        internal static extern MediaControllerError ForeachPlaylistItem(IntPtr handle,
+            PlaylistItemCallback callback, IntPtr userData);
+    }
+}
index abd6e58..ce0fe1c 100644 (file)
@@ -16,6 +16,7 @@
 
 using System;
 using System.Runtime.InteropServices;
+using Tizen.Applications;
 using Tizen.Multimedia.Remoting;
 
 internal static partial class Interop
@@ -24,7 +25,36 @@ internal static partial class Interop
     {
         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
         internal delegate void PlaybackStateCommandReceivedCallback(string clientName,
-            MediaControllerPlaybackCode state, IntPtr userData);
+            MediaControllerNativePlaybackAction nativeAction, IntPtr userData);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void PlaybackActionCommandReceivedCallback(string clientName,
+            string requestId, MediaControllerNativePlaybackAction nativeAction, IntPtr userData);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void PlaybackPositionCommandReceivedCallback(string clientName,
+            string requestId, ulong playbackPosition, IntPtr userData);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void PlaylistCommandReceivedCallback(string clientName,
+            string requestId, string playlistName, string index, MediaControllerNativePlaybackAction nativeAction,
+            ulong playbackPosition, IntPtr userData);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void ShuffleModeCommandReceivedCallback(string clientName,
+            string requestId, MediaControllerNativeShuffleMode shuffleMode, IntPtr userData);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void RepeatModeCommandReceivedCallback(string clientName,
+            string requestId, MediaControllerNativeRepeatMode repeatMode, IntPtr userData);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void CustomCommandReceivedCallback(string clientName,
+            string requestId, string customCommand, IntPtr bundleHandle, IntPtr userData);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void PlaylistCallback(IntPtr handle, IntPtr userData);
+
 
         [DllImport(Libraries.MediaController, EntryPoint = "mc_server_create")]
         internal static extern MediaControllerError Create(out IntPtr handle);
@@ -34,7 +64,7 @@ internal static partial class Interop
 
         [DllImport(Libraries.MediaController, EntryPoint = "mc_server_set_playback_state")]
         internal static extern MediaControllerError SetPlaybackState(IntPtr handle,
-            MediaControllerPlaybackCode state);
+            MediaControllerNativePlaybackState state);
 
         [DllImport(Libraries.MediaController, EntryPoint = "mc_server_set_playback_position")]
         internal static extern MediaControllerError SetPlaybackPosition(IntPtr handle, ulong position);
@@ -44,25 +74,75 @@ internal static partial class Interop
 
         [DllImport(Libraries.MediaController, EntryPoint = "mc_server_set_metadata")]
         internal static extern MediaControllerError SetMetadata(IntPtr handle,
-            MediaControllerAttribute attribute, string value);
+            MediaControllerNativeAttribute attribute, string value);
 
         [DllImport(Libraries.MediaController, EntryPoint = "mc_server_update_metadata")]
         internal static extern MediaControllerError UpdateMetadata(IntPtr handle);
 
         [DllImport(Libraries.MediaController, EntryPoint = "mc_server_update_shuffle_mode")]
         internal static extern MediaControllerError UpdateShuffleMode(IntPtr handle,
-            MediaControllerShuffleMode mode);
+            MediaControllerNativeShuffleMode mode);
 
         [DllImport(Libraries.MediaController, EntryPoint = "mc_server_update_repeat_mode")]
-        internal static extern MediaControllerError UpdateRepeatMode(IntPtr handle, NativeRepeatMode mode);
+        internal static extern MediaControllerError UpdateRepeatMode(IntPtr handle, MediaControllerNativeRepeatMode mode);
 
         [DllImport(Libraries.MediaController, EntryPoint = "mc_server_set_playback_state_command_received_cb")]
-        internal static extern MediaControllerError SetPlaybackStateCmdRecvCb(IntPtr handle,
+        internal static extern MediaControllerError SetPlaybackStateCommandReceivedCb(IntPtr handle,
             PlaybackStateCommandReceivedCallback callback, IntPtr userData = default(IntPtr));
 
         [DllImport(Libraries.MediaController, EntryPoint = "mc_server_unset_playback_state_command_received_cb")]
         internal static extern MediaControllerError UnsetPlaybackStateCmdRecvCb(IntPtr handle);
 
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_set_playback_action_cmd_received_cb")]
+        internal static extern MediaControllerError SetPlaybackActionCommandReceivedCb(IntPtr handle,
+            PlaybackActionCommandReceivedCallback callback, IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_unset_playback_action_cmd_received_cb")]
+        internal static extern MediaControllerError UnsetPlaybackActionCommandReceivedCb(IntPtr handle);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_set_playback_position_cmd_received_cb")]
+        internal static extern MediaControllerError SetPlaybackPosotionCommandReceivedCb(IntPtr handle,
+            PlaybackPositionCommandReceivedCallback callback, IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_unset_playback_position_cmd_received_cb")]
+        internal static extern MediaControllerError UnsetPlaybackPositionCommandReceivedCb(IntPtr handle);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_set_playlist_cmd_received_cb")]
+        internal static extern MediaControllerError SetPlaylistCommandReceivedCb(IntPtr handle,
+            PlaylistCommandReceivedCallback callback, IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_unset_playlist_cmd_received_cb")]
+        internal static extern MediaControllerError UnsetPlaylistCommandReceivedCb(IntPtr handle);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_set_shuffle_mode_cmd_received_cb")]
+        internal static extern MediaControllerError SetShuffleModeCommandReceivedCb(IntPtr handle,
+            ShuffleModeCommandReceivedCallback callback, IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_unset_shuffle_mode_cmd_received_cb")]
+        internal static extern MediaControllerError UnsetShuffleModeCommandReceivedCb(IntPtr handle);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_set_repeat_mode_cmd_received_cb")]
+        internal static extern MediaControllerError SetRepeatModeCommandReceivedCb(IntPtr handle,
+            RepeatModeCommandReceivedCallback callback, IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_unset_repeat_mode_cmd_received_cb")]
+        internal static extern MediaControllerError UnsetRepeatModeCommandReceivedCb(IntPtr handle);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_set_custom_cmd_received_cb")]
+        internal static extern MediaControllerError SetCustomCommandReceivedCb(IntPtr handle,
+            CustomCommandReceivedCallback callback, IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_unset_custom_cmd_received_cb")]
+        internal static extern MediaControllerError UnsetCustomCommandReceivedCb(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);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_send_cmd_reply")]
+        internal static extern MediaControllerError SendCommandReply(IntPtr handle,
+            string appId, string requestID, int result, IntPtr bundleHandle);
+
         [DllImport(Libraries.MediaController, EntryPoint = "mc_db_connect")]
         internal static extern MediaControllerError ConnectDb(out IntPtr dbHandle);
 
@@ -71,5 +151,28 @@ internal static partial class Interop
 
         [DllImport(Libraries.MediaController, EntryPoint = "mc_db_check_server_table_exist")]
         internal static extern MediaControllerError CheckServerExist(IntPtr dbHandle, string appId, out bool value);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_create_playlist")]
+        internal static extern MediaControllerError CreatePlaylist(IntPtr handle, string name, out IntPtr playlist);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_delete_playlist")]
+        internal static extern MediaControllerError DeletePlaylist(IntPtr handle, IntPtr playlist);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_foreach_playlist")]
+        internal static extern MediaControllerError ForeachPlaylist(IntPtr handle, PlaylistCallback callback, IntPtr userData);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_set_playlist_item_index")]
+        internal static extern MediaControllerError SetIndexOfCurrentPlayingMedia(IntPtr handle, string index);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_add_item_to_playlist")]
+        internal static extern MediaControllerError AddItemToPlaylist(IntPtr handle,
+            IntPtr playlist, string index, MediaControllerNativeAttribute attribute, string value);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_update_playlist_done")]
+        internal static extern MediaControllerError SavePlaylist(IntPtr handle, IntPtr playlist);
+
+        // 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);
     }
 }
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/CommandCompletedEventArgs.cs b/src/Tizen.Multimedia.Remoting/MediaController/CommandCompletedEventArgs.cs
new file mode 100644 (file)
index 0000000..a78351d
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * 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 Tizen.Applications;
+
+namespace Tizen.Multimedia.Remoting
+{
+    /// <summary>
+    /// Provides data for the <see cref="MediaController.CommandCompleted"/> event.
+    /// </summary>
+    /// <since_tizen> 5 </since_tizen>
+    internal class CommandCompletedEventArgs : EventArgs
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="CommandCompletedEventArgs"/> class.
+        /// </summary>
+        /// <param name="requestId">The request id for each command.</param>
+        /// <param name="result">The result of commands.</param>
+        /// <since_tizen> 5 </since_tizen>
+        internal CommandCompletedEventArgs(string requestId, MediaControllerError result)
+        {
+            RequestId = requestId;
+            Result = result;
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="CommandCompletedEventArgs"/> class with extra data.
+        /// </summary>
+        /// <param name="requestId">The request id for each command.</param>
+        /// <param name="result">The result of commands.</param>
+        /// <param name="bundle">The extra data.</param>
+        /// <since_tizen> 5 </since_tizen>
+        internal CommandCompletedEventArgs(string requestId, MediaControllerError result, Bundle bundle)
+            : this(requestId, result)
+        {
+            Bundle = bundle;
+        }
+
+        /// <summary>
+        /// Gets the request Id.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        internal string RequestId { get; }
+
+        /// <summary>
+        /// Gets the result code for matched commands.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        internal MediaControllerError Result { get; }
+
+        /// <summary>
+        /// Gets the extra data.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        internal Bundle Bundle { get; }
+    }
+}
\ No newline at end of file
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/CustomCommandReceivedEventArgs.cs b/src/Tizen.Multimedia.Remoting/MediaController/CustomCommandReceivedEventArgs.cs
new file mode 100644 (file)
index 0000000..9c65aba
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * 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 Tizen.Applications;
+
+namespace Tizen.Multimedia.Remoting
+{
+    /// <summary>
+    /// Provides data for the <see cref="MediaControlServer.CustomCommandReceived"/> event.
+    /// </summary>
+    /// <since_tizen> 5 </since_tizen>
+    public class CustomCommandReceivedEventArgs : EventArgs
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="CustomCommandReceivedEventArgs"/> class.
+        /// </summary>
+        /// <param name="command">The playback position command.</param>
+        /// <since_tizen> 5 </since_tizen>
+        public CustomCommandReceivedEventArgs(CustomCommand command)
+        {
+            Command = command;
+        }
+
+        /// <summary>
+        /// Gets the <see cref="CustomCommand"/>.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        public CustomCommand Command { get; }
+    }
+}
\ No newline at end of file
index d49135e..2d9fc59 100644 (file)
@@ -21,79 +21,91 @@ namespace Tizen.Multimedia.Remoting
 {
     internal static class EnumExtensions
     {
-        internal static MediaControlPlaybackState ToState(this MediaControllerPlaybackCode code)
+        internal static MediaControlPlaybackState ToPublic(this MediaControllerNativePlaybackState nativeState)
         {
-            switch (code)
+            switch (nativeState)
             {
-                case MediaControllerPlaybackCode.None: return MediaControlPlaybackState.None;
-                case MediaControllerPlaybackCode.Play: return MediaControlPlaybackState.Playing;
-                case MediaControllerPlaybackCode.Pause: return MediaControlPlaybackState.Paused;
-                case MediaControllerPlaybackCode.Stop: return MediaControlPlaybackState.Stopped;
-                case MediaControllerPlaybackCode.FastForward: return MediaControlPlaybackState.FastForwarding;
-                case MediaControllerPlaybackCode.Rewind: return MediaControlPlaybackState.Rewinding;
+                case MediaControllerNativePlaybackState.None: return MediaControlPlaybackState.None;
+                case MediaControllerNativePlaybackState.Play: return MediaControlPlaybackState.Playing;
+                case MediaControllerNativePlaybackState.Pause: return MediaControlPlaybackState.Paused;
+                case MediaControllerNativePlaybackState.Stop: return MediaControlPlaybackState.Stopped;
+                case MediaControllerNativePlaybackState.Next:
+                case MediaControllerNativePlaybackState.MovingToNext: return MediaControlPlaybackState.MovingToNext;
+                case MediaControllerNativePlaybackState.Prev:
+                case MediaControllerNativePlaybackState.MovingToPrev: return MediaControlPlaybackState.MovingToPrevious;
+                case MediaControllerNativePlaybackState.FastForward:
+                case MediaControllerNativePlaybackState.FastForwarding: return MediaControlPlaybackState.FastForwarding;
+                case MediaControllerNativePlaybackState.Rewind:
+                case MediaControllerNativePlaybackState.Rewinding: return MediaControlPlaybackState.Rewinding;
             }
 
-            Debug.Fail($"Not supported code for playback state{code}.");
+            Debug.Fail($"Not supported code for playback state{nativeState}.");
             return MediaControlPlaybackState.None;
         }
 
-        internal static MediaControllerPlaybackCode ToCode(this MediaControlPlaybackState state)
+        internal static MediaControllerNativePlaybackState ToNative(this MediaControlPlaybackState state)
         {
             switch (state)
             {
-                case MediaControlPlaybackState.Playing: return MediaControllerPlaybackCode.Play;
-                case MediaControlPlaybackState.Paused: return MediaControllerPlaybackCode.Pause;
-                case MediaControlPlaybackState.Stopped: return MediaControllerPlaybackCode.Stop;
-                case MediaControlPlaybackState.FastForwarding: return MediaControllerPlaybackCode.FastForward;
-                case MediaControlPlaybackState.Rewinding: return MediaControllerPlaybackCode.Rewind;
+                case MediaControlPlaybackState.Playing: return MediaControllerNativePlaybackState.Play;
+                case MediaControlPlaybackState.Paused: return MediaControllerNativePlaybackState.Pause;
+                case MediaControlPlaybackState.Stopped: return MediaControllerNativePlaybackState.Stop;
+                case MediaControlPlaybackState.MovingToNext: return MediaControllerNativePlaybackState.MovingToNext;
+                case MediaControlPlaybackState.MovingToPrevious: return MediaControllerNativePlaybackState.MovingToPrev;
+                case MediaControlPlaybackState.FastForwarding: return MediaControllerNativePlaybackState.FastForwarding;
+                case MediaControlPlaybackState.Rewinding: return MediaControllerNativePlaybackState.Rewinding;
             }
-            return MediaControllerPlaybackCode.None;
+            return MediaControllerNativePlaybackState.None;
         }
 
-        internal static MediaControlPlaybackCommand ToCommand(this MediaControllerPlaybackCode code)
+        internal static MediaControlPlaybackCommand ToPublic(this MediaControllerNativePlaybackAction nativeAction)
         {
-            switch (code)
+            switch (nativeAction)
             {
-                case MediaControllerPlaybackCode.Play: return MediaControlPlaybackCommand.Play;
-                case MediaControllerPlaybackCode.Pause: return MediaControlPlaybackCommand.Pause;
-                case MediaControllerPlaybackCode.Stop: return MediaControlPlaybackCommand.Stop;
-                case MediaControllerPlaybackCode.Next: return MediaControlPlaybackCommand.Next;
-                case MediaControllerPlaybackCode.Prev: return MediaControlPlaybackCommand.Previous;
-                case MediaControllerPlaybackCode.FastForward: return MediaControlPlaybackCommand.FastForward;
-                case MediaControllerPlaybackCode.Rewind: return MediaControlPlaybackCommand.Rewind;
+                case MediaControllerNativePlaybackAction.Play: return MediaControlPlaybackCommand.Play;
+                case MediaControllerNativePlaybackAction.Pause: return MediaControlPlaybackCommand.Pause;
+                case MediaControllerNativePlaybackAction.Stop: return MediaControlPlaybackCommand.Stop;
+                case MediaControllerNativePlaybackAction.Next: return MediaControlPlaybackCommand.Next;
+                case MediaControllerNativePlaybackAction.Prev: return MediaControlPlaybackCommand.Previous;
+                case MediaControllerNativePlaybackAction.FastForward: return MediaControlPlaybackCommand.FastForward;
+                case MediaControllerNativePlaybackAction.Rewind: return MediaControlPlaybackCommand.Rewind;
+                case MediaControllerNativePlaybackAction.Toggle: return MediaControlPlaybackCommand.Toggle;
             }
 
-            Debug.Fail($"Not supported code for playback command{code}.");
+            Debug.Fail($"Not supported code for playback command{nativeAction}.");
             return MediaControlPlaybackCommand.Play;
         }
 
-        internal static MediaControllerPlaybackCode ToCode(this MediaControlPlaybackCommand command)
+        internal static MediaControllerNativePlaybackAction ToNative(this MediaControlPlaybackCommand command)
         {
             switch (command)
             {
-                case MediaControlPlaybackCommand.Play: return MediaControllerPlaybackCode.Play;
-                case MediaControlPlaybackCommand.Pause: return MediaControllerPlaybackCode.Pause;
-                case MediaControlPlaybackCommand.Stop: return MediaControllerPlaybackCode.Stop;
-                case MediaControlPlaybackCommand.Next: return MediaControllerPlaybackCode.Next;
-                case MediaControlPlaybackCommand.Previous: return MediaControllerPlaybackCode.Prev;
-                case MediaControlPlaybackCommand.FastForward: return MediaControllerPlaybackCode.FastForward;
-                case MediaControlPlaybackCommand.Rewind: return MediaControllerPlaybackCode.Rewind;
+                case MediaControlPlaybackCommand.Play: return MediaControllerNativePlaybackAction.Play;
+                case MediaControlPlaybackCommand.Pause: return MediaControllerNativePlaybackAction.Pause;
+                case MediaControlPlaybackCommand.Stop: return MediaControllerNativePlaybackAction.Stop;
+                case MediaControlPlaybackCommand.Next: return MediaControllerNativePlaybackAction.Next;
+                case MediaControlPlaybackCommand.Previous: return MediaControllerNativePlaybackAction.Prev;
+                case MediaControlPlaybackCommand.FastForward: return MediaControllerNativePlaybackAction.FastForward;
+                case MediaControlPlaybackCommand.Rewind: return MediaControllerNativePlaybackAction.Rewind;
+                case MediaControlPlaybackCommand.Toggle: return MediaControllerNativePlaybackAction.Toggle;
             }
-            return MediaControllerPlaybackCode.Play;
+            return MediaControllerNativePlaybackAction.Play;
         }
 
-        internal static NativeRepeatMode ToNative(this MediaControlRepeatMode mode)
+        internal static MediaControllerNativeRepeatMode ToNative(this MediaControlRepeatMode mode)
         {
             Debug.Assert(Enum.IsDefined(typeof(MediaControlRepeatMode), mode));
 
-            return mode == MediaControlRepeatMode.Off ? NativeRepeatMode.On : NativeRepeatMode.Off;
+            return mode == MediaControlRepeatMode.Off ? MediaControllerNativeRepeatMode.On :
+                (mode == MediaControlRepeatMode.On ? MediaControllerNativeRepeatMode.Off : MediaControllerNativeRepeatMode.OneMedia);
         }
 
-        internal static MediaControlRepeatMode ToPublic(this NativeRepeatMode mode)
+        internal static MediaControlRepeatMode ToPublic(this MediaControllerNativeRepeatMode mode)
         {
-            Debug.Assert(Enum.IsDefined(typeof(NativeRepeatMode), mode));
+            Debug.Assert(Enum.IsDefined(typeof(MediaControllerNativeRepeatMode), mode));
 
-            return mode == NativeRepeatMode.Off ? MediaControlRepeatMode.On : MediaControlRepeatMode.Off;
+            return mode == MediaControllerNativeRepeatMode.Off ? MediaControlRepeatMode.On :
+                (mode == MediaControllerNativeRepeatMode.On ? MediaControlRepeatMode.Off : MediaControlRepeatMode.OneMedia);
         }
     }
 }
\ No newline at end of file
index b25c43b..70dbdab 100644 (file)
  * limitations under the License.
  */
 
-using System.Diagnostics;
-
 namespace Tizen.Multimedia.Remoting
 {
-    internal enum MediaControllerPlaybackCode
+    internal enum MediaControllerNativePlaybackState
     {
         None,
         Play,
         Pause,
         Stop,
+        Next,           // Deprecated since 4.0
+        Prev,           // Deprecated since 4.0
+        FastForward,    // Deprecated since 4.0
+        Rewind,         // Deprecated since 4.0
+        MovingToNext,   // Since 4.0
+        MovingToPrev,   // Since 4.0
+        FastForwarding, // Since 4.0
+        Rewinding       // Since 4.0
+    }
+
+    internal enum MediaControllerNativePlaybackAction
+    {
+        Play,
+        Pause,
+        Stop,
         Next,
         Prev,
         FastForward,
         Rewind,
+        Toggle
     }
 
-    internal enum MediaControllerServerState
+    internal enum MediaControllerNativeServerState
     {
         None,
         Activated,
         Deactivated,
     }
 
-    internal enum MediaControllerShuffleMode
+    internal enum MediaControllerNativeShuffleMode
     {
         On,
         Off,
     }
 
-    internal enum NativeRepeatMode
+    internal enum MediaControllerNativeRepeatMode
     {
         On,
         Off,
+        OneMedia
     }
 
-    internal enum MediaControllerAttribute
+    internal enum MediaControllerNativeAttribute
     {
         Title,
         Artist,
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/MediaControlCommand.cs b/src/Tizen.Multimedia.Remoting/MediaController/MediaControlCommand.cs
new file mode 100644 (file)
index 0000000..769d00b
--- /dev/null
@@ -0,0 +1,349 @@
+/*
+ * 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 Tizen.Applications;
+using System;
+using NativeClient = Interop.MediaControllerClient;
+using NativeServer = Interop.MediaControllerServer;
+using NativeClientHandle = Interop.MediaControllerClientHandle;
+
+namespace Tizen.Multimedia.Remoting
+{
+    /// <summary>
+    /// Provides a means to send command to media control server.
+    /// </summary>
+    /// <since_tizen> 5 </since_tizen>
+    public abstract class Command
+    {
+        private string _requestId;
+
+        internal NativeClientHandle _clientHandle;
+
+        private string _clientId;
+
+        /// <summary>
+        /// The server id.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        protected string _serverId;
+
+        /// <summary>
+        /// Initializes a <see cref="Command"/> base class.
+        /// </summary>
+        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)
+        {
+            _serverId = serverId;
+            _clientHandle = clientrHandle;
+        }
+
+        /// <summary>
+        /// Sets the client information.
+        /// </summary>
+        /// <param name="clientId">The client Id that will be received response.</param>
+        /// <param name="requestId">The request Id for each command.</param>
+        internal void SetClientInfo(string clientId, string requestId)
+        {
+            _clientId = clientId;
+            _requestId = requestId;
+        }
+    }
+
+
+    /// <summary>
+    /// Provides a means to send playback command to media control server.
+    /// </summary>
+    public sealed class PlaybackCommand : Command
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PlaybackCommand"/> class.
+        /// </summary>
+        /// <param name="action">A <see cref="MediaControlPlaybackCommand"/>.</param>
+        /// <since_tizen> 5 </since_tizen>
+        public PlaybackCommand(MediaControlPlaybackCommand action)
+        {
+            Action = action;
+        }
+
+        /// <summary>
+        /// Gets the playback action.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        public MediaControlPlaybackCommand Action { get; }
+
+        internal override string Request()
+        {
+            ValidationUtil.ValidateEnum(typeof(MediaControlPlaybackCommand), Action, nameof(MediaControlPlaybackCommand));
+
+            NativeClient.SendPlaybackActionCommand(_clientHandle, _serverId, Action.ToNative(), out string requestId)
+                .ThrowIfError("Failed to send playback command.");
+
+            return requestId;
+        }
+    }
+
+    /// <summary>
+    /// Provides a means to send playback command to order specific time position.
+    /// </summary>
+    public sealed class PlaybackPositionCommand : Command
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PlaybackPositionCommand"/> class.
+        /// </summary>
+        /// <param name="position">The playback position in milliseconds.</param>
+        /// <since_tizen> 5 </since_tizen>
+        public PlaybackPositionCommand(ulong position)
+        {
+            Position = position;
+        }
+
+        /// <summary>
+        /// Gets the position to play.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        public ulong Position { get; }
+
+        internal override string Request()
+        {
+            NativeClient.SendPlaybackPositionCommand(_clientHandle, _serverId, Position, out string requestId)
+                .ThrowIfError("Failed to send playback position command.");
+
+            return requestId;
+        }
+    }
+
+    /// <summary>
+    /// Provides a means to send playback command with playlist information.
+    /// </summary>
+    public sealed class PlaylistCommand : Command
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PlaybackCommand"/> class.
+        /// </summary>
+        /// <param name="action">A <see cref="MediaControlPlaybackCommand"/>.</param>
+        /// <param name="playlistName">The playlist name of the server.</param>
+        /// <param name="index">The index of the media in the playlist.</param>
+        /// <param name="position">The playback position in milliseconds.</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 vailed.
+        /// </exception>
+        /// <since_tizen> 5 </since_tizen>
+        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.");
+            Position = position;
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PlaybackCommand"/> class.
+        /// </summary>
+        /// <param name="action">A <see cref="MediaControlPlaybackCommand"/>.</param>
+        /// <param name="playlistName">The playlist name of the server.</param>
+        /// <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.
+        /// </exception>
+        /// <since_tizen> 5 </since_tizen>
+        public PlaylistCommand(MediaControlPlaybackCommand action, string playlistName, string index)
+            : this(action, playlistName, index, 0)
+        {
+        }
+
+        /// <summary>
+        /// Gets the playback action.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        public MediaControlPlaybackCommand Action { get; }
+
+        /// <summary>
+        /// Gets the position to play.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        public ulong Position { get; }
+
+        /// <summary>
+        /// Gets the index of playlist.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        public string Index { get; }
+
+        /// <summary>
+        /// Gets the name of playlist.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        public string Name { get; }
+
+        internal override string Request()
+        {
+            ValidationUtil.ValidateEnum(typeof(MediaControlPlaybackCommand), Action, nameof(MediaControlPlaybackCommand));
+
+            NativeClient.SendPlaylistCommand(_clientHandle, _serverId, Name, Index, Action.ToNative(),
+                Position, out string requestId).ThrowIfError("Failed to send playlist command.");
+
+            return requestId;
+        }
+    }
+
+    /// <summary>
+    /// Provides a means to to send shuffle mode commands.
+    /// </summary>
+    /// <since_tizen> 5 </since_tizen>
+    public sealed class ShuffleModeCommand : Command
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ShuffleModeCommand"/> class.
+        /// </summary>
+        /// <param name="enabled">A shuffle mode.</param>
+        /// <since_tizen> 5 </since_tizen>
+        public ShuffleModeCommand(bool enabled)
+        {
+            Enabled = enabled;
+        }
+
+        /// <summary>
+        /// Gets a value indicating whether the shuffle mode is enabled.
+        /// </summary>
+        public bool Enabled { get; }
+
+        internal override string Request()
+        {
+            var mode = Enabled ? MediaControllerNativeShuffleMode.On : MediaControllerNativeShuffleMode.Off;
+
+            NativeClient.SendShuffleModeCommand(_clientHandle, _serverId, mode, out string requestId).
+                ThrowIfError("Failed to send playback shuffle command.");
+
+            return requestId;
+        }
+    }
+
+    /// <summary>
+    /// Provides a means to to send repeat mode commands.
+    /// </summary>
+    /// <since_tizen> 5 </since_tizen>
+    public sealed class RepeatModeCommand : Command
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="RepeatModeCommand"/> class.
+        /// </summary>
+        /// <param name="mode">The <see cref="MediaControlRepeatMode"/>.</param>
+        /// <since_tizen> 5 </since_tizen>
+        public RepeatModeCommand(MediaControlRepeatMode mode)
+        {
+            Mode = mode;
+        }
+
+        /// <summary>
+        /// Gets the repeat mode.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        public MediaControlRepeatMode Mode { get; }
+
+        internal override string Request()
+        {
+            ValidationUtil.ValidateEnum(typeof(MediaControlRepeatMode), Mode, nameof(MediaControlRepeatMode));
+
+            NativeClient.SendRepeatModeCommand(_clientHandle, _serverId, Mode.ToNative(), out string requestId).
+                ThrowIfError("Failed to send playback repeat command.");
+
+            return requestId;
+        }
+    }
+
+    /// <summary>
+    /// Provides a means to to send custom commands.
+    /// </summary>
+    /// <since_tizen> 5 </since_tizen>
+    public sealed class CustomCommand : Command
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="CustomCommand"/> class.
+        /// </summary>
+        /// <param name="action">A predefined custom command.</param>
+        /// <since_tizen> 5 </since_tizen>
+        public CustomCommand(string action)
+        {
+            Action = action ?? throw new ArgumentNullException("Custom command is not set.");
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="CustomCommand"/> class.
+        /// </summary>
+        /// <param name="action">A predefined custom command.</param>
+        /// <param name="bundle">The extra data for custom command.</param>
+        /// <since_tizen> 5 </since_tizen>
+        public CustomCommand(string action, Bundle bundle)
+            : this(action)
+        {
+            Bundle = bundle;
+        }
+
+        ///<summary>
+        /// Gets the custom action.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        public string Action { get; }
+
+        /// <summary>
+        /// Gets the extra data.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        public Bundle Bundle { get; }
+
+        internal override string Request()
+        {
+            string requestId = null;
+
+            if (Bundle != null)
+            {
+                NativeClient.SendCustomCommandBundle(_clientHandle, _serverId, Action, Bundle.SafeBundleHandle, out requestId).
+                    ThrowIfError("Failed to send custom command.");
+            }
+            else
+            {
+                NativeClient.SendCustomCommand(_clientHandle, _serverId, Action, IntPtr.Zero, out requestId).
+                    ThrowIfError("Failed to send custom command.");
+            }
+
+            return requestId;
+        }
+    }
+}
\ No newline at end of file
index 813d343..ebee980 100644 (file)
@@ -1,4 +1,4 @@
-/*
+/*
  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
  *
  * Licensed under the Apache License, Version 2.0 (the License);
@@ -16,7 +16,7 @@
 
 using System;
 using System.Diagnostics;
-using Native = Interop.MediaControllerClient;
+using Native = Interop.MediaControllerPlaylist;
 
 namespace Tizen.Multimedia.Remoting
 {
@@ -38,17 +38,17 @@ namespace Tizen.Multimedia.Remoting
         {
             Debug.Assert(handle != IntPtr.Zero);
 
-            Title = Native.GetMetadata(handle, MediaControllerAttribute.Title);
-            Artist = Native.GetMetadata(handle, MediaControllerAttribute.Artist);
-            Album = Native.GetMetadata(handle, MediaControllerAttribute.Album);
-            Author = Native.GetMetadata(handle, MediaControllerAttribute.Author);
-            Genre = Native.GetMetadata(handle, MediaControllerAttribute.Genre);
-            Duration = Native.GetMetadata(handle, MediaControllerAttribute.Duration);
-            Date = Native.GetMetadata(handle, MediaControllerAttribute.Date);
-            Copyright = Native.GetMetadata(handle, MediaControllerAttribute.Copyright);
-            Description = Native.GetMetadata(handle, MediaControllerAttribute.Description);
-            TrackNumber = Native.GetMetadata(handle, MediaControllerAttribute.TrackNumber);
-            AlbumArtPath = Native.GetMetadata(handle, MediaControllerAttribute.Picture);
+            Title = Native.GetMetadata(handle, MediaControllerNativeAttribute.Title);
+            Artist = Native.GetMetadata(handle, MediaControllerNativeAttribute.Artist);
+            Album = Native.GetMetadata(handle, MediaControllerNativeAttribute.Album);
+            Author = Native.GetMetadata(handle, MediaControllerNativeAttribute.Author);
+            Genre = Native.GetMetadata(handle, MediaControllerNativeAttribute.Genre);
+            Duration = Native.GetMetadata(handle, MediaControllerNativeAttribute.Duration);
+            Date = Native.GetMetadata(handle, MediaControllerNativeAttribute.Date);
+            Copyright = Native.GetMetadata(handle, MediaControllerNativeAttribute.Copyright);
+            Description = Native.GetMetadata(handle, MediaControllerNativeAttribute.Description);
+            TrackNumber = Native.GetMetadata(handle, MediaControllerNativeAttribute.TrackNumber);
+            AlbumArtPath = Native.GetMetadata(handle, MediaControllerNativeAttribute.Picture);
         }
 
         /// <summary>
index f092ca8..1a924d4 100644 (file)
@@ -56,5 +56,11 @@ namespace Tizen.Multimedia.Remoting
         /// Rewind.
         /// </summary>
         Rewind,
+
+        /// <summary>
+        /// Toggle play/pause.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        Toggle,
     }
 }
\ No newline at end of file
index 3c4a973..12b54f5 100644 (file)
@@ -51,5 +51,17 @@ namespace Tizen.Multimedia.Remoting
         /// 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,
     }
 }
\ No newline at end of file
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/MediaControlPlaylist.cs b/src/Tizen.Multimedia.Remoting/MediaController/MediaControlPlaylist.cs
new file mode 100644 (file)
index 0000000..163a249
--- /dev/null
@@ -0,0 +1,260 @@
+/*
+ * 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 NativeClient = Interop.MediaControllerClient;
+using NativeServer = Interop.MediaControllerServer;
+using NativePlaylist = Interop.MediaControllerPlaylist;
+
+namespace Tizen.Multimedia.Remoting
+{
+    /// <summary>
+    /// Represents playlist for media control.
+    /// </summary>
+    /// <since_tizen> 5 </since_tizen>
+    public class MediaControlPlaylist : IDisposable
+    {
+        private IntPtr _handle;
+        private Dictionary<string, MediaControlMetadata> _metadata = null;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="MediaControlPlaylist"/> class by server side.
+        /// </summary>
+        /// <param name="name">The name of this playlist.</param>
+        internal MediaControlPlaylist(string name)
+        {
+            if (name == null)
+            {
+                throw new ArgumentNullException("The playlist name is not set.");
+            }
+
+            NativePlaylist.CreatePlaylist(name, out IntPtr handle).ThrowIfError("Failed to create playlist");
+
+            Name = name;
+
+            UpdateMetadata(handle);
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="MediaControlPlaylist"/> class with the playlist handle that created already.
+        /// </summary>
+        /// <param name="handle">The handle of playlist.</param>
+        internal MediaControlPlaylist(IntPtr handle)
+        {
+            if (handle == IntPtr.Zero)
+            {
+                throw new ArgumentNullException("The handle is not set.");
+            }
+
+            // handle will be destroyed in Native FW side.
+            Name = NativePlaylist.GetPlaylistName(handle);
+
+            UpdateMetadata(handle);
+        }
+
+        /// <summary>
+        /// Finalizes an instance of the <see cref="MediaControlPlaylist"/> class.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        ~MediaControlPlaylist()
+        {
+            Dispose(false);
+        }
+
+        internal IntPtr Handle
+        {
+            get
+            {
+                if (_handle == IntPtr.Zero)
+                {
+                    _handle = MediaControlServer.GetPlaylistHandle(Name);
+                }
+                return _handle;
+            }
+            set
+            {
+                _handle = value;
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets the name of playlist.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        public string Name { get; private set; }
+
+        /// <summary>
+        /// Gets the total number of media in this playlist.
+        /// </summary>
+        public int TotalCount
+        {
+            get
+            {
+                return _metadata != null ? _metadata.Count : 0;
+            }
+        }
+
+        private void UpdateMetadata(IntPtr handle)
+        {
+            NativePlaylist.PlaylistItemCallback playlistItemCallback = (index, metadataHandle, _) =>
+            {
+                _metadata.Add(index, new MediaControlMetadata(metadataHandle));
+                return true;
+            };
+            NativePlaylist.ForeachPlaylistItem(handle, playlistItemCallback, IntPtr.Zero).
+                ThrowIfError("Failed to retrieve playlist item.");
+        }
+
+        /// <summary>
+        /// Gets the playlist index and metadata pair.
+        /// </summary>
+        /// <returns>The dictionary set of index and <see cref="MediaControlMetadata"/> pair.</returns>
+        public Dictionary<string, MediaControlMetadata> GetMetadata()
+        {
+            if (_metadata == null)
+            {
+                UpdateMetadata(Handle);
+            }
+
+            return _metadata;
+        }
+
+        /// <summary>
+        /// Gets the metadata by index.
+        /// </summary>
+        /// <param name="index"></param>
+        /// <returns>A <see cref="MediaControlMetadata"/> instance.</returns>
+        public MediaControlMetadata GetMetadata(string index)
+        {
+            if (_metadata == null)
+            {
+                UpdateMetadata(Handle);
+            }
+
+            if (_metadata.TryGetValue(index, out MediaControlMetadata metadata))
+            {
+                return metadata;
+            }
+
+            return null;
+        }
+
+        /// <summary>
+        /// Sets the metadata to the playlist.
+        /// </summary>
+        /// <param name="metadata"></param>
+        /// <since_tizen> 5 </since_tizen>
+        public void AddMetadata(Dictionary<string, MediaControlMetadata> metadata)
+        {
+            foreach (var data in metadata)
+            {
+                AddMetadata(data.Key, data.Value);
+            }
+
+            MediaControlServer.SavePlaylist(Handle);
+        }
+
+        /// <summary>
+        /// Sets the metadata to the playlist.
+        /// </summary>
+        /// <param name="index"></param>
+        /// <param name="metadata"></param>
+        /// <since_tizen> 5 </since_tizen>
+        public void AddMetadata(string index, MediaControlMetadata metadata)
+        {
+            AddItemToPlaylist(index, metadata);
+            _metadata.Add(index, metadata);
+
+            MediaControlServer.SavePlaylist(Handle);
+        }
+
+        private void AddItemToPlaylist(string index, MediaControlMetadata metadata)
+        {
+            void AddMetadataToNative(string idx, MediaControllerNativeAttribute attribute, string value)
+            {
+                // This API doesn't save playlist to the storage. So we need to call MediaControlServer.SavePlaylist()
+                // after all items are updated.
+                NativePlaylist.UpdatePlaylist(Handle, idx, attribute, value)
+                    .ThrowIfError("Failed to update playlist");
+            }
+
+            AddMetadataToNative(index, MediaControllerNativeAttribute.Album, metadata.Album);
+            AddMetadataToNative(index, MediaControllerNativeAttribute.Artist, metadata.Artist);
+            AddMetadataToNative(index, MediaControllerNativeAttribute.Author, metadata.Author);
+            AddMetadataToNative(index, MediaControllerNativeAttribute.Copyright, metadata.Copyright);
+            AddMetadataToNative(index, MediaControllerNativeAttribute.Date, metadata.Date);
+            AddMetadataToNative(index, MediaControllerNativeAttribute.Description, metadata.Description);
+            AddMetadataToNative(index, MediaControllerNativeAttribute.Duration, metadata.Duration);
+            AddMetadataToNative(index, MediaControllerNativeAttribute.Genre, metadata.Genre);
+            AddMetadataToNative(index, MediaControllerNativeAttribute.Picture, metadata.AlbumArtPath);
+            AddMetadataToNative(index, MediaControllerNativeAttribute.Title, metadata.Title);
+            AddMetadataToNative(index, MediaControllerNativeAttribute.TrackNumber, metadata.TrackNumber);
+        }
+
+        /// <summary>
+        /// Update the playlist by lastest info.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        public void Update()
+        {
+            // Update the name of playlist.
+            Name = NativePlaylist.GetPlaylistName(Handle);
+
+            // Update metadata.
+            UpdateMetadata(Handle);
+        }
+
+        internal void Destroy()
+        {
+            NativePlaylist.DestroyPlaylist(Handle).ThrowIfError("Failed to delete playlist");
+        }
+
+        #region Dispose support
+        private bool _disposed;
+
+        /// <summary>
+        /// Releases the unmanaged resources used by the MediaControlPlaylist.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        public void Dispose()
+        {
+            Dispose(true);
+        }
+
+        /// <summary>
+        /// Releases the resources used by the Recorder.
+        /// </summary>
+        /// <param name="disposing">
+        /// true to release both managed and unmanaged resources; false to release only unmanaged resources.
+        /// </param>
+        /// <since_tizen> 3 </since_tizen>
+        protected virtual void Dispose(bool disposing)
+        {
+            if (!_disposed)
+            {
+                if (_handle != IntPtr.Zero)
+                {
+                    Destroy();
+                    _handle = IntPtr.Zero;
+                }
+
+                _disposed = true;
+            }
+        }
+        #endregion Dispose support
+    }
+}
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/MediaControlServer.Events.cs b/src/Tizen.Multimedia.Remoting/MediaController/MediaControlServer.Events.cs
new file mode 100644 (file)
index 0000000..951ad77
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ * 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 Tizen.Applications;
+using System;
+using Native = Interop.MediaControllerServer;
+
+namespace Tizen.Multimedia.Remoting
+{
+    public static partial class MediaControlServer
+    {
+        private static Native.PlaybackStateCommandReceivedCallback _playbackCommandCallback;
+        private static Native.PlaybackActionCommandReceivedCallback _playbackActionCommandCallback;
+        private static Native.PlaybackPositionCommandReceivedCallback _playbackPositionCommandCallback;
+        private static Native.PlaylistCommandReceivedCallback _playlistCommandCallback;
+        private static Native.ShuffleModeCommandReceivedCallback _shuffleModeCommandCallback;
+        private static Native.RepeatModeCommandReceivedCallback _repeatModeCommandCallback;
+        private static Native.CustomCommandReceivedCallback _customCommandCallback;
+
+        /// <summary>
+        /// Occurs when a client sends playback command.
+        /// </summary>
+        /// <since_tizen> 4 </since_tizen>
+        [Obsolete("Please do not use! This will be deprecated. Please use PlaybackActionCommandReceived instead.")]
+        public static event EventHandler<PlaybackCommandReceivedEventArgs> PlaybackCommandReceived;
+
+        /// <summary>
+        /// Occurs when a client sends playback command.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        public static event EventHandler<PlaybackActionCommandReceivedEventArgs> PlaybackActionCommandReceived;
+
+        /// <summary>
+        /// Occurs when a client sends playback position command.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        public static event EventHandler<PlaybackPositionCommandReceivedEventArgs> PlaybackPositionCommandReceived;
+
+        /// <summary>
+        /// Occurs when a client sends playlist command.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        public static event EventHandler<PlaylistCommandReceivedEventArgs> PlaylistCommandReceived;
+
+        /// <summary>
+        /// Occurs when a client sends shuffle mode command.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        public static event EventHandler<ShuffleModeCommandReceivedEventArgs> ShuffleModeCommandReceived;
+
+        /// <summary>
+        /// Occurs when a client sends repeat mode command.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        public static event EventHandler<RepeatModeCommandReceivedEventArgs> RepeatModeCommandReceived;
+
+        /// <summary>
+        /// Occurs when a client sends custom command.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        public static event EventHandler<CustomCommandReceivedEventArgs> CustomCommandReceived;
+
+        private static void RegisterPlaybackCommandReceivedEvent()
+        {
+            _playbackCommandCallback = (clientName, playbackCode, _) =>
+            {
+                PlaybackCommandReceived?.Invoke(null, new PlaybackCommandReceivedEventArgs(clientName, playbackCode.ToPublic()));
+            };
+            Native.SetPlaybackStateCommandReceivedCb(Handle, _playbackCommandCallback).
+                ThrowIfError("Failed to init PlaybackStateCommandReceived event.");
+        }
+
+        private static void RegisterPlaybackActionCommandReceivedEvent()
+        {
+            _playbackActionCommandCallback = (clientName, requestId, playbackCommand, _) =>
+            {
+                var command = new PlaybackCommand(playbackCommand.ToPublic());
+                command.SetClientInfo(clientName, requestId);
+
+                PlaybackActionCommandReceived?.Invoke(null, new PlaybackActionCommandReceivedEventArgs(command));
+            };
+            Native.SetPlaybackActionCommandReceivedCb(Handle, _playbackActionCommandCallback).
+                ThrowIfError("Failed to init PlaybackActionCommandReceived event.");
+        }
+
+        private static void RegisterPlaybackPositionCommandReceivedEvent()
+        {
+            _playbackPositionCommandCallback = (clientName, requestId, playbackPosition, _) =>
+            {
+                var command = new PlaybackPositionCommand(playbackPosition);
+                command.SetClientInfo(clientName, requestId);
+
+                PlaybackPositionCommandReceived?.Invoke(null, new PlaybackPositionCommandReceivedEventArgs(command));
+            };
+            Native.SetPlaybackPosotionCommandReceivedCb(Handle, _playbackPositionCommandCallback).
+                ThrowIfError("Failed to init PlaybackPositionCommandReceived event.");
+        }
+
+        private static void RegisterPlaylistCommandReceivedEvent()
+        {
+            _playlistCommandCallback = (clientName, requestId, playlistName, index, playbackCommand, playbackPosition, _) =>
+            {
+                var command = new PlaylistCommand(playbackCommand.ToPublic(), playlistName, index, playbackPosition);
+                command.SetClientInfo(clientName, requestId);
+
+                PlaylistCommandReceived?.Invoke(null, new PlaylistCommandReceivedEventArgs(command));
+            };
+            Native.SetPlaylistCommandReceivedCb(Handle, _playlistCommandCallback).
+                ThrowIfError("Failed to init PlaylistCommandReceived event.");
+        }
+
+        private static void RegisterShuffleModeCommandReceivedEvent()
+        {
+            _shuffleModeCommandCallback = (clientName, requestId, mode, _) =>
+            {
+                var command = new ShuffleModeCommand(mode == MediaControllerNativeShuffleMode.On ? true : false);
+                command.SetClientInfo(clientName, requestId);
+
+                ShuffleModeCommandReceived?.Invoke(null, new ShuffleModeCommandReceivedEventArgs(command));
+            };
+            Native.SetShuffleModeCommandReceivedCb(Handle, _shuffleModeCommandCallback).
+                ThrowIfError("Failed to init ShuffleModeCommandReceived event.");
+        }
+
+        private static void RegisterRepeatModeCommandReceivedEvent()
+        {
+            _repeatModeCommandCallback = (clientName, requestId, mode, _) =>
+            {
+                var command = new RepeatModeCommand(mode.ToPublic());
+                command.SetClientInfo(clientName, requestId);
+
+                RepeatModeCommandReceived?.Invoke(null, new RepeatModeCommandReceivedEventArgs(command));
+            };
+            Native.SetRepeatModeCommandReceivedCb(Handle, _repeatModeCommandCallback).
+                ThrowIfError("Failed to init RepeatModeCommandReceived event.");
+        }
+
+        private static void RegisterCustomCommandReceivedEvent()
+        {
+            _customCommandCallback = (clientName, requestId, customCommand, bundleHandle, _) =>
+            {
+                CustomCommand command = null;
+                if (bundleHandle != IntPtr.Zero)
+                {
+                    command = new CustomCommand(customCommand, new Bundle(new SafeBundleHandle(bundleHandle, true)));
+                }
+                else
+                {
+                    command = new CustomCommand(customCommand);
+                }
+
+                command.SetClientInfo(clientName, requestId);
+
+                CustomCommandReceived?.Invoke(null, new CustomCommandReceivedEventArgs(command));
+            };
+            Native.SetCustomCommandReceivedCb(Handle, _customCommandCallback).
+                ThrowIfError("Failed to init CustomCommandReceived event.");
+        }
+    }
+}
\ No newline at end of file
index 2f8ffa6..bdf5a14 100644 (file)
@@ -15,6 +15,8 @@
  */
 
 using System;
+using System.Collections.Generic;
+using Tizen.Applications;
 using Native = Interop.MediaControllerServer;
 
 namespace Tizen.Multimedia.Remoting
@@ -25,7 +27,7 @@ namespace Tizen.Multimedia.Remoting
     /// <seealso cref="MediaControllerManager"/>
     /// <seealso cref="MediaController"/>
     /// <since_tizen> 4 </since_tizen>
-    public static class MediaControlServer
+    public static partial class MediaControlServer
     {
         private static IntPtr _handle = IntPtr.Zero;
         private static bool? _isRunning;
@@ -103,6 +105,13 @@ namespace Tizen.Multimedia.Remoting
             try
             {
                 RegisterPlaybackCommandReceivedEvent();
+                RegisterPlaybackActionCommandReceivedEvent();
+                RegisterPlaybackPositionCommandReceivedEvent();
+                RegisterPlaylistCommandReceivedEvent();
+                RegisterShuffleModeCommandReceivedEvent();
+                RegisterRepeatModeCommandReceivedEvent();
+                RegisterCustomCommandReceivedEvent();
+
                 _isRunning = true;
             }
             catch
@@ -175,14 +184,14 @@ namespace Tizen.Multimedia.Remoting
                 throw new ArgumentOutOfRangeException(nameof(position), position, "position can't be less than zero.");
             }
 
-            Native.SetPlaybackState(Handle, state.ToCode()).ThrowIfError("Failed to set playback state.");
+            Native.SetPlaybackState(Handle, state.ToNative()).ThrowIfError("Failed to set playback state.");
 
             Native.SetPlaybackPosition(Handle, (ulong)position).ThrowIfError("Failed to set playback position.");
 
             Native.UpdatePlayback(Handle).ThrowIfError("Failed to set playback.");
         }
 
-        private static void SetMetadata(MediaControllerAttribute attribute, string value)
+        private static void SetMetadata(MediaControllerNativeAttribute attribute, string value)
         {
             Native.SetMetadata(Handle, attribute, value).ThrowIfError($"Failed to set metadata({attribute}).");
         }
@@ -205,17 +214,17 @@ namespace Tizen.Multimedia.Remoting
                 throw new ArgumentNullException(nameof(metadata));
             }
 
-            SetMetadata(MediaControllerAttribute.Title, metadata.Title);
-            SetMetadata(MediaControllerAttribute.Artist, metadata.Artist);
-            SetMetadata(MediaControllerAttribute.Album, metadata.Album);
-            SetMetadata(MediaControllerAttribute.Author, metadata.Author);
-            SetMetadata(MediaControllerAttribute.Genre, metadata.Genre);
-            SetMetadata(MediaControllerAttribute.Duration, metadata.Duration);
-            SetMetadata(MediaControllerAttribute.Date, metadata.Date);
-            SetMetadata(MediaControllerAttribute.Copyright, metadata.Copyright);
-            SetMetadata(MediaControllerAttribute.Description, metadata.Description);
-            SetMetadata(MediaControllerAttribute.TrackNumber, metadata.TrackNumber);
-            SetMetadata(MediaControllerAttribute.Picture, metadata.AlbumArtPath);
+            SetMetadata(MediaControllerNativeAttribute.Title, metadata.Title);
+            SetMetadata(MediaControllerNativeAttribute.Artist, metadata.Artist);
+            SetMetadata(MediaControllerNativeAttribute.Album, metadata.Album);
+            SetMetadata(MediaControllerNativeAttribute.Author, metadata.Author);
+            SetMetadata(MediaControllerNativeAttribute.Genre, metadata.Genre);
+            SetMetadata(MediaControllerNativeAttribute.Duration, metadata.Duration);
+            SetMetadata(MediaControllerNativeAttribute.Date, metadata.Date);
+            SetMetadata(MediaControllerNativeAttribute.Copyright, metadata.Copyright);
+            SetMetadata(MediaControllerNativeAttribute.Description, metadata.Description);
+            SetMetadata(MediaControllerNativeAttribute.TrackNumber, metadata.TrackNumber);
+            SetMetadata(MediaControllerNativeAttribute.Picture, metadata.AlbumArtPath);
 
             Native.UpdateMetadata(Handle).ThrowIfError("Failed to set metadata.");
         }
@@ -232,7 +241,7 @@ namespace Tizen.Multimedia.Remoting
         /// <since_tizen> 4 </since_tizen>
         public static void SetShuffleModeEnabled(bool enabled)
         {
-            Native.UpdateShuffleMode(Handle, enabled ? MediaControllerShuffleMode.On : MediaControllerShuffleMode.Off).
+            Native.UpdateShuffleMode(Handle, enabled ? MediaControllerNativeShuffleMode.On : MediaControllerNativeShuffleMode.Off).
                 ThrowIfError("Failed to set shuffle mode.");
         }
 
@@ -255,21 +264,84 @@ namespace Tizen.Multimedia.Remoting
         }
 
         /// <summary>
-        /// Occurs when a client sends playback command.
+        /// Sets the index of current playing media.
         /// </summary>
-        /// <since_tizen> 4 </since_tizen>
-        public static event EventHandler<PlaybackCommandReceivedEventArgs> PlaybackCommandReceived;
+        /// <param name="index">The index of current playing media.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="index"/> is null.</exception>
+        /// <exception cref="InvalidOperationException">
+        ///     The server is not running .<br/>
+        ///     -or-<br/>
+        ///     An internal error occurs.
+        /// </exception>
+        /// <since_tizen> 5 </since_tizen>
+        public static void SetIndexOfCurrentPlayingMedia(string index)
+        {
+            Native.SetIndexOfCurrentPlayingMedia(Handle, index)
+                .ThrowIfError("Failed to set the index of current playing media");
+        }
+
+        /// <summary>
+        /// Delete playlist.
+        /// </summary>
+        /// <param name="playlist">The name of playlist.</param>
+        /// <exception cref="InvalidOperationException">
+        ///     The server is not running .<br/>
+        ///     -or-<br/>
+        ///     An internal error occurs.
+        /// </exception>
+        /// <since_tizen> 5 </since_tizen>
+        public static void RemovePlaylist(MediaControlPlaylist playlist)
+        {
+            Native.DeletePlaylist(Handle, playlist.Handle);
+            playlist.Dispose();
+        }
 
-        private static Native.PlaybackStateCommandReceivedCallback _playbackCommandCallback;
+        // Saves the playlist to the persistent storage.
+        internal static void SavePlaylist(IntPtr playlistHandle)
+        {
+            Native.SavePlaylist(Handle, playlistHandle).ThrowIfError("Failed to save playlist");
+        }
 
-        private static void RegisterPlaybackCommandReceivedEvent()
+        // Gets the playlist handle by name.
+        internal static IntPtr GetPlaylistHandle(string name)
         {
-            _playbackCommandCallback = (clientName, playbackCode, _) =>
-            {
-                PlaybackCommandReceived?.Invoke(null, new PlaybackCommandReceivedEventArgs(clientName, playbackCode.ToCommand()));
-            };
-            Native.SetPlaybackStateCmdRecvCb(Handle, _playbackCommandCallback).
-                ThrowIfError("Failed to init PlaybackStateCommandReceived event."); ;
+            Native.GetPlaylistHandle(Handle, name, out IntPtr playlistHandle)
+                .ThrowIfError("Failed to get playlist handle by name");
+
+            return playlistHandle;
+        }
+
+        /// <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 static void Response(Command command, int result, Bundle bundle)
+        {
+            command.Response(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 static void Response(Command command, int result)
+        {
+            command.Response(Handle, result, null);
         }
     }
 }
\ No newline at end of file
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/MediaController.Events.cs b/src/Tizen.Multimedia.Remoting/MediaController/MediaController.Events.cs
new file mode 100644 (file)
index 0000000..08b7b47
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * 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 Tizen.Applications;
+using Native = Interop.MediaControllerClient;
+
+namespace Tizen.Multimedia.Remoting
+{
+    /// <summary>
+    /// Provides a means to to send commands to and handle events from media control server.
+    /// </summary>
+    /// <since_tizen> 4 </since_tizen>
+    public partial class MediaController
+    {
+        /// <summary>
+        /// Occurs when the server is stopped.
+        /// </summary>
+        /// <since_tizen> 4 </since_tizen>
+        public event EventHandler ServerStopped;
+
+        internal void RaiseStoppedEvent()
+        {
+            IsStopped = true;
+            ServerStopped?.Invoke(this, EventArgs.Empty);
+        }
+
+        /// <summary>
+        /// Occurs when the playback state is updated.
+        /// </summary>
+        /// <since_tizen> 4 </since_tizen>
+        public event EventHandler<PlaybackStateUpdatedEventArgs> PlaybackStateUpdated;
+
+        private PlaybackStateUpdatedEventArgs CreatePlaybackUpdatedEventArgs(IntPtr playbackHandle)
+        {
+            try
+            {
+                Native.GetPlaybackState(playbackHandle, out var playbackCode).ThrowIfError("Failed to get state.");
+
+                Native.GetPlaybackPosition(playbackHandle, out var position).ThrowIfError("Failed to get position.");
+
+                return new PlaybackStateUpdatedEventArgs(playbackCode.ToPublic(), (long)position);
+            }
+            catch (Exception e)
+            {
+                Log.Error(GetType().FullName, e.ToString());
+            }
+            return null;
+        }
+
+        internal void RaisePlaybackUpdatedEvent(IntPtr playbackHandle)
+        {
+            var eventHandler = PlaybackStateUpdated;
+
+            if (eventHandler == null)
+            {
+                return;
+            }
+
+            var args = CreatePlaybackUpdatedEventArgs(playbackHandle);
+
+            if (args != null)
+            {
+                eventHandler.Invoke(this, args);
+            }
+        }
+
+        /// <summary>
+        /// Occurs when the metadata is updated.
+        /// </summary>
+        /// <since_tizen> 4 </since_tizen>
+        public event EventHandler<MetadataUpdatedEventArgs> MetadataUpdated;
+
+        private MetadataUpdatedEventArgs CreateMetadataUpdatedEventArgs(IntPtr metadataHandle)
+        {
+            try
+            {
+                return new MetadataUpdatedEventArgs(new MediaControlMetadata(metadataHandle));
+            }
+            catch (Exception e)
+            {
+                Log.Error(GetType().FullName, e.ToString());
+            }
+            return null;
+        }
+
+        internal void RaiseMetadataUpdatedEvent(IntPtr metadataHandle)
+        {
+            var eventHandler = MetadataUpdated;
+
+            if (eventHandler == null)
+            {
+                return;
+            }
+
+            var args = CreateMetadataUpdatedEventArgs(metadataHandle);
+
+            if (args != null)
+            {
+                eventHandler.Invoke(this, args);
+            }
+        }
+
+        /// <summary>
+        /// Occurs when the shuffle mode is updated.
+        /// </summary>
+        /// <since_tizen> 4 </since_tizen>
+        public event EventHandler<ShuffleModeUpdatedEventArgs> ShuffleModeUpdated;
+
+        internal void RaiseShuffleModeUpdatedEvent(MediaControllerNativeShuffleMode mode)
+        {
+            ShuffleModeUpdated?.Invoke(this, new ShuffleModeUpdatedEventArgs(mode == MediaControllerNativeShuffleMode.On));
+        }
+
+        /// <summary>
+        /// Occurs when the repeat mode is updated.
+        /// </summary>
+        /// <since_tizen> 4 </since_tizen>
+        public event EventHandler<RepeatModeUpdatedEventArgs> RepeatModeUpdated;
+
+        internal void RaiseRepeatModeUpdatedEvent(MediaControlRepeatMode mode)
+        {
+            RepeatModeUpdated?.Invoke(this, new RepeatModeUpdatedEventArgs(mode));
+        }
+
+        /// <summary>
+        /// Occurs when the playlist is updated.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        public event EventHandler<PlaylistUpdatedEventArgs> PlaylistUpdated;
+
+        internal void RaisePlaylistUpdatedEvent(MediaControlPlaylistMode mode, string name)
+        {
+            PlaylistUpdated?.Invoke(this, new PlaylistUpdatedEventArgs(mode, name));
+        }
+
+        /// <summary>
+        /// Occurs when the command is completed.
+        /// </summary>
+        /// <remarks>
+        /// User can match the command and this event using <see cref="CommandCompletedEventArgs.RequestId"/> field.
+        /// </remarks>
+        /// <since_tizen> 5 </since_tizen>
+        internal event EventHandler<CommandCompletedEventArgs> CommandCompleted;
+
+        internal void RaiseCommandCompletedEvent(string requestId, MediaControllerError result, IntPtr bundleHandle)
+        {
+            if (bundleHandle != IntPtr.Zero)
+            {
+                CommandCompleted?.Invoke(this, new CommandCompletedEventArgs(requestId, result, new Bundle(new SafeBundleHandle(bundleHandle, true))));
+            }
+            else
+            {
+                CommandCompleted?.Invoke(this, new CommandCompletedEventArgs(requestId, result));
+            }
+        }
+    }
+}
\ No newline at end of file
index 54b2379..22f3de0 100644 (file)
  */
 
 using System;
+using System.Collections.Generic;
 using System.Diagnostics;
+using System.Threading.Tasks;
 using Native = Interop.MediaControllerClient;
+using NativePlaylist = Interop.MediaControllerPlaylist;
 
 namespace Tizen.Multimedia.Remoting
 {
     /// <summary>
-    /// Provides a means to to send commands to and handle events from media control server.
+    /// Provides a means to send commands to and handle events from media control server.
     /// </summary>
     /// <since_tizen> 4 </since_tizen>
-    public class MediaController
+    public partial class MediaController
     {
         internal MediaController(MediaControllerManager manager, string serverAppId)
         {
@@ -64,116 +67,6 @@ namespace Tizen.Multimedia.Remoting
         }
 
         /// <summary>
-        /// Occurs when the server is stopped.
-        /// </summary>
-        /// <since_tizen> 4 </since_tizen>
-        public event EventHandler ServerStopped;
-
-        internal void RaiseStoppedEvent()
-        {
-            IsStopped = true;
-            ServerStopped?.Invoke(this, EventArgs.Empty);
-        }
-
-        /// <summary>
-        /// Occurs when the playback state is updated.
-        /// </summary>
-        /// <since_tizen> 4 </since_tizen>
-        public event EventHandler<PlaybackStateUpdatedEventArgs> PlaybackStateUpdated;
-
-        private PlaybackStateUpdatedEventArgs CreatePlaybackUpdatedEventArgs(IntPtr playbackHandle)
-        {
-            try
-            {
-                Native.GetPlaybackState(playbackHandle, out var playbackCode).ThrowIfError("Failed to get state.");
-
-                Native.GetPlaybackPosition(playbackHandle, out var position).ThrowIfError("Failed to get position.");
-
-                return new PlaybackStateUpdatedEventArgs(playbackCode.ToState(), (long)position);
-            }
-            catch (Exception e)
-            {
-                Log.Error(GetType().FullName, e.ToString());
-            }
-            return null;
-        }
-
-        internal void RaisePlaybackUpdatedEvent(IntPtr playbackHandle)
-        {
-            var eventHandler = PlaybackStateUpdated;
-
-            if (eventHandler == null)
-            {
-                return;
-            }
-
-            var args = CreatePlaybackUpdatedEventArgs(playbackHandle);
-
-            if (args != null)
-            {
-                eventHandler.Invoke(this, args);
-            }
-        }
-
-        /// <summary>
-        /// Occurs when the metadata is updated.
-        /// </summary>
-        /// <since_tizen> 4 </since_tizen>
-        public event EventHandler<MetadataUpdatedEventArgs> MetadataUpdated;
-
-        private MetadataUpdatedEventArgs CreateMetadataUpdatedEventArgs(IntPtr metadataHandle)
-        {
-            try
-            {
-                return new MetadataUpdatedEventArgs(new MediaControlMetadata(metadataHandle));
-            }
-            catch (Exception e)
-            {
-                Log.Error(GetType().FullName, e.ToString());
-            }
-            return null;
-        }
-
-        internal void RaiseMetadataUpdatedEvent(IntPtr metadataHandle)
-        {
-            var eventHandler = MetadataUpdated;
-
-            if (eventHandler == null)
-            {
-                return;
-            }
-
-            var args = CreateMetadataUpdatedEventArgs(metadataHandle);
-
-            if (args != null)
-            {
-                eventHandler.Invoke(this, args);
-            }
-        }
-
-        /// <summary>
-        /// Occurs when the shuffle mode is updated.
-        /// </summary>
-        /// <since_tizen> 4 </since_tizen>
-        public event EventHandler<ShuffleModeUpdatedEventArgs> ShuffleModeUpdated;
-
-        internal void RaiseShuffleModeUpdatedEvent(MediaControllerShuffleMode mode)
-        {
-            ShuffleModeUpdated?.Invoke(this, new ShuffleModeUpdatedEventArgs(mode == MediaControllerShuffleMode.On));
-        }
-
-        /// <summary>
-        /// Occurs when the repeat mode is updated.
-        /// </summary>
-        /// <since_tizen> 4 </since_tizen>
-        public event EventHandler<RepeatModeUpdatedEventArgs> RepeatModeUpdated;
-
-        internal void RaiseRepeatModeUpdatedEvent(MediaControlRepeatMode mode)
-        {
-            RepeatModeUpdated?.Invoke(this, new RepeatModeUpdatedEventArgs(mode));
-        }
-
-        /// <summary>
         /// Returns the playback state set by the server.
         /// </summary>
         /// <returns>The playback state.</returns>
@@ -197,7 +90,7 @@ namespace Tizen.Multimedia.Remoting
 
                 Native.GetPlaybackState(playbackHandle, out var playbackCode).ThrowIfError("Failed to get state.");
 
-                return playbackCode.ToState();
+                return playbackCode.ToPublic();
             }
             finally
             {
@@ -263,7 +156,7 @@ namespace Tizen.Multimedia.Remoting
 
             try
             {
-                Native.GetServerMetadata(Manager.Handle, ServerAppId, out metadataHandle).
+                NativePlaylist.GetServerMetadata(Manager.Handle, ServerAppId, out metadataHandle).
                     ThrowIfError("Failed to get metadata.");
 
                 return new MediaControlMetadata(metadataHandle);
@@ -272,7 +165,66 @@ namespace Tizen.Multimedia.Remoting
             {
                 if (metadataHandle != IntPtr.Zero)
                 {
-                    Native.DestroyMetadata(metadataHandle);
+                    NativePlaylist.DestroyMetadata(metadataHandle);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Returns the all playlists.
+        /// </summary>
+        /// <returns><see cref="MediaControlPlaylist"/></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 IEnumerable<MediaControlPlaylist> GetPlaylists()
+        {
+            ThrowIfStopped();
+
+            List<MediaControlPlaylist> playlists = null;
+
+            NativePlaylist.PlaylistCallback playlistCallback = (handle, _) =>
+            {
+                playlists.Add(new MediaControlPlaylist(handle));
+            };
+            NativePlaylist.ForeachServerPlaylist(Manager.Handle, ServerAppId, playlistCallback, IntPtr.Zero)
+                .ThrowIfError("Failed to get playlist.");
+
+            return playlists;
+        }
+
+        /// <summary>
+        /// Returns the index of current playing media.
+        /// </summary>
+        /// <returns>The index of current playing media.</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 GetIndexOfCurrentPlayingMedia()
+        {
+            ThrowIfStopped();
+
+            IntPtr playbackHandle = IntPtr.Zero;
+
+            try
+            {
+                Native.GetServerPlayback(Manager.Handle, ServerAppId, out playbackHandle).ThrowIfError("Failed to get playback.");
+
+                return NativePlaylist.GetPlaylistIndex(playbackHandle);
+            }
+            finally
+            {
+                if (playbackHandle != IntPtr.Zero)
+                {
+                    Native.DestroyPlayback(playbackHandle);
                 }
             }
         }
@@ -296,7 +248,7 @@ namespace Tizen.Multimedia.Remoting
             Native.GetServerShuffleMode(Manager.Handle, ServerAppId, out var shuffleMode).
                 ThrowIfError("Failed to get shuffle mode state.");
 
-            return shuffleMode == MediaControllerShuffleMode.On;
+            return shuffleMode == MediaControllerNativeShuffleMode.On;
         }
 
         /// <summary>
@@ -322,7 +274,55 @@ namespace Tizen.Multimedia.Remoting
         }
 
         /// <summary>
-        /// Sends playback command to the server.</summary>
+        /// Requests command to the server.
+        /// </summary>
+        /// <remarks>
+        /// The client can request the server to execute <see cref="PlaybackCommand"/> or <see cref="ShuffleModeCommand"/> or
+        /// <see cref="RepeatModeCommand"/> or <see cref="CustomCommand"/>, <br/>
+        /// and then, the client receive the result of each request(command).
+        /// </remarks>
+        /// <param name="command">A <see cref="Command"/> class.</param>
+        /// <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 async Task RequestAsync(Command command)
+        {
+            ThrowIfStopped();
+
+            command.SetServerInfo(Manager.Handle, ServerAppId);
+
+            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();
+
+                (await tcs.Task).ThrowIfError("Failed to request command");
+            }
+            finally
+            {
+                CommandCompleted -= eventHandler;
+            }
+        }
+
+        /// <summary>
+        /// Sends playback command to the server.
+        /// </summary>
         /// <param name="command">A playback command.</param>
         /// <exception cref="InvalidOperationException">
         ///     The server has already been stopped.<br/>
@@ -333,13 +333,14 @@ namespace Tizen.Multimedia.Remoting
         /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed of.</exception>
         /// <seealso cref="MediaControlServer.PlaybackCommandReceived"/>
         /// <since_tizen> 4 </since_tizen>
+        [Obsolete("Please do not use! This will be deprecated. Please use Request instead.")]
         public void SendPlaybackCommand(MediaControlPlaybackCommand command)
         {
             ThrowIfStopped();
 
             ValidationUtil.ValidateEnum(typeof(MediaControlPlaybackCommand), command, nameof(command));
 
-            Native.SendPlaybackStateCommand(Manager.Handle, ServerAppId, command.ToCode()).
+            Native.SendPlaybackStateCommand(Manager.Handle, ServerAppId, command.ToNative()).
                 ThrowIfError("Failed to send command.");
         }
     }
index 7a492a8..d1b0344 100644 (file)
@@ -32,32 +32,33 @@ namespace Tizen.Multimedia.Remoting
 
     internal static class MediaControllerErrorExtensions
     {
-        internal static void ThrowIfError(this MediaControllerError error, string errorMessage)
+        internal static void ThrowIfError(this MediaControllerError error, string message)
         {
             if (error == MediaControllerError.None)
             {
                 return;
             }
 
+            string msg = $"{ (message ?? "Operation failed") } : { error.ToString() }.";
+
             switch (error)
             {
                 case MediaControllerError.InvalidParameter:
-                    throw new ArgumentException(errorMessage);
+                    throw new ArgumentException(msg);
 
+                // User should not throw System.OutOfMemoryException itself.
                 case MediaControllerError.OutOfMemory:
-                    throw new OutOfMemoryException(errorMessage);
-
                 case MediaControllerError.InvalidOperation:
-                    throw new InvalidOperationException(errorMessage);
+                    throw new InvalidOperationException(msg);
 
                 case MediaControllerError.NoSpaceOnDevice:
-                    throw new IOException($"Not enough storage : {errorMessage}");
+                    throw new IOException($"Not enough storage : {msg}");
 
                 case MediaControllerError.PermissionDenied:
-                    throw new UnauthorizedAccessException(errorMessage);
+                    throw new UnauthorizedAccessException(msg);
             }
 
-            throw new InvalidOperationException($"Unknown error({error}) : {errorMessage}");
+            throw new InvalidOperationException($"Unknown error({error}) : {message}");
         }
     }
 }
\ No newline at end of file
index 670443e..bd4079d 100644 (file)
@@ -16,6 +16,7 @@
 
 using System;
 using Native = Interop.MediaControllerClient;
+using NativePlaylist = Interop.MediaControllerPlaylist;
 
 namespace Tizen.Multimedia.Remoting
 {
@@ -23,9 +24,11 @@ namespace Tizen.Multimedia.Remoting
     {
         private Native.ServerUpdatedCallback _serverUpdatedCallback;
         private Native.PlaybackUpdatedCallback _playbackUpdatedCallback;
-        private Native.MetadataUpdatedCallback _metadataUpdatedCallback;
         private Native.ShuffleModeUpdatedCallback _shufflemodeUpdatedCallback;
         private Native.RepeatModeUpdatedCallback _repeatmodeUpdatedCallback;
+        private Native.CommandCompletedCallback _commandCompletedCallback;
+        private NativePlaylist.MetadataUpdatedCallback _metadataUpdatedCallback;
+        private NativePlaylist.PlaylistUpdatedCallback _playlistUpdatedCallback;
 
         /// <summary>
         /// Occurs when a server is started.
@@ -46,16 +49,17 @@ namespace Tizen.Multimedia.Remoting
             RegisterMetadataUpdatedEvent();
             RegisterShuffleModeUpdatedEvent();
             RegisterRepeatModeUpdatedEvent();
+            RegisterCommandCompletedEvent();
         }
 
-        private void RaiseServerChangedEvent(MediaControllerServerState state, MediaController controller)
+        private void RaiseServerChangedEvent(MediaControllerNativeServerState state, MediaController controller)
         {
             if (controller == null)
             {
                 return;
             }
 
-            if (state == MediaControllerServerState.Activated)
+            if (state == MediaControllerNativeServerState.Activated)
             {
                 ServerStarted?.Invoke(this, new MediaControlServerStartedEventArgs(controller));
             }
@@ -94,7 +98,7 @@ namespace Tizen.Multimedia.Remoting
                 GetController(serverName)?.RaiseMetadataUpdatedEvent(metadata);
             };
 
-            Native.SetMetadataUpdatedCb(Handle, _metadataUpdatedCallback).ThrowIfError("Failed to init MetadataUpdated event.");
+            NativePlaylist.SetMetadataUpdatedCb(Handle, _metadataUpdatedCallback).ThrowIfError("Failed to init MetadataUpdated event.");
         }
 
         private void RegisterShuffleModeUpdatedEvent()
@@ -118,5 +122,29 @@ namespace Tizen.Multimedia.Remoting
             Native.SetRepeatModeUpdatedCb(Handle, _repeatmodeUpdatedCallback).
                 ThrowIfError("Failed to init RepeatModeUpdated event.");
         }
+
+        private void RegisterPlaylistUpdatedEvent()
+        {
+            _playlistUpdatedCallback = (serverName, playlistMode, name, handle, _) =>
+            {
+                GetController(serverName)?.RaisePlaylistUpdatedEvent(playlistMode, name);
+            };
+
+            NativePlaylist.SetPlaylistModeUpdatedCb(Handle, _playlistUpdatedCallback).
+                ThrowIfError("Failed to init PlaylistUpdated event.");
+        }
+
+        private void RegisterCommandCompletedEvent()
+        {
+            _commandCompletedCallback = (serverName, requestId, result, bundleHandle, _) =>
+            {
+                // SafeHandles cannot be marshaled from unmanaged to managed.
+                // So we use IntPtr type for 'bundleHandle' in native callback.
+                GetController(serverName)?.RaiseCommandCompletedEvent(requestId, result, bundleHandle);
+            };
+
+            Native.SetCommandCompletedCb(Handle, _commandCompletedCallback).
+                ThrowIfError("Failed to init CommandCompleted event.");
+        }
     }
 }
\ No newline at end of file
index 5e8a81a..e0b6579 100644 (file)
@@ -147,13 +147,13 @@ namespace Tizen.Multimedia.Remoting
 
         #region Locking operations
 
-        private MediaController HandleServerUpdated(string serverName, MediaControllerServerState state)
+        private MediaController HandleServerUpdated(string serverName, MediaControllerNativeServerState state)
         {
             try
             {
                 _lock.EnterWriteLock();
 
-                if (state == MediaControllerServerState.Activated)
+                if (state == MediaControllerNativeServerState.Activated)
                 {
                     return HandleActivation(serverName);
                 }
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/MediaControllerPlaylistMode.cs b/src/Tizen.Multimedia.Remoting/MediaController/MediaControllerPlaylistMode.cs
new file mode 100644 (file)
index 0000000..b0a86dd
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+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,
+    }
+}
\ No newline at end of file
index d5dfb29..da434d8 100644 (file)
@@ -31,5 +31,11 @@ namespace Tizen.Multimedia.Remoting
         /// On.
         /// </summary>
         On,
+
+        /// <summary>
+        /// One media.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        OneMedia
     }
 }
\ No newline at end of file
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/PlaybackActionCommandReceivedEventArgs.cs b/src/Tizen.Multimedia.Remoting/MediaController/PlaybackActionCommandReceivedEventArgs.cs
new file mode 100644 (file)
index 0000000..e0b5721
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * 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;
+
+namespace Tizen.Multimedia.Remoting
+{
+    /// <summary>
+    /// Provides data for the <see cref="MediaControlServer.PlaybackActionCommandReceived"/> event.
+    /// </summary>
+    /// <since_tizen> 5 </since_tizen>
+    public class PlaybackActionCommandReceivedEventArgs : EventArgs
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PlaybackActionCommandReceivedEventArgs"/> class.
+        /// </summary>
+        /// <param name="command">The playback command.</param>
+        /// <since_tizen> 5 </since_tizen>
+        public PlaybackActionCommandReceivedEventArgs(PlaybackCommand command)
+        {
+            Command = command;
+        }
+
+        /// <summary>
+        /// Gets the <see cref="PlaybackCommand"/>.
+        /// </summary>
+        /// <seealso cref="MediaControlPlaybackCommand"/>
+        /// <since_tizen> 5 </since_tizen>
+        public PlaybackCommand Command { get; }
+    }
+}
\ No newline at end of file
index d5c2dc6..a3e8b6d 100644 (file)
@@ -22,6 +22,7 @@ namespace Tizen.Multimedia.Remoting
     /// Provides data for the <see cref="MediaControlServer.PlaybackCommandReceived"/> event.
     /// </summary>
     /// <since_tizen> 4 </since_tizen>
+    [Obsolete("Please do not use! This will be deprecated. Please use PlaybackActionCommandReceived instead.")]
     public class PlaybackCommandReceivedEventArgs : EventArgs
     {
         /// <summary>
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/PlaybackPositionCommandReceivedEventArgs.cs b/src/Tizen.Multimedia.Remoting/MediaController/PlaybackPositionCommandReceivedEventArgs.cs
new file mode 100644 (file)
index 0000000..8750c37
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * 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;
+
+namespace Tizen.Multimedia.Remoting
+{
+    /// <summary>
+    /// Provides data for the <see cref="MediaControlServer.PlaybackPositionCommandReceived"/> event.
+    /// </summary>
+    /// <since_tizen> 5 </since_tizen>
+    public class PlaybackPositionCommandReceivedEventArgs : EventArgs
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PlaybackPositionCommandReceivedEventArgs"/> class.
+        /// </summary>
+        /// <param name="command">The playback position command.</param>
+        /// <since_tizen> 5 </since_tizen>
+        public PlaybackPositionCommandReceivedEventArgs(PlaybackPositionCommand command)
+        {
+            Command = command;
+        }
+
+        /// <summary>
+        /// Gets the <see cref="PlaybackPositionCommand"/>.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        public PlaybackPositionCommand Command { get; }
+    }
+}
\ No newline at end of file
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/PlaylistCommandReceivedEventArgs.cs b/src/Tizen.Multimedia.Remoting/MediaController/PlaylistCommandReceivedEventArgs.cs
new file mode 100644 (file)
index 0000000..3d7519e
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * 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;
+
+namespace Tizen.Multimedia.Remoting
+{
+    /// <summary>
+    /// Provides data for the <see cref="MediaControlServer.PlaylistCommandReceived"/> event.
+    /// </summary>
+    /// <since_tizen> 5 </since_tizen>
+    public class PlaylistCommandReceivedEventArgs : EventArgs
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PlaylistCommandReceivedEventArgs"/> class.
+        /// </summary>
+        /// <param name="command">The playback position command.</param>
+        /// <since_tizen> 5 </since_tizen>
+        public PlaylistCommandReceivedEventArgs(PlaylistCommand command)
+        {
+            Command = command;
+        }
+
+        /// <summary>
+        /// Gets the <see cref="PlaylistCommand"/>.
+        /// </summary>
+        /// <seealso cref="PlaylistCommand"/>
+        /// <since_tizen> 5 </since_tizen>
+        public PlaylistCommand Command { get; }
+    }
+}
\ No newline at end of file
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/PlaylistUpdatedEventArgs.cs b/src/Tizen.Multimedia.Remoting/MediaController/PlaylistUpdatedEventArgs.cs
new file mode 100644 (file)
index 0000000..54cf2c5
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * 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;
+
+namespace Tizen.Multimedia.Remoting
+{
+    /// <summary>
+    /// Provides data for the <see cref="MediaController.PlaylistUpdated"/> event.
+    /// </summary>
+    /// <since_tizen> 5 </since_tizen>
+    public class PlaylistUpdatedEventArgs : EventArgs
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PlaylistUpdatedEventArgs"/> class.
+        /// </summary>
+        /// <param name="mode">A value indicating the updated repeat mode.</param>
+        /// <param name="name">A value indicating the playlist name.</param>
+        /// <exception cref="ArgumentException"><paramref name="mode"/> is invalid.</exception>
+        /// <since_tizen> 5 </since_tizen>
+        public PlaylistUpdatedEventArgs(MediaControlPlaylistMode mode, string name)
+        {
+            ValidationUtil.ValidateEnum(typeof(MediaControlPlaylistMode), mode, nameof(mode));
+
+            Mode = mode;
+            Name = name;
+        }
+
+        /// <summary>
+        /// Gets the updated playlist mode.
+        /// </summary>
+        /// <remarks>
+        /// If The <see cref="Mode"/> is <see cref="MediaControlPlaylistMode.Updated"/>,
+        /// Retrieves the playlist using <see cref="Name"/> and call <see cref="MediaControlPlaylist.Update"/> to keep the playlist up to date.
+        /// </remarks>
+        /// <value>The <see cref="MediaControlPlaylistMode"/>.</value>
+        /// <since_tizen> 5 </since_tizen>
+        public MediaControlPlaylistMode Mode { get; }
+
+        /// <summary>
+        /// Gets the playlist name.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        public string Name { get; }
+    }
+}
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/RepeatModeCommandReceivedEventArgs.cs b/src/Tizen.Multimedia.Remoting/MediaController/RepeatModeCommandReceivedEventArgs.cs
new file mode 100644 (file)
index 0000000..7489d77
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * 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;
+
+namespace Tizen.Multimedia.Remoting
+{
+    /// <summary>
+    /// Provides data for the <see cref="MediaControlServer.RepeatModeCommandReceived"/> event.
+    /// </summary>
+    /// <since_tizen> 5 </since_tizen>
+    public class RepeatModeCommandReceivedEventArgs : EventArgs
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="RepeatModeCommandReceivedEventArgs"/> class.
+        /// </summary>
+        /// <param name="command">The playback position command.</param>
+        /// <since_tizen> 5 </since_tizen>
+        public RepeatModeCommandReceivedEventArgs(RepeatModeCommand command)
+        {
+            Command = command;
+        }
+
+        /// <summary>
+        /// Gets the <see cref="RepeatModeCommand"/>.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        public RepeatModeCommand Command { get; }
+    }
+}
\ No newline at end of file
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/ShuffleModeCommandReceivedEventArgs.cs b/src/Tizen.Multimedia.Remoting/MediaController/ShuffleModeCommandReceivedEventArgs.cs
new file mode 100644 (file)
index 0000000..0683980
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * 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;
+
+namespace Tizen.Multimedia.Remoting
+{
+    /// <summary>
+    /// Provides data for the <see cref="MediaControlServer.ShuffleModeCommandReceived"/> event.
+    /// </summary>
+    /// <since_tizen> 5 </since_tizen>
+    public class ShuffleModeCommandReceivedEventArgs : EventArgs
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ShuffleModeCommandReceivedEventArgs"/> class.
+        /// </summary>
+        /// <param name="command">The playback position command.</param>
+        /// <since_tizen> 5 </since_tizen>
+        public ShuffleModeCommandReceivedEventArgs(ShuffleModeCommand command)
+        {
+            Command = command;
+        }
+
+        /// <summary>
+        /// Gets the <see cref="ShuffleModeCommand"/>.
+        /// </summary>
+        /// <since_tizen> 5 </since_tizen>
+        public ShuffleModeCommand Command { get; }
+    }
+}
\ No newline at end of file