Merge remote-tracking branch 'origin/master' into tizen
authoradmin <tizenapi@samsung.com>
Mon, 16 Sep 2019 07:21:02 +0000 (07:21 +0000)
committeradmin <tizenapi@samsung.com>
Mon, 16 Sep 2019 07:21:02 +0000 (07:21 +0000)
50 files changed:
packaging/PlatformFileList.txt
src/Tizen.MachineLearning.Inference/Interop/Interop.Nnstreamer.cs [new file with mode: 0755]
src/Tizen.MachineLearning.Inference/Tizen.MachineLearning.Inference.csproj [new file with mode: 0755]
src/Tizen.MachineLearning.Inference/Tizen.MachineLearning.Inference.sln [new file with mode: 0755]
src/Tizen.MachineLearning.Inference/Tizen.MachineLearning.Inference/Commons.cs [new file with mode: 0755]
src/Tizen.MachineLearning.Inference/Tizen.MachineLearning.Inference/SingleShot.cs [new file with mode: 0755]
src/Tizen.MachineLearning.Inference/Tizen.MachineLearning.Inference/TensorsData.cs [new file with mode: 0755]
src/Tizen.MachineLearning.Inference/Tizen.MachineLearning.Inference/TensorsInfo.cs [new file with mode: 0755]
src/Tizen.Multimedia.AudioIO/AudioIO/AudioChannel.cs
src/Tizen.Multimedia.AudioIO/AudioIO/AudioSampleType.cs
src/Tizen.Multimedia.Remoting/Interop/Interop.MediaControllerClient.cs
src/Tizen.Multimedia.Remoting/Interop/Interop.MediaControllerServer.cs
src/Tizen.Multimedia.Remoting/MediaController/DisplayModeCapabilityUpdatedEventArgs.cs [new file with mode: 0644]
src/Tizen.Multimedia.Remoting/MediaController/DisplayModeCommandReceivedEventArgs.cs [new file with mode: 0644]
src/Tizen.Multimedia.Remoting/MediaController/DisplayModeUpdatedEventArgs.cs [new file with mode: 0644]
src/Tizen.Multimedia.Remoting/MediaController/DisplayRotationCapabilityUpdatedEventArgs.cs [new file with mode: 0644]
src/Tizen.Multimedia.Remoting/MediaController/DisplayRotationCommandReceivedEventArgs.cs [new file with mode: 0644]
src/Tizen.Multimedia.Remoting/MediaController/DisplayRotationUpdatedEventArgs.cs [new file with mode: 0644]
src/Tizen.Multimedia.Remoting/MediaController/InternalEnums.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/MediaControlServer.Events.cs
src/Tizen.Multimedia.Remoting/MediaController/MediaControlServer.cs
src/Tizen.Multimedia.Remoting/MediaController/MediaController.Events.cs
src/Tizen.Multimedia.Remoting/MediaController/MediaController.cs
src/Tizen.Multimedia.Remoting/MediaController/MediaControllerManager.Events.cs
src/Tizen.Multimedia.Remoting/MediaController/Mode360CommandReceivedEventArgs.cs [new file with mode: 0644]
src/Tizen.Multimedia.Remoting/MediaController/Mode360UpdatedEventArgs.cs [new file with mode: 0644]
src/Tizen.Multimedia.Remoting/MediaController/RepeatModeCapabilityUpdatedEventArgs.cs
src/Tizen.Multimedia.Remoting/MediaController/RepeatModeCommandReceivedEventArgs.cs
src/Tizen.Multimedia.Remoting/MediaController/ShuffleModeCapabilityUpdatedEventArgs.cs
src/Tizen.Multimedia.Remoting/MediaController/ShuffleModeCommandReceivedEventArgs.cs
src/Tizen.Multimedia.Remoting/MediaController/SubtitleModeCommandReceivedEventArgs.cs [new file with mode: 0644]
src/Tizen.Multimedia.Remoting/MediaController/SubtitleModeUpdatedEventArgs.cs [new file with mode: 0644]
src/Tizen.Multimedia/Interop/Interop.MediaTool.cs
src/Tizen.Multimedia/MediaTool/AudioMediaFormat.cs
src/Tizen.Multimedia/MediaTool/MediaFormatChannelPosition.cs [new file with mode: 0644]
src/Tizen.Multimedia/MediaTool/MediaPacket.Lock.cs
src/Tizen.Multimedia/MediaTool/MediaPacket.cs
src/Tizen.Multimedia/MediaTool/MediaPacketVideoPlane.cs
test/Tizen.MachineLearning.Inference.Test/App.cs [new file with mode: 0755]
test/Tizen.MachineLearning.Inference.Test/Program.cs [new file with mode: 0755]
test/Tizen.MachineLearning.Inference.Test/SingleTest.cs [new file with mode: 0755]
test/Tizen.MachineLearning.Inference.Test/TensorsInfoTest.cs [new file with mode: 0755]
test/Tizen.MachineLearning.Inference.Test/Tizen.MachineLearning.Inference.Test.csproj [new file with mode: 0755]
test/Tizen.MachineLearning.Inference.Test/Tizen.MachineLearning.Inference.Test.sln [new file with mode: 0755]
test/Tizen.MachineLearning.Inference.Test/res/models/mobilenet_v1_1.0_224_quant.tflite [new file with mode: 0755]
test/Tizen.MachineLearning.Inference.Test/shared/res/Tizen.MachineLearning.Inference.Test.png [new file with mode: 0755]
test/Tizen.MachineLearning.Inference.Test/tizen-manifest.xml [new file with mode: 0755]

index ce2153c..4052c5b 100755 (executable)
@@ -39,6 +39,7 @@ Tizen.dll                                          #common #mobile #mobile-emul
 Tizen.Location.dll                                 #mobile #mobile-emul #tv #wearable
 Tizen.Location.Geofence.dll                        #mobile #mobile-emul
 Tizen.Log.dll                                      #common #mobile #mobile-emul #tv #wearable
+Tizen.MachineLearning.Inference.dll                #mobile #mobile-emul #tv #wearable
 Tizen.Maps.dll                                     #mobile #mobile-emul #tv #wearable
 Tizen.Messaging.dll                                #mobile #mobile-emul #wearable
 Tizen.Messaging.Push.dll                           #common #mobile #mobile-emul #tv #wearable
