Remove unused parameter
[platform/core/api/media-content.git] / src / media_content.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
21 static sqlite3 *db_handle = NULL;
22 static int ref_count = 0;
23 static GMutex db_mutex;
24 static uid_t content_g_uid = 0;
25
26 sqlite3 * _content_get_db_handle(void)
27 {
28         return db_handle;
29 }
30
31 uid_t _content_get_uid(void)
32 {
33         if (content_g_uid == 0)
34                 return tzplatform_getuid(TZ_USER_NAME);
35         else
36                 return content_g_uid;
37 }
38
39 int _content_query_prepare(sqlite3_stmt **stmt, char *select_query, char *condition_query, char *option_query)
40 {
41         int len = 0;
42         int err = MEDIA_CONTENT_ERROR_NONE;
43         char query[MAX_QUERY_SIZE] = {0, };
44         memset(query, '\0', sizeof(query));
45
46         media_content_retvm_if(db_handle == NULL, MEDIA_CONTENT_ERROR_DB_FAILED, "database is not connected");
47         media_content_retvm_if(!STRING_VALID(select_query), MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "invalid select_query");
48
49         if (!STRING_VALID(condition_query))
50                 condition_query = (char *)" ";
51
52         if (!STRING_VALID(option_query))
53                 option_query = (char *)" ";
54
55         /*query = sqlite3_mprintf("%s %s %s", select_query, condition_query, option_query);*/
56         len = snprintf(query, sizeof(query), "%s %s %s", select_query, condition_query, option_query);
57         if (len > 0 && len < sizeof(query))
58                 query[len] = '\0';
59         else if (len >= sizeof(query))
60                 query[MAX_QUERY_SIZE -1] = '\0';
61         else {
62                 media_content_error("snprintf failed");
63                 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
64         }
65
66         media_content_sec_debug("Query : [%s]", query);
67
68         err = sqlite3_prepare_v2(db_handle, query, strlen(query), stmt, NULL);
69         if (err != SQLITE_OK) {
70                 media_content_error("DB_FAILED(0x%08x) fail to sqlite3_prepare(), %s", MEDIA_CONTENT_ERROR_DB_FAILED, sqlite3_errmsg(db_handle));
71
72                 if (err == SQLITE_BUSY) {
73                         media_content_error(" BUSY ERROR");
74                         return MEDIA_CONTENT_ERROR_DB_BUSY;
75                 } else if (err == SQLITE_PERM) {
76                         media_content_error("PERMISSION EROR");
77                         return MEDIA_CONTENT_ERROR_PERMISSION_DENIED;
78                 } else {
79                         media_content_error("OTHER ERROR");
80                         return MEDIA_CONTENT_ERROR_DB_FAILED;
81                 }
82         }
83
84         return MEDIA_CONTENT_ERROR_NONE;
85 }
86
87 #ifdef _USE_SENIOR_MODE
88 int _content_query_prepare_by_union_select(sqlite3_stmt **stmt, char *select_query1, char *condition_query1, char *option_query1, char *select_query2, char *condition_query2, char *option_query2)
89 {
90         int len = 0;
91         int err = MEDIA_CONTENT_ERROR_NONE;
92         char query[MAX_QUERY_SIZE] = {0, };
93         memset(query, '\0', sizeof(query));
94
95         media_content_retvm_if(db_handle == NULL, MEDIA_CONTENT_ERROR_DB_FAILED, "database is not connected");
96         media_content_retvm_if(!STRING_VALID(select_query1), MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "invalid select_query1");
97         media_content_retvm_if(!STRING_VALID(select_query2), MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "invalid select_query2");
98
99         if (!STRING_VALID(condition_query1))
100                 condition_query1 = (char *)" ";
101
102         if (!STRING_VALID(option_query1))
103                 option_query1 = (char *)" ";
104
105         if (!STRING_VALID(condition_query2))
106                 condition_query2 = (char *)" ";
107
108         if (!STRING_VALID(option_query2))
109                 option_query2 = (char *)" ";
110
111         len = snprintf(query, sizeof(query), "SELECT * FROM (%s %s %s) as table1 UNION ALL SELECT * FROM (%s %s %s) as table2",
112                         select_query1, condition_query1, option_query1, select_query2, condition_query2, option_query2);
113         if (len > 0 && len < sizeof(query)) {
114                 query[len] = '\0';
115         } else if (len >= sizeof(query)) {
116                 query[MAX_QUERY_SIZE -1] = '\0';
117         } else {
118                 media_content_error("snprintf failed");
119                 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
120         }
121
122         media_content_sec_debug("Query : [%s]", query);
123
124         err = sqlite3_prepare_v2(db_handle, query, strlen(query), stmt, NULL);
125         if (err != SQLITE_OK) {
126                 media_content_error("DB_FAILED(0x%08x) fail to sqlite3_prepare(), %s", MEDIA_CONTENT_ERROR_DB_FAILED, sqlite3_errmsg(db_handle));
127
128                 if (err == SQLITE_BUSY) {
129                         media_content_error(" BUSY ERROR");
130                         return MEDIA_CONTENT_ERROR_DB_BUSY;
131                 } else if (err == SQLITE_PERM) {
132                         media_content_error("PERMISSION EROR");
133                         return MEDIA_CONTENT_ERROR_PERMISSION_DENIED;
134                 } else {
135                         media_content_error("OTHER ERROR");
136                         return MEDIA_CONTENT_ERROR_DB_FAILED;
137                 }
138         }
139
140         return MEDIA_CONTENT_ERROR_NONE;
141 }
142 #endif
143
144 int _content_error_capi(int content_error)
145 {
146         if (content_error != MEDIA_CONTENT_ERROR_NONE)
147                 media_content_error("MS Error[%d]", content_error);
148
149         /*Error None*/
150         if (content_error == MS_MEDIA_ERR_NONE)
151                 return MEDIA_CONTENT_ERROR_NONE;
152
153         /* Internal operation error*/
154         else if ((content_error == MS_MEDIA_ERR_INVALID_PARAMETER) ||
155                 (content_error == MS_MEDIA_ERR_INVALID_PATH) ||
156                 (content_error == MS_MEDIA_ERR_THUMB_DUPLICATED_REQUEST))
157                 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
158
159         else if (content_error == MS_MEDIA_ERR_OUT_OF_MEMORY)
160                 return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
161
162         /* DB operation error*/
163         else if (content_error == MS_MEDIA_ERR_DB_BUSY_FAIL)
164                 return MEDIA_CONTENT_ERROR_DB_BUSY;
165
166         else if ((content_error <= MS_MEDIA_ERR_DB_CONNECT_FAIL) && (content_error >= MS_MEDIA_ERR_DB_INTERNAL))
167                 return MEDIA_CONTENT_ERROR_DB_FAILED;
168
169         /* IPC operation error*/
170         else if ((content_error <= MS_MEDIA_ERR_SOCKET_CONN) && (content_error >= MS_MEDIA_ERR_SOCKET_INTERNAL))
171                 return MEDIA_CONTENT_ERROR_NETWORK;
172
173         /* MEDIA SERVER error*/
174         else if (content_error == MS_MEDIA_ERR_PERMISSION_DENIED)
175                 return MEDIA_CONTENT_ERROR_PERMISSION_DENIED;
176
177         /* Thumbnail error*/
178         else if ((content_error == MS_MEDIA_ERR_THUMB_TOO_BIG) || (content_error == MS_MEDIA_ERR_THUMB_UNSUPPORTED))
179                         return MEDIA_CONTENT_ERROR_UNSUPPORTED_CONTENT;
180
181         /*ETC*/
182         return MEDIA_CONTENT_ERROR_INVALID_OPERATION;
183 }
184
185 int _content_query_sql(char *query_str)
186 {
187         int ret = MEDIA_CONTENT_ERROR_NONE;
188
189         /*DB will be updated by Media Server.*/
190         ret = media_db_request_update_db(query_str, _content_get_uid());
191
192         return _content_error_capi(ret);
193 }
194
195 int media_content_connect(void)
196 {
197         int ret = MEDIA_CONTENT_ERROR_NONE;
198
199         g_mutex_lock(&db_mutex);
200         media_content_info("ref count : %d", ref_count);
201
202         if (ref_count == 0) {
203                 if (db_handle == NULL) {
204                         ret = media_db_connect(&db_handle, _content_get_uid(), false);
205                         ret = _content_error_capi(ret);
206                         if (ret == MEDIA_CONTENT_ERROR_NONE)
207                                 ref_count++;
208                 } else {
209                         media_content_error("Wrong DB Connection status");
210                         ret = MEDIA_CONTENT_ERROR_DB_FAILED;
211                 }
212         } else {
213                 if (db_handle != NULL) {
214                         ref_count++;
215                 } else {
216                         media_content_error("Wrong DB Handle status");
217                         ret = MEDIA_CONTENT_ERROR_DB_FAILED;
218                 }
219         }
220
221         media_content_info("ref count changed to: %d", ref_count);
222         g_mutex_unlock(&db_mutex);
223
224         return ret;
225 }
226
227 int media_content_connect_with_uid(uid_t uid)
228 {
229         media_content_sec_debug("media_content_connect_with_uid [%d]", uid);
230         content_g_uid = uid;
231
232         return media_content_connect();
233 }
234
235 int media_content_disconnect(void)
236 {
237         int ret = MEDIA_CONTENT_ERROR_NONE;
238
239         g_mutex_lock(&db_mutex);
240         media_content_debug("ref count : %d", ref_count);
241         if (ref_count > 0) {
242                 if (db_handle != NULL) {
243                         ref_count--;
244                 } else {
245                         media_content_error("Wrong DB Handle status");
246                         ret = MEDIA_CONTENT_ERROR_DB_FAILED;
247                 }
248         } else {
249                 media_content_error("DB_FAILED(0x%08x) database is not connected", MEDIA_CONTENT_ERROR_DB_FAILED);
250                 g_mutex_unlock(&db_mutex);
251                 return MEDIA_CONTENT_ERROR_DB_FAILED;
252         }
253
254         if (ref_count == 0) {
255                 if (db_handle != NULL) {
256                         ret = media_db_disconnect(db_handle);
257                         ret = _content_error_capi(ret);
258                         if (ret == MEDIA_CONTENT_ERROR_NONE) {
259                                 db_handle = NULL;
260                         } else {
261                                 media_content_error("database disconnect fail");
262                                 ref_count++;
263                         }
264                 } else {
265                         media_content_error("Wrong DB Handle status");
266                         ret = MEDIA_CONTENT_ERROR_DB_FAILED;
267                 }
268
269                 g_mutex_unlock(&db_mutex);
270
271                 media_content_info("ref count changed to: %d", ref_count);
272
273                 return ret;
274         }
275
276         g_mutex_unlock(&db_mutex);
277
278         media_content_info("ref count changed to: %d", ref_count);
279
280         return ret;
281 }
282
283 int media_content_scan_file(const char *path)
284 {
285         int ret = MEDIA_CONTENT_ERROR_NONE;
286         bool ignore_file = FALSE;
287         bool ignore_dir = FALSE;
288         char *folder_path = NULL;
289         int check_file = MEDIA_CONTENT_ERROR_NONE;
290         char storage_id[MEDIA_CONTENT_UUID_SIZE+1] = {0,};
291         char repl_path[MAX_PATH_LEN] = {0,};
292
293         media_content_retvm_if(!STRING_VALID(path), MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "invalid path");
294
295         media_content_sec_debug("Path : %s", path);
296
297         memset(repl_path, 0, sizeof(repl_path));
298         ret = _media_content_replace_path(path, repl_path);
299         media_content_retvm_if(!STRING_VALID(repl_path), MEDIA_CONTENT_ERROR_INVALID_OPERATION, "path replacement failed");
300
301         ret = _media_util_check_ignore_file(repl_path, &ignore_file);
302         media_content_retvm_if(ignore_file == TRUE, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid path");
303
304         memset(storage_id, 0x00, sizeof(storage_id));
305         ret = media_svc_get_storage_id(_content_get_db_handle(), repl_path, storage_id, _content_get_uid());
306         if (ret != MS_MEDIA_ERR_NONE) {
307                 media_content_error("media_svc_get_storage_id failed : %d", ret);
308                 return _content_error_capi(ret);
309         }
310
311         check_file = _media_util_check_file_exist(repl_path);
312         if (check_file == MEDIA_CONTENT_ERROR_NONE) {
313                 /* This means this path has to be inserted or refreshed */
314                 folder_path = g_path_get_dirname(repl_path);
315                 ret = _media_util_check_ignore_dir(folder_path, &ignore_dir);
316                 SAFE_FREE(folder_path);
317
318                 media_content_retvm_if(ignore_dir == TRUE, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid folder path");
319                 /* check feature */
320                 media_content_retvm_if(!_media_util_check_support_media_type(repl_path), MEDIA_CONTENT_ERROR_NOT_SUPPORTED, "Unsupported media type");
321
322                 ms_user_storage_type_e storage_type;
323
324                 ret = ms_user_get_storage_type(_content_get_uid(), repl_path, &storage_type);
325                 if (ret != MS_MEDIA_ERR_NONE) {
326                         media_content_sec_error("ms_user_get_storage_type failed : %d (%s)", ret, repl_path);
327                         return _content_error_capi(ret);
328                 }
329                 ret = media_svc_check_item_exist_by_path(_content_get_db_handle(), storage_id, repl_path);
330                 if (ret == MS_MEDIA_ERR_NONE) {
331                         /* Refresh */
332                         ret = media_svc_refresh_item(_content_get_db_handle(), storage_id, storage_type, repl_path, _content_get_uid());
333                         if (ret != MS_MEDIA_ERR_NONE) {
334                                 media_content_error("media_svc_refresh_item failed : %d", ret);
335                                 return _content_error_capi(ret);
336                         }
337
338                 } else if (ret == MS_MEDIA_ERR_DB_NO_RECORD) {
339                         /* Insert */
340                         ret = media_svc_insert_item_immediately(_content_get_db_handle(), storage_id, storage_type, repl_path, _content_get_uid());
341                         if (ret != MS_MEDIA_ERR_NONE) {
342                                 if (ret == MS_MEDIA_ERR_DB_CONSTRAINT_FAIL) {
343                                         media_content_sec_error("This item is already inserted. This may be normal operation because other process already did this (%s)", repl_path);
344                                         ret = MEDIA_CONTENT_ERROR_NONE;
345                                 } else {
346                                         media_content_sec_error("media_svc_insert_item_immediately failed : %d (%s)", ret, repl_path);
347                                 }
348
349                                 return _content_error_capi(ret);
350                         }
351                 } else {
352                         media_content_error("media_svc_check_item_exist_by_path failed : %d", ret);
353                         return _content_error_capi(ret);
354                 }
355         } else if (check_file == MEDIA_CONTENT_ERROR_PERMISSION_DENIED) {
356                 media_content_error("You have no permission for this file %d", ret);
357                 return MEDIA_CONTENT_ERROR_PERMISSION_DENIED;
358         } else {
359                 /* This means this path has to be deleted */
360                 media_content_debug("This path doesn't exists in file system... So now start to delete it from DB");
361                 ret = media_svc_delete_item_by_path(_content_get_db_handle(), storage_id, repl_path, _content_get_uid());
362                 if (ret != MS_MEDIA_ERR_NONE) {
363                         if (ret == MS_MEDIA_ERR_DB_NO_RECORD) {
364                                 media_content_error("Does not exist in media DB also... So, this is an invalid parameter");
365                                 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
366                         }
367
368                         media_content_error("media_svc_delete_item_by_path failed : %d", ret);
369                         return _content_error_capi(ret);
370                 }
371         }
372
373         return _content_error_capi(ret);
374 }
375
376 void _media_content_scan_cb(media_request_result_s* result, void *user_data)
377 {
378         int err = -1;
379         media_content_scan_cb_data *cb_data = user_data;
380
381         err = _content_error_capi(result->result);
382 #ifdef _USE_TVPD_MODE
383         if (result->request_type != MEDIA_REQUEST_SCAN_COMPLETE &&
384                 result->request_type != MEDIA_REQUEST_SCAN_PARTIAL) {
385                 if (cb_data && cb_data->callback) {
386                         media_content_debug("begin:User callback is being called now, result=%d", err);
387                         cb_data->callback(err, cb_data->user_data);
388                         media_content_debug("end:User callback is being called now, result=%d", err);
389                 }
390
391                 SAFE_FREE(cb_data);
392         }
393 #else
394         if (cb_data && cb_data->callback) {
395                 media_content_debug("User callback is being called now");
396                 cb_data->callback(err, cb_data->user_data);
397         }
398
399         SAFE_FREE(cb_data);
400 #endif
401
402         return;
403 }
404
405 #ifdef _USE_TVPD_MODE
406 void _media_content_scan_cb_v2(media_request_result_s* result, void *user_data)
407 {
408         int err = -1;
409         media_content_scan_cb_data_v2 *cb_data = user_data;
410         media_content_complete_phase_e complete_phase = -1;
411         if (!cb_data)
412                 media_content_debug("cb_data is NULL");
413         err = _content_error_capi(result->result);
414         media_content_debug("result is %d", err);
415
416         if (result->request_type == MEDIA_REQUEST_SCAN_PARTIAL)
417                 complete_phase = MEDIA_CONTENT_SCAN_PARTIAL_COMPLETE;
418         else if (result->request_type == MEDIA_REQUEST_SCAN_COMPLETE)
419                 complete_phase = MEDIA_CONTENT_SCAN_COMPLETE;
420         else if (result->request_type == MEDIA_REQUEST_EXTRACT_COMPLETE)
421                 complete_phase = MEDIA_CONTENT_EXTRACT_COMPLETE;
422
423         if (cb_data && cb_data->callback)
424                 cb_data->callback(err, complete_phase, cb_data->user_data);
425         else
426                 media_content_debug("run error");
427
428         if ((result->request_type != MEDIA_REQUEST_SCAN_COMPLETE) &&
429         (result->request_type != MEDIA_REQUEST_SCAN_PARTIAL))
430                 SAFE_FREE(cb_data);
431
432         return;
433 }
434 #endif
435
436 int media_content_scan_folder(const char *path, bool is_recursive, media_scan_completed_cb callback, void *user_data)
437 {
438         int ret = MEDIA_CONTENT_ERROR_NONE;
439         bool ignore_dir = FALSE;
440         char storage_id[MEDIA_CONTENT_UUID_SIZE+1] = {0, };
441         char repl_path[MAX_PATH_LEN] = {0, };
442         ms_user_storage_type_e storage_type = MS_USER_STORAGE_INTERNAL;
443
444         media_content_retvm_if(!STRING_VALID(path), MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid path");
445         memset(repl_path, 0, sizeof(repl_path));
446         ret = _media_content_replace_path(path, repl_path);
447         media_content_retvm_if(!STRING_VALID(repl_path), MEDIA_CONTENT_ERROR_INVALID_OPERATION, "path replacement failed");
448
449         memset(storage_id, 0x00, sizeof(storage_id));
450
451         ret = _media_content_check_dir(repl_path);
452         media_content_retvm_if(ret == MEDIA_CONTENT_ERROR_PERMISSION_DENIED, ret, "Permission Denied");
453
454         if (ret == MEDIA_CONTENT_ERROR_NONE) {
455                 /* If directory exist check that's ignore directory or not*/
456                 ret = _media_util_check_ignore_dir(repl_path, &ignore_dir);
457                 media_content_retvm_if((ignore_dir == TRUE || ret != MEDIA_CONTENT_ERROR_NONE), MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid folder path");
458         } else {
459                 /* This means this folder has to be deleted */
460                 /* Or, it is real invalid path.. check storage type */
461                 ret = ms_user_get_storage_type(_content_get_uid(), repl_path, &storage_type);
462                 if (ret != MS_MEDIA_ERR_NONE) {
463                         media_content_sec_error("ms_user_get_storage_type failed : %d (%s)", ret, repl_path);
464                         return _content_error_capi(ret);
465                 }
466
467                 media_content_debug("This path doesn't exists in file system... So will be deleted it from DB");
468         }
469
470         ret = media_svc_get_storage_id(_content_get_db_handle(), repl_path, storage_id, _content_get_uid());
471         if (ret != MS_MEDIA_ERR_NONE) {
472                 media_content_error("media_svc_get_storage_id failed : %d", ret);
473                 return _content_error_capi(ret);
474         }
475
476         media_content_scan_cb_data *cb_data = NULL;
477         cb_data = (media_content_scan_cb_data *)malloc(sizeof(media_content_scan_cb_data));
478         media_content_retvm_if(cb_data == NULL, MEDIA_CONTENT_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY");
479
480         cb_data->callback = callback;
481         cb_data->user_data = user_data;
482
483         ret = media_directory_scanning_async(repl_path, storage_id, is_recursive, _media_content_scan_cb, cb_data, _content_get_uid());
484         if (ret != MS_MEDIA_ERR_NONE) {
485                 media_content_error("media_directory_scanning_async failed : %d", ret);
486                 SAFE_FREE(cb_data);
487         }
488
489         return _content_error_capi(ret);
490 }
491
492 #ifdef _USE_TVPD_MODE
493 int media_content_scan_folder_v2(const char *path, bool is_recursive, media_scan_completed_cb_v2 callback, void *user_data)
494 {
495         int ret = MEDIA_CONTENT_ERROR_NONE;
496         bool ignore_dir = FALSE;
497         char storage_id[MEDIA_CONTENT_UUID_SIZE+1] = {0, };
498
499         media_content_retvm_if(!STRING_VALID(path), MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid path");
500         memset(storage_id, 0x00, sizeof(storage_id));
501
502         ret = _media_util_check_ignore_dir(path, &ignore_dir);
503         media_content_retvm_if(ignore_dir, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid folder path");
504
505         ret = _media_content_check_dir(path);
506         media_content_retvm_if(ret == MEDIA_CONTENT_ERROR_PERMISSION_DENIED, ret, "Permission Denied");
507         media_content_retvm_if(ret == MEDIA_CONTENT_ERROR_INVALID_PARAMETER, ret, "invalid path[%s]", path);
508
509         media_content_scan_cb_data_v2* cb_data = NULL;
510         cb_data = (media_content_scan_cb_data_v2*)malloc(sizeof(media_content_scan_cb_data_v2));
511         media_content_retvm_if(cb_data == NULL, MEDIA_CONTENT_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY");
512
513         cb_data->callback = callback;
514         cb_data->user_data = user_data;
515
516         ret = media_svc_get_storage_id(_content_get_db_handle(), path, storage_id, _content_get_uid());
517         /*FIX ME. need to check ret value?*/
518
519         ret = media_directory_scanning_async(path, storage_id, is_recursive, _media_content_scan_cb_v2, cb_data, _content_get_uid());
520         if (ret != MS_MEDIA_ERR_NONE)
521                 media_content_error("media_directory_scanning_async failed : %d", ret);
522
523         return _content_error_capi(ret);
524 }
525 #endif
526
527 int media_content_cancel_scan_folder(const char *path)
528 {
529         int ret = MEDIA_CONTENT_ERROR_NONE;
530         char repl_path[MAX_PATH_LEN] = {0, };
531
532         media_content_retvm_if(!STRING_VALID(path), MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid path");
533
534         memset(repl_path, 0, sizeof(repl_path));
535         ret = _media_content_replace_path(path, repl_path);
536         media_content_retvm_if(!STRING_VALID(repl_path), MEDIA_CONTENT_ERROR_INVALID_OPERATION, "path replacement failed");
537
538         ret = media_directory_scanning_cancel(repl_path, _content_get_uid());
539         if (ret != MS_MEDIA_ERR_NONE)
540                 media_content_error("media_directory_scanning_async failed : %d", ret);
541
542         return _content_error_capi(ret);
543 }
544
545 void _media_content_db_update_noti_cb(
546                                                         int pid,
547                                                         media_item_type_e item,
548                                                         media_item_update_type_e update_type,
549                                                         char* path,
550                                                         char* uuid,
551                                                         media_type_e content_type,
552                                                         char *mime_type,
553                                                         void *user_data)
554 {
555         int error_value = MEDIA_CONTENT_ERROR_NONE;
556
557         media_noti_cb_s *_noti_info = (media_noti_cb_s *)user_data;
558
559         if (_noti_info != NULL) {
560                 if (_noti_info->update_noti_cb)
561                         _noti_info->update_noti_cb(error_value, pid, item, update_type, content_type, uuid, path, mime_type, _noti_info->user_data);
562         }
563
564         return;
565 }
566
567 int media_content_add_db_updated_cb(media_content_db_update_cb callback, void *user_data, media_content_noti_h *noti_handle)
568 {
569         int ret = MEDIA_CONTENT_ERROR_NONE;
570         media_noti_cb_s *noti_info = NULL;
571
572         if (noti_handle == NULL) {
573                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
574                 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
575         }
576
577         if (callback == NULL) {
578                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
579                 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
580         }
581
582         noti_info = (media_noti_cb_s *)calloc(1, sizeof(media_noti_cb_s));
583         if (noti_info == NULL) {
584                 media_content_error("Failed to create noti info");
585                 return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
586         }
587
588         noti_info->update_noti_cb = callback;
589         noti_info->user_data = user_data;
590
591         ret = media_db_update_subscribe_internal((MediaNotiHandle*)noti_handle, _media_content_db_update_noti_cb, (void *)noti_info);
592
593         return _content_error_capi(ret);
594 }
595
596 void __media_content_clear_user_data(void *user_data)
597 {
598         media_noti_cb_s *noti_info = user_data;
599
600         SAFE_FREE(noti_info);
601
602         return;
603 }
604
605 int media_content_remove_db_updated_cb(media_content_noti_h noti_handle)
606 {
607         int ret = MEDIA_CONTENT_ERROR_NONE;
608
609         ret = media_db_update_unsubscribe_internal((MediaNotiHandle)noti_handle, __media_content_clear_user_data);
610
611         return _content_error_capi(ret);
612 }
613 #ifdef _USE_TVPD_MODE
614 GMutex* _content_get_db_mutex(void)
615 {
616         return &db_mutex;
617 }
618 #endif