From 447b7cb291fc3e2e9f666079cec3c8d376ee02b6 Mon Sep 17 00:00:00 2001 From: Minje Ahn Date: Tue, 23 Jun 2015 17:25:34 +0900 Subject: [PATCH] Update for modification of scanning process. Change-Id: I0a97afa98c39a3faaa34b99290933232b256ff1d Signed-off-by: Minje Ahn --- LICENSE.APLv2.0 | 1 + Makefile.am | 24 +- configure.ac | 8 - lib/include/media-server-ipc.h | 24 +- lib/include/media-util-db.h | 12 +- lib/include/media-util-dbg.h | 8 - lib/include/media-util-err.h | 8 - lib/include/media-util-internal.h | 16 +- lib/include/media-util-ipc.h | 21 +- lib/include/media-util-noti-common.h | 74 ++ lib/include/media-util-noti.h | 41 +- lib/include/media-util-register.h | 12 +- lib/include/media-util.h | 2 + lib/media-util-db.c | 348 +++---- lib/media-util-ipc.c | 203 +++- lib/media-util-noti.c | 341 +++---- lib/media-util-register.c | 247 ++++- packaging/media-server-user.service | 1 + packaging/media-server.spec | 10 +- src/common/include/media-common-dbg.h | 19 +- src/common/include/media-common-drm.h | 51 - src/common/include/media-common-external-storage.h | 27 +- src/common/include/media-common-types.h | 16 +- src/common/include/media-common-utils.h | 73 +- src/common/media-common-drm.c | 111 -- src/common/media-common-external-storage.c | 30 +- src/common/media-common-utils.c | 41 +- src/mediadb-update.c | 47 +- src/scanner/include/media-scanner-db-svc.h | 36 +- src/scanner/include/media-scanner-dbg.h | 12 +- src/scanner/include/media-scanner-scan.h | 18 +- src/scanner/include/media-scanner-socket.h | 12 +- src/scanner/media-scanner-db-svc.c | 300 ++++-- src/scanner/media-scanner-scan.c | 1063 +++++++++++++++----- src/scanner/media-scanner-socket.c | 215 ++-- src/scanner/media-scanner.c | 172 ++-- src/server/include/media-server-db-svc.h | 4 + src/server/include/media-server-dbg.h | 12 +- src/server/include/media-server-scanner.h | 9 +- src/server/include/media-server-socket.h | 23 +- src/server/include/media-server-thumb.h | 33 +- src/server/media-server-db-svc.c | 29 +- src/server/media-server-db.c | 19 +- src/server/media-server-main.c | 361 ++++--- src/server/media-server-scanner.c | 167 +-- src/server/media-server-socket.c | 808 ++++++++++----- src/server/media-server-thumb.c | 20 +- 47 files changed, 3101 insertions(+), 2028 deletions(-) create mode 100755 lib/include/media-util-noti-common.h delete mode 100755 src/common/include/media-common-drm.h delete mode 100755 src/common/media-common-drm.c diff --git a/LICENSE.APLv2.0 b/LICENSE.APLv2.0 index 8aa906c..f94008a 100644 --- a/LICENSE.APLv2.0 +++ b/LICENSE.APLv2.0 @@ -1,3 +1,4 @@ +Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. Apache License Version 2.0, January 2004 diff --git a/Makefile.am b/Makefile.am index e8b55b1..cf9dc44 100755 --- a/Makefile.am +++ b/Makefile.am @@ -57,15 +57,14 @@ bin_PROGRAMS = media-server \ media-scanner \ mediadb-update -media_server_SOURCES = src/common/media-common-drm.c \ - src/common/media-common-utils.c \ +media_server_SOURCES = src/common/media-common-utils.c \ src/common/media-common-external-storage.c \ src/server/media-server-db-svc.c \ src/server/media-server-db.c \ src/server/media-server-socket.c \ src/server/media-server-thumb.c \ src/server/media-server-scanner.c \ - src/server/media-server-main.c + src/server/media-server-main.c media_server_CFLAGS = -I${srcdir}/src/common/include \ -I${srcdir}/src/server/include \ @@ -74,10 +73,8 @@ media_server_CFLAGS = -I${srcdir}/src/common/include \ $(GLIB_CFLAGS) \ $(PHONESTATUS_CFLAGS) \ $(DLOG_CFLAGS) \ - $(DRM_SERVICE_CFLAGS) \ $(AUL_CFLAG)\ $(LIBPMCONTROL_CFLAGS) \ - $(HEYNOTI_CFLAGS) \ $(DBUS_CFLAGS) \ $(STATUS_CFLAGS) @@ -86,17 +83,14 @@ media_server_LDADD = libmedia-utils.la \ $(GTHREAD_LIBS) \ $(PHONESTATUS_LIBS) \ $(DLOG_LIBS) \ - $(DRM_SERVICE_LIBS) \ $(AUL_LIBS) \ $(LIBPMCONTROL_LIBS) \ - $(HEYNOTI_LIBS) \ $(DBUS_LIBS) \ -ldl \ $(STATUS_LIBS) media_scanner_SOURCES = src/common/media-common-utils.c \ src/common/media-common-external-storage.c \ - src/common/media-common-drm.c \ src/scanner/media-scanner-db-svc.c \ src/scanner/media-scanner-scan.c \ src/scanner/media-scanner-socket.c \ @@ -109,10 +103,8 @@ media_scanner_CFLAGS = -I${srcdir}/lib/include \ $(GLIB_CFLAGS) \ $(PHONESTATUS_CFLAGS) \ $(DLOG_CFLAGS) \ - $(DRM_SERVICE_CFLAGS) \ $(AUL_CFLAG)\ $(LIBPMCONTROL_CFLAGS) \ - $(HEYNOTI_CFLAGS) \ $(DBUS_CFLAGS) \ $(STATUS_CFLAGS) @@ -121,11 +113,9 @@ media_scanner_LDADD = libmedia-utils.la \ $(GTHREAD_LIBS) \ $(PHONESTATUS_LIBS) \ $(DLOG_LIBS) \ - $(DRM_SERVICE_LIBS) \ $(AUL_LIBS) \ $(LIBPMCONTROL_LIBS) \ $(THUMB_GEN_LIBS) \ - $(HEYNOTI_LIBS) \ $(DBUS_LIBS) \ -ldl \ $(STATUS_LIBS) @@ -136,13 +126,19 @@ mediadb_update_CFLAGS = -I${srcdir}/lib/include \ $(GTHREAD_CFLAGS) \ $(GLIB_CFLAGS) +mediadb_update_CFLAGS += -fPIE + +mediadb_update_LDFLAGS = -pie + mediadb_update_LDADD = libmedia-utils.la \ $(GLIB_LIBS) \ - $(GTHREAD_LIBS) + $(GTHREAD_LIBS) \ + -ldl ### includeheaders ### includeheadersdir = $(includedir)/media-utils -includeheaders_HEADERS = lib/include/media-util-noti.h \ +includeheaders_HEADERS = lib/include/media-util-noti-common.h \ + lib/include/media-util-noti.h \ lib/include/media-util-register.h \ lib/include/media-util-err.h \ lib/include/media-util-db.h \ diff --git a/configure.ac b/configure.ac index 926e34f..cd49033 100755 --- a/configure.ac +++ b/configure.ac @@ -66,10 +66,6 @@ PKG_CHECK_MODULES(DLOG, dlog) AC_SUBST(DLOG_CFLAGS) AC_SUBST(DLOG_LIBS) -PKG_CHECK_MODULES(DRM_SERVICE, drm-client) -AC_SUBST(DRM_SERVICE_CFLAGS) -AC_SUBST(DRM_SERVICE_LIBS) - PKG_CHECK_MODULES(PHONESTATUS, vconf) AC_SUBST(PHONESTATUS_CFLAGS) AC_SUBST(PHONESTATUS_LIBS) @@ -82,10 +78,6 @@ PKG_CHECK_MODULES(LIBPMCONTROL, pmapi) AC_SUBST(LIBPMCONTROL_CFLAGS) AC_SUBST(LIBPMCONTROL_LIBS) -PKG_CHECK_MODULES(HEYNOTI, heynoti) -AC_SUBST(HEYNOTI_CFLAGS) -AC_SUBST(HEYNOTI_LIBS) - PKG_CHECK_MODULES(DBUS, dbus-glib-1) AC_SUBST(DBUS_CFLAGS) AC_SUBST(DBUS_LIBS) diff --git a/lib/include/media-server-ipc.h b/lib/include/media-server-ipc.h index 5fcbab5..ebc3ab4 100755 --- a/lib/include/media-server-ipc.h +++ b/lib/include/media-server-ipc.h @@ -19,14 +19,6 @@ * */ -/** - * This file defines IPC protocol - * - * @file media-server-ipc.h - * @author Haejeong Kim(backto.kim@samsung.com) - * @version 1.0 - * @brief - */ #ifndef _MEDIA_SERVER_IPC_H_ #define _MEDIA_SERVER_IPC_H_ @@ -37,7 +29,6 @@ typedef enum{ MS_DB_BATCH_UPDATE_PORT = 0, /**< Media DB batch update */ MS_SCAN_DAEMON_PORT, /**< Port of communication between scanner and server */ - MS_SCAN_COMM_PORT, /**< Port of communication between scanner and server */ MS_SCANNER_PORT, /**< Directory Scanner */ MS_DB_UPDATE_PORT, /**< Media DB Update */ MS_THUMB_CREATOR_PORT, /**< Create thumbnail */ @@ -66,9 +57,22 @@ typedef enum{ MS_MSG_SCANNER_READY, /**< Ready from media scanner */ MS_MSG_SCANNER_RESULT, /**< Result of directory scanning */ MS_MSG_SCANNER_BULK_RESULT, /**< Request bulk insert */ + MS_MSG_STORAGE_META, /**< Request updating meta data */ + MS_MSG_DIRECTORY_SCANNING_CANCEL, /**< Request cancel directory scan*/ MS_MSG_MAX /**< Invalid msg type */ }ms_msg_type_e; +#define MS_SCANNER_FIFO_PATH_REQ "/tmp/media-scanner-fifo-req" +#define MS_SCANNER_FIFO_PATH_RES "/tmp/media-scanner-fifo-res" +#define MS_SCANNER_FIFO_MODE 0666 + +typedef struct +{ + int sock_fd; + int port; + char *sock_path; +}ms_sock_info_s; + typedef struct { ms_msg_type_e msg_type; @@ -76,7 +80,7 @@ typedef struct uid_t uid; int result; size_t msg_size; /*this is size of message below and this does not include the terminationg null byte ('\0'). */ - char msg[MAX_FILEPATH_LEN]; + char msg[MAX_MSG_SIZE]; }ms_comm_msg_s; typedef enum { diff --git a/lib/include/media-util-db.h b/lib/include/media-util-db.h index dae1811..27f1dd6 100755 --- a/lib/include/media-util-db.h +++ b/lib/include/media-util-db.h @@ -19,15 +19,7 @@ * */ -/** - * This file defines api utilities of contents manager engines. - * - * @file media-util-noti.h - * @author Yong Yeon Kim(yy9875.kim@samsung.com) - * @version 1.0 - * @brief - */ - #ifndef _MEDIA_UTIL_DB_H_ +#ifndef _MEDIA_UTIL_DB_H_ #define _MEDIA_UTIL_DB_H_ #ifdef __cplusplus @@ -48,7 +40,7 @@ int media_db_request_update_db_batch(const char *query_str, uid_t uid); int media_db_request_update_db_batch_end(const char *query_str, uid_t uid); -int media_db_request_directory_scan(const char *directory_path , uid_t uid); +int media_db_request_update_db_batch_clear(void); /** * @} diff --git a/lib/include/media-util-dbg.h b/lib/include/media-util-dbg.h index d5e06a3..13e19b8 100755 --- a/lib/include/media-util-dbg.h +++ b/lib/include/media-util-dbg.h @@ -19,14 +19,6 @@ * */ -/** - * This file defines api utilities of contents manager engines. - * - * @file media-util-dbg.h - * @author Yong Yeon Kim(yy9875.kim@samsung.com) - * @version 1.0 - * @brief - */ #ifndef _MEDIA_UTIL_DBG_H_ #define _MEDIA_UTIL_DBG_H_ diff --git a/lib/include/media-util-err.h b/lib/include/media-util-err.h index f483942..5873cf0 100755 --- a/lib/include/media-util-err.h +++ b/lib/include/media-util-err.h @@ -19,14 +19,6 @@ * */ -/** - * This file defines api utilities of contents manager engines. - * - * @file media-util-err.h - * @author Yong Yeon Kim(yy9875.kim@samsung.com) - * @version 1.0 - * @brief - */ #ifndef _MEDIA_UTIL_ERR_H_ #define _MEDIA_UTIL_ERR_H_ diff --git a/lib/include/media-util-internal.h b/lib/include/media-util-internal.h index ebbd5f5..3fa1b0d 100755 --- a/lib/include/media-util-internal.h +++ b/lib/include/media-util-internal.h @@ -19,15 +19,6 @@ * */ -/** - * This file defines api utilities of contents manager engines. - * - * @file media-util-internal.h - * @author Yong Yeon Kim(yy9875.kim@samsung.com) - * @version 1.0 - * @brief - */ - #ifndef _MEDIA_UTIL_INTERNAL_H_ #define _MEDIA_UTIL_INTERNAL_H_ @@ -42,15 +33,10 @@ #define MS_SAFE_FREE(src) { if(src) {free(src); src = NULL;} } #define MS_MALLOC(src, size) { if (size > SIZE_MAX || size <= 0) {src = NULL;} \ - else { src = malloc(size); memset(src, 0x0, size);} } + else { src = malloc(size); if(src) memset(src, 0x0, size);} } #define MS_STRING_VALID(str) \ ((str != NULL && strlen(str) > 0) ? TRUE : FALSE) -#define MS_MEDIA_DBUS_PATH "/com/mediaserver/dbus/notify" -#define MS_MEDIA_DBUS_INTERFACE "com.mediaserver.dbus.Signal" -#define MS_MEDIA_DBUS_NAME "ms_db_updated" -#define MS_MEDIA_DBUS_MATCH_RULE "type='signal',interface='com.mediaserver.dbus.Signal'" - int media_db_update_db(MediaDBHandle *handle, const char *query_str); int media_db_update_db_batch_start(const char *query_str); diff --git a/lib/include/media-util-ipc.h b/lib/include/media-util-ipc.h index 82090bf..d34d178 100755 --- a/lib/include/media-util-ipc.h +++ b/lib/include/media-util-ipc.h @@ -19,15 +19,7 @@ * */ -/** - * This file defines api utilities of IPC. - * - * @file media-util-ipc.h - * @author Haejeong Kim(backto.kim@samsung.com) - * @version 1.0 - * @brief - */ - #ifndef _MEDIA_UTIL_IPC_H_ +#ifndef _MEDIA_UTIL_IPC_H_ #define _MEDIA_UTIL_IPC_H_ #ifdef __cplusplus @@ -47,13 +39,18 @@ typedef enum { MS_PROTOCOL_TCP } ms_protocol_e; -int ms_ipc_create_client_socket(ms_protocol_e protocol, int timeout_sec, int *sock_fd, int port); -int ms_ipc_create_server_socket(ms_protocol_e protocol, int port, int *sock_fd); -int ms_ipc_send_msg_to_server(int sockfd, int port, ms_comm_msg_s *send_msg, struct sockaddr_un *serv_addr); +int ms_ipc_create_client_socket(ms_protocol_e protocol, int timeout_sec, ms_sock_info_s* sock_info); +int ms_ipc_create_server_socket(ms_protocol_e protocol, ms_msg_port_type_e port, int *sock_fd); +int ms_ipc_send_msg_to_server(int sockfd, ms_msg_port_type_e port, ms_comm_msg_s *send_msg, struct sockaddr_un *serv_addr); +int ms_ipc_send_msg_to_server_tcp(int sockfd, ms_msg_port_type_e port, ms_comm_msg_s *send_msg, struct sockaddr_un *serv_addr); int ms_ipc_send_msg_to_client(int sockfd, ms_comm_msg_s *send_msg, struct sockaddr_un *client_addr); +int ms_ipc_send_msg_to_client_tcp(int sockfd, ms_comm_msg_s *send_msg, struct sockaddr_un *client_addr); int ms_ipc_receive_message(int sockfd, void *recv_msg, unsigned int msg_size, struct sockaddr_un *client_addr, unsigned int *size); +int ms_ipc_receive_message_tcp(int client_sock, ms_comm_msg_s *recv_msg); int ms_ipc_wait_message(int sockfd, void *recv_msg, unsigned int msg_size, struct sockaddr_un *recv_addr, unsigned int *size); int ms_ipc_wait_block_message(int sockfd, void *recv_msg, unsigned int msg_size, struct sockaddr_un *recv_addr, unsigned int *size); +int ms_ipc_delete_client_socket(ms_sock_info_s* sock_info); +int ms_ipc_accept_client_tcp(int serv_sock, int* client_sock); #ifdef __cplusplus } diff --git a/lib/include/media-util-noti-common.h b/lib/include/media-util-noti-common.h new file mode 100755 index 0000000..c259b40 --- /dev/null +++ b/lib/include/media-util-noti-common.h @@ -0,0 +1,74 @@ +/* + * Media Utility + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Yong Yeon Kim + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef _MEDIA_UTIL_NOTI_COMMON_H_ +#define _MEDIA_UTIL_NOTI_COMMON_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + MS_MEDIA_ITEM_FILE = 0, + MS_MEDIA_ITEM_DIRECTORY = 1, +}media_item_type_e; + +typedef enum { + MS_MEDIA_ITEM_INSERT = 0, + MS_MEDIA_ITEM_DELETE = 1, + MS_MEDIA_ITEM_UPDATE = 2, +}media_item_update_type_e; + +typedef enum { + MS_MEDIA_UNKNOWN = -1, /**< Unknown Conntent*/ + MS_MEDIA_IMAGE = 0, /**< Image Content*/ + MS_MEDIA_VIDEO = 1, /**< Video Content*/ + MS_MEDIA_SOUND = 2, /**< Sound Content like Ringtone*/ + MS_MEDIA_MUSIC = 3, /**< Music Content like mp3*/ + MS_MEDIA_OTHER = 4, /**< Invalid Content*/ +}media_type_e; + +typedef void (*db_update_cb)(int pid, /* mandatory */ + media_item_type_e item, /* mandatory */ + media_item_update_type_e update_type, /* mandatory */ + char* path, /* mandatory */ + char* uuid, /* optional */ + media_type_e media_type, /* optional */ + char *mime_type, /* optional */ + void *user_data); + +typedef void (*clear_user_data_cb)(void * user_data); + +typedef void *MediaNotiHandle; /**< Handle */ + +#define MS_MEDIA_DBUS_PATH "/com/mediaserver/dbus/notify" +#define MS_MEDIA_DBUS_INTERFACE "com.mediaserver.dbus.Signal" +#define MS_MEDIA_DBUS_MATCH_RULE "type='signal',interface='com.mediaserver.dbus.Signal'" + +/** +* @} +*/ + +#ifdef __cplusplus +} +#endif + +#endif /*_MEDIA_UTIL_NOTI_COMMON_H_*/ diff --git a/lib/include/media-util-noti.h b/lib/include/media-util-noti.h index 1071a51..155b48f 100755 --- a/lib/include/media-util-noti.h +++ b/lib/include/media-util-noti.h @@ -19,21 +19,15 @@ * */ -/** - * This file defines api utilities of contents manager engines. - * - * @file media-util-noti.h - * @author Yong Yeon Kim(yy9875.kim@samsung.com) - * @version 1.0 - * @brief - */ - #ifndef _MEDIA_UTIL_NOTI_H_ +#ifndef _MEDIA_UTIL_NOTI_H_ #define _MEDIA_UTIL_NOTI_H_ #ifdef __cplusplus extern "C" { #endif +#include "media-util-noti-common.h" + /** * @fn int media_db_update_subscribe(void); * @brief This function announce media database is updated to other applications.
@@ -68,35 +62,6 @@ main (int argc, char **argv) */ -typedef enum { - MS_MEDIA_ITEM_FILE = 0, - MS_MEDIA_ITEM_DIRECTORY = 1, -}media_item_type_e; - -typedef enum { - MS_MEDIA_ITEM_INSERT = 0, - MS_MEDIA_ITEM_DELETE = 1, - MS_MEDIA_ITEM_UPDATE = 2, -}media_item_update_type_e; - -typedef enum { - MS_MEDIA_UNKNOWN = -1, /**< Unknown Conntent*/ - MS_MEDIA_IMAGE = 0, /**< Image Content*/ - MS_MEDIA_VIDEO = 1, /**< Video Content*/ - MS_MEDIA_SOUND = 2, /**< Sound Content like Ringtone*/ - MS_MEDIA_MUSIC = 3, /**< Music Content like mp3*/ - MS_MEDIA_OTHER = 4, /**< Invalid Content*/ -}media_type_e; - -typedef void (*db_update_cb)(int pid, /* mandatory */ - media_item_type_e item, /* mandatory */ - media_item_update_type_e update_type, /* mandatory */ - char* path, /* mandatory */ - char* uuid, /* optional */ - media_type_e media_type, /* optional */ - char *mime_type, /* optional */ - void *user_data); - int media_db_update_subscribe(db_update_cb user_cb, void *user_data); int media_db_update_unsubscribe(void); diff --git a/lib/include/media-util-register.h b/lib/include/media-util-register.h index d94c3fd..b17c088 100755 --- a/lib/include/media-util-register.h +++ b/lib/include/media-util-register.h @@ -19,15 +19,7 @@ * */ -/** - * This file defines api utilities of contents manager engines. - * - * @file media-util-register.h - * @author Yong Yeon Kim(yy9875.kim@samsung.com) - * @version 1.0 - * @brief - */ - #ifndef _MEDIA_UTIL_REGISTER_H_ +#ifndef _MEDIA_UTIL_REGISTER_H_ #define _MEDIA_UTIL_REGISTER_H_ #include @@ -56,6 +48,8 @@ typedef void (*insert_complete_cb)(media_request_result_s *, void *); int media_directory_scanning_async(const char *directory_path, bool recursive_on, scan_complete_cb user_callback, void *user_data, uid_t uid); +int media_directory_scanning_cancel(const char *directory_path, uid_t uid); + int media_files_register(const char *list_path, insert_complete_cb user_callback, void *user_data, uid_t uid); int media_burstshot_register(const char *list_path, insert_complete_cb user_callback, void *user_data, uid_t uid); diff --git a/lib/include/media-util.h b/lib/include/media-util.h index a4d326b..171f657 100755 --- a/lib/include/media-util.h +++ b/lib/include/media-util.h @@ -34,5 +34,7 @@ #define MEDIA_ROOT_PATH_SDCARD tzplatform_mkpath(TZ_SYS_STORAGE, "sdcard") #define MEDIA_DATA_PATH tzplatform_mkpath(TZ_SYS_DATA, "file-manager-service") #define MEDIA_DB_NAME tzplatform_mkpath(TZ_USER_DB, ".media.db") /**< media db name*/ +#define MEDIA_CONTENT_PATH "content" /**< user content folder name*/ + #endif /*_MEDIA_UTIL_H_*/ diff --git a/lib/media-util-db.c b/lib/media-util-db.c index 88ff720..07f6df2 100755 --- a/lib/media-util-db.c +++ b/lib/media-util-db.c @@ -19,64 +19,30 @@ * */ -/** - * This file defines api utilities of Media DB. - * - * @file media-util-db.c - * @author Haejeong Kim(backto.kim@samsung.com) - * @version 1.0 - * @brief - */ -#include -#include #include #include #include #include #include #include +#include +#include #include #include "media-server-ipc.h" #include "media-util-dbg.h" #include "media-util-internal.h" #include "media-util.h" -#define GLOBAL_USER 0 //#define tzplatform_getenv(TZ_GLOBAL) //TODO #define BUFSIZE 4096 - -#define QUERY_ATTACH "attach database '%s' as Global" -#define QUERY_CREATE_VIEW_ALBUM "CREATE temp VIEW album as select distinct * from (select * from main.album m union select * from Global.album g)" -#define QUERY_CREATE_VIEW_FOLDER "CREATE temp VIEW folder as select distinct * from (select * from main.folder m union select * from Global.folder g)" -#define QUERY_CREATE_VIEW_PLAYLIST "CREATE temp VIEW playlist as select distinct * from (select * from main.playlist m union select * from Global.playlist g)" -#define QUERY_CREATE_VIEW_PLAYLIST_VIEW "CREATE temp VIEW playlist_view as select distinct * from (select * from main.playlist_view m union select * from Global.playlist_view g)" -#define QUERY_CREATE_VIEW_TAG_MAP "CREATE temp VIEW tag_map as select distinct * from (select * from main.tag_map m union select * from Global.tag_map g)" -#define QUERY_CREATE_VIEW_BOOKMARK "CREATE temp VIEW bookmark as select distinct * from (select * from main.bookmark m union select * from Global.bookmark g)" -#define QUERY_CREATE_VIEW_MEDIA "CREATE temp VIEW media as select distinct * from (select * from main.media m union select * from Global.media g)" -#define QUERY_CREATE_VIEW_PLAYLIST_MAP "CREATE temp VIEW playlist_map as select distinct * from (select * from main.playlist_map m union select * from Global.playlist_map g)" -#define QUERY_CREATE_VIEW_TAG "CREATE temp VIEW tag as select distinct * from (select * from main.tag m union select * from Global.tag g)" -#define QUERY_CREATE_VIEW_TAG_VIEW "CREATE temp VIEW tag_view as select distinct * from (select * from main.tag_view m union select * from Global.tag_view g)" - -#define QUERY_DETACH "detach database Global" -#define QUERY_DROP_VIEW_ALBUM "DROP VIEW album" -#define QUERY_DROP_VIEW_FOLDER "DROP VIEW folder" -#define QUERY_DROP_VIEW_PLAYLIST "DROP VIEW playlist" -#define QUERY_DROP_VIEW_PLAYLIST_VIEW "DROP VIEW playlist_view" -#define QUERY_DROP_VIEW_TAG_MAP "DROP VIEW tag_map" -#define QUERY_DROP_VIEW_BOOKMARK "DROP VIEW bookmark" -#define QUERY_DROP_VIEW_MEDIA "DROP VIEW media" -#define QUERY_DROP_VIEW_PLAYLIST_MAP "DROP VIEW playlist_map" -#define QUERY_DROP_VIEW_TAG "DROP VIEW tag" -#define QUERY_DROP_VIEW_TAG_VIEW "DROP VIEW tag_view" - +#define GLOBAL_USER 0 //#define tzplatform_getenv(TZ_GLOBAL) //TODO static __thread char **sql_list = NULL; static __thread int g_list_idx = 0; static int __media_db_busy_handler(void *pData, int count); static int __media_db_connect_db_with_handle(sqlite3 **db_handle, uid_t uid); static int __media_db_disconnect_db_with_handle(sqlite3 *db_handle); -static int __media_db_request_update(ms_msg_type_e msg_type, const char *request_msg, uid_t uid); -void __media_db_destroy_sql_list() +static void __media_db_destroy_sql_list() { int i = 0; @@ -96,41 +62,6 @@ static int __media_db_busy_handler(void *pData, int count) return 100 - count; } -int _xsystem(const char *argv[]) -{ - int status = 0; - pid_t pid; - pid = fork(); - switch (pid) { - case -1: - perror("fork failed"); - return -1; - case 0: - /* child */ - execvp(argv[0], (char *const *)argv); - _exit(-1); - default: - /* parent */ - break; - } - if (waitpid(pid, &status, 0) == -1) - { - perror("waitpid failed"); - return -1; - } - if (WIFSIGNALED(status)) - { - perror("signal"); - return -1; - } - if (!WIFEXITED(status)) - { - /* shouldn't happen */ - perror("should not happen"); - return -1; - } - return WEXITSTATUS(status); -} static char* __media_get_media_DB(uid_t uid) { @@ -185,127 +116,16 @@ static char* __media_get_media_DB(uid_t uid) return result_psswd; } -static int __media_db_update_directly(sqlite3 *db_handle, const char *sql_str) -{ - int ret = MS_MEDIA_ERR_NONE; - char *zErrMsg = NULL; - - MSAPI_DBG_INFO("SQL = [%s]", sql_str); - - ret = sqlite3_exec(db_handle, sql_str, NULL, NULL, &zErrMsg); - - if (SQLITE_OK != ret) { - MSAPI_DBG_ERR("DB Update Fail SQL:%s [%s], err[%d]", sql_str, zErrMsg, ret); - if (ret == SQLITE_BUSY) - ret = MS_MEDIA_ERR_DB_BUSY_FAIL; - else - ret = MS_MEDIA_ERR_DB_UPDATE_FAIL; - } else { - MSAPI_DBG("DB Update Success"); - } - - if (zErrMsg) - sqlite3_free (zErrMsg); - - return ret; -} - static int __media_db_connect_db_with_handle(sqlite3 **db_handle,uid_t uid) { - int i; int ret = MS_MEDIA_ERR_NONE; - char *mediadb_path = NULL; - char *mediadbjournal_path = NULL; - - /*Init DB*/ - const char *tbls[46] = { - "CREATE TABLE IF NOT EXISTS album (album_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, artist TEXT, album_art TEXT, unique(name, artist));", - "CREATE TABLE IF NOT EXISTS bookmark (bookmark_id INTEGER PRIMARY KEY AUTOINCREMENT, media_uuid TEXT NOT NULL, marked_time INTEGER DEFAULT 0, thumbnail_path TEXT, unique(media_uuid, marked_time));", - "CREATE TABLE IF NOT EXISTS folder (folder_uuid TEXT PRIMARY KEY, path TEXT NOT NULL UNIQUE, name TEXT NOT NULL, modified_time INTEGER DEFAULT 0, name_pinyin TEXT, storage_type INTEGER, unique(path, name, storage_type));", - "CREATE TABLE IF NOT EXISTS media (media_uuid TEXT PRIMARY KEY, path TEXT NOT NULL UNIQUE, file_name TEXT NOT NULL, media_type INTEGER, mime_type TEXT, size INTEGER DEFAULT 0, added_time INTEGER DEFAULT 0, modified_time INTEGER DEFAULT 0, folder_uuid TEXT NOT NULL, thumbnail_path TEXT, title TEXT, album_id INTEGER DEFAULT 0, album TEXT, artist TEXT, album_artist TEXT, genre TEXT, composer TEXT, year TEXT, recorded_date TEXT, copyright TEXT, track_num TEXT, description TEXT, bitrate INTEGER DEFAULT -1, bitpersample INTEGER DEFAULT 0, samplerate INTEGER DEFAULT -1, channel INTEGER DEFAULT -1, duration INTEGER DEFAULT -1, longitude DOUBLE DEFAULT 0, latitude DOUBLE DEFAULT 0, altitude DOUBLE DEFAULT 0, width INTEGER DEFAULT -1, height INTEGER DEFAULT -1, datetaken TEXT, orientation INTEGER DEFAULT -1, burst_id TEXT, played_count INTEGER DEFAULT 0, last_played_time INTEGER DEFAULT 0, last_played_position INTEGER DEFAULT 0, rating INTEGER DEFAULT 0, favourite INTEGER DEFAULT 0, author TEXT, provider TEXT, content_name TEXT, category TEXT, location_tag TEXT, age_rating TEXT, keyword TEXT, is_drm INTEGER DEFAULT 0, storage_type INTEGER, timeline INTEGER DEFAULT 0, weather TEXT, sync_status INTEGER DEFAULT 0, file_name_pinyin TEXT, title_pinyin TEXT, album_pinyin TEXT, artist_pinyin TEXT, album_artist_pinyin TEXT, genre_pinyin TEXT, composer_pinyin TEXT, copyright_pinyin TEXT, description_pinyin TEXT, author_pinyin TEXT, provider_pinyin TEXT, content_name_pinyin TEXT, category_pinyin TEXT, location_tag_pinyin TEXT, age_rating_pinyin TEXT, keyword_pinyin TEXT, validity INTEGER DEFAULT 1, unique(path, file_name) );", - "CREATE TABLE IF NOT EXISTS playlist ( playlist_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL UNIQUE, thumbnail_path TEXT );", - "CREATE TABLE IF NOT EXISTS playlist_map ( _id INTEGER PRIMARY KEY AUTOINCREMENT, playlist_id INTEGER NOT NULL, media_uuid TEXT NOT NULL, play_order INTEGER NOT NULL );", - "CREATE TABLE IF NOT EXISTS tag ( tag_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL UNIQUE );", - "CREATE TABLE IF NOT EXISTS tag_map ( _id INTEGER PRIMARY KEY AUTOINCREMENT, tag_id INTEGER NOT NULL, media_uuid TEXT NOT NULL, unique(tag_id, media_uuid) );", - "CREATE INDEX folder_folder_uuid_idx on folder (folder_uuid);", - "CREATE INDEX folder_uuid_idx on media (folder_uuid);", - "CREATE INDEX media_album_idx on media (album);", - "CREATE INDEX media_artist_idx on media (artist);", - "CREATE INDEX media_author_idx on media (author);", - "CREATE INDEX media_category_idx on media (category);", - "CREATE INDEX media_composer_idx on media (composer);", - "CREATE INDEX media_content_name_idx on media (content_name);", - "CREATE INDEX media_file_name_idx on media (file_name);", - "CREATE INDEX media_genre_idx on media (genre);", - "CREATE INDEX media_location_tag_idx on media (location_tag);", - "CREATE INDEX media_media_type_idx on media (media_type);", - "CREATE INDEX media_media_uuid_idx on media (media_uuid);", - "CREATE INDEX media_modified_time_idx on media (modified_time);", - "CREATE INDEX media_path_idx on media (path);", - "CREATE INDEX media_provider_idx on media (provider);", - "CREATE INDEX media_title_idx on media (title);", - "CREATE VIEW IF NOT EXISTS playlist_view AS " - "SELECT " - "p.playlist_id, p.name, p.thumbnail_path, media_count, pm._id as pm_id, pm.play_order, m.media_uuid, path, file_name, media_type, mime_type, size, added_time, modified_time, m.thumbnail_path, description, rating, favourite, author, provider, content_name, category, location_tag, age_rating, keyword, is_drm, storage_type, longitude, latitude, altitude, width, height, datetaken, orientation, title, album, artist, genre, composer, year, recorded_date, copyright, track_num, bitrate, duration, played_count, last_played_time, last_played_position, samplerate, channel FROM playlist AS p " - "INNER JOIN playlist_map AS pm " - "INNER JOIN media AS m " - "INNER JOIN (SELECT count(playlist_id) as media_count, playlist_id FROM playlist_map group by playlist_id) as cnt_tbl " - "ON (p.playlist_id=pm.playlist_id AND pm.media_uuid = m.media_uuid AND cnt_tbl.playlist_id=pm.playlist_id AND m.validity=1) " - "UNION " - "SELECT " - "playlist_id, name, thumbnail_path, 0, 0, -1, NULL, NULL, -1, -1, -1, -1, -1, NULL, NULL, -1, -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1, -1, -1, -1, -1, -1, NULL, -1 FROM playlist " - "WHERE playlist_id " - "NOT IN (select playlist_id from playlist_map);", - "CREATE VIEW IF NOT EXISTS tag_view AS " - "SELECT " - "t.tag_id, t.name, media_count, tm._id as tm_id, m.media_uuid, path, file_name, media_type, mime_type, size, added_time, modified_time, thumbnail_path, description, rating, favourite, author, provider, content_name, category, location_tag, age_rating, keyword, is_drm, storage_type, longitude, latitude, altitude, width, height, datetaken, orientation, title, album, artist, genre, composer, year, recorded_date, copyright, track_num, bitrate, duration, played_count, last_played_time, last_played_position, samplerate, channel FROM tag AS t " - "INNER JOIN tag_map AS tm " - "INNER JOIN media AS m " - "INNER JOIN (SELECT count(tag_id) as media_count, tag_id FROM tag_map group by tag_id) as cnt_tbl " - "ON (t.tag_id=tm.tag_id AND tm.media_uuid = m.media_uuid AND cnt_tbl.tag_id=tm.tag_id AND m.validity=1)" - "UNION " - "SELECT " - "tag_id, name, 0, 0, NULL, NULL, -1, -1, -1, -1, -1, NULL, NULL, -1, -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1, -1, -1, -1, -1, -1, -1, -1, -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1, -1, -1, -1, -1, -1, NULL, -1 FROM tag " - "WHERE tag_id " - "NOT IN (select tag_id from tag_map); ", - "CREATE TRIGGER album_cleanup DELETE ON media BEGIN DELETE FROM album WHERE (SELECT count(*) FROM media WHERE album_id=old.album_id)=1 AND album_id=old.album_id;END;", - "CREATE TRIGGER bookmark_cleanup DELETE ON media BEGIN DELETE FROM bookmark WHERE media_uuid=old.media_uuid;END;", - "CREATE TRIGGER folder_cleanup DELETE ON media BEGIN DELETE FROM folder WHERE (SELECT count(*) FROM media WHERE folder_uuid=old.folder_uuid)=1 AND folder_uuid=old.folder_uuid;END;", - "CREATE TRIGGER playlist_map_cleanup DELETE ON media BEGIN DELETE FROM playlist_map WHERE media_uuid=old.media_uuid;END;", - "CREATE TRIGGER playlist_map_cleanup_1 DELETE ON playlist BEGIN DELETE FROM playlist_map WHERE playlist_id=old.playlist_id;END;", - "CREATE TRIGGER tag_map_cleanup DELETE ON media BEGIN DELETE FROM tag_map WHERE media_uuid=old.media_uuid;END;", - "CREATE TRIGGER tag_map_cleanup_1 DELETE ON tag BEGIN DELETE FROM tag_map WHERE tag_id=old.tag_id;END;", - NULL - }; - - mediadb_path = __media_get_media_DB(uid); - - if (access(mediadb_path, F_OK)) { - if (MS_MEDIA_ERR_NONE == db_util_open_with_options(mediadb_path, db_handle, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL)) { - for (i = 0; tbls[i] != NULL; i++) { - ret = __media_db_update_directly(*db_handle, tbls[i]); - } - if(smack_setlabel(__media_get_media_DB(uid), "User", SMACK_LABEL_ACCESS)){ - MSAPI_DBG_ERR("failed chsmack -a \"User\" %s", mediadb_path); - } else { - MSAPI_DBG_ERR("chsmack -a \"User\" %s", mediadb_path); - } - asprintf(&mediadbjournal_path, "%s-journal", mediadb_path); - if(smack_setlabel(mediadbjournal_path, "User", SMACK_LABEL_ACCESS)){ - MSAPI_DBG_ERR("failed chsmack -a \"User\" %s", mediadbjournal_path); - } else { - MSAPI_DBG_ERR("chsmack -a \"User\" %s", mediadbjournal_path); - } - } else { - MSAPI_DBG_ERR("Failed to create table %s\n",__media_get_media_DB(uid)); - return MS_MEDIA_ERR_DB_CONNECT_FAIL; - } - } + /*Connect DB*/ ret = db_util_open(__media_get_media_DB(uid), db_handle, DB_UTIL_REGISTER_HOOK_METHOD); + if (SQLITE_OK != ret) { - MSAPI_DBG_ERR("error when db open"); + MSAPI_DBG_ERR("error when db open [%s]", __media_get_media_DB(uid)); *db_handle = NULL; return MS_MEDIA_ERR_DB_CONNECT_FAIL; } @@ -349,19 +169,18 @@ static int __media_db_disconnect_db_with_handle(sqlite3 *db_handle) return MS_MEDIA_ERR_NONE; } -static int __media_db_request_update(ms_msg_type_e msg_type, const char *request_msg, uid_t uid) +extern char MEDIA_IPC_PATH[][70]; +#define MAX_RETRY_COUNT 3 + +static int __media_db_request_update_tcp(ms_msg_type_e msg_type, const char *request_msg, uid_t uid) { int ret = MS_MEDIA_ERR_NONE; int request_msg_size = 0; int sockfd = -1; - int err = -1; + ms_sock_info_s sock_info; struct sockaddr_un serv_addr; - int port = MS_DB_UPDATE_PORT; - - if(msg_type == MS_MSG_DB_UPDATE) - port = MS_DB_UPDATE_PORT; - else - port = MS_SCANNER_PORT; + int retry_count = 0; + sock_info.port = MS_DB_UPDATE_PORT; if(!MS_STRING_VALID(request_msg)) { @@ -387,60 +206,94 @@ static int __media_db_request_update(ms_msg_type_e msg_type, const char *request send_msg.uid = uid; /*Create Socket*/ - ret = ms_ipc_create_client_socket(MS_PROTOCOL_UDP, MS_TIMEOUT_SEC_10, &sockfd, port); + ret = ms_ipc_create_client_socket(MS_PROTOCOL_TCP, MS_TIMEOUT_SEC_10, &sock_info); + sockfd = sock_info.sock_fd; MSAPI_RETV_IF(ret != MS_MEDIA_ERR_NONE, ret); - ret = ms_ipc_send_msg_to_server(sockfd, port, &send_msg, &serv_addr); - if (ret != MS_MEDIA_ERR_NONE) { - MSAPI_DBG_ERR("ms_ipc_send_msg_to_server failed : %d", ret); + /*Set server Address*/ + memset(&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sun_family = AF_UNIX; +// MSAPI_DBG_SLOG("%s", MEDIA_IPC_PATH[port]); + strncpy(serv_addr.sun_path, MEDIA_IPC_PATH[sock_info.port], strlen(MEDIA_IPC_PATH[sock_info.port])); + + /* Connecting to the media db server */ + if (connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) { + MSAPI_DBG_STRERROR("connect error"); close(sockfd); return MS_MEDIA_ERR_SOCKET_CONN; } + /* Send request */ + if (send(sockfd, &send_msg, sizeof(send_msg), 0) != sizeof(send_msg)) { + MSAPI_DBG_STRERROR("send failed"); + close(sockfd); + return MS_MEDIA_ERR_SOCKET_SEND; + } /*Receive Response*/ - ms_comm_msg_s recv_msg; - memset(&recv_msg, 0x0, sizeof(ms_comm_msg_s)); + int recv_msg_size = -1; + int recv_msg = -1; +RETRY: + if ((recv_msg_size = recv(sockfd, &recv_msg, sizeof(recv_msg), 0)) < 0) { + MSAPI_DBG_ERR("recv failed : [%d]", sockfd); - /* connected socket*/ - err = ms_ipc_wait_message(sockfd, &recv_msg, sizeof(recv_msg), &serv_addr, NULL); - if (err != MS_MEDIA_ERR_NONE) { - ret = err; - } else { - MSAPI_DBG("RECEIVE OK [%d]", recv_msg.result); - ret = recv_msg.result; + if (errno == EINTR) { + MSAPI_DBG_STRERROR("catch interrupt"); + goto RETRY; + } + + if (errno == EWOULDBLOCK) { + if(retry_count < MAX_RETRY_COUNT) { + MSAPI_DBG_ERR("TIME OUT[%d]", retry_count); + retry_count ++; + goto RETRY; + } + + close(sockfd); + MSAPI_DBG_ERR("Timeout. Can't try any more"); + return MS_MEDIA_ERR_SOCKET_RECEIVE_TIMEOUT; + } else { + MSAPI_DBG_STRERROR("recv failed"); + + close(sockfd); + + return MS_MEDIA_ERR_SOCKET_RECEIVE; + } } + MSAPI_DBG("RECEIVE OK [%d]", recv_msg); + ret = recv_msg; + close(sockfd); return ret; } -static int g_tcp_client_sock = -1; +static __thread int g_tcp_client_sock = -1; static int __media_db_get_client_tcp_sock() { return g_tcp_client_sock; } -extern char MEDIA_IPC_PATH[][70]; - static int __media_db_prepare_tcp_client_socket() { int ret = MS_MEDIA_ERR_NONE; int sockfd = -1; + ms_sock_info_s sock_info; struct sockaddr_un serv_addr; - int port = MS_DB_BATCH_UPDATE_PORT; + sock_info.port = MS_DB_BATCH_UPDATE_PORT; /*Create TCP Socket*/ - ret = ms_ipc_create_client_socket(MS_PROTOCOL_TCP, MS_TIMEOUT_SEC_10, &sockfd, 0); + ret = ms_ipc_create_client_socket(MS_PROTOCOL_TCP, MS_TIMEOUT_SEC_10, &sock_info); + sockfd = sock_info.sock_fd; MSAPI_RETV_IF(ret != MS_MEDIA_ERR_NONE, ret); /*Set server Address*/ memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sun_family = AF_UNIX; - MSAPI_DBG("%s", MEDIA_IPC_PATH[port]); - strcpy(serv_addr.sun_path, MEDIA_IPC_PATH[port]); +// MSAPI_DBG_SLOG("%s", MEDIA_IPC_PATH[port]); + strncpy(serv_addr.sun_path, MEDIA_IPC_PATH[sock_info.port], strlen(MEDIA_IPC_PATH[sock_info.port])); /* Connecting to the media db server */ if (connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) { @@ -508,7 +361,6 @@ static int __media_db_request_batch_update(ms_msg_type_e msg_type, const char *r /* Send request */ if (send(sockfd, &send_msg, sizeof(send_msg), 0) != sizeof(send_msg)) { MSAPI_DBG_STRERROR("send failed"); - __media_db_close_tcp_client_socket(); return MS_MEDIA_ERR_SOCKET_SEND; } @@ -517,7 +369,6 @@ static int __media_db_request_batch_update(ms_msg_type_e msg_type, const char *r int recv_msg = -1; if ((recv_msg_size = recv(sockfd, &recv_msg, sizeof(recv_msg), 0)) < 0) { MSAPI_DBG_ERR("recv failed : [%d]", sockfd); - __media_db_close_tcp_client_socket(); if (errno == EWOULDBLOCK) { MSAPI_DBG_ERR("Timeout. Can't try any more"); return MS_MEDIA_ERR_SOCKET_RECEIVE_TIMEOUT; @@ -537,6 +388,34 @@ static int __media_db_request_batch_update(ms_msg_type_e msg_type, const char *r return ret; } +static int _media_db_update_directly(sqlite3 *db_handle, const char *sql_str) +{ + int ret = MS_MEDIA_ERR_NONE; + char *zErrMsg = NULL; + +// MSAPI_DBG_SLOG("SQL = [%s]", sql_str); + + ret = sqlite3_exec(db_handle, sql_str, NULL, NULL, &zErrMsg); + + if (SQLITE_OK != ret) { + MSAPI_DBG_ERR("DB Update Fail SQL:%s", sql_str); + MSAPI_DBG_ERR("ERROR [%s]", zErrMsg); + if (ret == SQLITE_BUSY) + ret = MS_MEDIA_ERR_DB_BUSY_FAIL; + else if (ret == SQLITE_CONSTRAINT) + ret = MS_MEDIA_ERR_DB_CONSTRAINT_FAIL; + else if (ret == SQLITE_FULL) + ret = MS_MEDIA_ERR_DB_FULL_FAIL; + else + ret = MS_MEDIA_ERR_DB_UPDATE_FAIL; + } + + if (zErrMsg) + sqlite3_free (zErrMsg); + + return ret; +} + int media_db_connect(MediaDBHandle **handle, uid_t uid) { int ret = MS_MEDIA_ERR_NONE; @@ -570,7 +449,10 @@ int media_db_request_update_db(const char *query_str, uid_t uid) MSAPI_RETVM_IF(!MS_STRING_VALID(query_str), MS_MEDIA_ERR_INVALID_PARAMETER, "Invalid Query"); - ret = __media_db_request_update(MS_MSG_DB_UPDATE, query_str ,uid); + ret = __media_db_request_update_tcp(MS_MSG_DB_UPDATE, query_str ,uid); + if (ret != MS_MEDIA_ERR_NONE) { + MSAPI_DBG_ERR("__media_db_request_update_tcp failed : %d", ret); + } return ret; } @@ -591,6 +473,9 @@ int media_db_request_update_db_batch_start(const char *query_str, uid_t uid) } ret = __media_db_request_batch_update(MS_MSG_DB_UPDATE_BATCH_START, query_str, uid); + if (ret != MS_MEDIA_ERR_NONE) { + __media_db_close_tcp_client_socket(); + } return ret; } @@ -604,6 +489,9 @@ int media_db_request_update_db_batch(const char *query_str, uid_t uid) MSAPI_RETVM_IF(!MS_STRING_VALID(query_str), MS_MEDIA_ERR_INVALID_PARAMETER, "Invalid Query"); ret = __media_db_request_batch_update(MS_MSG_DB_UPDATE_BATCH, query_str, uid); + if (ret != MS_MEDIA_ERR_NONE) { + __media_db_close_tcp_client_socket(); + } return ret; } @@ -627,17 +515,6 @@ int media_db_request_update_db_batch_end(const char *query_str, uid_t uid) return ret; } -int media_db_request_directory_scan(const char *directory_path, uid_t uid) -{ - int ret = MS_MEDIA_ERR_NONE; - - MSAPI_RETVM_IF(!MS_STRING_VALID(directory_path), MS_MEDIA_ERR_INVALID_PARAMETER, "Directory Path is NULL"); - - ret = __media_db_request_update(MS_MSG_DIRECTORY_SCANNING, directory_path, uid); - - return ret; -} - int media_db_update_db(MediaDBHandle *handle, const char *query_str) { sqlite3 * db_handle = (sqlite3 *)handle; @@ -646,7 +523,7 @@ int media_db_update_db(MediaDBHandle *handle, const char *query_str) MSAPI_RETVM_IF(db_handle == NULL, MS_MEDIA_ERR_INVALID_PARAMETER, "Handle is NULL"); MSAPI_RETVM_IF(!MS_STRING_VALID(query_str), MS_MEDIA_ERR_INVALID_PARAMETER, "Invalid Query"); - ret = __media_db_update_directly(db_handle, query_str); + ret = _media_db_update_directly(db_handle, query_str); return ret; } @@ -714,7 +591,7 @@ int media_db_update_db_batch_end(MediaDBHandle *handle, const char *query_str) char *current_sql = NULL; for (i = 0; i < g_list_idx; i++) { current_sql = sql_list[i]; - ret = __media_db_update_directly(db_handle, current_sql); + ret = _media_db_update_directly(db_handle, current_sql); if (ret < 0) { if (i == 0) { /* This is fail of "BEGIN" */ @@ -734,3 +611,12 @@ int media_db_update_db_batch_end(MediaDBHandle *handle, const char *query_str) return ret; } + +int media_db_request_update_db_batch_clear(void) +{ + int ret = MS_MEDIA_ERR_NONE; + + __media_db_destroy_sql_list(); + + return ret; +} diff --git a/lib/media-util-ipc.c b/lib/media-util-ipc.c index 90d96fd..ce233b6 100755 --- a/lib/media-util-ipc.c +++ b/lib/media-util-ipc.c @@ -19,15 +19,6 @@ * */ -/** - * This file defines api utilities of IPC. - * - * @file media-util-ipc.c - * @author Haejeong Kim(backto.kim@samsung.com) - * @version 1.0 - * @brief - */ - #include #include #include @@ -47,7 +38,6 @@ char MEDIA_IPC_PATH[][70] ={ {"/var/run/media-server/media_ipc_dbbatchupdate.socket"}, {"/var/run/media-server/media_ipc_scandaemon.socket"}, - {"/var/run/media-server/media_ipc_scancomm.socket"}, {"/var/run/media-server/media_ipc_scanner.socket"}, {"/var/run/media-server/media_ipc_dbupdate.socket"}, {"/var/run/media-server/media_ipc_thumbcreator.socket"}, @@ -58,7 +48,6 @@ char MEDIA_IPC_PATH[][70] ={ char MEDIA_IPC_PATH_CLIENT[][80] ={ {"/var/run/user/%i/media-server/media_ipc_dbbatchupdate_client%i.socket"}, {"/var/run/user/%i/media-server/media_ipc_scandaemon_client%i.socket"}, - {"/var/run/user/%i/media-server/media_ipc_scancomm_client%i.socket"}, {"/var/run/user/%i/media-server/media_ipc_scanner_client%i.socket"}, {"/var/run/user/%i/media-server/media_ipc_dbupdate_client%i.socket"}, {"/var/run/user/%i/media-server/media_ipc_thumbcreator_client%i.socket"}, @@ -69,7 +58,6 @@ char MEDIA_IPC_PATH_CLIENT[][80] ={ char MEDIA_IPC_PATH_CLIENT_ROOT[][80] ={ {"/var/run/media-server/media_ipc_dbbatchupdate_client%i.socket"}, {"/var/run/media-server/media_ipc_scandaemon_client%i.socket"}, - {"/var/run/media-server/media_ipc_scancomm_client%i.socket"}, {"/var/run/media-server/media_ipc_scanner_client%i.socket"}, {"/var/run/media-server/media_ipc_dbupdate_client%i.socket"}, {"/var/run/media-server/media_ipc_thumbcreator_client%i.socket"}, @@ -95,34 +83,32 @@ static int _mkdir(const char *dir, mode_t mode) { return mkdir(tmp, mode); } -int ms_ipc_create_client_socket(ms_protocol_e protocol, int timeout_sec, int *sock_fd, int port) +int ms_ipc_create_client_socket(ms_protocol_e protocol, int timeout_sec, ms_sock_info_s* sock_info) { int sock = -1; + struct sockaddr_un serv_addr; struct timeval tv_timeout = { timeout_sec, 0 }; - char *buffer; - char *path; - int cx,len; - - if (tzplatform_getuid(TZ_USER_NAME) == 0 ){ - cx = snprintf ( NULL, 0, MEDIA_IPC_PATH_CLIENT_ROOT[port],getpid()); - buffer = (char*)malloc((cx + 1 )*sizeof(char)); - snprintf ( buffer, cx + 1, MEDIA_IPC_PATH_CLIENT_ROOT[port],getpid()); - } else { - len = snprintf ( NULL, 0, "/var/run/user/%i/media-server", tzplatform_getuid(TZ_USER_NAME)); - path = (char*)malloc((len + 1 )*sizeof(char)); - snprintf ( path, len + 1, "/var/run/user/%i/media-server", tzplatform_getuid(TZ_USER_NAME)); - _mkdir(path, 0777); - free(path); - cx = snprintf ( NULL, 0, MEDIA_IPC_PATH_CLIENT[port], tzplatform_getuid(TZ_USER_NAME),getpid()); - buffer = (char*)malloc((cx + 1 )*sizeof(char)); - snprintf ( buffer, cx + 1, MEDIA_IPC_PATH_CLIENT[port],tzplatform_getuid(TZ_USER_NAME),getpid()); - } - if(protocol == MS_PROTOCOL_UDP) { - struct sockaddr_un serv_addr; + char *path; + int cx,len; + + if (tzplatform_getuid(TZ_USER_NAME) == 0 ){ + cx = snprintf ( NULL, 0, MEDIA_IPC_PATH_CLIENT_ROOT[sock_info->port],getpid()); + sock_info->sock_path = (char*)malloc((cx + 1 )*sizeof(char)); + snprintf ( sock_info->sock_path, cx + 1, MEDIA_IPC_PATH_CLIENT_ROOT[sock_info->port],getpid()); + } else { + len = snprintf ( NULL, 0, "/var/run/user/%i/media-server", tzplatform_getuid(TZ_USER_NAME)); + path = (char*)malloc((len + 1 )*sizeof(char)); + snprintf ( path, len + 1, "/var/run/user/%i/media-server", tzplatform_getuid(TZ_USER_NAME)); + _mkdir(path, 0777); + free(path); + cx = snprintf ( NULL, 0, MEDIA_IPC_PATH_CLIENT[sock_info->port], tzplatform_getuid(TZ_USER_NAME),getpid()); + sock_info->sock_path = (char*)malloc((cx + 1 )*sizeof(char)); + snprintf ( sock_info->sock_path, cx + 1, MEDIA_IPC_PATH_CLIENT[sock_info->port],tzplatform_getuid(TZ_USER_NAME),getpid()); + } /* Create a datagram/UDP socket */ if ((sock = socket(PF_FILE, SOCK_DGRAM, 0)) < 0) { @@ -132,15 +118,15 @@ int ms_ipc_create_client_socket(ms_protocol_e protocol, int timeout_sec, int *so memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sun_family = AF_UNIX; - MSAPI_DBG("%s", buffer); - unlink(buffer); - strcpy(serv_addr.sun_path, buffer); + MSAPI_DBG("%s", sock_info->sock_path); + unlink(sock_info->sock_path); + strcpy(serv_addr.sun_path, sock_info->sock_path); /* Bind to the local address */ if (bind(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { MSAPI_DBG_STRERROR("bind failed"); close(sock); - free(buffer); + free(sock_info->sock_path); return MS_MEDIA_ERR_SOCKET_CONN; } } @@ -149,7 +135,6 @@ int ms_ipc_create_client_socket(ms_protocol_e protocol, int timeout_sec, int *so /*Create TCP Socket*/ if ((sock = socket(PF_FILE, SOCK_STREAM, 0)) < 0) { MSAPI_DBG_STRERROR("socket failed"); - free(buffer); return MS_MEDIA_ERR_SOCKET_CONN; } } @@ -158,27 +143,38 @@ int ms_ipc_create_client_socket(ms_protocol_e protocol, int timeout_sec, int *so if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv_timeout, sizeof(tv_timeout)) == -1) { MSAPI_DBG_STRERROR("setsockopt failed"); close(sock); - free(buffer); - return MS_MEDIA_ERR_SOCKET_CONN; } } - *sock_fd = sock; - free(buffer); + sock_info->sock_fd = sock; return MS_MEDIA_ERR_NONE; } +int ms_ipc_delete_client_socket(ms_sock_info_s* sock_info) +{ + int err = 0; + + close(sock_info->sock_fd); + MSAPI_DBG("sockfd %d close", sock_info->sock_fd); + if (sock_info->sock_path != NULL) { + err = unlink(sock_info->sock_path); + if (err< 0) { + MSAPI_DBG_STRERROR("unlink failed"); + } + free(sock_info->sock_path); + } + + return 0; +} -int ms_ipc_create_server_socket(ms_protocol_e protocol, int port, int *sock_fd) +int ms_ipc_create_server_socket(ms_protocol_e protocol, ms_msg_port_type_e port, int *sock_fd) { int i; bool bind_success = false; int sock = -1; - int n_reuse = 1; struct sockaddr_un serv_addr; - mode_t orig_mode; unsigned short serv_port; serv_port = port; @@ -205,8 +201,7 @@ int ms_ipc_create_server_socket(ms_protocol_e protocol, int port, int *sock_fd) serv_addr.sun_family = AF_UNIX; // MSAPI_DBG_SLOG("%s", MEDIA_IPC_PATH[serv_port]); unlink(MEDIA_IPC_PATH[serv_port]); - strcpy(serv_addr.sun_path, MEDIA_IPC_PATH[serv_port]); - orig_mode = umask(0); + strncpy(serv_addr.sun_path, MEDIA_IPC_PATH[serv_port], strlen(MEDIA_IPC_PATH[serv_port])); /* Bind to the local address */ for (i = 0; i < 20; i ++) { @@ -218,8 +213,6 @@ int ms_ipc_create_server_socket(ms_protocol_e protocol, int port, int *sock_fd) usleep(250000); } - umask(orig_mode); - if (bind_success == false) { MSAPI_DBG_STRERROR("bind failed"); close(sock); @@ -239,12 +232,16 @@ int ms_ipc_create_server_socket(ms_protocol_e protocol, int port, int *sock_fd) MSAPI_DBG("Listening..."); } + /*change permission of sock file*/ + if (chmod(MEDIA_IPC_PATH[serv_port], 0777) < 0) + MSAPI_DBG_STRERROR("chmod failed"); + *sock_fd = sock; return MS_MEDIA_ERR_NONE; } -int ms_ipc_send_msg_to_server(int sockfd, int port, ms_comm_msg_s *send_msg, struct sockaddr_un *serv_addr) +int ms_ipc_send_msg_to_server(int sockfd, ms_msg_port_type_e port, ms_comm_msg_s *send_msg, struct sockaddr_un *serv_addr) { int res = MS_MEDIA_ERR_NONE; struct sockaddr_un addr; @@ -252,8 +249,8 @@ int ms_ipc_send_msg_to_server(int sockfd, int port, ms_comm_msg_s *send_msg, str /* Set server Address */ memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; - strcpy(addr.sun_path, MEDIA_IPC_PATH[port]); - MSAPI_DBG("%s", addr.sun_path); + strncpy(addr.sun_path, MEDIA_IPC_PATH[port], strlen(MEDIA_IPC_PATH[port])); +// MSAPI_DBG_SLOG("%s", addr.sun_path); if (sendto(sockfd, send_msg, sizeof(*(send_msg)), 0, (struct sockaddr *)&addr, sizeof(addr)) != sizeof(*(send_msg))) { MSAPI_DBG_STRERROR("sendto failed"); @@ -268,6 +265,38 @@ int ms_ipc_send_msg_to_server(int sockfd, int port, ms_comm_msg_s *send_msg, str return res; } +int ms_ipc_send_msg_to_server_tcp(int sockfd, ms_msg_port_type_e port, ms_comm_msg_s *send_msg, struct sockaddr_un *serv_addr) +{ + int res = MS_MEDIA_ERR_NONE; + struct sockaddr_un addr; + + /* Set server Address */ + memset(&addr, 0, sizeof(addr)); + + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, MEDIA_IPC_PATH[port], strlen(MEDIA_IPC_PATH[port])); +// MSAPI_DBG("%s", addr.sun_path); + + /* Connecting to the media db server */ + if (connect(sockfd, (struct sockaddr*)&addr, sizeof(addr)) < 0) { + MSAPI_DBG_STRERROR("connect error"); + close(sockfd); + return MS_MEDIA_ERR_SOCKET_CONN; + } + + if (write(sockfd, send_msg, sizeof(*(send_msg))) != sizeof(*(send_msg))) { + MSAPI_DBG_STRERROR("write failed"); + res = MS_MEDIA_ERR_SOCKET_SEND; + } else { + MSAPI_DBG("sent result [%d]", send_msg->result); + MSAPI_DBG_SLOG("result message [%s]", send_msg->msg); + if (serv_addr != NULL) + *serv_addr = addr; + } + + return res; +} + int ms_ipc_send_msg_to_client(int sockfd, ms_comm_msg_s *send_msg, struct sockaddr_un *client_addr) { int res = MS_MEDIA_ERR_NONE; @@ -283,6 +312,21 @@ int ms_ipc_send_msg_to_client(int sockfd, ms_comm_msg_s *send_msg, struct sockad return res; } +int ms_ipc_send_msg_to_client_tcp(int sockfd, ms_comm_msg_s *send_msg, struct sockaddr_un *client_addr) +{ + int res = MS_MEDIA_ERR_NONE; + + if (write(sockfd, send_msg, sizeof(*(send_msg))) != sizeof(*(send_msg))) { + MSAPI_DBG_STRERROR("sendto failed"); + res = MS_MEDIA_ERR_SOCKET_SEND; + } else { + MSAPI_DBG("sent result [%d]", send_msg->result); + MSAPI_DBG_SLOG("result message [%s]", send_msg->msg); + } + + return res; +} + int ms_ipc_receive_message(int sockfd, void *recv_msg, unsigned int msg_size, struct sockaddr_un *recv_addr, unsigned int *addr_size) { int recv_msg_size; @@ -349,6 +393,11 @@ int ms_ipc_wait_block_message(int sockfd, void *recv_msg, unsigned int msg_size, addr_len = sizeof(struct sockaddr_un); block_size = MS_SOCK_UDP_BLOCK_SIZE; block_buf = malloc(block_size * sizeof(unsigned char)); + if(block_buf == NULL) { + MSAPI_DBG_ERR("malloc failed."); + return MS_MEDIA_ERR_OUT_OF_MEMORY; + } + memset(block_buf, 0, block_size * sizeof(unsigned char)); while(remain_size > 0) { if(remain_size < MS_SOCK_UDP_BLOCK_SIZE) { @@ -358,9 +407,11 @@ int ms_ipc_wait_block_message(int sockfd, void *recv_msg, unsigned int msg_size, MSAPI_DBG_ERR("recvfrom failed [%s]", strerror(errno)); if (errno == EWOULDBLOCK) { MSAPI_DBG_ERR("recvfrom Timeout."); + MS_SAFE_FREE(block_buf); return MS_MEDIA_ERR_SOCKET_RECEIVE_TIMEOUT; } else { MSAPI_DBG_ERR("recvfrom error [%s]", strerror(errno)); + MS_SAFE_FREE(block_buf); return MS_MEDIA_ERR_SOCKET_RECEIVE; } } @@ -375,4 +426,50 @@ int ms_ipc_wait_block_message(int sockfd, void *recv_msg, unsigned int msg_size, MS_SAFE_FREE(block_buf); return MS_MEDIA_ERR_NONE; -} \ No newline at end of file +} + +int ms_ipc_accept_client_tcp(int serv_sock, int* client_sock) +{ + int sockfd = -1; + struct sockaddr_un client_addr; + socklen_t client_addr_len; + + if (client_sock == NULL) + return MS_MEDIA_ERR_INVALID_PARAMETER; + + client_addr_len = sizeof(client_addr); + if ((sockfd = accept(serv_sock, (struct sockaddr*)&client_addr, &client_addr_len)) < 0) { + MSAPI_DBG_STRERROR("accept failed"); + *client_sock = -1; + return MS_MEDIA_ERR_SOCKET_ACCEPT; + } + + *client_sock = sockfd; + + return MS_MEDIA_ERR_NONE; +} + +int ms_ipc_receive_message_tcp(int client_sock, ms_comm_msg_s *recv_msg) +{ + int recv_msg_size = 0; + + if ((recv_msg_size = read(client_sock, recv_msg, sizeof(ms_comm_msg_s))) < 0) { + if (errno == EWOULDBLOCK) { + MSAPI_DBG_ERR("Timeout. Can't try any more"); + return MS_MEDIA_ERR_SOCKET_RECEIVE_TIMEOUT; + } else { + MSAPI_DBG_STRERROR("recv failed"); + return MS_MEDIA_ERR_SOCKET_RECEIVE; + } + } + + MSAPI_DBG_SLOG("receive msg from [%d] %d, %s", recv_msg->pid, recv_msg->msg_type, recv_msg->msg); + + if (!(recv_msg->msg_size > 0 && recv_msg->msg_size < MAX_FILEPATH_LEN)) { + MSAPI_DBG_ERR("IPC message is wrong. message size is %d", recv_msg->msg_size); + return MS_MEDIA_ERR_INVALID_IPC_MESSAGE; + } + + return MS_MEDIA_ERR_NONE; +} + diff --git a/lib/media-util-noti.c b/lib/media-util-noti.c index 6475d20..6011333 100755 --- a/lib/media-util-noti.c +++ b/lib/media-util-noti.c @@ -19,148 +19,110 @@ * */ -/** - * This file defines api utilities of contents manager engines. - * - * @file media-util-noti.c - * @author Yong Yeon Kim(yy9875.kim@samsung.com) - * @version 1.0 - * @brief - */ - #include #include #include #include #include -#include -#include -#include +#include +#include #include "media-util-internal.h" #include "media-util-dbg.h" #include "media-util.h" +#include "media-util-noti.h" -DBusConnection *g_bus; -void *g_data_store; -GMutex *noti_mutex = NULL; -int ref_count; +static GDBusConnection *g_bus = NULL; +static guint g_handler = 0; +static void *g_data_store = NULL; +static GMutex noti_mutex; +static int ref_count = 0; + +#define MS_MEDIA_DBUS_NAME "ms_db_updated" typedef struct noti_callback_data{ db_update_cb user_callback; void *user_data; } noti_callback_data; -static void -__free_data_fuction(void *memory) +static bool __gdbus_message_is_signal(const char *iface, const char *signal) +{ + if ((strcmp(iface, MS_MEDIA_DBUS_INTERFACE) == 0) && (strcmp(signal, MS_MEDIA_DBUS_NAME) == 0)) + return TRUE; + + return FALSE; +} + +static void __get_message(GVariant *message, db_update_cb user_cb, void *userdata) { - MS_SAFE_FREE(memory); - g_data_store = NULL; + gint32 item = -1; + gint32 pid = 0; + gint32 update_type = MS_MEDIA_UNKNOWN; + gint32 content_type = -1; + char *update_path = NULL; + char *uuid = NULL; + char *mime_type = NULL; + + int item_number = g_variant_n_children(message); + + if (item_number == 7) + g_variant_get(message, "(iiissis)", &item, &pid, &update_type, &update_path, &uuid, &content_type, &mime_type); + else if (item_number == 5) + g_variant_get(message, "(iiiss)", &item, &pid, &update_type, &update_path, &uuid); + else if (item_number == 4) + g_variant_get(message, "(iiis)", &item, &pid, &update_type, &update_path); + + if (item == MS_MEDIA_ITEM_DIRECTORY) + content_type = MS_MEDIA_UNKNOWN; + + /* getting data complete */ + user_cb(pid, + item, + update_type, + update_path, + uuid, + content_type, + mime_type, + userdata); + + MS_SAFE_FREE(update_path); + MS_SAFE_FREE(uuid); + MS_SAFE_FREE(mime_type); } -static DBusHandlerResult -__message_filter (DBusConnection *connection, DBusMessage *message, void *user_data) +static void __message_filter(GDBusConnection* connection, + const gchar* sender_name, + const gchar* object_path, + const gchar* interface_name, + const gchar* signal_name, + GVariant* parameters, + gpointer user_data) { - db_update_cb user_cb = ((noti_callback_data*)user_data)->user_callback; - void *userdata = ((noti_callback_data*)user_data)->user_data; - - /* A Ping signal on the com.burtonini.dbus.Signal interface */ - if (dbus_message_is_signal (message, MS_MEDIA_DBUS_INTERFACE, MS_MEDIA_DBUS_NAME)) { - int i = 0; - int current_type = DBUS_TYPE_INVALID; - DBusError error; - DBusMessageIter read_iter; - DBusBasicValue value[6]; - - dbus_int32_t item = -1; - dbus_int32_t pid = 0; - dbus_int32_t update_type = MS_MEDIA_UNKNOWN; - dbus_int32_t content_type = -1; - char *update_path = NULL; - char *uuid = NULL; - char *mime_type = NULL; - void *recevie_path = NULL; - int path_len = 0; - - dbus_error_init (&error); - MSAPI_DBG("size [%d]", sizeof(value)); - memset(value, 0x0, sizeof(value)); - - /* get data from dbus message */ - dbus_message_iter_init (message, &read_iter); - while ((current_type = dbus_message_iter_get_arg_type (&read_iter)) != DBUS_TYPE_INVALID){ - if (current_type == DBUS_TYPE_ARRAY) { - DBusMessageIter sub; - dbus_message_iter_recurse(&read_iter, &sub); - dbus_message_iter_get_fixed_array(&sub, &recevie_path, &path_len); - } else { - dbus_message_iter_get_basic (&read_iter, &value[i]); - i ++; - } - dbus_message_iter_next (&read_iter); - } + if (__gdbus_message_is_signal(interface_name, signal_name)) { + db_update_cb user_cb = ((noti_callback_data*)user_data)->user_callback; + void *userdata = ((noti_callback_data*)user_data)->user_data; - item = value[0].i32; - pid = value[1].i32; - update_type = value[2].i32; - update_path = strndup(recevie_path, path_len); - if (value[3].str != NULL) uuid = strdup(value[3].str); - content_type = value[4].i32; - if (value[5].str != NULL) mime_type = strdup(value[5].str); - - if (item == MS_MEDIA_ITEM_DIRECTORY) - content_type = MS_MEDIA_UNKNOWN; - - /* getting data complete */ - user_cb(pid, - item, - update_type, - update_path, - uuid, - content_type, - mime_type, - userdata); - - MS_SAFE_FREE(update_path); - MS_SAFE_FREE(uuid); - MS_SAFE_FREE(mime_type); - - return DBUS_HANDLER_RESULT_HANDLED; + __get_message(parameters, user_cb, userdata); } - - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } int media_db_update_subscribe(db_update_cb user_cb, void *user_data) { int ret = MS_MEDIA_ERR_NONE; - DBusError error; + GError *error = NULL; noti_callback_data *callback_data = NULL; - if (noti_mutex == NULL) { - noti_mutex = g_mutex_new(); - if (noti_mutex == NULL) { - return MS_MEDIA_ERR_OUT_OF_MEMORY; - } - } - - g_mutex_lock(noti_mutex); + g_mutex_lock(¬i_mutex); if (g_bus == NULL) { - dbus_g_thread_init(); - - dbus_error_init (&error); - - g_bus = dbus_bus_get (DBUS_BUS_SYSTEM, &error); + g_bus = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); if (!g_bus) { - MSAPI_DBG ("Failed to connect to the D-BUS daemon: %s", error.message); - dbus_error_free (&error); + MSAPI_DBG ("Failed to connect to the g D-BUS daemon: %s", error->message); + g_error_free (error); ret = MS_MEDIA_ERR_INTERNAL; goto ERROR; } - dbus_connection_setup_with_g_main (g_bus, NULL); - MS_MALLOC(callback_data, sizeof(noti_callback_data)); if (callback_data == NULL) { MSAPI_DBG_ERR("MS_MALLOC failed"); @@ -171,32 +133,35 @@ int media_db_update_subscribe(db_update_cb user_cb, void *user_data) callback_data->user_data = user_data; /* listening to messages from all objects as no path is specified */ - dbus_bus_add_match (g_bus, MS_MEDIA_DBUS_MATCH_RULE, &error); - if( !dbus_connection_add_filter (g_bus, __message_filter, callback_data, __free_data_fuction)) { - dbus_bus_remove_match (g_bus, MS_MEDIA_DBUS_MATCH_RULE, NULL); - ret = MS_MEDIA_ERR_INTERNAL; - goto ERROR; - } + g_handler = g_dbus_connection_signal_subscribe( + g_bus, + NULL, + MS_MEDIA_DBUS_INTERFACE, + MS_MEDIA_DBUS_NAME, + MS_MEDIA_DBUS_PATH, + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + __message_filter, + callback_data, + NULL); g_data_store = (void *)callback_data; } ref_count ++; - g_mutex_unlock(noti_mutex); + g_mutex_unlock(¬i_mutex); return MS_MEDIA_ERR_NONE; ERROR: if (g_bus != NULL) { - dbus_connection_unref(g_bus); + g_object_unref(g_bus); g_bus = NULL; } MS_SAFE_FREE(callback_data); - g_mutex_unlock(noti_mutex); - g_mutex_free(noti_mutex); - noti_mutex = NULL; + g_mutex_unlock(¬i_mutex); return ret; } @@ -207,24 +172,21 @@ int media_db_update_unsubscribe(void) return MS_MEDIA_ERR_NONE; } - g_mutex_lock(noti_mutex); + g_mutex_lock(¬i_mutex); if (ref_count == 1) { - dbus_connection_remove_filter(g_bus, __message_filter, g_data_store); - dbus_bus_remove_match (g_bus, MS_MEDIA_DBUS_MATCH_RULE, NULL); - dbus_connection_unref(g_bus); - + g_dbus_connection_signal_unsubscribe(g_bus, g_handler); + g_object_unref(g_bus); g_bus = NULL; + + /*Release Callback*/ + MS_SAFE_FREE(g_data_store); + g_data_store = NULL; } ref_count --; - g_mutex_unlock(noti_mutex); - - if (ref_count == 0) { - g_mutex_free(noti_mutex); - noti_mutex = NULL; - } + g_mutex_unlock(¬i_mutex); return MS_MEDIA_ERR_NONE; } @@ -238,80 +200,75 @@ int media_db_update_send(int pid, /* mandatory */ char *mime_type /* optional */ ) { - DBusMessage *message; - DBusConnection *bus; - DBusError error; - unsigned char *path_array = NULL; - int path_length = strlen(path) + 1; - - /* Get a connection to the session bus */ - dbus_error_init (&error); - bus = dbus_bus_get (DBUS_BUS_SYSTEM, &error); + GVariant *message = NULL; + GDBusConnection *bus = NULL; + GError *error = NULL; + + bus = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); if (!bus) { - MSAPI_DBG ("Failed to connect to the D-BUS daemon: %s", error.message); - dbus_error_free (&error); + MSAPI_DBG ("Failed to get gdbus connection: %s", error->message); + g_error_free (error); return MS_MEDIA_ERR_INTERNAL; } - message = dbus_message_new_signal (MS_MEDIA_DBUS_PATH, MS_MEDIA_DBUS_INTERFACE, MS_MEDIA_DBUS_NAME); - if (message != NULL) { - path_array = malloc(sizeof(unsigned char) * path_length); - memcpy(path_array, path, path_length); - - if (item == MS_MEDIA_ITEM_FILE) { - MSAPI_DBG("FILE CHANGED"); - if (uuid != NULL && mime_type != NULL) { - /* fill all datas */ - dbus_message_append_args (message, - DBUS_TYPE_INT32, &item, - DBUS_TYPE_INT32, &pid, - DBUS_TYPE_INT32, &update_type, - DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &path_array, path_length, - DBUS_TYPE_STRING, &uuid, - DBUS_TYPE_INT32, &media_type, - DBUS_TYPE_STRING, &mime_type, - DBUS_TYPE_INVALID); - } else { - MSAPI_DBG_ERR("uuid or mime_type is NULL"); - return MS_MEDIA_ERR_INVALID_PARAMETER; - } - } else if (item == MS_MEDIA_ITEM_DIRECTORY) { - MSAPI_DBG("DIRECTORY CHANGED"); + if (item == MS_MEDIA_ITEM_FILE) { + MSAPI_DBG("FILE CHANGED"); + if (uuid != NULL && mime_type != NULL) { /* fill all datas */ - if(uuid != NULL) { - dbus_message_append_args (message, - DBUS_TYPE_INT32, &item, - DBUS_TYPE_INT32, &pid, - DBUS_TYPE_INT32, &update_type, - DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &path_array, path_length, - DBUS_TYPE_STRING, &uuid, - DBUS_TYPE_INVALID); - } else { - dbus_message_append_args (message, - DBUS_TYPE_INT32, &item, - DBUS_TYPE_INT32, &pid, - DBUS_TYPE_INT32, &update_type, - DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &path_array, path_length, - DBUS_TYPE_INVALID); - } + message = g_variant_new("(iiissis)", item, pid, update_type, path, uuid, media_type, mime_type); } else { - MSAPI_DBG("this request is wrong"); + MSAPI_DBG_ERR("uuid or mime_type is NULL"); + return MS_MEDIA_ERR_INVALID_PARAMETER; + } + } else if (item == MS_MEDIA_ITEM_DIRECTORY) { + MSAPI_DBG("DIRECTORY CHANGED"); + /* fill all datas */ + if(uuid != NULL) { + message = g_variant_new("(iiiss)", item, pid, update_type, path, uuid); + } else { + message = g_variant_new("(iiis)", item, pid, update_type, path); } - - MS_SAFE_FREE(path_array); - - /* Send the signal */ - dbus_connection_send (bus, message, NULL); - - /* Free the signal now we have finished with it */ - dbus_message_unref (message); - - MSAPI_DBG_ERR("success send notification"); } else { - MSAPI_DBG_ERR("dbus_message_new_signal failed"); + MSAPI_DBG("this request is wrong"); } + gboolean emmiting = g_dbus_connection_emit_signal( + bus, + NULL, + MS_MEDIA_DBUS_PATH, + MS_MEDIA_DBUS_INTERFACE, + MS_MEDIA_DBUS_NAME, + message, + &error); + if (!emmiting) + { + MSAPI_DBG_ERR("g_dbus_connection_emit_signal failed : %s", error?error->message:"none"); + if (error) + { + MSAPI_DBG_ERR("Error in g_dbus_connection_emit_signal"); + g_object_unref(bus); + g_error_free(error); + } + return MS_MEDIA_ERR_INTERNAL; + } + MSAPI_DBG("success send notification"); + + gboolean flush = FALSE; + flush = g_dbus_connection_flush_sync(bus, NULL, &error); + if (!flush) + { + MSAPI_DBG_ERR("g_dbus_connection_flush_sync failed"); + if (error) + { + MSAPI_DBG_ERR("error : [%s]", error->message); + g_object_unref(bus); + g_error_free(error); + return MS_MEDIA_ERR_INTERNAL; + } + } + + g_object_unref(bus); + /* Return TRUE to tell the event loop we want to be called again */ return MS_MEDIA_ERR_NONE; } - diff --git a/lib/media-util-register.c b/lib/media-util-register.c index c66e470..361d071 100755 --- a/lib/media-util-register.c +++ b/lib/media-util-register.c @@ -19,14 +19,6 @@ * */ -/** - * This file defines api utilities of contents manager engines. - * - * @file media-util-register.c - * @author Yong Yeon Kim(yy9875.kim@samsung.com) - * @version 1.0 - * @brief - */ #include #include #include @@ -51,8 +43,18 @@ typedef struct media_callback_data{ GSource *source; scan_complete_cb user_callback; void *user_data; + char *sock_path; } media_callback_data; +typedef struct media_scan_data{ + GIOChannel *src; + media_callback_data *cb_data; + int pid; + char *req_path; +} media_scan_data; + +GArray *req_list; + #define GLOBAL_USER 0 //#define tzplatform_getenv(TZ_GLOBAL) //TODO static char* __media_get_path(uid_t uid) @@ -93,17 +95,16 @@ static char* __media_get_path(uid_t uid) static bool _is_valid_path(const char *path, uid_t uid) { - - int lenght_path; + int length_path; char * user_path = NULL; if (path == NULL) return false; user_path = __media_get_path(uid); - lenght_path = strlen(user_path); + length_path = strlen(user_path); - if (strncmp(path, user_path, lenght_path) == 0) { + if (strncmp(path, user_path, length_path) == 0) { return true; } else if (strncmp(path, MEDIA_ROOT_PATH_SDCARD, strlen(MEDIA_ROOT_PATH_SDCARD)) == 0) { return true; @@ -155,8 +156,9 @@ gboolean _read_socket(GIOChannel *src, GIOCondition condition, gpointer data) void *user_data = NULL; ms_comm_msg_s recv_msg; media_request_result_s req_result; - int ret; int sockfd = -1; + char *sock_path = NULL; + int recv_msg_size = 0; sockfd = g_io_channel_unix_get_fd(src); if (sockfd < 0) { @@ -165,25 +167,25 @@ gboolean _read_socket(GIOChannel *src, GIOCondition condition, gpointer data) } memset(&recv_msg, 0x0, sizeof(ms_comm_msg_s)); + memset(&req_result, 0x0, sizeof(media_request_result_s)); - /* Socket is readable */ - struct sockaddr_in recv_add; - - ret = ms_ipc_wait_message(sockfd, &recv_msg, sizeof(recv_msg), &recv_add, NULL); - if (ret != MS_MEDIA_ERR_NONE) { - MSAPI_DBG("ms_ipc_wait_message failed"); - return TRUE; + if ((recv_msg_size = read(sockfd, &recv_msg, sizeof(ms_comm_msg_s))) < 0) { + MSAPI_DBG_STRERROR("recv failed"); + req_result.pid = -1; + req_result.result = MS_MEDIA_ERR_SOCKET_RECEIVE; + req_result.complete_path = NULL; + req_result.request_type = -1; + goto ERROR; } - memset(&req_result, 0x0, sizeof(media_request_result_s)); req_result.pid = recv_msg.pid; req_result.result = recv_msg.result; if (recv_msg.msg_type ==MS_MSG_SCANNER_RESULT) { - req_result.complete_path = strdup(recv_msg.msg); + req_result.complete_path = strndup(recv_msg.msg, MAX_FILEPATH_LEN); req_result.request_type = MEDIA_DIRECTORY_SCAN; MSAPI_DBG("complete_path :%d", req_result.complete_path); } else if (recv_msg.msg_type == MS_MSG_SCANNER_BULK_RESULT) { - req_result.complete_path = strdup(recv_msg.msg); + req_result.complete_path = strndup(recv_msg.msg, MAX_FILEPATH_LEN); req_result.request_type = MEDIA_FILES_REGISTER; } @@ -191,9 +193,11 @@ gboolean _read_socket(GIOChannel *src, GIOCondition condition, gpointer data) MSAPI_DBG("result :%d", req_result.result); MSAPI_DBG("request_type :%d", req_result.request_type); +ERROR: source = ((media_callback_data *)data)->source; user_callback = ((media_callback_data *)data)->user_callback; user_data = ((media_callback_data *)data)->user_data; + sock_path = ((media_callback_data *)data)->sock_path; /*call user define function*/ user_callback(&req_result, user_data); @@ -206,18 +210,128 @@ gboolean _read_socket(GIOChannel *src, GIOCondition condition, gpointer data) g_source_destroy(source); close(sockfd); + if (sock_path != NULL) { + MSAPI_DBG("delete path :%s", sock_path); + unlink(sock_path); + MS_SAFE_FREE(sock_path); + } MS_SAFE_FREE(data); return TRUE; } -static int _attach_callback(int *sockfd, scan_complete_cb user_callback, void *user_data) +static int _add_request(const char * req_path, media_callback_data *cb_data, GIOChannel *channel) +{ + media_scan_data *req_data = NULL; + + if (req_list == NULL) { + req_list = g_array_new(FALSE, FALSE, sizeof(media_scan_data*)); + } + + if (req_list == NULL) { + MSAPI_DBG_ERR("g_array_new falied"); + return MS_MEDIA_ERR_OUT_OF_MEMORY; + } + + req_data = malloc(sizeof(media_scan_data)); + if (req_data == NULL) { + MSAPI_DBG_ERR("malloc falied"); + return MS_MEDIA_ERR_OUT_OF_MEMORY; + } + + req_data->cb_data = cb_data; + req_data->req_path = strdup(req_path); + req_data->src = channel; + + g_array_append_val(req_list, req_data); + + return MS_MEDIA_ERR_NONE; + +} + +static int _remove_request(const char * req_path) +{ + media_scan_data *req_data = NULL; + media_callback_data *cb_data = NULL; + char *sock_path = NULL; + int i = 0; + int list_len = 0; + bool flag = false; + scan_complete_cb user_callback; + void *user_data = NULL; + GSource *source = NULL; + GIOChannel *src = NULL; + media_request_result_s req_result; + + if (req_list == NULL) { + MSAPI_DBG_ERR("The request list is NULL. This is invalid operation."); + return MS_MEDIA_ERR_INVALID_PARAMETER; + } + + list_len = req_list->len; + + for (i = 0; i < list_len; i++) { + req_data = g_array_index(req_list, media_scan_data*, i); + if (strcmp(req_data->req_path, req_path) == 0) { + flag = true; + g_array_remove_index (req_list, i); + } + } + + if (flag == false) { + MSAPI_DBG("Not in scan queue :%s", req_path); + return MS_MEDIA_ERR_INVALID_PARAMETER; + } + + req_result.pid = -1; + req_result.result = MS_MEDIA_ERR_NONE; + req_result.complete_path = strndup(req_path, strlen(req_path)); + req_result.request_type = MEDIA_FILES_REGISTER; + + src = req_data->src; + cb_data = req_data->cb_data; + source = ((media_callback_data *)cb_data)->source; + sock_path = ((media_callback_data *)cb_data)->sock_path; + user_callback = ((media_callback_data *)cb_data)->user_callback; + user_data = ((media_callback_data *)cb_data)->user_data; + + /*call user define function*/ + user_callback(&req_result, user_data); + + + /*close an IO channel*/ + g_io_channel_shutdown(src, FALSE, NULL); + g_io_channel_unref(src); + + g_source_destroy(source); + + if (sock_path != NULL) { + MSAPI_DBG("delete path :%s", sock_path); + unlink(sock_path); + MS_SAFE_FREE(sock_path); + } + + MS_SAFE_FREE(req_data->req_path); + MS_SAFE_FREE(req_data); + + return MS_MEDIA_ERR_NONE; + +} + +static int _attach_callback(const char *req_path, int *sockfd, char* sock_path, scan_complete_cb user_callback, void *user_data) { GIOChannel *channel = NULL; GMainContext *context = NULL; GSource *source = NULL; media_callback_data *cb_data; + cb_data = malloc(sizeof(media_callback_data)); + if (cb_data == NULL) { + MSAPI_DBG_ERR("Malloc failed"); + return MS_MEDIA_ERR_OUT_OF_MEMORY; + } + memset(cb_data, 0, sizeof(media_callback_data)); + /*get the global default main context*/ context = g_main_context_default(); @@ -225,16 +339,18 @@ static int _attach_callback(int *sockfd, scan_complete_cb user_callback, void *u channel = g_io_channel_unix_new(*sockfd); source = g_io_create_watch(channel, G_IO_IN); - cb_data = malloc(sizeof(media_callback_data)); cb_data->source = source; cb_data->user_callback = user_callback; cb_data->user_data = user_data; + cb_data->sock_path = sock_path; /* Set callback to be called when socket is readable */ g_source_set_callback(source, (GSourceFunc)_read_socket, cb_data, NULL); g_source_attach(source, context); g_source_unref(source); + _add_request(req_path, cb_data, channel); + return MS_MEDIA_ERR_NONE; } @@ -245,6 +361,8 @@ static int __media_db_request_update_async(ms_msg_type_e msg_type, const char *r int sockfd = -1; int port = MS_SCANNER_PORT; ms_comm_msg_s send_msg; + char *sock_path = NULL; + ms_sock_info_s sock_info; if(!MS_STRING_VALID(request_msg)) { @@ -255,9 +373,9 @@ static int __media_db_request_update_async(ms_msg_type_e msg_type, const char *r MSAPI_DBG("REQUEST DIRECTORY SCANNING"); request_msg_size = strlen(request_msg); - if(request_msg_size >= MAX_FILEPATH_LEN) + if(request_msg_size >= MAX_MSG_SIZE) { - MSAPI_DBG_ERR("Query is Too long. [%d] query size limit is [%d]", request_msg_size, MAX_FILEPATH_LEN); + MSAPI_DBG_ERR("Query is Too long. [%d] query size limit is [%d]", request_msg_size, MAX_MSG_SIZE); return MS_MEDIA_ERR_INVALID_PARAMETER; } @@ -271,23 +389,76 @@ static int __media_db_request_update_async(ms_msg_type_e msg_type, const char *r strncpy(send_msg.msg, request_msg, request_msg_size); /*Create Socket*/ - ret = ms_ipc_create_client_socket(MS_PROTOCOL_UDP, 0, &sockfd, port); + ret = ms_ipc_create_client_socket(MS_PROTOCOL_TCP, 0, &sock_info); + sockfd = sock_info.sock_fd; + if (sock_info.sock_path != NULL) + sock_path = sock_info.sock_path; + MSAPI_RETV_IF(ret != MS_MEDIA_ERR_NONE, ret); - ret = ms_ipc_send_msg_to_server(sockfd, port, &send_msg, NULL); + ret = ms_ipc_send_msg_to_server_tcp(sockfd, port, &send_msg, NULL); if (ret != MS_MEDIA_ERR_NONE) { MSAPI_DBG_ERR("ms_ipc_send_msg_to_server failed : %d", ret); - close(sockfd); + ms_ipc_delete_client_socket(&sock_info); return ret; } - ret = _attach_callback(&sockfd, user_callback ,user_data); + ret = _attach_callback(request_msg, &sockfd, sock_path, user_callback ,user_data); if(ret != MS_MEDIA_ERR_NONE) return ret; return ret; } +static int __media_db_request_update_cancel(ms_msg_type_e msg_type, const char *request_msg) +{ + int ret = MS_MEDIA_ERR_NONE; + int request_msg_size = 0; + int sockfd = -1; + ms_comm_msg_s send_msg; + ms_sock_info_s sock_info; + sock_info.port = MS_SCANNER_PORT; + + if(!MS_STRING_VALID(request_msg)) + { + MSAPI_DBG_ERR("invalid query"); + return MS_MEDIA_ERR_INVALID_PARAMETER; + } + + MSAPI_DBG("REQUEST CANCEL DIRECTORY SCANNING[%s]", request_msg); + + request_msg_size = strlen(request_msg); + if(request_msg_size >= MAX_MSG_SIZE) + { + MSAPI_DBG_ERR("Query is Too long. [%d] query size limit is [%d]", request_msg_size, MAX_MSG_SIZE); + return MS_MEDIA_ERR_INVALID_PARAMETER; + } + + memset((void *)&send_msg, 0, sizeof(ms_comm_msg_s)); + send_msg.msg_type = msg_type; + send_msg.pid = syscall(__NR_getpid); + send_msg.msg_size = request_msg_size; + strncpy(send_msg.msg, request_msg, request_msg_size); + + /*Create Socket*/ + ret = ms_ipc_create_client_socket(MS_PROTOCOL_TCP, 0, &sock_info); + sockfd = sock_info.sock_fd; + + MSAPI_RETV_IF(ret != MS_MEDIA_ERR_NONE, ret); + + ret = ms_ipc_send_msg_to_server_tcp(sockfd, sock_info.port, &send_msg, NULL); + ms_ipc_delete_client_socket(&sock_info); + if (ret != MS_MEDIA_ERR_NONE) { + MSAPI_DBG_ERR("ms_ipc_send_msg_to_server failed : %d", ret); + return ret; + } + + ret = _remove_request(request_msg); + if(ret != MS_MEDIA_ERR_NONE) + return ret; + + return ret; +} int media_directory_scanning_async(const char *directory_path, bool recursive_on, scan_complete_cb user_callback, void *user_data, uid_t uid) { @@ -305,6 +476,20 @@ int media_directory_scanning_async(const char *directory_path, bool recursive_on return ret; } +int media_directory_scanning_cancel(const char *directory_path, uid_t uid) +{ + int ret = MS_MEDIA_ERR_NONE; + + ret = _check_dir_path(directory_path, uid); + if(ret != MS_MEDIA_ERR_NONE) + return ret; + + ret = __media_db_request_update_cancel(MS_MSG_DIRECTORY_SCANNING_CANCEL, directory_path); + + return ret; +} + + int media_files_register(const char *list_path, insert_complete_cb user_callback, void *user_data, uid_t uid) { int ret = MS_MEDIA_ERR_NONE; diff --git a/packaging/media-server-user.service b/packaging/media-server-user.service index d94903e..4afae3a 100644 --- a/packaging/media-server-user.service +++ b/packaging/media-server-user.service @@ -6,6 +6,7 @@ Type=idle CPUAccounting=true CPUQuota=10% ExecStartPre=/usr/bin/sleep 5 +ExecStart=/usr/bin/sh -c "/usr/bin/mediadb-update check_db" ExecStart=/usr/bin/sh -c "/usr/bin/mediadb-update -r `/usr/bin/tzplatform-get TZ_USER_CONTENT | /usr/bin/sed -e 's/^.*=//g'`" [Install] diff --git a/packaging/media-server.spec b/packaging/media-server.spec index c3eca3a..b3b68c0 100755 --- a/packaging/media-server.spec +++ b/packaging/media-server.spec @@ -1,6 +1,6 @@ Name: media-server -Summary: File manager service server -Version: 0.2.50 +Summary: File manager service server. +Version: 0.2.51 Release: 0 Group: Multimedia/Service License: Apache-2.0 @@ -10,15 +10,12 @@ Source2: media-server-user.service Source1001: %{name}.manifest Source1002: libmedia-utils.manifest Source1003: libmedia-utils-devel.manifest -Source1004: media-data-sdk_create_db.sh Requires(post): /usr/bin/vconftool BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(vconf) BuildRequires: pkgconfig(dlog) -BuildRequires: pkgconfig(drm-client) BuildRequires: pkgconfig(aul) BuildRequires: pkgconfig(pmapi) -BuildRequires: pkgconfig(heynoti) BuildRequires: pkgconfig(dbus-glib-1) BuildRequires: pkgconfig(sqlite3) BuildRequires: pkgconfig(db-util) @@ -78,7 +75,6 @@ install -D -m 0775 ./data-media/dbspace/file-manager-service/.thumb/mmc/* %{buil install -m 0775 ./data-media/dbspace/file-manager-service/.thumb/phone/PHONE_THUMB_HERE %{buildroot}%{TZ_SYS_DATA}/file-manager-service/.thumb/phone/ install -m 0775 ./data-media/dbspace/file-manager-service/.thumb/phone/.jpg* %{buildroot}%{TZ_SYS_DATA}/file-manager-service/.thumb/phone/ install -D -m 0775 ./data-media/dbspace/file-manager-service/* %{buildroot}%{TZ_SYS_DATA}/file-manager-service/ -install -m 0775 %{SOURCE1004} %{buildroot}%{_bindir}/media-data-sdk_create_db.sh %post vconftool set -t int db/filemanager/dbupdate "1" -f @@ -86,7 +82,6 @@ vconftool set -t int memory/filemanager/Mmc "0" -i -f vconftool set -t string db/private/mediaserver/mmc_info "" -f vconftool set -t int file/private/mediaserver/scan_internal "1" -f vconftool set -t int file/private/mediaserver/scan_directory "1" -f -chgrp %TZ_SYS_USER_GROUP %{_bindir}/media-data-sdk_create_db.sh chgrp -R %TZ_SYS_USER_GROUP %{TZ_SYS_DATA}/data-media chgrp -R %TZ_SYS_USER_GROUP %{TZ_SYS_DATA}/file-manager-service @@ -111,7 +106,6 @@ ln -sf ../media-server-user.service %{_unitdir_user}/default.target.wants/ %{_unitdir}/multi-user.target.wants/media-server.service %{_unitdir_user}/media-server-user.service %license LICENSE.APLv2.0 -%{_bindir}/media-data-sdk_create_db.sh %{TZ_SYS_DATA}/data-media/* %{TZ_SYS_DATA}/file-manager-service/.thumb/* %{TZ_SYS_DATA}/file-manager-service/plugin-config diff --git a/src/common/include/media-common-dbg.h b/src/common/include/media-common-dbg.h index af9e42f..9f0336d 100755 --- a/src/common/include/media-common-dbg.h +++ b/src/common/include/media-common-dbg.h @@ -19,17 +19,8 @@ * */ -/** - * This file defines api utilities of contents manager engines. - * - * @file media-server-dbg.h - * @author Yong Yeon Kim(yy9875.kim@samsung.com) - * @version 1.0 - * @brief - */ - -#ifndef _MEDIA_SERVER_DBG_H_ -#define _MEDIA_SERVER_DBG_H_ +#ifndef _MEDIA_COMMON_DBG_H_ +#define _MEDIA_COMMON_DBG_H_ #include #include @@ -43,11 +34,9 @@ #define MS_DBG_STRERROR(fmt) do { \ char buf[BUF_LENGTH] = {0,}; \ - strerror_r(errno, buf, BUF_LENGTH); \ - LOGE(fmt" : STANDARD ERROR [%s]", buf); \ + LOGE(fmt" : STANDARD ERROR [%s]", strerror_r(errno, buf, BUF_LENGTH)); \ } while (0) - #define MS_DBG_SLOG(fmt, args...) SECURE_LOGD(fmt "\n", ##args); #define MS_DBG(fmt, args...) LOGD(fmt "\n", ##args); @@ -64,4 +53,4 @@ LOGE(fmt "\n", ##args); \ }} while(false) -#endif /*_MEDIA_SERVER_DBG_H_*/ +#endif /*_MEDIA_COMMON_DBG_H_*/ diff --git a/src/common/include/media-common-drm.h b/src/common/include/media-common-drm.h deleted file mode 100755 index 1006ab0..0000000 --- a/src/common/include/media-common-drm.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Media Server - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: Yong Yeon Kim - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -/** - * This file defines api utilities of contents manager engines. - * - * @file media-server-drm.h - * @author Yong Yeon Kim(yy9875.kim@samsung.com) - * @version 1.0 - * @brief This file implements main database operation. - */ -#ifndef _MEDIA_SERVER_DRM_H_ -#define _MEDIA_SERVER_DRM_H_ - -bool -ms_is_drm_file(const char *path); - -int -ms_drm_register(const char* path); - -void -ms_drm_unregister(const char* path); - -void -ms_drm_unregister_all(void); - -bool -ms_drm_insert_ext_memory(void); - -bool -ms_drm_extract_ext_memory(void); - -#endif /*_MEDIA_SERVER_DRM_H_*/ \ No newline at end of file diff --git a/src/common/include/media-common-external-storage.h b/src/common/include/media-common-external-storage.h index f381884..500191b 100755 --- a/src/common/include/media-common-external-storage.h +++ b/src/common/include/media-common-external-storage.h @@ -23,25 +23,12 @@ #include "media-common-types.h" -void -ms_init_default_path(void); - -void -ms_make_default_path_mmc(void); - -int -ms_update_mmc_info(void); - -void -ms_mmc_removed_handler(void); - -int -ms_present_mmc_status(ms_sdcard_status_type_t status); - -void -ms_mmc_vconf_cb(void *data); - -ms_dir_scan_type_t -ms_get_mmc_state(void); +void ms_init_default_path(void); +void ms_make_default_path_mmc(void); +int ms_update_mmc_info(void); +void ms_mmc_removed_handler(void); +int ms_present_mmc_status(ms_sdcard_status_type_t status); +void ms_mmc_vconf_cb(void *data); +ms_dir_scan_type_t ms_get_mmc_state(void); #endif /*_MEDIA_SERVER_EXTERNAL_STORAGE_H_*/ diff --git a/src/common/include/media-common-types.h b/src/common/include/media-common-types.h index a46488b..95674ed 100755 --- a/src/common/include/media-common-types.h +++ b/src/common/include/media-common-types.h @@ -19,15 +19,6 @@ * */ -/** - * This file defines api utilities of contents manager engines. - * - * @file media-common-types.h - * @author Yong Yeon Kim(yy9875.kim@samsung.com) - * @version 1.0 - * @brief - */ - #ifndef _MEDIA_SERVER_TYPES_H_ #define _MEDIA_SERVER_TYPES_H_ @@ -57,7 +48,7 @@ #define MS_SAFE_FREE(src) { if(src) {free(src); src = NULL;} } #define MS_MALLOC(src, size) { if (size > SIZE_MAX || size <= 0) {src = NULL;} \ - else { src = malloc(size); memset(src, 0x0, size);} } + else { src = malloc(size); if(src) memset(src, 0x0, size);} } /*System default folder definition*/ #define FAT_FILENAME_LEN_MAX 255 /* not inc null */ @@ -82,6 +73,7 @@ typedef enum { typedef enum { MS_SCAN_INVALID, MS_SCAN_PART, + MS_SCAN_META, MS_SCAN_ALL, } ms_dir_scan_type_t; @@ -110,8 +102,4 @@ typedef struct { int pid; } ms_register_data_t; -/** - * @} - */ - #endif /*_MEDIA_SERVER_TYPES_H_*/ diff --git a/src/common/include/media-common-utils.h b/src/common/include/media-common-utils.h index 3706d9c..8a43be4 100755 --- a/src/common/include/media-common-utils.h +++ b/src/common/include/media-common-utils.h @@ -19,72 +19,31 @@ * */ -/** - * This file defines api utilities of contents manager engines. - * - * @file media-common-utils.h - * @author Yong Yeon Kim(yy9875.kim@samsung.com) - * @version 1.0 - * @brief - */ #ifndef _MEDIA_SERVER_UTILS_H__ #define _MEDIA_SERVER_UTILS_H__ #include "media-common-types.h" -int -ms_db_init(bool need_db_create); - -bool -ms_is_mmc_inserted(void); - -void -ms_usb_vconf_cb(void *data); - -int -ms_start(bool need_db_create); - -void -ms_end(void); - -ms_storage_type_t -ms_get_storage_type_by_full(const char *path, uid_t uid); - -int -ms_strappend(char *res, const int size, const char *pattern, - const char *str1, const char *str2); - -int -ms_strcopy(char *res, const int size, const char *pattern, - const char *str1); - -bool -ms_config_get_int(const char *key, int *value); - -bool -ms_config_set_int(const char *key, int value); - -bool -ms_config_get_str(const char *key, char *value); - -bool -ms_config_set_str(const char *key, const char *value); - +int ms_db_init(bool need_db_create); +bool ms_is_mmc_inserted(void); +void ms_usb_vconf_cb(void *data); +int ms_start(bool need_db_create); +void ms_end(void); +ms_storage_type_t ms_get_storage_type_by_full(const char *path, uid_t uid); +int ms_strappend(char *res, const int size, const char *pattern, const char *str1, const char *str2); +int ms_strcopy(char *res, const int size, const char *pattern, const char *str1); +bool ms_config_get_int(const char *key, int *value); +bool ms_config_set_int(const char *key, int value); +bool ms_config_get_str(const char *key, char *value); +bool ms_config_set_str(const char *key, const char *value); +bool ms_config_get_bool(const char *key, int *value); #ifdef FMS_PERF -void -ms_check_start_time(struct timeval *start_time); - -void -ms_check_end_time(struct timeval *end_time); - -void -ms_check_time_diff(struct timeval *start_time, struct timeval *end_time); +void ms_check_start_time(struct timeval *start_time); +void ms_check_end_time(struct timeval *end_time); +void ms_check_time_diff(struct timeval *start_time, struct timeval *end_time); #endif/*FMS_PERF */ -/** - * @} - */ #endif/*_MEDIA_SERVER_UTILS_H__*/ diff --git a/src/common/media-common-drm.c b/src/common/media-common-drm.c deleted file mode 100755 index 360ea40..0000000 --- a/src/common/media-common-drm.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Media Server - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: Yong Yeon Kim - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -/** - * This file defines api utilities of contents manager engines. - * - * @file media-server-drm.c - * @author Yong Yeon Kim(yy9875.kim@samsung.com) - * @version 1.0 - * @brief This file implements main database operation. - */ -#include -#include - -#include "media-util.h" - -#include "media-common-dbg.h" -#include "media-common-types.h" -#include "media-common-drm.h" - -bool -ms_is_drm_file(const char *path) -{ -#ifdef __SUPPORT_DRM - int ret; - drm_bool_type_e is_drm_file = DRM_UNKNOWN; - - ret = drm_is_drm_file(path,&is_drm_file); - if(DRM_RETURN_SUCCESS == ret && DRM_TRUE == is_drm_file) - return true; -#endif - return false; -} - -int -ms_drm_register(const char* path) -{ - - int res = MS_MEDIA_ERR_NONE; -#ifdef __SUPPORT_DRM - int ret; - ret = drm_process_request(DRM_REQUEST_TYPE_REGISTER_FILE, (void *)path, NULL); - if (ret != DRM_RETURN_SUCCESS) { - MS_DBG_ERR("drm_svc_register_file error : %d", ret); - res = MS_MEDIA_ERR_DRM_REGISTER_FAIL; - } -#endif - return res; -} - -void -ms_drm_unregister(const char* path) -{ -#ifdef __SUPPORT_DRM - int ret; - - ret = drm_process_request(DRM_REQUEST_TYPE_UNREGISTER_FILE, (void *)path, NULL); - if (ret != DRM_RETURN_SUCCESS) - MS_DBG_ERR("drm_process_request error : %d", ret); -#endif -} - -void -ms_drm_unregister_all(void) -{ -#ifdef __SUPPORT_DRM - if (drm_process_request(DRM_REQUEST_TYPE_UNREGISTER_ALL_FILES , NULL, NULL) == DRM_RETURN_SUCCESS) - MS_DBG("drm_svc_unregister_all_contents OK"); -#endif -} - -bool -ms_drm_insert_ext_memory(void) -{ -#ifdef __SUPPORT_DRM - MS_DBG(""); - if (drm_process_request(DRM_REQUEST_TYPE_INSERT_EXT_MEMORY, NULL, NULL) != DRM_RETURN_SUCCESS) - return false; -#endif - return true; -} - -bool -ms_drm_extract_ext_memory(void) -{ -#ifdef __SUPPORT_DRM - MS_DBG(""); - if (drm_process_request(DRM_REQUEST_TYPE_EXTRACT_EXT_MEMORY , NULL, NULL) != DRM_RETURN_SUCCESS) - return false; -#endif - return true; -} - diff --git a/src/common/media-common-external-storage.c b/src/common/media-common-external-storage.c index b445aca..6d4cb15 100755 --- a/src/common/media-common-external-storage.c +++ b/src/common/media-common-external-storage.c @@ -31,7 +31,6 @@ #include "media-server-ipc.h" #include "media-common-dbg.h" #include "media-common-utils.h" -#include "media-common-drm.h" #include "media-common-external-storage.h" #include @@ -54,8 +53,7 @@ char default_path[][MS_FILE_NAME_LEN_MAX + 1] = { #define DIR_NUM ((int)(sizeof(default_path)/sizeof(default_path[0]))) -void -ms_init_default_path(void){ +void ms_init_default_path(void){ strcpy (default_path[0], PATH_IMAGES); strcpy (default_path[1], PATH_VIDEOS); @@ -64,8 +62,7 @@ ms_init_default_path(void){ strcpy (default_path[4], PATH_CAMERA); } -void -ms_make_default_path_mmc(void) +void ms_make_default_path_mmc(void) { int i = 0; int ret = 0; @@ -94,8 +91,7 @@ ms_make_default_path_mmc(void) } } -int -_ms_update_mmc_info(const char *cid) +int _ms_update_mmc_info(const char *cid) { bool res; @@ -113,8 +109,7 @@ _ms_update_mmc_info(const char *cid) return MS_MEDIA_ERR_NONE; } -bool -_ms_check_mmc_info(const char *cid) +bool _ms_check_mmc_info(const char *cid) { char pre_mmc_info[MMC_INFO_SIZE] = { 0 }; bool res = false; @@ -140,8 +135,7 @@ _ms_check_mmc_info(const char *cid) return false; } -static int -_get_contents(const char *filename, char *buf) +static int __get_contents(const char *filename, char *buf) { FILE *fp; @@ -159,8 +153,7 @@ _get_contents(const char *filename, char *buf) } /*need optimize*/ -int -_ms_get_mmc_info(char *cid) +int _ms_get_mmc_info(char *cid) { int i; int j; @@ -218,7 +211,7 @@ _ms_get_mmc_info(char *cid) continue; } - if (_get_contents(path, cid) != MS_MEDIA_ERR_NONE) + if (__get_contents(path, cid) != MS_MEDIA_ERR_NONE) break; else getdata = true; @@ -235,8 +228,7 @@ _ms_get_mmc_info(char *cid) return MS_MEDIA_ERR_NONE; } -ms_dir_scan_type_t -ms_get_mmc_state(void) +ms_dir_scan_type_t ms_get_mmc_state(void) { char cid[MMC_INFO_SIZE] = { 0 }; ms_dir_scan_type_t ret = MS_SCAN_ALL; @@ -252,8 +244,7 @@ ms_get_mmc_state(void) return ret; } -int -ms_update_mmc_info(void) +int ms_update_mmc_info(void) { int err; char cid[MMC_INFO_SIZE] = { 0 }; @@ -289,8 +280,7 @@ void update_lang(void) } } -int -ms_present_mmc_status(ms_sdcard_status_type_t status) +int ms_present_mmc_status(ms_sdcard_status_type_t status) { int ret = NOTIFICATION_ERROR_NONE; diff --git a/src/common/media-common-utils.c b/src/common/media-common-utils.c index e90c356..1c21766 100755 --- a/src/common/media-common-utils.c +++ b/src/common/media-common-utils.c @@ -19,17 +19,7 @@ * */ -/** - * This file defines api utilities of contents manager engines. - * - * @file media-server-utils.c - * @author Yong Yeon Kim(yy9875.kim@samsung.com) - * @version 1.0 - * @brief This file implements main database operation. - */ - #define _GNU_SOURCE - #include #include #include @@ -39,7 +29,6 @@ #include "media-util.h" #include "media-server-ipc.h" #include "media-common-dbg.h" -#include "media-common-drm.h" #include "media-common-utils.h" #ifdef FMS_PERF @@ -129,21 +118,21 @@ static char* __media_get_path(uid_t uid) ms_storage_type_t ms_get_storage_type_by_full(const char *path, uid_t uid) { - int lenght_path; + int length_path; char * user_path = NULL; if (path == NULL) return false; user_path = __media_get_path(uid); - lenght_path = strlen(user_path); + length_path = strlen(user_path); - if (strncmp(path, user_path, lenght_path) == 0) { + if (strncmp(path, user_path, length_path) == 0) { return MS_STORAGE_INTERNAL; } else if (strncmp(path, MEDIA_ROOT_PATH_SDCARD, strlen(MEDIA_ROOT_PATH_SDCARD)) == 0) { return MS_STORAGE_EXTERNAL; - } else - { free(user_path); + } else { + free(user_path); return MS_MEDIA_ERR_INVALID_PATH; } } @@ -278,3 +267,23 @@ ms_config_set_str(const char *key, const char *value) return false; } +bool +ms_config_get_bool(const char *key, int *value) +{ + int err; + + if (!key || !value) { + MS_DBG_ERR("Arguments key or value is NULL"); + return false; + } + + err = vconf_get_bool(key, value); + if (err == 0) + return true; + else if (err == -1) + return false; + else + MS_DBG_ERR("Unexpected error code: %d", err); + + return false; +} \ No newline at end of file diff --git a/src/mediadb-update.c b/src/mediadb-update.c index 2cc1641..f062208 100644 --- a/src/mediadb-update.c +++ b/src/mediadb-update.c @@ -26,7 +26,7 @@ #include #include #include - +#include #include #include "media-util.h" @@ -36,11 +36,14 @@ GMainLoop * mainloop = NULL; static MediaDBHandle *db_handle = NULL; +int (*svc_connect) (void ** handle, uid_t uid, char ** err_msg); +int (*svc_disconnect) (void * handle, char ** err_msg); +int (*svc_check_db) (void * handle, uid_t uid, char ** err_msg); + void callback(media_request_result_s * result, void *user_data) { printf("db updating done\n"); - media_db_disconnect(db_handle); g_main_loop_quit(mainloop); } @@ -61,6 +64,41 @@ void print_help() printf("=======================================================================================\n"); } +void check_media_db(void) +{ + void *funcHandle = NULL; + void *db_handle = NULL; + char *err_msg = NULL; + int ret = 0; + + funcHandle = dlopen ("/usr/lib/libmedia-content-plugin.so", RTLD_LAZY); + if(funcHandle == NULL) + { + printf("Error when open plug-in\n"); + return; + } + + svc_connect = dlsym (funcHandle, "connect_db"); + svc_disconnect = dlsym (funcHandle, "disconnect_db"); + svc_check_db = dlsym (funcHandle, "check_db"); + + ret = svc_connect(&db_handle,tzplatform_getuid(TZ_USER_NAME), &err_msg); + if(ret < 0) + printf("Error svc_connect\n"); + + ret = svc_check_db(db_handle,tzplatform_getuid(TZ_USER_NAME), &err_msg); + if(ret < 0) + printf("Error svc_check_db\n"); + + ret = svc_disconnect(db_handle, &err_msg); + if(ret < 0) + printf("Error svc_disconnect\n"); + + printf("Check media db done\n"); + + dlclose (funcHandle); +} + int dir_scan_non_recursive(char *path) { int ret = MS_MEDIA_ERR_NONE; @@ -141,6 +179,11 @@ int main(int argc, char **argv) exit(1); } + if (strcmp(argv1 , "check_db") == 0) { + check_media_db(); + exit(1); + } + if (check_path(argv1) == DIRECTORY_OK) { ret = dir_scan_non_recursive(argv1); if (ret != 0) { diff --git a/src/scanner/include/media-scanner-db-svc.h b/src/scanner/include/media-scanner-db-svc.h index b2dff2f..ef7f337 100755 --- a/src/scanner/include/media-scanner-db-svc.h +++ b/src/scanner/include/media-scanner-db-svc.h @@ -32,13 +32,13 @@ #include "media-common-types.h" -typedef int (*CHECK_ITEM)(const char*, char **); typedef int (*CONNECT)(void**, uid_t, char **); typedef int (*DISCONNECT)(void*, char **); -typedef int (*CHECK_ITEM_EXIST)(void*, const char*, int, char **); +typedef int (*CHECK_ITEM_EXIST)(void*, const char*, bool*, char **); typedef int (*INSERT_ITEM_BEGIN)(void*, int, int, int, char **); typedef int (*INSERT_ITEM_END)(void*, uid_t, char **); typedef int (*INSERT_ITEM)(void*, const char*, int, uid_t, char **); +typedef int (*INSERT_ITEM_IMMEDIATELY)(void*, const char*, int, uid_t, char **); typedef int (*SET_ALL_STORAGE_ITEMS_VALIDITY)(void*, int, int, uid_t, char **); typedef int (*SET_ITEM_VALIDITY_BEGIN)(void*, int, char **); typedef int (*SET_ITEM_VALIDITY_END)(void*, uid_t, char **); @@ -52,6 +52,12 @@ typedef int (*DELETE_ALL_INVALID_ITEMS_IN_FOLDER)(void*, const char*, uid_t, cha typedef int (*INSERT_BURST_ITEM)(void *, const char *, int, uid_t, char **); typedef int (*SEND_DIR_UPDATE_NOTI)(void *, const char *, char **); typedef int (*COUNT_DELETE_ITEMS_IN_FOLDER)(void *, const char *, int *, char **); +typedef int (*DELETE_ITEM)(void *, const char *, uid_t, char **); +typedef int (*GET_FOLDER_LIST)(void *, char*, char ***, int **, int **, int *, char **); +typedef int (*UPDATE_FOLDER_TIME)(void *, const char *, uid_t, char **); +typedef int (*UPDATE_ITEM_META)(void *, const char *, int, uid_t, char **); +typedef int (*UPDATE_ITEM_BEGIN)(void *, int, char **); +typedef int (*UPDATE_ITEM_END)(void *, uid_t, char **); int msc_load_functions(void); @@ -78,7 +84,7 @@ bool msc_delete_all_items(void **handle, ms_storage_type_t store_type, uid_t uid); int -msc_invalidate_all_items(void **handle, ms_storage_type_t store_type, uid_t uid); +msc_validaty_change_all_items(void **handle, ms_storage_type_t store_type, bool validity, uid_t uid); bool msc_delete_invalid_items(void **handle, ms_storage_type_t store_type, uid_t uid); @@ -95,6 +101,24 @@ msc_send_dir_update_noti(void **handle, const char*path); int msc_count_delete_items_in_folder(void **handle, const char*path, int *count); +typedef struct msc_dir_info_s { + char *dir_path; + int modified_time; + int item_num; +} msc_dir_info_s; + +int +msc_get_folder_list(void **handle, char* start_path, GArray **dir_array); + +int +msc_update_folder_time(void **handle, char *folder_path, uid_t uid); + +int +msc_insert_item_immediately(void **handle, const char *path, uid_t uid); + +int +msc_update_meta_batch(void **handle, const char *path, uid_t uid); + /**************************************************************************************************** FOR BULK COMMIT *****************************************************************************************************/ @@ -115,4 +139,10 @@ msc_validate_start(void **handle); void msc_validate_end(void **handle, uid_t uid); +void +msc_update_start(void **handle); + +void +msc_update_end(void **handle, uid_t uid); + #endif /*_MEDIA_SCANNER_DB_SVC_H_*/ diff --git a/src/scanner/include/media-scanner-dbg.h b/src/scanner/include/media-scanner-dbg.h index 735e4c1..9315d15 100755 --- a/src/scanner/include/media-scanner-dbg.h +++ b/src/scanner/include/media-scanner-dbg.h @@ -19,15 +19,6 @@ * */ -/** - * This file defines api utilities of contents manager engines. - * - * @file media-scanner-dbg.h - * @author Yong Yeon Kim(yy9875.kim@samsung.com) - * @version 1.0 - * @brief - */ - #ifndef _MEDIA_SCANNER_DBG_H_ #define _MEDIA_SCANNER_DBG_H_ #include @@ -42,8 +33,7 @@ #define MSC_DBG_STRERROR(fmt) do { \ char buf[BUF_LENGTH] = {0,}; \ - strerror_r(errno, buf, BUF_LENGTH); \ - LOGE(fmt" : STANDARD ERROR [%s]", buf); \ + LOGE(fmt" : STANDARD ERROR [%s]", strerror_r(errno, buf, BUF_LENGTH)); \ } while (0) #define MSC_DBG_SLOG(fmt, args...) do{ if (true) { \ diff --git a/src/scanner/include/media-scanner-scan.h b/src/scanner/include/media-scanner-scan.h index 49e32c9..9d778e5 100755 --- a/src/scanner/include/media-scanner-scan.h +++ b/src/scanner/include/media-scanner-scan.h @@ -19,14 +19,6 @@ * */ -/** - * This file defines api utilities of contents manager engines. - * - * @file media-server-scan.h - * @author Yong Yeon Kim(yy9875.kim@samsung.com) - * @version 1.0 - * @brief - */ #ifndef _MEDIA_SCANNER_SCAN_H_ #define _MEDIA_SCANNER_SCAN_H_ @@ -40,4 +32,14 @@ int msc_check_remain_task(void); ms_db_status_type_t msc_check_scanning_status(void); +int msc_set_cancel_path(const char *cancel_path); + +int msc_del_cancel_path(void); + +int msc_set_blocked_path(const char *blocked_path); + +int msc_del_blocked_path(void); + +void msc_metadata_update_thread(ms_comm_msg_s *recv_msg); + #endif /*_MEDIA_SCANNER_SCAN_H_*/ \ No newline at end of file diff --git a/src/scanner/include/media-scanner-socket.h b/src/scanner/include/media-scanner-socket.h index 5e39436..b3e33fb 100755 --- a/src/scanner/include/media-scanner-socket.h +++ b/src/scanner/include/media-scanner-socket.h @@ -19,14 +19,6 @@ * */ -/** - * This file defines api utilities of contents manager engines. - * - * @file media-server-thumb.c - * @author Yong Yeon Kim(yy9875.kim@samsung.com) - * @version 1.0 - * @brief - */ #ifndef _MEDIA_SCANNER_SOCKET_H_ #define _MEDIA_SCANNER_SOCKET_H_ @@ -37,8 +29,6 @@ gboolean msc_receive_request(GIOChannel *src, GIOCondition condition, gpointer d int msc_send_ready(void); -int msc_send_scan_result(int result, ms_comm_msg_s *scan_data); - -int msc_send_register_result(int result, ms_comm_msg_s *reg_data); +int msc_send_result(int result, ms_comm_msg_s *scan_data); #endif /*_MEDIA_SCANNER_SOCKET_H_*/ diff --git a/src/scanner/media-scanner-db-svc.c b/src/scanner/media-scanner-db-svc.c index 7d809f6..51b93f0 100755 --- a/src/scanner/media-scanner-db-svc.c +++ b/src/scanner/media-scanner-db-svc.c @@ -33,7 +33,6 @@ #include "media-util.h" #include "media-common-utils.h" -#include "media-common-drm.h" #include "media-scanner-dbg.h" #include "media-scanner-db-svc.h" @@ -45,7 +44,7 @@ #define MSC_REGISTER_COUNT 100 /*For bundle commit*/ #define MSC_VALID_COUNT 100 /*For bundle commit*/ -GMutex * db_mutex; +GMutex db_mutex; GArray *so_array; void ***func_array; int lib_num; @@ -53,13 +52,13 @@ void **scan_func_handle = NULL; /*dlopen handel*/ extern int insert_count; enum func_list { - eCHECK, eCONNECT, eDISCONNECT, eEXIST, eINSERT_BEGIN, eINSERT_END, eINSERT_BATCH, + eINSERT_ITEM_IMMEDIATELY, eSET_ALL_VALIDITY, eSET_VALIDITY_BEGIN, eSET_VALIDITY_END, @@ -73,25 +72,16 @@ enum func_list { eINSERT_BURST, eSEND_DIR_UPDATE_NOTI, eCOUNT_DELETE_ITEMS_IN_FOLDER, + eDELETE_ITEM, + eGET_FOLDER_LIST, + eUPDATE_FOLDER_TIME, + eUPDATE_ITEM_META, + eUPDATE_ITEM_BEGIN, + eUPDATE_ITEM_END, eFUNC_MAX }; static int -_msc_check_category(const char *path, int index) -{ - int ret; - char *err_msg = NULL; - - ret = ((CHECK_ITEM)func_array[index][eCHECK])(path, &err_msg); - if (ret != 0) { - MSC_DBG_ERR("error : %s [%s] %s", g_array_index(so_array, char*, index), err_msg, path); - MS_SAFE_FREE(err_msg); - } - - return ret; -} - -static int _msc_token_data(char *buf, char **name) { int len; @@ -145,13 +135,13 @@ msc_load_functions(void) { int lib_index = 0, func_index; char func_list[eFUNC_MAX][40] = { - "check_item", "connect_db", "disconnect_db", "check_item_exist", "insert_item_begin", "insert_item_end", "insert_item", + "insert_item_immediately", "set_all_storage_items_validity", "set_item_validity_begin", "set_item_validity_end", @@ -165,6 +155,12 @@ msc_load_functions(void) "insert_burst_item", "send_dir_update_noti", "count_delete_items_in_folder", + "delete_item", + "get_folder_list", + "update_folder_time", + "update_item_meta", + "update_item_begin", + "update_item_end", }; /*init array for adding name of so*/ so_array = g_array_new(FALSE, FALSE, sizeof(char*)); @@ -263,7 +259,18 @@ msc_unload_functions(void) MS_SAFE_FREE (func_array); MS_SAFE_FREE (scan_func_handle); - if (so_array) g_array_free(so_array, TRUE); + + if (so_array) { + /*delete all node*/ + while(so_array->len != 0) { + char *so_name = NULL; + so_name = g_array_index(so_array , char*, 0); + g_array_remove_index (so_array, 0); + MS_SAFE_FREE(so_name); + } + g_array_free(so_array, FALSE); + so_array = NULL; + } } int @@ -274,16 +281,21 @@ msc_connect_db(void ***handle, uid_t uid) char * err_msg = NULL; /*Lock mutex for openning db*/ - g_mutex_lock(db_mutex); + g_mutex_lock(&db_mutex); MS_MALLOC(*handle, sizeof (void*) * lib_num); + if (*handle == NULL) { + MSC_DBG_ERR("malloc failed"); + g_mutex_unlock(&db_mutex); + return MS_MEDIA_ERR_OUT_OF_MEMORY; + } for (lib_index = 0; lib_index < lib_num; lib_index++) { ret = ((CONNECT)func_array[lib_index][eCONNECT])(&((*handle)[lib_index]), uid, &err_msg); /*dlopen*/ if (ret != 0) { MSC_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg); MS_SAFE_FREE(err_msg); - g_mutex_unlock(db_mutex); + g_mutex_unlock(&db_mutex); return MS_MEDIA_ERR_DB_CONNECT_FAIL; } @@ -291,7 +303,7 @@ msc_connect_db(void ***handle, uid_t uid) MSC_DBG_INFO("connect Media DB"); - g_mutex_unlock(db_mutex); + g_mutex_unlock(&db_mutex); return MS_MEDIA_ERR_NONE; } @@ -326,52 +338,53 @@ msc_validate_item(void **handle, const char *path, uid_t uid) int res = MS_MEDIA_ERR_NONE; int ret; char *err_msg = NULL; - ms_storage_type_t storage_type; - - storage_type = ms_get_storage_type_by_full(path,uid); + bool modified = FALSE; for (lib_index = 0; lib_index < lib_num; lib_index++) { - if (!_msc_check_category(path, lib_index)) { - /*check exist in Media DB, If file is not exist, insert data in DB. */ - ret = ((CHECK_ITEM_EXIST)func_array[lib_index][eEXIST])(handle[lib_index], path, storage_type, &err_msg); /*dlopen*/ + /*check exist in Media DB, If file is not exist, insert data in DB. */ + ret = ((CHECK_ITEM_EXIST)func_array[lib_index][eEXIST])(handle[lib_index], path, &modified, &err_msg); /*dlopen*/ + if (ret != 0) { + MS_SAFE_FREE(err_msg); + ret = msc_insert_item_batch(handle, path, uid); if (ret != 0) { - MSC_DBG_ERR("not exist in %d. insert data", lib_index); - MS_SAFE_FREE(err_msg); - - ret = ((INSERT_ITEM)func_array[lib_index][eINSERT_BATCH])(handle[lib_index], path, storage_type, uid, &err_msg); /*dlopen*/ + res = MS_MEDIA_ERR_DB_INSERT_FAIL; + } else { + insert_count++; + } + } else { + if (modified == FALSE) { + /*if meta data of file exist, change valid field to "1" */ + ret = ((SET_ITEM_VALIDITY)func_array[lib_index][eSET_VALIDITY])(handle[lib_index], path, true, true, uid, &err_msg); /*dlopen*/ if (ret != 0) { MSC_DBG_ERR("error : %s [%s] %s", g_array_index(so_array, char*, lib_index), err_msg, path); - MSC_DBG_ERR("[%s]", path); MS_SAFE_FREE(err_msg); - res = MS_MEDIA_ERR_DB_INSERT_FAIL; - } else { - insert_count++; + res = MS_MEDIA_ERR_DB_UPDATE_FAIL; } } else { - /*if meta data of file exist, change valid field to "1" */ - ret = ((SET_ITEM_VALIDITY)func_array[lib_index][eSET_VALIDITY])(handle[lib_index], path, true, true, uid, &err_msg); /*dlopen*/ + /* the file has same name but it is changed, so we have to update DB */ + MSC_DBG_WAN("DELETE ITEM [%s]", path); + ret = ((DELETE_ITEM)func_array[lib_index][eDELETE_ITEM])(handle[lib_index], path, uid, &err_msg); /*dlopen*/ if (ret != 0) { MSC_DBG_ERR("error : %s [%s] %s", g_array_index(so_array, char*, lib_index), err_msg, path); - MSC_DBG_ERR("[%s]", path);; MS_SAFE_FREE(err_msg); - res = MS_MEDIA_ERR_DB_UPDATE_FAIL; + res = MS_MEDIA_ERR_DB_DELETE_FAIL; + } else { + ret = msc_insert_item_batch(handle, path, uid); + if (ret != 0) { + res = MS_MEDIA_ERR_DB_INSERT_FAIL; + } else { + insert_count++; + } } } - } else { - MSC_DBG_ERR("check category failed"); - MSC_DBG_ERR("[%s]", path); } } - if (ms_is_drm_file(path)) { - ret = ms_drm_register(path); - } - return res; } int -msc_invalidate_all_items(void **handle, ms_storage_type_t store_type , uid_t uid) +msc_validaty_change_all_items(void **handle, ms_storage_type_t store_type, bool validity , uid_t uid) { int lib_index; int res = MS_MEDIA_ERR_NONE; @@ -379,7 +392,7 @@ msc_invalidate_all_items(void **handle, ms_storage_type_t store_type , uid_t uid char *err_msg = NULL; for (lib_index = 0; lib_index < lib_num; lib_index++) { - ret = ((SET_ALL_STORAGE_ITEMS_VALIDITY)func_array[lib_index][eSET_ALL_VALIDITY])(handle[lib_index], store_type, false, uid, &err_msg); /*dlopen*/ + ret = ((SET_ALL_STORAGE_ITEMS_VALIDITY)func_array[lib_index][eSET_ALL_VALIDITY])(handle[lib_index], store_type, validity, uid, &err_msg); /*dlopen*/ if (ret != 0) { MSC_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg); MS_SAFE_FREE(err_msg); @@ -399,26 +412,38 @@ msc_insert_item_batch(void **handle, const char *path, uid_t uid) char *err_msg = NULL; ms_storage_type_t storage_type; - storage_type = ms_get_storage_type_by_full(path,uid); + storage_type = ms_get_storage_type_by_full(path, uid); for (lib_index = 0; lib_index < lib_num; lib_index++) { - if (!_msc_check_category(path, lib_index)) { - ret = ((INSERT_ITEM)func_array[lib_index][eINSERT_BATCH])(handle[lib_index], path, storage_type, uid, &err_msg); /*dlopen*/ - if (ret != 0) { - MSC_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg); - MSC_DBG_ERR("[%s]", path); - MS_SAFE_FREE(err_msg); - res = MS_MEDIA_ERR_DB_INSERT_FAIL; - } - } else { - MSC_DBG_ERR("check category failed"); - MSC_DBG_ERR("[%s]", path); + ret = ((INSERT_ITEM)func_array[lib_index][eINSERT_BATCH])(handle[lib_index], path, storage_type, uid, &err_msg); /*dlopen*/ + if (ret != 0) { + MSC_DBG_ERR("error : %s [%s] %s", g_array_index(so_array, char*, lib_index), err_msg, path); + MS_SAFE_FREE(err_msg); + res = MS_MEDIA_ERR_DB_INSERT_FAIL; } } - if (ms_is_drm_file(path)) { - ret = ms_drm_register(path); - res = ret; + return res; +} + +int +msc_insert_item_immediately(void **handle, const char *path, uid_t uid) +{ + int lib_index; + int res = MS_MEDIA_ERR_NONE; + int ret; + char *err_msg = NULL; + ms_storage_type_t storage_type; + + storage_type = ms_get_storage_type_by_full(path, uid); + + for (lib_index = 0; lib_index < lib_num; lib_index++) { + ret = ((INSERT_ITEM_IMMEDIATELY)func_array[lib_index][eINSERT_ITEM_IMMEDIATELY])(handle[lib_index], path, storage_type, uid, &err_msg); /*dlopen*/ + if (ret != 0) { + MSC_DBG_ERR("error : %s [%s] %s", g_array_index(so_array, char*, lib_index), err_msg, path); + MS_SAFE_FREE(err_msg); + res = MS_MEDIA_ERR_DB_INSERT_FAIL; + } } return res; @@ -436,25 +461,14 @@ msc_insert_burst_item(void **handle, const char *path , uid_t uid) storage_type = ms_get_storage_type_by_full(path,uid); for (lib_index = 0; lib_index < lib_num; lib_index++) { - if (!_msc_check_category(path, lib_index)) { - ret = ((INSERT_BURST_ITEM)func_array[lib_index][eINSERT_BURST])(handle[lib_index], path, storage_type, uid, &err_msg); /*dlopen*/ - if (ret != 0) { - MSC_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg); - MSC_DBG_ERR("[%s]", path); - MS_SAFE_FREE(err_msg); - res = MS_MEDIA_ERR_DB_INSERT_FAIL; - } - } else { - MSC_DBG_ERR("check category failed"); - MSC_DBG_ERR("[%s]", path); + ret = ((INSERT_BURST_ITEM)func_array[lib_index][eINSERT_BURST])(handle[lib_index], path, storage_type, uid, &err_msg); /*dlopen*/ + if (ret != 0) { + MSC_DBG_ERR("error : %s [%s] %s", g_array_index(so_array, char*, lib_index), err_msg, path); + MS_SAFE_FREE(err_msg); + res = MS_MEDIA_ERR_DB_INSERT_FAIL; } } - if (ms_is_drm_file(path)) { - ret = ms_drm_register(path); - res = ret; - } - return res; } @@ -571,7 +585,99 @@ msc_count_delete_items_in_folder(void **handle, const char*path, int *count) } return MS_MEDIA_ERR_NONE; +} + +int +msc_get_folder_list(void **handle, char* start_path, GArray **dir_array) +{ + int lib_index; + int ret; + char *err_msg = NULL; + + char **folder_list = NULL; + int *modified_time_list = NULL; + int *item_num_list = NULL; + int count = 0; + int i = 0; + + msc_dir_info_s* dir_info = NULL; + MSC_DBG_ERR("start path: %s", start_path); + + for (lib_index = 0; lib_index < lib_num; lib_index++) { + ret = ((GET_FOLDER_LIST)func_array[lib_index][eGET_FOLDER_LIST])(handle[lib_index], start_path, &folder_list, &modified_time_list, &item_num_list, &count, &err_msg); /*dlopen*/ + if (ret != 0) { + MSC_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg); + MS_SAFE_FREE(err_msg); + return MS_MEDIA_ERR_INTERNAL; + } + } + + MSC_DBG_ERR("OK"); + + *dir_array = g_array_new(FALSE, FALSE, sizeof(msc_dir_info_s*)); + if (count != 0) { + for(i = 0; i < count; i ++) { + dir_info = malloc(sizeof(msc_dir_info_s)); + if(dir_info) { + memset(dir_info, 0, sizeof(msc_dir_info_s)); + dir_info->dir_path = strdup(folder_list[i]); + dir_info->modified_time = modified_time_list[i]; + dir_info->item_num = item_num_list[i]; + g_array_append_val(*dir_array, dir_info); + MS_SAFE_FREE(folder_list[i]); +// MSC_DBG("%d get path : %s, %d", i, dir_info->dir_path, dir_info->modified_time); + } + } + } + + MS_SAFE_FREE(folder_list); + MS_SAFE_FREE(modified_time_list); + + return MS_MEDIA_ERR_NONE; +} +int +msc_update_folder_time(void **handle, char *folder_path, uid_t uid) +{ + int lib_index; + int ret; + char *err_msg = NULL; + + for (lib_index = 0; lib_index < lib_num; lib_index++) { + ret = ((UPDATE_FOLDER_TIME)func_array[lib_index][eUPDATE_FOLDER_TIME])(handle[lib_index], folder_path, uid, &err_msg); /*dlopen*/ + if (ret != 0) { + MSC_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg); + MS_SAFE_FREE(err_msg); + return MS_MEDIA_ERR_INTERNAL; + } + } + + return MS_MEDIA_ERR_NONE; +} + +int +msc_update_meta_batch(void **handle, const char *path, uid_t uid) +{ + int lib_index; + int res = MS_MEDIA_ERR_NONE; + int ret; + char *err_msg = NULL; + ms_storage_type_t storage_type; + + storage_type = ms_get_storage_type_by_full(path, uid); + + MSC_DBG_ERR(""); + + for (lib_index = 0; lib_index < lib_num; lib_index++) { + ret = ((UPDATE_ITEM_META)func_array[lib_index][eUPDATE_ITEM_META])(handle[lib_index], path, storage_type, uid, &err_msg); /*dlopen*/ + if (ret != 0) { + MSC_DBG_ERR("error : %s [%s] %s", g_array_index(so_array, char*, lib_index), err_msg, path); + MS_SAFE_FREE(err_msg); + res = MS_MEDIA_ERR_DB_INSERT_FAIL; + } + } + + return res; } /**************************************************************************************************** @@ -650,3 +756,35 @@ msc_validate_end(void **handle, uid_t uid) } } +void +msc_update_start(void **handle) +{ + int lib_index; + int ret = 0; + char *err_msg = NULL; + + for (lib_index = 0; lib_index < lib_num; lib_index++) { + ret = ((UPDATE_ITEM_BEGIN)func_array[lib_index][eUPDATE_ITEM_BEGIN])(handle[lib_index], MSC_VALID_COUNT, &err_msg);/*dlopen*/ + if (ret != 0) { + MSC_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg); + MS_SAFE_FREE(err_msg); + } + } +} + +void +msc_update_end(void **handle, uid_t uid) +{ + int lib_index; + int ret = 0; + char *err_msg = NULL; + + for (lib_index = 0; lib_index < lib_num; lib_index++) { + ret = ((UPDATE_ITEM_END)func_array[lib_index][eUPDATE_ITEM_END])(handle[lib_index], uid, &err_msg);/*dlopen*/ + if (ret != 0) { + MSC_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg); + MS_SAFE_FREE(err_msg); + } + } +} + diff --git a/src/scanner/media-scanner-scan.c b/src/scanner/media-scanner-scan.c index 0279738..255c705 100755 --- a/src/scanner/media-scanner-scan.c +++ b/src/scanner/media-scanner-scan.c @@ -19,14 +19,6 @@ * */ -/** - * This file defines api utilities of contents manager engines. - * - * @file media-server-scan.c - * @author Yong Yeon Kim(yy9875.kim@samsung.com) - * @version 1.0 - * @brief - */ #include #include #include @@ -59,14 +51,75 @@ GAsyncQueue * storage_queue; GAsyncQueue *scan_queue; GAsyncQueue *reg_queue; int insert_count; +GMutex scan_req_mutex; +GMutex blocked_mutex; +char *g_cancel_path; +char *g_blocked_path; +bool g_directory_scan_processing; +GArray *blocked_stg_list; + +int stg_scan_status; #ifdef FMS_PERF extern struct timeval g_mmc_start_time; extern struct timeval g_mmc_end_time; #endif -static int -_msc_set_power_mode(ms_db_status_type_t status) +static int __msc_set_power_mode(ms_db_status_type_t status); +static int __msc_set_db_status(ms_db_status_type_t status, ms_storage_type_t storage_type); +static int __msc_check_stop_status(ms_storage_type_t storage_type); +static int __msc_dir_scan(void **handle, const char*start_path, ms_storage_type_t storage_type, int scan_type, uid_t uid); +static int __msc_db_update(void **handle, const ms_comm_msg_s * scan_data); +static int __msc_check_file_path(const char *file_path, uid_t uid); +static int __msc_make_file_list(char *file_path, GArray **path_array, uid_t uid); +static int __msc_batch_insert(ms_msg_type_e current_msg, int pid, GArray *path_array, uid_t uid); +static int __msc_pop_register_request(GArray *register_array, ms_comm_msg_s **register_data); +static int __msc_clear_file_list(GArray *path_array); +static bool __msc_check_scan_ignore(char * path); +static bool __msc_is_valid_path(const char *path, uid_t uid); +static void __msc_check_dir_path(char *dir_path); +static void __msc_insert_register_request(GArray *register_array, ms_comm_msg_s *insert_data); +static void __msc_bacth_commit_enable(void* handle, bool ins_status, bool valid_status, bool noti_enable, int pid); +static void __msc_bacth_commit_disable(void* handle, bool ins_status, bool valid_status, uid_t uid); +static char* __msc_get_path(uid_t uid); + +static char* __msc_get_path(uid_t uid) +{ + char *result_psswd = NULL; + struct group *grpinfo = NULL; + if(uid == getuid()) + { + result_psswd = strdup(MEDIA_ROOT_PATH_INTERNAL); + grpinfo = getgrnam("users"); + if(grpinfo == NULL) { + MSC_DBG_ERR("getgrnam(users) returns NULL !"); + return NULL; + } + } + else + { + struct passwd *userinfo = getpwuid(uid); + if(userinfo == NULL) { + MSC_DBG_ERR("getpwuid(%d) returns NULL !", uid); + return NULL; + } + grpinfo = getgrnam("users"); + if(grpinfo == NULL) { + MSC_DBG_ERR("getgrnam(users) returns NULL !"); + return NULL; + } + // Compare git_t type and not group name + if (grpinfo->gr_gid != userinfo->pw_gid) { + MSC_DBG_ERR("UID [%d] does not belong to 'users' group!", uid); + return NULL; + } + asprintf(&result_psswd, "%s/%s", userinfo->pw_dir, MEDIA_CONTENT_PATH); + } + + return result_psswd; +} + +static int __msc_set_power_mode(ms_db_status_type_t status) { int res = MS_MEDIA_ERR_NONE; int err; @@ -90,8 +143,7 @@ _msc_set_power_mode(ms_db_status_type_t status) return res; } -static int -_msc_set_db_status(ms_db_status_type_t status) +static int __msc_set_db_status(ms_db_status_type_t status, ms_storage_type_t storage_type) { int res = MS_MEDIA_ERR_NONE; int err = 0; @@ -101,29 +153,49 @@ _msc_set_db_status(ms_db_status_type_t status) res = MS_MEDIA_ERR_VCONF_SET_FAIL; MSC_DBG_ERR("ms_config_set_int failed"); } + + if (storage_type == MS_STORAGE_EXTERNAL) { + if (!ms_config_set_int(VCONFKEY_FILEMANAGER_MMC_STATUS, VCONFKEY_FILEMANAGER_MMC_LOADING)) { + res = MS_MEDIA_ERR_VCONF_SET_FAIL; + MSC_DBG_ERR("ms_config_set_int failed"); + } + } } else if (status == MS_DB_UPDATED) { if(!ms_config_set_int(VCONFKEY_FILEMANAGER_DB_STATUS, VCONFKEY_FILEMANAGER_DB_UPDATED)) { res = MS_MEDIA_ERR_VCONF_SET_FAIL; MSC_DBG_ERR("ms_config_set_int failed"); } + + if (storage_type == MS_STORAGE_EXTERNAL) { + if (!ms_config_set_int(VCONFKEY_FILEMANAGER_MMC_STATUS, VCONFKEY_FILEMANAGER_MMC_LOADED)) { + res = MS_MEDIA_ERR_VCONF_SET_FAIL; + MSC_DBG_ERR("ms_config_set_int failed"); + } + } } - err = _msc_set_power_mode(status); + err = __msc_set_power_mode(status); if (err != MS_MEDIA_ERR_NONE) { - MSC_DBG_ERR("_msc_set_power_mode fail"); + MSC_DBG_ERR("__msc_set_power_mode fail"); res = err; } return res; } -static bool _msc_check_scan_ignore(char * path) +static bool __msc_check_scan_ignore(char * path) { DIR *dp = NULL; struct dirent entry; struct dirent *result; char *ignore_path = ".scan_ignore"; + if(strstr(path, "/.")) + { + MSC_DBG_ERR("hidden path"); + return true;; + } + dp = opendir(path); if (dp == NULL) { MSC_DBG_ERR("%s folder opendir fails", path); @@ -144,7 +216,39 @@ static bool _msc_check_scan_ignore(char * path) return false; } -static int _ms_check_stop_status(ms_storage_type_t storage_type) +#if 0 +GCond data_cond; +GMutex data_mutex; +gpointer current_data = NULL; + +static int __msc_resume_scan() +{ + g_mutex_lock (&data_mutex); + +// current_data = GINT_TO_POINTER(g_directory_scan_processing); + g_cond_signal (&data_cond); + + g_mutex_unlock (&data_mutex); + + return MS_MEDIA_ERR_NONE; +} +static int __msc_pause_scan() +{ + g_mutex_lock (&data_mutex); + +// while (current_data) + while (g_directory_scan_processing) + g_cond_wait (&data_cond, &data_mutex); + +// current_data = GPOINTER_TO_INT(g_directory_scan_processing); + + g_mutex_unlock (&data_mutex); + + return MS_MEDIA_ERR_NONE; +} +#endif + +static int __msc_check_stop_status(ms_storage_type_t storage_type) { int ret = MS_MEDIA_ERR_NONE; @@ -155,15 +259,16 @@ static int _ms_check_stop_status(ms_storage_type_t storage_type) } /*check SD card in out */ +#if 0 if ((mmc_state != VCONFKEY_SYSMAN_MMC_MOUNTED) && (storage_type == MS_STORAGE_EXTERNAL)) { MSC_DBG_ERR("Directory scanning is stopped"); ret = MS_MEDIA_ERR_SCANNER_FORCE_STOP; } - +#endif return ret; } -void _msc_check_dir_path(char *dir_path) +static void __msc_check_dir_path(char *dir_path) { /* need implementation */ /* if dir_path is not NULL terminated, this function will occure crash */ @@ -173,13 +278,12 @@ void _msc_check_dir_path(char *dir_path) dir_path[len -1] = '\0'; } -static int _msc_dir_scan(void **handle, const char*start_path, ms_storage_type_t storage_type, int scan_type, uid_t uid) +static int __msc_dir_scan(void **handle, const char*start_path, ms_storage_type_t storage_type, int scan_type, uid_t uid) { DIR *dp = NULL; GArray *dir_array = NULL; struct dirent entry; struct dirent *result = NULL; - int i; int ret = MS_MEDIA_ERR_NONE; char *new_path = NULL; char *current_path = NULL; @@ -195,15 +299,12 @@ static int _msc_dir_scan(void **handle, const char*start_path, ms_storage_type_t /* add first direcotiry to directory array */ g_array_append_val (dir_array, start_path); - if (scan_type == MS_MSG_STORAGE_ALL) - scan_function = msc_insert_item_batch; - else - scan_function = msc_validate_item; + scan_function = (scan_type == MS_MSG_STORAGE_ALL) ? msc_insert_item_batch : msc_validate_item; /*start db update. the number of element in the array , db update is complete.*/ while (dir_array->len != 0) { /*check poweroff status*/ - ret = _ms_check_stop_status(storage_type); + ret = __msc_check_stop_status(storage_type); if (ret != MS_MEDIA_ERR_NONE) { goto STOP_SCAN; } @@ -212,7 +313,7 @@ static int _msc_dir_scan(void **handle, const char*start_path, ms_storage_type_t g_array_remove_index (dir_array, 0); // MSC_DBG_SLOG("%d", dir_array->len); - if (_msc_check_scan_ignore(current_path)) { + if (__msc_check_scan_ignore(current_path)) { MSC_DBG_ERR("%s is ignore", current_path); MS_SAFE_FREE(current_path); continue; @@ -222,7 +323,7 @@ static int _msc_dir_scan(void **handle, const char*start_path, ms_storage_type_t if (dp != NULL) { while (!readdir_r(dp, &entry, &result)) { /*check poweroff status*/ - ret = _ms_check_stop_status(storage_type); + ret = __msc_check_stop_status(storage_type); if (ret != MS_MEDIA_ERR_NONE) { goto STOP_SCAN; } @@ -240,7 +341,7 @@ static int _msc_dir_scan(void **handle, const char*start_path, ms_storage_type_t } /* insert into media DB */ if (scan_function(handle,path,uid) != MS_MEDIA_ERR_NONE) { - MSC_DBG_ERR("failed to update db : %d\n", scan_type); + MSC_DBG_ERR("failed to update db : %d", scan_type); continue; } } else if (entry.d_type & DT_DIR) { @@ -259,6 +360,10 @@ static int _msc_dir_scan(void **handle, const char*start_path, ms_storage_type_t } } } + /* update modified time of directory */ + if (scan_type == MS_MSG_STORAGE_PARTIAL + && storage_type == MS_STORAGE_INTERNAL) + msc_update_folder_time(handle, current_path, uid); } else { MSC_DBG_ERR("%s folder opendir fails", current_path); } @@ -269,57 +374,45 @@ static int _msc_dir_scan(void **handle, const char*start_path, ms_storage_type_t STOP_SCAN: if (dp) closedir(dp); - /*delete all node*/ - if(dir_array != NULL) { - for (i =0; i < dir_array->len; i++) { - char *data = NULL; - data = g_array_index(dir_array , char*, 0); - g_array_remove_index (dir_array, 0); - MS_SAFE_FREE(data); - } - g_array_free (dir_array, TRUE); - dir_array = NULL; - } + __msc_clear_file_list(dir_array); - MSC_DBG_INFO("ret : %d", ret); + if (ret != MS_MEDIA_ERR_NONE) MSC_DBG_INFO("ret : %d", ret); return ret; } -static int _msc_db_update(void **handle, const ms_comm_msg_s * scan_data) +static int __msc_db_update(void **handle, const ms_comm_msg_s * scan_data) { int scan_type; int err = MS_MEDIA_ERR_NONE; char *start_path = NULL; ms_storage_type_t storage_type; - storage_type = ms_get_storage_type_by_full(scan_data->msg,scan_data->uid); + storage_type = ms_get_storage_type_by_full(scan_data->msg, scan_data->uid); scan_type = scan_data->msg_type; + start_path = strndup(scan_data->msg, scan_data->msg_size); /*if scan type is not MS_SCAN_NONE, check data in db. */ if (scan_type != MS_MSG_STORAGE_INVALID) { MSC_DBG_INFO("INSERT"); - start_path = strndup(scan_data->msg, scan_data->msg_size); - scan_type = scan_data->msg_type; - err = _msc_dir_scan(handle, start_path, storage_type, scan_type,scan_data->uid); + err = __msc_dir_scan(handle, start_path, storage_type, scan_type, scan_data->uid); if (err != MS_MEDIA_ERR_NONE) { MSC_DBG_ERR("error : %d", err); } } else if (scan_type == MS_MSG_STORAGE_INVALID) { MSC_DBG_INFO("INVALID"); - /*In this case, update just validation record*/ - /*update just valid type*/ - err = msc_invalidate_all_items(handle, storage_type,scan_data->uid); + + err = msc_set_folder_validity(handle, start_path, false, true, scan_data->uid); if (err != MS_MEDIA_ERR_NONE) { MSC_DBG_ERR("error : %d", err); } + + MS_SAFE_FREE(start_path); } sync(); - MSC_DBG_INFO("ret : %d", err); - return err; } @@ -355,7 +448,7 @@ gboolean msc_directory_scan_thread(void *data) goto NEXT; } - _msc_check_dir_path(scan_data->msg); + __msc_check_dir_path(scan_data->msg); /*change validity before scanning*/ if (scan_type == MS_MSG_DIRECTORY_SCANNING) @@ -366,15 +459,13 @@ gboolean msc_directory_scan_thread(void *data) MSC_DBG_ERR("error : %d", err); /*call for bundle commit*/ - msc_register_start(handle, MS_NOTI_DISABLE, 0); - msc_validate_start(handle); + __msc_bacth_commit_enable(handle, TRUE, TRUE, MS_NOTI_DISABLE, 0); /*insert data into media db */ - ret = _msc_db_update(handle, scan_data); - + ret = __msc_db_update(handle, scan_data); + /*call for bundle commit*/ - msc_register_end(handle,scan_data->uid); - msc_validate_end(handle,scan_data->uid); + __msc_bacth_commit_disable(handle, TRUE, TRUE,scan_data->uid); if (ret == MS_MEDIA_ERR_NONE) { MSC_DBG_INFO("working normally"); @@ -407,11 +498,11 @@ NEXT: /*Active flush */ malloc_trim(0); - msc_send_scan_result(ret, scan_data); + msc_send_result(ret, scan_data); MS_SAFE_FREE(scan_data); - MSC_DBG_INFO("DIRECTORY SCAN END"); + MSC_DBG_INFO("DIRECTORY SCAN END [%d]", ret); } /*thread while*/ _POWEROFF: @@ -422,16 +513,194 @@ _POWEROFF: } /* this thread process only the request of media-server */ +static int _check_folder_from_list(char *folder_path, int item_num, GArray *dir_array) +{ + int i; + int array_len = dir_array->len; + msc_dir_info_s* dir_info = NULL; + struct stat buf; + time_t mtime; + bool find_flag = false; + + if(stat(folder_path, &buf) == 0) { + mtime = buf.st_mtime; + } else { + return MS_MEDIA_ERR_INTERNAL; + } + + for (i = 0; i < array_len; i++) { + dir_info = g_array_index (dir_array, msc_dir_info_s*, i); + if (strcmp(folder_path, dir_info->dir_path) == 0) { + /* if modified time is same, the folder does not need updating */ + if ((mtime == dir_info->modified_time) && (item_num == dir_info->item_num)) { + if (mtime == 0) + continue; + + g_array_remove_index (dir_array, i); + MS_SAFE_FREE(dir_info->dir_path); + MS_SAFE_FREE(dir_info); + } + find_flag = true; + break; + } + } + + /* this folder does not exist in media DB, so this folder has to insert to DB */ + if ((find_flag == false) && + (item_num > 0)) { + dir_info = NULL; + dir_info = malloc(sizeof(msc_dir_info_s)); + if (dir_info == NULL) { + MSC_DBG_ERR("MALLOC failed"); + return MS_MEDIA_ERR_OUT_OF_MEMORY; + } + memset(dir_info, 0, sizeof(msc_dir_info_s)); + dir_info->dir_path = strdup(folder_path); + dir_info->modified_time = -1; + g_array_append_val(dir_array, dir_info); + } + + return MS_MEDIA_ERR_NONE; +} + +static int __msc_compare_with_db(void **handle, const char*update_path, int scan_type, GArray **dir_array) +{ + DIR *dp = NULL; + GArray *read_dir_array = NULL; + struct dirent entry; + struct dirent *result = NULL; + int ret = MS_MEDIA_ERR_NONE; + char *new_path = NULL; + char *current_path = NULL; + char path[MS_FILE_PATH_LEN_MAX] = { 0 }; + char * start_path = strdup(update_path); + int item_num = 0; + + /*get directories list from media db*/ + ret = msc_get_folder_list(handle, start_path, dir_array); + if (ret != MS_MEDIA_ERR_NONE) { + MS_SAFE_FREE(start_path); + MSC_DBG_ERR("msc_get_folder_list is failed", ret); + return ret; + } + + MSC_DBG_ERR(" "); + /* make new array for storing directory */ + read_dir_array = g_array_new (FALSE, FALSE, sizeof (char*)); + if (read_dir_array == NULL){ + MSC_DBG_ERR("g_array_new failed"); + return MS_MEDIA_ERR_OUT_OF_MEMORY; + } + /* add first direcotiry to directory array */ + g_array_append_val (read_dir_array, start_path); + + /*start db update. the number of element in the array , db update is complete.*/ + while (read_dir_array->len != 0) { + /* get the current path from directory array */ + current_path = g_array_index(read_dir_array , char*, 0); + g_array_remove_index (read_dir_array, 0); +// MSC_DBG_ERR("%s", current_path); + + if (__msc_check_scan_ignore(current_path)) { + MSC_DBG_ERR("%s is ignore", current_path); + MS_SAFE_FREE(current_path); + continue; + } + + dp = opendir(current_path); + if (dp != NULL) { + while (!readdir_r(dp, &entry, &result)) { + if (result == NULL) + break; + + if (entry.d_name[0] == '.') { + continue; + } + + if (entry.d_type & DT_DIR) { + if (ms_strappend(path, sizeof(path), "%s/%s", current_path, entry.d_name) != MS_MEDIA_ERR_NONE) { + MSC_DBG_ERR("ms_strappend failed"); + continue; + } + /* add new directory to dir_array */ + new_path = strdup(path); + g_array_append_val (read_dir_array, new_path); + } else if (entry.d_type & DT_REG) { + item_num++; + } + } + + /* find and compare modified time */ + _check_folder_from_list(current_path, item_num, *dir_array); + item_num = 0; + } else { + MSC_DBG_ERR("%s folder opendir fails", current_path); + } + if (dp) closedir(dp); + dp = NULL; + MS_SAFE_FREE(current_path); + } /*db update while */ + + __msc_clear_file_list(read_dir_array); + + MSC_DBG_INFO("ret : %d", ret); + MSC_DBG_INFO("update count : %d", (*dir_array)->len); + + return ret; +} + +static int _msc_db_update_partial(void **handle, ms_storage_type_t storage_type, GArray *dir_array, uid_t uid) +{ + int i; + int err = MS_MEDIA_ERR_NONE; + msc_dir_info_s* dir_info = NULL; + char *update_path = NULL; + + for (i = 0; i < dir_array->len; i ++) { + dir_info = g_array_index (dir_array, msc_dir_info_s*, i); + update_path = strdup(dir_info->dir_path); + +// MSC_DBG_SLOG("update_path : %s, %d", update_path, dir_info->modified_time); + if (dir_info->modified_time != -1) { + err = msc_set_folder_validity(handle, update_path, MS_INVALID, MS_NON_RECURSIVE, uid); + if (err != MS_MEDIA_ERR_NONE) { + MSC_DBG_SLOG("update_path : %s, %d", update_path, dir_info->modified_time); + MSC_DBG_ERR("error : %d", err); + } + } + + __msc_dir_scan(handle, update_path, storage_type, MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE, uid); + +// if (dir_info->modified_time != -1) { +// msc_update_folder_time(handle, tmp_path); +// } + } + + /*delete all node*/ + while(dir_array->len != 0) { + msc_dir_info_s *data = NULL; + data = g_array_index(dir_array , msc_dir_info_s*, 0); + g_array_remove_index (dir_array, 0); + MS_SAFE_FREE(data->dir_path); + MS_SAFE_FREE(data); + } + g_array_free(dir_array, FALSE); + dir_array = NULL; + + return MS_MEDIA_ERR_NONE; +} + gboolean msc_storage_scan_thread(void *data) { ms_comm_msg_s *scan_data = NULL; - bool res; int ret; int err; void **handle = NULL; - ms_storage_type_t storage_type; + ms_storage_type_t storage_type = MS_STORAGE_INTERNAL; int scan_type; - char *noti_path = NULL; + bool valid_status = TRUE; + char *update_path = NULL; + GArray *dir_array = NULL; while (1) { scan_data = g_async_queue_pop(storage_queue); @@ -451,73 +720,85 @@ gboolean msc_storage_scan_thread(void *data) goto NEXT; } - storage_type = ms_get_storage_type_by_full(scan_data->msg,scan_data->uid); - MSC_DBG_INFO("%d", storage_type); - /*connect to media db, if conneting is failed, db updating is stopped*/ err = msc_connect_db(&handle,scan_data->uid); if (err != MS_MEDIA_ERR_NONE) continue; + storage_type = ms_get_storage_type_by_full(scan_data->msg, scan_data->uid); + update_path = strndup(scan_data->msg, scan_data->msg_size); + /*start db updating */ - _msc_set_db_status(MS_DB_UPDATING); + __msc_set_db_status(MS_DB_UPDATING, storage_type); + + valid_status = (scan_type == MS_MSG_STORAGE_PARTIAL) ? TRUE : FALSE; + __msc_bacth_commit_enable(handle, TRUE, valid_status, MS_NOTI_DISABLE, 0); + +#ifdef FMS_PERF + ms_check_start_time(&g_mmc_start_time); +#endif + + if (scan_type == MS_MSG_STORAGE_PARTIAL && storage_type == MS_STORAGE_INTERNAL) { + msc_validaty_change_all_items(handle, storage_type, true, scan_data->uid); - /*Delete all data before full scanning*/ - if (scan_type == MS_MSG_STORAGE_ALL) { - res = msc_delete_all_items(handle, storage_type,scan_data->uid); - if (res != true) { - MSC_DBG_ERR("msc_delete_all_record fails"); + /* find and compare modified time */ + ret = __msc_compare_with_db(handle, update_path, scan_data->msg_type, &dir_array); + if (ret != MS_MEDIA_ERR_NONE) { + MSC_DBG_ERR("__msc_compare_with_db is falied"); + goto NEXT; } - } else if (scan_type == MS_MSG_STORAGE_PARTIAL) { - err = msc_invalidate_all_items(handle, storage_type,scan_data->uid); - if (err != MS_MEDIA_ERR_NONE) - MSC_DBG_ERR("error : %d", err); - } - if (storage_type == MS_STORAGE_EXTERNAL && scan_type == MS_MSG_STORAGE_ALL) { - ms_update_mmc_info(); - } + if (dir_array->len != 0) { + MSC_DBG_INFO("DB UPDATING IS NEEDED"); -#ifdef FMS_PERF - if (storage_type == MS_STORAGE_EXTERNAL) { - ms_check_start_time(&g_mmc_start_time); + ret = _msc_db_update_partial(handle, storage_type, dir_array, scan_data->uid); + } else { + MSC_DBG_INFO("THERE IS NO UPDATE"); + } + } else { + if (scan_type == MS_MSG_STORAGE_ALL) { + /* Delete all data before full scanning */ + if (!msc_delete_invalid_items(handle, storage_type, scan_data->uid)) { + MSC_DBG_ERR("msc_delete_all_record fails"); + } + + if (storage_type == MS_STORAGE_EXTERNAL) { + ms_update_mmc_info(); + } + } else if (scan_type == MS_MSG_STORAGE_PARTIAL) { + msc_validaty_change_all_items(handle, storage_type, false, scan_data->uid); + } + + ret = __msc_db_update(handle, scan_data); } -#endif + /*call for bundle commit*/ - msc_register_start(handle, MS_NOTI_DISABLE, 0); + __msc_bacth_commit_disable(handle, TRUE, valid_status,scan_data->uid); + if (scan_type == MS_MSG_STORAGE_PARTIAL) { - /*enable bundle commit*/ - msc_validate_start(handle); - } + int del_count = 0; - /*add inotify watch and insert data into media db */ - ret = _msc_db_update(handle, scan_data); + /*check delete count*/ + MSC_DBG_INFO("update path : %s", update_path); + msc_count_delete_items_in_folder(handle, update_path, &del_count); - /*call for bundle commit*/ - msc_register_end(handle,scan_data->uid); - if (scan_type == MS_MSG_STORAGE_PARTIAL) { - /*disable bundle commit*/ - msc_validate_end(handle,scan_data->uid); - if (ret == MS_MEDIA_ERR_NONE) { - MSC_DBG_INFO("working normally"); - msc_delete_invalid_items(handle, storage_type,scan_data->uid); - } + /*if there is no delete content, do not call delete API*/ + if (del_count != 0) + msc_delete_invalid_items(handle, storage_type, scan_data->uid); } /* send notification */ - noti_path = strndup(scan_data->msg, scan_data->msg_size); - msc_send_dir_update_noti(handle, noti_path); - MS_SAFE_FREE(noti_path); + msc_send_dir_update_noti(handle, update_path); + MS_SAFE_FREE(update_path); #ifdef FMS_PERF - if (storage_type == MS_STORAGE_EXTERNAL) { - ms_check_end_time(&g_mmc_end_time); - ms_check_time_diff(&g_mmc_start_time, &g_mmc_end_time); - } + ms_check_end_time(&g_mmc_end_time); + ms_check_time_diff(&g_mmc_start_time, &g_mmc_end_time); #endif +NEXT: /*set vconf key mmc loading for indicator */ - _msc_set_db_status(MS_DB_UPDATED); + __msc_set_db_status(MS_DB_UPDATED, storage_type); if (power_off) { MSC_DBG_ERR("[No-error] power off"); @@ -527,15 +808,14 @@ gboolean msc_storage_scan_thread(void *data) /*disconnect from media db*/ if (handle) msc_disconnect_db(&handle); -NEXT: /*Active flush */ malloc_trim(0); - msc_send_scan_result(ret, scan_data); + msc_send_result(ret, scan_data); MS_SAFE_FREE(scan_data); - MSC_DBG_INFO("STORAGE SCAN END"); + MSC_DBG_INFO("STORAGE SCAN END[%d]", ret); } /*thread while*/ _POWEROFF: @@ -545,7 +825,7 @@ _POWEROFF: return false; } -static void _msc_insert_register_request(GArray *register_array, ms_comm_msg_s *insert_data) +static void __msc_insert_register_request(GArray *register_array, ms_comm_msg_s *insert_data) { MSC_DBG_SLOG("path : %s", insert_data->msg); @@ -558,29 +838,38 @@ static void _msc_insert_register_request(GArray *register_array, ms_comm_msg_s * } } -static bool _is_valid_path(const char *path) +static bool __msc_is_valid_path(const char *path, uid_t uid) { + char *usr_path = NULL; + if (path == NULL) return false; - if (strncmp(path, MEDIA_ROOT_PATH_INTERNAL, strlen(MEDIA_ROOT_PATH_INTERNAL)) == 0) { + usr_path = __msc_get_path(uid); + if(usr_path == NULL) + return false; + + if (strncmp(path, usr_path, strlen(usr_path)) == 0) { + MS_SAFE_FREE(usr_path); return true; } else if (strncmp(path, MEDIA_ROOT_PATH_SDCARD, strlen(MEDIA_ROOT_PATH_SDCARD)) == 0) { + MS_SAFE_FREE(usr_path); return true; - } else + } else { + MS_SAFE_FREE(usr_path); return false; - + } return true; } -static int _check_file_path(const char *file_path) +static int __msc_check_file_path(const char *file_path, uid_t uid) { int exist; struct stat file_st; /* check location of file */ /* file must exists under "/opt/usr/media" or "/opt/storage/sdcard" */ - if(!_is_valid_path(file_path)) { + if(!__msc_is_valid_path(file_path, uid)) { MSC_DBG_ERR("Invalid path : %s", file_path); return MS_MEDIA_ERR_INVALID_PATH; } @@ -610,171 +899,489 @@ static int _check_file_path(const char *file_path) return MS_MEDIA_ERR_NONE; } -gboolean msc_register_thread(void *data) +static int __msc_clear_file_list(GArray *path_array) +{ + if (path_array) { + while(path_array->len != 0) { + char *data = NULL; + data = g_array_index(path_array , char*, 0); + g_array_remove_index (path_array, 0); + MS_SAFE_FREE(data); + } + g_array_free(path_array, FALSE); + path_array = NULL; + } + + return MS_MEDIA_ERR_NONE; +} + +static int __msc_check_ignore_dir(const char *full_path, uid_t uid) +{ + int ret = MS_MEDIA_ERR_NONE; + char *dir_path = NULL; + char *leaf_path = NULL; + + ret = __msc_check_file_path(full_path, uid); + if (ret != MS_MEDIA_ERR_NONE) { + MSC_DBG_ERR("invalid path : %s", full_path); + return MS_MEDIA_ERR_INVALID_PATH; + } + + dir_path = g_path_get_dirname(full_path); + if (strcmp(dir_path, ".") == 0) { + MSC_DBG_ERR("getting directory path is failed : %s", full_path); + MS_SAFE_FREE(dir_path); + return MS_MEDIA_ERR_INVALID_PATH; + } + + while(1) { + if(__msc_check_scan_ignore(dir_path)) { + ret = MS_MEDIA_ERR_INVALID_PATH; + break; + } + + /*If root path, Stop Scanning*/ + if(strcmp(dir_path, __msc_get_path(uid)) == 0) + break; + else if(strcmp(dir_path, MEDIA_ROOT_PATH_SDCARD) == 0) + break; + + leaf_path = strrchr(dir_path, '/'); + if(leaf_path != NULL) { + int seek_len = leaf_path -dir_path; + dir_path[seek_len] = '\0'; + } else { + MSC_DBG_ERR("Fail to find leaf path"); + ret = MS_MEDIA_ERR_INVALID_PATH; + break; + } + } + + MS_SAFE_FREE(dir_path); + + return ret; +} + +static int __msc_make_file_list(char *file_path, GArray **path_array, uid_t uid) { - ms_comm_msg_s *register_data = NULL; - ms_comm_msg_s *insert_data = NULL; - GArray *register_array = NULL; - GArray *path_array = NULL; FILE *fp = NULL; - char buf[MS_FILE_PATH_LEN_MAX]; - char *insert_path = NULL; + char buf[MS_FILE_PATH_LEN_MAX] = {0,}; char *path = NULL; - char *file_path = NULL; - int path_size; int length; + int res = MS_MEDIA_ERR_NONE; + int ret = MS_MEDIA_ERR_NONE; + + /* load the file list from file */ + fp = fopen(file_path, "rt"); + if (fp == NULL) { + MSC_DBG_STRERROR("fopen failed"); + res = MS_MEDIA_ERR_FILE_OPEN_FAIL; + goto FREE_RESOURCE; + } + + memset(buf, 0x0, MS_FILE_PATH_LEN_MAX); + /* This is an array for storing the path of insert datas*/ + *path_array = g_array_new (FALSE, FALSE, sizeof (char *)); + if (*path_array == NULL) { + MSC_DBG_ERR("g_array_new failed"); + res = MS_MEDIA_ERR_OUT_OF_MEMORY; + goto FREE_RESOURCE; + } + + /* read registering file path from stored file */ + while(fgets(buf, MS_FILE_PATH_LEN_MAX, fp) != NULL) { + length = strlen(buf); /*the return value of function, strlen(), includes "\n" */ + path = strndup(buf, length - 1); /*copying except "\n" and strndup fuction adds "\0" at the end of the copying string */ + + /* check valid path */ + ret = __msc_check_ignore_dir(path, uid); + if (ret != MS_MEDIA_ERR_NONE) { + MSC_DBG_ERR("invalide path : %s", path); + MS_SAFE_FREE(path); + continue; + } + /* insert getted path to the list */ + if (g_array_append_val(*path_array, path) == NULL) { + MSC_DBG_ERR("g_array_append_val failed"); + res = MS_MEDIA_ERR_OUT_OF_MEMORY; + goto FREE_RESOURCE; + } + } + + if(fp) fclose(fp); + fp = NULL; + + return MS_MEDIA_ERR_NONE; + +FREE_RESOURCE: + + __msc_clear_file_list(*path_array); + + if(fp) fclose(fp); + fp = NULL; + + return res; +} + +static int __msc_batch_insert(ms_msg_type_e current_msg, int pid, GArray *path_array, uid_t uid) +{ int err; int i; - int ret; void **handle = NULL; - ms_msg_type_e current_msg = MS_MSG_MAX; + char *insert_path = NULL; int (*insert_function)(void **, const char*, uid_t) = NULL; - /*create array for processing overlay data*/ - register_array = g_array_new (FALSE, FALSE, sizeof (ms_comm_msg_s *)); - if (register_array == NULL) { - MSC_DBG_ERR("g_array_new error"); - return false; + insert_function = (current_msg == MS_MSG_BULK_INSERT) ? msc_insert_item_batch : msc_insert_burst_item; + + /* connect to media db, if conneting is failed, db updating is stopped */ + err = msc_connect_db(&handle, uid); + if (err != MS_MEDIA_ERR_NONE) + return MS_MEDIA_ERR_DB_CONNECT_FAIL; + + /*start db updating */ + /*call for bundle commit*/ + __msc_bacth_commit_enable(handle, TRUE, FALSE, MS_NOTI_ENABLE, pid); + + MSC_DBG_ERR("BULK REGISTER START"); + + /* get the inserting file path from array and insert to db */ + for (i = 0; i < path_array->len; i++) { + + insert_path = g_array_index(path_array, char*, i); + + /* insert to db */ + err = insert_function(handle, insert_path, uid); + + if (power_off) { + MSC_DBG_ERR("power off"); + /*call for bundle commit*/ + msc_register_end(handle, uid); + break; + } } + /*call for bundle commit*/ + __msc_bacth_commit_disable(handle, TRUE, FALSE, uid); + + /*disconnect form media db*/ + if (handle) msc_disconnect_db(&handle); + + return MS_MEDIA_ERR_NONE; +} + +static int __msc_pop_register_request(GArray *register_array, ms_comm_msg_s **register_data) +{ + int remain_request; + ms_comm_msg_s *insert_data = NULL; + while (1) { - length = g_async_queue_length(reg_queue); + remain_request = g_async_queue_length(reg_queue); /*updating requests remain*/ - if (register_array->len != 0 && length == 0) { - register_data = g_array_index(register_array, ms_comm_msg_s*, 0); + if (register_array->len != 0 && remain_request == 0) { + *register_data = g_array_index(register_array, ms_comm_msg_s*, 0); g_array_remove_index (register_array, 0); - if (register_data->pid == POWEROFF) { - MSC_DBG_INFO("power off"); - goto _POWEROFF; - } - } else if (length != 0) { + break; + } else if (remain_request != 0) { insert_data = g_async_queue_pop(reg_queue); - _msc_insert_register_request(register_array, insert_data); + __msc_insert_register_request(register_array, insert_data); continue; - } else if (register_array->len == 0 && length == 0) { - /*Threre is no request, Wait until pushung new request*/ + } else if (register_array->len == 0 && remain_request == 0) { + /*Threre is no request, Wait until pushung new request*/ insert_data = g_async_queue_pop(reg_queue); - _msc_insert_register_request(register_array, insert_data); + __msc_insert_register_request(register_array, insert_data); continue; } + } - if((register_data->msg_size <= 0) ||(register_data->msg_size > MS_FILE_PATH_LEN_MAX)) { - MSC_DBG_ERR("message size[%d] is wrong", register_data->msg_size); - goto FREE_RESOURCE; - } else { - path_size = register_data->msg_size + 1; - } + if(((*register_data)->msg_size <= 0) ||((*register_data)->msg_size > MS_FILE_PATH_LEN_MAX)) { + MSC_DBG_ERR("message size[%d] is wrong", (*register_data)->msg_size); + return MS_MEDIA_ERR_INVALID_IPC_MESSAGE; + } - file_path = strndup(register_data->msg, register_data->msg_size); + return MS_MEDIA_ERR_NONE; - /* load the file list from file */ - fp = fopen(file_path, "rt"); - if (fp == NULL) { - MSC_DBG_ERR("fopen failed [%s]", strerror(errno)); - goto FREE_RESOURCE; - } +} - memset(buf, 0x0, MS_FILE_PATH_LEN_MAX); - /* This is an array for storing the path of insert datas*/ - path_array = g_array_new (FALSE, FALSE, sizeof (char *)); - if (path_array == NULL) { - MSC_DBG_ERR("g_array_new failed"); - goto FREE_RESOURCE; - } +gboolean msc_register_thread(void *data) +{ + ms_comm_msg_s *register_data = NULL; + GArray *register_array = NULL; + GArray *path_array = NULL; + char *file_path = NULL; + int ret; + int pid = 0; + ms_msg_type_e current_msg = MS_MSG_MAX; - /* read registering file path from stored file */ - while(fgets(buf, MS_FILE_PATH_LEN_MAX, fp) != NULL) { - length = strlen(buf); /*the return value of function, strlen(), includes "\n" */ - path = strndup(buf, length - 1); /*copying except "\n" and strndup fuction adds "\0" at the end of the copying string */ - MSC_DBG_INFO("insert path : %s [%d]", path, strlen(path)); - /* insert getted path to the list */ - if (g_array_append_val(path_array, path) == NULL) { - MSC_DBG_ERR("g_array_append_val failed"); - goto FREE_RESOURCE; - } + /*create array for processing overlay data*/ + register_array = g_array_new (FALSE, FALSE, sizeof (ms_comm_msg_s *)); + if (register_array == NULL) { + MSC_DBG_ERR("g_array_new error"); + return false; + } + + while (1) { + ret = __msc_pop_register_request(register_array, ®ister_data); + if (register_data->pid == POWEROFF) { + MSC_DBG_ERR("power off"); + goto _POWEROFF; } - /* connect to media db, if conneting is failed, db updating is stopped */ - err = msc_connect_db(&handle,register_data->uid); - if (err != MS_MEDIA_ERR_NONE) + if (ret != MS_MEDIA_ERR_NONE) { + MSC_DBG_ERR("__msc_pop_register_request failed [%d]", ret); goto FREE_RESOURCE; - - /*start db updating */ - /*call for bundle commit*/ - msc_register_start(handle, MS_NOTI_ENABLE, register_data->pid); + } /* check current request */ current_msg = register_data->msg_type; - if (current_msg == MS_MSG_BULK_INSERT) { - insert_function = msc_insert_item_batch; - } else if (current_msg == MS_MSG_BURSTSHOT_INSERT) { - insert_function = msc_insert_burst_item; - } else { + pid = register_data->pid; + + if ((current_msg != MS_MSG_BULK_INSERT) && + (current_msg != MS_MSG_BURSTSHOT_INSERT)) { MSC_DBG_ERR("wrong message type"); goto FREE_RESOURCE; } - /* get the inserting file path from array and insert to db */ - for (i = 0; i < path_array->len; i++) { - - insert_path = g_array_index(path_array, char*, i); - /* check the file */ - /* it is really existing */ - /* it is in /opt/usr/media or /opt/storage/sdcard */ - /* it is really regular file */ - ret = _check_file_path(insert_path); - if (ret != MS_MEDIA_ERR_NONE) { - MSC_DBG_ERR("Can't insert the meta of the path"); - continue; - } - - /* insert to db */ - err = insert_function(handle, insert_path, register_data->uid); - - if (power_off) { - MSC_DBG_INFO("power off"); - /*call for bundle commit*/ - msc_register_end(handle, register_data->uid); - goto _POWEROFF; - } + file_path = strndup(register_data->msg, register_data->msg_size); + if (file_path == NULL) { + MSC_DBG_ERR("file_path is NULL"); + goto FREE_RESOURCE; } - /*call for bundle commit*/ - msc_register_end(handle, register_data->uid); + ret = __msc_make_file_list(file_path, &path_array, register_data->uid); + if (ret != MS_MEDIA_ERR_NONE) { + MSC_DBG_ERR("__msc_make_file_list failed [%d]", ret); + goto FREE_RESOURCE; + } - /*disconnect from media db*/ - if (handle) msc_disconnect_db(&handle); + ret = __msc_batch_insert(current_msg, pid, path_array, register_data->uid); +FREE_RESOURCE: /*Active flush */ malloc_trim(0); /* If register_files operation is stopped, there is no necessrty for sending result. */ - msc_send_register_result(MS_MEDIA_ERR_NONE, register_data); -FREE_RESOURCE: - if (path_array) { - g_array_free(path_array, TRUE); - path_array = NULL; - } + msc_send_result(ret, register_data); - MS_SAFE_FREE(file_path); - MS_SAFE_FREE(register_data); + MSC_DBG_ERR("BULK REGISTER END [%d |%s]", ret, register_data->msg); - if(fp) fclose(fp); - fp = NULL; + __msc_clear_file_list(path_array); - /* reset function pointer */ - insert_function = NULL; + MS_SAFE_FREE(file_path); + MS_SAFE_FREE(register_data); } /*thread while*/ _POWEROFF: MS_SAFE_FREE(file_path); MS_SAFE_FREE(register_data); - if (register_array) g_array_free (register_array, TRUE); - if (path_array) g_array_free (path_array, TRUE); + if (register_array) { + while(register_array->len != 0) { + ms_comm_msg_s *data = NULL; + data = g_array_index(register_array , ms_comm_msg_s*, 0); + g_array_remove_index (register_array, 0); + MS_SAFE_FREE(data); + } + g_array_free (register_array, FALSE); + register_array = NULL; + } + + __msc_clear_file_list(path_array); + + return false; +} + +static void __msc_bacth_commit_enable(void* handle, bool ins_status, bool valid_status, bool noti_enable, int pid) +{ + /*call for bundle commit*/ + if (ins_status) msc_register_start(handle, noti_enable, pid); + if (valid_status) msc_validate_start(handle); + + return; +} + +static void __msc_bacth_commit_disable(void* handle, bool ins_status, bool valid_status, uid_t uid) +{ + /*call for bundle commit*/ + if (ins_status) msc_register_end(handle, uid); + if (valid_status) msc_validate_end(handle, uid); + + return; +} + +int msc_set_cancel_path(const char *cancel_path) +{ + if (g_cancel_path != NULL) { + MSC_DBG_ERR("g_cancel_path is not NULL"); + free(g_cancel_path); + g_cancel_path = NULL; + } + + g_cancel_path = strdup(cancel_path); + + return MS_MEDIA_ERR_NONE; +} + +static int __msc_dir_scan_meta_update(void **handle, const char*start_path, ms_storage_type_t storage_type, uid_t uid) +{ + DIR *dp = NULL; + GArray *dir_array = NULL; + struct dirent entry; + struct dirent *result = NULL; + int ret = MS_MEDIA_ERR_NONE; + char *new_path = NULL; + char *current_path = NULL; + char path[MS_FILE_PATH_LEN_MAX] = { 0 }; + int (*scan_function)(void **, const char*, uid_t) = msc_update_meta_batch; + + /* make new array for storing directory */ + dir_array = g_array_new (FALSE, FALSE, sizeof (char*)); + if (dir_array == NULL){ + MSC_DBG_ERR("g_array_new failed"); + return MS_MEDIA_ERR_OUT_OF_MEMORY; + } + /* add first direcotiry to directory array */ + g_array_append_val (dir_array, start_path); + + /*start db update. the number of element in the array , db update is complete.*/ + while (dir_array->len != 0) { + /*check poweroff status*/ + ret = __msc_check_stop_status(storage_type); + if (ret != MS_MEDIA_ERR_NONE) { + goto STOP_SCAN; + } + + /* get the current path from directory array */ + current_path = g_array_index(dir_array , char*, 0); + g_array_remove_index (dir_array, 0); +// MSC_DBG_SLOG("%d", dir_array->len); + + if (__msc_check_scan_ignore(current_path)) { + MSC_DBG_ERR("%s is ignore", current_path); + MS_SAFE_FREE(current_path); + continue; + } + + dp = opendir(current_path); + if (dp != NULL) { + while (!readdir_r(dp, &entry, &result)) { + /*check poweroff status*/ + ret = __msc_check_stop_status(storage_type); + if (ret != MS_MEDIA_ERR_NONE) { + goto STOP_SCAN; + } + + if (result == NULL) + break; + + if (entry.d_name[0] == '.') + continue; + + if (entry.d_type & DT_REG) { + MSC_DBG_ERR(""); + if (ms_strappend(path, sizeof(path), "%s/%s", current_path, entry.d_name) != MS_MEDIA_ERR_NONE) { + MSC_DBG_ERR("ms_strappend failed"); + continue; + } + /* insert into media DB */ + MSC_DBG_ERR("%s", path); + if (scan_function(handle,path, uid) != MS_MEDIA_ERR_NONE) { + MSC_DBG_ERR("failed to update db"); + continue; + } + } else if (entry.d_type & DT_DIR) { + /* this request is recursive scanning */ + if (ms_strappend(path, sizeof(path), "%s/%s", current_path, entry.d_name) != MS_MEDIA_ERR_NONE) { + MSC_DBG_ERR("ms_strappend failed"); + continue; + } + /* add new directory to dir_array */ + new_path = strdup(path); + g_array_append_val (dir_array, new_path); + } + } + } else { + MSC_DBG_ERR("%s folder opendir fails", current_path); + } + if (dp) closedir(dp); + dp = NULL; + MS_SAFE_FREE(current_path); + } /*db update while */ +STOP_SCAN: + if (dp) closedir(dp); + + __msc_clear_file_list(dir_array); + + if (ret != MS_MEDIA_ERR_NONE) MSC_DBG_INFO("ret : %d", ret); + + return ret; +} + + +gboolean msc_metadata_update(void *data) +{ + ms_comm_msg_s *scan_data = data; + int err; + int ret; + void **handle = NULL; + char *start_path = NULL; + ms_storage_type_t storage_type = MS_STORAGE_INTERNAL; + + MSC_DBG_INFO("META UPDATE START"); + + /*connect to media db, if conneting is failed, db updating is stopped*/ + err = msc_connect_db(&handle, scan_data->uid); + if (err != MS_MEDIA_ERR_NONE) + return false; + + /*call for bundle commit*/ + msc_update_start(handle); + + /*insert data into media db */ + + start_path = strdup(__msc_get_path(scan_data->uid)); + ret = __msc_dir_scan_meta_update(handle, start_path, storage_type, scan_data->uid); + + /* send notification */ + msc_send_dir_update_noti(handle, __msc_get_path(scan_data->uid)); + + if (mmc_state == VCONFKEY_SYSMAN_MMC_MOUNTED) { + storage_type = MS_STORAGE_EXTERNAL; + start_path = strdup(MEDIA_ROOT_PATH_SDCARD); + ret = __msc_dir_scan_meta_update(handle, start_path, storage_type, scan_data->uid); + /* send notification */ + msc_send_dir_update_noti(handle, MEDIA_ROOT_PATH_SDCARD); + } + + /*call for bundle commit*/ + msc_update_end(handle, scan_data->uid); + + if (power_off) { + MSC_DBG_WAN("power off"); + goto _POWEROFF; + } + + /*disconnect form media db*/ if (handle) msc_disconnect_db(&handle); - if(fp) fclose(fp); + /*Active flush */ + malloc_trim(0); + + msc_send_result(ret, scan_data); + + MS_SAFE_FREE(scan_data); + + MSC_DBG_INFO("META UPDATE END [%d]", ret); + + +_POWEROFF: + MS_SAFE_FREE(scan_data); + if (handle) msc_disconnect_db(&handle); return false; } + + +void msc_metadata_update_thread(ms_comm_msg_s *recv_msg) +{ + g_thread_new("update_thread", (GThreadFunc)msc_metadata_update, recv_msg); +} diff --git a/src/scanner/media-scanner-socket.c b/src/scanner/media-scanner-socket.c index 5000fa3..1df8396 100755 --- a/src/scanner/media-scanner-socket.c +++ b/src/scanner/media-scanner-socket.c @@ -19,16 +19,10 @@ * */ -/** - * This file defines api utilities of contents manager engines. - * - * @file media-server-thumb.c - * @author Yong Yeon Kim(yy9875.kim@samsung.com) - * @version 1.0 - * @brief - */ #include #include +#include +#include #include #include #include @@ -41,19 +35,59 @@ #include "media-scanner-dbg.h" #include "media-scanner-db-svc.h" #include "media-scanner-socket.h" +#include "media-scanner-scan.h" extern GAsyncQueue *storage_queue; extern GAsyncQueue *scan_queue; extern GAsyncQueue *reg_queue; -GMutex *receive_mutex; +extern GMutex scan_req_mutex; + +static int _msc_remove_request(GAsyncQueue *req_queue, ms_comm_msg_s *recv_msg) +{ + char *cancel_path = recv_msg->msg; + int pid = recv_msg->pid; + int i = 0; + int len = g_async_queue_length(req_queue); + ms_comm_msg_s *msg = NULL; + GAsyncQueue *temp_scan_queue = NULL; + + MSC_DBG_ERR("scan_req_mutex is LOCKED"); + g_mutex_lock(&scan_req_mutex); + + if (len == 0) { + MSC_DBG_ERR("Request is not stacked"); + goto END_REMOVE_REQUEST; + } + + msc_set_cancel_path(recv_msg->msg); + + temp_scan_queue = g_async_queue_new(); + + for (i = 0; i msg, cancel_path) == 0) && (pid == msg->pid)) { + MS_SAFE_FREE(msg); + } else { + g_async_queue_push(temp_scan_queue, GINT_TO_POINTER(msg)); + } + } + g_async_queue_unref (scan_queue); + scan_queue = temp_scan_queue; + +END_REMOVE_REQUEST: + g_mutex_unlock(&scan_req_mutex); + MSC_DBG_ERR("scan_req_mutex is UNLOCKED"); + + return MS_MEDIA_ERR_NONE; +} gboolean msc_receive_request(GIOChannel *src, GIOCondition condition, gpointer data) { ms_comm_msg_s *recv_msg = NULL; int sockfd = MS_SOCK_NOT_ALLOCATE; int req_num = MS_MSG_MAX; - int pid = -1; - int ret = MS_MEDIA_ERR_NONE; + int err = -1; sockfd = g_io_channel_unix_get_fd(src); if (sockfd < 0) { @@ -67,34 +101,59 @@ gboolean msc_receive_request(GIOChannel *src, GIOCondition condition, gpointer d return TRUE; } - /* Socket is readable */ - ret = ms_ipc_receive_message(sockfd, recv_msg, sizeof(*recv_msg), NULL, NULL); - if (ret != MS_MEDIA_ERR_NONE) { + /* read() is blocked until media scanner sends message */ + err = read(sockfd, recv_msg, sizeof(ms_comm_msg_s)); + if (err < 0) { + MSC_DBG_STRERROR("fifo read failed"); MS_SAFE_FREE(recv_msg); - return TRUE; + return MS_MEDIA_ERR_FILE_READ_FAIL; } - MSC_DBG_INFO("receive msg from [%d] %d, %s, uid %d", recv_msg->pid, recv_msg->msg_type, recv_msg->msg, recv_msg->uid); + MSC_DBG_SLOG("receive msg from [%d] %d, %s, uid %d", recv_msg->pid, recv_msg->msg_type, recv_msg->msg, recv_msg->uid); /* copy from recived data */ req_num = recv_msg->msg_type; - pid = recv_msg->pid; - - /* request bulk insert*/ - if (req_num == MS_MSG_BULK_INSERT ||req_num == MS_MSG_BURSTSHOT_INSERT) { - MSC_DBG_INFO("BULK INSERT"); - g_async_queue_push(reg_queue, GINT_TO_POINTER(recv_msg)); - } else if (req_num == MS_MSG_DIRECTORY_SCANNING ||req_num == MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE) { - /* this request from another apps */ - /* set the scan data for scanning thread */ - g_async_queue_push(scan_queue, GINT_TO_POINTER(recv_msg)); - } else if (req_num == MS_MSG_STORAGE_ALL ||req_num == MS_MSG_STORAGE_PARTIAL || req_num == MS_MSG_STORAGE_INVALID) { - /* this request from media-server */ - g_async_queue_push(storage_queue, GINT_TO_POINTER(recv_msg)); - } else { - MSC_DBG_ERR("THIS REQUEST IS INVALID %d", req_num); - MS_SAFE_FREE(recv_msg); - return TRUE; + + switch(req_num){ + case MS_MSG_BULK_INSERT: + case MS_MSG_BURSTSHOT_INSERT: + { + MSC_DBG_INFO("BULK INSERT"); + /* request bulk insert*/ + g_async_queue_push(reg_queue, GINT_TO_POINTER(recv_msg)); + } + break; + case MS_MSG_DIRECTORY_SCANNING: + case MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE: + { + /* this request from another apps */ + /* set the scan data for scanning thread */ + g_async_queue_push(scan_queue, GINT_TO_POINTER(recv_msg)); + } + break; + case MS_MSG_STORAGE_ALL: + case MS_MSG_STORAGE_PARTIAL: + case MS_MSG_STORAGE_INVALID: + { + /* this request from media-server */ + g_async_queue_push(storage_queue, GINT_TO_POINTER(recv_msg)); + } + break; + case MS_MSG_DIRECTORY_SCANNING_CANCEL: + { + _msc_remove_request(scan_queue, recv_msg); + MS_SAFE_FREE(recv_msg); + } + break; + case MS_MSG_STORAGE_META: + msc_metadata_update_thread(recv_msg); + break; + default: + { + MSC_DBG_ERR("THIS REQUEST IS INVALID %d", req_num); + MS_SAFE_FREE(recv_msg); + } + break; } /*Active flush */ @@ -103,83 +162,65 @@ gboolean msc_receive_request(GIOChannel *src, GIOCondition condition, gpointer d return TRUE; } -int msc_send_scan_result(int result, ms_comm_msg_s *scan_data) +int msc_send_ready(void) { - int ret; int res = MS_MEDIA_ERR_NONE; - int sockfd = -1; ms_comm_msg_s send_msg; + int fd = -1; + int err = -1; - /*Create Socket*/ - ret = ms_ipc_create_client_socket(MS_PROTOCOL_UDP, 0, &sockfd, MS_SCAN_COMM_PORT); - if (ret != MS_MEDIA_ERR_NONE) - return MS_MEDIA_ERR_SOCKET_CONN; + fd = open(MS_SCANNER_FIFO_PATH_RES, O_WRONLY); + if (fd < 0) { + MSC_DBG_STRERROR("fifo open failed"); + return MS_MEDIA_ERR_FILE_OPEN_FAIL; + } /* send ready message */ - memset(&send_msg, 0x0, sizeof(ms_comm_msg_s)); - send_msg.msg_type = MS_MSG_SCANNER_RESULT; - send_msg.pid = scan_data->pid; - send_msg.result = result; - send_msg.msg_size = strlen(scan_data->msg); - send_msg.uid = scan_data->uid; - strncpy(send_msg.msg, scan_data->msg, send_msg.msg_size); + memset(&send_msg, 0, sizeof(send_msg)); + send_msg.msg_type = MS_MSG_SCANNER_READY; - ret = ms_ipc_send_msg_to_server(sockfd, MS_SCAN_COMM_PORT, &send_msg, NULL); - if (ret != MS_MEDIA_ERR_NONE) - res = ret; + /* send ready message */ + err = write(fd, &send_msg, sizeof(send_msg)); + if (err < 0) { + MSC_DBG_STRERROR("fifo write failed"); + res = MS_MEDIA_ERR_FILE_READ_FAIL; + } - close(sockfd); + close(fd); return res; } -int msc_send_register_result(int result, ms_comm_msg_s *reg_data) +int msc_send_result(int result, ms_comm_msg_s *res_data) { - int ret = MS_MEDIA_ERR_NONE; - int sockfd = -1; + int res = MS_MEDIA_ERR_NONE; ms_comm_msg_s send_msg; + int fd = -1; + int err = -1; - /*Create Socket*/ - ret = ms_ipc_create_client_socket(MS_PROTOCOL_UDP, 0, &sockfd, MS_SCAN_COMM_PORT); - if (ret != MS_MEDIA_ERR_NONE) - return MS_MEDIA_ERR_SOCKET_CONN; + fd = open(MS_SCANNER_FIFO_PATH_RES, O_WRONLY); + if (fd < 0) { + MSC_DBG_STRERROR("fifo open failed"); + return MS_MEDIA_ERR_FILE_OPEN_FAIL; + } /* send result message */ memset(&send_msg, 0x0, sizeof(ms_comm_msg_s)); send_msg.msg_type = MS_MSG_SCANNER_BULK_RESULT; - send_msg.pid = reg_data->pid; + send_msg.pid = res_data->pid; send_msg.result = result; - send_msg.msg_size = reg_data->msg_size; - strncpy(send_msg.msg, reg_data->msg, send_msg.msg_size); - - ret = ms_ipc_send_msg_to_server(sockfd, MS_SCAN_COMM_PORT, &send_msg, NULL); - - close(sockfd); - - return ret; -} - -int msc_send_ready(void) -{ - int ret; - int res = MS_MEDIA_ERR_NONE; - int sockfd = -1; - ms_comm_msg_s send_msg; - - /*Create Socket*/ - ret = ms_ipc_create_client_socket(MS_PROTOCOL_UDP, 0, &sockfd, MS_SCAN_COMM_PORT); - if (ret != MS_MEDIA_ERR_NONE) - return MS_MEDIA_ERR_SOCKET_CONN; + send_msg.msg_size = res_data->msg_size; + send_msg.uid = res_data->uid; + strncpy(send_msg.msg, res_data->msg, send_msg.msg_size); /* send ready message */ - memset(&send_msg, 0, sizeof(send_msg)); - send_msg.msg_type = MS_MSG_SCANNER_READY; - - ret = ms_ipc_send_msg_to_server(sockfd, MS_SCAN_COMM_PORT, &send_msg, NULL); - if (ret != MS_MEDIA_ERR_NONE) - res = ret; + err = write(fd, &send_msg, sizeof(send_msg)); + if (err < 0) { + MSC_DBG_STRERROR("fifo write failed"); + res = MS_MEDIA_ERR_FILE_READ_FAIL; + } - close(sockfd); + close(fd); return res; } diff --git a/src/scanner/media-scanner.c b/src/scanner/media-scanner.c index aa239fd..95d5850 100755 --- a/src/scanner/media-scanner.c +++ b/src/scanner/media-scanner.c @@ -19,21 +19,14 @@ * */ -/** - * This file defines api utilities of contents manager engines. - * - * @file media-server-main.c - * @author Yong Yeon Kim(yy9875.kim@samsung.com) - * @version 1.0 - * @brief - */ - #include #include -#include +#include +#include +#include +#include #include "media-common-utils.h" -#include "media-common-drm.h" #include "media-common-external-storage.h" #include "media-util.h" @@ -44,14 +37,14 @@ #define APP_NAME "media-scanner" -static int heynoti_id; extern int mmc_state; extern GAsyncQueue *storage_queue; extern GAsyncQueue *scan_queue; extern GAsyncQueue *reg_queue; -extern GMutex *db_mutex; -extern GMutex *receive_mutex; +extern GMutex db_mutex; +extern GMutex scan_req_mutex; +extern bool g_directory_scan_processing; bool power_off; /*If this is TRUE, poweroff notification received*/ static GMainLoop *scanner_mainloop = NULL; @@ -130,35 +123,37 @@ static void _power_off_cb(void* data) if (scan_queue) { /*notify to scannig thread*/ MS_MALLOC(scan_data, sizeof(ms_comm_msg_s)); - scan_data->pid = POWEROFF; - g_async_queue_push(scan_queue, GINT_TO_POINTER(scan_data)); + if(scan_data) { + scan_data->pid = POWEROFF; + g_async_queue_push(scan_queue, GINT_TO_POINTER(scan_data)); + } } if (reg_queue) { /*notify to register thread*/ MS_MALLOC(reg_data, sizeof(ms_comm_msg_s)); - reg_data->pid = POWEROFF; - g_async_queue_push(reg_queue, GINT_TO_POINTER(reg_data)); + if(reg_data) { + reg_data->pid = POWEROFF; + g_async_queue_push(reg_queue, GINT_TO_POINTER(reg_data)); + } } if (storage_queue) { /*notify to register thread*/ MS_MALLOC(reg_data, sizeof(ms_comm_msg_s)); - reg_data->pid = POWEROFF; - g_async_queue_push(storage_queue, GINT_TO_POINTER(reg_data)); + if(reg_data) { + reg_data->pid = POWEROFF; + g_async_queue_push(storage_queue, GINT_TO_POINTER(reg_data)); + } } if (g_main_loop_is_running(scanner_mainloop)) g_main_loop_quit(scanner_mainloop); } -void -_msc_mmc_vconf_cb(void *data) +void _msc_mmc_vconf_cb(keynode_t *key, void* data) { int status = 0; -/* - ms_comm_msg_s *scan_msg; - ms_dir_scan_type_t scan_type = MS_SCAN_PART; -*/ + if (!ms_config_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &status)) { MSC_DBG_ERR("Get VCONFKEY_SYSMAN_MMC_STATUS failed."); } @@ -166,36 +161,7 @@ _msc_mmc_vconf_cb(void *data) MSC_DBG_INFO("VCONFKEY_SYSMAN_MMC_STATUS :%d", status); mmc_state = status; -/* - MS_MALLOC(scan_msg, sizeof(ms_comm_msg_s)); - if (mmc_state == VCONFKEY_SYSMAN_MMC_REMOVED || - mmc_state == VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED) { - scan_type = MS_SCAN_INVALID; - } else if (mmc_state == VCONFKEY_SYSMAN_MMC_MOUNTED) { - scan_type = ms_get_mmc_state(); - } - - switch (scan_type) { - case MS_SCAN_ALL: - scan_msg->msg_type = MS_MSG_STORAGE_ALL; - break; - case MS_SCAN_PART: - scan_msg->msg_type = MS_MSG_STORAGE_PARTIAL; - break; - case MS_SCAN_INVALID: - scan_msg->msg_type = MS_MSG_STORAGE_INVALID; - break; - } - - scan_msg->pid = 0; - scan_msg->msg_size = strlen(MEDIA_ROOT_PATH_SDCARD); - ms_strcopy(scan_msg->msg, scan_msg->msg_size+1, "%s", MEDIA_ROOT_PATH_SDCARD); - - MSC_DBG_INFO("ms_get_mmc_state is %d", scan_msg->msg_type); - - g_async_queue_push(storage_queue, GINT_TO_POINTER(scan_msg)); -*/ return; } @@ -208,69 +174,54 @@ int main(int argc, char **argv) GIOChannel *channel = NULL; GMainContext *context = NULL; - int sockfd = -1; - int err; - -#if 0 /* temporary */ - check_result = check_process(); - if (check_result == false) - exit(0); -#endif - if (!g_thread_supported()) { - g_thread_init(NULL); - } - - /*Init main loop*/ - scanner_mainloop = g_main_loop_new(NULL, FALSE); - - /*heynoti for power off*/ - if ((heynoti_id = heynoti_init()) <0) { - MSC_DBG_INFO("heynoti_init failed"); - } else { - err = heynoti_subscribe(heynoti_id, POWEROFF_NOTI_NAME, _power_off_cb, NULL); - if (err < 0) - MSC_DBG_INFO("heynoti_subscribe failed"); - - err = heynoti_attach_handler(heynoti_id); - if (err < 0) - MSC_DBG_INFO("heynoti_attach_handler failed"); - } + int err = -1; + int fd = -1; /*load functions from plusin(s)*/ err = msc_load_functions(); if (err != MS_MEDIA_ERR_NONE) { - MSC_DBG_ERR("function load failed"); - exit(0); + MSC_DBG_ERR("function load failed[%d]", err); + goto EXIT; } + /*Init main loop*/ + scanner_mainloop = g_main_loop_new(NULL, FALSE); + /*Init for register file*/ /*These are a communicator for thread*/ if (!scan_queue) scan_queue = g_async_queue_new(); if (!reg_queue) reg_queue = g_async_queue_new(); if (!storage_queue) storage_queue = g_async_queue_new(); - /*Init mutex variable*/ - if (!db_mutex) db_mutex = g_mutex_new(); - - /*prepare socket*/ - /* Create and bind new UDP socket */ - if (ms_ipc_create_server_socket(MS_PROTOCOL_UDP, MS_SCAN_DAEMON_PORT, &sockfd) - != MS_MEDIA_ERR_NONE) { - MSC_DBG_ERR("Failed to create socket\n"); - exit(0); - } else { - context = g_main_loop_get_context(scanner_mainloop); - - /* Create new channel to watch udp socket */ - channel = g_io_channel_unix_new(sockfd); - source = g_io_create_watch(channel, G_IO_IN); - - /* Set callback to be called when socket is readable */ - g_source_set_callback(source, (GSourceFunc)msc_receive_request, NULL, NULL); - g_source_attach(source, context); - g_source_unref(source); + /* Create pipe */ + err = unlink(MS_SCANNER_FIFO_PATH_REQ); + if (err !=0) { + MSC_DBG_STRERROR("unlink failed"); } + err = mkfifo(MS_SCANNER_FIFO_PATH_REQ, MS_SCANNER_FIFO_MODE); + if (err !=0) { + MSC_DBG_STRERROR("mkfifo failed"); + return MS_MEDIA_ERR_INTERNAL; + } + + fd = open(MS_SCANNER_FIFO_PATH_REQ, O_RDWR); + if (fd < 0) { + MSC_DBG_STRERROR("fifo open failed"); + return MS_MEDIA_ERR_FILE_OPEN_FAIL; + } + + context = g_main_loop_get_context(scanner_mainloop); + + /* Create new channel to watch pipe */ + channel = g_io_channel_unix_new(fd); + source = g_io_create_watch(channel, G_IO_IN); + + /* Set callback to be called when pipe is readable */ + g_source_set_callback(source, (GSourceFunc)msc_receive_request, NULL, NULL); + g_source_attach(source, context); + g_source_unref(source); + /*create each threads*/ storage_scan_thread = g_thread_new("storage_scan_thread", (GThreadFunc)msc_storage_scan_thread, NULL); scan_thread = g_thread_new("scanner_thread", (GThreadFunc)msc_directory_scan_thread, NULL); @@ -304,24 +255,19 @@ int main(int argc, char **argv) g_io_channel_unref(channel); } - heynoti_unsubscribe(heynoti_id, POWEROFF_NOTI_NAME, _power_off_cb); - heynoti_close(heynoti_id); - if (scan_queue) g_async_queue_unref(scan_queue); if (reg_queue) g_async_queue_unref(reg_queue); if (storage_queue) g_async_queue_unref(storage_queue); - /*Clear db mutex variable*/ - if (db_mutex) g_mutex_free (db_mutex); - - /*close socket*/ - close(sockfd); + /*close pipe*/ + close(fd); /*unload functions*/ msc_unload_functions(); +EXIT: MSC_DBG_INFO("SCANNER IS END"); - exit(0); + return 0; } diff --git a/src/server/include/media-server-db-svc.h b/src/server/include/media-server-db-svc.h index 4f47db1..c951f92 100755 --- a/src/server/include/media-server-db-svc.h +++ b/src/server/include/media-server-db-svc.h @@ -35,6 +35,7 @@ typedef int (*CONNECT)(void**, uid_t, char **); typedef int (*DISCONNECT)(void*, char **); typedef int (*SET_ALL_STORAGE_ITEMS_VALIDITY)(void*, int, int, uid_t,char **); +typedef int (*CHECK_DB)(void*, uid_t uid, char **); int ms_load_functions(void); @@ -51,4 +52,7 @@ ms_disconnect_db(void ***handle); int ms_invalidate_all_items(void **handle, ms_storage_type_t store_type, uid_t uid); +int +ms_check_db_upgrade(void **handle, uid_t uid); + #endif /*_MEDIA_SERVER_DB_SVC_H_*/ \ No newline at end of file diff --git a/src/server/include/media-server-dbg.h b/src/server/include/media-server-dbg.h index a4130f9..0c32939 100755 --- a/src/server/include/media-server-dbg.h +++ b/src/server/include/media-server-dbg.h @@ -19,15 +19,6 @@ * */ -/** - * This file defines api utilities of contents manager engines. - * - * @file media-server-dbg.h - * @author Yong Yeon Kim(yy9875.kim@samsung.com) - * @version 1.0 - * @brief - */ - #ifndef _MEDIA_SERVER_DBG_H_ #define _MEDIA_SERVER_DBG_H_ @@ -43,8 +34,7 @@ #define MS_DBG_STRERROR(fmt) do { \ char buf[BUF_LENGTH] = {0,}; \ - strerror_r(errno, buf, BUF_LENGTH); \ - LOGE(fmt" : STANDARD ERROR [%s]", buf); \ + LOGE(fmt" : STANDARD ERROR [%s]", strerror_r(errno, buf, BUF_LENGTH)); \ } while (0) #define MS_DBG_SLOG(fmt, args...) do{ if (true) { \ diff --git a/src/server/include/media-server-scanner.h b/src/server/include/media-server-scanner.h index 735a5df..d9ff3fa 100755 --- a/src/server/include/media-server-scanner.h +++ b/src/server/include/media-server-scanner.h @@ -19,10 +19,13 @@ * */ -int ms_scanner_start(void); +#ifndef _MEDIA_SERVER_SCANNER_H +#define _MEDIA_SERVER_SCANNER_H +int ms_scanner_start(void); bool ms_get_scanner_status(void); - void ms_reset_scanner_status(void); +int ms_get_scanner_pid(void); +void ms_cleanup_scanner(void); -int ms_get_scanner_pid(void); \ No newline at end of file +#endif /*_MEDIA_SERVER_SCANNER_H*/ \ No newline at end of file diff --git a/src/server/include/media-server-socket.h b/src/server/include/media-server-socket.h index 17e1cdd..6f7cae1 100755 --- a/src/server/include/media-server-socket.h +++ b/src/server/include/media-server-socket.h @@ -19,29 +19,18 @@ * */ -/** - * This file defines api utilities of contents manager engines. - * - * @file media-server-thumb.c - * @author Yong Yeon Kim(yy9875.kim@samsung.com) - * @version 1.0 - * @brief - */ #ifndef _MEDIA_SERVER_SOCKET_H_ #define _MEDIA_SERVER_SOCKET_H_ #include "media-common-types.h" #include "media-server-ipc.h" -gboolean ms_read_socket(GIOChannel *src, GIOCondition condition, gpointer data); - -gboolean ms_receive_message_from_scanner(GIOChannel *src, GIOCondition condition, gpointer data); - -int ms_send_scan_request(ms_comm_msg_s *send_msg); - -int ms_send_storage_scan_request(ms_storage_type_t storage_type, ms_dir_scan_type_t scan_type); - -gboolean ms_read_db_socket(GIOChannel *src, GIOCondition condition, gpointer data); +gboolean ms_read_socket(gpointer user_data); gboolean ms_read_db_tcp_socket(GIOChannel *src, GIOCondition condition, gpointer data); +gboolean ms_read_db_tcp_batch_socket(GIOChannel *src, GIOCondition condition, gpointer data); +int ms_send_scan_request(ms_comm_msg_s *send_msg, int client_sock); +int ms_send_storage_scan_request(ms_storage_type_t storage_type, ms_dir_scan_type_t scan_type); +gboolean ms_receive_message_from_scanner(GIOChannel *src, GIOCondition condition, gpointer data); +int ms_remove_request_owner(int pid, const char *req_path); #endif /*_MEDIA_SERVER_SOCKET_H_*/ diff --git a/src/server/include/media-server-thumb.h b/src/server/include/media-server-thumb.h index 0477b61..40045b6 100755 --- a/src/server/include/media-server-thumb.h +++ b/src/server/include/media-server-thumb.h @@ -30,35 +30,10 @@ #define MAX_THUMB_REQUEST 100 -GMainLoop * -ms_get_thumb_thread_mainloop(void); - -int -ms_thumb_get_server_pid(); - -void -ms_thumb_reset_server_status(); - -gpointer -ms_thumb_agent_start_thread(gpointer data); - -int -_ms_thumb_create_socket(int sock_type, int *sock); - -int -_ms_thumb_create_udp_socket(int *sock); - -gboolean -_ms_thumb_agent_prepare_udp_socket(); - -int -_ms_thumb_recv_msg(int sock, thumbMsg *msg); - -int -_ms_thumb_recv_udp_msg(int sock, int header_size, thumbMsg *msg, struct sockaddr_un *from_addr, unsigned int *from_size); - -int -_ms_thumb_set_buffer(thumbMsg *req_msg, unsigned char **buf, int *buf_size); +GMainLoop * ms_get_thumb_thread_mainloop(void); +int ms_thumb_get_server_pid(); +void ms_thumb_reset_server_status(); +gpointer ms_thumb_agent_start_thread(gpointer data); #endif /*_MEDIA_SERVER_THUMB_H_*/ diff --git a/src/server/media-server-db-svc.c b/src/server/media-server-db-svc.c index d2eb23f..551d9cb 100755 --- a/src/server/media-server-db-svc.c +++ b/src/server/media-server-db-svc.c @@ -33,7 +33,6 @@ #include "media-util.h" #include "media-common-utils.h" -#include "media-common-drm.h" #include "media-server-dbg.h" #include "media-server-db-svc.h" @@ -53,6 +52,7 @@ enum func_list { eCONNECT, eDISCONNECT, eSET_ALL_VALIDITY, + eCHECK_DB, eFUNC_MAX }; @@ -116,6 +116,7 @@ ms_load_functions(void) "connect_db", "disconnect_db", "set_all_storage_items_validity", + "check_db", }; /*init array for adding name of so*/ so_array = g_array_new(FALSE, FALSE, sizeof(char*)); @@ -153,7 +154,7 @@ ms_load_functions(void) dlerror(); /* Clear any existing error */ /*allocate for array of functions*/ - MS_MALLOC(func_array, sizeof(void*) * lib_num); + MS_MALLOC(func_array, sizeof(void**) * lib_num); if (func_array == NULL) { MS_DBG_ERR("malloc failed"); MS_SAFE_FREE(func_handle); @@ -225,6 +226,10 @@ ms_connect_db(void ***handle, uid_t uid) char * err_msg = NULL; MS_MALLOC(*handle, sizeof (void*) * lib_num); + if (*handle == NULL) { + MS_DBG_ERR("MS_MALLOC failed"); + return TRUE; + } for (lib_index = 0; lib_index < lib_num; lib_index++) { ret = ((CONNECT)func_array[lib_index][eCONNECT])(&((*handle)[lib_index]), uid, &err_msg); /*dlopen*/ @@ -283,3 +288,23 @@ ms_invalidate_all_items(void **handle, ms_storage_type_t store_type, uid_t uid) return res; } +int +ms_check_db_upgrade(void **handle, uid_t uid) +{ + int lib_index; + int res = MS_MEDIA_ERR_NONE; + int ret; + char *err_msg = NULL; + MS_DBG(""); + for (lib_index = 0; lib_index < lib_num; lib_index++) { + ret = ((CHECK_DB)func_array[lib_index][eCHECK_DB])(handle[lib_index], uid, &err_msg); /*dlopen*/ + if (ret != 0) { + MS_DBG_ERR("error : %s [%s]", g_array_index(so_array, char*, lib_index), err_msg); + MS_SAFE_FREE(err_msg); + res = MS_MEDIA_ERR_DB_UPDATE_FAIL; + } + } + MS_DBG(""); + return res; +} + diff --git a/src/server/media-server-db.c b/src/server/media-server-db.c index 53baf92..656fc46 100755 --- a/src/server/media-server-db.c +++ b/src/server/media-server-db.c @@ -19,15 +19,6 @@ * */ -/** - * This file defines api utilities of media db write. - * - * @file media-server-db.c - * @author Haejeong Kim(backto.kim@samsung.com) - * @version 1.0 - * @brief - */ - #include #include "media-util.h" @@ -62,9 +53,8 @@ gboolean ms_db_thread(void *data) GMainContext *context = NULL; MediaDBHandle *db_handle = NULL; - - /* Create Socket*/ - ret = ms_ipc_create_server_socket(MS_PROTOCOL_UDP, MS_DB_UPDATE_PORT, &sockfd); + /* Create TCP Socket*/ + ret = ms_ipc_create_server_socket(MS_PROTOCOL_TCP, MS_DB_UPDATE_PORT, &sockfd); if(ret != MS_MEDIA_ERR_NONE) { MS_DBG_ERR("Failed to create socket"); return FALSE; @@ -88,7 +78,7 @@ gboolean ms_db_thread(void *data) source = g_io_create_watch(channel, G_IO_IN); /* Set callback to be called when socket is readable */ - g_source_set_callback(source, (GSourceFunc)ms_read_db_socket, db_handle, NULL); + g_source_set_callback(source, (GSourceFunc)ms_read_db_tcp_socket, db_handle, NULL); g_source_attach(source, context); /* Create new channel to watch TCP socket */ @@ -96,7 +86,7 @@ gboolean ms_db_thread(void *data) tcp_source = g_io_create_watch(tcp_channel, G_IO_IN); /* Set callback to be called when socket is readable */ - g_source_set_callback(tcp_source, (GSourceFunc)ms_read_db_tcp_socket, db_handle, NULL); + g_source_set_callback(tcp_source, (GSourceFunc)ms_read_db_tcp_batch_socket, db_handle, NULL); g_source_attach(tcp_source, context); g_main_context_push_thread_default(context); @@ -116,7 +106,6 @@ gboolean ms_db_thread(void *data) g_io_channel_shutdown(channel, FALSE, NULL); g_io_channel_unref(channel); - /*close socket*/ close(sockfd); close(tcp_sockfd); diff --git a/src/server/media-server-main.c b/src/server/media-server-main.c index d3df529..5bb7d2c 100755 --- a/src/server/media-server-main.c +++ b/src/server/media-server-main.c @@ -19,27 +19,16 @@ * */ -/** - * This file defines api utilities of contents manager engines. - * - * @file media-server-main.c - * @author Yong Yeon Kim(yy9875.kim@samsung.com) - * @version 1.0 - * @brief - */ - #include #include +#include #include #include #include #include -#include -#include #include "media-util.h" #include "media-common-utils.h" -#include "media-common-drm.h" #include "media-common-external-storage.h" #include "media-server-dbg.h" #include "media-server-db-svc.h" @@ -50,9 +39,19 @@ #define APP_NAME "media-server" -extern GMutex *scanner_mutex; +extern GMutex scanner_mutex; GMainLoop *mainloop = NULL; +bool power_off; /*If this is TRUE, poweroff notification received*/ + +static void __ms_check_mediadb(void); +static void __ms_add_signal_handler(void); +static void __ms_remove_event_receiver(void); +static void __ms_add_event_receiver(GIOChannel *channel); +static void __ms_remove_requst_receiver(GIOChannel *channel); +static void __ms_add_requst_receiver(GMainLoop *mainloop, GIOChannel **channel); + +static char *priv_lang = NULL; bool check_process() { @@ -109,14 +108,13 @@ bool check_process() return ret; } -void init_process() +void _power_off_cb(void* data) { + MS_DBG_ERR("POWER OFF"); -} + GIOChannel *channel = (GIOChannel *)data; -static void _power_off_cb(void* data) -{ - MS_DBG_ERR("POWER OFF"); + power_off = TRUE; /*Quit Thumbnail Thread*/ GMainLoop *thumb_mainloop = ms_get_thumb_thread_mainloop(); @@ -130,10 +128,9 @@ static void _power_off_cb(void* data) g_main_loop_quit(db_mainloop); } - /*Quit Main Thread*/ - if (mainloop && g_main_loop_is_running(mainloop)) { - g_main_loop_quit(mainloop); - } + __ms_remove_requst_receiver(channel); + + __ms_remove_event_receiver(); return; } @@ -146,13 +143,19 @@ static void _db_clear(void) /*load functions from plusin(s)*/ err = ms_load_functions(); if (err != MS_MEDIA_ERR_NONE) { - MS_DBG_ERR("function load failed"); - exit(0); + MS_DBG_ERR("function load failed [%d]", err); + return; } /*connect to media db, if conneting is failed, db updating is stopped*/ ms_connect_db(&handle,tzplatform_getuid(TZ_USER_NAME)); + /* check schema of db is chaged and need upgrade */ + MS_DBG_WARN("Check DB upgrade start"); + if (ms_check_db_upgrade(handle,tzplatform_getuid(TZ_USER_NAME)) != MS_MEDIA_ERR_NONE) + MS_DBG_ERR("ms_check_db_upgrade fail"); + MS_DBG_WARN("Check DB upgrade end"); + /*update just valid type*/ if (ms_invalidate_all_items(handle, MS_STORAGE_EXTERNAL, tzplatform_getuid(TZ_USER_NAME)) != MS_MEDIA_ERR_NONE) MS_DBG_ERR("ms_change_valid_type fail"); @@ -166,35 +169,32 @@ static void _db_clear(void) void _ms_signal_handler(int n) { - MS_DBG("Receive SIGNAL"); int stat, pid, thumb_pid; int scanner_pid; thumb_pid = ms_thumb_get_server_pid(); - MS_DBG("Thumbnail server pid : %d", thumb_pid); - scanner_pid = ms_get_scanner_pid(); - pid = waitpid(-1, &stat, WNOHANG); - /* check pid of child process of thumbnail thread */ - MS_DBG_ERR("[PID %d] signal ID %d", pid, n); - - if (pid == thumb_pid) { - MS_DBG_ERR("Thumbnail server is dead"); - ms_thumb_reset_server_status(); - } else if (pid == scanner_pid) { - MS_DBG_ERR("Scanner is dead"); - ms_reset_scanner_status(); - } else if (pid == -1) { - MS_DBG_ERR("%s", strerror(errno)); - } - - if (WIFEXITED(stat)) { - MS_DBG_ERR("normal termination , exit status : %d", WEXITSTATUS(stat)); - } else if (WIFSIGNALED(stat)) { - MS_DBG_ERR("abnormal termination , signal number : %d", WTERMSIG(stat)); - } else if (WIFSTOPPED(stat)) { - MS_DBG_ERR("child process is stoped, signal number : %d", WSTOPSIG(stat)); + while ((pid = waitpid(-1, &stat, WNOHANG)) > 0) { + /* check pid of child process of thumbnail thread */ + if (pid == thumb_pid) { + MS_DBG_ERR("[%d] Thumbnail server is stopped by media-server", pid); + ms_thumb_reset_server_status(); + } else if (pid == scanner_pid) { + MS_DBG_ERR("[%d] Scanner is stopped by media-server", pid); + ms_reset_scanner_status(); + } else { + MS_DBG_ERR("[%d] is stopped", pid); + } +/* + if (WIFEXITED(stat)) { + MS_DBG_ERR("normal termination , exit status : %d", WEXITSTATUS(stat)); + } else if (WIFSIGNALED(stat)) { + MS_DBG_ERR("abnormal termination , signal number : %d", WTERMSIG(stat)); + } else if (WIFSTOPPED(stat)) { + MS_DBG_ERR("child process is stoped, signal number : %d", WSTOPSIG(stat)); + } +*/ } return; @@ -204,16 +204,15 @@ static void _ms_new_global_variable(void) { /*Init mutex variable*/ /*media scanner stop/start mutex*/ - if (!scanner_mutex) scanner_mutex = g_mutex_new(); + g_mutex_init(&scanner_mutex); } static void _ms_free_global_variable(void) { /*Clear mutex variable*/ - if (scanner_mutex) g_mutex_free(scanner_mutex); + g_mutex_clear(&scanner_mutex); } - void _ms_mmc_vconf_cb(void *data) { @@ -233,9 +232,6 @@ _ms_mmc_vconf_cb(void *data) /*remove added watch descriptors */ ms_present_mmc_status(MS_SDCARD_REMOVED); - if (!ms_drm_extract_ext_memory()) - MS_DBG_ERR("ms_drm_extract_ext_memory failed"); - ms_send_storage_scan_request(MS_STORAGE_EXTERNAL, MS_SCAN_INVALID); } else if (status == VCONFKEY_SYSMAN_MMC_MOUNTED) { @@ -243,15 +239,78 @@ _ms_mmc_vconf_cb(void *data) ms_present_mmc_status(MS_SDCARD_INSERTED); - if (!ms_drm_insert_ext_memory()) - MS_DBG_ERR("ms_drm_insert_ext_memory failed"); - ms_send_storage_scan_request(MS_STORAGE_EXTERNAL, ms_get_mmc_state()); } return; } +void +_ms_change_lang_vconf_cb(keynode_t *key, void* data) +{ + char lang[10] = {0,}; + char *eng = "en"; + char *chi = "zh"; + char *jpn = "ja"; + char *kor = "ko"; + bool need_update = FALSE; + + if (!ms_config_get_str(VCONFKEY_LANGSET, lang)) { + MS_DBG_ERR("Get VCONFKEY_LANGSET failed."); + return; + } + + MS_DBG("CURRENT LANGUAGE [%s %s]", priv_lang, lang); + + if (strcmp(priv_lang, lang) == 0) { + need_update = FALSE; + } else if ((strncmp(lang, eng, strlen(eng)) == 0) || + (strncmp(lang, chi, strlen(chi)) == 0) || + (strncmp(lang, jpn, strlen(jpn)) == 0) || + (strncmp(lang, kor, strlen(kor)) == 0)) { + need_update = TRUE; + } else { + if ((strncmp(priv_lang, eng, strlen(eng)) == 0) || + (strncmp(priv_lang, chi, strlen(chi)) == 0) || + (strncmp(priv_lang, jpn, strlen(jpn)) == 0) || + (strncmp(priv_lang, kor, strlen(kor)) == 0)) { + need_update = TRUE; + } + } + + if (need_update) { + ms_send_storage_scan_request(MS_STORAGE_INTERNAL, MS_SCAN_META); + } else { + MS_DBG_WARN("language is changed but do not update meta data"); + } + + MS_SAFE_FREE(priv_lang); + priv_lang = strdup(lang); + + return; +} + +static void _ms_check_pw_status(void) +{ + int pw_status = 0; + + if (!ms_config_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &pw_status)) { + MS_DBG_ERR("Get VCONFKEY_SYSMAN_POWER_OFF_STATUS failed."); + } + + if (pw_status == VCONFKEY_SYSMAN_POWER_OFF_DIRECT || + pw_status == VCONFKEY_SYSMAN_POWER_OFF_RESTART) { + power_off = TRUE; + + while(1) { + MS_DBG_WARN("wait power off"); + sleep(3); + } + } + + return; +} + static int _mkdir(const char *dir, mode_t mode) { char tmp[256]; char *p = NULL; @@ -274,129 +333,171 @@ int main(int argc, char **argv) { GThread *db_thread = NULL; GThread *thumb_thread = NULL; - GSource *source = NULL; GIOChannel *channel = NULL; - GMainContext *context = NULL; - int sockfd = MS_SOCK_NOT_ALLOCATE; - int err; - int heynoti_id; +#if 0 bool check_result = false; - struct sigaction sigset; +#endif + power_off = FALSE; + _ms_check_pw_status(); + +#if 0 check_result = check_process(); if (check_result == false) - exit(0); - - if (!g_thread_supported()) { - g_thread_init(NULL); - } - + goto EXIT; +#endif /*Init main loop*/ mainloop = g_main_loop_new(NULL, FALSE); - /*heynoti for power off*/ - if ((heynoti_id = heynoti_init()) <0) { - MS_DBG("heynoti_init failed"); - } else { - err = heynoti_subscribe(heynoti_id, POWEROFF_NOTI_NAME, _power_off_cb, NULL); - if (err < 0) - MS_DBG("heynoti_subscribe failed"); + _ms_new_global_variable(); + + __ms_add_requst_receiver(mainloop, &channel); - err = heynoti_attach_handler(heynoti_id); - if (err < 0) - MS_DBG("heynoti_attach_handler failed"); + /* recevie event from other modules */ + __ms_add_event_receiver(channel); + + __ms_add_signal_handler(); + + /*create each threads*/ + db_thread = g_thread_new("db_thread", (GThreadFunc)ms_db_thread, NULL); + thumb_thread = g_thread_new("thumb_agent_thread", (GThreadFunc)ms_thumb_agent_start_thread, NULL); + + /*clear previous data of sdcard on media database and check db status for updating*/ + while(!ms_db_get_thread_status()) { + MS_DBG_ERR("wait db thread"); + sleep(1); } - _ms_new_global_variable(); + /* update media DB */ + __ms_check_mediadb(); + + /*Active flush */ + malloc_trim(0); + + + MS_DBG_ERR("*** Media Server is running ***"); + + g_main_loop_run(mainloop); + + g_thread_join(db_thread); + g_thread_join(thumb_thread); + + _ms_free_global_variable(); + + MS_DBG_ERR("*** Media Server is stopped ***"); +#if 0 +EXIT: +#endif + return 0; +} + +static void __ms_add_requst_receiver(GMainLoop *mainloop, GIOChannel **channel) +{ + + int sockfd = -1; + GSource *source = NULL; + GMainContext *context = NULL; /*prepare socket*/ /* create dir socket */ _mkdir("/var/run/media-server",S_IRWXU | S_IRWXG | S_IRWXO); /* Create and bind new UDP socket */ - if (ms_ipc_create_server_socket(MS_PROTOCOL_UDP, MS_SCANNER_PORT, &sockfd) + if (ms_ipc_create_server_socket(MS_PROTOCOL_TCP, MS_SCANNER_PORT, &sockfd) != MS_MEDIA_ERR_NONE) { MS_DBG_ERR("Failed to create socket"); + return; } else { context = g_main_loop_get_context(mainloop); /* Create new channel to watch udp socket */ - channel = g_io_channel_unix_new(sockfd); - source = g_io_create_watch(channel, G_IO_IN); + *channel = g_io_channel_unix_new(sockfd); + source = g_io_create_watch(*channel, G_IO_IN); /* Set callback to be called when socket is readable */ - g_source_set_callback(source, (GSourceFunc)ms_read_socket, NULL, NULL); + g_source_set_callback(source, (GSourceFunc)ms_read_socket, *channel, NULL); g_source_attach(source, context); g_source_unref(source); } +} - /*create each threads*/ - db_thread = g_thread_new("db_thread", (GThreadFunc)ms_db_thread, NULL); - thumb_thread = g_thread_new("thumb_agent_thread", (GThreadFunc)ms_thumb_agent_start_thread, NULL); +static void __ms_remove_requst_receiver(GIOChannel *channel) +{ + int fd = -1; + + /*close an IO channel*/ + fd = g_io_channel_unix_get_fd(channel); + g_io_channel_shutdown(channel, FALSE, NULL); + g_io_channel_unref(channel); - /*set vconf callback function*/ + if (fd > 0) { + if (close(fd) < 0) { + MS_DBG_STRERROR("CLOSE ERROR"); + } + } +} + +static void __ms_add_event_receiver(GIOChannel *channel) +{ + int err; + char lang[10] = {0,}; + + /*set power off callback function*/ +// ms_add_poweoff_event_receiver(_power_off_cb,channel); + + /*add noti receiver for SD card event */ err = vconf_notify_key_changed(VCONFKEY_SYSMAN_MMC_STATUS, (vconf_callback_fn) _ms_mmc_vconf_cb, NULL); if (err == -1) MS_DBG_ERR("add call back function for event %s fails", VCONFKEY_SYSMAN_MMC_STATUS); - MS_DBG("*********************************************************"); - MS_DBG("*** Begin to check tables of file manager in database ***"); - MS_DBG("*********************************************************"); + if (!ms_config_get_str(VCONFKEY_LANGSET, lang)) { + MS_DBG_ERR("Get VCONFKEY_LANGSET failed."); + return; + } + + priv_lang = strdup(lang); + + err = vconf_notify_key_changed(VCONFKEY_LANGSET, (vconf_callback_fn) _ms_change_lang_vconf_cb, NULL); + if (err == -1) + MS_DBG_ERR("add call back function for event %s fails", VCONFKEY_LANGSET); + +} + +static void __ms_remove_event_receiver(void) +{ + vconf_ignore_key_changed(VCONFKEY_SYSMAN_MMC_STATUS, + (vconf_callback_fn) _ms_mmc_vconf_cb); +} + +static void __ms_add_signal_handler(void) +{ + struct sigaction sigset; /* Add signal handler */ sigemptyset(&sigset.sa_mask); sigaddset(&sigset.sa_mask, SIGCHLD); - sigset.sa_flags = 0; + sigset.sa_flags = SA_RESTART |SA_NODEFER; sigset.sa_handler = _ms_signal_handler; if (sigaction(SIGCHLD, &sigset, NULL) < 0) { MS_DBG_STRERROR("sigaction failed"); } - /*clear previous data of sdcard on media database and check db status for updating*/ - while(!ms_db_get_thread_status()) { - MS_DBG("wait db thread"); - sleep(1); - } + signal(SIGPIPE,SIG_IGN); +} +static void __ms_check_mediadb(void) +{ + _db_clear(); - if (ms_is_mmc_inserted()) { - if (!ms_drm_insert_ext_memory()) - MS_DBG_ERR("ms_drm_insert_ext_memory failed"); + /* update internal storage */ + ms_send_storage_scan_request(MS_STORAGE_INTERNAL, MS_SCAN_PART); + /* update external storage */ + if (ms_is_mmc_inserted()) { ms_make_default_path_mmc(); ms_present_mmc_status(MS_SDCARD_INSERTED); ms_send_storage_scan_request(MS_STORAGE_EXTERNAL, ms_get_mmc_state()); } - - /*Active flush */ - malloc_trim(0); - - MS_DBG("*****************************************"); - MS_DBG("*** Server of File Manager is running ***"); - MS_DBG("*****************************************"); - - g_main_loop_run(mainloop); - g_thread_join(db_thread); - g_thread_join(thumb_thread); - - /*close an IO channel*/ - g_io_channel_shutdown(channel, FALSE, NULL); - g_io_channel_unref(channel); - - heynoti_unsubscribe(heynoti_id, POWEROFF_NOTI_NAME, _power_off_cb); - heynoti_close(heynoti_id); - - /*********** - **remove call back functions - ************/ - vconf_ignore_key_changed(VCONFKEY_SYSMAN_MMC_STATUS, - (vconf_callback_fn) _ms_mmc_vconf_cb); - - _ms_free_global_variable(); - - /*close socket*/ - close(sockfd); - - exit(0); } + diff --git a/src/server/media-server-scanner.c b/src/server/media-server-scanner.c index 2c50167..2dc7548 100755 --- a/src/server/media-server-scanner.c +++ b/src/server/media-server-scanner.c @@ -23,6 +23,9 @@ #include #include #include +#include +#include +#include #include "media-util.h" #include "media-server-ipc.h" @@ -40,14 +43,14 @@ extern GMainLoop *mainloop; extern GArray *owner_list; -GMutex *scanner_mutex; +GMutex scanner_mutex; static bool scanner_ready; static int alarm_id; -static int receive_id; static int child_pid; +static int receive_id; - +int fifo_fd; static int _ms_check_remain_task(void) { @@ -76,24 +79,22 @@ ms_db_status_type_t ms_check_scanning_status(void) static gboolean _ms_stop_scanner (gpointer user_data) { - int sockfd; - int task_num; - GIOChannel *src = user_data; + int task_num = MS_NO_REMAIN_TASK; - g_mutex_lock(scanner_mutex); + g_mutex_lock(&scanner_mutex); /* check status of scanner */ /* If some task remain or scanner is running, scanner must not stop*/ task_num = _ms_check_remain_task(); if (task_num != MS_NO_REMAIN_TASK) { MS_DBG("[%d] task(s) remains", task_num); - g_mutex_unlock(scanner_mutex); + g_mutex_unlock(&scanner_mutex); return TRUE; } if (ms_check_scanning_status() == MS_DB_UPDATING) { MS_DBG("DB is updating"); - g_mutex_unlock(scanner_mutex); + g_mutex_unlock(&scanner_mutex); return TRUE; } else { MS_DBG("DB updating is not working"); @@ -103,15 +104,23 @@ static gboolean _ms_stop_scanner (gpointer user_data) if (child_pid >0 ) { if (kill(child_pid, SIGKILL) < 0) { MS_DBG_STRERROR("kill failed"); - g_mutex_unlock(scanner_mutex); + g_mutex_unlock(&scanner_mutex); return TRUE; } } - /* close socket */ - sockfd = g_io_channel_unix_get_fd(src); - g_io_channel_shutdown(src, FALSE, NULL); - g_io_channel_unref(src); - close(sockfd); + MS_DBG("KILL SCANNER"); + + /* close & delete FIFO */ + int res_fd = -1; + GIOChannel *res_channel = user_data; + + res_fd = g_io_channel_unix_get_fd(res_channel); + close(res_fd); + + unlink(MS_SCANNER_FIFO_PATH_RES); + unlink(MS_SCANNER_FIFO_PATH_REQ); + +// ms_reset_scanner_status(); g_source_destroy(g_main_context_find_source_by_id(g_main_loop_get_context (mainloop), alarm_id)); g_source_destroy(g_main_context_find_source_by_id(g_main_loop_get_context (mainloop), receive_id)); @@ -119,6 +128,26 @@ static gboolean _ms_stop_scanner (gpointer user_data) return FALSE; } +void ms_cleanup_scanner(void) +{ + g_mutex_lock(&scanner_mutex); + MS_DBG_ERR("_ms_cleanup_scanner START"); + + close(fifo_fd); + MS_DBG_ERR("close fd[%d]", fifo_fd); + + unlink(MS_SCANNER_FIFO_PATH_RES); + unlink(MS_SCANNER_FIFO_PATH_REQ); + + g_source_destroy(g_main_context_find_source_by_id(g_main_loop_get_context (mainloop), alarm_id)); + g_source_destroy(g_main_context_find_source_by_id(g_main_loop_get_context (mainloop), receive_id)); + + g_mutex_unlock(&scanner_mutex); + + MS_DBG_ERR("_ms_cleanup_scanner END"); + + return; +} static void _ms_add_timeout(guint interval, GSourceFunc func, gpointer data) { @@ -135,77 +164,83 @@ int ms_scanner_start(void) { int pid; - g_mutex_lock(scanner_mutex); + g_mutex_lock(&scanner_mutex); if (child_pid > 0) { MS_DBG_ERR("media scanner is already started"); - g_mutex_unlock(scanner_mutex); + g_mutex_unlock(&scanner_mutex); return MS_MEDIA_ERR_NONE; } if((pid = fork()) < 0) { MS_DBG_ERR("Fork error\n"); + g_mutex_unlock(&scanner_mutex); } else if (pid > 0) { /* parent process */ /* wait until scanner is ready*/ int ret = MS_MEDIA_ERR_NONE; - int sockfd = -1; int err = -1; - int n_reuse = 1; - struct sockaddr_un serv_addr; - unsigned int serv_addr_len = -1; - int port = MS_SCAN_COMM_PORT; + int fd = -1; ms_comm_msg_s recv_msg; + int scanner_status = -1; - GSource *res_source = NULL; - GIOChannel *res_channel = NULL; - GMainContext *res_context = NULL; + err = unlink(MS_SCANNER_FIFO_PATH_RES); + if (err !=0) { + MS_DBG_STRERROR("unlink failed"); + } + err = mkfifo(MS_SCANNER_FIFO_PATH_RES, MS_SCANNER_FIFO_MODE); + if (err !=0) { + MS_DBG_STRERROR("mkfifo failed"); + return MS_MEDIA_ERR_INTERNAL; + } - /*Create Socket*/ - ret = ms_ipc_create_server_socket(MS_PROTOCOL_UDP, MS_SCAN_COMM_PORT, &sockfd); - if (ret != MS_MEDIA_ERR_NONE) { - MS_DBG_ERR("ms_ipc_create_server_socket failed [%d]",ret); - g_mutex_unlock(scanner_mutex); - return MS_MEDIA_ERR_SOCKET_CONN; + fd = open(MS_SCANNER_FIFO_PATH_RES, O_RDWR); + if (fd < 0) { + MS_DBG_STRERROR("fifo open failed"); + return MS_MEDIA_ERR_FILE_OPEN_FAIL; } - /*Receive Response*/ - serv_addr_len = sizeof(serv_addr); + /* read() is blocked until media scanner sends message */ + err = read(fd, &recv_msg, sizeof(recv_msg)); + if (err < 0) { + MS_DBG_STRERROR("fifo read failed"); + close(fd); + return MS_MEDIA_ERR_FILE_READ_FAIL; + } - err = ms_ipc_wait_message(sockfd, &recv_msg, sizeof(recv_msg), &serv_addr, NULL); - if (err != MS_MEDIA_ERR_NONE) { - ret = err; - close(sockfd); + scanner_status = recv_msg.msg_type; + if (scanner_status == MS_MSG_SCANNER_READY) { + GSource *res_source = NULL; + GIOChannel *res_channel = NULL; + GMainContext *res_context = NULL; + + MS_DBG_ERR("SCANNER is ready"); + scanner_ready = true; + child_pid = pid; + /* attach result receiving socket to mainloop */ + res_context = g_main_loop_get_context(mainloop); + + /* Create new channel to watch udp socket */ + res_channel = g_io_channel_unix_new(fd); + res_source = g_io_create_watch(res_channel, G_IO_IN); + + /* Set callback to be called when socket is readable */ + g_source_set_callback(res_source, (GSourceFunc)ms_receive_message_from_scanner, NULL, NULL); + receive_id = g_source_attach(res_source, res_context); + g_source_unref(res_source); + + _ms_add_timeout(30, (GSourceFunc)_ms_stop_scanner, res_channel); + + ret = MS_MEDIA_ERR_NONE; } else { - int scanner_status = recv_msg.msg_type; - if (scanner_status == MS_MSG_SCANNER_READY) { - MS_DBG("RECEIVE OK [%d] %d", recv_msg.msg_type, pid); - scanner_ready = true; - child_pid = pid; - - /* attach result receiving socket to mainloop */ - res_context = g_main_loop_get_context(mainloop); - - /* Create new channel to watch udp socket */ - res_channel = g_io_channel_unix_new(sockfd); - res_source = g_io_create_watch(res_channel, G_IO_IN); - - /* Set callback to be called when socket is readable */ - g_source_set_callback(res_source, (GSourceFunc)ms_receive_message_from_scanner, NULL, NULL); - receive_id = g_source_attach(res_source, res_context); - g_source_unref(res_source); - - _ms_add_timeout(30, (GSourceFunc)_ms_stop_scanner, res_channel); - - ret = MS_MEDIA_ERR_NONE; - } else { - MS_DBG_ERR("Receive wrong message from scanner[%d]", scanner_status); - close(sockfd); - ret = MS_MEDIA_ERR_SOCKET_RECEIVE; - } + MS_DBG_ERR("SCANNER is not ready"); + ret = MS_MEDIA_ERR_SCANNER_NOT_READY; + close(fd); } - g_mutex_unlock(scanner_mutex); + fifo_fd = fd; + + g_mutex_unlock(&scanner_mutex); return ret; /* attach socket receive message callback */ @@ -214,7 +249,7 @@ int ms_scanner_start(void) MS_DBG_ERR("CHILD PROCESS"); MS_DBG("EXECUTE MEDIA SCANNER"); execl(MEDIA_SERVER_PATH, "media-scanner", NULL); - g_mutex_unlock(scanner_mutex); + g_mutex_unlock(&scanner_mutex); } return MS_MEDIA_ERR_NONE; @@ -230,7 +265,7 @@ void ms_reset_scanner_status(void) child_pid = 0; scanner_ready = false; - g_mutex_unlock(scanner_mutex); + g_mutex_unlock(&scanner_mutex); } int ms_get_scanner_pid(void) diff --git a/src/server/media-server-socket.c b/src/server/media-server-socket.c index 296606c..db731a9 100755 --- a/src/server/media-server-socket.c +++ b/src/server/media-server-socket.c @@ -19,23 +19,16 @@ * */ -/** - * This file defines api utilities of contents manager engines. - * - * @file media-server-thumb.c - * @author Yong Yeon Kim(yy9875.kim@samsung.com) - * @version 1.0 - * @brief - */ - -#define _GNU_SOURCE - #include #include +#include +#include #include #include #include #include +#include +#include #include "media-util.h" #include "media-util-internal.h" @@ -45,30 +38,71 @@ #include "media-server-db-svc.h" #include "media-server-scanner.h" #include "media-server-socket.h" -#include "media-server-db.h" extern GAsyncQueue *scan_queue; GAsyncQueue* ret_queue; GArray *owner_list; -extern GMutex *scanner_mutex; +GMutex scanner_mutex; +gint cur_running_task; + +extern bool power_off; typedef struct ms_req_owner_data { int pid; int index; - struct sockaddr_un *client_addr; - int client_socket; + int client_sockfd; + char *req_path; }ms_req_owner_data; -int _ms_add_owner(ms_req_owner_data *owner_data) +static int __ms_add_owner(int pid, int client_sock, char *path) { - owner_data->index = -1; - g_array_append_val(owner_list, owner_data); + if (pid != 0) { + ms_req_owner_data *owner_data = NULL; + int len = strlen(path); + + if (len > 0) { + /* If owner list is NULL, create it */ + /* pid and client address are stored in ower list */ + /* These are used for sending result of scanning */ + if (owner_list == NULL) { + /*create array for processing overlay data*/ + owner_list = g_array_new (FALSE, FALSE, sizeof (ms_req_owner_data *)); + if (owner_list == NULL) { + MS_DBG_ERR("g_array_new error"); + return MS_MEDIA_ERR_OUT_OF_MEMORY; + } + } + + /* store pid and client address */ + MS_MALLOC(owner_data, sizeof(ms_req_owner_data)); + + if (owner_data == NULL) { + MS_DBG_ERR("MS_MALLOC failed"); + g_array_free (owner_list, FALSE); + owner_list = NULL; + return MS_MEDIA_ERR_OUT_OF_MEMORY; + } + + owner_data->pid = pid; + owner_data->client_sockfd = client_sock; + + if (path[len -1] == '/') + path[len -1] = '\0'; + owner_data->req_path = strdup(path); + // MS_DBG("the length of array : %d", owner_list->len); + // MS_DBG("pid : %d", owner_data->pid); + // MS_DBG("client_addr : %p", owner_data->client_addr); + + owner_data->index = -1; + g_array_append_val(owner_list, owner_data); + } + } return MS_MEDIA_ERR_NONE; } -int _ms_find_owner(int pid, ms_req_owner_data **owner_data) +static int __ms_find_owner(int pid, const char *req_path, ms_req_owner_data **owner_data) { int i; int len = owner_list->len; @@ -81,7 +115,8 @@ int _ms_find_owner(int pid, ms_req_owner_data **owner_data) for (i=0; i < len; i++) { data = g_array_index(owner_list, ms_req_owner_data*, i); MS_DBG("%d %d", data->pid, pid); - if (data->pid == pid) { + MS_DBG("%s %s", data->req_path, req_path); + if (data->pid == pid && (strcmp(data->req_path, req_path) == 0)) { data->index = i; *owner_data = data; MS_DBG("FIND OWNER"); @@ -92,12 +127,11 @@ int _ms_find_owner(int pid, ms_req_owner_data **owner_data) return MS_MEDIA_ERR_NONE; } -int _ms_delete_owner(ms_req_owner_data *owner_data) +static int __ms_delete_owner(ms_req_owner_data *owner_data) { if (owner_data->index != -1) { g_array_remove_index(owner_list, owner_data->index); - close(owner_data->client_socket); - MS_SAFE_FREE(owner_data->client_addr); + MS_SAFE_FREE(owner_data->req_path); MS_SAFE_FREE(owner_data); MS_DBG("DELETE OWNER"); } @@ -105,55 +139,182 @@ int _ms_delete_owner(ms_req_owner_data *owner_data) return MS_MEDIA_ERR_NONE; } -gboolean ms_read_socket(GIOChannel *src, GIOCondition condition, gpointer data) +static char* __ms_get_path(uid_t uid) +{ + char *result_psswd = NULL; + struct group *grpinfo = NULL; + if(uid == getuid()) + { + result_psswd = strdup(MEDIA_ROOT_PATH_INTERNAL); + grpinfo = getgrnam("users"); + if(grpinfo == NULL) { + MS_DBG_ERR("getgrnam(users) returns NULL !"); + return NULL; + } + } + else + { + struct passwd *userinfo = getpwuid(uid); + if(userinfo == NULL) { + MS_DBG_ERR("getpwuid(%d) returns NULL !", uid); + return NULL; + } + grpinfo = getgrnam("users"); + if(grpinfo == NULL) { + MS_DBG_ERR("getgrnam(users) returns NULL !"); + return NULL; + } + // Compare git_t type and not group name + if (grpinfo->gr_gid != userinfo->pw_gid) { + MS_DBG_ERR("UID [%d] does not belong to 'users' group!", uid); + return NULL; + } + asprintf(&result_psswd, "%s/%s", userinfo->pw_dir, MEDIA_CONTENT_PATH); + } + + return result_psswd; +} + +static int __ms_send_result_to_client(int pid, ms_comm_msg_s *recv_msg) +{ + if(strlen(recv_msg->msg) == 0) { + MS_DBG_ERR("msg is NULL"); + return MS_MEDIA_ERR_INVALID_PARAMETER; + } + + if (owner_list != NULL) { + /* If the owner of result message is not media-server, media-server notify to the owner */ + /* The owner of message is distingushied by pid in received message*/ + /* find owner data */ + ms_req_owner_data *owner_data = NULL; + char *res_path = strdup(recv_msg->msg); + if(res_path == NULL) { + MS_DBG_ERR("res_path is NULL"); + return MS_MEDIA_ERR_OUT_OF_MEMORY; + } + + __ms_find_owner(pid, res_path, &owner_data); + if (owner_data != NULL) { + MS_DBG("PID : %d", owner_data->pid); + /* owner data exists */ + /* send result to the owner of request */ + ms_ipc_send_msg_to_client_tcp(owner_data->client_sockfd, recv_msg, NULL); + close(owner_data->client_sockfd); + + MS_SAFE_FREE(res_path); + + /* free owner data*/ + __ms_delete_owner(owner_data); + } else { + MS_DBG_ERR("Not found Owner"); + MS_SAFE_FREE(res_path); + return MS_MEDIA_ERR_INTERNAL; + } + } else { + /* owner data does not exist*/ + /* this is result of request of media server*/ + MS_DBG_ERR("There is no request, Owner list is NULL"); + return MS_MEDIA_ERR_INTERNAL; + } + + return MS_MEDIA_ERR_NONE; + +} + +static int __ms_privilege_check(const char *msg, gboolean *privilege) +{ +#define operation_cnt 3 +#define db_table_cnt 5 + + int o_idx = 0; + int t_idx = 0; + gboolean is_privilege = TRUE; + + char *operation[operation_cnt] = { + "INSERT INTO ", + "DELETE FROM ", + "UPDATE " + }; + + char *db_table[db_table_cnt] = { + "playlist_map", + "playlist", + "tag_map", + "tag", + "bookmark" + }; + + if(strlen(msg) < 10) { + MS_DBG_ERR("msg is too short!!"); + return MS_MEDIA_ERR_INVALID_PARAMETER; + } + + for(o_idx = 0; o_idx < operation_cnt; o_idx++) { + if(strncmp(operation[o_idx], msg, strlen(operation[o_idx])) == 0) { + for(t_idx = 0; t_idx < db_table_cnt; t_idx++) { + if(strncmp(db_table[t_idx], msg+strlen(operation[o_idx]), strlen(db_table[t_idx])) == 0) { + MS_DBG("Non privilege [%s][%s]", operation[o_idx], db_table[t_idx]); + is_privilege = FALSE; + break; + } + } + break; + } + } + + *privilege = is_privilege; + + return MS_MEDIA_ERR_NONE; +} + +static int __ms_privilege_ask(int client_sockfd) +{ +// int ret = 0; + int res = MS_MEDIA_ERR_NONE; +#if 0 + ret = security_server_check_privilege_by_sockfd(client_sockfd, "media-data::db", "w"); + if (ret == SECURITY_SERVER_API_ERROR_ACCESS_DENIED) { + MS_DBG_ERR("You do not have permission for this operation."); + res = MS_MEDIA_ERR_PERMISSION_DENIED; + } else { + MS_DBG("PERMISSION OK"); + } +#endif + return res; +} +gboolean ms_read_socket(gpointer user_data) { - struct sockaddr_un *client_addr = NULL; - socklen_t client_addr_len; ms_comm_msg_s recv_msg; - ms_comm_msg_s scan_msg; - int msg_size; int sockfd = MS_SOCK_NOT_ALLOCATE; int ret; + int res; int pid; - int req_num; - int path_size; + int req_num = -1; int client_sock = -1; - - g_mutex_lock(scanner_mutex); + GIOChannel *src = user_data; sockfd = g_io_channel_unix_get_fd(src); if (sockfd < 0) { MS_DBG_ERR("sock fd is invalid!"); - g_mutex_unlock(scanner_mutex); return TRUE; } - /* Socket is readable */ - MS_MALLOC(client_addr, sizeof(struct sockaddr_un)); - if (client_addr == NULL) { - MS_DBG_ERR("malloc failed"); - g_mutex_unlock(scanner_mutex); - return TRUE; - } - client_addr_len = sizeof(struct sockaddr_un); - ret = ms_ipc_receive_message(sockfd, &recv_msg, sizeof(recv_msg), client_addr, NULL); + /* get client socket fd */ + ret = ms_ipc_accept_client_tcp(sockfd, &client_sock); if (ret != MS_MEDIA_ERR_NONE) { - MS_DBG_ERR("ms_ipc_receive_message failed"); - MS_SAFE_FREE(client_addr); - g_mutex_unlock(scanner_mutex); return TRUE; } - MS_DBG("receive msg from [%d] %d, %s, uid %d", recv_msg.pid, recv_msg.msg_type, recv_msg.msg, recv_msg.uid); + ret = ms_ipc_receive_message_tcp(client_sock, &recv_msg); + if (ret != MS_MEDIA_ERR_NONE) { + res = ret; + goto ERROR; + } - if (recv_msg.msg_size > 0 && recv_msg.msg_size < MS_FILE_PATH_LEN_MAX) { - msg_size = recv_msg.msg_size; - path_size = msg_size + 1; - } else { - /*NEED IMPLEMETATION*/ - MS_SAFE_FREE(client_addr); - g_mutex_unlock(scanner_mutex); - return TRUE; + ret = __ms_privilege_ask(client_sock); + if (ret == MS_MEDIA_ERR_PERMISSION_DENIED) { + res = MS_MEDIA_ERR_PERMISSION_DENIED; + goto ERROR; } /* copy received data */ @@ -165,141 +326,113 @@ gboolean ms_read_socket(GIOChannel *src, GIOCondition condition, gpointer data) if (req_num == MS_MSG_DIRECTORY_SCANNING ||req_num == MS_MSG_BULK_INSERT ||req_num == MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE - || req_num == MS_MSG_BURSTSHOT_INSERT) { - /* this request process in media scanner */ - - ms_req_owner_data *owner_data = NULL; - - /* If owner list is NULL, create it */ - /* pid and client address are stored in ower list */ - /* These are used for sending result of scanning */ - if (owner_list == NULL) { - /*create array for processing overlay data*/ - owner_list = g_array_new (FALSE, FALSE, sizeof (ms_req_owner_data *)); - if (owner_list == NULL) { - MS_DBG_ERR("g_array_new error"); - MS_SAFE_FREE(client_addr); - g_mutex_unlock(scanner_mutex); - return TRUE; - } + || req_num == MS_MSG_BURSTSHOT_INSERT + || req_num == MS_MSG_DIRECTORY_SCANNING_CANCEL) { + if ((ret = ms_send_scan_request(&recv_msg, client_sock)) != MS_MEDIA_ERR_NONE) { + res = ret; + goto ERROR; } - /* store pid and client address */ - MS_MALLOC(owner_data, sizeof(ms_req_owner_data)); - owner_data->pid = recv_msg.pid; - owner_data->client_addr = client_addr; - owner_data->client_socket = client_sock; - - _ms_add_owner(owner_data); - - /* create send message for media scanner */ - scan_msg.msg_type = req_num; - scan_msg.pid = pid; - scan_msg.msg_size = msg_size; - scan_msg.uid = recv_msg.uid; - ms_strcopy(scan_msg.msg, path_size, "%s", recv_msg.msg); - - g_mutex_unlock(scanner_mutex); - - if (ms_get_scanner_status()) { - MS_DBG("Scanner is ready"); - ms_send_scan_request(&scan_msg); - } else { - MS_DBG("Scanner starts"); - ret = ms_scanner_start(); - if(ret == MS_MEDIA_ERR_NONE) { - ms_send_scan_request(&scan_msg); - } else { - MS_DBG("Scanner starting failed. %d", ret); - } - } + if (req_num == MS_MSG_DIRECTORY_SCANNING_CANCEL) + ms_remove_request_owner(pid, recv_msg.msg); } else { /* NEED IMPLEMENTATION */ - MS_SAFE_FREE(client_addr); - g_mutex_unlock(scanner_mutex); + close(client_sock); } /*Active flush */ malloc_trim(0); return TRUE; -} -gboolean ms_receive_message_from_scanner(GIOChannel *src, GIOCondition condition, gpointer data) -{ - ms_comm_msg_s recv_msg; - int sockfd = MS_SOCK_NOT_ALLOCATE; - int msg_type; - int ret; - int client_sock = -1; - struct sockaddr_un client_addr; +ERROR: + { + ms_comm_msg_s res_msg; - sockfd = g_io_channel_unix_get_fd(src); - if (sockfd < 0) { - MS_DBG_ERR("sock fd is invalid!"); - return TRUE; - } + memset(&res_msg, 0x0, sizeof(ms_comm_msg_s)); - /* Socket is readable */ - ret = ms_ipc_receive_message(sockfd, &recv_msg, sizeof(recv_msg), &client_addr, NULL); - if (ret != MS_MEDIA_ERR_NONE) { - MS_DBG_ERR("ms_ipc_receive_message failed [%s]", strerror(errno)); - return TRUE; + switch(req_num) { + case MS_MSG_DIRECTORY_SCANNING: + case MS_MSG_DIRECTORY_SCANNING_NON_RECURSIVE: + res_msg.msg_type = MS_MSG_SCANNER_RESULT; + break; + case MS_MSG_BULK_INSERT: + case MS_MSG_BURSTSHOT_INSERT: + res_msg.msg_type = MS_MSG_SCANNER_BULK_RESULT; + break; + default : + break; + } + + res_msg.result = res; + + ms_ipc_send_msg_to_client_tcp(client_sock, &res_msg, NULL); + close(client_sock); } - MS_DBG("receive msg from [%d] %d, %s", recv_msg.pid, recv_msg.msg_type, recv_msg.msg); + return TRUE; +} - msg_type = recv_msg.msg_type; - if ((msg_type == MS_MSG_SCANNER_RESULT) || - (msg_type == MS_MSG_SCANNER_BULK_RESULT)) { - if (owner_list != NULL) { - /* If the owner of result message is not media-server, media-server notify to the owner */ - /* The owner of message is distingushied by pid in received message*/ - /* find owner data */ - ms_req_owner_data *owner_data = NULL; - - _ms_find_owner(recv_msg.pid, &owner_data); - if (owner_data != NULL) { - MS_DBG("PID : %d", owner_data->pid); - - if (msg_type == MS_MSG_SCANNER_RESULT) { - MS_DBG("DIRECTORY SCANNING IS DONE"); - } +static int __ms_send_request(ms_comm_msg_s *send_msg) +{ + int res = MS_MEDIA_ERR_NONE; + int fd = -1; + int err = -1; - /* owner data exists */ - /* send result to the owner of request */ - ms_ipc_send_msg_to_client(sockfd, &recv_msg, owner_data->client_addr); + fd = open(MS_SCANNER_FIFO_PATH_REQ, O_WRONLY); + if (fd < 0) { + MS_DBG_STRERROR("fifo open failed"); + return MS_MEDIA_ERR_FILE_OPEN_FAIL; + } - /* free owner data*/ - _ms_delete_owner(owner_data); - } - } else { - /* owner data does not exist*/ - /* this is result of request of media server*/ - } - } else { - MS_DBG_ERR("This result message is wrong : %d", recv_msg.msg_type ); + /* send message */ + err = write(fd, send_msg, sizeof(ms_comm_msg_s)); + if (err < 0) { + MS_DBG_STRERROR("fifo write failed"); + close(fd); + return MS_MEDIA_ERR_FILE_READ_FAIL; } - return TRUE; + close(fd); + + return res; } -int ms_send_scan_request(ms_comm_msg_s *send_msg) +int ms_send_scan_request(ms_comm_msg_s *send_msg, int client_sock) { - int ret; int res = MS_MEDIA_ERR_NONE; - int sockfd = -1; + int err = MS_MEDIA_ERR_NONE; + int pid = send_msg->pid; - /*Create Socket*/ - ret = ms_ipc_create_client_socket(MS_PROTOCOL_UDP, 0, &sockfd, MS_SCAN_DAEMON_PORT); + g_mutex_lock(&scanner_mutex); - if (ret != MS_MEDIA_ERR_NONE) - return MS_MEDIA_ERR_SOCKET_CONN; + if (ms_get_scanner_status()) { + MS_DBG_WARN("Scanner is ready"); + __ms_send_request(send_msg); - ret = ms_ipc_send_msg_to_server(sockfd, MS_SCAN_DAEMON_PORT, send_msg, NULL); - if (ret != MS_MEDIA_ERR_NONE) - res = ret; + g_mutex_unlock(&scanner_mutex); + } else { + MS_DBG_WARN("Scanner starts"); + g_mutex_unlock(&scanner_mutex); + + err = ms_scanner_start(); + if(err == MS_MEDIA_ERR_NONE) { + err = __ms_send_request(send_msg); + if(err != MS_MEDIA_ERR_NONE) { + MS_DBG_ERR("__ms_send_request failed", err); + } + } else { + MS_DBG_ERR("Scanner starting failed. %d", err); + res = err; + } + } - close(sockfd); + if ((res == MS_MEDIA_ERR_NONE) && (send_msg->msg_type != MS_MSG_DIRECTORY_SCANNING_CANCEL)) { + /* this request process in media scanner */ + if ((err = __ms_add_owner(pid, client_sock, send_msg->msg)) != MS_MEDIA_ERR_NONE) { + MS_DBG_ERR("__ms_add_owner failed. %d", err); + res = err; + } + } return res; } @@ -326,6 +459,9 @@ int ms_send_storage_scan_request(ms_storage_type_t storage_type, ms_dir_scan_typ case MS_SCAN_INVALID: scan_msg.msg_type = MS_MSG_STORAGE_INVALID; break; + case MS_SCAN_META: + scan_msg.msg_type = MS_MSG_STORAGE_META; + break; default : ret = MS_MEDIA_ERR_INVALID_PARAMETER; MS_DBG_ERR("ms_send_storage_scan_request invalid parameter"); @@ -336,8 +472,8 @@ int ms_send_storage_scan_request(ms_storage_type_t storage_type, ms_dir_scan_typ /* msg_size & msg */ switch (storage_type) { case MS_STORAGE_INTERNAL: - scan_msg.msg_size = strlen(MEDIA_ROOT_PATH_INTERNAL); - strncpy(scan_msg.msg, MEDIA_ROOT_PATH_INTERNAL, scan_msg.msg_size ); + scan_msg.msg_size = strlen(__ms_get_path(tzplatform_getuid(TZ_USER_NAME))); + strncpy(scan_msg.msg, __ms_get_path(tzplatform_getuid(TZ_USER_NAME)), scan_msg.msg_size ); break; case MS_STORAGE_EXTERNAL: scan_msg.msg_size = strlen(MEDIA_ROOT_PATH_SDCARD); @@ -350,60 +486,67 @@ int ms_send_storage_scan_request(ms_storage_type_t storage_type, ms_dir_scan_typ break; } - g_mutex_lock(scanner_mutex); - - if (ms_get_scanner_status()) { - ms_send_scan_request(&scan_msg); - g_mutex_unlock(scanner_mutex); - } else { - g_mutex_unlock(scanner_mutex); - - ret = ms_scanner_start(); - if(ret == MS_MEDIA_ERR_NONE) { - ms_send_scan_request(&scan_msg); - } else { - MS_DBG("Scanner starting failed. "); - } - } + ret = ms_send_scan_request(&scan_msg, -1); ERROR: return ret; } -gboolean ms_read_db_socket(GIOChannel *src, GIOCondition condition, gpointer data) +gboolean ms_read_db_tcp_socket(GIOChannel *src, GIOCondition condition, gpointer data) { - struct sockaddr_un client_addr; - ms_comm_msg_s recv_msg; - int send_msg = MS_MEDIA_ERR_NONE; - int sockfd = MS_SOCK_NOT_ALLOCATE; + int sock = -1; int client_sock = -1; - int ret = MS_MEDIA_ERR_NONE; - MediaDBHandle *db_handle = NULL; - ms_comm_msg_s msg; char * sql_query = NULL; + ms_comm_msg_s recv_msg; + int ret = MS_MEDIA_ERR_NONE; + MediaDBHandle *db_handle = (MediaDBHandle *)data; + int send_msg = MS_MEDIA_ERR_NONE; + gboolean privilege = TRUE; - memset(&recv_msg, 0, sizeof(recv_msg)); + if (power_off == TRUE) { + MS_DBG_WARN("in the power off sequence"); + return TRUE; + } - sockfd = g_io_channel_unix_get_fd(src); - if (sockfd < 0) { + sock = g_io_channel_unix_get_fd(src); + if (sock < 0) { MS_DBG_ERR("sock fd is invalid!"); return TRUE; } - ret = ms_ipc_receive_message(sockfd, &recv_msg, sizeof(recv_msg), &client_addr, NULL); + /* get client socket fd */ + ret = ms_ipc_accept_client_tcp(sock, &client_sock); if (ret != MS_MEDIA_ERR_NONE) { return TRUE; } -// MS_DBG("msg_type[%d], msg_size[%d] msg[%s]", recv_msg.msg_type, recv_msg.msg_size, recv_msg.msg); + ret = ms_ipc_receive_message_tcp(client_sock, &recv_msg); + if (ret != MS_MEDIA_ERR_NONE) { + MS_DBG_ERR("ms_ipc_receive_message_tcp failed [%d]", ret); + send_msg = ret; + goto ERROR; + } - if((recv_msg.msg_size <= 0) ||(recv_msg.msg_size > MS_FILE_PATH_LEN_MAX) || (!MS_STRING_VALID(recv_msg.msg))) { + /* check privileage */ + if(__ms_privilege_check(recv_msg.msg, &privilege) != MS_MEDIA_ERR_NONE) { MS_DBG_ERR("invalid query. size[%d]", recv_msg.msg_size); - return TRUE; + send_msg = MS_MEDIA_ERR_SOCKET_RECEIVE; + goto ERROR; + } + + if (privilege == TRUE) { + ret = __ms_privilege_ask(client_sock); + if (ret == MS_MEDIA_ERR_PERMISSION_DENIED) { + send_msg = MS_MEDIA_ERR_PERMISSION_DENIED; + goto ERROR; + } } - media_db_connect(&db_handle, recv_msg.uid); + if(media_db_connect(&db_handle, recv_msg.uid) != MS_MEDIA_ERR_NONE) { + MS_DBG_ERR("Failed to connect DB"); + goto ERROR; + } sql_query = strndup(recv_msg.msg, recv_msg.msg_size); if (sql_query != NULL) { @@ -417,75 +560,61 @@ gboolean ms_read_db_socket(GIOChannel *src, GIOCondition condition, gpointer dat send_msg = MS_MEDIA_ERR_OUT_OF_MEMORY; } - memset(&msg, 0x0, sizeof(ms_comm_msg_s)); - msg.result = send_msg; - - ms_ipc_send_msg_to_client(sockfd, &msg, &client_addr); - media_db_disconnect(db_handle); - close(client_sock); +ERROR: + if (write(client_sock, &send_msg, sizeof(send_msg)) != sizeof(send_msg)) { + MS_DBG_STRERROR("send failed"); + } else { + MS_DBG("Sent successfully"); + } - /*Active flush */ - malloc_trim(0); + if (close(client_sock) <0) { + MS_DBG_STRERROR("close failed"); + } return TRUE; } -gboolean ms_read_db_tcp_socket(GIOChannel *src, GIOCondition condition, gpointer data) -{ - struct sockaddr_un client_addr; - unsigned int client_addr_len; - ms_comm_msg_s recv_msg; - int sock = -1; - int client_sock = -1; - int send_msg = MS_MEDIA_ERR_NONE; - int recv_msg_size = -1; +void _ms_process_tcp_message(gpointer data, gpointer user_data) +{ int ret = MS_MEDIA_ERR_NONE; char * sql_query = NULL; + ms_comm_msg_s recv_msg; + int client_sock = GPOINTER_TO_INT (data); + int send_msg = MS_MEDIA_ERR_NONE; MediaDBHandle *db_handle = NULL; - sock = g_io_channel_unix_get_fd(src); - if (sock < 0) { - MS_DBG_ERR("sock fd is invalid!"); - return TRUE; - } memset((void *)&recv_msg, 0, sizeof(ms_comm_msg_s)); - if ((client_sock = accept(sock, (struct sockaddr*)&client_addr, &client_addr_len)) < 0) { - MS_DBG_ERR("accept failed : %s", strerror(errno)); - return TRUE; - } - - MS_DBG("Client[%d] is accepted", client_sock); +// MS_DBG_ERR("client sokcet : %d", client_sock); while(1) { - if ((recv_msg_size = recv(client_sock, &recv_msg, sizeof(ms_comm_msg_s), 0)) < 0) { - MS_DBG_ERR("recv failed : %s", strerror(errno)); - - close(client_sock); - if (errno == EWOULDBLOCK) { - MS_DBG_ERR("Timeout. Can't try any more"); - return MS_MEDIA_ERR_SOCKET_RECEIVE_TIMEOUT; - } else { - MS_DBG_ERR("recv failed : %s", strerror(errno)); - return MS_MEDIA_ERR_SOCKET_RECEIVE; - } + if (power_off == TRUE) { + MS_DBG_WARN("in the power off sequence"); + break; } -// MS_DBG("Received [%d](%d) [%s]", recv_msg.msg_type, recv_msg.msg_size, recv_msg.msg); + ret = ms_ipc_receive_message_tcp(client_sock, &recv_msg); + if (ret != MS_MEDIA_ERR_NONE) { + media_db_request_update_db_batch_clear(); + MS_DBG_ERR("ms_ipc_receive_message_tcp failed [%d]", ret); + send_msg = ret; + goto ERROR; + } - if((recv_msg.msg_size <= 0) ||(recv_msg.msg_size > MS_FILE_PATH_LEN_MAX) || (!MS_STRING_VALID(recv_msg.msg))) { - MS_DBG_ERR("invalid query. size[%d]", recv_msg.msg_size); - MS_DBG_ERR("Received [%d](%d) [%s]", recv_msg.msg_type, recv_msg.msg_size, recv_msg.msg); - close(client_sock); - return TRUE; + /* Connect Media DB*/ + if(db_handle == NULL) { + if(media_db_connect(&db_handle, recv_msg.uid) != MS_MEDIA_ERR_NONE) { + MS_DBG_ERR("Failed to connect DB"); + send_msg = MS_MEDIA_ERR_DB_CONNECT_FAIL; + goto ERROR; + } } sql_query = strndup(recv_msg.msg, recv_msg.msg_size); if (sql_query != NULL) { - media_db_connect(&db_handle, recv_msg.uid); if (recv_msg.msg_type == MS_MSG_DB_UPDATE_BATCH_START) { ret = media_db_update_db_batch_start(sql_query); } else if(recv_msg.msg_type == MS_MSG_DB_UPDATE_BATCH_END) { @@ -495,28 +624,207 @@ gboolean ms_read_db_tcp_socket(GIOChannel *src, GIOCondition condition, gpointer } else { } - media_db_disconnect(db_handle); MS_SAFE_FREE(sql_query); send_msg = ret; - if (send(client_sock, &send_msg, sizeof(send_msg), 0) != sizeof(send_msg)) { - MS_DBG_ERR("send failed : %s", strerror(errno)); - } else { - MS_DBG("Sent successfully"); + if (write(client_sock, &send_msg, sizeof(send_msg)) != sizeof(send_msg)) { + MS_DBG_STRERROR("send failed"); + } + +// MS_DBG_ERR("client sokcet : %d", client_sock); + if (recv_msg.msg_type == MS_MSG_DB_UPDATE_BATCH_END) { + MS_DBG_WARN("Batch job is successfull!client sockfd [%d]", client_sock); + break; } - if (recv_msg.msg_type == MS_MSG_DB_UPDATE_BATCH_END) + if (ret < MS_MEDIA_ERR_NONE && recv_msg.msg_type == MS_MSG_DB_UPDATE_BATCH_START) { + MS_DBG_ERR("Batch job start is failed!client sockfd [%d]", client_sock); + media_db_request_update_db_batch_clear(); break; + } memset((void *)&recv_msg, 0, sizeof(ms_comm_msg_s)); } else { MS_DBG_ERR("MS_MALLOC failed"); - close(client_sock); - return TRUE; + media_db_request_update_db_batch_clear(); + /* send error to client */ + send_msg = MS_MEDIA_ERR_SOCKET_RECEIVE; + goto ERROR; + } + } + + if (close(client_sock) <0) { + MS_DBG_STRERROR("close failed"); + } + + /* Disconnect DB*/ + media_db_disconnect(db_handle); + MS_DBG_ERR("END"); + if (g_atomic_int_dec_and_test(&cur_running_task) == FALSE) + MS_DBG_ERR("g_atomic_int_dec_and_test failed"); + + return; + +ERROR: + + /* send error to client */ + if (write(client_sock, &send_msg, sizeof(send_msg)) != sizeof(send_msg)) { + MS_DBG_STRERROR("send failed"); + } else { + MS_DBG("Sent successfully"); + } + + if (close(client_sock) <0) { + MS_DBG_STRERROR("close failed"); + } + + /* Disconnect DB*/ + media_db_disconnect(db_handle); + MS_DBG_ERR("END"); + if (g_atomic_int_dec_and_test(&cur_running_task) == FALSE) + MS_DBG_ERR("g_atomic_int_dec_and_test failed"); + + return; +} + +gboolean ms_read_db_tcp_batch_socket(GIOChannel *src, GIOCondition condition, gpointer data) +{ +#define MAX_THREAD_NUM 3 + + static GThreadPool *gtp = NULL; + GError *error = NULL; + int ret = MS_MEDIA_ERR_NONE; + int res = MS_MEDIA_ERR_NONE; + int sock = -1; + int client_sock = -1; + + sock = g_io_channel_unix_get_fd(src); + if (sock < 0) { + MS_DBG_ERR("sock fd is invalid!"); + return TRUE; + } + + /* get client socket fd */ + ret = ms_ipc_accept_client_tcp(sock, &client_sock); + if (ret != MS_MEDIA_ERR_NONE) { + media_db_request_update_db_batch_clear(); + return TRUE; + } + + MS_DBG_SLOG("Client[%d] is accepted", client_sock); + + if (gtp == NULL) { + MS_DBG_SLOG("Create New Thread Pool %d", client_sock); + gtp = g_thread_pool_new((GFunc)_ms_process_tcp_message, NULL, MAX_THREAD_NUM, TRUE, &error); + if (error != NULL) { + res = MS_MEDIA_ERR_OUT_OF_MEMORY; + goto ERROR; + } + } + + /*check number of running thread */ + if (g_atomic_int_get(&cur_running_task) < MAX_THREAD_NUM) { + MS_DBG_SLOG("CURRENT RUNNING TASK %d", cur_running_task); + g_atomic_int_inc(&cur_running_task); + g_thread_pool_push(gtp, GINT_TO_POINTER(client_sock), &error); + + if (error != NULL) { + res = MS_MEDIA_ERR_INTERNAL; + goto ERROR; + } + } else { + /* all thread is working, return busy error */ + res = MS_MEDIA_ERR_DB_BATCH_UPDATE_BUSY; + goto ERROR; + } + + return TRUE; + +ERROR: + { + int send_msg = MS_MEDIA_ERR_NONE; + + if (error != NULL) { + MS_DBG_SLOG("g_thread_pool_push failed [%d]", error->message); + g_error_free(error); + error = NULL; + } + + /* send error to clinet*/ + send_msg = res; + if (write(client_sock, &send_msg, sizeof(send_msg)) != sizeof(send_msg)) { + MS_DBG_STRERROR("send failed"); + } else { + MS_DBG("Sent successfully"); + } + + if (close(client_sock) <0) { + MS_DBG_STRERROR("close failed"); } } - close(client_sock); return TRUE; } + +gboolean ms_receive_message_from_scanner(GIOChannel *src, GIOCondition condition, gpointer data) +{ + ms_comm_msg_s recv_msg; + int fd = MS_SOCK_NOT_ALLOCATE; + int msg_type; + int pid = -1; + int err; + + fd = g_io_channel_unix_get_fd(src); + if (fd < 0) { + MS_DBG_ERR("fd is invalid!"); + return TRUE; + } + + /* read() is blocked until media scanner sends message */ + err = read(fd, &recv_msg, sizeof(recv_msg)); + if (err < 0) { + MS_DBG_STRERROR("fifo read failed"); + close(fd); + return MS_MEDIA_ERR_FILE_READ_FAIL; + } + + MS_DBG_SLOG("receive result from scanner [%d] %d, %s", recv_msg.pid, recv_msg.result, recv_msg.msg); + + msg_type = recv_msg.msg_type; + pid = recv_msg.pid; + if ((msg_type == MS_MSG_SCANNER_RESULT) || + (msg_type == MS_MSG_SCANNER_BULK_RESULT)) { + MS_DBG_WARN("DB UPDATING IS DONE[%d]", msg_type); + + if (pid != 0) { + __ms_send_result_to_client(pid, &recv_msg); + } else { + MS_DBG_SLOG("This request is from media-server"); + } + } else { + MS_DBG_ERR("This result message is wrong : %d", recv_msg.msg_type ); + } + + return TRUE; +} + +int ms_remove_request_owner(int pid, const char *req_path) +{ + ms_req_owner_data *owner_data = NULL; + + __ms_find_owner(pid, req_path, &owner_data); + if (owner_data != NULL) { + MS_DBG("PID : %d", owner_data->pid); + + close(owner_data->client_sockfd); + /* free owner data*/ + __ms_delete_owner(owner_data); + } else { + MS_DBG_ERR("Not found Owner"); + return MS_MEDIA_ERR_INTERNAL; + } + + return MS_MEDIA_ERR_NONE; +} + diff --git a/src/server/media-server-thumb.c b/src/server/media-server-thumb.c index e7db58d..35e3628 100755 --- a/src/server/media-server-thumb.c +++ b/src/server/media-server-thumb.c @@ -18,7 +18,6 @@ * limitations under the License. * */ - #define _GNU_SOURCE #include @@ -28,7 +27,6 @@ #include "media-common-utils.h" #include "media-server-dbg.h" #include "media-server-thumb.h" - #include #ifdef LOG_TAG @@ -526,24 +524,26 @@ gboolean _ms_thumb_agent_execute_server() gboolean _ms_thumb_agent_send_msg_to_thumb_server(thumbMsg *recv_msg, thumbMsg *res_msg) { int sock; - const char *serv_ip = "127.0.0.1"; + ms_sock_info_s sock_info; struct sockaddr_un serv_addr; int send_str_len = strlen(recv_msg->org_path); + sock_info.port = MS_THUMB_DAEMON_PORT; if (send_str_len > MAX_FILEPATH_LEN) { MS_DBG_ERR("original path's length exceeds %d(max packet size)", MAX_FILEPATH_LEN); return FALSE; } - if (ms_ipc_create_client_socket(MS_PROTOCOL_UDP, MS_TIMEOUT_SEC_10, &sock, MS_THUMB_DAEMON_PORT) < 0) { + if (ms_ipc_create_client_socket(MS_PROTOCOL_UDP, MS_TIMEOUT_SEC_10, &sock_info) < 0) { MS_DBG_ERR("ms_ipc_create_client_socket failed"); return FALSE; } memset(&serv_addr, 0, sizeof(serv_addr)); + sock = sock_info.sock_fd; serv_addr.sun_family = AF_UNIX; - MS_DBG("%s", MEDIA_IPC_PATH[MS_THUMB_DAEMON_PORT]); - strcpy(serv_addr.sun_path, MEDIA_IPC_PATH[MS_THUMB_DAEMON_PORT]); +// MS_DBG_SLOG("%s", MEDIA_IPC_PATH[MS_THUMB_DAEMON_PORT]); + strncpy(serv_addr.sun_path, MEDIA_IPC_PATH[MS_THUMB_DAEMON_PORT], strlen(MEDIA_IPC_PATH[MS_THUMB_DAEMON_PORT])); int buf_size = 0; int header_size = 0; @@ -554,7 +554,7 @@ gboolean _ms_thumb_agent_send_msg_to_thumb_server(thumbMsg *recv_msg, thumbMsg * if (sendto(sock, buf, buf_size, 0, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) != buf_size) { MS_DBG_STRERROR("sendto failed"); MS_SAFE_FREE(buf); - close(sock); + ms_ipc_delete_client_socket(&sock_info); return FALSE; } @@ -567,12 +567,12 @@ gboolean _ms_thumb_agent_send_msg_to_thumb_server(thumbMsg *recv_msg, thumbMsg * if (_ms_thumb_recv_udp_msg(sock, header_size, res_msg, &client_addr, &client_addr_len) < 0) { MS_DBG_ERR("_ms_thumb_recv_udp_msg failed"); - close(sock); + ms_ipc_delete_client_socket(&sock_info); return FALSE; } - MS_DBG("recv %s from thumb daemon is successful", res_msg->dst_path); - close(sock); + MS_DBG_SLOG("recv %s from thumb daemon is successful", res_msg->dst_path); + ms_ipc_delete_client_socket(&sock_info); if (res_msg->msg_type == 2 && g_communicate_sock > 0) { // THUMB_REQUEST_ALL_MEDIA /* Create new channel to watch udp socket */ -- 2.7.4