Release 4.0.0-preview1-00051
[platform/core/csapi/tizenfx.git] / src / Tizen.Content.MediaContent / Tizen.Content.MediaContent / ContentManager.cs
1 /*
2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17
18
19 using System;
20 using System.Collections.Generic;
21 using System.Threading.Tasks;
22 using System.Threading;
23
24 /// <summary>
25 /// The Media Content API provides functions, enumerations used in the entire Content Service.
26 /// </summary>
27 /// <remarks>
28 /// The Media Content API provides functions and enumerations used in the entire Content Service.
29 /// The information about media items i.e.image, audio and video, are managed in the content database
30 /// and operations that involve database requires an active connection with the media content service.
31 /// During media scanning, Media Service extract media information automatically. media information
32 /// include basic file info like path, size, modified time etc and some metadata like ID3tag, EXIF,
33 /// thumbnail, etc. (thumbnail extracted only in Internal and SD card storage.
34 /// Media content services do not manage hidden files.
35 /// The API provides functions for connecting (media_content_connect()) and disconnecting(media_content_disconnect())
36 /// from the media content service.
37 /// </remarks>
38
39
40 namespace Tizen.Content.MediaContent
41 {
42     /// <summary>
43     /// ContentManager class is the interface class for accessing the ContentCollection and MediaInformation.
44     /// This class allows usre to create/update db operations for media content.
45     /// </summary>
46     public static class ContentManager
47     {
48         private static readonly ContentDatabase s_contentDB = new ContentDatabase();
49
50         /// <summary>
51         /// Database instance to do all the Database oprtions for media content management.
52         /// </summary>
53         /// <since_tizen> 3 </since_tizen>
54         public static ContentDatabase Database
55         {
56             get
57             {
58                 return s_contentDB;
59             }
60         }
61
62         /// <summary>
63         /// Requests to scan a media file.
64         /// </summary>
65         /// <since_tizen> 3 </since_tizen>
66         /// <param name="filePath">File path of the media to be scanned</param>
67         /// <returns>A reference to the MediaInformation object scanned</returns>
68         /// <remarks>
69         /// This function requests to scan a media file to the media server. If media file is not registered to DB yet,
70         /// that media file information will be added to the media DB. If it is already registered to the DB,
71         /// then this tries to refresh information. If requested file does not exist on file system,
72         /// information of the media file will be removed from the media DB.
73         /// </remarks>
74         public static void Scan(string filePath)
75         {
76             MediaContentValidator.ThrowIfError(Interop.Content.ScanFile(filePath), "Failed scan");
77         }
78
79         /// <summary>
80         /// Inserts a media to the media database
81         /// </summary>
82         /// <since_tizen> 3 </since_tizen>
83         /// <param name="filePath">File path of the media to be inserted</param>
84         /// <returns>the MediaInformation instance about added media path</returns>
85         public static MediaInformation AddMediaInformation(string filePath)
86         {
87             Interop.MediaInformation.SafeMediaInformationHandle mediaInformationHandle;
88             MediaContentValidator.ThrowIfError(
89                 Interop.MediaInformation.Insert(filePath, out mediaInformationHandle), "Failed to Insert MediaInformation to DB");
90
91             MediaContentType type;
92             MediaInformation res;
93             Interop.MediaInformation.GetMediaType(mediaInformationHandle, out type);
94             if (type == MediaContentType.Image)
95             {
96                 Interop.ImageInformation.SafeImageInformationHandle imageInfo;
97                 MediaContentValidator.ThrowIfError(
98                     Interop.MediaInformation.GetImage(mediaInformationHandle.DangerousGetHandle(), out imageInfo), "Failed to get image information");
99
100                 res = new ImageInformation(imageInfo, mediaInformationHandle);
101             }
102             else if ((type == MediaContentType.Music) || (type == MediaContentType.Sound))
103             {
104                 Interop.AudioInformation.SafeAudioInformationHandle audioInfo;
105                 MediaContentValidator.ThrowIfError(
106                     Interop.MediaInformation.GetAudio(mediaInformationHandle.DangerousGetHandle(), out audioInfo), "Failed to get audio information");
107
108                 res = new AudioInformation(audioInfo, mediaInformationHandle);
109             }
110             else if (type == MediaContentType.Video)
111             {
112                 Interop.VideoInformation.SafeVideoInformationHandle videoInfo;
113                 MediaContentValidator.ThrowIfError(
114                     Interop.MediaInformation.GetVideo(mediaInformationHandle.DangerousGetHandle(), out videoInfo), "Failed to get video information");
115
116                 res = new VideoInformation(videoInfo, mediaInformationHandle);
117             }
118             else
119             {
120                 res = new MediaInformation(mediaInformationHandle);
121             }
122
123             return res;
124         }
125
126         /// <summary>
127         /// Requests to scan a media folder, asynchronously.
128         /// </summary>
129         /// <since_tizen> 3 </since_tizen>
130         /// <param name="folderPath">The folder path</param>
131         /// <param name="recursive">Indicate sif the folder is to recursively scanned. Default value: true</param>
132         /// <remarks>
133         /// This function requests to scan a media folder to the media server with given completed callback function.
134         /// The sub folders are also scanned,if there are sub folders in that folder.
135         /// If any folder must not be scanned, a blank file ".scan_ignore" has to be created in that folder.
136         /// </remarks>
137         /// <returns>Task with scanning result</returns>
138         public static Task<MediaContentError> ScanFolderAsync(string folderPath, bool recursive = true)
139         {
140             var task = new TaskCompletionSource<MediaContentError>();
141
142             Interop.Content.MediaScanCompletedCallback scanCompleted = (MediaContentError scanResult, IntPtr data) =>
143             {
144                 MediaContentValidator.ThrowIfError(scanResult, "Failed to scan");
145                 task.SetResult(scanResult);
146             };
147
148             MediaContentValidator.ThrowIfError(
149                 Interop.Content.ScanFolder(folderPath, recursive, scanCompleted, IntPtr.Zero), "Failed to scan");
150
151             return task.Task;
152         }
153
154         internal static Interop.Content.MediaScanCompletedCallback scanCompletedWithToken = null;
155         internal static Object l = new Object();
156         /// <summary>
157         /// Requests to scan a media folder, asynchronously.
158         /// </summary>
159         /// <since_tizen> 3 </since_tizen>
160         /// <param name="folderPath">The folder path</param>
161         /// <param name="cancellationToken">Cancellation token required to cancel the current scan</param>
162         /// <param name="recursive">Indicate sif the folder is to recursively scanned. Default value: true</param>
163         /// <remarks>
164         /// This function requests to scan a media folder to the media server with given completed callback function.
165         /// The sub folders are also scanned,if there are sub folders in that folder.
166         /// If any folder must not be scanned, a blank file ".scan_ignore" has to be created in that folder.
167         /// </remarks>
168         /// <returns>Task with scanning result</returns>
169         public static Task ScanFolderAsync(string folderPath, CancellationToken cancellationToken, bool recursive = true)
170         {
171             var task = new TaskCompletionSource<int>();
172             bool taskCompleted = false;
173
174             cancellationToken.Register(() =>
175             {
176                 lock (l)
177                 {
178                     if (!taskCompleted)
179                     {
180                         taskCompleted = true;
181                         MediaContentValidator.ThrowIfError(
182                             Interop.Content.CancelScanFolder(folderPath), "Failed CancelScanFolder");
183
184                         task.SetCanceled();
185                     }
186                 }
187             });
188             scanCompletedWithToken = (MediaContentError scanResult, IntPtr data) =>
189             {
190                 lock (l)
191                 {
192                     if (!taskCompleted)
193                     {
194                         taskCompleted = true;
195                         MediaContentValidator.ThrowIfError(scanResult, "Failed scan");
196                         task.SetResult((int)scanResult);
197                     }
198                 }
199             };
200
201             MediaContentValidator.ThrowIfError(
202                 Interop.Content.ScanFolder(folderPath, recursive, scanCompletedWithToken, IntPtr.Zero), "Failed to scan");
203
204             return task.Task;
205
206         }
207
208         /// <summary>
209         /// Inserts media files into the media database, asynchronously.
210         /// </summary>
211         /// <since_tizen> 3 </since_tizen>
212         /// <param name="filePaths">The path array to the media files</param>
213         /// <returns>
214         /// Task with the result of batch insertion
215         /// </returns>
216         public static Task AddMediaInformationBatchAsync(IEnumerable<string> filePaths)
217         {
218             var task = new TaskCompletionSource<int>();
219             string[] paths = ((List<string>)filePaths).ToArray();
220             Interop.MediaInformation.MediaInsertCompletedCallback callback = (MediaContentError error, IntPtr userData) =>
221             {
222                 MediaContentValidator.ThrowIfError(error, "Failed to batch insert");
223                 task.SetResult((int)error);
224             };
225             MediaContentValidator.ThrowIfError(
226                 Interop.MediaInformation.BatchInsert(paths, paths.Length, callback, IntPtr.Zero), "Failed to add batch media");
227
228             return task.Task;
229         }
230
231         /// <summary>
232         /// Inserts the burst shot images into the media database, asynchronously.
233         /// </summary>
234         /// <since_tizen> 3 </since_tizen>
235         /// <param name="filePaths">The path array to the burst shot images</param>
236         /// <returns>
237         /// Task with the result of the burstshot insertion
238         /// </returns>
239         public static Task AddBurstShotImagesAsync(IEnumerable<string> filePaths)
240         {
241             var task = new TaskCompletionSource<int>();
242             string[] paths = ((List<string>)filePaths).ToArray();
243             Interop.MediaInformation.MediaInsertBurstShotCompletedCallback callback = (MediaContentError error, IntPtr userData) =>
244             {
245                 MediaContentValidator.ThrowIfError(error, "Failed to add burstshot");
246                 task.SetResult((int)error);
247             };
248             MediaContentValidator.ThrowIfError(
249                 Interop.MediaInformation.BurstShotInsert(paths, paths.Length, callback, IntPtr.Zero), "Failed to add burst shots to db");
250
251             return task.Task;
252         }
253
254         /// <summary>
255         /// Deletes media files from the media database. The media files for deletion can be specified as a condition in a filter.
256         /// This function deletes the media items from the content storage.Normally, deleting media files in the database are done automatically by the media server,
257         /// without calling this function.This function is only called when the media server is busy and user needs to get quick result of deleting.
258         /// </summary>
259         /// <since_tizen> 3 </since_tizen>
260         /// <param name="filter">The content filter to which media will be matched</param>
261         public static void RemoveMediaInformationBatch(ContentFilter filter)
262         {
263             IntPtr handle = (filter != null) ? filter.Handle : IntPtr.Zero;
264             MediaContentValidator.ThrowIfError(
265                 Interop.MediaInformation.BatchDelete(handle), "Failed to remove items");
266         }
267     }
268 }