diff --git a/src/Tizen.MachineLearning.Inference/Interop/Interop.Nnstreamer.cs b/src/Tizen.MachineLearning.Inference/Interop/Interop.Nnstreamer.cs
new file mode 100755 (executable)
index 0000000..883e1ab
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+* Copyright (c) 2019 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.MachineLearning.Inference;
+
+internal static partial class Interop
+{
+    internal static partial class Libraries
+    {
+        public const string Nnstreamer = "libcapi-nnstreamer.so.0";
+    }
+
+    internal static partial class SingleShot
+    {
+        /* int ml_single_open (ml_single_h *single, const char *model, const ml_tensors_info_h input_info, const ml_tensors_info_h output_info, ml_nnfw_type_e nnfw, ml_nnfw_hw_e hw) */
+        [DllImport(Libraries.Nnstreamer, EntryPoint = "ml_single_open", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern NNStreamerError OpenSingle(out IntPtr single_handle, string model_path, IntPtr input_info, IntPtr output_info, NNFWType nn_type, HWType hw_type);
+
+        /* int ml_single_close (ml_single_h single) */
+        [DllImport(Libraries.Nnstreamer, EntryPoint = "ml_single_close", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern NNStreamerError CloseSingle(IntPtr single_handle);
+
+        /* int ml_single_invoke (ml_single_h single, const ml_tensors_data_h input, ml_tensors_data_h *output) */
+        [DllImport(Libraries.Nnstreamer, EntryPoint = "ml_single_invoke", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern NNStreamerError InvokeSingle(IntPtr single_handle, IntPtr input_data, out IntPtr output_data);
+
+        /* int ml_single_get_input_info (ml_single_h single, ml_tensors_info_h *info) */
+        [DllImport(Libraries.Nnstreamer, EntryPoint = "ml_single_invoke", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern NNStreamerError GetInputTensorsInfoFromSingle(IntPtr single_handle, out IntPtr input_info);
+
+        /* int ml_single_get_output_info (ml_single_h single, ml_tensors_info_h *info) */
+        [DllImport(Libraries.Nnstreamer, EntryPoint = "ml_single_get_output_info", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern NNStreamerError GetOutputTensorsInfoFromSingle(IntPtr single_handle, out IntPtr output_info);
+    }
+
+    internal static partial class Util
+    {
+        /* int ml_tensors_info_create (ml_tensors_info_h *info) */
+        [DllImport(Libraries.Nnstreamer, EntryPoint = "ml_tensors_info_create", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern NNStreamerError CreateTensorsInfo(out IntPtr info);
+            
+        /* int ml_tensors_info_destroy (ml_tensors_info_h info) */
+        [DllImport(Libraries.Nnstreamer, EntryPoint = "ml_tensors_info_destroy", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern NNStreamerError DestroyTensorsInfo(IntPtr info);
+
+        /* int ml_tensors_info_validate (const ml_tensors_info_h info, bool *valid) */
+        [DllImport(Libraries.Nnstreamer, EntryPoint = "ml_tensors_info_validate", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern NNStreamerError ValidateTensorsInfo(IntPtr info, out bool valid);
+
+        /* int ml_tensors_info_clone (ml_tensors_info_h dest, const ml_tensors_info_h src) */
+        [DllImport(Libraries.Nnstreamer, EntryPoint = "ml_tensors_info_clone", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern NNStreamerError CloneTensorsInfo(out IntPtr dest_info, IntPtr src_info);
+
+        /* int ml_tensors_info_set_count (ml_tensors_info_h info, unsigned int count) */
+        [DllImport(Libraries.Nnstreamer, EntryPoint = "ml_tensors_info_set_count", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern NNStreamerError SetTensorsCount(IntPtr info, int count);
+
+        /* int ml_tensors_info_get_count (ml_tensors_info_h info, unsigned int *count) */
+        [DllImport(Libraries.Nnstreamer, EntryPoint = "ml_tensors_info_get_count", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern NNStreamerError GetTensorsCount(IntPtr info, out int count);
+
+        /* int ml_tensors_info_set_tensor_name (ml_tensors_info_h info, unsigned int index, const char *name) */
+        [DllImport(Libraries.Nnstreamer, EntryPoint = "ml_tensors_info_set_tensor_name", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern NNStreamerError SetTensorName(IntPtr info, int index, string name);
+
+        /* int ml_tensors_info_get_tensor_name (ml_tensors_info_h info, unsigned int index, char **name) */
+        [DllImport(Libraries.Nnstreamer, EntryPoint = "ml_tensors_info_get_tensor_name", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern NNStreamerError GetTensorName(IntPtr info, int index, out string name);
+
+        /* int ml_tensors_info_set_tensor_type (ml_tensors_info_h info, unsigned int index, const ml_tensor_type_e type) */
+        [DllImport(Libraries.Nnstreamer, EntryPoint = "ml_tensors_info_set_tensor_type", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern NNStreamerError SetTensorType(IntPtr info, int index, TensorType type);
+
+        /* int ml_tensors_info_get_tensor_type (ml_tensors_info_h info, unsigned int index, ml_tensor_type_e *type) */
+        [DllImport(Libraries.Nnstreamer, EntryPoint = "ml_tensors_info_get_tensor_type", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern NNStreamerError GetTensorType(IntPtr info, int index, out TensorType type);
+
+        /* int ml_tensors_info_set_tensor_dimension (ml_tensors_info_h info, unsigned int index, const ml_tensor_dimension dimension) */
+        [DllImport(Libraries.Nnstreamer, EntryPoint = "ml_tensors_info_set_tensor_dimension", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern NNStreamerError SetTensorDimension(IntPtr info, int index, int[] dimension);
+
+        /* int ml_tensors_info_get_tensor_dimension (ml_tensors_info_h info, unsigned int index, ml_tensor_dimension dimension) */
+        [DllImport(Libraries.Nnstreamer, EntryPoint = "ml_tensors_info_get_tensor_dimension", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern NNStreamerError GetTensorDimension(IntPtr info, int index, out int[] dimension);
+
+        /* size_t ml_tensors_info_get_size (const ml_tensors_info_h info) */
+        [DllImport(Libraries.Nnstreamer, EntryPoint = "ml_tensors_info_get_size", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern int GetTensorsSize(IntPtr info);
+
+        /* int ml_tensors_data_create (const ml_tensors_info_h info, ml_tensors_data_h *data) */
+        [DllImport(Libraries.Nnstreamer, EntryPoint = "ml_tensors_data_create", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern NNStreamerError CreateTensorsData(IntPtr info, out IntPtr data);
+
+        /* int ml_tensors_data_destroy (ml_tensors_data_h data) */
+        [DllImport(Libraries.Nnstreamer, EntryPoint = "ml_tensors_data_destroy", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern NNStreamerError DestroyTensorsData(IntPtr data);
+
+        /* int ml_tensors_data_get_tensor_data (ml_tensors_data_h data, unsigned int index, void **raw_data, size_t *data_size) */
+        [DllImport(Libraries.Nnstreamer, EntryPoint = "ml_tensors_data_get_tensor_data", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern NNStreamerError GetTensorData(IntPtr data, int index, out IntPtr raw_data, out int data_size);
+
+        /* int ml_tensors_data_set_tensor_data (ml_tensors_data_h data, unsigned int index, const void *raw_data, const size_t data_size) */
+        [DllImport(Libraries.Nnstreamer, EntryPoint = "ml_tensors_data_set_tensor_data", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern NNStreamerError SetTensorData(IntPtr data, int index, byte[] raw_data, int data_size);
+
+        /* int ml_check_nnfw_availability (ml_nnfw_type_e nnfw, ml_nnfw_hw_e hw, bool *available); */
+        [DllImport(Libraries.Nnstreamer, EntryPoint = "ml_check_nnfw_availability", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern NNStreamerError CheckNNFWAvailability(NNFWType nnfw, HWType hw, out bool available);
+
+        /* ml_tensors_data_get_tensor_count (ml_tensors_data_h data, unsigned int *num_tensors) */
+        [DllImport(Libraries.Nnstreamer, EntryPoint = "ml_tensors_data_get_tensor_count", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern NNStreamerError GetTensorsCount(IntPtr data, out uint count);
+
+        internal static byte[] IntPtrToByteArray(IntPtr unmanagedByteArray, int size)
+        {
+            byte[] retByte = new byte[size];
+            Marshal.Copy(unmanagedByteArray, retByte, 0, size);
+            return retByte;
+        }
+    }
+}
diff --git a/src/Tizen.MachineLearning.Inference/Tizen.MachineLearning.Inference.csproj b/src/Tizen.MachineLearning.Inference/Tizen.MachineLearning.Inference.csproj
new file mode 100755 (executable)
index 0000000..ccca1d1
--- /dev/null
@@ -0,0 +1,12 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>netstandard2.0</TargetFramework>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\Tizen.Log\Tizen.Log.csproj" />
+    <ProjectReference Include="..\Tizen\Tizen.csproj" />
+  </ItemGroup>
+
+</Project>
diff --git a/src/Tizen.MachineLearning.Inference/Tizen.MachineLearning.Inference.sln b/src/Tizen.MachineLearning.Inference/Tizen.MachineLearning.Inference.sln
new file mode 100755 (executable)
index 0000000..02b0ae5
--- /dev/null
@@ -0,0 +1,69 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.26124.0
+MinimumVisualStudioVersion = 15.0.26124.0
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen.MachineLearning.Inference", "Tizen.MachineLearning.Inference.csproj", "{AC675801-2A5D-4346-BFD3-3A9809EB9767}"
+       ProjectSection(ProjectDependencies) = postProject
+               {5BC75930-86EF-4A1B-BC26-BC8109773F9A} = {5BC75930-86EF-4A1B-BC26-BC8109773F9A}
+               {12E4988C-94E5-45BD-89FF-011970716A18} = {12E4988C-94E5-45BD-89FF-011970716A18}
+       EndProjectSection
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen", "..\Tizen\Tizen.csproj", "{5BC75930-86EF-4A1B-BC26-BC8109773F9A}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen.Log", "..\Tizen.Log\Tizen.Log.csproj", "{12E4988C-94E5-45BD-89FF-011970716A18}"
+EndProject
+Global
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution
+               Debug|Any CPU = Debug|Any CPU
+               Debug|x64 = Debug|x64
+               Debug|x86 = Debug|x86
+               Release|Any CPU = Release|Any CPU
+               Release|x64 = Release|x64
+               Release|x86 = Release|x86
+       EndGlobalSection
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution
+               {AC675801-2A5D-4346-BFD3-3A9809EB9767}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {AC675801-2A5D-4346-BFD3-3A9809EB9767}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {AC675801-2A5D-4346-BFD3-3A9809EB9767}.Debug|x64.ActiveCfg = Debug|Any CPU
+               {AC675801-2A5D-4346-BFD3-3A9809EB9767}.Debug|x64.Build.0 = Debug|Any CPU
+               {AC675801-2A5D-4346-BFD3-3A9809EB9767}.Debug|x86.ActiveCfg = Debug|Any CPU
+               {AC675801-2A5D-4346-BFD3-3A9809EB9767}.Debug|x86.Build.0 = Debug|Any CPU
+               {AC675801-2A5D-4346-BFD3-3A9809EB9767}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {AC675801-2A5D-4346-BFD3-3A9809EB9767}.Release|Any CPU.Build.0 = Release|Any CPU
+               {AC675801-2A5D-4346-BFD3-3A9809EB9767}.Release|x64.ActiveCfg = Release|Any CPU
+               {AC675801-2A5D-4346-BFD3-3A9809EB9767}.Release|x64.Build.0 = Release|Any CPU
+               {AC675801-2A5D-4346-BFD3-3A9809EB9767}.Release|x86.ActiveCfg = Release|Any CPU
+               {AC675801-2A5D-4346-BFD3-3A9809EB9767}.Release|x86.Build.0 = Release|Any CPU
+               {5BC75930-86EF-4A1B-BC26-BC8109773F9A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {5BC75930-86EF-4A1B-BC26-BC8109773F9A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {5BC75930-86EF-4A1B-BC26-BC8109773F9A}.Debug|x64.ActiveCfg = Debug|Any CPU
+               {5BC75930-86EF-4A1B-BC26-BC8109773F9A}.Debug|x64.Build.0 = Debug|Any CPU
+               {5BC75930-86EF-4A1B-BC26-BC8109773F9A}.Debug|x86.ActiveCfg = Debug|Any CPU
+               {5BC75930-86EF-4A1B-BC26-BC8109773F9A}.Debug|x86.Build.0 = Debug|Any CPU
+               {5BC75930-86EF-4A1B-BC26-BC8109773F9A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {5BC75930-86EF-4A1B-BC26-BC8109773F9A}.Release|Any CPU.Build.0 = Release|Any CPU
+               {5BC75930-86EF-4A1B-BC26-BC8109773F9A}.Release|x64.ActiveCfg = Release|Any CPU
+               {5BC75930-86EF-4A1B-BC26-BC8109773F9A}.Release|x64.Build.0 = Release|Any CPU
+               {5BC75930-86EF-4A1B-BC26-BC8109773F9A}.Release|x86.ActiveCfg = Release|Any CPU
+               {5BC75930-86EF-4A1B-BC26-BC8109773F9A}.Release|x86.Build.0 = Release|Any CPU
+               {12E4988C-94E5-45BD-89FF-011970716A18}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {12E4988C-94E5-45BD-89FF-011970716A18}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {12E4988C-94E5-45BD-89FF-011970716A18}.Debug|x64.ActiveCfg = Debug|Any CPU
+               {12E4988C-94E5-45BD-89FF-011970716A18}.Debug|x64.Build.0 = Debug|Any CPU
+               {12E4988C-94E5-45BD-89FF-011970716A18}.Debug|x86.ActiveCfg = Debug|Any CPU
+               {12E4988C-94E5-45BD-89FF-011970716A18}.Debug|x86.Build.0 = Debug|Any CPU
+               {12E4988C-94E5-45BD-89FF-011970716A18}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {12E4988C-94E5-45BD-89FF-011970716A18}.Release|Any CPU.Build.0 = Release|Any CPU
+               {12E4988C-94E5-45BD-89FF-011970716A18}.Release|x64.ActiveCfg = Release|Any CPU
+               {12E4988C-94E5-45BD-89FF-011970716A18}.Release|x64.Build.0 = Release|Any CPU
+               {12E4988C-94E5-45BD-89FF-011970716A18}.Release|x86.ActiveCfg = Release|Any CPU
+               {12E4988C-94E5-45BD-89FF-011970716A18}.Release|x86.Build.0 = Release|Any CPU
+       EndGlobalSection
+       GlobalSection(SolutionProperties) = preSolution
+               HideSolutionNode = FALSE
+       EndGlobalSection
+       GlobalSection(ExtensibilityGlobals) = postSolution
+               SolutionGuid = {A42C750C-B824-4DB3-A2E6-7C877C1EB6D2}
+       EndGlobalSection
+EndGlobal
diff --git a/src/Tizen.MachineLearning.Inference/Tizen.MachineLearning.Inference/Commons.cs b/src/Tizen.MachineLearning.Inference/Tizen.MachineLearning.Inference/Commons.cs
new file mode 100755 (executable)
index 0000000..d74aad1
--- /dev/null
@@ -0,0 +1,208 @@
+/*
+* Copyright (c) 2019 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.IO;
+
+namespace Tizen.MachineLearning.Inference
+{
+    /// <summary>
+    /// Possible data element types of Tensor in NNStreamer.
+    /// </summary>
+    /// <since_tizen> 6 </since_tizen>
+    public enum TensorType
+    {
+#pragma warning disable CA1720 // Identifier contains type name
+        /// <summary>
+        /// Integer 32bit
+        /// </summary>
+        Int32 = 0,
+        /// <summary>
+        /// Unsigned integer 32bit
+        /// </summary>
+        UInt32,
+        /// <summary>
+        /// Integer 16bit
+        /// </summary>
+        Int16,
+        /// <summary>
+        /// Unsigned integer 16bit
+        /// </summary>
+        UInt16,
+        /// <summary>
+        /// Integer 8bit
+        /// </summary>
+        Int8,
+        /// <summary>
+        /// Unsigned integer 8bit
+        /// </summary>
+        UInt8,
+        /// <summary>
+        /// Float 64bit
+        /// </summary>
+        Float64,
+        /// <summary>
+        /// Float 32bit
+        /// </summary>
+        Float32,
+        /// <summary>
+        /// Integer 64bit
+        /// </summary>
+        Int64,
+        /// <summary>
+        /// Unsigned integer 64bit
+        /// </summary>
+        UInt64,
+#pragma warning restore CA1720 // Identifier contains type name
+    }
+
+    internal enum NNStreamerError
+    {
+        None = Tizen.Internals.Errors.ErrorCode.None,
+        InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter,
+        StreamsPipe = Tizen.Internals.Errors.ErrorCode.StreamsPipe,
+        TryAgain = Tizen.Internals.Errors.ErrorCode.TryAgain,
+        Unknown = Tizen.Internals.Errors.ErrorCode.Unknown,
+        TimedOut = Tizen.Internals.Errors.ErrorCode.TimedOut,
+        NotSupported = Tizen.Internals.Errors.ErrorCode.NotSupported,
+    }
+
+    /// <summary>
+    /// Types of Neural Network Framework.
+    /// </summary>
+    /// <since_tizen> 6 </since_tizen>
+    public enum NNFWType
+    {
+        /// <summary>
+        /// NNHW is not specified (Try to determine the NNFW with file extension).
+        /// </summary>
+        Any = 0,
+        /// <summary>
+        /// Custom filter (Independent shared object).
+        /// </summary>
+        CustomFilter,
+        /// <summary>
+        /// Tensorflow-lite (.tflite).
+        /// </summary>
+        TensorflowLite,
+        /// <summary>
+        /// Tensorflow (.pb).
+        /// </summary>
+        Tensorflow,
+        /// <summary>
+        /// Neural Network Inference framework, which is developed by SR
+        /// </summary>
+        NNFW,
+    }
+
+    /// <summary>
+    /// Types of hardware resources to be used for NNFWs. Note that if the affinity (nnn) is not supported by the driver or hardware, it is ignored.
+    /// </summary>
+    /// <since_tizen> 6 </since_tizen>
+    public enum HWType
+    {
+        /// <summary>
+        /// Hardware resource is not specified.
+        /// </summary>
+        Any = 0,
+        /// <summary>
+        /// Try to schedule and optimize if possible.
+        /// </summary>
+        Auto = 1,
+        /// <summary>
+        /// Any CPU  if possible.
+        /// </summary>
+        CPU = 0x1000,
+        /// <summary>
+        /// Any GPU  if possible.
+        /// </summary>
+        GPU = 0x2000,
+        /// <summary>
+        /// Any NPU if possible.
+        /// </summary>
+        NPU = 0x3000,
+    }
+
+    internal static class Tensor
+    {
+        /// <summary>
+        /// The maximum rank that NNStreamer supports with Tizen APIs.
+        /// </summary>
+        internal const int RankLimit = 4;
+
+        /// <summary>
+        /// The maximum number of other/tensor instances that other/tensors may have.
+        /// </summary>
+        internal const int SizeLimit = 16;
+
+        /// <summary>
+        /// Unknown Type of Tensor information. It is internally used for error check.
+        /// </summary>
+        internal const int UnknownType = 10;
+
+        /// <summary>
+        /// Invalid count of TensorsData. It is internally used for error check.
+        /// </summary>
+        internal const int InvalidCount = -1;
+    }
+
+    internal static class NNStreamer
+    {
+        internal const string TAG = "ML.Inference";
+
+        internal static void CheckException(NNStreamerError error, string msg)
+        {
+            if (error != NNStreamerError.None)
+            {
+                Log.Error(NNStreamer.TAG, msg + ": " + error.ToString());
+                throw NNStreamerExceptionFactory.CreateException(error, msg);
+            }
+        }
+    }
+
+    internal class NNStreamerExceptionFactory
+    {
+        internal static Exception CreateException(NNStreamerError err, string msg)
+        {
+            Exception exp;
+            
+            switch (err)
+            {
+                case NNStreamerError.InvalidParameter:
+                    exp = new ArgumentException(msg);
+                    break;
+
+                case NNStreamerError.NotSupported:
+                    exp = new NotSupportedException(msg);
+                    break;
+
+                case NNStreamerError.StreamsPipe:
+                case NNStreamerError.TryAgain:
+                    exp = new IOException(msg);
+                    break;
+
+                case NNStreamerError.TimedOut:
+                    exp = new TimeoutException(msg);
+                    break;
+
+                default:
+                    exp = new InvalidOperationException(msg);
+                    break;
+            }
+            return exp;
+        }
+    }
+}
diff --git a/src/Tizen.MachineLearning.Inference/Tizen.MachineLearning.Inference/SingleShot.cs b/src/Tizen.MachineLearning.Inference/Tizen.MachineLearning.Inference/SingleShot.cs
new file mode 100755 (executable)
index 0000000..e3c2d48
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+* Copyright (c) 2019 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 System.Text;
+using System.IO;
+
+namespace Tizen.MachineLearning.Inference
+{
+    /// <summary>
+    /// The SingleShot class loads a Machine Learning model and make inferences from input data.
+    /// </summary>
+    /// <since_tizen> 6 </since_tizen>
+    public class SingleShot : IDisposable
+    {
+        private IntPtr _handle = IntPtr.Zero;
+        private bool _disposed = false;
+
+        /// <summary>
+        /// Loads the neural network model and configures runtime environment
+        /// </summary>
+        /// <param name="modelAbsPath">Absolute path to the neural network model file.</param>
+        /// <param name="inTensorsInfo">Input TensorsInfo object</param>
+        /// <param name="outTensorsInfo">Output TensorsInfo object for inference result</param>
+        /// <feature>http://tizen.org/feature/machine_learning.inference</feature>
+        /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
+        /// <exception cref="IOException">Thrown when constructing the pipeline is failed.</exception>
+        /// <exception cref="NotSupportedException">Thrown when the feature is not supported.</exception>
+        /// <since_tizen> 6 </since_tizen>
+        public SingleShot(string modelAbsPath, TensorsInfo inTensorsInfo, TensorsInfo outTensorsInfo)
+        {
+            CreateSingleShot(modelAbsPath, inTensorsInfo, outTensorsInfo);
+        }
+
+        /// <summary>
+        /// Destructor of the Single instance.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        ~SingleShot()
+        {
+            Dispose(false);
+        }
+
+        /// <summary>
+        /// Releases any unmanaged resources used by this object.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        public void Dispose()
+        {
+            Dispose(true);
+            GC.SuppressFinalize(this);
+        }
+
+        /// <summary>
+        /// Invokes the model with the given input data.
+        /// </summary>
+        /// <param name="inTensorsData">The input data to be inferred.</param>
+        /// <returns>TensorsData instance which contains the inferred result.</returns>
+        /// <feature>http://tizen.org/feature/machine_learning.inference</feature>
+        /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
+        /// <exception cref="IOException">Thrown when failed to push an input data into source element.</exception>
+        /// <exception cref="TimeoutException">Thrown when failed to get the result from sink element.</exception>
+        /// <exception cref="NotSupportedException">Thrown when the feature is not supported.</exception>
+        /// <since_tizen> 6 </since_tizen>
+        public TensorsData Invoke(TensorsData inTensorsData)
+        {
+            TensorsData out_data;
+            IntPtr out_ptr;
+            NNStreamerError ret = NNStreamerError.None;
+
+            ret = Interop.SingleShot.InvokeSingle(_handle, inTensorsData.Handle, out out_ptr);
+            NNStreamer.CheckException(ret, "fail to invoke the single inference engine");
+
+            out_data = TensorsData.CreateFromNativeHandle(out_ptr);
+            return out_data;
+        }
+
+        private void CreateSingleShot(string modelAbsPath, TensorsInfo inTensorInfo, TensorsInfo outTensorInfo)
+        {
+            NNStreamerError ret = NNStreamerError.None;
+            IntPtr input_info;
+            IntPtr output_info;
+
+            /* Check model path */
+            if (string.IsNullOrEmpty(modelAbsPath))
+                ret = NNStreamerError.InvalidParameter;
+            NNStreamer.CheckException(ret, "model path is invalid: " + modelAbsPath);
+
+            input_info = inTensorInfo.GetTensorsInfoHandle();
+            output_info = outTensorInfo.GetTensorsInfoHandle();
+
+            ret = Interop.SingleShot.OpenSingle(out _handle, modelAbsPath, input_info, output_info, NNFWType.Any, HWType.Any);
+            NNStreamer.CheckException(ret, "fail to open the single inference engine");
+        }
+
+        /// <summary>
+        /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
+        /// </summary>
+        /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
+        protected virtual void Dispose(bool disposing)
+        {
+            if (_disposed)
+                return;
+
+            if (disposing)
+            {
+                // release managed object
+            }
+
+            // release unmanaged objects
+            if (_handle != IntPtr.Zero)
+            {
+                NNStreamerError ret = NNStreamerError.None;
+                ret = Interop.SingleShot.CloseSingle(_handle);
+                if (ret != NNStreamerError.None)
+                {
+                    Log.Error(NNStreamer.TAG, "failed to close inference engine");
+                }
+                _handle = IntPtr.Zero;
+            }
+            _disposed = true;
+        }
+    }
+}
diff --git a/src/Tizen.MachineLearning.Inference/Tizen.MachineLearning.Inference/TensorsData.cs b/src/Tizen.MachineLearning.Inference/Tizen.MachineLearning.Inference/TensorsData.cs
new file mode 100755 (executable)
index 0000000..3ba452e
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+* Copyright (c) 2019 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.MachineLearning.Inference
+{
+    /// <summary>
+    /// The TensorsData class sets and gets the buffer data for each Tensor.
+    /// </summary>
+    /// <since_tizen> 6 </since_tizen>
+    public class TensorsData : IDisposable
+    {
+        private IntPtr _handle = IntPtr.Zero;
+        private bool _disposed = false;
+        private int _count = Tensor.InvalidCount;
+
+        /// <summary>
+        /// Creates a TensorsInfo instance with handle which is given by TensorsInfo.
+        /// </summary>
+        /// <param name="handle">The handle of tensors data.</param>
+        /// <since_tizen> 6 </since_tizen>
+        private TensorsData(IntPtr handle)
+        {
+            _handle = handle;
+        }
+
+        /// <summary>
+        /// Destructor of the TensorsData instance
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        ~TensorsData()
+        {
+            Dispose(false);
+        }
+
+        internal static TensorsData CreateFromNativeHandle(IntPtr handle)
+        {
+            TensorsData retTensorsData = new TensorsData(handle);
+
+            return retTensorsData;
+        }
+
+        /// <summary>
+        /// Gets the number of Tensor in TensorsData class
+        /// </summary>
+        /// <feature>http://tizen.org/feature/machine_learning.inference</feature>
+        /// <exception cref="NotSupportedException">Thrown when the feature is not supported.</exception>
+        /// <since_tizen> 6 </since_tizen>
+        public int Count
+        {
+            get {
+                if (_count != Tensor.InvalidCount)
+                    return _count;
+
+                NNStreamerError ret = NNStreamerError.None;
+                ret = Interop.Util.GetTensorsCount(_handle, out int count);
+                NNStreamer.CheckException(ret, "unable to get the count of TensorsData");
+
+                _count = count;
+                return _count;
+            }
+        }
+
+        /// <summary>
+        /// Sets a tensor data to given index.
+        /// </summary>
+        /// <param name="index">The index of the tensor.</param>
+        /// <param name="buffer">Raw tensor data to be set.</param>
+        /// <feature>http://tizen.org/feature/machine_learning.inference</feature>
+        /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
+        /// <exception cref="NotSupportedException">Thrown when the feature is not supported.</exception>
+        /// <since_tizen> 6 </since_tizen>
+        public void SetTensorData(int index, byte[] buffer)
+        {
+            NNStreamerError ret = NNStreamerError.None;
+
+            ret = Interop.Util.SetTensorData(_handle, index, buffer, buffer.Length);
+            NNStreamer.CheckException(ret, "unable to set the buffer of TensorsData: " + index.ToString());
+        }
+
+        /// <summary>
+        /// Gets a tensor data to given index.
+        /// </summary>
+        /// <param name="index">The index of the tensor.</param>
+        /// <returns>Raw tensor data</returns>
+        /// <feature>http://tizen.org/feature/machine_learning.inference</feature>
+        /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
+        /// <exception cref="NotSupportedException">Thrown when the feature is not supported.</exception>
+        /// <since_tizen> 6 </since_tizen>
+        public byte[] GetTensorData(int index)
+        {
+            byte[] retBuffer;
+            IntPtr raw_data;
+            int size;
+
+            NNStreamerError ret = NNStreamerError.None;
+            ret = Interop.Util.GetTensorData(_handle, index, out raw_data, out size);
+            NNStreamer.CheckException(ret, "unable to get the buffer of TensorsData: " + index.ToString());
+
+            retBuffer = Interop.Util.IntPtrToByteArray(raw_data, size);
+            return retBuffer;
+        }
+
+        /// <summary>
+        /// Releases any unmanaged resources used by this object.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        public void Dispose()
+        {
+            Dispose(true);
+            GC.SuppressFinalize(this);
+        }
+
+        /// <summary>
+        /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
+        /// </summary>
+        /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
+        protected virtual void Dispose(bool disposing)
+        {
+            if (_disposed)
+                return;
+
+            if (disposing)
+            {
+                // release managed object
+            }
+
+            // release unmanaged objects
+            if (_handle != IntPtr.Zero)
+            {
+                NNStreamerError ret = NNStreamerError.None;
+                ret = Interop.Util.DestroyTensorsData(_handle);
+                if (ret != NNStreamerError.None)
+                {
+                    Log.Error(NNStreamer.TAG, "failed to destroy TensorsData object");
+                }
+                _handle = IntPtr.Zero;
+            }
+            _disposed = true;
+        }
+
+        internal IntPtr Handle
+        {
+            get { return _handle; }
+        }
+    }
+}
diff --git a/src/Tizen.MachineLearning.Inference/Tizen.MachineLearning.Inference/TensorsInfo.cs b/src/Tizen.MachineLearning.Inference/Tizen.MachineLearning.Inference/TensorsInfo.cs
new file mode 100755 (executable)
index 0000000..4986b57
--- /dev/null
@@ -0,0 +1,368 @@
+/*
+* Copyright (c) 2019 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 Log = Tizen.Log;
+
+namespace Tizen.MachineLearning.Inference
+{
+    /// <summary>
+    /// The TensorsInfo class manages each Tensor information such as Name, Type and Dimension.
+    /// </summary>
+    /// <since_tizen> 6 </since_tizen>
+    public class TensorsInfo : IDisposable
+    {
+        private List<TensorInfo> _infoList;
+        private IntPtr _handle = IntPtr.Zero;
+        private bool _disposed = false;
+
+        /// <summary>
+        /// Get the number of Tensor information which is added.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        public int Count => _infoList.Count;
+
+        /// <summary>
+        /// Creates a TensorsInfo instance.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        public TensorsInfo()
+        {
+            Log.Info(NNStreamer.TAG, "TensorsInfo is created");
+            _infoList = new List<TensorInfo>();
+        }
+
+        /// <summary>
+        /// Destroys the TensorsInfo resource.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        ~TensorsInfo()
+        {
+            Dispose(false);
+        }
+
+        /// <summary>
+        /// Add a Tensor information to the TensorsInfo instance. Note that we support up to 16 tensors in TensorsInfo.
+        /// </summary>
+        /// <param name="type">Data element type of Tensor.</param>
+        /// <param name="dimension">Dimension of Tensor. Note that we support up to 4th ranks.</param>
+        /// <feature>http://tizen.org/feature/machine_learning.inference</feature>
+        /// <exception cref="IndexOutOfRangeException">Thrown when the number of Tensor already exceeds the size limits (i.e. Tensor.SlzeLimit)</exception>
+        /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
+        /// <exception cref="NotSupportedException">Thrown when the feature is not supported.</exception>
+        /// <since_tizen> 6 </since_tizen>
+        public void AddTensorInfo(TensorType type, int[] dimension)
+        {
+            AddTensorInfo(null, type, dimension);
+        }
+
+        /// <summary>
+        /// Add a Tensor information to the TensorsInfo instance. Note that we support up to 16 tensors in TensorsInfo.
+        /// </summary>
+        /// <param name="name">Name of Tensor.</param>
+        /// <param name="type">Data element type of Tensor.</param>
+        /// <param name="dimension">Dimension of Tensor. Note that we support up to 4th ranks.</param>
+        /// <feature>http://tizen.org/feature/machine_learning.inference</feature>
+        /// <exception cref="IndexOutOfRangeException">Thrown when the number of Tensor already exceeds the size limits (i.e. Tensor.SlzeLimit)</exception>
+        /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
+        /// <exception cref="NotSupportedException">Thrown when the feature is not supported.</exception>
+        /// <since_tizen> 6 </since_tizen>
+        public void AddTensorInfo(string name, TensorType type, int[] dimension)
+        {
+            int idx = _infoList.Count;
+            if (idx >= Tensor.SizeLimit) {
+                throw new IndexOutOfRangeException("Max size of the tensors is " + Tensor.SizeLimit);
+            }
+            _infoList.Add(new TensorInfo(name, type, dimension));
+
+            if (_handle != IntPtr.Zero)
+            {
+                NNStreamerError ret = NNStreamerError.None;
+
+                /* Set the number of tensors */
+                ret = Interop.Util.SetTensorsCount(_handle, _infoList.Count);
+                NNStreamer.CheckException(ret, "unable to set the number of tensors");
+
+                /* Set the type and dimension of Tensor */
+                ret = Interop.Util.SetTensorType(_handle, idx, type);
+                NNStreamer.CheckException(ret, "fail to set TensorsInfo type");
+
+                ret = Interop.Util.SetTensorDimension(_handle, idx, dimension);
+                NNStreamer.CheckException(ret, "fail to set TensorsInfo dimension");
+            }
+        }
+
+        /// <summary>
+        /// Sets the tensor name with given index.
+        /// </summary>
+        /// <param name="idx">The index of the tensor to be updated.</param>
+        /// <param name="name">The tensor name to be set.</param>
+        /// <feature>http://tizen.org/feature/machine_learning.inference</feature>
+        /// <exception cref="IndexOutOfRangeException">Thrown when the index is greater than the number of Tensor.</exception>
+        /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
+        /// <exception cref="NotSupportedException">Thrown when the feature is not supported.</exception>
+        /// <since_tizen> 6 </since_tizen>
+        public void SetTensorName(int idx, string name)
+        {
+            CheckIndexBoundary(idx);
+            _infoList[idx].Name = name;
+
+            if (_handle != IntPtr.Zero)
+            {
+                NNStreamerError ret = NNStreamerError.None;
+                ret = Interop.Util.SetTensorName(_handle, idx, name);
+                NNStreamer.CheckException(ret, "unable to set the name of tensor: " + idx.ToString());
+            }
+        }
+
+        /// <summary>
+        /// Gets the tensor name with given index.
+        /// </summary>
+        /// <param name="idx">The index of the tensor.</param>
+        /// <returns>The tensor name.</returns>
+        /// <exception cref="IndexOutOfRangeException">Thrown when the index is greater than the number of Tensor.</exception>
+        /// <since_tizen> 6 </since_tizen>
+        public string GetTensorName(int idx)
+        {
+            CheckIndexBoundary(idx);
+            return _infoList[idx].Name;
+        }
+
+        /// <summary>
+        /// Sets the tensor type with given index and its type.
+        /// </summary>
+        /// <param name="idx">The index of the tensor to be updated.</param>
+        /// <param name="type">The tensor type to be set.</param>
+        /// <feature>http://tizen.org/feature/machine_learning.inference</feature>
+        /// <exception cref="IndexOutOfRangeException">Thrown when the index is greater than the number of Tensor.</exception>
+        /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
+        /// <exception cref="NotSupportedException">Thrown when the feature is not supported.</exception>
+        /// <since_tizen> 6 </since_tizen>
+        public void SetTensorType(int idx, TensorType type)
+        {
+            CheckIndexBoundary(idx);
+            _infoList[idx].Type = type;
+
+            if (_handle != IntPtr.Zero)
+            {
+                NNStreamerError ret = NNStreamerError.None;
+                ret = Interop.Util.SetTensorType(_handle, idx, type);
+                NNStreamer.CheckException(ret, "unable to set the type of tensor: " + idx.ToString());
+            }
+        }
+
+        /// <summary>
+        /// Gets the tensor type with given index.
+        /// </summary>
+        /// <param name="idx">The index of the tensor.</param>
+        /// <returns>The tensor type</returns>
+        /// <exception cref="IndexOutOfRangeException">Thrown when the index is greater than the number of Tensor.</exception>
+        /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
+        /// <since_tizen> 6 </since_tizen>
+        public TensorType GetTensorType(int idx)
+        {
+            CheckIndexBoundary(idx);
+            return _infoList[idx].Type;
+        }
+
+        /// <summary>
+        /// Sets the tensor dimension with given index and dimension.
+        /// </summary>
+        /// <param name="idx">The index of the tensor to be updated.</param>
+        /// <param name="dimension">The tensor dimension to be set.</param>
+        /// <feature>http://tizen.org/feature/machine_learning.inference</feature>
+        /// <exception cref="IndexOutOfRangeException">Thrown when the index is greater than the number of Tensor.</exception>
+        /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
+        /// <exception cref="NotSupportedException">Thrown when the feature is not supported.</exception>
+        /// <since_tizen> 6 </since_tizen>
+        public void SetDimension(int idx, int[] dimension)
+        {
+            CheckIndexBoundary(idx);
+            _infoList[idx].SetDimension(dimension);
+
+            if (_handle != IntPtr.Zero)
+            {
+                NNStreamerError ret = NNStreamerError.None;
+                ret = Interop.Util.SetTensorDimension(_handle, idx, dimension);
+                NNStreamer.CheckException(ret, "unable to set the dimension of tensor: " + idx.ToString());
+            }
+        }
+
+        /// <summary>
+        /// Gets the tensor dimension with given index.
+        /// </summary>
+        /// <param name="idx">The index of the tensor.</param>
+        /// <returns>The tensor dimension.</returns>
+        /// <exception cref="IndexOutOfRangeException">Thrown when the index is greater than the number of Tensor.</exception>
+        /// <exception cref="ArgumentException">Thrown when the method failed due to an invalid parameter.</exception>
+        /// <since_tizen> 6 </since_tizen>
+        public int[] GetDimension(int idx)
+        {
+            CheckIndexBoundary(idx);
+            return _infoList[idx].Dimension;
+        }
+
+        /// <summary>
+        /// Creates a TensorsData instance based on informations of TensorsInfo
+        /// </summary>
+        /// <returns>TensorsData instance</returns>
+        /// <feature>http://tizen.org/feature/machine_learning.inference</feature>
+        /// <exception cref="ArgumentException">Thrown when the method failed due to TensorsInfo's information is invalid.</exception>
+        /// <exception cref="NotSupportedException">Thrown when the feature is not supported.</exception>
+        /// <since_tizen> 6 </since_tizen>
+        public TensorsData GetTensorsData()
+        {
+            IntPtr tensorsData_h;
+            TensorsData retTensorData;
+            NNStreamerError ret = NNStreamerError.None;
+
+            if (_handle == IntPtr.Zero)
+            {
+                Log.Info(NNStreamer.TAG, "_handle is IntPtr.Zero\n" + "  GetTensorsInfoHandle() is called");
+                GetTensorsInfoHandle();
+            }
+
+            ret = Interop.Util.CreateTensorsData(_handle, out tensorsData_h);
+            NNStreamer.CheckException(ret, "unable to create the tensorsData object");
+            Log.Info(NNStreamer.TAG, "success to CreateTensorsData()\n");
+
+            retTensorData = TensorsData.CreateFromNativeHandle(tensorsData_h);
+
+            return retTensorData;
+        }
+
+        internal IntPtr GetTensorsInfoHandle()
+        {
+            NNStreamerError ret = NNStreamerError.None;
+            IntPtr ret_handle;
+            int idx;
+
+            /* Already created */
+            if (_handle != IntPtr.Zero)
+                return _handle;
+
+            /* Check required parameters */
+            int num = _infoList.Count;
+            if (num <= 0 || num > Tensor.SizeLimit)
+                ret = NNStreamerError.InvalidParameter;
+            NNStreamer.CheckException(ret, "number of Tensor in TensorsInfo is invalid: " + _infoList.Count);
+
+            /* Create TensorsInfo object */
+            ret = Interop.Util.CreateTensorsInfo(out ret_handle);
+            NNStreamer.CheckException(ret, "fail to create TensorsInfo object");
+
+            /* Set the number of tensors */
+            ret = Interop.Util.SetTensorsCount(ret_handle, _infoList.Count);
+            NNStreamer.CheckException(ret, "unable to set the number of tensors");
+
+            /* Set each Tensor info */
+            idx = 0;
+            foreach (TensorInfo t in _infoList)
+            {
+                ret = Interop.Util.SetTensorType(ret_handle, idx, t.Type);
+                NNStreamer.CheckException(ret, "fail to set the type of tensor" + idx.ToString());
+
+                ret = Interop.Util.SetTensorDimension(ret_handle, idx, t.Dimension);
+                NNStreamer.CheckException(ret, "fail to set the dimension of tensor: " + idx.ToString());
+
+                idx += 1;
+            }
+
+            _handle = ret_handle;
+            return ret_handle;
+        }
+
+        /// <summary>
+        /// Releases any unmanaged resources used by this object.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        public void Dispose()
+        {
+            Dispose(true);
+            GC.SuppressFinalize(this);
+        }
+
+        /// <summary>
+        /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
+        /// </summary>
+        /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
+        protected virtual void Dispose(bool disposing)
+        {
+            if (_disposed)
+                return;
+
+            if (disposing)
+            {
+                // release managed objects
+                _infoList.Clear();
+            }
+
+            // release unmanaged objects
+            if (_handle != IntPtr.Zero)
+            {
+                NNStreamerError ret = NNStreamerError.None;
+                ret = Interop.Util.DestroyTensorsInfo(_handle);
+                if (ret != NNStreamerError.None)
+                {
+                    Log.Error(NNStreamer.TAG, "failed to destroy TensorsInfo object");
+                }
+            }
+            _disposed = true;
+        }
+        
+        private void CheckIndexBoundary(int idx)
+        {
+            if (idx < 0 || idx >= _infoList.Count) {
+                throw new IndexOutOfRangeException("Invalid index [" + idx + "] of the tensors");
+            }
+        }
+
+        private class TensorInfo
+        {
+            public TensorInfo(TensorType type, int[] dimension)
+            {
+                Type = type;
+                SetDimension(dimension);
+            }
+
+            public TensorInfo(string name, TensorType type, int[] dimension)
+            {
+                Name = name;
+                Type = type;
+                SetDimension(dimension);
+            }
+
+            public void SetDimension(int[] dimension)
+            {
+                if (dimension == null) {
+                    throw new ArgumentException("Max size of the tensor rank is" + Tensor.RankLimit);
+                }
+
+                if (dimension.Length > Tensor.RankLimit) {
+                    throw new ArgumentException("Max size of the tensor rank is" + Tensor.RankLimit);
+                }
+                Dimension = (int[])dimension.Clone();
+            }
+
+            public string Name { get; set; } = null;
+
+            public TensorType Type { get; set; } = TensorType.Int32;
+
+            public int[] Dimension { get; private set; } = new int[Tensor.RankLimit];
+        }
+    }
+}
index 1b26dc0..8dcec76 100644 (file)
@@ -29,9 +29,46 @@ namespace Tizen.Multimedia
         /// Mono.
         /// </summary>
         Mono = 0x80,
+
         /// <summary>
         /// Stereo.
         /// </summary>
-        Stereo
+        Stereo,
+
+        /// <summary>
+        /// 3 audio channels
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        MultiChannel3,
+
+        /// <summary>
+        /// 4 audio channels
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        MultiChannel4,
+
+        /// <summary>
+        /// 5 audio channels
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        MultiChannel5,
+
+        /// <summary>
+        /// 6 audio channels
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        MultiChannel6,
+
+        /// <summary>
+        /// 7 audio channels
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        MultiChannel7,
+
+        /// <summary>
+        /// 8 audio channels
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        MultiChannel8
     }
 }
index 689d7e2..bd4054a 100644 (file)
@@ -26,19 +26,28 @@ namespace Tizen.Multimedia
         /// Unsigned 8-bit audio samples.
         /// </summary>
         U8 = 0x70,
+
         /// <summary>
         /// Signed 16-bit audio samples.
         /// </summary>
         S16Le,
+
         /// <summary>
         /// Signed 24-bit audio samples.
         /// </summary>
         /// <since_tizen> 5 </since_tizen>
         S24Le,
+
         /// <summary>
         /// Signed 24-bit (packed in 32-bit) audio samples.
         /// </summary>
         /// <since_tizen> 5 </since_tizen>
-        S24LePacked
+        S24LePacked,
+
+        /// <summary>
+        /// Signed 32-bit audio samples.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        S32Le
     }
 }
index 9489e62..8bd2e18 100644 (file)
@@ -23,6 +23,12 @@ internal static partial class Interop
 {
     internal static partial class MediaControllerClient
     {
+        #region Callback delegate
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate bool ActivatedServerCallback(string serverName, IntPtr userData);
+
+
+        // Updated callbacks
         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
         internal delegate void ServerUpdatedCallback(string serverName, MediaControllerNativeServerState serverState,
             IntPtr userData);
@@ -35,17 +41,40 @@ internal static partial class Interop
             IntPtr userData);
 
         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate void RepeatModeUpdatedCallback(string serverName, MediaControllerNativeRepeatMode repeatMode, IntPtr userData);
+        internal delegate void RepeatModeUpdatedCallback(string serverName, MediaControllerNativeRepeatMode repeatMode,
+            IntPtr userData);
 
         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate bool ActivatedServerCallback(string serverName, IntPtr userData);
+        internal delegate void DisplayModeUpdatedCallback(string serverName, MediaControlNativeDisplayMode isEnabned, IntPtr userData);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void DisplayRotationUpdatedCallback(string serverName, MediaControlNativeDisplayRotation isEnabned, IntPtr userData);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void BoolAttributeUpdatedCallback(string serverName, bool isEnabled, IntPtr userData);
+
+
+        // Capability updated callbacks
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void PlaybackCapabilityUpdatedCallback(string serverName, IntPtr capaHandle, IntPtr userData);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void CategoryAttributeCapabilityUpdatedCallback(string serverName, uint updatedItem,
+            IntPtr userData);
 
         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void SimpleCapabilityUpdatedCallback(string serverName, MediaControlNativeCapabilityCategory category,
+            MediaControlCapabilitySupport support, IntPtr userData);
+
+
+        // Command callbacks
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
         internal delegate void CommandCompletedCallback(string serverName, string requestId, MediaControllerError result,
             IntPtr bundleHandle, IntPtr userData);
 
         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
         internal delegate void CustomCommandReceivedCallback(string serverName, string requestId, string customEvent, IntPtr bundleHandle, IntPtr userData);
+        #endregion Callback delegate
 
 
         [DllImport(Libraries.MediaController, EntryPoint = "mc_client_create")]
@@ -54,6 +83,68 @@ internal static partial class Interop
         [DllImport(Libraries.MediaController, EntryPoint = "mc_client_destroy")]
         internal static extern MediaControllerError Destroy(IntPtr handle);
 
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_destroy_playback")]
+        internal static extern MediaControllerError DestroyPlayback(IntPtr playback);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_foreach_server")]
+        internal static extern MediaControllerError ForeachActivatedServer(MediaControllerClientHandle handle,
+            ActivatedServerCallback callback, IntPtr userData);
+
+
+        #region Get information
+        // Playback information
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_server_playback_info")]
+        internal static extern MediaControllerError GetServerPlaybackHandle(MediaControllerClientHandle handle,
+            string serverName, out IntPtr playback);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_playback_state")]
+        internal static extern MediaControllerError GetPlaybackState(IntPtr playbackHandle, out MediaControllerNativePlaybackState state);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_playback_position")]
+        internal static extern MediaControllerError GetPlaybackPosition(IntPtr playbackHandle, out ulong position);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_age_rating")]
+        internal static extern MediaControllerError GetAgeRating(IntPtr playbackHandle, out int rating);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_playback_content_type")]
+        internal static extern MediaControllerError GetPlaybackContentType(IntPtr playbackHandle,
+            out MediaControlContentType type);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_latest_server_info")]
+        internal static extern MediaControllerError GetLatestServer(MediaControllerClientHandle handle,
+            out IntPtr serverName, out MediaControllerNativeServerState serverState);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_server_shuffle_mode")]
+        internal static extern MediaControllerError GetServerShuffleMode(MediaControllerClientHandle handle,
+            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 MediaControllerNativeRepeatMode mode);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_server_icon")]
+        internal static extern MediaControllerError GetServerIcon(MediaControllerClientHandle clientHandle,
+            string serverName, out string uri);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_server_subtitle_enabled")]
+        internal static extern MediaControllerError IsSubtitleEnabled(MediaControllerClientHandle clientHandle,
+            string serverName, out bool isEnabled);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_server_360_mode_enabled")]
+        internal static extern MediaControllerError IsMode360Enabled(MediaControllerClientHandle clientHandle,
+            string serverName, out bool isEnabled);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_server_display_mode")]
+        internal static extern MediaControllerError GetDisplayMode(MediaControllerClientHandle clientHandle,
+            string serverName, out MediaControlNativeDisplayMode mode);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_server_display_rotation")]
+        internal static extern MediaControllerError GetDisplayRotation(MediaControllerClientHandle clientHandle,
+            string serverName, out MediaControlNativeDisplayRotation mode);
+        #endregion Get information
+
+
+        #region Updated callback
         [DllImport(Libraries.MediaController, EntryPoint = "mc_client_set_server_updated_cb")]
         internal static extern MediaControllerError SetServerUpdatedCb(MediaControllerClientHandle handle,
             ServerUpdatedCallback callback, IntPtr userData = default(IntPtr));
@@ -82,57 +173,95 @@ internal static partial class Interop
         [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_set_subtitle_updated_cb")]
+        internal static extern MediaControllerError SetSubtitleUpdatedCb(MediaControllerClientHandle handle,
+            BoolAttributeUpdatedCallback 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_set_360_mode_updated_cb")]
+        internal static extern MediaControllerError SetMode360UpdatedCb(MediaControllerClientHandle handle,
+            BoolAttributeUpdatedCallback callback, IntPtr userData = default(IntPtr));
 
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_set_custom_event_received_cb")]
-        internal static extern MediaControllerError SetCustomEventCb(MediaControllerClientHandle handle,
-            CustomCommandReceivedCallback callback, IntPtr userData = default(IntPtr));
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_set_display_mode_updated_cb")]
+        internal static extern MediaControllerError SetDisplayModeUpdatedCb(MediaControllerClientHandle handle,
+            DisplayModeUpdatedCallback callback, IntPtr userData = default(IntPtr));
 
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_unset_custom_event_received_cb")]
-        internal static extern MediaControllerError UnsetCustomEventCb(MediaControllerClientHandle handle);
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_set_display_rotation_updated_cb")]
+        internal static extern MediaControllerError SetDisplayRotationUpdatedCb(MediaControllerClientHandle handle,
+            DisplayRotationUpdatedCallback callback, IntPtr userData = default(IntPtr));
+        #endregion Updated callback
 
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_playback_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);
+        #region Capability
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_server_playback_ability")]
+        internal static extern MediaControllerError GetPlaybackCapabilityHandle(MediaControllerClientHandle clientHandle,
+            string serverName, out IntPtr capaHandle);
 
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_destroy_playback")]
-        internal static extern MediaControllerError DestroyPlayback(IntPtr playback);
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_playback_action_is_supported")]
+        internal static extern MediaControllerError GetPlaybackCapability(IntPtr capaHandle,
+            MediaControllerNativePlaybackAction action, out MediaControlCapabilitySupport support);
 
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_latest_server_info")]
-        internal static extern MediaControllerError GetLatestServer(MediaControllerClientHandle handle,
-            out IntPtr serverName, out MediaControllerNativeServerState serverState);
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_playback_ability_destroy")]
+        internal static extern MediaControllerError DestroyCapability(IntPtr capaHandle);
 
-        [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_playback_ability_clone")]
+        internal static extern MediaControllerError CloneCapability(IntPtr capaSrcHandle, out IntPtr capaDstHandle);
 
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_server_shuffle_mode")]
-        internal static extern MediaControllerError GetServerShuffleMode(MediaControllerClientHandle handle,
-            string serverName, out MediaControllerNativeShuffleMode mode);
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_server_display_mode_ability")]
+        internal static extern MediaControllerError GetDisplayModeCapability(MediaControllerClientHandle clientHandle,
+            string serverName, out uint support);
 
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_server_repeat_mode")]
-        internal static extern MediaControllerError GetServerRepeatMode(MediaControllerClientHandle handle,
-            string serverName, out MediaControllerNativeRepeatMode mode);
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_server_display_rotation_ability")]
+        internal static extern MediaControllerError GetDisplayRotationCapability(MediaControllerClientHandle clientHandle,
+            string serverName, out uint support);
 
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_send_playback_state_command")]
-        internal static extern MediaControllerError SendPlaybackStateCommand(MediaControllerClientHandle handle,
-            string serverName, MediaControllerNativePlaybackAction command);
+        // Common
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_server_ability_support")]
+        internal static extern MediaControllerError GetSimpleCapability(MediaControllerClientHandle clientHandle,
+            string serverName, MediaControlNativeCapabilityCategory category, out MediaControlCapabilitySupport type);
+        #endregion Capability
 
-        [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);
+        #region Capability updated callback
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_set_playback_ability_updated_cb")]
+        internal static extern MediaControllerError SetPlaybackCapabilityUpdatedCb(MediaControllerClientHandle clientHandle,
+            PlaybackCapabilityUpdatedCallback callback, IntPtr userData = default(IntPtr));
 
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_unset_playback_ability_updated_cb")]
+        internal static extern MediaControllerError UnsetPlaybackCapabilityUpdatedCb(MediaControllerClientHandle clientHandle);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_set_display_mode_ability_updated_cb")]
+        internal static extern MediaControllerError SetDisplayModeCapabilityUpdatedCb(MediaControllerClientHandle clientHandle,
+            CategoryAttributeCapabilityUpdatedCallback callback, IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_set_display_rotation_ability_updated_cb")]
+        internal static extern MediaControllerError SetDisplayRotationCapabilityUpdatedCb(MediaControllerClientHandle clientHandle,
+            CategoryAttributeCapabilityUpdatedCallback callback, IntPtr userData = default(IntPtr));
+
+        // Common
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_set_ability_support_updated_cb")]
+        internal static extern MediaControllerError SetCategoryCapabilityUpdatedCb(MediaControllerClientHandle clientHandle,
+            SimpleCapabilityUpdatedCallback callback, IntPtr userData = default(IntPtr));
+        #endregion Capability updated callback
+
+
+        #region Search
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_search_create")]
+        internal static extern MediaControllerError CreateSearchHandle(out IntPtr searchHandle);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_search_set_condition")]
+        internal static extern MediaControllerError SetSearchCondition(IntPtr searchHandle,
+            MediaControlContentType type, MediaControlSearchCategory category, string keyword, IntPtr bundle);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_search_set_condition")]
+        internal static extern MediaControllerError SetSearchConditionBundle(IntPtr searchHandle,
+            MediaControlContentType type, MediaControlSearchCategory category, string keyword, SafeBundleHandle bundle);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_search_destroy")]
+        internal static extern MediaControllerError DestroySearchHandle(IntPtr searchHandle);
+        #endregion Search
+
+
+        #region Command
         [DllImport(Libraries.MediaController, EntryPoint = "mc_client_send_playback_action_cmd")]
         internal static extern MediaControllerError SendPlaybackActionCommand(MediaControllerClientHandle handle,
             string serverName, MediaControllerNativePlaybackAction action, out string requestId);
@@ -162,92 +291,54 @@ internal static partial class Interop
         internal static extern MediaControllerError SendSearchCommand(MediaControllerClientHandle handle,
             string serverName, IntPtr searchHandle, out string requestId);
 
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_send_event_reply")]
-        internal static extern MediaControllerError SendCustomEventReply(MediaControllerClientHandle handle,
-            string serverName, string requestId, int result, IntPtr bundleHandle);
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_send_event_reply")]
-        internal static extern MediaControllerError SendCustomEventReplyBundle(MediaControllerClientHandle handle,
-            string serverName, string requestId, int result, SafeBundleHandle bundleHandle);
-
-
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_foreach_server")]
-        internal static extern MediaControllerError ForeachActivatedServer(MediaControllerClientHandle handle,
-            ActivatedServerCallback callback, IntPtr userData);
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_send_subtitle_cmd")]
+        internal static extern MediaControllerError SendSubtitleModeCommand(MediaControllerClientHandle handle,
+            string serverName, bool isEnabled, out string requestId);
 
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_age_rating")]
-        internal static extern MediaControllerError GetAgeRating(IntPtr playbackHandle, out int rating);
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_send_360_mode_cmd")]
+        internal static extern MediaControllerError SendMode360Command(MediaControllerClientHandle handle,
+            string serverName, bool isEnabled, out string requestId);
 
-        #region Capability
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate void PlaybackCapabilityUpdatedCallback(string serverName, IntPtr capaHandle,
-            IntPtr userData = default(IntPtr));
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_send_display_mode_cmd")]
+        internal static extern MediaControllerError SendDisplayModeCommand(MediaControllerClientHandle handle,
+            string serverName, MediaControlNativeDisplayMode mode, out string requestId);
 
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate void ShuffleCapabilityUpdatedCallback(string serverName, MediaControlCapabilitySupport support,
-            IntPtr userData = default(IntPtr));
-
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate void RepeatCapabilityUpdatedCallback(string serverName, MediaControlCapabilitySupport support,
-            IntPtr userData = default(IntPtr));
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_send_display_rotation_cmd")]
+        internal static extern MediaControllerError SendDisplayRotationCommand(MediaControllerClientHandle handle,
+            string serverName, MediaControlNativeDisplayRotation mode, out string requestId);
 
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate void SimpleCapabilityCallback(string serverName, MediaControlCapabilityCategory category,
-            MediaControlCapabilitySupport support, IntPtr userData = default(IntPtr));
-
-
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_playback_content_type")]
-        internal static extern MediaControllerError GetPlaybackContentType(IntPtr playbackHandle,
-            out MediaControlContentType type);
-
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_server_icon")]
-        internal static extern MediaControllerError GetServerIcon(MediaControllerClientHandle clientHandle,
-            string serverName, out string uri);
-
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_server_playback_ability")]
-        internal static extern MediaControllerError GetPlaybackCapabilityHandle(MediaControllerClientHandle clientHandle,
-            string serverName, out IntPtr capaHandle);
-
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_set_playback_ability_updated_cb")]
-        internal static extern MediaControllerError SetPlaybackCapabilityUpdatedCb(MediaControllerClientHandle clientHandle,
-            PlaybackCapabilityUpdatedCallback callback, IntPtr userData = default(IntPtr));
-
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_unset_playback_ability_updated_cb")]
-        internal static extern MediaControllerError UnsetPlaybackCapabilityUpdatedCb(MediaControllerClientHandle clientHandle);
-
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_set_ability_support_updated_cb")]
-        internal static extern MediaControllerError SetSimpleCapabilityUpdatedCb(MediaControllerClientHandle clientHandle,
-            SimpleCapabilityCallback callback, IntPtr userData = default(IntPtr));
-
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_get_server_ability_support")]
-        internal static extern MediaControllerError GetSimpleCapability(MediaControllerClientHandle clientHandle,
-            string serverName, MediaControlCapabilityCategory category, out MediaControlCapabilitySupport type);
+        [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_playback_ability_clone")]
-        internal static extern MediaControllerError CloneCapability(IntPtr capaSrcHandle, out IntPtr capaDstHandle);
+        [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_playback_ability_destroy")]
-        internal static extern MediaControllerError DestroyCapability(IntPtr capaHandle);
+        [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_playback_action_is_supported")]
-        internal static extern MediaControllerError IsCapabilitySupported(IntPtr capaHandle,
-            MediaControllerNativePlaybackAction action, out MediaControlCapabilitySupport support);
-        #endregion Capability
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_unset_cmd_reply_received_cb")]
+        internal static extern MediaControllerError UnsetCommandCompletedCb(MediaControllerClientHandle handle);
+        #endregion Command
 
-        #region Search
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_search_create")]
-        internal static extern MediaControllerError CreateSearchHandle(out IntPtr searchHandle);
 
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_search_set_condition")]
-        internal static extern MediaControllerError SetSearchCondition(IntPtr searchHandle,
-            MediaControlContentType type, MediaControlSearchCategory category, string keyword, IntPtr bundle);
+        #region Event
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_set_custom_event_received_cb")]
+        internal static extern MediaControllerError SetCustomEventCb(MediaControllerClientHandle handle,
+            CustomCommandReceivedCallback callback, IntPtr userData = default(IntPtr));
 
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_search_set_condition")]
-        internal static extern MediaControllerError SetSearchConditionBundle(IntPtr searchHandle,
-            MediaControlContentType type, MediaControlSearchCategory category, string keyword, SafeBundleHandle bundle);
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_unset_custom_event_received_cb")]
+        internal static extern MediaControllerError UnsetCustomEventCb(MediaControllerClientHandle handle);
 
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_search_destroy")]
-        internal static extern MediaControllerError DestroySearchHandle(IntPtr searchHandle);
-        #endregion Search
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_send_event_reply")]
+        internal static extern MediaControllerError SendCustomEventReply(MediaControllerClientHandle handle,
+            string serverName, string requestId, int result, IntPtr bundleHandle);
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_client_send_event_reply")]
+        internal static extern MediaControllerError SendCustomEventReplyBundle(MediaControllerClientHandle handle,
+            string serverName, string requestId, int result, SafeBundleHandle bundleHandle);
+        #endregion Event
     }
 
     internal class MediaControllerClientHandle : SafeHandle
index 63c905d..50b7682 100644 (file)
@@ -23,6 +23,12 @@ internal static partial class Interop
 {
     internal static partial class MediaControllerServer
     {
+        #region Callback delegate
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate bool ActivatedClientCallback(string clientName, IntPtr userData);
+
+
+        // Received callbacks
         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
         internal delegate void PlaybackStateCommandReceivedCallback(string clientName,
             MediaControllerNativePlaybackAction nativeAction, IntPtr userData);
@@ -42,22 +48,30 @@ internal static partial class Interop
 
         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
         internal delegate void ShuffleModeCommandReceivedCallback(string clientName,
-            string requestId, MediaControllerNativeShuffleMode shuffleMode, IntPtr userData);
+            string requestId, MediaControllerNativeShuffleMode mode, IntPtr userData);
 
         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
         internal delegate void RepeatModeCommandReceivedCallback(string clientName,
-            string requestId, MediaControllerNativeRepeatMode repeatMode, IntPtr userData);
+            string requestId, MediaControllerNativeRepeatMode mode, IntPtr userData);
 
         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate void CustomCommandReceivedCallback(string clientName,
-            string requestId, string customCommand, IntPtr bundleHandle, IntPtr userData);
+        internal delegate void DisplayModeCommandReceivedCallback(string clientName,
+            string requestId, MediaControlNativeDisplayMode mode, IntPtr userData);
 
         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate bool PlaylistCallback(IntPtr handle, IntPtr userData);
+        internal delegate void DisplayRotationCommandReceivedCallback(string clientName,
+            string requestId, MediaControlNativeDisplayRotation rotation, IntPtr userData);
 
         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate bool ActivatedClientCallback(string clientName, IntPtr userData);
+        internal delegate void SimpleCommandReceivedCallback(string clientName,
+            string requestId, bool isEnabled, IntPtr userData);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void CustomCommandReceivedCallback(string clientName,
+            string requestId, string customCommand, IntPtr bundleHandle, IntPtr userData);
 
+
+        // Command callbacks
         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
         internal delegate void CommandCompletedCallback(string clientName, string requestId, MediaControllerError result, IntPtr bundleHandle,
             IntPtr userData = default(IntPtr));
@@ -66,9 +80,12 @@ internal static partial class Interop
         internal delegate void SearchCommandReceivedCallback(string clientName, string requestId, IntPtr searchHandle,
             IntPtr userData = default(IntPtr));
 
+
+        // Search callback
         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
         internal delegate bool SearchItemCallback(MediaControlContentType type, MediaControlSearchCategory category,
             string keyword, IntPtr bundleHandle, IntPtr userData = default(IntPtr));
+        #endregion Callback delegate
 
 
         [DllImport(Libraries.MediaController, EntryPoint = "mc_server_create")]
@@ -77,6 +94,12 @@ internal static partial class Interop
         [DllImport(Libraries.MediaController, EntryPoint = "mc_server_destroy")]
         internal static extern MediaControllerError Destroy(IntPtr handle);
 
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_foreach_client")]
+        internal static extern MediaControllerError ForeachActivatedClient(IntPtr handle, ActivatedClientCallback callback,
+            IntPtr userData = default(IntPtr));
+
+
+        #region Set information
         [DllImport(Libraries.MediaController, EntryPoint = "mc_server_set_playback_state")]
         internal static extern MediaControllerError SetPlaybackState(IntPtr handle,
             MediaControllerNativePlaybackState state);
@@ -101,6 +124,24 @@ internal static partial class Interop
         [DllImport(Libraries.MediaController, EntryPoint = "mc_server_update_repeat_mode")]
         internal static extern MediaControllerError UpdateRepeatMode(IntPtr handle, MediaControllerNativeRepeatMode mode);
 
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_set_content_age_rating")]
+        internal static extern MediaControllerError SetAgeRating(IntPtr handle, int rating);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_update_subtitle_enabled")]
+        internal static extern MediaControllerError UpdateSubtitleMode(IntPtr handle, bool isEnabled);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_update_360_mode_enabled")]
+        internal static extern MediaControllerError UpdateMode360(IntPtr handle, bool isEnabled);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_update_display_mode")]
+        internal static extern MediaControllerError UpdateDisplayMode(IntPtr handle, MediaControlNativeDisplayMode mode);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_update_display_rotation")]
+        internal static extern MediaControllerError UpdateDisplayRotaton(IntPtr handle, MediaControlNativeDisplayRotation rotation);
+        #endregion Set information
+
+
+        #region Received callback
         [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));
@@ -136,6 +177,22 @@ internal static partial class Interop
         [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_subtitle_cmd_received_cb")]
+        internal static extern MediaControllerError SetSubtitleModeCommandReceivedCb(IntPtr handle,
+            SimpleCommandReceivedCallback callback, IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_set_360_mode_cmd_received_cb")]
+        internal static extern MediaControllerError SetMode360CommandReceivedCb(IntPtr handle,
+            SimpleCommandReceivedCallback callback, IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_set_display_mode_cmd_received_cb")]
+        internal static extern MediaControllerError SetDisplayModeCommandReceivedCb(IntPtr handle,
+            DisplayModeCommandReceivedCallback callback, IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_set_display_rotation_cmd_received_cb")]
+        internal static extern MediaControllerError SetDisplayRotationCommandReceivedCb(IntPtr handle,
+            DisplayRotationCommandReceivedCallback callback, IntPtr userData = default(IntPtr));
+
         [DllImport(Libraries.MediaController, EntryPoint = "mc_server_set_custom_cmd_received_cb")]
         internal static extern MediaControllerError SetCustomCommandReceivedCb(IntPtr handle,
             CustomCommandReceivedCallback callback, IntPtr userData = default(IntPtr));
@@ -149,15 +206,10 @@ internal static partial class Interop
 
         [DllImport(Libraries.MediaController, EntryPoint = "mc_server_unset_search_cmd_received_cb")]
         internal static extern MediaControllerError UnsetSearchCommandReceivedCb(IntPtr handle);
+        #endregion Received callback
 
-        [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);
 
+        #region Database
         [DllImport(Libraries.MediaController, EntryPoint = "mc_db_connect")]
         internal static extern MediaControllerError ConnectDb(out IntPtr dbHandle);
 
@@ -166,7 +218,10 @@ 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);
+        #endregion Database
+
 
+        #region Playlist
         [DllImport(Libraries.MediaController, EntryPoint = "mc_server_create_playlist")]
         internal static extern MediaControllerError CreatePlaylist(IntPtr handle, string name, out IntPtr playlist);
 
@@ -185,28 +240,7 @@ internal static partial class Interop
 
         [DllImport(Libraries.MediaController, EntryPoint = "mc_server_update_playlist_done")]
         internal static extern MediaControllerError SavePlaylist(IntPtr handle, IntPtr playlist);
-
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_foreach_client")]
-        internal static extern MediaControllerError ForeachActivatedClient(IntPtr handle, ActivatedClientCallback callback,
-            IntPtr userData = default(IntPtr));
-
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_send_custom_event")]
-        internal static extern MediaControllerError SendCustomEvent(IntPtr handle, string appId, string customEvent,
-            IntPtr bundle, out string requestId);
-
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_send_custom_event")]
-        internal static extern MediaControllerError SendCustomEventBundle(IntPtr handle, string appId, string customEvent,
-            SafeBundleHandle bundle, out string requestId);
-
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_set_event_reply_received_cb")]
-        internal static extern MediaControllerError SetEventReceivedCb(IntPtr handle, CommandCompletedCallback callback,
-            IntPtr userData = default(IntPtr));
-
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_unset_event_reply_received_cb")]
-        internal static extern MediaControllerError UnsetEventReceivedCb(IntPtr handle);
-
-        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_set_content_age_rating")]
-        internal static extern MediaControllerError SetAgeRating(IntPtr handle, int rating);
+        #endregion Playlist
 
 
         #region Capability
@@ -224,11 +258,20 @@ internal static partial class Interop
         [DllImport(Libraries.MediaController, EntryPoint = "mc_server_update_playback_ability")]
         internal static extern MediaControllerError SaveAndNotifyPlaybackCapabilityUpdated(IntPtr serverHandle);
 
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_set_display_mode_ability")]
+        internal static extern MediaControllerError SetDisplayModeCapability(IntPtr serverHandle,
+            uint modes, MediaControlCapabilitySupport support);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_set_display_rotation_ability")]
+        internal static extern MediaControllerError SetDisplayRotationCapability(IntPtr serverHandle,
+            uint rotations, MediaControlCapabilitySupport support);
+
         [DllImport(Libraries.MediaController, EntryPoint = "mc_server_set_ability_support")]
         internal static extern MediaControllerError SetSimpleCapability(IntPtr serverHandle,
-            MediaControlCapabilityCategory category, MediaControlCapabilitySupport support);
+            MediaControlNativeCapabilityCategory category, MediaControlCapabilitySupport support);
         #endregion Capability
 
+
         #region Search
         [DllImport(Libraries.MediaController, EntryPoint = "mc_search_foreach_condition")]
         internal static extern MediaControllerError ForeachSearchCondition(IntPtr serverHandle,
@@ -241,5 +284,34 @@ internal static partial class Interop
         internal static extern MediaControllerError DestroySearchHandle(IntPtr searchHandle);
 
         #endregion Search
+
+
+        #region Command
+        [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);
+        #endregion Command
+
+
+        #region Event
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_send_custom_event")]
+        internal static extern MediaControllerError SendCustomEvent(IntPtr handle, string appId, string customEvent,
+            IntPtr bundle, out string requestId);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_send_custom_event")]
+        internal static extern MediaControllerError SendCustomEventBundle(IntPtr handle, string appId, string customEvent,
+            SafeBundleHandle bundle, out string requestId);
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_set_event_reply_received_cb")]
+        internal static extern MediaControllerError SetEventReceivedCb(IntPtr handle, CommandCompletedCallback callback,
+            IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.MediaController, EntryPoint = "mc_server_unset_event_reply_received_cb")]
+        internal static extern MediaControllerError UnsetEventReceivedCb(IntPtr handle);
+        #endregion Event
     }
 }
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/DisplayModeCapabilityUpdatedEventArgs.cs b/src/Tizen.Multimedia.Remoting/MediaController/DisplayModeCapabilityUpdatedEventArgs.cs
new file mode 100644 (file)
index 0000000..9470bf1
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2019 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 System.Collections.ObjectModel;
+
+namespace Tizen.Multimedia.Remoting
+{
+    /// <summary>
+    /// Provides data for the <see cref="MediaController.DisplayModeCapabilityUpdated"/> event.
+    /// </summary>
+    /// <since_tizen> 6 </since_tizen>
+    public class DisplayModeCapabilityUpdatedEventArgs : EventArgs
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="DisplayModeCapabilityUpdatedEventArgs"/> class.
+        /// </summary>
+        /// <param name="mode">The supported list of display mode capabilities.</param>
+        /// <since_tizen> 6 </since_tizen>
+        internal DisplayModeCapabilityUpdatedEventArgs(IList<MediaControlDisplayMode> mode)
+        {
+            DisplayMode = new ReadOnlyCollection<MediaControlDisplayMode>(mode);
+        }
+
+        /// <summary>
+        /// Gets the supported list of display mode capabilities.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        public ReadOnlyCollection<MediaControlDisplayMode> DisplayMode { get; }
+    }
+}
\ No newline at end of file
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/DisplayModeCommandReceivedEventArgs.cs b/src/Tizen.Multimedia.Remoting/MediaController/DisplayModeCommandReceivedEventArgs.cs
new file mode 100644 (file)
index 0000000..9bc1fa9
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2019 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.DisplayModeCommandReceived"/> event.
+    /// </summary>
+    /// <since_tizen> 6 </since_tizen>
+    public class DisplayModeCommandReceivedEventArgs : EventArgs
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="DisplayModeCommandReceivedEventArgs"/> class.
+        /// </summary>
+        /// <param name="command">The display mode command.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="command"/> is null.</exception>
+        /// <since_tizen> 6 </since_tizen>
+        internal DisplayModeCommandReceivedEventArgs(DisplayModeCommand command)
+        {
+            Command = command ?? throw new ArgumentNullException(nameof(command));
+        }
+
+        /// <summary>
+        /// Gets the <see cref="DisplayModeCommand"/>.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        public DisplayModeCommand Command { get; }
+    }
+}
\ No newline at end of file
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/DisplayModeUpdatedEventArgs.cs b/src/Tizen.Multimedia.Remoting/MediaController/DisplayModeUpdatedEventArgs.cs
new file mode 100644 (file)
index 0000000..83daca9
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2019 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.DisplayModeUpdated"/> event.
+    /// </summary>
+    /// <since_tizen> 6 </since_tizen>
+    public class DisplayModeUpdatedEventArgs : EventArgs
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="DisplayModeUpdatedEventArgs"/> class.
+        /// </summary>
+        /// <param name="mode">A value indicating the updated display mode.</param>
+        /// <since_tizen> 6 </since_tizen>
+        internal DisplayModeUpdatedEventArgs(MediaControlDisplayMode mode)
+        {
+            DisplayMode = mode;
+        }
+
+        /// <summary>
+        /// Gets the updated display mode.
+        /// </summary>
+        /// <value>The <see cref="MediaControlDisplayMode"/>.</value>
+        /// <since_tizen> 6 </since_tizen>
+        public MediaControlDisplayMode DisplayMode { get; }
+    }
+}
\ No newline at end of file
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/DisplayRotationCapabilityUpdatedEventArgs.cs b/src/Tizen.Multimedia.Remoting/MediaController/DisplayRotationCapabilityUpdatedEventArgs.cs
new file mode 100644 (file)
index 0000000..0daf0d1
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2019 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 System.Collections.ObjectModel;
+
+namespace Tizen.Multimedia.Remoting
+{
+    /// <summary>
+    /// Provides data for the <see cref="MediaController.DisplayRotationCapabilityUpdated"/> event.
+    /// </summary>
+    /// <since_tizen> 6 </since_tizen>
+    public class DisplayRotationCapabilityUpdatedEventArgs : EventArgs
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="DisplayRotationCapabilityUpdatedEventArgs"/> class.
+        /// </summary>
+        /// <param name="rotation">The list of supported display rotation capabilities.</param>
+        /// <since_tizen> 6 </since_tizen>
+        internal DisplayRotationCapabilityUpdatedEventArgs(IList<Rotation> rotation)
+        {
+            DisplayRotation = new ReadOnlyCollection<Rotation>(rotation);
+        }
+
+        /// <summary>
+        /// Gets the supported list of display rotation capabilities.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        public ReadOnlyCollection<Rotation> DisplayRotation { get; }
+    }
+}
\ No newline at end of file
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/DisplayRotationCommandReceivedEventArgs.cs b/src/Tizen.Multimedia.Remoting/MediaController/DisplayRotationCommandReceivedEventArgs.cs
new file mode 100644 (file)
index 0000000..3543289
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2019 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.DisplayRotationCommandReceived"/> event.
+    /// </summary>
+    /// <since_tizen> 6 </since_tizen>
+    public class DisplayRotationCommandReceivedEventArgs : EventArgs
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="DisplayRotationCommandReceivedEventArgs"/> class.
+        /// </summary>
+        /// <param name="command">The display rotation command.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="command"/> is null.</exception>
+        /// <since_tizen> 6 </since_tizen>
+        internal DisplayRotationCommandReceivedEventArgs(DisplayRotationCommand command)
+        {
+            Command = command ?? throw new ArgumentNullException(nameof(command));
+        }
+
+        /// <summary>
+        /// Gets the <see cref="DisplayRotationCommand"/>.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        public DisplayRotationCommand Command { get; }
+    }
+}
\ No newline at end of file
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/DisplayRotationUpdatedEventArgs.cs b/src/Tizen.Multimedia.Remoting/MediaController/DisplayRotationUpdatedEventArgs.cs
new file mode 100644 (file)
index 0000000..0e94c5b
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2019 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.DisplayRotationUpdated"/> event.
+    /// </summary>
+    /// <since_tizen> 6 </since_tizen>
+    public class DisplayRotationUpdatedEventArgs : EventArgs
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="DisplayRotationUpdatedEventArgs"/> class.
+        /// </summary>
+        /// <param name="rotation">A value indicating the updated display rotation.</param>
+        /// <since_tizen> 6 </since_tizen>
+        internal DisplayRotationUpdatedEventArgs(Rotation rotation)
+        {
+            Rotation = rotation;
+        }
+
+        /// <summary>
+        /// Gets the updated display rotation.
+        /// </summary>
+        /// <value>The <see cref="Rotation"/>.</value>
+        /// <since_tizen> 6 </since_tizen>
+        public Rotation Rotation { get; }
+    }
+}
\ No newline at end of file
index 9b3d0ad..df5aa6b 100644 (file)
@@ -13,6 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+using System;
 
 namespace Tizen.Multimedia.Remoting
 {
@@ -82,7 +83,7 @@ namespace Tizen.Multimedia.Remoting
         Resolution
     }
 
-    internal enum MediaControlCapabilityCategory
+    internal enum MediaControlNativeCapabilityCategory
     {
         Shuffle,
         Repeat,
@@ -93,4 +94,24 @@ namespace Tizen.Multimedia.Remoting
         Subtitle,
         Mode360
     }
+
+    [Flags]
+    internal enum MediaControlNativeDisplayMode
+    {
+        LetterBox = 1,
+        OriginSize = 2,
+        FullScreen = 4,
+        CroppedFull = 8,
+        All = LetterBox | OriginSize | FullScreen | CroppedFull
+    }
+
+    [Flags]
+    internal enum MediaControlNativeDisplayRotation
+    {
+        Rotate0 = 1,
+        Rotate90 = 2,
+        Rotate180 = 4,
+        Rotate270 = 8,
+        All = Rotate0 | Rotate90 | Rotate180 | Rotate270
+    }
 }
\ No newline at end of file
index 82730a3..1f0e07b 100644 (file)
@@ -357,6 +357,136 @@ namespace Tizen.Multimedia.Remoting
     }
 
     /// <summary>
+    /// Provides a means to to send subtitle mode command.
+    /// </summary>
+    /// <since_tizen> 6 </since_tizen>
+    public sealed class SubtitleModeCommand : Command
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="SubtitleModeCommand"/> class.
+        /// </summary>
+        /// <param name="isEnabled">A value indicating whether subtitle mode is enabled.</param>
+        /// <since_tizen> 6 </since_tizen>
+        public SubtitleModeCommand(bool isEnabled)
+        {
+            IsEnabled = isEnabled;
+        }
+
+        /// <summary>
+        /// Gets a value indicating whether subtitle mode is enabled or not.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        public bool IsEnabled { get; }
+
+        internal override string Request(NativeClientHandle clientHandle)
+        {
+            NativeClient.SendSubtitleModeCommand(clientHandle, ReceiverId, IsEnabled, out string requestId).
+                ThrowIfError("Failed to send subtitle mode command.");
+
+            return requestId;
+        }
+    }
+
+    /// <summary>
+    /// Provides a means to to send 360 mode command.
+    /// </summary>
+    /// <since_tizen> 6 </since_tizen>
+    public sealed class Mode360Command : Command
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="Mode360Command"/> class.
+        /// </summary>
+        /// <param name="isEnabled">A value indicating whether 360 mode is enabled or not.</param>
+        /// <since_tizen> 6 </since_tizen>
+        public Mode360Command(bool isEnabled)
+        {
+            IsEnabled = isEnabled;
+        }
+
+        /// <summary>
+        /// Gets a value indicating whether 360 mode is enabled or not.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        public bool IsEnabled { get; }
+
+        internal override string Request(NativeClientHandle clientHandle)
+        {
+            NativeClient.SendMode360Command(clientHandle, ReceiverId, IsEnabled, out string requestId).
+                ThrowIfError("Failed to send 360 mode command.");
+
+            return requestId;
+        }
+    }
+
+    /// <summary>
+    /// Provides a means to to send display mode command.
+    /// </summary>
+    /// <since_tizen> 6 </since_tizen>
+    public sealed class DisplayModeCommand : Command
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="DisplayModeCommand"/> class.
+        /// </summary>
+        /// <param name="mode">The <see cref="MediaControlDisplayMode"/>.</param>
+        /// <exception cref="ArgumentException"><paramref name="mode"/> is not valid.</exception>
+        /// <since_tizen> 6 </since_tizen>
+        public DisplayModeCommand(MediaControlDisplayMode mode)
+        {
+            ValidationUtil.ValidateEnum(typeof(MediaControlDisplayMode), mode, nameof(mode));
+
+            Mode = mode;
+        }
+
+        /// <summary>
+        /// Gets the display mode.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        public MediaControlDisplayMode Mode { get; }
+
+        internal override string Request(NativeClientHandle clientHandle)
+        {
+            NativeClient.SendDisplayModeCommand(clientHandle, ReceiverId, Mode.ToNative(), out string requestId).
+                ThrowIfError("Failed to send display mode command.");
+
+            return requestId;
+        }
+    }
+
+    /// <summary>
+    /// Provides a means to to send display rotation command.
+    /// </summary>
+    /// <since_tizen> 6 </since_tizen>
+    public sealed class DisplayRotationCommand : Command
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="DisplayRotationCommand"/> class.
+        /// </summary>
+        /// <param name="rotation">The <see cref="Rotation"/>.</param>
+        /// <exception cref="ArgumentException"><paramref name="rotation"/> is not valid.</exception>
+        /// <since_tizen> 6 </since_tizen>
+        public DisplayRotationCommand(Rotation rotation)
+        {
+            ValidationUtil.ValidateEnum(typeof(Rotation), rotation, nameof(rotation));
+
+            Rotation = rotation;
+        }
+
+        /// <summary>
+        /// Gets the display rotation.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        public Rotation Rotation { get; }
+
+        internal override string Request(NativeClientHandle clientHandle)
+        {
+            NativeClient.SendDisplayRotationCommand(clientHandle, ReceiverId, Rotation.ToNative(), out string requestId).
+                ThrowIfError("Failed to send display rotation command.");
+
+            return requestId;
+        }
+    }
+
+    /// <summary>
     /// Provides a means to to send custom commands.
     /// </summary>
     /// <remarks>This command can be used by both client and server to send predefined command or data.</remarks>
index 7a3bd62..1d84f55 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 using System;
+using System.Collections.Generic;
 using System.Diagnostics;
 
 namespace Tizen.Multimedia.Remoting
@@ -248,6 +249,33 @@ namespace Tizen.Multimedia.Remoting
         Tpo
     }
 
+    /// <summary>
+    /// Specifies the display mode.
+    /// </summary>
+    /// <since_tizen> 6 </since_tizen>
+    public enum MediaControlDisplayMode
+    {
+        /// <summary>
+        /// Letter box
+        /// </summary>
+        LetterBox,
+
+        /// <summary>
+        /// Original size
+        /// </summary>
+        OriginSize,
+
+        /// <summary>
+        /// Full screen
+        /// </summary>
+        FullScreen,
+
+        /// <summary>
+        /// Cropped full screen
+        /// </summary>
+        CroppedFull
+    }
+
     internal static class EnumExtensions
     {
         internal static MediaControlPlaybackState ToPublic(this MediaControllerNativePlaybackState nativeState)
@@ -336,5 +364,125 @@ namespace Tizen.Multimedia.Remoting
             return mode == MediaControlRepeatMode.Off ? MediaControllerNativeRepeatMode.On :
                 (mode == MediaControlRepeatMode.On ? MediaControllerNativeRepeatMode.Off : MediaControllerNativeRepeatMode.OneMedia);
         }
+
+        internal static MediaControlNativeDisplayMode ToNative(this MediaControlDisplayMode mode)
+        {
+            Debug.Assert(Enum.IsDefined(typeof(MediaControlDisplayMode), mode));
+
+            MediaControlNativeDisplayMode nativeMode = MediaControlNativeDisplayMode.LetterBox;
+            switch (mode)
+            {
+                case MediaControlDisplayMode.LetterBox:
+                    nativeMode = MediaControlNativeDisplayMode.LetterBox;
+                    break;
+                case MediaControlDisplayMode.OriginSize:
+                    nativeMode = MediaControlNativeDisplayMode.OriginSize;
+                    break;
+                case MediaControlDisplayMode.FullScreen:
+                    nativeMode = MediaControlNativeDisplayMode.FullScreen;
+                    break;
+                case MediaControlDisplayMode.CroppedFull:
+                    nativeMode = MediaControlNativeDisplayMode.CroppedFull;
+                    break;
+            }
+            return nativeMode;
+        }
+
+        internal static MediaControlDisplayMode ToPublic(this MediaControlNativeDisplayMode mode)
+        {
+            Debug.Assert(Enum.IsDefined(typeof(MediaControlNativeDisplayMode), mode));
+            MediaControlDisplayMode nativeMode = MediaControlDisplayMode.LetterBox;
+            switch (mode)
+            {
+                case MediaControlNativeDisplayMode.LetterBox:
+                    nativeMode = MediaControlDisplayMode.LetterBox;
+                    break;
+                case MediaControlNativeDisplayMode.OriginSize:
+                    nativeMode = MediaControlDisplayMode.OriginSize;
+                    break;
+                case MediaControlNativeDisplayMode.FullScreen:
+                    nativeMode = MediaControlDisplayMode.FullScreen;
+                    break;
+                case MediaControlNativeDisplayMode.CroppedFull:
+                    nativeMode = MediaControlDisplayMode.CroppedFull;
+                    break;
+            }
+            return nativeMode;
+        }
+
+        internal static IList<MediaControlDisplayMode> ToPublicList(this MediaControlNativeDisplayMode modes)
+        {
+            var supportedModes = new List<MediaControlDisplayMode>();
+
+            foreach (MediaControlNativeDisplayMode mode in Enum.GetValues(typeof(MediaControlNativeDisplayMode)))
+            {
+                if (modes.HasFlag(mode))
+                {
+                    supportedModes.Add(mode.ToPublic());
+                }
+            }
+
+            return supportedModes.AsReadOnly();
+        }
+
+        internal static MediaControlNativeDisplayRotation ToNative(this Rotation mode)
+        {
+            Debug.Assert(Enum.IsDefined(typeof(Rotation), mode));
+
+            MediaControlNativeDisplayRotation nativeMode = MediaControlNativeDisplayRotation.Rotate0;
+            switch (mode)
+            {
+                case Rotation.Rotate0:
+                    nativeMode = MediaControlNativeDisplayRotation.Rotate0;
+                    break;
+                case Rotation.Rotate90:
+                    nativeMode = MediaControlNativeDisplayRotation.Rotate90;
+                    break;
+                case Rotation.Rotate180:
+                    nativeMode = MediaControlNativeDisplayRotation.Rotate180;
+                    break;
+                case Rotation.Rotate270:
+                    nativeMode = MediaControlNativeDisplayRotation.Rotate270;
+                    break;
+            }
+            return nativeMode;
+        }
+
+        internal static Rotation ToPublic(this MediaControlNativeDisplayRotation mode)
+        {
+            Debug.Assert(Enum.IsDefined(typeof(MediaControlNativeDisplayRotation), mode));
+            Rotation nativeMode = Rotation.Rotate0;
+            switch (mode)
+            {
+                case MediaControlNativeDisplayRotation.Rotate0:
+                    nativeMode = Rotation.Rotate0;
+                    break;
+                case MediaControlNativeDisplayRotation.Rotate90:
+                    nativeMode = Rotation.Rotate90;
+                    break;
+                case MediaControlNativeDisplayRotation.Rotate180:
+                    nativeMode = Rotation.Rotate180;
+                    break;
+                case MediaControlNativeDisplayRotation.Rotate270:
+                    nativeMode = Rotation.Rotate270;
+                    break;
+            }
+            return nativeMode;
+        }
+
+        internal static IList<Rotation> ToPublicList(this MediaControlNativeDisplayRotation modes)
+        {
+            var supportedRotations = new List<Rotation>();
+
+            foreach (MediaControlNativeDisplayRotation mode in Enum.GetValues(typeof(MediaControlNativeDisplayRotation)))
+            {
+                if (modes.HasFlag(mode))
+                {
+                    supportedRotations.Add(mode.ToPublic());
+                }
+            }
+
+            return supportedRotations.AsReadOnly();
+        }
     }
 }
\ No newline at end of file
index 4a52e82..45d218b 100644 (file)
@@ -245,7 +245,7 @@ namespace Tizen.Multimedia.Remoting
         }
 
         /// <summary>
-        /// Update the playlist by lastest info.
+        /// Update the playlist by latest info.
         /// </summary>
         /// <since_tizen> 5 </since_tizen>
         public void Update()
index 3320b7d..466fc1c 100644 (file)
@@ -29,10 +29,16 @@ namespace Tizen.Multimedia.Remoting
         private static Native.PlaylistCommandReceivedCallback _playlistCommandCallback;
         private static Native.ShuffleModeCommandReceivedCallback _shuffleModeCommandCallback;
         private static Native.RepeatModeCommandReceivedCallback _repeatModeCommandCallback;
+        private static Native.SimpleCommandReceivedCallback _subtitleModeCommandCallback;
+        private static Native.SimpleCommandReceivedCallback _mode360CommandCallback;
+        private static Native.DisplayModeCommandReceivedCallback _displayModeCommandCallback;
+        private static Native.DisplayRotationCommandReceivedCallback _displayRotationCommandCallback;
+
         private static Native.CustomCommandReceivedCallback _customCommandCallback;
         private static Native.SearchCommandReceivedCallback _searchCommandCallback;
         private static Native.CommandCompletedCallback _commandCompletedCallback;
 
+
         /// <summary>
         /// Occurs when a client sends playback command.
         /// </summary>
@@ -71,6 +77,30 @@ namespace Tizen.Multimedia.Remoting
         public static event EventHandler<RepeatModeCommandReceivedEventArgs> RepeatModeCommandReceived;
 
         /// <summary>
+        /// Occurs when a client sends subtitle mode command.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        public static event EventHandler<SubtitleModeCommandReceivedEventArgs> SubtitleModeCommandReceived;
+
+        /// <summary>
+        /// Occurs when a client sends mode 360 command.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        public static event EventHandler<Mode360CommandReceivedEventArgs> Mode360CommandReceived;
+
+        /// <summary>
+        /// Occurs when a client sends display mode command.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        public static event EventHandler<DisplayModeCommandReceivedEventArgs> DisplayModeCommandReceived;
+
+        /// <summary>
+        /// Occurs when a client sends display rotation command.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        public static event EventHandler<DisplayRotationCommandReceivedEventArgs> DisplayRotationCommandReceived;
+
+        /// <summary>
         /// Occurs when a client sends custom command.
         /// </summary>
         /// <since_tizen> 5 </since_tizen>
@@ -163,6 +193,58 @@ namespace Tizen.Multimedia.Remoting
                 ThrowIfError("Failed to init RepeatModeCommandReceived event.");
         }
 
+        private static void RegisterSubtitleModeCommandReceivedEvent()
+        {
+            _subtitleModeCommandCallback = (clientName, requestId, isEnabled, _) =>
+            {
+                var command = new SubtitleModeCommand(isEnabled);
+                command.SetResponseInformation(clientName, requestId);
+
+                SubtitleModeCommandReceived?.Invoke(null, new SubtitleModeCommandReceivedEventArgs(command));
+            };
+            Native.SetSubtitleModeCommandReceivedCb(Handle, _subtitleModeCommandCallback).
+                ThrowIfError("Failed to init SubtitleModeCommandReceived event.");
+        }
+
+        private static void RegisterMode360CommandReceivedEvent()
+        {
+            _mode360CommandCallback = (clientName, requestId, isEnabled, _) =>
+            {
+                var command = new Mode360Command(isEnabled);
+                command.SetResponseInformation(clientName, requestId);
+
+                Mode360CommandReceived?.Invoke(null, new Mode360CommandReceivedEventArgs(command));
+            };
+            Native.SetMode360CommandReceivedCb(Handle, _mode360CommandCallback).
+                ThrowIfError("Failed to init Mode360CommandReceived event.");
+        }
+
+        private static void RegisterDisplayModeCommandReceivedEvent()
+        {
+            _displayModeCommandCallback = (clientName, requestId, mode, _) =>
+            {
+                var command = new DisplayModeCommand(mode.ToPublic());
+                command.SetResponseInformation(clientName, requestId);
+
+                DisplayModeCommandReceived?.Invoke(null, new DisplayModeCommandReceivedEventArgs(command));
+            };
+            Native.SetDisplayModeCommandReceivedCb(Handle, _displayModeCommandCallback).
+                ThrowIfError("Failed to init DisplayModeCommandReceived event.");
+        }
+
+        private static void RegisterDisplayRotationCommandReceivedEvent()
+        {
+            _displayRotationCommandCallback = (clientName, requestId, rotation, _) =>
+            {
+                var command = new DisplayRotationCommand(rotation.ToPublic());
+                command.SetResponseInformation(clientName, requestId);
+
+                DisplayRotationCommandReceived?.Invoke(null, new DisplayRotationCommandReceivedEventArgs(command));
+            };
+            Native.SetDisplayRotationCommandReceivedCb(Handle, _displayRotationCommandCallback).
+                ThrowIfError("Failed to init DisplayRotationCommandReceived event.");
+        }
+
         private static void RegisterCustomCommandReceivedEvent()
         {
             _customCommandCallback = (clientName, requestId, customCommand, bundleHandle, _) =>
index 907ef03..4b788b8 100644 (file)
@@ -112,6 +112,10 @@ namespace Tizen.Multimedia.Remoting
                 RegisterPlaylistCommandReceivedEvent();
                 RegisterShuffleModeCommandReceivedEvent();
                 RegisterRepeatModeCommandReceivedEvent();
+                RegisterSubtitleModeCommandReceivedEvent();
+                RegisterMode360CommandReceivedEvent();
+                RegisterDisplayModeCommandReceivedEvent();
+                RegisterDisplayRotationCommandReceivedEvent();
                 RegisterCustomCommandReceivedEvent();
                 RegisterCommandCompletedEvent();
                 RegisterSearchCommandReceivedEvent();
@@ -170,6 +174,34 @@ namespace Tizen.Multimedia.Remoting
         }
 
         /// <summary>
+        /// Gets the active clients.
+        /// </summary>
+        /// <exception cref="InvalidOperationException">
+        ///     The server is not running .<br/>
+        ///     -or-<br/>
+        ///     An internal error occurs.
+        /// </exception>
+        /// <returns>the activated client ids.</returns>
+        /// <since_tizen> 5 </since_tizen>
+        public static IEnumerable<string> GetActivatedClients()
+        {
+            var clientIds = new List<string>();
+
+            Native.ActivatedClientCallback activatedClientCallback = (name, _) =>
+            {
+                clientIds.Add(name);
+                return true;
+            };
+
+            Native.ForeachActivatedClient(Handle, activatedClientCallback).
+                ThrowIfError("Failed to get activated client.");
+
+            return clientIds.AsReadOnly();
+        }
+
+
+        #region Set information
+        /// <summary>
         /// Updates playback state and playback position.</summary>
         /// <param name="state">The playback state.</param>
         /// <param name="position">The playback position in milliseconds.</param>
@@ -276,31 +308,6 @@ namespace Tizen.Multimedia.Remoting
         }
 
         /// <summary>
-        /// Sets the index of current playing media.
-        /// </summary>
-        /// <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>
-        [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>
@@ -332,175 +339,160 @@ namespace Tizen.Multimedia.Remoting
         }
 
         /// <summary>
-        /// Delete playlist.
+        /// Sets the age rating of latest played media.
         /// </summary>
-        /// <param name="playlist">The name of playlist.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="playlist"/> is null.</exception>
+        /// <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 RemovePlaylist(MediaControlPlaylist playlist)
+        public static void SetAgeRating(int ageRating)
         {
-            if (playlist == null)
+            if (ageRating < 0 || ageRating > 19)
             {
-                throw new ArgumentNullException(nameof(playlist));
+                throw new ArgumentOutOfRangeException(nameof(ageRating));
             }
 
-            Native.DeletePlaylist(Handle, playlist.Handle);
-            playlist.Dispose();
+            Native.SetAgeRating(Handle, ageRating).ThrowIfError("Failed to set age rating.");
+
+            Native.UpdatePlayback(Handle).ThrowIfError("Failed to set playback.");
         }
 
-        // Saves the playlist to the persistent storage.
-        internal static void SavePlaylist(IntPtr playlistHandle)
+        /// <summary>
+        /// Sets the subtitle mode.
+        /// </summary>
+        /// <param name="isEnabled">A value indicating whether the subtitle mode is enabled.</param>
+        /// <exception cref="InvalidOperationException">
+        ///     The server is not running .<br/>
+        ///     -or-<br/>
+        ///     An internal error occurs.
+        /// </exception>
+        /// <since_tizen> 6 </since_tizen>
+        public static void SetSubtitleMode(bool isEnabled)
         {
-            Native.SavePlaylist(Handle, playlistHandle).ThrowIfError("Failed to save playlist");
+            Native.UpdateSubtitleMode(Handle, isEnabled).ThrowIfError("Failed to set subtitle mode.");
         }
 
-        // Gets the playlist handle by name.
-        internal static IntPtr GetPlaylistHandle(string name)
+        /// <summary>
+        /// Sets the 360 mode.
+        /// </summary>
+        /// <param name="isEnabled">A value indicating whether the 360 mode is enabled.</param>
+        /// <exception cref="InvalidOperationException">
+        ///     The server is not running .<br/>
+        ///     -or-<br/>
+        ///     An internal error occurs.
+        /// </exception>
+        /// <since_tizen> 6 </since_tizen>
+        public static void SetMode360(bool isEnabled)
         {
-            NativePlaylist.GetPlaylistHandle(_serverName, name, out IntPtr playlistHandle).
-                ThrowIfError("Failed to get playlist handle by name");
-
-            return playlistHandle;
+            Native.UpdateMode360(Handle, isEnabled).ThrowIfError("Failed to set 360 mode.");
         }
 
         /// <summary>
-        /// Gets the active clients.
+        /// Sets the display mode.
         /// </summary>
+        /// <param name="mode">A value indicating the <see cref="MediaControlDisplayMode"/>.</param>
         /// <exception cref="InvalidOperationException">
         ///     The server is not running .<br/>
         ///     -or-<br/>
         ///     An internal error occurs.
         /// </exception>
-        /// <returns>the activated client ids.</returns>
-        /// <since_tizen> 5 </since_tizen>
-        public static IEnumerable<string> GetActivatedClients()
+        /// <since_tizen> 6 </since_tizen>
+        public static void SetDisplayMode(MediaControlDisplayMode mode)
         {
-            var clientIds = new List<string>();
-
-            Native.ActivatedClientCallback activatedClientCallback = (name, _) =>
-            {
-                clientIds.Add(name);
-                return true;
-            };
-
-            Native.ForeachActivatedClient(Handle, activatedClientCallback).
-                ThrowIfError("Failed to get activated client.");
-
-            return clientIds.AsReadOnly();
+            Native.UpdateDisplayMode(Handle, mode.ToNative()).ThrowIfError("Failed to set display mode.");
         }
 
         /// <summary>
-        /// Requests commands to the client.
+        /// Sets the display rotation.
         /// </summary>
-        /// <remarks>
-        /// The client can request the command to execute <see cref="Command"/>, <br/>
-        /// and then, the server receive the result of each request(command).
-        /// </remarks>
-        /// <param name="command">A <see cref="Command"/> class.</param>
-        /// <param name="clientId">The client Id to send command.</param>
-        /// <returns><see cref="Bundle"/> represents the extra data from client and it can be null.</returns>
-        /// <exception cref="ArgumentNullException">
-        /// <paramref name="command"/> or <paramref name="clientId"/> is null.
-        /// </exception>
+        /// <param name="rotation">A value indicating the <see cref="Rotation"/>.</param>
         /// <exception cref="InvalidOperationException">
-        ///     The server has already been stopped.<br/>
+        ///     The server is not running .<br/>
         ///     -or-<br/>
         ///     An internal error occurs.
         /// </exception>
-        /// <since_tizen> 5 </since_tizen>
-        public static async Task<Bundle> RequestAsync(Command command, string clientId)
+        /// <since_tizen> 6 </since_tizen>
+        public static void SetDisplayRotation(Rotation rotation)
         {
-            if (command == null)
-            {
-                throw new ArgumentNullException(nameof(command));
-            }
-            if (clientId == null)
-            {
-                throw new ArgumentNullException(nameof(clientId));
-            }
-
-            command.SetRequestInformation(clientId);
-
-            var tcs = new TaskCompletionSource<MediaControllerError>();
-            string reqeustId = null;
-            Bundle bundle = null;
-
-            EventHandler<CommandCompletedEventArgs> eventHandler = (s, e) =>
-            {
-                if (e.RequestId == reqeustId)
-                {
-                    bundle = e.Bundle;
-                    tcs.TrySetResult(e.Result);
-                }
-            };
-
-            try
-            {
-                CommandCompleted += eventHandler;
-
-                reqeustId = command.Request(Handle);
-
-                (await tcs.Task).ThrowIfError("Failed to request event.");
-
-                return bundle;
-            }
-            finally
-            {
-                CommandCompleted -= eventHandler;
-            }
+            Native.UpdateDisplayRotaton(Handle, rotation.ToNative()).ThrowIfError("Failed to set display rotation.");
         }
 
         /// <summary>
-        /// Sends the result of each command.
+        /// Sets the index of current playing media.
         /// </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="ArgumentNullException"><paramref name="command"/> is null.</exception>
+        /// <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 Response(Command command, int result, Bundle bundle)
+        [Obsolete("Please do not use! This will be deprecated. Please use SetInfoOfCurrentPlayingMedia instead.")]
+        public static void SetIndexOfCurrentPlayingMedia(string index)
         {
-            if (command == null)
+            if (index == null)
             {
-                throw new ArgumentNullException(nameof(command));
+                throw new ArgumentNullException(nameof(index));
             }
 
-            command.Response(Handle, result, bundle);
+            Native.SetIndexOfCurrentPlayingMedia(Handle, index)
+                .ThrowIfError("Failed to set the index of current playing media");
+
+            Native.UpdatePlayback(Handle).ThrowIfError("Failed to set playback.");
         }
+        #endregion Set information
+
 
+        #region Playlist
         /// <summary>
-        /// Sends the result of each command.
+        /// Delete playlist.
         /// </summary>
-        /// <param name="command">The command that return to client.</param>
-        /// <param name="result">The result of <paramref name="command"/>.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="command"/> is null.</exception>
+        /// <remarks>Currently, only server can remove the playlist.</remarks>
+        /// <param name="playlist">The name of playlist.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="playlist"/> 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 Response(Command command, int result)
+        public static void RemovePlaylist(MediaControlPlaylist playlist)
         {
-            if (command == null)
+            if (playlist == null)
             {
-                throw new ArgumentNullException(nameof(command));
+                throw new ArgumentNullException(nameof(playlist));
             }
 
-            command.Response(Handle, result, null);
+            Native.DeletePlaylist(Handle, playlist.Handle);
+            playlist.Dispose();
+        }
+
+        // Saves the playlist to the persistent storage.
+        internal static void SavePlaylist(IntPtr playlistHandle)
+        {
+            Native.SavePlaylist(Handle, playlistHandle).ThrowIfError("Failed to save playlist");
         }
 
-        #region Capabilities
+        // Gets the playlist handle by name.
+        internal static IntPtr GetPlaylistHandle(string name)
+        {
+            NativePlaylist.GetPlaylistHandle(_serverName, name, out IntPtr playlistHandle).
+                ThrowIfError("Failed to get playlist handle by name");
+
+            return playlistHandle;
+        }
+        #endregion Playlist
+
+
+        #region Capability
         /// <summary>
         /// Sets the content type of latest played media.
         /// </summary>
@@ -605,12 +597,12 @@ namespace Tizen.Multimedia.Remoting
         {
             ValidationUtil.ValidateEnum(typeof(MediaControlCapabilitySupport), support, nameof(support));
 
-            Native.SetSimpleCapability(Handle, MediaControlCapabilityCategory.Shuffle, support).
+            Native.SetSimpleCapability(Handle, MediaControlNativeCapabilityCategory.Shuffle, support).
                 ThrowIfError("Failed to set shuffle mode capability.");
         }
 
         /// <summary>
-        /// Sets the content type of latest played media.
+        /// Sets the <see cref="MediaControlCapabilitySupport"/> indicating repeat mode is supported or not.
         /// </summary>
         /// <param name="support">A value indicating whether the <see cref="MediaControlRepeatMode"/> is supported or not.</param>
         /// <exception cref="InvalidOperationException">
@@ -624,35 +616,224 @@ namespace Tizen.Multimedia.Remoting
         {
             ValidationUtil.ValidateEnum(typeof(MediaControlCapabilitySupport), support, nameof(support));
 
-            Native.SetSimpleCapability(Handle, MediaControlCapabilityCategory.Repeat, support).
+            Native.SetSimpleCapability(Handle, MediaControlNativeCapabilityCategory.Repeat, support).
                 ThrowIfError("Failed to set repeat mode capability.");
         }
-        #endregion Capabilities
 
         /// <summary>
-        /// Sets the age rating of latest played media.
+        /// Sets the supported list of <see cref="MediaControlDisplayMode"/>.
         /// </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>
+        /// <remarks>
+        /// <see cref="MediaControlCapabilitySupport.NotDecided"/> is not allowed in display mode capability.
+        /// The default value of each <see cref="MediaControlDisplayMode"/> is not supported.
+        /// </remarks>
+        /// <param name="capabilities">The supported list of <see cref="MediaControlDisplayMode"/>.</param>
+        /// <exception cref="InvalidOperationException">
+        ///     The server is not running .<br/>
+        ///     -or-<br/>
+        ///     An internal error occurs.
+        /// </exception>
+        /// <exception cref="ArgumentException"><paramref name="capabilities"/> is invalid.</exception>
+        /// <since_tizen> 6 </since_tizen>
+        public static void SetDisplayModeCapabilities(IDictionary<MediaControlDisplayMode, MediaControlCapabilitySupport> capabilities)
+        {
+            foreach (var pair in capabilities)
+            {
+                SetDisplayModeCapability(pair.Key, pair.Value);
+            }
+        }
+
+        /// <summary>
+        /// Sets the <paramref name="mode"/> is supported or not.
+        /// </summary>
+        /// <remarks>
+        /// <see cref="MediaControlCapabilitySupport.NotDecided"/> is not allowed in display mode capability.<br/>
+        /// The default value of each <see cref="MediaControlDisplayMode"/> is not supported.
+        /// </remarks>
+        /// <param name="mode">The <see cref="MediaControlDisplayMode"/>.</param>
+        /// <param name="support">A value indicating whether the <paramref name="mode"/> is supported or not.</param>
         /// <exception cref="InvalidOperationException">
         ///     The server is not running .<br/>
         ///     -or-<br/>
         ///     An internal error occurs.
         /// </exception>
+        /// <exception cref="ArgumentException"><paramref name="mode"/> or <paramref name="support"/> is invalid.</exception>
+        /// <since_tizen> 6 </since_tizen>
+        public static void SetDisplayModeCapability(MediaControlDisplayMode mode, MediaControlCapabilitySupport support)
+        {
+            ValidationUtil.ValidateEnum(typeof(MediaControlDisplayMode), mode, nameof(mode));
+            ValidationUtil.ValidateEnum(typeof(MediaControlCapabilitySupport), support, nameof(support));
+
+            if (support == MediaControlCapabilitySupport.NotDecided)
+            {
+                throw new ArgumentException($"NotDecided is not allowed in {mode} capability.");
+            }
+
+            Native.SetDisplayModeCapability(Handle, (uint)mode.ToNative(), support).
+                ThrowIfError("Failed to set display mode capability.");
+        }
+
+        /// <summary>
+        /// Sets the supported list of <see cref="Rotation"/>.
+        /// </summary>
+        /// <remarks>
+        /// <see cref="MediaControlCapabilitySupport.NotDecided"/> is not allowed in display rotation capability.<br/>
+        /// The default value of each <see cref="Rotation"/> is not supported.
+        /// </remarks>
+        /// <param name="capabilities">The supported list of <see cref="Rotation"/>.</param>
+        /// <exception cref="InvalidOperationException">
+        ///     The server is not running .<br/>
+        ///     -or-<br/>
+        ///     An internal error occurs.
+        /// </exception>
+        /// <exception cref="ArgumentException"><paramref name="capabilities"/> is invalid.</exception>
+        /// <since_tizen> 6 </since_tizen>
+        public static void SetDisplayRotationCapabilities(IDictionary<Rotation, MediaControlCapabilitySupport> capabilities)
+        {
+            foreach (var pair in capabilities)
+            {
+                SetDisplayRotationCapability(pair.Key, pair.Value);
+            }
+        }
+
+        /// <summary>
+        /// Sets the <paramref name="rotation"/> is supported or not.
+        /// </summary>
+        /// <remarks>
+        /// <see cref="MediaControlCapabilitySupport.NotDecided"/> is not allowed in display rotation capability.<br/>
+        /// The default value of each <see cref="Rotation"/> is not supported.
+        /// </remarks>
+        /// <param name="rotation">The <see cref="Rotation"/>.</param>
+        /// <param name="support">A value indicating whether the <paramref name="rotation"/> is supported or not..</param>
+        /// <exception cref="InvalidOperationException">
+        ///     The server is not running .<br/>
+        ///     -or-<br/>
+        ///     An internal error occurs.
+        /// </exception>
+        /// <exception cref="ArgumentException"><paramref name="rotation"/> or <paramref name="support"/> is invalid.</exception>
+        /// <since_tizen> 6 </since_tizen>
+        public static void SetDisplayRotationCapability(Rotation rotation, MediaControlCapabilitySupport support)
+        {
+            ValidationUtil.ValidateEnum(typeof(Rotation), rotation, nameof(rotation));
+            ValidationUtil.ValidateEnum(typeof(MediaControlCapabilitySupport), support, nameof(support));
+
+            if (support == MediaControlCapabilitySupport.NotDecided)
+            {
+                throw new ArgumentException($"NotDecided is not allowed in {rotation} capability.");
+            }
+
+            Native.SetDisplayRotationCapability(Handle, (uint)rotation.ToNative(), support).
+                ThrowIfError("Failed to set display rotation capability.");
+        }
+        #endregion Capability
+
+
+        #region Command
+        /// <summary>
+        /// Requests commands to the client.
+        /// </summary>
+        /// <remarks>
+        /// The client can request the command to execute <see cref="Command"/>, <br/>
+        /// and then, the server receive the result of each request(command).
+        /// </remarks>
+        /// <param name="command">A <see cref="Command"/> class.</param>
+        /// <param name="clientId">The client Id to send command.</param>
+        /// <returns><see cref="Bundle"/> represents the extra data from client and it can be null.</returns>
+        /// <exception cref="ArgumentNullException">
+        /// <paramref name="command"/> or <paramref name="clientId"/> is null.
+        /// </exception>
+        /// <exception cref="InvalidOperationException">
+        ///     The server has already been stopped.<br/>
+        ///     -or-<br/>
+        ///     An internal error occurs.
+        /// </exception>
         /// <since_tizen> 5 </since_tizen>
-        public static void SetAgeRating(int ageRating)
+        public static async Task<Bundle> RequestAsync(Command command, string clientId)
         {
-            if (ageRating < 0 || ageRating > 19)
+            if (command == null)
             {
-                throw new ArgumentOutOfRangeException(nameof(ageRating));
+                throw new ArgumentNullException(nameof(command));
+            }
+            if (clientId == null)
+            {
+                throw new ArgumentNullException(nameof(clientId));
             }
 
-            Native.SetAgeRating(Handle, ageRating).ThrowIfError("Failed to set age rating.");
+            command.SetRequestInformation(clientId);
 
-            Native.UpdatePlayback(Handle).ThrowIfError("Failed to set playback.");
+            var tcs = new TaskCompletionSource<MediaControllerError>();
+            string reqeustId = null;
+            Bundle bundle = null;
+
+            EventHandler<CommandCompletedEventArgs> eventHandler = (s, e) =>
+            {
+                if (e.RequestId == reqeustId)
+                {
+                    bundle = e.Bundle;
+                    tcs.TrySetResult(e.Result);
+                }
+            };
+
+            try
+            {
+                CommandCompleted += eventHandler;
+
+                reqeustId = command.Request(Handle);
+
+                (await tcs.Task).ThrowIfError("Failed to request event.");
+
+                return bundle;
+            }
+            finally
+            {
+                CommandCompleted -= eventHandler;
+            }
+        }
+
+        /// <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="ArgumentNullException"><paramref name="command"/> 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 Response(Command command, int result, Bundle bundle)
+        {
+            if (command == null)
+            {
+                throw new ArgumentNullException(nameof(command));
+            }
+
+            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="ArgumentNullException"><paramref name="command"/> 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 Response(Command command, int result)
+        {
+            if (command == null)
+            {
+                throw new ArgumentNullException(nameof(command));
+            }
+
+            command.Response(Handle, result, null);
         }
+        #endregion Command
     }
 }
\ No newline at end of file
index 109818c..757bea0 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 using System;
+using System.Linq;
 using System.Collections.Generic;
 using Tizen.Applications;
 using Native = Interop.MediaControllerClient;
@@ -39,6 +40,7 @@ namespace Tizen.Multimedia.Remoting
             ServerStopped?.Invoke(this, EventArgs.Empty);
         }
 
+        #region Updated event
         /// <summary>
         /// Occurs when the playback state is updated.
         /// </summary>
@@ -80,6 +82,17 @@ namespace Tizen.Multimedia.Remoting
         }
 
         /// <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, IntPtr playlistHandle)
+        {
+            PlaylistUpdated?.Invoke(this, new PlaylistUpdatedEventArgs(mode, name, new MediaControlPlaylist(playlistHandle)));
+        }
+
+        /// <summary>
         /// Occurs when the metadata is updated.
         /// </summary>
         /// <since_tizen> 4 </since_tizen>
@@ -138,37 +151,48 @@ namespace Tizen.Multimedia.Remoting
         }
 
         /// <summary>
-        /// Occurs when the playlist is updated.
+        /// Occurs when the subtitle mode is updated.
         /// </summary>
-        /// <since_tizen> 5 </since_tizen>
-        public event EventHandler<PlaylistUpdatedEventArgs> PlaylistUpdated;
+        /// <since_tizen> 6 </since_tizen>
+        public event EventHandler<SubtitleModeUpdatedEventArgs> SubtitleModeUpdated;
+        internal void RaiseSubtitleModeUpdatedEvent(bool isEnabled)
+        {
+            SubtitleModeUpdated?.Invoke(this, new SubtitleModeUpdatedEventArgs(isEnabled));
+        }
 
-        internal void RaisePlaylistUpdatedEvent(MediaControlPlaylistMode mode, string name, IntPtr playlistHandle)
+        /// <summary>
+        /// Occurs when the 360 mode is updated.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        public event EventHandler<Mode360UpdatedEventArgs> Mode360Updated;
+        internal void RaiseMode360UpdatedEvent(bool isEnabled)
         {
-            PlaylistUpdated?.Invoke(this, new PlaylistUpdatedEventArgs(mode, name, new MediaControlPlaylist(playlistHandle)));
+            Mode360Updated?.Invoke(this, new Mode360UpdatedEventArgs(isEnabled));
         }
 
         /// <summary>
-        /// Occurs when the command is completed.
+        /// Occurs when the display mode is updated.
         /// </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;
+        /// <since_tizen> 6 </since_tizen>
+        public event EventHandler<DisplayModeUpdatedEventArgs> DisplayModeUpdated;
+        internal void RaiseDisplayModeUpdatedEvent(MediaControlNativeDisplayMode mode)
+        {
+            DisplayModeUpdated?.Invoke(this, new DisplayModeUpdatedEventArgs(mode.ToPublic()));
+        }
 
-        internal void RaiseCommandCompletedEvent(string requestId, MediaControllerError result, IntPtr bundleHandle)
+        /// <summary>
+        /// Occurs when the display rotation is updated.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        public event EventHandler<DisplayRotationUpdatedEventArgs> DisplayRotationUpdated;
+        internal void RaiseDisplayRotationUpdatedEvent(MediaControlNativeDisplayRotation rotation)
         {
-            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));
-            }
+            DisplayRotationUpdated?.Invoke(this, new DisplayRotationUpdatedEventArgs(rotation.ToPublic()));
         }
+        #endregion
+
 
+        #region Capability updated event
         /// <summary>
         /// Occurs when the playback capabilities are updated.
         /// </summary>
@@ -182,7 +206,7 @@ namespace Tizen.Multimedia.Remoting
             {
                 foreach (MediaControllerNativePlaybackAction action in Enum.GetValues(typeof(MediaControllerNativePlaybackAction)))
                 {
-                    Native.IsCapabilitySupported(playbackCapaHandle, action, out MediaControlCapabilitySupport support);
+                    Native.GetPlaybackCapability(playbackCapaHandle, action, out MediaControlCapabilitySupport support);
                     capabilities.Add(action.ToPublic(), support);
                 }
 
@@ -235,6 +259,52 @@ namespace Tizen.Multimedia.Remoting
         }
 
         /// <summary>
+        /// Occurs when the display mode capabilities are updated.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        public event EventHandler<DisplayModeCapabilityUpdatedEventArgs> DisplayModeCapabilityUpdated;
+
+        internal void RaiseDisplayModeCapabilityUpdatedEvent(MediaControlNativeDisplayMode modes)
+        {
+            DisplayModeCapabilityUpdated?.Invoke(this, new DisplayModeCapabilityUpdatedEventArgs(modes.ToPublicList()));
+        }
+
+        /// <summary>
+        /// Occurs when the display rotation capabilities are updated.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        public event EventHandler<DisplayRotationCapabilityUpdatedEventArgs> DisplayRotationCapabilityUpdated;
+
+        internal void RaiseDisplayRotationCapabilityUpdatedEvent(MediaControlNativeDisplayRotation rotations)
+        {
+            DisplayRotationCapabilityUpdated?.Invoke(this, new DisplayRotationCapabilityUpdatedEventArgs(rotations.ToPublicList()));
+        }
+        #endregion
+
+
+        #region Command
+        /// <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));
+            }
+        }
+
+        /// <summary>
         /// Occurs when a server sends custom event.
         /// </summary>
         /// <since_tizen> 5 </since_tizen>
@@ -244,5 +314,6 @@ namespace Tizen.Multimedia.Remoting
         {
             CustomCommandReceived?.Invoke(this, new CustomCommandReceivedEventArgs(command));
         }
+        #endregion
     }
 }
\ No newline at end of file
index cf4da2a..2f3e6d8 100644 (file)
@@ -68,6 +68,8 @@ namespace Tizen.Multimedia.Remoting
             }
         }
 
+
+        #region Get information
         /// <summary>
         /// Returns the playback state set by the server.
         /// </summary>
@@ -77,7 +79,7 @@ namespace Tizen.Multimedia.Remoting
         ///     -or-<br/>
         ///     An internal error occurs.
         /// </exception>
-        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed of.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed.</exception>
         /// <seealso cref="MediaControlServer.SetPlaybackState(MediaControlPlaybackState, long)"/>
         /// <since_tizen> 4 </since_tizen>
         public MediaControlPlaybackState GetPlaybackState()
@@ -88,7 +90,7 @@ namespace Tizen.Multimedia.Remoting
 
             try
             {
-                Native.GetServerPlayback(Manager.Handle, ServerAppId, out playbackHandle).ThrowIfError("Failed to get playback.");
+                Native.GetServerPlaybackHandle(Manager.Handle, ServerAppId, out playbackHandle).ThrowIfError("Failed to get playback.");
 
                 Native.GetPlaybackState(playbackHandle, out var playbackCode).ThrowIfError("Failed to get state.");
 
@@ -112,7 +114,7 @@ namespace Tizen.Multimedia.Remoting
         ///     -or-<br/>
         ///     An internal error occurs.
         /// </exception>
-        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed of.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed.</exception>
         /// <seealso cref="MediaControlServer.SetPlaybackState(MediaControlPlaybackState, long)"/>
         /// <since_tizen> 4 </since_tizen>
         public long GetPlaybackPosition()
@@ -123,7 +125,7 @@ namespace Tizen.Multimedia.Remoting
 
             try
             {
-                Native.GetServerPlayback(Manager.Handle, ServerAppId, out playbackHandle).ThrowIfError("Failed to get playback.");
+                Native.GetServerPlaybackHandle(Manager.Handle, ServerAppId, out playbackHandle).ThrowIfError("Failed to get playback.");
 
                 Native.GetPlaybackPosition(playbackHandle, out var position).ThrowIfError("Failed to get position.");
 
@@ -147,7 +149,7 @@ namespace Tizen.Multimedia.Remoting
         ///     -or-<br/>
         ///     An internal error occurs.
         /// </exception>
-        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed of.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed.</exception>
         /// <seealso cref="MediaControlServer.SetMetadata(MediaControlMetadata)"/>
         /// <since_tizen> 4 </since_tizen>
         public MediaControlMetadata GetMetadata()
@@ -181,7 +183,7 @@ namespace Tizen.Multimedia.Remoting
         ///     -or-<br/>
         ///     An internal error occurs.
         /// </exception>
-        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed of.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed.</exception>
         /// <since_tizen> 5 </since_tizen>
         public IEnumerable<MediaControlPlaylist> GetPlaylists()
         {
@@ -225,7 +227,7 @@ namespace Tizen.Multimedia.Remoting
         ///     -or-<br/>
         ///     An internal error occurs.
         /// </exception>
-        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed of.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed.</exception>
         /// <since_tizen> 5 </since_tizen>
         public MediaControlPlaylist GetPlaylistOfCurrentPlayingMedia()
         {
@@ -236,7 +238,7 @@ namespace Tizen.Multimedia.Remoting
             // Get the playlist name of current playing media.
             try
             {
-                Native.GetServerPlayback(Manager.Handle, ServerAppId, out playbackHandle).ThrowIfError("Failed to get playback.");
+                Native.GetServerPlaybackHandle(Manager.Handle, ServerAppId, out playbackHandle).ThrowIfError("Failed to get playback.");
 
                 var (name, index) = NativePlaylist.GetPlaylistInfo(playbackHandle);
 
@@ -260,7 +262,7 @@ namespace Tizen.Multimedia.Remoting
         ///     -or-<br/>
         ///     An internal error occurs.
         /// </exception>
-        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed of.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed.</exception>
         /// <since_tizen> 5 </since_tizen>
         public string GetIndexOfCurrentPlayingMedia()
         {
@@ -270,7 +272,7 @@ namespace Tizen.Multimedia.Remoting
 
             try
             {
-                Native.GetServerPlayback(Manager.Handle, ServerAppId, out playbackHandle).ThrowIfError("Failed to get playback.");
+                Native.GetServerPlaybackHandle(Manager.Handle, ServerAppId, out playbackHandle).ThrowIfError("Failed to get playback.");
 
                 var (name, index) = NativePlaylist.GetPlaylistInfo(playbackHandle);
                 return index;
@@ -293,7 +295,7 @@ namespace Tizen.Multimedia.Remoting
         ///     -or-<br/>
         ///     An internal error occurs.
         /// </exception>
-        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed of.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed.</exception>
         /// <seealso cref="MediaControlServer.SetShuffleModeEnabled(bool)"/>
         /// <since_tizen> 4 </since_tizen>
         public bool IsShuffleModeEnabled()
@@ -315,7 +317,7 @@ namespace Tizen.Multimedia.Remoting
         ///     -or-<br/>
         ///     An internal error occurs.
         /// </exception>
-        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed of.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed.</exception>
         /// <seealso cref="MediaControlServer.SetRepeatMode(MediaControlRepeatMode)"/>
         /// <since_tizen> 4 </since_tizen>
         public MediaControlRepeatMode GetRepeatMode()
@@ -329,223 +331,188 @@ namespace Tizen.Multimedia.Remoting
         }
 
         /// <summary>
-        /// Requests command to the server.
+        /// Gets the content type of current playing media.
         /// </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>
-        /// <returns><see cref="Bundle"/> represents the extra data from server and it can be null.</returns>
-        /// <exception cref="ArgumentNullException"><paramref name="command"/> is null.</exception>
+        /// <returns>The <see cref="MediaControlContentType"/>.</returns>
         /// <exception cref="InvalidOperationException">
         ///     The server has already been stopped.<br/>
         ///     -or-<br/>
         ///     An internal error occurs.
         /// </exception>
-        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed of.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed.</exception>
         /// <since_tizen> 5 </since_tizen>
-        public async Task<Bundle> RequestAsync(Command command)
+        public MediaControlContentType GetContentTypeOfCurrentPlayingMedia()
         {
-            if (command == null)
-            {
-                throw new ArgumentNullException(nameof(command));
-            }
-
             ThrowIfStopped();
 
-            command.SetRequestInformation(ServerAppId);
-
-            var tcs = new TaskCompletionSource<MediaControllerError>();
-            string reqeustId = null;
-            Bundle bundle = null;
-
-            EventHandler<CommandCompletedEventArgs> eventHandler = (s, e) =>
-            {
-                if (e.RequestId == reqeustId)
-                {
-                    bundle = e.Bundle;
-                    tcs.TrySetResult(e.Result);
-                }
-            };
+            IntPtr playbackHandle = IntPtr.Zero;
 
             try
             {
-                CommandCompleted += eventHandler;
-
-                reqeustId = command.Request(Manager.Handle);
+                Native.GetServerPlaybackHandle(Manager.Handle, ServerAppId, out playbackHandle).ThrowIfError("Failed to get playback.");
 
-                (await tcs.Task).ThrowIfError("Failed to request command");
+                Native.GetPlaybackContentType(playbackHandle, out MediaControlContentType type).
+                    ThrowIfError("Failed to get playback content type");
 
-                return bundle;
+                return type;
             }
             finally
             {
-                CommandCompleted -= eventHandler;
+                if (playbackHandle != IntPtr.Zero)
+                {
+                    Native.DestroyPlayback(playbackHandle);
+                }
             }
         }
 
         /// <summary>
-        /// Sends the result of each command.
+        /// Gets the icon path.
         /// </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="ArgumentNullException"><paramref name="command"/> is null.</exception>
+        /// <returns>The icon path.</returns>
         /// <exception cref="InvalidOperationException">
-        ///     The server is not running .<br/>
+        ///     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.</exception>
         /// <since_tizen> 5 </since_tizen>
-        public void Response(Command command, int result, Bundle bundle)
+        public string GetIconPath()
         {
-            if (command == null)
-            {
-                throw new ArgumentNullException(nameof(command));
-            }
+            ThrowIfStopped();
 
-            command.Response(Manager.Handle, result, bundle);
+            Native.GetServerIcon(Manager.Handle, ServerAppId, out string uri).
+                ThrowIfError("Failed to get icon path.");
+
+            return uri;
         }
 
         /// <summary>
-        /// Sends the result of each command.
+        /// Gets the age rating of current playing media.
         /// </summary>
-        /// <param name="command">The command that return to client.</param>
-        /// <param name="result">The result of <paramref name="command"/>.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="command"/> is null.</exception>
+        /// <returns>The Age rating of current playing media. The range is 0 to 19, inclusive.</returns>
         /// <exception cref="InvalidOperationException">
-        ///     The server is not running .<br/>
+        ///     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.</exception>
         /// <since_tizen> 5 </since_tizen>
-        public void Response(Command command, int result)
+        public int GetAgeRatingOfCurrentPlayingMedia()
         {
-            if (command == null)
+            ThrowIfStopped();
+
+            IntPtr playbackHandle = IntPtr.Zero;
+
+            try
             {
-                throw new ArgumentNullException(nameof(command));
-            }
+                Native.GetServerPlaybackHandle(Manager.Handle, ServerAppId, out playbackHandle).ThrowIfError("Failed to get playback.");
 
-            command.Response(Manager.Handle, result, null);
+                Native.GetAgeRating(playbackHandle, out int ageRating).ThrowIfError("Failed to get age rating.");
+
+                return ageRating;
+            }
+            finally
+            {
+                if (playbackHandle != IntPtr.Zero)
+                {
+                    Native.DestroyPlayback(playbackHandle);
+                }
+            }
         }
 
         /// <summary>
-        /// Sends playback command to the server.
+        /// Gets whether the subtitle mode is enabled or not.
         /// </summary>
-        /// <param name="command">A playback command.</param>
+        /// <returns>A value indicating whether the subtitle mode is enabled or not.</returns>
+        /// <value>true if the subtitle mode is enabled; otherwise, false.</value>
         /// <exception cref="InvalidOperationException">
         ///     The server has already been stopped.<br/>
         ///     -or-<br/>
         ///     An internal error occurs.
         /// </exception>
-        /// <exception cref="ArgumentException"><paramref name="command"/> is not valid.</exception>
-        /// <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)
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed.</exception>
+        /// <since_tizen> 6 </since_tizen>
+        public bool IsSubtitleModeEnabled()
         {
             ThrowIfStopped();
 
-            ValidationUtil.ValidateEnum(typeof(MediaControlPlaybackCommand), command, nameof(command));
+            Native.IsSubtitleEnabled(Manager.Handle, ServerAppId, out var isEnabled).
+                ThrowIfError("Failed to get subtitle mode state.");
 
-            Native.SendPlaybackActionCommandWithoutReqId(Manager.Handle, ServerAppId, command.ToNative()).
-                ThrowIfError("Failed to send command.");
+            return isEnabled;
         }
 
-        #region Capabilities
         /// <summary>
-        /// Gets the content type of current playing media.
+        /// Gets whether the 360 mode is enabled or not.
         /// </summary>
-        /// <returns>The <see cref="MediaControlContentType"/>.</returns>
+        /// <returns>A value indicating whether the 360 mode is enabled or not.</returns>
+        /// <value>true if the 360 mode is enabled; otherwise, false.</value>
         /// <exception cref="InvalidOperationException">
         ///     The server has already been stopped.<br/>
         ///     -or-<br/>
         ///     An internal error occurs.
         /// </exception>
-        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed of.</exception>
-        /// <since_tizen> 5 </since_tizen>
-        public MediaControlContentType GetContentTypeOfCurrentPlayingMedia()
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed.</exception>
+        /// <since_tizen> 6 </since_tizen>
+        public bool IsMode360Enabled()
         {
             ThrowIfStopped();
 
-            IntPtr playbackHandle = IntPtr.Zero;
-
-            try
-            {
-                Native.GetServerPlayback(Manager.Handle, ServerAppId, out playbackHandle).ThrowIfError("Failed to get playback.");
-
-                Native.GetPlaybackContentType(playbackHandle, out MediaControlContentType type).
-                    ThrowIfError("Failed to get playback content type");
+            Native.IsMode360Enabled(Manager.Handle, ServerAppId, out var isEnabled).
+                ThrowIfError("Failed to get 360 mode state.");
 
-                return type;
-            }
-            finally
-            {
-                if (playbackHandle != IntPtr.Zero)
-                {
-                    Native.DestroyPlayback(playbackHandle);
-                }
-            }
+            return isEnabled;
         }
 
         /// <summary>
-        /// Gets the icon path.
+        /// Gets the current display mode.
         /// </summary>
-        /// <returns>The icon path.</returns>
+        /// <returns>The <see cref="MediaControlDisplayMode"/>.</returns>
         /// <exception cref="InvalidOperationException">
         ///     The server has already been stopped.<br/>
         ///     -or-<br/>
         ///     An internal error occurs.
         /// </exception>
-        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed of.</exception>
-        /// <since_tizen> 5 </since_tizen>
-        public string GetIconPath()
+        /// <exception cref="ObjectDisposedException">
+        /// The <see cref="MediaControllerManager"/> has already been disposed.
+        /// </exception>
+        /// <since_tizen> 6 </since_tizen>
+        public MediaControlDisplayMode GetDisplayMode()
         {
             ThrowIfStopped();
 
-            Native.GetServerIcon(Manager.Handle, ServerAppId, out string uri).
-                ThrowIfError("Failed to get icon path.");
+            Native.GetDisplayMode(Manager.Handle, ServerAppId, out var mode).
+                ThrowIfError("Failed to get display mode state.");
 
-            return uri;
+            return mode.ToPublic();
         }
 
         /// <summary>
-        /// Gets the age rating of current playing media.
+        /// Gets the current display rotation.
         /// </summary>
-        /// <returns>The Age rating of current playing media. The range is 0 to 19, inclusive.</returns>
+        /// <returns>The <see cref="Rotation"/>.</returns>
         /// <exception cref="InvalidOperationException">
         ///     The server has already been stopped.<br/>
         ///     -or-<br/>
         ///     An internal error occurs.
         /// </exception>
-        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed of.</exception>
-        /// <since_tizen> 5 </since_tizen>
-        public int GetAgeRatingOfCurrentPlayingMedia()
+        /// <exception cref="ObjectDisposedException">
+        /// The <see cref="MediaControllerManager"/> has already been disposed.
+        /// </exception>
+        /// <since_tizen> 6 </since_tizen>
+        public Rotation GetDisplayRotation()
         {
             ThrowIfStopped();
 
-            IntPtr playbackHandle = IntPtr.Zero;
-
-            try
-            {
-                Native.GetServerPlayback(Manager.Handle, ServerAppId, out playbackHandle).ThrowIfError("Failed to get playback.");
+            Native.GetDisplayRotation(Manager.Handle, ServerAppId, out var rotation).
+                ThrowIfError("Failed to get display rotation state.");
 
-                Native.GetAgeRating(playbackHandle, out int ageRating).ThrowIfError("Failed to get age rating.");
-
-                return ageRating;
-            }
-            finally
-            {
-                if (playbackHandle != IntPtr.Zero)
-                {
-                    Native.DestroyPlayback(playbackHandle);
-                }
-            }
+            return rotation.ToPublic();
         }
+        #endregion Get information
+
 
+        #region Capability
         /// <summary>
         /// Gets the value whether <see cref="MediaControlPlaybackCommand"/> is supported or not.
         /// </summary>
@@ -557,7 +524,7 @@ namespace Tizen.Multimedia.Remoting
         ///     -or-<br/>
         ///     An internal error occurs.
         /// </exception>
-        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed of.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed.</exception>
         /// <since_tizen> 5 </since_tizen>
         public Dictionary<MediaControlPlaybackCommand, MediaControlCapabilitySupport> GetPlaybackCapabilities()
         {
@@ -574,7 +541,7 @@ namespace Tizen.Multimedia.Remoting
 
                 foreach (MediaControllerNativePlaybackAction action in Enum.GetValues(typeof(MediaControllerNativePlaybackAction)))
                 {
-                    Native.IsCapabilitySupported(playbackCapaHandle, action, out MediaControlCapabilitySupport support);
+                    Native.GetPlaybackCapability(playbackCapaHandle, action, out MediaControlCapabilitySupport support);
                     playbackCapabilities.Add(action.ToPublic(), support);
                 }
 
@@ -600,7 +567,7 @@ namespace Tizen.Multimedia.Remoting
         ///     -or-<br/>
         ///     An internal error occurs.
         /// </exception>
-        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed of.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed.</exception>
         /// <since_tizen> 5 </since_tizen>
         public MediaControlCapabilitySupport GetPlaybackCapability(MediaControlPlaybackCommand action)
         {
@@ -615,7 +582,7 @@ namespace Tizen.Multimedia.Remoting
                 Native.GetPlaybackCapabilityHandle(Manager.Handle, ServerAppId, out playbackCapaHandle).
                     ThrowIfError("Failed to get playback capability handle.");
 
-                Native.IsCapabilitySupported(playbackCapaHandle, action.ToNative(), out MediaControlCapabilitySupport support);
+                Native.GetPlaybackCapability(playbackCapaHandle, action.ToNative(), out MediaControlCapabilitySupport support);
 
                 return support;
             }
@@ -637,31 +604,16 @@ namespace Tizen.Multimedia.Remoting
         ///     -or-<br/>
         ///     An internal error occurs.
         /// </exception>
-        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed of.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed.</exception>
         /// <since_tizen> 5 </since_tizen>
         public MediaControlCapabilitySupport GetShuffleModeCapability()
         {
             ThrowIfStopped();
 
-            IntPtr playbackCapaHandle = IntPtr.Zero;
-
-            try
-            {
-                Native.GetPlaybackCapabilityHandle(Manager.Handle, ServerAppId, out playbackCapaHandle).
-                    ThrowIfError("Failed to get playback capability handle.");
-
-                Native.GetSimpleCapability(Manager.Handle, ServerAppId, MediaControlCapabilityCategory.Shuffle, out MediaControlCapabilitySupport support).
-                    ThrowIfError("Failed to get shuffle mode capability");
+            Native.GetSimpleCapability(Manager.Handle, ServerAppId, MediaControlNativeCapabilityCategory.Shuffle, out MediaControlCapabilitySupport support).
+                ThrowIfError("Failed to get shuffle mode capability");
 
-                return support;
-            }
-            finally
-            {
-                if (playbackCapaHandle != IntPtr.Zero)
-                {
-                    Native.DestroyCapability(playbackCapaHandle);
-                }
-            }
+            return support;
         }
 
         /// <summary>
@@ -673,32 +625,195 @@ namespace Tizen.Multimedia.Remoting
         ///     -or-<br/>
         ///     An internal error occurs.
         /// </exception>
-        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed of.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed.</exception>
         /// <since_tizen> 5 </since_tizen>
         public MediaControlCapabilitySupport GetRepeatModeCapability()
         {
             ThrowIfStopped();
 
-            IntPtr playbackCapaHandle = IntPtr.Zero;
+            Native.GetSimpleCapability(Manager.Handle, ServerAppId, MediaControlNativeCapabilityCategory.Repeat, out MediaControlCapabilitySupport support).
+                ThrowIfError("Failed to get repeat mode capability");
+
+            return support;
+        }
+
+        /// <summary>
+        /// Gets the value whether the repeat mode is supported or not.
+        /// </summary>
+        /// <returns>
+        /// If there's no supported display mode by server, it will return null.
+        /// otherwise, it will return the supported list of <see cref="MediaControlDisplayMode"/>.
+        /// </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.</exception>
+        /// <since_tizen> 6 </since_tizen>
+        public IEnumerable<MediaControlDisplayMode> GetDisplayModeCapability()
+        {
+            ThrowIfStopped();
+
+            Native.GetDisplayModeCapability(Manager.Handle, ServerAppId, out uint support).
+                ThrowIfError("Failed to get display mode capability");
+
+            return support != 0 ? ((MediaControlNativeDisplayMode)support).ToPublicList() : null;
+        }
+
+        /// <summary>
+        /// Gets the value whether the display mode is supported or not.
+        /// </summary>
+        /// <returns>
+        /// If there's no supported display rotation by server, it will return null.
+        /// otherwise, it will return the supported list of <see cref="Rotation"/>.
+        /// </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.</exception>
+        /// <since_tizen> 6 </since_tizen>
+        public IEnumerable<Rotation> GetDisplayRotationapability()
+        {
+            ThrowIfStopped();
+
+            Native.GetDisplayRotationCapability(Manager.Handle, ServerAppId, out uint support).
+                ThrowIfError("Failed to get display mode capability");
+
+            return support != 0 ? ((MediaControlNativeDisplayRotation)support).ToPublicList() : null;
+        }
+        #endregion Capability
+
+
+        #region Command
+        /// <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>
+        /// <returns><see cref="Bundle"/> represents the extra data from server and it can be null.</returns>
+        /// <exception cref="ArgumentNullException"><paramref name="command"/> is null.</exception>
+        /// <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.</exception>
+        /// <since_tizen> 5 </since_tizen>
+        public async Task<Bundle> RequestAsync(Command command)
+        {
+            if (command == null)
+            {
+                throw new ArgumentNullException(nameof(command));
+            }
+
+            ThrowIfStopped();
+
+            command.SetRequestInformation(ServerAppId);
+
+            var tcs = new TaskCompletionSource<MediaControllerError>();
+            string reqeustId = null;
+            Bundle bundle = null;
+
+            EventHandler<CommandCompletedEventArgs> eventHandler = (s, e) =>
+            {
+                if (e.RequestId == reqeustId)
+                {
+                    bundle = e.Bundle;
+                    tcs.TrySetResult(e.Result);
+                }
+            };
 
             try
             {
-                Native.GetPlaybackCapabilityHandle(Manager.Handle, ServerAppId, out playbackCapaHandle).
-                    ThrowIfError("Failed to get playback capability handle.");
+                CommandCompleted += eventHandler;
 
-                Native.GetSimpleCapability(Manager.Handle, ServerAppId, MediaControlCapabilityCategory.Repeat, out MediaControlCapabilitySupport support).
-                    ThrowIfError("Failed to get repeat mode capability");
+                reqeustId = command.Request(Manager.Handle);
 
-                return support;
+                (await tcs.Task).ThrowIfError("Failed to request command");
+
+                return bundle;
             }
             finally
             {
-                if (playbackCapaHandle != IntPtr.Zero)
-                {
-                    Native.DestroyCapability(playbackCapaHandle);
-                }
+                CommandCompleted -= eventHandler;
+            }
+        }
+
+        /// <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="ArgumentNullException"><paramref name="command"/> 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 void Response(Command command, int result, Bundle bundle)
+        {
+            if (command == null)
+            {
+                throw new ArgumentNullException(nameof(command));
+            }
+
+            command.Response(Manager.Handle, result, bundle);
+        }
+
+        /// <summary>
+        /// Sends the result of each command.
+        /// </summary>
+        /// <param name="command">The command that return to client.</param>
+        /// <param name="result">The result of <paramref name="command"/>.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="command"/> 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 void Response(Command command, int result)
+        {
+            if (command == null)
+            {
+                throw new ArgumentNullException(nameof(command));
             }
+
+            command.Response(Manager.Handle, result, null);
+        }
+
+        /// <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/>
+        ///     -or-<br/>
+        ///     An internal error occurs.
+        /// </exception>
+        /// <exception cref="ArgumentException"><paramref name="command"/> is not valid.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaControllerManager"/> has already been disposed.</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.SendPlaybackActionCommandWithoutReqId(Manager.Handle, ServerAppId, command.ToNative()).
+                ThrowIfError("Failed to send command.");
         }
-        #endregion Capabilities
+        #endregion Command
     }
 }
\ No newline at end of file
index d0c31fd..0ce3364 100644 (file)
@@ -23,17 +23,29 @@ namespace Tizen.Multimedia.Remoting
 {
     public partial class MediaControllerManager
     {
+        // Updated event
         private Native.ServerUpdatedCallback _serverUpdatedCallback;
         private Native.PlaybackUpdatedCallback _playbackUpdatedCallback;
+        private NativePlaylist.PlaylistUpdatedCallback _playlistUpdatedCallback;
+        private NativePlaylist.MetadataUpdatedCallback _metadataUpdatedCallback;
         private Native.ShuffleModeUpdatedCallback _shufflemodeUpdatedCallback;
         private Native.RepeatModeUpdatedCallback _repeatmodeUpdatedCallback;
-        private Native.CommandCompletedCallback _commandCompletedCallback;
-        private NativePlaylist.MetadataUpdatedCallback _metadataUpdatedCallback;
-        private NativePlaylist.PlaylistUpdatedCallback _playlistUpdatedCallback;
+        private Native.BoolAttributeUpdatedCallback _subtitleModeUpdatedCallback;
+        private Native.BoolAttributeUpdatedCallback _mode360UpdatedCallback;
+        private Native.DisplayModeUpdatedCallback _displayModeUpdatedCallback;
+        private Native.DisplayRotationUpdatedCallback _displayRotationUpdatedCallback;
+
+        // Capability updated event
         private Native.PlaybackCapabilityUpdatedCallback _playbackCapabilityUpdatedCallback;
-        private Native.SimpleCapabilityCallback _simpleCapabilityUpdatedCallback;
+        private Native.SimpleCapabilityUpdatedCallback _categoryCapabilityUpdatedCallback;
+        private Native.CategoryAttributeCapabilityUpdatedCallback _displayModeCapabilityUpdatedCallback;
+        private Native.CategoryAttributeCapabilityUpdatedCallback _displayRotationCapabilityUpdatedCallback;
+
+        // Command
+        private Native.CommandCompletedCallback _commandCompletedCallback;
         private Native.CustomCommandReceivedCallback _customCommandReceivedCallback;
 
+
         /// <summary>
         /// Occurs when a server is started.
         /// </summary>
@@ -54,10 +66,18 @@ namespace Tizen.Multimedia.Remoting
             RegisterShuffleModeUpdatedEvent();
             RegisterRepeatModeUpdatedEvent();
             RegisterPlaylistUpdatedEvent();
-            RegisterCommandCompletedEvent();
+            RegisterSubtitleModeUpdateEvent();
+            RegisterMode360UpdateEvent();
+            RegisterDisplayModeUpdateEvent();
+            RegisterDisplayRotationUpdateEvent();
+
             RegisterPlaybackCapabilitiesEvent();
+            RegisterDisplayModeCapabilityUpdatedEvent();
+            RegisterDisplayRotationCapabilityUpdatedEvent();
+            RegisterSimpleCapabilityUpdatedEvent();
+
+            RegisterCommandCompletedEvent();
             RegisterCustomCommandReceivedEvent();
-            RegisterSimpleCapabilityEvent();
         }
 
         private void RaiseServerChangedEvent(MediaControllerNativeServerState state, MediaController controller)
@@ -78,6 +98,8 @@ namespace Tizen.Multimedia.Remoting
             }
         }
 
+
+        #region Updated event
         private void RegisterServerUpdatedEvent()
         {
             _serverUpdatedCallback = (serverName, state, _) =>
@@ -85,7 +107,8 @@ namespace Tizen.Multimedia.Remoting
                 RaiseServerChangedEvent(state, HandleServerUpdated(serverName, state));
             };
 
-            Native.SetServerUpdatedCb(Handle, _serverUpdatedCallback).ThrowIfError("Failed to init server changed event.");
+            Native.SetServerUpdatedCb(Handle, _serverUpdatedCallback).
+                ThrowIfError("Failed to register server changed event.");
         }
 
         private void RegisterPlaybackUpdatedEvent()
@@ -95,9 +118,20 @@ namespace Tizen.Multimedia.Remoting
                 GetController(serverName)?.RaisePlaybackUpdatedEvent(playbackHandle);
             };
 
-            Native.SetPlaybackUpdatedCb(Handle, _playbackUpdatedCallback).ThrowIfError("Failed to init PlaybackUpdated event.");
+            Native.SetPlaybackUpdatedCb(Handle, _playbackUpdatedCallback).
+                ThrowIfError("Failed to register PlaybackUpdated event.");
         }
 
+        private void RegisterPlaylistUpdatedEvent()
+        {
+            _playlistUpdatedCallback = (serverName, playlistMode, name, playlistHandle, _) =>
+            {
+                GetController(serverName)?.RaisePlaylistUpdatedEvent(playlistMode, name, playlistHandle);
+            };
+
+            NativePlaylist.SetPlaylistModeUpdatedCb(Handle, _playlistUpdatedCallback).
+                ThrowIfError("Failed to register PlaylistUpdated event.");
+        }
 
         private void RegisterMetadataUpdatedEvent()
         {
@@ -106,7 +140,8 @@ namespace Tizen.Multimedia.Remoting
                 GetController(serverName)?.RaiseMetadataUpdatedEvent(metadata);
             };
 
-            NativePlaylist.SetMetadataUpdatedCb(Handle, _metadataUpdatedCallback).ThrowIfError("Failed to init MetadataUpdated event.");
+            NativePlaylist.SetMetadataUpdatedCb(Handle, _metadataUpdatedCallback).
+                ThrowIfError("Failed to register MetadataUpdated event.");
         }
 
         private void RegisterShuffleModeUpdatedEvent()
@@ -117,7 +152,7 @@ namespace Tizen.Multimedia.Remoting
             };
 
             Native.SetShuffleModeUpdatedCb(Handle, _shufflemodeUpdatedCallback).
-                ThrowIfError("Failed to init ShuffleModeUpdated event.");
+                ThrowIfError("Failed to register ShuffleModeUpdated event.");
         }
 
         private void RegisterRepeatModeUpdatedEvent()
@@ -128,42 +163,67 @@ namespace Tizen.Multimedia.Remoting
             };
 
             Native.SetRepeatModeUpdatedCb(Handle, _repeatmodeUpdatedCallback).
-                ThrowIfError("Failed to init RepeatModeUpdated event.");
+                ThrowIfError("Failed to register RepeatModeUpdated event.");
         }
 
-        private void RegisterPlaylistUpdatedEvent()
+        private void RegisterSubtitleModeUpdateEvent()
         {
-            _playlistUpdatedCallback = (serverName, playlistMode, name, playlistHandle, _) =>
+            _subtitleModeUpdatedCallback = (serverName, isEnabled, _) =>
             {
-                GetController(serverName)?.RaisePlaylistUpdatedEvent(playlistMode, name, playlistHandle);
+                GetController(serverName)?.RaiseSubtitleModeUpdatedEvent(isEnabled);
             };
 
-            NativePlaylist.SetPlaylistModeUpdatedCb(Handle, _playlistUpdatedCallback).
-                ThrowIfError("Failed to init PlaylistUpdated event.");
+            Native.SetSubtitleUpdatedCb(Handle, _subtitleModeUpdatedCallback).
+                ThrowIfError("Failed to register SubtitleModeUpdated event.");
         }
 
-        private void RegisterCommandCompletedEvent()
+        private void RegisterMode360UpdateEvent()
         {
-            _commandCompletedCallback = (serverName, requestId, result, bundleHandle, _) =>
+            _mode360UpdatedCallback = (serverName, isEnabled, _) =>
             {
-                // SafeHandles cannot be marshaled from unmanaged to managed.
-                // So we use IntPtr type for 'bundleHandle' in native callback.
-                GetController(serverName)?.RaiseCommandCompletedEvent(requestId, result, bundleHandle);
+                GetController(serverName)?.RaiseMode360UpdatedEvent(isEnabled);
             };
 
-            Native.SetCommandCompletedCb(Handle, _commandCompletedCallback).
-                ThrowIfError("Failed to init CommandCompleted event.");
+            Native.SetMode360UpdatedCb(Handle, _mode360UpdatedCallback).
+                ThrowIfError("Failed to register Mode360Updated event.");
         }
 
-        private void RegisterPlaybackCapabilitiesEvent()
+        private void RegisterDisplayModeUpdateEvent()
         {
-            _playbackCapabilityUpdatedCallback = (serverName, playbackCapaHandle, _) =>
+            _displayModeUpdatedCallback = (serverName, mode, _) =>
             {
-                GetController(serverName)?.RaisePlaybackCapabilityUpdatedEvent(playbackCapaHandle);
+                GetController(serverName)?.RaiseDisplayModeUpdatedEvent(mode);
             };
 
-            Native.SetPlaybackCapabilityUpdatedCb(Handle, _playbackCapabilityUpdatedCallback).
-                ThrowIfError("Failed to init PlaybackCapabilityUpdated event.");
+            Native.SetDisplayModeUpdatedCb(Handle, _displayModeUpdatedCallback).
+                ThrowIfError("Failed to register DisplayModeUpdated event.");
+        }
+
+        private void RegisterDisplayRotationUpdateEvent()
+        {
+            _displayRotationUpdatedCallback = (serverName, rotation, _) =>
+            {
+                GetController(serverName)?.RaiseDisplayRotationUpdatedEvent(rotation);
+            };
+
+            Native.SetDisplayRotationUpdatedCb(Handle, _displayRotationUpdatedCallback).
+                ThrowIfError("Failed to register DisplayRotationUpdated event.");
+        }
+        #endregion
+
+
+        #region Command
+        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 register CommandCompleted event.");
         }
 
         private void RegisterCustomCommandReceivedEvent()
@@ -186,26 +246,65 @@ namespace Tizen.Multimedia.Remoting
             };
 
             Native.SetCustomEventCb(Handle, _customCommandReceivedCallback).
-                ThrowIfError("Failed to init CustomCommandReceived event.");
+                ThrowIfError("Failed to register CustomCommandReceived event.");
+        }
+        #endregion
+
+
+        #region Capability updated event
+        private void RegisterPlaybackCapabilitiesEvent()
+        {
+            _playbackCapabilityUpdatedCallback = (serverName, playbackCapaHandle, _) =>
+            {
+                GetController(serverName)?.RaisePlaybackCapabilityUpdatedEvent(playbackCapaHandle);
+            };
+
+            Native.SetPlaybackCapabilityUpdatedCb(Handle, _playbackCapabilityUpdatedCallback).
+                ThrowIfError("Failed to register PlaybackCapabilityUpdated event.");
+        }
+
+        private void RegisterDisplayModeCapabilityUpdatedEvent()
+        {
+            _displayModeCapabilityUpdatedCallback = (serverName, modes, _) =>
+            {
+                GetController(serverName)?.RaiseDisplayModeCapabilityUpdatedEvent(
+                    (MediaControlNativeDisplayMode)modes);
+            };
+
+            Native.SetDisplayModeCapabilityUpdatedCb(Handle, _displayModeCapabilityUpdatedCallback).
+                ThrowIfError("Failed to register DisplayModeCapabilityUpdated event.");
+        }
+
+        private void RegisterDisplayRotationCapabilityUpdatedEvent()
+        {
+            _displayRotationCapabilityUpdatedCallback = (serverName, rotations, _) =>
+            {
+                GetController(serverName)?.RaiseDisplayRotationCapabilityUpdatedEvent(
+                    (MediaControlNativeDisplayRotation)rotations);
+            };
+
+            Native.SetDisplayRotationCapabilityUpdatedCb(Handle, _displayRotationCapabilityUpdatedCallback).
+                ThrowIfError("Failed to register DisplayRotationCapabilityUpdated event.");
         }
 
-        private void RegisterSimpleCapabilityEvent()
+        private void RegisterSimpleCapabilityUpdatedEvent()
         {
-            _simpleCapabilityUpdatedCallback = (serverName, category, support, _) =>
+            _categoryCapabilityUpdatedCallback = (serverName, category, support, _) =>
             {
                 switch (category)
                 {
-                    case MediaControlCapabilityCategory.Repeat:
+                    case MediaControlNativeCapabilityCategory.Repeat:
                         GetController(serverName)?.RaiseRepeatModeCapabilityUpdatedEvent(support);
                         break;
-                    case MediaControlCapabilityCategory.Shuffle:
+                    case MediaControlNativeCapabilityCategory.Shuffle:
                         GetController(serverName)?.RaiseShuffleModeCapabilityUpdatedEvent(support);
                         break;
                 }
             };
 
-            Native.SetSimpleCapabilityUpdatedCb(Handle, _simpleCapabilityUpdatedCallback).
-                ThrowIfError("Failed to init capability updated event.");
+            Native.SetCategoryCapabilityUpdatedCb(Handle, _categoryCapabilityUpdatedCallback).
+                ThrowIfError("Failed to register capability updated event.");
         }
+        #endregion
     }
 }
