2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 using System.Collections.Generic;
21 using System.Threading.Tasks;
23 /// The Media Content API provides functions, enumerations used in the entire Content Service.
26 /// The Media Content API provides functions and enumerations used in the entire Content Service.
27 /// The information about media items i.e.image, audio and video, are managed in the content database
28 /// and operations that involve database requires an active connection with the media content service.
29 /// During media scanning, Media Service extract media information automatically. media information
30 /// include basic file info like path, size, modified time etc and some metadata like ID3tag, EXIF,
31 /// thumbnail, etc. (thumbnail extracted only in Internal and SD card storage.
32 /// Media content services do not manage hidden files.
33 /// The API provides functions for connecting (media_content_connect()) and disconnecting(media_content_disconnect())
34 /// from the media content service.
38 namespace Tizen.Content.MediaContent
41 /// ContentDatabase class is the interface class for managing the ContentCollection and MediaInformation from/to the database.
42 /// This class allows usre to access/create/update db operations for media content.
44 public class ContentDatabase
46 private static IntPtr _updateHandle = IntPtr.Zero;
49 /// Connect to the media database to search, insert, remove or modify media information.
51 /// <since_tizen> 4 </since_tizen>
53 /// For information security, disconnect() after use media database.
55 public static void Connect()
57 MediaContentValidator.ThrowIfError(Interop.Content.Connect(), "Connect failed");
61 /// Disconnect from the media database.
63 /// <since_tizen> 4 </since_tizen>
64 public static void Disconnect()
66 MediaContentValidator.ThrowIfError(Interop.Content.Disconnect(), "Disconnect failed");
69 private static readonly Interop.Content.MediaContentDBUpdatedCallback s_contentUpdatedCallback = (
70 MediaContentError error,
72 MediaContentUpdateItemType updateItem,
73 MediaContentDBUpdateType updateType,
74 MediaContentType mediaType,
80 _contentUpdated?.Invoke(
81 null, new ContentUpdatedEventArgs(error, pid, updateItem, updateType, mediaType, uuid, filePath, mimeType));
84 private static event EventHandler<ContentUpdatedEventArgs> _contentUpdated;
86 /// ContentUpdated event is triggered when the media DB changes.
88 /// <since_tizen> 3 </since_tizen>
89 /// <param name="sender"></param>
90 /// <param name="e">A ContentUpdatedEventArgs object that contains information about the update operation.</param>
91 public static event EventHandler<ContentUpdatedEventArgs> ContentUpdated
95 if (_contentUpdated == null)
97 MediaContentValidator.ThrowIfError(
98 Interop.Content.AddDbUpdatedCb(s_contentUpdatedCallback, IntPtr.Zero, out _updateHandle), "Failed to set callback");
101 _contentUpdated += value;
106 _contentUpdated -= value;
107 if (_contentUpdated == null)
109 MediaContentValidator.ThrowIfError(
110 Interop.Content.RemoveDbUpdatedCb(_updateHandle), "Failed to unset callback");
116 /// Gets the count of ContentCollections for the ContentCollectionType and passed filter from the media database.
118 /// <since_tizen> 3 </since_tizen>
119 /// <param name="filter">The media filter</param>
120 /// <returns>The count of contents present in the media database for a ContentSourceType</returns>
121 public int GetCount<T>(ContentFilter filter) where T : class
124 IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
125 MediaGroupType groupType = MediaGroupType.DisplayName;
126 if (handle != IntPtr.Zero)
128 groupType = filter.GroupType;
131 if (typeof(T) == typeof(MediaInformation))
133 MediaContentValidator.ThrowIfError(
134 Interop.MediaInformation.GetMediaCount(handle, out count), "Failed to get count");
136 else if (typeof(T) == typeof(MediaBookmark))
138 MediaContentValidator.ThrowIfError(
139 Interop.MediaBookmark.GetBookmarkCountFromDb(handle, out count), "Failed to get count");
141 else if (typeof(T) == typeof(Album))
143 MediaContentValidator.ThrowIfError(
144 Interop.Group.MediaAlbumGetAlbumCountFromDb(handle, out count), "Failed to get count");
146 else if (typeof(T) == typeof(MediaFolder))
148 MediaContentValidator.ThrowIfError(
149 Interop.Folder.GetFolderCountFromDb(handle, out count), "Failed to get count");
151 else if (typeof(T) == typeof(Storage))
153 MediaContentValidator.ThrowIfError(
154 Interop.Storage.GetStorageCountFromDb(handle, out count), "Failed to get count");
156 else if (typeof(T) == typeof(Tag))
158 MediaContentValidator.ThrowIfError(
159 Interop.Tag.GetTagCountFromDb(handle, out count), "Failed to get count");
161 else if (typeof(T) == typeof(PlayList))
163 MediaContentValidator.ThrowIfError(
164 Interop.Playlist.GetPlaylistCountFromDb(handle, out count), "Failed to get count");
166 else if (typeof(T) == typeof(Group))
168 MediaContentValidator.ThrowIfError(
169 Interop.Group.GetGroupCountFromDb(handle, groupType, out count), "Failed to get count");
173 throw new ArgumentException("Wrong type");
180 /// Gets the MediaInformation object for the passed media Id.
182 /// <since_tizen> 3 </since_tizen>
183 /// <param name="id">The media id to fetch the respective MediaInformation instance</param>
184 /// <returns>MediaInformation instance for the associated id.It throws Exception for invalid Id.</returns>
185 public MediaInformation Select(string id)
187 Interop.MediaInformation.SafeMediaInformationHandle mediaHandle;
188 MediaContentValidator.ThrowIfError(
189 Interop.MediaInformation.GetMediaFromDB(id, out mediaHandle), "Failed to get information");
191 MediaContentType type;
192 MediaInformation res;
193 Interop.MediaInformation.GetMediaType(mediaHandle, out type);
194 if (type == MediaContentType.Image)
196 Interop.ImageInformation.SafeImageInformationHandle imageInfo;
197 MediaContentValidator.ThrowIfError(
198 Interop.MediaInformation.GetImage(mediaHandle.DangerousGetHandle(), out imageInfo), "Failed to get image information");
200 res = new ImageInformation(imageInfo, mediaHandle);
202 else if ((type == MediaContentType.Music) || (type == MediaContentType.Sound))
204 Interop.AudioInformation.SafeAudioInformationHandle audioInfo;
205 MediaContentValidator.ThrowIfError(
206 Interop.MediaInformation.GetAudio(mediaHandle.DangerousGetHandle(), out audioInfo), "Failed to get audio information");
208 res = new AudioInformation(audioInfo, mediaHandle);
210 else if (type == MediaContentType.Video)
212 Interop.VideoInformation.SafeVideoInformationHandle videoInfo;
213 MediaContentValidator.ThrowIfError(
214 Interop.MediaInformation.GetVideo(mediaHandle.DangerousGetHandle(), out videoInfo), "Failed to get video information");
216 res = new VideoInformation(videoInfo, mediaHandle);
220 res = new MediaInformation(mediaHandle);
227 /// Gets the ContentCollection object for the passed media Id.
228 /// Applicable for MediaFolder and Storage types.
230 /// <since_tizen> 3 </since_tizen>
231 /// <param name="id">The ContentCollection id to fetch the respective MediaInformation instance</param>
232 /// <returns>ContentCollection instance for the associated id.It throws Exception for invalid Id.</returns>
233 public T Select<T>(string id) where T : ContentCollection
235 ContentCollection result = null;
236 IntPtr handle = IntPtr.Zero;
238 if (typeof(T) == typeof(MediaFolder))
240 MediaContentValidator.ThrowIfError(
241 Interop.Folder.GetFolderFromDb(id, out handle), "Failed to get information");
243 if (handle != IntPtr.Zero)
245 result = new MediaFolder(handle);
250 else if (typeof(T) == typeof(Storage))
252 MediaContentValidator.ThrowIfError(
253 Interop.Storage.GetStorageInfoFromDb(id, out handle), "Failed to get information");
255 if (handle != IntPtr.Zero)
257 result = new Storage(handle);
267 /// Gets the ContentCollection object for the passed media Id.
268 /// Applicable for PlayList, Album and Tag types.
270 /// <since_tizen> 3 </since_tizen>
271 /// <param name="id">The ContentCollection id to fetch the respective MediaInformation instance</param>
272 /// <returns>ContentCollection instance for the associated id.It throws Exception for invalid Id.</returns>
273 public T Select<T>(int id) where T : ContentCollection
275 ContentCollection result = null;
276 IntPtr handle = IntPtr.Zero;
278 if (typeof(T) == typeof(PlayList))
280 MediaContentValidator.ThrowIfError(
281 Interop.Playlist.GetPlaylistFromDb(id, out handle), "Failed to get information");
283 if (handle != IntPtr.Zero)
285 result = new PlayList(handle);
289 else if (typeof(T) == typeof(Album))
291 MediaContentValidator.ThrowIfError(
292 Interop.Group.MediaAlbumGetAlbumFromDb(id, out handle), "Failed to get information");
294 if (handle != IntPtr.Zero)
296 result = new Album(handle);
300 else if (typeof(T) == typeof(Tag))
302 MediaContentValidator.ThrowIfError(
303 Interop.Tag.GetTagFromDb(id, out handle), "Failed to get information");
305 if (handle != IntPtr.Zero)
307 result = new Tag(handle);
315 private static IEnumerable<MediaFolder> ForEachFolder(ContentFilter filter)
317 List<MediaFolder> result = new List<MediaFolder>();
318 Interop.Folder.MediaFolderCallback callback = (IntPtr handle, IntPtr data) =>
320 IntPtr newHandle = IntPtr.Zero;
321 MediaContentValidator.ThrowIfError(
322 Interop.Folder.Clone(out newHandle, handle), "Failed to clone");
324 result.Add(new MediaFolder(newHandle));
327 IntPtr filterHandle = filter != null ? filter.Handle : IntPtr.Zero;
328 MediaContentValidator.ThrowIfError(
329 Interop.Folder.ForeachFolderFromDb(filterHandle, callback, IntPtr.Zero), "Failed to get information");
334 private static IEnumerable<Album> ForEachAlbum(ContentFilter filter)
336 List<Album> result = new List<Album>();
337 Interop.Group.MediaAlbumCallback callback = (IntPtr handle, IntPtr data) =>
339 IntPtr newHandle = IntPtr.Zero;
340 MediaContentValidator.ThrowIfError(
341 Interop.Group.MediaAlbumClone(out newHandle, handle), "Failed to clone");
343 result.Add(new Album(newHandle));
346 IntPtr filterHandle = (filter != null) ? filter.Handle : IntPtr.Zero;
347 MediaContentValidator.ThrowIfError(
348 Interop.Group.MediaAlbumForeachAlbumFromDb(filterHandle, callback, IntPtr.Zero), "Failed to get information");
353 private static IEnumerable<Group> ForEachGroup(ContentFilter filter)
355 IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
356 MediaGroupType groupType;
359 groupType = MediaGroupType.DisplayName;
363 groupType = filter.GroupType;
366 List<Group> result = new List<Group>();
367 Interop.Group.MediaGroupCallback callback = (string groupName, IntPtr data) =>
369 result.Add(new Group(groupName, groupType));
372 MediaContentValidator.ThrowIfError(
373 Interop.Group.ForeachGroupFromDb(handle, groupType, callback, IntPtr.Zero), "Failed to get information");
378 private static IEnumerable<Storage> ForEachStorage(ContentFilter filter)
380 IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
381 List<Storage> result = new List<Storage>();
382 Interop.Storage.MediaStorageCallback callback = (IntPtr storageHandle, IntPtr data) =>
384 IntPtr newHandle = IntPtr.Zero;
385 MediaContentValidator.ThrowIfError(
386 Interop.Storage.Clone(out newHandle, storageHandle), "Failed to clone");
388 result.Add(new Storage(newHandle));
391 MediaContentValidator.ThrowIfError(
392 Interop.Storage.ForeachStorageFromDb(handle, callback, IntPtr.Zero), "Failed to get information");
397 private static IEnumerable<Tag> ForEachTag(ContentFilter filter)
399 IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
401 List<Tag> result = new List<Tag>();
402 Interop.Tag.MediaTagCallback callback = (IntPtr tagHandle, IntPtr data) =>
404 IntPtr newHandle = IntPtr.Zero;
405 MediaContentValidator.ThrowIfError(
406 Interop.Tag.Clone(out newHandle, tagHandle), "Failed to clone");
408 result.Add(new Tag(newHandle));
411 MediaContentValidator.ThrowIfError(
412 Interop.Tag.ForeachTagFromDb(handle, callback, IntPtr.Zero), "Failed to get information");
417 private static IEnumerable<PlayList> ForEachPlayList(ContentFilter filter)
419 IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
421 List<PlayList> result = new List<PlayList>();
422 Interop.Playlist.MediaPlaylistCallback callback = (IntPtr playListHandle, IntPtr data) =>
424 IntPtr newHandle = IntPtr.Zero;
425 MediaContentValidator.ThrowIfError(
426 Interop.Playlist.Clone(out newHandle, playListHandle), "Failed to clone");
428 result.Add(new PlayList(newHandle));
431 MediaContentValidator.ThrowIfError(
432 Interop.Playlist.ForeachPlaylistFromDb(handle, callback, IntPtr.Zero), "Failed to get information");
438 /// Returns the ContentCollections with optional filter from the media database.
440 /// <since_tizen> 3 </since_tizen>
442 /// This function gets all ContentCollections matching the given filter. If NULL is passed to the filter, no filtering is applied.
444 /// <param name="filter">Filter for content items</param>
446 /// Task with the list of the ContentCollection
448 public IEnumerable<T> SelectAll<T>(ContentFilter filter)
450 if (typeof(T) == typeof(MediaInformation))
452 IEnumerable<MediaInformation> mediaList = GetMediaInformations(filter);
453 return (IEnumerable<T>)mediaList;
455 else if (typeof(T) == typeof(Album))
457 IEnumerable<Album> collectionList = ForEachAlbum(filter);
458 return (IEnumerable<T>)collectionList;
460 else if (typeof(T) == typeof(MediaFolder))
462 IEnumerable<MediaFolder> collectionList = ForEachFolder(filter);
463 return (IEnumerable<T>)collectionList;
465 else if (typeof(T) == typeof(Group))
467 IEnumerable<Group> collectionList = ForEachGroup(filter);
468 return (IEnumerable<T>)collectionList;
470 else if (typeof(T) == typeof(Storage))
472 IEnumerable<Storage> collectionList = ForEachStorage(filter);
473 return (IEnumerable<T>)collectionList;
475 else if (typeof(T) == typeof(Tag))
477 IEnumerable<Tag> collectionList = ForEachTag(filter);
478 return (IEnumerable<T>)collectionList;
480 else if (typeof(T) == typeof(PlayList))
482 IEnumerable<PlayList> collectionList = ForEachPlayList(filter);
483 return (IEnumerable<T>)collectionList;
490 /// Returns media from the media database.
491 /// This function gets all media meeting the given filter
493 /// <since_tizen> 3 </since_tizen>
494 /// <param name="filter">The media filter</param>
495 /// <returns>List of media</returns>
496 private IEnumerable<MediaInformation> GetMediaInformations(ContentFilter filter)
498 IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
499 List<MediaInformation> mediaInformationList = new List<MediaInformation>();
500 Interop.MediaInformation.MediaInformationCallback callback = (IntPtr mediaHandle, IntPtr userData) =>
502 Interop.MediaInformation.SafeMediaInformationHandle newHandle;
503 MediaContentValidator.ThrowIfError(
504 Interop.MediaInformation.Clone(out newHandle, mediaHandle), "Failed to clone");
506 MediaContentType type;
507 Interop.MediaInformation.GetMediaType(newHandle, out type);
508 if (type == MediaContentType.Image)
510 Interop.ImageInformation.SafeImageInformationHandle imageInfo;
511 MediaContentValidator.ThrowIfError(
512 Interop.MediaInformation.GetImage(mediaHandle, out imageInfo), "Failed to get image information");
514 mediaInformationList.Add(new ImageInformation(imageInfo, newHandle));
516 else if ((type == MediaContentType.Music) || (type == MediaContentType.Sound))
518 Interop.AudioInformation.SafeAudioInformationHandle audioInfo;
519 MediaContentValidator.ThrowIfError(
520 Interop.MediaInformation.GetAudio(mediaHandle, out audioInfo), "Failed to get audio information");
522 mediaInformationList.Add(new AudioInformation(audioInfo, newHandle));
524 else if (type == MediaContentType.Video)
526 Interop.VideoInformation.SafeVideoInformationHandle videoInfo;
527 MediaContentValidator.ThrowIfError(
528 Interop.MediaInformation.GetVideo(mediaHandle, out videoInfo), "Failed to get video information");
530 mediaInformationList.Add(new VideoInformation(videoInfo, newHandle));
532 else if (type == MediaContentType.Others)
534 mediaInformationList.Add(new MediaInformation(newHandle));
539 MediaContentValidator.ThrowIfError(
540 Interop.MediaInformation.GetAllMedia(handle, callback, IntPtr.Zero), "Failed to get media information");
542 return mediaInformationList;
546 /// Deletes a MediaInformation from the media database.
548 /// <since_tizen> 3 </since_tizen>
549 /// <param name="mediaInfo">The MediaInformation to be deleted</param>
550 public void Delete(MediaInformation mediaInfo)
552 MediaContentValidator.ThrowIfError(
553 Interop.MediaInformation.Delete(mediaInfo.MediaId), "Failed to remove information");
558 /// Deletes a content collection from the media database.
559 /// Applicable for Tag and PlayList only.
560 /// For other types ArgumentException is thrown.
562 /// <since_tizen> 3 </since_tizen>
563 /// <param name="contentcollection">The ContentCollection instance to be deleted</param>
564 public void Delete(ContentCollection contentcollection)
566 Type type = contentcollection.GetType();
568 if (type == typeof(Tag))
570 MediaContentValidator.ThrowIfError(
571 Interop.Tag.DeleteFromDb(((Tag)contentcollection).Id), "Failed to remove information");
573 else if (type == typeof(PlayList))
575 MediaContentValidator.ThrowIfError(
576 Interop.Playlist.DeleteFromDb(((PlayList)contentcollection).Id), "Failed to remove information");
580 throw new ArgumentException("The type of content collection is wrong");
584 internal void Delete(MediaBookmark bookmark)
586 MediaContentValidator.ThrowIfError(
587 Interop.MediaBookmark.DeleteFromDb(bookmark.Id), "Failed to remove information");
590 internal void Delete(MediaFace face)
592 MediaContentValidator.ThrowIfError(
593 Interop.Face.DeleteFromDb(face.Id), "Failed to remove face information");
597 /// Updates a content collection in the media database
598 /// Applicable for Tag, PlayList and MediagFolder types only.
600 /// <since_tizen> 3 </since_tizen>
601 /// <param name="contentCollection">The content collection to be updated</param>
602 public void Update(ContentCollection contentCollection)
604 Type type = contentCollection.GetType();
605 if (type == typeof(Tag))
607 MediaContentValidator.ThrowIfError(
608 Interop.Tag.UpdateToDb(((Tag)contentCollection).Handle), "Failed to update DB");
610 else if (type == typeof(PlayList))
612 MediaContentValidator.ThrowIfError(
613 Interop.Playlist.UpdateToDb(((PlayList)contentCollection).Handle), "Failed to update DB");
615 else if (type == typeof(MediaFolder))
617 MediaContentValidator.ThrowIfError(
618 Interop.Folder.UpdateToDb(((MediaFolder)contentCollection).Handle), "Failed to update DB");
622 throw new ArgumentException("The type of content collection is wrong");
627 /// Updates a media information instance in the media database
629 /// <since_tizen> 3 </since_tizen>
630 /// <param name="mediaInfo">The MediaInformation object to be updated</param>
631 public void Update(MediaInformation mediaInfo)
633 Type type = mediaInfo.GetType();
634 if (type == typeof(ImageInformation))
636 MediaContentValidator.ThrowIfError(
637 Interop.ImageInformation.UpdateToDB(((ImageInformation)mediaInfo).ImageHandle), "Failed to update DB");
639 MediaContentValidator.ThrowIfError(
640 Interop.MediaInformation.UpdateToDB(mediaInfo.MediaHandle), "Failed to update DB");
642 else if (type == typeof(AudioInformation))
644 MediaContentValidator.ThrowIfError(
645 Interop.AudioInformation.UpdateToDB(((AudioInformation)mediaInfo).AudioHandle), "Failed to update DB");
647 MediaContentValidator.ThrowIfError(
648 Interop.MediaInformation.UpdateToDB(mediaInfo.MediaHandle), "Failed to update DB");
650 else if (type == typeof(VideoInformation))
652 MediaContentValidator.ThrowIfError(
653 Interop.VideoInformation.UpdateToDB(((VideoInformation)mediaInfo).VideoHandle), "Failed to update DB");
655 MediaContentValidator.ThrowIfError(
656 Interop.MediaInformation.UpdateToDB(mediaInfo.MediaHandle), "Failed to update DB");
658 else if (type == typeof(MediaInformation))
660 MediaContentValidator.ThrowIfError(
661 Interop.MediaInformation.UpdateToDB(mediaInfo.MediaHandle), "Failed to update DB");
665 throw new ArgumentException("Invalid information type");
669 internal void Update(MediaFace face)
671 MediaContentValidator.ThrowIfError(Interop.Face.UpdateToDb(face.Handle), "Failed to update DB");
675 /// Inserts a content collection to the media database.
676 /// Applicable for Tag and PlayList types only.
678 /// <since_tizen> 3 </since_tizen>
679 /// <param name="contentCollection">The content collection to be inserted</param>
680 public void Insert(ContentCollection contentCollection)
682 Type type = contentCollection.GetType();
683 IntPtr handle = IntPtr.Zero;
684 if (type == typeof(Tag))
686 MediaContentValidator.ThrowIfError(
687 Interop.Tag.InsertToDb(((Tag)contentCollection).Name, out handle), "Failed to insert collection");
688 ((Tag)contentCollection).Handle = handle;
690 else if (type == typeof(PlayList))
692 MediaContentValidator.ThrowIfError(
693 Interop.Playlist.InsertToDb(((PlayList)contentCollection).Name, out handle), "Failed to insert collection");
694 ((PlayList)contentCollection).Handle = handle;
698 throw new ArgumentException("collection type is wrong");
702 internal void Insert(string mediaId, uint offset, string thumbnailPath)
704 MediaContentValidator.ThrowIfError(
705 Interop.MediaBookmark.InsertToDb(mediaId, offset, thumbnailPath), "Failed to insert information");
708 internal void Insert(MediaFace face)
710 MediaContentValidator.ThrowIfError(
711 Interop.Face.InsertToDb(((MediaFace)face).Handle), "Failed to insert information");