Remove the queue for the folder insertion
[platform/core/multimedia/libmedia-service.git] / src / common / media-svc.c
1 /*
2  * libmedia-service
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Hyunjun Ko <zzoon.ko@samsung.com>, Haejeong Kim <backto.kim@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <string.h>
23 #include <errno.h>
24 #include "media-svc.h"
25 #include "media-svc-media.h"
26 #include "media-svc-debug.h"
27 #include "media-svc-util.h"
28 #include "media-svc-db-utils.h"
29 #include "media-svc-env.h"
30 #include "media-svc-media-folder.h"
31 #include "media-svc-album.h"
32 #include "media-svc-noti.h"
33 #include "media-svc-storage.h"
34
35 static __thread int g_media_svc_item_validity_data_cnt = 1;
36 static __thread int g_media_svc_item_validity_cur_data_cnt = 0;
37
38 static __thread int g_media_svc_insert_item_data_cnt = 1;
39 static __thread int g_media_svc_insert_item_cur_data_cnt = 0;
40
41 static __thread int g_media_svc_update_item_data_cnt = 1;
42 static __thread int g_media_svc_update_item_cur_data_cnt = 0;
43
44 /* Flag for items to be published by notification */
45 static __thread int g_insert_with_noti = FALSE;
46
47 #define BATCH_REQUEST_MAX 300
48
49 int media_svc_get_user_version(sqlite3 *handle, int *user_version)
50 {
51         return _media_svc_get_user_version(handle, user_version);
52 }
53
54 int media_svc_create_table(uid_t uid)
55 {
56         int ret = MS_MEDIA_ERR_NONE;
57         char *sql = NULL;
58
59         media_svc_debug_fenter();
60
61         ret = _media_svc_init_table_query(MEDIA_SVC_DB_TABLE_MEDIA);
62         if (ret != MS_MEDIA_ERR_NONE) {
63                 media_svc_error("_media_svc_init_table_query fail.");
64                 goto ERROR;
65         }
66
67         /*create media table*/
68         ret = _media_svc_make_table_query(MEDIA_SVC_DB_TABLE_MEDIA, MEDIA_SVC_DB_LIST_MEDIA, uid);
69         if (ret != MS_MEDIA_ERR_NONE) {
70                 media_svc_error("_media_svc_make_table_query fail.");
71                 goto ERROR;
72         }
73
74         /*create folder table*/
75         ret = _media_svc_make_table_query(MEDIA_SVC_DB_TABLE_FOLDER, MEDIA_SVC_DB_LIST_FOLDER, uid);
76         if (ret != MS_MEDIA_ERR_NONE) {
77                 media_svc_error("_media_svc_make_table_query fail.");
78                 goto ERROR;
79         }
80
81         /*create playlist_map table*/
82         ret = _media_svc_make_table_query(MEDIA_SVC_DB_TABLE_PLAYLIST_MAP, MEDIA_SVC_DB_LIST_PLAYLIST_MAP, uid);
83         if (ret != MS_MEDIA_ERR_NONE) {
84                 media_svc_error("_media_svc_make_table_query fail.");
85                 goto ERROR;
86         }
87
88         /*create playlist table*/
89         ret = _media_svc_make_table_query(MEDIA_SVC_DB_TABLE_PLAYLIST, MEDIA_SVC_DB_LIST_PLAYLIST, uid);
90         if (ret != MS_MEDIA_ERR_NONE) {
91                 media_svc_error("_media_svc_make_table_query fail.");
92                 goto ERROR;
93         }
94
95         /* create album table*/
96         ret = _media_svc_make_table_query(MEDIA_SVC_DB_TABLE_ALBUM, MEDIA_SVC_DB_LIST_ALBUM, uid);
97         if (ret != MS_MEDIA_ERR_NONE) {
98                 media_svc_error("_media_svc_make_table_query fail.");
99                 goto ERROR;
100         }
101
102         /*create tag_map table*/
103         ret = _media_svc_make_table_query(MEDIA_SVC_DB_TABLE_TAG_MAP, MEDIA_SVC_DB_LIST_TAG_MAP, uid);
104         if (ret != MS_MEDIA_ERR_NONE) {
105                 media_svc_error("_media_svc_make_table_query fail.");
106                 goto ERROR;
107         }
108
109         /*create tag table*/
110         ret = _media_svc_make_table_query(MEDIA_SVC_DB_TABLE_TAG, MEDIA_SVC_DB_LIST_TAG, uid);
111         if (ret != MS_MEDIA_ERR_NONE) {
112                 media_svc_error("_media_svc_make_table_query fail.");
113                 goto ERROR;
114         }
115
116         /*create bookmark table*/
117         ret = _media_svc_make_table_query(MEDIA_SVC_DB_TABLE_BOOKMARK, MEDIA_SVC_DB_LIST_BOOKMARK, uid);
118         if (ret != MS_MEDIA_ERR_NONE) {
119                 media_svc_error("_media_svc_make_table_query fail.");
120                 goto ERROR;
121         }
122
123         /*create storage table from tizen 2.4 */
124         ret = _media_svc_make_table_query(MEDIA_SVC_DB_TABLE_STORAGE, MEDIA_SVC_DB_LIST_STORAGE, uid);
125         if (ret != MS_MEDIA_ERR_NONE) {
126                 media_svc_error("_media_svc_make_table_query fail.");
127                 goto ERROR;
128         }
129
130         /*create face table. from tizen 3.0*/
131         ret = _media_svc_make_table_query(MEDIA_SVC_DB_TABLE_FACE_SCAN_LIST, MEDIA_SVC_DB_LIST_FACE_SCAN_LIST, uid);
132         if (ret != MS_MEDIA_ERR_NONE) {
133                 media_svc_error("_media_svc_make_table_query fail.");
134                 goto ERROR;
135         }
136
137         ret = _media_svc_make_table_query(MEDIA_SVC_DB_TABLE_FACE, MEDIA_SVC_DB_LIST_FACE, uid);
138         if (ret != MS_MEDIA_ERR_NONE) {
139                 media_svc_error("_media_svc_make_table_query fail.");
140                 goto ERROR;
141         }
142
143         sql = sqlite3_mprintf("pragma user_version = %d;", LATEST_VERSION_NUMBER);
144         ret = _media_svc_sql_query(sql, uid);
145         if (ret != MS_MEDIA_ERR_NONE) {
146                 media_svc_error("user_version update fail.");
147                 goto ERROR;
148         }
149
150         _media_svc_destroy_table_query();
151
152         media_svc_debug_fleave();
153
154         return MS_MEDIA_ERR_NONE;
155 ERROR:
156         _media_svc_destroy_table_query();
157
158         media_svc_debug_fleave();
159
160         return ret;
161 }
162
163 int media_svc_check_item_exist_by_path(sqlite3 *handle, const char *storage_id, const char *path)
164 {
165         int ret = MS_MEDIA_ERR_NONE;
166         int count = -1;
167
168         ret = _media_svc_count_record_with_path(handle, storage_id, path, &count);
169         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
170
171         if (count > 0) {
172                 media_svc_debug("item is exist in database");
173                 return MS_MEDIA_ERR_NONE;
174         } else {
175                 media_svc_debug("item is not exist in database");
176                 return MS_MEDIA_ERR_DB_NO_RECORD;
177         }
178
179         return MS_MEDIA_ERR_NONE;
180 }
181
182 int media_svc_get_modified_time(sqlite3 *handle, const char *storage_id, const char *path, int *modified_time)
183 {
184         return _media_svc_get_modified_time(handle, storage_id, path, modified_time);
185 }
186
187 int media_svc_insert_item_begin(int data_cnt, int with_noti, int from_pid)
188 {
189         media_svc_retvm_if(data_cnt < 1, MS_MEDIA_ERR_INVALID_PARAMETER, "data_cnt shuld be bigger than 1");
190
191         g_media_svc_insert_item_data_cnt = data_cnt;
192         g_media_svc_insert_item_cur_data_cnt = 0;
193
194         /* Prepare for making noti item list */
195         if (with_noti) {
196                 media_svc_debug("making noti list from pid[%d]", from_pid);
197                 if (_media_svc_create_noti_list(data_cnt) != MS_MEDIA_ERR_NONE)
198                         return MS_MEDIA_ERR_OUT_OF_MEMORY;
199
200                 _media_svc_set_noti_from_pid(from_pid);
201                 g_insert_with_noti = TRUE;
202         }
203
204         return MS_MEDIA_ERR_NONE;
205 }
206
207 int media_svc_insert_item_end(uid_t uid)
208 {
209         int ret = MS_MEDIA_ERR_NONE;
210
211         media_svc_debug_fenter();
212
213         if (g_media_svc_insert_item_cur_data_cnt > 0) {
214
215                 ret = _media_svc_list_query_do(MEDIA_SVC_QUERY_INSERT_ITEM, uid);
216                 if (g_insert_with_noti) {
217                         media_svc_debug("sending noti list");
218                         _media_svc_publish_noti_list(g_media_svc_insert_item_cur_data_cnt);
219                         _media_svc_destroy_noti_list(g_media_svc_insert_item_cur_data_cnt);
220                         g_insert_with_noti = FALSE;
221                         _media_svc_set_noti_from_pid(-1);
222                 }
223         }
224
225         g_media_svc_insert_item_data_cnt = 1;
226         g_media_svc_insert_item_cur_data_cnt = 0;
227
228         return ret;
229 }
230
231 int media_svc_insert_item_bulk(sqlite3 *handle, const char *storage_id, ms_user_storage_type_e storage_type, const char *path, uid_t uid)
232 {
233         int ret = MS_MEDIA_ERR_NONE;
234         char folder_uuid[MEDIA_SVC_UUID_SIZE + 1] = {0, };
235
236         media_svc_retvm_if(handle == NULL, MS_MEDIA_ERR_INVALID_PARAMETER, "Handle is NULL");
237         media_svc_retvm_if(!STRING_VALID(storage_id), MS_MEDIA_ERR_INVALID_PARAMETER, "storage_id is NULL");
238         media_svc_retvm_if(!STRING_VALID(path), MS_MEDIA_ERR_INVALID_PARAMETER, "path is NULL");
239         media_svc_retvm_if(_media_svc_check_storage_type(storage_type) != TRUE, MS_MEDIA_ERR_INVALID_PARAMETER, "Invalid storage_type");
240
241         media_svc_content_info_s content_info;
242         memset(&content_info, 0, sizeof(media_svc_content_info_s));
243
244         /*Set media info*/
245         /* if drm_contentinfo is not NULL, the file is OMA DRM.*/
246         ret = _media_svc_set_media_info(&content_info, storage_id, storage_type, path, FALSE);
247         if (ret != MS_MEDIA_ERR_NONE)
248                 return ret;
249
250         if (content_info.media_type == MEDIA_SVC_MEDIA_TYPE_OTHER
251         || (content_info.media_type == MEDIA_SVC_MEDIA_TYPE_PVR)
252         || (content_info.media_type == MEDIA_SVC_MEDIA_TYPE_UHD)
253         || (content_info.media_type == MEDIA_SVC_MEDIA_TYPE_SCSA))
254                 media_svc_debug("Do nothing[%d]", content_info.media_type);
255         else if (content_info.media_type == MEDIA_SVC_MEDIA_TYPE_IMAGE)
256                 ret = _media_svc_extract_image_metadata(&content_info);
257         else
258                 ret = _media_svc_extract_media_metadata(handle, true, &content_info, uid);
259         media_svc_retv_del_if(ret != MS_MEDIA_ERR_NONE, ret, &content_info);
260
261         /*Set or Get folder id*/
262         ret = _media_svc_get_and_append_folder_id_by_path(handle, true, storage_id, path, storage_type, folder_uuid, uid);
263         media_svc_retv_del_if(ret != MS_MEDIA_ERR_NONE, ret, &content_info);
264
265         content_info.folder_uuid = g_strdup(folder_uuid);
266         media_svc_retv_del_if(content_info.folder_uuid == NULL, MS_MEDIA_ERR_INTERNAL, &content_info);
267
268         if (g_media_svc_insert_item_data_cnt == 1) {
269
270                 ret = _media_svc_insert_item_with_data(handle, true, storage_id, &content_info, FALSE, uid);
271                 media_svc_retv_del_if(ret != MS_MEDIA_ERR_NONE, ret, &content_info);
272
273                 if (g_insert_with_noti)
274                         _media_svc_insert_item_to_noti_list(&content_info, g_media_svc_insert_item_cur_data_cnt++);
275
276         } else if (g_media_svc_insert_item_cur_data_cnt < (g_media_svc_insert_item_data_cnt - 1)) {
277
278                 ret = _media_svc_insert_item_with_data(handle, true, storage_id, &content_info, TRUE, uid);
279                 media_svc_retv_del_if(ret != MS_MEDIA_ERR_NONE, ret, &content_info);
280
281                 if (g_insert_with_noti)
282                         _media_svc_insert_item_to_noti_list(&content_info, g_media_svc_insert_item_cur_data_cnt);
283
284                 g_media_svc_insert_item_cur_data_cnt++;
285
286         } else if (g_media_svc_insert_item_cur_data_cnt == (g_media_svc_insert_item_data_cnt - 1)) {
287
288                 ret = _media_svc_insert_item_with_data(handle, true, storage_id, &content_info, TRUE, uid);
289                 media_svc_retv_del_if(ret != MS_MEDIA_ERR_NONE, ret, &content_info);
290
291                 if (g_insert_with_noti)
292                         _media_svc_insert_item_to_noti_list(&content_info, g_media_svc_insert_item_cur_data_cnt);
293
294                 ret = _media_svc_list_query_do(MEDIA_SVC_QUERY_INSERT_ITEM, uid);
295                 media_svc_retv_del_if(ret != MS_MEDIA_ERR_NONE, ret, &content_info);
296
297                 if (g_insert_with_noti) {
298                         _media_svc_publish_noti_list(g_media_svc_insert_item_cur_data_cnt + 1);
299                         _media_svc_destroy_noti_list(g_media_svc_insert_item_cur_data_cnt + 1);
300
301                         /* Recreate noti list */
302                         ret = _media_svc_create_noti_list(g_media_svc_insert_item_data_cnt);
303                         media_svc_retv_del_if(ret != MS_MEDIA_ERR_NONE, ret, &content_info);
304                 }
305
306                 g_media_svc_insert_item_cur_data_cnt = 0;
307
308         } else {
309                 media_svc_error("Error in media_svc_insert_item_bulk");
310                 _media_svc_destroy_content_info(&content_info);
311                 return MS_MEDIA_ERR_INTERNAL;
312         }
313
314         _media_svc_destroy_content_info(&content_info);
315
316         return MS_MEDIA_ERR_NONE;
317 }
318
319 int media_svc_insert_item_immediately(sqlite3 *handle, const char *storage_id, ms_user_storage_type_e storage_type, const char *path, uid_t uid)
320 {
321         int ret = MS_MEDIA_ERR_NONE;
322         char folder_uuid[MEDIA_SVC_UUID_SIZE + 1] = {0, };
323
324         media_svc_retvm_if(handle == NULL, MS_MEDIA_ERR_INVALID_PARAMETER, "Handle is NULL");
325         media_svc_retvm_if(!STRING_VALID(storage_id), MS_MEDIA_ERR_INVALID_PARAMETER, "storage_id is NULL");
326         media_svc_retvm_if(!STRING_VALID(path), MS_MEDIA_ERR_INVALID_PARAMETER, "path is NULL");
327         media_svc_retvm_if(_media_svc_check_storage_type(storage_type) != TRUE, MS_MEDIA_ERR_INVALID_PARAMETER, "Invalid storage_type");
328
329         media_svc_content_info_s content_info;
330         memset(&content_info, 0, sizeof(media_svc_content_info_s));
331
332         /*Set media info*/
333         ret = _media_svc_set_media_info(&content_info, storage_id, storage_type, path, FALSE);
334         if (ret != MS_MEDIA_ERR_NONE)
335                 return ret;
336
337         if (content_info.media_type == MEDIA_SVC_MEDIA_TYPE_OTHER
338         || (content_info.media_type == MEDIA_SVC_MEDIA_TYPE_PVR)
339         || (content_info.media_type == MEDIA_SVC_MEDIA_TYPE_UHD)
340         || (content_info.media_type == MEDIA_SVC_MEDIA_TYPE_SCSA)) {
341                 /*Do nothing.*/
342         } else if (content_info.media_type == MEDIA_SVC_MEDIA_TYPE_IMAGE) {
343                 ret = _media_svc_extract_image_metadata(&content_info);
344         } else {
345                 ret = _media_svc_extract_media_metadata(handle, false, &content_info, uid);
346         }
347
348         media_svc_retv_del_if(ret != MS_MEDIA_ERR_NONE, ret, &content_info);
349
350         /*Set or Get folder id*/
351         ret = _media_svc_get_and_append_folder_id_by_path(handle, false, storage_id, path, storage_type, folder_uuid, uid);
352         media_svc_retv_del_if(ret != MS_MEDIA_ERR_NONE, ret, &content_info);
353
354         content_info.folder_uuid = g_strdup(folder_uuid);
355         media_svc_retv_del_if(content_info.folder_uuid == NULL, MS_MEDIA_ERR_INTERNAL, &content_info);
356
357         /* Extracting thumbnail */
358         if (content_info.thumbnail_path == NULL) {
359                 if (content_info.media_type == MEDIA_SVC_MEDIA_TYPE_IMAGE || content_info.media_type == MEDIA_SVC_MEDIA_TYPE_VIDEO) {
360                         char thumb_path[MEDIA_SVC_PATHNAME_SIZE + 1] = {0, };
361
362                         ret = _media_svc_create_thumbnail(content_info.path, thumb_path, content_info.media_type, uid);
363                         if (ret == MS_MEDIA_ERR_NONE)
364                                 content_info.thumbnail_path = g_strdup(thumb_path);
365                 }
366         }
367
368         ret = _media_svc_insert_item_with_data(handle, false, storage_id, &content_info, FALSE, uid);
369
370         if (ret == MS_MEDIA_ERR_NONE) {
371                 media_svc_debug("Insertion is successful. Sending noti for this");
372                 _media_svc_publish_noti(MS_MEDIA_ITEM_INSERT, content_info.path, content_info.media_type, content_info.media_uuid, content_info.mime_type);
373         } else if (ret == MS_MEDIA_ERR_DB_CONSTRAINT_FAIL) {
374                 media_svc_error("This item is already inserted. This may be normal operation because other process already did this");
375         }
376
377         _media_svc_destroy_content_info(&content_info);
378         return ret;
379 }
380
381 int media_svc_move_item(sqlite3 *handle,
382                                                                 const char *src_path,
383                                                                 const char *dest_path,
384                                                                 const char *media_id,
385                                                                 int media_type,
386                                                                 const char *mime_type,
387                                                                 uid_t uid)
388 {
389         int ret = MS_MEDIA_ERR_NONE;
390         char *file_name = NULL;
391         char *folder_path = NULL;
392         int modified_time = 0;
393         char folder_uuid[MEDIA_SVC_UUID_SIZE + 1] = {0, };
394         char old_thumb_path[MEDIA_SVC_PATHNAME_SIZE] = {0, };
395         char org_stg_id[MEDIA_SVC_UUID_SIZE + 1] = {0, };
396         char dst_stg_id[MEDIA_SVC_UUID_SIZE + 1] = {0, };
397         ms_user_storage_type_e org_stg_type = MS_USER_STORAGE_INTERNAL;
398         ms_user_storage_type_e dst_stg_type = MS_USER_STORAGE_INTERNAL;
399
400         media_svc_debug_fenter();
401
402         media_svc_retvm_if(handle == NULL, MS_MEDIA_ERR_INVALID_PARAMETER, "Handle is NULL");
403         media_svc_retvm_if(!STRING_VALID(src_path), MS_MEDIA_ERR_INVALID_PARAMETER, "src_path is NULL");
404         media_svc_retvm_if(!STRING_VALID(dest_path), MS_MEDIA_ERR_INVALID_PARAMETER, "dest_path is NULL");
405         media_svc_retvm_if(!STRING_VALID(media_id), MS_MEDIA_ERR_INVALID_PARAMETER, "media_id is NULL");
406         media_svc_retvm_if(!STRING_VALID(mime_type), MS_MEDIA_ERR_INVALID_PARAMETER, "mime_type is NULL");
407
408         /* Get storage_id */
409         ret = _media_svc_get_storage_uuid(handle, src_path, org_stg_id, uid);
410         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
411         ret = _media_svc_get_storage_uuid(handle, dest_path, dst_stg_id, uid);
412         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
413         /* Get storage_type */
414         ret = ms_user_get_storage_type(uid, src_path, &org_stg_type);
415         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
416         ret = ms_user_get_storage_type(uid, dest_path, &dst_stg_type);
417         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
418
419         /*check and update folder*/
420         ret = _media_svc_get_and_append_folder_id_by_path(handle, false, dst_stg_id, dest_path, dst_stg_type, folder_uuid, uid);
421         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
422
423         /*get filename*/
424         file_name = g_path_get_basename(dest_path);
425
426         /*get modified_time*/
427         modified_time = _media_svc_get_file_time(dest_path);
428
429         /*get old thumbnail_path and remove thumbnail */
430         ret = _media_svc_get_thumbnail_path_by_path(handle, src_path, old_thumb_path);
431         if ((ret != MS_MEDIA_ERR_NONE) && (ret != MS_MEDIA_ERR_DB_NO_RECORD)) {
432                 media_svc_error("_media_svc_get_thumbnail_path_by_path failed");
433                 SAFE_FREE(file_name);
434                 return ret;
435         }
436
437         if (STRING_VALID(old_thumb_path)) {
438                 ret = _media_svc_remove_file(old_thumb_path);
439                 if (ret != MS_MEDIA_ERR_NONE)
440                         media_svc_error("_media_svc_remove_file failed : %d", ret);
441         }
442
443         /*move item*/
444         ret = _media_svc_update_item_by_path(org_stg_id, src_path, dst_stg_id, dst_stg_type, dest_path, file_name, modified_time, folder_uuid, uid);
445         SAFE_FREE(file_name);
446         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
447
448         media_svc_debug("Move is successful. Sending noti for this");
449         _media_svc_publish_noti(MS_MEDIA_ITEM_UPDATE, src_path, media_type, media_id, mime_type);
450
451         /*update folder modified_time*/
452         folder_path = g_path_get_dirname(dest_path);
453         ret = _media_svc_update_folder_modified_time_by_folder_uuid(folder_uuid, folder_path, uid);
454         SAFE_FREE(folder_path);
455         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
456
457         return MS_MEDIA_ERR_NONE;
458 }
459
460 int media_svc_set_item_validity_begin(int data_cnt)
461 {
462         media_svc_debug("Transaction data count : [%d]", data_cnt);
463
464         media_svc_retvm_if(data_cnt < 1, MS_MEDIA_ERR_INVALID_PARAMETER, "data_cnt shuld be bigger than 1");
465
466         g_media_svc_item_validity_data_cnt = data_cnt;
467         g_media_svc_item_validity_cur_data_cnt = 0;
468
469         return MS_MEDIA_ERR_NONE;
470 }
471
472 int media_svc_set_item_validity_end(uid_t uid)
473 {
474         int ret = MS_MEDIA_ERR_NONE;
475
476         media_svc_debug_fenter();
477
478         if (g_media_svc_item_validity_cur_data_cnt > 0)
479                 ret = _media_svc_list_query_do(MEDIA_SVC_QUERY_SET_ITEM_VALIDITY, uid);
480
481         g_media_svc_item_validity_data_cnt = 1;
482         g_media_svc_item_validity_cur_data_cnt = 0;
483
484         return ret;
485 }
486
487 int media_svc_set_item_validity(const char *storage_id, const char *path, int validity, uid_t uid)
488 {
489         int ret = MS_MEDIA_ERR_NONE;
490
491         if (g_media_svc_item_validity_data_cnt == 1) {
492
493                 return _media_svc_update_item_validity(storage_id, path, validity, FALSE, uid);
494
495         } else if (g_media_svc_item_validity_cur_data_cnt < (g_media_svc_item_validity_data_cnt - 1)) {
496
497                 ret = _media_svc_update_item_validity(storage_id, path, validity, TRUE, uid);
498                 media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
499
500                 g_media_svc_item_validity_cur_data_cnt++;
501
502         } else if (g_media_svc_item_validity_cur_data_cnt == (g_media_svc_item_validity_data_cnt - 1)) {
503
504                 ret = _media_svc_update_item_validity(storage_id, path, validity, TRUE, uid);
505                 media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
506
507                 ret = _media_svc_list_query_do(MEDIA_SVC_QUERY_SET_ITEM_VALIDITY, uid);
508                 media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
509
510                 g_media_svc_item_validity_cur_data_cnt = 0;
511
512         } else {
513
514                 media_svc_error("Error in media_svc_set_item_validity");
515                 return MS_MEDIA_ERR_INTERNAL;
516         }
517
518         return MS_MEDIA_ERR_NONE;
519 }
520
521 int media_svc_delete_item_by_path(sqlite3 *handle, const char *storage_id, const char *path, uid_t uid)
522 {
523         int ret = MS_MEDIA_ERR_NONE;
524         char thumb_path[MEDIA_SVC_PATHNAME_SIZE] = {0, };
525         media_svc_noti_item *noti_item = NULL;
526
527         media_svc_debug_fenter();
528
529         /*Get thumbnail path to delete*/
530         ret = _media_svc_get_thumbnail_path_by_path(handle, path, thumb_path);
531         media_svc_retv_if((ret != MS_MEDIA_ERR_NONE) && (ret != MS_MEDIA_ERR_DB_NO_RECORD), ret);
532
533         /* Get notification info */
534         ret = _media_svc_get_noti_info(handle, storage_id, path, &noti_item);
535         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
536
537         /*Delete item*/
538         ret = _media_svc_delete_item_by_path(storage_id, path, uid);
539         if (ret != MS_MEDIA_ERR_NONE) {
540                 media_svc_error("_media_svc_delete_item_by_path failed : %d", ret);
541                 _media_svc_destroy_noti_item(noti_item);
542
543                 return ret;
544         }
545
546         /* Send notification */
547         media_svc_debug("Deletion is successful. Sending noti for this");
548         _media_svc_publish_noti(MS_MEDIA_ITEM_DELETE, path, noti_item->media_type, noti_item->media_uuid, noti_item->mime_type);
549         _media_svc_destroy_noti_item(noti_item);
550
551         /*Delete thumbnail*/
552         if (STRING_VALID(thumb_path)) {
553                 ret = _media_svc_remove_file(thumb_path);
554                 if (ret != MS_MEDIA_ERR_NONE)
555                         media_svc_error("fail to remove thumbnail file.");
556         }
557
558         return MS_MEDIA_ERR_NONE;
559 }
560
561 int media_svc_refresh_item(sqlite3 *handle, bool is_direct, const char *storage_id, ms_user_storage_type_e storage_type, const char *path, uid_t uid)
562 {
563         int ret = MS_MEDIA_ERR_NONE;
564         char thumb_path[MEDIA_SVC_PATHNAME_SIZE + 1] = {0, };
565
566         media_svc_retvm_if(handle == NULL, MS_MEDIA_ERR_INVALID_PARAMETER, "Handle is NULL");
567         media_svc_retvm_if(!STRING_VALID(storage_id), MS_MEDIA_ERR_INVALID_PARAMETER, "storage_id is NULL");
568         media_svc_retvm_if(!STRING_VALID(path), MS_MEDIA_ERR_INVALID_PARAMETER, "path is NULL");
569         media_svc_retvm_if(_media_svc_check_storage_type(storage_type) != TRUE, MS_MEDIA_ERR_INVALID_PARAMETER, "Invalid storage_type");
570
571         media_svc_content_info_s content_info;
572         memset(&content_info, 0, sizeof(media_svc_content_info_s));
573
574         /*Set media info*/
575         ret = _media_svc_set_media_info(&content_info, storage_id, storage_type, path, TRUE);
576         if (ret != MS_MEDIA_ERR_NONE)
577                 return ret;
578
579         /* Initialize thumbnail information to remake thumbnail. */
580         ret = _media_svc_get_thumbnail_path_by_path(handle, path, thumb_path);
581         if (ret != MS_MEDIA_ERR_NONE && ret != MS_MEDIA_ERR_DB_NO_RECORD) {
582                 _media_svc_destroy_content_info(&content_info);
583                 return ret;
584         }
585
586         if (STRING_VALID(thumb_path)) {
587                 if (g_file_test(thumb_path, G_FILE_TEST_EXISTS)) {
588                         ret = _media_svc_remove_file(thumb_path);
589                         if (ret != MS_MEDIA_ERR_NONE)
590                                 media_svc_error("_media_svc_remove_file failed : %s", thumb_path);
591                 }
592
593                 ret = _media_svc_update_thumbnail_path(storage_id, path, NULL, uid);
594                 if (ret != MS_MEDIA_ERR_NONE) {
595                         _media_svc_destroy_content_info(&content_info);
596                         return ret;
597                 }
598         }
599
600         /* Get notification info */
601         media_svc_noti_item *noti_item = NULL;
602         ret = _media_svc_get_noti_info(handle, storage_id, path, &noti_item);
603         if (ret != MS_MEDIA_ERR_NONE) {
604                 _media_svc_destroy_content_info(&content_info);
605                 return ret;
606         }
607
608         content_info.media_type = noti_item->media_type;
609
610         if (content_info.media_type == MEDIA_SVC_MEDIA_TYPE_OTHER
611         || (content_info.media_type == MEDIA_SVC_MEDIA_TYPE_PVR)
612         || (content_info.media_type == MEDIA_SVC_MEDIA_TYPE_UHD)
613         || (content_info.media_type == MEDIA_SVC_MEDIA_TYPE_SCSA))
614                 media_svc_debug("Do nothing [%d]", content_info.media_type);
615         else if (content_info.media_type == MEDIA_SVC_MEDIA_TYPE_IMAGE)
616                 ret = _media_svc_extract_image_metadata(&content_info);
617         else
618                 ret = _media_svc_extract_media_metadata(handle, is_direct, &content_info, uid);
619
620         if (ret != MS_MEDIA_ERR_NONE) {
621                 _media_svc_destroy_noti_item(noti_item);
622                 _media_svc_destroy_content_info(&content_info);
623                 return ret;
624         }
625
626         /* Extracting thumbnail */
627         if (content_info.thumbnail_path == NULL) {
628                 if (content_info.media_type == MEDIA_SVC_MEDIA_TYPE_IMAGE || content_info.media_type == MEDIA_SVC_MEDIA_TYPE_VIDEO) {
629                         memset(thumb_path, 0, sizeof(thumb_path));
630
631                         ret = _media_svc_create_thumbnail(content_info.path, thumb_path, content_info.media_type, uid);
632                         if (ret == MS_MEDIA_ERR_NONE)
633                                 content_info.thumbnail_path = g_strdup(thumb_path);
634                 }
635         }
636
637         ret = _media_svc_update_item_with_data(is_direct, storage_id, &content_info, uid);
638
639         if (ret == MS_MEDIA_ERR_NONE) {
640                 media_svc_debug("Update is successful. Sending noti for this");
641                 _media_svc_publish_noti(MS_MEDIA_ITEM_UPDATE, content_info.path, noti_item->media_type, noti_item->media_uuid, noti_item->mime_type);
642         } else {
643                 media_svc_error("_media_svc_update_item_with_data failed : %d", ret);
644         }
645
646         _media_svc_destroy_content_info(&content_info);
647         _media_svc_destroy_noti_item(noti_item);
648
649         return ret;
650 }
651
652 int media_svc_send_dir_update_noti(const char *dir_path, const char *folder_id, media_item_update_type_e update_type, int pid)
653 {
654         media_svc_retvm_if(!STRING_VALID(dir_path), MS_MEDIA_ERR_INVALID_PARAMETER, "dir_path is NULL");
655
656         return _media_svc_publish_dir_noti(update_type, dir_path, folder_id, pid);
657 }
658
659 int media_svc_check_db_upgrade(sqlite3 *handle, int user_version, uid_t uid)
660 {
661         media_svc_debug_fenter();
662
663         return _media_svc_check_db_upgrade(handle, user_version, uid);
664 }
665
666 int media_svc_update_item_begin(int data_cnt)
667 {
668         media_svc_debug("Transaction data count : [%d]", data_cnt);
669
670         media_svc_retvm_if(data_cnt < 1, MS_MEDIA_ERR_INVALID_PARAMETER, "data_cnt shuld be bigger than 1");
671
672         g_media_svc_update_item_data_cnt = data_cnt;
673         g_media_svc_update_item_cur_data_cnt = 0;
674
675         return MS_MEDIA_ERR_NONE;
676 }
677
678 int media_svc_update_item_end(uid_t uid)
679 {
680         int ret = MS_MEDIA_ERR_NONE;
681
682         media_svc_debug_fenter();
683
684         if (g_media_svc_update_item_cur_data_cnt > 0)
685                 ret = _media_svc_list_query_do(MEDIA_SVC_QUERY_UPDATE_ITEM, uid);
686
687         g_media_svc_update_item_data_cnt = 1;
688         g_media_svc_update_item_cur_data_cnt = 0;
689
690         return ret;
691 }
692
693 int media_svc_update_item_meta(const char *file_path, const char *storage_id, int storage_type, uid_t uid)
694 {
695         int ret = MS_MEDIA_ERR_NONE;
696         media_svc_content_info_s content_info;
697         memset(&content_info, 0, sizeof(media_svc_content_info_s));
698
699         /*Set media info*/
700         ret = _media_svc_set_media_info(&content_info, storage_id, storage_type, file_path, FALSE);
701         if (ret != MS_MEDIA_ERR_NONE)
702                 return ret;
703
704         if (content_info.media_type == MEDIA_SVC_MEDIA_TYPE_MUSIC)
705                 ret = _media_svc_extract_music_metadata_for_update(&content_info, content_info.media_type);
706         else {
707                 _media_svc_destroy_content_info(&content_info);
708                 return MS_MEDIA_ERR_NONE;
709         }
710
711         if (ret != MS_MEDIA_ERR_NONE) {
712                 _media_svc_destroy_content_info(&content_info);
713                 return ret;
714         }
715
716         if (g_media_svc_update_item_data_cnt == 1) {
717
718                 ret = _media_svc_update_meta_with_data(&content_info);
719                 media_svc_retv_del_if(ret != MS_MEDIA_ERR_NONE, ret, &content_info);
720
721         } else if (g_media_svc_update_item_cur_data_cnt < (g_media_svc_update_item_data_cnt - 1)) {
722
723                 ret = _media_svc_update_meta_with_data(&content_info);
724                 media_svc_retv_del_if(ret != MS_MEDIA_ERR_NONE, ret, &content_info);
725
726                 g_media_svc_update_item_cur_data_cnt++;
727
728         } else if (g_media_svc_update_item_cur_data_cnt == (g_media_svc_update_item_data_cnt - 1)) {
729
730                 ret = _media_svc_update_meta_with_data(&content_info);
731                 media_svc_retv_del_if(ret != MS_MEDIA_ERR_NONE, ret, &content_info);
732
733                 ret = _media_svc_list_query_do(MEDIA_SVC_QUERY_UPDATE_ITEM, uid);
734                 media_svc_retv_del_if(ret != MS_MEDIA_ERR_NONE, ret, &content_info);
735
736                 g_media_svc_update_item_cur_data_cnt = 0;
737
738         } else {
739                 media_svc_error("Error in media_svc_update_item_meta");
740                 _media_svc_destroy_content_info(&content_info);
741                 return MS_MEDIA_ERR_INTERNAL;
742         }
743
744         _media_svc_destroy_content_info(&content_info);
745
746         return ret;
747 }
748
749 int media_svc_publish_noti(media_item_update_type_e update_type, const char *path, media_type_e media_type, const char *uuid, const char *mime_type)
750 {
751         return _media_svc_publish_noti(update_type, path, media_type, uuid, mime_type);
752 }
753
754 int media_svc_get_pinyin(const char *src_str, char **pinyin_str)
755 {
756         return _media_svc_get_pinyin_str(src_str, pinyin_str);
757 }
758
759 int media_svc_check_pinyin_support(bool *support)
760 {
761         *support = _media_svc_check_pinyin_support();
762
763         return MS_MEDIA_ERR_NONE;
764 }
765
766 int media_svc_set_storage_validity(sqlite3 *handle, const char *storage_id, int validity, uid_t uid)
767 {
768         int ret = MS_MEDIA_ERR_NONE;
769
770         media_svc_retvm_if(handle == NULL, MS_MEDIA_ERR_INVALID_PARAMETER, "Handle is NULL");
771
772         ret = _media_svc_update_storage_validity(storage_id, validity, uid);
773         media_svc_retvm_if(ret != MS_MEDIA_ERR_NONE, ret, "update storage validity failed: %d", ret);
774
775         ret = _media_svc_update_media_view(handle, uid);
776         media_svc_retvm_if(ret != MS_MEDIA_ERR_NONE, ret, "update media view failed : %d", ret);
777
778         return ret;
779 }
780
781 int media_svc_get_storage_id(sqlite3 *handle, const char *path, char *storage_id, uid_t uid)
782 {
783         return _media_svc_get_storage_uuid(handle, path, storage_id, uid);
784 }
785
786 int media_svc_generate_uuid(char **uuid)
787 {
788         char *gen_uuid = NULL;
789         gen_uuid = _media_info_generate_uuid();
790         media_svc_retvm_if(gen_uuid == NULL, MS_MEDIA_ERR_INTERNAL, "Fail to generate uuid");
791
792         *uuid = strdup(gen_uuid);
793
794         return MS_MEDIA_ERR_NONE;
795 }
796
797 int media_svc_check_storage(sqlite3 *handle, const char *storage_id, char **storage_path, int *validity, uid_t uid)
798 {
799         return _media_svc_check_storage(handle, storage_id, storage_path, validity, uid);
800 }
801
802 int media_svc_update_storage(sqlite3 *handle, const char *storage_id, const char *storage_path, uid_t uid)
803 {
804         return _media_svc_update_storage_path(handle, storage_id, storage_path, uid);
805 }
806
807 int media_svc_insert_storage(sqlite3 *handle, const char *storage_id, const char *storage_path, ms_user_storage_type_e storage_type, uid_t uid)
808 {
809         int ret = MS_MEDIA_ERR_NONE;
810
811         media_svc_retvm_if(handle == NULL, MS_MEDIA_ERR_INVALID_PARAMETER, "Handle is NULL");
812         media_svc_retvm_if(storage_id == NULL, MS_MEDIA_ERR_INVALID_PARAMETER, "storage_id is NULL");
813         media_svc_retvm_if(storage_path == NULL, MS_MEDIA_ERR_INVALID_PARAMETER, "storage_path is NULL");
814         media_svc_retvm_if(_media_svc_check_storage_type(storage_type) != TRUE, MS_MEDIA_ERR_INVALID_PARAMETER, "Invalid storage_type");
815
816         ret = _media_svc_append_storage(storage_id, storage_path, storage_type, uid);
817         media_svc_retvm_if(ret != MS_MEDIA_ERR_NONE, ret, "append storage failed : %d", ret);
818
819         ret = _media_svc_create_media_table_with_id(storage_id, uid);
820         media_svc_retvm_if(ret != MS_MEDIA_ERR_NONE, ret, "create media table failed : %d", ret);
821
822         ret = _media_svc_update_media_view(handle, uid);
823         media_svc_retvm_if(ret != MS_MEDIA_ERR_NONE, ret, "update media view failed : %d", ret);
824
825         /* Remove external storage that validity is 0 */
826         ret = _media_svc_delete_invalid_storage(handle, uid);
827         media_svc_retvm_if(ret != MS_MEDIA_ERR_NONE, ret, "Delete invalid storage failed : %d", ret);
828
829         return ret;
830 }
831
832 int media_svc_insert_folder(sqlite3 *handle, const char *storage_id, ms_user_storage_type_e storage_type, const char *path, uid_t uid)
833 {
834         media_svc_retvm_if(handle == NULL, MS_MEDIA_ERR_INVALID_PARAMETER, "Handle is NULL");
835         media_svc_retvm_if(!STRING_VALID(storage_id), MS_MEDIA_ERR_INVALID_PARAMETER, "storage_id is NULL");
836         media_svc_retvm_if(!STRING_VALID(path), MS_MEDIA_ERR_INVALID_PARAMETER, "path is NULL");
837         media_svc_retvm_if(_media_svc_check_storage_type(storage_type) != TRUE, MS_MEDIA_ERR_INVALID_PARAMETER, "Invalid storage_type");
838
839         return _media_svc_get_and_append_folder_id_by_folder_path(handle, storage_id, path, storage_type, uid);
840 }
841
842 int media_svc_set_folder_validity(sqlite3 *handle, const char *storage_id, const char *start_path, int validity, bool is_recursive, uid_t uid)
843 {
844         return _media_svc_set_folder_validity(handle, true, storage_id, start_path, validity, is_recursive, uid);
845 }
846
847 int media_svc_check_folder_exist_by_path(sqlite3 *handle, const char *storage_id, const char *folder_path)
848 {
849         int ret = MS_MEDIA_ERR_NONE;
850         int count = -1;
851
852         ret = _media_svc_count_folder_with_path(handle, storage_id, folder_path, &count);
853         media_svc_retv_if(ret != MS_MEDIA_ERR_NONE, ret);
854
855         if (count > 0) {
856                 media_svc_debug("item is exist in database");
857                 return MS_MEDIA_ERR_NONE;
858         } else {
859                 media_svc_debug("item is not exist in database");
860                 return MS_MEDIA_ERR_DB_NO_RECORD;
861         }
862
863         return MS_MEDIA_ERR_NONE;
864 }
865
866 int media_svc_append_query(const char *query, uid_t uid)
867 {
868         return _media_svc_append_query_list(query, uid);
869 }
870
871 int media_svc_send_query(uid_t uid)
872 {
873         return _media_svc_list_query_do(MEDIA_SVC_QUERY_UPDATE_COMMON, uid);
874 }
875
876 int media_svc_get_media_type(const char *path, int *mediatype)
877 {
878         return _media_svc_get_media_type(path, mediatype);
879 }
880
881 int media_svc_create_thumbnail(const char *storage_id, const char *file_path, int media_type, uid_t uid, char **thumbnail_path)
882 {
883         int ret = MS_MEDIA_ERR_NONE;
884         char thumb_path[MEDIA_SVC_PATHNAME_SIZE + 1] = { 0, };
885         char *sql = NULL;
886
887         // 1. Check media type
888         if (media_type != MS_MEDIA_IMAGE && media_type != MS_MEDIA_VIDEO)
889                 return MS_MEDIA_ERR_UNSUPPORTED_CONTENT;
890
891         // 2. try to create thumbnail
892         ret = _media_svc_create_thumbnail(file_path, thumb_path, media_type, uid);
893         if (ret != MS_MEDIA_ERR_NONE) {
894                 media_svc_error("Failed to create thumbnail [%d]", ret);
895                 if (ret == MS_MEDIA_ERR_UNSUPPORTED_CONTENT)
896                         return ret;
897         }
898
899         // 3. Update creation result to media db
900         sql = sqlite3_mprintf("UPDATE '%q' SET media_thumbnail_path='%q' WHERE media_path='%q';", storage_id, thumb_path, file_path);
901
902         ret = _media_svc_sql_query(sql, uid);
903         SQLITE3_SAFE_FREE(sql);
904         if (ret != MS_MEDIA_ERR_NONE) {
905                 media_svc_error("Failed to update media db [%d]", ret);
906                 *thumbnail_path = g_strdup("");
907         } else {
908                 *thumbnail_path = g_strdup(thumb_path);
909         }
910
911         return ret;
912 }