From b32959021775c9aadf2687ed2bdf59a8958c00bd Mon Sep 17 00:00:00 2001 From: Minje Ahn Date: Tue, 29 Jan 2019 10:59:18 +0900 Subject: [PATCH] [ACR-1348] Fix bug of media_info_insert_to_db API When the media_info handle is returned, modify it to include the latest media information. (In the past, if the media info you requested was in the database, this API returned the media info without making sure it was up-to-date.) Change-Id: Ib3e6b63247fa3cc92e03177666b49b3de4be2dae Signed-off-by: Minje Ahn --- include/media_info.h | 15 +++++++++------ include/media_util_private.h | 1 + include_product/media_info.h | 15 +++++++++------ include_product/media_util_private.h | 1 + src/media_info.c | 37 +++++++++++++++++++++++------------- src/media_util_private.c | 17 +++++++++++++++++ 6 files changed, 61 insertions(+), 25 deletions(-) diff --git a/include/media_info.h b/include/media_info.h index 18a82a5..299082b 100755 --- a/include/media_info.h +++ b/include/media_info.h @@ -43,7 +43,10 @@ extern "C" { /** * @brief Inserts the content file into the media database. * @details In general, you can use this function to insert content files into the media database. \n - * You can use media_content_scan_file()/media_content_scan_folder() function instead of this function. + * You can use media_content_scan_file()/media_content_scan_folder() function instead of this function. \n + * If media information exists in the media database, this function returns information stored in the database.\n + * Since 5.5, if media information exists in the media database, + * this function will return the latest information after checking that the information is up-to-date. (Media database will be updated if necessary). * * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @@ -53,14 +56,14 @@ extern "C" { * %http://tizen.org/privilege/externalstorage * * @remarks The @a info should be released using media_info_destroy(). \n - * You must add privilege http://tizen.org/privilege/content.write. And You add more privilege depending on your choice of contents path. \n + * You must add the privilege http://tizen.org/privilege/content.write. You need to add more privileges depending on your choice of contents path. \n * If you want to access only internal storage by using this function, you should add privilege http://tizen.org/privilege/mediastorage. \n - * Or if you want to access only external storage by using this function, you should add privilege http://tizen.org/privilege/externalstorage. \n - * If you can access both storage, you must add all privilege. \n - * Since 4.0, This function does not allow a symbolic link. \n + * If you want to access only external storage by using this function, you should add privilege http://tizen.org/privilege/externalstorage. \n + * If you want to access storages of both types, you must add all privileges. \n + * Since 4.0, this function does not accept symbolic links. \n * @remarks Since 4.0, this function is related to the following feature:\n * %http://tizen.org/feature/content.scanning.others\n - * If this feature is not supported on the device, MEDIA_CONTENT_TYPE_OTHERS type file is not scanned. + * If this feature is not supported on the device, #MEDIA_CONTENT_TYPE_OTHERS type files are not scanned. * * @param[in] path The path of the content file to add * @param[out] info The handle of the inserted content file diff --git a/include/media_util_private.h b/include/media_util_private.h index 0f28d39..a734ea7 100755 --- a/include/media_util_private.h +++ b/include/media_util_private.h @@ -32,6 +32,7 @@ extern "C" { bool _media_util_check_support_media_type(const char *path); int _media_util_check_file_exist(const char *path); void _media_util_trim_path(const char *input_path, char **output_path); +int _media_util_get_file_time(const char *path); int _media_util_check_ignore_file(const char *path, bool *ignore); int _media_util_check_ignore_dir(const char *dir_path, bool *ignore); int _media_content_check_dir(const char *path); diff --git a/include_product/media_info.h b/include_product/media_info.h index 18a82a5..299082b 100755 --- a/include_product/media_info.h +++ b/include_product/media_info.h @@ -43,7 +43,10 @@ extern "C" { /** * @brief Inserts the content file into the media database. * @details In general, you can use this function to insert content files into the media database. \n - * You can use media_content_scan_file()/media_content_scan_folder() function instead of this function. + * You can use media_content_scan_file()/media_content_scan_folder() function instead of this function. \n + * If media information exists in the media database, this function returns information stored in the database.\n + * Since 5.5, if media information exists in the media database, + * this function will return the latest information after checking that the information is up-to-date. (Media database will be updated if necessary). * * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @@ -53,14 +56,14 @@ extern "C" { * %http://tizen.org/privilege/externalstorage * * @remarks The @a info should be released using media_info_destroy(). \n - * You must add privilege http://tizen.org/privilege/content.write. And You add more privilege depending on your choice of contents path. \n + * You must add the privilege http://tizen.org/privilege/content.write. You need to add more privileges depending on your choice of contents path. \n * If you want to access only internal storage by using this function, you should add privilege http://tizen.org/privilege/mediastorage. \n - * Or if you want to access only external storage by using this function, you should add privilege http://tizen.org/privilege/externalstorage. \n - * If you can access both storage, you must add all privilege. \n - * Since 4.0, This function does not allow a symbolic link. \n + * If you want to access only external storage by using this function, you should add privilege http://tizen.org/privilege/externalstorage. \n + * If you want to access storages of both types, you must add all privileges. \n + * Since 4.0, this function does not accept symbolic links. \n * @remarks Since 4.0, this function is related to the following feature:\n * %http://tizen.org/feature/content.scanning.others\n - * If this feature is not supported on the device, MEDIA_CONTENT_TYPE_OTHERS type file is not scanned. + * If this feature is not supported on the device, #MEDIA_CONTENT_TYPE_OTHERS type files are not scanned. * * @param[in] path The path of the content file to add * @param[out] info The handle of the inserted content file diff --git a/include_product/media_util_private.h b/include_product/media_util_private.h index bf082a7..28d4190 100755 --- a/include_product/media_util_private.h +++ b/include_product/media_util_private.h @@ -32,6 +32,7 @@ extern "C" { bool _media_util_check_support_media_type(const char *path); int _media_util_check_file_exist(const char *path); void _media_util_trim_path(const char *input_path, char **output_path); +int _media_util_get_file_time(const char *path); int _media_util_check_ignore_file(const char *path, bool *ignore); int _media_util_check_ignore_dir(const char *dir_path, bool *ignore); int _media_content_check_dir(const char *path); diff --git a/src/media_info.c b/src/media_info.c index 49e0b47..a911855 100755 --- a/src/media_info.c +++ b/src/media_info.c @@ -394,6 +394,8 @@ int media_info_insert_to_db(const char *path, media_info_h *info) char storage_id[MEDIA_CONTENT_UUID_SIZE+1] = {0, }; char repl_path[MAX_PATH_LEN] = {0, }; int ret = MEDIA_CONTENT_ERROR_NONE; + ms_user_storage_type_e storage_type = MS_USER_STORAGE_INTERNAL; + int modified_time = 0; media_content_retvm_if(!STRING_VALID(path), MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "invalid path"); media_content_retvm_if(info == NULL, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "invalid info"); @@ -411,20 +413,28 @@ int media_info_insert_to_db(const char *path, media_info_h *info) return _content_error_capi(MEDIA_CONTENT_TYPE, ret); } - ret = media_svc_check_item_exist_by_path(_content_get_db_handle(), storage_id, repl_path); - if (ret == MS_MEDIA_ERR_DB_NO_RECORD) { - media_content_sec_debug("media_svc_check_item_exist_by_path : no record : %s", repl_path); - media_content_retvm_if(!_media_util_check_support_media_type(repl_path), MEDIA_CONTENT_ERROR_NOT_SUPPORTED, "Unsupported media type"); - ms_user_storage_type_e storage_type = MS_USER_STORAGE_INTERNAL; + ret = ms_user_get_storage_type(_content_get_uid(), repl_path, &storage_type); + if (ret != MS_MEDIA_ERR_NONE) { + media_content_sec_error("ms_user_get_storage_type failed : %d", ret); + return _content_error_capi(MEDIA_CONTENT_TYPE, ret); + } - ret = ms_user_get_storage_type(_content_get_uid(), repl_path, &storage_type); - if (ret != MS_MEDIA_ERR_NONE) { - media_content_sec_error("ms_user_get_storage_type failed : %d", ret); - return _content_error_capi(MEDIA_CONTENT_TYPE, ret); + /* Get modified time for check exists */ + ret = media_svc_get_modified_time(_content_get_db_handle(), storage_id, repl_path, &modified_time); + if (ret == MS_MEDIA_ERR_NONE) { + /* Refresh if need */ + if (modified_time != _media_util_get_file_time(repl_path)) { + ret = media_svc_refresh_item(_content_get_db_handle(), storage_id, storage_type, repl_path, _content_get_uid()); + if (ret != MS_MEDIA_ERR_NONE) { + media_content_error("media_svc_refresh_item failed : %d", ret); + return _content_error_capi(MEDIA_CONTENT_TYPE, ret); + } } + } else if (ret == MS_MEDIA_ERR_DB_NO_RECORD) { + media_content_sec_debug("media_svc_check_item_exist_by_path : no record : %s", repl_path); + media_content_retvm_if(!_media_util_check_support_media_type(repl_path), MEDIA_CONTENT_ERROR_NOT_SUPPORTED, "Unsupported media type"); ret = media_svc_insert_item_immediately(_content_get_db_handle(), storage_id, storage_type, repl_path, _content_get_uid()); - if (ret != MS_MEDIA_ERR_NONE) { if (ret == MS_MEDIA_ERR_DB_CONSTRAINT_FAIL) { media_content_sec_error("This item is already inserted. This may be normal operation because other process already did this (%s)", repl_path); @@ -435,8 +445,8 @@ int media_info_insert_to_db(const char *path, media_info_h *info) return _content_error_capi(MEDIA_CONTENT_TYPE, ret); } - } else if (ret != MS_MEDIA_ERR_NONE) { - media_content_sec_error("media_svc_check_item_exist_by_path failed : %d (%s)", ret, repl_path); + } else { + media_content_sec_error("media_svc_get_modified_time failed : %d (%s)", ret, repl_path); return _content_error_capi(MEDIA_CONTENT_TYPE, ret); } @@ -449,6 +459,7 @@ int media_info_insert_to_db(const char *path, media_info_h *info) ret = _media_info_get_media_info_from_db(repl_path, DB_TABLE_MEDIA, (media_info_h)_media); *info = (media_info_h)_media; + return ret; } @@ -2170,4 +2181,4 @@ int media_info_set_display_name(media_info_h media, const char *display_name) } return ret; -} \ No newline at end of file +} diff --git a/src/media_util_private.c b/src/media_util_private.c index 65b7a1a..557afe9 100755 --- a/src/media_util_private.c +++ b/src/media_util_private.c @@ -20,6 +20,7 @@ #include #include #include +#include #ifdef _USE_SENIOR_MODE #include @@ -107,6 +108,22 @@ void _media_util_trim_path(const char *input_path, char **output_path) *output_path = g_strdup(buf); } + +int _media_util_get_file_time(const char *path) +{ + struct stat statbuf; + int ret = 0; + + memset(&statbuf, 0, sizeof(struct stat)); + ret = stat(path, &statbuf); + if (ret == -1) { + media_content_stderror("stat(%s) failed", path); + return ret; + } + + return statbuf.st_mtime; +} + int _media_util_check_ignore_file(const char *path, bool *ignore) { media_content_retvm_if(!STRING_VALID(path), MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "invalid path"); -- 2.7.4