\ No newline at end of file
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/Mode360CommandReceivedEventArgs.cs b/src/Tizen.Multimedia.Remoting/MediaController/Mode360CommandReceivedEventArgs.cs
new file mode 100644 (file)
index 0000000..f409180
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2019 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.Mode360CommandReceived"/> event.
+    /// </summary>
+    /// <since_tizen> 6 </since_tizen>
+    public class Mode360CommandReceivedEventArgs : EventArgs
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="Mode360CommandReceivedEventArgs"/> class.
+        /// </summary>
+        /// <param name="command">The 360 mode command.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="command"/> is null.</exception>
+        /// <since_tizen> 6 </since_tizen>
+        internal Mode360CommandReceivedEventArgs(Mode360Command command)
+        {
+            Command = command ?? throw new ArgumentNullException(nameof(command));
+        }
+
+        /// <summary>
+        /// Gets the <see cref="Mode360Command"/>.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        public Mode360Command Command { get; }
+    }
+}
\ No newline at end of file
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/Mode360UpdatedEventArgs.cs b/src/Tizen.Multimedia.Remoting/MediaController/Mode360UpdatedEventArgs.cs
new file mode 100644 (file)
index 0000000..0f000b9
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2019 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.Mode360Updated"/> event.
+    /// </summary>
+    /// <since_tizen> 6 </since_tizen>
+    public class Mode360UpdatedEventArgs : EventArgs
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="Mode360UpdatedEventArgs"/> class.
+        /// </summary>
+        /// <param name="isEnabled">A value indicating the updated 360 mode.</param>
+        /// <since_tizen> 6 </since_tizen>
+        internal Mode360UpdatedEventArgs(bool isEnabled)
+        {
+            IsEnabled = isEnabled;
+        }
+
+        /// <summary>
+        /// Gets the value indicating whether 360 mode is enabled or not.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        public bool IsEnabled { get; }
+    }
+}
\ No newline at end of file
index 12cc0c3..a465e28 100644 (file)
@@ -30,7 +30,7 @@ namespace Tizen.Multimedia.Remoting
         /// Initializes a new instance of the <see cref="RepeatModeCapabilityUpdatedEventArgs"/> class.
         /// </summary>
         /// <param name="support">The repeat mode capabilities.</param>
