From: Jiyong Min Date: Fri, 23 Jun 2017 07:41:35 +0000 (+0900) Subject: Code refactoring C++ to native C X-Git-Tag: submit/tizen/20170705.070223~7 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f6c6783235803d10ba25ba8ce8aec36d6135b8a7;p=platform%2Fcore%2Fmultimedia%2Fdcm-service.git Code refactoring C++ to native C - C code refactoring - Apply coding rule - Fix svace issue in local Change-Id: I57c294ce5b4522cb3f2e7ab7d5e53de2ab324cda Signed-off-by: Jiyong Min --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 580d781..ecd706d 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,11 +7,11 @@ SET(DCMSVC-LIB "dcm-service") SET(DCMFACE-LIB "dcm-face") SET(DCMUTIL-LIB "dcm-util") SET(SRCS - src/DcmColorUtils.cpp - src/DcmDbUtils.cpp - src/DcmFaceUtils.cpp - src/DcmIpcUtils.cpp - src/DcmScanSvc.cpp + src/dcm_svc_extract_color.c + src/dcm_svc_db.c + src/dcm_svc_detect_face.c + src/dcm_svc_ipc.c + src/dcm_svc_internal.c ) SET(FACE_SRCS @@ -20,7 +20,7 @@ SET(FACE_SRCS ) SET(UTIL_SRCS - libdcm-util/dcm_image_codec.cpp + libdcm-util/dcm_image_codec.c ) SET(VENDOR "samsung") diff --git a/include/DcmColorUtils.h b/include/DcmColorUtils.h deleted file mode 100755 index 1ea7f69..0000000 --- a/include/DcmColorUtils.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * 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 _DCM_SVC_COLOR_H_ -#define _DCM_SVC_COLOR_H_ - -#include - -namespace DcmColorUtils { - int runColorExtractProcess(DcmScanItem *scan_item, DcmImageInfo *image_info); -} - -#endif /*_DCM_SVC_COLOR_H_*/ - diff --git a/include/DcmDbUtils.h b/include/DcmDbUtils.h deleted file mode 100755 index f03db10..0000000 --- a/include/DcmDbUtils.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * 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 _DCM_DB_UTILS_H_ -#define _DCM_DB_UTILS_H_ - -#include -#include -#include -#include -/*#include */ -#include -#include - -typedef bool (*dcm_svc_db_face_cb)(DcmFaceItem *face_item, void *user_data); - -class DcmDbUtils { -private: - DcmDbUtils(); - static DcmDbUtils *dcmDbUtils; - static MediaDBHandle *db_handle; - -public: - uid_t dcm_uid; - static DcmDbUtils *getInstance(void); - int _dcm_svc_db_connect(uid_t uid); - int _dcm_svc_db_disconnect(); - int _dcm_svc_db_get_scan_image_list_by_path(GList **image_list, bool mmc_mounted, const char *file_path); - int _dcm_svc_db_get_scan_image_list_from_db(GList **image_list, bool mmc_mounted); - int _dcm_svc_db_insert_category_to_db(void *item); - int _dcm_svc_db_generate_uuid(DcmFaceItem **face); - int _dcm_svc_db_insert_face_to_db(DcmFaceItem *face); - int _dcm_svc_db_update_color_to_db(const DcmColorItem color); - int _dcm_svc_db_insert_face_to_face_scan_list(DcmScanItem *scan_item); - int _dcm_svc_db_check_scanned_by_media_uuid(const char *media_uuid, bool *media_scanned); -}; - -#endif /*_DCM_DB_UTILS_H_*/ - diff --git a/include/DcmDebugUtils.h b/include/DcmDebugUtils.h deleted file mode 100755 index 4fce682..0000000 --- a/include/DcmDebugUtils.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * 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 _DCM_DEBUG_UTILS_H_ -#define _DCM_DEBUG_UTILS_H_ - -#include - -#ifdef LOG_TAG -#undef LOG_TAG -#endif - -#define LOG_TAG "DCM_SVC" - -#define FONT_COLOR_RESET "\033[0m" -#define FONT_COLOR_RED "\033[31m" -#define FONT_COLOR_GREEN "\033[32m" -#define FONT_COLOR_YELLOW "\033[33m" -#define FONT_COLOR_BLUE "\033[34m" -#define FONT_COLOR_PURPLE "\033[35m" -#define FONT_COLOR_CYAN "\033[36m" -#define FONT_COLOR_GRAY "\033[37m" - -#define dcm_debug(fmt, arg...) do { \ - LOGD(FONT_COLOR_CYAN"" fmt "" FONT_COLOR_RESET, ##arg); \ - } while (0) - -#define dcm_info(fmt, arg...) do { \ - LOGI(FONT_COLOR_YELLOW"" fmt "" FONT_COLOR_RESET, ##arg); \ - } while (0) - -#define dcm_warn(fmt, arg...) do { \ - LOGW(FONT_COLOR_GREEN"" fmt "" FONT_COLOR_RESET, ##arg); \ - } while (0) - -#define dcm_error(fmt, arg...) do { \ - LOGE(FONT_COLOR_RED"" fmt "" FONT_COLOR_RESET, ##arg); \ - } while (0) - -#define dcm_sec_debug(fmt, arg...) do { \ - SECURE_LOGD(FONT_COLOR_CYAN"" fmt "" FONT_COLOR_RESET, ##arg); \ - } while (0) - -#define dcm_sec_info(fmt, arg...) do { \ - SECURE_LOGI(FONT_COLOR_YELLOW"" fmt "" FONT_COLOR_RESET, ##arg); \ - } while (0) - -#define dcm_sec_warn(fmt, arg...) do { \ - SECURE_LOGW(FONT_COLOR_GREEN"" fmt "" FONT_COLOR_RESET, ##arg); \ - } while (0) - -#define dcm_sec_error(fmt, arg...) do { \ - SECURE_LOGE(FONT_COLOR_RED"" fmt "" FONT_COLOR_RESET, ##arg); \ - } while (0) -#define dcm_debug_fenter() do { \ - LOGD(FONT_COLOR_RESET""); \ - } while (0) - -#define dcm_debug_fleave() do { \ - LOGD(FONT_COLOR_RESET""); \ - } while (0) -#define dcm_retm_if(expr, fmt, arg...) do { \ - if (expr) { \ - LOGE(FONT_COLOR_RED"" fmt "" FONT_COLOR_RESET, ##arg); \ - return; \ - } \ - } while (0) - -#define dcm_retvm_if(expr, val, fmt, arg...) do { \ - if (expr) { \ - LOGE(FONT_COLOR_RED"" fmt "" FONT_COLOR_RESET, ##arg); \ - return (val); \ - } \ - } while (0) - -#define ERR_BUF_LENGHT 256 -#define dcm_stderror(fmt) do { \ - char dcm_stderror_buf[ERR_BUF_LENGHT] = {0, }; \ - LOGE(fmt" : standard error= [%s]", strerror_r(errno, dcm_stderror_buf, ERR_BUF_LENGHT)); \ - } while (0) - -#define DCM_CHECK_VAL(expr, val) dcm_retvm_if(!(expr), val, "Invalid parameter, return ERROR code!") -#define DCM_CHECK_NULL(expr) dcm_retvm_if(!(expr), NULL, "Invalid parameter, return NULL!") -#define DCM_CHECK_FALSE(expr) dcm_retvm_if(!(expr), FALSE, "Invalid parameter, return FALSE!") -#define DCM_CHECK(expr) dcm_retm_if(!(expr), "Invalid parameter, return!") - -#define DCM_SAFE_FREE(ptr) { if (ptr) {free(ptr); ptr = NULL; } } - -#endif /* _DCM_DEBUG_UTILS_H_ */ - diff --git a/include/DcmFaceUtils.h b/include/DcmFaceUtils.h deleted file mode 100755 index 8e64a28..0000000 --- a/include/DcmFaceUtils.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * 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 _DCM_SVC_FACE_H_ -#define _DCM_SVC_FACE_H_ - -#include - -namespace DcmFaceUtils { - int initialize(); - int finalize(); - int runFaceRecognizeProcess(DcmScanItem *scan_item, DcmImageInfo *image_info); -} - -#endif /*_DCM_SVC_FACE_H_*/ - diff --git a/include/DcmIpcUtils.h b/include/DcmIpcUtils.h deleted file mode 100755 index 46ca092..0000000 --- a/include/DcmIpcUtils.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * 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 _DCM_SVC_IPC_H_ -#define _DCM_SVC_IPC_H_ - -#include -#include - -#define DCM_TIMEOUT_SEC_60 60 /**< Response to media server time out */ - -namespace DcmIpcUtils { - int createSocket(int *socket_fd, DcmIpcPortType port); - int acceptSocket(int serv_sock, int *client_sock); - int receiveSocketMsg(int client_sock, dcmMsg *recv_msg); - int sendSocketMsg(ms_dcm_msg_type_e msg_type, uid_t uid, const char *msg, DcmIpcPortType port); - int sendCompleteMsg(ms_dcm_msg_type_e msg_type, const unsigned int count, const char *msg, DcmIpcPortType port); - int sendClientSocketMsg(int socket_fd, ms_dcm_msg_type_e msg_type, unsigned int result, const char *msg, DcmIpcPortType port); - int closeSocket(int socket_fd); -} - -#endif /* _DCM_SVC_IPC_H_ */ - diff --git a/include/DcmMainSvc.h b/include/DcmMainSvc.h deleted file mode 100755 index b371a76..0000000 --- a/include/DcmMainSvc.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * 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 _DCM_MAIN_SVC_H_ -#define _DCM_MAIN_SVC_H_ - -#include -#include -#include - -#ifndef EXPORT_API -#define EXPORT_API __attribute__ ((visibility("default"))) -#endif - -class DcmMainSvc { - static DcmMainSvc *dcmMainSvc; - -public: - /* scan thread related */ - /* GMainLoop *g_dcm_svc_mainloop; */ - - /* scan thread related */ - GThread *scan_thread; - GAsyncQueue *scan_thread_ready; - - /* main thread related */ - GMainContext *main_loop_context; - GMainContext *main_thread_context; - GIOChannel *main_thread_recv_channel; - int main_thread_recv_socket; - GSource *main_thread_quit_timer; - bool scan_thread_working; - - static DcmMainSvc *getInstance(void); - void dcmServiceStartjobs(); - void dcmServiceFinishjobs(); - int waitScanThreadReady(); - int createScanThread(); - int createQuitTimerMainLoop(); - void quitDcmSvcMainLoop(); -}; - -#endif /* _DCM_MAIN_SVC_H_ */ - diff --git a/include/DcmScanSvc.h b/include/DcmScanSvc.h deleted file mode 100755 index dfa096a..0000000 --- a/include/DcmScanSvc.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * 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 _DCM_SCAN_SVC_H_ -#define _DCM_SCAN_SVC_H_ - -#include - -namespace DcmScanMain { - gboolean runScanThread(void *data); - int ScanSingle(const char *file_path, uid_t uid, int *face_count); -} - -#endif /* _DCM_SCAN_SVC_H_ */ - diff --git a/include/DcmTypes.h b/include/DcmTypes.h deleted file mode 100755 index 4d44708..0000000 --- a/include/DcmTypes.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * 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 _DCM_TYPES_H_ -#define _DCM_TYPES_H_ - -#include -#include - -/* - * Definitions defined here can be used by all threads - * If a definition can only be used in a specific thread, then this definition should be defined in that thread, not here. - */ - -#define DCM_MAX_PATH_SIZE 4096 -#define DCM_IPC_MSG_MAX_SIZE 4096 -#define DCM_DB_QUERY_MAX_SIZE 4096 - -typedef enum { - DCM_IPC_PORT_SCAN_RECV = 0, - DCM_IPC_PORT_DCM_RECV, - DCM_IPC_PORT_MS_RECV, - DCM_IPC_PORT_MAX, -} DcmIpcPortType; - -typedef enum { - DCM_SCAN_ITEM_TYPE_NONE, - DCM_SCAN_ITEM_TYPE_SCAN_ALL, - DCM_SCAN_ITEM_TYPE_SCAN_SINGLE, - DCM_SCAN_ITEM_TYPE_MAX, -} DcmScanItemType; - -typedef struct { - char *media_uuid; - char *file_path; - char *storage_uuid; - int image_width; - int image_height; - int image_orientation; - char *mime_type; - int face_count; - DcmScanItemType scan_item_type; -} DcmScanItem; - -typedef struct { - char *face_uuid; - char *media_uuid; - unsigned int face_rect_x; - unsigned int face_rect_y; - unsigned int face_rect_w; - unsigned int face_rect_h; - int orientation; -} DcmFaceItem; - -typedef struct { - char *media_uuid; - char *storage_uuid; - unsigned char rgb_r; - unsigned char rgb_g; - unsigned char rgb_b; -} DcmColorItem; - -typedef enum { - DCM_SVC_I420, - DCM_SVC_RGB, - DCM_SVC_RGBA, -} DcmImageDecodeType; - -typedef struct { - unsigned char *pixel; /* decoding results, must be freed after use */ - unsigned long long size; - int orientation; /* orientation information extracted from exif */ - unsigned int original_width; /* original image width */ - unsigned int original_height; /* original image height */ - unsigned int buffer_width; /* scaled image width used by decoder (width/height ratio should be the same as original) */ - unsigned int buffer_height; /* scaled image height used by decoder (width/height ratio should be the same as original) */ - DcmImageDecodeType decode_type; /* decoding pre-condition */ -} DcmImageInfo; - -#endif /* _DCM_TYPES_H_ */ - diff --git a/include/dcm_svc_db.h b/include/dcm_svc_db.h new file mode 100755 index 0000000..91e01bd --- /dev/null +++ b/include/dcm_svc_db.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * 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 _DCM_DB_UTILS_H_ +#define _DCM_DB_UTILS_H_ + +#include +#include +#include +#include +/*#include */ +#include +#include + +#define DCM_STRING_VALID(str) ((str != NULL && strlen(str) > 0) ? TRUE : FALSE) +#define DCM_SQLITE3_FINALIZE(x) { if (x != NULL) { sqlite3_finalize(x); x = NULL; } } +#define DCM_SQLITE3_FREE(x) { if (x != NULL) { sqlite3_free(x); x = NULL; } } + +#define DB_TABLE_FACE "face" +#define DB_TABLE_FACE_SCAN_LIST "face_scan_list" +#define DB_TABLE_MEDIA "media" +#define FACE_ITEM "face_uuid, media_uuid, face_rect_x , face_rect_y, face_rect_w , face_rect_h, orientation" + +#define SELECT_PATH_FROM_UNEXTRACTED_DCM_MEDIA "SELECT media_uuid, path, storage_uuid, width, height, orientation, mime_type FROM media WHERE media_uuid NOT IN (SELECT DISTINCT media_uuid FROM face_scan_list) AND validity=1 AND media_type=0 AND (storage_type = 0 OR storage_type = 1);" +#define SELECT_PATH_FROM_UNEXTRACTED_DCM_INTERNAL_MEDIA "SELECT media_uuid, path, storage_uuid, width, height, orientation, mime_type FROM media WHERE media_uuid NOT IN (SELECT DISTINCT media_uuid FROM face_scan_list) AND validity=1 AND media_type=0 AND storage_type=0;" + +#define SELECT_MEDIA_INFO_BY_FILE_PATH_FROM_DB "SELECT media_uuid, storage_uuid, width, height, orientation, mime_type FROM media WHERE path = '%q';" +#define INSERT_FACE_ITEM_TO_DB "INSERT INTO " DB_TABLE_FACE" (" FACE_ITEM") VALUES ('%q', '%q', %d, %d, %d, %d, %d);" + +typedef struct { + char *face_uuid; + char *media_uuid; + unsigned int face_rect_x; + unsigned int face_rect_y; + unsigned int face_rect_w; + unsigned int face_rect_h; + int orientation; +} dcm_face_item_s; + +typedef struct { + char *media_uuid; + char *storage_uuid; + unsigned char rgb_r; + unsigned char rgb_g; + unsigned char rgb_b; +} dcm_color_item_s; + +int dcm_svc_db_connect(uid_t uid); +int dcm_svc_db_disconnect(); +int dcm_svc_db_get_scan_image_list_by_path(GList **image_list, gboolean mmc_mounted, const char *file_path); +int dcm_svc_db_get_scan_image_list_from_db(GList **image_list, gboolean mmc_mounted); +int dcm_svc_db_insert_category_to_db(void *item); +int dcm_svc_db_generate_uuid(dcm_face_item_s **face); +int dcm_svc_db_insert_face_to_db(dcm_face_item_s *face); +int dcm_svc_db_update_color_to_db(const dcm_color_item_s color); +int dcm_svc_db_insert_face_to_face_scan_list(dcm_svc_item_s *scan_item); +int dcm_svc_db_check_scanned_by_media_uuid(const char *media_uuid, gboolean *media_scanned); + +#endif /*_DCM_DB_UTILS_H_*/ + diff --git a/include/dcm_svc_debug.h b/include/dcm_svc_debug.h new file mode 100755 index 0000000..4fce682 --- /dev/null +++ b/include/dcm_svc_debug.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * 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 _DCM_DEBUG_UTILS_H_ +#define _DCM_DEBUG_UTILS_H_ + +#include + +#ifdef LOG_TAG +#undef LOG_TAG +#endif + +#define LOG_TAG "DCM_SVC" + +#define FONT_COLOR_RESET "\033[0m" +#define FONT_COLOR_RED "\033[31m" +#define FONT_COLOR_GREEN "\033[32m" +#define FONT_COLOR_YELLOW "\033[33m" +#define FONT_COLOR_BLUE "\033[34m" +#define FONT_COLOR_PURPLE "\033[35m" +#define FONT_COLOR_CYAN "\033[36m" +#define FONT_COLOR_GRAY "\033[37m" + +#define dcm_debug(fmt, arg...) do { \ + LOGD(FONT_COLOR_CYAN"" fmt "" FONT_COLOR_RESET, ##arg); \ + } while (0) + +#define dcm_info(fmt, arg...) do { \ + LOGI(FONT_COLOR_YELLOW"" fmt "" FONT_COLOR_RESET, ##arg); \ + } while (0) + +#define dcm_warn(fmt, arg...) do { \ + LOGW(FONT_COLOR_GREEN"" fmt "" FONT_COLOR_RESET, ##arg); \ + } while (0) + +#define dcm_error(fmt, arg...) do { \ + LOGE(FONT_COLOR_RED"" fmt "" FONT_COLOR_RESET, ##arg); \ + } while (0) + +#define dcm_sec_debug(fmt, arg...) do { \ + SECURE_LOGD(FONT_COLOR_CYAN"" fmt "" FONT_COLOR_RESET, ##arg); \ + } while (0) + +#define dcm_sec_info(fmt, arg...) do { \ + SECURE_LOGI(FONT_COLOR_YELLOW"" fmt "" FONT_COLOR_RESET, ##arg); \ + } while (0) + +#define dcm_sec_warn(fmt, arg...) do { \ + SECURE_LOGW(FONT_COLOR_GREEN"" fmt "" FONT_COLOR_RESET, ##arg); \ + } while (0) + +#define dcm_sec_error(fmt, arg...) do { \ + SECURE_LOGE(FONT_COLOR_RED"" fmt "" FONT_COLOR_RESET, ##arg); \ + } while (0) +#define dcm_debug_fenter() do { \ + LOGD(FONT_COLOR_RESET""); \ + } while (0) + +#define dcm_debug_fleave() do { \ + LOGD(FONT_COLOR_RESET""); \ + } while (0) +#define dcm_retm_if(expr, fmt, arg...) do { \ + if (expr) { \ + LOGE(FONT_COLOR_RED"" fmt "" FONT_COLOR_RESET, ##arg); \ + return; \ + } \ + } while (0) + +#define dcm_retvm_if(expr, val, fmt, arg...) do { \ + if (expr) { \ + LOGE(FONT_COLOR_RED"" fmt "" FONT_COLOR_RESET, ##arg); \ + return (val); \ + } \ + } while (0) + +#define ERR_BUF_LENGHT 256 +#define dcm_stderror(fmt) do { \ + char dcm_stderror_buf[ERR_BUF_LENGHT] = {0, }; \ + LOGE(fmt" : standard error= [%s]", strerror_r(errno, dcm_stderror_buf, ERR_BUF_LENGHT)); \ + } while (0) + +#define DCM_CHECK_VAL(expr, val) dcm_retvm_if(!(expr), val, "Invalid parameter, return ERROR code!") +#define DCM_CHECK_NULL(expr) dcm_retvm_if(!(expr), NULL, "Invalid parameter, return NULL!") +#define DCM_CHECK_FALSE(expr) dcm_retvm_if(!(expr), FALSE, "Invalid parameter, return FALSE!") +#define DCM_CHECK(expr) dcm_retm_if(!(expr), "Invalid parameter, return!") + +#define DCM_SAFE_FREE(ptr) { if (ptr) {free(ptr); ptr = NULL; } } + +#endif /* _DCM_DEBUG_UTILS_H_ */ + diff --git a/include/dcm_svc_detect_face.h b/include/dcm_svc_detect_face.h new file mode 100755 index 0000000..841a138 --- /dev/null +++ b/include/dcm_svc_detect_face.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * 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 _DCM_SVC_FACE_H_ +#define _DCM_SVC_FACE_H_ + +#include + +int face_detect_initialize(); +int face_detect_finalize(); +int face_detect_process(dcm_svc_item_s *scan_item, dcm_image_info_s *image_info); + +#endif /*_DCM_SVC_FACE_H_*/ + diff --git a/include/dcm_svc_extract_color.h b/include/dcm_svc_extract_color.h new file mode 100755 index 0000000..e06aede --- /dev/null +++ b/include/dcm_svc_extract_color.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * 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 _DCM_SVC_COLOR_H_ +#define _DCM_SVC_COLOR_H_ + +#include + +int color_extract_process(dcm_svc_item_s *scan_item, dcm_image_info_s *image_info); + +#endif /*_DCM_SVC_COLOR_H_*/ + diff --git a/include/dcm_svc_internal.h b/include/dcm_svc_internal.h new file mode 100755 index 0000000..b9d89c5 --- /dev/null +++ b/include/dcm_svc_internal.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * 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 _DCM_SCAN_SVC_H_ +#define _DCM_SCAN_SVC_H_ + +#include + +typedef struct { + GMainLoop *main_loop; + GMainContext *main_context; + gboolean g_scan_cancel; + GSource *kill_timer_source; + + /* scan all images */ + GList *scan_all_item_list; + unsigned int scan_all_curr_index; + + /* scan single images */ + GList *scan_single_item_list; + unsigned int scan_single_curr_index; + + uid_t g_uid; +} dcm_scan_s; + +gboolean dcm_scan_thread(void *data); +int dcm_scan_single(const char *file_path, uid_t uid, int *face_count); + +void quit_scan_thread(); + +#endif /* _DCM_SCAN_SVC_H_ */ + diff --git a/include/dcm_svc_ipc.h b/include/dcm_svc_ipc.h new file mode 100755 index 0000000..e8606bd --- /dev/null +++ b/include/dcm_svc_ipc.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * 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 _DCM_SVC_IPC_H_ +#define _DCM_SVC_IPC_H_ + +#include +#include + +#define DCM_TIMEOUT_SEC_60 60 /**< Response to media server time out */ + +int dcm_ipc_create_socket(int *socket_fd, dcm_ipc_port_e port); +int dcm_ipc_accept_socket(int serv_sock, int *client_sock); +int dcm_ipc_receive_message(int client_sock, dcmMsg *recv_msg); +int dcm_ipc_send_message(ms_dcm_msg_type_e msg_type, uid_t uid, const char *msg, dcm_ipc_port_e port); +int dcm_ipc_send_complete(ms_dcm_msg_type_e msg_type, const unsigned int count, const char *msg, dcm_ipc_port_e port); +int dcm_ipc_send_client_message(int socket_fd, ms_dcm_msg_type_e msg_type, unsigned int result, const char *msg, dcm_ipc_port_e port); +int dcm_ipc_close_socket(int socket_fd); + +#endif /* _DCM_SVC_IPC_H_ */ + diff --git a/include/dcm_svc_main.h b/include/dcm_svc_main.h new file mode 100755 index 0000000..26aa670 --- /dev/null +++ b/include/dcm_svc_main.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * 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 _DCM_MAIN_SVC_H_ +#define _DCM_MAIN_SVC_H_ + +#include +#include +#include + +#ifndef EXPORT_API +#define EXPORT_API __attribute__ ((visibility("default"))) +#endif + +typedef struct { + // main thread + GMainLoop *main_loop; + GMainContext *main_context; + GSource *kill_timer_source; + + // scan thread + GThread *scan_thread; + GAsyncQueue *scan_thread_ready; + gboolean scan_thread_working; +} dcm_service_s; + +#endif /* _DCM_MAIN_SVC_H_ */ + diff --git a/include/dcm_svc_type.h b/include/dcm_svc_type.h new file mode 100755 index 0000000..4189971 --- /dev/null +++ b/include/dcm_svc_type.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * 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 _DCM_TYPES_H_ +#define _DCM_TYPES_H_ + +#include +#include + +/* + * Definitions defined here can be used by all threads + * If a definition can only be used in a specific thread, then this definition should be defined in that thread, not here. + */ + +#define DCM_MAX_PATH_SIZE 4096 +#define DCM_IPC_MSG_MAX_SIZE 4096 +#define DCM_DB_QUERY_MAX_SIZE 4096 + +typedef enum { + DCM_IPC_PORT_SCAN_RECV = 0, + DCM_IPC_PORT_DCM_RECV, + DCM_IPC_PORT_MS_RECV, + DCM_IPC_PORT_MAX, +} dcm_ipc_port_e; + +typedef enum { + DCM_SCAN_ITEM_TYPE_NONE, + DCM_SCAN_ITEM_TYPE_SCAN_ALL, + DCM_SCAN_ITEM_TYPE_SCAN_SINGLE, + DCM_SCAN_ITEM_TYPE_MAX, +} dcm_svc_type_e; + +typedef enum { + DCM_SVC_I420, + DCM_SVC_RGB, + DCM_SVC_RGBA, +} dcm_image_type_e; + +typedef struct { + char *media_uuid; + char *file_path; + char *storage_uuid; + int image_width; + int image_height; + int image_orientation; + char *mime_type; + int face_count; + dcm_svc_type_e scan_item_type; +} dcm_svc_item_s; + +typedef struct { + unsigned char *pixel; /* decoding results, must be freed after use */ + unsigned long long size; + int orientation; /* orientation information extracted from exif */ + unsigned int original_width; /* original image width */ + unsigned int original_height; /* original image height */ + unsigned int buffer_width; /* scaled image width used by decoder (width/height ratio should be the same as original) */ + unsigned int buffer_height; /* scaled image height used by decoder (width/height ratio should be the same as original) */ + dcm_image_type_e decode_type; /* decoding pre-condition */ +} dcm_image_info_s; + +#endif /* _DCM_TYPES_H_ */ + diff --git a/libdcm-util/dcm_image_codec.c b/libdcm-util/dcm_image_codec.c new file mode 100755 index 0000000..804bf5c --- /dev/null +++ b/libdcm-util/dcm_image_codec.c @@ -0,0 +1,299 @@ +/* + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MIME_TYPE_JPEG "image/jpeg" +#define MIME_TYPE_PNG "image/png" +#define MIME_TYPE_BMP "image/bmp" + +#define OPT_IMAGE_WIDTH 1280 +#define OPT_IMAGE_HEIGHT 720 + +static void _dcm_get_optimized_wh(unsigned int src_width, unsigned int src_height, unsigned int *calc_width, unsigned int *calc_height) +{ + *calc_width = 0; + *calc_height = 0; + + if (src_width <= OPT_IMAGE_WIDTH && src_height <= OPT_IMAGE_HEIGHT) { + dcm_debug("Original image is smaller than target image"); + *calc_width = src_width; + *calc_height = src_height; + return; + } + + if (src_width > src_height) { + *calc_width = OPT_IMAGE_WIDTH; + *calc_height = (int)(src_height * (((double) OPT_IMAGE_WIDTH) / ((double) src_width))); + } else { + *calc_width = (int)(src_width * (((double) OPT_IMAGE_HEIGHT) / ((double) src_height))); + *calc_height = OPT_IMAGE_HEIGHT; + } +} + +static int _dcm_rotate_image(const unsigned char *source, const dcm_image_format_e format, const int orientation, unsigned char **image_buffer, unsigned long long *size, unsigned int *buff_width, unsigned int *buff_height) +{ + int ret = IMAGE_UTIL_ERROR_NONE; + image_util_colorspace_e colorspace = IMAGE_UTIL_COLORSPACE_RGBA8888; + image_util_rotation_e rotate = IMAGE_UTIL_ROTATION_NONE; + unsigned char *rotated_buffer = NULL; + unsigned int rotated_buffer_size = 0; + int rotated_width = 0, rotated_height = 0; + + DCM_CHECK_VAL(source, MS_MEDIA_ERR_INVALID_PARAMETER); + + if (format == DCM_IMAGE_FORMAT_I420) + colorspace = IMAGE_UTIL_COLORSPACE_I420; + else if (format == DCM_IMAGE_FORMAT_RGB) + colorspace = IMAGE_UTIL_COLORSPACE_RGB888; + else if (format == DCM_IMAGE_FORMAT_RGBA) + colorspace = IMAGE_UTIL_COLORSPACE_RGBA8888; + else + return MS_MEDIA_ERR_UNSUPPORTED_CONTENT; + + /* Get rotate angle enum */ + if (orientation == DEGREE_180) + rotate = IMAGE_UTIL_ROTATION_180; + else if (orientation == DEGREE_90) + rotate = IMAGE_UTIL_ROTATION_90; + else if (orientation == DEGREE_270) + rotate = IMAGE_UTIL_ROTATION_270; + else + rotate = IMAGE_UTIL_ROTATION_NONE; + + dcm_debug("orientation: %d, rotate: %d", orientation, rotate); + + if (rotate == IMAGE_UTIL_ROTATION_90 || rotate == IMAGE_UTIL_ROTATION_270) { + rotated_width = *buff_height; + rotated_height = *buff_width; + } else { + rotated_width = *buff_width; + rotated_height = *buff_height; + } + + /* Calculate the rotated buffer size */ + ret = image_util_calculate_buffer_size(rotated_width, rotated_height, colorspace, &rotated_buffer_size); + if (ret != IMAGE_UTIL_ERROR_NONE) { + dcm_error("Failed to calculate buffer size! err: %d", ret); + return MS_MEDIA_ERR_INTERNAL; + } + + /* Allocate rotated buffer */ + if (rotated_buffer_size <= 0) { + dcm_error("Invalid rotated buffer size!"); + return MS_MEDIA_ERR_INTERNAL; + } + + dcm_debug("rotate buffer size: %u", rotated_buffer_size); + rotated_buffer = (unsigned char *) g_malloc0(rotated_buffer_size); + if (rotated_buffer == NULL) { + dcm_error("rotated_buffer is NULL!"); + return MS_MEDIA_ERR_INTERNAL; + } + + *size = rotated_buffer_size; + + /* Rotate input buffer */ + ret = image_util_rotate(rotated_buffer, &rotated_width, &rotated_height, rotate, source, + *buff_width, *buff_height, colorspace); + + if (ret != IMAGE_UTIL_ERROR_NONE || rotated_buffer == NULL) { + dcm_error("Failed to rotate image buffer! err: %d", ret); + DCM_SAFE_FREE(rotated_buffer); + return MS_MEDIA_ERR_INTERNAL; + } + + /* Decoded buffer size is set to rotated buffer size to match buffer */ + dcm_debug("After rotation: [width: %d] [height: %d]", rotated_width, rotated_height); + *buff_width = rotated_width; + *buff_height = rotated_height; + + /* Allocated data should be freed when scanning is finished for this rotated image */ + *image_buffer = rotated_buffer; + dcm_warn("rotated decode buffer: %p", *image_buffer); + + return MS_MEDIA_ERR_NONE; +} + +int _dcm_rotate_rgb(unsigned char *source, const unsigned long long *size, int format, unsigned int *ori_width, unsigned int *ori_height) +{ + unsigned int dpp = 0; /* data per pixel */ + unsigned int x = 0, y = 0; + unsigned int i = 0; + unsigned int width = 0, height = 0; + unsigned char *temp_buf = NULL; + size_t _size = (size_t)*size; + + if (format == DCM_IMAGE_FORMAT_RGBA) { + dpp = 4; + } else if (format == DCM_IMAGE_FORMAT_RGB) { + dpp = 3; + } else { + dcm_error("Invalid parameter"); + return MS_MEDIA_ERR_INVALID_PARAMETER; + } + + temp_buf = (unsigned char*)malloc(_size); + if (temp_buf == NULL) { + dcm_error("Failed to allocate memory"); + return MS_MEDIA_ERR_OUT_OF_MEMORY; + } + /* initialize */ + memset(temp_buf, 0x00, _size); + width = *ori_width; + height = *ori_height; + + /* rotate image to 90 degree clockwise */ + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + for (i = 0; i < dpp; i++) + temp_buf[(x * height + (height - y - 1)) * dpp + i] = source[(y * width + x) * dpp + i]; + } + } + + /* copy image from temp buffer to original buffer */ + memcpy(source, temp_buf, _size); + DCM_SAFE_FREE(temp_buf); + + /* swap width & height due to rotate 90 degree */ + *ori_width = height; + *ori_height = width; + + return MS_MEDIA_ERR_NONE; +} + +int dcm_decode_image(const char *file_path, const dcm_image_format_e format, + const char* mimne_type, const int orientation, const gboolean resize, + unsigned char **image_buffer, unsigned long long *size, + unsigned int *buff_width, unsigned int *buff_height) +{ + int ret = IMAGE_UTIL_ERROR_NONE; + image_util_colorspace_e colorspace = IMAGE_UTIL_COLORSPACE_RGBA8888; + mm_util_img_format mm_format = MM_UTIL_IMG_FMT_RGBA8888; + unsigned char *decode_buffer = NULL; + unsigned int decode_width = 0, decode_height = 0; + unsigned char *resize_buffer = NULL; + unsigned int buffer_size = 0; + image_util_decode_h handle = NULL; + + dcm_debug_fenter(); + + DCM_CHECK_VAL(file_path, MS_MEDIA_ERR_INVALID_PARAMETER); + + ret = image_util_decode_create(&handle); + if (ret != IMAGE_UTIL_ERROR_NONE) { + dcm_error("Error image_util_decode_create ret : %d", ret); + return MS_MEDIA_ERR_INTERNAL; + } + + ret = image_util_decode_set_input_path(handle, file_path); + if (ret != IMAGE_UTIL_ERROR_NONE) { + dcm_error("Error image_util_decode_set_input_path ret : %d", ret); + return MS_MEDIA_ERR_INTERNAL; + } + + if (strcmp(mimne_type, MIME_TYPE_JPEG) == 0) { + if (format == DCM_IMAGE_FORMAT_I420) { + colorspace = IMAGE_UTIL_COLORSPACE_I420; + mm_format = MM_UTIL_IMG_FMT_I420; + } else if (format == DCM_IMAGE_FORMAT_RGB) { + colorspace = IMAGE_UTIL_COLORSPACE_RGB888; + mm_format = MM_UTIL_IMG_FMT_RGB888; + } else if (format == DCM_IMAGE_FORMAT_RGBA) { + colorspace = IMAGE_UTIL_COLORSPACE_RGBA8888; + mm_format = MM_UTIL_IMG_FMT_RGBA8888; + } else { + return MS_MEDIA_ERR_UNSUPPORTED_CONTENT; + } + ret = image_util_decode_set_colorspace(handle, colorspace); + if (ret != IMAGE_UTIL_ERROR_NONE) { + dcm_error("Error image_util_decode_set_colorspace ret : %d", ret); + return MS_MEDIA_ERR_INTERNAL; + } + } + + ret = image_util_decode_set_output_buffer(handle, &decode_buffer); + if (ret != IMAGE_UTIL_ERROR_NONE) { + dcm_error("Error image_util_decode_set_output_buffer ret : %d", ret); + return MS_MEDIA_ERR_INTERNAL; + } + + ret = image_util_decode_run(handle, (unsigned long *)&decode_width, (unsigned long *)&decode_height, size); + if (ret != IMAGE_UTIL_ERROR_NONE) { + dcm_error("Error image_util_decode_run ret : %d", ret); + return MS_MEDIA_ERR_INTERNAL; + } + + ret = image_util_decode_destroy(handle); + if (ret != IMAGE_UTIL_ERROR_NONE) { + dcm_error("Error image_util_decode_destroy ret : %d", ret); + return MS_MEDIA_ERR_INTERNAL; + } + + + /* Get the optimized width/height to enhance performance for big size image */ + if (resize) { + _dcm_get_optimized_wh(decode_width, decode_height, buff_width, buff_height); + } else { + *buff_width = decode_width; + *buff_height = decode_height; + } + + /* Resize the big size image to enhance performance for big size image */ + if ((decode_width != *buff_width) || (decode_height != *buff_height)) { + ret = image_util_calculate_buffer_size(*buff_width, *buff_height, colorspace, &buffer_size); + if (ret != MS_MEDIA_ERR_NONE) { + dcm_error("Failed to calculate image buffer size! err: %d", ret); + return MS_MEDIA_ERR_INTERNAL; + } + *size = buffer_size; + resize_buffer = (unsigned char *)malloc(sizeof(unsigned char) * (buffer_size)); + if (resize_buffer != NULL) + mm_util_resize_image(decode_buffer, decode_width, decode_height, mm_format, resize_buffer, buff_width, buff_height); + } else { + resize_buffer = decode_buffer; + } + + /* Rotate the resized buffer according to orientation */ + if (orientation == 0) { + *image_buffer = resize_buffer; + } else { + if ((format == DCM_IMAGE_FORMAT_RGBA) || (format == DCM_IMAGE_FORMAT_RGB)) { + ret = _dcm_rotate_rgb(resize_buffer, size, format, buff_width, buff_height); + *image_buffer = resize_buffer; + } else { + ret = _dcm_rotate_image(resize_buffer, format, orientation, image_buffer, size, buff_width, buff_height); + } + if (ret != MS_MEDIA_ERR_NONE) { + dcm_error("Failed to rotate image buffer! err: %d", ret); + return MS_MEDIA_ERR_INTERNAL; + } + } + + dcm_debug_fleave(); + + return MS_MEDIA_ERR_NONE; +} diff --git a/libdcm-util/dcm_image_codec.cpp b/libdcm-util/dcm_image_codec.cpp deleted file mode 100755 index c4eff59..0000000 --- a/libdcm-util/dcm_image_codec.cpp +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * 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. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define MIME_TYPE_JPEG "image/jpeg" -#define MIME_TYPE_PNG "image/png" -#define MIME_TYPE_BMP "image/bmp" - -#define OPT_IMAGE_WIDTH 1280 -#define OPT_IMAGE_HEIGHT 720 - -static void _dcm_get_optimized_wh(unsigned int src_width, unsigned int src_height, unsigned int *calc_width, unsigned int *calc_height) -{ - *calc_width = 0; - *calc_height = 0; - - if (src_width <= OPT_IMAGE_WIDTH && src_height <= OPT_IMAGE_HEIGHT) { - dcm_debug("Original image is smaller than target image"); - *calc_width = src_width; - *calc_height = src_height; - return; - } - - if (src_width > src_height) { - *calc_width = OPT_IMAGE_WIDTH; - *calc_height = (int)(src_height * (((double) OPT_IMAGE_WIDTH) / ((double) src_width))); - } else { - *calc_width = (int)(src_width * (((double) OPT_IMAGE_HEIGHT) / ((double) src_height))); - *calc_height = OPT_IMAGE_HEIGHT; - } -} - -static int _dcm_rotate_image(const unsigned char *source, const dcm_image_format_e format, const int orientation, unsigned char **image_buffer, unsigned long long *size, unsigned int *buff_width, unsigned int *buff_height) -{ - int ret = IMAGE_UTIL_ERROR_NONE; - image_util_colorspace_e colorspace = IMAGE_UTIL_COLORSPACE_RGBA8888; - image_util_rotation_e rotate = IMAGE_UTIL_ROTATION_NONE; - unsigned char *rotated_buffer = NULL; - unsigned int rotated_buffer_size = 0; - int rotated_width = 0, rotated_height = 0; - - DCM_CHECK_VAL(source, MS_MEDIA_ERR_INVALID_PARAMETER); - - if (format == DCM_IMAGE_FORMAT_I420) { - colorspace = IMAGE_UTIL_COLORSPACE_I420; - } else if (format == DCM_IMAGE_FORMAT_RGB) { - colorspace = IMAGE_UTIL_COLORSPACE_RGB888; - } else if (format == DCM_IMAGE_FORMAT_RGBA) { - colorspace = IMAGE_UTIL_COLORSPACE_RGBA8888; - } else { - return MS_MEDIA_ERR_UNSUPPORTED_CONTENT; - } - - /* Get rotate angle enum */ - if (orientation == DEGREE_180) { - rotate = IMAGE_UTIL_ROTATION_180; - } else if (orientation == DEGREE_90) { - rotate = IMAGE_UTIL_ROTATION_90; - } else if (orientation == DEGREE_270) { - rotate = IMAGE_UTIL_ROTATION_270; - } else { - rotate = IMAGE_UTIL_ROTATION_NONE; - } - - dcm_debug("orientation: %d, rotate: %d", orientation, rotate); - - if (rotate == IMAGE_UTIL_ROTATION_90 || rotate == IMAGE_UTIL_ROTATION_270) { - rotated_width = *buff_height; - rotated_height = *buff_width; - } else { - rotated_width = *buff_width; - rotated_height = *buff_height; - } - - /* Calculate the rotated buffer size */ - ret = image_util_calculate_buffer_size(rotated_width, rotated_height, colorspace, &rotated_buffer_size); - if (ret != IMAGE_UTIL_ERROR_NONE) { - dcm_error("Failed to calculate buffer size! err: %d", ret); - return MS_MEDIA_ERR_INTERNAL; - } - - /* Allocate rotated buffer */ - if (rotated_buffer_size <= 0) { - dcm_error("Invalid rotated buffer size!"); - return MS_MEDIA_ERR_INTERNAL; - } - - dcm_debug("rotate buffer size: %u", rotated_buffer_size); - rotated_buffer = (unsigned char *) g_malloc0(rotated_buffer_size); - if (rotated_buffer == NULL) { - dcm_error("rotated_buffer is NULL!"); - return MS_MEDIA_ERR_INTERNAL; - } - - *size = rotated_buffer_size; - - /* Rotate input buffer */ - ret = image_util_rotate(rotated_buffer, &rotated_width, &rotated_height, rotate, source, - *buff_width, *buff_height, colorspace); - - if (ret != IMAGE_UTIL_ERROR_NONE || rotated_buffer == NULL) { - dcm_error("Failed to rotate image buffer! err: %d", ret); - DCM_SAFE_FREE(rotated_buffer); - return MS_MEDIA_ERR_INTERNAL; - } - - /* Decoded buffer size is set to rotated buffer size to match buffer */ - dcm_debug("After rotation: [width: %d] [height: %d]", rotated_width, rotated_height); - *buff_width = rotated_width; - *buff_height = rotated_height; - - /* Allocated data should be freed when scanning is finished for this rotated image */ - *image_buffer = rotated_buffer; - dcm_warn("rotated decode buffer: %p", *image_buffer); - - return MS_MEDIA_ERR_NONE; -} - -int _dcm_rotate_rgb(unsigned char *source, const unsigned long long *size, int format, unsigned int *ori_width, unsigned int *ori_height) -{ - unsigned int dpp = 0; /* data per pixel */ - unsigned int x = 0, y = 0; - unsigned int i = 0; - unsigned int width = 0, height = 0; - unsigned char *temp_buf = NULL; - size_t _size = (size_t)*size; - - if (format == DCM_IMAGE_FORMAT_RGBA) { - dpp = 4; - } else if (format == DCM_IMAGE_FORMAT_RGB) { - dpp = 3; - } else { - dcm_error("Invalid parameter"); - return MS_MEDIA_ERR_INVALID_PARAMETER; - } - - temp_buf = (unsigned char*)malloc(_size); - if (temp_buf == NULL) { - dcm_error("Failed to allocate memory"); - return MS_MEDIA_ERR_OUT_OF_MEMORY; - } - /* initialize */ - memset(temp_buf, 0x00, _size); - width = *ori_width; - height = *ori_height; - - /* rotate image to 90 degree clockwise */ - for (y = 0; y < height; y++) - { - for (x = 0; x < width; x++) { - for (i = 0; i < dpp; i++) { - temp_buf[(x * height + (height - y - 1)) * dpp + i] = source[(y * width + x) * dpp + i]; - } - } - } - - /* copy image from temp buffer to original buffer */ - memcpy(source, temp_buf, _size); - DCM_SAFE_FREE(temp_buf); - - /* swap width & height due to rotate 90 degree */ - *ori_width = height; - *ori_height = width; - - return MS_MEDIA_ERR_NONE; -} - -int dcm_decode_image(const char *file_path, const dcm_image_format_e format, - const char* mimne_type, const int orientation, const bool resize, - unsigned char **image_buffer, unsigned long long *size, - unsigned int *buff_width, unsigned int *buff_height) -{ - int ret = IMAGE_UTIL_ERROR_NONE; - image_util_colorspace_e colorspace = IMAGE_UTIL_COLORSPACE_RGBA8888; - mm_util_img_format mm_format = MM_UTIL_IMG_FMT_RGBA8888; - unsigned char *decode_buffer = NULL; - unsigned int decode_width = 0, decode_height = 0; - unsigned char *resize_buffer = NULL; - unsigned int buffer_size = 0; - image_util_decode_h handle = NULL; - - dcm_debug_fenter(); - - DCM_CHECK_VAL(file_path, MS_MEDIA_ERR_INVALID_PARAMETER); - - ret = image_util_decode_create(&handle); - if (ret != IMAGE_UTIL_ERROR_NONE) { - dcm_error("Error image_util_decode_create ret : %d", ret); - return MS_MEDIA_ERR_INTERNAL; - } - - ret = image_util_decode_set_input_path(handle, file_path); - if (ret != IMAGE_UTIL_ERROR_NONE) { - dcm_error("Error image_util_decode_set_input_path ret : %d", ret); - return MS_MEDIA_ERR_INTERNAL; - } - - if (strcmp(mimne_type, MIME_TYPE_JPEG) == 0) { - if (format == DCM_IMAGE_FORMAT_I420) { - colorspace = IMAGE_UTIL_COLORSPACE_I420; - mm_format = MM_UTIL_IMG_FMT_I420; - } else if (format == DCM_IMAGE_FORMAT_RGB) { - colorspace = IMAGE_UTIL_COLORSPACE_RGB888; - mm_format = MM_UTIL_IMG_FMT_RGB888; - } else if (format == DCM_IMAGE_FORMAT_RGBA) { - colorspace = IMAGE_UTIL_COLORSPACE_RGBA8888; - mm_format = MM_UTIL_IMG_FMT_RGBA8888; - } else { - return MS_MEDIA_ERR_UNSUPPORTED_CONTENT; - } - ret = image_util_decode_set_colorspace(handle, colorspace); - if (ret != IMAGE_UTIL_ERROR_NONE) { - dcm_error("Error image_util_decode_set_colorspace ret : %d", ret); - return MS_MEDIA_ERR_INTERNAL; - } - } - - ret = image_util_decode_set_output_buffer(handle, &decode_buffer); - if (ret != IMAGE_UTIL_ERROR_NONE) { - dcm_error("Error image_util_decode_set_output_buffer ret : %d", ret); - return MS_MEDIA_ERR_INTERNAL; - } - - ret = image_util_decode_run(handle, (unsigned long *)&decode_width, (unsigned long *)&decode_height, size); - if (ret != IMAGE_UTIL_ERROR_NONE) { - dcm_error("Error image_util_decode_run ret : %d", ret); - return MS_MEDIA_ERR_INTERNAL; - } - - ret = image_util_decode_destroy(handle); - if (ret != IMAGE_UTIL_ERROR_NONE) { - dcm_error("Error image_util_decode_destroy ret : %d", ret); - return MS_MEDIA_ERR_INTERNAL; - } - - - /* Get the optimized width/height to enhance performance for big size image */ - if (resize) { - _dcm_get_optimized_wh(decode_width, decode_height, buff_width, buff_height); - } else { - *buff_width = decode_width; - *buff_height = decode_height; - } - - /* Resize the big size image to enhance performance for big size image */ - if ((decode_width != *buff_width) || (decode_height != *buff_height)) { - ret = image_util_calculate_buffer_size(*buff_width, *buff_height, colorspace, &buffer_size); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to calculate image buffer size! err: %d", ret); - return MS_MEDIA_ERR_INTERNAL; - } - *size = buffer_size; - resize_buffer = (unsigned char *)malloc(sizeof(unsigned char) * (buffer_size)); - if (resize_buffer != NULL) { - mm_util_resize_image(decode_buffer, decode_width, decode_height, mm_format, resize_buffer, buff_width, buff_height); - } - } else { - resize_buffer = decode_buffer; - } - - /* Rotate the resized buffer according to orientation */ - if (orientation == 0) { - *image_buffer = resize_buffer; - } else { - if ((format == DCM_IMAGE_FORMAT_RGBA) || (format == DCM_IMAGE_FORMAT_RGB)) { - ret = _dcm_rotate_rgb(resize_buffer, size, format, buff_width, buff_height); - *image_buffer = resize_buffer; - } else { - ret = _dcm_rotate_image(resize_buffer, format, orientation, image_buffer, size, buff_width, buff_height); - } - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to rotate image buffer! err: %d", ret); - return MS_MEDIA_ERR_INTERNAL; - } - } - - dcm_debug_fleave(); - - return MS_MEDIA_ERR_NONE; -} diff --git a/libdcm-util/include/dcm_image_codec.h b/libdcm-util/include/dcm_image_codec.h index 7a0a7e4..22d8129 100755 --- a/libdcm-util/include/dcm_image_codec.h +++ b/libdcm-util/include/dcm_image_codec.h @@ -45,7 +45,7 @@ typedef struct { int dcm_decode_image(const char *file_path, const dcm_image_format_e format, - const char* mimne_type, const int orientation, const bool resize, + const char* mimne_type, const int orientation, const gboolean resize, unsigned char **image_buffer, unsigned long long *size, unsigned int *buff_width, unsigned int *buff_height); diff --git a/packaging/dcm-service.spec b/packaging/dcm-service.spec index 60edb61..dfd3d68 100755 --- a/packaging/dcm-service.spec +++ b/packaging/dcm-service.spec @@ -1,6 +1,6 @@ Name: dcm-service Summary: A media DCM(Digital Contents Management) Service -Version: 0.0.18 +Version: 0.1.0 Release: 0 Group: Multimedia/Service License: Apache-2.0 diff --git a/src/DcmColorUtils.cpp b/src/DcmColorUtils.cpp deleted file mode 100755 index 44c67e1..0000000 --- a/src/DcmColorUtils.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * 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. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -int DcmColorUtils::runColorExtractProcess(DcmScanItem *scan_item, DcmImageInfo *image_info) -{ - DCM_CHECK_VAL(scan_item, MS_MEDIA_ERR_INVALID_PARAMETER); - DCM_CHECK_VAL(image_info, MS_MEDIA_ERR_INVALID_PARAMETER); - DCM_CHECK_VAL(image_info->pixel, MS_MEDIA_ERR_INVALID_PARAMETER); - - dcm_debug_fenter(); -#if 0 - DcmDbUtils *dcmDbUtils = DcmDbUtils::getInstance(); - int ret = IMAGE_UTIL_ERROR_NONE; - DcmColorItem colorItem = {0,}; - memset(&colorItem, 0, sizeof(DcmColorItem)); - - // Extracting color supports only RGB888 format - ret = image_util_extract_color_from_memory(image_info->pixel, image_info->buffer_width, image_info->buffer_height, &(colorItem.rgb_r), &(colorItem.rgb_g), &(colorItem.rgb_b)); - if (ret != IMAGE_UTIL_ERROR_NONE) { - dcm_error("image_util_extract_color_from_memory err= %d", ret); - return MS_MEDIA_ERR_INTERNAL; - } - - dcm_debug("image_util_extract_color_from_memory result r:%02x, g:%02x, b:%02x", colorItem.rgb_r, colorItem.rgb_g, colorItem.rgb_b); - - colorItem.media_uuid = strdup(scan_item->media_uuid); - colorItem.storage_uuid = strdup(scan_item->storage_uuid); - ret = dcmDbUtils->_dcm_svc_db_update_color_to_db(colorItem); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to update color item into db! err: %d", ret); - return MS_MEDIA_ERR_DB_INTERNAL; - } -#endif - dcm_debug_fleave(); - - return MS_MEDIA_ERR_NONE; -} - diff --git a/src/DcmDbUtils.cpp b/src/DcmDbUtils.cpp deleted file mode 100755 index 9929faf..0000000 --- a/src/DcmDbUtils.cpp +++ /dev/null @@ -1,531 +0,0 @@ -/* - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * 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. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DCM_STRING_VALID(str) ((str != NULL && strlen(str) > 0) ? TRUE : FALSE) -#define DCM_SQLITE3_FINALIZE(x) {if (x != NULL) {sqlite3_finalize(x);x=NULL;}} -#define DCM_SQLITE3_FREE(x) {if (x != NULL) {sqlite3_free(x);x=NULL;}} - -#define DB_TABLE_FACE "face" -#define DB_TABLE_FACE_SCAN_LIST "face_scan_list" -#define DB_TABLE_MEDIA "media" -#define FACE_ITEM "face_uuid, media_uuid, face_rect_x , face_rect_y, face_rect_w , face_rect_h, orientation" - -#define SELECT_PATH_FROM_UNEXTRACTED_DCM_MEDIA "SELECT media_uuid, path, storage_uuid, width, height, orientation, mime_type FROM media WHERE media_uuid NOT IN (SELECT DISTINCT media_uuid FROM face_scan_list) AND validity=1 AND media_type=0 AND (storage_type = 0 OR storage_type = 1);" -#define SELECT_PATH_FROM_UNEXTRACTED_DCM_INTERNAL_MEDIA "SELECT media_uuid, path, storage_uuid, width, height, orientation, mime_type FROM media WHERE media_uuid NOT IN (SELECT DISTINCT media_uuid FROM face_scan_list) AND validity=1 AND media_type=0 AND storage_type=0;" - -#define SELECT_MEDIA_INFO_BY_FILE_PATH_FROM_DB "SELECT media_uuid, storage_uuid, width, height, orientation, mime_type FROM media WHERE path = '%q';" -#define INSERT_FACE_ITEM_TO_DB "INSERT INTO " DB_TABLE_FACE" (" FACE_ITEM") VALUES ('%q', '%q', %d, %d, %d, %d, %d);" - -static GMutex gMutexLock; - -namespace DcmDbUtilsInternal { -bool __dcm_svc_db_check_duplicated(MediaDBHandle *db_handle, DcmFaceItem *data); -bool __dcm_svc_db_check_duplicated_scan_list(MediaDBHandle *db_handle, const char *data); -static int __dcm_svc_sql_prepare_to_step(sqlite3 *handle, const char *sql_str, sqlite3_stmt** stmt); -static int __dcm_svc_sql_prepare_to_step_simple(sqlite3 *handle, const char *sql_str, sqlite3_stmt** stmt); -} - -DcmDbUtils* DcmDbUtils::getInstance(void) -{ - if (dcmDbUtils == NULL) { - g_mutex_trylock(&gMutexLock); - - if (dcmDbUtils == NULL) { - dcmDbUtils = new DcmDbUtils(); - } - - g_mutex_unlock(&gMutexLock); - } - - return dcmDbUtils; -} - -DcmDbUtils *DcmDbUtils::dcmDbUtils = NULL; -MediaDBHandle *DcmDbUtils::db_handle = NULL; - -DcmDbUtils::DcmDbUtils(void) -{ - -} - -bool DcmDbUtilsInternal::__dcm_svc_db_check_duplicated(MediaDBHandle *db_handle, DcmFaceItem *data) -{ - int ret = MS_MEDIA_ERR_NONE; - sqlite3 * handle = (sqlite3 *)db_handle; - sqlite3_stmt *sql_stmt = NULL; - char *query_string = NULL; - int count = 0; - - DCM_CHECK_FALSE((data != NULL)); - DCM_CHECK_FALSE((data->media_uuid != NULL)); - - query_string = sqlite3_mprintf("SELECT count(*) FROM %s WHERE (media_uuid='%s' AND" - " face_rect_x='%d' AND face_rect_y='%d' AND face_rect_w='%d' AND face_rect_h='%d' AND orientation='%d')" - , DB_TABLE_FACE, data->media_uuid - , data->face_rect_x, data->face_rect_y, data->face_rect_w, data->face_rect_h, data->orientation); - - ret = __dcm_svc_sql_prepare_to_step(handle, query_string, &sql_stmt); - - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("error when __dcm_svc_sql_prepare_to_step. ret = [%d]", ret); - return TRUE; - } - - count = sqlite3_column_int(sql_stmt, 0); - - DCM_SQLITE3_FINALIZE(sql_stmt); - - if (count > 0) { - dcm_warn("duplicated face data!"); - return TRUE; - } - - return FALSE; -} - -bool DcmDbUtilsInternal::__dcm_svc_db_check_duplicated_scan_list(MediaDBHandle *db_handle, const char *data) -{ - int ret = MS_MEDIA_ERR_NONE; - sqlite3 * handle = (sqlite3 *)db_handle; - sqlite3_stmt *sql_stmt = NULL; - char *query_string = NULL; - int count = 0; - - DCM_CHECK_FALSE((data != NULL)); - - query_string = sqlite3_mprintf("SELECT count(*) FROM %s WHERE media_uuid='%s'", DB_TABLE_FACE_SCAN_LIST, data); - - ret = __dcm_svc_sql_prepare_to_step(handle, query_string, &sql_stmt); - - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("error when __dcm_svc_sql_prepare_to_step. ret = [%d]", ret); - return TRUE; - } - - count = sqlite3_column_int(sql_stmt, 0); - - DCM_SQLITE3_FINALIZE(sql_stmt); - - if (count > 0) { - dcm_warn("duplicated media data!"); - return TRUE; - } - - return FALSE; -} - - -static int DcmDbUtilsInternal::__dcm_svc_sql_prepare_to_step(sqlite3 *handle, const char *sql_str, sqlite3_stmt** stmt) -{ - int ret = MS_MEDIA_ERR_NONE; - - dcm_debug("[SQL query] : %s", sql_str); - - if (!DCM_STRING_VALID(sql_str)) - { - dcm_error("invalid query"); - return MS_MEDIA_ERR_INVALID_PARAMETER; - } - - ret = sqlite3_prepare_v2(handle, sql_str, -1, stmt, NULL); - sqlite3_free((char *)sql_str); - - if (ret != SQLITE_OK) { - dcm_error ("prepare error %d[%s]", ret, sqlite3_errmsg(handle)); - if (ret == SQLITE_CORRUPT) { - return MS_MEDIA_ERR_DB_CORRUPT; - } else if (ret == SQLITE_PERM) { - return MS_MEDIA_ERR_DB_PERMISSION; - } - - return MS_MEDIA_ERR_DB_INTERNAL; - } - - ret = sqlite3_step(*stmt); - if (ret != SQLITE_ROW) { - dcm_error("[No-Error] Item not found. end of row [%s]", sqlite3_errmsg(handle)); - DCM_SQLITE3_FINALIZE(*stmt); - return MS_MEDIA_ERR_DB_NO_RECORD; - } - - return MS_MEDIA_ERR_NONE; -} - -static int DcmDbUtilsInternal::__dcm_svc_sql_prepare_to_step_simple(sqlite3 *handle, const char *sql_str, sqlite3_stmt** stmt) -{ - int ret = MS_MEDIA_ERR_NONE; - - dcm_debug("[SQL query] : %s", sql_str); - - if (!DCM_STRING_VALID(sql_str)) - { - dcm_error("invalid query"); - return MS_MEDIA_ERR_INVALID_PARAMETER; - } - - ret = sqlite3_prepare_v2(handle, sql_str, -1, stmt, NULL); - sqlite3_free((char *)sql_str); - - if (ret != SQLITE_OK) { - dcm_error ("prepare error %d[%s]", ret, sqlite3_errmsg(handle)); - if (ret == SQLITE_CORRUPT) { - return MS_MEDIA_ERR_DB_CORRUPT; - } else if (ret == SQLITE_PERM) { - return MS_MEDIA_ERR_DB_PERMISSION; - } - - return MS_MEDIA_ERR_DB_INTERNAL; - } - - return MS_MEDIA_ERR_NONE; -} - -int DcmDbUtils::_dcm_svc_db_connect(uid_t uid) -{ - int ret = MS_MEDIA_ERR_NONE; - - dcm_debug("_dcm_svc_db_connect uid: %d", uid); - dcm_uid = uid; - - ret = media_db_connect(&db_handle, dcm_uid, TRUE); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("media_db_connect failed: %d", ret); - db_handle = NULL; - return ret; - } - - dcm_warn("media db handle: %p", db_handle); - - dcm_debug_fleave(); - - return MS_MEDIA_ERR_NONE; -} - -int DcmDbUtils::_dcm_svc_db_disconnect(void) -{ - int ret = MS_MEDIA_ERR_NONE; - - dcm_warn("media db handle: %p", db_handle); - - if (db_handle != NULL) { - ret = media_db_disconnect(db_handle); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("media_db_disconnect failed: %d", ret); - db_handle = NULL; - return ret; - } - } - - db_handle = NULL; - - dcm_debug_fleave(); - - return MS_MEDIA_ERR_NONE; -} - - -int DcmDbUtils::_dcm_svc_db_get_scan_image_list_by_path(GList **image_list, bool mmc_mounted, const char *file_path) -{ - int ret = MS_MEDIA_ERR_NONE; - char *query_string = NULL; - sqlite3_stmt *sql_stmt = NULL; - - dcm_debug_fenter(); - - DCM_CHECK_VAL(db_handle, MS_MEDIA_ERR_INVALID_PARAMETER); - DCM_CHECK_VAL(file_path, MS_MEDIA_ERR_INVALID_PARAMETER); - - /* Make query */ - if (mmc_mounted == true) { - query_string = sqlite3_mprintf(SELECT_MEDIA_INFO_BY_FILE_PATH_FROM_DB, file_path); - } else { - query_string = sqlite3_mprintf(SELECT_MEDIA_INFO_BY_FILE_PATH_FROM_DB, file_path); - } - - if (query_string == NULL) { - dcm_error("Failed to make query!"); - return MS_MEDIA_ERR_OUT_OF_MEMORY; - } - - ret = DcmDbUtilsInternal::__dcm_svc_sql_prepare_to_step_simple((sqlite3 *)db_handle, query_string, &sql_stmt); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("error when __dcm_svc_sql_prepare_to_step. ret = [%d]", ret); - return TRUE; - } - - while(sqlite3_step(sql_stmt) == SQLITE_ROW) { - DcmScanItem *scan_item = (DcmScanItem *) g_malloc0(sizeof(DcmScanItem)); - if (!scan_item) { - dcm_error("Failed to allocate memory for scan_item!"); - continue; - } - - if (DCM_STRING_VALID((const char *)sqlite3_column_text(sql_stmt, 0))) - scan_item->media_uuid = strdup((const char *)sqlite3_column_text(sql_stmt, 0)); - - if (DCM_STRING_VALID(file_path)) - scan_item->file_path = strdup(file_path); - - if (DCM_STRING_VALID((const char *)sqlite3_column_text(sql_stmt, 1))) - scan_item->storage_uuid = strdup((const char *)sqlite3_column_text(sql_stmt, 1)); - - scan_item->image_width = sqlite3_column_int(sql_stmt, 2); - scan_item->image_height = sqlite3_column_int(sql_stmt, 3); - scan_item->image_orientation = sqlite3_column_int(sql_stmt, 4); - scan_item->mime_type = g_strdup((const char *)sqlite3_column_text(sql_stmt, 5)); - - /* scan item retrieved by this function will be marked as SCAN_SINGLE */ - scan_item->scan_item_type = DCM_SCAN_ITEM_TYPE_SCAN_SINGLE; - - *image_list = g_list_append(*image_list, scan_item); - - dcm_sec_debug("media uuid: [%s] file path: [%s]", scan_item->media_uuid, scan_item->file_path); - } - - DCM_SQLITE3_FINALIZE(sql_stmt); - - dcm_debug_fleave(); - - return ret; -} - -int DcmDbUtils::_dcm_svc_db_get_scan_image_list_from_db(GList **image_list, bool mmc_mounted) -{ - int ret = MS_MEDIA_ERR_NONE; - char * query_string = NULL; - sqlite3_stmt *sql_stmt = NULL; - - dcm_debug_fenter(); - - DCM_CHECK_VAL(db_handle, MS_MEDIA_ERR_INVALID_PARAMETER); - DCM_CHECK_VAL(image_list, MS_MEDIA_ERR_INVALID_PARAMETER); - - /* Make query */ - if (mmc_mounted == true) { - query_string = sqlite3_mprintf(SELECT_PATH_FROM_UNEXTRACTED_DCM_MEDIA); - } else { - query_string = sqlite3_mprintf(SELECT_PATH_FROM_UNEXTRACTED_DCM_INTERNAL_MEDIA); - } - - ret = DcmDbUtilsInternal::__dcm_svc_sql_prepare_to_step_simple((sqlite3 *)db_handle, query_string, &sql_stmt); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("error when __dcm_svc_sql_prepare_to_step_simple. ret = [%d]", ret); - return ret; - } - - while(sqlite3_step(sql_stmt) == SQLITE_ROW) { - DcmScanItem *scan_item = (DcmScanItem *) g_malloc0(sizeof(DcmScanItem)); - if (!scan_item) { - dcm_error("Failed to allocate memory for scan_item!"); - continue; - } - - if (DCM_STRING_VALID((const char *)sqlite3_column_text(sql_stmt, 0))) - scan_item->media_uuid = strdup((const char *)sqlite3_column_text(sql_stmt, 0)); - - if (DCM_STRING_VALID((const char *)sqlite3_column_text(sql_stmt, 1))) - scan_item->file_path = strdup((const char *)sqlite3_column_text(sql_stmt, 1)); - - if (DCM_STRING_VALID((const char *)sqlite3_column_text(sql_stmt, 2))) - scan_item->storage_uuid = strdup((const char *)sqlite3_column_text(sql_stmt, 2)); - - scan_item->image_width = sqlite3_column_int(sql_stmt, 3); - scan_item->image_height = sqlite3_column_int(sql_stmt, 4); - scan_item->image_orientation = sqlite3_column_int(sql_stmt, 5); - scan_item->mime_type = g_strdup((const char *)sqlite3_column_text(sql_stmt, 6)); - - /* scan item retrieved by this function will be marked as SCAN_ALL */ - scan_item->scan_item_type = DCM_SCAN_ITEM_TYPE_SCAN_ALL; - - *image_list = g_list_append(*image_list, scan_item); - - dcm_sec_debug("media uuid: [%s] file path: [%s]", scan_item->media_uuid, scan_item->file_path); - } - - DCM_SQLITE3_FINALIZE(sql_stmt); - - dcm_debug_fleave(); - - return MS_MEDIA_ERR_NONE; -} - -int DcmDbUtils::_dcm_svc_db_generate_uuid(DcmFaceItem **face) -{ - int ret = MS_MEDIA_ERR_NONE; - uuid_t uuid_value; - static char uuid_unparsed[50] = {0, }; - - dcm_debug_fenter(); - DCM_CHECK_VAL(face, MS_MEDIA_ERR_INVALID_PARAMETER); - - uuid_generate(uuid_value); - uuid_unparse(uuid_value, uuid_unparsed); - - (*face)->face_uuid = g_strdup(uuid_unparsed); - - if ((*face)->face_uuid == NULL) { - ret = MS_MEDIA_ERR_INTERNAL; - } else { - dcm_debug("set face_uuid :%s", (*face)->face_uuid); - } - - dcm_debug_fleave(); - - return ret; -} - -int DcmDbUtils::_dcm_svc_db_insert_face_to_db(DcmFaceItem *face) -{ - int ret = MS_MEDIA_ERR_NONE; - char* query_string = NULL; - - dcm_debug_fenter(); - - DCM_CHECK_VAL(db_handle, MS_MEDIA_ERR_INVALID_PARAMETER); - DCM_CHECK_VAL(face, MS_MEDIA_ERR_INVALID_PARAMETER); - DCM_CHECK_VAL(face->face_uuid, MS_MEDIA_ERR_INVALID_PARAMETER); - - if (DcmDbUtilsInternal::__dcm_svc_db_check_duplicated(db_handle, face) == TRUE) { - dcm_error("[__dcm_svc_db_check_duplicated] The data is duplicated!"); - return MS_MEDIA_ERR_INTERNAL; - } - - query_string = sqlite3_mprintf(INSERT_FACE_ITEM_TO_DB, face->face_uuid, face->media_uuid, face->face_rect_x, face->face_rect_y, face->face_rect_w, face->face_rect_h, face->orientation); - - dcm_debug("query is %s", query_string); - - g_mutex_trylock(&gMutexLock); - ret = media_db_request_update_db(query_string, dcm_uid); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("media_db_request_update_db fail = %d, %s", ret, sqlite3_errmsg((sqlite3 *)db_handle)); - } - g_mutex_unlock(&gMutexLock); - - DCM_SQLITE3_FREE(query_string); - - dcm_debug_fleave(); - - return ret; -} - -int DcmDbUtils::_dcm_svc_db_insert_face_to_face_scan_list(DcmScanItem *scan_item) -{ - int ret = MS_MEDIA_ERR_NONE; - char* query_string = NULL; - - dcm_debug_fenter(); - - DCM_CHECK_VAL(db_handle, MS_MEDIA_ERR_INVALID_PARAMETER); - DCM_CHECK_VAL(scan_item, MS_MEDIA_ERR_INVALID_PARAMETER); - DCM_CHECK_VAL(scan_item->media_uuid, MS_MEDIA_ERR_INVALID_PARAMETER); - - if (DcmDbUtilsInternal::__dcm_svc_db_check_duplicated_scan_list(db_handle, scan_item->media_uuid) == TRUE) { - dcm_error("[_dcm_svc_db_insert_face_to_face_scan_list] The data is duplicated!"); - return MS_MEDIA_ERR_INTERNAL; - } - - query_string = sqlite3_mprintf("INSERT INTO %s (media_uuid, storage_uuid) values('%q', '%q')", DB_TABLE_FACE_SCAN_LIST, scan_item->media_uuid, scan_item->storage_uuid); - - dcm_debug("query is %s", query_string); - - g_mutex_trylock(&gMutexLock); - ret = media_db_request_update_db(query_string, dcm_uid); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("media_db_request_update_db is failed: %d, %s", ret, sqlite3_errmsg((sqlite3 *)db_handle)); - } - g_mutex_unlock(&gMutexLock); - - DCM_SQLITE3_FREE(query_string); - - dcm_debug_fleave(); - - return ret; -} - -int DcmDbUtils::_dcm_svc_db_update_color_to_db(DcmColorItem color) -{ - int ret = MS_MEDIA_ERR_NONE; - - dcm_debug_fenter(); -#if 0 - char* query_string = NULL; - - DCM_CHECK_VAL(db_handle, MS_MEDIA_ERR_INVALID_PARAMETER); - DCM_CHECK_VAL(color.media_uuid, MS_MEDIA_ERR_INVALID_PARAMETER); - DCM_CHECK_VAL(color.storage_uuid, MS_MEDIA_ERR_INVALID_PARAMETER); - - query_string = sqlite3_mprintf(UPDATE_COLOR_ITEM_TO_DB, (int)(color.rgb_r), (int)(color.rgb_g), (int)(color.rgb_b), color.media_uuid, color.storage_uuid); - dcm_debug("query is %s", query_string); - - g_mutex_trylock(&gMutexLock); - ret = media_db_request_update_db(query_string, dcm_uid); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("media_db_request_update_db fail = %d, %s", ret, sqlite3_errmsg((sqlite3 *)db_handle)); - } - g_mutex_unlock(&gMutexLock); - - DCM_SQLITE3_FREE(query_string); -#endif - dcm_debug_fleave(); - - return ret; -} - -int DcmDbUtils::_dcm_svc_db_check_scanned_by_media_uuid(const char *media_uuid, bool *media_scanned) -{ - int ret = MS_MEDIA_ERR_NONE; - char *query_string = NULL; - sqlite3_stmt *sql_stmt = NULL; - int count = 0; - - dcm_debug_fenter(); - - DCM_CHECK_VAL(db_handle, MS_MEDIA_ERR_INVALID_PARAMETER); - DCM_CHECK_VAL(media_uuid, MS_MEDIA_ERR_INVALID_PARAMETER); - - query_string = sqlite3_mprintf("SELECT count(*) FROM %s WHERE (media_uuid='%q')", DB_TABLE_FACE_SCAN_LIST, media_uuid); - DCM_CHECK_VAL(query_string, MS_MEDIA_ERR_OUT_OF_MEMORY); - - ret = DcmDbUtilsInternal::__dcm_svc_sql_prepare_to_step((sqlite3 *)db_handle, query_string, &sql_stmt); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("error when __dcm_svc_sql_prepare_to_step. ret = [%d]", ret); - return ret; - } - - count = sqlite3_column_int(sql_stmt, 0); - - DCM_SQLITE3_FINALIZE(sql_stmt); - - if (count > 0) - *media_scanned = TRUE; - else - *media_scanned = FALSE; - - dcm_debug_fleave(); - - return ret; -} diff --git a/src/DcmFaceUtils.cpp b/src/DcmFaceUtils.cpp deleted file mode 100755 index 785bb07..0000000 --- a/src/DcmFaceUtils.cpp +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * 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. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -namespace DcmFaceApi { -int createFaceItem(DcmFaceItem **face); -double caculateScaleFactor(DcmImageInfo *image_info); -void freeDcmFaceItem(void *data); -} - -static dcm_face_h dcm_face_handle = NULL; - -int DcmFaceUtils::initialize() -{ - int ret = MS_MEDIA_ERR_NONE; - - dcm_debug_fenter(); - - ret = dcm_face_create(&dcm_face_handle); - - dcm_debug_fleave(); - - return ret; -} - -int DcmFaceUtils::finalize() -{ - int ret = MS_MEDIA_ERR_NONE; - - dcm_debug_fenter(); - - DCM_CHECK_VAL(dcm_face_handle, MS_MEDIA_ERR_INVALID_PARAMETER); - - ret = dcm_face_destroy(dcm_face_handle); - - dcm_face_handle = NULL; - - dcm_debug_fleave(); - - return ret; -} - -int DcmFaceUtils::runFaceRecognizeProcess(DcmScanItem *scan_item, DcmImageInfo *image_info) -{ - DcmDbUtils *dcmDbUtils = DcmDbUtils::getInstance(); - DcmFaceItem *face = NULL; - int face_area = 0; - int i = 0; - double scale_factor = 0.0; - int err = MS_MEDIA_ERR_NONE; - int ret = MS_MEDIA_ERR_NONE; - face_info_s *face_info = NULL; - - dcm_debug_fenter(); - - DCM_CHECK_VAL(dcm_face_handle, MS_MEDIA_ERR_INVALID_PARAMETER); - DCM_CHECK_VAL(scan_item, MS_MEDIA_ERR_INVALID_PARAMETER); - DCM_CHECK_VAL(scan_item->media_uuid, MS_MEDIA_ERR_INVALID_PARAMETER); - DCM_CHECK_VAL(image_info, MS_MEDIA_ERR_INVALID_PARAMETER); - DCM_CHECK_VAL(image_info->pixel, MS_MEDIA_ERR_INVALID_PARAMETER); - - dcm_debug("colorspce: [%d], w: [%d], h: [%d]", image_info->decode_type, image_info->buffer_width, image_info->buffer_height); - - ret = dcm_face_set_image_info(dcm_face_handle, (face_image_colorspace_e)image_info->decode_type, image_info->pixel, image_info->buffer_width, image_info->buffer_height, image_info->size); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to dcm_face_set_image_info! err: %d", err); - goto DCM_SVC_FACE_RECOGNIZE_BUFFER_FAILED; - } - - face_info = (face_info_s *)g_malloc0(sizeof(face_info_s)); - if (face_info == NULL) { - dcm_error("Failed to allocate face info"); - ret = MS_MEDIA_ERR_OUT_OF_MEMORY; - goto DCM_SVC_FACE_RECOGNIZE_BUFFER_FAILED; - } - - ret = dcm_face_get_face_info(dcm_face_handle, face_info); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to get face info! err: %d", err); - goto DCM_SVC_FACE_RECOGNIZE_BUFFER_FAILED; - } - - dcm_warn("detected face count: %d", face_info->count); - if (face_info->count <= 0) { - scan_item->face_count = 0; - goto DCM_SVC_FACE_RECOGNIZE_BUFFER_FAILED; - } - - scan_item->face_count = face_info->count; - - /* Compute scale factor between decode size and original size */ - scale_factor = DcmFaceApi::caculateScaleFactor(image_info); - - /* Insert every face rectangle into database */ - for (i = 0; i < face_info->count; i++) { - face = NULL; - - ret = DcmFaceApi::createFaceItem(&face); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to create face items! ret: %d", ret); - goto DCM_SVC_FACE_RECOGNIZE_BUFFER_FAILED; - } - - if (scale_factor > 1.0) { - face->face_rect_x = (int) (face_info->rects[i].x * scale_factor); - face->face_rect_y = (int) (face_info->rects[i].y * scale_factor); - face->face_rect_w = (int) (face_info->rects[i].w * scale_factor); - face->face_rect_h = (int) (face_info->rects[i].h * scale_factor); - } else { - face->face_rect_x = face_info->rects[i].x; - face->face_rect_y = face_info->rects[i].y; - face->face_rect_w = face_info->rects[i].w; - face->face_rect_h = face_info->rects[i].h; - } - face->orientation = face_info->rects[i].orientation; - - face_area += face->face_rect_w * face->face_rect_h; - dcm_debug("[#%d] face rect: XYWH (%d, %d, %d, %d)", i, face->face_rect_x, face->face_rect_y, face->face_rect_w, - face->face_rect_h); - - face->media_uuid = strdup(scan_item->media_uuid); - - /* Insert face rectangle into database */ - ret = dcmDbUtils->_dcm_svc_db_generate_uuid(&face); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to set uuid! ret: %d", ret); - goto DCM_SVC_FACE_RECOGNIZE_BUFFER_FAILED; - } - ret = dcmDbUtils->_dcm_svc_db_insert_face_to_db(face); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to insert face item into db! ret: %d", ret); - goto DCM_SVC_FACE_RECOGNIZE_BUFFER_FAILED; - } - - /* Send db updated notification */ - DcmFaceApi::freeDcmFaceItem(face); - face = NULL; - } - -DCM_SVC_FACE_RECOGNIZE_BUFFER_FAILED: - - err = dcmDbUtils->_dcm_svc_db_insert_face_to_face_scan_list(scan_item); - if (err != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to insert face item into face_scan_list! err: %d", err); - } - - dcm_face_destroy_face_info(face_info); - - if (face != NULL) { - DcmFaceApi::freeDcmFaceItem(face); - face = NULL; - } - - dcm_debug_fleave(); - - return ret; -} - -int DcmFaceApi::createFaceItem(DcmFaceItem **face) -{ - DCM_CHECK_VAL(face, MS_MEDIA_ERR_INVALID_PARAMETER); - - *face = NULL; - - DcmFaceItem *_face = (DcmFaceItem*)g_malloc0(sizeof(DcmFaceItem)); - if (_face == NULL) - return MS_MEDIA_ERR_OUT_OF_MEMORY; - - *face = _face; - - return MS_MEDIA_ERR_NONE; -} - -double DcmFaceApi::caculateScaleFactor(DcmImageInfo *image_info) -{ - double scale_factor = 0.0; - - DCM_CHECK_VAL(image_info, 0.0); - - if (image_info->original_width >= image_info->original_height) { - if (image_info->buffer_width >= image_info->buffer_height) { - scale_factor = ((double) (image_info->original_width)) / ((double) (image_info->buffer_width)); - } else { - scale_factor = ((double) (image_info->original_width)) / ((double) (image_info->buffer_height)); - } - } else { - if (image_info->buffer_height >= image_info->buffer_width) { - scale_factor = ((double) (image_info->original_height)) / ((double) (image_info->buffer_height)); - } else { - scale_factor = ((double) (image_info->original_height)) / ((double) (image_info->buffer_width)); - } - } - - dcm_debug("scale_factor: %lf", scale_factor); - - return scale_factor; -} - -void DcmFaceApi::freeDcmFaceItem(void *data) -{ - DcmFaceItem *_face = (DcmFaceItem *)data; - DCM_CHECK(_face); - - DCM_SAFE_FREE(_face->face_uuid); - DCM_SAFE_FREE(_face->media_uuid); - DCM_SAFE_FREE(_face); - - return; -} diff --git a/src/DcmIpcUtils.cpp b/src/DcmIpcUtils.cpp deleted file mode 100755 index a81e764..0000000 --- a/src/DcmIpcUtils.cpp +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * 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. - * - */ - - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -static char DCM_IPC_PATH[][100] = { - {"/var/run/media-server/dcm_ipc_scanthread.socket"}, - {"/var/run/media-server/media_ipc_dcmdaemon.socket"}, - {"/var/run/media-server/media_ipc_dcmcomm.socket"}, -}; - -int DcmIpcUtils::receiveSocketMsg(int client_sock, dcmMsg *recv_msg) -{ - int recv_msg_size = 0; - - if ((recv_msg_size = read(client_sock, recv_msg, sizeof(dcmMsg))) < 0) { - if (errno == EWOULDBLOCK) { - dcm_error("Timeout. Can't try any more"); - return MS_MEDIA_ERR_SOCKET_RECEIVE_TIMEOUT; - } else { - dcm_stderror("recv failed"); - return MS_MEDIA_ERR_SOCKET_RECEIVE; - } - } - dcm_sec_debug("[receive msg] type: %d, pid: %d, uid: %d, msg: %s, msg_size: %d", recv_msg->msg_type, recv_msg->pid, recv_msg->uid, (recv_msg->msg)?recv_msg->msg:"NULL", recv_msg->msg_size); - - if (!(recv_msg->msg_type >= 0 && recv_msg->msg_type < DCM_MSG_MAX)) { - dcm_error("IPC message is wrong!"); - return MS_MEDIA_ERR_INVALID_IPC_MESSAGE; - } - - return MS_MEDIA_ERR_NONE; -} - -int DcmIpcUtils::acceptSocket(int serv_sock, int* client_sock) -{ - DCM_CHECK_VAL(client_sock, MS_MEDIA_ERR_INVALID_PARAMETER); - int sockfd = -1; - struct sockaddr_un client_addr; - socklen_t client_addr_len = sizeof(client_addr); - - if ((sockfd = accept(serv_sock, (struct sockaddr*)&client_addr, &client_addr_len)) < 0) { - dcm_stderror("accept failed"); - *client_sock = -1; - return MS_MEDIA_ERR_SOCKET_ACCEPT; - } - - *client_sock = sockfd; - - return MS_MEDIA_ERR_NONE; -} - -int DcmIpcUtils::createSocket(int *socket_fd, DcmIpcPortType port) -{ - DCM_CHECK_VAL(socket_fd, MS_MEDIA_ERR_INVALID_PARAMETER); - int sock = -1; - struct sockaddr_un serv_addr; - bool bind_success = false; - int i = 0; - - /* Create a new TCP socket */ - if ((sock = socket(PF_FILE, SOCK_STREAM, 0)) < 0) { - dcm_stderror("socket failed"); - return MS_MEDIA_ERR_SOCKET_INTERNAL; - } - - /* Set socket address */ - memset(&serv_addr, 0, sizeof(serv_addr)); - serv_addr.sun_family = AF_UNIX; - unlink(DCM_IPC_PATH[port]); - strncpy(serv_addr.sun_path, DCM_IPC_PATH[port], sizeof(serv_addr.sun_path) - 1); - - /* Bind socket to local address */ - for (i = 0; i < 100; i++) { - if (bind(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == 0) { - bind_success = true; - break; - } - dcm_debug("#%d bind", i); - usleep(250000); - } - - if (bind_success == false) { - dcm_stderror("bind failed"); - close(sock); - return MS_MEDIA_ERR_SOCKET_BIND; - } - dcm_debug("bind success"); - - /* Listen */ - if (listen(sock, SOMAXCONN) < 0) { - dcm_stderror("listen failed"); - close(sock); - return MS_MEDIA_ERR_SOCKET_INTERNAL; - } - dcm_debug("Listening..."); - - /* change permission of local socket file */ - if (chmod(DCM_IPC_PATH[port], 0777) < 0) - dcm_stderror("chmod failed"); - - *socket_fd = sock; - - return MS_MEDIA_ERR_NONE; -} - -int DcmIpcUtils::sendClientSocketMsg(int socket_fd, ms_dcm_msg_type_e msg_type, unsigned int result, const char *msg, DcmIpcPortType port) -{ - if (port < 0 || port >= DCM_IPC_PORT_MAX) { - dcm_error("Invalid port! Stop sending message..."); - return MS_MEDIA_ERR_INVALID_PARAMETER; - } - dcm_debug("Send message type: [%d] msg : [%s] result : [%d]", msg_type, msg, result); - - dcmMsg send_msg; - int sock = -1; - - if (socket_fd < 0) { - struct sockaddr_un serv_addr; - struct timeval tv_timeout = { DCM_TIMEOUT_SEC_60, 0 }; /* timeout: 60 seconds */ - - if ((sock = socket(PF_FILE, SOCK_STREAM, 0)) < 0) { - dcm_stderror("socket failed"); - return MS_MEDIA_ERR_SOCKET_INTERNAL; - } - - if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv_timeout, sizeof(tv_timeout)) == -1) { - dcm_stderror("setsockopt failed"); - close(sock); - return MS_MEDIA_ERR_SOCKET_INTERNAL; - } - - memset(&serv_addr, 0, sizeof(serv_addr)); - serv_addr.sun_family = AF_UNIX; - strncpy(serv_addr.sun_path, DCM_IPC_PATH[port], sizeof(DCM_IPC_PATH[port])); - - /* Connecting to the thumbnail server */ - if (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) { - dcm_stderror("connect"); - close(sock); - return MS_MEDIA_ERR_SOCKET_CONN; - } - } else { - sock = socket_fd; - } - - /* Prepare send message */ - memset((void *)&send_msg, 0, sizeof(dcmMsg)); - send_msg.msg_type = msg_type; - send_msg.result = (int)result; - if (msg != NULL) { - send_msg.msg_size = strlen(msg); - g_strlcpy(send_msg.msg, msg, DCM_IPC_MSG_MAX_SIZE); - } - - /* If message size is larget than max_size, then message is invalid */ - if (send_msg.msg_size >= DCM_IPC_MSG_MAX_SIZE) { - dcm_error("Message size is invalid!"); - close(sock); - return MS_MEDIA_ERR_INVALID_IPC_MESSAGE; - } - - /* Send msg to the socket */ - if (send(sock, &send_msg, sizeof(send_msg), 0) != sizeof(send_msg)) { - dcm_stderror("send failed"); - close(sock); - return MS_MEDIA_ERR_SOCKET_SEND; - } - - dcm_debug("Sent message type: %d %d", send_msg.msg_type, send_msg.result); - - close(sock); - - return MS_MEDIA_ERR_NONE; -} - -int DcmIpcUtils::sendSocketMsg(ms_dcm_msg_type_e msg_type, uid_t uid, const char *msg, DcmIpcPortType port) -{ - if (port < 0 || port >= DCM_IPC_PORT_MAX) { - dcm_error("Invalid port! Stop sending message..."); - return MS_MEDIA_ERR_INVALID_PARAMETER; - } - - dcm_debug_fenter(); - - dcm_debug("Send message type: %d", msg_type); - - int socket_fd = -1; - struct sockaddr_un serv_addr; - dcmMsg send_msg; - - /* Prepare send message */ - memset((void *)&send_msg, 0, sizeof(dcmMsg)); - send_msg.msg_type = msg_type; - send_msg.uid = uid; - if (msg != NULL) { - send_msg.msg_size = strlen(msg); - g_strlcpy(send_msg.msg, msg, DCM_IPC_MSG_MAX_SIZE); - } - - /* If message size is larget than max_size, then message is invalid */ - if (send_msg.msg_size >= DCM_IPC_MSG_MAX_SIZE) { - dcm_error("Message size is invalid!"); - return MS_MEDIA_ERR_SOCKET_SEND; - } - - /* Create a new TCP socket */ - if ((socket_fd = socket(PF_FILE, SOCK_STREAM, 0)) < 0) { - dcm_stderror("socket failed"); - return MS_MEDIA_ERR_SOCKET_SEND; - } - - /* Set dcm thread socket address */ - memset(&serv_addr, 0, sizeof(serv_addr)); - serv_addr.sun_family = AF_UNIX; - strncpy(serv_addr.sun_path, DCM_IPC_PATH[port], sizeof(serv_addr.sun_path) - 1); - - /* Connect to the socket */ - if (connect(socket_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) { - dcm_stderror("connect error"); - close(socket_fd); - return MS_MEDIA_ERR_SOCKET_CONN; - } - - /* Send msg to the socket */ - if (send(socket_fd, &send_msg, sizeof(send_msg), 0) != sizeof(send_msg)) { - dcm_stderror("send failed"); - close(socket_fd); - return MS_MEDIA_ERR_SOCKET_SEND; - } - - close(socket_fd); - - dcm_debug_fleave(); - - return MS_MEDIA_ERR_NONE; -} - -int DcmIpcUtils::sendCompleteMsg(ms_dcm_msg_type_e msg_type, const unsigned int count, const char *msg, DcmIpcPortType port) -{ - if (port < 0 || port >= DCM_IPC_PORT_MAX) { - dcm_error("Invalid port! Stop sending message..."); - return MS_MEDIA_ERR_INVALID_PARAMETER; - } - - dcm_debug_fenter(); - - dcm_debug("Send message type: %d", msg_type); - - int socket_fd = -1; - struct sockaddr_un serv_addr; - dcmMsg send_msg; - - /* Prepare send message */ - memset((void *)&send_msg, 0, sizeof(dcmMsg)); - send_msg.msg_type = msg_type; - send_msg.result = count; - if (msg != NULL) { - send_msg.msg_size = strlen(msg); - g_strlcpy(send_msg.msg, msg, DCM_IPC_MSG_MAX_SIZE); - } - - /* If message size is larget than max_size, then message is invalid */ - if (send_msg.msg_size >= DCM_IPC_MSG_MAX_SIZE) { - dcm_error("Message size is invalid!"); - return MS_MEDIA_ERR_INVALID_IPC_MESSAGE; - } - - /* Create a new TCP socket */ - if ((socket_fd = socket(PF_FILE, SOCK_STREAM, 0)) < 0) { - dcm_stderror("socket failed"); - return MS_MEDIA_ERR_SOCKET_INTERNAL; - } - - /* Set dcm thread socket address */ - memset(&serv_addr, 0, sizeof(serv_addr)); - serv_addr.sun_family = AF_UNIX; - strncpy(serv_addr.sun_path, DCM_IPC_PATH[port], sizeof(serv_addr.sun_path) - 1); - - /* Connect to the socket */ - if (connect(socket_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) { - dcm_stderror("connect error"); - close(socket_fd); - return MS_MEDIA_ERR_SOCKET_CONN; - } - - /* Send msg to the socket */ - if (send(socket_fd, &send_msg, sizeof(send_msg), 0) != sizeof(send_msg)) { - dcm_stderror("send failed"); - close(socket_fd); - return MS_MEDIA_ERR_SOCKET_SEND; - } - - close(socket_fd); - - dcm_debug_fleave(); - - return MS_MEDIA_ERR_NONE; -} - - -int DcmIpcUtils::closeSocket(int socket_fd) -{ - close(socket_fd); - - return MS_MEDIA_ERR_NONE; -} diff --git a/src/DcmScanSvc.cpp b/src/DcmScanSvc.cpp deleted file mode 100755 index 3159142..0000000 --- a/src/DcmScanSvc.cpp +++ /dev/null @@ -1,865 +0,0 @@ -/* - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * 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. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../libdcm-util/include/dcm_image_codec.h" -#include -#include -#include -#include -#include -#include -#include -#include - -#define MIME_TYPE_JPEG "image/jpeg" -#define MIME_TYPE_PNG "image/png" -#define MIME_TYPE_BMP "image/bmp" - -#define DCM_SVC_SCAN_THREAD_TIMEOUT_SEC 1 - -class DcmScanSvc { -public: - GMainLoop *g_scan_thread_mainloop; - GMainContext *scan_thread_main_context; - gboolean g_scan_cancel; - GSource *scan_thread_quit_timer; - DcmDbUtils *dcmDBUtils; - uid_t g_uid; - - /* scan all images */ - GList *scan_all_item_list; - unsigned int scan_all_curr_index; - - /* scan single images */ - GList *scan_single_item_list; - unsigned int scan_single_curr_index; - - void quitScanThread(); - int createQuitTimerScanThread(); - int getMmcState(void); - int prepareImageList(); - int prepareImageListByPath(const char *file_path); - int clearAllItemList(); - int clearSingleItemList(); - int initialize(); - int finalize(); - int sendCompletedMsg(const char *msg, const unsigned int count, DcmIpcPortType port); - int sendTerminatedMsg(); - int getScanStatus(DcmScanItem *scan_item, bool *media_scanned); - int runScanProcess(DcmScanItem *scan_item); - int ScanAllItems(); - int ScanSingleItem(const char *file_path); - int terminateScanOperations(); - int receiveMsg(dcmMsg *recv_msg); - -}; - -namespace DcmScanCallback { - gboolean quitTimerAtScanThread(gpointer data); - void freeScanItem(void *data); - gboolean readyScanThreadIdle(gpointer data); - gboolean runScanThreadIdle(gpointer data); - gboolean readMsg(GIOChannel *src, GIOCondition condition, gpointer data); -} - -void DcmScanSvc::quitScanThread() -{ - if (g_scan_thread_mainloop != NULL) { - dcm_warn("Quit scan thread mainloop!"); - g_main_loop_quit(g_scan_thread_mainloop); - } else { - dcm_warn("Scan thread mainloop is invalid!"); - } - - return; -} - -gboolean DcmScanCallback::quitTimerAtScanThread(gpointer data) -{ - DcmScanSvc *dcmScanSvc = (DcmScanSvc *) data; - int ret; - - dcm_debug_fenter(); - - DCM_CHECK_FALSE(data); - - ret = DcmIpcUtils::sendSocketMsg(DCM_MSG_SCAN_TERMINATED, 0, NULL, DCM_IPC_PORT_DCM_RECV); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("send to terminated messge to DCM Main"); - } - - if (dcmScanSvc->scan_all_curr_index != 0 || dcmScanSvc->scan_single_curr_index != 0) { - dcm_warn("Scan thread is working! DO NOT quit main thread!"); - dcmScanSvc->createQuitTimerScanThread(); - } else { - dcm_warn("Quit dcm-svc main loop!"); - dcmScanSvc->quitScanThread(); - } - - dcm_debug_fleave(); - - return FALSE; -} - -int DcmScanSvc::createQuitTimerScanThread() -{ - dcm_debug_fenter(); - - if (scan_thread_quit_timer != NULL) { - dcm_debug("Delete old quit timer!"); - g_source_destroy(scan_thread_quit_timer); - scan_thread_quit_timer = NULL; - } - - scan_thread_quit_timer = g_timeout_source_new_seconds(DCM_SVC_SCAN_THREAD_TIMEOUT_SEC); - DCM_CHECK_VAL(scan_thread_quit_timer, MS_MEDIA_ERR_OUT_OF_MEMORY); - - g_source_set_callback(scan_thread_quit_timer, DcmScanCallback::quitTimerAtScanThread, (gpointer)this, NULL); - g_source_attach(scan_thread_quit_timer, scan_thread_main_context); - - dcm_debug_fleave(); - - return MS_MEDIA_ERR_NONE; -} - -int DcmScanSvc::getMmcState(void) -{ - int err = -1; - int status = -1; - - err = vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &status); - if (err != 0) { - dcm_error("vconf_get_int Unexpected error code: %d", err); - } - - return status; -} - -int DcmScanSvc::prepareImageList() -{ - int ret = MS_MEDIA_ERR_NONE; - DcmDbUtils *dcmDbUtils = DcmDbUtils::getInstance(); - bool mmc_mounted = false; - - if (getMmcState() == VCONFKEY_SYSMAN_MMC_MOUNTED) { - mmc_mounted = true; - } else { - mmc_mounted = false; - } - - /* Get scan image list from db */ - ret = dcmDbUtils->_dcm_svc_db_get_scan_image_list_from_db(&(scan_all_item_list), mmc_mounted); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to get image list from db! ret: %d", ret); - return ret; - } - - if (scan_all_item_list == NULL) { - dcm_debug("No image list for scanning"); - return MS_MEDIA_ERR_DB_NO_RECORD; - } - - if ((scan_all_item_list != NULL) && (g_list_length(scan_all_item_list) == 0)) { - dcm_debug("No image list from db!"); - return MS_MEDIA_ERR_DB_NO_RECORD; - } - - return MS_MEDIA_ERR_NONE; -} - -int DcmScanSvc::prepareImageListByPath(const char *file_path) -{ - int ret = MS_MEDIA_ERR_NONE; - DcmDbUtils *dcmDbUtils = DcmDbUtils::getInstance(); - bool mmc_mounted = false; - - if (getMmcState() == VCONFKEY_SYSMAN_MMC_MOUNTED) { - mmc_mounted = true; - } else { - mmc_mounted = false; - } - - /* Get scan image list from db */ - ret = dcmDbUtils->_dcm_svc_db_get_scan_image_list_by_path(&(scan_single_item_list), mmc_mounted, file_path); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to get image list from db! ret: %d", ret); - return ret; - } - - if (scan_single_item_list == NULL) { - dcm_debug("No image list for scanning"); - return MS_MEDIA_ERR_DB_NO_RECORD; - } - - if ((scan_single_item_list != NULL) && (g_list_length(scan_single_item_list) == 0)) { - dcm_debug("No image list from db!"); - return MS_MEDIA_ERR_DB_NO_RECORD; - } - - return MS_MEDIA_ERR_NONE; -} - -int DcmScanSvc::clearAllItemList() -{ - dcm_debug_fenter(); - - if (scan_all_item_list != NULL) { - g_list_free_full(scan_all_item_list, DcmScanCallback::freeScanItem); - scan_all_item_list = NULL; - } - - scan_all_curr_index = 0; - - return MS_MEDIA_ERR_NONE; -} - -int DcmScanSvc::clearSingleItemList() -{ - dcm_debug_fenter(); - - if (scan_single_item_list) { - g_list_free_full(scan_single_item_list, DcmScanCallback::freeScanItem); - scan_single_item_list = NULL; - } - - scan_single_curr_index = 0; - - return MS_MEDIA_ERR_NONE; -} - -int DcmScanSvc::initialize() -{ - scan_all_item_list = NULL; - scan_all_curr_index = 0; - scan_single_item_list = NULL; - scan_single_curr_index = 0; - g_scan_cancel = FALSE; - scan_thread_quit_timer = NULL; - - DcmFaceUtils::initialize(); - dcmDBUtils = DcmDbUtils::getInstance(); - - return MS_MEDIA_ERR_NONE; -} - -int DcmScanSvc::finalize() -{ - /* Only scan item lists are freed here, scan idles should be freed before this function */ - clearAllItemList(); - clearSingleItemList(); - DcmFaceUtils::finalize(); - - return MS_MEDIA_ERR_NONE; -} - -int DcmScanSvc::sendCompletedMsg(const char *msg, const unsigned int count, DcmIpcPortType port) -{ - if ((scan_all_item_list == NULL) && (scan_single_item_list == NULL)) { - dcm_debug("Send completed message"); - DcmIpcUtils::sendCompleteMsg(DCM_MSG_SCAN_COMPLETED, count, msg, port); - } else { - if (scan_all_item_list) - dcm_warn("scan_all_item_list"); - - if (scan_single_item_list) - dcm_warn("scan_single_item_list"); - - dcm_warn("Scan operation is not finished yet. Keep scanning..."); - } - - return MS_MEDIA_ERR_NONE; -} - -int DcmScanSvc::sendTerminatedMsg() -{ - dcm_debug("Terminated message is sent to DCM main..."); - - return MS_MEDIA_ERR_NONE; -} - -int DcmScanSvc::getScanStatus(DcmScanItem *scan_item, bool *media_scanned) -{ - int ret = MS_MEDIA_ERR_NONE; - DcmDbUtils *dcmDbUtils = DcmDbUtils::getInstance(); - - DCM_CHECK_VAL(scan_item, MS_MEDIA_ERR_INVALID_PARAMETER); - DCM_CHECK_VAL(scan_item->media_uuid, MS_MEDIA_ERR_INVALID_PARAMETER); - - /* Check if this media is scanned or not */ - ret = dcmDbUtils->_dcm_svc_db_check_scanned_by_media_uuid(scan_item->media_uuid, media_scanned); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to check if this media item is scanned or not!"); - } - - return ret; -} - -int DcmScanSvc::runScanProcess(DcmScanItem *scan_item) -{ - bool media_scanned = false; - int ret = MS_MEDIA_ERR_NONE; - - dcm_debug_fenter(); - DCM_CHECK_VAL(scan_item, MS_MEDIA_ERR_INVALID_PARAMETER); - DCM_CHECK_VAL(scan_item->file_path, MS_MEDIA_ERR_INVALID_PARAMETER); - - DcmImageInfo image_info = {0, }; - memset(&image_info, 0, sizeof(DcmImageInfo)); - dcm_image_format_e image_format = DCM_IMAGE_FORMAT_I420; - - /* Process scan operation if the file exists */ - if (g_file_test(scan_item->file_path, (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) == TRUE) { - /* Get necessary information from db again. - * Media information will be inserted after face is detected. - * If media uuid does not exist, retry is needed */ - ret = getScanStatus(scan_item, &media_scanned); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to get scan item info from db! err: %d", ret); - return ret; - } - - /* It is possible that when single and async scan for the same image is in the list. - * If the media uuid is already scanned, skip this scan. */ - if (media_scanned == true) { - dcm_warn("This media is scanned already! Skip..."); - DCM_SAFE_FREE(image_info.pixel); - return MS_MEDIA_ERROR_ALREADY_SCANNED; - } else { - dcm_debug("This media is NOT scanned yet."); - } - - dcm_sec_debug("scan file path : [%s]", scan_item->file_path); - dcm_sec_debug("scan media uuid : [%s]", scan_item->media_uuid); - - ImgCodecType type = IMG_CODEC_NONE; - - image_info.original_width = scan_item->image_width; - image_info.original_height = scan_item->image_height; - image_info.orientation = scan_item->image_orientation; - - dcm_debug("scan media w : [%d], h : [%d], orientation : [%d]", image_info.original_width, image_info.original_height, scan_item->image_orientation); - - if (image_info.original_width <= 0 && image_info.original_height <= 0) { - ret = ImgGetImageInfo((const char *)(scan_item->file_path), &type, &(image_info.original_width), &(image_info.original_height)); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("Failed ImgGetImageInfo! err: %d", ret); - return ret; - } - - dcm_debug("ImgGetImageInfo type: %d, width: %d, height: %d", type, image_info.original_width, image_info.original_height); - } - - if (strcmp(scan_item->mime_type, MIME_TYPE_JPEG) == 0) { - image_format = DCM_IMAGE_FORMAT_RGB; - } else if ((strcmp(scan_item->mime_type, MIME_TYPE_PNG) == 0) || - (strcmp(scan_item->mime_type, MIME_TYPE_BMP) == 0)) { - image_format = DCM_IMAGE_FORMAT_RGBA; - } else { - dcm_error("Failed not supported type! (%s)", scan_item->mime_type); - return MS_MEDIA_ERR_INVALID_PARAMETER; - } - - ret = dcm_decode_image((const char *) (scan_item->file_path), image_format, scan_item->mime_type, - image_info.orientation, FALSE, &(image_info.pixel), &(image_info.size), - &(image_info.buffer_width), &(image_info.buffer_height)); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("Failed dcm_decode_image! err: %d", ret); - return ret; - } - - image_info.decode_type = (DcmImageDecodeType)image_format; - - dcm_debug("Image info width: %d, height: %d, buf_width: %d, buf_height: %d", - image_info.original_width, image_info.original_height, image_info.buffer_width, image_info.buffer_height); - - /* Process face scan */ - ret = DcmFaceUtils::runFaceRecognizeProcess(scan_item, &image_info); - if (ret != MS_MEDIA_ERR_NONE) - dcm_error("Failed to process face detection! err: %d", ret); - -#if 0 - /* Process color extract */ - ret = DcmColorUtils::runColorExtractProcess(scan_item, &image_info); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to process color extraction! err: %d", ret); - } -#endif - - /* Free image buffer */ - DCM_SAFE_FREE(image_info.pixel); - } else { - dcm_warn("The file does not exist! Skip dcm scan for this file ..."); - } - - dcm_debug_fleave(); - - return ret; -} - -int DcmScanSvc::ScanAllItems() -{ - int ret = MS_MEDIA_ERR_NONE; - - dcm_debug_fenter(); - - clearAllItemList(); - - ret = prepareImageList(); - if (ret == MS_MEDIA_ERR_DB_NO_RECORD) { - dcm_debug("No items to Scan. Scan operation completed!!!"); - clearAllItemList(); - /* Send scan complete message to main thread (if all scan operations are finished) */ - sendCompletedMsg( NULL, 0, DCM_IPC_PORT_DCM_RECV); - ret = dcmDBUtils->_dcm_svc_db_disconnect(); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to disconnect db! err: %d", ret); - } - return MS_MEDIA_ERR_NONE; - } - - /* DCM scan started */ - g_idle_add(DcmScanCallback::runScanThreadIdle, (gpointer)this); - - dcm_debug_fleave(); - - return MS_MEDIA_ERR_NONE; -} - -int DcmScanSvc::ScanSingleItem(const char *file_path) -{ - int ret = MS_MEDIA_ERR_NONE; - DcmScanItem *scan_item = NULL; - DcmDbUtils *dcmDbUtils = DcmDbUtils::getInstance(); - int face_count = 0; - - DCM_CHECK_VAL(file_path, MS_MEDIA_ERR_INVALID_PARAMETER); - - dcm_debug_fenter(); - - clearSingleItemList(); - - ret = prepareImageListByPath(file_path); - if (ret == MS_MEDIA_ERR_DB_NO_RECORD) { - dcm_debug("No items to Scan. Scan operation completed!!!"); - clearSingleItemList(); - /* Send scan complete message to main thread (if all scan operations are finished) */ - sendCompletedMsg( file_path/*ret*/, 0, DCM_IPC_PORT_DCM_RECV); - return MS_MEDIA_ERR_NONE; - } - - dcm_debug("append scan item to scan item list"); - - /* DCM scan started */ - unsigned int list_len = g_list_length(scan_single_item_list); - if (scan_single_curr_index < list_len) { - scan_item = (DcmScanItem *)g_list_nth_data(scan_single_item_list, scan_single_curr_index); - dcm_sec_debug("current index: %d, path: %s, scan type: %d", scan_single_curr_index, scan_item->file_path, scan_item->scan_item_type); - - ret = runScanProcess(scan_item); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to process scan job! err: %d", ret); - - /* If the scan item is not scanned, insert media uuid into face_scan_list */ - if (ret != MS_MEDIA_ERROR_ALREADY_SCANNED) { - dcmDbUtils->_dcm_svc_db_insert_face_to_face_scan_list(scan_item); - } - } - - (scan_single_curr_index)++; - } - - if (scan_item != NULL) - face_count = scan_item->face_count; - else - face_count = 0; - - sendCompletedMsg( file_path/*ret*/, face_count, DCM_IPC_PORT_DCM_RECV); - - clearSingleItemList(); - - dcm_debug_fleave(); - - return MS_MEDIA_ERR_NONE; -} - -int DcmScanMain::ScanSingle(const char *file_path, uid_t uid, int *face_count) -{ - int ret = MS_MEDIA_ERR_NONE; - DcmScanSvc dcmScanSvc; - DcmScanItem *scan_item = NULL; - unsigned int list_len = 0; - - DCM_CHECK_VAL(file_path, MS_MEDIA_ERR_INVALID_PARAMETER); - DCM_CHECK_VAL(face_count, MS_MEDIA_ERR_INVALID_PARAMETER); - - dcm_debug_fenter(); - - /* Init global variables */ - ret = dcmScanSvc.initialize(); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to initialize scan thread global variable! err: %d", ret); - goto DCM_SVC_SCAN_SINGLE_FAILED; - } - dcmScanSvc.clearSingleItemList(); - - ret = dcmScanSvc.dcmDBUtils->_dcm_svc_db_connect(uid); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to connect db! err: %d", ret); - } - - ret = dcmScanSvc.prepareImageListByPath(file_path); - if (ret == MS_MEDIA_ERR_DB_NO_RECORD) { - dcm_debug("No items to Scan. Scan operation completed!!!"); - dcmScanSvc.clearSingleItemList(); - goto DCM_SVC_SCAN_SINGLE_FAILED; - } - - dcm_debug("append scan item to scan item list"); - - /* DCM scan started */ - list_len = (unsigned int)g_list_length(dcmScanSvc.scan_single_item_list); - if (dcmScanSvc.scan_single_curr_index < list_len) { - scan_item = (DcmScanItem *)g_list_nth_data(dcmScanSvc.scan_single_item_list, dcmScanSvc.scan_single_curr_index); - dcm_sec_debug("current index: %d, path: %s, scan type: %d", dcmScanSvc.scan_single_curr_index, scan_item->file_path, scan_item->scan_item_type); - - ret = dcmScanSvc.runScanProcess(scan_item); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to process scan job! err: %d", ret); - - /* If the scan item is not scanned, insert media uuid into face_scan_list */ - if (ret != MS_MEDIA_ERROR_ALREADY_SCANNED) { - dcmScanSvc.dcmDBUtils->_dcm_svc_db_insert_face_to_face_scan_list(scan_item); - } - } - - (dcmScanSvc.scan_single_curr_index)++; - } - -DCM_SVC_SCAN_SINGLE_FAILED: - ret = dcmScanSvc.dcmDBUtils->_dcm_svc_db_disconnect(); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to disconnect db! err: %d", ret); - } - - if (scan_item != NULL) - *face_count = scan_item->face_count; - else - *face_count = 0; - - dcm_debug("*face_count is %d", *face_count); - dcmScanSvc.clearSingleItemList(); - - ret = dcmScanSvc.finalize(); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to de-initialize scan thread global variable! err: %d", ret); - } - dcm_debug_fleave(); - - return MS_MEDIA_ERR_NONE; -} - -int DcmScanSvc::terminateScanOperations() -{ - dcm_debug("Terminate scanning operations, and quit scan thread main loop"); - - g_scan_cancel = TRUE; - - return createQuitTimerScanThread(); -} - -int DcmScanSvc::receiveMsg(dcmMsg *recv_msg) -{ - int ret = MS_MEDIA_ERR_NONE; - - dcmDBUtils = DcmDbUtils::getInstance(); - g_uid = recv_msg->uid; - DCM_CHECK_VAL(recv_msg, MS_MEDIA_ERR_INVALID_PARAMETER); - - dcm_debug("msg_type: %d", recv_msg->msg_type); - - if (recv_msg->msg_type == DCM_MSG_REQUEST_KILL_SERVER) - { - /* Destroy scan idles, and quit scan thread main loop */ - ret = terminateScanOperations(); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to terminate DCM scan service! err: %d", ret); - } - - return ret; - } - else if (recv_msg->msg_type == DCM_MSG_REQUEST_ALL_MEDIA) - { - /* Use timer to scan all unscanned images */ - ret = dcmDBUtils->_dcm_svc_db_connect(recv_msg->uid); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to disconnect db! err: %d", ret); - } - ScanAllItems(); - ret = dcmDBUtils->_dcm_svc_db_disconnect(); - } - else { - dcm_error("Invalid message type(%d)!", recv_msg->msg_type); - ret = MS_MEDIA_ERR_INVALID_IPC_MESSAGE; - } - - return ret; -} - -gboolean DcmScanCallback::readMsg(GIOChannel *src, GIOCondition condition, gpointer data) -{ - DcmScanSvc *dcmScanSvc = (DcmScanSvc *) data; - int sock = -1; - int client_sock = -1; - dcmMsg recv_msg; - int err = 0; - - DCM_CHECK_FALSE(data); - - /* Get socket fd from IO channel */ - sock = g_io_channel_unix_get_fd(src); - if (sock < 0) { - dcm_error("Invalid socket fd!"); - return TRUE; - } - - /* Accept tcp client socket */ - err = DcmIpcUtils::acceptSocket(sock, &client_sock); - if (err != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to accept tcp socket! err: %d", err); - return TRUE; - } - - /* Receive message from tcp socket */ - err = DcmIpcUtils::receiveSocketMsg(client_sock, &recv_msg); - if (err != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to receive tcp msg! err: %d", err); - goto DCM_SVC_SCAN_READ_THREAD_RECV_SOCKET_FAILED; - } - - /* Process received message */ - err = dcmScanSvc->receiveMsg(&recv_msg); - if (err != MS_MEDIA_ERR_NONE) { - dcm_error("Error ocurred when process received message: %d", err); - goto DCM_SVC_SCAN_READ_THREAD_RECV_SOCKET_FAILED; - } - -DCM_SVC_SCAN_READ_THREAD_RECV_SOCKET_FAILED: - - if (close(client_sock) < 0) { - dcm_stderror("close failed"); - } - - return TRUE; -} - -gboolean DcmScanCallback::readyScanThreadIdle(gpointer data) -{ - DcmMainSvc *ad = (DcmMainSvc *) data; - dcmMsg *async_queue_msg = NULL; - - dcm_debug_fenter(); - - DCM_CHECK_FALSE(data); - DCM_CHECK_FALSE(ad->scan_thread_ready); - - async_queue_msg = (dcmMsg*) g_malloc0(sizeof(dcmMsg)); - if (async_queue_msg == NULL) { - dcm_error("memory allocation failed"); - return FALSE; - } - - async_queue_msg->msg_type = DCM_MSG_SCAN_READY; - - dcm_debug("scan thread ready : %p", ad->scan_thread_ready); - dcm_debug("async_queue_msg : %d", async_queue_msg->msg_type); - - g_async_queue_push(ad->scan_thread_ready, (gpointer) async_queue_msg); - - dcm_debug_fleave(); - - return FALSE; -} - -gboolean DcmScanCallback::runScanThreadIdle(gpointer data) -{ - int ret = MS_MEDIA_ERR_NONE; - DcmScanSvc *scanSvc = (DcmScanSvc *)data; - DcmScanItem *scan_item = NULL; - DcmDbUtils *dcmDbUtils = DcmDbUtils::getInstance(); - - dcm_debug_fenter(); - - DCM_CHECK_FALSE(scanSvc); - DCM_CHECK_FALSE(dcmDbUtils); - - ret = scanSvc->dcmDBUtils->_dcm_svc_db_connect(scanSvc->g_uid); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to disconnect db! err: %d", ret); - } - /* DCM scan started */ - unsigned int list_len = g_list_length(scanSvc->scan_all_item_list); - if ((scanSvc->scan_all_curr_index < list_len) && !scanSvc->g_scan_cancel) { - scan_item = (DcmScanItem *)g_list_nth_data(scanSvc->scan_all_item_list, scanSvc->scan_all_curr_index); - dcm_sec_debug("current index: %d, path: %s state: %s", scanSvc->scan_all_curr_index, scan_item->file_path, (scanSvc->g_scan_cancel)?"cancel":"go"); - - ret = scanSvc->runScanProcess(scan_item); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to process scan job! err: %d", ret); - - /* If the scan item is not scanned, insert media uuid into face_scan_list */ - if (ret != MS_MEDIA_ERROR_ALREADY_SCANNED) { - dcmDbUtils->_dcm_svc_db_insert_face_to_face_scan_list(scan_item); - } - } - - (scanSvc->scan_all_curr_index)++; - } else { - dcm_warn("All images are scanned. Scan operation completed"); - scanSvc->clearAllItemList(); - ret = scanSvc->dcmDBUtils->_dcm_svc_db_disconnect(); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to disconnect db! err: %d", ret); - } - scanSvc->clearAllItemList(); - /* Send scan complete message to main thread (if all scan operations are finished) */ - scanSvc->sendCompletedMsg( NULL, 0, DCM_IPC_PORT_DCM_RECV); - dcm_debug_fleave(); - return FALSE; - } - ret = scanSvc->dcmDBUtils->_dcm_svc_db_disconnect(); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to disconnect db! err: %d", ret); - } - - dcm_debug_fleave(); - - return TRUE; -} - -void DcmScanCallback::freeScanItem(void *data) -{ - DcmScanItem *scan_item = (DcmScanItem *) data; - - dcm_debug_fenter(); - - DCM_CHECK(scan_item); - DCM_CHECK(scan_item->file_path); - DCM_CHECK(scan_item->media_uuid); - DCM_CHECK(scan_item->storage_uuid); - - dcm_sec_debug("Free scan item. path: [%s]", scan_item->file_path); - - DCM_SAFE_FREE(scan_item->file_path); - DCM_SAFE_FREE(scan_item->media_uuid); - DCM_SAFE_FREE(scan_item->storage_uuid); - DCM_SAFE_FREE(scan_item); - - dcm_debug_fleave(); - - return; -} - -gboolean DcmScanMain::runScanThread(void *data) -{ - DcmMainSvc *dcmManSvc = (DcmMainSvc*) data; - DcmScanSvc dcmScanSvc; - int socket_fd = -1; - GSource *source = NULL; - GIOChannel *channel = NULL; - GMainContext *context = NULL; - GSource *scan_thread_ready_idle = NULL; - int err = 0; - - DCM_CHECK_VAL(data, MS_MEDIA_ERR_INVALID_PARAMETER); - - /* Create TCP Socket to receive message from main thread */ - err = DcmIpcUtils::createSocket(&socket_fd, DCM_IPC_PORT_SCAN_RECV); - if (err != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to create socket! err: %d", err); - goto DCM_SVC_SCAN_CREATE_SCAN_THREAD_FAILED; - } - dcm_sec_warn("scan thread recv socket: %d", socket_fd); - - /* Init global variables */ - err = dcmScanSvc.initialize(); - if (err != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to initialize scan thread global variable! err: %d", err); - goto DCM_SVC_SCAN_CREATE_SCAN_THREAD_FAILED; - } - - /* Create a new main context for scan thread */ - context = g_main_context_new(); - dcmScanSvc.scan_thread_main_context = context; - - /* Create a new main event loop */ - dcmScanSvc.g_scan_thread_mainloop = g_main_loop_new(context, FALSE); - - /* Create a new channel to watch TCP socket */ - channel = g_io_channel_unix_new(socket_fd); - source = g_io_create_watch(channel, G_IO_IN); - - /* Attach channel to main context in scan thread */ - g_source_set_callback(source, (GSourceFunc) DcmScanCallback::readMsg, (gpointer) &dcmScanSvc, NULL); - g_source_attach(source, context); - - /* Create a idle after scan thread is ready */ - scan_thread_ready_idle = g_idle_source_new(); - g_source_set_callback(scan_thread_ready_idle, DcmScanCallback::readyScanThreadIdle, (gpointer) dcmManSvc, NULL); - g_source_attach(scan_thread_ready_idle, context); - - /* Push main context to scan thread */ - g_main_context_push_thread_default(context); - - dcm_debug("********************************************"); - dcm_debug("*** DCM Service scan thread is running ***"); - dcm_debug("********************************************"); - - /* Start to run main event loop for scan thread */ - g_main_loop_run(dcmScanSvc.g_scan_thread_mainloop); - - dcm_debug("*** DCM Service scan thread will be closed ***"); - - /* Destroy IO channel */ - g_io_channel_shutdown(channel, FALSE, NULL); - g_io_channel_unref(channel); - - /* Close the TCP socket */ - close(socket_fd); - - /* Descrease the reference count of main loop of scan thread */ - g_main_loop_unref(dcmScanSvc.g_scan_thread_mainloop); - dcmScanSvc.g_scan_thread_mainloop = NULL; - -DCM_SVC_SCAN_CREATE_SCAN_THREAD_FAILED: - - err = dcmScanSvc.finalize(); - if (err != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to de-initialize scan thread global variable! err: %d", err); - } - - return FALSE; -} - diff --git a/src/dcm_svc_db.c b/src/dcm_svc_db.c new file mode 100755 index 0000000..5fcc4c3 --- /dev/null +++ b/src/dcm_svc_db.c @@ -0,0 +1,486 @@ +/* + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dcm_svc_debug.h" + +static GMutex gMutexLock; +static MediaDBHandle *db_handle; +static uid_t dcm_uid; + +gboolean _dcm_svc_db_check_duplicated(MediaDBHandle *db_handle, dcm_face_item_s *data); +gboolean _dcm_svc_db_check_duplicated_scan_list(MediaDBHandle *db_handle, const char *data); +static int _dcm_svc_sql_prepare_to_step(sqlite3 *handle, const char *sql_str, sqlite3_stmt** stmt); +static int _dcm_svc_sql_prepare_to_step_simple(sqlite3 *handle, const char *sql_str, sqlite3_stmt** stmt); + +gboolean _dcm_svc_db_check_duplicated(MediaDBHandle *db_handle, dcm_face_item_s *data) +{ + int ret = MS_MEDIA_ERR_NONE; + sqlite3 * handle = (sqlite3 *)db_handle; + sqlite3_stmt *sql_stmt = NULL; + char *query_string = NULL; + int count = 0; + + DCM_CHECK_FALSE((data != NULL)); + DCM_CHECK_FALSE((data->media_uuid != NULL)); + + query_string = sqlite3_mprintf("SELECT count(*) FROM %s WHERE (media_uuid='%s' AND" + " face_rect_x='%d' AND face_rect_y='%d' AND face_rect_w='%d' AND face_rect_h='%d' AND orientation='%d')" + , DB_TABLE_FACE, data->media_uuid + , data->face_rect_x, data->face_rect_y, data->face_rect_w, data->face_rect_h, data->orientation); + + ret = _dcm_svc_sql_prepare_to_step(handle, query_string, &sql_stmt); + + if (ret != MS_MEDIA_ERR_NONE) { + dcm_error("error when __dcm_svc_sql_prepare_to_step. ret = [%d]", ret); + return TRUE; + } + + count = sqlite3_column_int(sql_stmt, 0); + + DCM_SQLITE3_FINALIZE(sql_stmt); + + if (count > 0) { + dcm_warn("duplicated face data!"); + return TRUE; + } + + return FALSE; +} + +gboolean _dcm_svc_db_check_duplicated_scan_list(MediaDBHandle *db_handle, const char *data) +{ + int ret = MS_MEDIA_ERR_NONE; + sqlite3 * handle = (sqlite3 *)db_handle; + sqlite3_stmt *sql_stmt = NULL; + char *query_string = NULL; + int count = 0; + + DCM_CHECK_FALSE((data != NULL)); + + query_string = sqlite3_mprintf("SELECT count(*) FROM %s WHERE media_uuid='%s'", DB_TABLE_FACE_SCAN_LIST, data); + + ret = _dcm_svc_sql_prepare_to_step(handle, query_string, &sql_stmt); + + if (ret != MS_MEDIA_ERR_NONE) { + dcm_error("error when __dcm_svc_sql_prepare_to_step. ret = [%d]", ret); + return TRUE; + } + + count = sqlite3_column_int(sql_stmt, 0); + + DCM_SQLITE3_FINALIZE(sql_stmt); + + if (count > 0) { + dcm_warn("duplicated media data!"); + return TRUE; + } + + return FALSE; +} + + +static int _dcm_svc_sql_prepare_to_step(sqlite3 *handle, const char *sql_str, sqlite3_stmt** stmt) +{ + int ret = MS_MEDIA_ERR_NONE; + + dcm_debug("[SQL query] : %s", sql_str); + + if (!DCM_STRING_VALID(sql_str)) { + dcm_error("invalid query"); + return MS_MEDIA_ERR_INVALID_PARAMETER; + } + + ret = sqlite3_prepare_v2(handle, sql_str, -1, stmt, NULL); + sqlite3_free((char *)sql_str); + + if (ret != SQLITE_OK) { + dcm_error("prepare error %d[%s]", ret, sqlite3_errmsg(handle)); + if (ret == SQLITE_CORRUPT) + return MS_MEDIA_ERR_DB_CORRUPT; + else if (ret == SQLITE_PERM) + return MS_MEDIA_ERR_DB_PERMISSION; + + return MS_MEDIA_ERR_DB_INTERNAL; + } + + ret = sqlite3_step(*stmt); + if (ret != SQLITE_ROW) { + dcm_error("[No-Error] Item not found. end of row [%s]", sqlite3_errmsg(handle)); + DCM_SQLITE3_FINALIZE(*stmt); + return MS_MEDIA_ERR_DB_NO_RECORD; + } + + return MS_MEDIA_ERR_NONE; +} + +static int _dcm_svc_sql_prepare_to_step_simple(sqlite3 *handle, const char *sql_str, sqlite3_stmt** stmt) +{ + int ret = MS_MEDIA_ERR_NONE; + + dcm_debug("[SQL query] : %s", sql_str); + + if (!DCM_STRING_VALID(sql_str)) { + dcm_error("invalid query"); + return MS_MEDIA_ERR_INVALID_PARAMETER; + } + + ret = sqlite3_prepare_v2(handle, sql_str, -1, stmt, NULL); + sqlite3_free((char *)sql_str); + + if (ret != SQLITE_OK) { + dcm_error("prepare error %d[%s]", ret, sqlite3_errmsg(handle)); + if (ret == SQLITE_CORRUPT) + return MS_MEDIA_ERR_DB_CORRUPT; + else if (ret == SQLITE_PERM) + return MS_MEDIA_ERR_DB_PERMISSION; + return MS_MEDIA_ERR_DB_INTERNAL; + } + + return MS_MEDIA_ERR_NONE; +} + +int dcm_svc_db_connect(uid_t uid) +{ + int ret = MS_MEDIA_ERR_NONE; + + dcm_debug("_dcm_svc_db_connect uid: %d", uid); + dcm_uid = uid; + + ret = media_db_connect(&db_handle, dcm_uid, TRUE); + if (ret != MS_MEDIA_ERR_NONE) { + dcm_error("media_db_connect failed: %d", ret); + db_handle = NULL; + return ret; + } + + dcm_warn("media db handle: %p", db_handle); + + dcm_debug_fleave(); + + return MS_MEDIA_ERR_NONE; +} + +int dcm_svc_db_disconnect(void) +{ + int ret = MS_MEDIA_ERR_NONE; + + dcm_warn("media db handle: %p", db_handle); + + if (db_handle != NULL) { + ret = media_db_disconnect(db_handle); + if (ret != MS_MEDIA_ERR_NONE) { + dcm_error("media_db_disconnect failed: %d", ret); + db_handle = NULL; + return ret; + } + } + + db_handle = NULL; + + dcm_debug_fleave(); + + return MS_MEDIA_ERR_NONE; +} + + +int dcm_svc_db_get_scan_image_list_by_path(GList **image_list, gboolean mmc_mounted, const char *file_path) +{ + int ret = MS_MEDIA_ERR_NONE; + char *query_string = NULL; + sqlite3_stmt *sql_stmt = NULL; + + dcm_debug_fenter(); + + DCM_CHECK_VAL(db_handle, MS_MEDIA_ERR_INVALID_PARAMETER); + DCM_CHECK_VAL(file_path, MS_MEDIA_ERR_INVALID_PARAMETER); + + /* Make query */ + if (mmc_mounted == true) + query_string = sqlite3_mprintf(SELECT_MEDIA_INFO_BY_FILE_PATH_FROM_DB, file_path); + else + query_string = sqlite3_mprintf(SELECT_MEDIA_INFO_BY_FILE_PATH_FROM_DB, file_path); + + if (query_string == NULL) { + dcm_error("Failed to make query!"); + return MS_MEDIA_ERR_OUT_OF_MEMORY; + } + + ret = _dcm_svc_sql_prepare_to_step_simple((sqlite3 *)db_handle, query_string, &sql_stmt); + if (ret != MS_MEDIA_ERR_NONE) { + dcm_error("error when __dcm_svc_sql_prepare_to_step. ret = [%d]", ret); + return TRUE; + } + + while (sqlite3_step(sql_stmt) == SQLITE_ROW) { + dcm_svc_item_s *scan_item = (dcm_svc_item_s *) g_malloc0(sizeof(dcm_svc_item_s)); + if (!scan_item) { + dcm_error("Failed to allocate memory for scan_item!"); + continue; + } + + if (DCM_STRING_VALID((const char *)sqlite3_column_text(sql_stmt, 0))) + scan_item->media_uuid = strdup((const char *)sqlite3_column_text(sql_stmt, 0)); + + if (DCM_STRING_VALID(file_path)) + scan_item->file_path = strdup(file_path); + + if (DCM_STRING_VALID((const char *)sqlite3_column_text(sql_stmt, 1))) + scan_item->storage_uuid = strdup((const char *)sqlite3_column_text(sql_stmt, 1)); + + scan_item->image_width = sqlite3_column_int(sql_stmt, 2); + scan_item->image_height = sqlite3_column_int(sql_stmt, 3); + scan_item->image_orientation = sqlite3_column_int(sql_stmt, 4); + scan_item->mime_type = g_strdup((const char *)sqlite3_column_text(sql_stmt, 5)); + + /* scan item retrieved by this function will be marked as SCAN_SINGLE */ + scan_item->scan_item_type = DCM_SCAN_ITEM_TYPE_SCAN_SINGLE; + + *image_list = g_list_append(*image_list, scan_item); + + dcm_sec_debug("media uuid: [%s] file path: [%s]", scan_item->media_uuid, scan_item->file_path); + } + + DCM_SQLITE3_FINALIZE(sql_stmt); + + dcm_debug_fleave(); + + return ret; +} + +int dcm_svc_db_get_scan_image_list_from_db(GList **image_list, gboolean mmc_mounted) +{ + int ret = MS_MEDIA_ERR_NONE; + char * query_string = NULL; + sqlite3_stmt *sql_stmt = NULL; + + dcm_debug_fenter(); + + DCM_CHECK_VAL(db_handle, MS_MEDIA_ERR_INVALID_PARAMETER); + DCM_CHECK_VAL(image_list, MS_MEDIA_ERR_INVALID_PARAMETER); + + /* Make query */ + if (mmc_mounted == true) + query_string = sqlite3_mprintf(SELECT_PATH_FROM_UNEXTRACTED_DCM_MEDIA); + else + query_string = sqlite3_mprintf(SELECT_PATH_FROM_UNEXTRACTED_DCM_INTERNAL_MEDIA); + + ret = _dcm_svc_sql_prepare_to_step_simple((sqlite3 *)db_handle, query_string, &sql_stmt); + if (ret != MS_MEDIA_ERR_NONE) { + dcm_error("error when __dcm_svc_sql_prepare_to_step_simple. ret = [%d]", ret); + return ret; + } + + while (sqlite3_step(sql_stmt) == SQLITE_ROW) { + dcm_svc_item_s *scan_item = (dcm_svc_item_s *) g_malloc0(sizeof(dcm_svc_item_s)); + if (!scan_item) { + dcm_error("Failed to allocate memory for scan_item!"); + continue; + } + + if (DCM_STRING_VALID((const char *)sqlite3_column_text(sql_stmt, 0))) + scan_item->media_uuid = strdup((const char *)sqlite3_column_text(sql_stmt, 0)); + + if (DCM_STRING_VALID((const char *)sqlite3_column_text(sql_stmt, 1))) + scan_item->file_path = strdup((const char *)sqlite3_column_text(sql_stmt, 1)); + + if (DCM_STRING_VALID((const char *)sqlite3_column_text(sql_stmt, 2))) + scan_item->storage_uuid = strdup((const char *)sqlite3_column_text(sql_stmt, 2)); + + scan_item->image_width = sqlite3_column_int(sql_stmt, 3); + scan_item->image_height = sqlite3_column_int(sql_stmt, 4); + scan_item->image_orientation = sqlite3_column_int(sql_stmt, 5); + scan_item->mime_type = g_strdup((const char *)sqlite3_column_text(sql_stmt, 6)); + + /* scan item retrieved by this function will be marked as SCAN_ALL */ + scan_item->scan_item_type = DCM_SCAN_ITEM_TYPE_SCAN_ALL; + + *image_list = g_list_append(*image_list, scan_item); + + dcm_sec_debug("media uuid: [%s] file path: [%s]", scan_item->media_uuid, scan_item->file_path); + } + + DCM_SQLITE3_FINALIZE(sql_stmt); + + dcm_debug_fleave(); + + return MS_MEDIA_ERR_NONE; +} + +int dcm_svc_db_generate_uuid(dcm_face_item_s **face) +{ + int ret = MS_MEDIA_ERR_NONE; + uuid_t uuid_value; + static char uuid_unparsed[50] = {0, }; + + dcm_debug_fenter(); + DCM_CHECK_VAL(face, MS_MEDIA_ERR_INVALID_PARAMETER); + + uuid_generate(uuid_value); + uuid_unparse(uuid_value, uuid_unparsed); + + (*face)->face_uuid = g_strdup(uuid_unparsed); + + if ((*face)->face_uuid == NULL) + ret = MS_MEDIA_ERR_INTERNAL; + else + dcm_debug("set face_uuid :%s", (*face)->face_uuid); + + dcm_debug_fleave(); + + return ret; +} + +int dcm_svc_db_insert_face_to_db(dcm_face_item_s *face) +{ + int ret = MS_MEDIA_ERR_NONE; + char* query_string = NULL; + + dcm_debug_fenter(); + + DCM_CHECK_VAL(db_handle, MS_MEDIA_ERR_INVALID_PARAMETER); + DCM_CHECK_VAL(face, MS_MEDIA_ERR_INVALID_PARAMETER); + DCM_CHECK_VAL(face->face_uuid, MS_MEDIA_ERR_INVALID_PARAMETER); + + if (_dcm_svc_db_check_duplicated(db_handle, face) == TRUE) { + dcm_error("[__dcm_svc_db_check_duplicated] The data is duplicated!"); + return MS_MEDIA_ERR_INTERNAL; + } + + query_string = sqlite3_mprintf(INSERT_FACE_ITEM_TO_DB, face->face_uuid, face->media_uuid, face->face_rect_x, face->face_rect_y, face->face_rect_w, face->face_rect_h, face->orientation); + + dcm_debug("query is %s", query_string); + + g_mutex_trylock(&gMutexLock); + ret = media_db_request_update_db(query_string, dcm_uid); + if (ret != MS_MEDIA_ERR_NONE) + dcm_error("media_db_request_update_db fail = %d, %s", ret, sqlite3_errmsg((sqlite3 *)db_handle)); + + g_mutex_unlock(&gMutexLock); + + DCM_SQLITE3_FREE(query_string); + + dcm_debug_fleave(); + + return ret; +} + +int dcm_svc_db_insert_face_to_face_scan_list(dcm_svc_item_s *scan_item) +{ + int ret = MS_MEDIA_ERR_NONE; + char* query_string = NULL; + + dcm_debug_fenter(); + + DCM_CHECK_VAL(db_handle, MS_MEDIA_ERR_INVALID_PARAMETER); + DCM_CHECK_VAL(scan_item, MS_MEDIA_ERR_INVALID_PARAMETER); + DCM_CHECK_VAL(scan_item->media_uuid, MS_MEDIA_ERR_INVALID_PARAMETER); + + if (_dcm_svc_db_check_duplicated_scan_list(db_handle, scan_item->media_uuid) == TRUE) { + dcm_error("[_dcm_svc_db_insert_face_to_face_scan_list] The data is duplicated!"); + return MS_MEDIA_ERR_INTERNAL; + } + + query_string = sqlite3_mprintf("INSERT INTO %s (media_uuid, storage_uuid) values('%q', '%q')", DB_TABLE_FACE_SCAN_LIST, scan_item->media_uuid, scan_item->storage_uuid); + + dcm_debug("query is %s", query_string); + + g_mutex_trylock(&gMutexLock); + ret = media_db_request_update_db(query_string, dcm_uid); + if (ret != MS_MEDIA_ERR_NONE) + dcm_error("media_db_request_update_db is failed: %d, %s", ret, sqlite3_errmsg((sqlite3 *)db_handle)); + + g_mutex_unlock(&gMutexLock); + + DCM_SQLITE3_FREE(query_string); + + dcm_debug_fleave(); + + return ret; +} + +int dcm_svc_db_update_color_to_db(dcm_color_item_s color) +{ + int ret = MS_MEDIA_ERR_NONE; + + dcm_debug_fenter(); +#if 0 + char* query_string = NULL; + + DCM_CHECK_VAL(db_handle, MS_MEDIA_ERR_INVALID_PARAMETER); + DCM_CHECK_VAL(color.media_uuid, MS_MEDIA_ERR_INVALID_PARAMETER); + DCM_CHECK_VAL(color.storage_uuid, MS_MEDIA_ERR_INVALID_PARAMETER); + + query_string = sqlite3_mprintf(UPDATE_COLOR_ITEM_TO_DB, (int)(color.rgb_r), (int)(color.rgb_g), (int)(color.rgb_b), color.media_uuid, color.storage_uuid); + dcm_debug("query is %s", query_string); + + g_mutex_trylock(&gMutexLock); + ret = media_db_request_update_db(query_string, dcm_uid); + if (ret != MS_MEDIA_ERR_NONE) + dcm_error("media_db_request_update_db fail = %d, %s", ret, sqlite3_errmsg((sqlite3 *)db_handle)); + g_mutex_unlock(&gMutexLock); + + DCM_SQLITE3_FREE(query_string); +#endif + dcm_debug_fleave(); + + return ret; +} + +int dcm_svc_db_check_scanned_by_media_uuid(const char *media_uuid, gboolean *media_scanned) +{ + int ret = MS_MEDIA_ERR_NONE; + char *query_string = NULL; + sqlite3_stmt *sql_stmt = NULL; + int count = 0; + + dcm_debug_fenter(); + + DCM_CHECK_VAL(db_handle, MS_MEDIA_ERR_INVALID_PARAMETER); + DCM_CHECK_VAL(media_uuid, MS_MEDIA_ERR_INVALID_PARAMETER); + + query_string = sqlite3_mprintf("SELECT count(*) FROM %s WHERE (media_uuid='%q')", DB_TABLE_FACE_SCAN_LIST, media_uuid); + DCM_CHECK_VAL(query_string, MS_MEDIA_ERR_OUT_OF_MEMORY); + + ret = _dcm_svc_sql_prepare_to_step((sqlite3 *)db_handle, query_string, &sql_stmt); + if (ret != MS_MEDIA_ERR_NONE) { + dcm_error("error when __dcm_svc_sql_prepare_to_step. ret = [%d]", ret); + return ret; + } + + count = sqlite3_column_int(sql_stmt, 0); + + DCM_SQLITE3_FINALIZE(sql_stmt); + + if (count > 0) + *media_scanned = TRUE; + else + *media_scanned = FALSE; + + dcm_debug_fleave(); + + return ret; +} diff --git a/src/dcm_svc_detect_face.c b/src/dcm_svc_detect_face.c new file mode 100755 index 0000000..4496cb9 --- /dev/null +++ b/src/dcm_svc_detect_face.c @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "dcm_svc_detect_face.h" + +static dcm_face_h dcm_face_handle = NULL; + +double _calculate_scale_factor(dcm_image_info_s *image_info) +{ + double scale_factor = 0.0; + + DCM_CHECK_VAL(image_info, 0.0); + + if (image_info->original_width >= image_info->original_height) { + if (image_info->buffer_width >= image_info->buffer_height) + scale_factor = ((double) (image_info->original_width)) / ((double) (image_info->buffer_width)); + else + scale_factor = ((double) (image_info->original_width)) / ((double) (image_info->buffer_height)); + } else { + if (image_info->buffer_height >= image_info->buffer_width) + scale_factor = ((double) (image_info->original_height)) / ((double) (image_info->buffer_height)); + else + scale_factor = ((double) (image_info->original_height)) / ((double) (image_info->buffer_width)); + } + + dcm_debug("scale_factor: %lf", scale_factor); + + return scale_factor; +} + +int _create_face_item(dcm_face_item_s **face) +{ + DCM_CHECK_VAL(face, MS_MEDIA_ERR_INVALID_PARAMETER); + + *face = NULL; + + dcm_face_item_s *_face = (dcm_face_item_s*)g_malloc0(sizeof(dcm_face_item_s)); + if (_face == NULL) + return MS_MEDIA_ERR_OUT_OF_MEMORY; + + *face = _face; + + return MS_MEDIA_ERR_NONE; +} + +void _destroy_face_item(void *data) +{ + dcm_face_item_s *_face = (dcm_face_item_s *)data; + DCM_CHECK(_face); + + DCM_SAFE_FREE(_face->face_uuid); + DCM_SAFE_FREE(_face->media_uuid); + DCM_SAFE_FREE(_face); + + return; +} + +int face_detect_initialize() +{ + int ret = MS_MEDIA_ERR_NONE; + + dcm_debug_fenter(); + + ret = dcm_face_create(&dcm_face_handle); + + dcm_debug_fleave(); + + return ret; +} + +int face_detect_finalize() +{ + int ret = MS_MEDIA_ERR_NONE; + + dcm_debug_fenter(); + + DCM_CHECK_VAL(dcm_face_handle, MS_MEDIA_ERR_INVALID_PARAMETER); + + ret = dcm_face_destroy(dcm_face_handle); + + dcm_face_handle = NULL; + + dcm_debug_fleave(); + + return ret; +} + +int face_detect_process(dcm_svc_item_s *scan_item, dcm_image_info_s *image_info) +{ + dcm_face_item_s *face = NULL; + int face_area = 0; + int i = 0; + double scale_factor = 0.0; + int err = MS_MEDIA_ERR_NONE; + int ret = MS_MEDIA_ERR_NONE; + face_info_s *face_info = NULL; + + dcm_debug_fenter(); + + DCM_CHECK_VAL(dcm_face_handle, MS_MEDIA_ERR_INVALID_PARAMETER); + DCM_CHECK_VAL(scan_item, MS_MEDIA_ERR_INVALID_PARAMETER); + DCM_CHECK_VAL(scan_item->media_uuid, MS_MEDIA_ERR_INVALID_PARAMETER); + DCM_CHECK_VAL(image_info, MS_MEDIA_ERR_INVALID_PARAMETER); + DCM_CHECK_VAL(image_info->pixel, MS_MEDIA_ERR_INVALID_PARAMETER); + + dcm_debug("colorspce: [%d], w: [%d], h: [%d]", image_info->decode_type, image_info->buffer_width, image_info->buffer_height); + + ret = dcm_face_set_image_info(dcm_face_handle, (face_image_colorspace_e)image_info->decode_type, image_info->pixel, image_info->buffer_width, image_info->buffer_height, image_info->size); + if (ret != MS_MEDIA_ERR_NONE) { + dcm_error("Failed to dcm_face_set_image_info! err: %d", err); + goto DCM_SVC_FACE_RECOGNIZE_BUFFER_FAILED; + } + + face_info = (face_info_s *)g_malloc0(sizeof(face_info_s)); + if (face_info == NULL) { + dcm_error("Failed to allocate face info"); + ret = MS_MEDIA_ERR_OUT_OF_MEMORY; + goto DCM_SVC_FACE_RECOGNIZE_BUFFER_FAILED; + } + + ret = dcm_face_get_face_info(dcm_face_handle, face_info); + if (ret != MS_MEDIA_ERR_NONE) { + dcm_error("Failed to get face info! err: %d", err); + goto DCM_SVC_FACE_RECOGNIZE_BUFFER_FAILED; + } + + dcm_warn("detected face count: %d", face_info->count); + if (face_info->count <= 0) { + scan_item->face_count = 0; + goto DCM_SVC_FACE_RECOGNIZE_BUFFER_FAILED; + } + scan_item->face_count = face_info->count; + + /* Compute scale factor between decode size and original size */ + scale_factor = _calculate_scale_factor(image_info); + + /* Insert every face rectangle into database */ + for (i = 0; i < face_info->count; i++) { + face = NULL; + + ret = _create_face_item(&face); + if (ret != MS_MEDIA_ERR_NONE) { + dcm_error("Failed to create face items! ret: %d", ret); + goto DCM_SVC_FACE_RECOGNIZE_BUFFER_FAILED; + } + + if (scale_factor > 1.0) { + face->face_rect_x = (int) (face_info->rects[i].x * scale_factor); + face->face_rect_y = (int) (face_info->rects[i].y * scale_factor); + face->face_rect_w = (int) (face_info->rects[i].w * scale_factor); + face->face_rect_h = (int) (face_info->rects[i].h * scale_factor); + } else { + face->face_rect_x = face_info->rects[i].x; + face->face_rect_y = face_info->rects[i].y; + face->face_rect_w = face_info->rects[i].w; + face->face_rect_h = face_info->rects[i].h; + } + face->orientation = face_info->rects[i].orientation; + + face_area += face->face_rect_w * face->face_rect_h; + dcm_debug("[#%d] face rect: XYWH (%d, %d, %d, %d)", i, face->face_rect_x, face->face_rect_y, face->face_rect_w, + face->face_rect_h); + + face->media_uuid = strdup(scan_item->media_uuid); + + /* Insert face rectangle into database */ + ret = dcm_svc_db_generate_uuid(&face); + if (ret != MS_MEDIA_ERR_NONE) { + dcm_error("Failed to set uuid! ret: %d", ret); + goto DCM_SVC_FACE_RECOGNIZE_BUFFER_FAILED; + } + ret = dcm_svc_db_insert_face_to_db(face); + if (ret != MS_MEDIA_ERR_NONE) { + dcm_error("Failed to insert face item into db! ret: %d", ret); + goto DCM_SVC_FACE_RECOGNIZE_BUFFER_FAILED; + } + + /* Send db updated notification */ + _destroy_face_item(face); + face = NULL; + } + +DCM_SVC_FACE_RECOGNIZE_BUFFER_FAILED: + + err = dcm_svc_db_insert_face_to_face_scan_list(scan_item); + if (err != MS_MEDIA_ERR_NONE) + dcm_error("Failed to insert face item into face_scan_list! err: %d", err); + + dcm_face_destroy_face_info(face_info); + + if (face != NULL) { + _destroy_face_item(face); + face = NULL; + } + + dcm_debug_fleave(); + + return ret; +} diff --git a/src/dcm_svc_extract_color.c b/src/dcm_svc_extract_color.c new file mode 100755 index 0000000..31c17c6 --- /dev/null +++ b/src/dcm_svc_extract_color.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "dcm_svc_debug.h" +#include "dcm_svc_extract_color.h" + +int color_extract_process(dcm_svc_item_s *scan_item, dcm_image_info_s *image_info) +{ + DCM_CHECK_VAL(scan_item, MS_MEDIA_ERR_INVALID_PARAMETER); + DCM_CHECK_VAL(image_info, MS_MEDIA_ERR_INVALID_PARAMETER); + DCM_CHECK_VAL(image_info->pixel, MS_MEDIA_ERR_INVALID_PARAMETER); + + dcm_debug_fenter(); +#if 0 + int ret = IMAGE_UTIL_ERROR_NONE; + dcm_color_item_s colorItem = {0,}; + memset(&colorItem, 0, sizeof(dcm_color_item_s)); + + // Extracting color supports only RGB888 format + ret = image_util_extract_color_from_memory(image_info->pixel, image_info->buffer_width, image_info->buffer_height, &(colorItem.rgb_r), &(colorItem.rgb_g), &(colorItem.rgb_b)); + if (ret != IMAGE_UTIL_ERROR_NONE) { + dcm_error("image_util_extract_color_from_memory err= %d", ret); + return MS_MEDIA_ERR_INTERNAL; + } + + dcm_debug("image_util_extract_color_from_memory result r:%02x, g:%02x, b:%02x", colorItem.rgb_r, colorItem.rgb_g, colorItem.rgb_b); + + colorItem.media_uuid = strdup(scan_item->media_uuid); + colorItem.storage_uuid = strdup(scan_item->storage_uuid); + ret = dcm_svc_db_update_color_to_db(colorItem); + if (ret != MS_MEDIA_ERR_NONE) { + dcm_error("Failed to update color item into db! err: %d", ret); + return MS_MEDIA_ERR_DB_INTERNAL; + } +#endif + dcm_debug_fleave(); + + return MS_MEDIA_ERR_NONE; +} + diff --git a/src/dcm_svc_internal.c b/src/dcm_svc_internal.c new file mode 100755 index 0000000..46fe605 --- /dev/null +++ b/src/dcm_svc_internal.c @@ -0,0 +1,753 @@ +/* + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../libdcm-util/include/dcm_image_codec.h" +#include +#include +#include +#include +#include + +#include "dcm_svc_debug.h" +#include "dcm_svc_extract_color.h" +#include "dcm_svc_detect_face.h" + +#define MIME_TYPE_JPEG "image/jpeg" +#define MIME_TYPE_PNG "image/png" +#define MIME_TYPE_BMP "image/bmp" + +#define DCM_SVC_SCAN_THREAD_TIMEOUT_SEC 1 + +int _dcm_scan_create_timer(gpointer data); + +void __dcm_scan_main_loop_quit(gpointer data) +{ + dcm_scan_s *_data = (dcm_scan_s *)data; + if (_data->main_loop != NULL) { + dcm_warn("Quit scan thread mainloop!"); + g_main_loop_quit(_data->main_loop); + } else { + dcm_warn("Scan thread mainloop is invalid!"); + } + + return; +} + +gboolean __dcm_scan_kill_scan_thread(gpointer data) +{ + dcm_scan_s *_data = (dcm_scan_s *)data; + int ret; + + dcm_debug_fenter(); + + DCM_CHECK_FALSE(data); + + ret = dcm_ipc_send_message(DCM_MSG_SCAN_TERMINATED, 0, NULL, DCM_IPC_PORT_DCM_RECV); + if (ret != MS_MEDIA_ERR_NONE) + dcm_error("send to terminated messge to DCM Main"); + + if (_data->scan_all_curr_index != 0 || _data->scan_single_curr_index != 0) { + dcm_warn("Scan thread is working! DO NOT quit main thread!"); + _dcm_scan_create_timer(data); + } else { + dcm_warn("Quit dcm-svc main loop!"); + __dcm_scan_main_loop_quit(data); + } + + dcm_debug_fleave(); + + return FALSE; +} + +int _dcm_scan_create_timer(gpointer data) +{ + dcm_scan_s *_data = (dcm_scan_s *)data; + dcm_debug_fenter(); + + if (_data->kill_timer_source != NULL) { + dcm_debug("Delete old quit timer!"); + g_source_destroy(_data->kill_timer_source); + _data->kill_timer_source = NULL; + } + + _data->kill_timer_source = g_timeout_source_new_seconds(DCM_SVC_SCAN_THREAD_TIMEOUT_SEC); + DCM_CHECK_VAL(_data->kill_timer_source, MS_MEDIA_ERR_OUT_OF_MEMORY); + + g_source_set_callback(_data->kill_timer_source, __dcm_scan_kill_scan_thread, (gpointer)data, NULL); + g_source_attach(_data->kill_timer_source, _data->main_context); + + dcm_debug_fleave(); + + return MS_MEDIA_ERR_NONE; +} + +void __destroy_scan_item(void *data) +{ + dcm_svc_item_s *scan_item = (dcm_svc_item_s *) data; + + dcm_debug_fenter(); + + DCM_CHECK(scan_item); + DCM_CHECK(scan_item->file_path); + DCM_CHECK(scan_item->media_uuid); + DCM_CHECK(scan_item->storage_uuid); + + dcm_sec_debug("Free scan item. path: [%s]", scan_item->file_path); + + DCM_SAFE_FREE(scan_item->file_path); + DCM_SAFE_FREE(scan_item->media_uuid); + DCM_SAFE_FREE(scan_item->storage_uuid); + DCM_SAFE_FREE(scan_item); + + dcm_debug_fleave(); + + return; +} + +int __dcm_scan_get_mmc_state(void) +{ + int err = -1; + int status = -1; + + err = vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &status); + if (err != 0) + dcm_error("vconf_get_int Unexpected error code: %d", err); + + return status; +} + +int __dcm_scan_get_item_list(dcm_scan_s *data) +{ + int ret = MS_MEDIA_ERR_NONE; + gboolean mmc_mounted = false; + + if (__dcm_scan_get_mmc_state() == VCONFKEY_SYSMAN_MMC_MOUNTED) + mmc_mounted = true; + else + mmc_mounted = false; + + /* Get scan image list from db */ + ret = dcm_svc_db_get_scan_image_list_from_db(&(data->scan_all_item_list), mmc_mounted); + if (ret != MS_MEDIA_ERR_NONE) { + dcm_error("Failed to get image list from db! ret: %d", ret); + return ret; + } + + if (data->scan_all_item_list == NULL) { + dcm_debug("No image list for scanning"); + return MS_MEDIA_ERR_DB_NO_RECORD; + } + + if ((data->scan_all_item_list != NULL) && (g_list_length(data->scan_all_item_list) == 0)) { + dcm_debug("No image list from db!"); + return MS_MEDIA_ERR_DB_NO_RECORD; + } + + return MS_MEDIA_ERR_NONE; +} + +int __dcm_scan_get_item_list_by_path(const char *file_path, dcm_scan_s *data) +{ + int ret = MS_MEDIA_ERR_NONE; + gboolean mmc_mounted = false; + + if (__dcm_scan_get_mmc_state() == VCONFKEY_SYSMAN_MMC_MOUNTED) + mmc_mounted = true; + else + mmc_mounted = false; + + /* Get scan image list from db */ + ret = dcm_svc_db_get_scan_image_list_by_path(&(data->scan_single_item_list), mmc_mounted, file_path); + if (ret != MS_MEDIA_ERR_NONE) { + dcm_error("Failed to get image list from db! ret: %d", ret); + return ret; + } + + if (data->scan_single_item_list == NULL) { + dcm_debug("No image list for scanning"); + return MS_MEDIA_ERR_DB_NO_RECORD; + } + + if ((data->scan_single_item_list != NULL) && (g_list_length(data->scan_single_item_list) == 0)) { + dcm_debug("No image list from db!"); + return MS_MEDIA_ERR_DB_NO_RECORD; + } + + return MS_MEDIA_ERR_NONE; +} + +int __dcm_scan_get_scan_status(dcm_svc_item_s *scan_item, gboolean *media_scanned) +{ + int ret = MS_MEDIA_ERR_NONE; + + DCM_CHECK_VAL(scan_item, MS_MEDIA_ERR_INVALID_PARAMETER); + DCM_CHECK_VAL(scan_item->media_uuid, MS_MEDIA_ERR_INVALID_PARAMETER); + + /* Check if this media is scanned or not */ + ret = dcm_svc_db_check_scanned_by_media_uuid(scan_item->media_uuid, media_scanned); + if (ret != MS_MEDIA_ERR_NONE) + dcm_error("Failed to check if this media item is scanned or not!"); + return ret; +} + +int __dcm_scan_send_result(dcm_scan_s *data, const char *msg, const unsigned int count, dcm_ipc_port_e port) +{ + if ((data->scan_all_item_list == NULL) && (data->scan_single_item_list == NULL)) { + dcm_debug("Send completed message"); + dcm_ipc_send_complete(DCM_MSG_SCAN_COMPLETED, count, msg, port); + } else { + if (data->scan_all_item_list) + dcm_warn("scan_all_item_list"); + + if (data->scan_single_item_list) + dcm_warn("scan_single_item_list"); + + dcm_warn("Scan operation is not finished yet. Keep scanning..."); + } + + return MS_MEDIA_ERR_NONE; +} + +int _dcm_scan_clear_all_items(gpointer data) +{ + dcm_scan_s *_data = (dcm_scan_s *)data; + + dcm_debug_fenter(); + + if (_data->scan_all_item_list != NULL) { + g_list_free_full(_data->scan_all_item_list, __destroy_scan_item); + _data->scan_all_item_list = NULL; + } + + _data->scan_all_curr_index = 0; + + return MS_MEDIA_ERR_NONE; +} + +int _dcm_scan_clear_single_item(gpointer data) +{ + dcm_scan_s *_data = (dcm_scan_s *)data; + + dcm_debug_fenter(); + + if (_data->scan_single_item_list) { + g_list_free_full(_data->scan_single_item_list, __destroy_scan_item); + _data->scan_single_item_list = NULL; + } + + _data->scan_single_curr_index = 0; + + return MS_MEDIA_ERR_NONE; +} + +int _dcm_scan_process(dcm_svc_item_s *scan_item) +{ + gboolean media_scanned = false; + int ret = MS_MEDIA_ERR_NONE; + + dcm_debug_fenter(); + DCM_CHECK_VAL(scan_item, MS_MEDIA_ERR_INVALID_PARAMETER); + DCM_CHECK_VAL(scan_item->file_path, MS_MEDIA_ERR_INVALID_PARAMETER); + + dcm_image_info_s image_info = {0, }; + memset(&image_info, 0, sizeof(dcm_image_info_s)); + dcm_image_format_e image_format = DCM_IMAGE_FORMAT_I420; + + /* Process scan operation if the file exists */ + if (g_file_test(scan_item->file_path, (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) == TRUE) { + /* Get necessary information from db again. + * Media information will be inserted after face is detected. + * If media uuid does not exist, retry is needed */ + ret = __dcm_scan_get_scan_status(scan_item, &media_scanned); + if (ret != MS_MEDIA_ERR_NONE) { + dcm_error("Failed to get scan item info from db! err: %d", ret); + return ret; + } + + /* It is possible that when single and async scan for the same image is in the list. + * If the media uuid is already scanned, skip this scan. */ + if (media_scanned == true) { + dcm_warn("This media is scanned already! Skip..."); + DCM_SAFE_FREE(image_info.pixel); + return MS_MEDIA_ERROR_ALREADY_SCANNED; + } else { + dcm_debug("This media is NOT scanned yet."); + } + + dcm_sec_debug("scan file path : [%s]", scan_item->file_path); + dcm_sec_debug("scan media uuid : [%s]", scan_item->media_uuid); + + ImgCodecType type = IMG_CODEC_NONE; + + image_info.original_width = scan_item->image_width; + image_info.original_height = scan_item->image_height; + image_info.orientation = scan_item->image_orientation; + + dcm_debug("scan media w : [%d], h : [%d], orientation : [%d]", image_info.original_width, image_info.original_height, scan_item->image_orientation); + + if (image_info.original_width <= 0 && image_info.original_height <= 0) { + ret = ImgGetImageInfo((const char *)(scan_item->file_path), &type, &(image_info.original_width), &(image_info.original_height)); + if (ret != MS_MEDIA_ERR_NONE) { + dcm_error("Failed ImgGetImageInfo! err: %d", ret); + return ret; + } + + dcm_debug("ImgGetImageInfo type: %d, width: %d, height: %d", type, image_info.original_width, image_info.original_height); + } + + if (strcmp(scan_item->mime_type, MIME_TYPE_JPEG) == 0) { + image_format = DCM_IMAGE_FORMAT_RGB; + } else if ((strcmp(scan_item->mime_type, MIME_TYPE_PNG) == 0) || + (strcmp(scan_item->mime_type, MIME_TYPE_BMP) == 0)) { + image_format = DCM_IMAGE_FORMAT_RGBA; + } else { + dcm_error("Failed not supported type! (%s)", scan_item->mime_type); + return MS_MEDIA_ERR_INVALID_PARAMETER; + } + + ret = dcm_decode_image((const char *) (scan_item->file_path), image_format, scan_item->mime_type, + image_info.orientation, FALSE, &(image_info.pixel), &(image_info.size), + &(image_info.buffer_width), &(image_info.buffer_height)); + if (ret != MS_MEDIA_ERR_NONE) { + dcm_error("Failed dcm_decode_image! err: %d", ret); + return ret; + } + + image_info.decode_type = (dcm_image_type_e)image_format; + + dcm_debug("Image info width: %d, height: %d, buf_width: %d, buf_height: %d", + image_info.original_width, image_info.original_height, image_info.buffer_width, image_info.buffer_height); + + /* Process face scan */ + ret = face_detect_process(scan_item, &image_info); + if (ret != MS_MEDIA_ERR_NONE) + dcm_error("Failed to process face detection! err: %d", ret); + +#if 0 + /* Process color extract */ + ret = color_extract_process(scan_item, &image_info); + if (ret != MS_MEDIA_ERR_NONE) + dcm_error("Failed to process color extraction! err: %d", ret); +#endif + + /* Free image buffer */ + DCM_SAFE_FREE(image_info.pixel); + } else { + dcm_warn("The file does not exist! Skip dcm scan for this file ..."); + } + + dcm_debug_fleave(); + + return ret; +} + +gboolean _dcm_scan_idle_process(gpointer data) +{ + int ret = MS_MEDIA_ERR_NONE; + dcm_scan_s *_data = (dcm_scan_s *)data; + dcm_svc_item_s *scan_item = NULL; + + dcm_debug_fenter(); + + DCM_CHECK_FALSE(_data); + + ret = dcm_svc_db_connect(_data->g_uid); + if (ret != MS_MEDIA_ERR_NONE) + dcm_error("Failed to disconnect db! err: %d", ret); + /* DCM scan started */ + unsigned int list_len = g_list_length(_data->scan_all_item_list); + if ((_data->scan_all_curr_index < list_len) && !_data->g_scan_cancel) { + scan_item = (dcm_svc_item_s *)g_list_nth_data(_data->scan_all_item_list, _data->scan_all_curr_index); + dcm_sec_debug("current index: %d, path: %s state: %s", _data->scan_all_curr_index, scan_item->file_path, (_data->g_scan_cancel) ? "cancel" : "go"); + + ret = _dcm_scan_process(scan_item); + if (ret != MS_MEDIA_ERR_NONE) { + dcm_error("Failed to process scan job! err: %d", ret); + + /* If the scan item is not scanned, insert media uuid into face_scan_list */ + if (ret != MS_MEDIA_ERROR_ALREADY_SCANNED) + dcm_svc_db_insert_face_to_face_scan_list(scan_item); + } + + (_data->scan_all_curr_index)++; + } else { + dcm_warn("All images are scanned. Scan operation completed"); + _dcm_scan_clear_all_items(data); + ret = dcm_svc_db_disconnect(); + if (ret != MS_MEDIA_ERR_NONE) + dcm_error("Failed to disconnect db! err: %d", ret); + _dcm_scan_clear_all_items(data); + /* Send scan complete message to main thread (if all scan operations are finished) */ + __dcm_scan_send_result(data, NULL, 0, DCM_IPC_PORT_DCM_RECV); + dcm_debug_fleave(); + return FALSE; + } + ret = dcm_svc_db_disconnect(); + if (ret != MS_MEDIA_ERR_NONE) + dcm_error("Failed to disconnect db! err: %d", ret); + dcm_debug_fleave(); + + return TRUE; +} + +int _dcm_scan_all_items(gpointer data) +{ + dcm_scan_s *_data = (dcm_scan_s *)data; + int ret = MS_MEDIA_ERR_NONE; + + dcm_debug_fenter(); + + _dcm_scan_clear_all_items(data); + + ret = __dcm_scan_get_item_list(_data); + if (ret == MS_MEDIA_ERR_DB_NO_RECORD) { + dcm_debug("No items to Scan. Scan operation completed!!!"); + _dcm_scan_clear_all_items(data); + /* Send scan complete message to main thread (if all scan operations are finished) */ + __dcm_scan_send_result(data, NULL, 0, DCM_IPC_PORT_DCM_RECV); + ret = dcm_svc_db_disconnect(); + if (ret != MS_MEDIA_ERR_NONE) + dcm_error("Failed to disconnect db! err: %d", ret); + return MS_MEDIA_ERR_NONE; + } + + /* DCM scan started */ + g_idle_add(_dcm_scan_idle_process, (gpointer)data); + + dcm_debug_fleave(); + + return MS_MEDIA_ERR_NONE; +} + +int _dcm_scan_kill_scanner(gpointer data) +{ + dcm_scan_s *_data = (dcm_scan_s *) data; + dcm_debug("Terminate scanning operations, and quit scan thread main loop"); + + _data->g_scan_cancel = TRUE; + + return _dcm_scan_create_timer(data); +} + +int _dcm_scan_receive_message(dcmMsg *recv_msg, gpointer data) +{ + dcm_scan_s *_data = (dcm_scan_s *) data; + int ret = MS_MEDIA_ERR_NONE; + + _data->g_uid = recv_msg->uid; + DCM_CHECK_VAL(recv_msg, MS_MEDIA_ERR_INVALID_PARAMETER); + + dcm_debug("msg_type: %d", recv_msg->msg_type); + + if (recv_msg->msg_type == DCM_MSG_REQUEST_KILL_SERVER) { + /* Destroy scan idles, and quit scan thread main loop */ + ret = _dcm_scan_kill_scanner(data); + if (ret != MS_MEDIA_ERR_NONE) + dcm_error("Failed to terminate DCM scan service! err: %d", ret); + return ret; + } else if (recv_msg->msg_type == DCM_MSG_REQUEST_ALL_MEDIA) { + /* Use timer to scan all unscanned images */ + ret = dcm_svc_db_connect(recv_msg->uid); + if (ret != MS_MEDIA_ERR_NONE) + dcm_error("Failed to disconnect db! err: %d", ret); + _dcm_scan_all_items(data); + ret = dcm_svc_db_disconnect(); + } else { + dcm_error("Invalid message type(%d)!", recv_msg->msg_type); + ret = MS_MEDIA_ERR_INVALID_IPC_MESSAGE; + } + + return ret; +} + +int dcm_scan_init(gpointer data) +{ + dcm_scan_s *_data = (dcm_scan_s *)data; + + _data->scan_all_item_list = NULL; + _data->scan_all_curr_index = 0; + _data->scan_single_item_list = NULL; + _data->scan_single_curr_index = 0; + _data->g_scan_cancel = FALSE; + _data->kill_timer_source = NULL; + + face_detect_initialize(); + + return MS_MEDIA_ERR_NONE; +} + +int dcm_scan_finalize(gpointer data) +{ + /* Only scan item lists are freed here, scan idles should be freed before this function */ + dcm_scan_s *_data = (dcm_scan_s *)data; + + _dcm_scan_clear_all_items(data); + _dcm_scan_clear_single_item(data); + face_detect_finalize(); + + if (_data != NULL) + free(_data); + + return MS_MEDIA_ERR_NONE; +} + +gboolean dcm_scan_reply_for_ready(gpointer data) +{ + dcm_service_s *_data = (dcm_service_s *) data; + dcmMsg *async_queue_msg = NULL; + + dcm_debug_fenter(); + + DCM_CHECK_FALSE(data); + DCM_CHECK_FALSE(_data->scan_thread_ready); + + async_queue_msg = (dcmMsg*) g_malloc0(sizeof(dcmMsg)); + if (async_queue_msg == NULL) { + dcm_error("memory allocation failed"); + return FALSE; + } + + async_queue_msg->msg_type = DCM_MSG_SCAN_READY; + + dcm_debug("scan thread ready : %p", _data->scan_thread_ready); + dcm_debug("async_queue_msg : %d", async_queue_msg->msg_type); + + g_async_queue_push(_data->scan_thread_ready, (gpointer) async_queue_msg); + + dcm_debug_fleave(); + + return FALSE; +} + +gboolean dcm_scan_read_request(GIOChannel *src, GIOCondition condition, gpointer data) +{ + int sock = -1; + int client_sock = -1; + dcmMsg recv_msg; + int err = 0; + + DCM_CHECK_FALSE(data); + + /* Get socket fd from IO channel */ + sock = g_io_channel_unix_get_fd(src); + if (sock < 0) { + dcm_error("Invalid socket fd!"); + return TRUE; + } + + /* Accept tcp client socket */ + err = dcm_ipc_accept_socket(sock, &client_sock); + if (err != MS_MEDIA_ERR_NONE) { + dcm_error("Failed to accept tcp socket! err: %d", err); + return TRUE; + } + + /* Receive message from tcp socket */ + err = dcm_ipc_receive_message(client_sock, &recv_msg); + if (err != MS_MEDIA_ERR_NONE) { + dcm_error("Failed to receive tcp msg! err: %d", err); + goto DCM_SVC_SCAN_READ_THREAD_RECV_SOCKET_FAILED; + } + + /* Process received message */ + err = _dcm_scan_receive_message(&recv_msg, data); + if (err != MS_MEDIA_ERR_NONE) { + dcm_error("Error ocurred when process received message: %d", err); + goto DCM_SVC_SCAN_READ_THREAD_RECV_SOCKET_FAILED; + } + +DCM_SVC_SCAN_READ_THREAD_RECV_SOCKET_FAILED: + if (close(client_sock) < 0) + dcm_stderror("close failed"); + + return TRUE; +} + +int dcm_scan_single(const char *file_path, uid_t uid, int *face_count) +{ + int ret = MS_MEDIA_ERR_NONE; + dcm_svc_item_s *scan_item = NULL; + unsigned int list_len = 0; + dcm_scan_s *dcm_scan_data = NULL; + + DCM_CHECK_VAL(file_path, MS_MEDIA_ERR_INVALID_PARAMETER); + DCM_CHECK_VAL(face_count, MS_MEDIA_ERR_INVALID_PARAMETER); + + dcm_debug_fenter(); + + /* Init global variables */ + dcm_scan_data = (dcm_scan_s *)calloc(1, sizeof(dcm_scan_s)); + if (dcm_scan_data == NULL) { + dcm_error("Failed to create DCM scan data!"); + return -1; + } + + ret = dcm_scan_init(dcm_scan_data); + if (ret != MS_MEDIA_ERR_NONE) { + dcm_error("Failed to initialize scan thread global variable! err: %d", ret); + goto DCM_SVC_SCAN_SINGLE_FAILED; + } + + _dcm_scan_clear_single_item(dcm_scan_data); + + ret = dcm_svc_db_connect(uid); + if (ret != MS_MEDIA_ERR_NONE) + dcm_error("Failed to connect db! err: %d", ret); + + ret = __dcm_scan_get_item_list_by_path(file_path, dcm_scan_data); + if (ret == MS_MEDIA_ERR_DB_NO_RECORD) { + dcm_debug("No items to Scan. Scan operation completed!!!"); + _dcm_scan_clear_single_item(dcm_scan_data); + goto DCM_SVC_SCAN_SINGLE_FAILED; + } + + dcm_debug("append scan item to scan item list"); + + /* DCM scan started */ + list_len = (unsigned int)g_list_length(dcm_scan_data->scan_single_item_list); + if (dcm_scan_data->scan_single_curr_index < list_len) { + scan_item = (dcm_svc_item_s *)g_list_nth_data(dcm_scan_data->scan_single_item_list, dcm_scan_data->scan_single_curr_index); + dcm_sec_debug("current index: %d, path: %s, scan type: %d", dcm_scan_data->scan_single_curr_index, scan_item->file_path, scan_item->scan_item_type); + + ret = _dcm_scan_process(scan_item); + if (ret != MS_MEDIA_ERR_NONE) { + dcm_error("Failed to process scan job! err: %d", ret); + + /* If the scan item is not scanned, insert media uuid into face_scan_list */ + if (ret != MS_MEDIA_ERROR_ALREADY_SCANNED) + dcm_svc_db_insert_face_to_face_scan_list(scan_item); + } + + (dcm_scan_data->scan_single_curr_index)++; + } + +DCM_SVC_SCAN_SINGLE_FAILED: + ret = dcm_svc_db_disconnect(); + if (ret != MS_MEDIA_ERR_NONE) + dcm_error("Failed to disconnect db! err: %d", ret); + + if (scan_item != NULL) + *face_count = scan_item->face_count; + else + *face_count = 0; + + dcm_debug("*face_count is %d", *face_count); + _dcm_scan_clear_single_item(dcm_scan_data); + + ret = dcm_scan_finalize(dcm_scan_data); + if (ret != MS_MEDIA_ERR_NONE) + dcm_error("Failed to de-initialize scan thread global variable! err: %d", ret); + + dcm_debug_fleave(); + + return MS_MEDIA_ERR_NONE; +} + +gboolean dcm_scan_thread(void *data) +{ + int socket_fd = -1; + GSource *source = NULL; + GIOChannel *channel = NULL; + GMainContext *context = NULL; + GSource *scan_thread_ready_idle = NULL; + dcm_scan_s *dcm_scan_data = NULL; + int err = 0; + + DCM_CHECK_FALSE(data); + + dcm_scan_data = (dcm_scan_s *)calloc(1, sizeof(dcm_scan_s)); + if (dcm_scan_data == NULL) { + dcm_error("Failed to create DCM scan data!"); + return -1; + } + + /* Create TCP Socket to receive message from main thread */ + err = dcm_ipc_create_socket(&socket_fd, DCM_IPC_PORT_SCAN_RECV); + if (err != MS_MEDIA_ERR_NONE) { + dcm_error("Failed to create socket! err: %d", err); + goto DCM_SVC_SCAN_CREATE_SCAN_THREAD_FAILED; + } + dcm_sec_warn("scan thread recv socket: %d", socket_fd); + + /* Init global variables */ + err = dcm_scan_init(dcm_scan_data); + if (err != MS_MEDIA_ERR_NONE) { + dcm_error("Failed to initialize scan thread global variable! err: %d", err); + goto DCM_SVC_SCAN_CREATE_SCAN_THREAD_FAILED; + } + + /* Create a new main context for scan thread */ + context = g_main_context_new(); + dcm_scan_data->main_context = context; + + /* Create a new main event loop */ + dcm_scan_data->main_loop = g_main_loop_new(context, FALSE); + + /* Create a new channel to watch TCP socket */ + channel = g_io_channel_unix_new(socket_fd); + source = g_io_create_watch(channel, G_IO_IN); + + /* Attach channel to main context in scan thread */ + g_source_set_callback(source, (GSourceFunc) dcm_scan_read_request, (gpointer) dcm_scan_data, NULL); + g_source_attach(source, context); + + /* Create a idle after scan thread is ready */ + scan_thread_ready_idle = g_idle_source_new(); + g_source_set_callback(scan_thread_ready_idle, dcm_scan_reply_for_ready, (gpointer) data, NULL); + g_source_attach(scan_thread_ready_idle, context); + + /* Push main context to scan thread */ + g_main_context_push_thread_default(context); + + dcm_debug("********************************************"); + dcm_debug("*** DCM Service scan thread is running ***"); + dcm_debug("********************************************"); + + /* Start to run main event loop for scan thread */ + g_main_loop_run(dcm_scan_data->main_loop); + + dcm_debug("*** DCM Service scan thread will be closed ***"); + + /* Destroy IO channel */ + g_io_channel_shutdown(channel, FALSE, NULL); + g_io_channel_unref(channel); + + /* Close the TCP socket */ + close(socket_fd); + + /* Descrease the reference count of main loop of scan thread */ + g_main_loop_unref(dcm_scan_data->main_loop); + dcm_scan_data->main_loop = NULL; + +DCM_SVC_SCAN_CREATE_SCAN_THREAD_FAILED: + + err = dcm_scan_finalize(dcm_scan_data); + if (err != MS_MEDIA_ERR_NONE) + dcm_error("Failed to de-initialize scan thread global variable! err: %d", err); + + return FALSE; +} + diff --git a/src/dcm_svc_ipc.c b/src/dcm_svc_ipc.c new file mode 100755 index 0000000..8bfd26f --- /dev/null +++ b/src/dcm_svc_ipc.c @@ -0,0 +1,336 @@ +/* + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +static char DCM_IPC_PATH[][100] = { + {"/var/run/media-server/dcm_ipc_scanthread.socket"}, + {"/var/run/media-server/media_ipc_dcmdaemon.socket"}, + {"/var/run/media-server/media_ipc_dcmcomm.socket"}, +}; + +int dcm_ipc_receive_message(int client_sock, dcmMsg *recv_msg) +{ + int recv_msg_size = 0; + + if ((recv_msg_size = read(client_sock, recv_msg, sizeof(dcmMsg))) < 0) { + if (errno == EWOULDBLOCK) { + dcm_error("Timeout. Can't try any more"); + return MS_MEDIA_ERR_SOCKET_RECEIVE_TIMEOUT; + } else { + dcm_stderror("recv failed"); + return MS_MEDIA_ERR_SOCKET_RECEIVE; + } + } + dcm_sec_debug("[receive msg] type: %d, pid: %d, uid: %d, msg: %s, msg_size: %d", recv_msg->msg_type, recv_msg->pid, recv_msg->uid, (recv_msg->msg) ? recv_msg->msg : "NULL", recv_msg->msg_size); + + if (!(recv_msg->msg_type >= 0 && recv_msg->msg_type < DCM_MSG_MAX)) { + dcm_error("IPC message is wrong!"); + return MS_MEDIA_ERR_INVALID_IPC_MESSAGE; + } + + return MS_MEDIA_ERR_NONE; +} + +int dcm_ipc_accept_socket(int serv_sock, int* client_sock) +{ + DCM_CHECK_VAL(client_sock, MS_MEDIA_ERR_INVALID_PARAMETER); + int sockfd = -1; + struct sockaddr_un client_addr; + socklen_t client_addr_len = sizeof(client_addr); + + if ((sockfd = accept(serv_sock, (struct sockaddr*)&client_addr, &client_addr_len)) < 0) { + dcm_stderror("accept failed"); + *client_sock = -1; + return MS_MEDIA_ERR_SOCKET_ACCEPT; + } + + *client_sock = sockfd; + + return MS_MEDIA_ERR_NONE; +} + +int dcm_ipc_create_socket(int *socket_fd, dcm_ipc_port_e port) +{ + DCM_CHECK_VAL(socket_fd, MS_MEDIA_ERR_INVALID_PARAMETER); + int sock = -1; + struct sockaddr_un serv_addr; + gboolean bind_success = false; + int i = 0; + + /* Create a new TCP socket */ + if ((sock = socket(PF_FILE, SOCK_STREAM, 0)) < 0) { + dcm_stderror("socket failed"); + return MS_MEDIA_ERR_SOCKET_INTERNAL; + } + + /* Set socket address */ + memset(&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sun_family = AF_UNIX; + unlink(DCM_IPC_PATH[port]); + strncpy(serv_addr.sun_path, DCM_IPC_PATH[port], sizeof(serv_addr.sun_path) - 1); + + /* Bind socket to local address */ + for (i = 0; i < 100; i++) { + if (bind(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == 0) { + bind_success = true; + break; + } + dcm_debug("#%d bind", i); + usleep(250000); + } + + if (bind_success == false) { + dcm_stderror("bind failed"); + close(sock); + return MS_MEDIA_ERR_SOCKET_BIND; + } + dcm_debug("bind success"); + + /* Listen */ + if (listen(sock, SOMAXCONN) < 0) { + dcm_stderror("listen failed"); + close(sock); + return MS_MEDIA_ERR_SOCKET_INTERNAL; + } + dcm_debug("Listening..."); + + /* change permission of local socket file */ + if (chmod(DCM_IPC_PATH[port], 0777) < 0) + dcm_stderror("chmod failed"); + + *socket_fd = sock; + + return MS_MEDIA_ERR_NONE; +} + +int dcm_ipc_send_client_message(int socket_fd, ms_dcm_msg_type_e msg_type, unsigned int result, const char *msg, dcm_ipc_port_e port) +{ + if (port < 0 || port >= DCM_IPC_PORT_MAX) { + dcm_error("Invalid port! Stop sending message..."); + return MS_MEDIA_ERR_INVALID_PARAMETER; + } + dcm_debug("Send message type: [%d] msg : [%s] result : [%d]", msg_type, msg, result); + + dcmMsg send_msg; + int sock = -1; + + if (socket_fd < 0) { + struct sockaddr_un serv_addr; + struct timeval tv_timeout = { DCM_TIMEOUT_SEC_60, 0 }; /* timeout: 60 seconds */ + + if ((sock = socket(PF_FILE, SOCK_STREAM, 0)) < 0) { + dcm_stderror("socket failed"); + return MS_MEDIA_ERR_SOCKET_INTERNAL; + } + + if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv_timeout, sizeof(tv_timeout)) == -1) { + dcm_stderror("setsockopt failed"); + close(sock); + return MS_MEDIA_ERR_SOCKET_INTERNAL; + } + + memset(&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sun_family = AF_UNIX; + strncpy(serv_addr.sun_path, DCM_IPC_PATH[port], sizeof(DCM_IPC_PATH[port])); + + /* Connecting to the thumbnail server */ + if (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) { + dcm_stderror("connect"); + close(sock); + return MS_MEDIA_ERR_SOCKET_CONN; + } + } else { + sock = socket_fd; + } + + /* Prepare send message */ + memset((void *)&send_msg, 0, sizeof(dcmMsg)); + send_msg.msg_type = msg_type; + send_msg.result = (int)result; + if (msg != NULL) { + send_msg.msg_size = strlen(msg); + g_strlcpy(send_msg.msg, msg, DCM_IPC_MSG_MAX_SIZE); + } + + /* If message size is larget than max_size, then message is invalid */ + if (send_msg.msg_size >= DCM_IPC_MSG_MAX_SIZE) { + dcm_error("Message size is invalid!"); + close(sock); + return MS_MEDIA_ERR_INVALID_IPC_MESSAGE; + } + + /* Send msg to the socket */ + if (send(sock, &send_msg, sizeof(send_msg), 0) != sizeof(send_msg)) { + dcm_stderror("send failed"); + close(sock); + return MS_MEDIA_ERR_SOCKET_SEND; + } + + dcm_debug("Sent message type: %d %d", send_msg.msg_type, send_msg.result); + + close(sock); + + return MS_MEDIA_ERR_NONE; +} + +int dcm_ipc_send_message(ms_dcm_msg_type_e msg_type, uid_t uid, const char *msg, dcm_ipc_port_e port) +{ + if (port < 0 || port >= DCM_IPC_PORT_MAX) { + dcm_error("Invalid port! Stop sending message..."); + return MS_MEDIA_ERR_INVALID_PARAMETER; + } + + dcm_debug_fenter(); + + dcm_debug("Send message type: %d", msg_type); + + int socket_fd = -1; + struct sockaddr_un serv_addr; + dcmMsg send_msg; + + /* Prepare send message */ + memset((void *)&send_msg, 0, sizeof(dcmMsg)); + send_msg.msg_type = msg_type; + send_msg.uid = uid; + if (msg != NULL) { + send_msg.msg_size = strlen(msg); + g_strlcpy(send_msg.msg, msg, DCM_IPC_MSG_MAX_SIZE); + } + + /* If message size is larget than max_size, then message is invalid */ + if (send_msg.msg_size >= DCM_IPC_MSG_MAX_SIZE) { + dcm_error("Message size is invalid!"); + return MS_MEDIA_ERR_SOCKET_SEND; + } + + /* Create a new TCP socket */ + if ((socket_fd = socket(PF_FILE, SOCK_STREAM, 0)) < 0) { + dcm_stderror("socket failed"); + return MS_MEDIA_ERR_SOCKET_SEND; + } + + /* Set dcm thread socket address */ + memset(&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sun_family = AF_UNIX; + strncpy(serv_addr.sun_path, DCM_IPC_PATH[port], sizeof(serv_addr.sun_path) - 1); + + /* Connect to the socket */ + if (connect(socket_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) { + dcm_stderror("connect error"); + close(socket_fd); + return MS_MEDIA_ERR_SOCKET_CONN; + } + + /* Send msg to the socket */ + if (send(socket_fd, &send_msg, sizeof(send_msg), 0) != sizeof(send_msg)) { + dcm_stderror("send failed"); + close(socket_fd); + return MS_MEDIA_ERR_SOCKET_SEND; + } + + close(socket_fd); + + dcm_debug_fleave(); + + return MS_MEDIA_ERR_NONE; +} + +int dcm_ipc_send_complete(ms_dcm_msg_type_e msg_type, const unsigned int count, const char *msg, dcm_ipc_port_e port) +{ + if (port < 0 || port >= DCM_IPC_PORT_MAX) { + dcm_error("Invalid port! Stop sending message..."); + return MS_MEDIA_ERR_INVALID_PARAMETER; + } + + dcm_debug_fenter(); + + dcm_debug("Send message type: %d", msg_type); + + int socket_fd = -1; + struct sockaddr_un serv_addr; + dcmMsg send_msg; + + /* Prepare send message */ + memset((void *)&send_msg, 0, sizeof(dcmMsg)); + send_msg.msg_type = msg_type; + send_msg.result = count; + if (msg != NULL) { + send_msg.msg_size = strlen(msg); + g_strlcpy(send_msg.msg, msg, DCM_IPC_MSG_MAX_SIZE); + } + + /* If message size is larget than max_size, then message is invalid */ + if (send_msg.msg_size >= DCM_IPC_MSG_MAX_SIZE) { + dcm_error("Message size is invalid!"); + return MS_MEDIA_ERR_INVALID_IPC_MESSAGE; + } + + /* Create a new TCP socket */ + if ((socket_fd = socket(PF_FILE, SOCK_STREAM, 0)) < 0) { + dcm_stderror("socket failed"); + return MS_MEDIA_ERR_SOCKET_INTERNAL; + } + + /* Set dcm thread socket address */ + memset(&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sun_family = AF_UNIX; + strncpy(serv_addr.sun_path, DCM_IPC_PATH[port], sizeof(serv_addr.sun_path) - 1); + + /* Connect to the socket */ + if (connect(socket_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) { + dcm_stderror("connect error"); + close(socket_fd); + return MS_MEDIA_ERR_SOCKET_CONN; + } + + /* Send msg to the socket */ + if (send(socket_fd, &send_msg, sizeof(send_msg), 0) != sizeof(send_msg)) { + dcm_stderror("send failed"); + close(socket_fd); + return MS_MEDIA_ERR_SOCKET_SEND; + } + + close(socket_fd); + + dcm_debug_fleave(); + + return MS_MEDIA_ERR_NONE; +} + + +int dcm_ipc_close_socket(int socket_fd) +{ + close(socket_fd); + + return MS_MEDIA_ERR_NONE; +} diff --git a/svc/DcmMainSvc.cpp b/svc/DcmMainSvc.cpp deleted file mode 100755 index 256472d..0000000 --- a/svc/DcmMainSvc.cpp +++ /dev/null @@ -1,325 +0,0 @@ -/* - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * 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. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#define DCM_SVC_MAIN_THREAD_TIMEOUT_SEC 1 - -namespace DcmMainSvcCallBack { -gboolean readMsg(GIOChannel *src, GIOCondition condition, gpointer data); -gboolean quitTimerAtMainLoop(gpointer data); -} - - -DcmMainSvc *DcmMainSvc::dcmMainSvc = NULL; -GMainLoop *g_dcm_svc_mainloop; -static GMutex gMutexLock; - -DcmMainSvc* DcmMainSvc::getInstance(void) -{ - if (dcmMainSvc == NULL) { - g_mutex_trylock(&gMutexLock); - - if (dcmMainSvc == NULL) { - dcmMainSvc = new DcmMainSvc(); - } - - g_mutex_unlock(&gMutexLock); - } - - return dcmMainSvc; -} - -void DcmMainSvc::dcmServiceStartjobs(void) -{ - if (createScanThread() != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to create scan thread! Exit main thread..."); - } - - /* Send ready response to dcm launcher */ - if (DcmIpcUtils::sendSocketMsg(DCM_MSG_SERVER_READY, 0, NULL, DCM_IPC_PORT_MS_RECV) != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to send ready message"); - } -} - -void DcmMainSvc::dcmServiceFinishjobs(void) -{ - /* TODO: free resources for dcm-service */ -} - -int DcmMainSvc::waitScanThreadReady() -{ - int ret = MS_MEDIA_ERR_NONE; - dcmMsg *async_queue_msg = NULL; - - /* Wait until the scan thread is ready (timeout: 5 sec) */ - async_queue_msg = (dcmMsg *)g_async_queue_timeout_pop(scan_thread_ready, 5000000); - if (async_queue_msg == NULL) { - dcm_error("Async queue timeout!"); - return MS_MEDIA_ERR_INTERNAL; - } - - /* Check if scan thread is created */ - if (async_queue_msg->msg_type == DCM_MSG_SCAN_READY) { - dcm_warn("DCM scan thread is ready!"); - g_async_queue_unref(scan_thread_ready); - scan_thread_ready = NULL; - } else { - dcm_error("Invalid async queue message!"); - ret = MS_MEDIA_ERR_INTERNAL; - } - - /* Free the received ipc message */ - DCM_SAFE_FREE(async_queue_msg); - - return ret; -} - -int DcmMainSvc::createScanThread() -{ - int ret = MS_MEDIA_ERR_NONE; - - dcm_debug_fenter(); - - /* Create a new async queue to wait util scan thread is created */ - scan_thread_ready = g_async_queue_new(); - if (scan_thread_ready == NULL) { - dcm_error("Failed to create async queue!"); - return MS_MEDIA_ERR_INTERNAL; - } - - /* Create the scan thread */ - scan_thread = g_thread_new("dcm_scan_thread", (GThreadFunc) DcmScanMain::runScanThread, (gpointer) this); - if (scan_thread == NULL) { - dcm_error("Failed to create scan thread!"); - return MS_MEDIA_ERR_INTERNAL; - } - - ret = waitScanThreadReady(); - /* Wait until scan thread is ready */ - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to wait for scan thread to be ready! err: %d", ret); - return ret; - } - - dcm_debug_fleave(); - - return MS_MEDIA_ERR_NONE; -} - -gboolean DcmMainSvcCallBack::readMsg(GIOChannel *src, GIOCondition condition, gpointer data) -{ - dcmMsg recv_msg; - int sock = -1; - int client_sock = -1; - int ret = 0; - int face_count; - - DcmMainSvc *dcmSvc = DcmMainSvc::getInstance(); - - memset((void *)&recv_msg, 0, sizeof(recv_msg)); - - sock = g_io_channel_unix_get_fd(src); - if (sock < 0) { - dcm_error("sock fd is invalid!"); - return TRUE; - } - - /* Accept tcp client socket */ - ret = DcmIpcUtils::acceptSocket(sock, &client_sock); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to accept tcp socket! err: %d", ret); - return TRUE; - } - - if (DcmIpcUtils::receiveSocketMsg(client_sock, &recv_msg) < 0) { - dcm_error("getRecvMsg failed"); - DcmIpcUtils::closeSocket(client_sock); - return TRUE; - } - - dcm_debug("Received msg_type : [%d]", recv_msg.msg_type); - - if (dcmSvc->scan_thread == NULL) { - dcm_debug("scan thread is not started yet!"); - /* Create scan thread before main loop is started */ - if (dcmSvc->createScanThread() != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to create scan thread! Exit main thread..."); - DcmIpcUtils::closeSocket(client_sock); - return TRUE; - } - - dcmSvc->scan_thread_working = true; - } else { - dcm_debug("scan thread is already running!"); - } - - if (recv_msg.msg_type == DCM_MSG_SCAN_TERMINATED) { - dcm_debug("Scan terminated!"); - dcmSvc->scan_thread_working = false; - dcmSvc->createQuitTimerMainLoop(); - } else if (recv_msg.msg_type == DCM_MSG_SCAN_COMPLETED) { - dcm_debug("Scan completed!"); - ret = DcmIpcUtils::sendClientSocketMsg(-1, DCM_MSG_EXTRACT_ALL_DONE, recv_msg.result, recv_msg.msg, DCM_IPC_PORT_MS_RECV); - } else if (recv_msg.msg_type == DCM_MSG_REQUEST_KILL_SERVER) { - dcm_warn("Quit dcm-svc main loop!"); - ret = DcmIpcUtils::sendSocketMsg(DCM_MSG_REQUEST_KILL_SERVER, recv_msg.uid, recv_msg.msg, DCM_IPC_PORT_SCAN_RECV); - } else if (recv_msg.msg_type == DCM_MSG_REQUEST_ALL_MEDIA) { - ret = DcmIpcUtils::sendSocketMsg(DCM_MSG_REQUEST_ALL_MEDIA, recv_msg.uid, NULL, DCM_IPC_PORT_SCAN_RECV); - if (ret == MS_MEDIA_ERR_NONE) { - ret = DcmIpcUtils::sendClientSocketMsg(client_sock, DCM_MSG_REQUEST_ALL_MEDIA, recv_msg.uid, NULL, DCM_IPC_PORT_DCM_RECV); - } - } else if (recv_msg.msg_type == DCM_MSG_REQUEST_MEDIA) { - dcm_debug("Scan single"); - ret = DcmScanMain::ScanSingle(recv_msg.msg, recv_msg.uid, &face_count); - dcm_debug("Scan single result: ret : [%d] face_count : [%d])", ret, face_count); - if (ret == MS_MEDIA_ERR_NONE) { - ret = DcmIpcUtils::sendClientSocketMsg(client_sock, DCM_MSG_REQUEST_MEDIA, face_count, recv_msg.msg, DCM_IPC_PORT_MS_RECV); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to sendClientSocketMsg! err: %d", ret); - } - } else { - ret = DcmIpcUtils::sendClientSocketMsg(client_sock, DCM_MSG_REQUEST_MEDIA, ret, recv_msg.msg, DCM_IPC_PORT_MS_RECV); - if (ret != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to sendClientSocketMsg! err: %d", ret); - } - } - } else { - dcm_debug("createDcmSvcReadSocket, invalid message(%d).", recv_msg.msg_type); - } - - if (DcmIpcUtils::closeSocket(client_sock) < 0) { - dcm_stderror("close failed"); - } - - return TRUE; -} - -gboolean DcmMainSvcCallBack::quitTimerAtMainLoop(gpointer data) -{ - DcmMainSvc *dcmSvcApp = (DcmMainSvc *) data; - - dcm_debug_fenter(); - - DCM_CHECK_FALSE(data); - - if (dcmSvcApp->scan_thread_working == true) { - dcm_warn("Scan thread is working! DO NOT quit main thread!"); - return TRUE; - } else { - dcm_warn("Quit dcm-svc main loop!"); - dcmSvcApp->quitDcmSvcMainLoop(); - } - - dcm_debug_fleave(); - - return FALSE; -} - -int DcmMainSvc::createQuitTimerMainLoop() -{ - GSource *quit_timer = NULL; - - dcm_debug_fenter(); - - if (main_thread_quit_timer != NULL) { - dcm_debug("Delete old quit timer!"); - g_source_destroy(main_thread_quit_timer); - main_thread_quit_timer = NULL; - } - - quit_timer = g_timeout_source_new_seconds(DCM_SVC_MAIN_THREAD_TIMEOUT_SEC); - DCM_CHECK_VAL(quit_timer, MS_MEDIA_ERR_OUT_OF_MEMORY); - - g_source_set_callback(quit_timer, DcmMainSvcCallBack::quitTimerAtMainLoop, (gpointer) this, NULL); - g_source_attach(quit_timer, main_loop_context); - main_thread_quit_timer = quit_timer; - - dcm_debug_fleave(); - - return MS_MEDIA_ERR_NONE; -} - -void DcmMainSvc::quitDcmSvcMainLoop() -{ - if (g_dcm_svc_mainloop != NULL) { - dcm_debug("Quit DCM thread main loop!"); - g_main_loop_quit(g_dcm_svc_mainloop); - } else { - dcm_error("Invalid DCM thread main loop!"); - } -} - -EXPORT_API int main(int argc, char *argv[]) -{ - DcmMainSvc *dcmSvc = DcmMainSvc::getInstance(); - int sockfd = -1; - - GSource *source = NULL; - GIOChannel *channel = NULL; - GMainContext *context = NULL; - - /* Create and bind new socket to mainloop */ - if (DcmIpcUtils::createSocket(&sockfd, DCM_IPC_PORT_DCM_RECV) != MS_MEDIA_ERR_NONE) { - dcm_error("Failed to create socket"); - return -1; - } - - g_dcm_svc_mainloop = g_main_loop_new(context, FALSE); - context = g_main_loop_get_context(g_dcm_svc_mainloop); - - /* Create new channel to watch new socket for mainloop */ - 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)DcmMainSvcCallBack::readMsg, NULL, NULL); - g_source_attach(source, context); - - dcmSvc->main_loop_context = context; - - dcmSvc->dcmServiceStartjobs(); - - dcm_debug("********************************************"); - dcm_debug("****** DCM Service is running ******"); - dcm_debug("********************************************"); - - g_main_loop_run(g_dcm_svc_mainloop); - - dcmSvc->dcmServiceFinishjobs(); - - dcm_debug("DCM Service is shutting down..."); - g_io_channel_shutdown(channel, FALSE, NULL); - g_io_channel_unref(channel); - close(sockfd); - g_main_loop_unref(g_dcm_svc_mainloop); - - return 0; -} diff --git a/svc/dcm_svc_main.c b/svc/dcm_svc_main.c new file mode 100755 index 0000000..b6e15f0 --- /dev/null +++ b/svc/dcm_svc_main.c @@ -0,0 +1,296 @@ +/* + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define DCM_SVC_MAIN_THREAD_TIMEOUT_SEC 1 + +int _dcm_svc_create_timer(gpointer data); + +void __dcm_svc_main_loop_quit(gpointer data) +{ + dcm_service_s *_data = (dcm_service_s *) data; + + if (_data->main_loop != NULL) { + dcm_debug("Quit DCM thread main loop!"); + g_main_loop_quit(_data->main_loop); + } else { + dcm_error("Invalid DCM thread main loop!"); + } +} + +gboolean __dcm_svc_kill_service(gpointer data) +{ + dcm_service_s *_data = (dcm_service_s *) data; + + dcm_debug_fenter(); + + DCM_CHECK_FALSE(data); + + if (_data->scan_thread_working == true) { + dcm_warn("Scan thread is working! DO NOT quit main thread!"); + return TRUE; + } else { + dcm_warn("Quit dcm-svc main loop!"); + __dcm_svc_main_loop_quit(data); + } + + dcm_debug_fleave(); + + return FALSE; +} + +int _dcm_svc_create_timer(gpointer data) +{ + dcm_service_s *_data = (dcm_service_s *) data; + GSource *quit_timer = NULL; + + dcm_debug_fenter(); + + if (_data->kill_timer_source != NULL) { + dcm_debug("Delete old quit timer!"); + g_source_destroy(_data->kill_timer_source); + _data->kill_timer_source = NULL; + } + + quit_timer = g_timeout_source_new_seconds(DCM_SVC_MAIN_THREAD_TIMEOUT_SEC); + DCM_CHECK_VAL(quit_timer, MS_MEDIA_ERR_OUT_OF_MEMORY); + + g_source_set_callback(quit_timer, __dcm_svc_kill_service, (gpointer) data, NULL); + g_source_attach(quit_timer, _data->main_context); + _data->kill_timer_source = quit_timer; + + dcm_debug_fleave(); + + return MS_MEDIA_ERR_NONE; +} + +int _dcm_svc_wait_scan_thread(gpointer data) +{ + dcm_service_s *_data = (dcm_service_s *)data; + int ret = MS_MEDIA_ERR_NONE; + dcmMsg *async_queue_msg = NULL; + + /* Wait until the scan thread is ready (timeout: 5 sec) */ + async_queue_msg = (dcmMsg *)g_async_queue_timeout_pop(_data->scan_thread_ready, 5000000); + if (async_queue_msg == NULL) { + dcm_error("Async queue timeout!"); + return MS_MEDIA_ERR_INTERNAL; + } + + /* Check if scan thread is created */ + if (async_queue_msg->msg_type == DCM_MSG_SCAN_READY) { + dcm_warn("DCM scan thread is ready!"); + g_async_queue_unref(_data->scan_thread_ready); + _data->scan_thread_ready = NULL; + } else { + dcm_error("Invalid async queue message!"); + ret = MS_MEDIA_ERR_INTERNAL; + } + + /* Free the received ipc message */ + DCM_SAFE_FREE(async_queue_msg); + + return ret; +} + +static int _dcm_svc_create_scan_thread(gpointer data) +{ + dcm_service_s *_data = (dcm_service_s *)data; + int ret = MS_MEDIA_ERR_NONE; + + dcm_debug_fenter(); + + /* Create a new async queue to wait util scan thread is created */ + _data->scan_thread_ready = g_async_queue_new(); + if (_data->scan_thread_ready == NULL) { + dcm_error("Failed to create async queue!"); + return MS_MEDIA_ERR_INTERNAL; + } + + /* Create the scan thread */ + _data->scan_thread = g_thread_new("dcm_scan_thread", (GThreadFunc) dcm_scan_thread, (gpointer) data); + if (_data->scan_thread == NULL) { + dcm_error("Failed to create scan thread!"); + return MS_MEDIA_ERR_INTERNAL; + } + + ret = _dcm_svc_wait_scan_thread(data); + /* Wait until scan thread is ready */ + if (ret != MS_MEDIA_ERR_NONE) { + dcm_error("Failed to wait for scan thread to be ready! err: %d", ret); + return ret; + } + + dcm_debug_fleave(); + + return MS_MEDIA_ERR_NONE; +} + +static void dcm_service_start(gpointer data) +{ + if (_dcm_svc_create_scan_thread(data) != MS_MEDIA_ERR_NONE) + dcm_error("Failed to create scan thread! Exit main thread..."); + + /* Send ready response to dcm launcher */ + if (dcm_ipc_send_message(DCM_MSG_SERVER_READY, 0, NULL, DCM_IPC_PORT_MS_RECV) != MS_MEDIA_ERR_NONE) + dcm_error("Failed to send ready message"); +} + +static void dcm_service_finish(gpointer data) +{ + dcm_service_s *_data = (dcm_service_s *)data; + if (_data != NULL) + free(_data); +} + +gboolean dcm_service_recieve_request(GIOChannel *src, GIOCondition condition, gpointer data) +{ + dcmMsg recv_msg; + int sock = -1; + int client_sock = -1; + int ret = 0; + int face_count; + dcm_service_s *_data = (dcm_service_s *)data; + + memset((void *)&recv_msg, 0, sizeof(recv_msg)); + + sock = g_io_channel_unix_get_fd(src); + if (sock < 0) { + dcm_error("sock fd is invalid!"); + return TRUE; + } + + /* Accept tcp client socket */ + ret = dcm_ipc_accept_socket(sock, &client_sock); + if (ret != MS_MEDIA_ERR_NONE) { + dcm_error("Failed to accept tcp socket! err: %d", ret); + return TRUE; + } + + if (dcm_ipc_receive_message(client_sock, &recv_msg) != MS_MEDIA_ERR_NONE) { + dcm_error("getRecvMsg failed"); + dcm_ipc_close_socket(client_sock); + return TRUE; + } + + dcm_debug("Received msg_type : [%d]", recv_msg.msg_type); + + if (recv_msg.msg_type == DCM_MSG_SCAN_TERMINATED) { + dcm_debug("Scan terminated!"); + _data->scan_thread_working = false; + _dcm_svc_create_timer(data); + } else if (recv_msg.msg_type == DCM_MSG_SCAN_COMPLETED) { + dcm_debug("Scan completed!"); + ret = dcm_ipc_send_client_message(-1, DCM_MSG_EXTRACT_ALL_DONE, recv_msg.result, recv_msg.msg, DCM_IPC_PORT_MS_RECV); + } else if (recv_msg.msg_type == DCM_MSG_REQUEST_KILL_SERVER) { + dcm_warn("Quit dcm-svc main loop!"); + ret = dcm_ipc_send_message(DCM_MSG_REQUEST_KILL_SERVER, recv_msg.uid, recv_msg.msg, DCM_IPC_PORT_SCAN_RECV); + } else if (recv_msg.msg_type == DCM_MSG_REQUEST_ALL_MEDIA) { + ret = dcm_ipc_send_message(DCM_MSG_REQUEST_ALL_MEDIA, recv_msg.uid, NULL, DCM_IPC_PORT_SCAN_RECV); + if (ret == MS_MEDIA_ERR_NONE) + ret = dcm_ipc_send_client_message(client_sock, DCM_MSG_REQUEST_ALL_MEDIA, recv_msg.uid, NULL, DCM_IPC_PORT_DCM_RECV); + } else if (recv_msg.msg_type == DCM_MSG_REQUEST_MEDIA) { + dcm_debug("Scan single"); + ret = dcm_scan_single(recv_msg.msg, recv_msg.uid, &face_count); + dcm_debug("Scan single result: ret : [%d] face_count : [%d])", ret, face_count); + if (ret == MS_MEDIA_ERR_NONE) { + ret = dcm_ipc_send_client_message(client_sock, DCM_MSG_REQUEST_MEDIA, face_count, recv_msg.msg, DCM_IPC_PORT_MS_RECV); + if (ret != MS_MEDIA_ERR_NONE) + dcm_error("Failed to dcm_ipc_send_client_message! err: %d", ret); + } else { + ret = dcm_ipc_send_client_message(client_sock, DCM_MSG_REQUEST_MEDIA, ret, recv_msg.msg, DCM_IPC_PORT_MS_RECV); + if (ret != MS_MEDIA_ERR_NONE) + dcm_error("Failed to dcm_ipc_send_client_message! err: %d", ret); + } + _dcm_svc_create_timer(data); + } else { + dcm_debug("createDcmSvcReadSocket, invalid message(%d).", recv_msg.msg_type); + } + + if (dcm_ipc_close_socket(client_sock) < 0) + dcm_stderror("close failed"); + + return TRUE; +} + +EXPORT_API int main(int argc, char *argv[]) +{ + int sockfd = -1; + GSource *source = NULL; + GIOChannel *channel = NULL; + GMainContext *context = NULL; + /* threads related */ + dcm_service_s *dcm_svc_data = NULL; + + dcm_svc_data = (dcm_service_s *)calloc(1, sizeof(dcm_service_s)); + if (dcm_svc_data == NULL) { + dcm_error("Failed to create DCM Service data!"); + return -1; + } + + /* Create and bind new socket to main_loop */ + if (dcm_ipc_create_socket(&sockfd, DCM_IPC_PORT_DCM_RECV) != MS_MEDIA_ERR_NONE) { + dcm_error("Failed to create socket"); + dcm_service_finish(dcm_svc_data); + return -1; + } + + dcm_svc_data->main_loop = g_main_loop_new(context, FALSE); + context = g_main_loop_get_context(dcm_svc_data->main_loop); + dcm_svc_data->main_context = context; + + /* Create new channel to watch new socket for main_loop */ + 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)dcm_service_recieve_request, NULL, (gpointer) dcm_svc_data); + g_source_attach(source, context); + + dcm_service_start(dcm_svc_data); + + dcm_debug("********************************************"); + dcm_debug("****** DCM Service is running ******"); + dcm_debug("********************************************"); + + g_main_loop_run(dcm_svc_data->main_loop); + + dcm_debug("DCM Service is shutting down..."); + + g_io_channel_shutdown(channel, FALSE, NULL); + g_io_channel_unref(channel); + close(sockfd); + g_main_loop_unref(dcm_svc_data->main_loop); + + dcm_service_finish(dcm_svc_data); + + return 0; +}