[MediaContent] Redesigned API. 69/144969/2
authorcoderhyme <jhyo.kim@samsung.com>
Sat, 19 Aug 2017 02:56:03 +0000 (11:56 +0900)
committerhj kim <backto.kim@samsung.com>
Tue, 22 Aug 2017 07:02:43 +0000 (07:02 +0000)
Change-Id: Ia7ba7d6040076b40d908a558682c4384433271ff
Signed-off-by: coderhyme <jhyo.kim@samsung.com>
79 files changed:
src/Tizen.Content.MediaContent/Interop/Interop.Album.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Interop/Interop.AudioInfo.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Interop/Interop.AudioInformation.cs [deleted file]
src/Tizen.Content.MediaContent/Interop/Interop.Bookmark.cs [moved from src/Tizen.Content.MediaContent/Interop/Interop.MediaBookmark.cs with 55% similarity, mode: 0644]
src/Tizen.Content.MediaContent/Interop/Interop.Common.cs [moved from src/Tizen.Content.MediaContent/Interop/Interop.Glib.cs with 73% similarity, mode: 0644]
src/Tizen.Content.MediaContent/Interop/Interop.Face.cs [moved from src/Tizen.Content.MediaContent/Interop/Interop.MediaFace.cs with 80% similarity, mode: 0644]
src/Tizen.Content.MediaContent/Interop/Interop.Filter.cs [moved from src/Tizen.Content.MediaContent/Interop/Interop.MediaFilter.cs with 50% similarity, mode: 0644]
src/Tizen.Content.MediaContent/Interop/Interop.Folder.cs [moved from src/Tizen.Content.MediaContent/Interop/Interop.MediaFolder.cs with 84% similarity, mode: 0644]
src/Tizen.Content.MediaContent/Interop/Interop.Group.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Interop/Interop.ImageInfo.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Interop/Interop.ImageInformation.cs [deleted file]
src/Tizen.Content.MediaContent/Interop/Interop.Libc.cs
src/Tizen.Content.MediaContent/Interop/Interop.Libraries.cs
src/Tizen.Content.MediaContent/Interop/Interop.MediaContent.cs
src/Tizen.Content.MediaContent/Interop/Interop.MediaContentHandle.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Interop/Interop.MediaGroup.cs [deleted file]
src/Tizen.Content.MediaContent/Interop/Interop.MediaInfo.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Interop/Interop.MediaInformation.cs [deleted file]
src/Tizen.Content.MediaContent/Interop/Interop.Playlist.cs [moved from src/Tizen.Content.MediaContent/Interop/Interop.MediaPlaylist.cs with 73% similarity, mode: 0644]
src/Tizen.Content.MediaContent/Interop/Interop.Storage.cs [moved from src/Tizen.Content.MediaContent/Interop/Interop.MediaStorage.cs with 65% similarity, mode: 0644]
src/Tizen.Content.MediaContent/Interop/Interop.Tag.cs [moved from src/Tizen.Content.MediaContent/Interop/Interop.MediaTag.cs with 67% similarity, mode: 0644]
src/Tizen.Content.MediaContent/Interop/Interop.VideoInfo.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Interop/Interop.VideoInformation.cs [deleted file]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent.csproj
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Album.cs
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/AlbumCommand.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/AudioInfo.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/AudioInformation.cs [deleted file]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Bookmark.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/BookmarkCommand.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Columns.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/CommandHelper.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentCollection.cs [deleted file]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentColumns.cs [deleted file]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentDatabase.cs [deleted file]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentEventArgs.cs [deleted file]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentFilter.cs [deleted file]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentManager.cs [deleted file]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Enums.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/EventArgs.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/FaceInfo.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/FaceInfoCommand.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/FaceRect.cs [deleted file]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Features.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Folder.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/FolderCommand.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Group.cs [deleted file]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ImageInfo.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ImageInformation.cs [deleted file]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/InteropHelper.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaBookmark.cs [deleted file]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaCommand.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaContentEnums.cs [deleted file]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaContentError.cs
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaDatabase.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaDatabaseException.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaFace.cs [deleted file]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaFolder.cs [deleted file]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaInfo.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaInfoColumnKey.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaInfoCommand.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaInfoUpdateValues.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaInformation.cs [deleted file]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/NamespaceDoc.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ObjectKeeper.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/PlayList.cs
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/PlaylistCommand.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/PlaylistMember.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/QueryArguments.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/RecordNotFoundException.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Rectangle.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Storage.cs
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/StorageCommand.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Tag.cs
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/TagCommand.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/UnsupportedContentException.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ValdiationUtil.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/VideoInfo.cs [new file with mode: 0644]
src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/VideoInformation.cs [deleted file]

diff --git a/src/Tizen.Content.MediaContent/Interop/Interop.Album.cs b/src/Tizen.Content.MediaContent/Interop/Interop.Album.cs
new file mode 100644 (file)
index 0000000..38bece8
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Content.MediaContent;
+
+internal static partial class Interop
+{
+    internal static partial class Album
+    {
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_album_get_album_count_from_db")]
+        internal static extern MediaContentError GetAlbumCountFromDb(FilterHandle filter, out int count);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_album_get_media_count_from_db")]
+        internal static extern MediaContentError GetMediaCountFromDb(int albumId, FilterHandle filter, out int count);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_album_destroy")]
+        internal static extern MediaContentError Destroy(IntPtr album);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_album_clone")]
+        internal static extern MediaContentError Clone(out IntPtr dst, IntPtr src);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_album_get_album_id")]
+        internal static extern MediaContentError GetId(IntPtr album, out int albumId);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_album_get_name")]
+        internal static extern MediaContentError GetName(IntPtr album, out IntPtr value);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_album_get_artist")]
+        internal static extern MediaContentError GetArtist(IntPtr album, out IntPtr value);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_album_get_album_art")]
+        internal static extern MediaContentError GetAlbumArt(IntPtr album, out IntPtr value);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_album_get_album_from_db")]
+        internal static extern MediaContentError GetAlbumFromDb(int albumId, out IntPtr album);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_album_foreach_album_from_db")]
+        internal static extern MediaContentError ForeachAlbumFromDb(FilterHandle filter,
+            Common.ItemCallback cb, IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_album_foreach_media_from_db")]
+        internal static extern MediaContentError ForeachMediaFromDb(int albumId, FilterHandle filter,
+            Common.ItemCallback callback, IntPtr userData = default(IntPtr));
+    }
+}
diff --git a/src/Tizen.Content.MediaContent/Interop/Interop.AudioInfo.cs b/src/Tizen.Content.MediaContent/Interop/Interop.AudioInfo.cs
new file mode 100644 (file)
index 0000000..f61f134
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Content.MediaContent;
+
+internal static partial class Interop
+{
+    internal static partial class AudioInfo
+    {
+        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_destroy", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError Destroy(IntPtr handle);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_album", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError GetAlbum(IntPtr handle, out IntPtr albumName);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_artist", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError GetArtist(IntPtr handle, out IntPtr artistName);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_album_artist", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError GetAlbumArtist(IntPtr handle, out IntPtr albumArtistName);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_genre", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError GetGenre(IntPtr handle, out IntPtr genreName);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_composer", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError GetComposer(IntPtr handle, out IntPtr composerName);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_year", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError GetYear(IntPtr handle, out IntPtr year);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_recorded_date", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError GetRecordedDate(IntPtr handle, out IntPtr recordedDate);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_copyright", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError GetCopyright(IntPtr handle, out IntPtr copyright);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_track_num", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError GetTrackNum(IntPtr handle, out IntPtr trackNum);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_bit_rate", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError GetBitRate(IntPtr handle, out int bitRate);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_bitpersample", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError GetBitPerSample(IntPtr handle, out int bitPerSample);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_sample_rate", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError GetSampleRate(IntPtr handle, out int sampleRate);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_channel", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError GetChannel(IntPtr handle, out int channel);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_duration", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError GetDuration(IntPtr handle, out int duration);
+    }
+}
diff --git a/src/Tizen.Content.MediaContent/Interop/Interop.AudioInformation.cs b/src/Tizen.Content.MediaContent/Interop/Interop.AudioInformation.cs
deleted file mode 100755 (executable)
index ccdf20c..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-using System;
-using System.Runtime.InteropServices;
-using Tizen.Content.MediaContent;
-
-internal static partial class Interop
-{
-    internal static partial class AudioInformation
-    {
-        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_destroy", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError Destroy(IntPtr media);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_clone", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError Clone(out SafeAudioInformationHandle dst, SafeAudioInformationHandle src);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_media_id", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetMediaId(SafeAudioInformationHandle audioInformationHandle, out IntPtr mediaId);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_album", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetAlbum(SafeAudioInformationHandle audioInformationHandle, out IntPtr albumName);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_artist", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetArtist(SafeAudioInformationHandle audioInformationHandle, out IntPtr artistName);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_album_artist", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetAlbumArtist(SafeAudioInformationHandle audioInformationHandle, out IntPtr albumArtistName);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_genre", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetGenre(SafeAudioInformationHandle audioInformationHandle, out IntPtr genreName);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_composer", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetComposer(SafeAudioInformationHandle audioInformationHandle, out IntPtr composerName);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_year", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetYear(SafeAudioInformationHandle audioInformationHandle, out IntPtr year);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_recorded_date", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetRecordedDate(SafeAudioInformationHandle audioInformationHandle, out IntPtr recordedDate);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_copyright", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetCopyright(SafeAudioInformationHandle audioInformationHandle, out IntPtr copyright);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_track_num", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetTrackNum(SafeAudioInformationHandle audioInformationHandle, out IntPtr trackNum);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_bit_rate", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetBitRate(SafeAudioInformationHandle audioInformationHandle, out int bitRate);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_bitpersample", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetBitPerSample(SafeAudioInformationHandle audioInformationHandle, out int bitPerSample);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_sample_rate", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetSampleRate(SafeAudioInformationHandle audioInformationHandle, out int sampleRate);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_channel", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetChannel(SafeAudioInformationHandle audioInformationHandle, out int channel);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_duration", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetDuration(SafeAudioInformationHandle audioInformationHandle, out int duration);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_played_count", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetPlayedCount(SafeAudioInformationHandle audioInformationHandle, out int playedCount);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_played_time", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetPlayedTime(SafeAudioInformationHandle audioInformationHandle, out int playedTime);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_get_played_position", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetPlayedPosition(SafeAudioInformationHandle audioInformationHandle, out int playedPosition);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_set_played_count", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError SetPlayedCount(SafeAudioInformationHandle audioInformationHandle, int playedCount);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_set_played_time", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError SetPlayedTime(SafeAudioInformationHandle audioInformationHandle, int playedTime);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_set_played_position", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError SetPlayedPosition(SafeAudioInformationHandle audioInformationHandle, int playedPosition);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "audio_meta_update_to_db", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError UpdateToDB(IntPtr audioInformationHandle);
-
-        internal sealed class SafeAudioInformationHandle : SafeHandle
-        {
-            public SafeAudioInformationHandle()
-                : base(IntPtr.Zero, true)
-            {
-            }
-
-            public override bool IsInvalid
-            {
-                get { return this.handle == IntPtr.Zero; }
-            }
-
-            protected override bool ReleaseHandle()
-            {
-                AudioInformation.Destroy(this.handle);
-                this.SetHandle(IntPtr.Zero);
-                return true;
-            }
-        }
-    }
-}
old mode 100755 (executable)
new mode 100644 (file)
similarity index 55%
rename from src/Tizen.Content.MediaContent/Interop/Interop.MediaBookmark.cs
rename to src/Tizen.Content.MediaContent/Interop/Interop.Bookmark.cs
index 6639fbb..3ea9f99
  * limitations under the License.
  */
 
-
 using System;
 using System.Runtime.InteropServices;
 using Tizen.Content.MediaContent;
 
 internal partial class Interop
 {
-    internal static partial class MediaBookmark
+    internal static partial class Bookmark
     {
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_bookmark_insert_to_db")]
-        internal static extern MediaContentError InsertToDb(string media_id, uint time, string thumbnail_path);
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_bookmark_create")]
+        internal static extern MediaContentError Create(string mediaId, int time, out IntPtr handle);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_bookmark_insert_to_db_v2")]
+        internal static extern MediaContentError Insert(IntPtr handle);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_bookmark_delete_from_db")]
-        internal static extern MediaContentError DeleteFromDb(int bookmark_id);
+        internal static extern MediaContentError Delete(int id);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_bookmark_get_bookmark_count_from_db")]
-        internal static extern MediaContentError GetBookmarkCountFromDb(IntPtr filter, out int bookmark_count);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_bookmark_clone")]
-        internal static extern MediaContentError Clone(out IntPtr dst, IntPtr src);
+        internal static extern MediaContentError GetCount(FilterHandle filter, out int count);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_bookmark_destroy")]
         internal static extern MediaContentError Destroy(IntPtr bookmark);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_bookmark_get_bookmark_id")]
-        internal static extern MediaContentError GetBookmarkId(IntPtr bookmark, out int bookmark_id);
+        internal static extern MediaContentError GetId(IntPtr bookmark, out int id);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_bookmark_get_marked_time")]
-        internal static extern MediaContentError GetMarkedTime(IntPtr bookmark, out uint marked_time);
+        internal static extern MediaContentError GetMarkedTime(IntPtr bookmark, out int time);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_bookmark_get_thumbnail_path")]
         internal static extern MediaContentError GetThumbnailPath(IntPtr bookmark, out IntPtr filePath);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_bookmark_set_thumbnail_path")]
+        internal static extern MediaContentError SetThumbnailPath(IntPtr bookmark, string filePath);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_bookmark_get_name")]
+        internal static extern MediaContentError GetName(IntPtr bookmark, out IntPtr name);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_bookmark_set_name")]
+        internal static extern MediaContentError SetName(IntPtr bookmark, string name);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_bookmark_foreach_bookmark_from_db")]
+        internal static extern MediaContentError ForeachFromDb(FilterHandle filter,
+            Common.ItemCallback callback, IntPtr userData = default(IntPtr));
     }
 }
old mode 100755 (executable)
new mode 100644 (file)
similarity index 73%
rename from src/Tizen.Content.MediaContent/Interop/Interop.Glib.cs
rename to src/Tizen.Content.MediaContent/Interop/Interop.Common.cs
index 81afefd..d6dc8a9
  * limitations under the License.
  */
 
-
 using System;
 using System.Runtime.InteropServices;
 
 internal static partial class Interop
 {
-    internal static partial class Glib
+    internal static partial class Common
     {
         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate bool GSourceFunc(IntPtr userData);
-
-        [DllImport(Libraries.Glib, EntryPoint = "g_idle_add", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern uint IdleAdd(GSourceFunc d, IntPtr data);
+        internal delegate bool ItemCallback(IntPtr itemHandle, IntPtr data);
     }
 }
old mode 100755 (executable)
new mode 100644 (file)
similarity index 80%
rename from src/Tizen.Content.MediaContent/Interop/Interop.MediaFace.cs
rename to src/Tizen.Content.MediaContent/Interop/Interop.Face.cs
index ce88a2c..ca3df6b
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-
 using System;
 using System.Runtime.InteropServices;
 using Tizen.Content.MediaContent;
@@ -30,39 +29,44 @@ internal static partial class Interop
         internal static extern MediaContentError Destroy(IntPtr face);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_face_get_face_id")]
-        internal static extern MediaContentError GetFaceId(IntPtr face, out IntPtr face_id);
+        internal static extern MediaContentError GetId(IntPtr face, out IntPtr faceId);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_face_get_media_id")]
-        internal static extern MediaContentError GetMediaId(IntPtr face, out IntPtr media_id);
+        internal static extern MediaContentError GetMediaId(IntPtr face, out IntPtr mediaId);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_face_get_face_rect")]
-        internal static extern MediaContentError GetFaceRect(IntPtr face, out int rect_x, out int rect_y, out int rect_w, out int IntPtr);
+        internal static extern MediaContentError GetFaceRect(IntPtr face,
+            out int x, out int y, out int w, out int h);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_face_get_orientation")]
-        internal static extern MediaContentError GetOrientation(IntPtr face, out int orientation);
+        internal static extern MediaContentError GetOrientation(IntPtr face, out Orientation orientation);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_face_get_tag")]
         internal static extern MediaContentError GetTag(IntPtr face, out IntPtr tag);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_face_create")]
-        internal static extern MediaContentError Create(string media_id, out IntPtr face);
+        internal static extern MediaContentError Create(string mediaId, out IntPtr face);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_face_set_face_rect")]
-        internal static extern MediaContentError SetFaceRect(IntPtr face, int rect_x, int rect_y, int rect_w, int IntPtr);
+        internal static extern MediaContentError SetFaceRect(IntPtr face, int x, int y, int w, int h);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_face_set_orientation")]
-        internal static extern MediaContentError SetOrientation(IntPtr face, int orientation);
+        internal static extern MediaContentError SetOrientation(IntPtr face, Orientation orientation);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_face_set_tag")]
         internal static extern MediaContentError SetTag(IntPtr face, string tag);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_face_insert_to_db")]
-        internal static extern MediaContentError InsertToDb(IntPtr face);
+        internal static extern MediaContentError InsertToDb(IntPtr handle);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_face_update_to_db")]
-        internal static extern MediaContentError UpdateToDb(IntPtr face);
+        internal static extern MediaContentError Update(IntPtr face);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_face_delete_from_db")]
-        internal static extern MediaContentError DeleteFromDb(string face_id);
+        internal static extern MediaContentError DeleteFromDb(string faceId);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_face_foreach_face_from_db")]
+        internal static extern MediaContentError ForeachFromDb(FilterHandle filter,
+            Common.ItemCallback callback, IntPtr userData = default(IntPtr));
     }
 }
old mode 100755 (executable)
new mode 100644 (file)
similarity index 50%
rename from src/Tizen.Content.MediaContent/Interop/Interop.MediaFilter.cs
rename to src/Tizen.Content.MediaContent/Interop/Interop.Filter.cs
index f66986b..d265681
@@ -14,9 +14,9 @@
  * limitations under the License.
  */
 
-
 using System;
 using System.Runtime.InteropServices;
+using Tizen;
 using Tizen.Content.MediaContent;
 
 internal static partial class Interop
@@ -24,33 +24,32 @@ internal static partial class Interop
     internal static partial class Filter
     {
         [DllImport(Libraries.MediaContent, EntryPoint = "media_filter_create")]
-        internal static extern MediaContentError Create(out IntPtr filter);
+        internal static extern MediaContentError Create(out FilterHandle filter);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_filter_destroy")]
         internal static extern MediaContentError Destroy(IntPtr filter);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_filter_set_offset")]
-        internal static extern MediaContentError SetOffset(IntPtr filter, int offset, int count);
+        internal static extern MediaContentError SetOffset(FilterHandle filter, int offset, int count);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_filter_set_condition")]
-        internal static extern MediaContentError SetCondition(IntPtr filter, string condition, ContentCollation type);
+        internal static extern MediaContentError SetCondition(FilterHandle filter, string condition,
+            Collation type);
 
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_filter_set_order")]
-        internal static extern MediaContentError SetOrder(IntPtr filter, ContentOrder order, string keyword, ContentCollation type);
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_filter_set_order_v2")]
+        internal static extern MediaContentError SetOrder(FilterHandle filter, string orderExpression);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_filter_set_storage")]
-        internal static extern MediaContentError SetStorage(IntPtr filter, string storageId);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_filter_get_offset")]
-        internal static extern MediaContentError GetOffset(IntPtr filter, out int offset, out int count);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_filter_get_condition")]
-        internal static extern MediaContentError GetCondition(IntPtr filter, out IntPtr condition, out ContentCollation type);
+        internal static extern MediaContentError SetStorage(FilterHandle filter, string storageId);
+    }
 
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_filter_get_order")]
-        internal static extern MediaContentError GetOrder(IntPtr filter, out ContentOrder order, out IntPtr keyword, out ContentCollation type);
+    internal class FilterHandle : MediaContentCriticalHandle
+    {
+        public static readonly FilterHandle Null = new FilterHandle();
 
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_filter_get_storage")]
-        internal static extern MediaContentError GetStorage(IntPtr filter, out IntPtr storageId);
+        protected override MediaContentError DestroyHandle()
+        {
+            return Filter.Destroy(handle);
+        }
     }
 }
old mode 100755 (executable)
new mode 100644 (file)
similarity index 84%
rename from src/Tizen.Content.MediaContent/Interop/Interop.MediaFolder.cs
rename to src/Tizen.Content.MediaContent/Interop/Interop.Folder.cs
index 8ba231d..dbd9890
@@ -24,10 +24,10 @@ internal static partial class Interop
     internal static partial class Folder
     {
         [DllImport(Libraries.MediaContent, EntryPoint = "media_folder_get_folder_count_from_db")]
-        internal static extern MediaContentError GetFolderCountFromDb(IntPtr filter, out int folder_count);
+        internal static extern MediaContentError GetFolderCountFromDb(FilterHandle filter, out int count);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_folder_get_media_count_from_db")]
-        internal static extern MediaContentError GetMediaCountFromDb(string folder_id, IntPtr filter, out int media_count);
+        internal static extern MediaContentError GetMediaCountFromDb(string folder_id, FilterHandle filter, out int count);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_folder_clone")]
         internal static extern MediaContentError Clone(out IntPtr dst, IntPtr src);
@@ -49,10 +49,10 @@ internal static partial class Interop
         internal static extern MediaContentError GetName(IntPtr folder, out IntPtr folder_name);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_folder_get_modified_time")]
-        internal static extern MediaContentError GetModifiedTime(IntPtr folder, out DateTime date);
+        internal static extern MediaContentError GetModifiedTime(IntPtr folder, out IntPtr date);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_folder_get_storage_type")]
-        internal static extern MediaContentError GetStorageType(IntPtr folder, out ContentStorageType storage_type);
+        internal static extern MediaContentError GetStorageType(IntPtr folder, out StorageType storage_type);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_folder_get_storage_id")]
         internal static extern MediaContentError GetStorageId(IntPtr folder, out IntPtr storage_id);
@@ -61,7 +61,7 @@ internal static partial class Interop
         internal static extern MediaContentError GetOrder(IntPtr folder, out int order);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_folder_get_folder_from_db")]
-        internal static extern MediaContentError GetFolderFromDb(string folder_id, out IntPtr folder);
+        internal static extern MediaContentError GetFolderFromDb(string id, out IntPtr folder);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_folder_set_name")]
         internal static extern MediaContentError SetName(IntPtr folder, string name);
@@ -72,16 +72,12 @@ internal static partial class Interop
         [DllImport(Libraries.MediaContent, EntryPoint = "media_folder_update_to_db")]
         internal static extern MediaContentError UpdateToDb(IntPtr folder);
 
-        //Callbacks
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate bool MediaFolderCallback(IntPtr folderHandle, IntPtr data);
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate bool MediaInfoCallback(IntPtr handle, IntPtr data);
-
         [DllImport(Libraries.MediaContent, EntryPoint = "media_folder_foreach_folder_from_db")]
-        internal static extern MediaContentError ForeachFolderFromDb(IntPtr filter, MediaFolderCallback callback, IntPtr user_data);
+        internal static extern MediaContentError ForeachFolderFromDb(FilterHandle filter,
+            Common.ItemCallback callback, IntPtr userData = default(IntPtr));
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_folder_foreach_media_from_db")]
-        internal static extern MediaContentError ForeachMediaFromDb(string folder_id, IntPtr filter, MediaInfoCallback callback, IntPtr user_data);
+        internal static extern MediaContentError ForeachMediaFromDb(string id, FilterHandle filter,
+            Common.ItemCallback callback, IntPtr user_data);
     }
 }
diff --git a/src/Tizen.Content.MediaContent/Interop/Interop.Group.cs b/src/Tizen.Content.MediaContent/Interop/Interop.Group.cs
new file mode 100644 (file)
index 0000000..f949364
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Content.MediaContent;
+
+internal static partial class Interop
+{
+    internal static partial class Group
+    {
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_group_get_group_count_from_db")]
+        internal static extern MediaContentError GetGroupCount(FilterHandle filter,
+            MediaInfoColumnKey group, out int count);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_group_get_media_count_from_db")]
+        internal static extern MediaContentError GetMediaCount(string groupName,
+            MediaInfoColumnKey groupType, FilterHandle filter, out int count);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate bool MediaGroupCallback(string groupName, IntPtr data);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_group_foreach_group_from_db")]
+        internal static extern MediaContentError ForeachGroup(FilterHandle filter,
+            MediaInfoColumnKey group, MediaGroupCallback callback, IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_group_foreach_media_from_db")]
+        internal static extern MediaContentError ForeachMedia(string groupName, MediaInfoColumnKey group,
+            FilterHandle filter, Common.ItemCallback callback, IntPtr userData = default(IntPtr));
+    }
+}
diff --git a/src/Tizen.Content.MediaContent/Interop/Interop.ImageInfo.cs b/src/Tizen.Content.MediaContent/Interop/Interop.ImageInfo.cs
new file mode 100644 (file)
index 0000000..c7d5ff8
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Content.MediaContent;
+
+internal static partial class Interop
+{
+    internal static partial class ImageInfo
+    {
+        [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_destroy", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError Destroy(IntPtr media);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_get_orientation", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError GetOrientation(IntPtr handle, out Orientation orientation);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_get_date_taken", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError GetDateTaken(IntPtr handle, out IntPtr dateTaken);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_get_burst_id", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError GetBurstId(IntPtr handle, out IntPtr burstId);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_get_exposure_time", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError GetExposureTime(IntPtr handle, out IntPtr exposureTime);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_get_fnumber", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError GetFNumber(IntPtr handle, out double fNumber);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_get_iso", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError GetISO(IntPtr handle, out int iso);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_get_model", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError GetModel(IntPtr handle, out IntPtr model);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_is_burst_shot", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError IsBurstShot(IntPtr handle, out bool isBurstShot);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_get_media_id", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError GetMediaId(IntPtr handle, out IntPtr mediaId);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_get_width", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError GetWidth(IntPtr handle, out int width);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_get_height", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError GetHeight(IntPtr handle, out int width);
+    }
+}
diff --git a/src/Tizen.Content.MediaContent/Interop/Interop.ImageInformation.cs b/src/Tizen.Content.MediaContent/Interop/Interop.ImageInformation.cs
deleted file mode 100755 (executable)
index cbcfffb..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-using System;
-using System.Runtime.InteropServices;
-using Tizen.Content.MediaContent;
-
-internal static partial class Interop
-{
-    internal static partial class ImageInformation
-    {
-        [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_destroy", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError Destroy(IntPtr media);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_clone", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError Clone(out SafeImageInformationHandle dst, SafeImageInformationHandle src);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_get_orientation", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetOrientation(SafeImageInformationHandle imageInformationHandle, out MediaContentOrientation orientation);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_get_date_taken", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetDateTaken(SafeImageInformationHandle imageInformationHandle, out IntPtr dateTaken);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_get_burst_id", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetBurstId(SafeImageInformationHandle imageInformationHandle, out IntPtr burstId);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_get_exposure_time", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetExposureTime(SafeImageInformationHandle imageInformationHandle, out IntPtr exposureTime);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_get_fnumber", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetFNumber(SafeImageInformationHandle imageInformationHandle, out double fNumber);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_get_iso", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetISO(SafeImageInformationHandle imageInformationHandle, out int iso);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_get_model", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetModel(SafeImageInformationHandle imageInformationHandle, out IntPtr model);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_is_burst_shot", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError IsBurstShot(SafeImageInformationHandle imageInformationHandle, out bool isBurstShot);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_set_orientation", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError SetOrientation(SafeImageInformationHandle imageInformationHandle, MediaContentOrientation orientation);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_get_media_id", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetMediaId(SafeImageInformationHandle imageInformationHandle, out IntPtr mediaId);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_get_width", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetWidth(SafeImageInformationHandle imageInformationHandle, out int width);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_get_height", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetHeight(SafeImageInformationHandle imageInformationHandle, out int width);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "image_meta_update_to_db", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError UpdateToDB(IntPtr imageInformationHandle);
-
-        internal sealed class SafeImageInformationHandle : SafeHandle
-        {
-            public SafeImageInformationHandle()
-                : base(IntPtr.Zero, true)
-            {
-            }
-
-            public override bool IsInvalid
-            {
-                get { return this.handle == IntPtr.Zero; }
-            }
-
-            protected override bool ReleaseHandle()
-            {
-                ImageInformation.Destroy(this.handle);
-                this.SetHandle(IntPtr.Zero);
-                return true;
-            }
-        }
-    }
-}
index c9e7ff8..825599e 100755 (executable)
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-
 using System;
 using System.Runtime.InteropServices;
 
index a2d161e..67fdba7 100755 (executable)
  * limitations under the License.
  */
 
-
 internal static partial class Interop
 {
     internal static partial class Libraries
     {
         public const string MediaContent = "libcapi-content-media-content.so.0";
-        public const string Glib = "libglib-2.0.so.0";
         public const string Libc = "libc.so.6";
     }
 }
index 02205f1..a90817c 100755 (executable)
  * limitations under the License.
  */
 
-
 using System;
 using System.Runtime.InteropServices;
 using Tizen.Content.MediaContent;
 
-
 internal static partial class Interop
 {
     internal static partial class Content
@@ -36,19 +34,22 @@ internal static partial class Interop
         [DllImport(Libraries.MediaContent, EntryPoint = "media_content_cancel_scan_folder")]
         internal static extern MediaContentError CancelScanFolder(string folderPath);
 
-        // Callback
         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
         internal delegate void MediaScanCompletedCallback(MediaContentError error, IntPtr data);
+
         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate void MediaContentDBUpdatedCallback(MediaContentError error, int pid, MediaContentUpdateItemType updateItem, MediaContentDBUpdateType updateType, MediaContentType mediaType, string uuid, string filePath, string mimeType, IntPtr data);
+        internal delegate void MediaContentDBUpdatedCallback(MediaContentError error, int pid, ItemType updateItem,
+            OperationType updateType, MediaType mediaType, string uuid, string filePath, string mimeType, IntPtr data);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_content_scan_folder")]
-        internal static extern MediaContentError ScanFolder(string folderPath, bool is_recursive, MediaScanCompletedCallback scanCompletedCallback, IntPtr userData);
+        internal static extern MediaContentError ScanFolder(string folderPath,
+            bool recursive, MediaScanCompletedCallback scanCompletedCallback, IntPtr userData = default(IntPtr));
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_content_add_db_updated_cb")]
-        internal static extern MediaContentError AddDbUpdatedCb(MediaContentDBUpdatedCallback mediaContentDBUpdatedCallback, IntPtr userData, out IntPtr noti_handle);
+        internal static extern MediaContentError AddDbUpdatedCb(MediaContentDBUpdatedCallback mediaContentDBUpdatedCallback,
+            IntPtr userData, out IntPtr notiHandle);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_content_remove_db_updated_cb")]
-        internal static extern MediaContentError RemoveDbUpdatedCb(IntPtr noti_handle);
+        internal static extern MediaContentError RemoveDbUpdatedCb(IntPtr notiHandle);
     }
 }
diff --git a/src/Tizen.Content.MediaContent/Interop/Interop.MediaContentHandle.cs b/src/Tizen.Content.MediaContent/Interop/Interop.MediaContentHandle.cs
new file mode 100644 (file)
index 0000000..09c8481
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen;
+using Tizen.Content.MediaContent;
+
+internal static partial class Interop
+{
+    internal abstract class MediaContentCriticalHandle : CriticalHandle
+    {
+        public MediaContentCriticalHandle() : base(IntPtr.Zero)
+        {
+        }
+
+        public override bool IsInvalid => handle == IntPtr.Zero;
+
+        protected override bool ReleaseHandle()
+        {
+            var result = DestroyHandle();
+            if (result != MediaContentError.None)
+            {
+                Log.Error(GetType().Name, $"Failed to destroy handle : {result}");
+                return false;
+            }
+
+            return true;
+        }
+
+        protected abstract MediaContentError DestroyHandle();
+    }
+}
diff --git a/src/Tizen.Content.MediaContent/Interop/Interop.MediaGroup.cs b/src/Tizen.Content.MediaContent/Interop/Interop.MediaGroup.cs
deleted file mode 100755 (executable)
index c879bcc..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-using System;
-using System.Runtime.InteropServices;
-using Tizen.Content.MediaContent;
-
-internal static partial class Interop
-{
-    internal static partial class Group
-    {
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_album_get_album_count_from_db")]
-        internal static extern MediaContentError MediaAlbumGetAlbumCountFromDb(IntPtr filter, out int album_count);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_album_get_media_count_from_db")]
-        internal static extern MediaContentError MediaAlbumGetMediaCountFromDb(int album_id, IntPtr filter, out int media_count);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_album_destroy")]
-        internal static extern MediaContentError MediaAlbumDestroy(IntPtr album);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_album_clone")]
-        internal static extern MediaContentError MediaAlbumClone(out IntPtr dst, IntPtr src);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_album_get_album_id")]
-        internal static extern MediaContentError MediaAlbumGetAlbumId(IntPtr album, out int album_id);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_album_get_name")]
-        internal static extern MediaContentError MediaAlbumGetName(IntPtr album, out IntPtr album_name);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_album_get_artist")]
-        internal static extern MediaContentError MediaAlbumGetArtist(IntPtr album, out IntPtr artist);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_album_get_album_art")]
-        internal static extern MediaContentError MediaAlbumGetAlbumArt(IntPtr album, out IntPtr album_art);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_album_get_album_from_db")]
-        internal static extern MediaContentError MediaAlbumGetAlbumFromDb(int album_id, out IntPtr album);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_group_get_group_count_from_db")]
-        internal static extern MediaContentError GetGroupCountFromDb(IntPtr filter, MediaGroupType group, out int group_count);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_group_get_media_count_from_db")]
-        internal static extern MediaContentError GetMediaCountFromDb(string group_name, MediaGroupType group, IntPtr filter, out int media_count);
-
-        //Callbacks
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate bool MediaInfoCallback(IntPtr mediaInformation, IntPtr data);
-
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate bool MediaGroupCallback(string groupName, IntPtr data);
-
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate bool MediaAlbumCallback(IntPtr albumHandle, IntPtr data);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_album_foreach_album_from_db")]
-        internal static extern MediaContentError MediaAlbumForeachAlbumFromDb(IntPtr filter, MediaAlbumCallback callback, IntPtr user_data);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_album_foreach_media_from_db")]
-        internal static extern MediaContentError MediaAlbumForeachMediaFromDb(int albumId, IntPtr filter, MediaInfoCallback callback, IntPtr user_data);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_group_foreach_group_from_db")]
-        internal static extern MediaContentError ForeachGroupFromDb(IntPtr filter, MediaGroupType group, MediaGroupCallback callback, IntPtr user_data);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_group_foreach_media_from_db")]
-        internal static extern MediaContentError ForeachMediaFromDb(string groupName, MediaGroupType group, IntPtr filter, MediaInfoCallback callback, IntPtr user_data);
-    }
-}
diff --git a/src/Tizen.Content.MediaContent/Interop/Interop.MediaInfo.cs b/src/Tizen.Content.MediaContent/Interop/Interop.MediaInfo.cs
new file mode 100644 (file)
index 0000000..244e98a
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Content.MediaContent;
+
+internal static partial class Interop
+{
+    internal static partial class MediaInfo
+    {
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void ThumbnailCompletedCallback(MediaContentError error, string filePath, IntPtr userData);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void FaceDetectionCompletedCallback(MediaContentError error, int count, IntPtr userData);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void InsertCompletedCallback(MediaContentError error, IntPtr userData);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void InsertBurstShotCompletedCallback(MediaContentError error, IntPtr userData);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_insert_to_db")]
+        internal static extern MediaContentError Insert(string filePath, out MediaInfoHandle info);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_insert_batch_to_db")]
+        internal static extern MediaContentError BatchInsert(string[] filePathArray, int arrayLength,
+            InsertCompletedCallback callback, IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_insert_burst_shot_to_db")]
+        internal static extern MediaContentError BurstShotInsert(string[] filePathArray, int arrayLength,
+            InsertBurstShotCompletedCallback callback, IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_delete_from_db")]
+        internal static extern MediaContentError Delete(string mediaId);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_delete_batch_from_db")]
+        internal static extern MediaContentError BatchDelete(FilterHandle filter);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_destroy")]
+        internal static extern MediaContentError Destroy(IntPtr handle);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_media_count_from_db")]
+        internal static extern MediaContentError GetMediaCount(FilterHandle filter, out int mediaCount);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_foreach_media_from_db")]
+        internal static extern MediaContentError ForeachMedia(FilterHandle filter, Common.ItemCallback callback,
+            IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_tag_count_from_db")]
+        internal static extern MediaContentError GetTagCount(string mediaId, FilterHandle filter, out int tagCount);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_foreach_tag_from_db")]
+        internal static extern MediaContentError ForeachTags(string mediaId, FilterHandle filter,
+            Common.ItemCallback callback, IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_bookmark_count_from_db")]
+        internal static extern MediaContentError GetBookmarkCount(string mediaId, FilterHandle filter, out int bookmarkCount);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_foreach_bookmark_from_db")]
+        internal static extern MediaContentError ForeachBookmarks(string mediaId, FilterHandle filter,
+            Common.ItemCallback callback, IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_face_count_from_db")]
+        internal static extern MediaContentError GetFaceCount(string mediaId, FilterHandle filter, out int bookmarkCount);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_foreach_face_from_db")]
+        internal static extern MediaContentError ForeachFaces(string mediaId, FilterHandle filter,
+            Common.ItemCallback callback, IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_image")]
+        internal static extern MediaContentError GetImage(MediaInfoHandle handle, out IntPtr imageHandle);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_video")]
+        internal static extern MediaContentError GetVideo(MediaInfoHandle handle, out IntPtr videoHandle);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_audio")]
+        internal static extern MediaContentError GetAudio(MediaInfoHandle handle, out IntPtr audioHandle);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_media_id")]
+        internal static extern MediaContentError GetMediaId(MediaInfoHandle mediaInformationHandle, out IntPtr mediaId);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_file_path")]
+        internal static extern MediaContentError GetFilePath(MediaInfoHandle mediaInformationHandle, out IntPtr filePath);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_display_name")]
+        internal static extern MediaContentError GetDisplayName(MediaInfoHandle mediaInformationHandle, out IntPtr name);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_media_type")]
+        internal static extern MediaContentError GetMediaType(MediaInfoHandle mediaInformationHandle, out MediaType type);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_mime_type")]
+        internal static extern MediaContentError GetMimeType(MediaInfoHandle mediaInformationHandle, out IntPtr mimeType);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_size")]
+        internal static extern MediaContentError GetSize(MediaInfoHandle mediaInformationHandle, out long size);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_added_time")]
+        internal static extern MediaContentError GetAddedTime(MediaInfoHandle handle, out IntPtr posixTime);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_modified_time")]
+        internal static extern MediaContentError GetModifiedTime(MediaInfoHandle handle, out IntPtr posixTime);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_timeline")]
+        internal static extern MediaContentError GetTimeline(MediaInfoHandle handle, out IntPtr posixTime);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_thumbnail_path")]
+        internal static extern MediaContentError GetThumbnailPath(MediaInfoHandle mediaInformationHandle, out IntPtr filePath);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_description")]
+        internal static extern MediaContentError GetDescription(MediaInfoHandle mediaInformationHandle, out IntPtr description);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_longitude")]
+        internal static extern MediaContentError GetLongitude(MediaInfoHandle mediaInformationHandle, out double longitude);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_latitude")]
+        internal static extern MediaContentError GetLatitude(MediaInfoHandle mediaInformationHandle, out double latitude);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_altitude")]
+        internal static extern MediaContentError GetAltitude(MediaInfoHandle mediaInformationHandle, out double altitude);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_weather")]
+        internal static extern MediaContentError GetWeather(MediaInfoHandle mediaInformationHandle, out IntPtr weather);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_rating")]
+        internal static extern MediaContentError GetRating(MediaInfoHandle mediaInformationHandle, out int rating);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_favorite")]
+        internal static extern MediaContentError GetFavorite(MediaInfoHandle mediaInformationHandle, out bool favorite);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_provider")]
+        internal static extern MediaContentError GetProvider(MediaInfoHandle mediaInformationHandle, out IntPtr provider);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_title")]
+        internal static extern MediaContentError GetTitle(MediaInfoHandle mediaInformationHandle, out IntPtr title);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_category")]
+        internal static extern MediaContentError GetCategory(MediaInfoHandle mediaInformationHandle, out IntPtr category);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_location_tag")]
+        internal static extern MediaContentError GetLocationTag(MediaInfoHandle mediaInformationHandle, out IntPtr locationTag);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_age_rating")]
+        internal static extern MediaContentError GetAgeRating(MediaInfoHandle mediaInformationHandle, out IntPtr ageRating);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_storage_id")]
+        internal static extern MediaContentError GetStorageId(MediaInfoHandle mediaInformationHandle, out IntPtr storageId);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_is_drm")]
+        internal static extern MediaContentError IsDrm(MediaInfoHandle mediaInformationHandle, out bool isDrm);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_storage_type")]
+        internal static extern MediaContentError GetStorageType(MediaInfoHandle mediaInformationHandle, out StorageType storageType);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_media_from_db")]
+        internal static extern MediaContentError GetMediaFromDB(string mediaId, out MediaInfoHandle handle);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_weather")]
+        internal static extern MediaContentError SetWeather(MediaInfoHandle mediaInformationHandle, string weather);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_favorite")]
+        internal static extern MediaContentError SetFavorite(MediaInfoHandle mediaInformationHandle, bool favorite);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_provider")]
+        internal static extern MediaContentError SetProvider(MediaInfoHandle mediaInformationHandle, string provider);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_category")]
+        internal static extern MediaContentError SetCategory(MediaInfoHandle mediaInformationHandle, string category);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_location_tag")]
+        internal static extern MediaContentError SetLocationTag(MediaInfoHandle mediaInformationHandle, string locationTag);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_age_rating")]
+        internal static extern MediaContentError SetAgeRating(MediaInfoHandle mediaInformationHandle, string ageRating);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_update_to_db")]
+        internal static extern MediaContentError UpdateToDB(MediaInfoHandle mediaInformationHandle);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_move_to_db")]
+        internal static extern MediaContentError MoveToDB(MediaInfoHandle mediaInformationHandle, string dstPath);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_create_thumbnail")]
+        internal static extern MediaContentError CreateThumbnail(MediaInfoHandle handle,
+            ThumbnailCompletedCallback callback, IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_cancel_thumbnail")]
+        internal static extern MediaContentError CancelThumbnail(MediaInfoHandle mediaInformationHandle);
+
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_start_face_detection")]
+        internal static extern MediaContentError StartFaceDetection(MediaInfoHandle handle,
+            FaceDetectionCompletedCallback callback, IntPtr userData = default(IntPtr));
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_cancel_face_detection")]
+        internal static extern MediaContentError CancelFaceDetection(MediaInfoHandle handle);
+    }
+
+    internal sealed class MediaInfoHandle : SafeHandle
+    {
+        public MediaInfoHandle()
+            : base(IntPtr.Zero, true)
+        {
+        }
+
+        public MediaInfoHandle(IntPtr handle)
+            : this()
+        {
+            SetHandle(handle);
+        }
+
+        public override bool IsInvalid
+        {
+            get { return handle == IntPtr.Zero; }
+        }
+
+        protected override bool ReleaseHandle()
+        {
+            MediaInfo.Destroy(handle);
+            return true;
+        }
+    }
+}
diff --git a/src/Tizen.Content.MediaContent/Interop/Interop.MediaInformation.cs b/src/Tizen.Content.MediaContent/Interop/Interop.MediaInformation.cs
deleted file mode 100755 (executable)
index 5d994fc..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-using System;
-using System.Runtime.InteropServices;
-using Tizen.Content.MediaContent;
-
-internal static partial class Interop
-{
-    internal static partial class MediaInformation
-    {
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate void MediaThumbnailCompletedCallback(MediaContentError error, string filePath, IntPtr UserData);
-
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate bool MediaTagCallback(IntPtr tagHandle, IntPtr UserData);
-
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate bool MediaBookmarkCallback(IntPtr bookmarkHandle, IntPtr UserData);
-
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate bool MediaFaceCallback(IntPtr bookmarkHandle, IntPtr UserData);
-
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate void MediaInsertCompletedCallback(MediaContentError error, IntPtr UserData);
-
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate void MediaInsertBurstShotCompletedCallback(MediaContentError error, IntPtr UserData);
-
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate bool MediaInformationCallback(IntPtr mediaInformationHandle, IntPtr UserData);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_insert_to_db", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError Insert(string filePath, out SafeMediaInformationHandle info);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_insert_batch_to_db", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError BatchInsert(string[] filePathArray, int arrayLength, MediaInsertCompletedCallback callback, IntPtr userData);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_insert_burst_shot_to_db", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError BurstShotInsert(string[] filePathArray, int arrayLength, MediaInsertBurstShotCompletedCallback callback, IntPtr userData);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_delete_from_db", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError Delete(string mediaId);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_delete_batch_from_db", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError BatchDelete(IntPtr filter);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_destroy", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError Destroy(IntPtr mediaInformationHandle);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_clone", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError Clone(out SafeMediaInformationHandle dst, IntPtr src);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_media_count_from_db", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetMediaCount(IntPtr filter, out int mediaCount);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_foreach_media_from_db", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetAllMedia(IntPtr filter, MediaInformationCallback callback, IntPtr userData);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_tag_count_from_db", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetTagCount(string mediaId, IntPtr filter, out int tagCount);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_foreach_tag_from_db", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetAllTags(string mediaId, IntPtr filter, MediaTagCallback callback, IntPtr userData);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_bookmark_count_from_db", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetBookmarkCount(string mediaId, IntPtr filter, out int bookmarkCount);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_foreach_bookmark_from_db", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetAllBookmarks(string mediaId, IntPtr filter, MediaBookmarkCallback callback, IntPtr userData);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_face_count_from_db", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetFaceCount(string mediaId, IntPtr filter, out int bookmarkCount);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_foreach_face_from_db", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetAllFaces(string mediaId, IntPtr filter, MediaFaceCallback callback, IntPtr userData);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_image", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetImage(IntPtr mediaInformationHandle, out Interop.ImageInformation.SafeImageInformationHandle image);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_video", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetVideo(IntPtr mediaInformationHandle, out Interop.VideoInformation.SafeVideoInformationHandle video);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_audio", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetAudio(IntPtr mediaInformationHandle, out Interop.AudioInformation.SafeAudioInformationHandle audio);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_media_id", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetMediaId(SafeMediaInformationHandle mediaInformationHandle, out IntPtr mediaId);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_file_path", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetFilePath(SafeMediaInformationHandle mediaInformationHandle, out IntPtr filePath);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_display_name", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetDisplayName(SafeMediaInformationHandle mediaInformationHandle, out IntPtr name);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_media_type", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetMediaType(SafeMediaInformationHandle mediaInformationHandle, out MediaContentType type);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_mime_type", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetMimeType(SafeMediaInformationHandle mediaInformationHandle, out IntPtr mimeType);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_size", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetSize(SafeMediaInformationHandle mediaInformationHandle, out long size);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_added_time", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetAddedTime(SafeMediaInformationHandle mediaInformationHandle, out int addedTime);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_modified_time", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetModifiedTime(SafeMediaInformationHandle mediaInformationHandle, out int time);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_timeline", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetTimeline(SafeMediaInformationHandle mediaInformationHandle, out int time);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_thumbnail_path", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetThumbnailPath(SafeMediaInformationHandle mediaInformationHandle, out IntPtr filePath);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_description", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetDescription(SafeMediaInformationHandle mediaInformationHandle, out IntPtr description);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_longitude", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetLongitude(SafeMediaInformationHandle mediaInformationHandle, out double longitude);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_latitude", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetLatitude(SafeMediaInformationHandle mediaInformationHandle, out double latitude);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_altitude", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetAltitude(SafeMediaInformationHandle mediaInformationHandle, out double altitude);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_weather", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetWeather(SafeMediaInformationHandle mediaInformationHandle, out IntPtr weather);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_rating", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetRating(SafeMediaInformationHandle mediaInformationHandle, out int rating);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_favorite", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetFavorite(SafeMediaInformationHandle mediaInformationHandle, out bool favorite);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_author", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetAuthor(SafeMediaInformationHandle mediaInformationHandle, out IntPtr author);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_provider", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetProvider(SafeMediaInformationHandle mediaInformationHandle, out IntPtr provider);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_content_name", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetContentName(SafeMediaInformationHandle mediaInformationHandle, out IntPtr contentName);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_title", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetTitle(SafeMediaInformationHandle mediaInformationHandle, out IntPtr title);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_category", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetCategory(SafeMediaInformationHandle mediaInformationHandle, out IntPtr category);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_location_tag", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetLocationTag(SafeMediaInformationHandle mediaInformationHandle, out IntPtr locationTag);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_age_rating", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetAgeRating(SafeMediaInformationHandle mediaInformationHandle, out IntPtr ageRating);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_keyword", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetKeyword(SafeMediaInformationHandle mediaInformationHandle, out IntPtr keyword);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_storage_id", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetStorageId(SafeMediaInformationHandle mediaInformationHandle, out IntPtr storageId);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_is_drm", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError IsDrm(SafeMediaInformationHandle mediaInformationHandle, out bool isDrm);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_storage_type", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetStorageType(SafeMediaInformationHandle mediaInformationHandle, out ContentStorageType storageType);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_played_count", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetPlayedCount(SafeMediaInformationHandle mediaInformationHandle, out int playedCount);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_played_time", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetPlayedAt(SafeMediaInformationHandle mediaInformationHandle, out int playedTime);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_get_media_from_db", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetMediaFromDB(string mediaId, out SafeMediaInformationHandle mediaInformationHandle);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_increase_played_count", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError IncreasePlayedCount(SafeMediaInformationHandle mediaInformationHandle);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_played_time", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError SetPlayedAt(SafeMediaInformationHandle mediaInformationHandle);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_display_name", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError SetDisplayName(SafeMediaInformationHandle mediaInformationHandle, string displayName);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_description", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError SetDescription(SafeMediaInformationHandle mediaInformationHandle, string description);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_longitude", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError SetLongitude(SafeMediaInformationHandle mediaInformationHandle, double longitude);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_latitude", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError SetLatitude(SafeMediaInformationHandle mediaInformationHandle, double latitude);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_altitude", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError SetAltitude(SafeMediaInformationHandle mediaInformationHandle, double altitude);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_weather", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError SetWeather(SafeMediaInformationHandle mediaInformationHandle, string weather);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_rating", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError SetRating(SafeMediaInformationHandle mediaInformationHandle, int rating);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_favorite", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError SetFavorite(SafeMediaInformationHandle mediaInformationHandle, bool favorite);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_author", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError SetAuthor(SafeMediaInformationHandle mediaInformationHandle, string author);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_provider", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError SetProvider(SafeMediaInformationHandle mediaInformationHandle, string provider);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_content_name", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError SetContentName(SafeMediaInformationHandle mediaInformationHandle, string contentName);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_category", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError SetCategory(SafeMediaInformationHandle mediaInformationHandle, string category);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_location_tag", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError SetLocationTag(SafeMediaInformationHandle mediaInformationHandle, string locationTag);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_age_rating", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError SetAgeRating(SafeMediaInformationHandle mediaInformationHandle, string ageRating);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_keyword", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError SetKeyword(SafeMediaInformationHandle mediaInformationHandle, string keyword);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_update_to_db", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError UpdateToDB(IntPtr mediaInformationHandle);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_refresh_metadata_to_db", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError RefreshMetadataToDB(string mediaId);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_set_added_time", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError SetAddedTime(SafeMediaInformationHandle mediaInformationHandle, int addedTime);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_move_to_db", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError MoveToDB(SafeMediaInformationHandle mediaInformationHandle, string dstPath);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_create_thumbnail", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError CreateThumbnail(SafeMediaInformationHandle mediaInformationHandle, MediaThumbnailCompletedCallback callback, IntPtr userData);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_info_cancel_thumbnail", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError CancelThumbnail(SafeMediaInformationHandle mediaInformationHandle);
-
-        internal sealed class SafeMediaInformationHandle : SafeHandle
-        {
-            public SafeMediaInformationHandle(IntPtr handle)
-                : base(handle, true)
-            {
-            }
-            public SafeMediaInformationHandle()
-                : base(IntPtr.Zero, true)
-            {
-            }
-
-            public override bool IsInvalid
-            {
-                get { return this.handle == IntPtr.Zero; }
-            }
-
-            protected override bool ReleaseHandle()
-            {
-                MediaInformation.Destroy(this.handle);
-                this.SetHandle(IntPtr.Zero);
-                return true;
-            }
-        }
-    }
-}
old mode 100755 (executable)
new mode 100644 (file)
similarity index 73%
rename from src/Tizen.Content.MediaContent/Interop/Interop.MediaPlaylist.cs
rename to src/Tizen.Content.MediaContent/Interop/Interop.Playlist.cs
index 25a9ccf..4f136eb
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-
 using System;
 using System.Runtime.InteropServices;
 using Tizen.Content.MediaContent;
@@ -23,20 +22,27 @@ internal static partial class Interop
 {
     internal static partial class Playlist
     {
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_create")]
+        internal static extern MediaContentError Create(out IntPtr handle);
+
         [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_get_playlist_count_from_db")]
-        internal static extern MediaContentError GetPlaylistCountFromDb(IntPtr filter, out int playlist_count);
+        internal static extern MediaContentError GetPlaylistCount(FilterHandle filter, out int count);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_get_media_count_from_db")]
-        internal static extern MediaContentError GetMediaCountFromDb(int playlist_id, IntPtr filter, out int media_count);
+        internal static extern MediaContentError GetMediaCountFromDb(int playlistId,
+            FilterHandle filter, out int count);
 
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_insert_to_db")]
-        internal static extern MediaContentError InsertToDb(string name, out IntPtr playlist);
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_insert_to_db_v2")]
+        internal static extern MediaContentError Insert(IntPtr playlist);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_delete_from_db")]
-        internal static extern MediaContentError DeleteFromDb(int playlist_id);
+        internal static extern MediaContentError Delete(int id);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_update_to_db_v2")]
+        internal static extern MediaContentError Update(int id, IntPtr playlist);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_get_playlist_from_db")]
-        internal static extern MediaContentError GetPlaylistFromDb(int playlist_id, out IntPtr playlist);
+        internal static extern MediaContentError GetPlaylistFromDb(int id, out IntPtr playlist);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_destroy")]
         internal static extern MediaContentError Destroy(IntPtr playlist);
@@ -45,13 +51,13 @@ internal static partial class Interop
         internal static extern MediaContentError Clone(out IntPtr dst, IntPtr src);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_get_playlist_id")]
-        internal static extern MediaContentError GetPlaylistId(IntPtr playlist, out int playlist_id);
+        internal static extern MediaContentError GetId(IntPtr playlist, out int id);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_get_name")]
-        internal static extern MediaContentError GetName(IntPtr playlist, out IntPtr playlist_name);
+        internal static extern MediaContentError GetName(IntPtr playlist, out IntPtr name);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_set_name")]
-        internal static extern MediaContentError SetName(IntPtr playlist, string playlist_name);
+        internal static extern MediaContentError SetName(IntPtr playlist, string name);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_get_thumbnail_path")]
         internal static extern MediaContentError GetThumbnailPath(IntPtr playlist, out IntPtr filePath);
@@ -60,37 +66,32 @@ internal static partial class Interop
         internal static extern MediaContentError SetThumbnailPath(IntPtr playlist, string filePath);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_set_play_order")]
-        internal static extern MediaContentError SetPlayOrder(IntPtr playlist, int playlist_member_id, int play_order);
+        internal static extern MediaContentError SetPlayOrder(IntPtr playlist, int memberId, int order);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_add_media")]
-        internal static extern MediaContentError AddMedia(IntPtr playlist, string media_id);
+        internal static extern MediaContentError AddMedia(IntPtr playlist, string mediaId);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_remove_media")]
-        internal static extern MediaContentError RemoveMedia(IntPtr playlist, int playlist_member_id);
+        internal static extern MediaContentError RemoveMedia(IntPtr playlist, int memberId);
 
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_get_play_order")]
-        internal static extern MediaContentError GetPlayOrder(IntPtr playlist, int playlist_member_id, out int play_order);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_update_to_db")]
-        internal static extern MediaContentError UpdateToDb(IntPtr playlist);
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_get_play_order_v2")]
+        internal static extern MediaContentError GetPlayOrder(int playlistId, int memberId, out int order);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_import_from_file")]
-        internal static extern MediaContentError ImportFromFile(string playlist_name, string filePath, out IntPtr playlist);
+        internal static extern MediaContentError ImportFromFile(string path, string name, out IntPtr playlist);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_export_to_file")]
         internal static extern MediaContentError ExportToFile(IntPtr playlist, string filePath);
 
-        //Callbacks
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate bool MediaPlaylistCallback(IntPtr playListHandle, IntPtr data);
-
         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate bool PlaylistMemberCallback(int playListMemberId, IntPtr mediaInformation, IntPtr data);
+        internal delegate bool PlaylistMemberCallback(int memberId, IntPtr mediaInfo, IntPtr data);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_foreach_playlist_from_db")]
-        internal static extern MediaContentError ForeachPlaylistFromDb(IntPtr filter, MediaPlaylistCallback callback, IntPtr user_data);
+        internal static extern MediaContentError ForeachPlaylistFromDb(FilterHandle filter,
+            Common.ItemCallback callback, IntPtr userData = default(IntPtr));
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_playlist_foreach_media_from_db")]
-        internal static extern MediaContentError ForeachMediaFromDb(int playlist_id, IntPtr filter, PlaylistMemberCallback callback, IntPtr user_data);
+        internal static extern MediaContentError ForeachMediaFromDb(int playlistId, FilterHandle filter,
+            PlaylistMemberCallback callback, IntPtr userData = default(IntPtr));
     }
 }
old mode 100755 (executable)
new mode 100644 (file)
similarity index 65%
rename from src/Tizen.Content.MediaContent/Interop/Interop.MediaStorage.cs
rename to src/Tizen.Content.MediaContent/Interop/Interop.Storage.cs
index b17768e..c3eb7dc
  * limitations under the License.
  */
 
-
 using System;
 using System.Runtime.InteropServices;
 using Tizen.Content.MediaContent;
 
 internal static partial class Interop
 {
-    internal static partial class Storage
+    internal static class Storage
     {
         [DllImport(Libraries.MediaContent, EntryPoint = "media_storage_get_storage_info_from_db")]
-        internal static extern MediaContentError GetStorageInfoFromDb(string storage_id, out IntPtr storage);
+        internal static extern MediaContentError GetStorageInfoFromDb(string id, out IntPtr storage);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_storage_get_storage_count_from_db")]
-        internal static extern MediaContentError GetStorageCountFromDb(IntPtr filter, out int storage_count);
+        internal static extern MediaContentError GetStorageCountFromDb(FilterHandle filter, out int count);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_storage_get_media_count_from_db")]
-        internal static extern MediaContentError GetMediaCountFromDb(string storage_id, IntPtr filter, out int media_count);
+        internal static extern MediaContentError GetMediaCountFromDb(string id, FilterHandle filter, out int count);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_storage_destroy")]
         internal static extern MediaContentError Destroy(IntPtr storage);
 
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_storage_clone")]
-        internal static extern MediaContentError Clone(out IntPtr dst, IntPtr src);
-
         [DllImport(Libraries.MediaContent, EntryPoint = "media_storage_get_id")]
-        internal static extern MediaContentError GetId(IntPtr storage, out IntPtr storage_id);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_storage_get_name")]
-        internal static extern MediaContentError GetName(IntPtr storage, out IntPtr storage_name);
+        internal static extern MediaContentError GetId(IntPtr storage, out IntPtr id);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_storage_get_path")]
-        internal static extern MediaContentError GetPath(IntPtr storage, out IntPtr storage_path);
+        internal static extern MediaContentError GetPath(IntPtr storage, out IntPtr path);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_storage_get_type")]
-        internal static extern MediaContentError GetType(IntPtr storage, out ContentStorageType storage_type);
-
-        //Callbacks
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate bool MediaStorageCallback(IntPtr mediaStorageHandle, IntPtr data);
-
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate bool MediaInfoCallback(IntPtr mediaInformation, IntPtr data);
+        internal static extern MediaContentError GetType(IntPtr storage, out StorageType type);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_storage_foreach_storage_from_db")]
-        internal static extern MediaContentError ForeachStorageFromDb(IntPtr filter, MediaStorageCallback callback, IntPtr user_data);
+        internal static extern MediaContentError ForeachStorageFromDb(FilterHandle filter, Common.ItemCallback callback,
+            IntPtr userData = default(IntPtr));
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_storage_foreach_media_from_db")]
-        internal static extern MediaContentError ForeachMediaFromDb(string storage_id, IntPtr filter, MediaInfoCallback callback, IntPtr user_data);
+        internal static extern MediaContentError ForeachMediaFromDb(string id, FilterHandle filter,
+            Common.ItemCallback callback, IntPtr userData = default(IntPtr));
     }
 }
old mode 100755 (executable)
new mode 100644 (file)
similarity index 67%
rename from src/Tizen.Content.MediaContent/Interop/Interop.MediaTag.cs
rename to src/Tizen.Content.MediaContent/Interop/Interop.Tag.cs
index 9895b62..596ec94
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-
 using System;
 using System.Runtime.InteropServices;
 using Tizen.Content.MediaContent;
@@ -23,56 +22,51 @@ internal static partial class Interop
 {
     internal static partial class Tag
     {
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_tag_create")]
+        internal static extern MediaContentError Create(out IntPtr handle);
+
         [DllImport(Libraries.MediaContent, EntryPoint = "media_tag_insert_to_db")]
-        internal static extern MediaContentError InsertToDb(string tag_name, out IntPtr tag);
+        internal static extern MediaContentError Insert(string name, out IntPtr handle);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_tag_delete_from_db")]
-        internal static extern MediaContentError DeleteFromDb(int tag_id);
+        internal static extern MediaContentError Delete(int tagId);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_tag_update_to_db_v2")]
+        internal static extern MediaContentError Update(int tagId, IntPtr tag);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_tag_get_tag_from_db")]
+        internal static extern MediaContentError GetTagFromDb(int tagId, out IntPtr tag);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_tag_get_tag_count_from_db")]
-        internal static extern MediaContentError GetTagCountFromDb(IntPtr filter, out int tag_count);
+        internal static extern MediaContentError GetTagCount(FilterHandle filter, out int count);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_tag_get_media_count_from_db")]
-        internal static extern MediaContentError GetMediaCountFromDb(int tag_id, IntPtr filter, out int media_count);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_tag_clone")]
-        internal static extern MediaContentError Clone(out IntPtr dst, IntPtr src);
+        internal static extern MediaContentError GetMediaCount(int tagId, FilterHandle filter, out int count);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_tag_destroy")]
         internal static extern MediaContentError Destroy(IntPtr tag);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_tag_get_tag_id")]
-        internal static extern MediaContentError GetTagId(IntPtr tag, out int tag_id);
+        internal static extern MediaContentError GetId(IntPtr tag, out int value);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_tag_get_name")]
-        internal static extern MediaContentError GetName(IntPtr tag, out IntPtr tag_name);
+        internal static extern MediaContentError GetName(IntPtr tag, out IntPtr value);
 
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_tag_get_tag_from_db")]
-        internal static extern MediaContentError GetTagFromDb(int tag_id, out IntPtr tag);
+        [DllImport(Libraries.MediaContent, EntryPoint = "media_tag_set_name")]
+        internal static extern MediaContentError SetName(IntPtr tag, string value);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_tag_add_media")]
-        internal static extern MediaContentError AddMedia(IntPtr tag, string media_id);
+        internal static extern MediaContentError AddMedia(IntPtr tag, string mediaId);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_tag_remove_media")]
-        internal static extern MediaContentError RemoveMedia(IntPtr tag, string media_id);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_tag_set_name")]
-        internal static extern MediaContentError SetName(IntPtr tag, string tag_name);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "media_tag_update_to_db")]
-        internal static extern MediaContentError UpdateToDb(IntPtr tag);
-
-        //Callbacks
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate bool MediaInfoCallback(IntPtr mediaInformation, IntPtr data);
-
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate bool MediaTagCallback(IntPtr tag, IntPtr data);
+        internal static extern MediaContentError RemoveMedia(IntPtr tag, string mediaId);
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_tag_foreach_tag_from_db")]
-        internal static extern MediaContentError ForeachTagFromDb(IntPtr filter, MediaTagCallback callback, IntPtr user_data);
+        internal static extern MediaContentError ForeachTagFromDb(FilterHandle filter,
+            Common.ItemCallback callback, IntPtr userData = default(IntPtr));
 
         [DllImport(Libraries.MediaContent, EntryPoint = "media_tag_foreach_media_from_db")]
-        internal static extern MediaContentError ForeachMediaFromDb(int tag_id, IntPtr filter, MediaInfoCallback callback, IntPtr user_data);
+        internal static extern MediaContentError ForeachMediaFromDb(int tagId, FilterHandle filter,
+            Common.ItemCallback callback, IntPtr userData = default(IntPtr));
     }
 }
diff --git a/src/Tizen.Content.MediaContent/Interop/Interop.VideoInfo.cs b/src/Tizen.Content.MediaContent/Interop/Interop.VideoInfo.cs
new file mode 100644 (file)
index 0000000..4fc7f94
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Content.MediaContent;
+
+internal static partial class Interop
+{
+    internal static partial class VideoInfo
+    {
+        [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_destroy", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError Destroy(IntPtr handle);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_album", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError GetAlbum(IntPtr handle, out IntPtr albumName);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_artist", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError GetArtist(IntPtr handle, out IntPtr artistName);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_album_artist", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError GetAlbumArtist(IntPtr handle, out IntPtr albumArtistName);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_genre", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError GetGenre(IntPtr handle, out IntPtr genreName);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_composer", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError GetComposer(IntPtr handle, out IntPtr composerName);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_year", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError GetYear(IntPtr handle, out IntPtr year);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_recorded_date", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError GetRecordedDate(IntPtr handle, out IntPtr recordedDate);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_copyright", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError GetCopyright(IntPtr handle, out IntPtr copyright);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_track_num", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError GetTrackNum(IntPtr handle, out IntPtr trackNum);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_bit_rate", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError GetBitRate(IntPtr handle, out int bitRate);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_duration", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError GetDuration(IntPtr handle, out int duration);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_width", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError GetWidth(IntPtr handle, out int width);
+
+        [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_height", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern MediaContentError GetHeight(IntPtr handle, out int width);
+    }
+}
diff --git a/src/Tizen.Content.MediaContent/Interop/Interop.VideoInformation.cs b/src/Tizen.Content.MediaContent/Interop/Interop.VideoInformation.cs
deleted file mode 100755 (executable)
index 8138990..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-using System;
-using System.Runtime.InteropServices;
-using Tizen.Content.MediaContent;
-
-internal static partial class Interop
-{
-    internal static partial class VideoInformation
-    {
-        [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_destroy", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError Destroy(IntPtr media);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_clone", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError Clone(out SafeVideoInformationHandle dst, SafeVideoInformationHandle src);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_media_id", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetMediaId(SafeVideoInformationHandle videoInformationHandle, out IntPtr mediaId);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_album", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetAlbum(SafeVideoInformationHandle videoInformationHandle, out IntPtr albumName);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_artist", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetArtist(SafeVideoInformationHandle videoInformationHandle, out IntPtr artistName);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_album_artist", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetAlbumArtist(SafeVideoInformationHandle videoInformationHandle, out IntPtr albumArtistName);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_genre", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetGenre(SafeVideoInformationHandle videoInformationHandle, out IntPtr genreName);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_composer", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetComposer(SafeVideoInformationHandle videoInformationHandle, out IntPtr composerName);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_year", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetYear(SafeVideoInformationHandle videoInformationHandle, out IntPtr year);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_recorded_date", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetRecordedDate(SafeVideoInformationHandle videoInformationHandle, out IntPtr recordedDate);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_copyright", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetCopyright(SafeVideoInformationHandle videoInformationHandle, out IntPtr copyright);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_track_num", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetTrackNum(SafeVideoInformationHandle videoInformationHandle, out IntPtr trackNum);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_bit_rate", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetBitRate(SafeVideoInformationHandle videoInformationHandle, out int bitRate);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_duration", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetDuration(SafeVideoInformationHandle videoInformationHandle, out int duration);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_width", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetWidth(SafeVideoInformationHandle videoInformationHandle, out int width);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_height", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetHeight(SafeVideoInformationHandle videoInformationHandle, out int width);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_played_count", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetPlayedCount(SafeVideoInformationHandle videoInformationHandle, out int playedCount);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_played_time", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetPlayedTime(SafeVideoInformationHandle videoInformationHandle, out int playedTime);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_get_played_position", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError GetPlayedPosition(SafeVideoInformationHandle videoInformationHandle, out int playedPosition);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_set_played_count", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError SetPlayedCount(SafeVideoInformationHandle videoInformationHandle, int playedCount);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_set_played_time", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError SetPlayedTime(SafeVideoInformationHandle videoInformationHandle, int playedTime);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_set_played_position", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError SetPlayedPosition(SafeVideoInformationHandle videoInformationHandle, int playedPosition);
-
-        [DllImport(Libraries.MediaContent, EntryPoint = "video_meta_update_to_db", CallingConvention = CallingConvention.Cdecl)]
-        internal static extern MediaContentError UpdateToDB(IntPtr videoInformationHandle);
-
-        internal sealed class SafeVideoInformationHandle : SafeHandle
-        {
-            public SafeVideoInformationHandle()
-                : base(IntPtr.Zero, true)
-            {
-            }
-
-            public override bool IsInvalid
-            {
-                get { return this.handle == IntPtr.Zero; }
-            }
-
-            protected override bool ReleaseHandle()
-            {
-                VideoInformation.Destroy(this.handle);
-                this.SetHandle(IntPtr.Zero);
-                return true;
-            }
-        }
-    }
-}
index 5ed2f1f..60809fb 100644 (file)
@@ -8,6 +8,7 @@
   <ItemGroup>
     <ProjectReference Include="..\Tizen\Tizen.csproj" />
     <ProjectReference Include="..\Tizen.Log\Tizen.Log.csproj" />
+    <ProjectReference Include="..\Tizen.System.Information\Tizen.System.Information.csproj" />
   </ItemGroup>
 
   <Import Project="../../build/common.targets" />
index 3763483..659c3fa 100755 (executable)
-/*
-* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
-*
-* Licensed under the Apache License, Version 2.0 (the License);
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an AS IS BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 using System;
-using System.Collections.Generic;
-using System.Runtime.InteropServices;
-using System.Threading.Tasks;
 
 namespace Tizen.Content.MediaContent
 {
     /// <summary>
-    /// An album is a logical collection or grouping of related audio files. It is also used for filtering media items.
-    /// The Media Album API allows to manage media albums which contains all video and audio items from the same album.
+    /// Represents a logical collection grouping of related media info.
     /// </summary>
-    public class Album : ContentCollection
+    /// <seealso cref="AlbumCommand"/>
+    public class Album
     {
-        private IntPtr _albumHandle = IntPtr.Zero;
-
-        private IntPtr Handle
+        internal Album(IntPtr handle)
         {
-            get
-            {
-                if (_albumHandle == IntPtr.Zero)
-                {
-                    throw new ObjectDisposedException(nameof(Album));
-                }
+            Id = InteropHelper.GetValue<int>(handle, Interop.Album.GetId);
 
-                return _albumHandle;
-            }
+            Artist = InteropHelper.GetString(handle, Interop.Album.GetArtist);
+            AlbumArtPath = InteropHelper.GetString(handle, Interop.Album.GetAlbumArt);
+            Name = InteropHelper.GetString(handle, Interop.Album.GetName);
         }
 
-        /// <summary>
-        /// The media album ID
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public int Id
-        {
-            get
-            {
-                int id = 0;
-                MediaContentValidator.ThrowIfError(
-                    Interop.Group.MediaAlbumGetAlbumId(Handle, out id), "Failed to get value");
-
-                return id;
-            }
-        }
+        internal static Album FromHandle(IntPtr handle) => new Album(handle);
 
         /// <summary>
-        /// The name of the media artist
-        /// If the media content has no album info, the property returns empty string.
+        /// Get the id of the album.
         /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string Artist
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.Group.MediaAlbumGetArtist(Handle, out val), "Failed to get value");
-
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
+        /// <value>The unique id of the album.</value>
+        public int Id { get; }
 
         /// <summary>
-        /// The path of the media album art
+        /// Gets the artist name of the album.
         /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string Art
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.Group.MediaAlbumGetAlbumArt(Handle, out val), "Failed to get value");
-
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
+        /// <value>The artist name.</value>
+        public string Artist { get; }
 
         /// <summary>
-        /// The name of the media album
-        /// If the media content has no album info, the property returns empty string.
+        /// Gets the path to the album art.
         /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string Name
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.Group.MediaAlbumGetName(Handle, out val), "Failed to get value");
-
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        internal Album(IntPtr handle)
-        {
-            _albumHandle = handle;
-        }
+        /// <value>The path to the album art.</value>
+        public string AlbumArtPath { get; }
 
         /// <summary>
-        /// Gets the number of MediaInformation Items for the given album present in the media database.
-        /// If NULL is passed to the filter, no filtering is applied.
+        /// Gets the name of the album.
         /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="filter">ContentFilter used to match media content from the media database.</param>
-        /// <returns>The number of media contents matching the filter passed</returns>
-        public override int GetMediaInformationCount(ContentFilter filter)
-        {
-            int mediaCount = 0;
-            IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
-
-            MediaContentValidator.ThrowIfError(
-                Interop.Group.MediaAlbumGetMediaCountFromDb(Id, handle, out mediaCount), "Failed to get count");
-
-            return mediaCount;
-        }
-
-        public override void Dispose()
-        {
-            if (_albumHandle != IntPtr.Zero)
-            {
-                Interop.Group.MediaAlbumDestroy(_albumHandle);
-                _albumHandle = IntPtr.Zero;
-            }
-        }
+        /// <value>The album name.</value>
+        public string Name { get; }
 
         /// <summary>
-        /// Iterates through the media files with a filter in the given media album from the media database.
-        /// This function gets all media files associated with the given media album and meeting desired filter option.
-        /// If NULL is passed to the filter, no filtering is applied.
+        /// Returns a string representation of the album.
         /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="filter">ContentFilter used to match media content from the media database.</param>
-        /// <returns>List of content media items matching the passed filter</returns>
-        public override IEnumerable<MediaInformation> GetMediaInformations(ContentFilter filter)
-        {
-            List<MediaInformation> mediaContents = new List<MediaInformation>();
-
-            IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
-            Interop.Group.MediaInfoCallback callback = (IntPtr mediaHandle, IntPtr data) =>
-            {
-                Interop.MediaInformation.SafeMediaInformationHandle newHandle;
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.Clone(out newHandle, mediaHandle), "Failed to clone");
-
-                MediaContentType type;
-                Interop.MediaInformation.GetMediaType(newHandle, out type);
-                if (type == MediaContentType.Image)
-                {
-                    Interop.ImageInformation.SafeImageInformationHandle imageInfo;
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.GetImage(mediaHandle, out imageInfo), "Failed to get image information");
-
-                    mediaContents.Add(new ImageInformation(imageInfo, newHandle));
-                }
-                else if ((type == MediaContentType.Music) || (type == MediaContentType.Sound))
-                {
-                    Interop.AudioInformation.SafeAudioInformationHandle audioInfo;
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.GetAudio(mediaHandle, out audioInfo), "Failed to get audio information");
-
-                    mediaContents.Add(new AudioInformation(audioInfo, newHandle));
-                }
-                else if (type == MediaContentType.Video)
-                {
-                    Interop.VideoInformation.SafeVideoInformationHandle videoInfo;
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.GetVideo(mediaHandle, out videoInfo), "Failed to get video information");
-
-                    mediaContents.Add(new VideoInformation(videoInfo, newHandle));
-                }
-                else if (type == MediaContentType.Others)
-                {
-                    mediaContents.Add(new MediaInformation(newHandle));
-                }
-
-                return true;
-            };
-            MediaContentValidator.ThrowIfError(
-                Interop.Group.MediaAlbumForeachMediaFromDb(Id, handle, callback, IntPtr.Zero), "Failed to get information");
-
-            return mediaContents;
-        }
+        /// <returns>A string representation of the current album.</returns>
+        public override string ToString() =>
+            $"Id={Id}, Name={Name}, Artist={Artist}, AlbumArtPath={AlbumArtPath}";
     }
 }
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/AlbumCommand.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/AlbumCommand.cs
new file mode 100644 (file)
index 0000000..e2a2037
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Content.MediaContent
+{
+    /// <summary>
+    /// Provides commands to manage albums in the database.
+    /// </summary>
+    /// <seealso cref="Album"/>
+    public class AlbumCommand : MediaCommand
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="AlbumCommand"/> class with the specified <see cref="MediaDatabase"/>.
+        /// </summary>
+        /// <param name="database">A <see cref="MediaDatabase"/> that the commands run on.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="database"/> is null.</exception>
+        /// <exception cref="ObjectDisposedException"><paramref name="database"/> has already been disposed of.</exception>
+        public AlbumCommand(MediaDatabase database) : base(database)
+        {
+        }
+
+        /// <summary>
+        /// Retrieves the number of albums.
+        /// </summary>
+        /// <returns>The number of albums.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        public int Count()
+        {
+            return Count(null);
+        }
+
+        /// <summary>
+        /// Retrieves the number of albums with <see cref="CountArguments"/>.
+        /// </summary>
+        /// <param name="arguments">The criteria to use to filter. This value can be null.</param>
+        /// <returns>The number of albums.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        public int Count(CountArguments arguments)
+        {
+            ValidateDatabase();
+
+            return CommandHelper.Count(Interop.Album.GetAlbumCountFromDb, arguments);
+        }
+
+        /// <summary>
+        /// Retrieves all the albums.
+        /// </summary>
+        /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        public MediaDataReader<Album> Select()
+        {
+            return Select(null);
+        }
+
+        /// <summary>
+        /// Retrieves the albums with <see cref="SelectArguments"/>.
+        /// </summary>
+        /// <param name="filter">The criteria to use to filter. This value can be null.</param>
+        /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        public MediaDataReader<Album> Select(SelectArguments filter)
+        {
+            ValidateDatabase();
+
+            return CommandHelper.Select(filter, Interop.Album.ForeachAlbumFromDb, Album.FromHandle);
+        }
+
+        /// <summary>
+        /// Retrieves an album with an album id.
+        /// </summary>
+        /// <param name="albumId">The id of the album to query with.</param>
+        /// <returns>The <see cref="Album"/> if <paramref name="albumId"/> exists, otherwise null.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="albumId"/> is equal to or less than zero.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        public Album Select(int albumId)
+        {
+            ValidateDatabase();
+
+            if (albumId <= 0)
+            {
+                throw new ArgumentOutOfRangeException(nameof(albumId), albumId,
+                    "The album id can't be equal to or less than zero.");
+            }
+
+            IntPtr handle = IntPtr.Zero;
+            try
+            {
+                Interop.Album.GetAlbumFromDb(albumId, out handle).ThrowIfError("Failed to query");
+
+                return handle == IntPtr.Zero ? null : new Album(handle);
+            }
+            finally
+            {
+                Interop.Album.Destroy(handle);
+            }
+        }
+
+        /// <summary>
+        /// Retrieves the number of media info that belongs to the album.
+        /// </summary>
+        /// <param name="albumId">The id of the album to query with.</param>
+        /// <returns>The number of media info.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="albumId"/> is equal to or less than zero.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        public int CountMember(int albumId)
+        {
+            return CountMember(albumId, null);
+        }
+
+        /// <summary>
+        /// Retrieves the number of media info that belongs to the album with <see cref="CountArguments"/>..
+        /// </summary>
+        /// <param name="albumId">The id of the album to count media.</param>
+        /// <param name="arguments">The criteria to use to filter. This value can be null.</param>
+        /// <returns>The number of media info.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="albumId"/> is equal to or less than zero.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        public int CountMember(int albumId, CountArguments arguments)
+        {
+            ValidateDatabase();
+
+            if (albumId <= 0)
+            {
+                throw new ArgumentOutOfRangeException(nameof(albumId), albumId,
+                    "The album id can't be equal to or less than zero.");
+            }
+
+            return CommandHelper.Count(Interop.Album.GetMediaCountFromDb, albumId, arguments);
+        }
+
+        /// <summary>
+        /// Retrieves the media info of an album.
+        /// </summary>
+        /// <param name="albumId">The id of the album to select media.</param>
+        /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        public MediaDataReader<MediaInfo> SelectMember(int albumId)
+        {
+            return SelectMember(albumId, null);
+        }
+
+        /// <summary>
+        /// Retrieves the media info of an album with <see cref="SelectArguments"/>.
+        /// </summary>
+        /// <param name="albumId">The id of the album to query with.</param>
+        /// <param name="filter">The criteria to use to filter. This value can be null.</param>
+        /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        public MediaDataReader<MediaInfo> SelectMember(int albumId, SelectArguments filter)
+        {
+            ValidateDatabase();
+
+            if (albumId <= 0)
+            {
+                throw new ArgumentOutOfRangeException(nameof(albumId), albumId,
+                    "The album id can't be equal to or less than zero.");
+            }
+
+            return CommandHelper.SelectMedia(Interop.Album.ForeachMediaFromDb, albumId, filter);
+        }
+    }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/AudioInfo.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/AudioInfo.cs
new file mode 100644 (file)
index 0000000..3d0db51
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Diagnostics;
+
+namespace Tizen.Content.MediaContent
+{
+    /// <summary>
+    /// Represents an audio media information.
+    /// </summary>
+    public class AudioInfo : MediaInfo
+    {
+        internal AudioInfo(Interop.MediaInfoHandle handle) : base(handle)
+        {
+            IntPtr audioHandle = IntPtr.Zero;
+
+            try
+            {
+                Interop.MediaInfo.GetAudio(handle, out audioHandle).ThrowIfError("Failed to retrieve data");
+
+                Debug.Assert(audioHandle != IntPtr.Zero);
+
+                Album = InteropHelper.GetString(audioHandle, Interop.AudioInfo.GetAlbum);
+                Artist = InteropHelper.GetString(audioHandle, Interop.AudioInfo.GetArtist);
+                AlbumArtist = InteropHelper.GetString(audioHandle, Interop.AudioInfo.GetAlbumArtist);
+                Genre = InteropHelper.GetString(audioHandle, Interop.AudioInfo.GetGenre);
+                Composer = InteropHelper.GetString(audioHandle, Interop.AudioInfo.GetComposer);
+                Year = InteropHelper.GetString(audioHandle, Interop.AudioInfo.GetYear);
+                DateRecorded = InteropHelper.GetString(audioHandle, Interop.AudioInfo.GetRecordedDate);
+                Copyright = InteropHelper.GetString(audioHandle, Interop.AudioInfo.GetCopyright);
+                TrackNumber = InteropHelper.GetString(audioHandle, Interop.AudioInfo.GetTrackNum);
+
+                BitRate = InteropHelper.GetValue<int>(audioHandle, Interop.AudioInfo.GetBitRate);
+                BitPerSample = InteropHelper.GetValue<int>(audioHandle, Interop.AudioInfo.GetBitPerSample);
+                SampleRate = InteropHelper.GetValue<int>(audioHandle, Interop.AudioInfo.GetSampleRate);
+                Channels = InteropHelper.GetValue<int>(audioHandle, Interop.AudioInfo.GetChannel);
+
+                Duration = InteropHelper.GetValue<int>(audioHandle, Interop.AudioInfo.GetDuration);
+            }
+            finally
+            {
+                Interop.AudioInfo.Destroy(audioHandle);
+            }
+        }
+
+        /// <summary>
+        /// Gets the album name.
+        /// </summary>
+        /// <value>The album from the metadata.</value>
+        public string Album { get; }
+
+        /// <summary>
+        /// Gets the artist name.
+        /// </summary>
+        /// <value>The artist from the metadata.</value>
+        public string Artist { get; }
+
+        /// <summary>
+        /// Gets the album artist name.
+        /// </summary>
+        /// <value>The album artist from the metadata.</value>
+        public string AlbumArtist { get; }
+
+        /// <summary>
+        /// Gets the genre.
+        /// </summary>
+        /// <value>The genre from the metadata.</value>
+        public string Genre { get; }
+
+        /// <summary>
+        /// Gets the composer.
+        /// </summary>
+        /// <value>The composer from the metadata.</value>
+        public string Composer { get; }
+
+        /// <summary>
+        /// Gets the year.
+        /// </summary>
+        /// <value>The year from the metadata.</value>
+        public string Year { get; }
+
+        /// <summary>
+        /// Gets the recorded date.
+        /// </summary>
+        /// <value>The recorded date from the metadata.</value>
+        public string DateRecorded { get; }
+
+        /// <summary>
+        /// Gets the copyright.
+        /// </summary>
+        /// <value>The copyright from the metadata.</value>
+        public string Copyright { get; }
+
+        /// <summary>
+        /// Gets the track number.
+        /// </summary>
+        /// <value>The track number from the metadata.</value>
+        public string TrackNumber { get; }
+
+        /// <summary>
+        /// Gets the bit rate in bit per second.
+        /// </summary>
+        /// <value>The bit rate in bit per second.</value>
+        public int BitRate { get; }
+
+        /// <summary>
+        /// Gets the bit per sample.
+        /// </summary>
+        /// <value>The bit per sample.</value>
+        public int BitPerSample { get; }
+
+        /// <summary>
+        /// Gets the sample rate in hertz.
+        /// </summary>
+        /// <value>The sample rate in hertz.</value>
+        public int SampleRate { get; }
+
+        /// <summary>
+        /// Gets the number of channels.
+        /// </summary>
+        /// <value>The number of channels.</value>
+        public int Channels { get; }
+
+        /// <summary>
+        /// Gets the track duration in milliseconds.
+        /// </summary>
+        /// <value>The track duration in milliseconds.</value>
+        public int Duration { get; }
+    }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/AudioInformation.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/AudioInformation.cs
deleted file mode 100755 (executable)
index e5fc8d8..0000000
+++ /dev/null
@@ -1,455 +0,0 @@
-/*
-* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
-*
-* Licensed under the Apache License, Version 2.0 (the License);
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an AS IS BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-
-
-using System;
-using System.Collections.Generic;
-using System.Runtime.InteropServices;
-using System.Threading.Tasks;
-using System.Collections.ObjectModel;
-
-namespace Tizen.Content.MediaContent
-{
-    /// <summary>
-    /// AudioContent class API gives the information related to the audio media stored in the device
-    /// Its purpose is threefold:
-    ///     - to provide information about audio content
-    ///     - to organize audio content logically(grouping)
-    /// </summary>
-    public class AudioInformation : MediaInformation
-    {
-        private readonly Interop.AudioInformation.SafeAudioInformationHandle _handle;
-
-        /// <summary>
-        ///  Gets the ID of the media.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string MediaId
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.AudioInformation.GetMediaId(_handle, out val), "Failed to get value");
-
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        /// <summary>
-        ///  Gets the album name.
-        ///  If the media content has no album info, the property returns empty string.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string Album
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.AudioInformation.GetAlbum(_handle, out val), "Failed to get value");
-
-                    return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        /// <summary>
-        ///  Gets the artist name.
-        ///  If the media content has no album info, the property returns empty string.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string Artist
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.AudioInformation.GetArtist(_handle, out val), "Failed to get value");
-
-                    return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        /// <summary>
-        ///  Gets the album artist name.
-        ///  If the media content has no album info, the property returns empty string.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string AlbumArtist
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.AudioInformation.GetAlbumArtist(_handle, out val), "Failed to get value");
-
-                    return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        /// <summary>
-        ///  Gets the genre.
-        ///  If the media content has no album info, the property returns empty string.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string Genre
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.AudioInformation.GetGenre(_handle, out val), "Failed to get value");
-
-                    return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        /// <summary>
-        ///  Gets the composer name.
-        ///  If the value is an empty string, the property returns "Unknown".
-        ///  If the media content has no album info, the property returns empty string.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string Composer
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.AudioInformation.GetComposer(_handle, out val), "Failed to get value");
-
-                    return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        /// <summary>
-        ///  Gets the year.
-        ///  If the media content has no album info, the property returns empty string.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string Year
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.AudioInformation.GetYear(_handle, out val), "Failed to get value");
-
-                    return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        /// <summary>
-        ///  Gets the recorded date.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string RecordedDate
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.AudioInformation.GetRecordedDate(_handle, out val), "Failed to get value");
-
-                    return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        /// <summary>
-        ///  Gets the copyright.
-        ///  If the media content has no copyright information, the property returns empty string.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string Copyright
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.AudioInformation.GetCopyright(_handle, out val), "Failed to get value");
-
-                    return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        /// <summary>
-        ///  Gets the track number.
-        ///  If the media content has no track information, the property returns empty string.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string TrackNumber
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.AudioInformation.GetTrackNum(_handle, out val), "Failed to get value");
-
-                    return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        /// <summary>
-        ///  Gets the bitrate in bit per second [bps].
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public int BitRate
-        {
-            get
-            {
-                int bitrate = 0;
-                MediaContentValidator.ThrowIfError(
-                    Interop.AudioInformation.GetBitRate(_handle, out bitrate), "Failed to get value");
-
-                return bitrate;
-            }
-        }
-
-        /// <summary>
-        ///  Gets bit per sample.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public int BitPerSample
-        {
-            get
-            {
-                int bitPerSample = 0;
-                MediaContentValidator.ThrowIfError(
-                    Interop.AudioInformation.GetBitPerSample(_handle, out bitPerSample), "Failed to get value");
-
-                return bitPerSample;
-            }
-        }
-
-        /// <summary>
-        ///  Gets the sample rate in hz.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public int SampleRate
-        {
-            get
-            {
-                int sampleRate = 0;
-                MediaContentValidator.ThrowIfError(
-                    Interop.AudioInformation.GetSampleRate(_handle, out sampleRate), "Failed to get value");
-
-                return sampleRate;
-            }
-        }
-
-        /// <summary>
-        ///  Gets the channel.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public int Channel
-        {
-            get
-            {
-                int channel = 0;
-                MediaContentValidator.ThrowIfError(
-                    Interop.AudioInformation.GetChannel(_handle, out channel), "Failed to get value");
-
-                return channel;
-            }
-        }
-
-        /// <summary>
-        ///  Gets the track duration in Milliseconds.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public int Duration
-        {
-            get
-            {
-                int duration = 0;
-                MediaContentValidator.ThrowIfError(
-                    Interop.AudioInformation.GetDuration(_handle, out duration), "Failed to get value");
-
-                return duration;
-            }
-        }
-
-        /// <summary>
-        /// Gets the number of MediaBookmark for the passed filter in the given media ID from the media database.
-        /// If NULL is passed to the filter, no filtering is applied.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <returns>
-        /// int count</returns>
-        /// <param name="filter">The Filter for matching Bookmarks</param>
-        public int GetMediaBookmarkCount(ContentFilter filter)
-        {
-            int count = 0;
-            IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
-            MediaContentValidator.ThrowIfError(
-                Interop.MediaInformation.GetBookmarkCount(MediaId, handle, out count), "Failed to get count");
-
-            return count;
-        }
-
-        /// <summary>
-        /// Returns the MediaBookmarks for the given media info from the media database.
-        /// If NULL is passed to the filter, no filtering is applied.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <returns>
-        /// Task to get all the Bookmarks
-        /// </returns>
-        /// <param name="filter"> filter for the Tags</param>
-        public IEnumerable<MediaBookmark> GetMediaBookmarks(ContentFilter filter)
-        {
-            Collection<MediaBookmark> coll = new Collection<MediaBookmark>();
-            IntPtr filterHandle = (filter != null) ? filter.Handle : IntPtr.Zero;
-            Interop.MediaInformation.MediaBookmarkCallback callback = (IntPtr handle, IntPtr userData) =>
-            {
-                IntPtr newHandle = IntPtr.Zero;
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaBookmark.Clone(out newHandle, handle), "Failed to clone");
-
-                coll.Add(new MediaBookmark(newHandle));
-                return true;
-            };
-            MediaContentValidator.ThrowIfError(
-                Interop.MediaInformation.GetAllBookmarks(MediaId, filterHandle, callback, IntPtr.Zero), "Failed to get value");
-
-            return coll;
-        }
-
-        /// <summary>
-        /// Adds a MediaBookmark to the audio
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="offset">Offset of the audio in seconds</param>
-        /// <returns>
-        /// Task with newly added MediaBookmark instance.
-        /// </returns>
-        public MediaBookmark AddBookmark(uint offset)
-        {
-            MediaBookmark result = null;
-            ContentManager.Database.Insert(MediaId, offset, null);
-            ContentFilter bookmarkfilter = new ContentFilter();
-            bookmarkfilter.Condition = ContentColumns.Bookmark.Offset + " = " + offset;
-            IEnumerable<MediaBookmark> bookmarksList = null;
-            bookmarksList = GetMediaBookmarks(bookmarkfilter);
-            foreach (MediaBookmark bookmark in bookmarksList)
-            {
-                if (bookmark.Offset == offset)
-                {
-                    result = bookmark;
-                    break;
-                }
-            }
-
-            bookmarkfilter.Dispose();
-            return result;
-        }
-
-        /// <summary>
-        /// Deletes a MediaBookmark item from the media database.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="bookmark">The MediaBookmark instance to be deleted</param>
-        public void DeleteBookmark(MediaBookmark bookmark)
-        {
-            ContentManager.Database.Delete(bookmark);
-        }
-
-        internal IntPtr AudioHandle
-        {
-            get
-            {
-                return _handle.DangerousGetHandle();
-            }
-        }
-
-        internal AudioInformation(Interop.AudioInformation.SafeAudioInformationHandle handle, Interop.MediaInformation.SafeMediaInformationHandle mediaInformationHandle)
-            : base(mediaInformationHandle)
-        {
-            _handle = handle;
-        }
-    }
-}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Bookmark.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Bookmark.cs
new file mode 100644 (file)
index 0000000..aee5128
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Content.MediaContent
+{
+    /// <summary>
+    /// Represents a media bookmark that allows you to mark interesting moment
+    /// in media(video and audio) to enable fast searching.
+    /// </summary>
+    public class Bookmark
+    {
+        internal Bookmark(IntPtr handle)
+        {
+            Id = InteropHelper.GetValue<int>(handle, Interop.Bookmark.GetId);
+            ThumbnailPath = InteropHelper.GetString(handle, Interop.Bookmark.GetThumbnailPath);
+            Offset = InteropHelper.GetValue<int>(handle, Interop.Bookmark.GetMarkedTime);
+            Name = InteropHelper.GetString(handle, Interop.Bookmark.GetName);
+        }
+
+        /// <summary>
+        /// Gets the id of the bookmark.
+        /// </summary>
+        /// <value>The id of the bookmark.</value>
+        public int Id { get; }
+
+        /// <summary>
+        /// Gets the thumbnail path of the bookmark.
+        /// </summary>
+        /// <value>The thumbnail path of the bookmark.</value>
+        public string ThumbnailPath { get; }
+
+        /// <summary>
+        /// Gets the offset in milliseconds.
+        /// </summary>
+        /// <value>The offset of the bookmark in media in milliseconds.</value>
+        public int Offset { get; }
+
+        /// <summary>
+        /// Gets the name of the bookmark.
+        /// </summary>
+        /// <value>The name of the bookmark.</value>
+        public string Name { get; }
+
+        internal static Bookmark FromHandle(IntPtr handle) => new Bookmark(handle);
+
+        /// <summary>
+        /// Returns a string representation of the bookmark.
+        /// </summary>
+        /// <returns>A string representation of the current bookmark.</returns>
+        public override string ToString() =>
+            $"Id={Id}, Name={Name}, ThumbnailPath={ThumbnailPath}, Offset={Offset}";
+    }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/BookmarkCommand.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/BookmarkCommand.cs
new file mode 100644 (file)
index 0000000..fd13fc9
--- /dev/null
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Content.MediaContent
+{
+    /// <summary>
+    /// Provides commands to manage bookmarks in database.
+    /// </summary>
+    /// <seealso cref="Bookmark"/>
+    public class BookmarkCommand : MediaCommand
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="BookmarkCommand"/> class with the specified <see cref="MediaDatabase"/>.
+        /// </summary>
+        /// <param name="database">A <see cref="MediaDatabase"/> that the commands run on.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="database"/> is null.</exception>
+        /// <exception cref="ObjectDisposedException"><paramref name="database"/> has already been disposed of.</exception>
+        public BookmarkCommand(MediaDatabase database) : base(database)
+        {
+        }
+
+        /// <summary>
+        /// Retrieves the number of bookmarks.
+        /// </summary>
+        /// <returns>The number of bookmarks.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        public int Count()
+        {
+            return Count(null);
+        }
+
+        /// <summary>
+        /// Retrieves the number of bookmarks with <see cref="CountArguments"/>.
+        /// </summary>
+        /// <param name="arguments">The criteria to use to filter. This value can be null.</param>
+        /// <returns>The number of bookmarks.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        public int Count(CountArguments arguments)
+        {
+            ValidateDatabase();
+
+            return CommandHelper.Count(Interop.Bookmark.GetCount, arguments);
+        }
+
+        /// <summary>
+        /// Inserts new bookmark into the database with the specified media and offset.
+        /// </summary>
+        /// <privilege>http://tizen.org/privilege/content.write</privilege>
+        /// <param name="mediaId">The media id to be associated with.</param>
+        /// <param name="offset">The time offset in milliseconds.</param>
+        /// <returns>The <see cref="Bookmark"/> instance that contains the record information inserted.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="mediaId"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="mediaId"/> is a zero-length string, contains only white space.</exception>
+        /// <exception cref="UnauthorizedAccessException">The caller has no required privilege.</exception>
+        public Bookmark Insert(string mediaId, int offset)
+        {
+            return Insert(mediaId, offset, null);
+        }
+
+        /// <summary>
+        /// Inserts new bookmark into the database with the specified media id, offset and name.
+        /// </summary>
+        /// <privilege>http://tizen.org/privilege/content.write</privilege>
+        /// <param name="mediaId">The media id to be associated with.</param>
+        /// <param name="offset">The time offset in milliseconds.</param>
+        /// <param name="name">The name of the bookmark. This value can be null.</param>
+        /// <returns>The <see cref="Bookmark"/> instance that contains the record information inserted.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="mediaId"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="mediaId"/> is a zero-length string, contains only white space.</exception>
+        /// <exception cref="UnauthorizedAccessException">The caller has no required privilege.</exception>
+        public Bookmark Insert(string mediaId, int offset, string name)
+        {
+            return Insert(mediaId, offset, name, null);
+        }
+
+        /// <summary>
+        /// Inserts new bookmark into the database with the specified media id, offset, name and thumbnail path.
+        /// </summary>
+        /// <privilege>http://tizen.org/privilege/content.write</privilege>
+        /// <remarks>
+        /// Thumbnail may be useful only when the media is video.
+        /// </remarks>
+        /// <param name="mediaId">The media id to be associated with.</param>
+        /// <param name="offset">The time offset in milliseconds.</param>
+        /// <param name="name">The name of the bookmark. This value can be null.</param>
+        /// <param name="thumbnailPath">The thumbnail path of the bookmark. This value can be null.</param>
+        /// <returns>The <see cref="Bookmark"/> instance that contains the record information inserted.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="mediaId"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="mediaId"/> is a zero-length string, contains only white space.</exception>
+        /// <exception cref="UnauthorizedAccessException">The caller has no required privilege.</exception>
+        public Bookmark Insert(string mediaId, int offset, string name, string thumbnailPath)
+        {
+            ValidateDatabase();
+
+            ValidationUtil.ValidateNotNullOrEmpty(mediaId, nameof(mediaId));
+
+            Interop.Bookmark.Create(mediaId, offset, out var handle).ThrowIfError("Failed to insert new bookmark");
+
+            try
+            {
+                Interop.Bookmark.SetName(handle, name).ThrowIfError("Failed to insert new bookmark");
+
+                if (thumbnailPath != null)
+                {
+                    Interop.Bookmark.SetThumbnailPath(handle, thumbnailPath).
+                        ThrowIfError("Failed to insert new bookmark");
+                }
+
+                Interop.Bookmark.Insert(handle).ThrowIfError("Failed to insert new bookmark");
+
+                return new Bookmark(handle);
+            }
+            finally
+            {
+                Interop.Bookmark.Destroy(handle);
+            }
+        }
+
+        /// <summary>
+        /// Deletes a bookmark from the database.
+        /// </summary>
+        /// <privilege>http://tizen.org/privilege/content.write</privilege>
+        /// <param name="bookmarkId">The bookmark id to delete.</param>
+        /// <returns>true if the matched record was found and deleted, otherwise false.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="bookmarkId"/> is less than zero.</exception>
+        /// <exception cref="UnauthorizedAccessException">The caller has no required privilege.</exception>
+        public bool Delete(int bookmarkId)
+        {
+            ValidateDatabase();
+
+            if (bookmarkId < 0)
+            {
+                throw new ArgumentOutOfRangeException(nameof(bookmarkId), bookmarkId,
+                    "Bookmark id shouldn't be negative.");
+            }
+
+            if (CommandHelper.Count(Interop.Bookmark.GetCount, $"{BookmarkColumns.Id}={bookmarkId}") == 0)
+            {
+                return false;
+            }
+
+            CommandHelper.Delete(Interop.Bookmark.Delete, bookmarkId);
+
+            return true;
+        }
+
+
+        /// <summary>
+        /// Retrieves the bookmarks.
+        /// </summary>
+        /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        public MediaDataReader<Bookmark> Select()
+        {
+            return Select(null);
+        }
+
+        /// <summary>
+        /// Retrieves the bookmarks with <see cref="SelectArguments"/>.
+        /// </summary>
+        /// <param name="filter">The criteria to use to filter. This value can be null.</param>
+        /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        public MediaDataReader<Bookmark> Select(SelectArguments filter)
+        {
+            ValidateDatabase();
+
+            return CommandHelper.Select(filter, Interop.Bookmark.ForeachFromDb, Bookmark.FromHandle);
+        }
+
+    }
+
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Columns.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Columns.cs
new file mode 100644 (file)
index 0000000..d4ae50c
--- /dev/null
@@ -0,0 +1,838 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Content.MediaContent
+{
+    /// <summary>
+    /// Provides the column names that can be used for Select and Count commands.
+    /// </summary>
+    /// <seealso cref="SelectArguments"/>
+    /// <seealso cref="CountArguments"/>
+    /// <seealso cref="QueryArguments.FilterExpression"/>
+    /// <seealso cref="SelectArguments.SortOrder"/>
+    /// <seealso cref="AlbumCommand.Count(CountArguments)"/>
+    /// <seealso cref="AlbumCommand.CountMember(int, CountArguments)"/>
+    /// <seealso cref="AlbumCommand.Select(SelectArguments)"/>
+    /// <seealso cref="AlbumCommand.SelectMember(int, SelectArguments)"/>
+    /// <seealso cref="BookmarkCommand.Count(CountArguments)"/>
+    /// <seealso cref="BookmarkCommand.Select(SelectArguments)"/>
+    /// <seealso cref="FaceInfoCommand.Select(SelectArguments)"/>
+    /// <seealso cref="FolderCommand.Count(CountArguments)"/>
+    /// <seealso cref="FolderCommand.CountMedia(string, CountArguments)"/>
+    /// <seealso cref="FolderCommand.Select(SelectArguments)"/>
+    /// <seealso cref="FolderCommand.SelectMedia(string, SelectArguments)"/>
+    /// <seealso cref="MediaInfoCommand.CountMedia(CountArguments)"/>
+    /// <seealso cref="MediaInfoCommand.SelectMedia(SelectArguments)"/>
+    /// <seealso cref="PlaylistCommand.Count(CountArguments)"/>
+    /// <seealso cref="PlaylistCommand.Select(SelectArguments)"/>
+    /// <seealso cref="PlaylistCommand.CountMember(int, CountArguments)"/>
+    /// <seealso cref="PlaylistCommand.SelectMember(int, SelectArguments)"/>
+    /// <seealso cref="TagCommand.Count(CountArguments)"/>
+    /// <seealso cref="TagCommand.CountMedia(int, CountArguments)"/>
+    /// <seealso cref="TagCommand.Select(SelectArguments)"/>
+    /// <seealso cref="TagCommand.SelectMedia(int, SelectArguments)"/>
+    public static class MediaInfoColumns
+    {
+        /// <summary>
+        /// Gets the column name for the id of media.
+        /// </summary>
+        /// <value>The column name for the id of media.</value>
+        /// <remarks>The value type is string.</remarks>
+        /// <seealso cref="MediaInfo.Id"/>
+        public static string Id => "MEDIA_ID";
+
+        /// <summary>
+        /// Gets the column name for the path of media.
+        /// </summary>
+        /// <value>The column name for the file path of media.</value>
+        /// <remarks>The value type is string.</remarks>
+        /// <seealso cref="MediaInfo.Path"/>
+        public static string Path => "MEDIA_PATH";
+
+        /// <summary>
+        /// Gets the column name for display name of media.
+        /// </summary>
+        /// <value>The column name for the display name of media.</value>
+        /// <remarks>The value type is string.</remarks>
+        /// <seealso cref="MediaInfo.DisplayName"/>
+        public static string DisplayName => "MEDIA_DISPLAY_NAME";
+
+        /// <summary>
+        /// Gets the column name for the type of media.
+        /// </summary>
+        /// <value>The column name for the type of media.</value>
+        /// <remarks>
+        /// The value type is integer.
+        /// The value should be an integer that is one of <see cref="MediaContent.MediaType"/> values.
+        /// </remarks>
+        /// <seealso cref="MediaInfo.MediaType"/>
+        public static string MediaType => "MEDIA_TYPE";
+
+        /// <summary>
+        /// Gets the column name for the mime type of media.
+        /// </summary>
+        /// <value>The column name for the mime type of media.</value>
+        /// <remarks>The value type is string.</remarks>
+        /// <seealso cref="MediaInfo.MimeType"/>
+        public static string MimeType => "MEDIA_MIME_TYPE";
+
+        /// <summary>
+        /// Gets the column name for the file size of media.
+        /// </summary>
+        /// <value>The column name for the file size of media.</value>
+        /// <remarks>The value type is integer.</remarks>
+        /// <seealso cref="MediaInfo.FileSize"/>
+        public static string FileSize => "MEDIA_SIZE";
+
+        /// <summary>
+        /// Gets the column name for the date added of media.
+        /// </summary>
+        /// <value>The column name for the date added of media.</value>
+        /// <remarks>
+        /// The value type is integer.
+        /// <see cref="System.DateTimeOffset"/> needs to be converted into the unix time.
+        /// </remarks>
+        /// <seealso cref="MediaInfo.DateAdded"/>
+        /// <seealso cref="System.DateTimeOffset.ToUnixTimeSeconds"/>
+        public static string DateAdded => "MEDIA_ADDED_TIME";
+
+        /// <summary>
+        /// Gets the column name for the date modified of media.
+        /// </summary>
+        /// <value>The column name for the date modified of media.</value>
+        /// <remarks>
+        /// The value type is integer.
+        /// <see cref="System.DateTimeOffset"/> needs to be converted into the unix time.
+        /// </remarks>
+        /// <seealso cref="MediaInfo.DateModified"/>
+        /// <seealso cref="System.DateTimeOffset.ToUnixTimeSeconds"/>
+        public static string DateModified => "MEDIA_MODIFIED_TIME";
+
+        /// <summary>
+        /// Gets the column name for the timeline of media.
+        /// </summary>
+        /// <value>The column name for the timeline of media.</value>
+        /// <remarks>
+        /// The value type is integer.
+        /// <see cref="System.DateTimeOffset"/> needs to be converted into the unix time.
+        /// </remarks>
+        /// <seealso cref="MediaInfo.Timeline"/>
+        /// <seealso cref="System.DateTimeOffset.ToUnixTimeSeconds"/>
+        public static string Timeline => "MEDIA_TIMELINE";
+
+        /// <summary>
+        /// Gets the column name for the thumbnail path of media.
+        /// </summary>
+        /// <value>The column name for the thumbnail path of media.</value>
+        /// <remarks>
+        /// The value type is string.
+        /// </remarks>
+        /// <seealso cref="MediaInfo.ThumbnailPath"/>
+        public static string ThumbnailPath => "MEDIA_THUMBNAIL_PATH";
+
+        /// <summary>
+        /// Gets the column name for the title of media.
+        /// </summary>
+        /// <value>The column name for the title of media.</value>
+        /// <remarks>
+        /// The value type is string.
+        /// </remarks>
+        /// <seealso cref="MediaInfo.ThumbnailPath"/>
+        public static string Title => "MEDIA_TITLE";
+
+        /// <summary>
+        /// Gets the column name for the album of media.
+        /// </summary>
+        /// <value>The column name for the album of media.</value>
+        /// <remarks>
+        /// The value type is string.
+        /// </remarks>
+        /// <seealso cref="AudioInfo.Album"/>
+        public static string Album => "MEDIA_ALBUM";
+
+        /// <summary>
+        /// Gets the column name for the artist of media.
+        /// </summary>
+        /// <value>The column name for the artist of media.</value>
+        /// <remarks>
+        /// The value type is string.
+        /// </remarks>
+        /// <seealso cref="AudioInfo.Artist"/>
+        /// <seealso cref="VideoInfo.Artist"/>
+        public static string Artist => "MEDIA_ARTIST";
+
+        /// <summary>
+        /// Gets the column name for the album artist of media.
+        /// </summary>
+        /// <value>The column name for the album artist of media.</value>
+        /// <remarks>
+        /// The value type is string.
+        /// </remarks>
+        /// <seealso cref="AudioInfo.AlbumArtist"/>
+        /// <seealso cref="VideoInfo.AlbumArtist"/>
+        public static string AlbumArtist => "MEDIA_ALBUM_ARTIST";
+
+        /// <summary>
+        /// Gets the column name for the genre of media.
+        /// </summary>
+        /// <value>The column name for the genre of media.</value>
+        /// <remarks>
+        /// The value type is string.
+        /// </remarks>
+        /// <seealso cref="AudioInfo.Genre"/>
+        /// <seealso cref="VideoInfo.Genre"/>
+        public static string Genre => "MEDIA_GENRE";
+
+        /// <summary>
+        /// Gets the column name for the composer of media.
+        /// </summary>
+        /// <value>The column name for the composer of media.</value>
+        /// <remarks>
+        /// The value type is string.
+        /// </remarks>
+        /// <seealso cref="AudioInfo.Composer"/>
+        /// <seealso cref="VideoInfo.Composer"/>
+        public static string Composer => "MEDIA_COMPOSER";
+
+        /// <summary>
+        /// Gets the column name for the year of media.
+        /// </summary>
+        /// <value>The column name for the year of media.</value>
+        /// <remarks>
+        /// The value type is string.
+        /// </remarks>
+        /// <seealso cref="AudioInfo.Year"/>
+        /// <seealso cref="VideoInfo.Year"/>
+        public static string Year => "MEDIA_YEAR";
+
+        /// <summary>
+        /// Gets the column name for the date recorded of media.
+        /// </summary>
+        /// <value>The column name for the date recorded of media.</value>
+        /// <remarks>
+        /// The value type is string.
+        /// </remarks>
+        /// <seealso cref="AudioInfo.DateRecorded"/>
+        /// <seealso cref="VideoInfo.DateRecorded"/>
+        public static string DateRecorded => "MEDIA_RECORDED_DATE";
+
+        /// <summary>
+        /// Gets the column name for the copyright of media.
+        /// </summary>
+        /// <value>The column name for the copyright of media.</value>
+        /// <remarks>
+        /// The value type is string.
+        /// </remarks>
+        /// <seealso cref="AudioInfo.Copyright"/>
+        /// <seealso cref="VideoInfo.Copyright"/>
+        public static string Copyright => "MEDIA_COPYRIGHT";
+
+        /// <summary>
+        /// Gets the column name for the track number of media.
+        /// </summary>
+        /// <value>The column name for the track number of media.</value>
+        /// <remarks>
+        /// The value type is string.
+        /// </remarks>
+        /// <seealso cref="AudioInfo.TrackNumber"/>
+        /// <seealso cref="VideoInfo.TrackNumber"/>
+        public static string TrackNumber => "MEDIA_TRACK_NUM";
+
+        /// <summary>
+        /// Gets the column name for the description of media.
+        /// </summary>
+        /// <value>The column name for the description of media.</value>
+        /// <remarks>
+        /// The value type is string.
+        /// </remarks>
+        /// <seealso cref="MediaInfo.Description"/>
+        public static string Description => "MEDIA_DESCRIPTION";
+
+        /// <summary>
+        /// Gets the column name for the bit rate of media.
+        /// </summary>
+        /// <value>The column name for the bit rate of media.</value>
+        /// <remarks>
+        /// The value type is integer.
+        /// </remarks>
+        /// <seealso cref="AudioInfo.BitRate"/>
+        /// <seealso cref="VideoInfo.BitRate"/>
+        public static string BitRate => "MEDIA_BITRATE";
+
+        /// <summary>
+        /// Gets the column name for the bit per sample of media.
+        /// </summary>
+        /// <value>The column name for the bit per sample of media.</value>
+        /// <remarks>
+        /// The value type is integer.
+        /// </remarks>
+        /// <seealso cref="AudioInfo.BitPerSample"/>
+        public static string BitPerSample => "MEDIA_BITPERSAMPLE";
+
+        /// <summary>
+        /// Gets the column name for the sample rate of media.
+        /// </summary>
+        /// <value>The column name for the sample rate of media.</value>
+        /// <remarks>
+        /// The value type is integer.
+        /// </remarks>
+        /// <seealso cref="AudioInfo.SampleRate"/>
+        public static string SampleRate => "MEDIA_SAMPLERATE";
+
+        /// <summary>
+        /// Gets the column name for the channels of media.
+        /// </summary>
+        /// <value>The column name for the channels of media.</value>
+        /// <remarks>
+        /// The value type is integer.
+        /// </remarks>
+        /// <seealso cref="AudioInfo.Channels"/>
+        public static string Channels => "MEDIA_CHANNEL";
+
+        /// <summary>
+        /// Gets the column name for the duration of media.
+        /// </summary>
+        /// <value>The column name for the duration of media.</value>
+        /// <remarks>
+        /// The value type is integer.
+        /// </remarks>
+        /// <seealso cref="AudioInfo.Duration"/>
+        /// <seealso cref="VideoInfo.Duration"/>
+        public static string Duration => "MEDIA_DURATION";
+
+        /// <summary>
+        /// Gets the column name for the longitude of media.
+        /// </summary>
+        /// <value>The column name for the longitude of media.</value>
+        /// <remarks>
+        /// The value type is real.
+        /// </remarks>
+        /// <seealso cref="MediaInfo.Longitude"/>
+        public static string Longitude => "MEDIA_LONGITUDE";
+
+        /// <summary>
+        /// Gets the column name for the latitude of media.
+        /// </summary>
+        /// <value>The column name for the latitude of media.</value>
+        /// <remarks>
+        /// The value type is real.
+        /// </remarks>
+        /// <seealso cref="MediaInfo.Latitude"/>
+        public static string Latitude => "MEDIA_LATITUDE";
+
+        /// <summary>
+        /// Gets the column name for the altitude of media.
+        /// </summary>
+        /// <value>The column name for the altitude of media.</value>
+        /// <remarks>
+        /// The value type is real.
+        /// </remarks>
+        /// <seealso cref="MediaInfo.Altitude"/>
+        public static string Altitude => "MEDIA_ALTITUDE";
+
+        /// <summary>
+        /// Gets the column name for the width of media.
+        /// </summary>
+        /// <value>The column name for the width of media.</value>
+        /// <remarks>
+        /// The value type is integer.
+        /// </remarks>
+        /// <seealso cref="ImageInfo.Width"/>
+        /// <seealso cref="VideoInfo.Width"/>
+        public static string Width => "MEDIA_WIDTH";
+
+        /// <summary>
+        /// Gets the column name for the height of media.
+        /// </summary>
+        /// <value>The column name for the height of media.</value>
+        /// <remarks>
+        /// The value type is integer.
+        /// </remarks>
+        /// <seealso cref="ImageInfo.Height"/>
+        /// <seealso cref="VideoInfo.Height"/>
+        public static string Height => "MEDIA_HEIGHT";
+
+        /// <summary>
+        /// Gets the column name for the date taken of media.
+        /// </summary>
+        /// <value>The column name for the date taken of media.</value>
+        /// <remarks>
+        /// The value type is integer.
+        /// </remarks>
+        /// <seealso cref="ImageInfo.DateTaken"/>
+        public static string DateTaken => "MEDIA_DATETAKEN";
+
+        /// <summary>
+        /// Gets the column name for the orientation of media.
+        /// </summary>
+        /// <value>The column name for the orientation of media.</value>
+        /// <remarks>
+        /// The value type is integer.
+        /// The value should be an integer that is one of <see cref="MediaContent.Orientation"/> values.
+        /// </remarks>
+        /// <seealso cref="MediaContent.Orientation"/>
+        /// <seealso cref="ImageInfo.Orientation"/>
+        public static string Orientation => "MEDIA_ORIENTATION";
+
+        /// <summary>
+        /// Gets the column name for the burst id of media.
+        /// </summary>
+        /// <value>The column name for the burst id of media.</value>
+        /// <remarks>
+        /// The value type is string.
+        /// </remarks>
+        /// <seealso cref="ImageInfo.BurstId"/>
+        public static string BurstId => "BURST_ID";
+
+        /// <summary>
+        /// Gets the column name for the rating of media.
+        /// </summary>
+        /// <value>The column name for the rating of media.</value>
+        /// <remarks>
+        /// The value type is integer.
+        /// </remarks>
+        /// <seealso cref="MediaInfo.Rating"/>
+        public static string Rating => "MEDIA_RATING";
+
+        /// <summary>
+        /// Gets the column name for the favorite status of media.
+        /// </summary>
+        /// <value>The column name for the favorite status of media.</value>
+        /// <remarks>
+        /// The value type is integer(1 : true, 0 : false).
+        /// </remarks>
+        /// <seealso cref="MediaInfo.IsFavorite"/>
+        public static string Favorite => "MEDIA_FAVOURITE";
+
+        /// <summary>
+        /// Gets the column name for the provider of media.
+        /// </summary>
+        /// <value>The column name for the provider of media.</value>
+        /// <remarks>
+        /// The value type is string.
+        /// </remarks>
+        /// <seealso cref="MediaInfo.Provider"/>
+        public static string Provider => "MEDIA_PROVIDER";
+
+        /// <summary>
+        /// Gets the column name for the category of media.
+        /// </summary>
+        /// <value>The column name for the category of media.</value>
+        /// <remarks>
+        /// The value type is string.
+        /// </remarks>
+        /// <seealso cref="MediaInfo.Category"/>
+        public static string Category => "MEDIA_CATEGORY";
+
+
+        /// <summary>
+        /// Gets the column name for the location tag of media.
+        /// </summary>
+        /// <value>The column name for the location tag of media.</value>
+        /// <remarks>
+        /// The value type is string.
+        /// </remarks>
+        /// <seealso cref="MediaInfo.LocationTag"/>
+        public static string LocationTag => "MEDIA_LOCATION_TAG";
+
+        /// <summary>
+        /// Gets the column name for the age rating of media.
+        /// </summary>
+        /// <value>The column name for the age rating of media.</value>
+        /// <remarks>
+        /// The value type is string.
+        /// </remarks>
+        /// <seealso cref="MediaInfo.AgeRating"/>>
+        public static string AgeRating => "MEDIA_AGE_RATING";
+
+        /// <summary>
+        /// Gets the column name for the weather information of media.
+        /// </summary>
+        /// <value>The column name for the weather information of media.</value>
+        /// <remarks>
+        /// The value type is string.
+        /// </remarks>
+        /// <seealso cref="MediaInfo.Weather"/>
+        public static string Weather => "MEDIA_WEATHER";
+
+        /// <summary>
+        /// Gets the column name for the drm of media.
+        /// </summary>
+        /// <value>The column name for the drm of media.</value>
+        /// <remarks>
+        /// The value type is integer(1 : true, 0 : false).
+        /// </remarks>
+        /// <seealso cref="MediaInfo.IsDrm"/>
+        public static string IsDrm => "MEDIA_IS_DRM";
+
+        /// <summary>
+        /// Gets the column name for the storage type of media.
+        /// </summary>
+        /// <value>The column name for the storage type of media.</value>
+        /// <remarks>
+        /// The value type is integer.
+        /// The value should be an integer that is one of <see cref="MediaContent.StorageType"/> values.
+        /// </remarks>
+        /// <seealso cref="MediaInfo.StorageType"/>
+        public static string StorageType => "MEDIA_STORAGE_TYPE";
+
+        /// <summary>
+        /// Gets the column name for the exposure time of media.
+        /// </summary>
+        /// <value>The column name for the exposure time of media.</value>
+        /// <remarks>
+        /// The value type is integer.
+        /// </remarks>
+        /// <seealso cref="ImageInfo.ExposureTime"/>
+        public static string ExposureTime => "MEDIA_EXPOSURE_TIME";
+
+        /// <summary>
+        /// Gets the column name for the FNumber of media.
+        /// </summary>
+        /// <value>The column name for the FNumber of media.</value>
+        /// <remarks>
+        /// The value type is integer.
+        /// </remarks>
+        /// <seealso cref="ImageInfo.FNumber"/>
+        public static string FNumber => "MEDIA_FNUMBER";
+
+        /// <summary>
+        /// Gets the column name for the iso of media.
+        /// </summary>
+        /// <value>The column name for the iso of media.</value>
+        /// <remarks>
+        /// The value type is integer.
+        /// </remarks>
+        /// <seealso cref="ImageInfo.Iso"/>
+        public static string Iso => "MEDIA_ISO";
+
+        /// <summary>
+        /// Gets the column name for the model of media.
+        /// </summary>
+        /// <value>The column name for the model of media.</value>
+        /// <remarks>
+        /// The value type is string.
+        /// </remarks>
+        /// <seealso cref="ImageInfo.Model"/>
+        public static string Model => "MEDIA_MODEL";
+    }
+
+
+    /// <summary>
+    /// Provides the folder column names that can be used for Select and Count commands.
+    /// </summary>
+    /// <seealso cref="SelectArguments"/>
+    /// <seealso cref="CountArguments"/>
+    /// <seealso cref="QueryArguments.FilterExpression"/>
+    /// <seealso cref="SelectArguments.SortOrder"/>
+    /// <seealso cref="AlbumCommand.Count(CountArguments)"/>
+    /// <seealso cref="AlbumCommand.Select(SelectArguments)"/>
+    public static class AlbumColumns
+    {
+        /// <summary>
+        /// Gets the column name for the name of album.
+        /// </summary>
+        /// <value>The column name for the name of album.</value>
+        /// <remarks>
+        /// The value type is string.
+        /// </remarks>
+        /// <seealso cref="Album.Name"/>
+        public static string Name => "MEDIA_ALBUM";
+
+        /// <summary>
+        /// Gets the column name for the artist of album.
+        /// </summary>
+        /// <value>The column name for the artist of album.</value>
+        /// <remarks>
+        /// The value type is string.
+        /// </remarks>
+        /// <seealso cref="Album.Artist"/>
+        public static string Artist => "MEDIA_ARTIST";
+    }
+
+    /// <summary>
+    /// Provides the folder column names that can be used for Select and Count commands.
+    /// </summary>
+    /// <seealso cref="SelectArguments"/>
+    /// <seealso cref="CountArguments"/>
+    /// <seealso cref="QueryArguments.FilterExpression"/>
+    /// <seealso cref="SelectArguments.SortOrder"/>
+    /// <seealso cref="FolderCommand.Count(CountArguments)"/>
+    /// <seealso cref="FolderCommand.Select(SelectArguments)"/>
+    public static class FolderColumns
+    {
+        /// <summary>
+        /// Gets the column name for the id of folder.
+        /// </summary>
+        /// <value>The column name for the id of folder.</value>
+        /// <remarks>
+        /// The value type is string.
+        /// </remarks>
+        /// <seealso cref="Folder.Id"/>
+        public static string Id => "FOLDER_ID";
+
+        /// <summary>
+        /// Gets the column name for the path of folder.
+        /// </summary>
+        /// <value>The column name for the path of folder.</value>
+        /// <remarks>
+        /// The value type is string.
+        /// </remarks>
+        /// <seealso cref="Folder.Path"/>
+        public static string Path => "FOLDER_PATH";
+
+        /// <summary>
+        /// Gets the column name for the name of folder.
+        /// </summary>
+        /// <value>The column name for the name of folder.</value>
+        /// <remarks>
+        /// The value type is string.
+        /// </remarks>
+        /// <seealso cref="Folder.Name"/>
+        public static string Name => "FOLDER_NAME";
+
+        /// <summary>
+        /// Gets the column name for the storage type of folder.
+        /// </summary>
+        /// <value>The column name for the storage type of folder.</value>
+        /// <remarks>
+        /// The value type is integer.
+        /// The value should be an integer that is one of <see cref="MediaContent.StorageType"/> values.
+        /// </remarks>
+        /// <seealso cref="Folder.StorageType"/>
+        public static string StorageType => "FOLDER_STORAGE_TYPE";
+    }
+
+    /// <summary>
+    /// Provides the playlist column names that can be used for Select and Count commands.
+    /// </summary>
+    /// <seealso cref="SelectArguments"/>
+    /// <seealso cref="CountArguments"/>
+    /// <seealso cref="QueryArguments.FilterExpression"/>
+    /// <seealso cref="SelectArguments.SortOrder"/>
+    /// <seealso cref="PlaylistCommand.Count(CountArguments)"/>
+    /// <seealso cref="PlaylistCommand.Select(SelectArguments)"/>
+    public static class PlaylistColumns
+    {
+        /// <summary>
+        /// Gets the column name for the name of playlist.
+        /// </summary>
+        /// <value>The column name for the name of playlist.</value>
+        /// <remarks>
+        /// The value type is string.
+        /// </remarks>
+        /// <seealso cref="Playlist.Name"/>
+        public static string Name => "PLAYLIST_NAME";
+
+        /// <summary>
+        /// Gets the column name for the id of playlist.
+        /// </summary>
+        /// <value>The column name for the id of playlist.</value>
+        /// <remarks>
+        /// The value type is integer.
+        /// </remarks>
+        /// <seealso cref="Playlist.Id"/>
+        public static string Id => "PLAYLIST_ID";
+
+        /// <summary>
+        /// Gets the column name for the member order of playlist.
+        /// </summary>
+        /// <value>The column name for the member order of playlist.</value>
+        /// <remarks>
+        /// The value type is integer.
+        /// </remarks>
+        /// <seealso cref="PlaylistCommand.UpdatePlayOrder(int, PlayOrder)"/>
+        public static string MemberOrder => "PLAYLIST_MEMBER_ORDER";
+
+        /// <summary>
+        /// Gets the column name for the number of members of playlist.
+        /// </summary>
+        /// <value>The column name for the number of members of playlist.</value>
+        /// <remarks>
+        /// The value type is integer.
+        /// </remarks>
+        /// <seealso cref="PlaylistCommand.AddMember(int, string)"/>
+        /// <seealso cref="PlaylistCommand.RemoveMember(int, int)"/>
+        public static string Count => "PLAYLIST_MEDIA_COUNT";
+    }
+
+    /// <summary>
+    /// Provides the tag column names that can be used for <see cref="SelectArguments"/>.
+    /// </summary>
+    /// <seealso cref="SelectArguments"/>
+    /// <seealso cref="CountArguments"/>
+    /// <seealso cref="QueryArguments.FilterExpression"/>
+    /// <seealso cref="SelectArguments.SortOrder"/>
+    /// <seealso cref="MediaInfoCommand.CountTag(string, CountArguments)"/>
+    /// <seealso cref="MediaInfoCommand.SelectTag(string, SelectArguments)"/>
+    /// <seealso cref="TagCommand.Count(CountArguments)"/>
+    /// <seealso cref="TagCommand.CountMedia(int, CountArguments)"/>
+    /// <seealso cref="TagCommand.Select(SelectArguments)"/>
+    /// <seealso cref="TagCommand.SelectMedia(int, SelectArguments)"/>
+    public static class TagColumns
+    {
+        /// <summary>
+        /// Gets the column name for the name of tag.
+        /// </summary>
+        /// <value>The column name for the name of tag.</value>
+        /// <remarks>
+        /// The value type is string.
+        /// </remarks>
+        /// <seealso cref="Tag.Name"/>
+        public static string Name => "TAG_NAME";
+
+        /// <summary>
+        /// Gets the column name for the number of media of tag.
+        /// </summary>
+        /// <value>The column name for the number of media of tag.</value>
+        /// <remarks>
+        /// The value type is integer.
+        /// </remarks>
+        /// <seealso cref="TagCommand.AddMedia(int, string)"/>
+        /// <seealso cref="TagCommand.RemoveMedia(int, string)"/>
+        public static string Count => "TAG_MEDIA_COUNT";
+
+        /// <summary>
+        /// Gets the column name for the id of tag.
+        /// </summary>
+        /// <value>The column name for the id of tag.</value>
+        /// <remarks>
+        /// The value type is integer.
+        /// </remarks>
+        /// <seealso cref="Tag.Id"/>
+        public static string Id => "TAG_ID";
+    }
+
+    /// <summary>
+    /// Provides the bookmark column names that can be used for Select and Count commands.
+    /// </summary>
+    /// <seealso cref="SelectArguments"/>
+    /// <seealso cref="CountArguments"/>
+    /// <seealso cref="QueryArguments.FilterExpression"/>
+    /// <seealso cref="SelectArguments.SortOrder"/>
+    /// <seealso cref="BookmarkCommand.Count(CountArguments)"/>
+    /// <seealso cref="BookmarkCommand.Select(SelectArguments)"/>
+    /// <seealso cref="MediaInfoCommand.CountBookmark(string, CountArguments)"/>
+    /// <seealso cref="MediaInfoCommand.SelectBookmark(string, SelectArguments)"/>
+    public static class BookmarkColumns
+    {
+        /// <summary>
+        /// Gets the column name for offset of bookmark.
+        /// </summary>
+        /// <value>The column name for the offset of bookmark.</value>
+        /// <remarks>
+        /// The value type is integer.
+        /// </remarks>
+        /// <seealso cref="Bookmark.Offset"/>
+        public static string Offset => "BOOKMARK_MARKED_TIME";
+
+        /// <summary>
+        /// Gets the column name for the id of bookmark.
+        /// </summary>
+        /// <value>The column name for the id of bookmark.</value>
+        /// <remarks>
+        /// The value type is integer.
+        /// </remarks>
+        /// <seealso cref="Bookmark.Id"/>
+        public static string Id => "BOOKMARK_ID";
+
+        /// <summary>
+        /// Gets the column name for the name of bookmark.
+        /// </summary>
+        /// <value>The column name for the name of bookmark.</value>
+        /// <remarks>
+        /// The value type is string.
+        /// </remarks>
+        /// <seealso cref="Bookmark.Name"/>
+        public static string Name => "BOOKMARK_NAME";
+    }
+
+    /// <summary>
+    /// Provides the face info column names that can be used for Select and Count commands.
+    /// </summary>
+    /// <seealso cref="SelectArguments"/>
+    /// <seealso cref="CountArguments"/>
+    /// <seealso cref="QueryArguments.FilterExpression"/>
+    /// <seealso cref="SelectArguments.SortOrder"/>
+    /// <seealso cref="FaceInfoCommand.Select(SelectArguments)"/>
+    /// <seealso cref="MediaInfoCommand.CountFaceInfo(string, CountArguments)"/>
+    /// <seealso cref="MediaInfoCommand.SelectFaceInfo(string, SelectArguments)"/>
+    public static class FaceInfoColumns
+    {
+        /// <summary>
+        /// Gets the column name for the tag of face info.
+        /// </summary>
+        /// <value>The column name for the tag of face info.</value>
+        /// <remarks>
+        /// The value type is string.
+        /// </remarks>
+        /// <seealso cref="FaceInfo.Tag"/>
+        public static string Tag => "MEDIA_FACE_TAG";
+
+        /// <summary>
+        /// Gets the column name for the id of face info.
+        /// </summary>
+        /// <value>The column name for the id of face info.</value>
+        /// <remarks>
+        /// The value type is string.
+        /// </remarks>
+        /// <seealso cref="FaceInfo.Id"/>
+        public static string Id => "MEDIA_FACE_ID";
+    }
+
+    /// <summary>
+    /// Provides the storage column names that can be used for Select and Count commands.
+    /// </summary>
+    /// <seealso cref="SelectArguments"/>
+    /// <seealso cref="CountArguments"/>
+    /// <seealso cref="QueryArguments.FilterExpression"/>
+    /// <seealso cref="SelectArguments.SortOrder"/>
+    /// <seealso cref="StorageCommand.Count(CountArguments)"/>
+    /// <seealso cref="StorageCommand.Select(SelectArguments)"/>
+    public static class StorageColumns
+    {
+        /// <summary>
+        /// Gets the column name for the id of storage.
+        /// </summary>
+        /// <value>The column name for the id of storage.</value>
+        /// <remarks>
+        /// The value type is string.
+        /// </remarks>
+        /// <seealso cref="Storage.Id"/>
+        public static string Id => "STORAGE_ID";
+
+        /// <summary>
+        /// Gets the column name for the path of storage.
+        /// </summary>
+        /// <value>The column name for the path of storage.</value>
+        /// <remarks>
+        /// The value type is string.
+        /// </remarks>
+        /// <seealso cref="Storage.Path"/>
+        public static string Path => "STORAGE_PATH";
+
+        /// <summary>
+        /// Gets the column name for the type of storage.
+        /// </summary>
+        /// <value>The column name for the type of storage.</value>
+        /// <remarks>
+        /// The value type is integer.
+        /// The value should be an integer that is one of <see cref="MediaContent.StorageType"/> values.
+        /// </remarks>
+        /// <seealso cref="Storage.Type"/>
+        public static string Type => "MEDIA_STORAGE_TYPE";
+    }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/CommandHelper.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/CommandHelper.cs
new file mode 100644 (file)
index 0000000..b244cf5
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using FilterHandle = Interop.FilterHandle;
+
+namespace Tizen.Content.MediaContent
+{
+    internal static class CommandHelper
+    {
+        internal delegate MediaContentError CountFunc(FilterHandle filter, out int count);
+
+        internal delegate MediaContentError CountFunc<T>(T param, FilterHandle filter,
+            out int count);
+
+        internal static int Count(CountFunc countFunc, CountArguments arguments)
+        {
+            using (var filter = QueryArguments.ToNativeHandle(arguments))
+            {
+                countFunc(filter, out var count).ThrowIfError("Failed to query count");
+                return count;
+            }
+        }
+
+        internal static int Count(CountFunc countFunc, string filter)
+        {
+            return Count(countFunc, new CountArguments { FilterExpression = filter });
+        }
+
+        internal static int Count<T>(CountFunc<T> countFunc, T param, CountArguments arguments)
+        {
+            using (var filter = QueryArguments.ToNativeHandle(arguments))
+            {
+                countFunc(param, filter, out var count).ThrowIfError("Failed to query count");
+                return count;
+            }
+        }
+
+        internal static void Delete<T>(Func<T, MediaContentError> func, T param)
+        {
+            func(param).ThrowIfError("Failed to execute the command");
+        }
+
+        internal delegate MediaContentError ForeachFunc<T>(T param, FilterHandle filter,
+            Interop.Common.ItemCallback callback, IntPtr data = default(IntPtr));
+
+        internal static MediaDataReader<MediaInfo> SelectMedia<T>(ForeachFunc<T> func, T param,
+            SelectArguments arguments)
+        {
+            using (var filter = QueryArguments.ToNativeHandle(arguments))
+            {
+                var items = new List<MediaInfo>();
+                Exception exception = null;
+
+                func(param, filter, (mediaInfoHandle, _) =>
+                {
+                    try
+                    {
+                        items.Add(MediaInfo.FromHandle(mediaInfoHandle));
+                        return true;
+                    }
+                    catch (Exception e)
+                    {
+                        exception = e;
+                        return false;
+                    }
+                }).ThrowIfError("Failed to query");
+
+                if (exception != null)
+                {
+                    throw exception;
+                }
+
+                return new MediaDataReader<MediaInfo>(items);
+            }
+        }
+
+        internal delegate MediaContentError ForeachFunc(FilterHandle filter,
+            Interop.Common.ItemCallback callback, IntPtr data = default(IntPtr));
+
+        internal static MediaDataReader<TRecord> Select<TRecord>(SelectArguments arguments,
+            ForeachFunc foreachFunc,
+            Func<IntPtr, TRecord> factoryFunc)
+        {
+            using (var filter = QueryArguments.ToNativeHandle(arguments))
+            {
+                Exception caught = null;
+                var items = new List<TRecord>();
+
+                foreachFunc(filter, (itemHandle, _) =>
+                {
+                    try
+                    {
+                        items.Add(factoryFunc(itemHandle));
+                        return true;
+                    }
+                    catch (Exception e)
+                    {
+                        caught = e;
+                        return false;
+                    }
+                }).ThrowIfError("Failed to execute query");
+
+                if (caught != null)
+                {
+                    throw caught;
+                }
+
+                return new MediaDataReader<TRecord>(items);
+            }
+        }
+
+
+        internal delegate MediaContentError CloneFunc(out IntPtr output, IntPtr input);
+
+        internal static IntPtr SelectScalar(ForeachFunc foreachFunc, string filterExpression,
+            CloneFunc cloneFunc)
+        {
+            using (var filter = QueryArguments.CreateNativeHandle(filterExpression))
+            {
+                IntPtr handle = IntPtr.Zero;
+
+                foreachFunc(filter, (itemHandle, _) =>
+                {
+                    cloneFunc(out handle, itemHandle);
+                    return false;
+                }).ThrowIfError("Failed to execute query");
+
+                return handle;
+            }
+        }
+
+        internal delegate MediaContentError ForeachMemberFunc<TParam>(TParam param,
+            FilterHandle filter, Interop.Common.ItemCallback callback, IntPtr data = default(IntPtr));
+
+        internal static MediaDataReader<TRecord> SelectMembers<TParam, TRecord>(TParam param,
+            SelectArguments arguments, ForeachMemberFunc<TParam> foreachFunc,
+            Func<IntPtr, TRecord> factoryFunc)
+        {
+            using (var filter = QueryArguments.ToNativeHandle(arguments))
+            {
+                Exception caught = null;
+                var items = new List<TRecord>();
+
+                foreachFunc(param, filter, (itemHandle, _) =>
+                {
+                    try
+                    {
+                        items.Add(factoryFunc(itemHandle));
+
+                        return true;
+                    }
+                    catch (Exception e)
+                    {
+                        caught = e;
+                        return false;
+                    }
+                }).ThrowIfError("Failed to execute query");
+
+                if (caught != null)
+                {
+                    throw caught;
+                }
+
+                return new MediaDataReader<TRecord>(items);
+            }
+        }
+    }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentCollection.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentCollection.cs
deleted file mode 100755 (executable)
index 2e4ae7e..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
-* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
-*
-* Licensed under the Apache License, Version 2.0 (the License);
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an AS IS BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-
-
-using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-
-namespace Tizen.Content.MediaContent
-{
-    public abstract class ContentCollection : IDisposable
-    {
-        /// <summary>
-        /// Gets the media count for this content store matching the passed filter
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="filter">the media filter</param>
-        /// <returns>Media count</returns>
-        public abstract int GetMediaInformationCount(ContentFilter filter);
-
-        /// <summary>
-        /// Destroys the unmanaged handles.
-        /// Call Dispose API once Contentcollection operations are completed.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public abstract void Dispose();
-
-        /// <summary>
-        /// Gets the media matching the passed filter for this content store, asynchronously
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="filter">The media filter</param>
-        /// <returns>Task with Media Information list</returns>
-        public abstract IEnumerable<MediaInformation> GetMediaInformations(ContentFilter filter);
-    }
-}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentColumns.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentColumns.cs
deleted file mode 100755 (executable)
index 6c10037..0000000
+++ /dev/null
@@ -1,1130 +0,0 @@
-/*
-* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
-*
-* Licensed under the Apache License, Version 2.0 (the License);
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an AS IS BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-
-
-namespace Tizen.Content.MediaContent
-{
-    /// <summary>
-    /// A ContentColumns class defines the keyword used for filter condition or sorting.
-    /// </summary>
-    public static class ContentColumns
-    {
-        /// <summary>
-        /// Media column set. \n
-        /// You can use this define to set the condition of media filter and order keyword.
-        /// </summary>
-        public class Media
-        {
-            /// <summary>
-            /// Media UUID
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Id
-            {
-                get
-                {
-                    return "MEDIA_ID";
-                }
-            }
-
-            /// <summary>
-            /// Media path
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Path
-            {
-                get
-                {
-                    return "MEDIA_PATH";
-                }
-            }
-
-            /// <summary>
-            /// Display name
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string DisplayName
-            {
-                get
-                {
-                    return "MEDIA_DISPLAY_NAME";
-                }
-            }
-
-            /// <summary>
-            /// The type of media (0-image, 1-video, 2-sound, 3-music, 4-other)
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string MediaType
-            {
-                get
-                {
-                    return "MEDIA_TYPE";
-                }
-            }
-
-            /// <summary>
-            /// Mime type
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string MimeType
-            {
-                get
-                {
-                    return "MEDIA_MIME_TYPE";
-                }
-            }
-
-
-            /// <summary>
-            /// File size
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Size
-            {
-                get
-                {
-                    return "MEDIA_SIZE";
-                }
-            }
-
-            /// <summary>
-            /// Added time
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string AddedTime
-            {
-                get
-                {
-                    return "MEDIA_ADDED_TIME";
-                }
-            }
-
-            /// <summary>
-            /// Modified time
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string ModifiedTime
-            {
-                get
-                {
-                    return "MEDIA_MODIFIED_TIME";
-                }
-            }
-
-            /// <summary>
-            /// Timeline. Normally, creation date of media
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Timeline
-            {
-                get
-                {
-                    return "MEDIA_TIMELINE";
-                }
-            }
-
-            /// <summary>
-            /// The path of thumbnail
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string ThumbnailPath
-            {
-                get
-                {
-                    return "MEDIA_THUMBNAIL_PATH";
-                }
-            }
-
-            /// <summary>
-            /// Title
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Title
-            {
-                get
-                {
-                    return "MEDIA_TITLE";
-                }
-            }
-
-            /// <summary>
-            /// Album name
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Album
-            {
-                get
-                {
-                    return "MEDIA_ALBUM";
-                }
-            }
-
-            /// <summary>
-            /// Artist
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Artist
-            {
-                get
-                {
-                    return "MEDIA_ARTIST";
-                }
-            }
-
-            /// <summary>
-            /// Album artist
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string AlbumArtist
-            {
-                get
-                {
-                    return "MEDIA_ALBUM_ARTIST";
-                }
-            }
-
-            /// <summary>
-            /// Genre
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Genre
-            {
-                get
-                {
-                    return "MEDIA_GENRE";
-                }
-            }
-
-            /// <summary>
-            /// Composer
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Composer
-            {
-                get
-                {
-                    return "MEDIA_COMPOSER";
-                }
-            }
-
-            /// <summary>
-            /// Release year
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Year
-            {
-                get
-                {
-                    return "MEDIA_YEAR";
-                }
-            }
-
-            /// <summary>
-            /// Recorded date
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string RecordedDate
-            {
-                get
-                {
-                    return "MEDIA_RECORDED_DATE";
-                }
-            }
-
-            /// <summary>
-            /// Copyright
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Copyright
-            {
-                get
-                {
-                    return "MEDIA_COPYRIGHT";
-                }
-            }
-
-            /// <summary>
-            /// Track Number
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string TrackNumber
-            {
-                get
-                {
-                    return "MEDIA_TRACK_NUM";
-                }
-            }
-
-            /// <summary>
-            /// Description
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Description
-            {
-                get
-                {
-                    return "MEDIA_DESCRIPTION";
-                }
-            }
-
-            /// <summary>
-            /// Bitrate
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Bitrate
-            {
-                get
-                {
-                    return "MEDIA_BITRATE";
-                }
-            }
-
-            /// <summary>
-            /// Bit per sample
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string BitPerSample
-            {
-                get
-                {
-                    return "MEDIA_BITPERSAMPLE";
-                }
-            }
-
-            /// <summary>
-            /// Samplerate
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Samplerate
-            {
-                get
-                {
-                    return "MEDIA_SAMPLERATE";
-                }
-            }
-
-            /// <summary>
-            /// Channel
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Channel
-            {
-                get
-                {
-                    return "MEDIA_CHANNEL";
-                }
-            }
-
-            /// <summary>
-            /// Duration
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Duration
-            {
-                get
-                {
-                    return "MEDIA_DURATION";
-                }
-            }
-
-            /// <summary>
-            /// Longitude
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Longitude
-            {
-                get
-                {
-                    return "MEDIA_LONGITUDE";
-                }
-            }
-
-            /// <summary>
-            /// Latitude
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Latitude
-            {
-                get
-                {
-                    return "MEDIA_LATITUDE";
-                }
-            }
-
-            /// <summary>
-            /// Altitude
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Altitude
-            {
-                get
-                {
-                    return "MEDIA_ALTITUDE";
-                }
-            }
-            /// <summary>
-            /// Width
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Width
-            {
-                get
-                {
-                    return "MEDIA_WIDTH";
-                }
-            }
-
-            /// <summary>
-            /// Height
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Height
-            {
-                get
-                {
-                    return "MEDIA_HEIGHT";
-                }
-            }
-
-            /// <summary>
-            /// Datetaken
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Datetaken
-            {
-                get
-                {
-                    return "MEDIA_DATETAKEN";
-                }
-            }
-
-            /// <summary>
-            /// Orientation
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Orientation
-            {
-                get
-                {
-                    return "MEDIA_ORIENTATION";
-                }
-            }
-
-            /// <summary>
-            /// Burst shot ID
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string BurstId
-            {
-                get
-                {
-                    return "BURST_ID";
-                }
-            }
-
-            /// <summary>
-            /// Played count
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string PlayedCount
-            {
-                get
-                {
-                    return "MEDIA_PLAYED_COUNT";
-                }
-            }
-
-            /// <summary>
-            /// Last played time
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string PlayedTime
-            {
-                get
-                {
-                    return "MEDIA_LAST_PLAYED_TIME";
-                }
-            }
-
-            /// <summary>
-            /// Last played position
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string PlayedPosition
-            {
-                get
-                {
-                    return "MEDIA_LAST_PLAYED_POSITION";
-                }
-            }
-
-            /// <summary>
-            /// Rating
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Rating
-            {
-                get
-                {
-                    return "MEDIA_RATING";
-                }
-            }
-
-            /// <summary>
-            /// Favourite
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Favourite
-            {
-                get
-                {
-                    return "MEDIA_FAVOURITE";
-                }
-            }
-
-            /// <summary>
-            /// Author
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Author
-            {
-                get
-                {
-                    return "MEDIA_AUTHOR";
-                }
-            }
-
-            /// <summary>
-            /// Provider
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Provider
-            {
-                get
-                {
-                    return "MEDIA_PROVIDER";
-                }
-            }
-            /// <summary>
-            /// Content name
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string ContentName
-            {
-                get
-                {
-                    return "MEDIA_CONTENT_NAME";
-                }
-            }
-
-            /// <summary>
-            /// Category
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Category
-            {
-                get
-                {
-                    return "MEDIA_CATEGORY";
-                }
-            }
-            /// <summary>
-            /// Location tag
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string LocationTag
-            {
-                get
-                {
-                    return "MEDIA_LOCATION_TAG";
-                }
-            }
-
-            /// <summary>
-            /// Age rating
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string AgeRating
-            {
-                get
-                {
-                    return "MEDIA_AGE_RATING";
-                }
-            }
-
-            /// <summary>
-            /// Keyword
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Keyword
-            {
-                get
-                {
-                    return "MEDIA_KEYWORD";
-                }
-            }
-
-            /// <summary>
-            /// Weather
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Weather
-            {
-                get
-                {
-                    return "MEDIA_WEATHER";
-                }
-            }
-
-            /// <summary>
-            /// Whether DRM(1) or not(0)
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string IsDRM
-            {
-                get
-                {
-                    return "MEDIA_IS_DRM";
-                }
-            }
-
-            /// <summary>
-            /// Storage type
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string StorageType
-            {
-                get
-                {
-                    return "MEDIA_STORAGE_TYPE";
-                }
-            }
-
-            /// <summary>
-            /// Exposure time
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string ExposureTime
-            {
-                get
-                {
-                    return "MEDIA_EXPOSURE_TIME";
-                }
-            }
-
-            /// <summary>
-            /// f-number
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string FNumber
-            {
-                get
-                {
-                    return "MEDIA_FNUMBER";
-                }
-            }
-
-            /// <summary>
-            /// ISO
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Iso
-            {
-                get
-                {
-                    return "MEDIA_ISO";
-                }
-            }
-
-            /// <summary>
-            /// Model
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Model
-            {
-                get
-                {
-                    return "MEDIA_MODEL";
-                }
-            }
-
-            /// <summary>
-            /// 360 content
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Media360
-            {
-                get
-                {
-                    return "MEDIA_360";
-                }
-            }
-
-            /// <summary>
-            /// Keyword for pinyin
-            /// </summary>
-            public class Pinyin
-            {
-                /// <summary>
-                /// File name (pinyin)
-                /// </summary>
-                /// <since_tizen> 4 </since_tizen>
-                public static string FileName
-                {
-                    get
-                    {
-                        return "MEDIA_FILE_NAME_PINYIN";
-                    }
-                }
-
-                /// <summary>
-                /// Title (pinyin)
-                /// </summary>
-                /// <since_tizen> 4 </since_tizen>
-                public static string Title
-                {
-                    get
-                    {
-                        return "MEDIA_TITLE_PINYIN";
-                    }
-                }
-
-                /// <summary>
-                /// Album (pinyin)
-                /// </summary>
-                /// <since_tizen> 4 </since_tizen>
-                public static string Album
-                {
-                    get
-                    {
-                        return "MEDIA_ALBUM_PINYIN";
-                    }
-                }
-
-                /// <summary>
-                /// Artist (pinyin)
-                /// </summary>
-                /// <since_tizen> 4 </since_tizen>
-                public static string Artist
-                {
-                    get
-                    {
-                        return "MEDIA_ARTIST_PINYIN";
-                    }
-                }
-
-                /// <summary>
-                /// Album artist (pinyin)
-                /// </summary>
-                /// <since_tizen> 4 </since_tizen>
-                public static string AlbumArtist
-                {
-                    get
-                    {
-                        return "MEDIA_ALBUM_ARTIST_PINYIN";
-                    }
-                }
-
-                /// <summary>
-                /// Genre (pinyin)
-                /// </summary>
-                /// <since_tizen> 4 </since_tizen>
-                public static string Genre
-                {
-                    get
-                    {
-                        return "MEDIA_GENRE_PINYIN";
-                    }
-                }
-
-                /// <summary>
-                /// Composer (pinyin)
-                /// </summary>
-                /// <since_tizen> 4 </since_tizen>
-                public static string Composer
-                {
-                    get
-                    {
-                        return "MEDIA_COMPOSER_PINYIN";
-                    }
-                }
-
-                /// <summary>
-                /// Copyright (pinyin)
-                /// </summary>
-                /// <since_tizen> 4 </since_tizen>
-                public static string Copyright
-                {
-                    get
-                    {
-                        return "MEDIA_COPYRIGHT_PINYIN";
-                    }
-                }
-
-                /// <summary>
-                /// Description (pinyin)
-                /// </summary>
-                /// <since_tizen> 4 </since_tizen>
-                public static string Description
-                {
-                    get
-                    {
-                        return "MEDIA_DESCRIPTION_PINYIN";
-                    }
-                }
-
-                /// <summary>
-                /// Author (pinyin)
-                /// </summary>
-                /// <since_tizen> 4 </since_tizen>
-                public static string Author
-                {
-                    get
-                    {
-                        return "MEDIA_AUTHOR_PINYIN";
-                    }
-                }
-
-                /// <summary>
-                /// Provider (pinyin)
-                /// </summary>
-                /// <since_tizen> 4 </since_tizen>
-                public static string Provider
-                {
-                    get
-                    {
-                        return "MEDIA_PROVIDER_PINYIN";
-                    }
-                }
-
-                /// <summary>
-                /// Content name (pinyin)
-                /// </summary>
-                /// <since_tizen> 4 </since_tizen>
-                public static string ContentName
-                {
-                    get
-                    {
-                        return "MEDIA_CONTENT_NAME_PINYIN";
-                    }
-                }
-
-                /// <summary>
-                /// Category (pinyin)
-                /// </summary>
-                /// <since_tizen> 4 </since_tizen>
-                public static string Category
-                {
-                    get
-                    {
-                        return "MEDIA_CATEGORY_PINYIN";
-                    }
-                }
-
-                /// <summary>
-                /// Location tag (pinyin)
-                /// </summary>
-                /// <since_tizen> 4 </since_tizen>
-                public static string LocationTag
-                {
-                    get
-                    {
-                        return "MEDIA_LOCATION_TAG_PINYIN";
-                    }
-                }
-
-                /// <summary>
-                /// Age rating (pinyin)
-                /// </summary>
-                /// <since_tizen> 4 </since_tizen>
-                public static string AgeRating
-                {
-                    get
-                    {
-                        return "MEDIA_AGE_RATING_PINYIN";
-                    }
-                }
-
-                /// <summary>
-                /// Keyword (pinyin)
-                /// </summary>
-                /// <since_tizen> 4 </since_tizen>
-                public static string Keyword
-                {
-                    get
-                    {
-                        return "MEDIA_KEYWORD_PINYIN";
-                    }
-                }
-            }
-        }
-
-        /// <summary>
-        /// Folder column set. \n
-        /// You can use this define to set the condition of folder filter and order keyword.
-        /// </summary>
-        public class Folder
-        {
-
-            /// <summary>
-            ///Folder UUID
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Id
-            {
-                get
-                {
-                    return "FOLDER_ID";
-                }
-            }
-
-            /// <summary>
-            /// Folder path
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Path
-            {
-                get
-                {
-                    return "FOLDER_PATH";
-                }
-            }
-
-            /// <summary>
-            /// Folder name
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Name
-            {
-                get
-                {
-                    return "FOLDER_NAME";
-                }
-            }
-
-            /// <summary>
-            /// Folder modified time
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string ModifiedTime
-            {
-                get
-                {
-                    return "FOLDER_MODIFIED_TIME";
-                }
-            }
-
-            /// <summary>
-            /// Folder storage type
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string StorageType
-            {
-                get
-                {
-                    return "FOLDER_STORAGE_TYPE";
-                }
-            }
-
-            /// <summary>
-            /// Keyword for pinyin
-            /// </summary>
-            public class Pinyin
-            {
-                /// <summary>
-                /// Folder name (pinyin)
-                /// </summary>
-                /// <since_tizen> 4 </since_tizen>
-                public static string Name
-                {
-                    get
-                    {
-                        return "FOLDER_NAME_PINYIN";
-                    }
-                }
-
-            }
-
-            /// <summary>
-            /// Folder order. Default is 0
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Order
-            {
-                get
-                {
-                    return "FOLDER_ORDER";
-                }
-            }
-
-            /// <summary>
-            /// Parent folder UUID
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string ParentId
-            {
-                get
-                {
-                    return "FOLDER_PARENT_FOLDER_ID";
-                }
-            }
-        }
-
-        /// <summary>
-        /// Playlist column set. \n
-        /// You can use this define to set the condition of playlist filter and order keyword.
-        /// </summary>
-        public class Playlist
-        {
-            /// <summary>
-            /// Playlist name
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Name
-            {
-                get
-                {
-                    return "PLAYLIST_NAME";
-                }
-            }
-            /// <summary>
-            /// Playlist member's play order
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Order
-            {
-                get
-                {
-                    return "PLAYLIST_MEMBER_ORDER";
-                }
-            }
-
-            /// <summary>
-            /// Count of media in the playlist
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Count
-            {
-                get
-                {
-                    return "PLAYLIST_MEDIA_COUNT";
-                }
-            }
-        }
-
-        /// <summary>
-        /// Tag column set. \n
-        /// You can use this define to set the condition of tag filter and order keyword.
-        /// </summary>
-        public class Tag
-        {
-            /// <summary>
-            /// Tag name
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Name
-            {
-                get
-                {
-                    return "TAG_NAME";
-                }
-            }
-
-            /// <summary>
-            /// Count of media in the tag
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Count
-            {
-                get
-                {
-                    return "TAG_MEDIA_COUNT";
-                }
-            }
-        }
-
-        /// <summary>
-        /// Bookmark column set. \n
-        /// You can use this define to set the condition of bookmark filter and order keyword.
-        /// </summary>
-        public class Bookmark
-        {
-            /// <summary>
-            /// Bookmarked offset
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Offset
-            {
-                get
-                {
-                    return "BOOKMARK_MARKED_TIME";
-                }
-            }
-        }
-
-        /// <summary>
-        /// Storage column set. \n
-        /// You can use this define to set the condition of storage filter and order keyword.
-        /// </summary>
-        public class Storage
-        {
-            /// <summary>
-            /// Storage UUID
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Id
-            {
-                get
-                {
-                    return "STORAGE_ID";
-                }
-            }
-
-            /// <summary>
-            /// Storage path
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Path
-            {
-                get
-                {
-                    return "STORAGE_PATH";
-                }
-            }
-        }
-
-        /// <summary>
-        /// Face column set. \n
-        /// You can use this define to set the condition of face filter and order keyword.
-        /// </summary>
-        public class Face
-        {
-            /// <summary>
-            /// face tag
-            /// </summary>
-            /// <since_tizen> 4 </since_tizen>
-            public static string Tag
-            {
-                get
-                {
-                    return "MEDIA_FACE_TAG";
-                }
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentDatabase.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentDatabase.cs
deleted file mode 100755 (executable)
index e2389a3..0000000
+++ /dev/null
@@ -1,714 +0,0 @@
-/*
-* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
-*
-* Licensed under the Apache License, Version 2.0 (the License);
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an AS IS BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-
-
-using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-/// <summary>
-/// The Media Content API provides functions, enumerations used in the entire Content Service.
-/// </summary>
-/// <remarks>
-/// The Media Content API provides functions and enumerations used in the entire Content Service.
-/// The information about media items i.e.image, audio and video, are managed in the content database
-/// and operations that involve database requires an active connection with the media content service.
-/// During media scanning, Media Service extract media information automatically. media information
-/// include basic file info like path, size, modified time etc and some metadata like ID3tag, EXIF,
-/// thumbnail, etc. (thumbnail extracted only in Internal and SD card storage.
-/// Media content services do not manage hidden files.
-/// The API provides functions for connecting (media_content_connect()) and disconnecting(media_content_disconnect())
-/// from the media content service.
-/// </remarks>
-
-
-namespace Tizen.Content.MediaContent
-{
-    /// <summary>
-    /// ContentDatabase class is the interface class for managing the ContentCollection and MediaInformation from/to the database.
-    /// This class allows usre to access/create/update db operations for media content.
-    /// </summary>
-    public class ContentDatabase
-    {
-        private static IntPtr _updateHandle = IntPtr.Zero;
-
-        /// <summary>
-        /// Connect to the media database to search, insert, remove or modify media information.
-        /// </summary>
-        /// <since_tizen> 4 </since_tizen>
-        /// <remarks>
-        /// For information security, disconnect() after use media database.
-        /// </remarks>
-        public static void Connect()
-        {
-            MediaContentValidator.ThrowIfError(Interop.Content.Connect(), "Connect failed");
-        }
-
-        /// <summary>
-        /// Disconnect from the media database.
-        /// </summary>
-        /// <since_tizen> 4 </since_tizen>
-        public static void Disconnect()
-        {
-            MediaContentValidator.ThrowIfError(Interop.Content.Disconnect(), "Disconnect failed");
-        }
-
-        private static readonly Interop.Content.MediaContentDBUpdatedCallback s_contentUpdatedCallback = (
-            MediaContentError error,
-            int pid,
-            MediaContentUpdateItemType updateItem,
-            MediaContentDBUpdateType updateType,
-            MediaContentType mediaType,
-            string uuid,
-            string filePath,
-            string mimeType,
-            IntPtr userData) =>
-        {
-            _contentUpdated?.Invoke(
-                null, new ContentUpdatedEventArgs(error, pid, updateItem, updateType, mediaType, uuid, filePath, mimeType));
-        };
-
-        private static event EventHandler<ContentUpdatedEventArgs> _contentUpdated;
-        /// <summary>
-        /// ContentUpdated event is triggered when the media DB changes.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="sender"></param>
-        /// <param name="e">A ContentUpdatedEventArgs object that contains information about the update operation.</param>
-        public static event EventHandler<ContentUpdatedEventArgs> ContentUpdated
-        {
-            add
-            {
-                if (_contentUpdated == null)
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.Content.AddDbUpdatedCb(s_contentUpdatedCallback, IntPtr.Zero, out _updateHandle), "Failed to set callback");
-                }
-
-                _contentUpdated += value;
-            }
-
-            remove
-            {
-                _contentUpdated -= value;
-                if (_contentUpdated == null)
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.Content.RemoveDbUpdatedCb(_updateHandle), "Failed to unset callback");
-                }
-            }
-        }
-
-        /// <summary>
-        /// Gets the count of ContentCollections for the ContentCollectionType and passed filter from the media database.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="filter">The media filter</param>
-        /// <returns>The count of contents present in the media database for a ContentSourceType</returns>
-        public int GetCount<T>(ContentFilter filter) where T : class
-        {
-            int count = 0;
-            IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
-            MediaGroupType groupType = MediaGroupType.DisplayName;
-            if (handle != IntPtr.Zero)
-            {
-                groupType = filter.GroupType;
-            }
-
-            if (typeof(T) == typeof(MediaInformation))
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.GetMediaCount(handle, out count), "Failed to get count");
-            }
-            else if (typeof(T) == typeof(MediaBookmark))
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaBookmark.GetBookmarkCountFromDb(handle, out count), "Failed to get count");
-            }
-            else if (typeof(T) == typeof(Album))
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.Group.MediaAlbumGetAlbumCountFromDb(handle, out count), "Failed to get count");
-            }
-            else if (typeof(T) == typeof(MediaFolder))
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.Folder.GetFolderCountFromDb(handle, out count), "Failed to get count");
-            }
-            else if (typeof(T) == typeof(Storage))
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.Storage.GetStorageCountFromDb(handle, out count), "Failed to get count");
-            }
-            else if (typeof(T) == typeof(Tag))
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.Tag.GetTagCountFromDb(handle, out count), "Failed to get count");
-            }
-            else if (typeof(T) == typeof(PlayList))
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.Playlist.GetPlaylistCountFromDb(handle, out count), "Failed to get count");
-            }
-            else if (typeof(T) == typeof(Group))
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.Group.GetGroupCountFromDb(handle, groupType, out count), "Failed to get count");
-            }
-            else
-            {
-                throw new ArgumentException("Wrong type");
-            }
-
-            return count;
-        }
-
-        /// <summary>
-        /// Gets the MediaInformation object for the passed media Id.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="id">The media id to fetch the respective MediaInformation instance</param>
-        /// <returns>MediaInformation instance for the associated id.It throws Exception for invalid Id.</returns>
-        public MediaInformation Select(string id)
-        {
-            Interop.MediaInformation.SafeMediaInformationHandle mediaHandle;
-            MediaContentValidator.ThrowIfError(
-                Interop.MediaInformation.GetMediaFromDB(id, out mediaHandle), "Failed to get information");
-
-            MediaContentType type;
-            MediaInformation res;
-            Interop.MediaInformation.GetMediaType(mediaHandle, out type);
-            if (type == MediaContentType.Image)
-            {
-                Interop.ImageInformation.SafeImageInformationHandle imageInfo;
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.GetImage(mediaHandle.DangerousGetHandle(), out imageInfo), "Failed to get image information");
-
-                res = new ImageInformation(imageInfo, mediaHandle);
-            }
-            else if ((type == MediaContentType.Music) || (type == MediaContentType.Sound))
-            {
-                Interop.AudioInformation.SafeAudioInformationHandle audioInfo;
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.GetAudio(mediaHandle.DangerousGetHandle(), out audioInfo), "Failed to get audio information");
-
-                res = new AudioInformation(audioInfo, mediaHandle);
-            }
-            else if (type == MediaContentType.Video)
-            {
-                Interop.VideoInformation.SafeVideoInformationHandle videoInfo;
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.GetVideo(mediaHandle.DangerousGetHandle(), out videoInfo), "Failed to get video information");
-
-                res = new VideoInformation(videoInfo, mediaHandle);
-            }
-            else
-            {
-                res = new MediaInformation(mediaHandle);
-            }
-
-            return res;
-        }
-
-        /// <summary>
-        /// Gets the ContentCollection object for the passed media Id.
-        /// Applicable for MediaFolder and Storage types.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="id">The ContentCollection id to fetch the respective MediaInformation instance</param>
-        /// <returns>ContentCollection instance for the associated id.It throws Exception for invalid Id.</returns>
-        public T Select<T>(string id) where T : ContentCollection
-        {
-            ContentCollection result = null;
-            IntPtr handle = IntPtr.Zero;
-
-            if (typeof(T) == typeof(MediaFolder))
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.Folder.GetFolderFromDb(id, out handle), "Failed to get information");
-
-                if (handle != IntPtr.Zero)
-                {
-                    result = new MediaFolder(handle);
-                    return (T)result;
-                }
-
-            }
-            else if (typeof(T) == typeof(Storage))
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.Storage.GetStorageInfoFromDb(id, out handle), "Failed to get information");
-
-                if (handle != IntPtr.Zero)
-                {
-                    result = new Storage(handle);
-                    return (T)result;
-                }
-            }
-
-            return null;
-        }
-
-
-        /// <summary>
-        /// Gets the ContentCollection object for the passed media Id.
-        /// Applicable for PlayList, Album and Tag types.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="id">The ContentCollection id to fetch the respective MediaInformation instance</param>
-        /// <returns>ContentCollection instance for the associated id.It throws Exception for invalid Id.</returns>
-        public T Select<T>(int id) where T : ContentCollection
-        {
-            ContentCollection result = null;
-            IntPtr handle = IntPtr.Zero;
-
-            if (typeof(T) == typeof(PlayList))
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.Playlist.GetPlaylistFromDb(id, out handle), "Failed to get information");
-
-                if (handle != IntPtr.Zero)
-                {
-                    result = new PlayList(handle);
-                    return (T)result;
-                }
-            }
-            else if (typeof(T) == typeof(Album))
-            {
-                MediaContentValidator.ThrowIfError(
-                Interop.Group.MediaAlbumGetAlbumFromDb(id, out handle), "Failed to get information");
-
-                if (handle != IntPtr.Zero)
-                {
-                    result = new Album(handle);
-                    return (T)result;
-                }
-            }
-            else if (typeof(T) == typeof(Tag))
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.Tag.GetTagFromDb(id, out handle), "Failed to get information");
-
-                if (handle != IntPtr.Zero)
-                {
-                    result = new Tag(handle);
-                    return (T)result;
-                }
-            }
-
-            return null;
-        }
-
-        private static IEnumerable<MediaFolder> ForEachFolder(ContentFilter filter)
-        {
-            List<MediaFolder> result = new List<MediaFolder>();
-            Interop.Folder.MediaFolderCallback callback = (IntPtr handle, IntPtr data) =>
-            {
-                IntPtr newHandle = IntPtr.Zero;
-                MediaContentValidator.ThrowIfError(
-                    Interop.Folder.Clone(out newHandle, handle), "Failed to clone");
-
-                result.Add(new MediaFolder(newHandle));
-                return true;
-            };
-            IntPtr filterHandle = filter != null ? filter.Handle : IntPtr.Zero;
-            MediaContentValidator.ThrowIfError(
-                Interop.Folder.ForeachFolderFromDb(filterHandle, callback, IntPtr.Zero), "Failed to get information");
-
-            return result;
-        }
-
-        private static IEnumerable<Album> ForEachAlbum(ContentFilter filter)
-        {
-            List<Album> result = new List<Album>();
-            Interop.Group.MediaAlbumCallback callback = (IntPtr handle, IntPtr data) =>
-            {
-                IntPtr newHandle = IntPtr.Zero;
-                MediaContentValidator.ThrowIfError(
-                    Interop.Group.MediaAlbumClone(out newHandle, handle), "Failed to clone");
-
-                result.Add(new Album(newHandle));
-                return true;
-            };
-            IntPtr filterHandle = (filter != null) ? filter.Handle : IntPtr.Zero;
-            MediaContentValidator.ThrowIfError(
-                Interop.Group.MediaAlbumForeachAlbumFromDb(filterHandle, callback, IntPtr.Zero), "Failed to get information");
-
-            return result;
-        }
-
-        private static IEnumerable<Group> ForEachGroup(ContentFilter filter)
-        {
-            IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
-            MediaGroupType groupType;
-            if (filter == null)
-            {
-                groupType = MediaGroupType.DisplayName;
-            }
-            else
-            {
-                groupType = filter.GroupType;
-            }
-
-            List<Group> result = new List<Group>();
-            Interop.Group.MediaGroupCallback callback = (string groupName, IntPtr data) =>
-            {
-                result.Add(new Group(groupName, groupType));
-                return true;
-            };
-            MediaContentValidator.ThrowIfError(
-                Interop.Group.ForeachGroupFromDb(handle, groupType, callback, IntPtr.Zero), "Failed to get information");
-
-            return result;
-        }
-
-        private static IEnumerable<Storage> ForEachStorage(ContentFilter filter)
-        {
-            IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
-            List<Storage> result = new List<Storage>();
-            Interop.Storage.MediaStorageCallback callback = (IntPtr storageHandle, IntPtr data) =>
-            {
-                IntPtr newHandle = IntPtr.Zero;
-                MediaContentValidator.ThrowIfError(
-                    Interop.Storage.Clone(out newHandle, storageHandle), "Failed to clone");
-
-                result.Add(new Storage(newHandle));
-                return true;
-            };
-            MediaContentValidator.ThrowIfError(
-                Interop.Storage.ForeachStorageFromDb(handle, callback, IntPtr.Zero), "Failed to get information");
-
-            return result;
-        }
-
-        private static IEnumerable<Tag> ForEachTag(ContentFilter filter)
-        {
-            IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
-
-            List<Tag> result = new List<Tag>();
-            Interop.Tag.MediaTagCallback callback = (IntPtr tagHandle, IntPtr data) =>
-            {
-                IntPtr newHandle = IntPtr.Zero;
-                MediaContentValidator.ThrowIfError(
-                    Interop.Tag.Clone(out newHandle, tagHandle), "Failed to clone");
-
-                result.Add(new Tag(newHandle));
-                return true;
-            };
-            MediaContentValidator.ThrowIfError(
-                Interop.Tag.ForeachTagFromDb(handle, callback, IntPtr.Zero), "Failed to get information");
-
-            return result;
-        }
-
-        private static IEnumerable<PlayList> ForEachPlayList(ContentFilter filter)
-        {
-            IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
-
-            List<PlayList> result = new List<PlayList>();
-            Interop.Playlist.MediaPlaylistCallback callback = (IntPtr playListHandle, IntPtr data) =>
-            {
-                IntPtr newHandle = IntPtr.Zero;
-                MediaContentValidator.ThrowIfError(
-                    Interop.Playlist.Clone(out newHandle, playListHandle), "Failed to clone");
-
-                result.Add(new PlayList(newHandle));
-                return true;
-            };
-            MediaContentValidator.ThrowIfError(
-                Interop.Playlist.ForeachPlaylistFromDb(handle, callback, IntPtr.Zero), "Failed to get information");
-
-            return result;
-        }
-
-        /// <summary>
-        /// Returns the ContentCollections with optional filter from the media database.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <remarks>
-        /// This function gets all ContentCollections matching the given filter. If NULL is passed to the filter, no filtering is applied.
-        /// </remarks>
-        /// <param name="filter">Filter for content items</param>
-        /// <returns>
-        /// Task with the list of the ContentCollection
-        /// </returns>
-        public IEnumerable<T> SelectAll<T>(ContentFilter filter)
-        {
-            if (typeof(T) == typeof(MediaInformation))
-            {
-                IEnumerable<MediaInformation> mediaList = GetMediaInformations(filter);
-                return (IEnumerable<T>)mediaList;
-            }
-            else if (typeof(T) == typeof(Album))
-            {
-                IEnumerable<Album> collectionList = ForEachAlbum(filter);
-                return (IEnumerable<T>)collectionList;
-            }
-            else if (typeof(T) == typeof(MediaFolder))
-            {
-                IEnumerable<MediaFolder> collectionList = ForEachFolder(filter);
-                return (IEnumerable<T>)collectionList;
-            }
-            else if (typeof(T) == typeof(Group))
-            {
-                IEnumerable<Group> collectionList = ForEachGroup(filter);
-                return (IEnumerable<T>)collectionList;
-            }
-            else if (typeof(T) == typeof(Storage))
-            {
-                IEnumerable<Storage> collectionList = ForEachStorage(filter);
-                return (IEnumerable<T>)collectionList;
-            }
-            else if (typeof(T) == typeof(Tag))
-            {
-                IEnumerable<Tag> collectionList = ForEachTag(filter);
-                return (IEnumerable<T>)collectionList;
-            }
-            else if (typeof(T) == typeof(PlayList))
-            {
-                IEnumerable<PlayList> collectionList = ForEachPlayList(filter);
-                return (IEnumerable<T>)collectionList;
-            }
-
-            return null;
-        }
-
-        /// <summary>
-        /// Returns media from the media database.
-        /// This function gets all media meeting the given filter
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="filter">The media filter</param>
-        /// <returns>List of media</returns>
-        private IEnumerable<MediaInformation> GetMediaInformations(ContentFilter filter)
-        {
-            IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
-            List<MediaInformation> mediaInformationList = new List<MediaInformation>();
-            Interop.MediaInformation.MediaInformationCallback callback = (IntPtr mediaHandle, IntPtr userData) =>
-            {
-                Interop.MediaInformation.SafeMediaInformationHandle newHandle;
-                MediaContentValidator.ThrowIfError(
-                Interop.MediaInformation.Clone(out newHandle, mediaHandle), "Failed to clone");
-
-                MediaContentType type;
-                Interop.MediaInformation.GetMediaType(newHandle, out type);
-                if (type == MediaContentType.Image)
-                {
-                    Interop.ImageInformation.SafeImageInformationHandle imageInfo;
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.GetImage(mediaHandle, out imageInfo), "Failed to get image information");
-
-                    mediaInformationList.Add(new ImageInformation(imageInfo, newHandle));
-                }
-                else if ((type == MediaContentType.Music) || (type == MediaContentType.Sound))
-                {
-                    Interop.AudioInformation.SafeAudioInformationHandle audioInfo;
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.GetAudio(mediaHandle, out audioInfo), "Failed to get audio information");
-
-                    mediaInformationList.Add(new AudioInformation(audioInfo, newHandle));
-                }
-                else if (type == MediaContentType.Video)
-                {
-                    Interop.VideoInformation.SafeVideoInformationHandle videoInfo;
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.GetVideo(mediaHandle, out videoInfo), "Failed to get video information");
-
-                    mediaInformationList.Add(new VideoInformation(videoInfo, newHandle));
-                }
-                else if (type == MediaContentType.Others)
-                {
-                    mediaInformationList.Add(new MediaInformation(newHandle));
-                }
-
-                return true;
-            };
-            MediaContentValidator.ThrowIfError(
-                Interop.MediaInformation.GetAllMedia(handle, callback, IntPtr.Zero), "Failed to get media information");
-
-            return mediaInformationList;
-        }
-
-        /// <summary>
-        /// Deletes a MediaInformation from the media database.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="mediaInfo">The MediaInformation to be deleted</param>
-        public void Delete(MediaInformation mediaInfo)
-        {
-            MediaContentValidator.ThrowIfError(
-                Interop.MediaInformation.Delete(mediaInfo.MediaId), "Failed to remove information");
-        }
-
-
-        /// <summary>
-        /// Deletes a content collection from the media database.
-        /// Applicable for Tag and PlayList only.
-        /// For other types ArgumentException is thrown.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="contentcollection">The ContentCollection instance to be deleted</param>
-        public void Delete(ContentCollection contentcollection)
-        {
-            Type type = contentcollection.GetType();
-
-            if (type == typeof(Tag))
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.Tag.DeleteFromDb(((Tag)contentcollection).Id), "Failed to remove information");
-            }
-            else if (type == typeof(PlayList))
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.Playlist.DeleteFromDb(((PlayList)contentcollection).Id), "Failed to remove information");
-            }
-            else
-            {
-                throw new ArgumentException("The type of content collection is wrong");
-            }
-        }
-
-        internal void Delete(MediaBookmark bookmark)
-        {
-            MediaContentValidator.ThrowIfError(
-                Interop.MediaBookmark.DeleteFromDb(bookmark.Id), "Failed to remove information");
-        }
-
-        internal void Delete(MediaFace face)
-        {
-            MediaContentValidator.ThrowIfError(
-                Interop.Face.DeleteFromDb(face.Id), "Failed to remove face information");
-        }
-
-        /// <summary>
-        /// Updates a content collection in the media database
-        /// Applicable for Tag, PlayList and MediagFolder types only.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="contentCollection">The content collection to be updated</param>
-        public void Update(ContentCollection contentCollection)
-        {
-            Type type = contentCollection.GetType();
-            if (type == typeof(Tag))
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.Tag.UpdateToDb(((Tag)contentCollection).Handle), "Failed to update DB");
-            }
-            else if (type == typeof(PlayList))
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.Playlist.UpdateToDb(((PlayList)contentCollection).Handle), "Failed to update DB");
-            }
-            else if (type == typeof(MediaFolder))
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.Folder.UpdateToDb(((MediaFolder)contentCollection).Handle), "Failed to update DB");
-            }
-            else
-            {
-                throw new ArgumentException("The type of content collection is wrong");
-            }
-        }
-
-        /// <summary>
-        /// Updates a media information instance in the media database
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="mediaInfo">The MediaInformation object to be updated</param>
-        public void Update(MediaInformation mediaInfo)
-        {
-            Type type = mediaInfo.GetType();
-            if (type == typeof(ImageInformation))
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.ImageInformation.UpdateToDB(((ImageInformation)mediaInfo).ImageHandle), "Failed to update DB");
-
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.UpdateToDB(mediaInfo.MediaHandle), "Failed to update DB");
-            }
-            else if (type == typeof(AudioInformation))
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.AudioInformation.UpdateToDB(((AudioInformation)mediaInfo).AudioHandle), "Failed to update DB");
-
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.UpdateToDB(mediaInfo.MediaHandle), "Failed to update DB");
-            }
-            else if (type == typeof(VideoInformation))
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.VideoInformation.UpdateToDB(((VideoInformation)mediaInfo).VideoHandle), "Failed to update DB");
-
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.UpdateToDB(mediaInfo.MediaHandle), "Failed to update DB");
-            }
-            else if (type == typeof(MediaInformation))
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.UpdateToDB(mediaInfo.MediaHandle), "Failed to update DB");
-            }
-            else
-            {
-                throw new ArgumentException("Invalid information type");
-            }
-        }
-
-        internal void Update(MediaFace face)
-        {
-            MediaContentValidator.ThrowIfError(Interop.Face.UpdateToDb(face.Handle), "Failed to update DB");
-        }
-
-        /// <summary>
-        /// Inserts a content collection to the media database.
-        /// Applicable for Tag and PlayList types only.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="contentCollection">The content collection to be inserted</param>
-        public void Insert(ContentCollection contentCollection)
-        {
-            Type type = contentCollection.GetType();
-            IntPtr handle = IntPtr.Zero;
-            if (type == typeof(Tag))
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.Tag.InsertToDb(((Tag)contentCollection).Name, out handle), "Failed to insert collection");
-                ((Tag)contentCollection).Handle = handle;
-            }
-            else if (type == typeof(PlayList))
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.Playlist.InsertToDb(((PlayList)contentCollection).Name, out handle), "Failed to insert collection");
-                ((PlayList)contentCollection).Handle = handle;
-            }
-            else
-            {
-                throw new ArgumentException("collection type is wrong");
-            }
-        }
-
-        internal void Insert(string mediaId, uint offset, string thumbnailPath)
-        {
-            MediaContentValidator.ThrowIfError(
-                Interop.MediaBookmark.InsertToDb(mediaId, offset, thumbnailPath), "Failed to insert information");
-        }
-
-        internal void Insert(MediaFace face)
-        {
-            MediaContentValidator.ThrowIfError(
-                Interop.Face.InsertToDb(((MediaFace)face).Handle), "Failed to insert information");
-        }
-    }
-}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentEventArgs.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentEventArgs.cs
deleted file mode 100755 (executable)
index 283fc87..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
-* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
-*
-* Licensed under the Apache License, Version 2.0 (the License);
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an AS IS BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-
-
-using System;
-
-namespace Tizen.Content.MediaContent
-{
-    /// <summary>
-    /// Event arguments passed when content is updated in the media database
-    /// </summary>
-    public class ContentUpdatedEventArgs : EventArgs
-    {
-        internal ContentUpdatedEventArgs(MediaContentError error, int pid, MediaContentUpdateItemType updateItem,
-            MediaContentDBUpdateType updateType, MediaContentType mediaType, string uuid, string filePath, string mimeType)
-        {
-            Error = error;
-            Pid = pid;
-            UpdateItem = updateItem;
-            UpdateType = updateType;
-            MediaType = mediaType;
-            Uuid = uuid;
-            FilePath = filePath;
-            MimeType = mimeType;
-        }
-        /// <summary>
-        /// The error code
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public MediaContentError Error
-        {
-            get;
-            internal set;
-        }
-
-        /// <summary>
-        /// The PID which publishes notification
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public int Pid
-        {
-            get; set;
-        }
-
-        /// <summary>
-        /// The update item of notification
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public MediaContentUpdateItemType UpdateItem
-        {
-            get; set;
-        }
-
-        /// <summary>
-        /// The update type of notification
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public MediaContentDBUpdateType UpdateType
-        {
-            get; set;
-        }
-
-        /// <summary>
-        /// The type of the media content
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public MediaContentType MediaType
-        {
-            get; set;
-        }
-
-        /// <summary>
-        /// The UUID of media or directory, which is updated
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string Uuid
-        {
-            get; set;
-        }
-
-        /// <summary>
-        /// The path of the media or directory
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string FilePath
-        {
-            get; set;
-        }
-
-        /// <summary>
-        /// The mime type of the media info
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string MimeType
-        {
-            get; set;
-        }
-    }
-}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentFilter.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentFilter.cs
deleted file mode 100755 (executable)
index 97d4998..0000000
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
-* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
-*
-* Licensed under the Apache License, Version 2.0 (the License);
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an AS IS BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-
-using System;
-using System.Runtime.InteropServices;
-
-namespace Tizen.Content.MediaContent
-{
-    /// <summary>
-    /// The Content Filter API provides functions to manage media filters.
-    /// </summary>
-    /// <remarks>
-    /// A Content filter is required for filtering information associated with Media Folder, Tag, Audio, MediaBookmark and Media Information on basis of details like offset, count, order and condition for searching.
-    /// It provide functionality to set properties associated with a given content filter.
-    /// Setting content filter properties helps to limit the number of filtered items as following:
-    /// <list>
-    /// <item><description>
-    /// Offset - Used to set starting position of the filter's search
-    /// </description></item>
-    /// <item><description>
-    /// Count - Used to set number of items to be searched from offset
-    /// </description></item>
-    /// <item><description>
-    /// Condition - Used to set keyword which user want to search
-    /// </description></item>
-    /// <item><description>
-    /// Order - Used to set type of media to be ordered by the filter
-    /// </description></item>
-    /// </list>
-    /// Searchable expression can use one of the following forms:
-    /// <list>
-    /// <item><description>
-    /// column = value
-    /// </description></item>
-    /// <item><description>
-    /// column > value
-    /// </description></item>
-    /// <item><description>
-    /// column >= value
-    /// </description></item>
-    /// <item><description>
-    /// column < value
-    /// </description></item>
-    /// <item><description>
-    /// column <= value
-    /// </description></item>
-    /// <item><description>
-    /// value = column
-    /// </description></item>
-    /// <item><description>
-    /// value >= column
-    /// </description></item>
-    /// <item><description>
-    /// value < column
-    /// </description></item>
-    /// <item><description>
-    /// value <= column
-    /// </description></item>
-    /// <item><description>
-    /// column IN (value)
-    /// </description></item>
-    /// <item><description>
-    /// column IN(value-list)
-    /// </description></item>
-    /// <item><description>
-    /// column NOT IN(value)
-    /// </description></item>
-    /// <item><description>
-    /// column NOT IN(value-list)
-    /// </description></item>
-    /// <item><description>
-    /// column LIKE value
-    /// </description></item>
-    /// <item><description>
-    /// expression1 AND expression2 OR expression3
-    /// </description></item>
-    /// </list>
-    /// Note that if you want to set qoutation(" ' " or " " ") as value of LIKE operator, you should use two times.(" '' " or " "" ") \n And the optional ESCAPE clause is supported. Both percent symbol("%") and underscore symbol("_") are used in the LIKE pattern.
-    /// If these characters are used as value of LIKE operation, then the expression following the ESCAPE caluse of sqlite.
-    /// </remarks>
-    public class ContentFilter : IDisposable
-    {
-        private IntPtr _filterHandle = IntPtr.Zero;
-        private bool _disposedValue = false;
-        private ContentCollation _conditionCollate = ContentCollation.Default;
-        private ContentCollation _orderCollate = ContentCollation.Default;
-        private ContentOrder _orderType = ContentOrder.Asc;
-        private string _orderKeyword = null;
-        private string _conditionMsg = null;
-
-        internal IntPtr Handle
-        {
-            get
-            {
-                if (_filterHandle == IntPtr.Zero)
-                {
-                    throw new ObjectDisposedException(nameof(ContentFilter));
-                }
-
-                return _filterHandle;
-            }
-        }
-        /// <summary>
-        /// The start position of the given filter Starting from zero.
-        /// Please note that count value has to be set properly for correct result.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public int Offset
-        {
-            get
-            {
-                int offset;
-                int count;
-                MediaContentValidator.ThrowIfError(
-                    Interop.Filter.GetOffset(Handle, out offset, out count), "Failed to get offset");
-
-                return offset;
-            }
-
-            set
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.Filter.SetOffset(Handle, value, this.Count), "Failed to set offset");
-            }
-        }
-
-        public ContentFilter()
-        {
-            MediaContentValidator.ThrowIfError(
-                Interop.Filter.Create(out _filterHandle), "Failed to Create Filter handle.");
-        }
-
-        /// <summary>
-        /// The number of items to be searched with respect to the offset
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public int Count
-        {
-            get
-            {
-                int offset;
-                int count;
-                MediaContentValidator.ThrowIfError(
-                    Interop.Filter.GetOffset(Handle, out offset, out count), "Failed to get count");
-
-                return count;
-            }
-
-            set
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.Filter.SetOffset(Handle, this.Offset, value), "Failed to set count");
-            }
-        }
-
-        /// <summary>
-        /// Gets the media filter content order and order keyword.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public ContentOrder Order
-        {
-            get
-            {
-                return _orderType;
-            }
-
-            set
-            {
-                if (_orderKeyword != null)
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.Filter.SetOrder(Handle, value, _orderKeyword, _orderCollate), "Failed to set order");
-                }
-
-                _orderType = value;
-            }
-        }
-
-        /// <summary>
-        /// The search order keyword
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string OrderKey
-        {
-            get
-            {
-                ContentOrder order;
-                IntPtr val = IntPtr.Zero;
-                ContentCollation type;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.Filter.GetOrder(Handle, out order, out val, out type), "Failed to GetOrder for OrderKey");
-
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-
-            set
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.Filter.SetOrder(Handle, _orderType, value, _orderCollate), "Failed to set OrderKey");
-
-                _orderKeyword = value;
-            }
-        }
-
-        /// <summary>
-        /// The collate type for comparing two strings
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public ContentCollation OrderCollationType
-        {
-            get
-            {
-                return _orderCollate;
-            }
-
-            set
-            {
-                if (_orderKeyword != null)
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.Filter.SetOrder(Handle, _orderType, _orderKeyword, value), "Failed to set collation");
-                }
-
-                _orderCollate = value;
-            }
-        }
-
-        /// <summary>
-        /// Gets/Sets the condition for the given filter.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string Condition
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                ContentCollation type;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.Filter.GetCondition(Handle, out val, out type), "Failed to get condition");
-
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-
-            set
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.Filter.SetCondition(Handle, value, _conditionCollate), "Failed to set condition");
-
-                _conditionMsg = value;
-            }
-        }
-
-        /// <summary>
-        /// The collate type for comparing two strings
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public ContentCollation ConditionCollationType
-        {
-            get
-            {
-                return _conditionCollate;
-            }
-
-            set
-            {
-                if (_conditionMsg != null)
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.Filter.SetCondition(Handle, _conditionMsg, value), "Failed to set collation");
-                }
-
-                _conditionCollate = value;
-            }
-        }
-
-        /// <summary>
-        /// Sets the storage id for the given filter.
-        /// You can use this property when you want to search items only in the specific storage
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string StorageId
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.Filter.GetStorage(Handle, out val), "Failed to get condition");
-
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-
-            set
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.Filter.SetStorage(Handle, value), "Failed to set condition");
-            }
-        }
-
-        /// <summary>
-        /// The type of the media group
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public MediaGroupType GroupType { get; set; }
-
-        /// <summary>
-        /// Dispose API for closing the internal resources.
-        /// This function can be used to stop all effects started by Vibrate().
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public void Dispose()
-        {
-            Dispose(true);
-            GC.SuppressFinalize(this);
-        }
-
-        protected virtual void Dispose(bool disposing)
-        {
-            if (!_disposedValue)
-            {
-                if (_filterHandle != IntPtr.Zero)
-                {
-                    Interop.Filter.Destroy(_filterHandle);
-                    _filterHandle = IntPtr.Zero;
-                }
-
-                _disposedValue = true;
-            }
-        }
-    }
-}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentManager.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentManager.cs
deleted file mode 100755 (executable)
index 6044b87..0000000
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
-* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
-*
-* Licensed under the Apache License, Version 2.0 (the License);
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an AS IS BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-
-
-using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-using System.Threading;
-
-/// <summary>
-/// The Media Content API provides functions, enumerations used in the entire Content Service.
-/// </summary>
-/// <remarks>
-/// The Media Content API provides functions and enumerations used in the entire Content Service.
-/// The information about media items i.e.image, audio and video, are managed in the content database
-/// and operations that involve database requires an active connection with the media content service.
-/// During media scanning, Media Service extract media information automatically. media information
-/// include basic file info like path, size, modified time etc and some metadata like ID3tag, EXIF,
-/// thumbnail, etc. (thumbnail extracted only in Internal and SD card storage.
-/// Media content services do not manage hidden files.
-/// The API provides functions for connecting (media_content_connect()) and disconnecting(media_content_disconnect())
-/// from the media content service.
-/// </remarks>
-
-
-namespace Tizen.Content.MediaContent
-{
-    /// <summary>
-    /// ContentManager class is the interface class for accessing the ContentCollection and MediaInformation.
-    /// This class allows usre to create/update db operations for media content.
-    /// </summary>
-    public static class ContentManager
-    {
-        private static readonly ContentDatabase s_contentDB = new ContentDatabase();
-
-        /// <summary>
-        /// Database instance to do all the Database oprtions for media content management.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public static ContentDatabase Database
-        {
-            get
-            {
-                return s_contentDB;
-            }
-        }
-
-        /// <summary>
-        /// Requests to scan a media file.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="filePath">File path of the media to be scanned</param>
-        /// <returns>A reference to the MediaInformation object scanned</returns>
-        /// <remarks>
-        /// This function requests to scan a media file to the media server. If media file is not registered to DB yet,
-        /// that media file information will be added to the media DB. If it is already registered to the DB,
-        /// then this tries to refresh information. If requested file does not exist on file system,
-        /// information of the media file will be removed from the media DB.
-        /// </remarks>
-        public static void Scan(string filePath)
-        {
-            MediaContentValidator.ThrowIfError(Interop.Content.ScanFile(filePath), "Failed scan");
-        }
-
-        /// <summary>
-        /// Inserts a media to the media database
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="filePath">File path of the media to be inserted</param>
-        /// <returns>the MediaInformation instance about added media path</returns>
-        public static MediaInformation AddMediaInformation(string filePath)
-        {
-            Interop.MediaInformation.SafeMediaInformationHandle mediaInformationHandle;
-            MediaContentValidator.ThrowIfError(
-                Interop.MediaInformation.Insert(filePath, out mediaInformationHandle), "Failed to Insert MediaInformation to DB");
-
-            MediaContentType type;
-            MediaInformation res;
-            Interop.MediaInformation.GetMediaType(mediaInformationHandle, out type);
-            if (type == MediaContentType.Image)
-            {
-                Interop.ImageInformation.SafeImageInformationHandle imageInfo;
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.GetImage(mediaInformationHandle.DangerousGetHandle(), out imageInfo), "Failed to get image information");
-
-                res = new ImageInformation(imageInfo, mediaInformationHandle);
-            }
-            else if ((type == MediaContentType.Music) || (type == MediaContentType.Sound))
-            {
-                Interop.AudioInformation.SafeAudioInformationHandle audioInfo;
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.GetAudio(mediaInformationHandle.DangerousGetHandle(), out audioInfo), "Failed to get audio information");
-
-                res = new AudioInformation(audioInfo, mediaInformationHandle);
-            }
-            else if (type == MediaContentType.Video)
-            {
-                Interop.VideoInformation.SafeVideoInformationHandle videoInfo;
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.GetVideo(mediaInformationHandle.DangerousGetHandle(), out videoInfo), "Failed to get video information");
-
-                res = new VideoInformation(videoInfo, mediaInformationHandle);
-            }
-            else
-            {
-                res = new MediaInformation(mediaInformationHandle);
-            }
-
-            return res;
-        }
-
-        /// <summary>
-        /// Requests to scan a media folder, asynchronously.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="folderPath">The folder path</param>
-        /// <param name="recursive">Indicate sif the folder is to recursively scanned. Default value: true</param>
-        /// <remarks>
-        /// This function requests to scan a media folder to the media server with given completed callback function.
-        /// The sub folders are also scanned,if there are sub folders in that folder.
-        /// If any folder must not be scanned, a blank file ".scan_ignore" has to be created in that folder.
-        /// </remarks>
-        /// <returns>Task with scanning result</returns>
-        public static Task<MediaContentError> ScanFolderAsync(string folderPath, bool recursive = true)
-        {
-            var task = new TaskCompletionSource<MediaContentError>();
-
-            Interop.Content.MediaScanCompletedCallback scanCompleted = (MediaContentError scanResult, IntPtr data) =>
-            {
-                MediaContentValidator.ThrowIfError(scanResult, "Failed to scan");
-                task.SetResult(scanResult);
-            };
-
-            MediaContentValidator.ThrowIfError(
-                Interop.Content.ScanFolder(folderPath, recursive, scanCompleted, IntPtr.Zero), "Failed to scan");
-
-            return task.Task;
-        }
-
-        internal static Interop.Content.MediaScanCompletedCallback scanCompletedWithToken = null;
-        internal static Object l = new Object();
-        /// <summary>
-        /// Requests to scan a media folder, asynchronously.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="folderPath">The folder path</param>
-        /// <param name="cancellationToken">Cancellation token required to cancel the current scan</param>
-        /// <param name="recursive">Indicate sif the folder is to recursively scanned. Default value: true</param>
-        /// <remarks>
-        /// This function requests to scan a media folder to the media server with given completed callback function.
-        /// The sub folders are also scanned,if there are sub folders in that folder.
-        /// If any folder must not be scanned, a blank file ".scan_ignore" has to be created in that folder.
-        /// </remarks>
-        /// <returns>Task with scanning result</returns>
-        public static Task ScanFolderAsync(string folderPath, CancellationToken cancellationToken, bool recursive = true)
-        {
-            var task = new TaskCompletionSource<int>();
-            bool taskCompleted = false;
-
-            cancellationToken.Register(() =>
-            {
-                lock (l)
-                {
-                    if (!taskCompleted)
-                    {
-                        taskCompleted = true;
-                        MediaContentValidator.ThrowIfError(
-                            Interop.Content.CancelScanFolder(folderPath), "Failed CancelScanFolder");
-
-                        task.SetCanceled();
-                    }
-                }
-            });
-            scanCompletedWithToken = (MediaContentError scanResult, IntPtr data) =>
-            {
-                lock (l)
-                {
-                    if (!taskCompleted)
-                    {
-                        taskCompleted = true;
-                        MediaContentValidator.ThrowIfError(scanResult, "Failed scan");
-                        task.SetResult((int)scanResult);
-                    }
-                }
-            };
-
-            MediaContentValidator.ThrowIfError(
-                Interop.Content.ScanFolder(folderPath, recursive, scanCompletedWithToken, IntPtr.Zero), "Failed to scan");
-
-            return task.Task;
-
-        }
-
-        /// <summary>
-        /// Inserts media files into the media database, asynchronously.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="filePaths">The path array to the media files</param>
-        /// <returns>
-        /// Task with the result of batch insertion
-        /// </returns>
-        public static Task AddMediaInformationBatchAsync(IEnumerable<string> filePaths)
-        {
-            var task = new TaskCompletionSource<int>();
-            string[] paths = ((List<string>)filePaths).ToArray();
-            Interop.MediaInformation.MediaInsertCompletedCallback callback = (MediaContentError error, IntPtr userData) =>
-            {
-                MediaContentValidator.ThrowIfError(error, "Failed to batch insert");
-                task.SetResult((int)error);
-            };
-            MediaContentValidator.ThrowIfError(
-                Interop.MediaInformation.BatchInsert(paths, paths.Length, callback, IntPtr.Zero), "Failed to add batch media");
-
-            return task.Task;
-        }
-
-        /// <summary>
-        /// Inserts the burst shot images into the media database, asynchronously.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="filePaths">The path array to the burst shot images</param>
-        /// <returns>
-        /// Task with the result of the burstshot insertion
-        /// </returns>
-        public static Task AddBurstShotImagesAsync(IEnumerable<string> filePaths)
-        {
-            var task = new TaskCompletionSource<int>();
-            string[] paths = ((List<string>)filePaths).ToArray();
-            Interop.MediaInformation.MediaInsertBurstShotCompletedCallback callback = (MediaContentError error, IntPtr userData) =>
-            {
-                MediaContentValidator.ThrowIfError(error, "Failed to add burstshot");
-                task.SetResult((int)error);
-            };
-            MediaContentValidator.ThrowIfError(
-                Interop.MediaInformation.BurstShotInsert(paths, paths.Length, callback, IntPtr.Zero), "Failed to add burst shots to db");
-
-            return task.Task;
-        }
-
-        /// <summary>
-        /// Deletes media files from the media database. The media files for deletion can be specified as a condition in a filter.
-        /// This function deletes the media items from the content storage.Normally, deleting media files in the database are done automatically by the media server,
-        /// without calling this function.This function is only called when the media server is busy and user needs to get quick result of deleting.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="filter">The content filter to which media will be matched</param>
-        public static void RemoveMediaInformationBatch(ContentFilter filter)
-        {
-            IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
-            MediaContentValidator.ThrowIfError(
-                Interop.MediaInformation.BatchDelete(handle), "Failed to remove items");
-        }
-    }
-}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Enums.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Enums.cs
new file mode 100644 (file)
index 0000000..525fddc
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Content.MediaContent
+{
+    /// <summary>
+    /// Specifies how the strings are compared.
+    /// </summary>
+    internal enum Collation
+    {
+        /// <summary>
+        /// Default collation, binary.
+        /// </summary>
+        Default,
+        /// <summary>
+        /// Case-insensitive.
+        /// </summary>
+        NoCase,
+        /// <summary>
+        /// Trailing space characters are ignored.
+        /// </summary>
+        Rtrim,
+        /// <summary>
+        /// Localized, NoCase also applied.
+        /// </summary>
+        Localized
+    }
+
+    /// <summary>
+    /// Specifies storage types.
+    /// </summary>
+    public enum StorageType
+    {
+        /// <summary>
+        /// The device's internal storage.
+        /// </summary>
+        Internal = 0,
+
+        /// <summary>
+        /// The device's external storage like sd card.
+        /// </summary>
+        External = 1,
+
+        /// <summary>
+        /// The external usb storage.
+        /// </summary>
+        ExternalUsb = 2
+    }
+
+    /// <summary>
+    /// Specifies database operation types.
+    /// </summary>
+    public enum OperationType
+    {
+        /// <summary>
+        /// Insert operation.
+        /// </summary>
+        Insert,
+
+        /// <summary>
+        /// Delete operation.
+        /// </summary>
+        Delete,
+
+        /// <summary>
+        /// Update operation.
+        /// </summary>
+        Update
+    }
+
+    internal enum ItemType
+    {
+        File,
+        Directory
+    }
+
+    /// <summary>
+    /// Specifies types of <see cref="MediaInfo"/>.
+    /// </summary>
+    public enum MediaType
+    {
+        /// <summary>
+        /// The type of an image.
+        /// </summary>
+        /// <seealso cref="ImageInfo"/>
+        Image = 0,
+
+        /// <summary>
+        /// The type of a video.
+        /// </summary>
+        /// <seealso cref="VideoInfo"/>
+        Video = 1,
+
+        /// <summary>
+        /// The type of sound.
+        /// </summary>
+        /// <seealso cref="AudioInfo"/>
+        Sound = 2,
+
+        /// <summary>
+        /// The type of music.
+        /// </summary>
+        /// <seealso cref="AudioInfo"/>
+        Music = 3,
+
+        /// <summary>
+        /// The type of other.
+        /// </summary>
+        Other = 4
+    }
+
+    /// <summary>
+    /// Specifies orientation types of media.
+    /// </summary>
+    public enum Orientation
+    {
+        /// <summary>
+        /// None.
+        /// </summary>
+        Rotate0 = 0,
+        /// <summary>
+        /// Normal.
+        /// </summary>
+        Normal = 1,
+        /// <summary>
+        /// Rotate 90 degrees.
+        /// </summary>
+        Rotate90 = 6,
+        /// <summary>
+        /// Rotate 180 degrees.
+        /// </summary>
+        Rotate180 = 3,
+        /// <summary>
+        /// Rotate 270 degrees.
+        /// </summary>
+        Rotate270 = 8,
+        /// <summary>
+        /// Flip horizontal.
+        /// </summary>
+        FlipHorizontal = 2,
+        /// <summary>
+        /// Flip vertical.
+        /// </summary>
+        FlipVertical = 4,
+        /// <summary>
+        /// Transpose.
+        /// </summary>
+        Transpose = 5,
+        /// <summary>
+        /// Transverse.
+        /// </summary>
+        Transverse = 7,
+    }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/EventArgs.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/EventArgs.cs
new file mode 100644 (file)
index 0000000..b8f49fd
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Content.MediaContent
+{
+
+    /// <summary>
+    /// Provides data for the <see cref="MediaDatabase.MediaInfoUpdated"/> event.
+    /// </summary>
+    public class MediaInfoUpdatedEventArgs : EventArgs
+    {
+        internal MediaInfoUpdatedEventArgs(int pid,
+            OperationType operationType, MediaType mediaType, string id, string path, string mimeType)
+        {
+            ProcessId = pid;
+            OperationType = operationType;
+            Id = id;
+            Path = path;
+
+            MediaType = mediaType;
+            MimeType = mimeType;
+        }
+
+        /// <summary>
+        /// Gets the process id which triggers the event.
+        /// </summary>
+        /// <value>The process id which triggers the event.</value>
+        public int ProcessId
+        {
+            get;
+        }
+
+        /// <summary>
+        /// Gets the operation type.
+        /// </summary>
+        /// <value>The operation type which triggers the event.</value>
+        public OperationType OperationType
+        {
+            get;
+        }
+
+        /// <summary>
+        /// Gets the id of the media updated.
+        /// </summary>
+        /// <value>The id of the media updated.</value>
+        public string Id
+        {
+            get;
+        }
+
+        /// <summary>
+        /// Gets the path of the media updated.
+        /// </summary>
+        /// <value>The path of the media updated.</value>
+        public string Path
+        {
+            get;
+        }
+
+        /// <summary>
+        /// Gets the type of the media updated.
+        /// </summary>
+        /// <value>The <see cref="MediaType"/> of the media updated.</value>
+        public MediaType MediaType
+        {
+            get;
+        }
+
+        /// <summary>
+        /// The mime type of the media updated.
+        /// </summary>
+        /// <value>The mime type of the media updated.</value>
+        public string MimeType
+        {
+            get;
+        }
+    }
+
+
+    /// <summary>
+    /// Provides data for the <see cref="MediaDatabase.FolderUpdated"/> event.
+    /// </summary>
+    public class FolderUpdatedEventArgs : EventArgs
+    {
+        internal FolderUpdatedEventArgs(OperationType operationType, string id, string path)
+        {
+            OperationType = operationType;
+            Id = id;
+            Path = path;
+        }
+
+        /// <summary>
+        /// Gets the operation type.
+        /// </summary>
+        /// <value>The operation type which triggers the event.</value>
+        public OperationType OperationType
+        {
+            get;
+        }
+
+        /// <summary>
+        /// Gets the id of the folder updated.
+        /// </summary>
+        /// <value>The id of the folder updated.</value>
+        public string Id
+        {
+            get;
+        }
+
+        /// <summary>
+        /// Gets the path of the folder updated.
+        /// </summary>
+        /// <value>The path of the folder updated.</value>
+        public string Path
+        {
+            get;
+        }
+    }
+
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/FaceInfo.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/FaceInfo.cs
new file mode 100644 (file)
index 0000000..bdbf132
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Content.MediaContent
+{
+    /// <summary>
+    /// Represents the face information for media.
+    /// </summary>
+    public class FaceInfo
+    {
+        internal FaceInfo(IntPtr handle)
+        {
+            Id = InteropHelper.GetString(handle, Interop.Face.GetId);
+            MediaInfoId = InteropHelper.GetString(handle, Interop.Face.GetMediaId);
+
+            Tag = InteropHelper.GetString(handle, Interop.Face.GetTag);
+            Orientation = InteropHelper.GetValue<IntPtr, Orientation>(handle, Interop.Face.GetOrientation);
+
+            Rect = GetRect(handle);
+        }
+
+        private static Rectangle GetRect(IntPtr faceHandle)
+        {
+            Interop.Face.GetFaceRect(faceHandle, out var x, out var y, out var width, out var height).
+                ThrowIfError("Failed to get rect for the face info");
+
+            return new Rectangle(x, y, width, height);
+        }
+
+        /// <summary>
+        /// Gets the region.
+        /// </summary>
+        /// <value>The region of face in the media.</value>
+        /// <remarks>
+        /// The coordinates of the rectangle are orientation-applied values.
+        /// </remarks>
+        public Rectangle Rect { get; }
+
+        /// <summary>
+        /// Gets the id of face info.
+        /// </summary>
+        public string Id { get; }
+
+        /// <summary>
+        /// Gets the media id that the face info is added.
+        /// </summary>
+        /// <value>The media id that the face info is added.</value>
+        public string MediaInfoId { get; }
+
+        /// <summary>
+        /// Gets the tag name.
+        /// </summary>
+        /// <value>The tag name of face info.</value>
+        public string Tag { get; }
+
+        /// <summary>
+        /// Gets the orientation of face info.
+        /// </summary>
+        /// <value>The orientation of face info.</value>
+        public Orientation Orientation { get; }
+
+        internal static FaceInfo FromHandle(IntPtr handle)
+        {
+            return new FaceInfo(handle);
+        }
+
+        /// <summary>
+        /// Returns a string representation of the face info.
+        /// </summary>
+        /// <returns>A string representation of the current face info.</returns>
+        public override string ToString() =>
+            $"Id={Id}, MediaInfoId={MediaInfoId}, Rect=({Rect}), Tag={Tag}";
+    }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/FaceInfoCommand.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/FaceInfoCommand.cs
new file mode 100644 (file)
index 0000000..45b4ae2
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Content.MediaContent
+{
+    /// <summary>
+    /// Provides commands to manage face infos in the database.
+    /// </summary>
+    /// <seealso cref="Album"/>
+    public class FaceInfoCommand : MediaCommand
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="FaceInfoCommand"/> class with the specified <see cref="MediaDatabase"/>.
+        /// </summary>
+        /// <param name="database">A <see cref="MediaDatabase"/> that the commands run on.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="database"/> is null.</exception>
+        /// <exception cref="ObjectDisposedException"><paramref name="database"/> has already been disposed of.</exception>
+        public FaceInfoCommand(MediaDatabase database) : base(database)
+        {
+        }
+
+        /// <summary>
+        /// Deletes a face info from the database.
+        /// </summary>
+        /// <privilege>http://tizen.org/privilege/content.write</privilege>
+        /// <param name="faceInfoId">The face info id to delete.</param>
+        /// <returns>true if the matched record was found and deleted, otherwise false.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="faceInfoId"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="faceInfoId"/> is a zero-length string, contains only white space.</exception>
+        /// <exception cref="UnauthorizedAccessException">The caller has no required privilege.</exception>
+        public bool Delete(string faceInfoId)
+        {
+            ValidateDatabase();
+
+            ValidationUtil.ValidateNotNullOrEmpty(faceInfoId, nameof(faceInfoId));
+
+            var reader = Select(new SelectArguments { FilterExpression = $"{FaceInfoColumns.Id}='{faceInfoId}'" });
+
+            if (reader.Read() == false)
+            {
+                return false;
+            }
+
+            CommandHelper.Delete(Interop.Face.DeleteFromDb, faceInfoId);
+            return true;
+        }
+
+        /// <summary>
+        /// Retrieves the face info.
+        /// </summary>
+        /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        public MediaDataReader<FaceInfo> Select()
+        {
+            return Select(null);
+        }
+
+        /// <summary>
+        /// Retrieves the face info with <see cref="SelectArguments"/>.
+        /// </summary>
+        /// <param name="filter">The criteria to use to filter. This value can be null.</param>
+        /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        public MediaDataReader<FaceInfo> Select(SelectArguments filter)
+        {
+            ValidateDatabase();
+
+            return CommandHelper.Select(filter, Interop.Face.ForeachFromDb, FaceInfo.FromHandle);
+        }
+
+        /// <summary>
+        /// Updates a tag with the specified tag.
+        /// </summary>
+        /// <privilege>http://tizen.org/privilege/content.write</privilege>
+        /// <param name="faceInfoId">The face info id to update.</param>
+        /// <param name="tag">The tag value for update.</param>
+        /// <returns>true if the matched record was found and updated, otherwise false.</returns>
+        /// <remarks>Only values set in <see cref="PlaylistUpdateValues"/> are updated.</remarks>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="faceInfoId"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="faceInfoId"/> is a zero-length string, contains only white space.</exception>
+        /// <exception cref="UnauthorizedAccessException">The caller has no required privilege.</exception>
+        public bool UpdateTag(string faceInfoId, string tag)
+        {
+            ValidateDatabase();
+
+            ValidationUtil.ValidateNotNullOrEmpty(faceInfoId, nameof(faceInfoId));
+
+            if (tag == null)
+            {
+                throw new ArgumentNullException(nameof(tag));
+            }
+
+            var handle = CommandHelper.SelectScalar(Interop.Face.ForeachFromDb, $"{FaceInfoColumns.Id}='{faceInfoId}'",
+                Interop.Face.Clone);
+
+            if (handle == IntPtr.Zero)
+            {
+                return false;
+            }
+
+            try
+            {
+                Interop.Face.SetTag(handle, tag).ThrowIfError("Failed to update(setting tag)");
+
+                Interop.Face.Update(handle).ThrowIfError("Failed to update(executing query)");
+                return true;
+            }
+            finally
+            {
+                Interop.Face.Destroy(handle);
+            }
+        }
+    }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/FaceRect.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/FaceRect.cs
deleted file mode 100755 (executable)
index 93298a9..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
-* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
-*
-* Licensed under the Apache License, Version 2.0 (the License);
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an AS IS BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-
-
-namespace Tizen.Content.MediaContent
-{
-    /// <summary>
-    /// FaceRect represents a rectangle dimension to create a Face in an image.
-    /// It is used to create or tag a MediaFace in an image file.
-    /// </summary>
-    public class FaceRect
-    {
-        public FaceRect(int x, int y, int width, int height)
-        {
-            X = x;
-            Y = y;
-            Width = width;
-            Height = height;
-        }
-
-        /// <summary>
-        /// X coordinate of the FaceRect
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public readonly int X;
-
-        /// <summary>
-        /// Y coordinate of the FaceRect
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public readonly int Y;
-
-        /// <summary>
-        /// Width of the FaceRect
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public readonly int Width;
-
-        /// <summary>
-        /// Height of the FaceRect
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public readonly int Height;
-    }
-}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Features.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Features.cs
new file mode 100644 (file)
index 0000000..245a94a
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using Tizen.System;
+
+static internal class Features
+{
+    internal const string FaceRecognition = "http://tizen.org/feature/vision.face_recognition";
+
+    internal static bool IsSupported(string key)
+    {
+        if (SystemInfo.TryGetValue(key, out bool value))
+        {
+            return value;
+        }
+        return false;
+    }
+}
\ No newline at end of file
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Folder.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Folder.cs
new file mode 100644 (file)
index 0000000..d48ead4
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+
+namespace Tizen.Content.MediaContent
+{
+    /// <summary>
+    /// Represents the folder information for media.
+    /// </summary>
+    /// <remarks>
+    /// A <see cref="Folder"/> is used to organize media content files i.e. image, audio, video files,
+    /// in the physical storage of the device.
+    /// </remarks>
+    public class Folder
+    {
+        internal Folder(IntPtr handle)
+        {
+            Id = InteropHelper.GetString(handle, Interop.Folder.GetFolderId);
+            Path = InteropHelper.GetString(handle, Interop.Folder.GetPath);
+            Name = InteropHelper.GetString(handle, Interop.Folder.GetName);
+
+            StorageType = InteropHelper.GetValue<StorageType>(handle, Interop.Folder.GetStorageType);
+            StorageId = InteropHelper.GetString(handle, Interop.Folder.GetStorageId);
+        }
+
+        internal static Folder FromHandle(IntPtr handle) => new Folder(handle);
+
+        /// <summary>
+        /// Gets the id of folder.
+        /// </summary>
+        /// <value>The unique id of folder.</value>
+        public string Id { get; }
+
+        /// <summary>
+        /// Gets the path of folder.
+        /// </summary>
+        /// <value>The path of folder.</value>
+        public string Path { get; }
+
+        /// <summary>
+        /// Gets the name of folder.
+        /// </summary>
+        /// <value>The name of folder.</value>
+        public string Name { get; }
+
+        /// <summary>
+        /// Gets the <see cref="StorageType"/> of the storage that the folder exists.
+        /// </summary>
+        /// <value>The <see cref="StorageType"/> of the storage that the folder exists.</value>
+        public StorageType StorageType { get; }
+
+        /// <summary>
+        /// Gets the storage id of the storage that the folder exists.
+        /// </summary>
+        /// <value>The storage id of the storage that the folder exists.</value>
+        public string StorageId { get; }
+
+        /// <summary>
+        /// Returns a string representation of the folder.
+        /// </summary>
+        /// <returns>A string representation of the current folder.</returns>
+        public override string ToString() =>
+            $"Id={Id}, Name={Name}, Path={Path}, StorageType={StorageType}, StorageId={StorageType}";
+    }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/FolderCommand.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/FolderCommand.cs
new file mode 100644 (file)
index 0000000..05c7fb3
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Content.MediaContent
+{
+    /// <summary>
+    /// Provides commands to manage folders and query related media items in the database.
+    /// </summary>
+    public class FolderCommand : MediaCommand
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="FolderCommand"/> class with the specified <see cref="MediaDatabase"/>.
+        /// </summary>
+        /// <param name="database">A <see cref="MediaDatabase"/> that the commands run on.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="database"/> is null.</exception>
+        /// <exception cref="ObjectDisposedException"><paramref name="database"/> has already been disposed of.</exception>
+        public FolderCommand(MediaDatabase database) : base(database)
+        {
+        }
+
+        /// <summary>
+        /// Retrieves the number of folders.
+        /// </summary>
+        /// <returns>The number of folders.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        public int Count()
+        {
+            return Count(null);
+        }
+
+        /// <summary>
+        /// Retrieves the number of folders with <see cref="CountArguments"/>.
+        /// </summary>
+        /// <param name="arguments">The criteria to use to filter. This value can be null.</param>
+        /// <returns>The number of folders.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        public int Count(CountArguments arguments)
+        {
+            ValidateDatabase();
+
+            return CommandHelper.Count(Interop.Folder.GetFolderCountFromDb, arguments);
+        }
+
+        /// <summary>
+        /// Retrieves the folders.
+        /// </summary>
+        /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        public MediaDataReader<Folder> Select()
+        {
+            return Select(arguments: null);
+        }
+
+        /// <summary>
+        /// Retrieves the folders with <see cref="SelectArguments"/>.
+        /// </summary>
+        /// <param name="arguments">The criteria to use to filter. This value can be null.</param>
+        /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        public MediaDataReader<Folder> Select(SelectArguments arguments)
+        {
+            ValidateDatabase();
+
+            return CommandHelper.Select(arguments, Interop.Folder.ForeachFolderFromDb, Folder.FromHandle);
+        }
+
+        /// <summary>
+        /// Retrieves the folder.
+        /// </summary>
+        /// <param name="folderId">The folder id to query with.</param>
+        /// <returns>The <see cref="Folder"/> instance if the matched record was found in the database, otherwise null.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="folderId"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="folderId"/> is a zero-length string, contains only white space.</exception>
+        public Folder Select(string folderId)
+        {
+            ValidateDatabase();
+
+            ValidationUtil.ValidateNotNullOrEmpty(folderId, nameof(folderId));
+
+            Interop.Folder.GetFolderFromDb(folderId, out var handle).ThrowIfError("Failed to query");
+
+            if (handle == IntPtr.Zero)
+            {
+                return null;
+            }
+
+            try
+            {
+                return new Folder(handle);
+            }
+            finally
+            {
+                Interop.Folder.Destroy(handle);
+            }
+        }
+
+        /// <summary>
+        /// Retrieves the number of media info under the folder.
+        /// </summary>
+        /// <param name="folderId">The id of the folder to count media in the folder.</param>
+        /// <returns>The number of media info.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="folderId"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="folderId"/> is a zero-length string, contains only white space.</exception>
+        public int CountMedia(string folderId)
+        {
+            return CountMedia(folderId, null);
+        }
+
+        /// <summary>
+        /// Retrieves the number of media info under the folder with <see cref="CountArguments"/>.
+        /// </summary>
+        /// <param name="folderId">The id of the folder to count media in the folder.</param>
+        /// <param name="arguments">The criteria to use to filter. This value can be null.</param>
+        /// <returns>The number of media info.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="folderId"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="folderId"/> is a zero-length string, contains only white space.</exception>
+        public int CountMedia(string folderId, CountArguments arguments)
+        {
+            ValidateDatabase();
+
+            ValidationUtil.ValidateNotNullOrEmpty(folderId, nameof(folderId));
+
+            return CommandHelper.Count(Interop.Folder.GetMediaCountFromDb, folderId, arguments);
+        }
+
+        /// <summary>
+        /// Retrieves the media info under the folder.
+        /// </summary>
+        /// <param name="folderId">The id of the folder to select media in the folder.</param>
+        /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="folderId"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="folderId"/> is a zero-length string, contains only white space.</exception>
+        public MediaDataReader<MediaInfo> SelectMedia(string folderId)
+        {
+            return SelectMedia(folderId, null);
+        }
+
+        /// <summary>
+        /// Retrieves the media info under the folder with <see cref="SelectArguments"/>.
+        /// </summary>
+        /// <param name="folderId">The id of the folder to select media in the folder.</param>
+        /// <param name="filter">The criteria to use to filter. This value can be null.</param>
+        /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="folderId"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="folderId"/> is a zero-length string, contains only white space.</exception>
+        public MediaDataReader<MediaInfo> SelectMedia(string folderId, SelectArguments filter)
+        {
+            ValidateDatabase();
+
+            ValidationUtil.ValidateNotNullOrEmpty(folderId, nameof(folderId));
+
+            return CommandHelper.SelectMedia(Interop.Folder.ForeachMediaFromDb, folderId, filter);
+        }
+    }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Group.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Group.cs
deleted file mode 100755 (executable)
index d037f3b..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
-* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
-*
-* Licensed under the Apache License, Version 2.0 (the License);
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an AS IS BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-
-using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-
-namespace Tizen.Content.MediaContent
-{
-    /// <summary>
-    /// A Media Group represents logical grouping of media files with respect to their group name.
-    /// It is also used for filtering media items.
-    /// </summary>
-    public class Group : ContentCollection
-    {
-        private readonly string _groupName;
-        private readonly MediaGroupType _groupType;
-        private bool _disposedValue = false;
-
-        /// <summary>
-        /// The name of the media group
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string Name
-        {
-            get { return _groupName; }
-        }
-
-        internal Group(string name, MediaGroupType groupType)
-        {
-            _groupName = name;
-            _groupType = groupType;
-        }
-
-        public override void Dispose()
-        {
-            Dispose(true);
-            GC.SuppressFinalize(this);
-        }
-
-        protected virtual void Dispose(bool disposing)
-        {
-            if (!_disposedValue)
-            {
-                _disposedValue = true;
-            }
-        }
-
-        /// <summary>
-        /// Gets the count of the media info for the given media group present in the media database.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="filter">ContentFilter used to match media content from the media database.</param>
-        /// <returns>The number of media contents matching the filter passed</returns>
-        public override int GetMediaInformationCount(ContentFilter filter)
-        {
-            int mediaCount = 0;
-            IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
-            MediaContentValidator.ThrowIfError(
-                Interop.Group.GetMediaCountFromDb(Name, _groupType, handle, out mediaCount), "Failed to GetMediaCountFromDb");
-
-            return mediaCount;
-        }
-
-
-        /// <summary>
-        /// Iterates through the media files with an optional filter in the given group from the media database.
-        /// This function gets all media files associated with the given group and meeting desired filter option.
-        /// If NULL is passed to the filter, no filtering is applied.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="filter">ContentFilter used to match media content from the media database.</param>
-        /// <returns>List of content media items matching the passed filter</returns>
-        public override IEnumerable<MediaInformation> GetMediaInformations(ContentFilter filter)
-        {
-            List<MediaInformation> mediaContents = new List<MediaInformation>();
-            IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
-            Interop.Group.MediaInfoCallback callback = (IntPtr mediaHandle, IntPtr data) =>
-            {
-                Interop.MediaInformation.SafeMediaInformationHandle newHandle;
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.Clone(out newHandle, mediaHandle), "Failed to clone MediaInformation instance");
-
-                MediaContentType type;
-                Interop.MediaInformation.GetMediaType(newHandle, out type);
-                if (type == MediaContentType.Image)
-                {
-                    Interop.ImageInformation.SafeImageInformationHandle imageInfo;
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.GetImage(mediaHandle, out imageInfo), "Failed to get image information");
-
-                    mediaContents.Add(new ImageInformation(imageInfo, newHandle));
-                }
-                else if ((type == MediaContentType.Music) || (type == MediaContentType.Sound))
-                {
-                    Interop.AudioInformation.SafeAudioInformationHandle audioInfo;
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.GetAudio(mediaHandle, out audioInfo), "Failed to get audio information");
-
-                    mediaContents.Add(new AudioInformation(audioInfo, newHandle));
-                }
-                else if (type == MediaContentType.Video)
-                {
-                    Interop.VideoInformation.SafeVideoInformationHandle videoInfo;
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.GetVideo(mediaHandle, out videoInfo), "Failed to get video information");
-
-                    mediaContents.Add(new VideoInformation(videoInfo, newHandle));
-                }
-                else if (type == MediaContentType.Others)
-                {
-                    mediaContents.Add(new MediaInformation(newHandle));
-                }
-
-                return true;
-            };
-            MediaContentValidator.ThrowIfError(
-                Interop.Group.ForeachMediaFromDb(Name, _groupType, handle, callback, IntPtr.Zero), "Failed to get media information for the group");
-
-            return mediaContents;
-        }
-    }
-}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ImageInfo.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ImageInfo.cs
new file mode 100644 (file)
index 0000000..5ea5416
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Diagnostics;
+
+namespace Tizen.Content.MediaContent
+{
+    /// <summary>
+    /// Represents the image media stored in the device.
+    /// </summary>
+    public class ImageInfo : MediaInfo
+    {
+        internal ImageInfo(Interop.MediaInfoHandle handle) : base(handle)
+        {
+            IntPtr imageHandle = IntPtr.Zero;
+
+            try
+            {
+                Interop.MediaInfo.GetImage(handle, out imageHandle).ThrowIfError("Failed to retrieve data");
+
+                Debug.Assert(imageHandle != IntPtr.Zero);
+
+                Width = InteropHelper.GetValue<int>(imageHandle, Interop.ImageInfo.GetWidth);
+                Height = InteropHelper.GetValue<int>(imageHandle, Interop.ImageInfo.GetHeight);
+
+                Orientation = InteropHelper.GetValue<Orientation>(imageHandle, Interop.ImageInfo.GetOrientation);
+
+                DateTaken = InteropHelper.GetString(imageHandle, Interop.ImageInfo.GetDateTaken);
+                BurstId = InteropHelper.GetString(imageHandle, Interop.ImageInfo.GetBurstId);
+                ExposureTime = InteropHelper.GetString(imageHandle, Interop.ImageInfo.GetExposureTime);
+
+                FNumber = InteropHelper.GetValue<double>(imageHandle, Interop.ImageInfo.GetFNumber);
+                Iso = InteropHelper.GetValue<int>(imageHandle, Interop.ImageInfo.GetISO);
+
+                Model = InteropHelper.GetString(imageHandle, Interop.ImageInfo.GetModel);
+
+                IsBurstShot = InteropHelper.GetValue<bool>(imageHandle, Interop.ImageInfo.IsBurstShot);
+
+            }
+            finally
+            {
+                Interop.ImageInfo.Destroy(imageHandle);
+            }
+        }
+
+        /// <summary>
+        /// Gets the image width in pixels.
+        /// </summary>
+        /// <value>The image width in pixels.</value>
+        public int Width { get; }
+
+        /// <summary>
+        /// Gets the image height in pixels.
+        /// </summary>
+        /// <value>The image height in pixels.</value>
+        public int Height { get; }
+
+        /// <summary>
+        /// Gets the orientation of image.
+        /// </summary>
+        /// <value>The orientation of image.</value>
+        public Orientation Orientation { get; }
+
+        /// <summary>
+        /// Gets the date of the creation time as a formatted string.
+        /// </summary>
+        /// <value>The date of the creation time as a formatted string.</value>
+        public string DateTaken { get; }
+
+        /// <summary>
+        /// Gets the burst shot id.
+        /// </summary>
+        /// <value>The burst shot id if it is a burst shot, otherwise an empty string.</value>
+        /// <seealso cref="IsBurstShot"/>
+        public string BurstId { get; }
+
+        /// <summary>
+        /// Gets the exposure time from exif.
+        /// </summary>
+        /// <value>The exposure time from exif.</value>
+        public string ExposureTime { get; }
+
+        /// <summary>
+        /// Gets the FNumber from exif.
+        /// </summary>
+        /// <value>The FNumber from exif.</value>
+        public double FNumber { get; }
+
+        /// <summary>
+        /// Gets the iso from exif.
+        /// </summary>
+        /// <value>The iso from exif.</value>
+        public int Iso { get; }
+
+        /// <summary>
+        /// Gets the model from exif.
+        /// </summary>
+        /// <value>The model from exif.</value>
+        public string Model { get; }
+
+        /// <summary>
+        /// Gets the value indicating whether the media is a burst shot image.
+        /// </summary>
+        /// <value>true if the media is a burst shot image, otherwise false.</value>
+        public bool IsBurstShot { get; }
+    }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ImageInformation.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ImageInformation.cs
deleted file mode 100755 (executable)
index e6922d3..0000000
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
-* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
-*
-* Licensed under the Apache License, Version 2.0 (the License);
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an AS IS BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-
-
-using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-using System.Collections.ObjectModel;
-using System.Runtime.InteropServices;
-
-namespace Tizen.Content.MediaContent
-{
-    /// <summary>
-    /// ImageContent class API gives the information related to the image media stored in the device</summary>
-    public class ImageInformation : MediaInformation
-    {
-        private readonly Interop.ImageInformation.SafeImageInformationHandle _handle;
-
-        /// <summary>
-        ///  Gets the id of the media.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string MediaId
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.ImageInformation.GetMediaId(_handle, out val), "Failed to get value");
-
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        /// <summary>
-        ///  Gets the image width in pixels.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public int Width
-        {
-            get
-            {
-                int width = 0;
-                MediaContentValidator.ThrowIfError(
-                    Interop.ImageInformation.GetWidth(_handle, out width), "Failed to get value");
-
-                return width;
-            }
-        }
-
-        /// <summary>
-        ///  Gets the image height in pixels.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public int Height
-        {
-            get
-            {
-                int height = 0;
-                MediaContentValidator.ThrowIfError(
-                    Interop.ImageInformation.GetHeight(_handle, out height), "Failed to get value");
-
-                return height;
-            }
-        }
-
-        /// <summary>
-        ///  Image orientation.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public MediaContentOrientation Orientation
-        {
-            get
-            {
-                MediaContentOrientation orientation = MediaContentOrientation.NotAvailable;
-                MediaContentValidator.ThrowIfError(
-                    Interop.ImageInformation.GetOrientation(_handle, out orientation), "Failed to get value");
-
-                return orientation;
-            }
-
-            set
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.ImageInformation.SetOrientation(_handle, value), "Failed to set value");
-            }
-        }
-
-        /// <summary>
-        /// Gets the image creation time in seconds, since the Epoch.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string TakenDate
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.ImageInformation.GetDateTaken(_handle, out val), "Failed to get value");
-
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        /// <summary>
-        /// Gets the burst shot ID.
-        /// If BurstId is null, this is not a burst shot
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string BurstId
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.ImageInformation.GetBurstId(_handle, out val), "Failed to get value");
-
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        /// <summary>
-        /// Gets the exposure time from exif.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string ExposureTime
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.ImageInformation.GetExposureTime(_handle, out val), "Failed to get value");
-
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        /// <summary>
-        /// Gets the fnumber from exif.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public double FNumber
-        {
-            get
-            {
-                double fNumber = 0.0;
-                MediaContentValidator.ThrowIfError(
-                    Interop.ImageInformation.GetFNumber(_handle, out fNumber), "Failed to get value");
-
-                return fNumber;
-            }
-        }
-
-        /// <summary>
-        /// Gets the iso from exif.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public int Iso
-        {
-            get
-            {
-                int iso = 0;
-                MediaContentValidator.ThrowIfError(
-                    Interop.ImageInformation.GetISO(_handle, out iso), "Failed to get value");
-
-                return iso;
-            }
-        }
-
-        /// <summary>
-        /// Gets the model from exif.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string Model
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.ImageInformation.GetModel(_handle, out val), "Failed to get value");
-
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        /// <summary>
-        /// Checks whether the media is a burst shot image.
-        /// The value is true if the media is a burst shot image,
-        /// otherwise false if the media is not a burst shot image.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public bool IsBurstShot
-        {
-            get
-            {
-                bool isBurst = false;
-                MediaContentValidator.ThrowIfError(
-                    Interop.ImageInformation.IsBurstShot(_handle, out isBurst), "Failed to get value");
-
-                return isBurst;
-            }
-        }
-
-        /// <summary>
-        /// Iterates through the media faces with filter in the given media file from the media database.
-        /// If NULL is passed to the filter, no filtering is applied.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <returns>
-        /// Task to get all the MediaFaces </returns>
-        /// <param name="filter"> filter for the Tags</param>
-        public IEnumerable<MediaFace> GetMediaFaces(ContentFilter filter)
-        {
-            Collection<MediaFace> coll = new Collection<MediaFace>();
-
-            Interop.MediaInformation.MediaFaceCallback callback = (IntPtr faceHandle, IntPtr userData) =>
-            {
-                IntPtr newHandle = IntPtr.Zero;
-                MediaContentValidator.ThrowIfError(
-                    Interop.Face.Clone(out newHandle, faceHandle), "Failed to clone Tag");
-
-                coll.Add(new MediaFace(newHandle));
-                return true;
-            };
-            IntPtr filterHandle = (filter != null) ? filter.Handle : IntPtr.Zero;
-            MediaContentValidator.ThrowIfError(
-                Interop.MediaInformation.GetAllFaces(MediaId, filterHandle, callback, IntPtr.Zero), "Failed to get value");
-
-            return coll;
-        }
-
-        /// <summary>
-        /// Gets the number of faces for the passed filter in the given media ID from the media database.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <returns>
-        /// int count</returns>
-        /// <param name="filter">The Filter for matching Face</param>
-        public int GetMediaFaceCount(ContentFilter filter)
-        {
-            int count = 0;
-            IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
-            MediaContentValidator.ThrowIfError(
-                Interop.MediaInformation.GetFaceCount(MediaId, handle, out count), "Failed to get value");
-
-            return count;
-        }
-
-
-        /// <summary>
-        /// Inserts a MediaFace item to the media database
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="image">The image on which face is to be added</param>
-        /// <param name="rect">The dimensions of the face</param>
-        /// <returns>The MediaFace instance</returns>
-        public MediaFace AddFace(ImageInformation image, FaceRect rect)
-        {
-            MediaFace face = new MediaFace(image, rect);
-            ContentManager.Database.Insert(face);
-            return face;
-        }
-
-        /// <summary>
-        /// Deletes the MediaFace from the media database.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="face">The face instance to be deleted</param>
-        public void DeleteFace(MediaFace face)
-        {
-            ContentManager.Database.Delete(face);
-        }
-
-        /// <summary>
-        /// Updates the MediaFace in the media database
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="face">The MediaFace object to be updated</param>
-        public void UpdateFace(MediaFace face)
-        {
-            ContentManager.Database.Update(face);
-        }
-
-        internal IntPtr ImageHandle
-        {
-            get
-            {
-                return _handle.DangerousGetHandle();
-            }
-        }
-
-        internal ImageInformation(Interop.ImageInformation.SafeImageInformationHandle handle, Interop.MediaInformation.SafeMediaInformationHandle mediaInformationHandle)
-            : base(mediaInformationHandle)
-        {
-            _handle = handle;
-        }
-    }
-}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/InteropHelper.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/InteropHelper.cs
new file mode 100644 (file)
index 0000000..1d9d933
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Content.MediaContent
+{
+    internal static class InteropHelper
+    {
+        internal delegate MediaContentError GetStringFunc<T>(T handle, out IntPtr value);
+
+        internal static string GetString<T>(T handle, GetStringFunc<T> func)
+        {
+            IntPtr val = IntPtr.Zero;
+            try
+            {
+                func(handle, out val).ThrowIfError("Failed to get value");
+
+                if (val == IntPtr.Zero)
+                {
+                    return string.Empty;
+                }
+
+                return Marshal.PtrToStringAnsi(val);
+            }
+            finally
+            {
+                Interop.Libc.Free(val);
+            }
+        }
+
+        internal delegate MediaContentError GetValueFunc<T, TValue>(T handle, out TValue value);
+
+        internal static TValue GetValue<T, TValue>(T handle, GetValueFunc<T, TValue> func)
+        {
+            func(handle, out var val).ThrowIfError("Failed to get value");
+
+            return val;
+        }
+
+        internal static TValue GetValue<TValue>(IntPtr handle, GetValueFunc<IntPtr, TValue> func)
+        {
+            func(handle, out var val).ThrowIfError("Failed to get value");
+
+            return val;
+        }
+
+        internal static TValue GetValue<TValue>(Interop.MediaInfoHandle handle,
+            GetValueFunc<Interop.MediaInfoHandle, TValue> func)
+        {
+            func(handle, out var val).ThrowIfError("Failed to get value");
+
+            return val;
+        }
+
+        internal static DateTimeOffset GetDateTime<T>(T handle,
+            GetValueFunc<T, IntPtr> func)
+        {
+            IntPtr time = IntPtr.Zero;
+
+            func(handle, out time).ThrowIfError("Failed to get value");
+
+            return DateTimeOffset.FromUnixTimeSeconds(time.ToInt64());
+        }
+    }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaBookmark.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaBookmark.cs
deleted file mode 100755 (executable)
index 07e14bb..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
-* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
-*
-* Licensed under the Apache License, Version 2.0 (the License);
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an AS IS BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-
-
-using System;
-using System.Runtime.InteropServices;
-
-namespace Tizen.Content.MediaContent
-{
-    /// <summary>
-    /// A MediaBookmark allows you to mark interesting moment in a media(video and audio) to enable fast searching.
-    /// The MediaBookmark Information API provides functions to get information about bookmarks associated with video and audio items.
-    /// </summary>
-    public class MediaBookmark : IDisposable
-    {
-        private IntPtr _bookmarkHandle = IntPtr.Zero;
-        private bool _disposedValue = false;
-
-        private IntPtr Handle
-        {
-            get
-            {
-                if (_bookmarkHandle == IntPtr.Zero)
-                {
-                    throw new ObjectDisposedException(nameof(MediaBookmark));
-                }
-
-                return _bookmarkHandle;
-            }
-        }
-        internal MediaBookmark(IntPtr handle)
-        {
-            _bookmarkHandle = handle;
-        }
-
-        ~MediaBookmark()
-        {
-            Dispose(false);
-        }
-        /// <summary>
-        /// The media bookmark ID
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public int Id
-        {
-            get
-            {
-                int id;
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaBookmark.GetBookmarkId(Handle, out id), "Failed to get bookmark id");
-
-                return id;
-            }
-        }
-
-        /// <summary>
-        /// The thumbnail path of media bookmark
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string ThumbnailPath
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaBookmark.GetThumbnailPath(Handle, out val), "Failed to get bookmark thumbnail");
-
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        /// <summary>
-        /// The bookmark time offset (in milliseconds)
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public uint Offset
-        {
-            get
-            {
-                uint offset;
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaBookmark.GetMarkedTime(Handle, out offset), "Failed to get bookmarked time");
-
-                return offset;
-            }
-        }
-
-        public void Dispose()
-        {
-            Dispose(true);
-            GC.SuppressFinalize(this);
-        }
-
-        protected virtual void Dispose(bool disposing)
-        {
-            if (!_disposedValue)
-            {
-                if (_bookmarkHandle != IntPtr.Zero)
-                {
-                    Interop.MediaBookmark.Destroy(_bookmarkHandle);
-                    _bookmarkHandle = IntPtr.Zero;
-                }
-
-                _disposedValue = true;
-            }
-        }
-    }
-}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaCommand.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaCommand.cs
new file mode 100644 (file)
index 0000000..5ae3bf5
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Content.MediaContent
+{
+    /// <summary>
+    /// <see cref="MediaCommand"/> is a base class for command classes.
+    /// </summary>
+    public abstract class MediaCommand
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="MediaCommand"/> class with the specified <see cref="MediaDatabase"/>.
+        /// </summary>
+        /// <param name="database">A <see cref="MediaDatabase"/> that the commands run on.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="database"/> is null.</exception>
+        /// <exception cref="ObjectDisposedException"><paramref name="database"/> has already been disposed of.</exception>
+        protected MediaCommand(MediaDatabase database)
+        {
+            Database = database ?? throw new ArgumentNullException(nameof(database));
+
+            if (database.IsDisposed)
+            {
+                throw new ObjectDisposedException(nameof(database));
+            }
+        }
+
+        internal void ValidateDatabase()
+        {
+            Database.ValidateState();
+        }
+
+        /// <summary>
+        /// Gets the <see cref="MediaDatabase"/>.
+        /// </summary>
+        /// <value>The <see cref="MediaDatabase"/> which commands execute on.</value>
+        public MediaDatabase Database { get; }
+    }
+
+    /// <summary>
+    /// Provides a means of reading results obtained by executing a query.
+    /// </summary>
+    public interface IMediaDataReader
+    {
+        /// <summary>
+        /// Advances to the next record.
+        /// </summary>
+        /// <returns>true if there are more rows; otherwise false.</returns>
+        bool Read();
+
+        /// <summary>
+        /// Gets the current record.
+        /// </summary>
+        /// <value>The current record object.</value>
+        object Current { get; }
+    }
+
+    /// <summary>
+    /// Provides a means of reading results obtained by executing a query.
+    /// </summary>
+    /// <typeparam name="TRecord"></typeparam>
+    public class MediaDataReader<TRecord> : IMediaDataReader, IDisposable
+    {
+        private readonly IEnumerator<TRecord> _enumerator;
+
+        internal MediaDataReader(IEnumerable<TRecord> items)
+        {
+            _enumerator = items.GetEnumerator();
+        }
+
+        /// <summary>
+        /// Gets the current record.
+        /// </summary>
+        /// <value>The current record if the position is valid; otherwise null.</value>
+        public TRecord Current
+        {
+            get
+            {
+                ValidateNotDisposed();
+                return _enumerator.Current;
+            }
+        }
+
+        /// <summary>
+        /// Advances to the next record.
+        /// </summary>
+        /// <returns>true if there are more rows; otherwise false.</returns>
+        public bool Read()
+        {
+            ValidateNotDisposed();
+            return _enumerator.MoveNext();
+        }
+
+        object IMediaDataReader.Current => Current;
+
+        #region IDisposable Support
+        private bool _disposed = false;
+
+        /// <summary>
+        /// Disposes of the resources (other than memory) used by the MediaDataReader.
+        /// </summary>
+        /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
+        protected virtual void Dispose(bool disposing)
+        {
+            if (!_disposed)
+            {
+                _disposed = true;
+            }
+        }
+
+        /// <summary>
+        /// Releases all resources used by the current instance.
+        /// </summary>
+        public void Dispose()
+        {
+            Dispose(true);
+        }
+
+        internal void ValidateNotDisposed()
+        {
+            if (_disposed)
+            {
+                throw new ObjectDisposedException(GetType().Name);
+            }
+        }
+        #endregion
+    }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaContentEnums.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaContentEnums.cs
deleted file mode 100755 (executable)
index 2c59329..0000000
+++ /dev/null
@@ -1,411 +0,0 @@
-/*
-* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
-*
-* Licensed under the Apache License, Version 2.0 (the License);
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an AS IS BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-
-
-namespace Tizen.Content.MediaContent
-{
-    /// <summary>
-    /// Enumeration for ordering
-    /// </summary>
-    /// <since_tizen> 3 </since_tizen>
-    public enum ContentOrder
-    {
-        /// <summary>
-        /// Ascending order
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Asc,
-        /// <summary>
-        /// Descending order
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Desc
-    }
-
-    /// <summary>
-    /// Enumeration for collations.
-    /// </summary>
-    /// <since_tizen> 3 </since_tizen>
-    public enum ContentCollation
-    {
-        /// <summary>
-        /// Default collation BINARY
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Default,
-        /// <summary>
-        /// Collation NOCASE, not case sensitive
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Nocase,
-        /// <summary>
-        /// Collation RTRIM, trailing space characters are ignored
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Rtim,
-        /// <summary>
-        /// Collation LOCALIZATION, NOCASE also applied
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Localized
-    }
-
-    /// <summary>
-    /// Enumeration for a media group.
-    /// </summary>
-    /// <since_tizen> 3 </since_tizen>
-    public enum MediaGroupType
-    {
-        /// <summary>
-        /// Media group ID for display name
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        DisplayName,
-        /// <summary>
-        /// Media group ID for a media type
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Type,
-        /// <summary>
-        /// Media group ID for a mime type
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        MimeType,
-        /// <summary>
-        /// Media group ID for content size
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Size,
-        /// <summary>
-        /// Media group ID for the added time
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        AddedTime,
-        /// <summary>
-        /// Media group ID for the modified time
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        ModifiedTime,
-        /// <summary>
-        /// Media group ID for a content title
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Title,
-        /// <summary>
-        /// Media group ID for an artist
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Artist,
-        /// <summary>
-        /// Media group ID for an album artist
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        AlbumArtist,
-        /// <summary>
-        /// Media group ID for a genre
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Genre,
-        /// <summary>
-        /// Media group ID for a composer
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Composer,
-        /// <summary>
-        /// Media group ID for a year
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Year,
-        /// <summary>
-        /// Media group ID for the recorded date
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        RecordedDate,
-        /// <summary>
-        /// Media group ID for the copyright
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Copyright,
-        /// <summary>
-        /// Media group ID for a track number
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Tracknum,
-        /// <summary>
-        /// Media group ID for a description
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Description,
-        /// <summary>
-        /// Media group ID for the longitude
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Longitude,
-        /// <summary>
-        /// Media group ID for the latitude
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Latitude,
-        /// <summary>
-        /// Media group ID for the altitude
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Altitude,
-        /// <summary>
-        /// Media group ID for the burst shot
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        BurstImage,
-        /// <summary>
-        /// Media group ID for a rating
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Rating,
-        /// <summary>
-        /// Media group ID for an author
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Author,
-        /// <summary>
-        /// Media group ID for a provide
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Provider,
-        /// <summary>
-        /// Media group ID for the content name
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        ContentName,
-        /// <summary>
-        /// Media group ID for a category
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Category,
-        /// <summary>
-        /// Media group ID for a location tag
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        LocationTag,
-        /// <summary>
-        /// Media group ID for an age rating
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        AgeRating,
-        /// <summary>
-        /// Media group ID for a keyword
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Keyword,
-        /// <summary>
-        /// Media group ID for the weather
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Weather,
-        /// <summary>
-        /// Invalid media group ID
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Max
-    }
-
-    /// <summary>
-    /// Enum to give the type of storage.
-    /// </summary>
-    /// <since_tizen> 3 </since_tizen>
-    public enum ContentStorageType : int
-    {
-        /// <summary>
-        /// The device's internal storage
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Internal = 0,
-        /// <summary>
-        /// The device's external storage like sd card
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        External = 1,
-        /// <summary>
-        /// The external USB storage
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        ExternalUSB = 2
-    };
-
-    /// <summary>
-    /// Enums for media database update type
-    /// </summary>
-    /// <since_tizen> 3 </since_tizen>
-    public enum MediaContentDBUpdateType
-    {
-        /// <summary>
-        /// Updating the database with inserts.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Insert,
-        /// <summary>
-        /// Updating the database with removes.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Delete,
-        /// <summary>
-        /// Updating the database with updates.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Update
-    }
-
-    /// <summary>
-    /// Enums for the type of item updated in media database
-    /// </summary>
-    /// <since_tizen> 3 </since_tizen>
-    public enum MediaContentUpdateItemType
-    {
-        /// <summary>
-        /// The file information is updated.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        File,
-        /// <summary>
-        /// The folder information and the file information included in the folder are updated.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Directory
-    }
-
-    /// <summary>
-    /// Enums for content collection types
-    /// </summary>
-    /// <since_tizen> 3 </since_tizen>
-    public enum ContentCollectionType
-    {
-        /// <summary>
-        ///Content Collection type folder
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Folder,
-        /// <summary>
-        ///Content Collection type storage
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Storage,
-        /// <summary>
-        /// Content Collection type album
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Album,
-        /// <summary>
-        ///Content Collection type playlist
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        PlayList,
-        /// <summary>
-        ///Content Collection type tag
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Tag,
-        /// <summary>
-        ///Content Collection type group
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Group
-    }
-    /// <summary>
-    /// Enum to give the type of media information.
-    /// </summary>
-    /// <since_tizen> 3 </since_tizen>
-    public enum MediaContentType : int
-    {
-        /// <summary>
-        /// The type of an image.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Image = 0,
-        /// <summary>
-        /// The type of a video.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Video = 1,
-        /// <summary>
-        /// The type of sound.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Sound = 2,
-        /// <summary>
-        /// The type of music.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Music = 3,
-        /// <summary>
-        /// The type of other.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Others = 4
-    };
-
-    /// <summary>
-    /// Enum to give the orientation type of the media.
-    /// </summary>
-    /// <since_tizen> 3 </since_tizen>
-    public enum MediaContentOrientation : int
-    {
-        /// <summary>
-        /// Not available.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        NotAvailable = 0,
-        /// <summary>
-        /// Normal.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Normal = 1,
-        /// <summary>
-        /// Flip horizontal.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        HFlip = 2,
-        /// <summary>
-        /// Rotate 180 degrees.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Rot180 = 3,
-        /// <summary>
-        /// Flip vertical.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        VFlip = 4,
-        /// <summary>
-        /// Transpose.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Transpose = 5,
-        /// <summary>
-        /// Rotate 90 degrees.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Rot90 = 6,
-        /// <summary>
-        /// Transverse.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Transverse = 7,
-        /// <summary>
-        /// Rotate 270 degrees.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        Rot270 = 8
-    };
-}
index 421c370..5e0cd5d 100755 (executable)
@@ -1,32 +1,28 @@
-/*
-* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
-*
-* Licensed under the Apache License, Version 2.0 (the License);
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an AS IS BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 using System;
+using System.Diagnostics;
 using System.IO;
+using System.Linq;
 using Tizen.Internals.Errors;
 
 namespace Tizen.Content.MediaContent
 {
-    /// <summary>
-    /// Enumeration for media content's error code
-    /// </summary>
-    /// <since_tizen> 3 </since_tizen>
-    /// <remarks><paramref name="NotSupported"/> error occurs when the device does not support the function.</remarks>
-    public enum MediaContentError
+    internal enum MediaContentError
     {
         None = ErrorCode.None,
         InvalidParameter = ErrorCode.InvalidParameter,
@@ -42,38 +38,56 @@ namespace Tizen.Content.MediaContent
         NotSupported = ErrorCode.NotSupported,
     }
 
-    internal class MediaContentValidator
+    internal static class MediaContentErrorExtensions
     {
-        internal const string LogTag = "Tizen.Content.MediaContent";
+        internal static MediaContentError Ignore(this MediaContentError err, params MediaContentError[] ignores)
+        {
+            if (ignores.Contains(err))
+            {
+                return MediaContentError.None;
+            }
+            return err;
+        }
 
-        internal static void ThrowIfError(MediaContentError err, string msg)
+
+        internal static void ThrowIfError(this MediaContentError err, string msg)
         {
+            if (err == MediaContentError.None)
+            {
+                return;
+            }
+
+            throw err.AsException(msg);
+        }
+
+        internal static Exception AsException(this MediaContentError err, string msg)
+        {
+            Debug.Assert(err != MediaContentError.None);
+
             switch (err)
             {
                 case MediaContentError.InvalidParameter:
-                    throw new ArgumentException(msg);
+                    return new ArgumentException($"{msg}.");
                 case MediaContentError.OutOfMemory:
-                    throw new OutOfMemoryException(msg);
+                    return new OutOfMemoryException($"{msg}.");
                 case MediaContentError.InvalidOperation:
-                    throw new InvalidOperationException(msg);
+                    return new InvalidOperationException($"{msg}.");
                 case MediaContentError.FileNoSpaceOnDevice:
-                    throw new IOException(msg);
+                    return new IOException($"{msg} : {err}.");
                 case MediaContentError.PermissionDenied:
-                    throw new UnauthorizedAccessException(msg);
+                    return new UnauthorizedAccessException($"{msg}.");
                 case MediaContentError.DatabaseFailed:
-                    throw new InvalidOperationException("[DB Failed]" + msg);
+                    return new MediaDatabaseException(MediaDatabaseError.OperationFailed);
                 case MediaContentError.DatabaseBusy:
-                    throw new InvalidOperationException("[DB Busy]" + msg);
+                    return new MediaDatabaseException(MediaDatabaseError.DatabaseBusy);
                 case MediaContentError.NetworkFailed:
-                    throw new InvalidOperationException("[Network Error]" + msg);
+                    return new InvalidOperationException($"{msg} : {err}.");
                 case MediaContentError.UnsupportedContent:
-                    throw new PlatformNotSupportedException(msg);
-            }
-        }
+                    return new UnsupportedContentException();
 
-        internal static string CheckString(string value)
-        {
-            return (value != null) ? value : "";
+                default:
+                    return new InvalidOperationException($"Unknown Error : {err.ToString()}, {msg}.");
+            }
         }
     }
 }
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaDatabase.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaDatabase.cs
new file mode 100644 (file)
index 0000000..d9a152e
--- /dev/null
@@ -0,0 +1,466 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Tizen.Content.MediaContent
+{
+    /// <summary>
+    /// Provides the ability to connect to and manage the database.
+    /// </summary>
+    public class MediaDatabase : IDisposable
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="MediaDatabase"/> class.
+        /// </summary>
+        public MediaDatabase()
+        {
+        }
+
+        private object _lock = new object();
+
+        /// <summary>
+        /// Connects to the database.
+        /// </summary>
+        /// <exception cref="InvalidOperationException">The database is already connected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while connecting.</exception>
+        public void Connect()
+        {
+            ValidateNotDisposed();
+
+            lock (_lock)
+            {
+                if (IsConnected)
+                {
+                    throw new InvalidOperationException("The database is already connected.");
+                }
+
+                Interop.Content.Connect().ThrowIfError("Failed to connect");
+
+                IsConnected = true;
+            }
+        }
+
+        /// <summary>
+        /// Disconnects from the media database.
+        /// </summary>
+        /// <exception cref="InvalidOperationException">The database is not connected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while connecting.</exception>
+        public void Disconnect()
+        {
+            ValidateNotDisposed();
+
+            lock (_lock)
+            {
+                if (!IsConnected)
+                {
+                    throw new InvalidOperationException("The database is not connected.");
+                }
+
+                Interop.Content.Disconnect().ThrowIfError("Failed to disconnect");
+
+                IsConnected = false;
+            }
+        }
+
+        private static readonly Interop.Content.MediaContentDBUpdatedCallback _mediaInfoUpdatedCb = (
+            MediaContentError error, int pid, ItemType updateItem, OperationType updateType,
+            MediaType mediaType, string uuid, string filePath, string mimeType, IntPtr _) =>
+        {
+            if (updateItem == ItemType.Directory)
+            {
+                return;
+            }
+
+            _mediaInfoUpdated?.Invoke(
+                null, new MediaInfoUpdatedEventArgs(pid, updateType, mediaType, uuid, filePath, mimeType));
+        };
+
+        private static IntPtr _mediaInfoUpdatedHandle = IntPtr.Zero;
+        private static event EventHandler<MediaInfoUpdatedEventArgs> _mediaInfoUpdated;
+        private static readonly object _mediaInfoUpdatedLock = new object();
+
+        /// <summary>
+        /// Occurs when there is a change for media in the database.
+        /// </summary>
+        public static event EventHandler<MediaInfoUpdatedEventArgs> MediaInfoUpdated
+        {
+            add
+            {
+                lock (_mediaInfoUpdatedLock)
+                {
+                    if (_mediaInfoUpdated == null)
+                    {
+                        Interop.Content.AddDbUpdatedCb(_mediaInfoUpdatedCb, IntPtr.Zero,
+                            out _mediaInfoUpdatedHandle).ThrowIfError("Failed to register an event handler");
+                    }
+
+                    _mediaInfoUpdated += value;
+                }
+            }
+            remove
+            {
+                if (value == null)
+                {
+                    return;
+                }
+
+                lock (_mediaInfoUpdatedLock)
+                {
+                    if (_mediaInfoUpdated == value)
+                    {
+                        Interop.Content.RemoveDbUpdatedCb(_mediaInfoUpdatedHandle).ThrowIfError("Failed to unregister");
+                    }
+
+                    _mediaInfoUpdated -= value;
+                }
+            }
+        }
+
+
+        private static readonly Interop.Content.MediaContentDBUpdatedCallback _folderUpdatedCb = (
+            MediaContentError error, int pid, ItemType updateItem, OperationType updateType,
+            MediaType mediaType, string uuid, string filePath, string mimeType, IntPtr _) =>
+        {
+            if (updateItem == ItemType.File)
+            {
+                return;
+            }
+
+            _folderUpdated?.Invoke(null, new FolderUpdatedEventArgs(updateType, uuid, filePath));
+        };
+
+        private static IntPtr _folderUpdatedHandle = IntPtr.Zero;
+        private static event EventHandler<FolderUpdatedEventArgs> _folderUpdated;
+        private static readonly object _folderUpdatedLock = new object();
+
+        /// <summary>
+        /// Occurs when there is a change for folder in the database.
+        /// </summary>
+        public static event EventHandler<FolderUpdatedEventArgs> FolderUpdated
+        {
+            add
+            {
+                lock (_folderUpdatedLock)
+                {
+                    if (_folderUpdated == null)
+                    {
+                        Interop.Content.AddDbUpdatedCb(_folderUpdatedCb, IntPtr.Zero,
+                            out _folderUpdatedHandle).ThrowIfError("Failed to register an event handler");
+                    }
+
+                    _folderUpdated += value;
+                }
+            }
+            remove
+            {
+                if (value == null)
+                {
+                    return;
+                }
+
+                lock (_folderUpdatedLock)
+                {
+                    if (_folderUpdated == value)
+                    {
+                        Interop.Content.RemoveDbUpdatedCb(_folderUpdatedHandle).ThrowIfError("Failed to unregister");
+                    }
+
+                    _folderUpdated -= value;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Requests to scan a media file.
+        /// </summary>
+        /// <param name="path">The path of the media to be scanned.</param>
+        /// <remarks>
+        /// It requests to scan a media file to the media server.\n
+        /// If the specified file is not registered to the database yet,
+        /// the media file information will be added to the database.\n
+        /// If it is already registered to the database, the media information is refreshed.\n
+        /// If the specified file does not exist,
+        /// the record of the media file will be deleted from the database.\n
+        /// \n
+        /// If you want to access internal storage, you should add privilege http://tizen.org/privilege/mediastorage.\n
+        /// If you want to access external storage, you should add privilege http://tizen.org/privilege/externalstorage.
+        /// </remarks>
+        /// <privilege>http://tizen.org/privilege/content.write</privilege>
+        /// <privilege>http://tizen.org/privilege/mediastorage</privilege>
+        /// <privilege>http://tizen.org/privilege/externalstorage</privilege>
+        /// <exception cref="InvalidOperationException">The database is not connected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
+        /// <exception cref="ArgumentException">
+        ///     <paramref name="path"/> is a zero-length string, contains only white space.\n
+        ///     -or-\n
+        ///     <paramref name="path"/> contains a hidden path that starts with '.'.\n
+        ///     -or-\n
+        ///     <paramref name="path"/> contains a directory containing the ".scan_ignore" file.
+        /// </exception>
+        /// <exception cref="UnauthorizedAccessException">The caller has no required privilege.</exception>
+        public void ScanFile(string path)
+        {
+            ValidateState();
+
+            ValidationUtil.ValidateNotNullOrEmpty(path, nameof(path));
+
+            Interop.Content.ScanFile(path).Ignore(MediaContentError.InvalidParameter).ThrowIfError("Failed to scan");
+        }
+
+        /// <summary>
+        /// Requests to scan a folder, recursively.
+        /// </summary>
+        /// <remarks>
+        ///     If you want to access internal storage, you should add privilege http://tizen.org/privilege/mediastorage.\n
+        ///     If you want to access external storage, you should add privilege http://tizen.org/privilege/externalstorage.
+        /// </remarks>
+        /// <privilege>http://tizen.org/privilege/content.write</privilege>
+        /// <privilege>http://tizen.org/privilege/mediastorage</privilege>
+        /// <privilege>http://tizen.org/privilege/externalstorage</privilege>
+        /// <param name="folderPath">The path to scan.</param>
+        /// <remarks>Folders that contains a file named ".scan_ignore" will not be scanned.</remarks>
+        /// <returns>A task that represents the asynchronous scan operation.</returns>
+        /// <exception cref="InvalidOperationException">The database is not connected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="UnauthorizedAccessException">The caller has no required privilege.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="folderPath"/> is null.</exception>
+        /// <exception cref="ArgumentException">
+        ///     <paramref name="folderPath"/> is a zero-length string, contains only white space.\n
+        ///     -or-\n
+        ///     <paramref name="folderPath"/> contains a hidden path that starts with '.'.\n
+        ///     -or-\n
+        ///     <paramref name="folderPath"/> contains a directory containing the ".scan_ignore" file.
+        /// </exception>
+        public Task ScanFolderAsync(string folderPath)
+        {
+            return ScanFolderAsync(folderPath, true);
+        }
+
+        /// <summary>
+        /// Requests to scan a folder.
+        /// </summary>
+        /// <remarks>
+        ///     If you want to access internal storage, you should add privilege http://tizen.org/privilege/mediastorage.\n
+        ///     If you want to access external storage, you should add privilege http://tizen.org/privilege/externalstorage.
+        /// </remarks>
+        /// <privilege>http://tizen.org/privilege/content.write</privilege>
+        /// <privilege>http://tizen.org/privilege/mediastorage</privilege>
+        /// <privilege>http://tizen.org/privilege/externalstorage</privilege>
+        /// <param name="folderPath">The path to scan.</param>
+        /// <param name="recursive">The value indicating if the folder is to recursively scanned.</param>
+        /// <remarks>Folders that contains a file named ".scan_ignore" will not be scanned.</remarks>
+        /// <returns>A task that represents the asynchronous scan operation.</returns>
+        /// <exception cref="InvalidOperationException">The database is not connected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="UnauthorizedAccessException">The caller has no required privilege.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="folderPath"/> is null.</exception>
+        /// <exception cref="ArgumentException">
+        ///     <paramref name="folderPath"/> is a zero-length string, contains only white space.\n
+        ///     -or-\n
+        ///     <paramref name="folderPath"/> contains a hidden path that starts with '.'.\n
+        ///     -or-\n
+        ///     <paramref name="folderPath"/> contains a directory containing the ".scan_ignore" file.
+        /// </exception>
+        public Task ScanFolderAsync(string folderPath, bool recursive)
+        {
+            return ScanFolderAsync(folderPath, recursive, CancellationToken.None);
+        }
+
+        /// <summary>
+        /// Requests to scan a folder, recursively.
+        /// </summary>
+        /// <remarks>
+        ///     If you want to access internal storage, you should add privilege http://tizen.org/privilege/mediastorage.\n
+        ///     If you want to access external storage, you should add privilege http://tizen.org/privilege/externalstorage.
+        /// </remarks>
+        /// <privilege>http://tizen.org/privilege/content.write</privilege>
+        /// <privilege>http://tizen.org/privilege/mediastorage</privilege>
+        /// <privilege>http://tizen.org/privilege/externalstorage</privilege>
+        /// <param name="folderPath">The path to scan.</param>
+        /// <param name="cancellationToken">The token to stop scanning.</param>
+        /// <remarks>Folders that contains a file named ".scan_ignore" will not be scanned.</remarks>
+        /// <returns>A task that represents the asynchronous scan operation.</returns>
+        /// <exception cref="InvalidOperationException">The database is not connected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="UnauthorizedAccessException">The caller has no required privilege.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="folderPath"/> is null.</exception>
+        /// <exception cref="ArgumentException">
+        ///     <paramref name="folderPath"/> is a zero-length string, contains only white space.\n
+        ///     -or-\n
+        ///     <paramref name="folderPath"/> contains a hidden path that starts with '.'.\n
+        ///     -or-\n
+        ///     <paramref name="folderPath"/> contains a directory containing the ".scan_ignore" file.
+        /// </exception>
+        public Task ScanFolderAsync(string folderPath, CancellationToken cancellationToken)
+        {
+            return ScanFolderAsync(folderPath, true, cancellationToken);
+        }
+
+        /// <summary>
+        /// Requests to scan a folder, recursively.
+        /// </summary>
+        /// <remarks>
+        ///     If you want to access internal storage, you should add privilege http://tizen.org/privilege/mediastorage.\n
+        ///     If you want to access external storage, you should add privilege http://tizen.org/privilege/externalstorage.
+        /// </remarks>
+        /// <privilege>http://tizen.org/privilege/content.write</privilege>
+        /// <privilege>http://tizen.org/privilege/mediastorage</privilege>
+        /// <privilege>http://tizen.org/privilege/externalstorage</privilege>
+        /// <param name="folderPath">The path to scan.</param>
+        /// <param name="recursive">The value indicating if the folder is to recursively scanned.</param>
+        /// <param name="cancellationToken">The token to stop scanning.</param>
+        /// <remarks>Folders that contains a file named ".scan_ignore" will not be scanned.</remarks>
+        /// <returns>A task that represents the asynchronous scan operation.</returns>
+        /// <exception cref="InvalidOperationException">The database is not connected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="UnauthorizedAccessException">The caller has no required privilege.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="folderPath"/> is null.</exception>
+        /// <exception cref="ArgumentException">
+        ///     <paramref name="folderPath"/> is a zero-length string, contains only white space.\n
+        ///     -or-\n
+        ///     <paramref name="folderPath"/> contains a hidden path that starts with '.'.\n
+        ///     -or-\n
+        ///     <paramref name="folderPath"/> contains a directory containing the ".scan_ignore" file.
+        /// </exception>
+        public Task ScanFolderAsync(string folderPath, bool recursive, CancellationToken cancellationToken)
+        {
+            ValidateState();
+
+            ValidationUtil.ValidateNotNullOrEmpty(folderPath, nameof(folderPath));
+
+            return cancellationToken.IsCancellationRequested ? Task.FromCanceled(cancellationToken) :
+                ScanFolderAsyncCore(folderPath, recursive, cancellationToken);
+        }
+
+        private async Task ScanFolderAsyncCore(string folderPath, bool recursive, CancellationToken cancellationToken)
+        {
+            var tcs = new TaskCompletionSource<bool>();
+
+            using (var cbKeeper = ObjectKeeper.Get(GetScanCompletedCallback(tcs)))
+            using (RegisterCancellationAction(tcs, folderPath, cancellationToken))
+            {
+
+                Interop.Content.ScanFolder(folderPath, recursive, cbKeeper.Target)
+                    .ThrowIfError("Failed to scan");
+
+                await tcs.Task;
+            }
+        }
+
+        private static Interop.Content.MediaScanCompletedCallback GetScanCompletedCallback(TaskCompletionSource<bool> tcs)
+        {
+            return (scanResult, _) =>
+            {
+                if (scanResult == MediaContentError.None)
+                {
+                    tcs.TrySetResult(true);
+                }
+                else
+                {
+                    tcs.TrySetException(scanResult.AsException("Failed to scan"));
+                }
+            };
+        }
+
+        private static IDisposable RegisterCancellationAction(TaskCompletionSource<bool> tcs,
+            string folderPath, CancellationToken cancellationToken)
+        {
+            if (cancellationToken.CanBeCanceled == false)
+            {
+                return null;
+            }
+
+            return cancellationToken.Register(() =>
+            {
+                if (tcs.Task.IsCompleted)
+                {
+                    return;
+                }
+
+                Interop.Content.CancelScanFolder(folderPath).ThrowIfError("Failed to cancel scanning");
+                tcs.TrySetCanceled();
+            });
+        }
+
+        internal bool IsConnected { get; set; }
+
+        internal void ValidateState()
+        {
+            ValidateNotDisposed();
+
+            if (IsConnected == false)
+            {
+                throw new InvalidOperationException("Database is not connected.");
+            }
+        }
+
+        private void ValidateNotDisposed()
+        {
+            if (IsDisposed)
+            {
+                throw new ObjectDisposedException(nameof(MediaDatabase));
+            }
+        }
+
+        #region IDisposable Support
+        private bool _disposed = false;
+
+        /// <summary>
+        /// Disposes of the resources (other than memory) used by the MediaDatabase.
+        /// </summary>
+        /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
+        protected virtual void Dispose(bool disposing)
+        {
+            if (!_disposed)
+            {
+                if (IsConnected)
+                {
+                    var disconnectResult = Interop.Content.Disconnect();
+
+                    if (disconnectResult != MediaContentError.None)
+                    {
+                        Log.Warn(nameof(MediaDatabase), $"Failed to disconnect {disconnectResult.ToString()}.");
+                    }
+                }
+
+                _disposed = true;
+            }
+        }
+
+        /// <summary>
+        /// Releases all resources.
+        /// </summary>
+        public void Dispose()
+        {
+            Dispose(true);
+        }
+
+        /// <summary>
+        /// Gets the value indicating whether the database has been disposed of.
+        /// </summary>
+        /// <value>true if the database has been disposed of; otherwise, false.</value>
+        public bool IsDisposed => _disposed;
+        #endregion
+
+    }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaDatabaseException.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaDatabaseException.cs
new file mode 100644 (file)
index 0000000..34723ba
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Content.MediaContent
+{
+    /// <summary>
+    /// Specifies database errors.
+    /// </summary>
+    public enum MediaDatabaseError
+    {
+        /// <summary>
+        /// Operation failed.
+        /// </summary>
+        OperationFailed,
+
+        /// <summary>
+        /// Operation failed because the database is busy.
+        /// </summary>
+        DatabaseBusy
+    }
+
+    /// <summary>
+    /// The exception that is thrown when an database operation failed.
+    /// </summary>
+    public class MediaDatabaseException : Exception
+    {
+        internal MediaDatabaseException(MediaDatabaseError error) : this(error, error.ToString())
+        {
+        }
+
+        internal MediaDatabaseException(MediaDatabaseError error, string message) : this(error, message, null)
+        {
+        }
+
+        internal MediaDatabaseException(MediaDatabaseError error, string message, Exception innerException) :
+            base(message, innerException)
+        {
+            Error = error;
+        }
+
+        /// <summary>
+        /// Gets the error that causes the exception.
+        /// </summary>
+        /// <value>The <see cref="MediaDatabaseError"/> that causes the exception.</value>
+        public MediaDatabaseError Error { get; }
+    }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaFace.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaFace.cs
deleted file mode 100755 (executable)
index 134ab1f..0000000
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
-* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
-*
-* Licensed under the Apache License, Version 2.0 (the License);
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an AS IS BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-
-
-using System;
-using System.Runtime.InteropServices;
-
-namespace Tizen.Content.MediaContent
-{
-    /// <summary>
-    /// The Media Face Information API provides functions to manage the face information in the image files.
-    /// </summary>
-    public class MediaFace : IDisposable
-    {
-        private IntPtr _faceHandle = IntPtr.Zero;
-        private bool _disposedValue = false;
-        internal IntPtr Handle
-        {
-            get
-            {
-                if (_faceHandle == IntPtr.Zero)
-                {
-                    throw new ObjectDisposedException(nameof(MediaFace));
-                }
-
-                return _faceHandle;
-            }
-        }
-
-
-        internal MediaFace(IntPtr handle)
-        {
-            _faceHandle = handle;
-        }
-
-        /// <summary>
-        /// Create Face for Given Image
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="image">
-        ///image item through which FaceRect has to be tagged.
-        ///</param>
-        ///<param name="rect">Position about the detacted face in the media</param>
-        internal MediaFace(MediaInformation image, FaceRect rect)
-        {
-            MediaContentValidator.ThrowIfError(
-                Interop.Face.Create(image.MediaId, out _faceHandle), "Failed to create MediaFace");
-
-            try
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.Face.SetFaceRect(Handle, rect.X, rect.Y, rect.Width, rect.Height), "Failed to set Rect to MediaFace");
-            }
-            catch (Exception)
-            {
-                Interop.Face.Destroy(_faceHandle);
-                throw;
-            }
-        }
-
-        ~MediaFace()
-        {
-            Dispose(false);
-        }
-
-        /// <summary>
-        /// The Media Face Information API provides functions to manage the face information in the image files.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public FaceRect Rect
-        {
-            get
-            {
-                int x;
-                int y;
-                int width;
-                int height;
-                MediaContentValidator.ThrowIfError(
-                    Interop.Face.GetFaceRect(Handle, out x, out y, out width, out height), "Failed to get Rect for the Face");
-
-                return new FaceRect(x, y, width, height);
-            }
-
-            set
-            {
-                FaceRect rect = (FaceRect)value;
-                MediaContentValidator.ThrowIfError(
-                    Interop.Face.SetFaceRect(Handle, rect.X, rect.Y, rect.Width, rect.Height), "Failed to set Rect for the Face");
-            }
-        }
-
-        /// <summary>
-        /// Face id.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string Id
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.Face.GetFaceId(Handle, out val), "Failed to get value");
-
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        /// <summary>
-        /// Media uuid from the face
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string MediaInformationId
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.Face.GetMediaId(Handle, out val), "Failed to get value");
-
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-        /// <summary>
-        /// Tag name for the MediaFace.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string Tag
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.Face.GetTag(Handle, out val), "Failed to get value");
-
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-
-            set
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.Face.SetTag(Handle, value), "Failed to set value");
-            }
-        }
-
-        /// <summary>
-        /// Orientation Value for the face
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public MediaContentOrientation Orientation
-        {
-            get
-            {
-                int orientation;
-                MediaContentValidator.ThrowIfError(
-                    Interop.Face.GetOrientation(Handle, out orientation), "Failed to value");
-
-                return (MediaContentOrientation)orientation;
-            }
-
-            set
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.Face.SetOrientation(Handle, (int)value), "Failed to set value");
-            }
-        }
-
-        /// <summary>
-        /// Dispose API for closing the internal resources.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public void Dispose()
-        {
-            Dispose(true);
-            GC.SuppressFinalize(this);
-        }
-
-        protected virtual void Dispose(bool disposing)
-        {
-            if (!_disposedValue)
-            {
-                if (_faceHandle != IntPtr.Zero)
-                {
-                    Interop.Face.Destroy(_faceHandle);
-                    _faceHandle = IntPtr.Zero;
-                }
-
-                _disposedValue = true;
-            }
-        }
-    }
-}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaFolder.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaFolder.cs
deleted file mode 100755 (executable)
index af120ca..0000000
+++ /dev/null
@@ -1,330 +0,0 @@
-/*
-* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
-*
-* Licensed under the Apache License, Version 2.0 (the License);
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an AS IS BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-
-
-using System;
-using System.Collections.Generic;
-using System.Runtime.InteropServices;
-using System.Threading.Tasks;
-
-namespace Tizen.Content.MediaContent
-{
-    /// <summary>
-    /// A Folder is used to organize media content files i.e. image, audio, video files, in the physical storage of the device.
-    /// The Media Folder API provides functions to get basic information about existing folders e.g. folder name, path and storage type.
-    /// It also provides functions to get information related to media items present in the folder.
-    /// </summary>
-    public class MediaFolder : ContentCollection
-    {
-        private IntPtr _folderHandle = IntPtr.Zero;
-        private bool _disposedValue = false;
-        internal IntPtr Handle
-        {
-            get
-            {
-                if (_folderHandle == IntPtr.Zero)
-                {
-                    throw new ObjectDisposedException(nameof(MediaFolder));
-                }
-
-                return _folderHandle;
-            }
-        }
-        /// <summary>
-        /// The ID of the media folder. For each MediaFolder this id is unique.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string Id
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.Folder.GetFolderId(Handle, out val), "Failed to get value");
-
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        /// <summary>
-        /// ParentId of the MediaFolder that is the ID of the upper media folder (parent folder).
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string ParentId
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.Folder.GetParentFolderId(Handle, out val), "Failed to get value");
-
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        /// <summary>
-        /// The path of the media folder
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string FolderPath
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.Folder.GetPath(Handle, out val), "Failed to get value");
-
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        /// <summary>
-        /// The name of the media folder
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string Name
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.Folder.GetName(Handle, out val), "Failed to get value");
-
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-
-            set
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.Folder.SetName(Handle, value), "Failed to set value");
-            }
-        }
-
-        /// <summary>
-        /// The storage type of the media folder.
-        /// Storage types give information about the location of storage like Internal memory, USB or External Storage etc...
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public ContentStorageType StorageType
-        {
-            get
-            {
-                ContentStorageType type;
-                MediaContentValidator.ThrowIfError(
-                    Interop.Folder.GetStorageType(Handle, out type), "Failed to get value");
-
-                return type;
-            }
-        }
-
-        /// <summary>
-        /// The storage id of the media folder
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string StorageId
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.Folder.GetStorageId(Handle, out val), "Failed to get value");
-
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        /// <summary>
-        /// The modified date of the media folder
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public DateTime ModifiedTime
-        {
-            get
-            {
-                DateTime date;
-                MediaContentValidator.ThrowIfError(
-                    Interop.Folder.GetModifiedTime(Handle, out date), "Failed to get value");
-
-                return date;
-            }
-        }
-
-        /// <summary>
-        /// The folder order value. Get/Set the folder viewing order.
-        /// Default Order value is zero.
-        /// If you set the order value for each folder, you can sort in ascending or descending order as the set order values using the filter.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public int Order
-        {
-            get
-            {
-                int order;
-                MediaContentValidator.ThrowIfError(
-                    Interop.Folder.GetOrder(Handle, out order), "Failed to get value");
-
-                return order;
-            }
-
-            set
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.Folder.SetOrder(Handle, value), "Failed to set value");
-            }
-        }
-
-        internal MediaFolder(IntPtr handle)
-        {
-            _folderHandle = handle;
-        }
-
-        /// <summary>
-        /// Gets the count of media files for the passed filter in the given folder from the media database.
-        /// If NULL is passed to the filter, no filtering is applied.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="filter">ContentFilter used to match media content from teh media database.</param>
-        /// <returns>The number of media contents matching the filter passed</returns>
-        public override int GetMediaInformationCount(ContentFilter filter)
-        {
-            int mediaCount;
-            IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
-            MediaContentValidator.ThrowIfError(
-                Interop.Folder.GetMediaCountFromDb(Id, handle, out mediaCount), "Failed to get count");
-
-            return mediaCount;
-        }
-
-        ~MediaFolder()
-        {
-            Dispose(false);
-        }
-
-        public override void Dispose()
-        {
-            Dispose(true);
-            GC.SuppressFinalize(this);
-        }
-
-        protected virtual void Dispose(bool disposing)
-        {
-            if (!_disposedValue)
-            {
-                if (_folderHandle != IntPtr.Zero)
-                {
-                    Interop.Folder.Destroy(_folderHandle);
-                    _folderHandle = IntPtr.Zero;
-                }
-
-                _disposedValue = true;
-            }
-        }
-
-        /// <summary>
-        /// Iterates through the media files with an filter in the given folder from the media database.
-        /// This function gets all media files associated with the given folder and meeting desired filter option.
-        /// If NULL is passed to the filter, no filtering is applied.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="filter">ContentFilter used to match media content from the media database.</param>
-        /// <returns>List of content media items matching the passed filter</returns>
-        public override IEnumerable<MediaInformation> GetMediaInformations(ContentFilter filter)
-        {
-            List<MediaInformation> mediaContents = new List<MediaInformation>();
-            IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
-
-            Interop.Folder.MediaInfoCallback callback = (IntPtr mediaHandle, IntPtr data) =>
-            {
-                Interop.MediaInformation.SafeMediaInformationHandle newHandle;
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.Clone(out newHandle, mediaHandle), "Failed to clone");
-
-                MediaContentType type;
-                Interop.MediaInformation.GetMediaType(newHandle, out type);
-                if (type == MediaContentType.Image)
-                {
-                    Interop.ImageInformation.SafeImageInformationHandle imageInfo;
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.GetImage(mediaHandle, out imageInfo), "Failed to get image information");
-
-                    mediaContents.Add(new ImageInformation(imageInfo, newHandle));
-                }
-                else if ((type == MediaContentType.Music) || (type == MediaContentType.Sound))
-                {
-                    Interop.AudioInformation.SafeAudioInformationHandle audioInfo;
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.GetAudio(mediaHandle, out audioInfo), "Failed to get audio information");
-
-                    mediaContents.Add(new AudioInformation(audioInfo, newHandle));
-                }
-                else if (type == MediaContentType.Video)
-                {
-                    Interop.VideoInformation.SafeVideoInformationHandle videoInfo;
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.GetVideo(mediaHandle, out videoInfo), "Failed to get video information");
-
-                    mediaContents.Add(new VideoInformation(videoInfo, newHandle));
-                }
-                else if (type == MediaContentType.Others)
-                {
-                    mediaContents.Add(new MediaInformation(newHandle));
-                }
-
-                return true;
-            };
-            MediaContentValidator.ThrowIfError(
-                Interop.Folder.ForeachMediaFromDb(Id, handle, callback, IntPtr.Zero), "Failed to get information");
-
-            return mediaContents;
-        }
-    }
-}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaInfo.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaInfo.cs
new file mode 100644 (file)
index 0000000..0072d38
--- /dev/null
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Content.MediaContent
+{
+
+    /// <summary>
+    /// Represents the information related to the media stored.
+    /// </summary>
+    /// <seealso cref="MediaInfoCommand"/>
+    /// <seealso cref="MediaInfoUpdateValues"/>
+    public class MediaInfo
+    {
+        internal MediaInfo(Interop.MediaInfoHandle handle)
+        {
+            Id = InteropHelper.GetString(handle, Interop.MediaInfo.GetMediaId);
+
+            Path = InteropHelper.GetString(handle, Interop.MediaInfo.GetFilePath);
+            DisplayName = InteropHelper.GetString(handle, Interop.MediaInfo.GetDisplayName);
+
+            MediaType = InteropHelper.GetValue<MediaType>(handle, Interop.MediaInfo.GetMediaType);
+
+            MimeType = InteropHelper.GetString(handle, Interop.MediaInfo.GetMimeType);
+
+            FileSize = InteropHelper.GetValue<long>(handle, Interop.MediaInfo.GetSize);
+
+            DateAdded = InteropHelper.GetDateTime(handle, Interop.MediaInfo.GetAddedTime);
+            DateModified = InteropHelper.GetDateTime(handle, Interop.MediaInfo.GetModifiedTime);
+            Timeline = InteropHelper.GetDateTime(handle, Interop.MediaInfo.GetTimeline);
+
+            ThumbnailPath = InteropHelper.GetString(handle, Interop.MediaInfo.GetThumbnailPath);
+            Description = InteropHelper.GetString(handle, Interop.MediaInfo.GetDescription);
+
+            Longitude = InteropHelper.GetValue<double>(handle, Interop.MediaInfo.GetLongitude);
+            Latitude = InteropHelper.GetValue<double>(handle, Interop.MediaInfo.GetLatitude);
+            Altitude = InteropHelper.GetValue<double>(handle, Interop.MediaInfo.GetAltitude);
+
+            Weather = InteropHelper.GetString(handle, Interop.MediaInfo.GetWeather);
+            Rating = InteropHelper.GetValue<int>(handle, Interop.MediaInfo.GetRating);
+            IsFavorite = InteropHelper.GetValue<bool>(handle, Interop.MediaInfo.GetFavorite);
+            Provider = InteropHelper.GetString(handle, Interop.MediaInfo.GetProvider);
+            Title = InteropHelper.GetString(handle, Interop.MediaInfo.GetTitle);
+            Category = InteropHelper.GetString(handle, Interop.MediaInfo.GetCategory);
+            LocationTag = InteropHelper.GetString(handle, Interop.MediaInfo.GetLocationTag);
+            AgeRating = InteropHelper.GetString(handle, Interop.MediaInfo.GetAgeRating);
+            StorageId = InteropHelper.GetString(handle, Interop.MediaInfo.GetStorageId);
+            IsDrm = InteropHelper.GetValue<bool>(handle, Interop.MediaInfo.IsDrm);
+
+            StorageType = InteropHelper.GetValue<StorageType>(handle, Interop.MediaInfo.GetStorageType);
+        }
+
+        /// <summary>
+        /// Gets the id of media.
+        /// </summary>
+        /// <value>The unique id of media.</value>
+        public string Id { get; }
+
+        /// <summary>
+        /// Gets the path to media.
+        /// </summary>
+        /// <value>The full path of the media file.</value>
+        public string Path { get; }
+
+        /// <summary>
+        /// Gets the name of media.
+        /// </summary>
+        /// <value>The base name of the media file.</value>
+        public string DisplayName { get; }
+
+        /// <summary>
+        /// Gets the <see cref="MediaType"/> of media.
+        /// </summary>
+        /// <value>The <see cref="MediaType"/> of media.</value>
+        public MediaType MediaType { get; }
+
+        /// <summary>
+        /// Gets the mime type from media.
+        /// </summary>
+        /// <value>The mime type of media.</value>
+        public string MimeType { get; }
+
+        /// <summary>
+        /// Gets the file size of media in bytes.
+        /// </summary>
+        /// <value>The file size of media in bytes.</value>
+        public long FileSize { get; }
+
+        /// <summary>
+        /// Gets the date of addition of media.
+        /// </summary>
+        /// <value>The date of addition of media.</value>
+        public DateTimeOffset DateAdded { get; }
+
+        /// <summary>
+        /// Gets the date of modification of media.
+        /// </summary>
+        /// <value>The date of modification of media.</value>
+        public DateTimeOffset DateModified { get; }
+
+        /// <summary>
+        /// Gets the timeline of media.
+        /// </summary>
+        /// <value>
+        /// The creation date if the file has the creation information (like recorded date or Image creation date),
+        /// otherwise the modified date.
+        /// </value>
+        public DateTimeOffset Timeline { get; }
+
+        /// <summary>
+        /// Gets the thumbnail of media.
+        /// </summary>
+        /// <value>The thumbnail path of media.</value>
+        public string ThumbnailPath { get; }
+
+        /// <summary>
+        /// Gets the description of media.
+        /// </summary>
+        /// <value>The description from the metadata.</value>
+        public string Description { get; }
+
+        /// <summary>
+        /// Gets the longitude of media.
+        /// </summary>
+        /// <value>The longitude.</value>
+        public double Longitude { get; }
+
+        /// <summary>
+        /// Gets the latitude of media.
+        /// </summary>
+        /// <value>The latitude.</value>
+        public double Latitude { get; }
+
+        /// <summary>
+        /// Gets the altitude of media.
+        /// </summary>
+        /// <value>The altitude.</value>
+        public double Altitude { get; }
+
+        /// <summary>
+        /// Gets the weather information of media.
+        /// </summary>
+        /// <value>The weather information which a user sets.</value>
+        public string Weather { get; }
+
+        /// <summary>
+        /// Gets the rating of media.
+        /// </summary>
+        /// <value>The rating from the metadata.</value>
+        public int Rating { get; }
+
+        /// <summary>
+        /// Gets the favorite status of media.
+        /// </summary>
+        /// <value>true if media is set as favorite, otherwise false.</value>
+        public bool IsFavorite { get; }
+
+        /// <summary>
+        /// Gets the provider of media.
+        /// </summary>
+        /// <value>The provider which a user sets.</value>
+        public string Provider { get; }
+
+        /// <summary>
+        /// Gets the title of media.
+        /// </summary>
+        /// <value>The title of media.</value>
+        public string Title { get; }
+
+        /// <summary>
+        /// Gets the category of media.
+        /// </summary>
+        /// <value>The category which a user sets.</value>
+        public string Category { get; }
+
+        /// <summary>
+        /// Gets the location tag of media.
+        /// </summary>
+        /// <value>The location tag which a user sets.</value>
+        public string LocationTag { get; }
+
+        /// <summary>
+        /// Gets the age rating of media.
+        /// </summary>
+        /// <value>The age rating which a user sets.</value>
+        public string AgeRating { get; }
+
+        /// <summary>
+        /// Gets the storage id of the storage that the media is stored on.
+        /// </summary>
+        /// <value>The storage id of the storage that the media is stored on.</value>
+        public string StorageId { get; }
+
+        /// <summary>
+        /// Gets the value indicating whether the media is DRM-protected.
+        /// </summary>
+        /// <value>A bool value indicating whether the media is DRM-protected.</value>
+        public bool IsDrm { get; }
+
+        /// <summary>
+        /// Gets the storage type of the storage that the media is stored on.
+        /// </summary>
+        /// <value>The storage type of the storage that the media is stored on.</value>
+        public StorageType StorageType { get; }
+
+        /// <summary>
+        /// Returns a string representation of the media info.
+        /// </summary>
+        /// <returns>A string representation of the current media info.</returns>
+        public override string ToString() => $"Id={Id}, Path={Path}, MediaType={MediaType}";
+
+        internal static MediaInfo FromHandle(Interop.MediaInfoHandle handle)
+        {
+            if (handle == null || handle.IsInvalid)
+            {
+                return null;
+            }
+
+            var type = InteropHelper.GetValue<MediaType>(handle, Interop.MediaInfo.GetMediaType);
+
+            switch (type)
+            {
+                case MediaType.Image:
+                    return new ImageInfo(handle);
+
+                case MediaType.Music:
+                case MediaType.Sound:
+                    return new AudioInfo(handle);
+
+                case MediaType.Video:
+                    return new VideoInfo(handle);
+            }
+
+            return new MediaInfo(handle);
+        }
+
+        internal static MediaInfo FromHandle(IntPtr handle)
+        {
+            var safeHandle = new Interop.MediaInfoHandle(handle);
+            try
+            {
+                return FromHandle(safeHandle);
+            }
+            finally
+            {
+                safeHandle.SetHandleAsInvalid();
+            }
+        }
+    }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaInfoColumnKey.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaInfoColumnKey.cs
new file mode 100644 (file)
index 0000000..8c6d799
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Content.MediaContent
+{
+    /// <summary>
+    /// Specifies group keys for <see cref="MediaInfo"/>.
+    /// </summary>
+    public enum MediaInfoColumnKey
+    {
+        /// <summary>
+        /// Display name.
+        /// </summary>
+        DisplayName,
+        /// <summary>
+        /// Media type.
+        /// </summary>
+        Type,
+        /// <summary>
+        /// Mime type.
+        /// </summary>
+        MimeType,
+        /// <summary>
+        /// File size.
+        /// </summary>
+        Size,
+        /// <summary>
+        /// Date added.
+        /// </summary>
+        DateAdded,
+        /// <summary>
+        /// Date modified.
+        /// </summary>
+        DateModified,
+        /// <summary>
+        /// Content title.
+        /// </summary>
+        Title,
+        /// <summary>
+        /// Artist.
+        /// </summary>
+        Artist,
+        /// <summary>
+        /// Album artist.
+        /// </summary>
+        AlbumArtist,
+        /// <summary>
+        /// Genre.
+        /// </summary>
+        Genre,
+        /// <summary>
+        /// Composer.
+        /// </summary>
+        Composer = 10,
+        /// <summary>
+        /// Year.
+        /// </summary>
+        Year,
+        /// <summary>
+        /// Date recorded.
+        /// </summary>
+        DateRecorded,
+        /// <summary>
+        /// Copyright.
+        /// </summary>
+        Copyright,
+        /// <summary>
+        /// Track number.
+        /// </summary>
+        TrackNumber,
+        /// <summary>
+        /// Description.
+        /// </summary>
+        Description,
+        /// <summary>
+        /// Longitude.
+        /// </summary>
+        Longitude,
+        /// <summary>
+        /// Latitude.
+        /// </summary>
+        Latitude,
+        /// <summary>
+        /// Altitude.
+        /// </summary>
+        Altitude,
+        /// <summary>
+        /// Burst shot.
+        /// </summary>
+        BurstImage,
+        /// <summary>
+        /// Rating.
+        /// </summary>
+        Rating = 20,
+
+        /// <summary>
+        /// Provider.
+        /// </summary>
+        Provider = 22,
+
+        /// <summary>
+        /// Category.
+        /// </summary>
+        Category = 24,
+        /// <summary>
+        /// Location tag.
+        /// </summary>
+        LocationTag,
+        /// <summary>
+        /// Age rating.
+        /// </summary>
+        AgeRating,
+        /// <summary>
+        /// Weather.
+        /// </summary>
+        Weather = 28
+    }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaInfoCommand.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaInfoCommand.cs
new file mode 100644 (file)
index 0000000..f74d8b1
--- /dev/null
@@ -0,0 +1,1129 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Tizen.Content.MediaContent
+{
+    /// <summary>
+    /// Provides commands to manage media info and query related items in the database.
+    /// </summary>
+    public class MediaInfoCommand : MediaCommand
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="FolderCommand"/> class with the specified <see cref="MediaDatabase"/>.
+        /// </summary>
+        /// <param name="database">A <see cref="MediaDatabase"/> that the commands run on.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="database"/> is null.</exception>
+        /// <exception cref="ObjectDisposedException"><paramref name="database"/> has already been disposed of.</exception>
+        public MediaInfoCommand(MediaDatabase database) : base(database)
+        {
+        }
+
+        /// <summary>
+        /// Retrieves the number of the bookmarks added to the media.
+        /// </summary>
+        /// <param name="mediaId">The media id to count bookmarks added to the media.</param>
+        /// <returns>The number of bookmarks.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="mediaId"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="mediaId"/> is a zero-length string, contains only white space.</exception>
+        public int CountBookmark(string mediaId)
+        {
+            return CountBookmark(mediaId, null);
+        }
+
+        /// <summary>
+        /// Retrieves the number of the bookmarks added to the media with <see cref="CountArguments"/>.
+        /// </summary>
+        /// <param name="mediaId">The media id to count bookmarks added to the media.</param>
+        /// <param name="arguments">The criteria to use to filter. This value can be null.</param>
+        /// <returns>The number of bookmarks.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="mediaId"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="mediaId"/> is a zero-length string, contains only white space.</exception>
+        public int CountBookmark(string mediaId, CountArguments arguments)
+        {
+            ValidateDatabase();
+
+            ValidationUtil.ValidateNotNullOrEmpty(mediaId, nameof(mediaId));
+
+            return CommandHelper.Count(Interop.MediaInfo.GetBookmarkCount, mediaId, arguments);
+        }
+
+        /// <summary>
+        /// Retrieves the bookmarks added to the media.
+        /// </summary>
+        /// <param name="mediaId">The media id to select bookmarks added to the media.</param>
+        /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="mediaId"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="mediaId"/> is a zero-length string, contains only white space.</exception>
+        public MediaDataReader<Bookmark> SelectBookmark(string mediaId)
+        {
+            return SelectBookmark(mediaId, null);
+        }
+
+        /// <summary>
+        /// Retrieves the bookmarks added to the media with <see cref="SelectArguments"/>.
+        /// </summary>
+        /// <param name="mediaId">The media id to select bookmarks added to the media.</param>
+        /// <param name="filter">The criteria to use to filter. This value can be null.</param>
+        /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="mediaId"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="mediaId"/> is a zero-length string, contains only white space.</exception>
+        public MediaDataReader<Bookmark> SelectBookmark(string mediaId, SelectArguments filter)
+        {
+            ValidateDatabase();
+
+            ValidationUtil.ValidateNotNullOrEmpty(mediaId, nameof(mediaId));
+
+            return CommandHelper.SelectMembers(mediaId, filter, Interop.MediaInfo.ForeachBookmarks,
+                Bookmark.FromHandle);
+        }
+
+
+        /// <summary>
+        /// Retrieves the number of the face info added to or detected from the media.
+        /// </summary>
+        /// <param name="mediaId">The media id to count face info added to the media.</param>
+        /// <returns>The number of face info.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="mediaId"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="mediaId"/> is a zero-length string, contains only white space.</exception>
+        public int CountFaceInfo(string mediaId)
+        {
+            return CountFaceInfo(mediaId, null);
+        }
+
+        /// <summary>
+        /// Retrieves the number of the face info added to or detected from the media with filter.
+        /// </summary>
+        /// <param name="mediaId">The media id to count face info added to the media.</param>
+        /// <param name="arguments">The criteria to use to filter. This value can be null.</param>
+        /// <returns>The number of face info.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="mediaId"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="mediaId"/> is a zero-length string, contains only white space.</exception>
+        public int CountFaceInfo(string mediaId, CountArguments arguments)
+        {
+            ValidateDatabase();
+
+            ValidationUtil.ValidateNotNullOrEmpty(mediaId, nameof(mediaId));
+
+            return CommandHelper.Count(Interop.MediaInfo.GetFaceCount, mediaId, arguments);
+        }
+
+        /// <summary>
+        /// Retrieves the face info added to or detected from the media.
+        /// </summary>
+        /// <param name="mediaId">The media id to select face info added to the media.</param>
+        /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="mediaId"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="mediaId"/> is a zero-length string, contains only white space.</exception>
+        public MediaDataReader<FaceInfo> SelectFaceInfo(string mediaId)
+        {
+            return SelectFaceInfo(mediaId, null);
+        }
+
+        /// <summary>
+        /// Retrieves the face info added to or detected from the media with <see cref="SelectArguments"/>.
+        /// </summary>
+        /// <param name="mediaId">The media id to select face info added to the media.</param>
+        /// <param name="arguments">The criteria to use to filter. This value can be null.</param>
+        /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="mediaId"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="mediaId"/> is a zero-length string, contains only white space.</exception>
+        public MediaDataReader<FaceInfo> SelectFaceInfo(string mediaId, SelectArguments arguments)
+        {
+            ValidateDatabase();
+
+            ValidationUtil.ValidateNotNullOrEmpty(mediaId, nameof(mediaId));
+
+            return CommandHelper.SelectMembers(mediaId, arguments, Interop.MediaInfo.ForeachFaces,
+                FaceInfo.FromHandle);
+        }
+
+        /// <summary>
+        /// Retrieves the number of tags that the media has.
+        /// </summary>
+        /// <returns>The number of tags.</returns>
+        /// <param name="mediaId">The media id to count tags added to the media.</param>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="mediaId"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="mediaId"/> is a zero-length string, contains only white space.</exception>
+        public int CountTag(string mediaId)
+        {
+            return CountTag(mediaId, null);
+        }
+
+        /// <summary>
+        /// Retrieves the number of tags that the media has with <see cref="CountArguments"/>.
+        /// </summary>
+        /// <param name="mediaId">The media id to count tags added to the media.</param>
+        /// <param name="arguments">The criteria to use to filter. This value can be null.</param>
+        /// <returns>The number of tags.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="mediaId"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="mediaId"/> is a zero-length string, contains only white space.</exception>
+        public int CountTag(string mediaId, CountArguments arguments)
+        {
+            ValidateDatabase();
+
+            ValidationUtil.ValidateNotNullOrEmpty(mediaId, nameof(mediaId));
+
+            return CommandHelper.Count(Interop.MediaInfo.GetTagCount, mediaId, arguments);
+        }
+
+        /// <summary>
+        /// Retrieves the tags that the media has.
+        /// </summary>
+        /// <param name="mediaId">The media id to select tags added to the media.</param>
+        /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="mediaId"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="mediaId"/> is a zero-length string, contains only white space.</exception>
+        public MediaDataReader<Tag> SelectTag(string mediaId)
+        {
+            return SelectTag(mediaId, null);
+        }
+
+        /// <summary>
+        /// Retrieves the tags that the media has with <see cref="SelectArguments"/>.
+        /// </summary>
+        /// <param name="mediaId">The media id to select tags added to the media.</param>
+        /// <param name="filter">The criteria to use to filter. This value can be null.</param>
+        /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="mediaId"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="mediaId"/> is a zero-length string, contains only white space.</exception>
+        public MediaDataReader<Tag> SelectTag(string mediaId, SelectArguments filter)
+        {
+            ValidateDatabase();
+
+            ValidationUtil.ValidateNotNullOrEmpty(mediaId, nameof(mediaId));
+
+            return CommandHelper.SelectMembers(mediaId, filter, Interop.MediaInfo.ForeachTags,
+                Tag.FromHandle);
+        }
+
+
+        /// <summary>
+        /// Retrieves the number of the media info.
+        /// </summary>
+        /// <returns>The number of media info.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        public int CountMedia()
+        {
+            return CountMedia(null);
+        }
+
+        /// <summary>
+        /// Retrieves the number of the media info with <see cref="SelectArguments"/>.
+        /// </summary>
+        /// <param name="arguments">The criteria to use to filter. This value can be null.</param>
+        /// <returns>The number of media info.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        public int CountMedia(CountArguments arguments)
+        {
+            ValidateDatabase();
+
+            return CommandHelper.Count(Interop.MediaInfo.GetMediaCount, arguments);
+        }
+
+        /// <summary>
+        /// Retrieves the media.
+        /// </summary>
+        /// <param name="mediaId">The media id to retrieve.</param>
+        /// <returns>The <see cref="MediaInfo"/> instance if the matched record was found in the database, otherwise null.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="mediaId"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="mediaId"/> is a zero-length string, contains only white space.</exception>
+        public MediaInfo SelectMedia(string mediaId)
+        {
+            ValidateDatabase();
+
+            ValidationUtil.ValidateNotNullOrEmpty(mediaId, nameof(mediaId));
+
+            Interop.MediaInfo.GetMediaFromDB(mediaId, out var handle).Ignore(MediaContentError.InvalidParameter).
+                ThrowIfError("Failed to query");
+
+            try
+            {
+                return MediaInfo.FromHandle(handle);
+            }
+            finally
+            {
+                handle.Dispose();
+            }
+        }
+
+        /// <summary>
+        /// Retrieves the number of values grouped by the specified column with <see cref="SelectArguments"/>.
+        /// </summary>
+        /// <param name="columnKey">The column key.</param>
+        /// <returns>The number of groups.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentException"><paramref name="columnKey"/> is invalid.</exception>
+        public int CountGroupBy(MediaInfoColumnKey columnKey)
+        {
+            return CountGroupBy(columnKey, null);
+        }
+
+        /// <summary>
+        /// Retrieves the number of values grouped by the specified column with <see cref="SelectArguments"/>.
+        /// </summary>
+        /// <param name="columnKey">The column key.</param>
+        /// <param name="arguments">The criteria to use to filter. This value can be null.</param>
+        /// <returns>The number of groups.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentException"><paramref name="columnKey"/> is invalid.</exception>
+        public int CountGroupBy(MediaInfoColumnKey columnKey, CountArguments arguments)
+        {
+            ValidateDatabase();
+
+            ValidationUtil.ValidateEnum(typeof(MediaInfoColumnKey), columnKey, nameof(columnKey));
+
+            using (var filter = QueryArguments.ToNativeHandle(arguments))
+            {
+                Interop.Group.GetGroupCount(filter, columnKey, out var count).ThrowIfError("Failed to query count");
+                return count;
+            }
+        }
+
+        /// <summary>
+        /// Retrieves the group values of the specified column.
+        /// </summary>
+        /// <param name="columnKey">The column key.</param>
+        /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentException"><paramref name="columnKey"/> is invalid.</exception>
+        public MediaDataReader<string> SelectGroupBy(MediaInfoColumnKey columnKey)
+        {
+            return SelectGroupBy(columnKey, null);
+        }
+
+        /// <summary>
+        /// Retrieves the group values of the specified column. with <see cref="SelectArguments"/>.
+        /// </summary>
+        /// <param name="columnKey">The column key.</param>
+        /// <param name="arguments">The criteria to use to filter. This value can be null.</param>
+        /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentException"><paramref name="columnKey"/> is invalid.</exception>
+        public MediaDataReader<string> SelectGroupBy(MediaInfoColumnKey columnKey, SelectArguments arguments)
+        {
+            ValidateDatabase();
+
+            ValidationUtil.ValidateEnum(typeof(MediaInfoColumnKey), columnKey, nameof(columnKey));
+
+            List<string> list = new List<string>();
+
+            using (var filter = QueryArguments.ToNativeHandle(arguments))
+            {
+                Interop.Group.ForeachGroup(filter, columnKey, (name, _) =>
+                {
+                    list.Add(name);
+
+                    return true;
+                }).ThrowIfError("Failed to query");
+
+                return new MediaDataReader<string>(list);
+            }
+        }
+
+        /// <summary>
+        /// Retrieves all the media.
+        /// </summary>
+        /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        public MediaDataReader<MediaInfo> SelectMedia()
+        {
+            return SelectMedia(arguments: null);
+        }
+
+        /// <summary>
+        /// Retrieves the media with <see cref="SelectArguments"/>.
+        /// </summary>
+        /// <param name="arguments">The criteria to use to filter. This value can be null.</param>
+        /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        public MediaDataReader<MediaInfo> SelectMedia(SelectArguments arguments)
+        {
+            ValidateDatabase();
+
+            return new MediaDataReader<MediaInfo>(QueryMedia(arguments));
+        }
+
+        private static List<MediaInfo> QueryMedia(SelectArguments arguments)
+        {
+            using (var filter = QueryArguments.ToNativeHandle(arguments))
+            {
+                List<MediaInfo> list = new List<MediaInfo>();
+
+                Exception caught = null;
+
+                Interop.MediaInfo.ForeachMedia(filter, (handle, _) =>
+                {
+                    try
+                    {
+                        list.Add(MediaInfo.FromHandle(handle));
+                        return true;
+                    }
+                    catch (Exception e)
+                    {
+                        caught = e;
+                        return false;
+                    }
+                });
+
+                if (caught != null)
+                {
+                    throw caught;
+                }
+
+                return list;
+            }
+        }
+
+        /// <summary>
+        /// Deletes a media from the database.
+        /// </summary>
+        /// <privilege>http://tizen.org/privilege/content.write</privilege>
+        /// <param name="mediaId">The media id to delete.</param>
+        /// <returns>true if the matched record was found and deleted, otherwise false.</returns>
+        /// <remarks><see cref="MediaDatabase.ScanFile(string)"/> or <see cref="MediaDatabase.ScanFolderAsync(string)"/> can be used instead.</remarks>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="mediaId"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="mediaId"/> is a zero-length string, contains only white space.</exception>
+        /// <exception cref="UnauthorizedAccessException">The caller has no required privilege.</exception>
+        public bool Delete(string mediaId)
+        {
+            ValidateDatabase();
+
+            ValidationUtil.ValidateNotNullOrEmpty(mediaId, nameof(mediaId));
+
+            if (CommandHelper.Count(
+                Interop.MediaInfo.GetMediaCount, $"{MediaInfoColumns.Id}='{mediaId}'") == 0)
+            {
+                return false;
+            }
+
+            CommandHelper.Delete(Interop.MediaInfo.Delete, mediaId);
+            return true;
+        }
+
+        /// <summary>
+        /// Adds media to the database.
+        /// </summary>
+        /// <param name="path">The file path to add.</param>
+        /// <returns>The <see cref="MediaInfo"/> instance that contains the record information in the database.</returns>
+        /// <remarks>
+        ///     If the media already exists in the database, it returns existing information.\n
+        ///     \n
+        ///     <see cref="MediaDatabase.ScanFile(string)"/> or <see cref="MediaDatabase.ScanFolderAsync(string)"/> can be used instead.\n
+        ///     \n
+        ///     If you want to access internal storage, you should add privilege http://tizen.org/privilege/mediastorage.\n
+        ///     If you want to access external storage, you should add privilege http://tizen.org/privilege/externalstorage.
+        /// </remarks>
+        /// <privilege>http://tizen.org/privilege/content.write</privilege>
+        /// <privilege>http://tizen.org/privilege/mediastorage</privilege>
+        /// <privilege>http://tizen.org/privilege/externalstorage</privilege>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
+        /// <exception cref="ArgumentException">
+        ///     <paramref name="path"/> is a zero-length string, contains only white space.\n
+        ///     -or-\n
+        ///     <paramref name="path"/> contains a hidden path that starts with '.'.\n
+        ///     -or-\n
+        ///     <paramref name="path"/> contains a directory containing the ".scan_ignore" file.
+        /// </exception>
+        /// <exception cref="FileNotFoundException"><paramref name="path"/> does not exists.</exception>
+        /// <exception cref="UnauthorizedAccessException">The caller has no required privilege.</exception>
+        public MediaInfo Add(string path)
+        {
+            ValidateDatabase();
+
+            ValidationUtil.ValidateNotNullOrEmpty(path, nameof(path));
+
+            if (File.Exists(path) == false)
+            {
+                throw new FileNotFoundException("destination is not valid path.", path);
+            }
+
+            if (File.GetAttributes(path).HasFlag(FileAttributes.Hidden))
+            {
+                throw new ArgumentException($"{nameof(path)} contains a hidden path.", nameof(path));
+            }
+
+            Interop.MediaInfoHandle handle = null;
+
+            try
+            {
+                Interop.MediaInfo.Insert(path, out handle).ThrowIfError("Failed to insert");
+
+                return MediaInfo.FromHandle(handle);
+            }
+            finally
+            {
+                if (handle != null)
+                {
+                    handle.Dispose();
+                }
+            }
+        }
+
+        private static void ValidatePaths(IEnumerable<string> paths)
+        {
+            if (paths == null)
+            {
+                throw new ArgumentNullException(nameof(paths));
+            }
+
+            if (paths.Count() > 300)
+            {
+                throw new ArgumentException("Too many paths to add.");
+            }
+
+            foreach (var path in paths)
+            {
+                if (path == null)
+                {
+                    throw new ArgumentException($"{nameof(paths)} contains null.", nameof(paths));
+                }
+
+                if (File.Exists(path) == false)
+                {
+                    throw new FileNotFoundException($"{nameof(paths)} contains a path that does not exist. Path={path}.", path);
+                }
+            }
+
+        }
+
+        /// <summary>
+        /// Adds media files into the media database.
+        /// </summary>
+        /// <remarks>
+        ///     The paths that already exist in the database will be ignored.\n
+        ///     At most 300 items can be added at once.\n
+        ///     \n
+        ///     If you want to access internal storage, you should add privilege http://tizen.org/privilege/mediastorage.\n
+        ///     If you want to access external storage, you should add privilege http://tizen.org/privilege/externalstorage.
+        /// </remarks>
+        /// <privilege>http://tizen.org/privilege/content.write</privilege>
+        /// <privilege>http://tizen.org/privilege/mediastorage</privilege>
+        /// <privilege>http://tizen.org/privilege/externalstorage</privilege>
+        /// <param name="paths">The paths of the media files to add.</param>
+        /// <returns>A task that represents the asynchronous add operation.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="paths"/> is null.</exception>
+        /// <exception cref="ArgumentException">
+        ///     <paramref name="paths"/> contains null.\n
+        ///     -or-\n
+        ///     <paramref name="paths"/> contains invalid path.\n
+        ///     -or-\n
+        ///     The number of <paramref name="paths"/> is 300 or more items.
+        /// </exception>
+        /// <exception cref="FileNotFoundException"><paramref name="paths"/> contains a path that does not exist.</exception>
+        /// <exception cref="UnauthorizedAccessException">The caller has no required privilege.</exception>
+        public async Task AddAsync(IEnumerable<string> paths)
+        {
+            ValidateDatabase();
+
+            ValidatePaths(paths);
+
+            var pathArray = paths.ToArray();
+            var tcs = new TaskCompletionSource<bool>();
+
+            Interop.MediaInfo.InsertCompletedCallback callback = (error, _) =>
+            {
+                if (error == MediaContentError.None)
+                {
+                    tcs.TrySetResult(true);
+                }
+                else
+                {
+                    tcs.TrySetException(error.AsException("Failed to add"));
+                }
+            };
+
+            using (ObjectKeeper.Get(callback))
+            {
+                Interop.MediaInfo.BatchInsert(pathArray, pathArray.Length, callback).ThrowIfError("Failed to add");
+
+                await tcs.Task;
+            }
+        }
+
+        /// <summary>
+        /// Adds burst shot images into the media database.
+        /// </summary>
+        /// <param name="paths">The paths of the burst shot images to add.</param>
+        /// <returns>A task that represents the asynchronous add operation.</returns>
+        /// <remarks>
+        ///     The paths that already exist in the database.\n
+        ///     At most 300 items can be added at once.
+        ///     \n
+        ///     If you want to access internal storage, you should add privilege http://tizen.org/privilege/mediastorage.\n
+        ///     If you want to access external storage, you should add privilege http://tizen.org/privilege/externalstorage.
+        /// </remarks>
+        /// <privilege>http://tizen.org/privilege/content.write</privilege>
+        /// <privilege>http://tizen.org/privilege/mediastorage</privilege>
+        /// <privilege>http://tizen.org/privilege/externalstorage</privilege>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="paths"/> is null.</exception>
+        /// <exception cref="ArgumentException">
+        ///     <paramref name="paths"/> contains null.\n
+        ///     -or-\n
+        ///     <paramref name="paths"/> contains invalid path.\n
+        ///     -or-\n
+        ///     The number of <paramref name="paths"/> is 300 or more items.
+        /// </exception>
+        /// <exception cref="FileNotFoundException"><paramref name="paths"/> contains a path that does not exist.</exception>
+        /// <exception cref="UnauthorizedAccessException">The caller has no required privilege.</exception>
+        public async Task AddBurstShotImagesAsync(IEnumerable<string> paths)
+        {
+            ValidateDatabase();
+
+            ValidatePaths(paths);
+
+            var tcs = new TaskCompletionSource<bool>();
+            string[] pathArray = paths.ToArray();
+
+            Interop.MediaInfo.InsertBurstShotCompletedCallback callback = (error, _) =>
+            {
+                if (error == MediaContentError.None)
+                {
+                    tcs.TrySetResult(true);
+                }
+                else
+                {
+                    tcs.TrySetException(error.AsException("Failed to add burst shot images"));
+                }
+            };
+
+            using (ObjectKeeper.Get(callback))
+            {
+                Interop.MediaInfo.BurstShotInsert(pathArray, pathArray.Length, callback).
+                    ThrowIfError("Failed to add burst shots to db");
+
+                await tcs.Task;
+            }
+        }
+
+        private static void SetUpdateValue<T>(Interop.MediaInfoHandle handle, T value,
+            Func<Interop.MediaInfoHandle, T, MediaContentError> func)
+        {
+            if (value != null)
+            {
+                func(handle, value).ThrowIfError("Failed to update");
+            }
+        }
+
+
+        private static void SetUpdateValue<T>(Interop.MediaInfoHandle handle, Nullable<T> value,
+            Func<Interop.MediaInfoHandle, T, MediaContentError> func) where T : struct
+        {
+            if (value.HasValue)
+            {
+                func(handle, value.Value).ThrowIfError("Failed to update");
+            }
+        }
+
+        /// <summary>
+        /// Updates a media with the specified values.
+        /// </summary>
+        /// <privilege>http://tizen.org/privilege/content.write</privilege>
+        /// <param name="mediaId">The media id to update.</param>
+        /// <param name="values">The values for update.</param>
+        /// <returns>true if the matched record was found and updated, otherwise false.</returns>
+        /// <remarks>Only values set in <see cref="MediaInfoUpdateValues"/> are updated.</remarks>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException">
+        ///     <paramref name="mediaId"/> is null.\n
+        ///     -or-\n
+        ///     <paramref name="values"/> is null.
+        /// </exception>
+        /// <exception cref="ArgumentException"><paramref name="mediaId"/> is a zero-length string, contains only white space.</exception>
+        /// <exception cref="UnauthorizedAccessException">The caller has no required privilege.</exception>
+        public bool Update(string mediaId, MediaInfoUpdateValues values)
+        {
+            ValidateDatabase();
+
+            ValidationUtil.ValidateNotNullOrEmpty(mediaId, nameof(mediaId));
+
+            if (values == null)
+            {
+                throw new ArgumentNullException(nameof(values));
+            }
+
+            if (CommandHelper.Count(
+                Interop.MediaInfo.GetMediaCount, $"{MediaInfoColumns.Id}='{mediaId}'") == 0)
+            {
+                return false;
+            }
+
+            Interop.MediaInfo.GetMediaFromDB(mediaId, out var handle).ThrowIfError("Failed to update");
+
+            if (handle.IsInvalid)
+            {
+                return false;
+            }
+
+            try
+            {
+                SetUpdateValue(handle, values.Weather, Interop.MediaInfo.SetWeather);
+                SetUpdateValue(handle, values.IsFavorite, Interop.MediaInfo.SetFavorite);
+                SetUpdateValue(handle, values.Provider, Interop.MediaInfo.SetProvider);
+                SetUpdateValue(handle, values.Category, Interop.MediaInfo.SetCategory);
+                SetUpdateValue(handle, values.LocationTag, Interop.MediaInfo.SetLocationTag);
+                SetUpdateValue(handle, values.AgeRating, Interop.MediaInfo.SetAgeRating);
+
+                Interop.MediaInfo.UpdateToDB(handle).ThrowIfError("Failed to update");
+                return true;
+            }
+            finally
+            {
+                handle.Dispose();
+            }
+        }
+
+        /// <summary>
+        /// Updates the path of the media to the specified destination path in the database.
+        /// </summary>
+        /// <privilege>http://tizen.org/privilege/content.write</privilege>
+        /// <privilege>http://tizen.org/privilege/mediastorage</privilege>
+        /// <privilege>http://tizen.org/privilege/externalstorage</privilege>
+        /// <param name="mediaId">The media id to move.</param>
+        /// <param name="newPath">The path that the media has been moved to.</param>
+        /// <returns>true if the matched record was found and updated, otherwise false.</returns>
+        /// <remarks>
+        ///     Usually, it is used after the media file is moved to another path.\n
+        ///     \n
+        ///     If you want to access internal storage, you should add privilege http://tizen.org/privilege/mediastorage.\n
+        ///     If you want to access external storage, you should add privilege http://tizen.org/privilege/externalstorage.
+        /// </remarks>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException">
+        ///     <paramref name="mediaId"/> is null.\n
+        ///     -or-\n
+        ///     <paramref name="newPath"/> is null.
+        /// </exception>
+        /// <exception cref="ArgumentException">
+        ///     <paramref name="mediaId"/> is a zero-length string, contains only white space.\n
+        ///     -or-\n
+        ///     <paramref name="newPath"/> is a zero-length string, contains only white space.\n
+        ///     -or-\n
+        ///     <paramref name="newPath"/> contains a hidden directory that starts with '.'.\n
+        ///     -or-\n
+        ///     <paramref name="newPath"/> contains a directory containing the ".scan_ignore" file.
+        /// </exception>
+        /// <exception cref="FileNotFoundException"><paramref name="newPath"/> does not exists.</exception>
+        /// <exception cref="UnauthorizedAccessException">The caller has no required privilege.</exception>
+        public bool Move(string mediaId, string newPath)
+        {
+            ValidateDatabase();
+
+            ValidationUtil.ValidateNotNullOrEmpty(mediaId, nameof(mediaId));
+
+            ValidationUtil.ValidateNotNullOrEmpty(newPath, nameof(newPath));
+
+            if (File.Exists(newPath) == false)
+            {
+                throw new FileNotFoundException("destination is not valid path.", newPath);
+            }
+
+            if (File.GetAttributes(newPath).HasFlag(FileAttributes.Hidden))
+            {
+                throw new ArgumentException($"{nameof(newPath)} contains a hidden path.", nameof(newPath));
+            }
+
+            //TODO can be improved if MoveToDB supports result value.
+            Interop.MediaInfo.GetMediaFromDB(mediaId, out var handle).
+                Ignore(MediaContentError.InvalidParameter).ThrowIfError("Failed to move");
+
+            if (handle.IsInvalid)
+            {
+                return false;
+            }
+
+            try
+            {
+                Interop.MediaInfo.MoveToDB(handle, newPath).ThrowIfError("Failed to move");
+            }
+            finally
+            {
+                handle.Dispose();
+            }
+
+            return true;
+        }
+
+        #region CreateThumbnailAsync
+        /// <summary>
+        /// Creates a thumbnail image for the given media.
+        /// If a thumbnail already exists for the given media, the existing path will be returned.
+        /// </summary>
+        /// <privilege>http://tizen.org/privilege/content.write</privilege>
+        /// <param name="mediaId">The media id to create thumbnail.</param>
+        /// <returns>A task that represents the asynchronous operation. The task result contains the thumbnail path.</returns>
+        /// <exception cref="InvalidOperationException">
+        ///     The <see cref="MediaDatabase"/> is disconnected.\n
+        ///     -or-\n
+        ///     An internal error occurred while executing.
+        /// </exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="mediaId"/> is null.</exception>
+        /// <exception cref="RecordNotFoundException"><paramref name="mediaId"/> does not exist in the database.</exception>
+        /// <exception cref="ArgumentException">
+        ///     <paramref name="mediaId"/> is a zero-length string, contains only white space.
+        /// </exception>
+        /// <exception cref="FileNotFoundException">The file of the media does not exists; moved or deleted.</exception>
+        /// <exception cref="UnsupportedContentException">
+        ///     Thumbnail is not available for the given media.\n
+        ///     -or-\n
+        ///     The media is in external usb storage(<see cref="MediaInfo.StorageType"/> is <see cref="StorageType.ExternalUsb"/>).
+        /// </exception>
+        public Task<string> CreateThumbnailAsync(string mediaId)
+        {
+            return CreateThumbnailAsync(mediaId, CancellationToken.None);
+        }
+
+        /// <summary>
+        /// Creates a thumbnail image for the given media.
+        /// If a thumbnail already exists for the given media, the existing path will be returned.
+        /// </summary>
+        /// <privilege>http://tizen.org/privilege/content.write</privilege>
+        /// <param name="mediaId">The media id to create thumbnail.</param>
+        /// <param name="cancellationToken">The token to cancel the operation.</param>
+        /// <returns>A task that represents the asynchronous operation. The task result contains the thumbnail path.</returns>
+        /// <exception cref="InvalidOperationException">
+        ///     The <see cref="MediaDatabase"/> is disconnected.\n
+        ///     -or-\n
+        ///     An internal error occurred while executing.
+        /// </exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="mediaId"/> is null.</exception>
+        /// <exception cref="RecordNotFoundException"><paramref name="mediaId"/> does not exist in the database.</exception>
+        /// <exception cref="ArgumentException">
+        ///     <paramref name="mediaId"/> is a zero-length string, contains only white space.
+        /// </exception>
+        /// <exception cref="FileNotFoundException">The file of the media does not exists; moved or deleted.</exception>
+        /// <exception cref="UnsupportedContentException">
+        ///     Thumbnail is not available for the given media.\n
+        ///     -or-\n
+        ///     The media is in external usb storage(<see cref="MediaInfo.StorageType"/> is <see cref="StorageType.ExternalUsb"/>).
+        /// </exception>
+        public Task<string> CreateThumbnailAsync(string mediaId, CancellationToken cancellationToken)
+        {
+            ValidateDatabase();
+
+            return cancellationToken.IsCancellationRequested ? Task.FromCanceled<string>(cancellationToken) :
+                CreateThumbnailAsyncCore(mediaId, cancellationToken);
+        }
+
+        private async Task<string> CreateThumbnailAsyncCore(string mediaId, CancellationToken cancellationToken)
+        {
+            ValidationUtil.ValidateNotNullOrEmpty(mediaId, nameof(mediaId));
+
+            var tcs = new TaskCompletionSource<string>();
+
+            Interop.MediaInfo.GetMediaFromDB(mediaId, out var handle).ThrowIfError("Failed to create thumbnail");
+
+            if (handle.IsInvalid)
+            {
+                throw new RecordNotFoundException("Media does not exist.");
+            }
+
+            using (handle)
+            {
+                if (InteropHelper.GetValue<StorageType>(handle, Interop.MediaInfo.GetStorageType) == StorageType.ExternalUsb)
+                {
+                    throw new UnsupportedContentException("The media is in external usb storage.");
+                }
+
+                var path = InteropHelper.GetString(handle, Interop.MediaInfo.GetFilePath);
+
+                if (File.Exists(path) == false)
+                {
+                    throw new FileNotFoundException($"The media file does not exist. Path={path}.", path);
+                }
+
+                using (RegisterCancelThumbnail(cancellationToken, tcs, handle))
+                using (var cbKeeper = ObjectKeeper.Get(GetCreateThumbnailCallback(tcs)))
+                {
+                    Interop.MediaInfo.CreateThumbnail(handle, cbKeeper.Target).ThrowIfError("Failed to create thumbnail");
+
+                    return await tcs.Task;
+                }
+            }
+        }
+
+        private static Interop.MediaInfo.ThumbnailCompletedCallback GetCreateThumbnailCallback(
+            TaskCompletionSource<string> tcs)
+        {
+            return (error, path, _) =>
+            {
+                if (error != MediaContentError.None)
+                {
+                    tcs.TrySetException(error.AsException("Failed to create thumbnail"));
+                }
+                else
+                {
+                    tcs.TrySetResult(path);
+                }
+            };
+        }
+
+        private static IDisposable RegisterCancelThumbnail(CancellationToken cancellationToken,
+            TaskCompletionSource<string> tcs, Interop.MediaInfoHandle handle)
+        {
+            if (cancellationToken.CanBeCanceled == false)
+            {
+                return null;
+            }
+
+            return cancellationToken.Register(() =>
+            {
+                if (tcs.Task.IsCompleted)
+                {
+                    return;
+                }
+
+                Interop.MediaInfo.CancelThumbnail(handle).ThrowIfError("Failed to cancel");
+                tcs.TrySetCanceled();
+            });
+        }
+        #endregion
+
+        #region DetectFaceAsync
+        /// <summary>
+        /// Detects faces from the given media.
+        /// If a thumbnail already exists for the given media, the existing path will be returned.
+        /// </summary>
+        /// <privilege>http://tizen.org/privilege/content.write</privilege>
+        /// <feature>http://tizen.org/feature/vision.face_recognition</feature>
+        /// <param name="mediaId">The media id to create thumbnail.</param>
+        /// <returns>A task that represents the asynchronous add operation. The task result contains the number of faces detected.</returns>
+        /// <exception cref="InvalidOperationException">
+        ///     The <see cref="MediaDatabase"/> is disconnected.\n
+        ///     -or-\n
+        ///     An internal error occurred while executing.
+        /// </exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="mediaId"/> is null.</exception>
+        /// <exception cref="RecordNotFoundException"><paramref name="mediaId"/> does not exist in the database.</exception>
+        /// <exception cref="ArgumentException">
+        ///     <paramref name="mediaId"/> is a zero-length string, contains only white space.
+        /// </exception>
+        /// <exception cref="FileNotFoundException">The file of the media does not exists; moved or deleted.</exception>
+        /// <exception cref="UnsupportedContentException">Feace detection is not available for the given media.</exception>
+        /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+        /// <exception cref="UnauthorizedAccessException">The caller has no required privilege.</exception>
+        public Task<int> DetectFaceAsync(string mediaId)
+        {
+            return DetectFaceAsync(mediaId, CancellationToken.None);
+        }
+
+        /// <summary>
+        /// Creates a thumbnail image for the given media.
+        /// If a thumbnail already exists for the given media, the existing path will be returned.
+        /// </summary>
+        /// <remarks>
+        ///     Media in external storage is not supported, with the exception of MMC.
+        /// </remarks>
+        /// <privilege>http://tizen.org/privilege/content.write</privilege>
+        /// <feature>http://tizen.org/feature/vision.face_recognition</feature>
+        /// <param name="mediaId">The media id to create thumbnail.</param>
+        /// <param name="cancellationToken">The token to cancel the operation.</param>
+        /// <returns>A task that represents the asynchronous operation. The task result contains the number of faces detected.</returns>
+        /// <exception cref="InvalidOperationException">
+        ///     The <see cref="MediaDatabase"/> is disconnected.\n
+        ///     -or-\n
+        ///     An internal error occurred while executing.
+        /// </exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="mediaId"/> is null.</exception>
+        /// <exception cref="RecordNotFoundException"><paramref name="mediaId"/> does not exist in the database.</exception>
+        /// <exception cref="ArgumentException">
+        ///     <paramref name="mediaId"/> is a zero-length string, contains only white space.
+        /// </exception>
+        /// <exception cref="FileNotFoundException">The file of the media does not exists; moved or deleted.</exception>
+        /// <exception cref="UnsupportedContentException">
+        ///     Face detection is not available for the given media.\n
+        ///     -or-\n
+        ///     The media is in external usb storage(<see cref="MediaInfo.StorageType"/> is <see cref="StorageType.ExternalUsb"/>).
+        /// </exception>
+        /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
+        public Task<int> DetectFaceAsync(string mediaId, CancellationToken cancellationToken)
+        {
+            if (Features.IsSupported(Features.FaceRecognition) == false)
+            {
+                throw new NotSupportedException($"The feature({Features.FaceRecognition}) is not supported.");
+            }
+
+            ValidateDatabase();
+
+            return cancellationToken.IsCancellationRequested ? Task.FromCanceled<int>(cancellationToken) :
+                DetectFaceAsyncCore(mediaId, cancellationToken);
+        }
+
+        private static async Task<int> DetectFaceAsyncCore(string mediaId, CancellationToken cancellationToken)
+        {
+            ValidationUtil.ValidateNotNullOrEmpty(mediaId, nameof(mediaId));
+
+            var tcs = new TaskCompletionSource<int>();
+
+            Interop.MediaInfo.GetMediaFromDB(mediaId, out var handle).ThrowIfError("Failed to detect faces");
+
+            if (handle.IsInvalid)
+            {
+                throw new RecordNotFoundException("Media does not exist.");
+            }
+
+            using (handle)
+            {
+                if (InteropHelper.GetValue<StorageType>(handle, Interop.MediaInfo.GetStorageType) == StorageType.ExternalUsb)
+                {
+                    throw new UnsupportedContentException("The media is in external usb storage.");
+                }
+
+                if (InteropHelper.GetValue<MediaType>(handle, Interop.MediaInfo.GetMediaType) != MediaType.Image)
+                {
+                    throw new UnsupportedContentException("Only image is supported.");
+                }
+
+                var path = InteropHelper.GetString(handle, Interop.MediaInfo.GetFilePath);
+
+                if (File.Exists(path) == false)
+                {
+                    throw new FileNotFoundException($"The media file does not exist. Path={path}.", path);
+                }
+
+                using (RegisterCancelFaceDetection(cancellationToken, tcs, handle))
+                using (var cbKeeper = ObjectKeeper.Get(GetFaceDetectionCallback(tcs)))
+                {
+                    Interop.MediaInfo.StartFaceDetection(handle, cbKeeper.Target).ThrowIfError("Failed to detect faces");
+
+                    return await tcs.Task;
+                }
+            }
+        }
+
+        private static Interop.MediaInfo.FaceDetectionCompletedCallback GetFaceDetectionCallback(
+            TaskCompletionSource<int> tcs)
+        {
+            return (error, count, _) =>
+            {
+                if (error != MediaContentError.None)
+                {
+                    tcs.TrySetException(error.AsException("Failed to detect faces"));
+                }
+                else
+                {
+                    tcs.TrySetResult(count);
+                }
+            };
+        }
+
+        private static IDisposable RegisterCancelFaceDetection(CancellationToken cancellationToken,
+            TaskCompletionSource<int> tcs, Interop.MediaInfoHandle handle)
+        {
+            if (cancellationToken.CanBeCanceled == false)
+            {
+                return null;
+            }
+
+            return cancellationToken.Register(() =>
+            {
+                if (tcs.Task.IsCompleted)
+                {
+                    return;
+                }
+
+                Interop.MediaInfo.CancelFaceDetection(handle).ThrowIfError("Failed to cancel");
+                tcs.TrySetCanceled();
+            });
+        }
+        #endregion
+    }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaInfoUpdateValues.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaInfoUpdateValues.cs
new file mode 100644 (file)
index 0000000..9947f38
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Content.MediaContent
+{
+    /// <summary>
+    /// Provides means to set values used for the update command.
+    /// </summary>
+    /// <remarks>
+    /// The values only set in the object will be affected to the update command.
+    /// </remarks>
+    /// <seealso cref="MediaInfoCommand.Update(string, MediaInfoUpdateValues)"/>
+    public class MediaInfoUpdateValues
+    {
+        /// <summary>
+        /// Gets or sets the weather information for update.
+        /// </summary>
+        /// <remarks>If the value is null, the update operation will have no effect on the field.</remarks>
+        /// <value>A string for weather; the field will not be updated if null.</value>
+        public string Weather { get; set; }
+
+        /// <summary>
+        /// Gets or sets the favorite status for update.
+        /// </summary>
+        /// <remarks>If the value is null, the update operation will have no effect on the field.</remarks>
+        /// <value>A value indicating whether the media is favorite; the field will not be updated if null.</value>
+        public bool? IsFavorite { get; set; }
+
+        /// <summary>
+        /// Gets or sets the provider information for update.
+        /// </summary>
+        /// <remarks>If the value is null, the update operation will have no effect on the field.</remarks>
+        /// <value>A string for provider; the field will not be updated if null.</value>
+        public string Provider { get; set; }
+
+        /// <summary>
+        /// Gets or sets the category information for update.
+        /// </summary>
+        /// <remarks>If the value is null, the update operation will have no effect on the field.</remarks>
+        /// <value>A string for category; the field will not be updated if null.</value>
+        public string Category { get; set; }
+
+
+        /// <summary>
+        /// Gets or sets the location tag for update.
+        /// </summary>
+        /// <remarks>If the value is null, the update operation will have no effect on the field.</remarks>
+        /// <value>A string for location tag; the field will not be updated if null.</value>
+        public string LocationTag { get; set; }
+
+        /// <summary>
+        /// Gets or sets the age rating information for update.
+        /// </summary>
+        /// <remarks>If the value is null, the update operation will have no effect on the field.</remarks>
+        /// <value>A string for age rating; the field will not be updated if null.</value>
+        public string AgeRating { get; set; }
+    }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaInformation.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaInformation.cs
deleted file mode 100755 (executable)
index 49b1788..0000000
+++ /dev/null
@@ -1,897 +0,0 @@
-/*
-* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
-*
-* Licensed under the Apache License, Version 2.0 (the License);
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an AS IS BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-
-
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Runtime.InteropServices;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace Tizen.Content.MediaContent
-{
-    /// <summary>
-    /// MediaContent class API gives the information related to the media stored in the device</summary>
-    /// <remarks>
-    /// The API's provide the functionlity to insert, clone, delete, get the number and content of files from DB.
-    /// You can get and set properties and parameters such as storage type, provider, and category of media info,
-    /// handling with thumbnail and updating media info to DB.</remarks>
-    public class MediaInformation
-    {
-        private readonly Interop.MediaInformation.SafeMediaInformationHandle _handle;
-
-        /// <summary>
-        /// Gets the count of media tags for the passed filter in the given mediaId from the media database.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <returns>
-        /// int count</returns>
-        /// <param name="filter">The Filter for matching Tags</param>
-        public int GetTagCount(ContentFilter filter)
-        {
-            int count = 0;
-            IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
-            MediaContentValidator.ThrowIfError(
-                Interop.MediaInformation.GetTagCount(MediaId, handle, out count), "Failed to get count");
-
-            return count;
-        }
-
-        /// <summary>
-        /// Moves the media info to the given destination path in the media database.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <returns>
-        /// void </returns>
-        /// <param name="destination">The Destination path</param>
-        public void Move(string destination)
-        {
-            MediaContentValidator.ThrowIfError(
-                Interop.MediaInformation.MoveToDB(_handle, destination), "Failed to move");
-        }
-
-        /// <summary>
-        /// Refreshes the media metadata to the media database.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <returns>
-        /// void </returns>
-        public void Refresh()
-        {
-            MediaContentValidator.ThrowIfError(
-                Interop.MediaInformation.RefreshMetadataToDB(MediaId), "Failed to refresh");
-        }
-
-        /// <summary>
-        /// Creates a thumbnail image for the given media, asynchronously
-        /// If a thumbnail already exists for the given media, then the path of thumbnail will be returned.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <returns>
-        /// Task for creation of Thumbnail </returns>
-        public Task<string> CreateThumbnailAsync()
-        {
-            var task = new TaskCompletionSource<string>();
-            Interop.MediaInformation.MediaThumbnailCompletedCallback thumbnailResult = (MediaContentError createResult, string path, IntPtr userData) =>
-            {
-                if (createResult != MediaContentError.None)
-                {
-                    task.SetException(new InvalidOperationException("Failed to create thumbnail:" + createResult));
-                }
-
-                task.SetResult(path);
-            };
-            MediaContentValidator.ThrowIfError(
-                Interop.MediaInformation.CreateThumbnail(_handle, thumbnailResult, IntPtr.Zero), "Failed to create thumbnail");
-
-            return task.Task;
-        }
-
-        /// <summary>
-        /// Creates a thumbnail image for the given media, asynchronously
-        /// which can be cancelled
-        /// If a thumbnail already exists for the given media, then the path of thumbnail will be returned.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="cancellationToken">Token to cancel the requested operation</param>
-        /// <returns>
-        /// Task for creation of Thumbnail
-        /// </returns>
-        public Task<string> CreateThumbnailAsync(CancellationToken cancellationToken)
-        {
-            var task = new TaskCompletionSource<string>();
-            cancellationToken.Register(() =>
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.CancelThumbnail(_handle), "Failed to cancel");
-
-                task.SetCanceled();
-            });
-
-            Interop.MediaInformation.MediaThumbnailCompletedCallback thumbnailResult = (MediaContentError createResult, string path, IntPtr userData) =>
-            {
-                if (createResult != MediaContentError.None)
-                {
-                    task.SetException(new InvalidOperationException("Failed to create thumbnail:" + createResult));
-                }
-
-                task.SetResult(path);
-            };
-
-            MediaContentValidator.ThrowIfError(
-                Interop.MediaInformation.CreateThumbnail(_handle, thumbnailResult, IntPtr.Zero), "Failed to create thumbnail");
-
-            return task.Task;
-        }
-
-        /// <summary>
-        /// Iterates through the media tag in the given media info from the media database.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <returns>
-        /// Task to get all the Tags </returns>
-        /// <param name="filter"> The filter for the Tags</param>
-        public IEnumerable<Tag> GetTags(ContentFilter filter)
-        {
-            Collection<Tag> coll = new Collection<Tag>();
-
-            IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
-            Interop.MediaInformation.MediaTagCallback tagsCallback = (IntPtr tagHandle, IntPtr userData) =>
-            {
-                IntPtr newHandle;
-                MediaContentValidator.ThrowIfError(
-                    Interop.Tag.Clone(out newHandle, tagHandle), "Failed to clone");
-                coll.Add(new Tag(newHandle));
-
-                return true;
-            };
-            MediaContentValidator.ThrowIfError(
-                Interop.MediaInformation.GetAllTags(MediaId, handle, tagsCallback, IntPtr.Zero), "Failed to get information");
-
-            return coll;
-        }
-
-        /// <summary>
-        ///  Gets the ID of the media.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public virtual string MediaId
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.GetMediaId(_handle, out val), "Failed to get value");
-
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        /// <summary>
-        ///  Gets the path to the media.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string FilePath
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.GetFilePath(_handle, out val), "Failed to get value");
-
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        /// <summary>
-        ///  Name of the media.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string DisplayName
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.GetDisplayName(_handle, out val), "Failed to get value");
-
-                    return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-
-            set
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.SetDisplayName(_handle, value), "failed to set value");
-            }
-        }
-
-        /// <summary>
-        ///  Gets the content type of the media.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public MediaContentType MediaType
-        {
-            get
-            {
-                MediaContentType contentType = MediaContentType.Others;
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.GetMediaType(_handle, out contentType), "Failed to get value");
-
-                return contentType;
-            }
-        }
-
-        /// <summary>
-        ///  Gets the MIME type from the media.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string MimeType
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.GetMimeType(_handle, out val), "Failed to get value");
-
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        /// <summary>
-        ///  Gets the media file size in bytes.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public long Size
-        {
-            get
-            {
-                long size;
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.GetSize(_handle, out size), "Failed to get value");
-
-                return size;
-            }
-        }
-
-        /// <summary>
-        ///  Addition time of the media.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public DateTime AddedAt
-        {
-            get
-            {
-                int time;
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.GetAddedTime(_handle, out time), "Failed to get value");
-
-                DateTime utc = DateTime.SpecifyKind(new DateTime(1970, 1, 1).AddSeconds(time), DateTimeKind.Utc);
-
-                return utc.ToLocalTime();
-            }
-
-            set
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.SetAddedTime(_handle, (int)value.ToUniversalTime().Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds), "failed to set time");
-            }
-        }
-
-        /// <summary>
-        ///  Gets the date of modification of media.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public DateTime ModifiedAt
-        {
-            get
-            {
-                int time;
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.GetModifiedTime(_handle, out time), "Failed to get value");
-
-                DateTime utc = DateTime.SpecifyKind(new DateTime(1970, 1, 1).AddSeconds(time), DateTimeKind.Utc);
-
-                return utc.ToLocalTime();
-            }
-        }
-
-        /// <summary>
-        ///  Gets the timeline of media.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public DateTime TimeLine
-        {
-            get
-            {
-                int time;
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.GetTimeline(_handle, out time), "Failed to get value");
-
-                DateTime utc = DateTime.SpecifyKind(new DateTime(1970, 1, 1).AddSeconds(time), DateTimeKind.Utc);
-
-                return utc.ToLocalTime();
-            }
-        }
-
-        /// <summary>
-        ///  Gets the thumbnail of media.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string ThumbnailPath
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.GetThumbnailPath(_handle, out val), "Failed to get value");
-
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        /// <summary>
-        ///  Description of media.
-        ///  If the media info has no description, the property returns empty string.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string Description
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.GetDescription(_handle, out val), "Failed to get value");
-
-                    return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-
-            set
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.SetDescription(_handle, value), "failed to set value");
-            }
-        }
-
-        /// <summary>
-        /// Longitude of media.
-        /// Default Value is 0.0.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public double Longitude
-        {
-            get
-            {
-                double longitude = 0.0;
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.GetLongitude(_handle, out longitude), "Failed to get value");
-
-                return longitude;
-            }
-
-            set
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.SetLongitude(_handle, value), "failed to set value");
-            }
-        }
-
-        /// <summary>
-        /// Latitude of media.
-        /// Default Value is 0.0.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public double Latitude
-        {
-            get
-            {
-                double latitude = 0.0;
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.GetLatitude(_handle, out latitude), "Failed to get value");
-
-                return latitude;
-            }
-
-            set
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.SetLatitude(_handle, value), "failed to set value");
-            }
-        }
-
-        /// <summary>
-        /// Altitude of media.
-        /// Default Value is 0.0.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public double Altitude
-        {
-            get
-            {
-                double altitude = 0.0;
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.GetAltitude(_handle, out altitude), "Failed to get value");
-
-                return altitude;
-            }
-
-            set
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.SetAltitude(_handle, value), "failed to set value");
-            }
-        }
-
-        /// <summary>
-        /// Weather information of media.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string Weather
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.GetWeather(_handle, out val), "Failed to get value");
-
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-
-            set
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.SetWeather(_handle, value), "failed to set value");
-            }
-        }
-
-        /// <summary>
-        /// Rating of media.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public int Rating
-        {
-            get
-            {
-                int rating = 0;
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.GetRating(_handle, out rating), "Failed to get value");
-                return rating;
-            }
-
-            set
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.SetRating(_handle, value), "failed to set value");
-            }
-        }
-
-        /// <summary>
-        /// Favorite status of media.
-        /// true if media info is set as favorite, otherwise false if media info is not set as favorite.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public bool IsFavourite
-        {
-            get
-            {
-                bool isFavourtite = false;
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.GetFavorite(_handle, out isFavourtite), "Failed to get value");
-
-                return isFavourtite;
-            }
-
-            set
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.SetFavorite(_handle, value), "failed to set value");
-            }
-        }
-
-        /// <summary>
-        /// Author of media.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string Author
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.GetAuthor(_handle, out val), "Failed to get value");
-
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-
-            set
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.SetAuthor(_handle, value), "failed to set value");
-            }
-        }
-
-        /// <summary>
-        /// Provider of media.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string Provider
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.GetProvider(_handle, out val), "Failed to get value");
-
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-
-            set
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.SetProvider(_handle, value), "failed to set value");
-            }
-        }
-
-        /// <summary>
-        /// Content name of media.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string ContentName
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.GetContentName(_handle, out val), "Failed to get value");
-
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-
-            set
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.SetContentName(_handle, value), "failed to set value");
-            }
-        }
-
-        /// <summary>
-        /// Gets the title of media.
-        /// If the media content has no title, the property returns empty string.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string Title
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.GetTitle(_handle, out val), "Failed to get value");
-
-                    return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        /// <summary>
-        /// Category of media.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string Category
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.GetCategory(_handle, out val), "Failed to get value");
-
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-
-            set
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.SetCategory(_handle, value), "failed to set value");
-            }
-        }
-
-        /// <summary>
-        /// location tag of media.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string LocationTag
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.GetLocationTag(_handle, out val), "Failed to get value");
-
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-
-            set
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.SetLocationTag(_handle, value), "failed to set value");
-            }
-        }
-
-        /// <summary>
-        /// Age Rating of media.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string AgeRating
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.GetAgeRating(_handle, out val), "Failed to get value");
-
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-
-            set
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.SetAgeRating(_handle, value), "Failed to set value");
-            }
-        }
-
-        /// <summary>
-        /// Keyword of media.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string Keyword
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.GetKeyword(_handle, out val), "Failed to get value");
-
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-
-            set
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.SetKeyword(_handle, value), "failed to set value");
-            }
-        }
-
-        /// <summary>
-        /// Gets the storage id of media.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string StorageId
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.GetStorageId(_handle, out val), "Failed to get value");
-
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        /// <summary>
-        /// Checks whether the media is protected via DRM.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public bool IsDrm
-        {
-            get
-            {
-                bool isDRM = false;
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.IsDrm(_handle, out isDRM), "Failed to get value");
-
-                return isDRM;
-            }
-        }
-
-        /// <summary>
-        /// Gets the storage type of media.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public ContentStorageType StorageType
-        {
-            get
-            {
-                ContentStorageType storageType = ContentStorageType.Internal;
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.GetStorageType(_handle, out storageType), "Failed to get value");
-
-                return storageType;
-            }
-        }
-
-        /// <summary>
-        /// Number which represents how many times given content has been played.
-        /// While Setting the played count, it will only be incremented by 1, the value provided will be ignored.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public int PlayedCount
-        {
-            get
-            {
-                int playedCount = 0;
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.GetPlayedCount(_handle, out playedCount), "Failed to get value");
-
-                return playedCount;
-            }
-
-            set
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.IncreasePlayedCount(_handle), "failed to set value");
-            }
-        }
-
-        /// <summary>
-        ///  Content's latest played(opened) time of the media file.
-        ///  for set the current time is automatically taken from the system, the value provided will be ignored.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public DateTime PlayedAt
-        {
-            get
-            {
-                int time;
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.GetPlayedAt(_handle, out time), "Failed to get value");
-
-                DateTime utc = DateTime.SpecifyKind(new DateTime(1970, 1, 1).AddSeconds(time), DateTimeKind.Utc);
-
-                return utc.ToLocalTime();
-            }
-
-            set
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.SetPlayedAt(_handle), "failed to set value");
-            }
-        }
-
-        internal IntPtr MediaHandle
-        {
-            get
-            {
-                return _handle.DangerousGetHandle();
-            }
-        }
-
-        internal MediaInformation(Interop.MediaInformation.SafeMediaInformationHandle handle)
-        {
-            _handle = handle;
-        }
-    }
-}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/NamespaceDoc.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/NamespaceDoc.cs
new file mode 100644 (file)
index 0000000..7df929a
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/// <summary>
+/// The Tizen.Content.MediaContent namespace provides types used in the entire content service.
+/// The information about media items(i.e. image, audio and video) are managed in the content database
+/// and operations that involve database require an active connection with the media content service.
+/// During media scanning, Media content service extracts media information automatically. Media information
+/// includes basic file info like path, size, modified time etc and some metadata like ID3 tag, EXIF,
+/// thumbnail, etc. (thumbnail extracted only in Internal and SD card storage.
+/// </summary>
+/// <remarks>Media content service does not manage hidden files.</remarks>
+namespace Tizen.Content.MediaContent { }
\ No newline at end of file
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ObjectKeeper.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ObjectKeeper.cs
new file mode 100644 (file)
index 0000000..06d9b8c
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Content.MediaContent
+{
+    internal abstract class ObjectKeeper : IDisposable
+    {
+        private ObjectKeeper()
+        {
+        }
+
+        public abstract void Dispose();
+
+        public static ObjectKeeperImpl<T> Get<T>(T target)
+        {
+            return new ObjectKeeperImpl<T>(target);
+        }
+
+        internal class ObjectKeeperImpl<T> : ObjectKeeper
+        {
+            private readonly GCHandle _handle;
+
+            internal ObjectKeeperImpl(T obj)
+            {
+                Target = obj;
+                _handle = GCHandle.Alloc(obj);
+            }
+
+            ~ObjectKeeperImpl()
+            {
+                Dispose(false);
+            }
+
+            private bool disposedValue = false;
+
+            protected virtual void Dispose(bool disposing)
+            {
+                if (!disposedValue)
+                {
+                    if (disposing)
+                    {
+                        _handle.Free();
+                    }
+
+                    disposedValue = true;
+                }
+            }
+
+            public override void Dispose()
+            {
+                Dispose(true);
+                GC.SuppressFinalize(this);
+            }
+
+            public T Target
+            {
+                get;
+            }
+        }
+    }
+}
index e440707..beabf44 100755 (executable)
-/*
-* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
-*
-* Licensed under the Apache License, Version 2.0 (the License);
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an AS IS BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 using System;
-using System.Collections.Generic;
-using System.Runtime.InteropServices;
-using System.Threading.Tasks;
 
 namespace Tizen.Content.MediaContent
 {
     /// <summary>
-    /// The PlayList API provides functions to manage media playlists.
+    /// Represents a playlist that is a group of media(usually songs).
     /// </summary>
-    /// <remarks>
-    /// A PlayList is a list of songs which can be played in some sequence i.e. sequential or shuffled order.
-    /// The Media PlayList API provides functions to insert, delete or updates a media playlist in the database.
-    /// </remarks>
-    public class PlayList : ContentCollection
+    public class Playlist
     {
-        private readonly IDictionary<string, int> _dictionary = new Dictionary<string, int>();
-        private IntPtr _playlistHandle = IntPtr.Zero;
-        internal IntPtr Handle
+        internal Playlist(IntPtr handle)
         {
-            get
-            {
-                if (_playlistHandle == IntPtr.Zero)
-                {
-                    throw new ObjectDisposedException(nameof(PlayList));
-                }
-
-                return _playlistHandle;
-            }
+            Name = InteropHelper.GetString(handle, Interop.Playlist.GetName);
+            ThumbnailPath = InteropHelper.GetString(handle, Interop.Playlist.GetThumbnailPath);
 
-            set
-            {
-                _playlistHandle = value;
-            }
+            Id = InteropHelper.GetValue<IntPtr, int>(handle, Interop.Playlist.GetId);
         }
 
-        private void RefreshPlaylistDictionary()
-        {
-            _dictionary.Clear();
-            Interop.Playlist.PlaylistMemberCallback callback = (int memberId, IntPtr mediaHandle, IntPtr data) =>
-            {
-                Interop.MediaInformation.SafeMediaInformationHandle newHandle;
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.Clone(out newHandle, mediaHandle), "Failed to clone media");
-
-                    Interop.MediaInformation.GetMediaId(newHandle, out val);
-                    _dictionary.Add(Marshal.PtrToStringAnsi(val), memberId);
-                    return true;
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            };
-            MediaContentValidator.ThrowIfError(
-                Interop.Playlist.ForeachMediaFromDb(Id, IntPtr.Zero, callback, IntPtr.Zero), "Failed to get playlist items");
-        }
+        internal static Playlist FromHandle(IntPtr handle) => new Playlist(handle);
 
         /// <summary>
-        /// The ID of the media playlist
+        /// Gets the ID of the playlist.
         /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public int Id
-        {
-            get
-            {
-                int id;
-                MediaContentValidator.ThrowIfError(
-                    Interop.Playlist.GetPlaylistId(Handle, out id), "Failed to get value");
+        /// <value>The unique id of the playlist.</value>
+        public int Id { get; }
 
-                return id;
-            }
-        }
-
-        internal string _playListName;
         /// <summary>
-        /// The playlist name
+        /// Gets the name of the playlist.
         /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string Name
-        {
-            get
-            {
-                return _playListName;
-            }
+        /// <value>The name of the playlist.</value>
+        public string Name { get; }
 
-            set
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.Playlist.SetName(Handle, value), "Failed to set value");
-                _playListName = value;
-            }
-        }
         /// <summary>
-        /// The path of the thumbnail
+        /// Gets the path to the thumbnail.
         /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string ThumbnailPath
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.Playlist.GetThumbnailPath(Handle, out val), "Failed to get value");
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-
-            set
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.Playlist.SetThumbnailPath(Handle, value), "Failed to set value");
-            }
-        }
+        /// <value>The path to the thumbnail.</value>
+        public string ThumbnailPath { get; }
 
         /// <summary>
-        /// The constructor to create a new playlist with the given name in the media database.
+        /// Returns a string representation of the playlist.
         /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="name">The name of the inserted playlist</param>
-        public PlayList(string name)
-        {
-            _playListName = name;
-        }
-
-        internal PlayList(IntPtr handle)
-        {
-            _playlistHandle = handle;
-            IntPtr val = IntPtr.Zero;
-            try
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.Playlist.GetName(handle, out val), "Failed to get value");
-                _playListName = Marshal.PtrToStringAnsi(val);
-            }
-            finally
-            {
-                Interop.Libc.Free(val);
-            }
-        }
-
-        /// <summary>
-        /// Adds a new media info to the playlist.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="mediaContent">The AudioContent obect to be added</param>
-        public void AddItem(MediaInformation mediaContent)
-        {
-            MediaContentValidator.ThrowIfError(
-                Interop.Playlist.AddMedia(Handle, mediaContent.MediaId), "Failed to add item");
-        }
-
-        /// <summary>
-        /// Removes the playlist members related with the media from the given playlist.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="media">The AudioContent object to be removed</param>
-        public void RemoveItem(MediaInformation media)
-        {
-            int memberId = 0;
-            RefreshPlaylistDictionary();
-            _dictionary.TryGetValue(media.MediaId, out memberId);
-            MediaContentValidator.ThrowIfError(
-                Interop.Playlist.RemoveMedia(Handle, memberId), "Failed to remove item");
-        }
+        /// <returns>A string representation of the current playlist.</returns>
+        public override string ToString() =>
+            $"Id={Id}, Name={Name}, ThumbnailPath={ThumbnailPath}";
+    }
 
+    /// <summary>
+    /// Provides means to set values used for the update command.
+    /// </summary>
+    /// <remarks>
+    /// The values only set in the object will be affected to the update command.
+    /// </remarks>
+    /// <seealso cref="PlaylistCommand.Update(int, PlaylistUpdateValues)"/>
+    public class PlaylistUpdateValues
+    {
         /// <summary>
-        /// Sets the playing order in the playlist.
+        /// Gets or sets the name of playlist for update.
         /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="media">The playlist reference</param>
-        /// <param name="playOrder">The playing order</param>
-        public void SetPlayOrder(MediaInformation media, int playOrder)
-        {
-            int memberId;
-            RefreshPlaylistDictionary();
-            _dictionary.TryGetValue(media.MediaId, out memberId);
-            MediaContentValidator.ThrowIfError(
-                Interop.Playlist.SetPlayOrder(Handle, memberId, playOrder), "Failed to set play order");
-        }
+        /// <remarks>If the value is null, the update operation will have no effect on the field.</remarks>
+        /// <value>A string for name; the field will not be updated if null.</value>
+        public string Name { get; set; }
 
         /// <summary>
-        /// Gets the playing order in the playlist for the passed member id.
+        /// Gets or sets the thumbnail path of playlist for update.
         /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="media">The MediaInformation instance</param>
-        /// <returns>The number of play order</returns>
-        public int GetPlayOrder(MediaInformation media)
-        {
-            int playOrder;
-            int memberId;
-            RefreshPlaylistDictionary();
-            _dictionary.TryGetValue(media.MediaId, out memberId);
-            MediaContentValidator.ThrowIfError(
-                Interop.Playlist.GetPlayOrder(Handle, memberId, out playOrder), "Failed to get play order");
-
-            return playOrder;
-        }
+        /// <remarks>If the value is null, the update operation will have no effect on the field.</remarks>
+        /// <value>A string for thumbnail path; the field will not be updated if null.</value>
+        public string ThumbnailPath { get; set; }
+    }
 
+    /// <summary>
+    /// Represents an order of a member of a playlist.
+    /// </summary>
+    public class PlayOrder
+    {
         /// <summary>
-        /// Imports the playlist from m3u playlist file.
+        /// Initializes a new instance of the <see cref="Playlist"/> class with the specified member id and order value.
         /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="name">The name of the playlist to save</param>
-        /// <param name="filePath">The path to import the playlist file</param>
-        /// <returns>The imported PlayList object</returns>
-        public static PlayList Import(string name, string filePath)
+        /// <param name="memberId">The id of member.</param>
+        /// <param name="orderValue">The order value.</param>
+        /// <exception cref="ArgumentOutOfRangeException">
+        ///     <paramref name="memberId"/> is less than or equal to zero.\n
+        ///     -or-\n
+        ///     <paramref name="orderValue"/> is less than zero.
+        /// </exception>
+        public PlayOrder(int memberId, int orderValue)
         {
-            PlayList playList = null;
-            IntPtr playlistHandle;
-
-            MediaContentValidator.ThrowIfError(
-                Interop.Playlist.ImportFromFile(name, filePath, out playlistHandle), "Failed to import");
-
-            playList = new PlayList(name);
-            playList.Handle = playlistHandle;
-            return playList;
+            MemberId = memberId;
+            Value = orderValue;
         }
 
-        /// <summary>
-        /// Exports the playlist to m3u playlist file.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="list">The playlist instance to export</param>
-        /// <param name="filePath">The path to save exported playlist</param>
-        /// <returns>path The path to export the playlist</returns>
-        public static void Export(PlayList list, string filePath)
-        {
-            MediaContentValidator.ThrowIfError(
-                Interop.Playlist.ExportToFile(list.Handle, filePath), "Failed to export playlist:" + filePath);
-        }
+        private int _memberId;
 
         /// <summary>
-        /// Gets the number of the media info for the given playlist present in the media database.
+        /// Gets or sets the member id.
         /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="filter">ContentFilter used to match media content from the media database.</param>
-        /// <returns>The number of media contents matching the filter passed</returns>
-        public override int GetMediaInformationCount(ContentFilter filter)
+        /// <value>The member id.</value>
+        /// <exception cref="ArgumentOutOfRangeException">
+        /// <paramref name="value"/> is less than or equal to zero.
+        /// </exception>
+        public int MemberId
         {
-            int mediaCount;
-            IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
-            MediaContentValidator.ThrowIfError(
-                Interop.Playlist.GetMediaCountFromDb(Id, handle, out mediaCount), "Failed to get media count");
-
-            return mediaCount;
-        }
-
-        public override void Dispose()
-        {
-            if (_playlistHandle != IntPtr.Zero)
+            get => _memberId;
+            set
             {
-                Interop.Playlist.Destroy(_playlistHandle);
-                _playlistHandle = IntPtr.Zero;
+                if (value <= 0)
+                {
+                    throw new ArgumentOutOfRangeException(nameof(value), value,
+                    "Member id can't be less than or equal to zero.");
+                }
+                _memberId = value;
             }
         }
 
+        private int _value;
+
         /// <summary>
-        /// Iterates through the media files with an optional filter in the given audio playlist from the media database.
-        /// This function gets all media files associated with the given media playlist and meeting desired filter option.
-        /// If NULL is passed to the filter, no filtering is applied.
+        /// Gets or sets the value indicating the order of the member in a playlist.
         /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="filter">ContentFilter used to match media content from the media database.</param>
-        /// <returns>List of content media items matching the passed filter</returns>
-        public override IEnumerable<MediaInformation> GetMediaInformations(ContentFilter filter)
+        /// <value>A integer value indicating the order of the member in a playlist.</value>
+        /// <exception cref="ArgumentOutOfRangeException">
+        ///     <paramref name="value"/> is less than zero.
+        /// </exception>
+        public int Value
         {
-            List<MediaInformation> mediaContents = new List<MediaInformation>();
-            IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
-            Interop.Playlist.PlaylistMemberCallback callback = (int memberId, IntPtr mediaHandle, IntPtr data) =>
+            get => _value;
+            set
             {
-                Interop.MediaInformation.SafeMediaInformationHandle newHandle;
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.Clone(out newHandle, mediaHandle), "Failed to clone media");
-
-                MediaContentType type;
-                Interop.MediaInformation.GetMediaType(newHandle, out type);
-                if (type == MediaContentType.Image)
+                if (value < 0)
                 {
-                    Interop.ImageInformation.SafeImageInformationHandle imageInfo;
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.GetImage(mediaHandle, out imageInfo), "Failed to get image information");
-
-                    mediaContents.Add(new ImageInformation(imageInfo, newHandle));
+                    throw new ArgumentOutOfRangeException(nameof(value), value,
+                        "Order can't be less than zero.");
                 }
-                else if ((type == MediaContentType.Music) || (type == MediaContentType.Sound))
-                {
-                    Interop.AudioInformation.SafeAudioInformationHandle audioInfo;
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.GetAudio(mediaHandle, out audioInfo), "Failed to get audio information");
-
-                    mediaContents.Add(new AudioInformation(audioInfo, newHandle));
-                }
-                else if (type == MediaContentType.Video)
-                {
-                    Interop.VideoInformation.SafeVideoInformationHandle videoInfo;
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.GetVideo(mediaHandle, out videoInfo), "Failed to get video information");
-
-                    mediaContents.Add(new VideoInformation(videoInfo, newHandle));
-                }
-                else if (type == MediaContentType.Others)
-                {
-                    mediaContents.Add(new MediaInformation(newHandle));
-                }
-
-                return true;
-            };
-            MediaContentValidator.ThrowIfError(
-                Interop.Playlist.ForeachMediaFromDb(Id, handle, callback, IntPtr.Zero), "Failed to get media information");
-
-            return mediaContents;
+                _value = value;
+            }
         }
     }
 }
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/PlaylistCommand.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/PlaylistCommand.cs
new file mode 100644 (file)
index 0000000..94d90b0
--- /dev/null
@@ -0,0 +1,872 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+
+namespace Tizen.Content.MediaContent
+{
+    /// <summary>
+    /// Provides commands to manage playlists in the database.
+    /// </summary>
+    /// <seealso cref="Playlist"/>
+    public class PlaylistCommand : MediaCommand
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PlaylistCommand"/> class with the specified <see cref="MediaDatabase"/>.
+        /// </summary>
+        /// <param name="database">A <see cref="MediaDatabase"/> that the commands run on.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="database"/> is null.</exception>
+        /// <exception cref="ObjectDisposedException"><paramref name="database"/> has already been disposed of.</exception>
+        public PlaylistCommand(MediaDatabase database) : base(database)
+        {
+        }
+
+        /// <summary>
+        /// Retrieves the number of playlists.
+        /// </summary>
+        /// <returns>The number of playlists.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        public int Count()
+        {
+            return Count(null);
+        }
+
+        /// <summary>
+        /// Retrieves the number of playlists with <see cref="CountArguments"/>.
+        /// </summary>
+        /// <param name="arguments">The criteria to use to filter. This value can be null.</param>
+        /// <returns>The number of playlists.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        public int Count(CountArguments arguments)
+        {
+            ValidateDatabase();
+
+            return CommandHelper.Count(Interop.Playlist.GetPlaylistCount, arguments);
+        }
+
+        /// <summary>
+        /// Retrieves the play order of the member.
+        /// </summary>
+        /// <param name="playlistId">The playlist id.</param>
+        /// <param name="memberId">The member id of the playlist.</param>
+        /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentOutOfRangeException">
+        ///     <paramref name="playlistId"/> is less than or equal to zero.\n
+        ///     -or-\n
+        ///     <paramref name="memberId"/> is less than or equal to zero.
+        /// </exception>
+        public int GetPlayOrder(int playlistId, int memberId)
+        {
+            ValidateDatabase();
+
+            if (playlistId <= 0)
+            {
+                throw new ArgumentOutOfRangeException(nameof(playlistId), playlistId,
+                    "Playlist id can't be less than or equal to zero.");
+            }
+
+            if (memberId <= 0)
+            {
+                throw new ArgumentOutOfRangeException(nameof(memberId), memberId,
+                    "Member id can't be less than or equal to zero.");
+            }
+
+            Interop.Playlist.GetPlayOrder(playlistId, memberId, out var order).ThrowIfError("Failed to query");
+
+            return order;
+        }
+
+        /// <summary>
+        /// Deletes a playlist from the database.
+        /// </summary>
+        /// <privilege>http://tizen.org/privilege/content.write</privilege>
+        /// <param name="playlistId">The playlist id to delete.</param>
+        /// <returns>true if the matched record was found and deleted, otherwise false.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="playlistId"/> is less than or equal to zero.</exception>
+        /// <exception cref="UnauthorizedAccessException">The caller has no required privilege.</exception>
+        public bool Delete(int playlistId)
+        {
+            ValidateDatabase();
+
+            if (playlistId <= 0)
+            {
+                throw new ArgumentOutOfRangeException(nameof(playlistId), playlistId,
+                    "Playlist id can't be less than or equal to zero.");
+            }
+
+            if (Select(playlistId) == null)
+            {
+                return false;
+            }
+
+            CommandHelper.Delete(Interop.Playlist.Delete, playlistId);
+            return true;
+        }
+
+        /// <summary>
+        /// Inserts a playlist into the database from the specified m3u file.
+        /// </summary>
+        /// <remarks>
+        ///     If you want to access internal storage, you should add privilege http://tizen.org/privilege/mediastorage.\n
+        ///     If you want to access external storage, you should add privilege http://tizen.org/privilege/externalstorage.
+        /// </remarks>
+        /// <privilege>http://tizen.org/privilege/content.write</privilege>
+        /// <privilege>http://tizen.org/privilege/mediastorage</privilege>
+        /// <privilege>http://tizen.org/privilege/externalstorage</privilege>
+        /// <param name="name">The name of playlist.</param>
+        /// <param name="path">The path to a m3u file to import.</param>
+        /// <returns>The <see cref="Playlist"/> instance that contains the record information inserted.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException">
+        ///     <paramref name="name"/> is null.\n
+        ///     -or-\n
+        ///     <paramref name="path"/> is null.
+        /// </exception>
+        /// <exception cref="ArgumentException">
+        ///     <paramref name="name"/> is a zero-length string.\n
+        ///     -or-\n
+        ///     <paramref name="path"/> is a zero-length string, contains only white space.
+        /// </exception>
+        /// <exception cref="FileNotFoundException"><paramref name="path"/> does not exists.</exception>
+        /// <exception cref="UnauthorizedAccessException">The caller has no required privilege.</exception>
+        public Playlist InsertFromFile(string name, string path)
+        {
+            ValidateDatabase();
+
+            if (name == null)
+            {
+                throw new ArgumentNullException(nameof(name));
+            }
+
+            if (name.Length == 0)
+            {
+                throw new ArgumentException("Playlist name can't be an empty string.");
+            }
+
+            ValidationUtil.ValidateNotNullOrEmpty(path, nameof(path));
+
+            if (File.Exists(path) == false)
+            {
+                throw new FileNotFoundException("The specified path does not exists.", path);
+            }
+
+            IntPtr handle = IntPtr.Zero;
+            Interop.Playlist.ImportFromFile(path, name, out handle).ThrowIfError("Failed to insert");
+
+            try
+            {
+                return new Playlist(handle);
+            }
+            finally
+            {
+                if (handle != IntPtr.Zero)
+                {
+                    Interop.Playlist.Destroy(handle);
+                }
+            }
+        }
+        /// <summary>
+        /// Exports a playlist to a m3u file.
+        /// </summary>
+        /// <remarks>
+        ///     If the file already exists in the file system, then it will be overwritten.\n
+        ///     \n
+        ///     If you want to access internal storage, you should add privilege http://tizen.org/privilege/mediastorage.\n
+        ///     If you want to access external storage, you should add privilege http://tizen.org/privilege/externalstorage.
+        /// </remarks>
+        /// <privilege>http://tizen.org/privilege/mediastorage</privilege>
+        /// <privilege>http://tizen.org/privilege/externalstorage</privilege>
+        /// <param name="playlistId">The playlist id to export.</param>
+        /// <param name="path">The path to a m3u file.</param>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="path"/> is a zero-length string, contains only white space.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="playlistId"/> is less than or equal to zero.</exception>
+        /// <exception cref="RecordNotFoundException">No matching playlist exists.</exception>
+        /// <exception cref="UnauthorizedAccessException">The caller has no required privilege.</exception>
+        public void ExportToFile(int playlistId, string path)
+        {
+            ValidateDatabase();
+
+            ValidationUtil.ValidateNotNullOrEmpty(path, nameof(path));
+
+            if (playlistId <= 0)
+            {
+                throw new ArgumentOutOfRangeException(nameof(playlistId), playlistId,
+                    "Playlist id can't be less than or equal to zero.");
+            }
+
+            IntPtr handle = IntPtr.Zero;
+            try
+            {
+                Interop.Playlist.GetPlaylistFromDb(playlistId, out handle).ThrowIfError("Failed to query");
+
+                if (handle == IntPtr.Zero)
+                {
+                    throw new RecordNotFoundException("No matching playlist exists.");
+                }
+
+                Interop.Playlist.ExportToFile(handle, path).ThrowIfError("Failed to export");
+            }
+            finally
+            {
+                if (handle != IntPtr.Zero)
+                {
+                    Interop.Playlist.Destroy(handle);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Inserts a playlist into the database with the specified name.
+        /// </summary>
+        /// <privilege>http://tizen.org/privilege/content.write</privilege>
+        /// <param name="name">The name of playlist.</param>
+        /// <returns>The <see cref="Playlist"/> instance that contains the record information inserted.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="name"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="name"/> is a zero-length string.</exception>
+        /// <exception cref="UnauthorizedAccessException">The caller has no required privilege.</exception>
+        public Playlist Insert(string name)
+        {
+            return Insert(name, null);
+        }
+
+        /// <summary>
+        /// Inserts a playlist into the database with the specified name and thumbnail path.
+        /// </summary>
+        /// <privilege>http://tizen.org/privilege/content.write</privilege>
+        /// <param name="name">The name of playlist.</param>
+        /// <param name="thumbnailPath">The path of thumbnail for playlist. This value can be null.</param>
+        /// <returns>The <see cref="Playlist"/> instance that contains the record information inserted.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="name"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="name"/> is a zero-length string.</exception>
+        /// <exception cref="UnauthorizedAccessException">The caller has no required privilege.</exception>
+        public Playlist Insert(string name, string thumbnailPath)
+        {
+            ValidateDatabase();
+
+            if (name == null)
+            {
+                throw new ArgumentNullException(nameof(name));
+            }
+
+            if (name.Length == 0)
+            {
+                throw new ArgumentException("Playlist name can't be an empty string.");
+            }
+
+            IntPtr handle = IntPtr.Zero;
+            Interop.Playlist.Create(out handle).ThrowIfError("Failed to insert");
+
+            try
+            {
+                Interop.Playlist.SetName(handle, name).ThrowIfError("Failed to insert");
+
+                if (thumbnailPath != null)
+                {
+                    Interop.Playlist.SetThumbnailPath(handle, thumbnailPath).ThrowIfError("Failed to insert");
+                }
+
+                Interop.Playlist.Insert(handle).ThrowIfError("Failed to insert");
+                return new Playlist(handle);
+            }
+            finally
+            {
+                if (handle != IntPtr.Zero)
+                {
+                    Interop.Playlist.Destroy(handle);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Retrieves the playlists.
+        /// </summary>
+        /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        public MediaDataReader<Playlist> Select()
+        {
+            return Select(null);
+        }
+
+        /// <summary>
+        /// Retrieves the playlists with <see cref="SelectArguments"/>.
+        /// </summary>
+        /// <param name="filter">The criteria to use to filter. This value can be null.</param>
+        /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        public MediaDataReader<Playlist> Select(SelectArguments filter)
+        {
+            ValidateDatabase();
+
+            return CommandHelper.Select(filter, Interop.Playlist.ForeachPlaylistFromDb,
+                Playlist.FromHandle);
+        }
+
+        /// <summary>
+        /// Retrieves the playlist with the specified playlist id.
+        /// </summary>
+        /// <param name="playlistId">The playlist id to select.</param>
+        /// <returns>The <see cref="Playlist"/> instance if the matched record was found in the database, otherwise null.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="playlistId"/> is less than or equal to zero.</exception>
+        public Playlist Select(int playlistId)
+        {
+            ValidateDatabase();
+
+            if (playlistId <= 0)
+            {
+                throw new ArgumentOutOfRangeException(nameof(playlistId), playlistId,
+                    "Playlist id can't be less than or equal to zero.");
+            }
+
+            IntPtr handle = IntPtr.Zero;
+
+            try
+            {
+                Interop.Playlist.GetPlaylistFromDb(playlistId, out handle).ThrowIfError("Failed to query");
+
+                if (handle == IntPtr.Zero)
+                {
+                    return null;
+                }
+
+                return new Playlist(handle);
+            }
+            finally
+            {
+                if (handle != IntPtr.Zero)
+                {
+                    Interop.Playlist.Destroy(handle);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Retrieves the number of media info of the playlist.
+        /// </summary>
+        /// <param name="playlistId">The playlist id to count media added to the playlist.</param>
+        /// <returns>The number of media info.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="playlistId"/> is less than or equal to zero.</exception>
+        public int CountMember(int playlistId)
+        {
+            return CountMember(playlistId, null);
+        }
+
+        /// <summary>
+        /// Retrieves the number of media info of the playlist with <see cref="CountArguments"/>.
+        /// </summary>
+        /// <param name="playlistId">The playlist id to count media added to the playlist.</param>
+        /// <param name="arguments">The criteria to use to filter. This value can be null.</param>
+        /// <returns>The number of media info.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="playlistId"/> is less than or equal to zero.</exception>
+        public int CountMember(int playlistId, CountArguments arguments)
+        {
+            ValidateDatabase();
+
+            if (playlistId <= 0)
+            {
+                throw new ArgumentOutOfRangeException(nameof(playlistId), playlistId,
+                    "Playlist id can't be less than or equal to zero.");
+            }
+
+            return CommandHelper.Count(Interop.Playlist.GetMediaCountFromDb, playlistId, arguments);
+
+        }
+
+        private static List<PlaylistMember> GetMembers(int playlistId, SelectArguments arguments)
+        {
+            using (var filter = QueryArguments.ToNativeHandle(arguments))
+            {
+                Exception caught = null;
+                List<PlaylistMember> list = new List<PlaylistMember>();
+
+                Interop.Playlist.ForeachMediaFromDb(playlistId, filter, (memberId, mediaInfoHandle, _) =>
+                {
+                    try
+                    {
+                        list.Add(new PlaylistMember(memberId, MediaInfo.FromHandle(mediaInfoHandle)));
+
+                        return true;
+                    }
+                    catch (Exception e)
+                    {
+                        caught = e;
+                        return false;
+                    }
+                }).ThrowIfError("Failed to query");
+
+                if (caught != null)
+                {
+                    throw caught;
+                }
+
+                return list;
+            }
+        }
+
+        /// <summary>
+        /// Retrieves the member id of the media in the playlist.
+        /// </summary>
+        /// <param name="playlistId">The playlist id.</param>
+        /// <param name="mediaId">The media id.</param>
+        /// <returns>The member id if the member was found in the playlist, otherwise -1.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="playlistId"/> is less than or equal to zero.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="mediaId"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="mediaId"/> is a zero-length string, contains only white space.</exception>
+        public int GetMemberId(int playlistId, string mediaId)
+        {
+            ValidateDatabase();
+
+            ValidationUtil.ValidateNotNullOrEmpty(mediaId, nameof(mediaId));
+
+            if (playlistId <= 0)
+            {
+                throw new ArgumentOutOfRangeException(nameof(playlistId), playlistId,
+                    "Playlist id can't be less than or equal to zero.");
+            }
+
+            var reader = SelectMember(playlistId, new SelectArguments()
+            {
+                FilterExpression = $"{MediaInfoColumns.Id}='{mediaId}'"
+            });
+            reader.Read();
+
+            return reader.Current?.MemberId ?? -1;
+        }
+
+        /// <summary>
+        /// Retrieves the media info of the playlist.
+        /// </summary>
+        /// <param name="playlistId">The playlist id to query with.</param>
+        /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="playlistId"/> is less than or equal to zero.</exception>
+        public MediaDataReader<PlaylistMember> SelectMember(int playlistId)
+        {
+            return SelectMember(playlistId, null);
+        }
+
+        /// <summary>
+        /// Retrieves the media info of the playlist with <see cref="SelectArguments"/>.
+        /// </summary>
+        /// <param name="playlistId">The playlist id to query with.</param>
+        /// <param name="filter">The criteria to use to filter. This value can be null.</param>
+        /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="playlistId"/> is less than or equal to zero.</exception>
+        public MediaDataReader<PlaylistMember> SelectMember(int playlistId, SelectArguments filter)
+        {
+            ValidateDatabase();
+
+            if (playlistId <= 0)
+            {
+                throw new ArgumentOutOfRangeException(nameof(playlistId), playlistId,
+                    "Playlist id can't be less than or equal to zero.");
+            }
+
+            return new MediaDataReader<PlaylistMember>(GetMembers(playlistId, filter));
+        }
+
+        /// <summary>
+        /// Updates a playlist with the specified values.
+        /// </summary>
+        /// <privilege>http://tizen.org/privilege/content.write</privilege>
+        /// <param name="playlistId">The playlist id to update.</param>
+        /// <param name="values">The values for update.</param>
+        /// <returns>true if the matched record was found and updated, otherwise false.</returns>
+        /// <remarks>Only values set in <see cref="PlaylistUpdateValues"/> are updated.</remarks>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="values"/> is null.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="playlistId"/> is less than or equal to zero.</exception>
+        /// <exception cref="UnauthorizedAccessException">The caller has no required privilege.</exception>
+        public bool Update(int playlistId, PlaylistUpdateValues values)
+        {
+            ValidateDatabase();
+
+            if (playlistId <= 0)
+            {
+                throw new ArgumentOutOfRangeException(nameof(playlistId), playlistId,
+                    "Playlist id can't be less than or equal to zero.");
+            }
+
+            if (values == null)
+            {
+                throw new ArgumentNullException(nameof(values));
+            }
+
+            if (CommandHelper.Count(
+                Interop.Playlist.GetPlaylistCount, $"{PlaylistColumns.Id}={playlistId}") == 0)
+            {
+                return false;
+            }
+
+            Interop.Playlist.Create(out var handle).ThrowIfError("Failed to update");
+
+            try
+            {
+                if (values.Name != null)
+                {
+                    Interop.Playlist.SetName(handle, values.Name).ThrowIfError("Failed to update");
+                }
+
+                if (values.ThumbnailPath != null)
+                {
+                    Interop.Playlist.SetThumbnailPath(handle, values.ThumbnailPath).ThrowIfError("Failed to update");
+                }
+
+                Interop.Playlist.Update(playlistId, handle).ThrowIfError("Failed to update");
+                return true;
+            }
+            finally
+            {
+                if (handle != IntPtr.Zero)
+                {
+                    Interop.Playlist.Destroy(handle);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Adds media to a playlist.
+        /// </summary>
+        /// <param name="playlistId">The playlist id that the media will be added to.</param>
+        /// <param name="mediaId">The media id to add to the playlist.</param>
+        /// <returns>true if the matched record was found and updated, otherwise false.</returns>
+        /// <remarks>The invalid media id will be ignored.</remarks>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="mediaId"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="mediaId"/> is a zero-length string, contains only white space.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="playlistId"/> is less than or equal to zero.</exception>
+        public bool AddMember(int playlistId, string mediaId)
+        {
+            ValidationUtil.ValidateNotNullOrEmpty(mediaId, nameof(mediaId));
+
+            return AddMembers(playlistId, new string[] { mediaId });
+        }
+
+        /// <summary>
+        /// Adds a media set to a playlist.
+        /// </summary>
+        /// <param name="playlistId">The playlist id that the media will be added to.</param>
+        /// <param name="mediaIds">The collection of media id to add to the playlist.</param>
+        /// <returns>true if the matched record was found and updated, otherwise false.</returns>
+        /// <remarks>The invalid media ids will be ignored.</remarks>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="mediaIds"/> is null.</exception>
+        /// <exception cref="ArgumentException">
+        ///     <paramref name="mediaIds"/> has no element.\n
+        ///     -or-\n
+        ///     <paramref name="mediaIds"/> contains null value.\n
+        ///     -or-\n
+        ///     <paramref name="mediaIds"/> contains a zero-length string or white space.\n
+        /// </exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="playlistId"/> is less than or equal to zero.</exception>
+        public bool AddMembers(int playlistId, IEnumerable<string> mediaIds)
+        {
+            ValidateDatabase();
+
+            if (playlistId <= 0)
+            {
+                throw new ArgumentOutOfRangeException(nameof(playlistId), playlistId,
+                    "Playlist id can't be less than or equal to zero.");
+            }
+
+            if (mediaIds == null)
+            {
+                throw new ArgumentNullException(nameof(mediaIds));
+            }
+
+            if (mediaIds.Count() == 0)
+            {
+                throw new ArgumentException("mediaIds has no element.", nameof(mediaIds));
+            }
+
+            if (CommandHelper.Count(
+                Interop.Playlist.GetPlaylistCount, $"{PlaylistColumns.Id}={playlistId}") == 0)
+            {
+                return false;
+            }
+
+            IntPtr handle = IntPtr.Zero;
+            Interop.Playlist.Create(out handle).ThrowIfError("Failed to add member");
+
+            try
+            {
+                foreach (var mediaId in mediaIds)
+                {
+                    if (mediaId == null)
+                    {
+                        throw new ArgumentException("Media id should not be null.", nameof(mediaIds));
+                    }
+
+                    if (string.IsNullOrWhiteSpace(mediaId))
+                    {
+                        throw new ArgumentException("Media id should not be empty.", nameof(mediaId));
+                    }
+
+                    Interop.Playlist.AddMedia(handle, mediaId).ThrowIfError("Failed to add member");
+                }
+
+                Interop.Playlist.Update(playlistId, handle).ThrowIfError("Failed to add member");
+                return true;
+            }
+            finally
+            {
+                if (handle != IntPtr.Zero)
+                {
+                    Interop.Playlist.Destroy(handle);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Removes a member from a playlist.
+        /// </summary>
+        /// <param name="playlistId">The playlist id.</param>
+        /// <param name="memberId">The member id to be removed.</param>
+        /// <returns>true if the matched record was found and updated, otherwise false.</returns>
+        /// <remarks>The invalid id will be ignored.</remarks>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentOutOfRangeException">
+        ///     <paramref name="playlistId"/> is less than or equal to zero.\n
+        ///     -or-\n
+        ///     <paramref name="memberId"/> is less than or equal to zero.\n
+        /// </exception>
+        public bool RemoveMember(int playlistId, int memberId)
+        {
+            if (memberId <= 0)
+            {
+                throw new ArgumentOutOfRangeException(nameof(memberId), memberId,
+                    "Member id can't be less than or equal to zero.");
+            }
+
+            return RemoveMembers(playlistId, new int[] { memberId });
+        }
+
+        /// <summary>
+        /// Removes a media set from a playlist.
+        /// </summary>
+        /// <param name="playlistId">The playlist id.</param>
+        /// <param name="memberIds">The collection of member id to remove from to the playlist.</param>
+        /// <returns>true if the matched record was found and updated, otherwise false.</returns>
+        /// <remarks>The invalid ids will be ignored.</remarks>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="memberIds"/> is null.</exception>
+        /// <exception cref="ArgumentException">
+        ///     <paramref name="memberIds"/> has no element.\n
+        ///     -or-\n
+        ///     <paramref name="memberIds"/> contains a value which is less than or equal to zero.
+        /// </exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="playlistId"/> is less than or equal to zero.</exception>
+        public bool RemoveMembers(int playlistId, IEnumerable<int> memberIds)
+        {
+            ValidateDatabase();
+
+            if (playlistId <= 0)
+            {
+                throw new ArgumentOutOfRangeException(nameof(playlistId), playlistId,
+                    "Playlist id can't be less than or equal to zero.");
+            }
+
+            if (memberIds == null)
+            {
+                throw new ArgumentNullException(nameof(memberIds));
+            }
+
+            if (memberIds.Count() == 0)
+            {
+                throw new ArgumentException("memberIds has no element.", nameof(memberIds));
+            }
+
+            if (CommandHelper.Count(
+                Interop.Playlist.GetPlaylistCount, $"{PlaylistColumns.Id}={playlistId}") == 0)
+            {
+                return false;
+            }
+
+            IntPtr handle = IntPtr.Zero;
+            Interop.Playlist.Create(out handle).ThrowIfError("Failed to add member");
+
+            try
+            {
+                foreach (var memberId in memberIds)
+                {
+                    if (memberId <= 0)
+                    {
+                        throw new ArgumentException(nameof(memberIds),
+                            "Member id can't be less than or equal to zero.");
+                    }
+
+                    Interop.Playlist.RemoveMedia(handle, memberId).ThrowIfError("Failed to add member");
+                }
+
+                Interop.Playlist.Update(playlistId, handle).ThrowIfError("Failed to add member");
+                return true;
+            }
+            finally
+            {
+                if (handle != IntPtr.Zero)
+                {
+                    Interop.Playlist.Destroy(handle);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Updates a play order of a playlist.
+        /// </summary>
+        /// <param name="playlistId">The playlist id.</param>
+        /// <param name="playOrder">The <see cref="PlayOrder"/> to apply.</param>
+        /// <returns>true if the matched record was found and updated, otherwise false.</returns>
+        /// <remarks>The <see cref="PlayOrder.MemberId"/> that is invalid will be ignored.</remarks>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="playOrder"/> is null.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="playlistId"/> is less than or equal to zero.</exception>
+        public bool UpdatePlayOrder(int playlistId, PlayOrder playOrder)
+        {
+            if (playOrder == null)
+            {
+                throw new ArgumentNullException(nameof(playOrder));
+            }
+            return UpdatePlayOrders(playlistId, new PlayOrder[] { playOrder });
+        }
+
+        /// <summary>
+        /// Updates play orders of a playlist.
+        /// </summary>
+        /// <param name="playlistId">The playlist id.</param>
+        /// <param name="orders">The collection of <see cref="PlayOrder"/> to apply.</param>
+        /// <returns>true if the matched record was found and updated, otherwise false.</returns>
+        /// <remarks>The <see cref="PlayOrder.MemberId"/> that is invalid will be ignored.</remarks>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="orders"/> is null.</exception>
+        /// <exception cref="ArgumentException">
+        ///     <paramref name="orders"/> has no element.\n
+        ///     -or-\n
+        ///     <paramref name="orders"/> contains a null value.
+        /// </exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="playlistId"/> is less than or equal to zero.</exception>
+        public bool UpdatePlayOrders(int playlistId, IEnumerable<PlayOrder> orders)
+        {
+            ValidateDatabase();
+
+            if (playlistId <= 0)
+            {
+                throw new ArgumentOutOfRangeException(nameof(playlistId), playlistId,
+                    "Playlist id can't be less than or equal to zero.");
+            }
+
+            if (orders == null)
+            {
+                throw new ArgumentNullException(nameof(orders));
+            }
+
+            if (orders.Count() == 0)
+            {
+                throw new ArgumentException("memberIds has no element.", nameof(orders));
+            }
+
+            if (CommandHelper.Count(
+                Interop.Playlist.GetPlaylistCount, $"{PlaylistColumns.Id}={playlistId}") == 0)
+            {
+                return false;
+            }
+
+            IntPtr handle = IntPtr.Zero;
+            Interop.Playlist.Create(out handle).ThrowIfError("Failed to add member");
+
+            try
+            {
+                foreach (var order in orders)
+                {
+                    if (order == null)
+                    {
+                        throw new ArgumentException(nameof(orders),
+                            "orders should not contain null value.");
+                    }
+                    Interop.Playlist.SetPlayOrder(handle, order.MemberId, order.Value).ThrowIfError("Failed to add member");
+                }
+
+                Interop.Playlist.Update(playlistId, handle).ThrowIfError("Failed to add member");
+                return true;
+            }
+            finally
+            {
+                if (handle != IntPtr.Zero)
+                {
+                    Interop.Playlist.Destroy(handle);
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/PlaylistMember.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/PlaylistMember.cs
new file mode 100644 (file)
index 0000000..e0d047c
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Content.MediaContent
+{
+    /// <summary>
+    /// Represents a member of <see cref="Playlist"/>.
+    /// </summary>
+    public class PlaylistMember
+    {
+        /// <summary>
+        /// Gets the member id.
+        /// </summary>
+        /// <value>The member id of playlist.</value>
+        public int MemberId { get; }
+
+        /// <summary>
+        /// Gets the media info of the member.
+        /// </summary>
+        /// <value>The <see cref="MediaInfo"/> of the member.</value>
+        public MediaInfo MediaInfo { get; }
+
+        internal PlaylistMember(int memberId, MediaInfo mediaInfo)
+        {
+            MemberId = memberId;
+            MediaInfo = mediaInfo;
+        }
+    }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/QueryArguments.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/QueryArguments.cs
new file mode 100644 (file)
index 0000000..b249158
--- /dev/null
@@ -0,0 +1,282 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Diagnostics;
+using FilterHandle = Interop.FilterHandle;
+
+namespace Tizen.Content.MediaContent
+{
+    /// <summary>
+    /// Base class for query arguments.
+    /// </summary>
+    /// <remarks>
+    /// A filter is required for filtering information associated with Album, Folder, Tag, Bookmark, Playlist
+    /// and MediaInfo on basis of details like limit, order and condition.
+    /// </remarks>
+    public class QueryArguments
+    {
+        private string _filter;
+
+        /// <summary>
+        /// Gets or sets the filtering expression that is applied.
+        /// </summary>
+        /// <value>A string that represents a filtering expression applied when data is retrieved.</value>
+        /// <remarks>
+        /// Expressions for the filter can be one of the following forms:
+        /// <list>
+        /// <item><description>column = value</description></item>
+        /// <item><description>column > value</description></item>
+        /// <item><description>column >= value</description></item>
+        /// <item><description>column < value</description></item>
+        /// <item><description>column <= value</description></item>
+        /// <item><description>value = column</description></item>
+        /// <item><description>value >= column</description></item>
+        /// <item><description>value < column</description></item>
+        /// <item><description>value <= column</description></item>
+        /// <item><description>column IN (value)</description></item>
+        /// <item><description>column IN(value-list)</description></item>
+        /// <item><description>column NOT IN(value)</description></item>
+        /// <item><description>column NOT IN(value-list)</description></item>
+        /// <item><description>column LIKE value</description></item>
+        /// <item><description>expression COLLATE NOCASE</description></item>
+        /// <item><description>expression COLLATE RTRIM</description></item>
+        /// <item><description>expression COLLATE LOCALIZED</description></item>
+        /// <item><description>expression1 AND expression2 OR expression3 ... </description></item>
+        /// </list>
+        ///
+        /// Note that if you want to set quotation(" ' " or " " ") as value of LIKE operator, you should use two times.(" '' " or " "" ").
+        /// And the optional ESCAPE clause is supported. Both percent symbol("%") and underscore symbol("_") are used in the LIKE pattern.
+        /// If these characters are used as value of LIKE operation, then the expression following the ESCAPE clause of sqlite will be ignored.\n
+        /// \n
+        /// For example,\n
+        /// - column LIKE('#%') ESCAPE('#') - "#" is escape character, it will be ignored.
+        /// </remarks>
+        /// <exception cref="ArgumentException"><paramref name="value"/> is a zero-length string, contains only white space.</exception>
+        /// <seealso cref="MediaInfoColumns"/>
+        /// <seealso cref="AlbumColumns"/>
+        /// <seealso cref="FolderColumns"/>
+        /// <seealso cref="PlaylistColumns"/>
+        /// <seealso cref="TagColumns"/>
+        /// <seealso cref="BookmarkColumns"/>
+        /// <seealso cref="FaceInfoColumns"/>
+        public string FilterExpression
+        {
+            get => _filter;
+            set
+            {
+                if (value != null)
+                {
+                    ValidationUtil.ValidateNotNullOrEmpty(value, nameof(value));
+                }
+
+                _filter = value;
+            }
+        }
+
+        private string _storageId;
+
+        /// <summary>
+        /// Gets or sets the storage id for the given filter.
+        /// You can use this property when you want to search items only in the specific storage.
+        /// </summary>
+        /// <value>The storage id to restrict storage to search, or null for all storages.</value>
+        /// <exception cref="ArgumentException"><paramref name="value"/> is a zero-length string, contains only white space.</exception>
+        public string StorageId
+        {
+            get => _storageId;
+            set
+            {
+                if (value != null)
+                {
+                    ValidationUtil.ValidateNotNullOrEmpty(value, nameof(value));
+                }
+
+                _storageId = value;
+            }
+        }
+
+        internal static FilterHandle ToNativeHandle(QueryArguments arguments)
+        {
+            if (arguments == null || arguments.IsEmpty())
+            {
+                return FilterHandle.Null;
+            }
+
+            Interop.Filter.Create(out var handle).ThrowIfError("Failed to apply arguments.");
+
+            try
+            {
+                arguments.FillHandle(handle);
+            }
+            catch (Exception)
+            {
+                handle.Dispose();
+                throw;
+            }
+
+            return handle;
+        }
+
+        internal static FilterHandle CreateNativeHandle(string filterExpression)
+        {
+            Debug.Assert(filterExpression != null);
+
+            Interop.Filter.Create(out var handle).ThrowIfError("Failed to apply arguments.");
+
+            Interop.Filter.SetCondition(handle, filterExpression, Collation.Default).
+                ThrowIfError("Failed to create filter handle.");
+
+            return handle;
+        }
+
+        internal virtual bool IsEmpty()
+        {
+            return StorageId == null && FilterExpression == null;
+        }
+
+        internal virtual void FillHandle(FilterHandle handle)
+        {
+            if (FilterExpression != null)
+            {
+                Interop.Filter.SetCondition(handle, FilterExpression, Collation.Default).
+                    ThrowIfError("Failed to create filter handle(condition)");
+            }
+
+            if (StorageId != null)
+            {
+                Interop.Filter.SetStorage(handle, StorageId).
+                    ThrowIfError("Failed to create filter handle(storage id)"); ;
+            }
+        }
+    }
+
+    /// <summary>
+    /// Provides the ability to filter the result of a Select command.
+    /// </summary>
+    /// <remarks>
+    /// A filter is required for filtering information associated with Album, Folder, Tag, Bookmark, Playlist
+    /// and MediaInfo.
+    /// </remarks>
+    public class SelectArguments : QueryArguments
+    {
+        private int _startRowIndex;
+
+        /// <summary>
+        /// Gets or sets the starting row position of a query(starting from zero).
+        /// </summary>
+        /// <value>An integer value that indicates the starting row position of a query.</value>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="value"/> is less than zero.\n</exception>
+        public int StartRowIndex
+        {
+            get => _startRowIndex;
+            set
+            {
+                if (value < 0)
+                {
+                    throw new ArgumentOutOfRangeException(nameof(value), value, "StartRowIndex can't be less than zero.");
+                }
+
+                _startRowIndex = value;
+            }
+        }
+
+        private int _totalRowCount;
+
+        /// <summary>
+        /// Gets or sets the number of rows to be retrieved.
+        /// </summary>
+        /// <value>An integer value that indicates the limit of rows of the result.</value>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="value"/> is less than zero.</exception>
+        public int TotalRowCount
+        {
+            get => _totalRowCount;
+            set
+            {
+                if (value < 0)
+                {
+                    throw new ArgumentOutOfRangeException(nameof(value), value, "TotalRowCount can't be less than zero.");
+                }
+
+                _totalRowCount = value;
+            }
+        }
+
+        private string _sortOrder;
+
+        /// <summary>
+        /// Gets or sets the sort order of the results.
+        /// </summary>
+        /// <value>The expression for the sort order.</value>
+        /// <remarks>
+        /// Expressions for the sort order can be:\n
+        /// column [COLLATE NOCASE/RTRIM/LOCALIZED] [ASC/DESC], column2 ...
+        /// </remarks>
+        /// <exception cref="ArgumentException"><paramref name="value"/> is a zero-length string, contains only white space.</exception>
+        /// <seealso cref="MediaInfoColumns"/>
+        /// <seealso cref="AlbumColumns"/>
+        /// <seealso cref="FolderColumns"/>
+        /// <seealso cref="PlaylistColumns"/>
+        /// <seealso cref="TagColumns"/>
+        /// <seealso cref="BookmarkColumns"/>
+        /// <seealso cref="FaceInfoColumns"/>
+        public string SortOrder
+        {
+            get => _sortOrder;
+            set
+            {
+                if (value != null)
+                {
+                    ValidationUtil.ValidateNotNullOrEmpty(value, nameof(value));
+                }
+
+                _sortOrder = value;
+            }
+        }
+
+        internal override bool IsEmpty()
+        {
+            return base.IsEmpty() && StartRowIndex == 0 && TotalRowCount == 0 && SortOrder == null;
+        }
+
+        internal override void FillHandle(FilterHandle handle)
+        {
+            base.FillHandle(handle);
+
+            if (StartRowIndex != 0 || TotalRowCount != 0)
+            {
+                Interop.Filter.SetOffset(handle, StartRowIndex, TotalRowCount).
+                    ThrowIfError("Failed to create filter handle(limit)");
+            }
+
+            if (SortOrder != null)
+            {
+                Interop.Filter.SetOrder(handle, SortOrder).ThrowIfError("Failed to create filter handle(order)");
+            }
+        }
+    }
+
+    /// <summary>
+    /// Provides the ability to filter the result of a Count command.
+    /// </summary>
+    /// <remarks>
+    /// A filter is required for filtering information associated with Album, Folder, Tag, Bookmark, Playlist
+    /// and MediaInfo.
+    /// </remarks>
+    public class CountArguments : QueryArguments
+    {
+    }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/RecordNotFoundException.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/RecordNotFoundException.cs
new file mode 100644 (file)
index 0000000..452fb0f
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Content.MediaContent
+{
+    /// <summary>
+    /// The exception that is thrown when no record is found in the database.
+    /// </summary>
+    public class RecordNotFoundException : Exception
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="RecordNotFoundException"/> class.
+        /// </summary>
+        public RecordNotFoundException() : base("No record found.")
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="RecordNotFoundException"/> class with a specified error message.
+        /// </summary>
+        /// <param name="message">The message that describes the error.</param>
+        public RecordNotFoundException(string message) : base(message)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="RecordNotFoundException"/> class with a specified error message
+        /// and a reference to the inner exception that is the cause of this exception.
+        /// </summary>
+        /// <param name="message">The message that describes the error.</param>
+        /// <param name="innerException">The exception that is the cause of the current exception.</param>
+        public RecordNotFoundException(string message, Exception innerException) : base(message, innerException)
+        {
+        }
+    }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Rectangle.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Rectangle.cs
new file mode 100644 (file)
index 0000000..29d437b
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Content.MediaContent
+{
+    /// <summary>
+    /// Represents location of the object bounded by rectangle defined by
+    /// coordinates of top left corner, width and height.
+    /// </summary>
+    public struct Rectangle
+    {
+        /// <summary>
+        /// Initializes a new instance of the Rectangle with the specified values.
+        /// </summary>
+        /// <param name="x">The x-coordinate of the upper-left corner of the rectangle.</param>
+        /// <param name="y">The y-coordinate of the upper-left corner of the rectangle.</param>
+        /// <param name="width">The Width of the rectangle.</param>
+        /// <param name="height">The Height of the rectangle.</param>
+        public Rectangle(int x, int y, int width, int height)
+        {
+            X = x;
+            Y = y;
+            Width = width;
+            Height = height;
+        }
+
+        /// <summary>
+        /// Gets or sets the x-coordinate of the upper-left corner of the rectangle.
+        /// </summary>
+        /// <value>The x-coordinate of the upper-left edge of the rectangle.</value>
+        public int X { get; set; }
+
+        /// <summary>
+        /// Gets or sets the y-coordinate of the upper-left corner of the rectangle.
+        /// </summary>
+        /// <value>The y-coordinate of the upper-left edge of the rectangle.</value>
+        public int Y { get; set; }
+
+        /// <summary>
+        /// Gets or sets the width of the rectangle.
+        /// </summary>
+        /// <value>The width of the rectangle.</value>
+        public int Width { get; set; }
+
+        /// <summary>
+        /// Gets or sets the height of the rectangle.
+        /// </summary>
+        /// <value>The height of the rectangle.</value>
+        public int Height { get; set; }
+
+        /// <summary>
+        /// Gets the x-coordinate of the left edge of the rectangle.
+        /// </summary>
+        /// <value>The x-coordinate of the left edge of the rectangle.</value>
+        public int Left => X;
+
+        /// <summary>
+        /// Gets the y-coordinate of the top edge of the rectangle.
+        /// </summary>
+        /// <value>The y-coordinate of the top edge of the rectangle.</value>
+        public int Top => Y;
+
+        /// <summary>
+        /// Gets the x-coordinate of the right edge of the rectangle.
+        /// </summary>
+        /// <value>The x-coordinate of the right edge of the rectangle.</value>
+        public int Right => X + Width;
+
+        /// <summary>
+        /// Gets the y-coordinate of the bottom edge of the rectangle.
+        /// </summary>
+        /// <value>The y-coordinate of the bottom edge of the rectangle.</value>
+        public int Bottom => Y + Height;
+
+        /// <summary>
+        /// Returns a string representation of the rectangle.
+        /// </summary>
+        /// <returns>A string representation of the current rectangle.</returns>
+        public override string ToString() =>
+            $"X={X.ToString()}, Y={Y.ToString()}, Width={Width.ToString()}, Height={Height.ToString()}";
+
+        /// <summary>
+        /// Returns the hash code for this Rectangle structure.
+        /// </summary>
+        /// <returns>An integer that represents the hash code for this rectangle.</returns>
+        public override int GetHashCode() => new { X, Y, Width, Height }.GetHashCode();
+
+        /// <summary>
+        /// Tests whether obj is a Rectangle structure with the same location and size of this Rectangle structure.
+        /// </summary>
+        /// <param name="obj">A <see cref="Object"/> to compare.</param>
+        /// <returns>
+        /// true if obj is a Rectangle structure and its X, Y, Width and Height properties are
+        /// equal to the corresponding properties of this Rectangle structure; otherwise, false.
+        /// </returns>
+        public override bool Equals(object obj) => obj is Rectangle && this == (Rectangle)obj;
+
+        /// <summary>
+        /// Tests whether two Rectangle structures have equal location and size.
+        /// </summary>
+        /// <param name="rect1">A <see cref="Rectangle"/> to compare.</param>
+        /// <param name="rect2">A <see cref="Rectangle"/> to compare.</param>
+        /// <returns>true if the two Rectangle structures have equal X, Y, Width, and Height properties; otherwise, false.</returns>
+        public static bool operator ==(Rectangle rect1, Rectangle rect2)
+            => rect1.X == rect2.X && rect1.Y == rect2.Y && rect1.Width == rect2.Width && rect1.Height == rect2.Height;
+
+        /// <summary>
+        /// Tests whether two Rectangle structures differ in location or size.
+        /// </summary>
+        /// <param name="rect1">A <see cref="Rectangle"/> to compare.</param>
+        /// <param name="rect2">A <see cref="Rectangle"/> to compare.</param>
+        /// <returns>true if any of the X, Y, Width or Height properties of the two Rectangle structures are unequal; otherwise false.</returns>
+        public static bool operator !=(Rectangle rect1, Rectangle rect2) => !(rect1 == rect2);
+    }
+}
index b6935ef..840d673 100755 (executable)
-/*
-* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
-*
-* Licensed under the Apache License, Version 2.0 (the License);
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an AS IS BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 using System;
-using System.Collections.Generic;
-using System.Runtime.InteropServices;
-using System.Threading.Tasks;
 
 namespace Tizen.Content.MediaContent
 {
     /// <summary>
-    /// A Storage allows you to manage external storage.
-    /// The system generates the storage id when the external storage is added.And the system manages the media information in each of the storage by using storage id.
-    /// So you can get the information from the storage that you want to view.
+    /// Represents the storage information for media.
     /// </summary>
-    public class Storage : ContentCollection
+    /// <remarks>
+    /// The system generates the storage id when the external storage is added. and manages the media information
+    /// in each of the storage by using storage id.
+    /// </remarks>
+    public class Storage
     {
-        private IntPtr _storageHandle = IntPtr.Zero;
-        private IntPtr Handle
+        internal Storage(IntPtr handle)
         {
-            get
-            {
-                if (_storageHandle == IntPtr.Zero)
-                {
-                    throw new ObjectDisposedException(nameof(Storage));
-                }
-
-                return _storageHandle;
-            }
+            Path = InteropHelper.GetString(handle, Interop.Storage.GetPath);
+            Id = InteropHelper.GetString(handle, Interop.Storage.GetId);
+            Type = InteropHelper.GetValue<StorageType>(handle, Interop.Storage.GetType);
         }
-        /// <summary>
-        /// The storage id of the media storage
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string Id
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.Storage.GetId(Handle, out val), "Failed to get value");
 
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
+        internal static Storage FromHandle(IntPtr handle) => new Storage(handle);
 
         /// <summary>
-        /// The storage path of the media storage
+        /// Gets the id of the storage.
         /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string StoragePath
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.Storage.GetPath(Handle, out val), "Failed to get value");
-
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
+        /// <value>The unique id of the storage.</value>
+        public string Id { get; }
 
         /// <summary>
-        /// The storage name of the media storage
+        /// Gets the path of the storage.
         /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string Name
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.Storage.GetName(Handle, out val), "Failed to get value");
-
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
+        /// <value>The path of the storage.</value>
+        public string Path { get; }
 
         /// <summary>
-        /// The storage type of the media storage
+        /// Gets the type of the storage.
         /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public ContentStorageType StorageType
-        {
-            get
-            {
-                ContentStorageType storageType;
-                MediaContentValidator.ThrowIfError(
-                    Interop.Storage.GetType(Handle, out storageType), "Failed to get value");
-
-                return storageType;
-            }
-        }
-
-        internal Storage(IntPtr handle)
-        {
-            _storageHandle = handle;
-        }
-
-        /// <summary>
-        /// Gets the count of media files for the passed filter in the given storage from the media database.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="filter">ContentFilter used to match media content from the media database.</param>
-        /// <returns>The number of media contents matching the filter passed</returns>
-        public override int GetMediaInformationCount(ContentFilter filter)
-        {
-            int mediaCount;
-            IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
-            MediaContentValidator.ThrowIfError(
-                Interop.Storage.GetMediaCountFromDb(Id, handle, out mediaCount), "Failed to get count");
-
-            return mediaCount;
-        }
-
-        public override void Dispose()
-        {
-            if (_storageHandle != IntPtr.Zero)
-            {
-                Interop.Storage.Destroy(_storageHandle);
-                _storageHandle = IntPtr.Zero;
-            }
-        }
+        /// <value>The type of the storage.</value>
+        public StorageType Type { get; }
 
         /// <summary>
-        /// Iterates through the media files with an optional filter in the given storage from the media database.
-        /// This function gets all media files associated with the given storage and meeting desired filter option.
-        /// If NULL is passed to the filter, no filtering is applied.
+        /// Returns a string representation of the storage.
         /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="filter">ContentFilter used to match media content from the media database.</param>
-        /// <returns>List of content media items matching the passed filter</returns>
-        public override IEnumerable<MediaInformation> GetMediaInformations(ContentFilter filter)
-        {
-            List<MediaInformation> mediaContents = new List<MediaInformation>();
-
-            IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
-            Interop.Storage.MediaInfoCallback callback = (IntPtr mediaHandle, IntPtr data) =>
-            {
-                Interop.MediaInformation.SafeMediaInformationHandle newHandle;
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.Clone(out newHandle, mediaHandle), "Failed to clone media");
-
-                MediaContentType type;
-                Interop.MediaInformation.GetMediaType(newHandle, out type);
-                if (type == MediaContentType.Image)
-                {
-                    Interop.ImageInformation.SafeImageInformationHandle imageInfo;
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.GetImage(mediaHandle, out imageInfo), "Failed to get image information");
-
-                    mediaContents.Add(new ImageInformation(imageInfo, newHandle));
-                }
-                else if ((type == MediaContentType.Music) || (type == MediaContentType.Sound))
-                {
-                    Interop.AudioInformation.SafeAudioInformationHandle audioInfo;
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.GetAudio(mediaHandle, out audioInfo), "Failed to get audio information");
-
-                    mediaContents.Add(new AudioInformation(audioInfo, newHandle));
-                }
-                else if (type == MediaContentType.Video)
-                {
-                    Interop.VideoInformation.SafeVideoInformationHandle videoInfo;
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.GetVideo(mediaHandle, out videoInfo), "Failed to get video information");
-
-                    mediaContents.Add(new VideoInformation(videoInfo, newHandle));
-                }
-                else if (type == MediaContentType.Others)
-                {
-                    mediaContents.Add(new MediaInformation(newHandle));
-                }
-
-                return true;
-            };
-            MediaContentValidator.ThrowIfError(
-                Interop.Storage.ForeachMediaFromDb(Id, handle, callback, IntPtr.Zero), "Failed to get information");
-
-            return mediaContents;
-        }
+        /// <returns>A string representation of the current storage.</returns>
+        public override string ToString() =>
+            $"Id={Id}, Path={Path}, Type={Type}";
     }
 }
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/StorageCommand.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/StorageCommand.cs
new file mode 100644 (file)
index 0000000..6975660
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Content.MediaContent
+{
+    /// <summary>
+    /// Provides commands to manage external storages in the database.
+    /// </summary>
+    /// <remarks>
+    /// Internal storage is not managed.
+    /// </remarks>
+    /// <seealso cref="Storage"/>
+    public class StorageCommand : MediaCommand
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="StorageCommand"/> class with the specified <see cref="MediaDatabase"/>.
+        /// </summary>
+        /// <param name="database">A <see cref="MediaDatabase"/> that the commands run on.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="database"/> is null.</exception>
+        /// <exception cref="ObjectDisposedException"><paramref name="database"/> has already been disposed of.</exception>
+        public StorageCommand(MediaDatabase database) : base(database)
+        {
+        }
+
+        /// <summary>
+        /// Retrieves the number of storages.
+        /// </summary>
+        /// <returns>The number of storages.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        public int Count() => Count(arguments: null);
+
+        /// <summary>
+        /// Retrieves the number of storages with <see cref="CountArguments"/>.
+        /// </summary>
+        /// <param name="arguments">The criteria to use to filter. This value can be null.</param>
+        /// <returns>The number of storages filtered.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        public int Count(CountArguments arguments)
+        {
+            ValidateDatabase();
+
+            return CommandHelper.Count(Interop.Storage.GetStorageCountFromDb, arguments);
+        }
+
+        /// <summary>
+        /// Retrieves the storage with the specified id.
+        /// </summary>
+        /// <param name="storageId">The storage id to select.</param>
+        /// <returns>The <see cref="Storage"/> instance if the matched record was found in the database, otherwise null.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="storageId"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="storageId"/> is a zero-length string, contains only white space.</exception>
+        public Storage Select(string storageId)
+        {
+            ValidateDatabase();
+
+            ValidationUtil.ValidateNotNullOrEmpty(storageId, nameof(storageId));
+
+            IntPtr handle = IntPtr.Zero;
+
+            try
+            {
+                Interop.Storage.GetStorageInfoFromDb(storageId, out handle).ThrowIfError("Failed to query");
+
+                return handle == IntPtr.Zero ? null : new Storage(handle);
+            }
+            finally
+            {
+                if (handle != IntPtr.Zero)
+                {
+                    Interop.Storage.Destroy(handle);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Retrieves all the storages.
+        /// </summary>
+        /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        public MediaDataReader<Storage> Select() => Select(arguments: null);
+
+        /// <summary>
+        /// Retrieves the storages with <see cref="SelectArguments"/>.
+        /// </summary>
+        /// <param name="arguments">The criteria to use to filter. This value can be null.</param>
+        /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        public MediaDataReader<Storage> Select(SelectArguments arguments)
+        {
+            ValidateDatabase();
+
+            return CommandHelper.Select(arguments, Interop.Storage.ForeachStorageFromDb, Storage.FromHandle);
+        }
+
+        private bool Exists(string storageId)
+        {
+            ValidateDatabase();
+
+            ValidationUtil.ValidateNotNullOrEmpty(storageId, nameof(storageId));
+
+            return Count(new CountArguments { FilterExpression = $"{StorageColumns.Id}='{storageId}'" }) != 0;
+        }
+
+        /// <summary>
+        /// Retrieves the number of media info of the storage.
+        /// </summary>
+        /// <param name="storageId">The storage id.</param>
+        /// <returns>The number of media info.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="storageId"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="storageId"/> is a zero-length string, contains only white space.</exception>
+        public int CountMedia(string storageId) => CountMedia(storageId, null);
+
+        /// <summary>
+        /// Retrieves the number of media info of the storage with <see cref="CountArguments"/>.
+        /// </summary>
+        /// <param name="storageId">The storage id to query with.</param>
+        /// <param name="arguments">The criteria to use to filter. This value can be null.</param>
+        /// <returns>The number of media info.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="storageId"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="storageId"/> is a zero-length string, contains only white space.</exception>
+        public int CountMedia(string storageId, CountArguments arguments)
+        {
+            if (Exists(storageId) == false)
+            {
+                return 0;
+            }
+
+            return CommandHelper.Count(Interop.Storage.GetMediaCountFromDb, storageId, arguments);
+        }
+
+        /// <summary>
+        /// Retrieves the media info of the storage.
+        /// </summary>
+        /// <param name="storageId">The storage id.</param>
+        /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="storageId"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="storageId"/> is a zero-length string, contains only white space.</exception>
+        public MediaDataReader<MediaInfo> SelectMedia(string storageId) => SelectMedia(storageId, null);
+
+        /// <summary>
+        /// Retrieves the media info of the storage with <see cref="SelectArguments"/>.
+        /// </summary>
+        /// <param name="storageId">The storage id.</param>
+        /// <param name="filter">The criteria to use to filter. This value can be null.</param>
+        /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="storageId"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="storageId"/> is a zero-length string, contains only white space.</exception>
+        public MediaDataReader<MediaInfo> SelectMedia(string storageId, SelectArguments filter)
+        {
+            if (Exists(storageId) == false)
+            {
+                return new MediaDataReader<MediaInfo>(new MediaInfo[0]);
+            }
+
+            return CommandHelper.SelectMedia(Interop.Storage.ForeachMediaFromDb, storageId, filter);
+        }
+
+    }
+}
index 181b763..43dd24e 100755 (executable)
-/*
-* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
-*
-* Licensed under the Apache License, Version 2.0 (the License);
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an AS IS BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
 using System;
-using System.Collections.Generic;
-using System.Runtime.InteropServices;
-using System.Threading.Tasks;
 
 namespace Tizen.Content.MediaContent
 {
     /// <summary>
-    /// A Tag is a special piece of information that may be associated with media content items.
-    /// Tagging allows a user to organize large number of items into logical groups providing a simplified and faster way of accessing media content items.
+    /// Represents a special piece of information that may be associated with media.\n
+    /// Tagging allows a user to organize large number of items into logical groups providing
+    /// a simplified and faster way of accessing media items.
     /// </summary>
-    public class Tag : ContentCollection
+    public class Tag
     {
-        private IntPtr _tagHandle = IntPtr.Zero;
-        private string _tagName = "";
-
-        internal IntPtr Handle
+        internal Tag(IntPtr handle)
         {
-            get
-            {
-                if (_tagHandle == IntPtr.Zero)
-                {
-                    throw new ObjectDisposedException(nameof(Tag));
-                }
-
-                return _tagHandle;
-            }
-
-            set
-            {
-                _tagHandle = value;
-            }
-        }
-        /// <summary>
-        /// The ID of the media tag
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public int Id
-        {
-            get
-            {
-                int id;
-                MediaContentValidator.ThrowIfError(
-                    Interop.Tag.GetTagId(Handle, out id), "Failed to get value");
-                return id;
-            }
+            Name = InteropHelper.GetString(handle, Interop.Tag.GetName);
+            Id = InteropHelper.GetValue<int>(handle, Interop.Tag.GetId);
         }
 
         /// <summary>
-        /// The name of the tag
+        /// Gets the id of the tag.
         /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string Name
-        {
-            get
-            {
-                return _tagName;
-            }
-
-            set
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.Tag.SetName(Handle, value), "Failed to set value");
-                _tagName = value;
-            }
-        }
-
-        internal Tag(IntPtr tagHandle)
-        {
-            _tagHandle = tagHandle;
-            IntPtr val = IntPtr.Zero;
-            try
-            {
-                MediaContentValidator.ThrowIfError(
-                    Interop.Tag.GetName(Handle, out val), "Failed to get value");
-                _tagName = Marshal.PtrToStringAnsi(val);
-            }
-            finally
-            {
-                Interop.Libc.Free(val);
-            }
-        }
+        /// <value>The unique id of the tag.</value>
+        public int Id { get; }
 
         /// <summary>
-        /// Creates a Tag object which can be inserted to the media database using ContentManager:InsertToDatabaseAsync(ContentCollection)
+        /// Gets the name of the tag.
         /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="tagName">The name of the media tag</param>
-        public Tag(string tagName)
-        {
-            _tagName = tagName;
-        }
+        /// <value>The name of the tag.</value>
+        public string Name { get; }
 
-        /// <summary>
-        /// Adds a new media info to the tag.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="mediaContent">The media info which is added</param>
-        public void AddItem(MediaInformation mediaContent)
-        {
-            MediaContentValidator.ThrowIfError(
-                Interop.Tag.AddMedia(Handle, mediaContent.MediaId), "Failed to add item");
-        }
+        internal static Tag FromHandle(IntPtr handle) => new Tag(handle);
 
         /// <summary>
-        /// Removes the media info from the given tag.
+        /// Returns a string representation of the tag.
         /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="mediaContent">The media info which is removed</param>
-        public void RemoveItem(MediaInformation mediaContent)
-        {
-            MediaContentValidator.ThrowIfError(
-                Interop.Tag.RemoveMedia(Handle, mediaContent.MediaId), "Failed to remove item");
-        }
+        /// <returns>A string representation of the current tag.</returns>
+        public override string ToString() => $"Id={Id}, Name={Name}";
 
-        /// <summary>
-        /// Gets the number of media files for the passed filter in the given tag from the media database.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="filter">ContentFilter used to match media content from the media database.</param>
-        /// <returns>The number of media contents matching the filter passed</returns>
-        public override int GetMediaInformationCount(ContentFilter filter)
-        {
-            int mediaCount;
-            IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
-            MediaContentValidator.ThrowIfError(
-                Interop.Tag.GetMediaCountFromDb(Id, handle, out mediaCount), "Failed to get count");
-
-            return mediaCount;
-        }
-
-        public override void Dispose()
-        {
-            if (_tagHandle != IntPtr.Zero)
-            {
-                Interop.Tag.Destroy(_tagHandle);
-                _tagHandle = IntPtr.Zero;
-            }
-        }
-
-        /// <summary>
-        /// Iterates through media items for a given tag from the media database.
-        /// This function gets all media items associated with a given tag and meeting a desired filter.
-        /// If NULL is passed to the filter, no filtering is applied.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="filter">ContentFilter used to match media content from the media database.</param>
-        /// <returns>List of content media items matching the passed filter</returns>
-        public override IEnumerable<MediaInformation> GetMediaInformations(ContentFilter filter)
-        {
-            List<MediaInformation> mediaContents = new List<MediaInformation>();
-            IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
-
-            Interop.Tag.MediaInfoCallback callback = (IntPtr mediaHandle, IntPtr data) =>
-            {
-                Interop.MediaInformation.SafeMediaInformationHandle newHandle;
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaInformation.Clone(out newHandle, mediaHandle), "Failed to clone media");
-
-                MediaContentType type;
-                Interop.MediaInformation.GetMediaType(newHandle, out type);
-                if (type == MediaContentType.Image)
-                {
-                    Interop.ImageInformation.SafeImageInformationHandle imageInfo;
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.GetImage(mediaHandle, out imageInfo), "Failed to get image information");
-
-                    mediaContents.Add(new ImageInformation(imageInfo, newHandle));
-                }
-                else if ((type == MediaContentType.Music) || (type == MediaContentType.Sound))
-                {
-                    Interop.AudioInformation.SafeAudioInformationHandle audioInfo;
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.GetAudio(mediaHandle, out audioInfo), "Failed to get audio information");
-
-                    mediaContents.Add(new AudioInformation(audioInfo, newHandle));
-                }
-                else if (type == MediaContentType.Video)
-                {
-                    Interop.VideoInformation.SafeVideoInformationHandle videoInfo;
-                    MediaContentValidator.ThrowIfError(
-                        Interop.MediaInformation.GetVideo(mediaHandle, out videoInfo), "Failed to get video information");
-
-                    mediaContents.Add(new VideoInformation(videoInfo, newHandle));
-                }
-                else if (type == MediaContentType.Others)
-                {
-                    mediaContents.Add(new MediaInformation(newHandle));
-                }
-
-                return true;
-            };
-
-            MediaContentValidator.ThrowIfError(
-                Interop.Tag.ForeachMediaFromDb(Id, handle, callback, IntPtr.Zero), "Failed to get information");
-
-            return mediaContents;
-        }
     }
 }
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/TagCommand.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/TagCommand.cs
new file mode 100644 (file)
index 0000000..37730ec
--- /dev/null
@@ -0,0 +1,471 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Tizen.Content.MediaContent
+{
+    /// <summary>
+    /// Provides commands to manage tags in the database.
+    /// </summary>
+    /// <seealso cref="Tag"/>
+    public class TagCommand : MediaCommand
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="TagCommand"/> class with the specified <see cref="MediaDatabase"/>.
+        /// </summary>
+        /// <param name="database">A <see cref="MediaDatabase"/> that the commands run on.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="database"/> is null.</exception>
+        /// <exception cref="ObjectDisposedException"><paramref name="database"/> has already been disposed of.</exception>
+        public TagCommand(MediaDatabase database) : base(database)
+        {
+        }
+
+        /// <summary>
+        /// Retrieves the number of tags.
+        /// </summary>
+        /// <returns>The number of tags.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        public int Count()
+        {
+            return Count(arguments: null);
+        }
+
+        /// <summary>
+        /// Retrieves the number of tags with <see cref="CountArguments"/>.
+        /// </summary>
+        /// <param name="arguments">The criteria to use to filter. This value can be null.</param>
+        /// <returns>The number of tags filtered.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        public int Count(CountArguments arguments)
+        {
+            ValidateDatabase();
+
+            return CommandHelper.Count(Interop.Tag.GetTagCount, arguments);
+        }
+
+
+        /// <summary>
+        /// Deletes a tag from the database.
+        /// </summary>
+        /// <privilege>http://tizen.org/privilege/content.write</privilege>
+        /// <param name="tagId">The tag id to delete.</param>
+        /// <returns>true if the matched record was found and deleted, otherwise false.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="tagId"/> is less than or equal to zero.</exception>
+        /// <exception cref="UnauthorizedAccessException">The caller has no required privilege.</exception>
+        public bool Delete(int tagId)
+        {
+            ValidateDatabase();
+
+            if (tagId <= 0)
+            {
+                throw new ArgumentOutOfRangeException(nameof(tagId), tagId,
+                    "Tag id can't be less than or equal to zero.");
+            }
+
+            if (CommandHelper.Count(Interop.Tag.GetTagCount, $"{TagColumns.Id}={tagId}") == 0)
+            {
+                return false;
+            }
+
+            CommandHelper.Delete(Interop.Tag.Delete, tagId);
+            return true;
+        }
+
+
+        /// <summary>
+        /// Inserts a tag into the database with the specified name.
+        /// </summary>
+        /// <privilege>http://tizen.org/privilege/content.write</privilege>
+        /// <param name="name">The name of tag.</param>
+        /// <returns>The <see cref="Tag"/> instance that contains the record information inserted.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="name"/> is null.</exception>
+        /// <exception cref="UnauthorizedAccessException">The caller has no required privilege.</exception>
+        public Tag Insert(string name)
+        {
+            ValidateDatabase();
+
+            if (name == null)
+            {
+                throw new ArgumentNullException(nameof(name));
+            }
+
+            if (name.Length == 0)
+            {
+                throw new ArgumentException("Tag name can't be an empty string.");
+            }
+
+            Interop.Tag.Insert(name, out var handle).ThrowIfError("Failed to insert a new tag");
+
+            try
+            {
+                return new Tag(handle);
+            }
+            finally
+            {
+                Interop.Tag.Destroy(handle);
+            }
+        }
+
+        /// <summary>
+        /// Updates a tag with the specified name.
+        /// </summary>
+        /// <privilege>http://tizen.org/privilege/content.write</privilege>
+        /// <param name="tagId">The tag id to update.</param>
+        /// <param name="name">The new name.</param>
+        /// <returns>true if the matched record was found and updated, otherwise false.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="name"/> is null.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="tagId"/> is less than or equal to zero.</exception>
+        /// <exception cref="UnauthorizedAccessException">The caller has no required privilege.</exception>
+        public bool UpdateName(int tagId, string name)
+        {
+            ValidateDatabase();
+
+            if (tagId <= 0)
+            {
+                throw new ArgumentOutOfRangeException(nameof(tagId), tagId,
+                    "Tag id can't be less than or equal to zero.");
+            }
+
+            if (name == null)
+            {
+                throw new ArgumentNullException(nameof(name));
+            }
+
+            if (CommandHelper.Count(Interop.Tag.GetTagCount, $"{TagColumns.Id}={tagId}") == 0)
+            {
+                return false;
+            }
+
+            Interop.Tag.Create(out var handle).ThrowIfError("Failed to update");
+
+            try
+            {
+                Interop.Tag.SetName(handle, name).ThrowIfError("Failed to update");
+                Interop.Tag.Update(tagId, handle).ThrowIfError("Failed to update");
+
+                return true;
+            }
+            finally
+            {
+                Interop.Tag.Destroy(handle);
+            }
+        }
+
+        /// <summary>
+        /// Retrieves the tag with the specified id.
+        /// </summary>
+        /// <param name="tagId">The tag id to select.</param>
+        /// <returns>The <see cref="Tag"/> instance if the matched record was found in the database, otherwise null.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="tagId"/> is less than or equal to zero.</exception>
+        public Tag Select(int tagId)
+        {
+            ValidateDatabase();
+
+            if (tagId <= 0)
+            {
+                throw new ArgumentOutOfRangeException(nameof(tagId), tagId,
+                    "Tag id can't be less than or equal to zero.");
+            }
+
+            IntPtr handle = IntPtr.Zero;
+
+            try
+            {
+                Interop.Tag.GetTagFromDb(tagId, out handle).ThrowIfError("Failed to query");
+
+                if (handle == IntPtr.Zero)
+                {
+                    return null;
+                }
+                return new Tag(handle);
+            }
+            finally
+            {
+                if (handle != IntPtr.Zero)
+                {
+                    Interop.Tag.Destroy(handle);
+                }
+            }
+
+        }
+
+        /// <summary>
+        /// Retrieves all the tags.
+        /// </summary>
+        /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        public MediaDataReader<Tag> Select()
+        {
+            return Select(arguments: null);
+        }
+
+        /// <summary>
+        /// Retrieves the tags with <see cref="SelectArguments"/>.
+        /// </summary>
+        /// <param name="arguments">The criteria to use to filter. This value can be null.</param>
+        /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        public MediaDataReader<Tag> Select(SelectArguments arguments)
+        {
+            ValidateDatabase();
+
+            return CommandHelper.Select(arguments, Interop.Tag.ForeachTagFromDb, Tag.FromHandle);
+        }
+
+        /// <summary>
+        /// Retrieves the number of media info of the tag.
+        /// </summary>
+        /// <param name="tagId">The tag id.</param>
+        /// <returns>The number of media info.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="tagId"/> is less than or equal to zero.</exception>
+        public int CountMedia(int tagId)
+        {
+            return CountMedia(tagId, null);
+        }
+
+        /// <summary>
+        /// Retrieves the number of media info of the tag with <see cref="CountArguments"/>.
+        /// </summary>
+        /// <param name="tagId">The tag id to query with.</param>
+        /// <param name="arguments">The criteria to use to filter. This value can be null.</param>
+        /// <returns>The number of media info.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="tagId"/> is less than or equal to zero.</exception>
+        public int CountMedia(int tagId, CountArguments arguments)
+        {
+            ValidateDatabase();
+
+            if (tagId <= 0)
+            {
+                throw new ArgumentOutOfRangeException(nameof(tagId), tagId,
+                    "Tag id can't be less than or equal to zero.");
+            }
+
+            return CommandHelper.Count(Interop.Tag.GetMediaCount, tagId, arguments);
+        }
+
+        /// <summary>
+        /// Retrieves the media info of the tag.
+        /// </summary>
+        /// <param name="tagId">The tag id.</param>
+        /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="tagId"/> is less than or equal to zero.</exception>
+        public MediaDataReader<MediaInfo> SelectMedia(int tagId)
+        {
+            return SelectMedia(tagId, null);
+        }
+
+        /// <summary>
+        /// Retrieves the media info of the tag with <see cref="SelectArguments"/>.
+        /// </summary>
+        /// <param name="tagId">The tag id.</param>
+        /// <param name="filter">The criteria to use to filter. This value can be null.</param>
+        /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="tagId"/> is less than or equal to zero.</exception>
+        public MediaDataReader<MediaInfo> SelectMedia(int tagId, SelectArguments filter)
+        {
+            ValidateDatabase();
+
+            if (tagId <= 0)
+            {
+                throw new ArgumentOutOfRangeException(nameof(tagId), tagId,
+                    "Tag id can't be less than or equal to zero.");
+            }
+
+            return CommandHelper.SelectMedia(Interop.Tag.ForeachMediaFromDb, tagId, filter);
+        }
+
+        private bool UpdateMember(int tagId, IEnumerable<string> mediaIds,
+            Func<IntPtr, string, MediaContentError> func)
+        {
+            ValidateDatabase();
+
+            if (tagId <= 0)
+            {
+                throw new ArgumentOutOfRangeException(nameof(tagId), tagId,
+                    "Tag id can't be less than or equal to zero.");
+            }
+
+            if (mediaIds == null)
+            {
+                throw new ArgumentNullException(nameof(mediaIds));
+            }
+
+            if (mediaIds.Count() == 0)
+            {
+                throw new ArgumentException("mediaIds has no element.", nameof(mediaIds));
+            }
+
+            if (CommandHelper.Count(Interop.Tag.GetTagCount, $"{TagColumns.Id}={tagId}") == 0)
+            {
+                return false;
+            }
+
+            IntPtr handle = IntPtr.Zero;
+            Interop.Tag.Create(out handle).ThrowIfError("Failed to initialize update member operation");
+
+            try
+            {
+                foreach (var mediaId in mediaIds)
+                {
+                    if (mediaId == null)
+                    {
+                        throw new ArgumentException("Media id should not be null.", nameof(mediaIds));
+                    }
+
+                    if (string.IsNullOrWhiteSpace(mediaId))
+                    {
+                        throw new ArgumentException("Media id should not be a zero-length string.", nameof(mediaId));
+                    }
+
+                    func(handle, mediaId).ThrowIfError("Failed to update member");
+                }
+
+                Interop.Tag.Update(tagId, handle).ThrowIfError("Failed to run member update");
+                return true;
+            }
+            finally
+            {
+                if (handle != IntPtr.Zero)
+                {
+                    Interop.Tag.Destroy(handle);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Adds media to a tag.
+        /// </summary>
+        /// <param name="tagId">The tag id that the media will be added to.</param>
+        /// <param name="mediaId">The media id to add to the tag.</param>
+        /// <returns>true if the matched record was found and updated, otherwise false.</returns>
+        /// <remarks>The invalid media id will be ignored.</remarks>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="mediaId"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="mediaId"/> is a zero-length string, contains only white space.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="tagId"/> is less than or equal to zero.</exception>
+        public bool AddMedia(int tagId, string mediaId)
+        {
+            ValidationUtil.ValidateNotNullOrEmpty(mediaId, nameof(mediaId));
+
+            return AddMedia(tagId, new string[] { mediaId });
+        }
+
+        /// <summary>
+        /// Adds a media set to a tag.
+        /// </summary>
+        /// <param name="tagId">The tag id that the media will be added to.</param>
+        /// <param name="mediaIds">The media id to add to the tag.</param>
+        /// <returns>true if the matched record was found and updated, otherwise false.</returns>
+        /// <remarks>The invalid media ids will be ignored.</remarks>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="mediaIds"/> is null.</exception>
+        /// <exception cref="ArgumentException">
+        ///     <paramref name="mediaIds"/> has no element.\n
+        ///     -or-\n
+        ///     <paramref name="mediaIds"/> contains null value.\n
+        ///     -or-\n
+        ///     <paramref name="mediaIds"/> contains a zero-length string, contains only white space.\n
+        /// </exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="tagId"/> is less than or equal to zero.</exception>
+        public bool AddMedia(int tagId, IEnumerable<string> mediaIds)
+        {
+            return UpdateMember(tagId, mediaIds, Interop.Tag.AddMedia);
+        }
+
+        /// <summary>
+        /// Removes media from a tag.
+        /// </summary>
+        /// <param name="tagId">The tag id.</param>
+        /// <param name="mediaId">The media id to remove from the tag.</param>
+        /// <returns>true if the matched record was found and updated, otherwise false.</returns>
+        /// <remarks>The invalid media id will be ignored.</remarks>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="mediaId"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="mediaId"/> is a zero-length string, contains only white space.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="tagId"/> is less than or equal to zero.</exception>
+        public bool RemoveMedia(int tagId, string mediaId)
+        {
+            ValidationUtil.ValidateNotNullOrEmpty(mediaId, nameof(mediaId));
+
+            return RemoveMedia(tagId, new string[] { mediaId });
+        }
+
+        /// <summary>
+        /// Removes a media set from a tag.
+        /// </summary>
+        /// <param name="tagId">The tag id.</param>
+        /// <param name="mediaIds">The collection of media id to remove from the tag.</param>
+        /// <returns>true if the matched record was found and updated, otherwise false.</returns>
+        /// <remarks>The invalid ids will be ignored.</remarks>
+        /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
+        /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="mediaIds"/> is null.</exception>
+        /// <exception cref="ArgumentException">
+        ///     <paramref name="mediaIds"/> has no element.\n
+        ///     -or-\n
+        ///     <paramref name="mediaIds"/> contains null value.\n
+        ///     -or-\n
+        ///     <paramref name="mediaIds"/> contains a zero-length string or white space.\n
+        /// </exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="tagId"/> is less than or equal to zero.</exception>
+        public bool RemoveMedia(int tagId, IEnumerable<string> mediaIds)
+        {
+            return UpdateMember(tagId, mediaIds, Interop.Tag.RemoveMedia);
+        }
+    }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/UnsupportedContentException.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/UnsupportedContentException.cs
new file mode 100644 (file)
index 0000000..a0b1b69
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Content.MediaContent
+{
+    /// <summary>
+    /// The exception that is thrown when a requested operation is not supported for content.
+    /// </summary>
+    public class UnsupportedContentException : Exception
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="UnsupportedContentException"/> class.
+        /// </summary>
+        public UnsupportedContentException() : base("The operation is not supported for the given media.")
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="UnsupportedContentException"/> class with a specified error message.
+        /// </summary>
+        /// <param name="message">The message that describes the error.</param>
+        public UnsupportedContentException(string message) : base(message)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="UnsupportedContentException"/> class with a specified error message
+        /// and a reference to the inner exception that is the cause of this exception.
+        /// </summary>
+        /// <param name="message">The message that describes the error.</param>
+        /// <param name="innerException">The exception that is the cause of the current exception.</param>
+        public UnsupportedContentException(string message, Exception innerException) : base(message, innerException)
+        {
+        }
+    }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ValdiationUtil.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ValdiationUtil.cs
new file mode 100644 (file)
index 0000000..30c3644
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Content.MediaContent
+{
+    internal static class ValidationUtil
+    {
+        internal static void ValidateEnum(Type enumType, object value, string paramName)
+        {
+            if (!Enum.IsDefined(enumType, value))
+            {
+                throw new ArgumentException($"Invalid { enumType.Name } value : { value }", paramName);
+            }
+        }
+
+        internal static void ValidateNotNullOrEmpty(string value, string paramName)
+        {
+            if (value == null)
+            {
+                throw new ArgumentNullException(paramName);
+            }
+
+            if (string.IsNullOrWhiteSpace(value))
+            {
+                throw new ArgumentException($"{paramName} is a zero-length string.", paramName);
+            }
+        }
+    }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/VideoInfo.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/VideoInfo.cs
new file mode 100644 (file)
index 0000000..bca5890
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Diagnostics;
+
+namespace Tizen.Content.MediaContent
+{
+    /// <summary>
+    /// Represents a video media information.
+    /// </summary>
+    public class VideoInfo : MediaInfo
+    {
+        internal VideoInfo(Interop.MediaInfoHandle handle) : base(handle)
+        {
+            IntPtr videoHandle = IntPtr.Zero;
+
+            try
+            {
+                Interop.MediaInfo.GetVideo(handle, out videoHandle).ThrowIfError("Failed to retrieve data");
+
+                Debug.Assert(videoHandle != IntPtr.Zero);
+
+                Album = InteropHelper.GetString(videoHandle, Interop.VideoInfo.GetAlbum);
+                Artist = InteropHelper.GetString(videoHandle, Interop.VideoInfo.GetArtist);
+                AlbumArtist = InteropHelper.GetString(videoHandle, Interop.VideoInfo.GetAlbumArtist);
+                Genre = InteropHelper.GetString(videoHandle, Interop.VideoInfo.GetGenre);
+                Composer = InteropHelper.GetString(videoHandle, Interop.VideoInfo.GetComposer);
+                Year = InteropHelper.GetString(videoHandle, Interop.VideoInfo.GetYear);
+                DateRecorded = InteropHelper.GetString(videoHandle, Interop.VideoInfo.GetRecordedDate);
+                Copyright = InteropHelper.GetString(videoHandle, Interop.VideoInfo.GetCopyright);
+                TrackNumber = InteropHelper.GetString(videoHandle, Interop.VideoInfo.GetTrackNum);
+
+                BitRate = InteropHelper.GetValue<int>(videoHandle, Interop.VideoInfo.GetBitRate);
+                Duration = InteropHelper.GetValue<int>(videoHandle, Interop.VideoInfo.GetDuration);
+                Width = InteropHelper.GetValue<int>(videoHandle, Interop.VideoInfo.GetWidth);
+                Height = InteropHelper.GetValue<int>(videoHandle, Interop.VideoInfo.GetHeight);
+            }
+            finally
+            {
+                Interop.VideoInfo.Destroy(videoHandle);
+            }
+        }
+
+        /// <summary>
+        /// Gets the album name.
+        /// </summary>
+        /// <value>The album name from the metadata.</value>
+        public string Album { get; }
+
+        /// <summary>
+        /// Gets the artist name.
+        /// </summary>
+        /// <value>The artist name from the metadata.</value>
+        public string Artist { get; }
+
+        /// <summary>
+        /// Gets the album artist name.
+        /// </summary>
+        /// <value>The album artist name from the metadata.</value>
+        public string AlbumArtist { get; }
+
+        /// <summary>
+        /// Gets the genre.
+        /// </summary>
+        /// <value>The genre name from the metadata.</value>
+        public string Genre { get; }
+
+        /// <summary>
+        /// Gets the composer name.
+        /// </summary>
+        /// <value>The composer name from the metadata.</value>
+        public string Composer { get; }
+
+        /// <summary>
+        /// Gets the year.
+        /// </summary>
+        /// <value>The year from the metadata.</value>
+        public string Year { get; }
+
+        /// <summary>
+        /// Gets the recorded date.
+        /// </summary>
+        /// <value>The recorded date information from the metadata if exists; otherwise, the modified date of the file.</value>
+        public string DateRecorded { get; }
+
+        /// <summary>
+        /// Gets the copyright notice.
+        /// </summary>
+        /// <value>The copyright notice from the metadata.</value>
+        public string Copyright { get; }
+
+        /// <summary>
+        /// Gets the track number.
+        /// </summary>
+        /// <value>The track number from the metadata.</value>
+        public string TrackNumber { get; }
+
+        /// <summary>
+        /// Gets the bitrate in bit per second.
+        /// </summary>
+        /// <value>The bit rate of the video.</value>
+        public int BitRate { get; }
+
+        /// <summary>
+        /// Gets the track duration in milliseconds.
+        /// </summary>
+        /// <value>The track duration of the video in milliseconds.</value>
+        public int Duration { get; }
+
+        /// <summary>
+        /// Gets the video width in pixels.
+        /// </summary>
+        /// <value>The width of the video in pixels.</value>
+        public int Width { get; }
+
+        /// <summary>
+        /// Gets the video height in pixels.
+        /// </summary>
+        /// <value>The height of the video in pixels.</value>
+        public int Height { get; }
+
+    }
+}
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/VideoInformation.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/VideoInformation.cs
deleted file mode 100755 (executable)
index da48d28..0000000
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
-* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
-*
-* Licensed under the Apache License, Version 2.0 (the License);
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an AS IS BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-
-
-using System;
-using System.Collections.Generic;
-using System.Runtime.InteropServices;
-using System.Threading.Tasks;
-using System.Collections.ObjectModel;
-
-namespace Tizen.Content.MediaContent
-{
-    /// <summary>
-    /// VideoContent class API gives the information related to the image media stored in the device
-    /// </summary>
-    public class VideoInformation : MediaInformation
-    {
-        /// <summary>
-        ///  Gets the ID of the media.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string MediaId
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.VideoInformation.GetMediaId(_handle, out val), "Failed to get value");
-
-                    return Marshal.PtrToStringAnsi(val);
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        /// <summary>
-        ///  Gets the album name.
-        ///  If the media content has no album information, the property returns empty string.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string Album
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.VideoInformation.GetAlbum(_handle, out val), "Failed to get value");
-
-                    return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        /// <summary>
-        ///  Gets the artist name.
-        ///  If the media content has no artist information, the property returns empty string.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string Artist
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.VideoInformation.GetArtist(_handle, out val), "Failed to get value");
-
-                    return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        /// <summary>
-        ///  Gets the album artist name.
-        ///  If the media content has no album artist information, the property returns empty string.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string AlbumArtist
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.VideoInformation.GetAlbumArtist(_handle, out val), "Failed to get value");
-
-                    return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        /// <summary>
-        ///  Gets the genre name.
-        ///  If the media content has no genre information, the property returns empty string.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string Genre
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.VideoInformation.GetGenre(_handle, out val), "Failed to get value");
-
-                    return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        /// <summary>
-        ///  Gets the composer name.
-        ///  If the media content has no composer information, the property returns empty string.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string Composer
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.VideoInformation.GetComposer(_handle, out val), "Failed to get value");
-
-                    return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        /// <summary>
-        ///  Gets the year.
-        ///  If the media content has no year information, the property returns empty string.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string Year
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.VideoInformation.GetYear(_handle, out val), "Failed to get value");
-
-                    return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        /// <summary>
-        ///  Gets the recorded date.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string RecordedDate
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.VideoInformation.GetRecordedDate(_handle, out val), "Failed to get value");
-
-                    return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        /// <summary>
-        ///  Gets the copyright notice.
-        ///  If the media content has no copyright information, the property returns empty string.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string Copyright
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.VideoInformation.GetCopyright(_handle, out val), "Failed to get value");
-
-                    return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        /// <summary>
-        ///  Gets the track number.
-        ///  If the media content has no track information, the property returns empty string.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public string TrackNumber
-        {
-            get
-            {
-                IntPtr val = IntPtr.Zero;
-                try
-                {
-                    MediaContentValidator.ThrowIfError(
-                        Interop.VideoInformation.GetTrackNum(_handle, out val), "Failed to get value");
-
-                    return MediaContentValidator.CheckString(Marshal.PtrToStringAnsi(val));
-                }
-                finally
-                {
-                    Interop.Libc.Free(val);
-                }
-            }
-        }
-
-        /// <summary>
-        ///  Gets the bitrate in bit per second [bps].
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public int BitRate
-        {
-            get
-            {
-                int bitrate = 0;
-                MediaContentValidator.ThrowIfError(
-                    Interop.VideoInformation.GetBitRate(_handle, out bitrate), "Failed to get value");
-
-                return bitrate;
-            }
-        }
-
-        /// <summary>
-        ///  Gets the track duration in Milliseconds.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public int Duration
-        {
-            get
-            {
-                int duration = 0;
-                MediaContentValidator.ThrowIfError(
-                    Interop.VideoInformation.GetDuration(_handle, out duration), "Failed to get value");
-
-                return duration;
-            }
-        }
-
-        /// <summary>
-        ///  Gets the video width in pixels.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public int Width
-        {
-            get
-            {
-                int width = 0;
-                MediaContentValidator.ThrowIfError(
-                    Interop.VideoInformation.GetWidth(_handle, out width), "Failed to get value");
-
-                return width;
-            }
-        }
-
-        /// <summary>
-        ///  Gets the video height in pixels.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        public int Height
-        {
-            get
-            {
-                int height = 0;
-                MediaContentValidator.ThrowIfError(
-                    Interop.VideoInformation.GetHeight(_handle, out height), "Failed to get value");
-
-                return height;
-            }
-        }
-
-        /// <summary>
-        /// Gets the number of bookmarks for the passed filter in the given media ID from the media database.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <returns>
-        /// int count</returns>
-        /// <param name="filter">The Filter for matching Bookmarks</param>
-        public int GetMediaBookmarkCount(ContentFilter filter)
-        {
-            int count = 0;
-            IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
-            MediaContentValidator.ThrowIfError(
-                Interop.MediaInformation.GetBookmarkCount(MediaId, handle, out count), "Failed to get count");
-
-            return count;
-        }
-
-        /// <summary>
-        /// Iterates through the media bookmark in the given media info from the media database.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <returns>
-        /// Task to get all the Bookmarks </returns>
-        /// <param name="filter"> filter for the Tags</param>
-        public IEnumerable<MediaBookmark> GetMediaBookmarks(ContentFilter filter)
-        {
-            Collection<MediaBookmark> result = new Collection<MediaBookmark>();
-            IntPtr filterHandle = (filter != null) ? filter.Handle : IntPtr.Zero;
-            Interop.MediaInformation.MediaBookmarkCallback callback = (IntPtr handle, IntPtr userData) =>
-            {
-                IntPtr newHandle = IntPtr.Zero;
-                MediaContentValidator.ThrowIfError(
-                    Interop.MediaBookmark.Clone(out newHandle, handle), "Failed to clone Tag");
-                result.Add(new MediaBookmark(newHandle));
-                return true;
-            };
-            MediaContentValidator.ThrowIfError(
-                Interop.MediaInformation.GetAllBookmarks(MediaId, filterHandle, callback, IntPtr.Zero), "Failed to get value");
-
-            return result;
-        }
-
-        /// <summary>
-        /// Adds a bookmark to the video
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="offset">Offset of the video in seconds</param>
-        /// <param name="thumbnailPath">Thumbnail path for the bookmark</param>
-        /// <returns>Task with added MediaBookmark instance </returns>
-        public MediaBookmark AddBookmark(uint offset, string thumbnailPath)
-        {
-            MediaBookmark result = null;
-            ContentManager.Database.Insert(MediaId, offset, thumbnailPath);
-            ContentFilter bookmarkfilter = new ContentFilter();
-            bookmarkfilter.Condition = ContentColumns.Bookmark.Offset + " = " + offset;
-            IEnumerable<MediaBookmark> bookmarksList = null;
-            bookmarksList = GetMediaBookmarks(bookmarkfilter);
-            foreach (MediaBookmark bookmark in bookmarksList)
-            {
-                if (bookmark.Offset == offset)
-                {
-                    result = bookmark;
-                    break;
-                }
-            }
-
-            bookmarkfilter.Dispose();
-            return result;
-        }
-
-        /// <summary>
-        /// Deletes a bookmark from the media database.
-        /// For other types Unsupported exception is thrown.
-        /// </summary>
-        /// <since_tizen> 3 </since_tizen>
-        /// <param name="bookmark">The bookmark to be deleted</param>
-        public void DeleteBookmark(MediaBookmark bookmark)
-        {
-            ContentManager.Database.Delete(bookmark);
-        }
-
-        internal IntPtr VideoHandle
-        {
-            get
-            {
-                return _handle.DangerousGetHandle();
-            }
-        }
-
-        private readonly Interop.VideoInformation.SafeVideoInformationHandle _handle;
-
-        internal VideoInformation(Interop.VideoInformation.SafeVideoInformationHandle handle, Interop.MediaInformation.SafeMediaInformationHandle mediaInformationHandle)
-            : base(mediaInformationHandle)
-        {
-            _handle = handle;
-        }
-    }
-}