-        /// <exception cref="ArgumentException"><paramref name="support"/> is not vaild.</exception>
+        /// <exception cref="ArgumentException"><paramref name="support"/> is not valid.</exception>
         /// <since_tizen> 5 </since_tizen>
         public RepeatModeCapabilityUpdatedEventArgs(MediaControlCapabilitySupport support)
         {
index a63f9e0..17c35f7 100644 (file)
@@ -27,7 +27,7 @@ namespace Tizen.Multimedia.Remoting
         /// <summary>
         /// Initializes a new instance of the <see cref="RepeatModeCommandReceivedEventArgs"/> class.
         /// </summary>
-        /// <param name="command">The playback position command.</param>
+        /// <param name="command">The repeat mode command.</param>
         /// <exception cref="ArgumentNullException"><paramref name="command"/> is null.</exception>
         /// <since_tizen> 5 </since_tizen>
         public RepeatModeCommandReceivedEventArgs(RepeatModeCommand command)
index 5be1456..3b74fdb 100644 (file)
@@ -30,7 +30,7 @@ namespace Tizen.Multimedia.Remoting
         /// Initializes a new instance of the <see cref="ShuffleModeCapabilityUpdatedEventArgs"/> class.
         /// </summary>
         /// <param name="support">The shuffle mode capabilities.</param>
-        /// <exception cref="ArgumentException"><paramref name="support"/> is not vaild.</exception>
+        /// <exception cref="ArgumentException"><paramref name="support"/> is not valid.</exception>
         /// <since_tizen> 5 </since_tizen>
         public ShuffleModeCapabilityUpdatedEventArgs(MediaControlCapabilitySupport support)
         {
index 666cd1f..043b298 100644 (file)
@@ -27,7 +27,7 @@ namespace Tizen.Multimedia.Remoting
         /// <summary>
         /// Initializes a new instance of the <see cref="ShuffleModeCommandReceivedEventArgs"/> class.
         /// </summary>
-        /// <param name="command">The playback position command.</param>
+        /// <param name="command">The shuffle mode command.</param>
         /// <exception cref="ArgumentNullException"><paramref name="command"/> is null.</exception>
         /// <since_tizen> 5 </since_tizen>
         public ShuffleModeCommandReceivedEventArgs(ShuffleModeCommand command)
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/SubtitleModeCommandReceivedEventArgs.cs b/src/Tizen.Multimedia.Remoting/MediaController/SubtitleModeCommandReceivedEventArgs.cs
new file mode 100644 (file)
index 0000000..c45c000
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2019 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.SubtitleModeCommandReceived"/> event.
+    /// </summary>
+    /// <since_tizen> 6 </since_tizen>
+    public class SubtitleModeCommandReceivedEventArgs : EventArgs
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="SubtitleModeCommandReceivedEventArgs"/> class.
+        /// </summary>
+        /// <param name="command">The subtitle command.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="command"/> is null.</exception>
+        /// <since_tizen> 6 </since_tizen>
+        internal SubtitleModeCommandReceivedEventArgs(SubtitleModeCommand command)
+        {
+            Command = command ?? throw new ArgumentNullException(nameof(command));
+        }
+
+        /// <summary>
+        /// Gets the <see cref="SubtitleModeCommand"/>.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        public SubtitleModeCommand Command { get; }
+    }
+}
\ No newline at end of file
diff --git a/src/Tizen.Multimedia.Remoting/MediaController/SubtitleModeUpdatedEventArgs.cs b/src/Tizen.Multimedia.Remoting/MediaController/SubtitleModeUpdatedEventArgs.cs
new file mode 100644 (file)
index 0000000..debcc82
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2019 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.SubtitleModeUpdated"/> event.
+    /// </summary>
+    /// <since_tizen> 6 </since_tizen>
+    public class SubtitleModeUpdatedEventArgs : EventArgs
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="SubtitleModeUpdatedEventArgs"/> class.
+        /// </summary>
+        /// <param name="isEnabled">A value indicating the updated subtitle mode.</param>
+        /// <since_tizen> 6 </since_tizen>
+        internal SubtitleModeUpdatedEventArgs(bool isEnabled)
+        {
+            IsEnabled = isEnabled;
+        }
+
+        /// <summary>
+        /// Gets the value indicating whether subtitle is enabled or not.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        public bool IsEnabled { get; }
+    }
+}
\ No newline at end of file
index 35c5e4a..3174f14 100644 (file)
@@ -173,6 +173,26 @@ namespace Tizen.Multimedia
 
             [DllImport(Libraries.MediaTool, EntryPoint = "media_format_set_audio_aac_header_type")]
             internal static extern int SetAudioAacType(IntPtr handle, MediaFormatAacType value);
