673f556dfeb755419f1564e894fb160a9524cb74
[platform/core/api/media-content.git] / src / media_folder.c
1  /*
2  * Copyright (c) 2011 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 #include <media_info_private.h>
19 #include <media_util_private.h>
20 #ifdef _USE_TVPD_MODE
21 #include <media_content_type_product.h>
22 #endif
23
24 #ifdef _USE_TVPD_MODE
25 static char *g_src_path = NULL;
26 #endif
27
28 int media_folder_get_folder_count_from_db(filter_h filter, int *folder_count)
29 {
30         int ret = MEDIA_CONTENT_ERROR_NONE;
31
32         if (!folder_count) {
33                 content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
34                 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
35         }
36 #ifdef _USE_TVPD_MODE
37         g_mutex_lock(_content_get_db_mutex());
38 #endif
39
40         ret = _media_db_get_group_count(filter, MEDIA_GROUP_FOLDER, folder_count);
41
42 #ifdef _USE_TVPD_MODE
43         g_mutex_unlock(_content_get_db_mutex());
44 #endif
45
46
47         return ret;
48 }
49
50 int media_folder_foreach_folder_from_db(filter_h filter, media_folder_cb callback, void *user_data)
51 {
52         int ret = MEDIA_CONTENT_ERROR_NONE;
53
54         if (callback == NULL) {
55                 content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
56                 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
57         }
58
59 #ifdef _USE_TVPD_MODE
60         g_mutex_lock(_content_get_db_mutex());
61 #endif
62
63         ret = _media_db_get_folder(filter, callback, user_data);
64
65 #ifdef _USE_TVPD_MODE
66         g_mutex_unlock(_content_get_db_mutex());
67 #endif
68
69         return ret;
70 }
71
72 int media_folder_get_media_count_from_db(const char *folder_id, filter_h filter, int *media_count)
73 {
74         int ret = MEDIA_CONTENT_ERROR_NONE;
75
76         if (STRING_VALID(folder_id) && media_count) {
77 #ifdef _USE_TVPD_MODE
78                 g_mutex_lock(_content_get_db_mutex());
79 #endif
80
81                 ret = _media_db_get_group_item_count(folder_id, filter, MEDIA_GROUP_FOLDER, media_count);
82
83 #ifdef _USE_TVPD_MODE
84                 g_mutex_unlock(_content_get_db_mutex());
85 #endif
86
87         } else {
88                 content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
89                 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
90         }
91
92         return ret;
93 }
94
95 int media_folder_foreach_media_from_db(const char *folder_id, filter_h filter, media_info_cb callback, void *user_data)
96 {
97         int ret = MEDIA_CONTENT_ERROR_NONE;
98
99         if ((callback != NULL) && STRING_VALID(folder_id)) {
100 #ifdef _USE_TVPD_MODE
101                 g_mutex_lock(_content_get_db_mutex());
102 #endif
103
104                 ret = _media_db_get_group_item(folder_id, filter, callback, user_data, MEDIA_GROUP_FOLDER);
105
106 #ifdef _USE_TVPD_MODE
107                 g_mutex_unlock(_content_get_db_mutex());
108 #endif
109
110         } else {
111                 content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
112                 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
113         }
114
115         return ret;
116 }
117
118 #ifdef _USE_SENIOR_MODE
119 int media_folder_foreach_media_from_db_by_union_select(const char* folder_id, filter_h filter1, filter_h filter2, media_info_cb callback, void* user_data)
120 {
121         int ret = MEDIA_CONTENT_ERROR_NONE;
122
123         if ((callback != NULL) && STRING_VALID(folder_id)) {
124                 ret = _media_db_get_group_item_by_union_select(folder_id, filter1, filter2, callback, user_data);
125         } else {
126                 content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
127                 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
128         }
129
130         return ret;
131 }
132 #endif
133
134 int media_folder_destroy(media_folder_h folder)
135 {
136         int ret = MEDIA_CONTENT_ERROR_NONE;
137         media_folder_s *_folder = (media_folder_s*)folder;
138         if (_folder) {
139                 SAFE_FREE(_folder->path);
140                 SAFE_FREE(_folder->name);
141                 SAFE_FREE(_folder->folder_id);
142                 SAFE_FREE(_folder->storage_uuid);
143                 SAFE_FREE(_folder);
144                 ret = MEDIA_CONTENT_ERROR_NONE;
145         } else {
146                 content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
147                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
148         }
149
150         return ret;
151 }
152 int media_folder_clone(media_folder_h *dst, media_folder_h src)
153 {
154         int ret = MEDIA_CONTENT_ERROR_NONE;
155         media_folder_s *_src = (media_folder_s*)src;
156
157         if (_src != NULL) {
158                 media_folder_s *_dst = (media_folder_s*)calloc(1, sizeof(media_folder_s));
159                 content_retvm_if(_dst == NULL, MEDIA_CONTENT_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY");
160
161                 if (STRING_VALID(_src->folder_id)) {
162                         _dst->folder_id = strdup(_src->folder_id);
163                         if (_dst->folder_id == NULL) {
164                                 SAFE_FREE(_dst);
165                                 content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
166                                 return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
167                         }
168                 }
169
170                 if (STRING_VALID(_src->name)) {
171                         _dst->name = strdup(_src->name);
172                         if (_dst->name == NULL) {
173                                 content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
174                                 media_folder_destroy((media_folder_h)_dst);
175                                 return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
176                         }
177                 }
178
179                 if (STRING_VALID(_src->path)) {
180                         _dst->path = strdup(_src->path);
181                         if (_dst->path == NULL) {
182                                 content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
183                                 media_folder_destroy((media_folder_h)_dst);
184                                 return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
185                         }
186                 }
187
188                 if (STRING_VALID(_src->storage_uuid)) {
189                         _dst->storage_uuid = strdup(_src->storage_uuid);
190                         if (_dst->storage_uuid == NULL) {
191                                 content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
192                                 media_folder_destroy((media_folder_h)_dst);
193                                 return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
194                         }
195                 }
196
197                 _dst->storage_type = _src->storage_type;
198
199                 *dst = (media_folder_h)_dst;
200
201                 ret = MEDIA_CONTENT_ERROR_NONE;
202         } else {
203                 content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
204                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
205         }
206
207         return ret;
208 }
209
210 int media_folder_get_folder_id(media_folder_h folder, char **folder_id)
211 {
212         int ret = MEDIA_CONTENT_ERROR_NONE;
213         media_folder_s *_folder = (media_folder_s*)folder;
214
215         if (_folder) {
216                 if (STRING_VALID(_folder->folder_id)) {
217                         *folder_id = strdup(_folder->folder_id);
218                         content_retvm_if(*folder_id == NULL, MEDIA_CONTENT_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY");
219                 } else {
220                         *folder_id = NULL;
221                 }
222                 ret = MEDIA_CONTENT_ERROR_NONE;
223         } else {
224                 content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
225                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
226         }
227
228         return ret;
229 }
230
231 int media_folder_get_path(media_folder_h folder, char **path)
232 {
233         int ret = MEDIA_CONTENT_ERROR_NONE;
234         media_folder_s *_folder = (media_folder_s*)folder;
235
236         if (_folder) {
237                 if (STRING_VALID(_folder->path)) {
238                         *path = strdup(_folder->path);
239                         content_retvm_if(*path == NULL, MEDIA_CONTENT_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY");
240                 } else {
241                         *path = NULL;
242                 }
243                 ret = MEDIA_CONTENT_ERROR_NONE;
244
245         } else {
246                 content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
247                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
248         }
249
250         return ret;
251
252 }
253
254 int media_folder_get_name(media_folder_h folder, char **name)
255 {
256         int ret = MEDIA_CONTENT_ERROR_NONE;
257         media_folder_s *_folder = (media_folder_s*)folder;
258
259         if (_folder) {
260                 if (STRING_VALID(_folder->name)) {
261                         *name = strdup(_folder->name);
262                         content_retvm_if(*name == NULL, MEDIA_CONTENT_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY");
263                 } else {
264                         *name = NULL;
265                 }
266                 ret = MEDIA_CONTENT_ERROR_NONE;
267
268         } else {
269                 content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
270                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
271         }
272
273         return ret;
274 }
275
276 int media_folder_get_storage_type(media_folder_h folder, media_content_storage_e* storage_type)
277 {
278         int ret = MEDIA_CONTENT_ERROR_NONE;
279         content_warn("DEPRECATION WARNING: media_folder_get_storage_type() is deprecated and will be removed from next release. Use storage_get_type_dev() instead.");
280         media_folder_s *_folder = (media_folder_s*)folder;
281
282         if (_folder) {
283                 *storage_type = _folder->storage_type;
284                 ret = MEDIA_CONTENT_ERROR_NONE;
285         } else {
286                 content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
287                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
288         }
289
290         return ret;
291 }
292
293 int media_folder_get_storage_id(media_folder_h folder, char **storage_id)
294 {
295         int ret = MEDIA_CONTENT_ERROR_NONE;
296         content_warn("DEPRECATION WARNING: media_folder_get_storage_id() is deprecated and will be removed from next release.");
297         media_folder_s *_folder = (media_folder_s*)folder;
298
299         if (_folder) {
300                 if (STRING_VALID(_folder->storage_uuid)) {
301                         *storage_id = strdup(_folder->storage_uuid);
302                         content_retvm_if(*storage_id == NULL, MEDIA_CONTENT_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY");
303                 } else {
304                         *storage_id = NULL;
305                 }
306                 ret = MEDIA_CONTENT_ERROR_NONE;
307
308         } else {
309                 content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
310                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
311         }
312
313         return ret;
314 }
315
316 int media_folder_get_folder_from_db(const char *folder_id, media_folder_h *folder)
317 {
318         int ret = MEDIA_CONTENT_ERROR_NONE;
319         sqlite3_stmt *stmt = NULL;
320         char select_query[DEFAULT_QUERY_SIZE];
321         media_folder_s *_folder = NULL;
322
323         if (!STRING_VALID(folder_id)) {
324                 content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
325                 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
326         }
327
328         memset(select_query, 0x00, sizeof(select_query));
329         snprintf(select_query, sizeof(select_query), SELECT_FOLDER_FROM_FOLDER, folder_id);
330
331         ret = _content_get_result(select_query, &stmt);
332         content_retv_if(ret != MEDIA_CONTENT_ERROR_NONE, ret);
333
334         if (sqlite3_step(stmt) == SQLITE_ROW) {
335                 _folder = (media_folder_s*)calloc(1, sizeof(media_folder_s));
336                 if (_folder == NULL) {
337                         content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
338                         SQLITE3_FINALIZE(stmt);
339                         return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
340                 }
341
342                 _folder->folder_id = g_strdup(folder_id);
343                 _folder->path = g_strdup((const char *)sqlite3_column_text(stmt, 0));
344                 _folder->name = g_strdup((const char *)sqlite3_column_text(stmt, 1));
345                 _folder->storage_type = (int)sqlite3_column_int(stmt, 2);
346                 _folder->storage_uuid = g_strdup((const char *)sqlite3_column_text(stmt, 3));
347
348                 *folder = (media_folder_h)_folder;
349         }
350
351         SQLITE3_FINALIZE(stmt);
352
353         return ret;
354 }
355 #ifdef _USE_TVPD_MODE
356 int media_folder_update_to_db(media_folder_h folder)
357 {
358         int ret = MEDIA_CONTENT_ERROR_NONE;
359         content_warn("DEPRECATION WARNING: media_folder_update_to_db() is deprecated and will be removed from next release.");
360         media_folder_s *_folder = (media_folder_s*)folder;
361         char repl_path[MAX_PATH_LEN] = {0, };
362
363         if ((_folder == NULL) || (_folder->folder_id == NULL)) {
364                 content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
365                 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
366         }
367
368         if (STRING_VALID(_folder->folder_id) && g_src_path) {
369                 ret = _media_content_replace_path(_folder->path, repl_path);
370                 if (ret != MEDIA_CONTENT_ERROR_NONE) {
371                         SAFE_FREE(g_src_path);
372                         return ret;
373                 }
374                 ret = media_svc_rename_folder(_content_get_db_handle(), _folder->storage_uuid, g_src_path, repl_path, _content_get_uid());
375                 SAFE_FREE(g_src_path);
376
377                 return _content_error_capi(ret);
378         }
379
380         return ret;
381 }
382
383 int media_folder_set_name(media_folder_h folder, const char *name)
384 {
385         int ret = MEDIA_CONTENT_ERROR_NONE;
386         content_warn("DEPRECATION WARNING: media_folder_set_name() is deprecated and will be removed from next release.");
387         media_folder_s *_folder = (media_folder_s*)folder;
388
389         if (_folder != NULL && STRING_VALID(name) && name[0] != '.') {
390                 if (STRING_VALID(_folder->path) && STRING_VALID(_folder->name)) {
391                         char *folder_path = NULL;
392                         char new_folder_path[MAX_PATH_LEN] = {0,};
393                         char repl_path[MAX_PATH_LEN] = {0, };
394
395                         memset(repl_path, 0, sizeof(repl_path));
396                         ret = _media_content_replace_path(_folder->path, repl_path);
397                         content_retvm_if(!STRING_VALID(repl_path), MEDIA_CONTENT_ERROR_INVALID_OPERATION, "path replacement failed");
398
399                         folder_path = g_path_get_dirname(repl_path);
400                         content_sec_debug("Existed Folder Path : %s", repl_path);
401                         snprintf(new_folder_path, sizeof(new_folder_path), "%s/%s", folder_path, name);
402                         content_sec_debug("New Path : %s", new_folder_path);
403
404                         SAFE_FREE(g_src_path);
405                         g_src_path = strdup(repl_path);
406
407                         SAFE_FREE(_folder->path);
408                         SAFE_FREE(_folder->name);
409                         SAFE_FREE(folder_path);
410
411                         _folder->path = strdup(new_folder_path);
412                         content_retvm_if(_folder->path == NULL, MEDIA_CONTENT_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY");
413                         _folder->name = strdup(name);
414                         content_retvm_if(_folder->name == NULL, MEDIA_CONTENT_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY");
415                 } else {
416                         content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
417                         ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
418                 }
419         } else {
420                 content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
421                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
422         }
423
424         return ret;
425 }
426
427 int media_folder_insert_to_db(const char *path)
428 {
429         char repl_path[MAX_PATH_LEN] = {0, };
430         int ret = MEDIA_CONTENT_ERROR_NONE;
431         char storage_id[MEDIA_CONTENT_UUID_SIZE+1] = {0, };
432         bool ignore_dir = FALSE;
433
434         content_retvm_if(!STRING_VALID(path), MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "invalid path");
435         memset(repl_path, 0, sizeof(repl_path));
436         ret = _media_content_replace_path(path, repl_path);
437         content_retvm_if(!STRING_VALID(repl_path), MEDIA_CONTENT_ERROR_INVALID_OPERATION, "path replacement failed");
438
439         ret = _media_util_check_ignore_dir(repl_path, &ignore_dir);
440         content_retvm_if(ignore_dir, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid folder path");
441
442         ret = _media_content_check_dir(repl_path);
443         content_retvm_if(ret == MEDIA_CONTENT_ERROR_PERMISSION_DENIED, ret, "Permission Denied");
444         content_retvm_if(ret == MEDIA_CONTENT_ERROR_INVALID_PARAMETER, ret, "invalid path[%s]", path);
445
446         ret = media_svc_get_storage_id(_content_get_db_handle(), repl_path, storage_id, _content_get_uid());
447         if (ret != MS_MEDIA_ERR_NONE) {
448                 content_error("media_svc_get_storage_id failed : %d", ret);
449                 return _content_error_capi(ret);
450         }
451
452         ret = media_svc_check_folder_exist_by_path(_content_get_db_handle(), storage_id, repl_path);
453         if (ret == MS_MEDIA_ERR_DB_NO_RECORD) {
454                 content_sec_debug("media_svc_check_folder_exist_by_path : no record : %s", repl_path);
455                 ms_user_storage_type_e storage_type = MS_USER_STORAGE_INTERNAL;
456
457                 ret = ms_user_get_storage_type(_content_get_uid(), repl_path, &storage_type);
458                 if (ret != MS_MEDIA_ERR_NONE) {
459                         content_sec_error("ms_user_get_storage_type failed : %d", ret);
460                         return _content_error_capi(ret);
461                 }
462
463                 ret = media_svc_insert_folder(_content_get_db_handle(), storage_id, storage_type, repl_path, _content_get_uid());
464                 if (ret != MS_MEDIA_ERR_NONE) {
465                         if (ret == MS_MEDIA_ERR_DB_CONSTRAINT_FAIL) {
466                                 content_sec_error("This item is already inserted. This may be normal operation because other process already did this (%s)", repl_path);
467                                 ret = MEDIA_CONTENT_ERROR_NONE;
468                         } else {
469                                 content_sec_error("media_svc_insert_folder failed : %d (%s)", ret, repl_path);
470                         }
471
472                         return _content_error_capi(ret);
473                 }
474
475                 ret = media_svc_set_folder_scan_status(storage_id, repl_path, MEDIA_DIR_SCAN_DONE, _content_get_uid());
476                 if (ret != MS_MEDIA_ERR_NONE) {
477                         content_sec_error("ms_set_folder_scan_status failed : %d", ret);
478                         return _content_error_capi(ret);
479                 }
480         } else if (ret != MS_MEDIA_ERR_NONE) {
481                 content_sec_error("media_svc_check_folder_exist_by_path failed : %d (%s)", ret, repl_path);
482                 return _content_error_capi(ret);
483         }
484
485         return ret;
486 }
487
488 int media_folder_get_scan_status(const char *storage_uuid, char* path, media_folder_scan_status_e *scan_status)
489 {
490         int ret = MEDIA_CONTENT_ERROR_NONE;
491         int status = MEDIA_DIR_SCAN_NONE;
492
493         if (STRING_VALID(storage_uuid) && STRING_VALID(path)) {
494                 ret = media_svc_get_folder_scan_status(_content_get_db_handle(), storage_uuid, path, &status);
495                 if (ret != MS_MEDIA_ERR_NONE) {
496                         content_error("media_svc_get_folder_scan_status failed");
497                         ret = _content_error_capi(ret);
498                 } else {
499                         *scan_status = status;
500                 }
501         } else {
502                 content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
503                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
504         }
505
506         return ret;
507 }
508
509 int media_folder_reset_scan_status(const char *storage_uuid, const char* path)
510 {
511         int ret = MEDIA_CONTENT_ERROR_NONE;
512         if (STRING_VALID(path)) {
513                 ret = media_svc_set_folder_validity(FALSE, storage_uuid, path, 0, TRUE, _content_get_uid());
514                 if (ret != MS_MEDIA_ERR_NONE) {
515                         content_error("set folder validity failed");
516                         ret = _content_error_capi(ret);
517                         return ret;
518                 }
519
520                 ret = media_svc_set_folder_scan_status(storage_uuid, path, MEDIA_DIR_SCAN_NONE, _content_get_uid());
521                 if (ret != MS_MEDIA_ERR_NONE) {
522                         content_error("media_folder_reset_scan_status failed");
523                         ret = _content_error_capi(ret);
524                 }
525         } else {
526                 content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
527                 ret = MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
528         }
529
530         return ret;
531 }
532 #endif