[MediaController] Add APIs to create playlist (#484)
authorhsgwon <haesu.gwon@samsung.com>
Fri, 28 Sep 2018 07:43:11 +0000 (16:43 +0900)
committerGitHub <noreply@github.com>
Fri, 28 Sep 2018 07:43:11 +0000 (16:43 +0900)
* [MediaController] Add APIs to create playlist and fix some bugs

src/Tizen.Multimedia.Remoting/Interop/Interop.MediaControllerPlaylist.cs
src/Tizen.Multimedia.Remoting/Interop/Interop.MediaControllerServer.cs
src/Tizen.Multimedia.Remoting/MediaController/MediaControlCommand.cs
src/Tizen.Multimedia.Remoting/MediaController/MediaControlEnums.cs
src/Tizen.Multimedia.Remoting/MediaController/MediaControlPlaylist.cs
src/Tizen.Multimedia.Remoting/MediaController/MediaControlSearchCondition.cs
src/Tizen.Multimedia.Remoting/MediaController/MediaControlServer.Events.cs
src/Tizen.Multimedia.Remoting/MediaController/MediaControlServer.cs
src/Tizen.Multimedia.Remoting/MediaController/MediaController.cs
src/Tizen.Multimedia.Remoting/MediaController/MediaControllerManager.Events.cs

index 8877da3..ea048a6 100644 (file)
@@ -101,6 +101,7 @@ internal static partial class Interop
         [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_playlist_item_index")]
         private static extern MediaControllerError GetPlaylistIndex(IntPtr playbackHandle, out IntPtr index);
 
+        [Obsolete("Please do not use! This will be deprecated. Please use GetPlaylistInfo instead.")]
         internal static string GetPlaylistIndex(IntPtr playbackHandle)
         {
             IntPtr valuePtr = IntPtr.Zero;
@@ -119,7 +120,7 @@ internal static partial class Interop
         [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_playlist_item_info")]
         internal static extern MediaControllerError GetPlaylistInfo(IntPtr playbackHandle, out IntPtr playlistName, out IntPtr index);
 
-        internal static string GetPlaylistInfo(IntPtr playbackHandle)
+        internal static (string name, string index) GetPlaylistInfo(IntPtr playbackHandle)
         {
             IntPtr playlistName = IntPtr.Zero;
             IntPtr index = IntPtr.Zero;
@@ -127,7 +128,8 @@ internal static partial class Interop
             try
             {
                 GetPlaylistInfo(playbackHandle, out playlistName, out index).ThrowIfError($"Failed to get playlist info.");
-                return Marshal.PtrToStringAnsi(playlistName);
+
+                return (Marshal.PtrToStringAnsi(playlistName), Marshal.PtrToStringAnsi(index));
             }
             finally
             {
index ee4a97b..971c0db 100644 (file)
@@ -186,6 +186,9 @@ internal static partial class Interop
         [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_set_playlist_item_info")]
+        internal static extern MediaControllerError SetInfoOfCurrentPlayingMedia(IntPtr handle, string name, 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);
@@ -245,7 +248,7 @@ internal static partial class Interop
         #endregion Capability
 
         #region Search
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_search_foreach")]
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_search_foreach_condition")]
         internal static extern MediaControllerError ForeachSearchCondition(IntPtr serverHandle,
             SearchItemCallback callback, IntPtr userData = default(IntPtr));
 
index 9f7d88d..43a30ad 100644 (file)
@@ -92,6 +92,7 @@ namespace Tizen.Multimedia.Remoting
         {
             try
             {
+
                 if (bundle != null)
                 {
                     NativeServer.SendCommandReplyBundle(serverHandle, ReceiverId, _requestId, result, bundle.SafeBundleHandle)
@@ -518,48 +519,27 @@ namespace Tizen.Multimedia.Remoting
             }
         }
 
+        /// <summary>
+        /// Initializes a new instance of the <see cref="SearchCommand"/> class by server side.
+        /// </summary>
         internal SearchCommand(List<MediaControlSearchCondition> conditions, IntPtr searchHandle)
         {
             _searchHandle = searchHandle;
-
-            try
-            {
-                foreach (var condition in conditions)
-                {
-                    if (condition.Bundle != null)
-                    {
-                        NativeClient.SetSearchConditionBundle(_searchHandle, condition.ContentType, condition.Category,
-                            condition.Keyword, condition.Bundle.SafeBundleHandle).
-                            ThrowIfError("Failed to set search condition.");
-                    }
-                    else
-                    {
-                        NativeClient.SetSearchCondition(_searchHandle, condition.ContentType, condition.Category,
-                            condition.Keyword, IntPtr.Zero).
-                            ThrowIfError("Failed to set search condition.");
-                    }
-                }
-            }
-            catch
-            {
-                if (_searchHandle != IntPtr.Zero)
-                {
-                    NativeClient.DestroySearchHandle(_searchHandle).ThrowIfError("Failed to destroy search handle");
-                }
-                throw;
-            }
+            Conditions = conditions;
         }
 
+        /// <summary>
+        /// Gets or sets the search conditions.
+        /// </summary>
+        /// <remarks>This property is used by MediaControlServer.</remarks>
+        /// <since_tizen> 5 </since_tizen>
+        public IEnumerable<MediaControlSearchCondition> Conditions { get; private set; }
+
         internal override string Request(NativeClientHandle clientHandle)
         {
             NativeClient.SendSearchCommand(clientHandle, ReceiverId, _searchHandle, out string requestId).
                 ThrowIfError("Failed to send search command.");
 
-            if (_searchHandle != IntPtr.Zero)
-            {
-                NativeClient.DestroySearchHandle(_searchHandle).ThrowIfError("Failed to destroy search handle");
-            }
-
             return requestId;
         }
 
@@ -570,11 +550,6 @@ namespace Tizen.Multimedia.Remoting
         protected override void OnResponseCompleted()
         {
             base.OnResponseCompleted();
-
-            if (_searchHandle != IntPtr.Zero)
-            {
-                NativeClient.DestroySearchHandle(_searchHandle).ThrowIfError("Failed to destroy search handle");
-            }
         }
     }
-}
\ No newline at end of file
+}
index 241dd12..7a3bd62 100644 (file)
@@ -175,6 +175,7 @@ namespace Tizen.Multimedia.Remoting
         /// <summary>
         /// There's no support info in server.
         /// </summary>
+        /// <remarks>User should not set this value directly.</remarks>
         NotDecided
     }
 
index 5cc1af6..e8fa129 100644 (file)
@@ -16,8 +16,6 @@
 
 using System;
 using System.Collections.Generic;
-using NativeClient = Interop.MediaControllerClient;
-using NativeServer = Interop.MediaControllerServer;
 using NativePlaylist = Interop.MediaControllerPlaylist;
 
 namespace Tizen.Multimedia.Remoting
@@ -32,21 +30,37 @@ namespace Tizen.Multimedia.Remoting
         private Dictionary<string, MediaControlMetadata> _metadata = new Dictionary<string, MediaControlMetadata>();
 
         /// <summary>
-        /// Initializes a new instance of the <see cref="MediaControlPlaylist"/> class by server side.
+        /// Initializes a new instance of the <see cref="MediaControlPlaylist"/> class.
         /// </summary>
         /// <param name="name">The name of this playlist.</param>
-        internal MediaControlPlaylist(string name)
+        /// <exception cref="InvalidOperationException">An internal error occurs.</exception>
+        /// <since_tizen> 5 </since_tizen>
+        public MediaControlPlaylist(string name)
         {
             if (name == null)
             {
-                throw new ArgumentNullException("The playlist name is not set.");
+                throw new ArgumentNullException(nameof(name));
             }
 
             NativePlaylist.CreatePlaylist(name, out IntPtr handle).ThrowIfError("Failed to create playlist");
 
             Name = name;
+            _handle = handle;
 
-            UpdateMetadata(handle);
+            MediaControlServer.SavePlaylist(handle);
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="MediaControlPlaylist"/> class.
+        /// </summary>
+        /// <param name="name">The name of this playlist.</param>
+        /// <param name="metadata">The metadata of this playlist.</param>
+        /// <exception cref="InvalidOperationException">An internal error occurs.</exception>
+        /// <since_tizen> 5 </since_tizen>
+        public MediaControlPlaylist(string name, Dictionary<string, MediaControlMetadata> metadata)
+            : this(name)
+        {
+            AddMetadata(metadata);
         }
 
         /// <summary>
@@ -57,7 +71,7 @@ namespace Tizen.Multimedia.Remoting
         {
             if (handle == IntPtr.Zero)
             {
-                throw new ArgumentNullException("The handle is not set.");
+                throw new ArgumentNullException(nameof(handle));
             }
 
             // handle will be destroyed in Native FW side.
@@ -136,7 +150,7 @@ namespace Tizen.Multimedia.Remoting
         /// <summary>
         /// Gets the metadata by index.
         /// </summary>
-        /// <param name="index"></param>
+        /// <param name="index">The index of media in the playlist.</param>
         /// <returns>A <see cref="MediaControlMetadata"/> instance.</returns>
         public MediaControlMetadata GetMetadata(string index)
         {
@@ -156,7 +170,7 @@ namespace Tizen.Multimedia.Remoting
         /// <summary>
         /// Sets the metadata to the playlist.
         /// </summary>
-        /// <param name="metadata"></param>
+        /// <param name="metadata">The metadata of media.</param>
         /// <since_tizen> 5 </since_tizen>
         public void AddMetadata(Dictionary<string, MediaControlMetadata> metadata)
         {
@@ -171,8 +185,8 @@ namespace Tizen.Multimedia.Remoting
         /// <summary>
         /// Sets the metadata to the playlist.
         /// </summary>
-        /// <param name="index"></param>
-        /// <param name="metadata"></param>
+        /// <param name="index">The index of media in the playlist.</param>
+        /// <param name="metadata">The metadata of media.</param>
         /// <since_tizen> 5 </since_tizen>
         public void AddMetadata(string index, MediaControlMetadata metadata)
         {
@@ -233,6 +247,7 @@ namespace Tizen.Multimedia.Remoting
         public void Dispose()
         {
             Dispose(true);
+            GC.SuppressFinalize(this);
         }
 
         /// <summary>
index 4ed37ba..8f76392 100644 (file)
@@ -32,6 +32,10 @@ namespace Tizen.Multimedia.Remoting
         /// <summary>
         /// Initializes a new instance of the <see cref="MediaControlSearchCondition"/> class.
         /// </summary>
+        /// <param name="type">The search type.</param>
+        /// <param name="category">The search category.</param>
+        /// <param name="keyword">The search keyword.</param>
+        /// <param name="bundle">The extra data.</param>
         /// <since_tizen> 5 </since_tizen>
         public MediaControlSearchCondition(MediaControlContentType type, MediaControlSearchCategory category,
             string keyword, Bundle bundle)
@@ -46,6 +50,9 @@ namespace Tizen.Multimedia.Remoting
         /// Initializes a new instance of the <see cref="MediaControlSearchCondition"/> class.
         /// </summary>
         /// <remarks>The <see cref="MediaControlSearchCategory"/> will be set internally by <see cref="MediaControlSearchCategory.All"/>.</remarks>
+        /// <param name="type" > The search type.</param>
+        /// <param name="keyword">The search keyword.</param>
+        /// <param name="bundle">The extra data.</param>
         /// <since_tizen> 5 </since_tizen>
         public MediaControlSearchCondition(MediaControlContentType type, string keyword, Bundle bundle)
         {
index 8b8b689..e3d7249 100644 (file)
@@ -192,6 +192,7 @@ namespace Tizen.Multimedia.Remoting
             Native.SearchItemCallback searchItemCallback = (type, category, keyword, bundleHandle, _) =>
             {
                 Bundle bundle = null;
+
                 if (bundleHandle != IntPtr.Zero)
                 {
                     bundle = new Bundle(new SafeBundleHandle(bundleHandle, true));
@@ -201,6 +202,7 @@ namespace Tizen.Multimedia.Remoting
 
                 return true;
             };
+
             Native.ForeachSearchCondition(searchHandle, searchItemCallback).
                 ThrowIfError("Failed to get search items.");
 
index 3c14975..62a1a0b 100644 (file)
@@ -277,10 +277,49 @@ namespace Tizen.Multimedia.Remoting
         ///     An internal error occurs.
         /// </exception>
         /// <since_tizen> 5 </since_tizen>
+        [Obsolete("Please do not use! This will be deprecated. Please use SetInfoOfCurrentPlayingMedia instead.")]
         public static void SetIndexOfCurrentPlayingMedia(string index)
         {
+            if (index == null)
+            {
+                throw new ArgumentNullException(nameof(index));
+            }
+
             Native.SetIndexOfCurrentPlayingMedia(Handle, index)
                 .ThrowIfError("Failed to set the index of current playing media");
+
+            Native.UpdatePlayback(Handle).ThrowIfError("Failed to set playback.");
+        }
+
+        /// <summary>
+        /// Sets the playlist name and index of current playing media.
+        /// </summary>
+        /// <param name="playlistName">The playlist name of current playing media.</param>
+        /// <param name="index">The index of current playing media.</param>
+        /// <exception cref="ArgumentNullException">
+        /// <paramref name="playlistName"/> or <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 SetInfoOfCurrentPlayingMedia(string playlistName, string index)
+        {
+            if (playlistName == null)
+            {
+                throw new ArgumentNullException(nameof(playlistName));
+            }
+            if (index == null)
+            {
+                throw new ArgumentNullException(nameof(index));
+            }
+
+            Native.SetInfoOfCurrentPlayingMedia(Handle, playlistName, index)
+                .ThrowIfError("Failed to set the playlist name and index of current playing media");
+
+            Native.UpdatePlayback(Handle).ThrowIfError("Failed to set playback.");
         }
 
         /// <summary>
@@ -435,6 +474,8 @@ namespace Tizen.Multimedia.Remoting
             ValidationUtil.ValidateEnum(typeof(MediaControlContentType), type, nameof(type));
 
             Native.SetPlaybackContentType(Handle, type).ThrowIfError("Failed to set playback content type.");
+
+            Native.UpdatePlayback(Handle).ThrowIfError("Failed to set playback.");
         }
 
         /// <summary>
@@ -469,7 +510,7 @@ namespace Tizen.Multimedia.Remoting
         /// </exception>
         /// <exception cref="ArgumentException"><paramref name="capabilities"/> is invalid.</exception>
         /// <since_tizen> 5 </since_tizen>
-        public static void SetPlaybackCapability(Dictionary<MediaControlPlaybackCommand, MediaControlCapabilitySupport> capabilities)
+        public static void SetPlaybackCapabilities(Dictionary<MediaControlPlaybackCommand, MediaControlCapabilitySupport> capabilities)
         {
             foreach (var pair in capabilities)
             {
@@ -542,5 +583,31 @@ namespace Tizen.Multimedia.Remoting
             Native.SetRepeatModeCapability(Handle, support).ThrowIfError("Failed to set shuffle mode capability.");
         }
         #endregion Capabilities
+
+        /// <summary>
+        /// Sets the age rating of latest played media.
+        /// </summary>
+        /// <param name="ageRating">
+        /// The Age rating of latest played media. The valid range is 0 to 19, inclusive.
+        /// Especially, 0 means that media is suitable for all ages.
+        /// </param>
+        /// <exception cref="ArgumentOutOfRangeException">The specified <paramref name="ageRating"/> is not valid.</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 SetAgeRating(int ageRating)
+        {
+            if (ageRating < 0 || ageRating > 19)
+            {
+                throw new ArgumentOutOfRangeException(nameof(ageRating));
+            }
+
+            Native.SetAgeRating(Handle, ageRating).ThrowIfError("Failed to set age rating.");
+
+            Native.UpdatePlayback(Handle).ThrowIfError("Failed to set playback.");
+        }
     }
 }
\ No newline at end of file
index dd61ccf..622390d 100644 (file)
@@ -215,14 +215,15 @@ namespace Tizen.Multimedia.Remoting
             ThrowIfStopped();
 
             IntPtr playbackHandle = IntPtr.Zero;
-            string name = null;
 
             // Get the playlist name of current playing media.
             try
             {
                 Native.GetServerPlayback(Manager.Handle, ServerAppId, out playbackHandle).ThrowIfError("Failed to get playback.");
 
-                name = NativePlaylist.GetPlaylistIndex(playbackHandle);
+                var (name, index) = NativePlaylist.GetPlaylistInfo(playbackHandle);
+
+                return GetPlaylists().FirstOrDefault(playlist => playlist.Name == name);
             }
             finally
             {
@@ -231,8 +232,6 @@ namespace Tizen.Multimedia.Remoting
                     Native.DestroyPlayback(playbackHandle).ThrowIfError("Failed to destroy playback handle.");
                 }
             }
-
-            return GetPlaylists().FirstOrDefault(playlist => playlist.Name == name);
         }
 
         /// <summary>
@@ -256,7 +255,8 @@ namespace Tizen.Multimedia.Remoting
             {
                 Native.GetServerPlayback(Manager.Handle, ServerAppId, out playbackHandle).ThrowIfError("Failed to get playback.");
 
-                return NativePlaylist.GetPlaylistIndex(playbackHandle);
+                var (name, index) = NativePlaylist.GetPlaylistInfo(playbackHandle);
+                return index;
             }
             finally
             {
@@ -562,7 +562,7 @@ namespace Tizen.Multimedia.Remoting
         /// </exception>
         /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed of.</exception>
         /// <since_tizen> 5 </since_tizen>
-        public MediaControlCapabilitySupport GetPlaybackCapabilities(MediaControlPlaybackCommand action)
+        public MediaControlCapabilitySupport GetPlaybackCapability(MediaControlPlaybackCommand action)
         {
             ThrowIfStopped();
 
index 23166bf..d8acb49 100644 (file)
@@ -54,6 +54,7 @@ namespace Tizen.Multimedia.Remoting
             RegisterMetadataUpdatedEvent();
             RegisterShuffleModeUpdatedEvent();
             RegisterRepeatModeUpdatedEvent();
+            RegisterPlaylistUpdatedEvent();
             RegisterCommandCompletedEvent();
             RegisterPlaybackCapabilitiesEvent();
             RegisterRepeatModeCapabilitiesEvent();
@@ -164,7 +165,7 @@ namespace Tizen.Multimedia.Remoting
             };
 
             Native.SetPlaybackCapabilityUpdatedCb(Handle, _playbackCapabilityUpdatedCallback).
-                ThrowIfError("Failed to init PlaylistUpdated event.");
+                ThrowIfError("Failed to init PlaybackCapabilityUpdated event.");
         }
 
         private void RegisterRepeatModeCapabilitiesEvent()