+
+            [DllImport(Libraries.MediaTool, EntryPoint = "media_format_set_audio_channel_mask")]
+            internal static extern int SetAudioChannelMask(IntPtr handle, ulong mask);
+
+            [DllImport(Libraries.MediaTool, EntryPoint = "media_format_get_audio_channel_mask")]
+            internal static extern int GetAudioChannelMask(IntPtr handle, out ulong mask);
+
+            [DllImport(Libraries.MediaTool, EntryPoint = "media_format_is_little_endian")]
+            internal static extern int IsLittleEndian(IntPtr handle, out bool isLittleEndian);
+
+            [DllImport(Libraries.MediaTool, EntryPoint = "media_format_get_audio_bit_depth")]
+            internal static extern int GetAudioBitDepth(IntPtr handle, out int bitDepth);
+
+            [DllImport(Libraries.MediaTool, EntryPoint = "media_format_channel_positions_from_mask")]
+            internal static extern int GetChannelPositionFromMask(IntPtr handle, ulong mask,
+                out MediaFormatAudioChannelPosition[] position);
+
+            [DllImport(Libraries.MediaTool, EntryPoint = "media_format_channel_positions_to_mask")]
+            internal static extern int GetMaskFromChannelPosition(IntPtr handle,
+                MediaFormatAudioChannelPosition[] position, out ulong mask);
             #endregion
 
             [DllImport(Libraries.MediaTool, EntryPoint = "media_format_get_text_info")]
