diff options
Diffstat (limited to 'src/Tizen.Content.MediaContent/Tizen.Content.MediaContent')
21 files changed, 7142 insertions, 0 deletions
diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Album.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Album.cs new file mode 100755 index 0000000..3763483 --- /dev/null +++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Album.cs @@ -0,0 +1,224 @@ +/* +* 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. + /// </summary> + public class Album : ContentCollection + { + private IntPtr _albumHandle = IntPtr.Zero; + + private IntPtr Handle + { + get + { + if (_albumHandle == IntPtr.Zero) + { + throw new ObjectDisposedException(nameof(Album)); + } + + return _albumHandle; + } + } + + /// <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; + } + } + + /// <summary> + /// The name of the media artist + /// 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.Group.MediaAlbumGetArtist(Handle, out val), "Failed to get value"); + + return Marshal.PtrToStringAnsi(val); + } + finally + { + Interop.Libc.Free(val); + } + } + } + + /// <summary> + /// The path of the media album art + /// </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); + } + } + } + + /// <summary> + /// The name of the media album + /// If the media content has no album info, the property returns empty string. + /// </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; + } + + /// <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. + /// </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; + } + } + + /// <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. + /// </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; + } + } +} diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/AudioInformation.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/AudioInformation.cs new file mode 100755 index 0000000..e5fc8d8 --- /dev/null +++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/AudioInformation.cs @@ -0,0 +1,455 @@ +/* +* 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/ContentCollection.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentCollection.cs new file mode 100755 index 0000000..2e4ae7e --- /dev/null +++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentCollection.cs @@ -0,0 +1,50 @@ +/* +* 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 new file mode 100755 index 0000000..6c10037 --- /dev/null +++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentColumns.cs @@ -0,0 +1,1130 @@ +/* +* 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 new file mode 100755 index 0000000..e2389a3 --- /dev/null +++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentDatabase.cs @@ -0,0 +1,714 @@ +/* +* 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 new file mode 100755 index 0000000..283fc87 --- /dev/null +++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentEventArgs.cs @@ -0,0 +1,113 @@ +/* +* 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 new file mode 100755 index 0000000..97d4998 --- /dev/null +++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentFilter.cs @@ -0,0 +1,365 @@ +/* +* 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 new file mode 100755 index 0000000..6044b87 --- /dev/null +++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ContentManager.cs @@ -0,0 +1,268 @@ +/* +* 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/FaceRect.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/FaceRect.cs new file mode 100755 index 0000000..93298a9 --- /dev/null +++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/FaceRect.cs @@ -0,0 +1,59 @@ +/* +* 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/Group.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Group.cs new file mode 100755 index 0000000..d037f3b --- /dev/null +++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Group.cs @@ -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.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/ImageInformation.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ImageInformation.cs new file mode 100755 index 0000000..e6922d3 --- /dev/null +++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/ImageInformation.cs @@ -0,0 +1,347 @@ +/* +* 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/MediaBookmark.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaBookmark.cs new file mode 100755 index 0000000..07e14bb --- /dev/null +++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaBookmark.cs @@ -0,0 +1,129 @@ +/* +* 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/MediaContentEnums.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaContentEnums.cs new file mode 100755 index 0000000..2c59329 --- /dev/null +++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaContentEnums.cs @@ -0,0 +1,411 @@ +/* +* 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 + }; +} diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaContentError.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaContentError.cs new file mode 100755 index 0000000..421c370 --- /dev/null +++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaContentError.cs @@ -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; +using System.IO; +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 + { + None = ErrorCode.None, + InvalidParameter = ErrorCode.InvalidParameter, + OutOfMemory = ErrorCode.OutOfMemory, + InvalidOperation = ErrorCode.InvalidOperation, + FileNoSpaceOnDevice = ErrorCode.FileNoSpaceOnDevice, + PermissionDenied = ErrorCode.PermissionDenied, + TizenMediaContentError = -0x01610000, + DatabaseFailed = TizenMediaContentError | 0x01, + DatabaseBusy = TizenMediaContentError | 0x02, + NetworkFailed = TizenMediaContentError | 0x03, + UnsupportedContent = TizenMediaContentError | 0x04, + NotSupported = ErrorCode.NotSupported, + } + + internal class MediaContentValidator + { + internal const string LogTag = "Tizen.Content.MediaContent"; + + internal static void ThrowIfError(MediaContentError err, string msg) + { + switch (err) + { + case MediaContentError.InvalidParameter: + throw new ArgumentException(msg); + case MediaContentError.OutOfMemory: + throw new OutOfMemoryException(msg); + case MediaContentError.InvalidOperation: + throw new InvalidOperationException(msg); + case MediaContentError.FileNoSpaceOnDevice: + throw new IOException(msg); + case MediaContentError.PermissionDenied: + throw new UnauthorizedAccessException(msg); + case MediaContentError.DatabaseFailed: + throw new InvalidOperationException("[DB Failed]" + msg); + case MediaContentError.DatabaseBusy: + throw new InvalidOperationException("[DB Busy]" + msg); + case MediaContentError.NetworkFailed: + throw new InvalidOperationException("[Network Error]" + msg); + case MediaContentError.UnsupportedContent: + throw new PlatformNotSupportedException(msg); + } + } + + internal static string CheckString(string value) + { + return (value != null) ? value : ""; + } + } +} diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaFace.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaFace.cs new file mode 100755 index 0000000..134ab1f --- /dev/null +++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaFace.cs @@ -0,0 +1,226 @@ +/* +* 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 new file mode 100755 index 0000000..af120ca --- /dev/null +++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaFolder.cs @@ -0,0 +1,330 @@ +/* +* 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/MediaInformation.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaInformation.cs new file mode 100755 index 0000000..49b1788 --- /dev/null +++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/MediaInformation.cs @@ -0,0 +1,897 @@ +/* +* 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/PlayList.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/PlayList.cs new file mode 100755 index 0000000..e440707 --- /dev/null +++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/PlayList.cs @@ -0,0 +1,341 @@ +/* +* 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. + /// </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 + { + private readonly IDictionary<string, int> _dictionary = new Dictionary<string, int>(); + private IntPtr _playlistHandle = IntPtr.Zero; + internal IntPtr Handle + { + get + { + if (_playlistHandle == IntPtr.Zero) + { + throw new ObjectDisposedException(nameof(PlayList)); + } + + return _playlistHandle; + } + + set + { + _playlistHandle = value; + } + } + + 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"); + } + + /// <summary> + /// The ID of the media 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"); + + return id; + } + } + + internal string _playListName; + /// <summary> + /// The playlist name + /// </summary> + /// <since_tizen> 3 </since_tizen> + public string Name + { + get + { + return _playListName; + } + + set + { + MediaContentValidator.ThrowIfError( + Interop.Playlist.SetName(Handle, value), "Failed to set value"); + _playListName = value; + } + } + /// <summary> + /// The path of 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"); + } + } + + /// <summary> + /// The constructor to create a new playlist with the given name in the media database. + /// </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"); + } + + /// <summary> + /// Sets the playing order in the playlist. + /// </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"); + } + + /// <summary> + /// Gets the playing order in the playlist for the passed member id. + /// </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; + } + + /// <summary> + /// Imports the playlist from m3u playlist file. + /// </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) + { + 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; + } + + /// <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); + } + + /// <summary> + /// Gets the number of the media info for the given playlist 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; + 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) + { + Interop.Playlist.Destroy(_playlistHandle); + _playlistHandle = IntPtr.Zero; + } + } + + /// <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. + /// </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.Playlist.PlaylistMemberCallback callback = (int memberId, 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.Playlist.ForeachMediaFromDb(Id, handle, callback, IntPtr.Zero), "Failed to get media information"); + + return mediaContents; + } + } +} diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Storage.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Storage.cs new file mode 100755 index 0000000..b6935ef --- /dev/null +++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Storage.cs @@ -0,0 +1,219 @@ +/* +* 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. + /// </summary> + public class Storage : ContentCollection + { + private IntPtr _storageHandle = IntPtr.Zero; + private IntPtr Handle + { + get + { + if (_storageHandle == IntPtr.Zero) + { + throw new ObjectDisposedException(nameof(Storage)); + } + + return _storageHandle; + } + } + /// <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); + } + } + } + + /// <summary> + /// The storage path of the media 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); + } + } + } + + /// <summary> + /// The storage name of the media 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); + } + } + } + + /// <summary> + /// The storage type of the media 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; + } + } + + /// <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. + /// </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; + } + } +} diff --git a/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Tag.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Tag.cs new file mode 100755 index 0000000..181b763 --- /dev/null +++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/Tag.cs @@ -0,0 +1,217 @@ +/* +* 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. + /// </summary> + public class Tag : ContentCollection + { + private IntPtr _tagHandle = IntPtr.Zero; + private string _tagName = ""; + + internal 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; + } + } + + /// <summary> + /// The name 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); + } + } + + /// <summary> + /// Creates a Tag object which can be inserted to the media database using ContentManager:InsertToDatabaseAsync(ContentCollection) + /// </summary> + /// <since_tizen> 3 </since_tizen> + /// <param name="tagName">The name of the media tag</param> + public Tag(string tagName) + { + _tagName = tagName; + } + + /// <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"); + } + + /// <summary> + /// Removes the media info from the given 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"); + } + + /// <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/VideoInformation.cs b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/VideoInformation.cs new file mode 100755 index 0000000..da48d28 --- /dev/null +++ b/src/Tizen.Content.MediaContent/Tizen.Content.MediaContent/VideoInformation.cs @@ -0,0 +1,431 @@ +/* +* 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; + } + } +} |