index db99fff..e75bc2e 100644 (file)
  * limitations under the License.
  */
 using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
 using System.Diagnostics;
 using Tizen.Internals.Errors;
+using Native = Tizen.Multimedia.Interop.MediaFormat;
 
 namespace Tizen.Multimedia
 {
@@ -66,6 +70,91 @@ namespace Tizen.Multimedia
         /// <since_tizen> 3 </since_tizen>
         public AudioMediaFormat(MediaFormatAudioMimeType mimeType,
             int channel, int sampleRate, int bit, int bitRate, MediaFormatAacType aacType)
+            : this(mimeType, channel, sampleRate, bit, bitRate, aacType, 0, null)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the AudioMediaFormat class with the specified mime type,
+        /// channel, sample rate, bit, bit rate, bit depth, and audio channel map.
+        /// </summary>
+        /// <remarks>
+        /// If <paramref name="audioChannelMap"/> contains <see cref="MediaFormatAudioChannelPosition.None"/>,
+        /// <paramref name="channel"/> should be set greater than 0.<br/>
+        /// If <paramref name="audioChannelMap"/> contains <see cref="MediaFormatAudioChannelPosition.Mono"/>,
+        /// <paramref name="channel"/> should be set 1.<br/>
+        /// User can not set <see cref="MediaFormatAudioChannelPosition.None"/> with another channel positions.<br/>
+        /// User can not set <see cref="MediaFormatAudioChannelPosition.Mono"/> with another channel positions.<br/>
+        /// If same channel position is added in <paramref name="audioChannelMap"/> more than once, the duplicaiton will be removed.
+        /// </remarks>
+        /// <param name="mimeType">The mime type of the format.</param>
+        /// <param name="channel">The channel value of the format.</param>
+        /// <param name="sampleRate">The sample rate value of the format.</param>
+        /// <param name="bit">The bit value of the format.</param>
+        /// <param name="bitRate">The bit rate value of the format.</param>
+        /// <param name="bitDepth">The bit depth value of the PCM audio format.</param>
+        /// <param name="audioChannelMap">The loudspeaker position in PCM audio format.</param>
+        /// <exception cref="ArgumentException">
+        ///     <paramref name="mimeType"/> is invalid (i.e. undefined value).<br/>
+        /// </exception>
+        /// <exception cref="ArgumentException">
+        /// <paramref name="audioChannelMap"/> is invalid or mismatched with <paramref name="channel"/> like the following:<br/>
+        ///     <paramref name="audioChannelMap"/> is not matched correctly with <paramref name="channel"/>.
+        ///     -or-<br/>
+        ///     <paramref name="audioChannelMap"/> is set to <see cref="MediaFormatAudioChannelPosition.Invaild"/>.
+        ///     -or-<br/>
+        ///     <see cref="MediaFormatAudioChannelPosition.Mono"/> or <see cref="MediaFormatAudioChannelPosition.None"/> is set with another channel position.
+        /// </exception>
+        /// <exception cref="ArgumentOutOfRangeException">
+        ///     <paramref name="channel"/>, <paramref name="sampleRate"/>, <paramref name="bit"/>, or <paramref name="bitRate"/> is less than zero.
+        /// </exception>
+        /// <since_tizen> 6 </since_tizen>
+        public AudioMediaFormat(MediaFormatAudioMimeType mimeType,
+            int channel, int sampleRate, int bit, int bitRate, int bitDepth, IList<MediaFormatAudioChannelPosition> audioChannelMap)
+            : this(mimeType, channel, sampleRate, bit, bitRate, MediaFormatAacType.None, bitDepth, audioChannelMap)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the AudioMediaFormat class with the specified mime type,
+        /// channel, sample rate, bit, bit rate, bit depth, and audio channel map.
+        /// </summary>
+        /// <remarks>
+        /// If <paramref name="audioChannelMap"/> contains <see cref="MediaFormatAudioChannelPosition.None"/>,
+        /// <paramref name="channel"/> should be set greater than 0.<br/>
+        /// If <paramref name="audioChannelMap"/> contains <see cref="MediaFormatAudioChannelPosition.Mono"/>,
+        /// <paramref name="channel"/> should be set 1.<br/>
+        /// User can not set <see cref="MediaFormatAudioChannelPosition.None"/> with another channel positions.<br/>
+        /// User can not set <see cref="MediaFormatAudioChannelPosition.Mono"/> with another channel positions.<br/>
+        /// If same channel position is added in <paramref name="audioChannelMap"/> more than twice, its duplicaiton will be removed.
+        /// </remarks>
+        /// <param name="mimeType">The mime type of the format.</param>
+        /// <param name="channel">The channel value of the format.</param>
+        /// <param name="sampleRate">The sample rate value of the format.</param>
+        /// <param name="bit">The bit value of the format.</param>
+        /// <param name="bitRate">The bit rate value of the format.</param>
+        /// <param name="aacType">The AAC bitstream format(ADIF or ADTS).</param>
+        /// <param name="bitDepth">The bit depth value of the PCM audio format.</param>
+        /// <param name="audioChannelMap">The loudspeaker position in PCM audio format.</param>
+        /// <exception cref="ArgumentException">
+        ///     <paramref name="mimeType"/> or <paramref name="aacType"/> is invalid (i.e. undefined value).<br/>
+        ///     -or-<br/>
+        ///     <paramref name="aacType"/> is not <see cref="MediaFormatAacType.None"/>, but <paramref name="mimeType"/> is one of the AAC types.
+        /// </exception>
+        /// <exception cref="ArgumentException">
+        /// <paramref name="audioChannelMap"/> is invalid or mismatched with <paramref name="channel"/> like the following:<br/>
+        ///     <paramref name="audioChannelMap"/> is not matched correctly with <paramref name="channel"/>.
+        ///     -or-<br/>
+        ///     <paramref name="audioChannelMap"/> is set to <see cref="MediaFormatAudioChannelPosition.Invaild"/>.
+        ///     -or-<br/>
+        ///     <see cref="MediaFormatAudioChannelPosition.Mono"/> or <see cref="MediaFormatAudioChannelPosition.None"/> is set with another channel position.
+        /// </exception>
+        /// <exception cref="ArgumentOutOfRangeException">
+        ///     <paramref name="channel"/>, <paramref name="sampleRate"/>, <paramref name="bit"/>, or <paramref name="bitRate"/> is less than zero.
+        /// </exception>
+        /// <since_tizen> 6 </since_tizen>
+        public AudioMediaFormat(MediaFormatAudioMimeType mimeType,
+            int channel, int sampleRate, int bit, int bitRate, MediaFormatAacType aacType, int bitDepth, IList<MediaFormatAudioChannelPosition> audioChannelMap)
             : base(MediaFormatType.Audio)
         {
             ValidationUtil.ValidateEnum(typeof(MediaFormatAudioMimeType), mimeType, nameof(mimeType));
@@ -99,11 +188,53 @@ namespace Tizen.Multimedia
             }
 
             MimeType = mimeType;
+            AacType = aacType;
             Channel = channel;
             SampleRate = sampleRate;
             Bit = bit;
             BitRate = bitRate;
-            AacType = aacType;
+            BitDepth = bitDepth;
+
+            if (audioChannelMap != null)
+            {
+                audioChannelMap = audioChannelMap.Distinct().OrderBy(p => p).ToList();
+
+                ValidateAudioChannelMap(audioChannelMap);
+
+                AudioChannelMap = new ReadOnlyCollection<MediaFormatAudioChannelPosition>(audioChannelMap);
+            }
+        }
+
+        private void ValidateAudioChannelMap(IList<MediaFormatAudioChannelPosition> audioChannelMap)
+        {
+            if (audioChannelMap.Contains(MediaFormatAudioChannelPosition.Invaild))
+            {
+                throw new ArgumentException("Invalid channel position.", nameof(audioChannelMap));
+            }
+
+            if ((audioChannelMap.Contains(MediaFormatAudioChannelPosition.Mono) && audioChannelMap.Count > 1) ||
+                (audioChannelMap.Contains(MediaFormatAudioChannelPosition.None) && audioChannelMap.Count > 1))
+            {
+                throw new ArgumentException($"Mono and None can not be set with another channel position.",
+                    nameof(audioChannelMap));
+            }
+
+            if (audioChannelMap.Contains(MediaFormatAudioChannelPosition.None))
+            {
+                if (Channel <= 0)
+                {
+                    throw new ArgumentException($"Channel should be greater than 0 in {MediaFormatAudioChannelPosition.None}.",
+                        nameof(audioChannelMap));
+                }
+            }
+            else
+            {
+                if (audioChannelMap.Count != Channel)
+                {
+                    throw new ArgumentException("Channel should be the same with number of audioChannelMap.",
+                        nameof(audioChannelMap));
+                }
+            }
         }
 
         /// <summary>
@@ -123,6 +254,19 @@ namespace Tizen.Multimedia
             Bit = bit;
             BitRate = bitRate;
             AacType = IsAacSupportedMimeType(mimeType) ? GetAacType(handle) : MediaFormatAacType.None;
+            AudioChannelMap = GetAudioChannelMap(handle);
+        }
+
+        private static ReadOnlyCollection<MediaFormatAudioChannelPosition> GetAudioChannelMap(IntPtr handle)
+        {
+            var ret = Native.GetAudioChannelMask(handle, out ulong mask);
+            MultimediaDebug.AssertNoError(ret);
+
+            ret = Native.GetChannelPositionFromMask(handle, mask, out MediaFormatAudioChannelPosition[] positions);
+            MultimediaDebug.AssertNoError(ret);
+
+            return positions == null ? null :
+                new ReadOnlyCollection<MediaFormatAudioChannelPosition>(positions.Distinct().OrderBy(p => p).ToList());
         }
 
         /// <summary>
@@ -150,7 +294,7 @@ namespace Tizen.Multimedia
         {
             Debug.Assert(handle != IntPtr.Zero, "The handle is invalid!");
 
-            int ret = Interop.MediaFormat.GetAudioInfo(handle,
+            int ret = Native.GetAudioInfo(handle,
                 out mimeType, out channel, out sampleRate, out bit, out bitRate);
 
             MultimediaDebug.AssertNoError(ret);
@@ -167,7 +311,7 @@ namespace Tizen.Multimedia
         {
             Debug.Assert(handle != IntPtr.Zero, "The handle is invalid!");
 
-            int ret = Interop.MediaFormat.GetAudioAacType(handle, out var aacType);
+            int ret = Native.GetAudioAacType(handle, out var aacType);
 
             MultimediaDebug.AssertNoError(ret);
 
@@ -180,23 +324,38 @@ namespace Tizen.Multimedia
         {
             Debug.Assert(Type == MediaFormatType.Audio);
 
-            int ret = Interop.MediaFormat.SetAudioMimeType(handle, MimeType);
+            int ret = Native.SetAudioMimeType(handle, MimeType);
             MultimediaDebug.AssertNoError(ret);
 
-            ret = Interop.MediaFormat.SetAudioChannel(handle, Channel);
+            ret = Native.SetAudioChannel(handle, Channel);
             MultimediaDebug.AssertNoError(ret);
 
-            ret = Interop.MediaFormat.SetAudioSampleRate(handle, SampleRate);
+            ret = Native.SetAudioSampleRate(handle, SampleRate);
             MultimediaDebug.AssertNoError(ret);
 
-            ret = Interop.MediaFormat.SetAudioBit(handle, Bit);
+            ret = Native.SetAudioBit(handle, Bit);
             MultimediaDebug.AssertNoError(ret);
 
-            ret = Interop.MediaFormat.SetAudioAverageBps(handle, BitRate);
+            ret = Native.SetAudioAverageBps(handle, BitRate);
             MultimediaDebug.AssertNoError(ret);
 
-            ret = Interop.MediaFormat.SetAudioAacType(handle, AacType);
+            ret = Native.SetAudioAacType(handle, AacType);
             MultimediaDebug.AssertNoError(ret);
+
+            if (AudioChannelMap != null)
+            {
+                ret = Native.SetAudioChannelMask(handle, GetAudioChannelMask(handle, AudioChannelMap));
+                MultimediaDebug.AssertNoError(ret);
+            }
+        }
+
+        private static ulong GetAudioChannelMask(IntPtr handle, IList<MediaFormatAudioChannelPosition> audioChannelMap)
+        {
+            int ret = Native.GetMaskFromChannelPosition(handle, audioChannelMap.ToArray(),
+                out ulong mask);
+            MultimediaDebug.AssertNoError(ret);
+
+            return mask;
         }
 
         /// <summary>
@@ -212,6 +371,18 @@ namespace Tizen.Multimedia
         public int Channel { get; }
 
         /// <summary>
+        /// Gets or sets the list of channel position value of PCM audio format.
+        /// </summary>
+        /// <remarks>
+        /// The channel mask specifies the mapping of channels to speakers.
+        /// default value is 0.
+        /// </remarks>
+        /// <seealso cref="Channel"/>
+        /// <seealso cref="MediaFormatAudioChannelPosition"/>
+        /// <since_tizen> 6 </since_tizen>
+        public ReadOnlyCollection<MediaFormatAudioChannelPosition> AudioChannelMap { get; }
+
+        /// <summary>
         /// Gets the sample rate value of the current format.
         /// </summary>
         /// <since_tizen> 3 </since_tizen>
@@ -230,6 +401,12 @@ namespace Tizen.Multimedia
         public int BitRate { get; }
 
         /// <summary>
+        /// Gets the bit depth value of the current format.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        public int BitDepth { get; }
+
+        /// <summary>
         /// Gets the AAC type of the current format.
         /// </summary>
         /// <since_tizen> 3 </since_tizen>
@@ -241,8 +418,17 @@ namespace Tizen.Multimedia
         /// <returns>A string that represents the current object.</returns>
         /// <since_tizen> 3 </since_tizen>
         public override string ToString()
-            => $@"MimeType={ MimeType.ToString() }, Channel={ Channel.ToString() }, SampleRate=
-                { SampleRate }, Bit={ Bit.ToString() }, BitRate={ BitRate.ToString() }, AacType={ AacType.ToString() }";
+        {
+            var toString = $@"MimeType={ MimeType.ToString() }, Channel={ Channel.ToString() }, SampleRate={ SampleRate },
+                Bit={ Bit.ToString() }, BitRate={ BitRate.ToString() }, BitDepth={ BitDepth.ToString() }, AacType={ AacType.ToString()}";
+
+            if (AudioChannelMap != null)
+            {
+                toString += ", AudioChannelMap=" + $"{string.Join(",", AudioChannelMap)}";
+            }
+
+            return toString;
+        }
 
         /// <summary>
         /// Compares an object to an instance of <see cref="AudioMediaFormat"/> for equality.
@@ -258,8 +444,23 @@ namespace Tizen.Multimedia
                 return false;
             }
 
+            var mapCompare = true;
+            // We don't care the case of both properties are null.
+            if (AudioChannelMap != null && rhs.AudioChannelMap != null)
+            {
+                for (int i = 0; i < AudioChannelMap.Count; i++)
+                {
+                    mapCompare = AudioChannelMap[i].Equals(rhs.AudioChannelMap[i]);
+                }
+            }
+            else if ((AudioChannelMap == null && rhs.AudioChannelMap != null) ||
+                (AudioChannelMap != null && rhs.AudioChannelMap == null))
+            {
+                mapCompare = false;
+            }
+
             return MimeType == rhs.MimeType && Channel == rhs.Channel && SampleRate == rhs.SampleRate &&
-                Bit == rhs.Bit && BitRate == rhs.BitRate && AacType == rhs.AacType;
+                Bit == rhs.Bit && BitRate == rhs.BitRate && BitDepth == rhs.BitDepth && AacType == rhs.AacType && mapCompare;
         }
 
         /// <summary>
@@ -268,6 +469,6 @@ namespace Tizen.Multimedia
         /// <returns>The hash code for this instance of <see cref="AudioMediaFormat"/>.</returns>
         /// <since_tizen> 3 </since_tizen>
         public override int GetHashCode()
-            => new { MimeType, Channel, SampleRate, Bit, BitRate, AacType }.GetHashCode();
+            => new { MimeType, Channel, SampleRate, Bit, BitRate, BitDepth, AacType, AudioChannelMap }.GetHashCode();
     }
 }
diff --git a/src/Tizen.Multimedia/MediaTool/MediaFormatChannelPosition.cs b/src/Tizen.Multimedia/MediaTool/MediaFormatChannelPosition.cs
new file mode 100644 (file)
index 0000000..9e06ce6
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2019 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
+{
+    /// <summary>
+    /// Specifies the channel position of <see cref="MediaFormatAudioMimeType.Pcm"/> media format.
+    /// </summary>
+    /// <remarks>This type is based on SMPTE 2036-2-2008 standard.</remarks>
+    /// <seealso cref="MediaFormatAudioMimeType"/>
+    /// <since_tizen> 6 </since_tizen>
+    public enum MediaFormatAudioChannelPosition
+    {
+        /// <summary>
+        /// This is used for position-less channels.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        None = -3,
+
+        /// <summary>
+        /// Mono channel.
+        /// </summary>
+        /// <remarks>If user want to set this value, <see cref="AudioMediaFormat.Channel"/> should be 1.</remarks>
+        /// <since_tizen> 6 </since_tizen>
+        Mono = -2,
+
+        /// <summary>
+        /// Invalid position.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        Invaild = -1,
+
+        /// <summary>
+        /// A loudspeaker position located at far left and centered vertically with the middle layer.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        FrontLeft = 0,
+
+        /// <summary>
+        /// A loudspeaker position located at far right and centered vertically with the middle layer.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        FrontRight,
+
+        /// <summary>
+        /// A loudspeaker position located at the middle layer corresponding to the center of the television
+        /// screen as viewed from the seating area.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        FrontCenter,
+
+        /// <summary>
+        /// A Low Frequency Effects(band-limited low frequency channel) loudspeaker position located at
+        /// the bottom layer and normally far left front, when LFE2 is used.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        LFE1,
+
+        /// <summary>
+        /// A loudspeaker position located at far left back of the middle layer.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        BackLeft,
+
+        /// <summary>
+        /// A loudspeaker position located at far right back of the middle layer.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        BackRight,
+
+        /// <summary>
+        /// A loudspeaker position located mid-way between the front center and front left of the middle layer.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        FrontLeftOrCenter,
+
+        /// <summary>
+        /// A loudspeaker position located mid-way between the front center and front right of the middle layer.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        FrontRightOrCenter,
+
+        /// <summary>
+        /// A loudspeaker position located at center back of the middle layer.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        BackCenter,
+
+        /// <summary>
+        /// A Low Frequency Effects(band-limited low frequency channel) loudspeaker position located at the
+        /// bottom layer, and is normally at far right front of the bottom layer, when LFE1 is used. 
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        LFE2,
+
+        /// <summary>
+        /// A loudspeaker position located at left side of the middle layer.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        SideLeft,
+
+        /// <summary>
+        /// A loudspeaker position located at right side of the middle layer.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        SideRight,
+
+        /// <summary>
+        /// A loudspeaker position located at far left front of the top layer.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        TopFrontLeft,
+
+        /// <summary>
+        /// A loudspeaker position located at far right front of the top layer.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        TopFrontRight,
+
+        /// <summary>
+        /// A loudspeaker position located at center front of the top layer.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        TopFrontCenter,
+
+        /// <summary>
+        /// A loudspeaker position located at the center of the top layer directly above the seating area.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        TopCenter,
+
+        /// <summary>
+        /// A loudspeaker position located at far left back of the top layer.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        TopBackLeft,
+
+        /// <summary>
+        /// A loudspeaker position located at far right back of the top layer.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        TopBackRight,
+
+        /// <summary>
+        /// A loudspeaker position located at left side of the top layer.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        TopSideLeft,
+
+        /// <summary>
+        /// A loudspeaker position located at right side of the top layer.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        TopSideRight,
+
+        /// <summary>
+        /// A loudspeaker position located at center back of the top layer.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        TopBackCenter,
+
+        /// <summary>
+        /// A loudspeaker position located at center front of the bottom layer.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        BottomFrontCenter,
+
+        /// <summary>
+        /// A loudspeaker position located at far left front of the bottom layer.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        BottomFrontLeft,
+
+        /// <summary>
+        /// A loudspeaker position located at far right front of the bottom layer.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        BottomFrontRight,
+
+        /// <summary>
+        /// A loudspeaker position located between front left and side left.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        WideLeft,
+
+        /// <summary>
+        /// A loudspeaker position located between front right and side right.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        WideRight,
+
+        /// <summary>
+        /// A loudspeaker position located between back left and side left.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        SurroundLeft,
+
+        /// <summary>
+        /// A loudspeaker position located between back right and side right.
+        /// </summary>
+        /// <since_tizen> 6 </since_tizen>
+        SurroundRight
+    }
+}
index 5629119..94706d4 100644 (file)
@@ -19,6 +19,7 @@ using System.Diagnostics;
 using System.Runtime.InteropServices;
 using System.Threading;
 using Tizen.Internals.Errors;
+using Native = Tizen.Multimedia.Interop.MediaPacket;
 
 namespace Tizen.Multimedia
 {
@@ -136,14 +137,14 @@ namespace Tizen.Multimedia
 
             private void SetExtra(IntPtr ptr)
             {
-                int ret = Interop.MediaPacket.SetExtra(_packet._handle, ptr);
+                int ret = Native.SetExtra(_packet._handle, ptr);
 
                 MultimediaDebug.AssertNoError(ret);
             }
 
             private static IntPtr GetExtra(IntPtr handle)
             {
-                int ret = Interop.MediaPacket.GetExtra(handle, out var value);
+                int ret = Native.GetExtra(handle, out var value);
 
                 MultimediaDebug.AssertNoError(ret);
 
index 54ca5b1..43ba0c4 100644 (file)
@@ -16,9 +16,9 @@
 
 using System;
 using System.Diagnostics;
-using System.Runtime.InteropServices;
-using System.Threading;
 using Tizen.Internals.Errors;
+using Native = Tizen.Multimedia.Interop.MediaPacket;
+using NativeFormat = Tizen.Multimedia.Interop.MediaFormat;
 
 namespace Tizen.Multimedia
 {
@@ -59,7 +59,7 @@ namespace Tizen.Multimedia
         {
             _handle = handle;
 
-            int ret = Interop.MediaPacket.GetFormat(handle, out IntPtr formatHandle);
+            int ret = Native.GetFormat(handle, out IntPtr formatHandle);
 
             MultimediaDebug.AssertNoError(ret);
 
@@ -72,7 +72,7 @@ namespace Tizen.Multimedia
             }
             finally
             {
-                Interop.MediaFormat.Unref(formatHandle);
+                NativeFormat.Unref(formatHandle);
             }
         }
 
@@ -103,7 +103,7 @@ namespace Tizen.Multimedia
             {
                 formatHandle = format.AsNativeHandle();
 
-                int ret = Interop.MediaPacket.Create(formatHandle, IntPtr.Zero, IntPtr.Zero, out _handle);
+                int ret = Native.Create(formatHandle, IntPtr.Zero, IntPtr.Zero, out _handle);
                 MultimediaDebug.AssertNoError(ret);
 
                 Debug.Assert(_handle != IntPtr.Zero, "Created handle must not be null");
@@ -114,7 +114,7 @@ namespace Tizen.Multimedia
             {
                 if (_handle != IntPtr.Zero)
                 {
-                    Interop.MediaPacket.Destroy(_handle);
+                    Native.Destroy(_handle);
                     _handle = IntPtr.Zero;
                 }
 
@@ -124,7 +124,7 @@ namespace Tizen.Multimedia
             {
                 if (formatHandle != IntPtr.Zero)
                 {
-                    Interop.MediaFormat.Unref(formatHandle);
+                    NativeFormat.Unref(formatHandle);
                 }
             }
         }
@@ -135,7 +135,7 @@ namespace Tizen.Multimedia
         /// <exception cref="InvalidOperationException">Operation failed.</exception>
         private void Alloc()
         {
-            ErrorCode ret = (ErrorCode)Interop.MediaPacket.Alloc(_handle);
+            ErrorCode ret = (ErrorCode)Native.Alloc(_handle);
             if (ret == ErrorCode.None)
             {
                 return;
@@ -183,7 +183,7 @@ namespace Tizen.Multimedia
             {
                 ValidateNotDisposed();
 
-                int ret = Interop.MediaPacket.GetPts(_handle, out var value);
+                int ret = Native.GetPts(_handle, out var value);
 
                 MultimediaDebug.AssertNoError(ret);
 
@@ -194,7 +194,7 @@ namespace Tizen.Multimedia
                 ValidateNotDisposed();
                 ValidateNotLocked();
 
-                int ret = Interop.MediaPacket.SetPts(_handle, value);
+                int ret = Native.SetPts(_handle, value);
 
                 MultimediaDebug.AssertNoError(ret);
             }
@@ -214,7 +214,7 @@ namespace Tizen.Multimedia
             {
                 ValidateNotDisposed();
 
-                int ret = Interop.MediaPacket.GetDts(_handle, out var value);
+                int ret = Native.GetDts(_handle, out var value);
                 MultimediaDebug.AssertNoError(ret);
 
                 return value;
@@ -224,7 +224,7 @@ namespace Tizen.Multimedia
                 ValidateNotDisposed();
                 ValidateNotLocked();
 
-                int ret = Interop.MediaPacket.SetDts(_handle, value);
+                int ret = Native.SetDts(_handle, value);
                 MultimediaDebug.AssertNoError(ret);
             }
         }
@@ -243,7 +243,7 @@ namespace Tizen.Multimedia
             {
                 ValidateNotDisposed();
 
-                int ret = Interop.MediaPacket.GetDuration(_handle, out var value);
+                int ret = Native.GetDuration(_handle, out var value);
                 MultimediaDebug.AssertNoError(ret);
 
                 return value;
@@ -253,7 +253,7 @@ namespace Tizen.Multimedia
                 ValidateNotDisposed();
                 ValidateNotLocked();
 
-                int ret = Interop.MediaPacket.SetDuration(_handle, value);
+                int ret = Native.SetDuration(_handle, value);
                 MultimediaDebug.AssertNoError(ret);
             }
         }
@@ -270,7 +270,7 @@ namespace Tizen.Multimedia
             {
                 ValidateNotDisposed();
 
-                int ret = Interop.MediaPacket.IsEncoded(_handle, out var value);
+                int ret = Native.IsEncoded(_handle, out var value);
                 MultimediaDebug.AssertNoError(ret);
 
                 return value;
@@ -292,7 +292,7 @@ namespace Tizen.Multimedia
             {
                 ValidateNotDisposed();
 
-                int ret = Interop.MediaPacket.GetRotation(_handle, out var value);
+                int ret = Native.GetRotation(_handle, out var value);
                 MultimediaDebug.AssertNoError(ret);
 
                 var rotation = value < RotationFlip.HorizontalFlip ? (Rotation)value : Rotation.Rotate0;
@@ -305,7 +305,7 @@ namespace Tizen.Multimedia
                 ValidateNotLocked();
                 ValidationUtil.ValidateEnum(typeof(Rotation), value, nameof(value));
 
-                int ret = Interop.MediaPacket.SetRotation(_handle, (RotationFlip)value);
+                int ret = Native.SetRotation(_handle, (RotationFlip)value);
                 MultimediaDebug.AssertNoError(ret);
             }
         }
@@ -328,7 +328,7 @@ namespace Tizen.Multimedia
             {
                 ValidateNotDisposed();
 
-                int ret = Interop.MediaPacket.GetRotation(_handle, out var value);
+                int ret = Native.GetRotation(_handle, out var value);
                 MultimediaDebug.AssertNoError(ret);
 
                 var flip = (value < RotationFlip.HorizontalFlip) ? Flips.None :
@@ -349,7 +349,7 @@ namespace Tizen.Multimedia
 
                 var flip = value == Flips.Horizontal ? RotationFlip.HorizontalFlip : RotationFlip.VerticalFlip;
 
-                int ret = Interop.MediaPacket.SetRotation(_handle, flip);
+                int ret = Native.SetRotation(_handle, flip);
                 MultimediaDebug.AssertNoError(ret);
             }
         }
@@ -400,7 +400,7 @@ namespace Tizen.Multimedia
             {
                 ValidateNotDisposed();
 
-                int ret = Interop.MediaPacket.GetBufferSize(_handle, out var value);
+                int ret = Native.GetBufferSize(_handle, out var value);
                 MultimediaDebug.AssertNoError(ret);
 
                 Debug.Assert(value < int.MaxValue);
@@ -426,7 +426,7 @@ namespace Tizen.Multimedia
                         "value must be less than Buffer.Size.");
                 }
 
-                int ret = Interop.MediaPacket.SetBufferSize(_handle, (ulong)value);
+                int ret = Native.SetBufferSize(_handle, (ulong)value);
                 MultimediaDebug.AssertNoError(ret);
             }
         }
@@ -476,7 +476,7 @@ namespace Tizen.Multimedia
             {
                 ValidateNotDisposed();
 
-                int ret = Interop.MediaPacket.GetBufferFlags(_handle, out var value);
+                int ret = Native.GetBufferFlags(_handle, out var value);
 
                 MultimediaDebug.AssertNoError(ret);
 
@@ -488,11 +488,11 @@ namespace Tizen.Multimedia
                 ValidateNotDisposed();
                 ValidateNotLocked();
 
-                int ret = Interop.MediaPacket.ResetBufferFlags(_handle);
+                int ret = Native.ResetBufferFlags(_handle);
 
                 MultimediaDebug.AssertNoError(ret);
 
-                ret = Interop.MediaPacket.SetBufferFlags(_handle, (int)value);
+                ret = Native.SetBufferFlags(_handle, (int)value);
 
                 MultimediaDebug.AssertNoError(ret);
             }
@@ -543,7 +543,7 @@ namespace Tizen.Multimedia
 
             if (_handle != IntPtr.Zero)
             {
-                Interop.MediaPacket.Destroy(_handle);
+                Native.Destroy(_handle);
                 _handle = IntPtr.Zero;
             }
 
@@ -606,7 +606,7 @@ namespace Tizen.Multimedia
         {
             Debug.Assert(_handle != IntPtr.Zero, "The handle is invalid!");
 
-            int ret = Interop.MediaPacket.GetNumberOfVideoPlanes(_handle, out var numberOfPlanes);
+            int ret = Native.GetNumberOfVideoPlanes(_handle, out var numberOfPlanes);
 
             MultimediaDebug.AssertNoError(ret);
 
@@ -630,12 +630,12 @@ namespace Tizen.Multimedia
 
             Debug.Assert(_handle != IntPtr.Zero, "The handle is invalid!");
 
-            int ret = Interop.MediaPacket.GetBufferData(_handle, out var dataHandle);
+            int ret = Native.GetBufferData(_handle, out var dataHandle);
             MultimediaDebug.AssertNoError(ret);
 
             Debug.Assert(dataHandle != IntPtr.Zero, "Data handle is invalid!");
 
-            ret = Interop.MediaPacket.GetAllocatedBufferSize(_handle, out var size);
+            ret = Native.GetAllocatedBufferSize(_handle, out var size);
             MultimediaDebug.AssertNoError(ret);
 
             Debug.Assert(size >= 0, "size must not be negative!");
index a751126..31ffcb2 100644 (file)
@@ -16,6 +16,7 @@
 
 using System;
 using System.Diagnostics;
+using Native = Tizen.Multimedia.Interop.MediaPacket;
 
 namespace Tizen.Multimedia
 {
@@ -39,15 +40,15 @@ namespace Tizen.Multimedia
 
             _packet = packet;
 
-            int ret = Interop.MediaPacket.GetVideoStrideWidth(packet.GetHandle(), index, out _strideWidth);
+            int ret = Native.GetVideoStrideWidth(packet.GetHandle(), index, out _strideWidth);
             MultimediaDebug.AssertNoError(ret);
 
-            ret = Interop.MediaPacket.GetVideoStrideHeight(packet.GetHandle(), index, out _strideHeight);
+            ret = Native.GetVideoStrideHeight(packet.GetHandle(), index, out _strideHeight);
             MultimediaDebug.AssertNoError(ret);
 
             Debug.Assert(_strideWidth >= 0 && _strideHeight >= 0, "size must not be negative!");
 
-            ret = Interop.MediaPacket.GetVideoPlaneData(packet.GetHandle(), index, out var dataHandle);
+            ret = Native.GetVideoPlaneData(packet.GetHandle(), index, out var dataHandle);
             MultimediaDebug.AssertNoError(ret);
 
             Debug.Assert(dataHandle != IntPtr.Zero, "Data handle is invalid!");
diff --git a/test/Tizen.MachineLearning.Inference.Test/App.cs b/test/Tizen.MachineLearning.Inference.Test/App.cs
new file mode 100755 (executable)
index 0000000..3f4e518
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ *  Copyright (c) 2019 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 Log = Tizen.Log;
+using Xamarin.Forms;
+using Tizen.MachineLearning.Inference.Test;
+
+namespace XamarinForTizen.Tizen
+{
+    public class App : Application
+    {
+        Button btnPipeline;
+        Button btnSingle;
+        Button btnTensorsInfo;
+        Label lblResult;
+        
+        
+        public App()
+        {
+            btnPipeline = new Button
+            {
+                Text = "Pipeline Test",
+                HorizontalOptions = LayoutOptions.FillAndExpand,
+                VerticalOptions = LayoutOptions.StartAndExpand,
+            };
+            btnPipeline.Clicked += OnBtnPilelineClicked;
+
+            btnSingle = new Button
+            {
+                Text = "Single Test",
+                HorizontalOptions = LayoutOptions.FillAndExpand,
+                VerticalOptions = LayoutOptions.StartAndExpand,
+            };
+            btnSingle.Clicked += OnBtnSingleClicked;
+
+            btnTensorsInfo = new Button
+            {
+                Text = "TensorsInfo Test",
+                HorizontalOptions = LayoutOptions.FillAndExpand,
+                VerticalOptions = LayoutOptions.StartAndExpand,
+            };
+            btnTensorsInfo.Clicked += OnBtnTensorsInfoClicked;
+
+            lblResult = new Label
+            {
+                Text = "",
+                HorizontalOptions = LayoutOptions.FillAndExpand,
+            };
+            // The root page of your application
+            MainPage = new ContentPage
+            {
+                Content = new StackLayout
+                {
+                    VerticalOptions = LayoutOptions.Start,
+                    Children = {
+                        btnPipeline,
+                        btnSingle,
+                        btnTensorsInfo,
+                        lblResult,
+                    }
+                }
+            };
+        }
+
+        protected override void OnStart()
+        {
+            // Handle when your app starts
+        }
+
+        protected override void OnSleep()
+        {
+            // Handle when your app sleeps
+        }
+
+        protected override void OnResume()
+        {
+            // Handle when your app resumes
+        }
+
+        private void OnBtnPilelineClicked(object s, EventArgs e)
+        {
+            string retMsg = "";
+            retMsg += "Pipeline Test Started\n\n";
+
+            retMsg += "\nPipeline Test Done";
+
+            lblResult.Text = retMsg;
+        }
+
+        private void OnBtnSingleClicked(object s, EventArgs e)
+        {
+            string msg = "Single Test Started\n";
+
+            msg += "  * BasicSingleTest_Success00: ";
+            msg += SingleShotTest.BasicSingleTest_Success00() ? "OK\n" : "Failed\n";
+
+            msg += "Single Test is Done\n";
+
+            lblResult.Text = msg;
+        }
+
+        private void OnBtnTensorsInfoClicked(object s, EventArgs e)
+        {
+            string msg = "TensorsInfo Test Started\n";
+            
+            msg += "  * BasicTensorTest_Success00: ";
+            msg += TensorsInfoTest.BasicTensorTest_Success00() ? "OK\n" : "Failed\n";
+
+            msg += "  * BasicTensorTest_Success01: ";
+            msg += TensorsInfoTest.BasicTensorTest_Success01() ? "OK\n" : "Failed\n";
+
+            msg += "  * BasicTensorTest_Success02: ";
+            msg += TensorsInfoTest.BasicTensorTest_Success02() ? "OK\n" : "Failed\n";
+
+            lblResult.Text = msg;
+        }
+    }
+}
diff --git a/test/Tizen.MachineLearning.Inference.Test/Program.cs b/test/Tizen.MachineLearning.Inference.Test/Program.cs
new file mode 100755 (executable)
index 0000000..f8d0fb7
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ *  Copyright (c) 2019 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 XamarinForTizen.Tizen
+{
+    class Program : global::Xamarin.Forms.Platform.Tizen.FormsApplication
+    {
+        protected override void OnCreate()
+        {
+            base.OnCreate();
+
+            LoadApplication(new App());
+        }
+
+        static void Main(string[] args)
+        {
+            var app = new Program();
+            global::Xamarin.Forms.Platform.Tizen.Forms.Init(app);
+            app.Run(args);
+        }
+    }
+}
diff --git a/test/Tizen.MachineLearning.Inference.Test/SingleTest.cs b/test/Tizen.MachineLearning.Inference.Test/SingleTest.cs
new file mode 100755 (executable)
index 0000000..78c6b8b
--- /dev/null
@@ -0,0 +1,57 @@
+using System;
+using System.IO;
+using System.Text;
+using System.Threading.Tasks;
+using Tizen.MachineLearning.Inference;
+
+namespace Tizen.MachineLearning.Inference.Test
+{
+    class SingleShotTest
+    {
+        const string TAG = "ML.Inference.Test";
+        private static string ResourcePath = Tizen.Applications.Application.Current.DirectoryInfo.Resource;
+
+        public static bool BasicSingleTest_Success00()
+        {
+            byte[] in_buffer = new byte[3 * 224 * 224 * 1];
+            byte[] out_buffer;
+            string model_path = ResourcePath + "models/mobilenet_v1_1.0_224_quant.tflite";
+
+            TensorsInfo in_info;
+            TensorsInfo out_info;
+            TensorsData in_data;
+            TensorsData out_data;
+
+            /* Set input & output TensorsInfo */
+            in_info = new TensorsInfo();
+            in_info.AddTensorInfo(TensorType.UInt8, new int[4] { 3, 224, 224, 1 });
+
+            out_info = new TensorsInfo();
+            out_info.AddTensorInfo(TensorType.UInt8, new int[4] { 1001, 1, 1, 1 });
+
+            /* Create single inference engine */
+            SingleShot single = new SingleShot(model_path, in_info, out_info);
+
+            /* Set input data */
+            in_data = in_info.GetTensorsData();
+            in_data.SetTensorData(0, in_buffer);
+
+            /* Single shot invoke */
+            out_data = single.Invoke(in_data);
+
+            /* Get output data from TensorsData */
+            out_buffer = out_data.GetTensorData(0);
+
+            /* Release Single inference instance */
+            single.Dispose();
+
+            /* clean up */
+            in_data.Dispose();
+            out_data.Dispose();
+            in_info.Dispose();
+            out_info.Dispose();
+
+            return true;
+        }
+    }
+}
diff --git a/test/Tizen.MachineLearning.Inference.Test/TensorsInfoTest.cs b/test/Tizen.MachineLearning.Inference.Test/TensorsInfoTest.cs
new file mode 100755 (executable)
index 0000000..460e658
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2019 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.IO;
+using Tizen.MachineLearning.Inference;
+
+namespace Tizen.MachineLearning.Inference.Test
+{
+    public static class TensorsInfoTest
+    {
+        const string TAG = "Nnstreamer";
+
+        public static bool BasicTensorTest_Success00()
+        {
+            int[] in_dim = new int[4] { 3, 224, 224, 1 };
+
+            TensorsInfo tensorsInfo = new TensorsInfo();
+            tensorsInfo.AddTensorInfo(TensorType.UInt8, in_dim);
+
+            /* Check */
+            if (tensorsInfo.GetTensorType(0) != TensorType.UInt8)
+                return false;
+
+            int[] in_res = tensorsInfo.GetDimension(0);
+            for (int i = 0; i < 4; ++i)
+            {
+                if (in_dim[i] != in_res[i])
+                    return false;
+            }
+            return true;
+        }
+        public static bool BasicTensorTest_Success01()
+        {
+            TensorsInfo tensorsInfo;
+            TensorsData tensorsData;
+            int[] in_dim = new int[4] { 10, 1, 1, 1 };
+            byte[] buffer_in = new byte[] { 17, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
+            byte[] buffer_out;
+
+            tensorsInfo = new TensorsInfo();
+            tensorsInfo.AddTensorInfo(TensorType.UInt8, in_dim);
+            Log.Info(TAG, "Current Count: " + tensorsInfo.Count);
+
+            tensorsData = tensorsInfo.GetTensorsData();
+            tensorsData.SetTensorData(0, buffer_in);
+
+            buffer_out = tensorsData.GetTensorData(0);
+
+            if (buffer_in.Length != buffer_out.Length)
+            {
+                Log.Error(TAG, "The size of buffers is different");
+                return false;
+            }
+
+            for (int i = 0; i < buffer_in.Length; ++i)
+            {
+                if (buffer_in[i] != buffer_out[i])
+                {
+                    Log.Error(TAG, "The value of " + i.ToString() + " th element is different");
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        public static bool BasicTensorTest_Success02()
+        {
+            TensorsInfo tensorsInfo;
+            TensorsData tensorsData;
+            int[] in_dim = new int[4] { 10, 1, 1, 1 };
+            byte[] buffer_in = new byte[] { 17, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
+            byte[] buffer_out;
+
+            tensorsInfo = new TensorsInfo();
+            tensorsInfo.AddTensorInfo(TensorType.UInt8, in_dim);
+
+            tensorsData = tensorsInfo.GetTensorsData();
+            tensorsData.SetTensorData(0, buffer_in);
+            buffer_out = tensorsData.GetTensorData(0);
+
+            if (buffer_in.Length != buffer_out.Length)
+            {
+                Log.Error(TAG, "The size of buffers is different");
+                return false;
+            }
+
+            for (int i = 0; i < buffer_in.Length; ++i)
+            {
+                if (buffer_in[i] != buffer_out[i])
+                {
+                    Log.Error(TAG, "The value of " + i.ToString() + " th element is different");
+                    return false;
+                }
+            }
+            tensorsData.Dispose();
+
+            /* Add new tensor */
+            int[] in2_dim = new int[4] { 5, 1, 1, 1 };
+            byte[] buffer_in2 = new byte[] { 10, 20, 30, 40, 50 };
+            byte[] buffer_out2;
+
+
+            tensorsInfo.AddTensorInfo(TensorType.UInt8, in2_dim);
+
+            tensorsData = tensorsInfo.GetTensorsData();
+            tensorsData.SetTensorData(0, buffer_in);
+            buffer_out = tensorsData.GetTensorData(0);
+            tensorsData.SetTensorData(1, buffer_in2);
+            buffer_out2 = tensorsData.GetTensorData(1);
+
+            if (buffer_in2.Length != buffer_out2.Length)
+            {
+                Log.Error(TAG, "The size of buffers is different");
+                return false;
+            }
+
+            for (int i = 0; i < buffer_in2.Length; ++i)
+            {
+                if (buffer_in2[i] != buffer_out2[i])
+                {
+                    Log.Error(TAG, "The value of " + i.ToString() + " th element is different");
+                    return false;
+                }
+            }
+
+            return true;
+        }
+    }
+}
diff --git a/test/Tizen.MachineLearning.Inference.Test/Tizen.MachineLearning.Inference.Test.csproj b/test/Tizen.MachineLearning.Inference.Test/Tizen.MachineLearning.Inference.Test.csproj
new file mode 100755 (executable)
index 0000000..85e0af0
--- /dev/null
@@ -0,0 +1,29 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <!-- Property Group for Tizen50 Project -->
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>tizen60</TargetFramework>
+  </PropertyGroup>
+
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugType>portable</DebugType>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>None</DebugType>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <Folder Include="lib\" />
+    <Folder Include="res\" />
+  </ItemGroup>
+  
+
+  <!-- Include Nuget Package for Tizen Project building -->
+  <ItemGroup>
+    <PackageReference Include="Tizen.NET" Version="6.0.0.14863" />
+    <PackageReference Include="Tizen.NET.Sdk" Version="1.0.3" />
+    <PackageReference Include="Xamarin.Forms" Version="4.0.0.482894" />
+  </ItemGroup>
+
+</Project>
diff --git a/test/Tizen.MachineLearning.Inference.Test/Tizen.MachineLearning.Inference.Test.sln b/test/Tizen.MachineLearning.Inference.Test/Tizen.MachineLearning.Inference.Test.sln
new file mode 100755 (executable)
index 0000000..3df090c
--- /dev/null
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.28307.645
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen.MachineLearning.Inference.Test", "Tizen.MachineLearning.Inference.Test.csproj", "{55443533-832E-49A8-B8E4-1A4C07A97F87}"
+EndProject
+Global
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution
+               Debug|Any CPU = Debug|Any CPU
+               Release|Any CPU = Release|Any CPU
+       EndGlobalSection
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution
+               {55443533-832E-49A8-B8E4-1A4C07A97F87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {55443533-832E-49A8-B8E4-1A4C07A97F87}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {55443533-832E-49A8-B8E4-1A4C07A97F87}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {55443533-832E-49A8-B8E4-1A4C07A97F87}.Release|Any CPU.Build.0 = Release|Any CPU
+       EndGlobalSection
+       GlobalSection(SolutionProperties) = preSolution
+               HideSolutionNode = FALSE
+       EndGlobalSection
+       GlobalSection(ExtensibilityGlobals) = postSolution
+               SolutionGuid = {2EFA7F43-50B6-4153-8FE6-290DD0A33E80}
+       EndGlobalSection
+EndGlobal
diff --git a/test/Tizen.MachineLearning.Inference.Test/res/models/mobilenet_v1_1.0_224_quant.tflite b/test/Tizen.MachineLearning.Inference.Test/res/models/mobilenet_v1_1.0_224_quant.tflite
new file mode 100755 (executable)
index 0000000..9a81d7c
Binary files /dev/null and b/test/Tizen.MachineLearning.Inference.Test/res/models/mobilenet_v1_1.0_224_quant.tflite differ
diff --git a/test/Tizen.MachineLearning.Inference.Test/shared/res/Tizen.MachineLearning.Inference.Test.png b/test/Tizen.MachineLearning.Inference.Test/shared/res/Tizen.MachineLearning.Inference.Test.png
new file mode 100755 (executable)
index 0000000..9f3cb98
Binary files /dev/null and b/test/Tizen.MachineLearning.Inference.Test/shared/res/Tizen.MachineLearning.Inference.Test.png differ
diff --git a/test/Tizen.MachineLearning.Inference.Test/tizen-manifest.xml b/test/Tizen.MachineLearning.Inference.Test/tizen-manifest.xml
new file mode 100755 (executable)
index 0000000..468c117
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest package="org.tizen.machine.inference.Test" version="1.0.0" api-version="5" xmlns="http://tizen.org/ns/packages">
+    <profile name="mobile" />
+    <ui-application appid="org.tizen.machine.Inference.Test" exec="Tizen.MachineLearning.Inference.Test.dll" multiple="false" nodisplay="false" taskmanage="true" type="dotnet" launch_mode="single">
+        <label>Tizen.MachineLearning.Inference.Test.dll</label>
+        <icon>Tizen.MachineLearning.Inference.Test.png</icon>
+        <metadata key="http://tizen.org/metadata/prefer_dotnet_aot" value="true" />
+        <splash-screens />
+    </ui-application>
+    <shortcut-list />
+    <provides-appdefined-privileges />
+</manifest>